jfory
驱动小牛
驱动小牛
  • 注册日期2002-05-14
  • 最后登录2003-06-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:930回复:0

一个问题!

楼主#
更多 发布于:2002-11-18 17:47
我做的是一个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;
}

游客

返回顶部