summaryrefslogtreecommitdiff
path: root/serial/VirtualSerial/device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'serial/VirtualSerial/device.cpp')
-rw-r--r--serial/VirtualSerial/device.cpp674
1 files changed, 0 insertions, 674 deletions
diff --git a/serial/VirtualSerial/device.cpp b/serial/VirtualSerial/device.cpp
deleted file mode 100644
index 11d47775..00000000
--- a/serial/VirtualSerial/device.cpp
+++ /dev/null
@@ -1,674 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved.
-
-Module Name:
-
- Device.cpp
-
-Abstract:
-
- This module contains the implementation of the UMDF VirtualSerial sample
- driver's device callback object.
-
- The VirtualSerial sample device does very little. It does not implement
- either of the PNP interfaces so once the device is setup, it won't ever get
- any callbacks until the device is removed.
-
-Environment:
-
- Windows User-Mode Driver Framework (WUDF)
-
---*/
-
-#include "internal.h"
-#include "device.tmh"
-
-HRESULT
-CMyDevice::CreateInstance(
- _In_ IWDFDriver *FxDriver,
- _In_ IWDFDeviceInitialize * FxDeviceInit,
- _Out_ PCMyDevice *Device
- )
-/*++
-
- Routine Description:
-
- This method creates and initializs an instance of the VirtualSerial driver's
- device callback object.
-
- Arguments:
-
- FxDeviceInit - the settings for the device.
-
- Device - a location to store the referenced pointer to the device object.
-
- Return Value:
-
- Status
-
---*/
-{
- PCMyDevice device;
- HRESULT hr;
-
- //
- // Allocate a new instance of the device class.
- //
-
- device = new CMyDevice();
-
- if (NULL == device)
- {
- return E_OUTOFMEMORY;
- }
-
- //
- // Initialize the instance.
- //
-
- hr = device->Initialize(FxDriver, FxDeviceInit);
-
- if (SUCCEEDED(hr))
- {
- *Device = device;
- }
- else
- {
- device->Release();
- }
-
- return hr;
-}
-
-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;
- HRESULT hr;
-
- //
- // Configure things like the locking model before we go to create our
- // partner device.
- //
- FxDeviceInit->SetLockingConstraint(WdfDeviceLevel);
-
- //
- // 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.
- //
-
- {
- IUnknown *unknown = this->QueryIUnknown();
-
- hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice);
-
- unknown->Release();
- }
-
- //
- // If that succeeded then set our FxDevice member variable.
- //
-
- if (SUCCEEDED(hr))
- {
- m_FxDevice = fxDevice;
-
- //
- // 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();
- }
-
- 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
-
---*/
-{
- IWDFPropertyStoreFactory *pPropertyStoreFactory = NULL;
- IWDFNamedPropertyStore2 * pHardwarePropertyStore = NULL;
- IWDFNamedPropertyStore2 * pLegacyHardwarePropertyStore = NULL;
- WDF_PROPERTY_STORE_ROOT RootSpecifier;
- PROPVARIANT comPortPV;
- WCHAR portName[] = L"PortName";
- size_t comPortSuffixCch = 0;
- WCHAR *comPortFullName = NULL;
- size_t comPortFullNameCch = 0;
- WCHAR *pdoName = NULL;
- PCMyQueue defaultQueue;
-
-#ifdef _FAKE_MODEM
- //
- // Compiled as fake modem
- //
- LPGUID pGuid = (LPGUID) &GUID_DEVINTERFACE_MODEM;
-#else
- //
- // Compiled as virtual serial port
- //
- LPGUID pGuid = (LPGUID) &GUID_DEVINTERFACE_COMPORT;
-#endif
-
- HRESULT hr;
-
- PropVariantInit(&comPortPV);
-
- //
- // Create device interface
- //
- hr = m_FxDevice->CreateDeviceInterface(pGuid,
- NULL);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Cannot create device interface (%!GUID!)",
- pGuid
- );
-
- goto Exit;
- }
-
- hr = m_FxDevice->AssignDeviceInterfaceState(pGuid,
- NULL,
- TRUE);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Cannot enable device interface (%!GUID!)",
- pGuid
- );
-
- goto Exit;
- }
-
- //
- // Create Symbolic Link
- //
-
- //
- // First we need to read the COM number from the registry
- //
-
- hr = m_FxDevice->QueryInterface(IID_PPV_ARGS(&pPropertyStoreFactory));
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: QI for IWDFPropertyStoreFactory failed"
- );
-
- goto Exit;
- }
-
- RootSpecifier.LengthCb = sizeof(WDF_PROPERTY_STORE_ROOT);
- RootSpecifier.RootClass = WdfPropertyStoreRootClassHardwareKey;
- RootSpecifier.Qualifier.HardwareKey.ServiceName =
- WDF_PROPERTY_STORE_HARDWARE_KEY_ROOT;
-
- hr = pPropertyStoreFactory->RetrieveDevicePropertyStore(
- &RootSpecifier,
- WdfPropertyStoreNormal,
- KEY_QUERY_VALUE,
- NULL,
- &pHardwarePropertyStore,
- NULL
- );
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Failed to retrieve device hardware key root"
- );
- goto Exit;
- }
-
- hr = pHardwarePropertyStore->GetNamedValue(portName, &comPortPV);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Failed to read value %ws",
- portName
- );
- goto Exit;
- }
-
- //
- // Then we need to construct the COM port name
- //
- hr = StringCchLength(comPortPV.pwszVal,
- STRSAFE_MAX_CCH,
- &comPortSuffixCch);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Overflow while calculating COM port suffix length"
- );
- goto Exit;
- }
-
- hr = SizeTAdd(ARRAYSIZE(SYMBOLIC_LINK_NAME_PREFIX),
- comPortSuffixCch,
- &comPortFullNameCch);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Overflow while calculating symbolic link length"
- );
- goto Exit;
- }
-
- comPortFullName = (WCHAR*) new WCHAR[comPortFullNameCch];
-
- if (NULL == comPortFullName)
- {
- hr = E_OUTOFMEMORY;
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Unable to allocate memory for full port name"
- );
- goto Exit;
- }
-
- hr = StringCchPrintf(comPortFullName,
- comPortFullNameCch,
- L"%ws%ws",
- SYMBOLIC_LINK_NAME_PREFIX,
- comPortPV.pwszVal);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Cannot create full name for COM port"
- );
- goto Exit;
- }
-
- //
- // Finally we create the symbolic link
- //
- hr = m_FxDevice->CreateSymbolicLink(comPortFullName);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Cannot create symbolic link %ws",
- comPortFullName
- );
- goto Exit;
- }
-
- //
- // Write the com name to the legacy hardware key
- //
- hr = GetPdoName(&pdoName);
-
- if (FAILED(hr) || (pdoName == NULL))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Cannot retrieve PDO name"
- );
- goto Exit;
- }
-
- //
- // Write the name to the legacy hardware key
- //
- RootSpecifier.LengthCb = sizeof(WDF_PROPERTY_STORE_ROOT);
- RootSpecifier.RootClass = WdfPropertyStoreRootClassLegacyHardwareKey;
- RootSpecifier.Qualifier.LegacyHardwareKey.LegacyMapName = L"SERIALCOMM";
-
- hr = pPropertyStoreFactory->RetrieveDevicePropertyStore(
- &RootSpecifier,
- WdfPropertyStoreCreateVolatile,
- KEY_SET_VALUE,
- NULL,
- &pLegacyHardwarePropertyStore,
- NULL
- );
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Failed to retrieve device legacy hardware key"
- );
- goto Exit;
- }
-
- hr = pLegacyHardwarePropertyStore->SetNamedValue(pdoName,
- &comPortPV);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Failed to write device name to legacy hardware key"
- );
- goto Exit;
- }
-
- m_CreatedLegacyHardwareKey = TRUE;
- m_LegacyHardwarePropertyStore = pLegacyHardwarePropertyStore;
- m_PdoName = pdoName;
-
- //
- // Create and configure the queues
- //
- hr = CMyQueue::CreateInstance(this, m_FxDevice, &defaultQueue);
-
- if (FAILED(hr))
- {
- Trace(
- TRACE_LEVEL_ERROR,
- L"ERROR: Failed to create default queue"
- );
- goto Exit;
- }
-
- defaultQueue->Release();
-
-
-Exit:
-
- if (m_CreatedLegacyHardwareKey == FALSE)
- {
- //
- // If the legacy hardware key has been written, then the cleanup
- // will happen, when the device is unloaded
- //
- SAFE_RELEASE(pLegacyHardwarePropertyStore);
- if (pdoName != NULL)
- {
- delete[] pdoName;
- }
- }
-
- SAFE_RELEASE(pHardwarePropertyStore);
- SAFE_RELEASE(pPropertyStoreFactory);
-
- PropVariantClear(&comPortPV);
-
- if (comPortFullName != NULL)
- {
- delete[] comPortFullName;
- }
-
- return hr;
-}
-
-HRESULT
-CMyDevice::QueryInterface(
- _In_ REFIID InterfaceId,
- _Out_ PVOID *Object
- )
-/*++
-
- Routine Description:
-
- This method is called to get a pointer to one of the object's callback
- interfaces.
-
- Arguments:
-
- InterfaceId - the interface being requested
-
- Object - a location to store the interface pointer if successful
-
- Return Value:
-
- S_OK or E_NOINTERFACE
-
---*/
-{
- HRESULT hr;
-
- if(IsEqualIID(InterfaceId, __uuidof(IObjectCleanup)))
- {
- *Object = QueryIObjectCleanup();
- hr = S_OK;
- }
- else
- {
- hr = CUnknown::QueryInterface(InterfaceId, Object);
- }
-
- return hr;
-}
-
-VOID
-CMyDevice::OnCleanup(
- IWDFObject* pWdfObject
-)
-{
- UNREFERENCED_PARAMETER(pWdfObject);
-
- if ((m_CreatedLegacyHardwareKey == TRUE) &&
- (m_LegacyHardwarePropertyStore != NULL))
- {
- m_LegacyHardwarePropertyStore->DeleteNamedValue(m_PdoName);
- SAFE_RELEASE(m_LegacyHardwarePropertyStore);
- delete[] m_PdoName;
- }
-}
-
-HRESULT
-CMyDevice::GetPdoName(
- _Out_ LPWSTR *PdoName
- )
-{
- HRESULT hr = S_OK;
- WCHAR *devInstId = NULL;
- ULONG devInstIdLen;
- HDEVINFO hDevInfoSet = INVALID_HANDLE_VALUE;
- SP_DEVINFO_DATA devInfoData;
- WCHAR *pdoName = NULL;
- DWORD pdoNameCb = 0;
-
- WUDF_TEST_DRIVER_ASSERT(m_FxDevice);
-
- //
- // First let's get the device instance ID
- //
- devInstIdLen = 0;
- hr = m_FxDevice->RetrieveDeviceInstanceId(NULL, &devInstIdLen);
- if (SUCCEEDED(hr))
- {
- devInstId = (WCHAR*) new WCHAR[devInstIdLen];
- if (NULL == devInstId)
- {
- hr = E_OUTOFMEMORY;
- }
- }
- if (SUCCEEDED(hr))
- {
- hr = m_FxDevice->RetrieveDeviceInstanceId(devInstId, &devInstIdLen);
- }
-
- //
- // Now use the SetupDiXxx functions to get a handle to the device's
- // hardware key
- //
- if (SUCCEEDED(hr))
- {
- //
- // Create a new device information set
- //
- hDevInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
- if (INVALID_HANDLE_VALUE == hDevInfoSet)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
- }
-
- if (SUCCEEDED(hr))
- {
- //
- // Add our device to this device information set
- //
- ZeroMemory(&devInfoData, sizeof(devInfoData));
- devInfoData.cbSize = sizeof(devInfoData);
- if (!SetupDiOpenDeviceInfo(hDevInfoSet,
- devInstId,
- NULL,
- 0,
- &devInfoData))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
- }
-
- if (SUCCEEDED(hr))
- {
- //
- // Get the length of the PDO name
- //
- if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet,
- &devInfoData,
- SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
- NULL,
- (PBYTE)pdoName,
- 0,
- &pdoNameCb))
- {
- //
- // The only reason for this call is to get the length of the
- // buffer. The only non acceptable reason for failure is, if we
- // asked for invalid data.
- //
- if (GetLastError() == ERROR_INVALID_DATA)
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
- }
- }
-
- //
- // Get the PDO name
- //
- if (SUCCEEDED(hr))
- {
- pdoName = (WCHAR *)new BYTE[pdoNameCb];
-
- if (pdoName == NULL)
- {
- hr = E_OUTOFMEMORY;
- }
- }
-
- if (SUCCEEDED(hr))
- {
- if (!SetupDiGetDeviceRegistryProperty(hDevInfoSet,
- &devInfoData,
- SPDRP_PHYSICAL_DEVICE_OBJECT_NAME,
- NULL,
- (PBYTE)pdoName,
- pdoNameCb,
- NULL))
- {
- hr = HRESULT_FROM_WIN32(GetLastError());
- }
-
- }
-
- if (SUCCEEDED(hr))
- {
- *PdoName = pdoName;
- }
-
- //
- // clean up to be done regardless of success or failure
- //
- if (NULL != devInstId)
- {
- delete[] devInstId;
- }
-
- if (INVALID_HANDLE_VALUE != hDevInfoSet)
- {
- SetupDiDestroyDeviceInfoList(hDevInfoSet);
- }
-
- //
- // clean up to be done in case of failure only
- //
- if (FAILED(hr))
- {
- if (NULL != pdoName)
- {
- delete[] pdoName;
- pdoName = NULL;
- }
- }
-
- return hr;
-}