diff --git a/VirtualSerial2/ComPort/VirtualSerial2um.vcxproj b/VirtualSerial2/ComPort/VirtualSerial2um.vcxproj
deleted file mode 100644
index e733174..0000000
--- a/VirtualSerial2/ComPort/VirtualSerial2um.vcxproj
+++ /dev/null
@@ -1,187 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- {65A037CB-9245-442A-A791-5CFC34E97BF7}
- $(MSBuildProjectName)
- 2
- Debug
- Win32
- {D3E77C62-C6F0-4210-824E-1875C7B48EC5}
-
-
-
- Windows10
- False
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
- Windows10
- True
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
- Windows10
- False
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
- Windows10
- True
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
-
- $(IntDir)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- VirtualSerial2um
-
-
- VirtualSerial2um
-
-
- VirtualSerial2um
-
-
- VirtualSerial2um
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/VirtualSerial2/ComPort/VirtualSerial2um.vcxproj.Filters b/VirtualSerial2/ComPort/VirtualSerial2um.vcxproj.Filters
deleted file mode 100644
index 7025cdf..0000000
--- a/VirtualSerial2/ComPort/VirtualSerial2um.vcxproj.Filters
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*
- {75562F82-D2DC-4C96-8D1E-01C195D61A2C}
-
-
- h;hpp;hxx;hm;inl;inc;xsd
- {0748F304-5FE6-4C01-B27A-3CD7B1A268B7}
-
-
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml
- {87F14B94-F7A4-42E8-9931-8ADDA3989EBD}
-
-
- inf;inv;inx;mof;mc;
- {30F678DB-C12C-461E-8128-CE409AAC9C42}
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- Resource Files
-
-
-
\ No newline at end of file
diff --git a/VirtualSerial2/ComPort/virtualserial2um.inx b/VirtualSerial2/ComPort/virtualserial2um.inx
deleted file mode 100644
index 6d95d79..0000000
Binary files a/VirtualSerial2/ComPort/virtualserial2um.inx and /dev/null differ
diff --git a/VirtualSerial2/ComPort/virtualserial2um.rc b/VirtualSerial2/ComPort/virtualserial2um.rc
deleted file mode 100644
index f9f0a8d..0000000
--- a/VirtualSerial2/ComPort/virtualserial2um.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 v2 Driver Sample"
-#define VER_INTERNALNAME_STR "VirtualSerial2um"
-#define VER_ORIGINALFILENAME_STR "Virtualserial2um.dll"
-
-#include "common.ver"
diff --git a/VirtualSerial2/FakeModem/fakemodem2um.inx b/VirtualSerial2/FakeModem/fakemodem2um.inx
deleted file mode 100644
index 35bbc3c..0000000
Binary files a/VirtualSerial2/FakeModem/fakemodem2um.inx and /dev/null differ
diff --git a/VirtualSerial2/FakeModem/fakemodem2um.rc b/VirtualSerial2/FakeModem/fakemodem2um.rc
deleted file mode 100644
index 7d916be..0000000
--- a/VirtualSerial2/FakeModem/fakemodem2um.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 "FakeModem2um"
-#define VER_ORIGINALFILENAME_STR "FakeModem2um.dll"
-
-#include "common.ver"
diff --git a/VirtualSerial2/FakeModem/fakemodem2um.vcxproj b/VirtualSerial2/FakeModem/fakemodem2um.vcxproj
deleted file mode 100644
index cb21918..0000000
--- a/VirtualSerial2/FakeModem/fakemodem2um.vcxproj
+++ /dev/null
@@ -1,187 +0,0 @@
-
-
-
-
- Debug
- Win32
-
-
- Release
- Win32
-
-
- Debug
- x64
-
-
- Release
- x64
-
-
-
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}
- $(MSBuildProjectName)
- 2
- Debug
- Win32
- {3E00ED06-5DB5-444F-8FFA-D098A0218DF2}
-
-
-
- Windows10
- False
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
- Windows10
- True
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
- Windows10
- False
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
- Windows10
- True
- Universal
- UMDF
- WindowsUserModeDriver10.0
- DynamicLibrary
-
-
-
- $(IntDir)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- fakemodem2um
-
-
- fakemodem2um
-
-
- fakemodem2um
-
-
- fakemodem2um
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(PreprocessorDefinitions);_UNICODE;UNICODE;_FAKE_MODEM=1
- %(AdditionalIncludeDirectories);$(DDK_INC_PATH)\wdm;..\..\inc
-
-
- %(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/VirtualSerial2/FakeModem/fakemodem2um.vcxproj.Filters b/VirtualSerial2/FakeModem/fakemodem2um.vcxproj.Filters
deleted file mode 100644
index 4d54300..0000000
--- a/VirtualSerial2/FakeModem/fakemodem2um.vcxproj.Filters
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
- cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*
- {5A926099-4361-4BDC-BF0F-D98AD6F55C3A}
-
-
- h;hpp;hxx;hm;inl;inc;xsd
- {9C5FC831-BCE8-4E84-8BED-0B1182AA7358}
-
-
- rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml
- {43B83C13-0033-4A5E-A0DB-F0BA1B304FB0}
-
-
- inf;inv;inx;mof;mc;
- {83A3125A-7FA1-4416-B24A-FA9C1EECAAF0}
-
-
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
- Source Files
-
-
-
-
- Resource Files
-
-
-
\ No newline at end of file
diff --git a/VirtualSerial2/README.md b/VirtualSerial2/README.md
deleted file mode 100644
index 9c743dc..0000000
--- a/VirtualSerial2/README.md
+++ /dev/null
@@ -1,64 +0,0 @@
----
-page_type: sample
-urlFragment: virtual-serial-driver-sample-v2
-description: "Demonstrates UMDF version 2 serial drivers and includes a simple virtual serial driver (ComPort) and a controller-less modem driver (FakeModem)."
-languages:
-- cpp
-products:
-- windows
-- windows-wdk
----
-
-# Virtual serial driver sample (V2)
-
-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/VirtualSerial2/VirtualSerial.sln b/VirtualSerial2/VirtualSerial.sln
deleted file mode 100644
index 79d6c48..0000000
--- a/VirtualSerial2/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", "{F7F21610-DDE7-4709-9C48-68A0ABD1FF65}"
-EndProject
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FakeModem", "FakeModem", "{704FA9C6-88FA-4381-8FA5-3407E62FAF20}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VirtualSerial2um", "ComPort\VirtualSerial2um.vcxproj", "{65A037CB-9245-442A-A791-5CFC34E97BF7}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fakemodem2um", "FakeModem\fakemodem2um.vcxproj", "{CD78D78F-B132-4E6F-A11F-B62185A6152A}"
-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
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Debug|Win32.ActiveCfg = Debug|Win32
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Debug|Win32.Build.0 = Debug|Win32
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Release|Win32.ActiveCfg = Release|Win32
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Release|Win32.Build.0 = Release|Win32
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Debug|x64.ActiveCfg = Debug|x64
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Debug|x64.Build.0 = Debug|x64
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Release|x64.ActiveCfg = Release|x64
- {65A037CB-9245-442A-A791-5CFC34E97BF7}.Release|x64.Build.0 = Release|x64
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Debug|Win32.ActiveCfg = Debug|Win32
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Debug|Win32.Build.0 = Debug|Win32
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Release|Win32.ActiveCfg = Release|Win32
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Release|Win32.Build.0 = Release|Win32
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Debug|x64.ActiveCfg = Debug|x64
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Debug|x64.Build.0 = Debug|x64
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Release|x64.ActiveCfg = Release|x64
- {CD78D78F-B132-4E6F-A11F-B62185A6152A}.Release|x64.Build.0 = Release|x64
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {65A037CB-9245-442A-A791-5CFC34E97BF7} = {F7F21610-DDE7-4709-9C48-68A0ABD1FF65}
- {CD78D78F-B132-4E6F-A11F-B62185A6152A} = {704FA9C6-88FA-4381-8FA5-3407E62FAF20}
- EndGlobalSection
-EndGlobal
diff --git a/VirtualSerial2/device.c b/VirtualSerial2/device.c
deleted file mode 100644
index 82f9f9a..0000000
--- a/VirtualSerial2/device.c
+++ /dev/null
@@ -1,449 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved.
-
-Module Name:
-
- Device.c
-
-Abstract:
-
- This module contains the implementation of the 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 Driver Framework
-
---*/
-
-#include "internal.h"
-
-NTSTATUS
-DeviceCreate(
- _In_ WDFDRIVER Driver,
- _In_ PWDFDEVICE_INIT DeviceInit,
- _Out_ PDEVICE_CONTEXT *DeviceContext
- )
-/*++
-
- 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
-
---*/
-{
- NTSTATUS status;
- WDF_OBJECT_ATTRIBUTES deviceAttributes;
- WDFDEVICE device;
- PDEVICE_CONTEXT deviceContext;
- UNREFERENCED_PARAMETER (Driver);
-
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
- &deviceAttributes,
- DEVICE_CONTEXT);
-
- deviceAttributes.SynchronizationScope = WdfSynchronizationScopeDevice;
- deviceAttributes.EvtCleanupCallback = EvtDeviceCleanup;
-
- status = WdfDeviceCreate(&DeviceInit,
- &deviceAttributes,
- &device);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfDeviceCreate failed 0x%x", status);
- return status;
- }
-
- deviceContext = GetDeviceContext(device);
- deviceContext->Device = device;
-
- *DeviceContext = deviceContext;
-
- return status;
-}
-
-
-NTSTATUS
-DeviceConfigure(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-/*++
-
- 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
-
---*/
-{
- NTSTATUS status;
- WDFDEVICE device = DeviceContext->Device;
- WDFKEY key;
- LPGUID guid;
- errno_t errorNo;
-
- DECLARE_CONST_UNICODE_STRING(portName, REG_VALUENAME_PORTNAME);
- DECLARE_UNICODE_STRING_SIZE (comPort, 10);
- DECLARE_UNICODE_STRING_SIZE (symbolicLinkName, SYMBOLIC_LINK_NAME_LENGTH);
-
-#ifdef _FAKE_MODEM
- //
- // Compiled as fake modem
- //
- guid = (LPGUID) &GUID_DEVINTERFACE_MODEM;
-#else
- //
- // Compiled as virtual serial port
- //
- guid = (LPGUID) &GUID_DEVINTERFACE_COMPORT;
-#endif
-
- //
- // Create device interface
- //
- status = WdfDeviceCreateDeviceInterface(
- device,
- guid,
- NULL);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Cannot create device interface");
- goto Exit;
- }
-
- //
- // Read the COM port number from the registry, which has been automatically
- // created by "MsPorts!PortsClassInstaller" if INF file says "Class=Ports"
- //
- status = WdfDeviceOpenRegistryKey(
- device,
- PLUGPLAY_REGKEY_DEVICE,
- KEY_QUERY_VALUE,
- WDF_NO_OBJECT_ATTRIBUTES,
- &key);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to retrieve device hardware key root");
- goto Exit;
- }
-
- status = WdfRegistryQueryUnicodeString(
- key,
- &portName,
- NULL,
- &comPort);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to read PortName");
- goto Exit;
- }
-
- //
- // Manually create the symbolic link name. Length is the length in
- // bytes not including the NULL terminator.
- //
- // 6054 and 26035 are code analysis warnings that comPort.Buffer might
- // not be NULL terminated, while we know that they are.
- //
- #pragma warning(suppress: 6054 26035)
- symbolicLinkName.Length = (USHORT)((wcslen(comPort.Buffer) * sizeof(wchar_t))
- + sizeof(SYMBOLIC_LINK_NAME_PREFIX) - sizeof(UNICODE_NULL));
-
- if (symbolicLinkName.Length >= symbolicLinkName.MaximumLength) {
-
- Trace(TRACE_LEVEL_ERROR, "Error: Buffer overflow when creating COM port name. Size"
- " is %d, buffer length is %d", symbolicLinkName.Length, symbolicLinkName.MaximumLength);
- status = STATUS_BUFFER_OVERFLOW;
- goto Exit;
- }
-
- errorNo = wcscpy_s(symbolicLinkName.Buffer,
- SYMBOLIC_LINK_NAME_LENGTH,
- SYMBOLIC_LINK_NAME_PREFIX);
-
- if (errorNo != 0) {
- Trace(TRACE_LEVEL_ERROR,
- "Failed to copy %ws to buffer with error %d",
- SYMBOLIC_LINK_NAME_PREFIX, errorNo);
- status = STATUS_INVALID_PARAMETER;
- goto Exit;
- }
-
- errorNo = wcscat_s(symbolicLinkName.Buffer,
- SYMBOLIC_LINK_NAME_LENGTH,
- comPort.Buffer);
-
- if (errorNo != 0) {
- Trace(TRACE_LEVEL_ERROR,
- "Failed to copy %ws to buffer with error %d",
- comPort.Buffer, errorNo);
- status = STATUS_INVALID_PARAMETER;
- goto Exit;
- }
-
- //
- // Create symbolic link
- //
- status = WdfDeviceCreateSymbolicLink(
- device,
- &symbolicLinkName);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Cannot create symbolic link %ws", symbolicLinkName.Buffer);
- goto Exit;
- }
-
- status = DeviceGetPdoName(DeviceContext);
- if (!NT_SUCCESS(status)) {
- goto Exit;
- }
-
- status = DeviceWriteLegacyHardwareKey(
- DeviceContext->PdoName,
- comPort.Buffer,
- DeviceContext->Device);
- if (NT_SUCCESS(status)) {
- DeviceContext->CreatedLegacyHardwareKey = TRUE;
- }
-
- status = QueueCreate(DeviceContext);
- if (!NT_SUCCESS(status)) {
- goto Exit;
- }
-
-Exit:
- return status;
-}
-
-
-NTSTATUS
-DeviceGetPdoName(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-{
- NTSTATUS status;
- WDFDEVICE device = DeviceContext->Device;
- WDF_OBJECT_ATTRIBUTES attributes;
- WDFMEMORY memory;
-
- WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
- attributes.ParentObject = device;
-
- status = WdfDeviceAllocAndQueryProperty(
- device,
- DevicePropertyPhysicalDeviceObjectName,
- NonPagedPoolNx,
- &attributes,
- &memory);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to query PDO name");
- goto Exit;
- }
-
- DeviceContext->PdoName = (PWCHAR) WdfMemoryGetBuffer(memory, NULL);
- Trace(TRACE_LEVEL_ERROR,
- "PDO Name is %ws", DeviceContext->PdoName);
-
-Exit:
- return status;
-}
-
-
-NTSTATUS
-DeviceWriteLegacyHardwareKey(
- _In_ PWSTR PdoName,
- _In_ PWSTR ComPort,
- _In_ WDFDEVICE Device
- )
-{
- WDFKEY key = NULL;
- NTSTATUS status;
- UNICODE_STRING pdoString = {0};
- UNICODE_STRING comPort = {0};
-
- DECLARE_CONST_UNICODE_STRING(deviceSubkey, SERIAL_DEVICE_MAP);
-
- RtlInitUnicodeString(&pdoString, PdoName);
- RtlInitUnicodeString(&comPort, ComPort);
-
- status = WdfDeviceOpenDevicemapKey(Device,
- &deviceSubkey,
- KEY_SET_VALUE,
- WDF_NO_OBJECT_ATTRIBUTES,
- &key);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to open DEVICEMAP\\SERIALCOMM key 0x%x", status);
- goto exit;
- }
-
- status = WdfRegistryAssignUnicodeString(key,
- &pdoString,
- &comPort);
-
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to write to DEVICEMAP\\SERIALCOMM key 0x%x", status);
- goto exit;
- }
-
-exit:
-
- if (key != NULL) {
- WdfRegistryClose(key);
- key = NULL;
- }
-
- return status;
-}
-
-
-VOID
-EvtDeviceCleanup(
- _In_ WDFOBJECT Object
- )
-{
- WDFDEVICE device = (WDFDEVICE) Object;
- PDEVICE_CONTEXT deviceContext = GetDeviceContext(device);
- NTSTATUS status;
- WDFKEY key = NULL;
- UNICODE_STRING pdoString = {0};
-
- DECLARE_CONST_UNICODE_STRING(deviceSubkey, SERIAL_DEVICE_MAP);
-
- if (deviceContext->CreatedLegacyHardwareKey == TRUE) {
-
- RtlInitUnicodeString(&pdoString, deviceContext->PdoName);
-
- status = WdfDeviceOpenDevicemapKey(device,
- &deviceSubkey,
- KEY_SET_VALUE,
- WDF_NO_OBJECT_ATTRIBUTES,
- &key);
-
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to open DEVICEMAP\\SERIALCOMM key 0x%x", status);
- goto exit;
- }
-
- status = WdfRegistryRemoveValue(key,
- &pdoString);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to delete %S key, 0x%x", pdoString.Buffer, status);
- goto exit;
- }
-
- status = WdfRegistryRemoveKey(key);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: Failed to delete %S, 0x%x", SERIAL_DEVICE_MAP, status);
- goto exit;
- }
- }
-
-exit:
-
- if (key != NULL) {
- WdfRegistryClose(key);
- key = NULL;
- }
-
- return;
-}
-
-
-ULONG
-GetBaudRate(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-{
- return DeviceContext->BaudRate;
-}
-
-VOID
-SetBaudRate(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _In_ ULONG BaudRate
- )
-{
- DeviceContext->BaudRate = BaudRate;
-}
-
-ULONG *
-GetModemControlRegisterPtr(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-{
- return &DeviceContext->ModemControlRegister;
-}
-
-ULONG *
-GetFifoControlRegisterPtr(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-{
- return &DeviceContext->FifoControlRegister;
-}
-
-ULONG *
-GetLineControlRegisterPtr(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-{
- return &DeviceContext->LineControlRegister;
-}
-
-VOID
-SetValidDataMask(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _In_ UCHAR Mask
- )
-{
- DeviceContext->ValidDataMask = Mask;
-}
-
-VOID
-SetTimeouts(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _In_ SERIAL_TIMEOUTS Timeouts
- )
-{
- DeviceContext->Timeouts = Timeouts;
-}
-
-VOID
-GetTimeouts(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _Out_ SERIAL_TIMEOUTS *Timeouts
- )
-{
- *Timeouts = DeviceContext->Timeouts;
-}
diff --git a/VirtualSerial2/device.h b/VirtualSerial2/device.h
deleted file mode 100644
index e271884..0000000
--- a/VirtualSerial2/device.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- Device.h
-
-Abstract:
-
- This module contains the type definitions for the VirtualSerial sample
- driver's device callback class.
-
-Environment:
-
- Windows Driver Framework
-
---*/
-
-#pragma once
-
-#define SYMBOLIC_LINK_NAME_LENGTH 32
-#define SYMBOLIC_LINK_NAME_PREFIX L"\\DosDevices\\Global\\"
-#define REG_PATH_DEVICEMAP L"HARDWARE\\DEVICEMAP"
-#define SERIAL_DEVICE_MAP L"SERIALCOMM"
-#define REG_VALUENAME_PORTNAME L"PortName"
-#define REG_PATH_SERIALCOMM REG_PATH_DEVICEMAP L"\\" SERIAL_DEVICE_MAP
-
-typedef struct _DEVICE_CONTEXT
-{
- WDFDEVICE Device;
-
- ULONG BaudRate;
-
- ULONG ModemControlRegister;
-
- ULONG FifoControlRegister;
-
- ULONG LineControlRegister;
-
- UCHAR ValidDataMask;
-
- SERIAL_TIMEOUTS Timeouts;
-
- BOOLEAN CreatedLegacyHardwareKey;
-
- PWSTR PdoName;
-
-} DEVICE_CONTEXT, *PDEVICE_CONTEXT;
-
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext);
-
-
-NTSTATUS
-DeviceCreate(
- _In_ WDFDRIVER Driver,
- _In_ PWDFDEVICE_INIT DeviceInit,
- _Out_ PDEVICE_CONTEXT *DeviceContext
- );
-
-NTSTATUS
-DeviceConfigure(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-NTSTATUS
-DeviceGetPdoName(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-NTSTATUS
-DeviceWriteLegacyHardwareKey(
- _In_ PWSTR PdoName,
- _In_ PWSTR ComPort,
- _In_ WDFDEVICE Device
- );
-
-EVT_WDF_DEVICE_CONTEXT_CLEANUP EvtDeviceCleanup;
-
-ULONG
-GetBaudRate(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-VOID
-SetBaudRate(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _In_ ULONG BaudRate
- );
-
-ULONG *
-GetModemControlRegisterPtr(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-ULONG *
-GetFifoControlRegisterPtr(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-ULONG *
-GetLineControlRegisterPtr(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-VOID
-SetValidDataMask(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _In_ UCHAR Mask
- );
-
-VOID
-SetTimeouts(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _In_ SERIAL_TIMEOUTS Timeouts
- );
-
-VOID
-GetTimeouts(
- _In_ PDEVICE_CONTEXT DeviceContext,
- _Out_ SERIAL_TIMEOUTS *Timeouts
- );
\ No newline at end of file
diff --git a/VirtualSerial2/driver.c b/VirtualSerial2/driver.c
deleted file mode 100644
index bb7f4c7..0000000
--- a/VirtualSerial2/driver.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved.
-
-Module Name:
-
- Driver.c
-
-Abstract:
-
- This module contains the implementation of the VirtualSerial Sample's
- core driver callback object.
-
-Environment:
-
- Windows Driver Framework
-
---*/
-
-#include
-#include "internal.h"
-
-NTSTATUS
-DriverEntry(
- _In_ PDRIVER_OBJECT DriverObject,
- _In_ PUNICODE_STRING RegistryPath
- )
-{
- NTSTATUS status;
- WDF_DRIVER_CONFIG driverConfig;
-
- WDF_DRIVER_CONFIG_INIT(&driverConfig,
- EvtDeviceAdd);
-
- status = WdfDriverCreate(DriverObject,
- RegistryPath,
- WDF_NO_OBJECT_ATTRIBUTES,
- &driverConfig,
- WDF_NO_HANDLE);
- if (!NT_SUCCESS(status)) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfDriverCreate failed 0x%x", status);
- return status;
- }
-
- return status;
-}
-
-NTSTATUS
-EvtDeviceAdd(
- _In_ WDFDRIVER Driver,
- _Inout_ PWDFDEVICE_INIT DeviceInit
- )
-{
- NTSTATUS status;
- PDEVICE_CONTEXT deviceContext;
-
- status = DeviceCreate(Driver,
- DeviceInit,
- &deviceContext);
- if (!NT_SUCCESS(status)) {
- return status;
- }
-
- status = DeviceConfigure(deviceContext);
- if (!NT_SUCCESS(status)) {
- return status;
- }
-
- return status;
-}
-
diff --git a/VirtualSerial2/driver.h b/VirtualSerial2/driver.h
deleted file mode 100644
index 787cef0..0000000
--- a/VirtualSerial2/driver.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- Driver.h
-
-Abstract:
-
- This module contains the type definitions for the VirtualSerial sample's
- driver callback class.
-
-Environment:
-
- Windows Driver Framework
-
---*/
-
-#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.
-//
-
-DRIVER_INITIALIZE DriverEntry;
-
-EVT_WDF_DRIVER_DEVICE_ADD EvtDeviceAdd;
diff --git a/VirtualSerial2/internal.h b/VirtualSerial2/internal.h
deleted file mode 100644
index 82c149e..0000000
--- a/VirtualSerial2/internal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- Internal.h
-
-Abstract:
-
- This module contains the local type definitions for the VirtualSerial
- driver sample.
-
-Environment:
-
- Windows Driver Framework
-
---*/
-
-#pragma once
-
-#ifdef _KERNEL_MODE
-#include
-#else
-#include
-#endif
-
-#include
-
-#define _NTDEF_
-
-//
-// Include the type specific headers.
-//
-#include "serial.h"
-#include "driver.h"
-#include "device.h"
-#include "ringbuffer.h"
-#include "queue.h"
-
-//
-// Tracing and Assert
-//
-
-#define Trace(level, _fmt_, ...) \
- DbgPrintEx(DPFLTR_DEFAULT_ID, level, \
- _fmt_ "\n", __VA_ARGS__)
-
-#define TRACE_LEVEL_ERROR DPFLTR_ERROR_LEVEL
-#define TRACE_LEVEL_INFO DPFLTR_INFO_LEVEL
-
-#ifndef ASSERT
-#define ASSERT(exp) { \
- if (!(exp)) { \
- RtlAssert(#exp, __FILE__, __LINE__, NULL); \
- } \
-}
-#endif
\ No newline at end of file
diff --git a/VirtualSerial2/queue.c b/VirtualSerial2/queue.c
deleted file mode 100644
index 80571b4..0000000
--- a/VirtualSerial2/queue.c
+++ /dev/null
@@ -1,963 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- Queue.c
-
-Abstract:
-
- This file implements the I/O queue interface and performs
- the read/write/ioctl operations.
-
-Environment:
-
- Windows Driver Framework
-
---*/
-
-
-#include "internal.h"
-
-NTSTATUS
-QueueCreate(
- _In_ PDEVICE_CONTEXT DeviceContext
- )
-{
- NTSTATUS status;
- WDFDEVICE device = DeviceContext->Device;
- WDF_IO_QUEUE_CONFIG queueConfig;
- WDF_OBJECT_ATTRIBUTES queueAttributes;
- WDFQUEUE queue;
- PQUEUE_CONTEXT queueContext;
-
- //
- // Create the default queue
- //
-
- WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(
- &queueConfig,
- WdfIoQueueDispatchParallel);
-
- queueConfig.EvtIoRead = EvtIoRead;
- queueConfig.EvtIoWrite = EvtIoWrite;
- queueConfig.EvtIoDeviceControl = EvtIoDeviceControl;
-
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(
- &queueAttributes,
- QUEUE_CONTEXT);
-
- status = WdfIoQueueCreate(
- device,
- &queueConfig,
- &queueAttributes,
- &queue);
-
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfIoQueueCreate failed 0x%x", status);
- return status;
- }
-
- queueContext = GetQueueContext(queue);
- queueContext->Queue = queue;
- queueContext->DeviceContext = DeviceContext;
-
- //
- // 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
- //
-
- WDF_IO_QUEUE_CONFIG_INIT(
- &queueConfig,
- WdfIoQueueDispatchManual);
-
- status = WdfIoQueueCreate(
- device,
- &queueConfig,
- WDF_NO_OBJECT_ATTRIBUTES,
- &queue);
-
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfIoQueueCreate manual queue failed 0x%x", status);
- return status;
- }
-
- queueContext->ReadQueue = queue;
-
- //
- // Create another manual queue to hold pending IOCTL_SERIAL_WAIT_ON_MASK
- //
-
- WDF_IO_QUEUE_CONFIG_INIT(
- &queueConfig,
- WdfIoQueueDispatchManual);
-
- status = WdfIoQueueCreate(
- device,
- &queueConfig,
- WDF_NO_OBJECT_ATTRIBUTES,
- &queue);
-
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfIoQueueCreate manual queue failed 0x%x", status);
- return status;
- }
-
- queueContext->WaitMaskQueue = queue;
-
- RingBufferInitialize(&queueContext->RingBuffer,
- queueContext->Buffer,
- sizeof(queueContext->Buffer));
-
- return status;
-}
-
-
-NTSTATUS
-RequestCopyFromBuffer(
- _In_ WDFREQUEST Request,
- _In_ PVOID SourceBuffer,
- _In_ size_t NumBytesToCopyFrom
- )
-{
- NTSTATUS status;
- WDFMEMORY memory;
-
- status = WdfRequestRetrieveOutputMemory(Request, &memory);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestRetrieveOutputMemory failed 0x%x", status);
- return status;
- }
-
- status = WdfMemoryCopyFromBuffer(memory, 0,
- SourceBuffer, NumBytesToCopyFrom);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfMemoryCopyFromBuffer failed 0x%x", status);
- return status;
- }
-
- WdfRequestSetInformation(Request, NumBytesToCopyFrom);
- return status;
-}
-
-
-NTSTATUS
-RequestCopyToBuffer(
- _In_ WDFREQUEST Request,
- _In_ PVOID DestinationBuffer,
- _In_ size_t NumBytesToCopyTo
- )
-{
- NTSTATUS status;
- WDFMEMORY memory;
-
- status = WdfRequestRetrieveInputMemory(Request, &memory);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestRetrieveInputMemory failed 0x%x", status);
- return status;
- }
-
- status = WdfMemoryCopyToBuffer(memory, 0,
- DestinationBuffer, NumBytesToCopyTo);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfMemoryCopyToBuffer failed 0x%x", status);
- return status;
- }
-
- WdfRequestSetInformation(Request, NumBytesToCopyTo);
- return status;
-}
-
-
-VOID
-EvtIoDeviceControl(
- _In_ WDFQUEUE Queue,
- _In_ WDFREQUEST Request,
- _In_ size_t OutputBufferLength,
- _In_ size_t InputBufferLength,
- _In_ ULONG IoControlCode
- )
-{
- NTSTATUS status;
- PQUEUE_CONTEXT queueContext = GetQueueContext(Queue);
- PDEVICE_CONTEXT deviceContext = queueContext->DeviceContext;
- UNREFERENCED_PARAMETER (OutputBufferLength);
- UNREFERENCED_PARAMETER (InputBufferLength);
-
- Trace(TRACE_LEVEL_INFO,
- "EvtIoDeviceControl 0x%x", IoControlCode);
-
- switch (IoControlCode)
- {
-
- 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};
-
- status = RequestCopyToBuffer(Request,
- &baudRateBuffer,
- sizeof(baudRateBuffer));
-
- if( NT_SUCCESS(status) ) {
- SetBaudRate(deviceContext, baudRateBuffer.BaudRate);
- };
- break;
- }
-
- case IOCTL_SERIAL_GET_BAUD_RATE:
- {
- SERIAL_BAUD_RATE baudRateBuffer = {0};
-
- baudRateBuffer.BaudRate = GetBaudRate(deviceContext);
-
- status = RequestCopyFromBuffer(Request,
- &baudRateBuffer,
- sizeof(baudRateBuffer));
- 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 *modemControlRegister = GetModemControlRegisterPtr(deviceContext);
-
- ASSERT(modemControlRegister);
-
- status = RequestCopyToBuffer(Request,
- modemControlRegister,
- sizeof(ULONG));
- break;
- }
-
- case IOCTL_SERIAL_GET_MODEM_CONTROL:
- {
- ULONG *modemControlRegister = GetModemControlRegisterPtr(deviceContext);
-
- ASSERT(modemControlRegister);
-
- status = RequestCopyFromBuffer(Request,
- modemControlRegister,
- 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 *fifoControlRegister = GetFifoControlRegisterPtr(deviceContext);
-
- ASSERT(fifoControlRegister);
-
- status = RequestCopyToBuffer(Request,
- fifoControlRegister,
- sizeof(ULONG));
- break;
- }
-
- case IOCTL_SERIAL_GET_LINE_CONTROL:
- {
- status = QueueProcessGetLineControl(
- queueContext,
- Request);
- break;
- }
-
-
- case IOCTL_SERIAL_SET_LINE_CONTROL:
- {
- status = QueueProcessSetLineControl(
- queueContext,
- Request);
- break;
- }
-
- case IOCTL_SERIAL_GET_TIMEOUTS:
- {
- SERIAL_TIMEOUTS timeoutValues = {0};
-
- status = RequestCopyFromBuffer(Request,
- (void*) &timeoutValues,
- sizeof(timeoutValues));
- break;
- }
-
- case IOCTL_SERIAL_SET_TIMEOUTS:
- {
- SERIAL_TIMEOUTS timeoutValues = {0};
-
- status = RequestCopyToBuffer(Request,
- (void*) &timeoutValues,
- sizeof(timeoutValues));
-
- if( NT_SUCCESS(status) )
- {
- if ((timeoutValues.ReadIntervalTimeout == MAXULONG) &&
- (timeoutValues.ReadTotalTimeoutMultiplier == MAXULONG) &&
- (timeoutValues.ReadTotalTimeoutConstant == MAXULONG))
- {
- status = STATUS_INVALID_PARAMETER;
- }
- }
-
- if( NT_SUCCESS(status) ) {
- SetTimeouts(deviceContext, timeoutValues);
- }
-
- break;
- }
-
- case IOCTL_SERIAL_WAIT_ON_MASK:
- {
- //
- // NOTE: A wait-on-mask request should not be completed until either:
- // 1) A wait event occurs; or
- // 2) A set-wait-mask request is received
- //
- // This is a driver for a virtual serial port. Since there is no
- // actual hardware, we complete the request with some failure code.
- //
- WDFREQUEST savedRequest;
-
- status = WdfIoQueueRetrieveNextRequest(
- queueContext->WaitMaskQueue,
- &savedRequest);
-
- if (NT_SUCCESS(status)) {
- WdfRequestComplete(savedRequest,
- STATUS_UNSUCCESSFUL);
- }
-
- //
- // Keep the request in a manual queue and the framework will take
- // care of cancelling them when the app exits
- //
- status = WdfRequestForwardToIoQueue(
- Request,
- queueContext->WaitMaskQueue);
-
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestForwardToIoQueue failed 0x%x", status);
- WdfRequestComplete(Request, status);
- }
-
- //
- // Instead of "break", use "return" to prevent the current request
- // from being completed.
- //
- return;
- }
-
- case IOCTL_SERIAL_SET_WAIT_MASK:
- {
- //
- // NOTE: If a wait-on-mask request is already pending when set-wait-mask
- // request is processed, the pending wait-on-event request is completed
- // with STATUS_SUCCESS and the output wait event mask is set to zero.
- //
- WDFREQUEST savedRequest;
-
- status = WdfIoQueueRetrieveNextRequest(
- queueContext->WaitMaskQueue,
- &savedRequest);
-
- if (NT_SUCCESS(status)) {
-
- ULONG eventMask = 0;
- status = RequestCopyFromBuffer(
- savedRequest,
- &eventMask,
- sizeof(eventMask));
-
- WdfRequestComplete(savedRequest, status);
- }
-
- //
- // NOTE: The application expects STATUS_SUCCESS for these IOCTLs.
- //
- status = STATUS_SUCCESS;
- 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.
- //
- status = STATUS_SUCCESS;
- break;
-
- default:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
-
- //
- // complete the request
- //
- WdfRequestComplete(Request, status);
-}
-
-
-VOID
-EvtIoWrite(
- _In_ WDFQUEUE Queue,
- _In_ WDFREQUEST Request,
- _In_ size_t Length
- )
-{
- NTSTATUS status;
- PQUEUE_CONTEXT queueContext = GetQueueContext(Queue);
- WDFMEMORY memory;
- WDFREQUEST savedRequest;
- size_t availableData = 0;
-
- Trace(TRACE_LEVEL_INFO,
- "EvtIoWrite 0x%p", Request);
-
- status = WdfRequestRetrieveInputMemory(Request, &memory);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestRetrieveInputMemory failed 0x%x", status);
- return;
- }
-
- //
- // Process input
- //
- status = QueueProcessWriteBytes(
- queueContext,
- (PUCHAR)WdfMemoryGetBuffer(memory, NULL),
- Length);
- if( !NT_SUCCESS(status) ) {
- return;
- }
-
- WdfRequestCompleteWithInformation(Request, status, Length);
-
- //
- // Get the amount of data available in the ring buffer
- //
- RingBufferGetAvailableData(
- &queueContext->RingBuffer,
- &availableData);
-
- if (availableData == 0) {
- return;
- }
-
- //
- // Continue with the next request, if there is one pending
- //
- for ( ; ; ) {
-
- status = WdfIoQueueRetrieveNextRequest(
- queueContext->ReadQueue,
- &savedRequest);
-
- if (!NT_SUCCESS(status)) {
- break;
- }
-
- status = WdfRequestForwardToIoQueue(
- savedRequest,
- Queue);
-
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestForwardToIoQueue failed 0x%x", status);
- WdfRequestComplete(savedRequest, status);
- }
- }
-}
-
-
-VOID
-EvtIoRead(
- _In_ WDFQUEUE Queue,
- _In_ WDFREQUEST Request,
- _In_ size_t Length
- )
-{
- NTSTATUS status;
- PQUEUE_CONTEXT queueContext = GetQueueContext(Queue);
- WDFMEMORY memory;
- size_t bytesCopied = 0;
-
- Trace(TRACE_LEVEL_INFO,
- "EvtIoRead 0x%p", Request);
-
- status = WdfRequestRetrieveOutputMemory(Request, &memory);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestRetrieveOutputMemory failed 0x%x", status);
- WdfRequestComplete(Request, status);
- return;
- }
-
- status = RingBufferRead(&queueContext->RingBuffer,
- (BYTE*)WdfMemoryGetBuffer(memory, NULL),
- Length,
- &bytesCopied);
- if( !NT_SUCCESS(status) ) {
- WdfRequestComplete(Request, status);
- return;
- }
-
- if (bytesCopied > 0) {
- //
- // Data was read from buffer succesfully
- //
- WdfRequestCompleteWithInformation(Request, status, bytesCopied);
- return;
- }
- else {
- //
- // No data to read. Queue the request for later processing.
- //
- status = WdfRequestForwardToIoQueue(Request,
- queueContext->ReadQueue);
- if( !NT_SUCCESS(status) ) {
- Trace(TRACE_LEVEL_ERROR,
- "Error: WdfRequestForwardToIoQueue failed 0x%x", status);
- WdfRequestComplete(Request, status);
- }
- }
-}
-
-
-NTSTATUS
-QueueProcessWriteBytes(
- _In_ PQUEUE_CONTEXT QueueContext,
- _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.
---*/
-{
- NTSTATUS status = STATUS_SUCCESS;
- 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;
- }
-
- status = RingBufferWrite(&QueueContext->RingBuffer,
- ¤tCharacter,
- sizeof(currentCharacter));
- if( !NT_SUCCESS(status) ) {
- return status;
- }
-
- switch (QueueContext->CommandMatchState) {
-
- case COMMAND_MATCH_STATE_IDLE:
-
- if ((currentCharacter == 'a') || (currentCharacter == 'A')) {
- //
- // got an A
- //
- QueueContext->CommandMatchState = COMMAND_MATCH_STATE_GOT_A;
- QueueContext->ConnectCommand = FALSE;
- QueueContext->IgnoreNextChar = FALSE;
- }
- break;
-
- case COMMAND_MATCH_STATE_GOT_A:
-
- if ((currentCharacter == 't') || (currentCharacter == 'T')) {
- //
- // got a T
- //
- QueueContext->CommandMatchState = COMMAND_MATCH_STATE_GOT_T;
- }
- else {
- QueueContext->CommandMatchState = COMMAND_MATCH_STATE_IDLE;
- }
-
- break;
-
- case COMMAND_MATCH_STATE_GOT_T:
-
- if (! QueueContext->IgnoreNextChar) {
- //
- // the last char was not a special char
- // check for CONNECT command
- //
- if ((currentCharacter == 'A') || (currentCharacter == 'a')) {
- QueueContext->ConnectCommand = TRUE;
- }
-
- if ((currentCharacter == 'D') || (currentCharacter == 'd')) {
- QueueContext->ConnectCommand = TRUE;
- }
- }
-
- QueueContext->IgnoreNextChar = TRUE;
-
- if (currentCharacter == '\r') {
- //
- // got a CR, send a response to the command
- //
- QueueContext->CommandMatchState = COMMAND_MATCH_STATE_IDLE;
-
- if (QueueContext->ConnectCommand) {
- //
- // place CONNECT in the buffer
- //
- status = RingBufferWrite(&QueueContext->RingBuffer,
- connectString,
- connectStringCch);
- if( !NT_SUCCESS(status) ) {
- return status;
- }
- //
- // connected now raise CD
- //
- QueueContext->CurrentlyConnected = TRUE;
- QueueContext->ConnectionStateChanged = TRUE;
- }
- else {
- //
- // place OK in the buffer
- //
- status = RingBufferWrite(&QueueContext->RingBuffer,
- okString,
- okStringCch);
- if( !NT_SUCCESS(status) ) {
- return status;
- }
- }
- }
- break;
-
- default:
- break;
- }
- }
- return status;
-}
-
-
-NTSTATUS
-QueueProcessGetLineControl(
- _In_ PQUEUE_CONTEXT QueueContext,
- _In_ WDFREQUEST Request
- )
-{
- NTSTATUS status;
- PDEVICE_CONTEXT deviceContext;
- SERIAL_LINE_CONTROL lineControl = {0};
- ULONG lineControlSnapshot;
- ULONG *lineControlRegister;
-
- deviceContext = QueueContext->DeviceContext;
- lineControlRegister = GetLineControlRegisterPtr(deviceContext);
-
- ASSERT(lineControlRegister);
-
- //
- // Take a snapshot of the line control register variable
- //
- lineControlSnapshot = *lineControlRegister;
-
- //
- // 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
- //
- status = RequestCopyFromBuffer(Request,
- (void*) &lineControl,
- sizeof(lineControl));
- return status;
-}
-
-
-NTSTATUS
-QueueProcessSetLineControl(
- _In_ PQUEUE_CONTEXT QueueContext,
- _In_ WDFREQUEST Request
- )
-{
- NTSTATUS status;
- PDEVICE_CONTEXT deviceContext;
- SERIAL_LINE_CONTROL lineControl = {0};
- ULONG *lineControlRegister;
- UCHAR lineControlData = 0;
- UCHAR lineControlStop = 0;
- UCHAR lineControlParity = 0;
- ULONG lineControlSnapshot;
- ULONG lineControlNew;
- ULONG lineControlPrevious;
- ULONG i;
-
- deviceContext = QueueContext->DeviceContext;
- lineControlRegister = GetLineControlRegisterPtr(deviceContext);
-
- ASSERT(lineControlRegister);
-
- //
- // 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.
- //
- status = RequestCopyToBuffer(Request,
- (void*) &lineControl,
- sizeof(lineControl));
-
- //
- // Bits 0 and 1 of the line control register
- //
- if( NT_SUCCESS(status) )
- {
- switch (lineControl.WordLength)
- {
- case 5:
- lineControlData = SERIAL_5_DATA;
- SetValidDataMask(deviceContext, 0x1f);
- break;
-
- case 6:
- lineControlData = SERIAL_6_DATA;
- SetValidDataMask(deviceContext, 0x3f);
- break;
-
- case 7:
- lineControlData = SERIAL_7_DATA;
- SetValidDataMask(deviceContext, 0x7f);
- break;
-
- case 8:
- lineControlData = SERIAL_8_DATA;
- SetValidDataMask(deviceContext, 0xff);
- break;
-
- default:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
-
- //
- // Bit 2 of the line control register
- //
- if( NT_SUCCESS(status) )
- {
- switch (lineControl.StopBits)
- {
- case STOP_BIT_1:
- lineControlStop = SERIAL_1_STOP;
- break;
-
- case STOP_BITS_1_5:
- if (lineControlData != SERIAL_5_DATA)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- lineControlStop = SERIAL_1_5_STOP;
- break;
-
- case STOP_BITS_2:
- if (lineControlData == SERIAL_5_DATA)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- lineControlStop = SERIAL_2_STOP;
- break;
-
- default:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
-
- //
- // Bits 3, 4 and 5 of the line control register
- //
- if( NT_SUCCESS(status) )
- {
- 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:
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- }
-
- //
- // 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.
- //
-#ifdef _KERNEL_MODE
- LARGE_INTEGER interval;
- interval.QuadPart = 0;
- KeDelayExecutionThread(UserMode, FALSE, &interval);
-#else
- SwitchToThread();
-#endif
- }
-
- lineControlSnapshot = *lineControlRegister;
-
- lineControlNew = (lineControlSnapshot & SERIAL_LCR_BREAK) |
- (lineControlData | lineControlParity | lineControlStop);
-
- lineControlPrevious = InterlockedCompareExchange(
- (LONG *) lineControlRegister,
- lineControlNew,
- lineControlSnapshot);
-
- } while (lineControlPrevious != lineControlSnapshot);
-
- return status;
-}
diff --git a/VirtualSerial2/queue.h b/VirtualSerial2/queue.h
deleted file mode 100644
index 909d699..0000000
--- a/VirtualSerial2/queue.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- queue.h
-
-Abstract:
-
- This file defines the queue callback interface.
-
-Environment:
-
- Windows Driver Framework
-
---*/
-
-#pragma once
-
-#include "internal.h"
-
-// Set ring buffer size
-#define DATA_BUFFER_SIZE 1024
-
-//
-// Device states
-//
-#define COMMAND_MATCH_STATE_IDLE 0
-#define COMMAND_MATCH_STATE_GOT_A 1
-#define COMMAND_MATCH_STATE_GOT_T 2
-
-//
-// Define useful macros
-//
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif
-
-#define MAXULONG 0xffffffff
-
-typedef struct _QUEUE_CONTEXT
-{
- UCHAR CommandMatchState;
-
- BOOLEAN ConnectCommand;
-
- BOOLEAN IgnoreNextChar;
-
- BOOLEAN ConnectionStateChanged;
-
- BOOLEAN CurrentlyConnected;
-
- RING_BUFFER RingBuffer; // Ring buffer for pending data
-
- BYTE Buffer[DATA_BUFFER_SIZE];
-
- WDFQUEUE Queue; // Default parallel queue
-
- WDFQUEUE ReadQueue; // Manual queue for pending reads
-
- WDFQUEUE WaitMaskQueue; // Manual queue for pending ioctl wait-on-mask
-
- PDEVICE_CONTEXT DeviceContext;
-
-} QUEUE_CONTEXT, *PQUEUE_CONTEXT;
-
-WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(QUEUE_CONTEXT, GetQueueContext);
-
-EVT_WDF_IO_QUEUE_IO_READ EvtIoRead;
-EVT_WDF_IO_QUEUE_IO_WRITE EvtIoWrite;
-EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL EvtIoDeviceControl;
-
-NTSTATUS
-QueueCreate(
- _In_ PDEVICE_CONTEXT DeviceContext
- );
-
-NTSTATUS
-QueueProcessWriteBytes(
- _In_ PQUEUE_CONTEXT QueueContext,
- _In_reads_bytes_(Length)
- PUCHAR Characters,
- _In_ size_t Length
- );
-
-NTSTATUS
-QueueProcessGetLineControl(
- _In_ PQUEUE_CONTEXT QueueContext,
- _In_ WDFREQUEST Request
- );
-
-NTSTATUS
-QueueProcessSetLineControl(
- _In_ PQUEUE_CONTEXT QueueContext,
- _In_ WDFREQUEST Request
- );
-
-NTSTATUS
-RequestCopyFromBuffer(
- _In_ WDFREQUEST Request,
- _In_ PVOID SourceBuffer,
- _In_ size_t NumBytesToCopyFrom
- );
-
-NTSTATUS
-RequestCopyToBuffer(
- _In_ WDFREQUEST Request,
- _In_ PVOID DestinationBuffer,
- _In_ size_t NumBytesToCopyTo
- );
-
diff --git a/VirtualSerial2/ringbuffer.c b/VirtualSerial2/ringbuffer.c
deleted file mode 100644
index 0efbe82..0000000
--- a/VirtualSerial2/ringbuffer.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*++
-
-Copyright (c) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- RingBuffer.c
-
-Abstract:
-
- This file implements the Ring Buffer
-
-Environment:
-
---*/
-
-#include "internal.h"
-
-VOID
-RingBufferInitialize(
- _In_ PRING_BUFFER Self,
- _In_reads_bytes_(BufferSize)
- BYTE* Buffer,
- _In_ size_t BufferSize
- )
-{
- Self->Size = BufferSize;
- Self->Base = Buffer;
- Self->End = Buffer + BufferSize;
- Self->Head = Buffer;
- Self->Tail = Buffer;
-}
-
-
-VOID
-RingBufferGetAvailableSpace(
- _In_ PRING_BUFFER Self,
- _Out_ size_t *AvailableSpace
- )
-{
- BYTE* headSnapshot = NULL;
- BYTE* tailSnapshot = NULL;
- BYTE* tailPlusOne = NULL;
-
- ASSERT(AvailableSpace);
-
- //
- // 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 = Self->Head;
- tailSnapshot = Self->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) == Self->End) ? Self->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 = Self->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 = Self->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;
- }
- }
-}
-
-
-VOID
-RingBufferGetAvailableData(
- _In_ PRING_BUFFER Self,
- _Out_ size_t *AvailableData
- )
-{
- size_t availableSpace;
-
- ASSERT(AvailableData);
-
- RingBufferGetAvailableSpace(Self, &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 = Self->Size - availableSpace - 1;
-}
-
-
-NTSTATUS
-RingBufferWrite(
- _In_ PRING_BUFFER Self,
- _In_reads_bytes_(DataSize)
- BYTE* Data,
- _In_ size_t DataSize
- )
-{
- size_t availableSpace;
- size_t bytesToCopy;
- size_t spaceFromCurrToEnd;
-
- ASSERT(Data && (0 != DataSize));
-
- if (Self->Tail >= Self->End)
- {
- return STATUS_INTERNAL_ERROR;
- }
-
- //
- // Get the amount of space available in the buffer
- //
- RingBufferGetAvailableSpace(Self, &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 ((Self->Tail + bytesToCopy) > Self->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 = Self->End - Self->Tail;
-
- RtlCopyMemory(Self->Tail, Data, spaceFromCurrToEnd);
-
- Data += spaceFromCurrToEnd;
-
- bytesToCopy -= spaceFromCurrToEnd;
-
- //
- // The second step of the copy ...
- //
- RtlCopyMemory(Self->Base, Data, bytesToCopy);
-
- //
- // Advance the tail pointer
- //
- Self->Tail = Self->Base + bytesToCopy;
- }
- else
- {
- //
- // Data does NOT wrap around the end of the buffer. Just copy it
- // over in a single step
- //
- RtlCopyMemory(Self->Tail, Data, bytesToCopy);
-
- //
- // Advance the tail pointer
- //
- Self->Tail += bytesToCopy;
- if (Self->Tail == Self->End)
- {
- //
- // We have exactly reached the end of the buffer. The next
- // write should wrap around and start from the beginning.
- //
- Self->Tail = Self->Base;
- }
- }
-
- ASSERT(Self->Tail < Self->End);
- }
-
- return STATUS_SUCCESS;
-}
-
-
-NTSTATUS
-RingBufferRead(
- _In_ PRING_BUFFER Self,
- _Out_writes_bytes_to_(DataSize, *BytesCopied)
- BYTE* Data,
- _In_ size_t DataSize,
- _Out_ size_t *BytesCopied
- )
-{
- size_t availableData;
- size_t dataFromCurrToEnd;
-
- ASSERT(Data && (DataSize != 0));
-
- if (Self->Head >= Self->End)
- {
- return STATUS_INTERNAL_ERROR;
- }
-
- //
- // Get the amount of data available in the buffer
- //
- RingBufferGetAvailableData(Self, &availableData);
-
- if (availableData == 0)
- {
- *BytesCopied = 0;
- return STATUS_SUCCESS;
- }
-
- if (DataSize > availableData)
- {
- DataSize = availableData;
- }
-
- *BytesCopied = DataSize;
-
- if ((Self->Head + DataSize) > Self->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 = Self->End - Self->Head;
- RtlCopyMemory(Data, Self->Head, dataFromCurrToEnd);
- Data += dataFromCurrToEnd;
- DataSize -= dataFromCurrToEnd;
-
- //
- // The second step of the copy ...
- //
- RtlCopyMemory(Data, Self->Base, DataSize);
-
- //
- // Advance the head pointer
- //
- Self->Head = Self->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.
- //
- RtlCopyMemory(Data, Self->Head, DataSize);
-
- //
- // Advance the head pointer
- //
- Self->Head += DataSize;
- if (Self->Head == Self->End)
- {
- //
- // We have exactly reached the end of the buffer. The next
- // read should wrap around and start from the beginning.
- //
- Self->Head = Self->Base;
- }
- }
-
- ASSERT(Self->Head < Self->End);
-
- return STATUS_SUCCESS;
-}
-
diff --git a/VirtualSerial2/ringbuffer.h b/VirtualSerial2/ringbuffer.h
deleted file mode 100644
index 8c5e3e3..0000000
--- a/VirtualSerial2/ringbuffer.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- Ringbuffer.h
-
---*/
-
-#pragma once
-
-typedef struct _RING_BUFFER
-{
- //
- // The size in bytes of the ring buffer.
- //
- size_t Size;
-
- //
- // A pointer to the base of the ring buffer.
- //
- BYTE* Base;
-
- //
- // A pointer to the byte beyond the end of the ring buffer. Used for
- // quick comparisons when determining if we need to wrap.
- //
- BYTE* 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.
- //
- //
- BYTE* 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.
- //
- BYTE* Tail;
-
-} RING_BUFFER, *PRING_BUFFER;
-
-
-VOID
-RingBufferInitialize(
- _In_ PRING_BUFFER Self,
- _In_reads_bytes_(BufferSize)
- BYTE* Buffer,
- _In_ size_t BufferSize
- );
-
-NTSTATUS
-RingBufferWrite(
- _In_ PRING_BUFFER Self,
- _In_reads_bytes_(DataSize)
- BYTE* Data,
- _In_ size_t DataSize
- );
-
-NTSTATUS
-RingBufferRead(
- _In_ PRING_BUFFER Self,
- _Out_writes_bytes_to_(DataSize, *BytesCopied)
- BYTE* Data,
- _In_ size_t DataSize,
- _Out_ size_t *BytesCopied
- );
-
-VOID
-RingBufferGetAvailableSpace(
- _In_ PRING_BUFFER Self,
- _Out_ size_t *AvailableSpace
- );
-
-VOID
-RingBufferGetAvailableData(
- _In_ PRING_BUFFER Self,
- _Out_ size_t *AvailableData
- );
diff --git a/VirtualSerial2/serial.h b/VirtualSerial2/serial.h
deleted file mode 100644
index 223c1ce..0000000
--- a/VirtualSerial2/serial.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/*++
-
-Copyright (C) Microsoft Corporation, All Rights Reserved
-
-Module Name:
-
- Serial.h
-
-Abstract:
-
- Type definitions and data for the serial port driver
-
---*/
-
-#pragma once
-
-//
-// 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)
-
-#ifdef _KERNEL_MODE
-
-#include
-
-#else
-
-////////////////////////////////////////////////////////////////////////////////
-//
-// Instead of #include , the following are copied from that header,
-// as ntddser.h is conflicted with winioctl.h which is included from wdf.h
-//
-////////////////////////////////////////////////////////////////////////////////
-
-#define IOCTL_SERIAL_SET_BAUD_RATE CTL_CODE(FILE_DEVICE_SERIAL_PORT, 1,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_QUEUE_SIZE CTL_CODE(FILE_DEVICE_SERIAL_PORT, 2,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_LINE_CONTROL CTL_CODE(FILE_DEVICE_SERIAL_PORT, 3,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_BREAK_ON CTL_CODE(FILE_DEVICE_SERIAL_PORT, 4,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_BREAK_OFF CTL_CODE(FILE_DEVICE_SERIAL_PORT, 5,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_IMMEDIATE_CHAR CTL_CODE(FILE_DEVICE_SERIAL_PORT, 6,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_TIMEOUTS CTL_CODE(FILE_DEVICE_SERIAL_PORT, 7,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_TIMEOUTS CTL_CODE(FILE_DEVICE_SERIAL_PORT, 8,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_DTR CTL_CODE(FILE_DEVICE_SERIAL_PORT, 9,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_CLR_DTR CTL_CODE(FILE_DEVICE_SERIAL_PORT,10,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_RESET_DEVICE CTL_CODE(FILE_DEVICE_SERIAL_PORT,11,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_RTS CTL_CODE(FILE_DEVICE_SERIAL_PORT,12,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_CLR_RTS CTL_CODE(FILE_DEVICE_SERIAL_PORT,13,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_XOFF CTL_CODE(FILE_DEVICE_SERIAL_PORT,14,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_XON CTL_CODE(FILE_DEVICE_SERIAL_PORT,15,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_WAIT_MASK CTL_CODE(FILE_DEVICE_SERIAL_PORT,16,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_WAIT_MASK CTL_CODE(FILE_DEVICE_SERIAL_PORT,17,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_WAIT_ON_MASK CTL_CODE(FILE_DEVICE_SERIAL_PORT,18,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_PURGE CTL_CODE(FILE_DEVICE_SERIAL_PORT,19,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_BAUD_RATE CTL_CODE(FILE_DEVICE_SERIAL_PORT,20,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_LINE_CONTROL CTL_CODE(FILE_DEVICE_SERIAL_PORT,21,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_CHARS CTL_CODE(FILE_DEVICE_SERIAL_PORT,22,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_CHARS CTL_CODE(FILE_DEVICE_SERIAL_PORT,23,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_HANDFLOW CTL_CODE(FILE_DEVICE_SERIAL_PORT,24,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_HANDFLOW CTL_CODE(FILE_DEVICE_SERIAL_PORT,25,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_MODEMSTATUS CTL_CODE(FILE_DEVICE_SERIAL_PORT,26,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_COMMSTATUS CTL_CODE(FILE_DEVICE_SERIAL_PORT,27,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_XOFF_COUNTER CTL_CODE(FILE_DEVICE_SERIAL_PORT,28,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_PROPERTIES CTL_CODE(FILE_DEVICE_SERIAL_PORT,29,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_GET_DTRRTS CTL_CODE(FILE_DEVICE_SERIAL_PORT,30,METHOD_BUFFERED,FILE_ANY_ACCESS)
-
-#define IOCTL_SERIAL_GET_MODEM_CONTROL CTL_CODE(FILE_DEVICE_SERIAL_PORT,37,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_MODEM_CONTROL CTL_CODE(FILE_DEVICE_SERIAL_PORT,38,METHOD_BUFFERED,FILE_ANY_ACCESS)
-#define IOCTL_SERIAL_SET_FIFO_CONTROL CTL_CODE(FILE_DEVICE_SERIAL_PORT,39,METHOD_BUFFERED,FILE_ANY_ACCESS)
-
-
-typedef struct _SERIAL_BAUD_RATE {
- ULONG BaudRate;
- } SERIAL_BAUD_RATE,*PSERIAL_BAUD_RATE;
-
-typedef struct _SERIAL_LINE_CONTROL {
- UCHAR StopBits;
- UCHAR Parity;
- UCHAR WordLength;
- } SERIAL_LINE_CONTROL,*PSERIAL_LINE_CONTROL;
-
-typedef struct _SERIAL_TIMEOUTS {
- ULONG ReadIntervalTimeout;
- ULONG ReadTotalTimeoutMultiplier;
- ULONG ReadTotalTimeoutConstant;
- ULONG WriteTotalTimeoutMultiplier;
- ULONG WriteTotalTimeoutConstant;
- } SERIAL_TIMEOUTS,*PSERIAL_TIMEOUTS;
-
-#define STOP_BIT_1 0
-#define STOP_BITS_1_5 1
-#define STOP_BITS_2 2
-
-#define NO_PARITY 0
-#define ODD_PARITY 1
-#define EVEN_PARITY 2
-#define MARK_PARITY 3
-#define SPACE_PARITY 4
-
-#endif // #ifdef _KERNEL_MODE, #include
-
-//
-// DEFINE_GUID(GUID_DEVINTERFACE_MODEM, 0x2c7089aa, 0x2e0e, 0x11d1, 0xb1, 0x14, 0x00, 0xc0, 0x4f, 0xc2, 0xaa, 0xe4);
-//
-#include