From: yang on 17 Mar 2006 04:25 Hi, I had developed a usb hid device. In user mode, it works well by the hid api. But I can't communication with it in kernel, when I iocall it by the device io control irp, the return value is SUCCESS, but no data return.The source code use some driver sample, I don't know why? Somebody help me? Or some sample codes? Thanks!!!! yang -- Help
From: Doron Holan [MS] on 17 Mar 2006 11:33 how about posting the source code thatis not working d -- Please do not send e-mail directly to this alias. this alias is for newsgroup purposes only. This posting is provided "AS IS" with no warranties, and confers no rights. "yang" <yy_bj(a)hotmail.com> wrote in message news:A159B2F0-D094-492E-AF6B-519684A697C8(a)microsoft.com... > Hi, > I had developed a usb hid device. In user mode, it works well by the hid > api. > But I can't communication with it in kernel, when I iocall it by the > device > io control irp, the return value is SUCCESS, but no data return.The > source > code use some driver sample, I don't know why? Somebody help me? Or some > sample codes? > > Thanks!!!! > > yang > > -- > Help
From: yang on 19 Mar 2006 20:31 Thank you very much. the part of suorce code is this: /////////////////////////////////////////////////////////////////////////////////// // CallHidIoctl: Make an IOCTL call to the HID class driver static NTSTATUS CallHidIoctl( IN PDEVICE_OBJECT HidDevice, IN ULONG IoControlCode, OUT PVOID Output, IN ULONG OutputLen) { IO_STATUS_BLOCK IoStatus; KEVENT event; // Initialise IRP completion event KeInitializeEvent(&event, NotificationEvent, FALSE); // Build Internal IOCTL IRP PIRP Irp = IoBuildDeviceIoControlRequest( IoControlCode, HidDevice, NULL, 0, // Input buffer Output, OutputLen, // Output buffer TRUE, &event, &IoStatus); // Call the driver and wait for completion if necessary NTSTATUS status = IoCallDriver( HidDevice, Irp); if (status == STATUS_PENDING) { DebugPrintMsg("CallHidIoctl: waiting for completion"); status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); } else IoStatus.Status = status; // return IRP completion status status = IoStatus.Status; DebugPrint("CallHidIoctl: status %x", status); return status; } /////////////////////////////////////////////////////////////////////////////////// // GetPreparsedData: Get the HID device preparsed data static bool GetPreparsedData( IN PDEVICE_OBJECT HidDevice, OUT PHIDP_PREPARSED_DATA &HidPreparsedData) { HID_COLLECTION_INFORMATION HidCi; NTSTATUS status = CallHidIoctl( HidDevice, IOCTL_HID_GET_COLLECTION_INFORMATION, &HidCi, sizeof(HidCi)); if( !NT_SUCCESS(status)) { DebugPrint("IOCTL_HID_GET_COLLECTION_INFORMATION failed %x", status); return false; } //RETURN VALUE IS ZERO DebugPrint("HID attributes: VendorID=%4x, ProductID=%4x, VersionNumber=%4x", HidCi.VendorID, HidCi.ProductID, HidCi.VersionNumber); ULONG PreparsedDatalen = HidCi.DescriptorSize; DebugPrint("PreparsedDatalen %d",PreparsedDatalen); HidPreparsedData = (PHIDP_PREPARSED_DATA)ExAllocatePool( NonPagedPool, PreparsedDatalen); if( HidPreparsedData==NULL) { DebugPrintMsg("No memory"); return false; } status = CallHidIoctl( HidDevice, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, HidPreparsedData, PreparsedDatalen); if( !NT_SUCCESS(status)) { DebugPrint("IOCTL_HID_GET_COLLECTION_DESCRIPTOR failed %x", status); return false; } return true; } /////////////////////////////////////////////////////////////////////////////////// // GetCapabilities: Get capabilities to see if a HID keyboard // Return true if HID keyboard found static bool GetCapabilities( IN PDEVICE_OBJECT HidDevice, PHIDP_PREPARSED_DATA &HidPreparsedData, USHORT& InputReportLen, USHORT& OutputReportLen) { ULONG status; PDEVICE_OBJECT ChdPDO = NULL; HidPreparsedData = NULL; InputReportLen = 0; OutputReportLen = 0; if( !GetPreparsedData( HidDevice, HidPreparsedData)) { DebugPrintMsg("GetPreparsedData failed"); return false; } return true; } void CreateDevice( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING HidSymLinkName) { PFILE_OBJECT HidFileObject = NULL; PDEVICE_OBJECT HidDevice; NTSTATUS status = IoGetDeviceObjectPointer( HidSymLinkName, FILE_ALL_ACCESS, &HidFileObject, &HidDevice); if( !NT_SUCCESS(status)) { DebugPrint("IoGetDeviceObjectPointer failed %x", status); return; } // Close file object ObDereferenceObject(HidFileObject); ObReferenceObjectByPointer(HidDevice, FILE_ALL_ACCESS, NULL, KernelMode); // Inspect HID capabilities here PHIDP_PREPARSED_DATA HidPreparsedData = NULL; USHORT HidInputReportLen, HidOutputReportLen; if( !GetCapabilities( HidDevice, HidPreparsedData, HidInputReportLen, HidOutputReportLen)) { DebugPrintMsg("GetCapabilities failed"); ObDereferenceObject(HidDevice); FreeIfAllocated(HidPreparsedData); return; } FreeIfAllocated(HidPreparsedData); ObDereferenceObject(HidDevice); DebugPrintMsg("Device created OK"); } ///////////////////////////////////////////////////////////////////////////// // HidKbdDicCallback: PnP Notify callback for device interface changes // Process device arrival and removal messages NTSTATUS HidKbdDicCallback( IN PVOID NotificationStructure, IN PVOID Context) { PDEVICE_INTERFACE_CHANGE_NOTIFICATION dicn = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION)NotificationStructure; PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Context; if( IsEqualGUID( dicn->Event, GUID_DEVICE_INTERFACE_ARRIVAL)) { DebugPrint("Device arrival: %T", dicn->SymbolicLinkName); CreateDevice( DriverObject, dicn->SymbolicLinkName); } else if( IsEqualGUID( dicn->Event, GUID_DEVICE_INTERFACE_REMOVAL)) { DebugPrint("Device removal: %T", dicn->SymbolicLinkName); //DeleteDevice( dicn->SymbolicLinkName); } else DebugPrint("Some other device event: %T", dicn->SymbolicLinkName); return STATUS_SUCCESS; } #pragma code_seg("INIT") // start INIT section ///////////////////////////////////////////////////////////////////////////// // RegisterForPnpNotification: Ask for device interface change events NTSTATUS RegisterForPnpNotification( IN PDRIVER_OBJECT DriverObject) { DebugPrintMsg("RegisterForPnpNotification"); NTSTATUS status = IoRegisterPlugPlayNotification( EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_CLASS_INPUT, DriverObject, HidKbdDicCallback, DriverObject, &diNotificationEntry); return status; } ///////////////////////////////////////////////////////////////////////////// // DriverEntry: // // Description: // This function initializes the driver, and creates // any objects needed to process I/O requests. // // Arguments: // Pointer to the Driver object // Registry path string for driver service key // // Return Value: // This function returns STATUS_XXX extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; DebugPrintInit("vHidSk1 Entry"); DebugPrint("Registry_Path is %T",RegistryPath); // Export other driver entry points... DriverObject->DriverExtension->AddDevice = HidRdrAddDevice; DriverObject->DriverUnload = HidRdrUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = HidRdrCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidRdrClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = HidRdrCleanup; DriverObject->MajorFunction[IRP_MJ_PNP] = HidRdrPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = HidRdrPower; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HidRdrDeviceControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HidRdrInternalDeviceControl; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidRdrSystemControl; // Initialise spin lock which protects access to shared memory buffer ExInitializeFastMutex(&g_StateLock); RtlZeroBytes(g_ReaderName, 10 * sizeof(ULONG *)); RegisterForPnpNotification(DriverObject); DebugPrint("DriverEntry completed %x", status); return status; } #pragma code_seg() // end INIT section ////////////////////////////////////////////////////////////////////////////// // HidRdrUnload // // Description: // Unload the driver by removing any remaining objects, etc. // // Arguments: // Pointer to the Driver object // // Return Value: // None #pragma code_seg("PAGE") // start PAGE section ////////////////////////////////////////////////////////////////////////////// // UnregisterForPnpNotification: Stop device interface change events void UnregisterForPnpNotification() { //DeleteDevice(NULL); DebugPrintMsg("UnregisterForPnpNotification"); if( diNotificationEntry!=NULL) { IoUnregisterPlugPlayNotification(diNotificationEntry); diNotificationEntry = NULL; } } VOID HidRdrUnload(IN PDRIVER_OBJECT DriverObject) { DebugPrintMsg("HidRdrUnload"); DebugPrintClose(); UnregisterForPnpNotification(); return; }
From: Doron Holan [MS] on 20 Mar 2006 00:20 you need to keep the fileobject after IoGetDeviceObjectPointer. furthermore you need to set the next stack location FileObject value to it on every I/O you send. deref the fileobject when you close down the device. finally, you need to register for file handle notifications on the fileobject itself so that you can be notified when the HID device is being removed and close down the device. see the toastmon example for how to do this. d -- Please do not send e-mail directly to this alias. this alias is for newsgroup purposes only. This posting is provided "AS IS" with no warranties, and confers no rights. "yang" <yy_bj(a)hotmail.com> wrote in message news:7199414A-F69B-4E52-85E7-1F312B1852C6(a)microsoft.com... > Thank you very much. > the part of suorce code is this: > /////////////////////////////////////////////////////////////////////////////////// > // CallHidIoctl: Make an IOCTL call to the HID class driver > > static NTSTATUS CallHidIoctl( IN PDEVICE_OBJECT HidDevice, IN ULONG > IoControlCode, > OUT PVOID Output, IN ULONG OutputLen) > { > IO_STATUS_BLOCK IoStatus; > KEVENT event; > > // Initialise IRP completion event > KeInitializeEvent(&event, NotificationEvent, FALSE); > > // Build Internal IOCTL IRP > PIRP Irp = IoBuildDeviceIoControlRequest( > IoControlCode, HidDevice, > NULL, 0, // Input buffer > Output, OutputLen, // Output buffer > TRUE, &event, &IoStatus); > // Call the driver and wait for completion if necessary > NTSTATUS status = IoCallDriver( HidDevice, Irp); > if (status == STATUS_PENDING) > { > DebugPrintMsg("CallHidIoctl: waiting for completion"); > status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, > NULL); > } > else > IoStatus.Status = status; > > // return IRP completion status > status = IoStatus.Status; > DebugPrint("CallHidIoctl: status %x", status); > return status; > } > > /////////////////////////////////////////////////////////////////////////////////// > // GetPreparsedData: Get the HID device preparsed data > > static bool GetPreparsedData( IN PDEVICE_OBJECT HidDevice, OUT > PHIDP_PREPARSED_DATA &HidPreparsedData) > { > HID_COLLECTION_INFORMATION HidCi; > NTSTATUS status = CallHidIoctl( HidDevice, > IOCTL_HID_GET_COLLECTION_INFORMATION, > &HidCi, sizeof(HidCi)); > if( !NT_SUCCESS(status)) > { > DebugPrint("IOCTL_HID_GET_COLLECTION_INFORMATION failed %x", status); > return false; > } > > //RETURN VALUE IS ZERO > DebugPrint("HID attributes: VendorID=%4x, ProductID=%4x, > VersionNumber=%4x", > HidCi.VendorID, HidCi.ProductID, HidCi.VersionNumber); > > ULONG PreparsedDatalen = HidCi.DescriptorSize; > DebugPrint("PreparsedDatalen %d",PreparsedDatalen); > HidPreparsedData = (PHIDP_PREPARSED_DATA)ExAllocatePool( NonPagedPool, > PreparsedDatalen); > if( HidPreparsedData==NULL) > { > DebugPrintMsg("No memory"); > return false; > } > > status = CallHidIoctl( HidDevice, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, > HidPreparsedData, PreparsedDatalen); > if( !NT_SUCCESS(status)) > { > DebugPrint("IOCTL_HID_GET_COLLECTION_DESCRIPTOR failed %x", status); > return false; > } > > return true; > } > /////////////////////////////////////////////////////////////////////////////////// > // GetCapabilities: Get capabilities to see if a HID keyboard > // Return true if HID keyboard found > > static bool GetCapabilities( IN PDEVICE_OBJECT HidDevice, > PHIDP_PREPARSED_DATA &HidPreparsedData, > USHORT& InputReportLen, USHORT& OutputReportLen) > { > ULONG status; > PDEVICE_OBJECT ChdPDO = NULL; > > HidPreparsedData = NULL; > InputReportLen = 0; > OutputReportLen = 0; > if( !GetPreparsedData( HidDevice, HidPreparsedData)) > { > DebugPrintMsg("GetPreparsedData failed"); > return false; > } > > return true; > } > > void CreateDevice( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING > HidSymLinkName) > { > PFILE_OBJECT HidFileObject = NULL; > PDEVICE_OBJECT HidDevice; > NTSTATUS status = IoGetDeviceObjectPointer( HidSymLinkName, > FILE_ALL_ACCESS, > &HidFileObject, &HidDevice); > if( !NT_SUCCESS(status)) > { > DebugPrint("IoGetDeviceObjectPointer failed %x", status); > return; > } > > // Close file object > ObDereferenceObject(HidFileObject); > > ObReferenceObjectByPointer(HidDevice, FILE_ALL_ACCESS, NULL, KernelMode); > > // Inspect HID capabilities here > PHIDP_PREPARSED_DATA HidPreparsedData = NULL; > USHORT HidInputReportLen, HidOutputReportLen; > > if( !GetCapabilities( HidDevice, HidPreparsedData, HidInputReportLen, > HidOutputReportLen)) > { > DebugPrintMsg("GetCapabilities failed"); > ObDereferenceObject(HidDevice); > FreeIfAllocated(HidPreparsedData); > return; > } > > FreeIfAllocated(HidPreparsedData); > ObDereferenceObject(HidDevice); > > DebugPrintMsg("Device created OK"); > } > ///////////////////////////////////////////////////////////////////////////// > // HidKbdDicCallback: PnP Notify callback for device interface changes > // Process device arrival and removal messages > > NTSTATUS HidKbdDicCallback( > IN PVOID NotificationStructure, > IN PVOID Context) > { > PDEVICE_INTERFACE_CHANGE_NOTIFICATION dicn = > (PDEVICE_INTERFACE_CHANGE_NOTIFICATION)NotificationStructure; > PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Context; > > if( IsEqualGUID( dicn->Event, GUID_DEVICE_INTERFACE_ARRIVAL)) > { > DebugPrint("Device arrival: %T", dicn->SymbolicLinkName); > CreateDevice( DriverObject, dicn->SymbolicLinkName); > } > else if( IsEqualGUID( dicn->Event, GUID_DEVICE_INTERFACE_REMOVAL)) > { > DebugPrint("Device removal: %T", dicn->SymbolicLinkName); > //DeleteDevice( dicn->SymbolicLinkName); > } > else > DebugPrint("Some other device event: %T", dicn->SymbolicLinkName); > > return STATUS_SUCCESS; > } > > #pragma code_seg("INIT") // start INIT section > > ///////////////////////////////////////////////////////////////////////////// > // RegisterForPnpNotification: Ask for device interface change events > > NTSTATUS RegisterForPnpNotification( IN PDRIVER_OBJECT DriverObject) > { > DebugPrintMsg("RegisterForPnpNotification"); > > NTSTATUS status = IoRegisterPlugPlayNotification( > EventCategoryDeviceInterfaceChange, > PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, > (PVOID)&GUID_CLASS_INPUT, DriverObject, > HidKbdDicCallback, DriverObject, > &diNotificationEntry); > return status; > } > > ///////////////////////////////////////////////////////////////////////////// > // DriverEntry: > // > // Description: > // This function initializes the driver, and creates > // any objects needed to process I/O requests. > // > // Arguments: > // Pointer to the Driver object > // Registry path string for driver service key > // > // Return Value: > // This function returns STATUS_XXX > > extern "C" > NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, > IN PUNICODE_STRING RegistryPath) > { > NTSTATUS status = STATUS_SUCCESS; > > DebugPrintInit("vHidSk1 Entry"); > DebugPrint("Registry_Path is %T",RegistryPath); > > // Export other driver entry points... > DriverObject->DriverExtension->AddDevice = HidRdrAddDevice; > DriverObject->DriverUnload = HidRdrUnload; > > DriverObject->MajorFunction[IRP_MJ_CREATE] = HidRdrCreate; > DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidRdrClose; > > DriverObject->MajorFunction[IRP_MJ_CLEANUP] = HidRdrCleanup; > > DriverObject->MajorFunction[IRP_MJ_PNP] = HidRdrPnp; > DriverObject->MajorFunction[IRP_MJ_POWER] = HidRdrPower; > > DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HidRdrDeviceControl; > > DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = > HidRdrInternalDeviceControl; > > DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidRdrSystemControl; > > // Initialise spin lock which protects access to shared memory buffer > ExInitializeFastMutex(&g_StateLock); > RtlZeroBytes(g_ReaderName, 10 * sizeof(ULONG *)); > > RegisterForPnpNotification(DriverObject); > > DebugPrint("DriverEntry completed %x", status); > > return status; > } > #pragma code_seg() // end INIT section > > ////////////////////////////////////////////////////////////////////////////// > // HidRdrUnload > // > // Description: > // Unload the driver by removing any remaining objects, etc. > // > // Arguments: > // Pointer to the Driver object > // > // Return Value: > // None > > #pragma code_seg("PAGE") // start PAGE section > > ////////////////////////////////////////////////////////////////////////////// > // UnregisterForPnpNotification: Stop device interface change events > > void UnregisterForPnpNotification() > { > //DeleteDevice(NULL); > DebugPrintMsg("UnregisterForPnpNotification"); > if( diNotificationEntry!=NULL) > { > IoUnregisterPlugPlayNotification(diNotificationEntry); > diNotificationEntry = NULL; > } > } > > VOID HidRdrUnload(IN PDRIVER_OBJECT DriverObject) > { > DebugPrintMsg("HidRdrUnload"); > DebugPrintClose(); > > UnregisterForPnpNotification(); > > return; > } >
From: yang on 20 Mar 2006 09:59
Thank you! I have modified my source code as you said.But no effect. I revised it as blow: /////////////////////////////////////////////////////////////////////////////////// // CallHidIoctl: Make an IOCTL call to the HID class driver static NTSTATUS CallHidIoctl( IN PDEVICE_OBJECT HidDevice, PFILE_OBJECT HidFileObject, IN ULONG IoControlCode, OUT PVOID Output, IN ULONG OutputLen) { IO_STATUS_BLOCK IoStatus; KEVENT event; // Initialise IRP completion event KeInitializeEvent(&event, NotificationEvent, FALSE); // Build Internal IOCTL IRP PIRP Irp = IoBuildDeviceIoControlRequest( IoControlCode, HidDevice, NULL, 0, // Input buffer Output, OutputLen, // Output buffer TRUE, &event, &IoStatus); // Store file object pointer PIO_STACK_LOCATION IrpStack = IoGetNextIrpStackLocation(Irp); IrpStack->FileObject = HidFileObject; // Call the driver and wait for completion if necessary NTSTATUS status = IoCallDriver( HidDevice, Irp); if (status == STATUS_PENDING) { DebugPrintMsg("CallHidIoctl: waiting for completion"); status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); } else IoStatus.Status = status; // return IRP completion status status = IoStatus.Status; DebugPrint("CallHidIoctl: status %x", status); return status; } /////////////////////////////////////////////////////////////////////////////////// // GetPreparsedData: Get the HID device preparsed data static bool GetPreparsedData( IN PDEVICE_OBJECT HidDevice, PFILE_OBJECT HidFileObject, OUT PHIDP_PREPARSED_DATA &HidPreparsedData) { HID_COLLECTION_INFORMATION HidCi; NTSTATUS status = CallHidIoctl( HidDevice, HidFileObject, IOCTL_HID_GET_COLLECTION_INFORMATION, &HidCi, sizeof(HidCi)); if( !NT_SUCCESS(status)) { DebugPrint("IOCTL_HID_GET_COLLECTION_INFORMATION failed %x", status); return false; } DebugPrint("HID attributes: VendorID=%4x, ProductID=%4x, VersionNumber=%4x", HidCi.VendorID, HidCi.ProductID, HidCi.VersionNumber); ULONG PreparsedDatalen = HidCi.DescriptorSize; DebugPrint("PreparsedDatalen %d",PreparsedDatalen); HidPreparsedData = (PHIDP_PREPARSED_DATA)ExAllocatePool( NonPagedPool, PreparsedDatalen); if( HidPreparsedData==NULL) { DebugPrintMsg("No memory"); return false; } status = CallHidIoctl( HidDevice, HidFileObject, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, HidPreparsedData, PreparsedDatalen); if( !NT_SUCCESS(status)) { DebugPrint("IOCTL_HID_GET_COLLECTION_DESCRIPTOR failed %x", status); return false; } return true; } /////////////////////////////////////////////////////////////////////////////////// // GetCapabilities: Get capabilities to see if a HID keyboard // Return true if HID keyboard found static bool GetCapabilities( IN PDEVICE_OBJECT HidDevice, PFILE_OBJECT HidFileObject, PHIDP_PREPARSED_DATA &HidPreparsedData, USHORT& InputReportLen, USHORT& OutputReportLen) { ULONG status; PDEVICE_OBJECT ChdPDO = NULL; /* // Call the port driver with the request and wait for it to complete. status = CallUsbPnP(HidDevice, &ChdPDO, IRP_MN_QUERY_DEVICE_RELATIONS); if ( status != STATUS_SUCCESS ) return(false); DebugPrint("ChdPDO = %x", ChdPDO); if (ChdPDO) ObDereferenceObject( ChdPDO ); */ HidPreparsedData = NULL; InputReportLen = 0; OutputReportLen = 0; if( !GetPreparsedData( HidDevice, HidFileObject, HidPreparsedData)) { DebugPrintMsg("GetPreparsedData failed"); return false; } return true; } void CreateDevice( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING HidSymLinkName) { PFILE_OBJECT HidFileObject = NULL; PDEVICE_OBJECT HidDevice; NTSTATUS status = IoGetDeviceObjectPointer( HidSymLinkName, FILE_ALL_ACCESS, &HidFileObject, &HidDevice); if( !NT_SUCCESS(status)) { DebugPrint("IoGetDeviceObjectPointer failed %x", status); return; } // Close file object //ObDereferenceObject(HidFileObject); //ObReferenceObjectByPointer(HidDevice, FILE_ALL_ACCESS, NULL, KernelMode); // Inspect HID capabilities here PHIDP_PREPARSED_DATA HidPreparsedData = NULL; USHORT HidInputReportLen, HidOutputReportLen; if( !GetCapabilities( HidDevice, HidFileObject, HidPreparsedData, HidInputReportLen, HidOutputReportLen)) { DebugPrintMsg("GetCapabilities failed"); // Close file object ObDereferenceObject(HidFileObject); FreeIfAllocated(HidPreparsedData); return; } FreeIfAllocated(HidPreparsedData); ObDereferenceObject(HidFileObject); DebugPrintMsg("Device created OK"); } ///////////////////////////////////////////////////////////////////////////// // HidKbdDicCallback: PnP Notify callback for device interface changes // Process device arrival and removal messages NTSTATUS HidKbdDicCallback( IN PVOID NotificationStructure, IN PVOID Context) { PDEVICE_INTERFACE_CHANGE_NOTIFICATION dicn = (PDEVICE_INTERFACE_CHANGE_NOTIFICATION)NotificationStructure; PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Context; if( IsEqualGUID( dicn->Event, GUID_DEVICE_INTERFACE_ARRIVAL)) { DebugPrint("Device arrival: %T", dicn->SymbolicLinkName); CreateDevice( DriverObject, dicn->SymbolicLinkName); } else if( IsEqualGUID( dicn->Event, GUID_DEVICE_INTERFACE_REMOVAL)) { DebugPrint("Device removal: %T", dicn->SymbolicLinkName); //DeleteDevice( dicn->SymbolicLinkName); } else DebugPrint("Some other device event: %T", dicn->SymbolicLinkName); return STATUS_SUCCESS; } #pragma code_seg("INIT") // start INIT section ///////////////////////////////////////////////////////////////////////////// // RegisterForPnpNotification: Ask for device interface change events NTSTATUS RegisterForPnpNotification( IN PDRIVER_OBJECT DriverObject) { DebugPrintMsg("RegisterForPnpNotification"); NTSTATUS status = IoRegisterPlugPlayNotification( EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_CLASS_INPUT, DriverObject, HidKbdDicCallback, DriverObject, &diNotificationEntry); return status; } ///////////////////////////////////////////////////////////////////////////// // DriverEntry: // // Description: // This function initializes the driver, and creates // any objects needed to process I/O requests. // // Arguments: // Pointer to the Driver object // Registry path string for driver service key // // Return Value: // This function returns STATUS_XXX extern "C" NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; DebugPrintInit("vHidSk1 Entry"); DebugPrint("Registry_Path is %T",RegistryPath); // Export other driver entry points... DriverObject->DriverExtension->AddDevice = HidRdrAddDevice; DriverObject->DriverUnload = HidRdrUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = HidRdrCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = HidRdrClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = HidRdrCleanup; DriverObject->MajorFunction[IRP_MJ_PNP] = HidRdrPnp; DriverObject->MajorFunction[IRP_MJ_POWER] = HidRdrPower; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HidRdrDeviceControl; DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = HidRdrInternalDeviceControl; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = HidRdrSystemControl; // Initialise spin lock which protects access to shared memory buffer ExInitializeFastMutex(&g_StateLock); RtlZeroBytes(g_ReaderName, 10 * sizeof(ULONG *)); RegisterForPnpNotification(DriverObject); DebugPrint("DriverEntry completed %x", status); return status; } #pragma code_seg() // end INIT section ////////////////////////////////////////////////////////////////////////////// // HidRdrUnload // // Description: // Unload the driver by removing any remaining objects, etc. // // Arguments: // Pointer to the Driver object // // Return Value: // None #pragma code_seg("PAGE") // start PAGE section ////////////////////////////////////////////////////////////////////////////// // UnregisterForPnpNotification: Stop device interface change events void UnregisterForPnpNotification() { //DeleteDevice(NULL); DebugPrintMsg("UnregisterForPnpNotification"); if( diNotificationEntry!=NULL) { IoUnregisterPlugPlayNotification(diNotificationEntry); diNotificationEntry = NULL; } } VOID HidRdrUnload(IN PDRIVER_OBJECT DriverObject) { DebugPrintMsg("HidRdrUnload"); DebugPrintClose(); UnregisterForPnpNotification(); return; } |