openni2 usb驱动中的一个问题

openni2 源码中的通过deviceIoControl将命令发到驱动程序,按照常理,IpOutBuffer是从驱动中读取返回的数据,但是openni2 将这个参数 往设备发送数据。跟踪到驱动的代码。

 case IOCTL_PSDRV_CONTROL_TRANSFER:
   PSDrv_DbgPrint(3, ("IOControl: ControlTransfer\n"));

   //Get a pointer to the input buffer
   status = WdfRequestRetrieveInputMemory(Request, &WdfMem);
   if(!NT_SUCCESS(status))
   {
    PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
    status = STATUS_INVALID_PARAMETER;
    break;
   }

   if (WdfMem == NULL)
   {
    PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
    status = STATUS_INVALID_PARAMETER;
    break;
   }

   pControlTransfer = WdfMemoryGetBuffer(WdfMem, NULL);
   if (pControlTransfer == NULL)
   {
    PSDrv_DbgPrint(1, ("pControlTransfer is NULL!\n"));
    status = STATUS_INVALID_PARAMETER;
    break;
   }

   //Get a pointer to the output buffer
   if (OutputBufferLength != 0)
   {
    status = WdfRequestRetrieveOutputMemory(Request, &WdfMemOut);
    if(!NT_SUCCESS(status))
    {
     PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputMemory failed! (Status = %x)\n", status));
     status = STATUS_INVALID_PARAMETER;
     break;
    }

    if (WdfMemOut == NULL)
    {
     PSDrv_DbgPrint(1, ("WdfMemOut is NULL!\n"));
     status = STATUS_INVALID_PARAMETER;
     break;
    }

    pControlBuffer = WdfMemoryGetBuffer(WdfMemOut, NULL);
    if (pControlBuffer == NULL)
    {
     PSDrv_DbgPrint(1, ("pControlBuffer is NULL!\n"));
     status = STATUS_INVALID_PARAMETER;
     break;
    }
   }
   else
   {
    PSDrv_DbgPrint(1, ("This control request has no buffer...\n"));
    pControlBuffer = NULL;
   }

   // Call the control transfer function
   status = ControlTransfer(pDevContext, pControlTransfer, pControlBuffer, OutputBufferLength, &length);

   break;


NTSTATUS ControlTransfer(IN PDEVICE_CONTEXT pDeviceContext, IN PSUSBDRV_CONTROL_TRANSFER* pControlTransfer, IN OUT PUCHAR pControlBuffer, IN size_t nControlBufferSize, OUT ULONG* pLength)
{
 NTSTATUS      status = STATUS_SUCCESS;
 unsigned int     nTimeout = PSUSBDRV_DEFAULT_CONTROL_TIMEOUT;
 WDF_REQUEST_SEND_OPTIONS  sendOptions;
 WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket;
 WDF_MEMORY_DESCRIPTOR   memDesc;

 PAGED_CODE();

 RtlZeroMemory(&controlSetupPacket, sizeof(WDF_USB_CONTROL_SETUP_PACKET));

 controlSetupPacket.Packet.bm.Request.Dir = pControlTransfer->cDirection;
 controlSetupPacket.Packet.bm.Request.Type = pControlTransfer->cRequestType;
 controlSetupPacket.Packet.bm.Request.Recipient = BmRequestToDevice;
 controlSetupPacket.Packet.bRequest = pControlTransfer->cRequest;
 controlSetupPacket.Packet.wValue.Value = pControlTransfer->nValue;
 controlSetupPacket.Packet.wIndex.Value = pControlTransfer->nIndex;

 PSDrv_DbgPrint(3, ("ControlTransfer: Dir:%d Type:%d Request:%d Value:%d Index:%d.\n", pControlTransfer->cDirection, pControlTransfer->cRequestType,  pControlTransfer->cRequest, pControlTransfer->nValue, pControlTransfer->nIndex));

 if (pControlTransfer->nTimeout != 0)
 {
  if (pControlTransfer->nTimeout > PSUSBDRV_DEFAULT_CONTROL_TIMEOUT)
  {
   PSDrv_DbgPrint(3, ("ControlTransfer: Timeout was truncated from %d to %d!\n", pControlTransfer->nTimeout, PSUSBDRV_DEFAULT_CONTROL_TIMEOUT));

   nTimeout = PSUSBDRV_DEFAULT_CONTROL_TIMEOUT;
  }
  else
  {
   nTimeout = pControlTransfer->nTimeout;
  }
 }

 WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT);
 WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(nTimeout)); 

 PSDrv_DbgPrint(3, ("ControlTransfer: Timeout is set to: %d.\n", nTimeout));

 PSDrv_DbgPrint(3, ("ControlTransfer: Performing the control transfer...\n"));

 if (pControlBuffer != NULL)
 {
  PSDrv_DbgPrint(3, ("ControlTransfer: Buffer:%x Length:%d\n", pControlBuffer, nControlBufferSize));

  if (nControlBufferSize == 0)
  {
   PSDrv_DbgPrint(3, ("ControlTransfer: pControlBuffer is not NULL but nControlBufferSize is 0!\n"));

   return (STATUS_INVALID_PARAMETER);
  }

  WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pControlBuffer, (ULONG)nControlBufferSize);

  status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDeviceContext->WdfUsbTargetDevice, WDF_NO_HANDLE, &sendOptions, &controlSetupPacket, &memDesc, pLength);
 }
 else
 {
  status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDeviceContext->WdfUsbTargetDevice, WDF_NO_HANDLE, &sendOptions, &controlSetupPacket, NULL, pLength);
 }

 PSDrv_DbgPrint(3, ("ControlTransfer: Finished! Status=%x BytesTransferred=%d\n", status, *pLength));

 return status;
}

