void CQueue::OnDeviceIoControl( __in IWDFIoQueue* pQueue, __in IWDFIoRequest* pRequest, __in ULONG ControlCode, __in SIZE_T /*InputBufferSizeInBytes*/, __in SIZE_T /*OutputBufferSizeInBytes*/ ) /*++ Routine Description: The framework calls this function when somone has called DeviceIoControl on the device. Arguments: Return Value: None --*/ { HRESULT hr = S_OK; IWDFDevice *pDevice = NULL; Trace(TRACE_LEVEL_INFORMATION,"%!FUNC!"); // // Retrieve the queue's parent device object // pQueue->GetDevice(&pDevice); WUDF_TEST_DRIVER_ASSERT(pDevice); switch (ControlCode) { case IOCTL_TOASTER_DONT_DISPLAY_IN_UI_DEVICE: // // This is just an example on how to hide your device in the // device manager. Please remove your code when you adapt this // sample for your hardware. // pDevice->SetPnpState(WdfPnpStateDontDisplayInUI, WdfTrue); pDevice->CommitPnpState(); break; default: hr = E_FAIL; //invalid request Trace(TRACE_LEVEL_ERROR,"%!FUNC! Invalid IOCTL %!hresult!",hr); } pRequest->Complete(hr); return; }
CMyQueue::~CMyQueue( VOID ) /*++ Routine Description: IUnknown implementation of Release Arguments: Return Value: --*/ { WUDF_TEST_DRIVER_ASSERT(m_Device); m_Device->Release(); }
void CMyReadWriteQueue::ForwardFormattedRequest( __in IWDFIoRequest* pRequest, __in IWDFIoTarget* pIoTarget ) { // //First set the completion callback // IRequestCallbackRequestCompletion * pCompletionCallback = NULL; HRESULT hrQI = this->QueryInterface(IID_PPV_ARGS(&pCompletionCallback)); WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI) && (NULL != pCompletionCallback)); pRequest->SetCompletionCallback( pCompletionCallback, NULL ); pCompletionCallback->Release(); pCompletionCallback = NULL; // //Send down the request // HRESULT hrSend = S_OK; hrSend = pRequest->Send(pIoTarget, 0, //flags 0); //timeout if (FAILED(hrSend)) { pRequest->CompleteWithInformation(hrSend, 0); } return; }
HRESULT CMyDevice::Initialize( __in IWDFDriver * FxDriver, __in IWDFDeviceInitialize * FxDeviceInit ) /*++ Routine Description: This method initializes the device callback object and creates the partner device object. The method should perform any device-specific configuration that: * could fail (these can't be done in the constructor) * must be done before the partner object is created -or- * can be done after the partner object is created and which aren't influenced by any device-level parameters the parent (the driver in this case) might set. Arguments: FxDeviceInit - the settings for this device. Return Value: status. --*/ { IWDFDevice *fxDevice = NULL; HRESULT hr = S_OK; // // TODO: If you're writing a filter driver then indicate that here. // // FxDeviceInit->SetFilter(); // // // Set no locking unless you need an automatic callbacks synchronization // FxDeviceInit->SetLockingConstraint(None); // // Only one driver in the stack can be the Power policy owner (PPO). // // NOTE: If we want UMDF to be the PPO we also ask WinUsb.sys // to not set itself as the PPO by setting the // WinUsbPowerPolicyOwnershipDisabled key through // an AddReg in the INF. // #if defined(_NOT_POWER_POLICY_OWNER_) FxDeviceInit->SetPowerPolicyOwnership(FALSE); #else FxDeviceInit->SetPowerPolicyOwnership(TRUE); #endif // // TODO: Any per-device initialization which must be done before // creating the partner object. // // // Create a new FX device object and assign the new callback object to // handle any device level events that occur. // // // QueryIUnknown references the IUnknown interface that it returns // (which is the same as referencing the device). We pass that to // CreateDevice, which takes its own reference if everything works. // if (SUCCEEDED(hr)) { IUnknown *unknown = this->QueryIUnknown(); hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice); unknown->Release(); } // // If that succeeded then set our FxDevice member variable. // if (SUCCEEDED(hr)) { // // Drop the reference we got from CreateDevice. Since this object // is partnered with the framework object they have the same // lifespan - there is no need for an additional reference. // fxDevice->Release(); IWDFDevice2 *fxDevice2 = NULL; HRESULT hrQI = fxDevice->QueryInterface(__uuidof(IWDFDevice2), (void**) &fxDevice2); WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hrQI) && fxDevice2); m_FxDevice = fxDevice2; // // Drop the reference we got from QueryInterface(). Since this object // is partnered with the framework object they have the same // lifespan - there is no need for an additional reference. // fxDevice2->Release(); } return hr; }
HRESULT CMyDevice::CreateUsbIoTargets( ) /*++ Routine Description: This routine creates Usb device, interface and pipe objects Arguments: None Return Value: HRESULT --*/ { HRESULT hr; UCHAR NumEndPoints = 0; IWDFUsbTargetFactory * pIUsbTargetFactory = NULL; IWDFUsbTargetDevice * pIUsbTargetDevice = NULL; IWDFUsbInterface * pIUsbInterface = NULL; IWDFUsbTargetPipe * pIUsbPipe = NULL; hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pIUsbTargetFactory)); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Cannot get usb target factory %!HRESULT!", hr ); } if (SUCCEEDED(hr)) { hr = pIUsbTargetFactory->CreateUsbTargetDevice( &pIUsbTargetDevice); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Unable to create USB Device I/O Target %!HRESULT!", hr ); } else { m_pIUsbTargetDevice = pIUsbTargetDevice; // // Release the creation reference as object tree will maintain a reference // pIUsbTargetDevice->Release(); } } if (SUCCEEDED(hr)) { UCHAR NumInterfaces = pIUsbTargetDevice->GetNumInterfaces(); WUDF_TEST_DRIVER_ASSERT(1 == NumInterfaces); hr = pIUsbTargetDevice->RetrieveUsbInterface(0, &pIUsbInterface); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Unable to retrieve USB interface from USB Device I/O Target %!HRESULT!", hr ); } else { m_pIUsbInterface = pIUsbInterface; pIUsbInterface->Release(); //release creation reference } } if (SUCCEEDED(hr)) { NumEndPoints = pIUsbInterface->GetNumEndPoints(); if (NumEndPoints != NUM_OSRUSB_ENDPOINTS) { hr = E_UNEXPECTED; TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Has %d endpoints, expected %d, returning %!HRESULT! ", NumEndPoints, NUM_OSRUSB_ENDPOINTS, hr ); } } if (SUCCEEDED(hr)) { for (UCHAR PipeIndex = 0; PipeIndex < NumEndPoints; PipeIndex++) { hr = pIUsbInterface->RetrieveUsbPipeObject(PipeIndex, &pIUsbPipe); if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Unable to retrieve USB Pipe for PipeIndex %d, %!HRESULT!", PipeIndex, hr ); } else { if ( pIUsbPipe->IsInEndPoint() ) { if ( UsbdPipeTypeInterrupt == pIUsbPipe->GetType() ) { m_pIUsbInterruptPipe = pIUsbPipe; WUDF_TEST_DRIVER_ASSERT(m_pIoTargetInterruptPipeStateMgmt == NULL); hr = m_pIUsbInterruptPipe->QueryInterface(__uuidof( IWDFIoTargetStateManagement), reinterpret_cast<void**>(&m_pIoTargetInterruptPipeStateMgmt) ); if (FAILED(hr)) { m_pIoTargetInterruptPipeStateMgmt = NULL; } } else if ( UsbdPipeTypeBulk == pIUsbPipe->GetType() ) { m_pIUsbInputPipe = pIUsbPipe; } else { pIUsbPipe->DeleteWdfObject(); } } else if ( pIUsbPipe->IsOutEndPoint() && (UsbdPipeTypeBulk == pIUsbPipe->GetType()) ) { m_pIUsbOutputPipe = pIUsbPipe; } else { pIUsbPipe->DeleteWdfObject(); } SAFE_RELEASE(pIUsbPipe); //release creation reference } } if (NULL == m_pIUsbInputPipe || NULL == m_pIUsbOutputPipe) { hr = E_UNEXPECTED; TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Input or output pipe not found, returning %!HRESULT!", hr ); } } SAFE_RELEASE(pIUsbTargetFactory); return hr; }
VOID STDMETHODCALLTYPE CMyQueue::OnDeviceIoControl( _In_ IWDFIoQueue *pWdfQueue, _In_ IWDFIoRequest *pWdfRequest, _In_ ULONG ControlCode, _In_ SIZE_T InputBufferSizeInBytes, _In_ SIZE_T OutputBufferSizeInBytes ) /*++ Routine Description: DeviceIoControl dispatch routine Arguments: pWdfQueue - Framework Queue instance pWdfRequest - Framework Request instance ControlCode - IO Control Code InputBufferSizeInBytes - Length of input buffer OutputBufferSizeInBytes - Length of output buffer Always succeeds DeviceIoIoctl Return Value: VOID --*/ { UNREFERENCED_PARAMETER(OutputBufferSizeInBytes); UNREFERENCED_PARAMETER(InputBufferSizeInBytes); UNREFERENCED_PARAMETER(pWdfQueue); HRESULT hr = S_OK; SIZE_T reqCompletionInfo = 0; IWDFMemory *inputMemory = NULL; IWDFMemory *outputMemory = NULL; UINT i; WUDF_TEST_DRIVER_ASSERT(pWdfRequest); WUDF_TEST_DRIVER_ASSERT(m_Device); switch (ControlCode) { case IOCTL_SERIAL_SET_BAUD_RATE: { // // This is a driver for a virtual serial port. Since there is no // actual hardware, we just store the baud rate and don't do // anything with it. // SERIAL_BAUD_RATE baudRateBuffer = {0}; pWdfRequest->GetInputMemory(&inputMemory); if (NULL == inputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { hr = inputMemory->CopyToBuffer(0, (void*) &baudRateBuffer, sizeof(SERIAL_BAUD_RATE)); } if (SUCCEEDED(hr)) { m_Device->SetBaudRate(baudRateBuffer.BaudRate); } break; } case IOCTL_SERIAL_GET_BAUD_RATE: { SERIAL_BAUD_RATE baudRateBuffer = {0}; baudRateBuffer.BaudRate = m_Device->GetBaudRate(); pWdfRequest->GetOutputMemory(&outputMemory); if (NULL == outputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { hr = outputMemory->CopyFromBuffer(0, (void*) &baudRateBuffer, sizeof(SERIAL_BAUD_RATE)); } if (SUCCEEDED(hr)) { reqCompletionInfo = sizeof(SERIAL_BAUD_RATE); } break; } case IOCTL_SERIAL_SET_MODEM_CONTROL: { // // This is a driver for a virtual serial port. Since there is no // actual hardware, we just store the modem control register // configuration and don't do anything with it. // ULONG *pModemControlRegister = NULL; pWdfRequest->GetInputMemory(&inputMemory); if (NULL == inputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { pModemControlRegister = m_Device->GetModemControlRegisterPtr(); WUDF_TEST_DRIVER_ASSERT(pModemControlRegister); hr = inputMemory->CopyToBuffer(0, (void*) pModemControlRegister, sizeof(ULONG)); } break; } case IOCTL_SERIAL_GET_MODEM_CONTROL: { ULONG *pModemControlRegister = NULL; pWdfRequest->GetOutputMemory(&outputMemory); if (NULL == outputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { pModemControlRegister = m_Device->GetModemControlRegisterPtr(); WUDF_TEST_DRIVER_ASSERT(pModemControlRegister); hr = outputMemory->CopyFromBuffer(0, (void*) pModemControlRegister, sizeof(ULONG)); } if (SUCCEEDED(hr)) { reqCompletionInfo = sizeof(ULONG); } break; } case IOCTL_SERIAL_SET_FIFO_CONTROL: { // // This is a driver for a virtual serial port. Since there is no // actual hardware, we just store the FIFO control register // configuration and don't do anything with it. // ULONG *pFifoControlRegister = NULL; pWdfRequest->GetInputMemory(&inputMemory); if (NULL == inputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { pFifoControlRegister = m_Device->GetFifoControlRegisterPtr(); hr = inputMemory->CopyToBuffer(0, (void*) pFifoControlRegister, sizeof(ULONG)); } break; } case IOCTL_SERIAL_GET_LINE_CONTROL: { ULONG *pLineControlRegister = NULL; SERIAL_LINE_CONTROL lineControl = {0}; ULONG lineControlSnapshot; pLineControlRegister = m_Device->GetLineControlRegisterPtr(); WUDF_TEST_DRIVER_ASSERT(pLineControlRegister); // // Take a snapshot of the line control register variable // lineControlSnapshot = *pLineControlRegister; // // Decode the word length // if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_5_DATA) { lineControl.WordLength = 5; } else if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_6_DATA) { lineControl.WordLength = 6; } else if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_7_DATA) { lineControl.WordLength = 7; } else if ((lineControlSnapshot & SERIAL_DATA_MASK) == SERIAL_8_DATA) { lineControl.WordLength = 8; } // // Decode the parity // if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_NONE_PARITY) { lineControl.Parity = NO_PARITY; } else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_ODD_PARITY) { lineControl.Parity = ODD_PARITY; } else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_EVEN_PARITY) { lineControl.Parity = EVEN_PARITY; } else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_MARK_PARITY) { lineControl.Parity = MARK_PARITY; } else if ((lineControlSnapshot & SERIAL_PARITY_MASK) == SERIAL_SPACE_PARITY) { lineControl.Parity = SPACE_PARITY; } // // Decode the length of the stop bit // if (lineControlSnapshot & SERIAL_2_STOP) { if (lineControl.WordLength == 5) { lineControl.StopBits = STOP_BITS_1_5; } else { lineControl.StopBits = STOP_BITS_2; } } else { lineControl.StopBits = STOP_BIT_1; } // // Copy the information that was decoded to the caller's buffer // pWdfRequest->GetOutputMemory(&outputMemory); if (NULL == outputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { hr = outputMemory->CopyFromBuffer(0, (void*) &lineControl, sizeof(SERIAL_LINE_CONTROL)); } if (SUCCEEDED(hr)) { reqCompletionInfo = sizeof(SERIAL_LINE_CONTROL); } break; } case IOCTL_SERIAL_SET_LINE_CONTROL: { ULONG *pLineControlRegister = NULL; SERIAL_LINE_CONTROL lineControl = {0}; UCHAR lineControlData = 0; UCHAR lineControlStop = 0; UCHAR lineControlParity = 0; ULONG lineControlSnapshot; ULONG lineControlNew; ULONG lineControlPrevious; pLineControlRegister = m_Device->GetLineControlRegisterPtr(); WUDF_TEST_DRIVER_ASSERT(pLineControlRegister); // // This is a driver for a virtual serial port. Since there is no // actual hardware, we just store the line control register // configuration and don't do anything with it. // pWdfRequest->GetInputMemory(&inputMemory); if (NULL == inputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { hr = inputMemory->CopyToBuffer(0, (void*) &lineControl, sizeof(SERIAL_LINE_CONTROL)); } // // Bits 0 and 1 of the line control register // if (SUCCEEDED(hr)) { switch (lineControl.WordLength) { case 5: lineControlData = SERIAL_5_DATA; m_Device->SetValidDataMask(0x1f); break; case 6: lineControlData = SERIAL_6_DATA; m_Device->SetValidDataMask(0x3f); break; case 7: lineControlData = SERIAL_7_DATA; m_Device->SetValidDataMask(0x7f); break; case 8: lineControlData = SERIAL_8_DATA; m_Device->SetValidDataMask(0xff); break; default: hr = E_INVALIDARG; } } // // Bit 2 of the line control register // if (SUCCEEDED(hr)) { switch (lineControl.StopBits) { case STOP_BIT_1: lineControlStop = SERIAL_1_STOP; break; case STOP_BITS_1_5: if (lineControlData != SERIAL_5_DATA) { hr = E_INVALIDARG; break; } lineControlStop = SERIAL_1_5_STOP; break; case STOP_BITS_2: if (lineControlData == SERIAL_5_DATA) { hr = E_INVALIDARG; break; } lineControlStop = SERIAL_2_STOP; break; default: hr = E_INVALIDARG; } } // // Bits 3, 4 and 5 of the line control register // if (SUCCEEDED(hr)) { switch (lineControl.Parity) { case NO_PARITY: lineControlParity = SERIAL_NONE_PARITY; break; case EVEN_PARITY: lineControlParity = SERIAL_EVEN_PARITY; break; case ODD_PARITY: lineControlParity = SERIAL_ODD_PARITY; break; case SPACE_PARITY: lineControlParity = SERIAL_SPACE_PARITY; break; case MARK_PARITY: lineControlParity = SERIAL_MARK_PARITY; break; default: hr = E_INVALIDARG; } } // // Update our line control register variable atomically // i=0; do { i++; if ((i & 0xf) == 0) { // // We've been spinning in a loop for a while trying to // update the line control register variable atomically. // Yield the CPU for other threads for a while. // SwitchToThread(); } lineControlSnapshot = *pLineControlRegister; lineControlNew = (lineControlSnapshot & SERIAL_LCR_BREAK) | (lineControlData | lineControlParity | lineControlStop); lineControlPrevious = InterlockedCompareExchange((LONG *) pLineControlRegister, lineControlNew, lineControlSnapshot); } while (lineControlPrevious != lineControlSnapshot); break; } case IOCTL_SERIAL_GET_TIMEOUTS: { SERIAL_TIMEOUTS timeoutValues = {0}; pWdfRequest->GetOutputMemory(&outputMemory); if (NULL == outputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { m_Device->GetTimeouts(&timeoutValues); hr = outputMemory->CopyFromBuffer(0, (void*) &timeoutValues, sizeof(timeoutValues)); } if (SUCCEEDED(hr)) { reqCompletionInfo = sizeof(SERIAL_TIMEOUTS); } break; } case IOCTL_SERIAL_SET_TIMEOUTS: { SERIAL_TIMEOUTS timeoutValues = {0}; pWdfRequest->GetInputMemory(&inputMemory); if (NULL == inputMemory) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); } if (SUCCEEDED(hr)) { hr = inputMemory->CopyToBuffer(0, (void*) &timeoutValues, sizeof(timeoutValues)); } if (SUCCEEDED(hr)) { if ((timeoutValues.ReadIntervalTimeout == MAXULONG) && (timeoutValues.ReadTotalTimeoutMultiplier == MAXULONG) && (timeoutValues.ReadTotalTimeoutConstant == MAXULONG)) { hr = E_INVALIDARG; } } if (SUCCEEDED(hr)) { m_Device->SetTimeouts(timeoutValues); } break; } case IOCTL_SERIAL_SET_QUEUE_SIZE: case IOCTL_SERIAL_SET_DTR: case IOCTL_SERIAL_SET_WAIT_MASK: case IOCTL_SERIAL_SET_RTS: case IOCTL_SERIAL_CLR_RTS: case IOCTL_SERIAL_SET_XON: case IOCTL_SERIAL_SET_XOFF: case IOCTL_SERIAL_SET_CHARS: case IOCTL_SERIAL_GET_CHARS: case IOCTL_SERIAL_GET_HANDFLOW: case IOCTL_SERIAL_SET_HANDFLOW: case IOCTL_SERIAL_RESET_DEVICE: { // // NOTE: The application expects STATUS_SUCCESS for these IOCTLs. // so don't merge this with default. // break; } default: { hr = E_INVALIDARG; } } // // clean up // if (inputMemory) { inputMemory->Release(); } if (outputMemory) { outputMemory->Release(); } // // complete the request // pWdfRequest->CompleteWithInformation(hr, reqCompletionInfo); return; }
HRESULT CMyDevice::OnPrepareHardware( _In_ IWDFDevice * /* FxDevice */ ) /*++ Routine Description: This routine is invoked to ready the driver to talk to hardware. It opens the handle to the device and talks to it using the HID interface. Arguments: FxDevice : Pointer to the WDF device interface Return Value: HRESULT --*/ { PWSTR instanceId = NULL; DWORD instanceIdCch = 0; HRESULT hr = S_OK; m_SwitchState.SwitchesAsUChar = 0; if (SUCCEEDED(hr)) { // // Find out the instance id buffer size. // hr = m_FxDevice->RetrieveDeviceInstanceId(NULL, &instanceIdCch); } if (SUCCEEDED(hr)) { // // Allocate the buffer. // instanceId = new WCHAR[instanceIdCch]; if (instanceId == NULL) { hr = E_OUTOFMEMORY; TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Out of memory" ); } } if (SUCCEEDED(hr)) { // // Get the instance id. // hr = m_FxDevice->RetrieveDeviceInstanceId(instanceId, &instanceIdCch); } if (SUCCEEDED(hr)) { TraceEvents(TRACE_LEVEL_INFORMATION, TEST_TRACE_DEVICE, "%!FUNC! Device instance id %S", instanceId ); } else { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Cannot get device instance id %!HRESULT!", hr ); } if(SUCCEEDED(hr)) { // // Create a file object. // hr = m_FxDevice->CreateWdfFile( NULL, &m_WdfFile ); if (SUCCEEDED(hr) && nullptr != m_WdfFile) { // // Get our parent driver object. // m_FxDevice->GetDriver( &m_WdfDriver ); // // Get the default I/O target. This allows us to send IOCTLs // to the HID collection below us in the stack. // if (nullptr != m_WdfDriver) { m_FxDevice->GetDefaultIoTarget( &m_WdfIoTarget ); } else { hr = E_UNEXPECTED; Trace(TRACE_LEVEL_ERROR, "Failed during GetDriver(), hr = %!HRESULT!", hr); } if (nullptr == m_WdfIoTarget) { hr = E_UNEXPECTED; Trace(TRACE_LEVEL_ERROR, "Failed during GetDefaultIoTarget(), hr = %!HRESULT!", hr); } } else { Trace(TRACE_LEVEL_ERROR, "m_WdfFile is NULL, hr = %!HRESULT!", hr); } } else { Trace(TRACE_LEVEL_ERROR, "Failed during CreateWdfFile(), hr = %!HRESULT!", hr); } if (SUCCEEDED(hr)) { // // Get the HID capabilities and attributes. // hr = GetHidCapabilities(); } if (SUCCEEDED(hr)) { // // Queue up a pending read for input reports. // WUDF_TEST_DRIVER_ASSERT(m_Caps.InputReportByteLength == sizeof (m_SwitchStateReport)); IWDFIoRequest *pWdfRequest; // // Create child request for the default I/O target // hr = m_FxDevice->CreateRequest(NULL, m_WdfIoTarget, &pWdfRequest); if (SUCCEEDED(hr)) { hr = SendReadRequest(pWdfRequest); pWdfRequest->Release(); } else { Trace(TRACE_LEVEL_ERROR, "Failed to create a request, hr = %!HRESULT!", hr); } } if (SUCCEEDED(hr)) { // // Set the seven segement display and bar graph to indicate that we're done with // prepare hardware. // hr = IndicateDeviceReady(); } if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! failed %!HRESULT!", hr ); } delete[] instanceId; return hr; }
HRESULT CMyDevice::Configure( VOID ) /*++ Routine Description: This method is called after the device callback object has been initialized and returned to the driver. It would setup the device's queues and their corresponding callback objects. Arguments: FxDevice - the framework device object for which we're handling events. Return Value: status --*/ { HRESULT hr = S_OK; hr = CMyReadWriteQueue::CreateInstance(this, &m_ReadWriteQueue); if (FAILED(hr)) { return hr; } // // We use default queue for read/write // hr = m_ReadWriteQueue->Configure(); m_ReadWriteQueue->Release(); // // Create the control queue and configure forwarding for IOCTL requests. // if (SUCCEEDED(hr)) { hr = CMyControlQueue::CreateInstance(this, &m_ControlQueue); if (SUCCEEDED(hr)) { hr = m_ControlQueue->Configure(); if (SUCCEEDED(hr)) { m_FxDevice->ConfigureRequestDispatching( m_ControlQueue->GetFxQueue(), WdfRequestDeviceIoControl, true ); } m_ControlQueue->Release(); } } // // Create a manual I/O queue to hold requests for notification when // the switch state changes. // hr = m_FxDevice->CreateIoQueue(NULL, FALSE, WdfIoQueueDispatchManual, FALSE, FALSE, &m_SwitchChangeQueue); // // Release creation reference as object tree will keep a reference // m_SwitchChangeQueue->Release(); if (SUCCEEDED(hr)) { // TODO: Expose your device interface GUID here. hr = m_FxDevice->CreateDeviceInterface(&GUID_DEVINTERFACE_OSRUSBFX2, NULL); } // // Mark the interface as restricted to allow access to applications bound // using device metadata. // if (SUCCEEDED(hr)) { WDF_PROPERTY_STORE_ROOT RootSpecifier; IWDFUnifiedPropertyStoreFactory * pUnifiedPropertyStoreFactory = NULL; IWDFUnifiedPropertyStore * pUnifiedPropertyStore = NULL; DEVPROP_BOOLEAN isRestricted = DEVPROP_TRUE; hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pUnifiedPropertyStoreFactory)); WUDF_TEST_DRIVER_ASSERT(SUCCEEDED(hr)); RootSpecifier.LengthCb = sizeof(RootSpecifier); RootSpecifier.RootClass = WdfPropertyStoreRootClassDeviceInterfaceKey; // TODO: Use your device interface GUID here. RootSpecifier.Qualifier.DeviceInterfaceKey.InterfaceGUID = &GUID_DEVINTERFACE_OSRUSBFX2; RootSpecifier.Qualifier.DeviceInterfaceKey.ReferenceString = NULL; hr = pUnifiedPropertyStoreFactory->RetrieveUnifiedDevicePropertyStore(&RootSpecifier, &pUnifiedPropertyStore); if (SUCCEEDED(hr)) { hr = pUnifiedPropertyStore->SetPropertyData(&DEVPKEY_DeviceInterface_Restricted, 0, // Lcid 0, // Flags DEVPROP_TYPE_BOOLEAN, sizeof(isRestricted), &isRestricted); } if (FAILED(hr)) { TraceEvents(TRACE_LEVEL_ERROR, TEST_TRACE_DEVICE, "%!FUNC! Could not set restricted property %!HRESULT!", hr ); } SAFE_RELEASE(pUnifiedPropertyStoreFactory); SAFE_RELEASE(pUnifiedPropertyStore); } return hr; }