diff --git a/serial/VirtualSerial/ComPort/exports.def b/serial/VirtualSerial/ComPort/exports.def deleted file mode 100644 index 5d92ff036..000000000 --- a/serial/VirtualSerial/ComPort/exports.def +++ /dev/null @@ -1,6 +0,0 @@ -; exports.def : Declares the module parameters. - -LIBRARY "Virtualserial.DLL" - -EXPORTS - DllGetClassObject PRIVATE diff --git a/serial/VirtualSerial/ComPort/virtualserial.inx b/serial/VirtualSerial/ComPort/virtualserial.inx deleted file mode 100644 index d7c8f01c9..000000000 Binary files a/serial/VirtualSerial/ComPort/virtualserial.inx and /dev/null differ diff --git a/serial/VirtualSerial/ComPort/virtualserial.rc b/serial/VirtualSerial/ComPort/virtualserial.rc deleted file mode 100644 index eeda38a78..000000000 --- a/serial/VirtualSerial/ComPort/virtualserial.rc +++ /dev/null @@ -1,17 +0,0 @@ -//--------------------------------------------------------------------------- -// Virtualserial.rc -// -// Copyright (c) Microsoft Corporation, All Rights Reserved -//--------------------------------------------------------------------------- - - -#include -#include - -#define VER_FILETYPE VFT_DLL -#define VER_FILESUBTYPE VFT_UNKNOWN -#define VER_FILEDESCRIPTION_STR "WDF:UMDF VirtualSerial User-Mode Driver Sample" -#define VER_INTERNALNAME_STR "VirtualSerial" -#define VER_ORIGINALFILENAME_STR "Virtualserial.dll" - -#include "common.ver" diff --git a/serial/VirtualSerial/ComPort/virtualserial.vcxproj b/serial/VirtualSerial/ComPort/virtualserial.vcxproj deleted file mode 100644 index 4adeded9f..000000000 --- a/serial/VirtualSerial/ComPort/virtualserial.vcxproj +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184} - $(MSBuildProjectName) - 1 - Debug - Win32 - {A88B1CA4-202D-4915-94D1-94E8D74FCFF5} - - - - Windows10 - False - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - Windows10 - True - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - Windows10 - False - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - Windows10 - True - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - - $(IntDir) - - - - - - - - - - - - - - - - true - true - ..\internal.h - - - true - true - ..\internal.h - - - - virtualserial - - - virtualserial - - - virtualserial - - - virtualserial - - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_UNICODE;UNICODE - - - - 0x0A00 - 0x0A000000 - - - 0x0A00 - 0x0A000000 - - - 0x0A00 - 0x0A000000 - - - 0x0A00 - 0x0A000000 - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/serial/VirtualSerial/ComPort/virtualserial.vcxproj.Filters b/serial/VirtualSerial/ComPort/virtualserial.vcxproj.Filters deleted file mode 100644 index d8da803f8..000000000 --- a/serial/VirtualSerial/ComPort/virtualserial.vcxproj.Filters +++ /dev/null @@ -1,49 +0,0 @@ - - - - - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* - {FD27BABE-0C58-4B98-AF81-08289AA3B68B} - - - h;hpp;hxx;hm;inl;inc;xsd - {F310CB18-6DEC-47F7-8CA0-21A1439D1363} - - - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml - {52CDBF35-D541-4FFF-A0C5-8C8189885A23} - - - inf;inv;inx;mof;mc; - {51F65D19-3BDF-4759-9AD1-DDA85ACA2524} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/serial/VirtualSerial/FakeModem/exports.def b/serial/VirtualSerial/FakeModem/exports.def deleted file mode 100644 index 48845d0c1..000000000 --- a/serial/VirtualSerial/FakeModem/exports.def +++ /dev/null @@ -1,6 +0,0 @@ -; exports.def : Declares the module parameters. - -LIBRARY "FakeModem.DLL" - -EXPORTS - DllGetClassObject PRIVATE diff --git a/serial/VirtualSerial/FakeModem/fakemodem.inx b/serial/VirtualSerial/FakeModem/fakemodem.inx deleted file mode 100644 index 54cf099d1..000000000 Binary files a/serial/VirtualSerial/FakeModem/fakemodem.inx and /dev/null differ diff --git a/serial/VirtualSerial/FakeModem/fakemodem.rc b/serial/VirtualSerial/FakeModem/fakemodem.rc deleted file mode 100644 index 6bb6ed962..000000000 --- a/serial/VirtualSerial/FakeModem/fakemodem.rc +++ /dev/null @@ -1,17 +0,0 @@ -//--------------------------------------------------------------------------- -// FakeModem.rc -// -// Copyright (c) Microsoft Corporation, All Rights Reserved -//--------------------------------------------------------------------------- - - -#include -#include - -#define VER_FILETYPE VFT_DLL -#define VER_FILESUBTYPE VFT_UNKNOWN -#define VER_FILEDESCRIPTION_STR "WDF:UMDF Fake Modem User-Mode Driver Sample" -#define VER_INTERNALNAME_STR "FakeModem" -#define VER_ORIGINALFILENAME_STR "FakeModem.dll" - -#include "common.ver" diff --git a/serial/VirtualSerial/FakeModem/fakemodem.vcxproj b/serial/VirtualSerial/FakeModem/fakemodem.vcxproj deleted file mode 100644 index fb0caada4..000000000 --- a/serial/VirtualSerial/FakeModem/fakemodem.vcxproj +++ /dev/null @@ -1,250 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - Debug - x64 - - - Release - x64 - - - - {ACC7F2B5-F886-4169-84C0-32E44847E2B3} - $(MSBuildProjectName) - 1 - Debug - Win32 - {632318C9-FA2B-44A3-BB8C-3ADC5F2E2A86} - - - - Windows10 - False - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - Windows10 - True - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - Windows10 - False - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - Windows10 - True - Desktop - UMDF - WindowsUserModeDriver10.0 - DynamicLibrary - - - - $(IntDir) - - - - - - - - - - - - - - - - true - true - ..\internal.h - - - true - true - ..\internal.h - - - - fakemodem - - - fakemodem - - - fakemodem - - - fakemodem - - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - %(PreprocessorDefinitions);_FAKE_MODEM=1;_UNICODE;UNICODE - - - - 0x0A00 - 0x0A000000 - - - 0x0A00 - 0x0A000000 - - - 0x0A00 - 0x0A000000 - - - 0x0A00 - 0x0A000000 - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - _DllMainCRTStartup@12 - _DllMainCRTStartup - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - true - Level4 - - - - - %(AdditionalDependencies);$(SDK_LIB_PATH)\strsafe.lib;$(SDK_LIB_PATH)\ntdll.lib;$(SDK_LIB_PATH)\kernel32.lib;$(SDK_LIB_PATH)\advapi32.lib;$(SDK_LIB_PATH)\Ole32.lib;$(SDK_LIB_PATH)\setupapi.lib - exports.def - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/serial/VirtualSerial/FakeModem/fakemodem.vcxproj.Filters b/serial/VirtualSerial/FakeModem/fakemodem.vcxproj.Filters deleted file mode 100644 index 52ccc10a3..000000000 --- a/serial/VirtualSerial/FakeModem/fakemodem.vcxproj.Filters +++ /dev/null @@ -1,49 +0,0 @@ - - - - - cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;* - {1F2A9E59-0673-4608-95E9-CF60343773E6} - - - h;hpp;hxx;hm;inl;inc;xsd - {10F80ED7-1AD5-4B8B-B840-DE4146B936E1} - - - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml - {AA21B933-B73E-406C-AD32-1EC06E712F89} - - - inf;inv;inx;mof;mc; - {842CBD81-76BE-44AA-80B7-0BE49BE0DE56} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/serial/VirtualSerial/README.md b/serial/VirtualSerial/README.md deleted file mode 100644 index 3eeb97642..000000000 --- a/serial/VirtualSerial/README.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -page_type: sample -description: "Demonstrates a simple virtual serial driver (ComPort) and a controller-less modem driver (FakeModem)." -languages: -- cpp -products: -- windows -- windows-wdk ---- - -# Virtual serial driver sample - -This sample demonstrates these two serial drivers: - -- A simple virtual serial driver (ComPort) - -- A controller-less modem driver (FakeModem).This driver supports sending and receiving AT commands using the ReadFile and WriteFile calls or via a TAPI interface using an application such as, HyperTerminal. - -This sample driver is a minimal driver meant to demonstrate the usage of the User-Mode Driver Framework. It is not intended for use in a production environment. - -For more information, see the [Serial Controller Driver Design Guide](https://docs.microsoft.com/windows-hardware/drivers/serports/). - -## Code tour - -### comsup.cpp and comsup.h - -- COM Support code - specifically base classes which provide implementations for the standard COM interfaces **IUnknown** and **IClassFactory** which are used throughout the sample. - -- The implementation of **IClassFactory** is designed to create instances of the CMyDriver class. If you should change the name of your base driver class, you would also need to modify this file. - -### dllsup.cpp - -- DLL Support code - provides the DLL's entry point as well as the single required export (**DllGetClassObject**). - -- These depend on comsup.cpp to perform the necessary class creation. - -### exports.def - -- This file lists the functions that the driver DLL exports. - -### internal.h - -- This is the main header file for the sample driver. - -### driver.cpp and driver.h - -- Definition and implementation of the driver callback class (CMyDriver) for the sample. This includes **DriverEntry** and events on the framework driver object. - -### device.cpp and driver.h - -- Definition and implementation of the device callback class (CMyDriver) for the sample. This includes events on the framework device object. - -### queue.cpp and queue.h - -- Definition and implementation of the base queue callback class (CMyQueue). This includes events on the framework I/O queue object. - -### VirtualSerial.rc /FakeModem.rc - -- This file defines resource information for the sample driver. - -### VirtualSerial.inf / FakeModem.inf - -- INF file that contains installation information for this driver. diff --git a/serial/VirtualSerial/VirtualSerial.sln b/serial/VirtualSerial/VirtualSerial.sln deleted file mode 100644 index 8ca42edbd..000000000 --- a/serial/VirtualSerial/VirtualSerial.sln +++ /dev/null @@ -1,46 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0 -MinimumVisualStudioVersion = 12.0 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ComPort", "ComPort", "{56318356-CB41-44F9-9830-F051C326B8C2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FakeModem", "FakeModem", "{209B0D63-1DB3-4114-9531-FCBDE7CE1B5C}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "virtualserial", "ComPort\virtualserial.vcxproj", "{CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fakemodem", "FakeModem\fakemodem.vcxproj", "{ACC7F2B5-F886-4169-84C0-32E44847E2B3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Debug|Win32.ActiveCfg = Debug|Win32 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Debug|Win32.Build.0 = Debug|Win32 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Release|Win32.ActiveCfg = Release|Win32 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Release|Win32.Build.0 = Release|Win32 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Debug|x64.ActiveCfg = Debug|x64 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Debug|x64.Build.0 = Debug|x64 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Release|x64.ActiveCfg = Release|x64 - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184}.Release|x64.Build.0 = Release|x64 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Debug|Win32.ActiveCfg = Debug|Win32 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Debug|Win32.Build.0 = Debug|Win32 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Release|Win32.ActiveCfg = Release|Win32 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Release|Win32.Build.0 = Release|Win32 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Debug|x64.ActiveCfg = Debug|x64 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Debug|x64.Build.0 = Debug|x64 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Release|x64.ActiveCfg = Release|x64 - {ACC7F2B5-F886-4169-84C0-32E44847E2B3}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {CF30C8F0-084B-4E2D-A9C3-E76B4E9D0184} = {56318356-CB41-44F9-9830-F051C326B8C2} - {ACC7F2B5-F886-4169-84C0-32E44847E2B3} = {209B0D63-1DB3-4114-9531-FCBDE7CE1B5C} - EndGlobalSection -EndGlobal diff --git a/serial/VirtualSerial/comsup.cpp b/serial/VirtualSerial/comsup.cpp deleted file mode 100644 index fd2984700..000000000 --- a/serial/VirtualSerial/comsup.cpp +++ /dev/null @@ -1,344 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved - -Module Name: - - ComSup.cpp - -Abstract: - - This module contains implementations for the functions and methods - used for providing COM support. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#include "internal.h" - -#include "comsup.tmh" - -// -// Implementation of CUnknown methods. -// - -CUnknown::CUnknown( - VOID - ) : m_ReferenceCount(1) -/*++ - - Routine Description: - - Constructor for an instance of the CUnknown class. This simply initializes - the reference count of the object to 1. The caller is expected to - call Release() if it wants to delete the object once it has been allocated. - - Arguments: - - None - - Return Value: - - None - ---*/ -{ - // do nothing. -} - -HRESULT -STDMETHODCALLTYPE -CUnknown::QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ) -/*++ - - Routine Description: - - This method provides the basic support for query interface on CUnknown. - If the interface requested is IUnknown it references the object and - returns an interface pointer. Otherwise it returns an error. - - Arguments: - - InterfaceId - the IID being requested - - Object - a location to store the interface pointer to return. - - Return Value: - - S_OK or E_NOINTERFACE - ---*/ -{ - if (IsEqualIID(InterfaceId, __uuidof(IUnknown))) - { - *Object = QueryIUnknown(); - return S_OK; - } - else - { - *Object = NULL; - return E_NOINTERFACE; - } -} - -IUnknown * -CUnknown::QueryIUnknown( - VOID - ) -/*++ - - Routine Description: - - This helper method references the object and returns a pointer to the - object's IUnknown interface. - - This allows other methods to convert a CUnknown pointer into an IUnknown - pointer without a typecast and without calling QueryInterface and dealing - with the return value. - - Arguments: - - None - - Return Value: - - A pointer to the object's IUnknown interface. - ---*/ -{ - AddRef(); - return static_cast(this); -} - -ULONG -STDMETHODCALLTYPE -CUnknown::AddRef( - VOID - ) -/*++ - - Routine Description: - - This method adds one to the object's reference count. - - Arguments: - - None - - Return Value: - - The new reference count. The caller should only use this for debugging - as the object's actual reference count can change while the caller - examines the return value. - ---*/ -{ - return InterlockedIncrement(&m_ReferenceCount); -} - -ULONG -STDMETHODCALLTYPE -CUnknown::Release( - VOID - ) -/*++ - - Routine Description: - - This method subtracts one to the object's reference count. If the count - goes to zero, this method deletes the object. - - Arguments: - - None - - Return Value: - - The new reference count. If the caller uses this value it should only be - to check for zero (i.e. this call caused or will cause deletion) or - non-zero (i.e. some other call may have caused deletion, but this one - didn't). - ---*/ -{ - ULONG count = InterlockedDecrement(&m_ReferenceCount); - - if (count == 0) - { - delete this; - } - return count; -} - -// -// Implementation of CClassFactory methods. -// - -// -// Define storage for the factory's static lock count variable. -// - -LONG CClassFactory::s_LockCount = 0; - -IClassFactory * -CClassFactory::QueryIClassFactory( - VOID - ) -/*++ - - Routine Description: - - This helper method references the object and returns a pointer to the - object's IClassFactory interface. - - This allows other methods to convert a CClassFactory pointer into an - IClassFactory pointer without a typecast and without dealing with the - return value QueryInterface. - - Arguments: - - None - - Return Value: - - A referenced pointer to the object's IClassFactory interface. - ---*/ -{ - AddRef(); - return static_cast(this); -} - -HRESULT -CClassFactory::QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ) -/*++ - - Routine Description: - - This method attempts to retrieve the requested interface from the object. - - If the interface is found then the reference count on that interface (and - thus the object itself) is incremented. - - Arguments: - - InterfaceId - the interface the caller is requesting. - - Object - a location to store the interface pointer. - - Return Value: - - S_OK or E_NOINTERFACE - ---*/ -{ - // - // This class only supports IClassFactory so check for that. - // - - if (IsEqualIID(InterfaceId, __uuidof(IClassFactory))) - { - *Object = QueryIClassFactory(); - return S_OK; - } - else - { - // - // See if the base class supports the interface. - // - - return CUnknown::QueryInterface(InterfaceId, Object); - } -} - -HRESULT -STDMETHODCALLTYPE -CClassFactory::CreateInstance( - _In_opt_ IUnknown * /* OuterObject */, - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ) -/*++ - - Routine Description: - - This COM method is the factory routine - it creates instances of the driver - callback class and returns the specified interface on them. - - Arguments: - - OuterObject - only used for aggregation, which our driver callback class - does not support. - - InterfaceId - the interface ID the caller would like to get from our - new object. - - Object - a location to store the referenced interface pointer to the new - object. - - Return Value: - - Status. - ---*/ -{ - HRESULT hr; - - PCMyDriver driver; - - *Object = NULL; - - hr = CMyDriver::CreateInstance(&driver); - - if (SUCCEEDED(hr)) - { - hr = driver->QueryInterface(InterfaceId, Object); - driver->Release(); - } - - return hr; -} - -HRESULT -STDMETHODCALLTYPE -CClassFactory::LockServer( - _In_ BOOL Lock - ) -/*++ - - Routine Description: - - This COM method can be used to keep the DLL in memory. However since the - driver's DllCanUnloadNow function always returns false, this has little - effect. Still it tracks the number of lock and unlock operations. - - Arguments: - - Lock - Whether the caller wants to lock or unlock the "server" - - Return Value: - - S_OK - ---*/ -{ - if (Lock) - { - InterlockedIncrement(&s_LockCount); - } - else - { - InterlockedDecrement(&s_LockCount); - } - return S_OK; -} - diff --git a/serial/VirtualSerial/comsup.h b/serial/VirtualSerial/comsup.h deleted file mode 100644 index a73938b6e..000000000 --- a/serial/VirtualSerial/comsup.h +++ /dev/null @@ -1,215 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved - -Module Name: - - ComSup.h - -Abstract: - - This module contains classes and functions use for providing COM support - code. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#pragma once - -// -// Forward type declarations. They are here rather than in internal.h as -// you only need them if you choose to use these support classes. -// - -typedef class CUnknown *PCUnknown; -typedef class CClassFactory *PCClassFactory; - -// -// Base class to implement IUnknown. You can choose to derive your COM -// classes from this class, or simply implement IUnknown in each of your -// classes. -// - -class CUnknown : public IUnknown -{ - -// -// Private data members and methods. These are only accessible by the methods -// of this class. -// -private: - - // - // The reference count for this object. Initialized to 1 in the - // constructor. - // - - LONG m_ReferenceCount; - -// -// Protected data members and methods. These are accessible by the subclasses -// but not by other classes. -// -protected: - - // - // The constructor and destructor are protected to ensure that only the - // subclasses of CUnknown can create and destroy instances. - // - - CUnknown( - VOID - ); - - // - // The destructor MUST be virtual. Since any instance of a CUnknown - // derived class should only be deleted from within CUnknown::Release, - // the destructor MUST be virtual or only CUnknown::~CUnknown will get - // invoked on deletion. - // - // If you see that your CMyDevice specific destructor is never being - // called, make sure you haven't deleted the virtual destructor here. - // - - virtual - ~CUnknown( - VOID - ) - { - // Do nothing - } - -// -// Public Methods. These are accessible by any class. -// -public: - - IUnknown * - QueryIUnknown( - VOID - ); - -// -// COM Methods. -// -public: - - // - // IUnknown methods - // - - virtual - ULONG - STDMETHODCALLTYPE - AddRef( - VOID - ); - - virtual - ULONG - STDMETHODCALLTYPE - Release( - VOID - ); - - virtual - HRESULT - STDMETHODCALLTYPE - QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ); -}; - -// -// Class factory support class. Create an instance of this from your -// DllGetClassObject method and modify the implementation to create -// an instance of your driver event handler class. -// - -class CClassFactory : public CUnknown, public IClassFactory -{ -// -// Private data members and methods. These are only accessible by the methods -// of this class. -// -private: - - // - // The lock count. This is shared across all instances of IClassFactory - // and can be queried through the public IsLocked method. - // - - static LONG s_LockCount; - -// -// Public Methods. These are accessible by any class. -// -public: - - IClassFactory * - QueryIClassFactory( - VOID - ); - -// -// COM Methods. -// -public: - - // - // IUnknown methods - // - - virtual - ULONG - STDMETHODCALLTYPE - AddRef( - VOID - ) - { - return __super::AddRef(); - } - - _At_(this, __drv_freesMem(object)) - virtual - ULONG - STDMETHODCALLTYPE - Release( - VOID - ) - { - return __super::Release(); - } - - virtual - HRESULT - STDMETHODCALLTYPE - QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ); - - // - // IClassFactory methods. - // - - virtual - HRESULT - STDMETHODCALLTYPE - CreateInstance( - _In_opt_ IUnknown *OuterObject, - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ); - - virtual - HRESULT - STDMETHODCALLTYPE - LockServer( - _In_ BOOL Lock - ); -}; diff --git a/serial/VirtualSerial/device.cpp b/serial/VirtualSerial/device.cpp deleted file mode 100644 index 11d477751..000000000 --- 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; -} diff --git a/serial/VirtualSerial/device.h b/serial/VirtualSerial/device.h deleted file mode 100644 index 1fc54aeb0..000000000 --- a/serial/VirtualSerial/device.h +++ /dev/null @@ -1,261 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved - -Module Name: - - Device.h - -Abstract: - - This module contains the type definitions for the UMDF VirtualSerial sample - driver's device callback class. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#pragma once -#include "initguid.h" -#include "serial.h" - -DEFINE_GUID(GUID_DEVINTERFACE_MODEM, 0x2c7089aa, 0x2e0e, 0x11d1, 0xb1, 0x14, 0x00, 0xc0, 0x4f, 0xc2, 0xaa, 0xe4); -DEFINE_GUID(GUID_DEVINTERFACE_COMPORT, 0x86e0d1e0L, 0x8089, 0x11d0, 0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73); - -#define SYMBOLIC_LINK_NAME_PREFIX L"\\DosDevices\\Global\\" - -// -// Class for the VirtualSerial driver. -// - -class CMyDevice : - public CUnknown, - public IObjectCleanup -{ - -// -// Private data members. -// -private: - - IWDFDevice *m_FxDevice; - - // - // Baud rate - // - ULONG m_BaudRate; - - // - // Modem control register - // - ULONG m_MCR; - - // - // FIFO control register - // - ULONG m_FCR; - - // - // Line control register - // - ULONG m_LCR; - - // - // Valid data mask - // - UCHAR m_ValidDataMask; - - // - // Timeouts - // - SERIAL_TIMEOUTS m_Timeouts; - - // - // Legacy hardware key property store - // - BOOL m_CreatedLegacyHardwareKey; - - IWDFNamedPropertyStore2 * m_LegacyHardwarePropertyStore; - - PWCHAR m_PdoName; -// -// Private methods. -// - -private: - - CMyDevice( - VOID - ) : - m_FxDevice(NULL), - m_BaudRate(0), - m_MCR(0), - m_FCR(0), - m_LCR(0), - m_ValidDataMask(0), - m_CreatedLegacyHardwareKey(FALSE), - m_LegacyHardwarePropertyStore(NULL), - m_PdoName(NULL) - { - ZeroMemory(&m_Timeouts, sizeof(SERIAL_TIMEOUTS)); - } - - HRESULT - Initialize( - _In_ IWDFDriver *FxDriver, - _In_ IWDFDeviceInitialize *FxDeviceInit - ); - - HRESULT - CMyDevice::GetPdoName( - _Out_ LPWSTR *PdoName - ); -// -// Public methods -// -public: - - // - // The factory method used to create an instance of this driver. - // - - static - HRESULT - CreateInstance( - _In_ IWDFDriver *FxDriver, - _In_ IWDFDeviceInitialize *FxDeviceInit, - _Out_ PCMyDevice *Device - ); - - HRESULT - Configure( - VOID - ); - -// -// COM methods -// -public: - - // - // IUnknown methods. - // - - virtual - ULONG - STDMETHODCALLTYPE - AddRef( - VOID - ) - { - return __super::AddRef(); - } - - _At_(this, __drv_freesMem(object)) - virtual - ULONG - STDMETHODCALLTYPE - Release( - VOID - ) - { - return __super::Release(); - } - - virtual - HRESULT - STDMETHODCALLTYPE - QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ); - - // - // IObjectCleanup - // - IObjectCleanup * - QueryIObjectCleanup( - VOID - ) - { - AddRef(); - return static_cast(this); - } - - virtual - void - STDMETHODCALLTYPE - OnCleanup( - IWDFObject* pWdfObject - ); - - - ULONG - GetBaudRate( - VOID - ) - { - return m_BaudRate; - } - - void - SetBaudRate( - _In_ ULONG BaudRate - ) - { - m_BaudRate = BaudRate; - - return; - } - - ULONG * - GetModemControlRegisterPtr( - VOID - ) - { - return &m_MCR; - } - - ULONG * - GetFifoControlRegisterPtr( - VOID - ) - { - return &m_FCR; - } - - ULONG * - GetLineControlRegisterPtr( - VOID - ) - { - return &m_LCR; - } - - VOID - SetValidDataMask( - _In_ UCHAR Mask - ) - { - m_ValidDataMask = Mask; - } - - VOID - SetTimeouts( - _In_ SERIAL_TIMEOUTS Timeouts - ) - { - m_Timeouts = Timeouts; - } - - VOID - GetTimeouts( - _Out_ SERIAL_TIMEOUTS *Timeouts - ) - { - *Timeouts = m_Timeouts;; - } - -}; diff --git a/serial/VirtualSerial/dllsup.cpp b/serial/VirtualSerial/dllsup.cpp deleted file mode 100644 index 6c2540853..000000000 --- a/serial/VirtualSerial/dllsup.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved. - -Module Name: - - dllsup.cpp - -Abstract: - - This module contains the implementation of the UMDF VirtualSerial Sample - Driver's entry point and its exported functions for providing COM support. - - This module can be copied without modification to a new UMDF driver. It - depends on some of the code in comsup.cpp & comsup.h to handle DLL - registration and creating the first class factory. - - This module is dependent on the following defines: - - MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing - tracing. For example, VirtualSerial uses - L"Microsoft\\UMDF\\VirtualSerial" - - MYDRIVER_CLASS_ID - A GUID encoded in struct format used to - initialize the driver's ClassID. - - These are defined in internal.h for the sample. If you choose - to use a different primary include file, you should ensure they are - defined there as well. - -Environment: - - WDF User-Mode Driver Framework (WDF:UMDF) - ---*/ - -#include "internal.h" -#include "dllsup.tmh" - -const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID; - -BOOL -WINAPI -DllMain( - HINSTANCE ModuleHandle, - DWORD Reason, - PVOID /* Reserved */ - ) -/*++ - - Routine Description: - - This is the entry point and exit point for the I/O trace driver. This - does very little as the I/O trace driver has minimal global data. - - This method initializes tracing. - - Arguments: - - ModuleHandle - the DLL handle for this module. - - Reason - the reason this entry point was called. - - Reserved - unused - - Return Value: - - TRUE - ---*/ -{ - - UNREFERENCED_PARAMETER( ModuleHandle ); - - if (DLL_PROCESS_ATTACH == Reason) - { - // - // Initialize tracing. - // - - WPP_INIT_TRACING(MYDRIVER_TRACING_ID); - - } - else if (DLL_PROCESS_DETACH == Reason) - { - // - // Cleanup tracing. - // - - WPP_CLEANUP(); - } - - return TRUE; -} - -HRESULT -STDAPICALLTYPE -DllGetClassObject( - _In_ REFCLSID ClassId, - _In_ REFIID InterfaceId, - _Outptr_ LPVOID *Interface - ) -/*++ - - Routine Description: - - This routine is called by COM in order to instantiate the - driver callback object and do an initial query interface on it. - - This method only creates an instance of the driver's class factory, as this - is the minimum required to support UMDF. - - Arguments: - - ClassId - the CLSID of the object being "gotten" - - InterfaceId - the interface the caller wants from that object. - - Interface - a location to store the referenced interface pointer - - Return Value: - - S_OK if the function succeeds or error indicating the cause of the - failure. - ---*/ -{ - PCClassFactory factory; - - HRESULT hr = S_OK; - - *Interface = NULL; - - // - // If the CLSID doesn't match that of our "coclass" (defined in the IDL - // file) then we can't create the object the caller wants. This may - // indicate that the COM registration is incorrect, and another CLSID - // is referencing this drvier. - // - - if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false) - { - Trace( - TRACE_LEVEL_ERROR, - L"ERROR: Called to create instance of unrecognized class (%!GUID!)", - &ClassId - ); - - return CLASS_E_CLASSNOTAVAILABLE; - } - - // - // Create an instance of the class factory for the caller. - // - - factory = new CClassFactory(); - - if (NULL == factory) - { - hr = E_OUTOFMEMORY; - } - - // - // Query the object we created for the interface the caller wants. After - // that we release the object. This will drive the reference count to - // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed). - // In the later case the object is automatically deleted. - // - - if (SUCCEEDED(hr)) - { - hr = factory->QueryInterface(InterfaceId, Interface); - factory->Release(); - } - - return hr; -} diff --git a/serial/VirtualSerial/driver.cpp b/serial/VirtualSerial/driver.cpp deleted file mode 100644 index 0ec28ec5f..000000000 --- a/serial/VirtualSerial/driver.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved. - -Module Name: - - Driver.cpp - -Abstract: - - This module contains the implementation of the UMDF VirtualSerial Sample's - core driver callback object. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#include "internal.h" -#include "driver.tmh" - -HRESULT -CMyDriver::CreateInstance( - _Out_ PCMyDriver *Driver - ) -/*++ - - Routine Description: - - This static method is invoked in order to create and initialize a new - instance of the driver class. The caller should arrange for the object - to be released when it is no longer in use. - - Arguments: - - Driver - a location to store a referenced pointer to the new instance - - Return Value: - - S_OK if successful, or error otherwise. - ---*/ -{ - PCMyDriver driver; - HRESULT hr; - - // - // Allocate the callback object. - // - - driver = new CMyDriver(); - - if (NULL == driver) - { - return E_OUTOFMEMORY; - } - - // - // Initialize the callback object. - // - - hr = driver->Initialize(); - - if (SUCCEEDED(hr)) - { - // - // Store a pointer to the new, initialized object in the output - // parameter. - // - - *Driver = driver; - } - else - { - - // - // Release the reference on the driver object to get it to delete - // itself. - // - - driver->Release(); - } - - return hr; -} - -HRESULT -CMyDriver::Initialize( - VOID - ) -/*++ - - Routine Description: - - This method is called to initialize a newly created driver callback object - before it is returned to the creator. Unlike the constructor, the - Initialize method contains operations which could potentially fail. - - Arguments: - - None - - Return Value: - - None - ---*/ -{ - return S_OK; -} - -HRESULT -CMyDriver::QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Interface - ) -/*++ - - Routine Description: - - This method returns a pointer to the requested interface on the callback - object.. - - Arguments: - - InterfaceId - the IID of the interface to query/reference - - Interface - a location to store the interface pointer. - - Return Value: - - S_OK if the interface is supported. - E_NOINTERFACE if it is not supported. - ---*/ -{ - if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry))) - { - *Interface = QueryIDriverEntry(); - return S_OK; - } - else - { - return CUnknown::QueryInterface(InterfaceId, Interface); - } -} - -HRESULT -CMyDriver::OnDeviceAdd( - _In_ IWDFDriver *FxWdfDriver, - _In_ IWDFDeviceInitialize *FxDeviceInit - ) -/*++ - - Routine Description: - - The FX invokes this method when it wants to install our driver on a device - stack. This method creates a device callback object, then calls the Fx - to create an Fx device object and associate the new callback object with - it. - - Arguments: - - FxWdfDriver - the Fx driver object. - - FxDeviceInit - the initialization information for the device. - - Return Value: - - status - ---*/ -{ - HRESULT hr; - - PCMyDevice device = NULL; - - // - // TODO: Do any per-device initialization (reading settings from the - // registry for example) that's necessary before creating your - // device callback object here. Otherwise you can leave such - // initialization to the initialization of the device event - // handler. - // - - // - // Create a new instance of our device callback object - // - - hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device); - - // - // TODO: Change any per-device settings that the object exposes before - // calling Configure to let it complete its initialization. - // - - // - // If that succeeded then call the device's construct method. This - // allows the device to create any queues or other structures that it - // needs now that the corresponding fx device object has been created. - // - - if (SUCCEEDED(hr)) - { - hr = device->Configure(); - } - - // - // Release the reference on the device callback object now that it's been - // associated with an fx device object. - // - - if (NULL != device) - { - device->Release(); - } - - return hr; -} diff --git a/serial/VirtualSerial/driver.h b/serial/VirtualSerial/driver.h deleted file mode 100644 index 5be609b19..000000000 --- a/serial/VirtualSerial/driver.h +++ /dev/null @@ -1,149 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved - -Module Name: - - Driver.h - -Abstract: - - This module contains the type definitions for the UMDF VirtualSerial sample's - driver callback class. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#pragma once - -// -// This class handles driver events for the VirtualSerial sample. In particular -// it supports the OnDeviceAdd event, which occurs when the driver is called -// to setup per-device handlers for a new device stack. -// - -class CMyDriver : public CUnknown, public IDriverEntry -{ -// -// Private data members. -// -private: - -// -// Private methods. -// -private: - - // - // Returns a refernced pointer to the IDriverEntry interface. - // - - IDriverEntry * - QueryIDriverEntry( - VOID - ) - { - AddRef(); - return static_cast(this); - } - - HRESULT - Initialize( - VOID - ); - -// -// Public methods -// -public: - - // - // The factory method used to create an instance of this driver. - // - - static - HRESULT - CreateInstance( - _Out_ PCMyDriver *Driver - ); - -// -// COM methods -// -public: - - // - // IDriverEntry methods - // - - virtual - HRESULT - STDMETHODCALLTYPE - OnInitialize( - _In_ IWDFDriver *FxWdfDriver - ) - { - UNREFERENCED_PARAMETER( FxWdfDriver ); - - return S_OK; - } - - virtual - HRESULT - STDMETHODCALLTYPE - OnDeviceAdd( - _In_ IWDFDriver *FxWdfDriver, - _In_ IWDFDeviceInitialize *FxDeviceInit - ); - - virtual - VOID - STDMETHODCALLTYPE - OnDeinitialize( - _In_ IWDFDriver *FxWdfDriver - ) - { - UNREFERENCED_PARAMETER( FxWdfDriver ); - - return; - } - - // - // IUnknown methods. - // - // We have to implement basic ones here that redirect to the - // base class becuase of the multiple inheritance. - // - - virtual - ULONG - STDMETHODCALLTYPE - AddRef( - VOID - ) - { - return __super::AddRef(); - } - - _At_(this, __drv_freesMem(object)) - virtual - ULONG - STDMETHODCALLTYPE - Release( - VOID - ) - { - return __super::Release(); - } - - virtual - HRESULT - STDMETHODCALLTYPE - QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ); -}; diff --git a/serial/VirtualSerial/internal.h b/serial/VirtualSerial/internal.h deleted file mode 100644 index dd89de21c..000000000 --- a/serial/VirtualSerial/internal.h +++ /dev/null @@ -1,133 +0,0 @@ -/*++ - -Copyright (C) Microsoft Corporation, All Rights Reserved - -Module Name: - - Internal.h - -Abstract: - - This module contains the local type definitions for the UMDF VirtualSerial - driver sample. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -// -// Include the WUDF DDI -// - -#include "wudfddi.h" - -// -// Use specstrings for in/out annotation of function parameters. -// - -#include "specstrings.h" - -// -// Forward definitions of classes in the other header files. -// - -typedef class CMyDriver *PCMyDriver; -typedef class CMyDevice *PCMyDevice; -typedef class CMyQueue *PCMyQueue; -typedef class CRingBuffer *PCMyRingBuffer; - -// -// Define useful macros -// - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) -#endif - -#define SAFE_RELEASE(p) {if ((p)) { (p)->Release(); (p) = NULL; }} - -// -// Define the tracing flags. -// - -#define WPP_CONTROL_GUIDS \ - WPP_DEFINE_CONTROL_GUID( \ - MyDriverTraceControl, (C31877A2,C8C8,4c58,B5B8,7D6311D5E343), \ - \ - WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \ - ) - -#define WPP_FLAG_LEVEL_LOGGER(flag, level) \ - WPP_LEVEL_LOGGER(flag) - -#define WPP_FLAG_LEVEL_ENABLED(flag, level) \ - (WPP_LEVEL_ENABLED(flag) && \ - WPP_CONTROL(WPP_BIT_ ## flag).Level >= level) - -// -// This comment block is scanned by the trace preprocessor to define our -// Trace function. -// -// begin_wpp config -// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...); -// end_wpp -// - -// -// Driver specific #defines -// - -#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\VirtualSerial" -#define MYDRIVER_CLASS_ID { 0xc8ecc087, 0x6b79, 0x4de5, { 0x8f, 0xb4, 0xc0, 0x33, 0x58, 0xa2, 0x96, 0x17 } } - -__forceinline -#ifdef _PREFAST_ -__declspec(noreturn) -#endif -VOID -WdfTestNoReturn( - VOID - ) -{ - // do nothing. -} - -#define WUDF_TEST_DRIVER_ASSERT(p) \ -{ \ - if ( !(p) ) \ - { \ - DebugBreak(); \ - WdfTestNoReturn(); \ - } \ -} - -#define MAXULONG 0xffffffff - -// -// Device states -// -#define COMMAND_MATCH_STATE_IDLE 0 -#define COMMAND_MATCH_STATE_GOT_A 1 -#define COMMAND_MATCH_STATE_GOT_T 2 - -// -// Include the type specific headers. -// - -#include "comsup.h" -#include "driver.h" -#include "device.h" -#include "ringbuffer.h" -#include "queue.h" -#include "serial.h" diff --git a/serial/VirtualSerial/queue.cpp b/serial/VirtualSerial/queue.cpp deleted file mode 100644 index 5a7b5bad1..000000000 --- a/serial/VirtualSerial/queue.cpp +++ /dev/null @@ -1,1188 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation, All Rights Reserved - -Module Name: - - queue.cpp - -Abstract: - - This file implements the I/O queue interface and performs - the read/write/ioctl operations. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - - -#include "internal.h" - -// -// IUnknown implementation -// - -// -// Queue destructor. -// Free up the buffer, wait for thread to terminate and -// delete critical section. -// - - -CMyQueue::~CMyQueue( - VOID - ) -/*++ - -Routine Description: - - - IUnknown implementation of Release - -Arguments: - - -Return Value: - ---*/ -{ - WUDF_TEST_DRIVER_ASSERT(m_Device); - - m_Device->Release(); -} - - -// -// Initialize -HRESULT -CMyQueue::CreateInstance( - _In_ CMyDevice *pDevice, - _In_ IWDFDevice *FxDevice, - _Out_ PCMyQueue *Queue - ) -/*++ - -Routine Description: - - - CreateInstance creates an instance of the queue object. - -Arguments: - - ppUkwn - OUT parameter is an IUnknown interface to the queue object - -Return Value: - - HRESULT indicating success or failure - ---*/ -{ - CMyQueue *pMyQueue = new CMyQueue(pDevice); - HRESULT hr; - - if (pMyQueue == NULL) { - return E_OUTOFMEMORY; - } - - hr = pMyQueue->Initialize(FxDevice); - - if (SUCCEEDED(hr)) - { - *Queue = pMyQueue; - } - else - { - pMyQueue->Release(); - } - return hr; -} - -HRESULT -CMyQueue::Initialize( - _In_ IWDFDevice *FxDevice - ) -{ - IWDFIoQueue *fxQueue; - IUnknown *unknown = NULL; - HRESULT hr; - - // - // Initialize ring buffer - // - - hr = m_RingBuffer.Initialize(DATA_BUFFER_SIZE); - - if (FAILED(hr)) - { - goto Exit; - } - - unknown = QueryIUnknown(); - - // - // Create the default queue - // - - { - hr = FxDevice->CreateIoQueue(unknown, - TRUE, - WdfIoQueueDispatchParallel, - TRUE, - FALSE, - &fxQueue); - } - - if (FAILED(hr)) - { - goto Exit; - } - - m_FxQueue = fxQueue; - - fxQueue->Release(); - - // - // Create a manual queue to hold pending read requests. By keeping - // them in the queue, framework takes care of cancelling them if the app - // exits - // - - { - hr = FxDevice->CreateIoQueue(NULL, - FALSE, - WdfIoQueueDispatchManual, - TRUE, - FALSE, - &fxQueue); - } - - if (FAILED(hr)) - { - goto Exit; - } - - m_FxReadQueue = fxQueue; - - fxQueue->Release(); - - // - // Create a manual queue to hold pending ioctl wait-on-mask requests. - // - - { - hr = FxDevice->CreateIoQueue(NULL, - FALSE, - WdfIoQueueDispatchManual, - TRUE, - FALSE, - &fxQueue); - } - - if (FAILED(hr)) - { - goto Exit; - } - - m_FxWaitMaskQueue = fxQueue; - - fxQueue->Release(); - -Exit: - SAFE_RELEASE(unknown); - return hr; -} - -HRESULT -STDMETHODCALLTYPE -CMyQueue::QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ) -/*++ - -Routine Description: - - - Query Interface - -Arguments: - - Follows COM specifications - -Return Value: - - HRESULT indicating success or failure - ---*/ -{ - HRESULT hr; - - - if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackWrite))) { - *Object = QueryIQueueCallbackWrite(); - hr = S_OK; - } else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackRead))) { - *Object = QueryIQueueCallbackRead(); - hr = S_OK; - } else if (IsEqualIID(InterfaceId, __uuidof(IQueueCallbackDeviceIoControl))) { - *Object = QueryIQueueCallbackDeviceIoControl(); - hr = S_OK; - } else { - hr = CUnknown::QueryInterface(InterfaceId, Object); - } - - 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_WAIT_ON_MASK: - { - // - // NOTE: the contract is that this ioctl should be marked pending - // and not to be completed until some wait event happens. Therefore - // it is incorrect for the driver to complete the ioctl right away, - // no matter whether success or failure is returned. In either case - // most likely the app will send down another iocl of wait-on-mask - // in a tight loop, and that gets completed again, and again. - // The end result will be high CPU utilization in task manager. - // - // The correct way would be to mark the ioctl as pending, or as in - // WDF world, keep it in a manual queue. Since this is a driver for - // a virtual serial port and there is no actual hardware, there will - // be no wait event happening. The ioctl stays in the queue until - // the calling app decides to no longer wait for it by means of - // sending down a set-wait-mask request. - // - - // - // At most one pending wait-on-mask request is expected - // - IWDFIoRequest *pSavedRequest; - hr = m_FxWaitMaskQueue->RetrieveNextRequest(&pSavedRequest); - if (SUCCEEDED(hr)) - { - pSavedRequest->Complete(E_FAIL); - - // - // RetrieveNextRequest from a manual queue increments the reference - // counter by 1. We need to decrement it, otherwise the request will - // not be released and there will be an object leak. - // - SAFE_RELEASE(pSavedRequest); - } - - // - // Keep the request in a manual queue and the framework will take - // care of cancelling them when the app exits. - // - pWdfRequest->ForwardToIoQueue(m_FxWaitMaskQueue); - - // - // Instead of "break" out of the switch statement and complete the - // request at the end of this function, use "return" directly. - // - return; - } - case IOCTL_SERIAL_SET_WAIT_MASK: - { - // - // NOTE: the contract says a set-wait-mask will cause any pending - // wait-on-mask to complete with STATUS_SUCCESS and the output wait - // event mask is set to zero. This is also the way for app to break - // out of the loop of sending down wait-on-mask - // - - IWDFIoRequest *pSavedRequest; - hr = m_FxWaitMaskQueue->RetrieveNextRequest(&pSavedRequest); - if (SUCCEEDED(hr)) - { - pSavedRequest->GetOutputMemory(&outputMemory); - if (NULL == outputMemory) - { - hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); - } - - if (SUCCEEDED(hr)) - { - ULONG eventMask = 0; - - hr = outputMemory->CopyFromBuffer(0, - (void*) &eventMask, - sizeof(eventMask)); - - pSavedRequest->CompleteWithInformation(hr, sizeof(eventMask)); - } - else - { - pSavedRequest->Complete(hr); - } - - SAFE_RELEASE(pSavedRequest); - - // - // outputMemory will be released at the end of the function - // - } - - // - // NOTE: The application expects STATUS_SUCCESS for these IOCTLs. - // - hr = S_OK; - - break; - } - case IOCTL_SERIAL_SET_QUEUE_SIZE: - case IOCTL_SERIAL_SET_DTR: - 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; -} - -VOID -STDMETHODCALLTYPE -CMyQueue::OnWrite( - _In_ IWDFIoQueue *pWdfQueue, - _In_ IWDFIoRequest *pWdfRequest, - _In_ SIZE_T BytesToWrite - ) -/*++ - -Routine Description: - - - Write dispatch routine - IQueueCallbackWrite - -Arguments: - - pWdfQueue - Framework Queue instance - pWdfRequest - Framework Request instance - BytesToWrite - Length of bytes in the write buffer - - Allocate and copy data to local buffer -Return Value: - - VOID - ---*/ -{ - IWDFMemory* pRequestMemory = NULL; - IWDFIoRequest* pSavedRequest = NULL; - SIZE_T availableData = 0; - SIZE_T savedRequestBufferSize = 0; - HRESULT hr = S_OK; - - UNREFERENCED_PARAMETER(pWdfQueue); - - // - // Get memory object - // - - pWdfRequest->GetInputMemory(&pRequestMemory); - - // - // Process input - // - - ProcessWriteBytes((PUCHAR)pRequestMemory->GetDataBuffer(NULL), BytesToWrite); - - // - // Release memory object and complete request - // - SAFE_RELEASE(pRequestMemory); - pWdfRequest->CompleteWithInformation(hr, BytesToWrite); - - // - // Get the amount of data available in the ring buffer - // - m_RingBuffer.GetAvailableData(&availableData); - - if (availableData > 0) - { - // - // Continue with the next request, if there is one pending - // - hr = m_FxReadQueue->RetrieveNextRequest(&pSavedRequest); - if ((pSavedRequest == NULL) || (FAILED(hr))) - { - goto Exit; - } - - pSavedRequest->GetReadParameters(&savedRequestBufferSize, NULL, NULL); - - OnRead(m_FxQueue, - pSavedRequest, - savedRequestBufferSize); - - // - // RetrieveNextRequest from a manual queue increments the reference - // counter by 1. We need to decrement it, otherwise the request will - // not be released and there will be an object leak. - // - SAFE_RELEASE(pSavedRequest); - } - -Exit: - return; -} - -VOID -STDMETHODCALLTYPE -CMyQueue::OnRead( - _In_ IWDFIoQueue *pWdfQueue, - _In_ IWDFIoRequest *pWdfRequest, - _In_ SIZE_T SizeInBytes - ) -/*++ - -Routine Description: - - - Read dispatch routine - IQueueCallbackRead - -Arguments: - - pWdfQueue - Framework Queue instance - pWdfRequest - Framework Request instance - SizeInBytes - Length of bytes in the read buffer - - Copy available data into the read buffer -Return Value: - - VOID - ---*/ -{ - IWDFMemory* pRequestMemory = NULL; - SIZE_T BytesCopied = 0; - HRESULT hr; - - UNREFERENCED_PARAMETER(pWdfQueue); - - // - // Get memory object - // - pWdfRequest->GetOutputMemory(&pRequestMemory); - - hr = m_RingBuffer.Read((PBYTE)pRequestMemory->GetDataBuffer(NULL), - SizeInBytes, - &BytesCopied); - - // - // Release memory object. - // - SAFE_RELEASE(pRequestMemory); - - if (FAILED(hr)) - { - // - // Error reading buffer - // - pWdfRequest->Complete(hr); - goto Exit; - } - - if (BytesCopied > 0) - { - // - // Data was read from buffer succesfully - // - pWdfRequest->CompleteWithInformation(hr, BytesCopied); - } - else - { - // - // No data to read. Queue the request for later processing. - // - pWdfRequest->ForwardToIoQueue(m_FxReadQueue); - } - -Exit: - return; -} - -VOID -CMyQueue::ProcessWriteBytes( - _In_reads_bytes_(Length) PUCHAR Characters, - _In_ SIZE_T Length - ) -/*++ -Routine Description: - - This function is called when the framework receives IRP_MJ_WRITE - requests from the system. The write event handler(FmEvtIoWrite) calls ProcessWriteBytes. - It parses the Characters passed in and looks for the for sequences "AT" -ok , - "ATA" --CONNECT, ATD -- CONNECT and sets the state of the device appropriately. - These bytes are placed in the read Buffer to be processed later since this device - works in a loopback fashion. - - -Arguments: - - Characters - Pointer to the write IRP's system buffer. - - Length - Length of the IO operation - The default property of the queue is to not dispatch - zero lenght read & write requests to the driver and - complete is with status success. So we will never get - a zero length request. - -Return Value: - - VOID - ---*/ - -{ - - UCHAR currentCharacter; - UCHAR connectString[] = "\r\nCONNECT\r\n"; - UCHAR connectStringCch = ARRAY_SIZE(connectString) - 1; - UCHAR okString[] = "\r\nOK\r\n"; - UCHAR okStringCch = ARRAY_SIZE(okString) - 1; - - while (Length != 0) { - - currentCharacter = *(Characters++); - Length--; - - if(currentCharacter == '\0') - { - continue; - } - - m_RingBuffer.Write(¤tCharacter, sizeof(currentCharacter)); - - switch (m_CommandMatchState) { - case COMMAND_MATCH_STATE_IDLE: - if ((currentCharacter == 'a') || (currentCharacter == 'A')) - { - // - // got an A - // - m_CommandMatchState=COMMAND_MATCH_STATE_GOT_A; - m_ConnectCommand=FALSE; - m_IgnoreNextChar=FALSE; - } - - break; - - case COMMAND_MATCH_STATE_GOT_A: - if ((currentCharacter == 't') || (currentCharacter == 'T')) - { - // - // got a T - // - m_CommandMatchState=COMMAND_MATCH_STATE_GOT_T; - } - else - { - m_CommandMatchState=COMMAND_MATCH_STATE_IDLE; - } - - break; - - case COMMAND_MATCH_STATE_GOT_T: - - if (!m_IgnoreNextChar) - { - // - // the last char was not a special char - // check for CONNECT command - // - if ((currentCharacter == 'A') || (currentCharacter == 'a')) - { - - m_ConnectCommand=TRUE; - } - - if ((currentCharacter == 'D') || (currentCharacter == 'd')) - { - - m_ConnectCommand=TRUE; - } - } - - m_IgnoreNextChar=TRUE; - - if (currentCharacter == '\r') - { - // - // got a CR, send a response to the command - // - m_CommandMatchState = COMMAND_MATCH_STATE_IDLE; - - if (m_ConnectCommand) - { - // - // place CONNECT in the buffer - // - m_RingBuffer.Write(connectString, connectStringCch); - - // - // connected now raise CD - // - m_CurrentlyConnected = TRUE; - m_ConnectionStateChanged = TRUE; - - } - else - { - // - // place OK in the buffer - // - m_RingBuffer.Write(okString, okStringCch); - } - } - - break; - default: - break; - } - } - return; -} diff --git a/serial/VirtualSerial/queue.h b/serial/VirtualSerial/queue.h deleted file mode 100644 index 445ee48e4..000000000 --- a/serial/VirtualSerial/queue.h +++ /dev/null @@ -1,206 +0,0 @@ -/*++ - -Copyright (c) Microsoft Corporation, All Rights Reserved - -Module Name: - - queue.h - -Abstract: - - This file defines the queue callback interface. - -Environment: - - Windows User-Mode Driver Framework (WUDF) - ---*/ - -#pragma once - -#include "internal.h" - -// Set ring buffer size -#define DATA_BUFFER_SIZE 1024 - -// -// Macro definition for defining IOCTL and FSCTL function control codes. Note -// that function codes 0-2047 are reserved for Microsoft Corporation, and -// 2048-4095 are reserved for customers. -// - -#define CTL_CODE( DeviceType, Function, Method, Access ) ( \ - ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \ -) - - -// -// Queue Callback Object. -// - -class CMyQueue : - public IQueueCallbackDeviceIoControl, - public IQueueCallbackRead, - public IQueueCallbackWrite, - public CUnknown -{ - UCHAR m_CommandMatchState; // Device state - BOOL m_ConnectCommand; - BOOL m_IgnoreNextChar; - BOOL m_ConnectionStateChanged; - BOOL m_CurrentlyConnected; - - IWDFIoQueue *m_FxQueue; // Default parallel queue - IWDFIoQueue *m_FxReadQueue; // Manual queue for pending reads - IWDFIoQueue *m_FxWaitMaskQueue; // Manual queue for pending ioctl wait-on-mask - - CRingBuffer m_RingBuffer; // Ring buffer for pending data - - PCMyDevice m_Device; - - CMyQueue( - CMyDevice *pDevice - ) : - m_CommandMatchState(COMMAND_MATCH_STATE_IDLE), - m_ConnectCommand(FALSE), - m_IgnoreNextChar(FALSE), - m_ConnectionStateChanged(FALSE), - m_CurrentlyConnected(FALSE), - m_FxQueue(NULL), - m_FxReadQueue(NULL) - { - WUDF_TEST_DRIVER_ASSERT(pDevice); - - pDevice->AddRef(); - m_Device = pDevice; - } - - virtual ~CMyQueue(); - - HRESULT - Initialize( - _In_ IWDFDevice *FxDevice - ); - - VOID - CMyQueue::ProcessWriteBytes( - _In_reads_bytes_(Length) PUCHAR Characters, - _In_ SIZE_T Length - ); - -public: - - static - HRESULT - CreateInstance( - _In_ CMyDevice *pDevice, - _In_ IWDFDevice *FxDevice, - _Out_ PCMyQueue *Queue - ); - - HRESULT - Configure( - VOID - ) - { - return S_OK; - } - - - IQueueCallbackDeviceIoControl * - QueryIQueueCallbackDeviceIoControl( - VOID - ) - { - AddRef(); - return static_cast(this); - } - - IQueueCallbackRead * - QueryIQueueCallbackRead( - VOID - ) - { - AddRef(); - return static_cast(this); - } - - IQueueCallbackWrite * - QueryIQueueCallbackWrite( - VOID - ) - { - AddRef(); - return static_cast(this); - } - - // - // IUnknown - // - - virtual - ULONG - STDMETHODCALLTYPE - AddRef( - VOID - ) { - return CUnknown::AddRef(); - } - - _At_(this, __drv_freesMem(object)) - virtual - ULONG - STDMETHODCALLTYPE - Release( - VOID - ) { - return CUnknown::Release(); - } - - virtual - HRESULT - STDMETHODCALLTYPE - QueryInterface( - _In_ REFIID InterfaceId, - _Out_ PVOID *Object - ); - - // - // Wdf Callbacks - // - - // IQueueCallbackDeviceIoControl - // - virtual - VOID - STDMETHODCALLTYPE - OnDeviceIoControl( - _In_ IWDFIoQueue *pWdfQueue, - _In_ IWDFIoRequest *pWdfRequest, - _In_ ULONG ControlCode, - _In_ SIZE_T InputBufferSizeInBytes, - _In_ SIZE_T OutputBufferSizeInBytes - ); - - // IQueueCallbackWrite - // - virtual - VOID - STDMETHODCALLTYPE - OnWrite( - _In_ IWDFIoQueue *pWdfQueue, - _In_ IWDFIoRequest *pWdfRequest, - _In_ SIZE_T NumOfBytesToWrite - ); - - // IQueueCallbackRead - // - virtual - VOID - STDMETHODCALLTYPE - OnRead( - _In_ IWDFIoQueue *pWdfQueue, - _In_ IWDFIoRequest *pWdfRequest, - _In_ SIZE_T NumOfBytesToRead - ); -}; diff --git a/serial/VirtualSerial/ringbuffer.cpp b/serial/VirtualSerial/ringbuffer.cpp deleted file mode 100644 index fbbbd6b87..000000000 --- a/serial/VirtualSerial/ringbuffer.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include "internal.h" - -CRingBuffer::CRingBuffer( - VOID - ) : m_Size(0), - m_Base(NULL), - m_End(NULL), - m_Head(NULL), - m_Tail(NULL) -{ - return; -} - -CRingBuffer::~CRingBuffer( - VOID - ) -{ - if (m_Base) - { - delete[] m_Base; - } -} - -HRESULT -CRingBuffer::Initialize( - _In_ SIZE_T BufferSize - ) -{ - HRESULT hr = S_OK; - PBYTE buffer = NULL; - - if (0 == BufferSize) - { - hr = E_INVALIDARG; - } - - // - // Allocate the buffer. - // - if (SUCCEEDED(hr)) - { - buffer = new BYTE[BufferSize]; - if (buffer == NULL) - { - hr = E_OUTOFMEMORY; - } - } - - // - // Initialize the ring buffer pointers. - // - if (SUCCEEDED(hr)) - { - m_Size = BufferSize; - m_Base = buffer; - m_End = buffer + BufferSize; - m_Head = buffer; - m_Tail = buffer; - } - - if (FAILED(hr)) - { - if (buffer) - { - delete[] buffer; - m_Base = NULL; - } - } - - return hr; -} - -HRESULT -CRingBuffer::Write( - _In_reads_bytes_(DataSize) PBYTE Data, - _In_ SIZE_T DataSize - ) -{ - SIZE_T availableSpace; - SIZE_T bytesToCopy; - SIZE_T spaceFromCurrToEnd; - - WUDF_TEST_DRIVER_ASSERT(Data && (0 != DataSize)); - - if (m_Tail >= m_End) - { - return E_UNEXPECTED; - } - - // - // Get the amount of space available in the buffer - // - GetAvailableSpace(&availableSpace); - - // - // If there is not enough space to fit in all the data passed in by the - // caller then copy as much as possible and throw away the rest - // - if (availableSpace < DataSize) - { - bytesToCopy = availableSpace; - } - else - { - bytesToCopy = DataSize; - } - - if (bytesToCopy) - { - // - // The buffer has some space at least - // - if ((m_Tail+bytesToCopy) > m_End) - { - // - // The data being written will wrap around the end of the buffer. - // So the copy has to be done in two steps - - // * X bytes from current position to end of the buffer - // * the remaining (bytesToCopy - X) from the start of the buffer - // - - // - // The first step of the copy ... - // - spaceFromCurrToEnd = m_End - m_Tail; - CopyMemory(m_Tail, Data, spaceFromCurrToEnd); - Data += spaceFromCurrToEnd; - bytesToCopy -= spaceFromCurrToEnd; - - // - // The second step of the copy ... - // - CopyMemory(m_Base, Data, bytesToCopy); - - // - // Advance the tail pointer - // - m_Tail = m_Base + bytesToCopy; - } - else - { - // - // Data does NOT wrap around the end of the buffer. Just copy it - // over in a single step - // - CopyMemory(m_Tail, Data, bytesToCopy); - - // - // Advance the tail pointer - // - m_Tail += bytesToCopy; - if (m_Tail == m_End) - { - // - // We have exactly reached the end of the buffer. The next - // write should wrap around and start from the beginning. - // - m_Tail = m_Base; - } - } - - WUDF_TEST_DRIVER_ASSERT(m_Tail < m_End); - } - - return S_OK; -} - -HRESULT -CRingBuffer::Read( - _Out_writes_bytes_to_(DataSize, *BytesCopied) PBYTE Data, - _In_ SIZE_T DataSize, - _Out_ SIZE_T *BytesCopied - ) -{ - SIZE_T availableData; - SIZE_T dataFromCurrToEnd; - - WUDF_TEST_DRIVER_ASSERT(Data && (DataSize != 0)); - - if (m_Head >= m_End) - { - return E_UNEXPECTED; - } - - // - // Get the amount of data available in the buffer - // - GetAvailableData(&availableData); - - if (availableData == 0) - { - *BytesCopied = 0; - return S_OK; - } - - if (DataSize > availableData) - { - DataSize = availableData; - } - - *BytesCopied = DataSize; - - if ((m_Head + DataSize) > m_End) - { - // - // The data requested by the caller is wrapped around the end of the - // buffer. So we'll do the copy in two steps - - // * Copy X bytes from the current position to the end buffer into - // the caller's buffer - // * Copy (DataSize - X) bytes from the beginning to the buffer into - // the caller's buffer - // - - // - // The first step of the copy ... - // - dataFromCurrToEnd = m_End - m_Head; - CopyMemory(Data, m_Head, dataFromCurrToEnd); - Data += dataFromCurrToEnd; - DataSize -= dataFromCurrToEnd; - - // - // The second step of the copy ... - // - CopyMemory(Data, m_Base, DataSize); - - // - // Advance the head pointer - // - m_Head = m_Base + DataSize; - } - else - { - // - // The data in the buffer is NOT wrapped around the end of the buffer. - // Simply copy the data over to the caller's buffer in a single step. - // - CopyMemory(Data, m_Head, DataSize); - - // - // Advance the head pointer - // - m_Head += DataSize; - if (m_Head == m_End) - { - // - // We have exactly reached the end of the buffer. The next - // read should wrap around and start from the beginning. - // - m_Head = m_Base; - } - } - - WUDF_TEST_DRIVER_ASSERT(m_Head < m_End); - - return S_OK; -} - diff --git a/serial/VirtualSerial/ringbuffer.h b/serial/VirtualSerial/ringbuffer.h deleted file mode 100644 index 130055d9a..000000000 --- a/serial/VirtualSerial/ringbuffer.h +++ /dev/null @@ -1,223 +0,0 @@ -#pragma once - -#include "internal.h" - -class CRingBuffer -{ -private: - - // - // Private local variables. - // - - // - // The size in bytes of the ring buffer. - // - SIZE_T m_Size; - - // - // A pointer to the base of the ring buffer. - // - PBYTE m_Base; - - // - // A pointer to the byte beyond the end of the ring buffer. Used for - // quick comparisons when determining if we need to wrap. - // - PBYTE m_End; - - // - // A pointer to the current read point in the ring buffer. - // - // Updates to this are not protected by any lock. This is different from - // the write pointer, which is protected by the "pending read pointer" - // lock. The reason for this difference is that in this driver, we do not - // keep write requests pending. If there is not enough space to write all - // the data that was requested, we write as much as we can and drop the - // rest (lossy data transfer). - // - // If we had multiple threads modifying this pointer, then that would - // provide yet another reason for protecting updates to the pointer using a - // lock. However, in this driver, at any given time we have only one thread - // that modifies this pointer (the thread that runs the read callback). - // This is true because we use a sequential queue for read requests. If we - // were to change our read queue to be a parallel queue, this would no - // longer be true. - // - // - PBYTE m_Head; - - // - // A pointer to the current write point in the ring buffer. - // - // Updates to this pointer are protected by the "pending read pointer - // lock", because we do not want a consumer thread to mark a read request - // as pending while we are in the process of writing data to the buffer. - // The reason is that the write that we are currently performing might - // actually supply enough data to satisfy the read request, in which case - // it should not be marked pending at all. - // If the read request were to be marked pending in the situation described - // above, then we would need some trigger to later retrieve the request and - // complete it. In our driver, arrival of data is the only event that can - // trigger this. So if no more data arrives, the request will remain - // pending forever, even though there is enough data in the buffer to - // complete it. Hence we do not keep a read request pending in situations - // where the read buffer contains enough data to satisfy it. - // - // If we had multiple threads modifying this pointer, then that would - // provide yet another reason for protecting updates to the pointer using a - // lock. However, in this driver, at any given time we have only one thread - // that modifies this pointer (the thread that runs the write callback). - // This is true because we use a sequential queue for write requests. If we - // were to change our write queue to be a parallel queue, this would no - // longer be true. - // - PBYTE m_Tail; - -private: - - // - // Private Internal Methods. - // - void - GetAvailableSpace( - _Out_ SIZE_T *AvailableSpace - ) - { - WUDF_TEST_DRIVER_ASSERT(AvailableSpace); - - PBYTE headSnapshot = NULL; - PBYTE tailSnapshot = NULL; - PBYTE tailPlusOne = NULL; - - // - // Take a snapshot of the head and tail pointers. We will compute the - // available space based on this snapshot. This is safe to do in a - // single-producer, single-consumer model, because - - // * A producer will call GetAvailableSpace() to determine whether - // there is enough space to write the data it is trying to write. - // The only other thread that could modify the amount of space - // available is the consumer thread, which can only increase the - // amount of space available. Hence it is safe for the producer - // to write based on this snapshot. - // * A consumer thread will call GetAvailableSpace() to determine - // whether there is enough data in the buffer for it to read. - // (Available data = Buffer size - Available space). The only - // other thread that could modify the amount of space available - // is the producer thread, which can only decrease the amount of - // space available (thereby increasing the amount of data - // available. Hence it is safe for the consumer to read based on - // this snapshot. - // - headSnapshot = m_Head; - tailSnapshot = m_Tail; - - // - // In order to distinguish between a full buffer and an empty buffer, - // we always leave the last byte of the buffer unused. So, an empty - // buffer is denoted by - - // tail == head - // ... and a full buffer is denoted by - - // (tail+1) == head - // - tailPlusOne = ((tailSnapshot+1) == m_End) ? m_Base : (tailSnapshot+1); - - if (tailPlusOne == headSnapshot) - { - // - // Buffer full - // - *AvailableSpace = 0; - } - else if (tailSnapshot == headSnapshot) - { - // - // Buffer empty - // The -1 in the computation below is to account for the fact that - // we always leave the last byte of the ring buffer unused in order - // to distinguish between an empty buffer and a full buffer. - // - *AvailableSpace = m_Size - 1; - } - else - { - if (tailSnapshot > headSnapshot) - { - // - // Data has not wrapped around the end of the buffer - // The -1 in the computation below is to account for the fact - // that we always leave the last byte of the ring buffer unused - // in order to distinguish between an empty buffer and a full - // buffer. - // - *AvailableSpace = m_Size - (tailSnapshot - headSnapshot) - 1; - } - else - { - // - // Data has wrapped around the end of the buffer - // The -1 in the computation below is to account for the fact - // that we always leave the last byte of the ring buffer unused - // in order to distinguish between an empty buffer and a full - // buffer. - // - *AvailableSpace = (headSnapshot - tailSnapshot) - 1; - } - } - - return; - } - -public: - - // - // Public Internal methods. - // - - CRingBuffer( - VOID - ); - - ~CRingBuffer( - VOID - ); - - HRESULT - Initialize( - _In_ SIZE_T BufferSize - ); - - HRESULT - Write( - _In_reads_bytes_(DataSize) PBYTE Data, - _In_ SIZE_T DataSize - ); - - HRESULT - Read( - _Out_writes_bytes_to_(DataSize, *BytesCopied) PBYTE Data, - _In_ SIZE_T DataSize, - _Out_ SIZE_T *BytesCopied - ); - - void - GetAvailableData( - _Out_ SIZE_T *AvailableData - ) - { - SIZE_T availableSpace; - - WUDF_TEST_DRIVER_ASSERT(AvailableData); - - GetAvailableSpace(&availableSpace); - - // - // The -1 in the arithmetic below accounts for the fact that we always - // keep 1 byte of the ring buffer unused in order to distinguish - // between a full buffer and an empty buffer. - // - *AvailableData = m_Size - availableSpace - 1; - - return; - } -}; diff --git a/serial/VirtualSerial/serial.h b/serial/VirtualSerial/serial.h deleted file mode 100644 index 0ae911865..000000000 --- a/serial/VirtualSerial/serial.h +++ /dev/null @@ -1,48 +0,0 @@ -/*++ - -Module Name : - - serial.h - -Abstract: - - Type definitions and data for the serial port driver - -Author: - - ---*/ - -#pragma once - -#define SYMBOLIC_NAME_LENGTH 32 -#define SYMBOLIC_LINK_NAME_PREFIX L"\\DosDevices\\Global\\" - -// -// This defines the bit used to control whether the device is sending -// a break. When this bit is set the device is sending a space (logic 0). -// -// Most protocols will assume that this is a hangup. -// -#define SERIAL_LCR_BREAK 0x40 - -// -// These defines are used to set the line control register. -// -#define SERIAL_5_DATA ((UCHAR)0x00) -#define SERIAL_6_DATA ((UCHAR)0x01) -#define SERIAL_7_DATA ((UCHAR)0x02) -#define SERIAL_8_DATA ((UCHAR)0x03) -#define SERIAL_DATA_MASK ((UCHAR)0x03) - -#define SERIAL_1_STOP ((UCHAR)0x00) -#define SERIAL_1_5_STOP ((UCHAR)0x04) // Only valid for 5 data bits -#define SERIAL_2_STOP ((UCHAR)0x04) // Not valid for 5 data bits -#define SERIAL_STOP_MASK ((UCHAR)0x04) - -#define SERIAL_NONE_PARITY ((UCHAR)0x00) -#define SERIAL_ODD_PARITY ((UCHAR)0x08) -#define SERIAL_EVEN_PARITY ((UCHAR)0x18) -#define SERIAL_MARK_PARITY ((UCHAR)0x28) -#define SERIAL_SPACE_PARITY ((UCHAR)0x38) -#define SERIAL_PARITY_MASK ((UCHAR)0x38)