Как собрать и зарегистрировать драйвер? А далее запустить и просмотреть его работу
wdk 8, 8.1, 10 установлены. Какой проект надо создать в VS2015 чтобы система собрала драйвер? Я так понимаю расширение драйвера должен быть .sys? И как запустить его и проверить? Заранее спасибо.
Отслеживать
задан 25 мар 2016 в 8:19
718 8 8 серебряных знаков 20 20 бронзовых знаков
Драйвер не запускают, а загружают. По сборке, думаю, должна быть информация там, откуда вы взяли этот пример.
25 мар 2016 в 9:20
да, спасибо. все запустил
Регистрация в качестве промежуточного драйвера NDIS
Промежуточный драйвер NDIS должен регистрировать свои функции MiniportXxx и функции ProtocolXxx с помощью NDIS в контексте функции DriverEntry . Чтобы зарегистрировать функции MiniportXxx, промежуточный драйвер должен вызвать NdisMRegisterMiniportDriver с установленным флагом NDIS_INTERMEDIATE_DRIVER. Этот флаг находится в структуре NDIS_MINIPORT_DRIVER_CHARACTERISTICS , которую драйвер передает в MiniportDriverCharacteristics . Этот вызов экспортирует функции MiniportXxx промежуточного драйвера. Дополнительные сведения о регистрации функций MiniportXxx см. в разделе Регистрация промежуточного драйвера в качестве драйвера miniport.
Обратите внимание, что промежуточный драйвер управляет тем, когда инициализированы его виртуальные минипорты, и, следовательно, когда драйвер готов принимать отправки и запросы на адаптере. NDIS вызывает функцию MiniportInitializeEx промежуточного драйвера после запуска диспетчером Plug and Play (PnP) виртуального мини-порта и после того, как промежуточный драйвер вызвал NdisIMInitializeDeviceInstanceEx для этого устройства. Вызов MiniportInitializeEx может произойти позже и, следовательно, не обязательно находится в контексте вызова NdisIMInitializeDeviceInstanceEx. Если промежуточный драйвер экспортирует несколько виртуальных мини-портов, драйвер должен вызывать NdisIMInitializeDeviceInstanceEx для каждого виртуального мини-порта, который он делает доступным для сетевых запросов.
Чтобы зарегистрировать функции ProtocolXxx , промежуточный драйвер должен вызвать функцию NdisRegisterProtocolDriver . Дополнительные сведения о регистрации функций ProtocolXxx см. в разделе Регистрация промежуточного драйвера в качестве драйвера протокола.
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Windows driver documentation
Регистрация составного устройства
В этом разделе описывается, как драйвер многофункционального USB-устройства, называемого составным драйвером, может зарегистрировать и отменить регистрацию составного устройства в базовом стеке драйверов USB. Предоставленный корпорацией Майкрософт драйвер, Usbccgp.sys, является составным драйвером по умолчанию, который загружается Windows. Процедура, описанная в этом разделе, применяется к составным драйверам на основе пользовательской модели драйвера Windows (WDM), который заменяет Usbccgp.sys.
Устройство универсальной последовательной шины (USB) может предоставлять несколько активных одновременно функций. Такие многофункционные устройства также называются составными устройствами. Например, составное устройство может определить функцию для функций клавиатуры и другую функцию для мыши. Функции устройства перечисляются составным драйвером. Составной драйвер может управлять этими функциями в монолитной модели или создавать физические объекты устройств (PDO) для каждой из функций. Эти отдельные PDO управляются соответствующими драйверами функций USB, драйвером клавиатуры и драйвером мыши.
Спецификация USB 3.0 определяет функцию приостановки и удаленного пробуждения , которая позволяет отдельным функциям входить в состояния с низким энергопотреблением и выходить из нее, не влияя на состояние питания других функций или всего устройства. Дополнительные сведения о функции см. в разделе How to Implement Function Suspend in a Composite Driver.
Чтобы использовать эту функцию, составной драйвер должен зарегистрировать устройство в базовом стеке драйверов USB. Так как эта функция применяется к устройствам USB 3.0, составной драйвер должен убедиться, что базовый стек поддерживает версию USBD_INTERFACE_VERSION_602. С помощью запроса на регистрацию составной драйвер:
- Сообщает базовому стеку USB-драйверов о том, что драйвер отвечает за отправку запроса на передачу функции для удаленного пробуждения. Запрос удаленного пробуждения обрабатывается стеком драйверов USB, который отправляет необходимые запросы протокола на устройство.
- Получает список дескрипторов функций (по одному для каждой функции), назначенных стеком драйверов USB. Затем составной драйвер может использовать дескриптор функции в запросе драйвера для удаленного пробуждения функции, связанной с дескриптором.
Как правило, составной драйвер отправляет запрос на регистрацию в процедуре AddDevice драйвера или start-device для обработки IRP_MN_START_DEVICE. Следовательно, составной драйвер освобождает ресурсы, выделенные для регистрации в подпрограммах выгрузки драйвера, таких как остановка устройства (IRP_MN_STOP_DEVICE) или процедура удаления устройства (IRP_MN_REMOVE_DEVICE).
Предварительные требования
Перед отправкой запроса на регистрацию убедитесь, что:
- У вас есть количество функций на устройстве. Это число может быть производным от дескрипторов, полученных запросом get-configuration.
- Вы получили дескриптор USBD в предыдущем вызове USBD_CreateHandle.
- Базовый стек драйверов USB поддерживает устройства USB 3.0. Для этого вызовите USBD_IsInterfaceVersionSupported и передайте USBD_INTERFACE_VERSION_602 в качестве версии для проверка.
Инструкции
Регистрация составного устройства
В следующей процедуре описывается, как выполнить сборку и отправить запрос на регистрацию для связывания составного драйвера со стеком usb-драйверов.
- Выделите структуру COMPOSITE_DEVICE_CAPABILITIES и инициализируйте ее, вызвав макрос COMPOSITE_DEVICE_CAPABILITIES_INIT .
- Задайте для элемента CapabilityFunctionSuspendэлемента COMPOSITE_DEVICE_CAPABILITIES значение 1.
- Выделите REGISTER_COMPOSITE_DEVICE структуру и инициализируйте структуру, вызвав подпрограмму USBD_BuildRegisterCompositeDevice . В вызове укажите дескриптор USBD, инициализированную структуру COMPOSITE_DEVICE_CAPABILITIES и количество функций.
- Выделите пакет запроса ввода-вывода (IRP), вызвав IoAllocateIrp и получите указатель на первое расположение стека IRP (IO_STACK_LOCATION), вызвав IoGetNextIrpStackLocation.
- Выделите память для буфера, который достаточно велик для хранения массива дескрипторов функций (USBD_FUNCTION_HANDLE). Число элементов в массиве должно быть числом PDO.
- Создайте запрос, задав следующие элементы IO_STACK_LOCATION:
- Укажите тип запроса, задав для параметра Parameters.DeviceIoControl.IoControlCodeзначение IOCTL_INTERNAL_USB_REGISTER_COMPOSITE_DEVICE.
- Укажите входной параметр, задав для Parameters.Others.Argument1 адрес инициализированной структуры REGISTER_COMPOSITE_DEVICE .
- Укажите выходной параметр, задав для AssociatedIrp.SystemBuffer буфер, выделенный на шаге 5.
- Вызовите IoCallDriver , чтобы отправить запрос, передав IRP в следующее расположение стека.
По завершении проверьте массив дескрипторов функций, возвращаемых стеком драйверов USB. Вы можете сохранить массив в контексте устройства драйвера для дальнейшего использования.
В следующем примере кода показано, как создать и отправить запрос на регистрацию. В примере предполагается, что составной драйвер сохраняет ранее полученное число функций и дескриптор USBD в контексте устройства драйвера.
VOID RegisterCompositeDriver(PPARENT_FDO_EXT parentFdoExt) < PIRP irp; REGISTER_COMPOSITE_DRIVER registerInfo; COMPOSITE_DRIVER_CAPABILITIES capabilities; NTSTATUS status; PVOID buffer; ULONG bufSize; PIO_STACK_LOCATION nextSp; buffer = NULL; COMPOSITE_DRIVER_CAPABILITIES_INIT(&capabilities); capabilities.CapabilityFunctionSuspend = 1; USBD_BuildRegisterCompositeDriver(parentFdoExt->usbdHandle, capabilities, parentFdoExt->numFunctions, ®isterInfo); irp = IoAllocateIrp(parentFdoExt->topDevObj->StackSize, FALSE); if (irp == NULL) < //IoAllocateIrp failed. status = STATUS_INSUFFICIENT_RESOURCES; goto ExitRegisterCompositeDriver; >nextSp = IoGetNextIrpStackLocation(irp); bufSize = parentFdoExt->numFunctions * sizeof(USBD_FUNCTION_HANDLE); buffer = ExAllocatePoolWithTag (NonPagedPool, bufSize, POOL_TAG); if (buffer == NULL) < // Memory alloc for function-handles failed. status = STATUS_INSUFFICIENT_RESOURCES; goto ExitRegisterCompositeDriver; >nextSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_REGISTER_COMPOSITE_DRIVER; //Set the input buffer in Argument1 nextSp->Parameters.Others.Argument1 = ®isterInfo; //Set the output buffer in SystemBuffer field for USBD_FUNCTION_HANDLE. irp->AssociatedIrp.SystemBuffer = buffer; // Pass the IRP down to the next device object in the stack. Not shown. status = CallNextDriverSync(parentFdoExt, irp, FALSE); if (!NT_SUCCESS(status)) < //Failed to register the composite driver. goto ExitRegisterCompositeDriver; >parentFdoExt->compositeDriverRegistered = TRUE; parentFdoExt->functionHandleArray = (PUSBD_FUNCTION_HANDLE) buffer; End: if (!NT_SUCCESS(status)) < if (buffer != NULL) < ExFreePoolWithTag (buffer, POOL_TAG); buffer = NULL; >> if (irp != NULL) < IoFreeIrp(irp); irp = NULL; >return; >
Отмена регистрации составного устройства
- Выделите IRP, вызвав IoAllocateIrp и получите указатель на первое расположение стека (IO_STACK_LOCATION) IRP, вызвав IoGetNextIrpStackLocation.
- Создайте запрос, задав для элемента Parameters.DeviceIoControl.IoControlCodeIO_STACK_LOCATIONзначение IOCTL_INTERNAL_USB_UNREGISTER_COMPOSITE_DEVICE.
- Вызовите IoCallDriver , чтобы отправить запрос, передав IRP в следующее расположение стека.
Запрос IOCTL_INTERNAL_USB_UNREGISTER_COMPOSITE_DEVICE отправляется один раз составным драйвером в контексте процедуры remove-device. Цель запроса — удалить связь между стеком драйверов USB и составным драйвером и его перечислимой функцией. Запрос также очищает все ресурсы, созданные для поддержания этой связи, и все дескрипторы функций, возвращенные в предыдущем запросе на регистрацию.
В следующем примере кода показано, как создать и отправить запрос на отмену регистрации составного устройства. В примере предполагается, что составной драйвер был ранее зарегистрирован с помощью запроса на регистрацию, как описано ранее в этом разделе.
VOID UnregisterCompositeDriver( PPARENT_FDO_EXT parentFdoExt ) < PIRP irp; PIO_STACK_LOCATION nextSp; NTSTATUS status; PAGED_CODE(); irp = IoAllocateIrp(parentFdoExt->topDevObj->StackSize, FALSE); if (irp == NULL) < //IoAllocateIrp failed. status = STATUS_INSUFFICIENT_RESOURCES; return; >nextSp = IoGetNextIrpStackLocation(irp); nextSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; nextSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_UNREGISTER_COMPOSITE_DRIVER; // Pass the IRP down to the next device object in the stack. Not shown. status = CallNextDriverSync(parentFdoExt, irp, FALSE); if (NT_SUCCESS(status)) < parentFdoExt->compositeDriverRegistered = FALSE; > IoFreeIrp(irp); return; >
Регистрация драйвера и управление запуском и остановкой
При запуске операционной системы Windows загружает RDBSS и все сетевые драйверы мини-перенаправления на основе параметров в реестре. Для монолитного драйвера мини-перенаправления сети, который статически связан с rdbsslib.lib, драйвер должен вызвать подпрограмму RxDriverEntry из своей подпрограммы DriverEntry , чтобы инициализировать копию библиотеки RDBSSLIB, связанной с сетевым драйвером. В этом случае подпрограмма RxDriverEntry должна вызываться перед вызовом и использованием других процедур RDBSS. Для не монолитного сетевого мини-перенаправления драйвера (перенаправления Microsoft SMB) драйвер устройства rdbss.sys инициализируется в собственной подпрограмме DriverEntry при загрузке.
Сетевой мини-перенаправитель регистрируется в RDBSS, когда драйвер загружается ядром, и отменяет регистрацию в RDBSS при выгрузке драйвера. Сетевой мини-перенаправитель сообщает RDBSS о том, что он был загружен, вызвав RxRegisterMinirdr, подпрограмму регистрации, экспортированную из RDBSS. В рамках этого процесса регистрации мини-перенаправитель сети передает параметр в RxRegisterMinirdr , который является указателем на большую структуру, MINIRDR_DISPATCH. Эта структура содержит сведения о конфигурации для сетевого мини-перенаправления и таблицу отправки указателей на процедуры обратного вызова, реализованные драйвером ядра сетевого мини-перенаправления. RDBSS вызывает драйвер сетевого мини-перенаправления через этот список процедур обратного вызова.
Подпрограмма RxRegisterMinirdr задает все подпрограммы диспетчеризации драйверов драйвера сетевого мини-перенаправления, указывая на подпрограмму диспетчера RDBSS верхнего уровня RxFsdDispatch. Сетевой мини-перенаправитель может переопределить это поведение, сохранив собственные точки входа и перезаписав отправку драйвера с собственными точками входа после вызова RxRegisterMinirdr или установив специальный параметр при вызове RxRegisterMinirdr.
Драйвер мини-перенаправления сети фактически не запускает работу, пока не получит вызов к своей подпрограмме MRxStart , одной из подпрограмм обратного вызова, переданных в MINIRDR_DISPATCH структуре. Подпрограмма обратного вызова MrxStart должна быть реализована драйвером сетевого мини-перенаправления, если он хочет получать подпрограммы обратного вызова для операций, если мини-перенаправитель сети не сохраняет собственные точки входа диспетчеризации драйвера. В противном случае RDBSS разрешит драйверу только следующие пакеты запросов ввода-вывода, пока MrxStart не вернет успешно:
- IRP-запросы для создания устройств и операций устройства, где fileObject-FileName.Length> в IRPSP равно нулю, а FileObject-RelatedFileObject> имеет значение NULL.
Для любого другого запроса IRP подпрограмма RxFsdDispatch диспетчеризации RDBSS вернет состояние STATUS_REDIRECTOR_NOT_STARTED.
Подпрограмма диспетчеризации RDBSS также завершит сбой всех запросов для следующих пакетов запросов ввода-вывода:
- IRP_MJ_CREATE_MAILSLOT
- IRP_MJ_CREATE_NAMED_PIPE
Подпрограмма обратного вызова MrxStart , реализованная мини-перенаправлением сети, вызывается RDBSS при вызове подпрограммы RxStartMinirdr . Подпрограмма RxStartMinirdr RDBSS обычно вызывается в результате запроса кода управления файловой системой (FSCTL) или кода управления вводом-выводом (IOCTL) от приложения или службы пользовательского режима для запуска мини-перенаправления сети. Вызов RxStartMinirdr не может быть выполнен из подпрограммы DriverEntry мини-перенаправления сети после успешного вызова RxRegisterMinirdr, так как для некоторых процессов запуска требуется завершить инициализацию драйвера. После получения вызова RxStartMinirdr RDBSS завершает процесс запуска, вызывая подпрограмму MrxStart мини-перенаправителя сети. Если вызов MrxStart возвращает успешное выполнение, RDBSS устанавливает внутреннее состояние мини-перенаправления в RDBSS на RDBSS_STARTED.
RDBSS экспортирует подпрограмму RxSetDomainForMailslotBroadcast, чтобы задать домен для широковещательных передач mailslot. Эта подпрограмма используется во время регистрации, если мини-перенаправление сети поддерживает почтовые узлы.
Удобную подпрограмму , __RxFillAndInstallFastIoDispatch, экспортируемую RDBSS, можно использовать для копирования всех указателей IRP_MJ_XXX драйвера для обработки запросов ввода-вывода в сопоставимые векторы диспетчеризации быстрых операций ввода-вывода, но эта подпрограмма работает только для не монолитных драйверов.
RDBSS также экспортирует подпрограммы для уведомления RDBSS о том, что мини-перенаправление сети запускается или останавливается. Эти вызовы используются, если сетевой мини-перенаправление включает в себя службу администрирования пользовательского режима или служебное приложение, которое запускает и останавливает перенаправитель. Эта служба или приложение в пользовательском режиме может отправлять пользовательские запросы FSCTL или IOCTL драйверу сетевого мини-перенаправления, чтобы указать, что он должен запускаться или останавливаться. Перенаправитель может вызвать подпрограммы RDBSS RxStartMinirdr или RxStopMinirdr , чтобы уведомить RDBSS о запуске или остановке этого мини-перенаправления сети.
В следующей таблице перечислены процедуры регистрации драйвера RDBSS и управления запуском и остановкой.
Эта подпрограмма вызывается монолитным драйвером мини-перенаправления сети из подпрограммы DriverEntry для инициализации RDBSS.
Для не монолитных драйверов эта подпрограмма инициализации эквивалентна процедуре DriverEntry драйвера устройства rbss.sys.
Эта подпрограмма вызывается драйвером сетевого мини-перенаправления для регистрации драйвера в RDBSS, который добавляет сведения о регистрации во внутреннюю таблицу регистрации. RDBSS также создает объект устройства для мини-перенаправления сети.
Эта подпрограмма вызывается драйвером сетевого мини-перенаправления, чтобы задать домен, используемый для широковещательной рассылки, если почтовые узлы поддерживаются драйвером.
Эта подпрограмма запускает сетевой мини-перенаправитель, который вызывается для регистрации. RDBSS также зарегистрирует драйвер сетевого мини-перенаправления в качестве поставщика UNC в MUP, если драйвер указывает на поддержку UNC-имен.
Эта процедура останавливает драйвер сетевого мини-перенаправления. Остановленный драйвер больше не будет получать новые команды, кроме запросов IOCTL или FSCTL.
Эта подпрограмма вызывается драйвером сетевого мини-перенаправления для отмены регистрации драйвера в RDBSS и удаления сведений о регистрации из внутренней таблицы регистрации RDBSS.
Эта подпрограмма является встроенной функцией, определенной в rxstruc.h, которая вызывается драйвером мини-перенаправления сети для отмены регистрации драйвера в RDBSS и удаления сведений о регистрации из внутренней таблицы регистрации RDBSS. Встроенная функция RxUnregisterMinirdr внутренне вызывает RxpUnregisterMinirdr.
Эта подпрограмма заполняет быстрый вектор диспетчеризации ввода-вывода, чтобы он был идентичен обычному вектору ввода-вывода диспетчера, и устанавливает его в объект драйвера, связанный с переданным объектом устройства.
Следующий макрос определен в файле заголовка mrx.h, который вызывает одну из этих подпрограмм. Обычно этот макрос используется вместо вызова подпрограммы __RxFillAndInstallFastIoDispatch напрямую.
RxFillAndInstallFastIoDispatch(__devobj, __fastiodisp)
Этот макрос вызывает __RxFillAndInstallFastIoDispatchдля заполнения вектора быстрой диспетчеризации ввода-вывода, чтобы он был идентичен обычному вектору ввода-вывода диспетчера, и устанавливает его в объект драйвера, связанный с переданным объектом устройства.
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.
Windows driver documentation