阅读:930回复:0
一个问题!
我做的是一个HID设备,用HID.SYS没有问题,但用我自己做的驱动程序就不行了
问题是顺序读写还可以,可是这样效率太低,若要用两个线程一个读,一个写, 只可以得取后的几个数据,请指教! 这是驱动部分代码: 写操作: NTSTATUS UsbKbdWrite( IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PUSBKBD_DEVICE_EXTENSION dx = (PUSBKBD_DEVICE_EXTENSION)fdo->DeviceExtension; if( dx->IODisabled) return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0); if (!LockDevice(dx)) return CompleteIrp( Irp, STATUS_DELETE_PENDING, 0); PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status = STATUS_SUCCESS; ULONG BytesTxd = 0; // Get call parameters LONGLONG FilePointer = IrpStack->Parameters.Write.ByteOffset.QuadPart; ULONG WriteLen = IrpStack->Parameters.Write.Length; DebugPrint(\"Write %d bytes from file pointer %d\",(int)WriteLen,(int)FilePointer); if( FilePointer<0 || WriteLen<1) status = STATUS_INVALID_PARAMETER; else { // Only ever write one byte BytesTxd = 1; PUCHAR pData = (PUCHAR)Irp->AssociatedIrp.SystemBuffer; UsbSendOutputReport( dx,pData); } DebugPrint(\"Write: %d bytes written\",(int)BytesTxd); // Complete IRP CompleteIrp(Irp,status,BytesTxd); UnlockDevice(dx); return status; } NTSTATUS UsbSendOutputReport( IN PUSBKBD_DEVICE_EXTENSION dx, PUCHAR OutputData) { // Allocate memory for URB USHORT UrbSize = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); PURB urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize); if( urb==NULL) { DebugPrintMsg(\"No URB memory\"); return STATUS_INSUFFICIENT_RESOURCES; } // Build URB to send Class interface control request on Default pipe UsbBuildVendorRequest( urb, URB_FUNCTION_CLASS_INTERFACE, UrbSize, USBD_TRANSFER_DIRECTION_OUT, // Direction out 0, // Reserved bits SET_REPORT, // Request 0x0200, // Output report type, Report id zero //add by the 0x0200 is special value for the KBD 0, // interface index OutputData,//change by &OutputData, // Output data NULL, 8, //change by old value is 1 NULL); // Call the USB driver DebugPrintMsg(\"Sending set report\"); NTSTATUS status = CallUSBDI( dx, urb); // Check statuses if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status)) { //add by DebugPrintMsg(\"Send URB Error.add by \"); DebugPrint(\"status %x URB status %x\", status, urb->UrbHeader.Status); status = STATUS_UNSUCCESSFUL; } ExFreePool(urb); return status; } NTSTATUS CallUSBDI( IN PUSBKBD_DEVICE_EXTENSION dx, IN PVOID UrbEtc, IN ULONG IoControlCode/*=IOCTL_INTERNAL_USB_SUBMIT_URB*/, IN ULONG Arg2/*=0*/) { IO_STATUS_BLOCK IoStatus; KEVENT event; // Initialise IRP completion event KeInitializeEvent(&event, NotificationEvent, FALSE); // Build Internal IOCTL IRP PIRP Irp = IoBuildDeviceIoControlRequest( IoControlCode, dx->NextStackDevice, NULL, 0, // Input buffer NULL, 0, // Output buffer TRUE, &event, &IoStatus); // Get IRP stack location for next driver down (already set up) PIO_STACK_LOCATION NextIrpStack = IoGetNextIrpStackLocation(Irp); // Store pointer to the URB etc NextIrpStack->Parameters.Others.Argument1 = UrbEtc; NextIrpStack->Parameters.Others.Argument2 = (PVOID)Arg2; // Call the driver and wait for completion if necessary NTSTATUS status = IoCallDriver( dx->NextStackDevice, Irp); if (status == STATUS_PENDING) { // DebugPrintMsg(\"CallUSBDI: waiting for URB completion\"); status = KeWaitForSingleObject( &event, Suspended, KernelMode, FALSE, NULL); status = IoStatus.Status; } // return IRP completion status // DebugPrint(\"CallUSBDI returned %x\",status); return status; } /////////////////////////////////// 读操作: NTSTATUS UsbKbdRead( IN PDEVICE_OBJECT fdo, IN PIRP Irp) { PUSBKBD_DEVICE_EXTENSION dx = (PUSBKBD_DEVICE_EXTENSION)fdo->DeviceExtension; if( dx->IODisabled) return CompleteIrp( Irp, STATUS_DEVICE_NOT_CONNECTED, 0); if (!LockDevice(dx)) return CompleteIrp( Irp, STATUS_DELETE_PENDING, 0); PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status = STATUS_SUCCESS; ULONG BytesTxd = 0; // Get call parameters LONGLONG FilePointer = IrpStack->Parameters.Read.ByteOffset.QuadPart; ULONG ReadLen = IrpStack->Parameters.Read.Length; DebugPrint(\"Read %d bytes from file pointer %d\",(int)ReadLen,(int)FilePointer); // Check file pointer if( FilePointer<0) status = STATUS_INVALID_PARAMETER; else { status = UsbDoInterruptTransfer( dx, Irp->AssociatedIrp.SystemBuffer, ReadLen); BytesTxd = ReadLen; } DebugPrint(\"Read: %x %d bytes returned\",status,(int)BytesTxd); // Complete IRP CompleteIrp(Irp,status,BytesTxd); UnlockDevice(dx); return status; } NTSTATUS UsbDoInterruptTransfer( IN PUSBKBD_DEVICE_EXTENSION dx, IN PVOID UserBuffer, ULONG& UserBufferSize) { // Check we\'re selected if( dx->UsbPipeHandle==NULL) return STATUS_INVALID_HANDLE; // Check input parameters ULONG InputBufferSize = UserBufferSize; UserBufferSize = 0; if( UserBuffer==NULL || InputBufferSize<8) return STATUS_INVALID_PARAMETER; // Keyboard input reports are always 8 bytes long NTSTATUS status = STATUS_SUCCESS; ULONG OutputBufferSize = 8; // Allocate memory for URB USHORT UrbSize = sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER); PURB urb = (PURB)ExAllocatePool(NonPagedPool, UrbSize); if( urb==NULL) { DebugPrintMsg(\"No URB memory\"); return STATUS_INSUFFICIENT_RESOURCES; } UsbBuildInterruptOrBulkTransferRequest( urb, UrbSize, dx->UsbPipeHandle, UserBuffer, NULL, OutputBufferSize, USBD_TRANSFER_DIRECTION_IN, NULL); // Call the USB driver status = CallUSBDI( dx, urb); // Check statuses if( !NT_SUCCESS(status) || !USBD_SUCCESS( urb->UrbHeader.Status)) { DebugPrint(\"status %x URB status %x\", status, urb->UrbHeader.Status); status = STATUS_UNSUCCESSFUL; goto Read_Ednd; } // Give up if count of bytes transferred was not 8 if( urb->UrbBulkOrInterruptTransfer.TransferBufferLength!=OutputBufferSize) { status = STATUS_UNSUCCESSFUL; goto Read_Ednd; } UserBufferSize = urb->UrbBulkOrInterruptTransfer.TransferBufferLength; // DebugPrint(\"Transfer length %d\", urb->UrbBulkOrInterruptTransfer.TransferBufferLength); Read_Ednd: if( NT_SUCCESS(status)) { PUCHAR bd = (PUCHAR)UserBuffer; DebugPrint(\"Transfer data %2x %2x %2x %2x %2x %2x %2x %2x\", bd[0], bd[1], bd[2], bd[3], bd[4], bd[5], bd[6], bd[7]); } ExFreePool(urb); return status; } |
|