openni2 源码中的通过deviceIoControl将命令发到驱动程序,按照常理,IpOutBuffer是从驱动中读取返回的数据,但是openni2 将这个参数 往设备发送数据。跟踪到驱动的代码。
PSDrv_DbgPrint(3, ("IOControl: ControlTransfer\n"));
status = WdfRequestRetrieveInputMemory(Request, &WdfMem);
if(!NT_SUCCESS(status))
{
PSDrv_DbgPrint(1, ("WdfRequestRetrieveInputMemory failed! (Status = %x)\n", status));
status = STATUS_INVALID_PARAMETER;
break;
}
{
PSDrv_DbgPrint(1, ("WdfMem is NULL!\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
if (pControlTransfer == NULL)
{
PSDrv_DbgPrint(1, ("pControlTransfer is NULL!\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
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;
}
{
PSDrv_DbgPrint(1, ("WdfMemOut is NULL!\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
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;
}
status = ControlTransfer(pDevContext, pControlTransfer, pControlBuffer, OutputBufferLength, &length);
{
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;
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;
{
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));
}
else
{
nTimeout = pControlTransfer->nTimeout;
}
}
WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(nTimeout));
{
PSDrv_DbgPrint(3, ("ControlTransfer: Buffer:%x Length:%d\n", pControlBuffer, nControlBufferSize));
{
PSDrv_DbgPrint(3, ("ControlTransfer: pControlBuffer is not NULL but nControlBufferSize is 0!\n"));
}
}
else
{
status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDeviceContext->WdfUsbTargetDevice, WDF_NO_HANDLE, &sendOptions, &controlSetupPacket, NULL, pLength);
}
}
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.