其中 WdfUsbTargetDeviceSendControlTransferSynchronously的MemoryDescriptor参数可以是输入的buffer,也可以是输出的buffer,通过这个参数可以将主机Host的数据设置到设备。:
NTSTATUS WdfUsbTargetDeviceSendControlTransferSynchronously(
  [in]             WDFUSBDEVICE UsbDevice,
  [in, optional]   WDFREQUEST Request,
  [in, optional]   PWDF_REQUEST_SEND_OPTIONS RequestOptions,
  [in]             PWDF_USB_CONTROL_SETUP_PACKET SetupPacket,
  [in, optional]   PWDF_MEMORY_DESCRIPTOR MemoryDescriptor,
  [out, optional]  PULONG BytesTransferred
);

参数

UsbDevice [in]

A handle to a USB device object that was obtained from a previous call to WdfUsbTargetDeviceCreate.

Request [in, optional]

A handle to a framework request object. This parameter is optional and can be NULL. For more information, see the following Remarks section.

RequestOptions [in, optional]

A pointer to a caller-allocated WDF_REQUEST_SEND_OPTIONS structure that specifies options for the request. This pointer is optional and can be NULL. For more information, see the following Remarks section.

SetupPacket [in]

A pointer to a caller-allocated WDF_USB_CONTROL_SETUP_PACKET structure that describes the control transfer.

MemoryDescriptor [in, optional]

A pointer to a caller-allocated WDF_MEMORY_DESCRIPTOR structure that describes either an input or an output buffer, depending on the device-specific command. This pointer is optional and can be NULL. For more information, see the following Remarks section.

BytesTransferred [out, optional]

A pointer to a location that receives the number of bytes that are transferred. This parameter is optional and can be NULL.


附:

BOOL WINAPI DeviceIoControl(
  _In_        HANDLE       hDevice,
  _In_        DWORD        dwIoControlCode,
  _In_opt_    LPVOID       lpInBuffer,
  _In_        DWORD        nInBufferSize,
  _Out_opt_   LPVOID       lpOutBuffer,
  _In_        DWORD        nOutBufferSize,
  _Out_opt_   LPDWORD      lpBytesReturned,
  _Inout_opt_ LPOVERLAPPED lpOverlapped
);

Parameters

hDevice [in]

A handle to the device on which the operation is to be performed. The device is typically a volume, directory, file, or stream. To retrieve a device handle, use theCreateFile function. For more information, see Remarks.

dwIoControlCode [in]

The control code for the operation. This value identifies the specific operation to be performed and the type of device on which to perform it.

For a list of the control codes, see Remarks. The documentation for each control code provides usage details for thelpInBuffer, nInBufferSize, lpOutBuffer, and nOutBufferSize parameters.

lpInBuffer [in, optional]

A pointer to the input buffer that contains the data required to perform the operation. The format of this data depends on the value of thedwIoControlCode parameter.

This parameter can be NULL if dwIoControlCode specifies an operation that does not require input data.

nInBufferSize [in]

The size of the input buffer, in bytes.

lpOutBuffer [out, optional]

A pointer to the output buffer that is to receive the data returned by the operation. The format of this data depends on the value of thedwIoControlCode parameter.

This parameter can be NULL if dwIoControlCode specifies an operation that does not return data.

nOutBufferSize [in]

The size of the output buffer, in bytes.

lpBytesReturned [out, optional]

A pointer to a variable that receives the size of the data stored in the output buffer, in bytes.

If the output buffer is too small to receive any data, the call fails, GetLastError returns ERROR_INSUFFICIENT_BUFFER, andlpBytesReturned is zero.

If the output buffer is too small to hold all of the data but can hold some entries, some drivers will return as much data as fits. In this case, the call fails,GetLastError returnsERROR_MORE_DATA, and lpBytesReturned indicates the amount of data received. Your application should callDeviceIoControl again with the same operation, specifying a new starting point.

If lpOverlapped is NULL, lpBytesReturned cannot beNULL. Even when an operation returns no output data and lpOutBuffer isNULL, DeviceIoControl makes use of lpBytesReturned. After such an operation, the value oflpBytesReturned is meaningless.

If lpOverlapped is not NULL, lpBytesReturned can beNULL. If this parameter is not NULL and the operation returns data,lpBytesReturned is meaningless until the overlapped operation has completed. To retrieve the number of bytes returned, callGetOverlappedResult. IfhDevice is associated with an I/O completion port, you can retrieve the number of bytes returned by callingGetQueuedCompletionStatus.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值