Пожалуйста, расскажите по-подробнее об этой функции. Что она конкретно делает? И что означает член DevicesArePolled в структуре HID_MINIDRIVER_REGISTRATION ?
Грубого говоря, региструруешь свой драйвер для получения запросов IOCTL\ INTERNAL _IOCTL от HID (IOCTL_HID_GET_DEVICE_DESCRIPTOR, IOCTL_HID_READ_REPORT and etc.) DevicesArePolled если установлен, то система может слать не сколько запросов (IOCTL_HID_READ_REPORT), если нет соотвественно только один. Не которые устройства не могут обробатывать несколько запросов(клавиатура, кей уп, даун) ... Но если устройство может, то пул(не сколько запросов) дает хороший прирост производительности .. П.С Но в целом лучше прочитайте матчасть: http://msdn.microsoft.com/en-us/library/ff543301%28v=VS.85%29.aspx
Мне тогда HidRegisterMinidriver вообще не понадобилась, а сейчас она мне действительно нужна, к тому же я тогда программировал на МАСМе, сейчас же программирую на Си, но линкер выдаёт: Собираю в DDK 7600.16385.1, который я сам встроил в Visual studio 2015 MKJoy.c Code (Text): #include "MKJoy.h" NTSTATUS DriverEntry (PDRIVER_OBJECT, PUNICODE_STRING); #ifdef ALLOC_PRAGMA #pragma alloc_text (INIT, DriverEntry) #pragma alloc_text (PAGE, MKJoy_AddDevice) #pragma alloc_text (PAGE, MKJoy_PnP) #pragma alloc_text (PAGE, MKJoy_Power) #pragma alloc_text (PAGE, MKJoy_Unload) #endif NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) /*++ Routine Description: Initialize the entry points of the driver. --*/ { ULONG i; HID_MINIDRIVER_REGISTRATION reg; // // Fill in all the dispatch entry points with the pass through function // and the explicitly fill in the functions we are going to intercept // for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = MKJoy_DispatchPassThrough; } DriverObject->MajorFunction [IRP_MJ_PNP] = MKJoy_PnP; DriverObject->MajorFunction [IRP_MJ_POWER] = MKJoy_Power; DriverObject->DriverUnload = MKJoy_Unload; DriverObject->DriverExtension->AddDevice = MKJoy_AddDevice; RtlZeroMemory(®, sizeof(reg)); reg.Revision = HID_REVISION; reg.DriverObject = DriverObject; reg.RegistryPath = RegistryPath; reg.DeviceExtensionSize = 0; //sizeof(DEVICE_EXTENSION) + GetSizeofGenericExtension(); reg.DevicesArePolled = FALSE; return HidRegisterMinidriver(®); } NTSTATUS MKJoy_AddDevice( IN PDRIVER_OBJECT Driver, IN PDEVICE_OBJECT PDO ) { PAGED_CODE(); return STATUS_SUCCESS; } NTSTATUS MKJoy_Complete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: Generic completion routine that allows the driver to send the irp down the stack, catch it on the way up, and do more processing at the original IRQL. --*/ { PKEVENT event; event = (PKEVENT) Context; // // We could switch on the major and minor functions of the IRP to perform // different functions, but we know that Context is an event that needs // to be set. // KeSetEvent(event, 0, FALSE); // // Allows the caller to use the IRP after it is completed // return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS MKJoy_DispatchPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: Passes a request on to the lower driver. Considerations: If you are creating another device object (to communicate with user mode via IOCTLs), then this function must act differently based on the intended device object. If the IRP is being sent to the solitary device object, then this function should just complete the IRP (becuase there is no more stack locations below it). If the IRP is being sent to the PnP built stack, then the IRP should be passed down the stack. These changes must also be propagated to all the other IRP_MJ dispatch functions (such as create, close, cleanup, etc.) as well! --*/ { PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp); // // Pass the IRP to the target // IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(GET_NEXT_DEVICE_OBJECT(DeviceObject), Irp); } NTSTATUS MKJoy_PnP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine is the dispatch routine for plug and play irps Arguments: DeviceObject - Pointer to the device object. Irp - Pointer to the request packet. Return Value: Status is returned. --*/ { PHID_DEVICE_EXTENSION devExt; PIO_STACK_LOCATION irpStack; NTSTATUS status = STATUS_SUCCESS; KIRQL oldIrql; KEVENT event; PAGED_CODE(); devExt = (PHID_DEVICE_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); switch (irpStack->MinorFunction) { case IRP_MN_START_DEVICE: { // // The device is starting. // // We cannot touch the device (send it any non pnp irps) until a // start device has been passed down to the lower drivers. // IoCopyCurrentIrpStackLocationToNext(Irp); KeInitializeEvent(&event, NotificationEvent, FALSE ); IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) MKJoy_Complete, &event, TRUE, TRUE, TRUE); // No need for Cancel status = IoCallDriver(devExt->NextDeviceObject, Irp); if (STATUS_PENDING == status) { KeWaitForSingleObject( &event, Executive, // Waiting for reason of a driver KernelMode, // Waiting in kernel mode FALSE, // No allert NULL); // No timeout } Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); break; } default: // // Here the filter driver might modify the behavior of these IRPS // Please see PlugPlay documentation for use of these IRPs. // IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(devExt->NextDeviceObject, Irp); break; } return status; } NTSTATUS MKJoy_Power( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine is the dispatch routine for power irps Does nothing except record the state of the device. Arguments: DeviceObject - Pointer to the device object. Irp - Pointer to the request packet. Return Value: Status is returned. --*/ { PHID_DEVICE_EXTENSION devExt; PAGED_CODE(); devExt = (PHID_DEVICE_EXTENSION) DeviceObject->DeviceExtension; PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); return PoCallDriver(devExt->NextDeviceObject, Irp); } VOID MKJoy_Unload( IN PDRIVER_OBJECT Driver ) /*++ Routine Description: Free all the allocated resources associated with this driver. Arguments: DriverObject - Pointer to the driver object. Return Value: None. --*/ { PAGED_CODE(); UNREFERENCED_PARAMETER(Driver); ASSERT(NULL == Driver->DeviceObject); } MKJoy.h Code (Text): #ifndef MKJoy_H #define MKJoy_H #include "ntddk.h" #include "wdm.h" //#include "hidtoken.h" #include "hidusage.h" #include "hidport.h" //#include "gameport.h" #define GET_NEXT_DEVICE_OBJECT(DO) (((PHID_DEVICE_EXTENSION)(DO)->DeviceExtension)->NextDeviceObject) /*typedef struct _DEVICE_EXTENSION { } DEVICE_EXTENSION, *PDEVICE_EXTENSION; */ // // Prototypes // NTSTATUS MKJoy_AddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT BusDeviceObject ); NTSTATUS MKJoy_DispatchPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS MKJoy_PnP ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); NTSTATUS MKJoy_Power ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); VOID MKJoy_Unload ( IN PDRIVER_OBJECT DriverObject ); #endif // MKJoy_H Подскажите, пожалуйста, почему возникает эта ошибка?
Не линкеровалось из-за этой строки в makefile Code (Text): RESOURCE_ONLY_DLL = 1 Я её написал, чтобы компилировать драйвер без ссылки на *.pdb