CDefaultQueue::OnCreateFile( _In_ IWDFIoQueue* pQueue, _In_ IWDFIoRequest* pRequest, _In_ IWDFFile* pFileObject ) { UNREFERENCED_PARAMETER(pFileObject); CComPtr<WpdBaseDriver> pWpdBaseDriver; CComPtr<IWDFDevice> pDevice; HRESULT hr = S_OK; pQueue->GetDevice(&pDevice); hr = GetWpdBaseDriver(pDevice, &pWpdBaseDriver); CHECK_HR(hr, "Failed to get WpdBaseDriver"); if (hr == S_OK) { hr = pRequest->ForwardToIoQueue(pWpdBaseDriver->m_pWpdQueue); CHECK_HR(hr, "Failed to get WpdBaseDriver"); } if (FAILED(hr)) pRequest->Complete(hr); return; }
CDefaultQueue::OnDeviceIoControl( _In_ IWDFIoQueue* pQueue, _In_ IWDFIoRequest* pRequest, ULONG ControlCode, SIZE_T InputBufferSizeInBytes, SIZE_T OutputBufferSizeInBytes ) { CComPtr<WpdBaseDriver> pWpdBaseDriver; CComPtr<IWDFDevice> pDevice; HRESULT hr = S_OK; pQueue->GetDevice(&pDevice); hr = GetWpdBaseDriver(pDevice, &pWpdBaseDriver); CHECK_HR(hr, "Failed to get WpdBaseDriver"); if (hr == S_OK) { if (IS_WPD_IOCTL(ControlCode)) { hr = pRequest->ForwardToIoQueue(pWpdBaseDriver->m_pWpdQueue); CHECK_HR(hr, "Failed to forward to WPD queue"); } else if (pWpdBaseDriver->m_pQueueCallback) { pWpdBaseDriver->m_pQueueCallback->OnDeviceIoControl( pQueue, pRequest, ControlCode, InputBufferSizeInBytes, OutputBufferSizeInBytes ); } else { hr = E_UNEXPECTED; CHECK_HR(hr, "Unable to handle IOCTL code '0x%lx'", ControlCode); } } if (FAILED(hr)) pRequest->Complete(hr); return; }
/****************************************************************************** * This function calls the WpdBaseDriver to handle the WPD message. In order * to do this it does the following: * * - Deserializes pBuffer into an IPortableDeviceValues which holds the command * input parameters from the WPD application. * - Creates an IPortableDeviceValues for the results. * - Calls the WpdBaseDriver to handle the message. (The results of this * operation are put into the previously created results IPortableDeviceValues.) * - The results IPortableDeviceValues is then serialized back into pBuffer, making * sure that it does not overrun ulOutputBufferLength. * *****************************************************************************/ HRESULT CQueue::ProcessWpdMessage( ULONG ControlCode, ContextMap* pClientContextMap, IWDFDevice* pDevice, PVOID pInBuffer, ULONG ulInputBufferLength, PVOID pOutBuffer, ULONG ulOutputBufferLength, DWORD* pdwBytesWritten) { CComCritSecLock<CComAutoCriticalSection> Lock(m_CriticalSection); HRESULT hr = S_OK; CComPtr<IPortableDeviceValues> pParams; CComPtr<IPortableDeviceValues> pResults; CComPtr<WpdBaseDriver> pWpdBaseDriver; if (hr == S_OK) { hr = m_pWpdSerializer->GetIPortableDeviceValuesFromBuffer((BYTE*)pInBuffer, ulInputBufferLength, &pParams); CHECK_HR(hr, "Failed to deserialize command parameters from input buffer"); } // Verify that that command was sent with the appropriate access if (hr == S_OK) { hr = VERIFY_WPD_COMMAND_ACCESS(ControlCode, pParams, g_WpdCommandAccessMap); CHECK_HR(hr, "Wpd Command was sent with incorrect access flags"); } // Create the WPD results collection if (hr == S_OK) { hr = CoCreateInstance(CLSID_PortableDeviceValues, NULL, CLSCTX_INPROC_SERVER, IID_IPortableDeviceValues, (VOID**)&pResults); CHECK_HR(hr, "Failed to CoCreate CLSID_PortableDeviceValues"); } // Insert the client context map as one of this driver's private properties. This is // just a convenient place holder which allows other methods down the chain to // access the context map. if (hr == S_OK) { hr = pParams->SetIUnknownValue(PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP, pClientContextMap); CHECK_HR(hr, "Failed to set PRIVATE_SAMPLE_DRIVER_CLIENT_CONTEXT_MAP"); } // Insert the IWDFDevice interface as one of this driver's private properties. This is // just a convenient place holder which allows other methods down the chain to // access the WUDF Device object. if (hr == S_OK) { hr = pParams->SetIUnknownValue(PRIVATE_SAMPLE_DRIVER_WUDF_DEVICE_OBJECT, pDevice); CHECK_HR(hr, "Failed to set PRIVATE_SAMPLE_DRIVER_WUDF_DEVICE_OBJECT"); } // Insert the IWpdSerializer interface as one of this driver's private properties. This is // just a convenient place holder which allows other methods down the chain to // access the WPD Serializer object. if (hr == S_OK) { hr = pParams->SetIUnknownValue(PRIVATE_SAMPLE_DRIVER_WPD_SERIALIZER_OBJECT, m_pWpdSerializer); CHECK_HR(hr, "Failed to set PRIVATE_SAMPLE_DRIVER_WPD_SERIALIZER_OBJECT"); } // Get the WpdBaseDriver so we can dispatch the message if (hr == S_OK) { hr = GetWpdBaseDriver(pDevice, &pWpdBaseDriver); CHECK_HR(hr, "Failed to get WpdBaseDriver"); } if (hr == S_OK) { hr = pWpdBaseDriver->DispatchWpdMessage(pParams, pResults); CHECK_HR(hr, "Failed to handle WPD command"); } if (hr == S_OK) { hr = m_pWpdSerializer->WriteIPortableDeviceValuesToBuffer(ulOutputBufferLength, pResults, (BYTE*)pOutBuffer, pdwBytesWritten); CHECK_HR(hr, "Failed to serialize results to output buffer"); } return hr; }