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