NTSTATUS GetVendorAndProductID( _In_ WDFIOTARGET IoTarget, _Out_ USHORT * VendorID, _Out_ USHORT * ProductID ) { NTSTATUS Status = STATUS_SUCCESS; WDF_MEMORY_DESCRIPTOR EnumInfoMemDescriptor; BTH_ENUMERATOR_INFO EnumInfo; RtlZeroMemory(&EnumInfo, sizeof(EnumInfo)); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&EnumInfoMemDescriptor, &EnumInfo, sizeof(EnumInfo)); Status = WdfIoTargetSendInternalIoctlSynchronously( IoTarget, NULL, IOCTL_INTERNAL_BTHENUM_GET_ENUMINFO, NULL, &EnumInfoMemDescriptor, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } (*ProductID) = EnumInfo.Pid; (*VendorID) = EnumInfo.Vid; return Status; }
NTSTATUS kmdf1394_SubmitIrpSynch ( IN WDFIOTARGET IoTarget, IN WDFREQUEST Request, IN PIRB Irb) /*++ Routine Description: Synchronous Irp submission routine Arguments: IoTarget - pointer to the IoTarget object. Request - the WDF Request packet to use Irb - 1394 I/O Request Block to submit Return Value: NTSTATUS value --*/ { NTSTATUS ntStatus = STATUS_SUCCESS; WDF_REQUEST_SEND_OPTIONS option; WDF_MEMORY_DESCRIPTOR descriptor; UNREFERENCED_PARAMETER (Request); ENTER ("kmdf1394_SubmitIrpSynch"); ASSERT (KeGetCurrentIrql() < DISPATCH_LEVEL); ASSERT (Irb); WDF_REQUEST_SEND_OPTIONS_INIT (&option, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER (&descriptor, Irb, sizeof (IRB)); ntStatus = WdfIoTargetSendInternalIoctlOthersSynchronously ( IoTarget, NULL, IOCTL_1394_CLASS, &descriptor, NULL, NULL, &option, NULL); if (!NT_SUCCESS(ntStatus)) { TRACE(TL_ERROR, ("WdfIoTargetSendInternalIoctlSynchronously " "Failed with status %x\n",ntStatus)); } EXIT ("kmdf1394_SubmitIrpSynch", ntStatus); return ntStatus; } //kmdf1394_SubmitIrpSynch
NTSTATUS BthEchoSharedGetHostSupportedFeatures( _In_ PBTHECHOSAMPLE_DEVICE_CONTEXT_HEADER DevCtxHdr ) /*++ Routine Description: This routine synchronously checks the local stack's supported features Arguments: DevCtxHdr - Information about the local device Return Value: NTSTATUS Status code. --*/ { WDF_MEMORY_DESCRIPTOR outMemDesc = {0}; BTH_HOST_FEATURE_MASK localFeatures = {0}; NTSTATUS status = STATUS_SUCCESS; DevCtxHdr->LocalFeatures.Mask = 0; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &outMemDesc, &localFeatures, sizeof(localFeatures) ); status = WdfIoTargetSendIoctlSynchronously( DevCtxHdr->IoTarget, NULL, IOCTL_BTH_GET_HOST_SUPPORTED_FEATURES, NULL, &outMemDesc, NULL, NULL ); if (!NT_SUCCESS(status)) { return status; } DevCtxHdr->LocalFeatures = localFeatures; return status; }
NTSTATUS PrepareBluetooth( _In_ PDEVICE_CONTEXT DeviceContext ) { NTSTATUS Status = STATUS_SUCCESS; PBLUETOOTH_DEVICE_CONTEXT BluetoothContext = &(DeviceContext->BluetoothContext); WDF_MEMORY_DESCRIPTOR DeviceInfoMemDescriptor; BTH_DEVICE_INFO DeviceInfo; BluetoothContext->ControlChannelHandle = NULL; BluetoothContext->InterruptChannelHandle = NULL; //Get Interfaces Status = WdfFdoQueryForInterface( DeviceContext->Device, &GUID_BTHDDI_PROFILE_DRIVER_INTERFACE, (PINTERFACE)(&(BluetoothContext->ProfileDriverInterface)), sizeof(BluetoothContext->ProfileDriverInterface), BTHDDI_PROFILE_DRIVER_INTERFACE_VERSION_FOR_QI, NULL); if (!NT_SUCCESS(Status)) { return Status; } //Get BluetoothAdress RtlZeroMemory(&DeviceInfo, sizeof(DeviceInfo)); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&DeviceInfoMemDescriptor, &DeviceInfo, sizeof(DeviceInfo)); Status = WdfIoTargetSendInternalIoctlSynchronously( DeviceContext->IoTarget, NULL, IOCTL_INTERNAL_BTHENUM_GET_DEVINFO, NULL, &DeviceInfoMemDescriptor, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } BluetoothContext->DeviceAddress = DeviceInfo.address; return Status; }
// This function gets the switch state of the USB device directly from the hardware // NTSTATUS HidFx2GetSwitchState(_In_ WDFDEVICE hDevice, _Out_ unsigned char *pbSwitchState) { PDEVICE_EXTENSION pDevContext = NULL; NTSTATUS status = STATUS_SUCCESS; WDF_MEMORY_DESCRIPTOR memDesc; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; ULONG cBytesTransferred = 0; if(pbSwitchState != NULL) { *pbSwitchState = 0; } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Entry\n"); pDevContext = GetDeviceContext(hDevice); // set the segment state on the USB device WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, HIDFX2_READ_SWITCH_STATE, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pbSwitchState, sizeof(*pbSwitchState)); status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDevContext->hUsbDevice, NULL, // Optional WDFREQUEST NULL, // PWDF_REQUEST_SEND_OPTIONS &controlSetupPacket, &memDesc, &cBytesTransferred); if (!NT_SUCCESS(status)) { TraceErr(DBG_IOCTL, "(%!FUNC!) Failed to read switch state - %!STATUS! \n", status); } else { TraceVerbose(DBG_IOCTL, "(%!FUNC!) Switch state is 0x%x\n", *pbSwitchState); *pbSwitchState = ~(*pbSwitchState); // switchs are inverted on hardware boards TraceVerbose(DBG_IOCTL, "(%!FUNC!) Switch state is 0x%x\n", *pbSwitchState); } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit, status: %!STATUS!\n", status); return status; }
//This routine sets the state of the Feature: in this case Segment Display on the USB FX2 board. NTSTATUS SendVendorCommand(_In_ WDFDEVICE hDevice, _In_ unsigned char bVendorCommand, _In_ unsigned char bCommandData) { NTSTATUS status = STATUS_SUCCESS; ULONG cBytesTransferred = 0; PDEVICE_EXTENSION pDevContext = NULL; WDF_MEMORY_DESCRIPTOR memDesc; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; PAGED_CODE(); TraceVerbose(DBG_IOCTL, "(%!FUNC!) Enter\n"); pDevContext = GetDeviceContext(hDevice); TraceInfo(DBG_IOCTL, "(%!FUNC!): Command:0x%x, data: 0x%x\n", bVendorCommand, bCommandData); // Send the I/O with a timeout. // We do that because we send the I/O in the context of the user thread and if it gets stuck, it would prevent the user process from existing. WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_SEC(5)); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, bVendorCommand, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, &bCommandData, sizeof(bCommandData)); status = WdfUsbTargetDeviceSendControlTransferSynchronously(pDevContext->hUsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST &sendOptions, // PWDF_REQUEST_SEND_OPTIONS &controlSetupPacket, &memDesc, &cBytesTransferred); if (!NT_SUCCESS(status)) { TraceErr(DBG_IOCTL, "(%!FUNC!): Failed to set Segment Display state - %!STATUS!\n", status); } TraceVerbose(DBG_IOCTL, "(%!FUNC!) Exit\n"); return status; }
NTSTATUS HidFx2GetSwitchState( IN WDFDEVICE Device, OUT PUCHAR SwitchState ) /*++ Routine Description: This function gets the swicth state of teh USB device Arguments: Device - Handle to a framework device object. SwitchState - Pointer to a variable that receives the switch state Return Value: Success implies that the device can be used. Failure will result in the device stack being torn down. --*/ { PDEVICE_EXTENSION devContext = NULL; NTSTATUS status = STATUS_SUCCESS; WDF_MEMORY_DESCRIPTOR memDesc; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; ULONG bytesTransferred = 0; devContext = GetDeviceContext(Device); // // set the segment state on the USB device // WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, HIDFX2_READ_SWITCH_STATE, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, SwitchState, sizeof(UCHAR)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( devContext->UsbDevice, NULL, // Optional WDFREQUEST NULL, // PWDF_REQUEST_SEND_OPTIONS &controlSetupPacket, &memDesc, &bytesTransferred ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "GetSwitchState: Failed to read switch state - 0x%x \n", status); } else { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSwitchState: Switch state is 0x%x\n", *SwitchState); } return status; }
NTSTATUS GetSwitchState( _In_ PDEVICE_CONTEXT DevContext, _In_ PSWITCH_STATE SwitchState ) /*++ Routine Description This routine gets the state of the switches on the board Arguments: DevContext - One of our device extensions Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> GetSwitchState\n"); PAGED_CODE(); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, DEFAULT_CONTROL_TRANSFER_TIMEOUT ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, USBFX2LK_READ_SWITCHES, // Request 0, // Value 0); // Index SwitchState->SwitchesAsUChar = 0; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, SwitchState, sizeof(SWITCH_STATE)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( DevContext->UsbDevice, NULL, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "GetSwitchState: Failed to Get switches - 0x%x \n", status); } else { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSwitchState: Switch mask is 0x%x\n", SwitchState->SwitchesAsUChar); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- GetSwitchState\n"); return status; }
NTSTATUS Acpi_EvaluatePld ( _In_ PACPI_CONTEXT AcpiCtx, _In_ LPCSTR DeviceName, _Out_ PACPI_PLD_BUFFER PldBuffer ) { NTSTATUS status; WDFDEVICE device; WDF_MEMORY_DESCRIPTOR inputMemDesc; ACPI_EVAL_INPUT_BUFFER_EX inputBuffer; size_t inputBufferSize; WDFMEMORY outputMemory; WDF_MEMORY_DESCRIPTOR outputMemDesc; PACPI_EVAL_OUTPUT_BUFFER outputBuffer; size_t outputBufferSize; size_t outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); outputMemory = WDF_NO_HANDLE; inputBufferSize = sizeof(inputBuffer); RtlZeroMemory(&inputBuffer, inputBufferSize); inputBuffer.Signature = ACPI_EVAL_INPUT_BUFFER_SIGNATURE_EX; status = RtlStringCchPrintfA(inputBuffer.MethodName, sizeof(inputBuffer.MethodName), "%s._PLD", DeviceName); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] RtlStringCchPrintfA for creating method name failed - %!STATUS!", device, status); goto Exit; } outputArgumentBufferSize = 1024; outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, outputBufferSize, &outputMemory, (PVOID*) &outputBuffer); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, outputBufferSize, status); goto Exit; } RtlZeroMemory(outputBuffer, outputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputMemDesc, &inputBuffer, (ULONG) inputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&outputMemDesc, outputMemory, NULL); status = WdfIoTargetSendInternalIoctlSynchronously( WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_EVAL_METHOD_EX, &inputMemDesc, &outputMemDesc, NULL, NULL); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD_EX for %s failed - %!STATUS!", device, inputBuffer.MethodName, status); goto Exit; } if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device); goto Exit; } if (outputBuffer->Count < 1) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _PLD for %s didn't return anything", device, inputBuffer.MethodName); goto Exit; } if (outputBuffer->Argument[0].Type != ACPI_METHOD_ARGUMENT_BUFFER) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] _PLD for %s returned an unexpected argument of type %d", device, inputBuffer.MethodName, outputBuffer->Argument[0].Type); goto Exit; } if (outputBuffer->Argument[0].DataLength < sizeof(*PldBuffer)) { status = STATUS_ACPI_INVALID_DATA; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] Unexpected _PLD buffer size for %s. Expected %Iu bytes, got %Iu bytes", device, inputBuffer.MethodName, sizeof(*PldBuffer), outputBuffer->Argument[0].DataLength); goto Exit; } *PldBuffer = *((PACPI_PLD_BUFFER) outputBuffer->Argument[0].Data); Exit: if (outputMemory != WDF_NO_HANDLE) { WdfObjectDelete(outputMemory); } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
NTSTATUS GetDevInfoLength( __in PFILTER_EXTENSION filterExt, __out BYTE* pDevInfoLen ) /*++ Routine Description This routine gets the length of device info, so caller app can prepare proper buffer to retrieve the actual content info Arguments: pDevInfoLen - One of our device extensions Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; PAGED_CODE(); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, WDF_REL_TIMEOUT_IN_SEC(5) ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, USBFX2LK_READ_DEVINFO_LEN, // Request 0, // Value 0); // Index // // Set the buffer to 0, the board will OR in everything that is set // *pDevInfoLen = 0; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pDevInfoLen, sizeof(BYTE)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( filterExt->UsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { KdPrint( ("GetDevInfoLength: Failed - 0x%x \n", status)); } else { KdPrint( ("GetDevInfoLength: %d \n", *pDevInfoLen )); } return status; }
NTSTATUS BthEchoCliRetrieveServerSdpRecord( __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx, __out PBTH_SDP_STREAM_RESPONSE * ServerSdpRecord ) /*++ Description: Retrive server SDP record. We call this function on every file open to get the PSM Arguments: DevCtx - Client context ServerSdpRecord - SDP record retrieved Return Value: NTSTATUS Status code. --*/ { NTSTATUS status, statusReuse, disconnectStatus; WDF_MEMORY_DESCRIPTOR inMemDesc; WDF_MEMORY_DESCRIPTOR outMemDesc; WDF_REQUEST_REUSE_PARAMS ReuseParams; BTH_SDP_CONNECT connect = {0}; BTH_SDP_DISCONNECT disconnect = {0}; BTH_SDP_SERVICE_ATTRIBUTE_SEARCH_REQUEST requestSdp = {0}; BTH_SDP_STREAM_RESPONSE responseSdp = {0}; ULONG requestSize; PBTH_SDP_STREAM_RESPONSE serverSdpRecord = NULL; WDFREQUEST request; WDF_OBJECT_ATTRIBUTES attributes; PAGED_CODE(); // // Allocate the request we will use for obtaining sdp record // NOTE that we do it for every file open, hence we // // can't use reserve request from the context // WDF_OBJECT_ATTRIBUTES_INIT(&attributes); status = WdfRequestCreate( &attributes, DevCtx->Header.IoTarget, &request ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "Failed to allocate request for retriving server sdp record, Status code %!STATUS!\n", status); goto exit; } connect.bthAddress = DevCtx->ServerBthAddress; connect.requestTimeout = SDP_REQUEST_TO_DEFAULT; connect.fSdpConnect = 0; // // Connect to the SDP service. // WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &inMemDesc, &connect, sizeof(connect) ); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &outMemDesc, &connect, sizeof(connect) ); status = WdfIoTargetSendIoctlSynchronously( DevCtx->Header.IoTarget, request, IOCTL_BTH_SDP_CONNECT, &inMemDesc, &outMemDesc, NULL, //sendOptions NULL //bytesReturned ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "IOCTL_BTH_SDP_CONNECT failed, Status code %!STATUS!\n", status); goto exit1; } // // Obtain the required size of the SDP record // requestSdp.hConnection = connect.hConnection; requestSdp.uuids[0].u.uuid128 = BTHECHOSAMPLE_SVC_GUID; requestSdp.uuids[0].uuidType = SDP_ST_UUID128; requestSdp.range[0].minAttribute = 0; requestSdp.range[0].maxAttribute = 0xFFFF; WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED); statusReuse = WdfRequestReuse(request, &ReuseParams); ASSERT(NT_SUCCESS(statusReuse)); UNREFERENCED_PARAMETER(statusReuse); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &inMemDesc, &requestSdp, sizeof(requestSdp) ); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &outMemDesc, &responseSdp, sizeof(responseSdp) ); status = WdfIoTargetSendIoctlSynchronously( DevCtx->Header.IoTarget, request, IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH, &inMemDesc, &outMemDesc, NULL, //sendOptions NULL //bytesReturned ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed while querying response size, " "status code %!STATUS!\n", status); goto exit2; } // // Allocate the required size for SDP record // status = RtlULongAdd( responseSdp.requiredSize, sizeof(BTH_SDP_STREAM_RESPONSE), &requestSize ); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "SDP record size too large, status code %!STATUS!\n", status); goto exit2; } serverSdpRecord = ExAllocatePoolWithTag(NonPagedPool, requestSize, POOLTAG_BTHECHOSAMPLE); if (NULL == serverSdpRecord) { status = STATUS_INSUFFICIENT_RESOURCES; TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "Allocating SDP record failed, returning status code %!STATUS!\n", status); goto exit2; } // // Send request with required size // WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED); statusReuse = WdfRequestReuse(request, &ReuseParams); ASSERT(NT_SUCCESS(statusReuse)); UNREFERENCED_PARAMETER(statusReuse); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &inMemDesc, &requestSdp, sizeof(requestSdp) ); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &outMemDesc, serverSdpRecord, requestSize ); status = WdfIoTargetSendIoctlSynchronously( DevCtx->Header.IoTarget, request, IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH, &inMemDesc, &outMemDesc, NULL, //sendOptions NULL //bytesReturned ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_SDP, "IOCTL_BTH_SDP_SERVICE_ATTRIBUTE_SEARCH failed, status code %!STATUS!\n", status); ExFreePoolWithTag(serverSdpRecord, POOLTAG_BTHECHOSAMPLE); } else { *ServerSdpRecord = serverSdpRecord; } exit2: // // Disconnect from SDP service. // WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED); statusReuse = WdfRequestReuse(request, &ReuseParams); ASSERT(NT_SUCCESS(statusReuse)); UNREFERENCED_PARAMETER(statusReuse); disconnect.hConnection = connect.hConnection; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &inMemDesc, &disconnect, sizeof(disconnect) ); disconnectStatus = WdfIoTargetSendIoctlSynchronously( DevCtx->Header.IoTarget, request, IOCTL_BTH_SDP_DISCONNECT, &inMemDesc, NULL, //outMemDesc NULL, //sendOptions NULL //bytesReturned ); ASSERT(NT_SUCCESS(disconnectStatus)); //Disconnect should not fail if (!NT_SUCCESS(disconnectStatus)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "IOCTL_BTH_SDP_DISCONNECT failed, Status code %!STATUS!\n", status); } exit1: WdfObjectDelete(request); exit: return status; }
VOID Rio500_EvtIoDeviceControl( _In_ WDFQUEUE Queue, _In_ WDFREQUEST Request, _In_ size_t OutputBufferLength, _In_ size_t InputBufferLength, _In_ ULONG IoControlCode ) /*++ 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 --*/ { WDFDEVICE device; PVOID ioBuffer; PRIO_IOCTL_BLOCK ioBufferRio; size_t bufLength; NTSTATUS status; PDEVICE_CONTEXT pDevContext; ULONG length = 0; URB urb; PMDL pMdl = NULL; WDF_MEMORY_DESCRIPTOR memoryDesc; #ifdef _WIN64 BOOLEAN isWowRequest = FALSE; #endif // _WIN64 UNREFERENCED_PARAMETER(OutputBufferLength); UNREFERENCED_PARAMETER(InputBufferLength); Rio500_DbgPrint(3, ("Entered Rio500_DispatchDevCtrl\n")); PAGED_CODE(); // // initialize variables // device = WdfIoQueueGetDevice(Queue); pDevContext = GetDeviceContext(device); switch(IoControlCode) { case IOCTL_RIO500_RESET_PIPE: status = ResetPipe(pDevContext->ReadPipe); if (NT_SUCCESS(status)) { status = ResetPipe(pDevContext->WritePipe); } break; case IOCTL_RIO500_GET_CONFIG_DESCRIPTOR: if (pDevContext->UsbConfigurationDescriptor) { length = pDevContext->UsbConfigurationDescriptor->wTotalLength; status = WdfRequestRetrieveOutputBuffer(Request, length, &ioBuffer, &bufLength); if (!NT_SUCCESS(status)) { Rio500_DbgPrint(1, ("WdfRequestRetrieveInputBuffer failed\n")); break; } RtlCopyMemory(ioBuffer, pDevContext->UsbConfigurationDescriptor, length); status = STATUS_SUCCESS; } else { status = STATUS_INVALID_DEVICE_STATE; } break; case IOCTL_RIO500_RESET_DEVICE: status = ResetDevice(device); break; case IOCTL_RIO500_RIO_COMMAND: #ifdef _WIN64 if (IoIs32bitProcess(NULL)) { bufLength = sizeof(RIO_IOCTL_BLOCK) - sizeof(DWORD32); isWowRequest = TRUE; } else #endif // _WIN64 { bufLength = sizeof(RIO_IOCTL_BLOCK); } status = WdfRequestRetrieveInputBuffer( Request, bufLength, &ioBufferRio, NULL ); if (NT_SUCCESS(status)) { #ifdef _WIN64 if (isWowRequest) { ioBuffer = (PVOID)ioBufferRio->MsgData.DataWow; } else #endif // _WIN64 { ioBuffer = ioBufferRio->MsgData.Data; } if (ioBufferRio->MsgLength != 0 && ioBuffer != NULL) { pMdl = IoAllocateMdl( ioBuffer, ioBufferRio->MsgLength, FALSE, FALSE, NULL ); MmProbeAndLockPages(pMdl, (KPROCESSOR_MODE)KernelMode, IoModifyAccess); } memset(&urb, 0, sizeof(urb)); urb.UrbControlVendorClassRequest.Hdr.Length = sizeof(struct _URB_CONTROL_VENDOR_OR_CLASS_REQUEST); urb.UrbControlVendorClassRequest.Hdr.Function = URB_FUNCTION_VENDOR_DEVICE; urb.UrbControlVendorClassRequest.TransferBuffer = NULL; urb.UrbControlVendorClassRequest.RequestTypeReservedBits = 0x00; urb.UrbControlVendorClassRequest.TransferBufferLength = ioBufferRio->MsgLength; urb.UrbControlVendorClassRequest.TransferBufferMDL = pMdl; urb.UrbControlVendorClassRequest.Request = ioBufferRio->RequestCode; urb.UrbControlVendorClassRequest.Value = ioBufferRio->MsgValue; urb.UrbControlVendorClassRequest.Index = ioBufferRio->MsgIndex; urb.UrbControlVendorClassRequest.TransferFlags = USBD_SHORT_TRANSFER_OK; if (ioBufferRio->RequestType & 0x80) { urb.UrbControlVendorClassRequest.TransferFlags |= USBD_TRANSFER_DIRECTION_IN; } urb.UrbControlVendorClassRequest.UrbLink = NULL; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memoryDesc, &urb, sizeof(urb)); status = WdfIoTargetSendInternalIoctlOthersSynchronously( WdfDeviceGetIoTarget(device), Request, IOCTL_INTERNAL_USB_SUBMIT_URB, &memoryDesc, NULL, NULL, NULL, NULL ); if (pMdl != NULL) { MmUnlockPages(pMdl); IoFreeMdl(pMdl); } } break; default: status = STATUS_INVALID_DEVICE_REQUEST; break; } WdfRequestCompleteWithInformation(Request, status, length); Rio500_DbgPrint(3, ("Exit Rio500_DispatchDevCtrl\n")); }
NTSTATUS FORCEINLINE BthEchoSharedSendBrbSynchronously( _In_ WDFIOTARGET IoTarget, _In_ WDFREQUEST Request, _In_ PBRB Brb, _In_ ULONG BrbSize ) /*++ Routine Description: This routine formats a request with brb and sends it synchronously Arguments: IoTarget - Target to send the brb to Request - request object to be formatted with brb Brb - Brb to be sent BrbSize - size of the Brb data structure Return Value: NTSTATUS Status code. Notes: This routine does calls WdfRequestReuse on the Request passed in. Caller need not do so before passing in the request. This routine does not complete the request in case of failure. Caller must complete the request in case of failure. --*/ { NTSTATUS status; WDF_REQUEST_REUSE_PARAMS reuseParams; WDF_MEMORY_DESCRIPTOR OtherArg1Desc; WDF_REQUEST_REUSE_PARAMS_INIT( &reuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED ); status = WdfRequestReuse(Request, &reuseParams); if (!NT_SUCCESS(status)) { goto exit; } WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &OtherArg1Desc, Brb, BrbSize ); status = WdfIoTargetSendInternalIoctlOthersSynchronously( IoTarget, Request, IOCTL_INTERNAL_BTH_SUBMIT_BRB, &OtherArg1Desc, NULL, //OtherArg2 NULL, //OtherArg4 NULL, //RequestOptions NULL //BytesReturned ); exit: return status; }
NTSTATUS FireflySetFeature( IN PDEVICE_CONTEXT DeviceContext, IN UCHAR PageId, IN USHORT FeatureId, IN BOOLEAN EnableFeature ) /*++ Routine Description: This routine sets the HID feature by sending HID ioctls to our device. These IOCTLs will be handled by HIDUSB and converted into USB requests and send to the device. Arguments: DeviceContext - Context for our device PageID - UsagePage of the light control feature. FeatureId - Usage ID of the feature. EnanbleFeature - True to turn the light on, Falst to turn if off. Return Value: NT Status code --*/ { WDF_MEMORY_DESCRIPTOR inputDescriptor, outputDescriptor; NTSTATUS status; HID_COLLECTION_INFORMATION collectionInformation = {0}; PHIDP_PREPARSED_DATA preparsedData; HIDP_CAPS caps; USAGE usage; ULONG usageLength; PCHAR report; WDFIOTARGET hidTarget; WDF_IO_TARGET_OPEN_PARAMS openParams; PAGED_CODE(); // // Preinit for error. // preparsedData = NULL; report = NULL; hidTarget = NULL; status = WdfIoTargetCreate(WdfObjectContextGetObject(DeviceContext), WDF_NO_OBJECT_ATTRIBUTES, &hidTarget); if (!NT_SUCCESS(status)) { KdPrint(("FireFly: WdfIoTargetCreate failed 0x%x\n", status)); return status; } // // Open it up, write access only! // WDF_IO_TARGET_OPEN_PARAMS_INIT_OPEN_BY_NAME( &openParams, &DeviceContext->PdoName, FILE_WRITE_ACCESS); // // We will let the framework to respond automatically to the pnp // state changes of the target by closing and opening the handle. // openParams.ShareAccess = FILE_SHARE_WRITE | FILE_SHARE_READ; status = WdfIoTargetOpen(hidTarget, &openParams); if (!NT_SUCCESS(status)) { KdPrint(("FireFly: WdfIoTargetOpen failed 0x%x\n", status)); goto ExitAndFree; } WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor, (PVOID) &collectionInformation, sizeof(HID_COLLECTION_INFORMATION)); // // Now get the collection information for this device // status = WdfIoTargetSendIoctlSynchronously(hidTarget, NULL, IOCTL_HID_GET_COLLECTION_INFORMATION, NULL, &outputDescriptor, NULL, NULL); if (!NT_SUCCESS(status)) { KdPrint(("FireFly: WdfIoTargetSendIoctlSynchronously failed 0x%x\n", status)); goto ExitAndFree; } preparsedData = (PHIDP_PREPARSED_DATA) ExAllocatePoolWithTag( NonPagedPool, collectionInformation.DescriptorSize, 'ffly'); if (preparsedData == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto ExitAndFree; } WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputDescriptor, (PVOID) preparsedData, collectionInformation.DescriptorSize); status = WdfIoTargetSendIoctlSynchronously(hidTarget, NULL, IOCTL_HID_GET_COLLECTION_DESCRIPTOR, NULL, &outputDescriptor, NULL, NULL); if (!NT_SUCCESS(status)) { KdPrint(("FireFly: WdfIoTargetSendIoctlSynchronously failed 0x%x\n", status)); goto ExitAndFree; } // // Now get the capabilities. // RtlZeroMemory(&caps, sizeof(HIDP_CAPS)); status = HidP_GetCaps(preparsedData, &caps); if (!NT_SUCCESS(status)) { goto ExitAndFree; } // // Create a report to send to the device. // report = (PCHAR) ExAllocatePoolWithTag( NonPagedPool, caps.FeatureReportByteLength, 'ffly'); if (report == NULL) { goto ExitAndFree; } // // Start with a zeroed report. If we are disabling the feature, this might // be all we need to do. // RtlZeroMemory(report, caps.FeatureReportByteLength); status = STATUS_SUCCESS; if (EnableFeature) { // // Edit the report to reflect the enabled feature // usage = FeatureId; usageLength = 1; status = HidP_SetUsages( HidP_Feature, PageId, 0, &usage, // pointer to the usage list &usageLength, // number of usages in the usage list preparsedData, report, caps.FeatureReportByteLength ); if (!NT_SUCCESS(status)) { KdPrint(("FireFly: HidP_SetUsages failed 0x%x\n", status)); goto ExitAndFree; } } WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&inputDescriptor, report, caps.FeatureReportByteLength); status = WdfIoTargetSendIoctlSynchronously(hidTarget, NULL, IOCTL_HID_SET_FEATURE, &inputDescriptor, NULL, NULL, NULL); if (!NT_SUCCESS(status)) { KdPrint(("FireFly: WdfIoTargetSendIoctlSynchronously failed 0x%x\n", status)); goto ExitAndFree; } ExitAndFree: if (preparsedData != NULL) { ExFreePool(preparsedData); preparsedData = NULL; } if (report != NULL) { ExFreePool(report); report = NULL; } if (hidTarget != NULL) { WdfObjectDelete(hidTarget); } return status; }
NTSTATUS Acpi_EvaluateUcsiDsm ( _In_ PACPI_CONTEXT AcpiCtx, _In_ ULONG FunctionIndex, _Outptr_opt_ PACPI_EVAL_OUTPUT_BUFFER* Output ) /*++ N.B. Caller is expected to free the Output buffer. --*/ { NTSTATUS status; WDFDEVICE device; WDFMEMORY inputMemory; WDF_MEMORY_DESCRIPTOR inputMemDesc; PACPI_EVAL_INPUT_BUFFER_COMPLEX inputBuffer; size_t inputBufferSize; size_t inputArgumentBufferSize; PACPI_METHOD_ARGUMENT argument; WDF_MEMORY_DESCRIPTOR outputMemDesc; PACPI_EVAL_OUTPUT_BUFFER outputBuffer; size_t outputBufferSize; size_t outputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES attributes; WDF_REQUEST_SEND_OPTIONS sendOptions; PAGED_CODE(); TRACE_FUNC_ENTRY(TRACE_FLAG_ACPI); device = Context_GetWdfDevice(AcpiCtx); inputMemory = WDF_NO_HANDLE; outputBuffer = nullptr; inputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(GUID)) + ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)) + ACPI_METHOD_ARGUMENT_LENGTH(0); inputBufferSize = FIELD_OFFSET(ACPI_EVAL_INPUT_BUFFER_COMPLEX, Argument) + inputArgumentBufferSize; WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = device; status = WdfMemoryCreate(&attributes, NonPagedPoolNx, 0, inputBufferSize, &inputMemory, (PVOID*) &inputBuffer); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] WdfMemoryCreate failed for %Iu bytes - %!STATUS!", device, inputBufferSize, status); goto Exit; } RtlZeroMemory(inputBuffer, inputBufferSize); inputBuffer->Signature = ACPI_EVAL_INPUT_BUFFER_COMPLEX_SIGNATURE; inputBuffer->Size = (ULONG) inputArgumentBufferSize; inputBuffer->ArgumentCount = 4; inputBuffer->MethodNameAsUlong = (ULONG) 'MSD_'; argument = &(inputBuffer->Argument[0]); ACPI_METHOD_SET_ARGUMENT_BUFFER(argument, &GUID_UCSI_DSM, sizeof(GUID_UCSI_DSM)); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, UCSI_DSM_REVISION); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); ACPI_METHOD_SET_ARGUMENT_INTEGER(argument, FunctionIndex); argument = ACPI_METHOD_NEXT_ARGUMENT(argument); argument->Type = ACPI_METHOD_ARGUMENT_PACKAGE_EX; argument->DataLength = 0; outputArgumentBufferSize = ACPI_METHOD_ARGUMENT_LENGTH(sizeof(ULONG)); outputBufferSize = FIELD_OFFSET(ACPI_EVAL_OUTPUT_BUFFER, Argument) + outputArgumentBufferSize; outputBuffer = (PACPI_EVAL_OUTPUT_BUFFER) ExAllocatePoolWithTag(NonPagedPoolNx, outputBufferSize, TAG_UCSI); if (outputBuffer == nullptr) { status = STATUS_INSUFFICIENT_RESOURCES; TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ExAllocatePoolWithTag failed for %Iu bytes", device, outputBufferSize); goto Exit; } RtlZeroMemory(outputBuffer, outputBufferSize); WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&inputMemDesc, inputMemory, NULL); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&outputMemDesc, outputBuffer, (ULONG) outputBufferSize); WDF_REQUEST_SEND_OPTIONS_INIT(&sendOptions, WDF_REQUEST_SEND_OPTION_SYNCHRONOUS); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT(&sendOptions, WDF_REL_TIMEOUT_IN_MS(UCSI_DSM_EXECUTION_TIMEOUT_IN_MS)); status = WdfIoTargetSendInternalIoctlSynchronously( WdfDeviceGetIoTarget(device), NULL, IOCTL_ACPI_EVAL_METHOD, &inputMemDesc, &outputMemDesc, &sendOptions, NULL); if (!NT_SUCCESS(status)) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] IOCTL_ACPI_EVAL_METHOD for _DSM failed - %!STATUS!", device, status); goto Exit; } if (outputBuffer->Signature != ACPI_EVAL_OUTPUT_BUFFER_SIGNATURE) { TRACE_ERROR(TRACE_FLAG_ACPI, "[Device: 0x%p] ACPI_EVAL_OUTPUT_BUFFER signature is incorrect", device); status = STATUS_ACPI_INVALID_DATA; goto Exit; } Exit: if (inputMemory != WDF_NO_HANDLE) { WdfObjectDelete(inputMemory); } if (!NT_SUCCESS(status) || (Output == nullptr)) { if (outputBuffer) { ExFreePoolWithTag(outputBuffer, TAG_UCSI); } } else { *Output = outputBuffer; } TRACE_FUNC_EXIT(TRACE_FLAG_ACPI); return status; }
NTSTATUS SetBarGraphState( _In_ PDEVICE_CONTEXT DevContext, _In_ PBAR_GRAPH_STATE BarGraphState ) /*++ Routine Description This routine sets the state of the bar graph on the board Arguments: DevContext - One of our device extensions BarGraphState - Struct that describes the bar graph's desired state Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; PAGED_CODE(); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetBarGraphState\n"); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, DEFAULT_CONTROL_TRANSFER_TIMEOUT ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, USBFX2LK_SET_BARGRAPH_DISPLAY, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, BarGraphState, sizeof(BAR_GRAPH_STATE)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( DevContext->UsbDevice, NULL, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "SetBarGraphState: Failed - 0x%x \n", status); } else { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "SetBarGraphState: LED mask is 0x%x\n", BarGraphState->BarsAsUChar); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetBarGraphState\n"); return status; }
/*++ Routine Description: This routine sets a property on a pipe. Arguments: pDeviceContext - Device context handle pControlTransfer - The control transfer property struct Return Value: NT status value --*/ 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; }
NTSTATUS GetSevenSegmentState( _In_ PDEVICE_CONTEXT DevContext, _Out_ PUCHAR SevenSegment ) /*++ Routine Description This routine gets the state of the 7 segment display on the board by sending a synchronous control command. NOTE: It's not a good practice to send a synchronous request in the context of the user thread because if the transfer takes long time to complete, you end up holding the user thread. I'm choosing to do synchronous transfer because a) I know this one completes immediately b) and for demonstration. Arguments: DevContext - One of our device extensions SevenSegment - receives the state of the 7 segment display Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Enter\n"); PAGED_CODE(); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, DEFAULT_CONTROL_TRANSFER_TIMEOUT ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, USBFX2LK_READ_7SEGMENT_DISPLAY, // Request 0, // Value 0); // Index // // Set the buffer to 0, the board will OR in everything that is set // *SevenSegment = 0; WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, SevenSegment, sizeof(UCHAR)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( DevContext->UsbDevice, NULL, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "GetSevenSegmentState: Failed to get 7 Segment state - 0x%x \n", status); } else { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "GetSetSevenSegmentState: Exit\n"); return status; }
NTSTATUS BthEchoCliRetrieveServerBthAddress( __in PBTHECHOSAMPLE_CLIENT_CONTEXT DevCtx ) /*++ Description: Retrieve server Bth address Arguments: DevCtx - Client context where we store bth address Return Value: NTSTATUS Status code. --*/ { NTSTATUS status, statusReuse; WDF_MEMORY_DESCRIPTOR outMemDesc; WDF_REQUEST_REUSE_PARAMS ReuseParams; BTH_DEVICE_INFO serverDeviceInfo; WDF_REQUEST_REUSE_PARAMS_INIT(&ReuseParams, WDF_REQUEST_REUSE_NO_FLAGS, STATUS_NOT_SUPPORTED); statusReuse = WdfRequestReuse(DevCtx->Header.Request, &ReuseParams); ASSERT(NT_SUCCESS(statusReuse)); UNREFERENCED_PARAMETER(statusReuse); RtlZeroMemory( &serverDeviceInfo, sizeof(serverDeviceInfo) ); WDF_MEMORY_DESCRIPTOR_INIT_BUFFER( &outMemDesc, &serverDeviceInfo, sizeof(serverDeviceInfo) ); status = WdfIoTargetSendInternalIoctlSynchronously( DevCtx->Header.IoTarget, DevCtx->Header.Request, IOCTL_INTERNAL_BTHENUM_GET_DEVINFO, NULL, //inMemDesc &outMemDesc, NULL, //sendOptions NULL //bytesReturned ); if (!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "Failed to obtain server device info, Status code %!STATUS!\n", status); goto exit; } DevCtx->ServerBthAddress = serverDeviceInfo.address; exit: return status; }
NTSTATUS SetSevenSegmentState( _In_ PDEVICE_CONTEXT DevContext, _In_ PUCHAR SevenSegment ) /*++ Routine Description This routine sets the state of the 7 segment display on the board Arguments: DevContext - One of our device extensions SevenSegment - desired state of the 7 segment display Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; PAGED_CODE(); TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "--> SetSevenSegmentState\n"); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, DEFAULT_CONTROL_TRANSFER_TIMEOUT ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestHostToDevice, BmRequestToDevice, USBFX2LK_SET_7SEGMENT_DISPLAY, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, SevenSegment, sizeof(UCHAR)); status = WdfUsbTargetDeviceSendControlTransferSynchronously( DevContext->UsbDevice, NULL, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { TraceEvents(TRACE_LEVEL_ERROR, DBG_IOCTL, "SetSevenSegmentState: Failed to set 7 Segment state - 0x%x \n", status); } else { TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "SetSevenSegmentState: 7 Segment mask is 0x%x\n", *SevenSegment); } TraceEvents(TRACE_LEVEL_VERBOSE, DBG_IOCTL, "<-- SetSevenSegmentState\n"); return status; }
NTSTATUS GetDevInfoData( __in PFILTER_EXTENSION filterExt, __in ULONG DevInfoLen, __out BYTE* pDevInfoData, __out size_t* bytesRead ) /*++ Routine Description This routine gets the data of the device Arguments: pDevInfoLen - One of our device extensions Return Value: NT status value --*/ { NTSTATUS status; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_REQUEST_SEND_OPTIONS sendOptions; WDF_MEMORY_DESCRIPTOR memDesc; ULONG bytesTransferred; PAGED_CODE(); WDF_REQUEST_SEND_OPTIONS_INIT( &sendOptions, WDF_REQUEST_SEND_OPTION_TIMEOUT ); WDF_REQUEST_SEND_OPTIONS_SET_TIMEOUT( &sendOptions, WDF_REL_TIMEOUT_IN_SEC(5) ); WDF_USB_CONTROL_SETUP_PACKET_INIT_VENDOR(&controlSetupPacket, BmRequestDeviceToHost, BmRequestToDevice, USBFX2LK_READ_DEVINFO_DATA, // Request 0, // Value 0); // Index WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&memDesc, pDevInfoData, DevInfoLen); status = WdfUsbTargetDeviceSendControlTransferSynchronously( filterExt->UsbDevice, WDF_NO_HANDLE, // Optional WDFREQUEST &sendOptions, &controlSetupPacket, &memDesc, &bytesTransferred); if(!NT_SUCCESS(status)) { KdPrint( ("GetDevInfoData: Failed - 0x%x \n", status)); *bytesRead = 0; } else { KdPrint( ("GetDevInfoData: transferred bytes %d \n", bytesTransferred )); *bytesRead = (size_t)bytesTransferred; } return status; }
static NTSTATUS CyGetUSB30DeviceConfiguration(__in PDEVICE_CONTEXT pDevContext,WDFMEMORY *pUsb30DeviceConfig) {/* WdfUsbTargetDeviceRetrieveConfigDescriptor function return the selected interface detail while the WdfUsbTargetDeviceFormatRequestForControlTransfer function return the device whole configuration(including the multiple interface) which is we don't want, adding specific implementation for the getting configuration descriptor here*/ USHORT ConfigLen = 0; PUSB_CONFIGURATION_DESCRIPTOR configurationDescriptor = NULL; WDF_OBJECT_ATTRIBUTES objectAttribs; NTSTATUS NtStatus =STATUS_SUCCESS; WDF_USB_CONTROL_SETUP_PACKET controlSetupPacket; WDF_MEMORY_DESCRIPTOR tmpmemoryDescriptor; WDF_MEMORY_DESCRIPTOR tmpmemoryDescriptor1; USB_CONFIGURATION_DESCRIPTOR UsbConfigDec; CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "Start CyGetUSB30DeviceConfiguration\n"); // first get the configuration length //Initialze the buffer WDF_MEMORY_DESCRIPTOR_INIT_BUFFER(&tmpmemoryDescriptor, (PVOID) &UsbConfigDec, sizeof(USB_CONFIGURATION_DESCRIPTOR)); //Initialize control setup packet to get total configuration length. controlSetupPacket.Packet.bm.Request.Dir = BmRequestDeviceToHost ; controlSetupPacket.Packet.bm.Request.Type = BmRequestStandard; controlSetupPacket.Packet.bm.Request.Recipient = BmRequestToDevice; controlSetupPacket.Packet.bRequest = USB_REQUEST_GET_DESCRIPTOR; controlSetupPacket.Packet.wIndex.Bytes.HiByte = 0; controlSetupPacket.Packet.wIndex.Bytes.LowByte = 0; controlSetupPacket.Packet.wValue.Bytes.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; controlSetupPacket.Packet.wValue.Bytes.LowByte =0; controlSetupPacket.Packet.wLength = sizeof(USB_CONFIGURATION_DESCRIPTOR); NtStatus = WdfUsbTargetDeviceSendControlTransferSynchronously( pDevContext->CyUsbDevice, WDF_NO_HANDLE, NULL, &controlSetupPacket, &tmpmemoryDescriptor, NULL ); if (!NT_SUCCESS(NtStatus)) { CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfUsbTargetDeviceSendControlTransferSynchronously failed:%x \n",NtStatus); CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; } // allocate memory to get the device configuration WDF_OBJECT_ATTRIBUTES_INIT(&objectAttribs); objectAttribs.ParentObject = pDevContext->CyUsbDevice; // This object will be deleted after NtStatus = WdfMemoryCreate( &objectAttribs, NonPagedPool, CYMEM_TAG, UsbConfigDec.wTotalLength, pUsb30DeviceConfig, (PVOID)&configurationDescriptor ); if (!NT_SUCCESS(NtStatus)) { CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfMemoryCreate failed:%x \n",NtStatus); CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; } WDF_MEMORY_DESCRIPTOR_INIT_HANDLE(&tmpmemoryDescriptor1, *pUsb30DeviceConfig, NULL); //Get whole device configuration using the wTotalLenght od configuration descriptor //Initialize control setup packet to get total configuration length. controlSetupPacket.Packet.bm.Request.Dir = BmRequestDeviceToHost ; controlSetupPacket.Packet.bm.Request.Type = BmRequestStandard; controlSetupPacket.Packet.bm.Request.Recipient = BmRequestToDevice ; controlSetupPacket.Packet.bRequest = USB_REQUEST_GET_DESCRIPTOR; controlSetupPacket.Packet.wIndex.Bytes.HiByte = 0; controlSetupPacket.Packet.wIndex.Bytes.LowByte = 0; controlSetupPacket.Packet.wValue.Bytes.HiByte = USB_CONFIGURATION_DESCRIPTOR_TYPE; controlSetupPacket.Packet.wValue.Bytes.LowByte =0; controlSetupPacket.Packet.wLength = UsbConfigDec.wTotalLength; NtStatus = WdfUsbTargetDeviceSendControlTransferSynchronously( pDevContext->CyUsbDevice, WDF_NO_HANDLE, NULL, &controlSetupPacket, &tmpmemoryDescriptor1, NULL ); if (!NT_SUCCESS(NtStatus)) { CyTraceEvents(TRACE_LEVEL_ERROR, DBG_PNP, "WdfUsbTargetDeviceSendControlTransferSynchronously failed:%x \n",NtStatus); CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; } CyTraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "End CyGetUSB30DeviceConfiguration\n"); return NtStatus; }