HRESULT CUSBSimEndpoint::GetDescriptor (BYTE Type, BYTE Index, PVOID pBuffer, USHORT BufferSize, PUSHORT pLength) { return ControlTransfer (0x80, GET_DESCRIPTOR, (Type << 8) | Index, 0, BufferSize, pBuffer, pLength); }
/*++ Routine Description: This event is called when the framework receives IRP_MJ_DEVICE_CONTROL requests from the system. Arguments: Queue - Handle to the framework queue object that is associated with the I/O request. Request - Handle to a framework request object. OutputBufferLength - length of the request's output buffer, if an output buffer is available. InputBufferLength - length of the request's input buffer, if an input buffer is available. IoControlCode - the driver-defined or system-defined I/O control code (IOCTL) that is associated with the request. Return Value: VOID --*/ VOID PSDrv_EvtIoDeviceControl(IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode) { WDFDEVICE device; PVOID ioBuffer; size_t bufLength; NTSTATUS status; PDEVICE_CONTEXT pDevContext; PFILE_CONTEXT pFileContext; ULONG length = 0; PSUSBDRV_PIPE_PROPERTY* pPipeProp; PSUSBDRV_CONTROL_TRANSFER* pControlTransfer; PSUSBDRV_DRIVER_VERSION* pDriverVersion; PSUSBDRV_INTERFACE_PROPERTY* pInterfaceProperty; unsigned int* pnDeviceSpeed; WDFMEMORY WdfMem = NULL; PUCHAR pControlBuffer; WDFMEMORY WdfMemOut = NULL; WDF_USB_INTERFACE_SELECT_SETTING_PARAMS selectSettingParams; UNREFERENCED_PARAMETER(InputBufferLength); PSDrv_DbgPrint(3, ("PSDrv_EvtIoDeviceControl - begins\n")); PAGED_CODE(); // initialize variables device = WdfIoQueueGetDevice(Queue); pDevContext = GetDeviceContext(device); switch(IoControlCode) { case IOCTL_PSDRV_RESET_PIPE: PSDrv_DbgPrint(3, ("IOControl: ResetPipe\n")); pFileContext = GetFileContext(WdfRequestGetFileObject(Request)); if (pFileContext->Pipe == NULL) { PSDrv_DbgPrint(3, ("Invalid pipe!\n")); status = STATUS_INVALID_PARAMETER; } else { status = ResetPipe(pFileContext->Pipe); } break; case IOCTL_PSDRV_ABORT_PIPE: PSDrv_DbgPrint(3, ("IOControl: AbortPipe\n")); pFileContext = GetFileContext(WdfRequestGetFileObject(Request)); if (pFileContext->Pipe == NULL) { PSDrv_DbgPrint(3, ("Invalid pipe!\n")); status = STATUS_INVALID_PARAMETER; } else { status = AbortPipe(pFileContext->Pipe); } break; case IOCTL_PSDRV_GET_CONFIG_DESCRIPTOR: PSDrv_DbgPrint(3, ("IOControl: GetConfigDescriptor\n")); if (pDevContext->UsbConfigurationDescriptor) { length = pDevContext->UsbConfigurationDescriptor->wTotalLength; status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength); if(!NT_SUCCESS(status)) { PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status)); status = STATUS_INVALID_PARAMETER; break; } RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length); status = STATUS_SUCCESS; } else { PSDrv_DbgPrint(3, ("UsbConfigurationDescriptor is NULL!\n")); status = STATUS_INVALID_DEVICE_STATE; } break; case IOCTL_PSDRV_RESET_DEVICE: PSDrv_DbgPrint(3, ("IOControl: ResetDevice\n")); status = ResetDevice(device); break; 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; case IOCTL_PSDRV_SET_PIPE_PROPERTY: PSDrv_DbgPrint(3, ("IOControl: SetPipeProperty\n")); 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; } pPipeProp = WdfMemoryGetBuffer(WdfMem, NULL); if (pPipeProp == NULL) { PSDrv_DbgPrint(1, ("pPipeProp is NULL!\n")); status = STATUS_INVALID_PARAMETER; break; } pFileContext = GetFileContext(WdfRequestGetFileObject(Request)); if (pFileContext->Pipe == NULL) { PSDrv_DbgPrint(3, ("Invalid pipe!\n")); status = STATUS_INVALID_PARAMETER; } else { status = SetPipeProperty(pFileContext, pPipeProp); } break; case IOCTL_PSDRV_SET_INTERFACE: PSDrv_DbgPrint(3, ("IOControl: SetInterface\n")); 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; } pInterfaceProperty = WdfMemoryGetBuffer(WdfMem, NULL); if (pInterfaceProperty == NULL) { PSDrv_DbgPrint(1, ("pInterfaceProperty is NULL!\n")); status = STATUS_INVALID_PARAMETER; break; } PSDrv_DbgPrint(3, ("SetInterface: Going to change AltIF to %d...\n", pInterfaceProperty->nAltIF)); WDF_USB_INTERFACE_SELECT_SETTING_PARAMS_INIT_SETTING(&selectSettingParams, pInterfaceProperty->nAltIF); status = WdfUsbInterfaceSelectSetting(pDevContext->UsbInterface, WDF_NO_OBJECT_ATTRIBUTES, &selectSettingParams); if (status == STATUS_SUCCESS) { pDevContext->nCurrIf = 0; pDevContext->nCurrAltIf = pInterfaceProperty->nAltIF; PSDrv_DbgPrint(3, ("SetInterface: AltIF is now %d...\n", pInterfaceProperty->nAltIF)); } break; case IOCTL_PSDRV_GET_INTERFACE: PSDrv_DbgPrint(3, ("IOControl: GetInterface\n")); length = sizeof(PSUSBDRV_INTERFACE_PROPERTY); status = WdfRequestRetrieveOutputBuffer(Request, length, &pInterfaceProperty, &bufLength); if(!NT_SUCCESS(status)) { PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status)); status = STATUS_INVALID_PARAMETER; break; } pInterfaceProperty->nIF = pDevContext->nCurrIf; pInterfaceProperty->nAltIF = pDevContext->nCurrAltIf; status = STATUS_SUCCESS; break; case IOCTL_PSDRV_GET_DRIVER_VERSION: PSDrv_DbgPrint(3, ("IOControl: GetDriverVersion\n")); length = sizeof(PSUSBDRV_DRIVER_VERSION); status = WdfRequestRetrieveOutputBuffer(Request, length, &pDriverVersion, &bufLength); if(!NT_SUCCESS(status)) { PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status)); status = STATUS_INVALID_PARAMETER; break; } pDriverVersion->nMajor = PSUSBDRV_MAJOR_VERSION; pDriverVersion->nMinor = PSUSBDRV_MINOR_VERSION; pDriverVersion->nMaintenance = PSUSBDRV_MAINTENANCE_VERSION; pDriverVersion->nBuild = PSUSBDRV_BUILD_VERSION; status = STATUS_SUCCESS; break; case IOCTL_PSDRV_GET_DEVICE_SPEED: PSDrv_DbgPrint(3, ("IOControl: GetDeviceSpeed\n")); length = sizeof(unsigned int); status = WdfRequestRetrieveOutputBuffer(Request, length, &pnDeviceSpeed, &bufLength); if(!NT_SUCCESS(status)) { PSDrv_DbgPrint(1, ("WdfRequestRetrieveOutputBuffer failed! (Status = %x)\n", status)); status = STATUS_INVALID_PARAMETER; break; } if (pDevContext->IsDeviceHighSpeed == TRUE) { *pnDeviceSpeed = PSUSBDRV_DEVICE_HIGH_SPEED; } else { *pnDeviceSpeed = PSUSBDRV_DEVICE_FULL_SPEED; } break; default: PSDrv_DbgPrint(3, ("Unknown IOControl! (ControlCode = %x)\n", IoControlCode)); status = STATUS_INVALID_DEVICE_REQUEST; break; } WdfRequestCompleteWithInformation(Request, status, length); PSDrv_DbgPrint(3, ("PSDrv_EvtIoDeviceControl - ends\n")); return; }