[
  {
    "path": ".gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\n[Xx]64/\n[Xx]86/\n[Bb]uild/\nbld/\n[Bb]in/\n[Oo]bj/\n\n# Visual Studio 2015 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUNIT\n*.VisualState.xml\nTestResult.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# DNX\nproject.lock.json\nartifacts/\n\n*_i.c\n*_p.c\n*_i.h\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# JustCode is a .NET coding add-in\n.JustCode\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n\n# TODO: Un-comment the next line if you do not want to checkin\n# your web deploy settings because they may include unencrypted\n# passwords\n#*.pubxml\n*.publishproj\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n# NuGet v3's project.json files produces more ignoreable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directory\nAppPackages/\nBundleArtifacts/\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!*.[Cc]ache/\n\n# Others\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.pfx\n*.publishsettings\nnode_modules/\norleans.codegen.cs\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\n*.mdf\n*.ldf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# LightSwitch generated files\nGeneratedArtifacts/\nModelManifest.xml\n\n# Paket dependency manager\n.paket/paket.exe\n\n# FAKE - F# Make\n.fake/\n/UDVC-Server/ReadMe.txt\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) 2020 Balazs Bucsay\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Universal Dynamic Virtual Channel connector for Remote Desktop Services (UDVC) #\nTerminal Services (or Remote Desktop Services) are offering many hidden features for those who want to dig deeper. One of these services is the Dynamic Virtual Channel that enables us to communicate over an open RDP connection without the need to open a new socket, connection or a port on a firewall. These channels can be used to hide data from active network devices, to bypass firewalls, to implement device drivers over networks or just to help penetration testers to transfer data. The possibilities  are endless.\n\nThe real reason why this project was created is [XFLTReaT](https://github.com/earthquake/XFLTReaT). This could be used to build up a \"VPN\" over segregated networks and finally it enables testing over jumpboxes without requesting firewall changes. In a nutshell it makes penetration testers' life easier.\n\n### How does this work? ###\nYou need to install a plugin (*.dll*) on your client computer that you use to connect to the RDP server. On the RDP server you need to use the other half of the project the *.exe*, which creates the channel between the plugin and the server executable. \nIf you want to know more details, please scroll down.\n\n### Installation ###\n**It is Windows only.** Dynamic Virtual Channels were introduced in **Window Server 2008 & Windows Vista SP1**. These **and** anything **newer** than these should be good to go.\n\nYou can grab the whole project and compile it by yourself or just use the compiled binaries from the [Releases section](https://github.com/earthquake/UniversalDVC/releases). It is important that the correct binary is used in all cases, please select the correct one for the corresponding architecture (if your client is 32bit but the server is 64bit then grab the 32bit dll and 64bit exe).\nThe *.dll* needs to be placed on the client computer in any directory (for long-term use, you can put it into the %SYSROOT%\\\\system32\\\\ or %SYSROOT%\\\\SysWoW64\\\\) and install it with the following command as an elevated user (a.k.a Administrator): \n`regsvr32.exe UDVC-Plugin.dll`\n\nIf your user is not an administrator, you need to import the registry settings under your user too. Please use the *UDVC-Plugin.reg* file for that.\n\nIf you wish to remove it: \n`regsvr32.exe /u UDVC-Plugin.dll`\n\n\n**Every time you connect to an RDP server from now on, this plugin will be loaded and will configure itself as it was specified in the registry (see below).**\n\n\nThe *.exe* needs to be put on the RDP server and run as any user.\n\n### Modes supported ###\nBoth sides support three modes at the moment: \n#### Socket server mode (0 - default)\nWhen this mode is enabled, then a listener will be set up on the defined port and interface (IP address).\n#### Socket client mode (1)\nIn this mode a connection will be made towards a listener on the defined IP address and port.\n#### Named Pipe mode (2)\nThis mode sets up a Named Pipe with the specified name. As an example: this mode can be used for other tools to do IPC communication over RDP. Unfortunately, Named Pipes are written to the disk so it is considered slow compared to the socket modes. **If you care about the bandwith, please use the socket modes.**\n\n### Options/Configuration ###\nBoth the client and the server binary act the same way and it can be configured with the same options.\n* **enabled**: *0* disabled, *1* enabled (plugin only). By default it is enabled and will tell you in a messagebox every time you initiate a connection.\n* **mode**: *0* for listen(), *1* for connect() and *2* for creating a Named Pipe\n* **ip**: which IP to connect to or bind to\n* **port**: which port to connect to or bind to\n* **namedpipename**: name of the named pipe\n* **priority** (server binary only) *LOW, MEDIUM, HIGH, REAL* priorities for data transmission. *REAL* priority could severely affect the accessibility of the session in case of an intense data transfer, since the protocol prioritizes data over the control. \n\nThe server binary will read the options from the command line.\n```\nPS C:\\Users\\UDVC\\> .\\UDVC-Server.exe -h\nUniversal Dynamic Virtual Channel server application\n\nUsage: C:\\Users\\UDVC\\UDVC-Server.exe [-s | -c [-p port [-h ip]] | -m [-n name]] [-0 | -1 | -2 | -3]\nSocket server mode -s (default) OR\nSocket client mode -c:\n        -p port   port to bind the listener (default: 31337)\n        -i ip     ip to bind the listener (default: 127.0.0.1)\n\nNamed pipe mode -m:\n        -n name   name of the named pipe (by default: \"\\\\.\\pipe\\UDVC_{RDP SESSION NUMBER}\")\n\nData transfer priority parameters:\n        -0        real time             (WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL)\n        -1        high priority         (WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH) - default\n        -2        medium priority       (WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED)\n        -3        low priority          (WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW)\n```\n\nThe client *.dll*  reads all the options from the registry, the values can be found under the following key:\n`HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Terminal Server Client\\Default\\AddIns\\UDVC-Plugin`\n  \nEvery time the module is enabled and before the connection is made a reminder warning is showed. Just like this:\n![warning](https://github.com/earthquake/UniversalDVC/blob/master/wiki/warning.png?raw=true)\n\nThis warning ensures that the user knows about the plugin is loaded and with what settings.\n\n### Usage\nThe listeners, connections or named pipes are only created when the server executable was able to connect to the plugin dll. It depends on your configuration, but by default when the Virtual Channel connection was made (the plugin was loaded properly, the server binary was executed) it listens on the localhost:31337 on both endpoints. When you connect to these ports and send data through the socket, it will show up on the other side.\n\n### Example use cases\nJust to show a few uses cases where this tool can be used.\n\nVery basic port forwarding. The Segregated 1 machine has a HTTP service on tcp/80. That network is not routed from the 192.168.0.0/24 network, the dual homed jump box must be used to access. Listen mode is configured on the client side on 0.0.0.0:31337 and the server binary was executed with the connect mode settings to create a connection to the web server. The user on the RDP client can use its browser to open http://127.0.0.1:31337 to access the content from http://10.13.37.2:80.\n![scenario1](https://github.com/earthquake/UniversalDVC/blob/master/wiki/scenario1.png?raw=true)\n\nA bit more advanced scenario to transfer files. Both endpoints are configured to listen on 0.0.0.0:31337. First the Hacking box connects to the RDP client and waits for the input. Then the Segregated 2 machine connects to the Jump box and reads the whole file into the socket.\n![scenario2](https://github.com/earthquake/UniversalDVC/blob/master/wiki/scenario2.png?raw=true)\n\nAs an extra, Named Pipes can be used as well. In this case both the RDP client and Jump box create a Named Pipe on both sides (hIPC-client and hIPC-server) and the other machines can connect to these pipes. Whatever is written on the pipes it will show up on the other end. It is not really different from the listen mode example above, except it is using Named Pipes instead of TCP sockets.\n![scenario3](https://github.com/earthquake/UniversalDVC/blob/master/wiki/scenario3.png?raw=true)\n\n### Issues\nIn case the plugin does not load or the executable does not run because it is missing some DLLs for example the VCRUNTIME140.DLL, you might want to install the [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) package.\n\n"
  },
  {
    "path": "UDVC-Plugin/Resource.h",
    "content": "//{{NO_DEPENDENCIES}}\n// Microsoft Visual C++ generated include file.\n// Used by UDVC-Plugin.rc\n//\n\n#define IDS_PROJNAME                    100\n#define IDR_UDVCPLUGIN\t\t\t\t\t101\n#define IDR_UDVCCLIENTPLUGIN            102\n\n// Next default values for new objects\n//\n#ifdef APSTUDIO_INVOKED\n#ifndef APSTUDIO_READONLY_SYMBOLS\n#define _APS_NEXT_RESOURCE_VALUE        201\n#define _APS_NEXT_COMMAND_VALUE         32768\n#define _APS_NEXT_CONTROL_VALUE         201\n#define _APS_NEXT_SYMED_VALUE           106\n#endif\n#endif\n"
  },
  {
    "path": "UDVC-Plugin/UDVC-Plugin.cpp",
    "content": "/*\n* MIT License\n*\n* Copyright(c) 2018-2020 Balazs Bucsay\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files(the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions :\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*/\n\n#include \"stdafx.h\"\n#include \"resource.h\"\n#include \"UDVC-Plugin.h\"\n\n#pragma comment(lib, \"Ws2_32.lib\")\n\n#define UDVC_CHANNEL_NAME \"UniversalDVC\"\n\nstruct arguments {\n\tDWORD enabled;\n\tDWORD mode; // 0 sock listen(); 1 sock connect(); 2 namedpipe\n\tWCHAR *namedpipename;\n\tWCHAR *ip;\n\tWCHAR *port;\n};\n\nstruct threadhandles {\n\tSOCKET sock = NULL;\n\tSOCKET sockserver = NULL;\n\tHANDLE pipe = NULL;\n};\n\nstruct threadargs {\n\tstruct arguments *running_args;\n\tstruct threadhandles *threadhandle;\n\tIWTSVirtualChannel *m_ptrChannel = NULL;\n\tHANDLE hThread = NULL;\n};\n\nWSADATA\t\twsaData;\n\nusing namespace ATL;\n\n#define CHECK_QUIT_HR( _x_ )    if(FAILED(hr)) { return hr; }\n\nclass ATL_NO_VTABLE UDVCPlugin :\n\tpublic CComObjectRootEx<CComMultiThreadModel>,\n\tpublic CComCoClass<UDVCPlugin, &CLSID_CompReg>,\n\tpublic IWTSPlugin,\n\tpublic IWTSVirtualChannelCallback,\n\tpublic IWTSListenerCallback\n{\npublic:\n\tCComPtr<IWTSVirtualChannel> m_ptrChannel;\n\n\tDECLARE_REGISTRY_RESOURCEID(IDR_UDVCPLUGIN)\n\n\tBEGIN_COM_MAP(UDVCPlugin)\n\t\tCOM_INTERFACE_ENTRY(IWTSPlugin)\n\t\tCOM_INTERFACE_ENTRY(IWTSVirtualChannelCallback)\n\t\tCOM_INTERFACE_ENTRY(IWTSListenerCallback)\n\tEND_COM_MAP()\n\n\tDECLARE_PROTECT_FINAL_CONSTRUCT()\n\n\n\tHRESULT FinalConstruct()\n\t{\n\t\treturn S_OK;\n\t}\n\n\tvoid FinalRelease()\n\t{\n\t}\n\n\t// IWTSPlugin.\n\t//\n\tHRESULT STDMETHODCALLTYPE\n\t\tInitialize(IWTSVirtualChannelManager *pChannelMgr);\n\n\tHRESULT STDMETHODCALLTYPE Connected();\n\n\tHRESULT STDMETHODCALLTYPE Disconnected(DWORD dwDisconnectCode)\n\t{\n\t\t// Prevent C4100 \"unreferenced parameter\" warnings.\n\t\tWSACleanup();\n\t\tdwDisconnectCode;\n\t\treturn S_OK;\n\t}\n\n\tHRESULT STDMETHODCALLTYPE Terminated()\n\t{\n\t\treturn S_OK;\n\t}\n\n\tVOID SetChannel(IWTSVirtualChannel *pChannel, struct threadargs *pTa);\n\n\t// IWTSVirtualChannelCallback\n\t//\n\tHRESULT STDMETHODCALLTYPE OnDataReceived(ULONG cbSize, __in_bcount(cbSize) BYTE *pBuffer);\n\t\n\tHRESULT STDMETHODCALLTYPE OnClose()\n\t{\n\t\tDebugPrint(0, L\"[*] Terminating thread, closing socket and channel\");\n\t\tif (pta->threadhandle->sockserver)\n\t\t\tclosesocket(pta->threadhandle->sockserver);\n\t\tTerminateThread(pta->hThread, 0);\n\t\treturn S_OK;// m_ptrChannel->Close();\n\t}\n\n\tHRESULT STDMETHODCALLTYPE\n\t\tOnNewChannelConnection(\n\t\t\t__in IWTSVirtualChannel *pChannel,\n\t\t\t__in_opt BSTR data,\n\t\t\t__out BOOL *pbAccept,\n\t\t\t__out IWTSVirtualChannelCallback **ppCallback);\n\n\t// non-inherited ones\n\n\tstruct threadargs ta, *pta;\n\tstruct arguments running_args;\n\tstruct threadhandles threadhandle;\n\n\tstatic VOID UDVCPlugin::DebugPrint(HRESULT hrDbg, __in_z LPWSTR fmt, ...);\n\tLONG UDVCPlugin::GetDWORDRegKey(HKEY hKey, WCHAR *strValueName, DWORD *nValue);\n\tLONG UDVCPlugin::GetStringRegKey(HKEY hKey, WCHAR *strValueName, WCHAR **strValue);\n\tBOOL UDVCPlugin::GetRegistrySettings();\n\tstatic DWORD WINAPI UDVCPlugin::ListenerThread(PVOID param);\n\tstatic DWORD WINAPI UDVCPlugin::RsWcThread(PVOID param);\n\n};\n\nOBJECT_ENTRY_AUTO(__uuidof(CompReg), UDVCPlugin)\n\n\nVOID UDVCPlugin::DebugPrint(HRESULT hrDbg, __in_z LPWSTR fmt, ...)\n{\n\tHRESULT\thr;\n\tTCHAR\tBuffer[DEBUG_PRINT_BUFFER_SIZE];\n\tsize_t\tLen;\n\n\thr = StringCchPrintf(Buffer, DEBUG_PRINT_BUFFER_SIZE, TEXT(\"[hr=0x%8x]\"), hrDbg);\n\tassert(SUCCEEDED(hr)); // buffer is sure to be big enough\n\n\thr = StringCchLength(Buffer, DEBUG_PRINT_BUFFER_SIZE, &Len);\n\tassert(SUCCEEDED(hr)); // StringCchPrintf is supposed to always NULL term\n\n\tva_list argptr;\n\tva_start(argptr, fmt);\n\n\thr = StringCchVPrintf(Buffer + Len, DEBUG_PRINT_BUFFER_SIZE - Len,\n\t\tfmt, argptr);\n\n\t// the above could fail but we don't care since we\n\t// should get a NULL terminated partial string\n\n\t// insert terminating eol (despite failure)\n\thr = StringCchLength(Buffer, DEBUG_PRINT_BUFFER_SIZE, &Len);\n\tassert(SUCCEEDED(hr)); // again there should be a NULL term\n\n\tif (Len < DEBUG_PRINT_BUFFER_SIZE - 1)\n\t{\n\t\tLen++;\n\t\tBuffer[Len] = TEXT('\\0');\n\t}\n\n\tBuffer[Len - 1] = TEXT('\\n');\n\tOutputDebugString(Buffer);\n}\n\nLONG UDVCPlugin::GetDWORDRegKey(HKEY hKey, WCHAR *strValueName, DWORD *nValue)\n{\n\tDWORD dwBufferSize(sizeof(DWORD));\n\tDWORD nResult;\n\tLONG nError;\n\n\tif ((nError = RegQueryValueEx(hKey, strValueName, 0, NULL, (LPBYTE)&nResult, &dwBufferSize)) == ERROR_SUCCESS)\n\t{\n\t\t*nValue = nResult;\n\t}\n\treturn nError;\n}\n\nLONG UDVCPlugin::GetStringRegKey(HKEY hKey, WCHAR *strValueName, WCHAR **strValue)\n{\n\tLPVOID szTemp = NULL;\n\tDWORD buflen = 255;\n\tLONG nError;\n\n\tif ((szTemp = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (size_t)buflen)) == NULL)\n\t{\n\t\tDebugPrint(GetLastError(), L\"[-] Error allocating heap for read buffer %ld\", GetLastError());\n\t\treturn -1;\n\t}\n\n\tif ((nError = RegQueryValueExW(hKey, strValueName, 0, NULL, (LPBYTE)szTemp, &buflen)) != ERROR_SUCCESS)\n\t{\n\t\tHeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, szTemp);\n\t\tszTemp = NULL;\n\t}\n\t*strValue = (WCHAR *)szTemp;\n\n\treturn nError;\n}\n\nBOOL UDVCPlugin::GetRegistrySettings()\n{\n\tHKEY hKey;\n\tLONG lRes;\n\tWCHAR *szTemp;\n\n\tif ((lRes = RegOpenKeyEx(HKEY_CURRENT_USER, L\"SOFTWARE\\\\Microsoft\\\\Terminal Server Client\\\\Default\\\\AddIns\\\\UDVC-Plugin\\\\\", 0, KEY_READ, &hKey)) != ERROR_SUCCESS)\n\t{\n\t\tDebugPrint(lRes, L\"[-] Error opening registry hive/key\");\n\t\treturn FALSE;\n\t}\n\n\tGetDWORDRegKey(hKey, L\"enabled\", &running_args.enabled);\n\tGetDWORDRegKey(hKey, L\"mode\", &(running_args.mode));\n\tif ((running_args.mode == 0) || (running_args.mode == 1))\n\t{\n\t\tGetStringRegKey(hKey, L\"ip\", &szTemp);\n\t\tif (szTemp != NULL)\n\t\t{\n\t\t\tif (wcslen(szTemp) < 16)\n\t\t\t{\n\t\t\t\trunning_args.ip = szTemp;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMessageBox(NULL, L\"IP too long. Please fix it under the following key:\\r\\nHKCU\\\\SOFTWARE\\\\Microsoft\\\\Terminal Server Client\\\\Default\\\\AddIns\\\\UDVC-Plugin\\\\\", L\"Registry value error\", MB_OK);\n\t\t\t}\n\t\t}\n\t\tGetStringRegKey(hKey, L\"port\", &szTemp);\n\t\tif (szTemp != NULL)\n\t\t{\n\t\t\tif (wcslen(szTemp) < 6)\n\t\t\t{\n\t\t\t\trunning_args.port = szTemp;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tMessageBox(NULL, L\"Port too long. Please fix it under the following key:\\r\\nHKCU\\\\SOFTWARE\\\\Microsoft\\\\Terminal Server Client\\\\Default\\\\AddIns\\\\UDVC-Plugin\\\\\", L\"Registry value error\", MB_OK);\n\t\t\t}\n\t\t}\n\t}\n\tif (running_args.mode == 2)\n\t{\n\t\tGetStringRegKey(hKey, L\"namedpipename\", &szTemp);\n\t\tif (szTemp != NULL)\n\t\t{\n\t\t\tif (wcsncmp(szTemp, L\"\\\\\\\\.\\\\pipe\\\\\", 9))\n\t\t\t{\n\t\t\t\tMessageBox(NULL, L\"Named pipe name has to start with: \\\\\\\\.\\\\pipe\\\\\\r\\nPlease fix it under the following key:\\r\\nHKCU\\\\SOFTWARE\\\\Microsoft\\\\Terminal Server Client\\\\Default\\\\AddIns\\\\UDVC-Plugin\\\\\", L\"Registry value error\", MB_OK);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\trunning_args.namedpipename = szTemp;\n\t\t\t}\n\t\t}\n\t}\n\t\n\treturn TRUE;\n}\n\n\n// IWTSPlugin::Initialize implementation.\nHRESULT UDVCPlugin::Initialize(__in IWTSVirtualChannelManager *pChannelMgr)\n{\n\tHRESULT\thr;\n\tCComObject<UDVCPlugin> *pListenerCallback;\n\tCComPtr<UDVCPlugin> ptrListenerCallback;\n\tCComPtr<IWTSListener> ptrListener;\n\tWCHAR\tenabledmsg[256];\n\tint\t\tret;\n\n\trunning_args.enabled = 0;\n\trunning_args.mode = 0;\n\trunning_args.port = L\"31337\";\n\trunning_args.namedpipename = L\"\\\\\\\\.\\\\pipe\\\\UDVC_default\";\n\trunning_args.ip = L\"127.0.0.1\";\n\n\tif (!GetRegistrySettings())\n\t{\n\t\tDebugPrint(-1, L\"[-] Could not access the registry settings\");\n\t}\n\n\tif (!running_args.enabled)\n\t{\n\t\tDebugPrint(0, L\"[*] Plugin disabled\");\n\t\treturn -1;\n\t}\n\n\tif ((ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)\n\t{\n\t\tDebugPrint(ret, L\"WSAStartup() failed with error: %ld\", ret);\n\t\treturn -1;\n\t}\n\n\tif (running_args.mode == 0)\n\t\twnsprintf(enabledmsg, 255, L\"The UDVC plugin is enabled. When the server binary gets executed, it will listen on: %s:%s\", running_args.ip, running_args.port);\n\tif (running_args.mode == 1)\n\t\twnsprintf(enabledmsg, 255, L\"The UDVC plugin is enabled. When the server binary gets executed, it will connect to: %s:%s\", running_args.ip, running_args.port);\n\tif (running_args.mode == 2)\n\t\twnsprintf(enabledmsg, 255, L\"The UDVC plugin is enabled. When the server binary gets executed, it will listen on: %s\", running_args.namedpipename);\n\n\tMessageBox(NULL, enabledmsg, L\"UDVC plugin is enabled\", MB_OK | MB_ICONWARNING);\n\n\n\t// Create an instance of the CSampleListenerCallback object.\n\thr = CComObject<UDVCPlugin>::CreateInstance(&pListenerCallback);\n\tCHECK_QUIT_HR(\"CSampleListenerCallback::CreateInstance\");\n\tptrListenerCallback = pListenerCallback;\n\n\t// Attach the callback to the endpoint.\n\thr = pChannelMgr->CreateListener(\n\t\tUDVC_CHANNEL_NAME,\n\t\t0,\n\t\t(UDVCPlugin*)ptrListenerCallback,\n\t\t&ptrListener);\n\tCHECK_QUIT_HR(\"CreateListener\");\n\n\treturn hr;\n}\n\nHRESULT STDMETHODCALLTYPE UDVCPlugin::Connected()\n{\n\treturn S_OK;\n}\n\nDWORD UDVCPlugin::ListenerThread(PVOID param)\n{\n\tstruct threadargs *threadarg = (struct threadargs *)param;\n\tADDRINFOW\t*result = NULL;\n\tADDRINFOW\thints;\n\tSOCKET\t\ts, c;\n\tHANDLE\t\thNamedPipe = NULL;\n\tint\t\t\tret;\n\tu_long\t\tblocking = 0;\n\n\tif (threadarg->running_args->mode == 0)\n\t{\n\t\tDebugPrint(0, L\"[*] Setting up server socket\");\n\n\t\tZeroMemory(&hints, sizeof(hints));\n\t\thints.ai_family = AF_INET;\n\t\thints.ai_socktype = SOCK_STREAM;\n\t\thints.ai_protocol = IPPROTO_TCP;\n\t\thints.ai_flags = AI_PASSIVE;\n\n\t\tif ((ret = GetAddrInfoW(threadarg->running_args->ip, threadarg->running_args->port, &hints, &result)) != 0) {\n\t\t\tDebugPrint(ret, L\"[-] GetAddrInfoW() failed with error: %ld\", ret);\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((s = socket(result->ai_family, result->ai_socktype, result->ai_protocol)) == INVALID_SOCKET) {\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] socket() failed with error: %ld\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\treturn -1;\n\t\t}\n\t\tthreadarg->threadhandle->sockserver = s;\n\n\t\tif ((ret = bind(s, result->ai_addr, (int)result->ai_addrlen)) == SOCKET_ERROR) {\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] bind() failed with error: %ld\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\tclosesocket(s);\n\t\t\treturn -1;\n\t\t}\n\n\t\tFreeAddrInfoW(result);\n\t\tDebugPrint(0, L\"[*] Listening on: %s:%s\", threadarg->running_args->ip, threadarg->running_args->port);\n\n\t\tif ((ret = listen(s, SOMAXCONN)) == SOCKET_ERROR) {\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] listen() failed with error: %ld\", WSAGetLastError());\n\t\t\tclosesocket(s);\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((c = accept(s, NULL, NULL)) == INVALID_SOCKET) {\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] accept() failed with error: %ld\", WSAGetLastError());\n\t\t\tclosesocket(s);\n\t\t\treturn -1;\n\t\t}\n\t\tDebugPrint(0, L\"[+] Client connected\");\n\n\t\tclosesocket(s);\n\t\tthreadarg->threadhandle->sockserver = NULL;\n\n\t\tret = ioctlsocket(c, FIONBIO, &blocking);\n\t\tif (ret != NO_ERROR)\n\t\t{\n\t\t\tDebugPrint(ret, L\"[-] ioctlsocket() failed with error: %ld\", ret);\n\t\t\tclosesocket(c);\n\t\t\treturn -1;\n\t\t}\n\t\tthreadarg->threadhandle->sock = c;\n\t}\n\tif (threadarg->running_args->mode == 1)\n\t{\n\t\tDebugPrint(0, L\"[*] Setting up client socket\");\n\n\t\tZeroMemory(&hints, sizeof(hints));\n\t\thints.ai_family = AF_INET;\n\t\thints.ai_socktype = SOCK_STREAM;\n\t\thints.ai_protocol = IPPROTO_TCP;\n\t\thints.ai_flags = AI_PASSIVE;\n\n\t\tif ((ret = GetAddrInfoW(threadarg->running_args->ip, threadarg->running_args->port, &hints, &result)) != 0) {\n\t\t\tDebugPrint(ret, L\"[-] GetAddrInfoW() failed with error: %ld\", ret);\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((c = socket(result->ai_family, result->ai_socktype, result->ai_protocol)) == INVALID_SOCKET) {\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] socket() failed with error: %ld\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((ret = connect(c, result->ai_addr, (int)result->ai_addrlen)) == SOCKET_ERROR) {\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] connect() failed with error: %ld\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\tclosesocket(c);\n\t\t\treturn -1;\n\t\t}\n\t\tFreeAddrInfoW(result);\n\t\tDebugPrint(0, L\"[*] Connected to: %s:%s\", threadarg->running_args->ip, threadarg->running_args->port);\n\n\t\tret = ioctlsocket(c, FIONBIO, &blocking);\n\t\tif (ret != NO_ERROR)\n\t\t{\n\t\t\tDebugPrint(ret, L\"[-] ioctlsocket() failed with error: %ld\", ret);\n\t\t\tclosesocket(c);\n\t\t\treturn -1;\n\t\t}\n\t\tthreadarg->threadhandle->sock = c;\n\t}\n\tif (threadarg->running_args->mode == 2)\n\t{\n\t\tDebugPrint(0, L\"[*] Setting up named pipe\");\n\n\t\tif ((hNamedPipe = CreateNamedPipe(threadarg->running_args->namedpipename,\n\t\t\tPIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,\n\t\t\tPIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, 1, 4096, 4096,\n\t\t\tNMPWAIT_USE_DEFAULT_WAIT, NULL)) == INVALID_HANDLE_VALUE)\n\t\t{\n\t\t\tDebugPrint(GetLastError(), L\"[-] CreateNamedPipe() failed with: %ld\", GetLastError());\n\t\t\treturn -1;\n\t\t}\n\n\t\tDebugPrint(0, L\"[*] Listening on pipe: %s\\n\", threadarg->running_args->namedpipename);\n\t\tif (!ConnectNamedPipe(hNamedPipe, NULL))\n\t\t{\n\t\t\tDebugPrint(GetLastError(), L\"[-] ConnectNamedPipe() failed with: %ld\", GetLastError());\n\t\t\treturn -1;\n\t\t}\n\n\t\tthreadarg->threadhandle->pipe = hNamedPipe;\n\t\tDebugPrint(0, L\"[+] Client connected to the pipe.\");\n\t}\n\n\treturn RsWcThread(param);\n}\n\nDWORD WINAPI UDVCPlugin::RsWcThread(PVOID param)\n{\n\tstruct threadargs *threadarg = (struct threadargs *)param;\n\tDWORD\tdw;\n\tBOOL    bSucc;\n\tHANDLE  hEvent_pipe;\n\tBYTE\t*readBuf;\n\tDWORD\theapsize = 4096;\n\n\tif ((readBuf = (BYTE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, heapsize)) == NULL)\n\t{\n\t\tDebugPrint(GetLastError(), L\"[-] Error allocating heap for read buffer %ld\", GetLastError());\n\t\treturn -1;\n\t}\n\n\thEvent_pipe = CreateEvent(NULL, FALSE, FALSE, NULL);\n\tOVERLAPPED Overlapped_pipe = { 0 };\n\tOverlapped_pipe.hEvent = hEvent_pipe;\n\n\twhile (TRUE)\n\t{\n\t\tif (threadarg->threadhandle->sock)\n\t\t{\n\t\t\tif ((dw = recv(threadarg->threadhandle->sock, (char *)readBuf, heapsize, 0)) == INVALID_SOCKET)\n\t\t\t{\n\t\t\t\tDebugPrint(WSAGetLastError(), L\"[-] [RsWc] recv() failed with error %d, exiting thread...\\n\", WSAGetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (dw == 0)\n\t\t\t{\n\t\t\t\tDebugPrint(WSAGetLastError(), L\"[-] [RsWc] socket closed, exiting thread...\\n\", WSAGetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tif (threadarg->threadhandle->pipe)\n\t\t{\n\t\t\tbSucc = ReadFile(threadarg->threadhandle->pipe, readBuf, heapsize, &dw, &Overlapped_pipe);\n\t\t\tif (!bSucc)\n\t\t\t{\n\t\t\t\tif (GetLastError() == ERROR_IO_PENDING)\n\t\t\t\t{\n\t\t\t\t\tdw = WaitForSingleObject(Overlapped_pipe.hEvent, INFINITE);\n\t\t\t\t\tbSucc = GetOverlappedResult(threadarg->threadhandle->pipe, &Overlapped_pipe, &dw, FALSE);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!bSucc)\n\t\t\t{\n\t\t\t\tDebugPrint(GetLastError(), L\"[-] [RsWc] ReadFile()/WaitForSingleObject() error: %ld\\n\", GetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tif (ResetEvent(Overlapped_pipe.hEvent) == FALSE)\n\t\t\t{\n\t\t\t\tDebugPrint(GetLastError(), L\"[-] [RsWc] ResetEvent() failed with error = %d\\n\", GetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\n\t\tif (threadarg->m_ptrChannel != NULL)\n\t\t\tthreadarg->m_ptrChannel->Write(dw, readBuf, NULL);\n\t\telse\n\t\t\treturn -1;\n\t}\n\n\treturn 0;\n}\n\n// IWTSListenerCallback::OnNewChannelConnection implementation.\nHRESULT UDVCPlugin::OnNewChannelConnection(__in IWTSVirtualChannel *pChannel,\n\t__in_opt BSTR data, __out BOOL *pbAccept, __out IWTSVirtualChannelCallback **ppCallback)\n{\n\tHRESULT\t\thr;\n\tDWORD\t\tdwThreadId;\n\tCComObject<UDVCPlugin> *pCallback;\n\tCComPtr<UDVCPlugin> ptrCallback;\n\n\t// Prevent C4100 \"unreferenced parameter\" warnings.\n\tdata;\n\n\t*pbAccept = FALSE;\n\n\thr = CComObject<UDVCPlugin>::CreateInstance(&pCallback);\n\tCHECK_QUIT_HR(\"UDVCPlugin::CreateInstance\");\n\tptrCallback = pCallback;\n\n\tptrCallback->SetChannel(pChannel, &ta);\n\n\tta.running_args = &running_args;\n\tta.threadhandle = &threadhandle;\n\tta.m_ptrChannel = pChannel;\n\n\trunning_args.enabled = 0;\n\trunning_args.mode = 0;\n\trunning_args.port = L\"31337\";\n\trunning_args.namedpipename = L\"\\\\\\\\.\\\\pipe\\\\UDVC_default\";\n\trunning_args.ip = L\"127.0.0.1\";\n\n\tif (!GetRegistrySettings())\n\t{\n\t\tDebugPrint(-1, L\"[-] Could not access the registry settings\");\n\t}\n\n\tHANDLE hListenerThread = CreateThread(\n\t\tNULL,\n\t\t0,\n\t\t&UDVCPlugin::ListenerThread,\n\t\t&ta,\n\t\t0,\n\t\t&dwThreadId);\n\n\tta.hThread = hListenerThread;\n\n\t*ppCallback = ptrCallback;\n\t(*ppCallback)->AddRef();\n\n\t*pbAccept = TRUE;\n\n\treturn hr;\n}\n\nVOID UDVCPlugin::SetChannel(IWTSVirtualChannel *pChannel, struct threadargs *pTa)\n{\n\tm_ptrChannel = pChannel;\n\tpta\t= pTa;\n}\n\nHRESULT STDMETHODCALLTYPE UDVCPlugin::OnDataReceived(ULONG cbSize, __in_bcount(cbSize) BYTE *pBuffer)\n{\n\tDWORD       ret, dw;\n\tHANDLE      hEvent;\n\tBOOL        bSucc;\n\n\thEvent = CreateEvent(NULL, FALSE, FALSE, NULL);\n\tOVERLAPPED  Overlapped = { 0 };\n\tOverlapped.hEvent = hEvent;\n\n\tif (pta->threadhandle->sock)\n\t{\n\t\tif ((ret = send(pta->threadhandle->sock, (char *)pBuffer, cbSize, 0)) == SOCKET_ERROR)\n\t\t{\n\t\t\tDebugPrint(WSAGetLastError(), L\"[-] [RsWc] send() failed with error %ld\", WSAGetLastError());\n\t\t\tm_ptrChannel->Close();\n\t\t\treturn -1;\n\t\t}\n\t}\n\tif (pta->threadhandle->pipe)\n\t{\n\t\tbSucc = WriteFile(pta->threadhandle->pipe, pBuffer, cbSize, &ret, &Overlapped);\n\t\tif (!bSucc)\n\t\t{\n\t\t\tif (GetLastError() == ERROR_IO_PENDING)\n\t\t\t{\n\t\t\t\tdw = WaitForSingleObject(Overlapped.hEvent, INFINITE);\n\t\t\t\tbSucc = GetOverlappedResult(pta->threadhandle->pipe, &Overlapped, &ret, FALSE);\n\t\t\t}\n\t\t}\n\t\tif (!bSucc)\n\t\t{\n\t\t\tDebugPrint(GetLastError(), L\"[-] [RsWc] WriteFile()/WaitForSingleObject() error: %ld\", GetLastError());\n\t\t\tm_ptrChannel->Close();\n\t\t\treturn -1;\n\t\t}\n\t}\n\n\treturn ret;\n}"
  },
  {
    "path": "UDVC-Plugin/UDVC-Plugin.def",
    "content": "; UDVC-Plugin.def : Declares the module parameters.\n\nLIBRARY\n\nEXPORTS\n\tDllCanUnloadNow\t\tPRIVATE\n\tDllGetClassObject\tPRIVATE\n\tDllRegisterServer\tPRIVATE\n\tDllUnregisterServer\tPRIVATE\n\tDllInstall\t\tPRIVATE\n"
  },
  {
    "path": "UDVC-Plugin/UDVC-Plugin.h",
    "content": "// TsClientPlgn.h : Declaration of the CTsClientPlgn\n\n#pragma once\n#include \"stdafx.h\"\n#include \"resource.h\"       // main symbols\n\n#include \"UDVCPlugin_i.h\"\n\n// debug\n#include <StrSafe.h>\n#include <assert.h>\n\n\n#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)\n#error \"Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms.\"\n#endif\n\n\n// CTsClientPlgn\nclass ATL_NO_VTABLE CTsClientPlgn :\n\tpublic CComObjectRootEx<CComSingleThreadModel>,\n\tpublic CComCoClass<CTsClientPlgn, &CLSID_CompReg>,\n\tpublic IDispatchImpl<IComponentRegistrar, &IID_IComponentRegistrar, &LIBID_UDVCPluginLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,\n    public IWTSPlugin,\n    public IWTSListenerCallback,\n    public IWTSVirtualChannelCallback\n{\npublic:\n    CTsClientPlgn(): _hCurrentFile(INVALID_HANDLE_VALUE)\n\t{\n\t}\n\nDECLARE_REGISTRY_RESOURCEID(IDR_UDVCCLIENTPLUGIN)\n\n\nBEGIN_COM_MAP(CTsClientPlgn)\n\tCOM_INTERFACE_ENTRY(IComponentRegistrar)\n\tCOM_INTERFACE_ENTRY(IDispatch)\n\tCOM_INTERFACE_ENTRY(IWTSPlugin)\n\tCOM_INTERFACE_ENTRY(IWTSListenerCallback)\n\tCOM_INTERFACE_ENTRY(IWTSVirtualChannelCallback)\nEND_COM_MAP()\n\n\tDECLARE_PROTECT_FINAL_CONSTRUCT()\n\n\tHRESULT FinalConstruct()\n\t{\n\t\treturn S_OK;\n\t}\n\n\tvoid FinalRelease()\n\t{\n\t}\n\n    // IWTSPlugin\npublic:\n    /*\n     *  Called immediately after instantiating the COM class\n     */\n    STDMETHOD(Initialize)(\n        IWTSVirtualChannelManager *pChannelMgr\n        );\n\n    /*\n     *  Called when the TS client is connected to the TS server\n     */\n    STDMETHOD(Connected)();\n\n    /*\n     *  Called when the TS client is disconnected to the TS server\n     *  Might be followed by another Connected() call\n     */\n    STDMETHOD(Disconnected)(\n        DWORD dwDisconnectCode\n        );\n\n    /*\n     *  The last method called by the TS client before \n     *  terminating the object\n     */\n    STDMETHOD(Terminated)();\n\n    // IWTSListenerCallback\npublic:\n\tVOID CTsClientPlgn::SetChannel(IWTSVirtualChannel *pChannel);\npublic:\n    /*\n     *  Called whenever a request for new channel connection\n     *  from the server is received.\n     */\n    STDMETHOD(OnNewChannelConnection)(\n        IWTSVirtualChannel *pChannel,\n        BSTR data,           // optional data passed as part of the connect method\n        BOOL *pbAccept,      // the callee should return TRUE if connection is accepted\n        IWTSVirtualChannelCallback **ppCallback // connection related events\n        );\n    \n    // IWTSVirtualChannelCallback\npublic:\n\n    /*\n     *  Called whenever a full message from the server is received\n     *  The message is fully reassembled and has the exact size\n     *  as the Write() call on the server\n     */\n    STDMETHOD(OnDataReceived)(\n        ULONG cbSize,            // size of data in bytes\n        BYTE *pBuffer            // data buffer\n        );\n\n    /*\n     *  The channel is disconnected, all Write() calls will fail\n     *  no more incomming data is expected. \n     */\n    STDMETHOD(OnClose)();\n\nprivate:\n\n    HRESULT CleanState();\n\n\n    HRESULT StartFile(\n        __in_z LPWSTR szFileName,\n        BOOL bDir);\n\n    HRESULT WriteData(\n        __in_bcount(usLen) PBYTE pData,\n        USHORT usLen);\n\n    HRESULT EndFile(BOOL bDir);\n\n    CComPtr<IWTSListener> _spListener;\n    CComPtr<IWTSVirtualChannel> _spChannel;\n\n    HANDLE _hCurrentFile;\n\n    WStringVector _vDirList;\n};\n\n//OBJECT_ENTRY_AUTO(__uuidof(CompReg), CTsClientPlgn)\n\n\n// DEBUG:\n#define DEBUG_PRINT_BUFFER_SIZE 1024\n"
  },
  {
    "path": "UDVC-Plugin/UDVC-Plugin.rgs",
    "content": "HKCR\n{\n\tCLSID\n\t{\n\t\tUDVC-Plugin.UDVC-Plugin.1 = s 'UDVC-Plugin Class'\n\t\t{\n\t\t\tCLSID = s '{3C8458A3-2EBE-4840-BB07-3BA5BF810588}'\n\t\t}\n\t\tUDVC-Plugin.UDVC-Plugin = s 'UDVC-Plugin Class'\n\t\t{\n\t\t\tCLSID = s '{3C8458A3-2EBE-4840-BB07-3BA5BF810588}'\n\t\t\tCurVer = s 'UDVC-Plugin.UDVC-Plugin.1'\n\t\t}\n\t\tForceRemove {3C8458A3-2EBE-4840-BB07-3BA5BF810588} = s 'UDVC-Plugin Class'\n\t\t{\n\t\t\tProgID = s 'UDVC-Plugin.UDVC-Plugin.1'\n\t\t\tVersionIndependentProgID = s 'UDVC-Plugin.UDVC-Plugin'\n\t\t\tForceRemove 'Programmable'\n\t\t\tInprocServer32 = s '%MODULE%'\n\t\t\t{\n\t\t\t\tval ThreadingModel = s 'Free'\n\t\t\t}\n\t\t\t'TypeLib' = s '{392B9DEE-7E00-4C58-831B-50C58EAA887F}'\n\t\t}\t\t\n\t}\t\t\n}\n\nHKCU\n{ \n\tSoftware\n\t{\n\t\tMicrosoft\n\t\t{\n\t\t\t'Terminal Server Client'\n\t\t\t{\n\t\t\t\tDefault\n\t\t\t\t{\n\t\t\t\t\tAddIns\n\t\t\t\t\t{\n\t\t\t\t\t\tUDVC-Plugin\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tval Name = s '{3C8458A3-2EBE-4840-BB07-3BA5BF810588}'\n\t\t\t\t\t\t\tval namedpipename = s '\\\\.\\pipe\\UDVC_default'\n\t\t\t\t\t\t\tval ip = s '127.0.0.1'\n\t\t\t\t\t\t\tval port = s '31337'\n\t\t\t\t\t\t\tval mode = d '0'\n\t\t\t\t\t\t\tval enabled = d '1'\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "UDVC-Plugin/UDVC-Plugin.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{9402DF45-A060-4881-9F64-D16E094B97A7}</ProjectGuid>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n    <Keyword>AtlProj</Keyword>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IgnoreImportLibrary>true</IgnoreImportLibrary>\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IgnoreImportLibrary>true</IgnoreImportLibrary>\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IgnoreImportLibrary>true</IgnoreImportLibrary>\n    <LinkIncremental>false</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IgnoreImportLibrary>true</IgnoreImportLibrary>\n    <LinkIncremental>false</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Midl>\n      <MkTypLibCompatible>false</MkTypLibCompatible>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <HeaderFileName>UDVCPlugin_i.h</HeaderFileName>\n      <InterfaceIdentifierFileName>UDVCPlugin_i.c</InterfaceIdentifierFileName>\n      <ProxyFileName>UDVCPlugin_p.c</ProxyFileName>\n      <GenerateStublessProxies>true</GenerateStublessProxies>\n      <TypeLibraryName>$(IntDir)UDVCPlugin.tlb</TypeLibraryName>\n      <DllDataFileName />\n      <ValidateAllParameters>true</ValidateAllParameters>\n    </Midl>\n    <ResourceCompile>\n      <Culture>0x0409</Culture>\n      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <ModuleDefinitionFile>.\\UDVC-Plugin.def</ModuleDefinitionFile>\n      <AdditionalDependencies>comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_WINDOWS;_DEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Midl>\n      <MkTypLibCompatible>false</MkTypLibCompatible>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <HeaderFileName>UDVCPlugin_i.h</HeaderFileName>\n      <InterfaceIdentifierFileName>UDVCPlugin_i.c</InterfaceIdentifierFileName>\n      <ProxyFileName>UDVCPlugin_p.c</ProxyFileName>\n      <GenerateStublessProxies>true</GenerateStublessProxies>\n      <TypeLibraryName>$(IntDir)UDVCPlugin.tlb</TypeLibraryName>\n      <DllDataFileName />\n      <ValidateAllParameters>true</ValidateAllParameters>\n    </Midl>\n    <ResourceCompile>\n      <Culture>0x0409</Culture>\n      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <ModuleDefinitionFile>.\\UDVC-Plugin.def</ModuleDefinitionFile>\n      <AdditionalDependencies>comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Midl>\n      <MkTypLibCompatible>false</MkTypLibCompatible>\n      <TargetEnvironment>Win32</TargetEnvironment>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <HeaderFileName>UDVCPlugin_i.h</HeaderFileName>\n      <InterfaceIdentifierFileName>UDVCPlugin_i.c</InterfaceIdentifierFileName>\n      <ProxyFileName>UDVCPlugin_p.c</ProxyFileName>\n      <GenerateStublessProxies>true</GenerateStublessProxies>\n      <TypeLibraryName>$(IntDir)UDVCPlugin.tlb</TypeLibraryName>\n      <DllDataFileName />\n      <ValidateAllParameters>true</ValidateAllParameters>\n    </Midl>\n    <ResourceCompile>\n      <Culture>0x0409</Culture>\n      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <ModuleDefinitionFile>.\\UDVC-Plugin.def</ModuleDefinitionFile>\n      <AdditionalDependencies>comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>MaxSpeed</Optimization>\n      <PreprocessorDefinitions>_WINDOWS;NDEBUG;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Midl>\n      <MkTypLibCompatible>false</MkTypLibCompatible>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <HeaderFileName>UDVCPlugin_i.h</HeaderFileName>\n      <InterfaceIdentifierFileName>UDVCPlugin_i.c</InterfaceIdentifierFileName>\n      <ProxyFileName>UDVCPlugin_p.c</ProxyFileName>\n      <GenerateStublessProxies>true</GenerateStublessProxies>\n      <TypeLibraryName>$(IntDir)UDVCPlugin.tlb</TypeLibraryName>\n      <DllDataFileName />\n      <ValidateAllParameters>true</ValidateAllParameters>\n    </Midl>\n    <ResourceCompile>\n      <Culture>0x0409</Culture>\n      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ResourceCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <ModuleDefinitionFile>.\\UDVC-Plugin.def</ModuleDefinitionFile>\n      <AdditionalDependencies>comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"compreg.cpp\" />\n    <ClCompile Include=\"UDVC-Plugin.cpp\" />\n    <ClCompile Include=\"dllmain.cpp\">\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n      </PrecompiledHeader>\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n      </PrecompiledHeader>\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n      </PrecompiledHeader>\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n      </PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"stdafx.cpp\">\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Create</PrecompiledHeader>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">Create</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"dllfunc.cpp\" />\n    <ClCompile Include=\"UDVCPlugin_i.c\">\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n      </PrecompiledHeader>\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n      </PrecompiledHeader>\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n      </PrecompiledHeader>\n      <CompileAsManaged Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">false</CompileAsManaged>\n      <PrecompiledHeader Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n      </PrecompiledHeader>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"compreg.h\" />\n    <ClInclude Include=\"dllmain.h\" />\n    <ClInclude Include=\"Resource.h\" />\n    <ClInclude Include=\"stdafx.h\" />\n    <ClInclude Include=\"targetver.h\" />\n    <ClInclude Include=\"UDVC-Plugin.h\" />\n    <ClInclude Include=\"UDVCPlugin_i.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"UDVC-Plugin.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Text Include=\"ReadMe.txt\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"UDVC-Plugin.def\" />\n    <None Include=\"UDVC-Plugin.rgs\" />\n  </ItemGroup>\n  <ItemGroup>\n    <Midl Include=\"UDVCPlugin.idl\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "UDVC-Plugin/UDVC-Plugin.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Generated Files\">\n      <UniqueIdentifier>{2467f173-a17f-4363-a3f3-5f66776727f8}</UniqueIdentifier>\n      <SourceControlFiles>False</SourceControlFiles>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"stdafx.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"dllmain.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"compreg.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"UDVCPlugin_i.c\">\n      <Filter>Generated Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"dllfunc.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"UDVC-Plugin.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"stdafx.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"targetver.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"dllmain.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"compreg.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"UDVCPlugin_i.h\">\n      <Filter>Generated Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"UDVC-Plugin.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Resource.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"UDVC-Plugin.rc\">\n      <Filter>Resource Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <Text Include=\"ReadMe.txt\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"UDVC-Plugin.rgs\">\n      <Filter>Resource Files</Filter>\n    </None>\n    <None Include=\"UDVC-Plugin.def\">\n      <Filter>Source Files</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <Midl Include=\"UDVCPlugin.idl\">\n      <Filter>Source Files</Filter>\n    </Midl>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "UDVC-Plugin/UDVC-PluginPS.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{15DEE2D8-6972-49C0-9369-35730A29A2CF}</ProjectGuid>\n    <Keyword>AtlPSProj</Keyword>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)PS\\</IntDir>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)PS\\</IntDir>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <IntDir>$(Platform)\\$(Configuration)PS\\</IntDir>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <IntDir>$(Platform)\\$(Configuration)PS\\</IntDir>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PreprocessorDefinitions>WIN32;REGISTER_PROXY_DLL;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;ole32.lib;advapi32.lib;comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <ModuleDefinitionFile>UDVC-PluginPS.def</ModuleDefinitionFile>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n    <PreBuildEvent>\n      <Command>if exist dlldata.c goto :END\necho Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project.\nExit 1\n:END\n</Command>\n      <Message>Checking for required files</Message>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PreprocessorDefinitions>REGISTER_PROXY_DLL;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;ole32.lib;advapi32.lib;comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <ModuleDefinitionFile>UDVC-PluginPS.def</ModuleDefinitionFile>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n    <PreBuildEvent>\n      <Command>if exist dlldata.c goto :END\necho Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project.\nExit 1\n:END\n</Command>\n      <Message>Checking for required files</Message>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <PreprocessorDefinitions>WIN32;REGISTER_PROXY_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;ole32.lib;advapi32.lib;comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <ModuleDefinitionFile>UDVC-PluginPS.def</ModuleDefinitionFile>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n    <PreBuildEvent>\n      <Command>if exist dlldata.c goto :END\necho Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project.\nExit 1\n:END\n</Command>\n      <Message>Checking for required files</Message>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <Optimization>MaxSpeed</Optimization>\n      <PreprocessorDefinitions>REGISTER_PROXY_DLL;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n    </ClCompile>\n    <Link>\n      <AdditionalDependencies>kernel32.lib;rpcns4.lib;rpcrt4.lib;oleaut32.lib;uuid.lib;ole32.lib;advapi32.lib;comsvcs.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <ModuleDefinitionFile>UDVC-PluginPS.def</ModuleDefinitionFile>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <RegisterOutput>true</RegisterOutput>\n    </Link>\n    <PreBuildEvent>\n      <Command>if exist dlldata.c goto :END\necho Error: MIDL will not generate DLLDATA.C unless you have at least 1 interface in the main project.\nExit 1\n:END\n</Command>\n      <Message>Checking for required files</Message>\n    </PreBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <None Include=\"UDVC-Pluginps.def\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"dlldata.c\" />\n    <ClCompile Include=\"UDVCPlugin_i.c\" />\n    <ClCompile Include=\"UDVCPlugin_p.c\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "UDVC-Plugin/UDVC-PluginPS.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{3ae88138-7c28-4919-a9b2-4b5e1473c72b}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Generated Files\">\n      <UniqueIdentifier>{d3ce00e0-04ef-4a7b-ad63-435441b697a5}</UniqueIdentifier>\n      <SourceControlFiles>False</SourceControlFiles>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"UDVC-Pluginps.def\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"UDVCPlugin_i.c\">\n      <Filter>Generated Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"UDVCPlugin_p.c\">\n      <Filter>Generated Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"dlldata.c\">\n      <Filter>Generated Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "UDVC-Plugin/UDVC-Pluginps.def",
    "content": "\nLIBRARY\n\nEXPORTS\n\tDllGetClassObject\t\tPRIVATE\n\tDllCanUnloadNow\t\t\tPRIVATE\n\tDllRegisterServer\t\tPRIVATE\n\tDllUnregisterServer\t\tPRIVATE\n"
  },
  {
    "path": "UDVC-Plugin/UDVCPlugin.idl",
    "content": "// UDVCPlugin.idl : IDL source for UDVC-Plugin\n//\n\n// This file will be processed by the MIDL tool to\n// produce the type library (UDVCPlugin.tlb) and marshalling code.\n\nimport \"oaidl.idl\";\nimport \"ocidl.idl\";\n\n[\n\tobject,\n\tuuid(a817e7a2-43fa-11d0-9e44-00aa00b6770a),\n\tdual,\t\n\tpointer_default(unique)\n]\ninterface IComponentRegistrar : IDispatch\n{\n\t[id(1)]\tHRESULT Attach([in] BSTR bstrPath);\n\t[id(2)]\tHRESULT RegisterAll();\n\t[id(3)]\tHRESULT UnregisterAll();\n\t[id(4)]\tHRESULT GetComponents([out] SAFEARRAY(BSTR)* pbstrCLSIDs, [out] SAFEARRAY(BSTR)* pbstrDescriptions);\n\t[id(5)]\tHRESULT RegisterComponent([in] BSTR bstrCLSID);\n\t[id(6)] HRESULT UnregisterComponent([in] BSTR bstrCLSID);\n};\n\n[\n\tuuid(392B9DEE-7E00-4C58-831B-50C58EAA887F),\n\tversion(1.0),\n\tcustom(a817e7a1-43fa-11d0-9e44-00aa00b6770a,\"{3C8458A3-2EBE-4840-BB07-3BA5BF810588}\")\n]\nlibrary UDVCPluginLib\n{\n\timportlib(\"stdole2.tlb\");\n\t[\n\t\tuuid(3C8458A3-2EBE-4840-BB07-3BA5BF810588)\t\t\n\t]\n\tcoclass CompReg\n\t{\n\t\t[default] interface IComponentRegistrar;\n\t};\n};\n\n"
  },
  {
    "path": "UDVC-Plugin/compreg.cpp",
    "content": "// compreg.cpp : Implementation of CCompReg\n\n#include \"stdafx.h\"\n#include \"compreg.h\"\n\n\n// CCompReg\n"
  },
  {
    "path": "UDVC-Plugin/compreg.h",
    "content": "// compreg.h : Declaration of the CCompReg\n\n#pragma once\n\n#include \"resource.h\"       // main symbols\n#include \"UDVCPlugin_i.h\"\n \n"
  },
  {
    "path": "UDVC-Plugin/dllfunc.cpp",
    "content": "/*\n* MIT License\n*\n* Copyright(c) 2018 Balazs Bucsay\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files(the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions :\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*/\n\n#include \"stdafx.h\"\n#include \"resource.h\"\n#include \"UDVCPlugin_i.h\"\n#include \"dllmain.h\"\n#include \"compreg.h\"\n\n\nusing namespace ATL;\n\n// Used to determine whether the DLL can be unloaded by OLE.\nSTDAPI DllCanUnloadNow(void)\n{\n\t\t\treturn _AtlModule.DllCanUnloadNow();\n\t}\n\n// Returns a class factory to create an object of the requested type.\n_Check_return_\nSTDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _Outptr_ LPVOID* ppv)\n{\n\t\treturn _AtlModule.DllGetClassObject(rclsid, riid, ppv);\n}\n\n// DllRegisterServer - Adds entries to the system registry.\nSTDAPI DllRegisterServer(void)\n{\n\t// registers object, typelib and all interfaces in typelib\n\tHRESULT hr = _AtlModule.DllRegisterServer();\n\t\treturn hr;\n}\n\n// DllUnregisterServer - Removes entries from the system registry.\nSTDAPI DllUnregisterServer(void)\n{\n\tHRESULT hr = _AtlModule.DllUnregisterServer();\n\t\treturn hr;\n}\n\n// DllInstall - Adds/Removes entries to the system registry per user per machine.\nSTDAPI DllInstall(BOOL bInstall, _In_opt_  LPCWSTR pszCmdLine)\n{\n\tHRESULT hr = E_FAIL;\n\tstatic const wchar_t szUserSwitch[] = L\"user\";\n\n\tif (pszCmdLine != NULL)\n\t{\n\t\tif (_wcsnicmp(pszCmdLine, szUserSwitch, _countof(szUserSwitch)) == 0)\n\t\t{\n\t\t\tATL::AtlSetPerUserRegistration(true);\n\t\t}\n\t}\n\n\tif (bInstall)\n\t{\t\n\t\thr = DllRegisterServer();\n\t\tif (FAILED(hr))\n\t\t{\n\t\t\tDllUnregisterServer();\n\t\t}\n\t}\n\telse\n\t{\n\t\thr = DllUnregisterServer();\n\t}\n\n\treturn hr;\n}\n\n\n"
  },
  {
    "path": "UDVC-Plugin/dllmain.cpp",
    "content": "/*\n* MIT License\n*\n* Copyright(c) 2018 Balazs Bucsay\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files(the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions :\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*/\n\n#include \"stdafx.h\"\n#include \"resource.h\"\n#include \"UDVCPlugin_i.h\"\n#include \"dllmain.h\"\n#include \"compreg.h\"\n\nCUDVCPluginModule _AtlModule;\n\n// DLL Entry Point\nextern \"C\" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)\n{\n\thInstance;\n\treturn _AtlModule.DllMain(dwReason, lpReserved); \n}\n"
  },
  {
    "path": "UDVC-Plugin/dllmain.h",
    "content": "// dllmain.h : Declaration of module class.\n\nclass CUDVCPluginModule : public ATL::CAtlDllModuleT< CUDVCPluginModule >\n{\npublic :\n\tDECLARE_LIBID(LIBID_UDVCPluginLib)\n\tDECLARE_REGISTRY_APPID_RESOURCEID(IDR_UDVCPLUGIN, \"{B8DC075B-7F8D-4B06-8733-7EB586CA06F0}\")\n};\n\nextern class CUDVCPluginModule _AtlModule;\n"
  },
  {
    "path": "UDVC-Plugin/stdafx.cpp",
    "content": "/*\n* MIT License\n*\n* Copyright(c) 2018 Balazs Bucsay\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files(the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions :\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*/\n\n#include \"stdafx.h\"\n"
  },
  {
    "path": "UDVC-Plugin/stdafx.h",
    "content": "// stdafx.h : include file for standard system include files,\n// or project specific include files that are used frequently,\n// but are changed infrequently\n\n#pragma once\n\n#ifndef STRICT\n#define STRICT\n#endif\n\n#include \"targetver.h\"\n\n#define _ATL_APARTMENT_THREADED\n#define _ATL_NO_AUTOMATIC_NAMESPACE\n\n#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS\t// some CString constructors will be explicit\n#define _ATL_REGISTER_PER_USER  // This setting must be consistent with the project's RGS file\n\n\n#include \"resource.h\"\n//#include <afx.h>\n#include <atlbase.h>\n#include <atlcom.h>\n#include <atlctl.h>\n\nusing namespace ATL;\n\n// adtn'l includes\n#include <ShlObj.h>\n#include <TsVirtualChannels.h>\n#include <IntSafe.h>\n\n#include <fstream>\n#include <vector>\n\n#include <winsock2.h>\n#include <Ws2tcpip.h>\n#include <windows.h>\n\ntypedef std::basic_ofstream<BYTE> ByteFile;\ntypedef std::basic_string<WCHAR> WString;\ntypedef std::vector<WString> WStringVector;\n"
  },
  {
    "path": "UDVC-Plugin/targetver.h",
    "content": "#pragma once\n\n// Including SDKDDKVer.h defines the highest available Windows platform.\n\n// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and\n// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.\n\n#include <SDKDDKVer.h>\n"
  },
  {
    "path": "UDVC-Plugin.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 14\nVisualStudioVersion = 14.0.25420.1\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"UDVC-Plugin\", \"UDVC-Plugin\\UDVC-Plugin.vcxproj\", \"{9402DF45-A060-4881-9F64-D16E094B97A7}\"\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"UDVC-PluginPS\", \"UDVC-Plugin\\UDVC-PluginPS.vcxproj\", \"{15DEE2D8-6972-49C0-9369-35730A29A2CF}\"\n\tProjectSection(ProjectDependencies) = postProject\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7} = {9402DF45-A060-4881-9F64-D16E094B97A7}\n\tEndProjectSection\nEndProject\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"UDVC-Server\", \"UDVC-Server\\UDVC-Server.vcxproj\", \"{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tDebug|x86 = Debug|x86\n\t\tRelease|x64 = Release|x64\n\t\tRelease|x86 = Release|x86\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Debug|x64.Build.0 = Debug|x64\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Debug|x86.Build.0 = Debug|Win32\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Release|x64.ActiveCfg = Release|x64\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Release|x64.Build.0 = Release|x64\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Release|x86.ActiveCfg = Release|Win32\n\t\t{9402DF45-A060-4881-9F64-D16E094B97A7}.Release|x86.Build.0 = Release|Win32\n\t\t{15DEE2D8-6972-49C0-9369-35730A29A2CF}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{15DEE2D8-6972-49C0-9369-35730A29A2CF}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{15DEE2D8-6972-49C0-9369-35730A29A2CF}.Release|x64.ActiveCfg = Release|x64\n\t\t{15DEE2D8-6972-49C0-9369-35730A29A2CF}.Release|x86.ActiveCfg = Release|Win32\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Debug|x64.Build.0 = Debug|x64\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Debug|x86.ActiveCfg = Debug|Win32\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Debug|x86.Build.0 = Debug|Win32\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Release|x64.ActiveCfg = Release|x64\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Release|x64.Build.0 = Release|x64\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Release|x86.ActiveCfg = Release|Win32\n\t\t{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}.Release|x86.Build.0 = Release|Win32\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "UDVC-Server/UDVC-Server.cpp",
    "content": "/*\n * MIT License\n *\n * Copyright(c) 2018-2020 Balazs Bucsay\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files(the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and / or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions :\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\n#include <winsock2.h>\n#include <Ws2tcpip.h>\n#include <windows.h>\n#include <wtsapi32.h>\n#include <pchannel.h>\n#include <crtdbg.h>\n#include <stdio.h>\n\n\n#pragma comment(lib, \"wtsapi32.lib\")\n#pragma comment(lib, \"Ws2_32.lib\")\n\n#define UDVC_CHANNEL_NAME \"UniversalDVC\"\n\nDWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE *phFile);\nDWORD WINAPI RcWsThread(PVOID param);\nDWORD WINAPI RsWcThread(PVOID param);\n\nstruct arguments {\n\tDWORD\tmode; // 0 socket; 1 namedpiep\n\tWCHAR\t*namedpipename;\n\tWCHAR\t*ip;\n\tWCHAR\t*port;\n\tBYTE\tpriority;\n} running_args;\n\nstruct threadhandles {\n\tHANDLE\thRDP = NULL;\n\tSOCKET\tsock = NULL;\n\tHANDLE\tpipe = NULL;\n};\n\nHANDLE      hEvent_RDP_global;\n\nVOID usage(WCHAR *cmdname)\n{\n\twprintf(L\"Usage: %s [-s | -c [-p port [-i ip]] | -m [-n name]] [-0 | -1 | -2 | -3]\\n\"\n\t\t\"Socket server mode -s (default)\\n\"\n\t\t\"\\t-p port\\t  port to bind the listener (default: 31337)\\n\"\n\t\t\"\\t-i ip\\t  ip to bind the listener (default: 127.0.0.1)\\n\\n\"\n\t\t\"OR \\n\"\n\t\t\"Socket client mode -c:\\n\"\n\t\t\"\\t-p port\\t  port to connect to\\n\"\n\t\t\"\\t-i ip\\t  ip to connect to\\n\\n\"\n\t\t\"Named pipe mode -m:\\n\"\n\t\t\"\\t-n name\\t  name of the named pipe (by default: \\\"\\\\\\\\.\\\\pipe\\\\UDVC_{RDP SESSION NUMBER}\\\")\\n\\n\"\n\t\t\"Data transfer priority parameters:\\n\"\n\t\t\"\\t-0\\t  real time\\t\\t(WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL)\\n\"\n\t\t\"\\t-1\\t  high priority\\t\\t(WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH) - default\\n\"\n\t\t\"\\t-2\\t  medium priority\\t(WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED)\\n\"\n\t\t\"\\t-3\\t  low priority\\t\\t(WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW)\\n\", cmdname);\n\n\treturn;\n}\n\nBOOL parse_argv(INT argc, __in_ecount(argc) WCHAR **argv)\n{\n\tint num = 0;\n\n\twhile (num < argc - 1)\n\t{\n\t\tnum++;\n\n\t\tif (wcsncmp(argv[num], L\"-\", 1))\n\t\t{\n\t\t\twprintf(L\"[-] Invalid argument: %s\\n\", argv[num]);\n\t\t\tusage(argv[0]);\n\t\t\treturn FALSE;\n\t\t}\n\n\t\tswitch (argv[num][1])\n\t\t{\n\t\t\tcase 'h':\n\t\t\tcase '?':\n\t\t\t\tusage(argv[0]);\n\t\t\t\treturn FALSE;\n\t\t\tcase 'c':\n\t\t\t\trunning_args.mode = 1;\n\t\t\t\tbreak;\n\t\t\tcase 'm':\n\t\t\t\trunning_args.mode = 2;\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\tnum++;\n\n\t\t\t\tif (wcsncmp(argv[num], L\"\\\\\\\\.\\\\pipe\\\\\", 9))\n\t\t\t\t{\n\t\t\t\t\twprintf(L\"[-] Named pipe name has to start with: \\\\\\\\.\\\\pipe\\\\\\n\");\n\t\t\t\t\tusage(argv[0]);\n\t\t\t\t\treturn FALSE;\n\t\t\t\t}\n\t\t\t\trunning_args.namedpipename = argv[num];\n\t\t\t\tbreak;\n\n\t\t\tcase 's':\n\t\t\t\trunning_args.mode = 0;\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\t\tnum++;\n\n\t\t\t\trunning_args.port = argv[num];\n\t\t\t\tbreak;\n\t\t\tcase 'i':\n\t\t\t\tnum++;\n\n\t\t\t\trunning_args.ip = argv[num];\n\t\t\t\tbreak;\n\n\t\t\tcase '0':\n\t\t\t\trunning_args.priority = WTS_CHANNEL_OPTION_DYNAMIC_PRI_REAL;\n\t\t\t\tbreak;\n\t\t\tcase '1':\n\t\t\t\trunning_args.priority = WTS_CHANNEL_OPTION_DYNAMIC_PRI_HIGH;\n\t\t\t\tbreak;\n\t\t\tcase '2':\n\t\t\t\trunning_args.priority = WTS_CHANNEL_OPTION_DYNAMIC_PRI_MED;\n\t\t\t\tbreak;\n\t\t\tcase '3':\n\t\t\t\trunning_args.priority = WTS_CHANNEL_OPTION_DYNAMIC_PRI_LOW;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\twprintf(L\"[-] Invalid argument: %s\\n\", argv[num]);\n\t\t\t\tusage(argv[0]);\n\t\t\t\treturn FALSE;\n\t\t}\n\t}\n\treturn TRUE;\n}\n\nULONG GetCurrentSessionId(void) {\n\tLPTSTR\tpBuf;\n\tDWORD\tlen;\n\tULONG\tret;\n\n\tif (!WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSSessionId, &pBuf, &len))\n\t{\n\t\treturn -1;\n\t}\n\n\tret = (ULONG)*pBuf;\n\tWTSFreeMemory(pBuf);\n\t\n\treturn ret;\n}\n\nINT _cdecl wmain(INT argc, __in_ecount(argc) WCHAR **argv)\n{\n\tHANDLE\thFile;\n\tWSADATA\twsaData;\n\tADDRINFOW *result = NULL;\n\tADDRINFOW hints;\n\tSOCKET\ts, c;\n\tWCHAR\ttempnamepipename[24];\n\tHANDLE\thNamedPipe = NULL;\n\tULONG\tsessionId;\n\tint\t\tret;\n\n\tstruct threadhandles threadhandle;\n\n\tsessionId = GetCurrentSessionId();\n\twsprintf(tempnamepipename, L\"\\\\\\\\.\\\\pipe\\\\UDVC_%08X\", sessionId);\n\n\trunning_args.mode = 0;\n\trunning_args.port = L\"31337\";\n\trunning_args.priority = 4;\n\trunning_args.namedpipename = tempnamepipename;\n\trunning_args.ip = L\"127.0.0.1\";\n\n\twprintf(L\"Universal Dynamic Virtual Channel server application\\n\\n\");\n\n\tif (argc > 1)\n\t\tif (!parse_argv(argc, argv))\n\t\t\treturn -1;\n\n\t\n\tif ((ret = OpenDynamicChannel(UDVC_CHANNEL_NAME, &hFile)) != ERROR_SUCCESS)\n\t{\n\t\tif (ret == 31)\n\t\t\twprintf(L\"[-] Could not open Dynamic Virtual Channel, plugin was not loaded on the client side: %ld\\n\", ret);\n\t\telse\n\t\t\twprintf(L\"[-] Could not open Dynamic Virtual Channel: %ld\\n\", ret);\n\t\treturn -1;\n\t}\n\n\tif (running_args.mode == 0)\n\t{\n\t\twprintf(L\"[*] Setting up server socket\\n\");\n\t\tif ((ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)\n\t\t{ \n\t\t\twprintf(L\"[-] WSAStartup() failed with error: %ld\\n\", ret);\n\t\t\treturn -1;\n\t\t}\n\n\t\tZeroMemory(&hints, sizeof(hints));\n\t\thints.ai_family = AF_INET;\n\t\thints.ai_socktype = SOCK_STREAM;\n\t\thints.ai_protocol = IPPROTO_TCP;\n\t\thints.ai_flags = AI_PASSIVE;\n\n\t\tif ((ret = GetAddrInfoW(running_args.ip, running_args.port, &hints, &result)) != 0) {\n\t\t\twprintf(L\"[-] GetAddrInfoW() failed with error: %ld\\n\", ret);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((s = socket(result->ai_family, result->ai_socktype, result->ai_protocol)) == INVALID_SOCKET) {\n\t\t\twprintf(L\"[-] socket() failed with error: %ld\\n\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((ret = bind(s, result->ai_addr, (int)result->ai_addrlen)) == SOCKET_ERROR) {\n\t\t\twprintf(L\"[-] bind() failed with error: %ld\\n\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\tclosesocket(s);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\t\tFreeAddrInfoW(result);\n\t\twprintf(L\"[*] Listening on: %s:%s\\n\", running_args.ip, running_args.port);\n\n\t\tif ((ret = listen(s, SOMAXCONN)) == SOCKET_ERROR) {\n\t\t\twprintf(L\"[-] listen() failed with error: %ld\\n\", WSAGetLastError());\n\t\t\tclosesocket(s);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((c = accept(s, NULL, NULL)) == INVALID_SOCKET) {\n\t\t\twprintf(L\"[-] accept() failed with error: %ld\\n\", WSAGetLastError());\n\t\t\tclosesocket(s);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\t\twprintf(L\"[+] Client connected\\n\");\n\n\t\tclosesocket(s);\n\n\t\tu_long blocking = 0;\n\t\tret = ioctlsocket(c, FIONBIO, &blocking);\n\t\tif (ret != NO_ERROR)\n\t\t{\n\t\t\twprintf(L\"[-] ioctlsocket() failed with error: %ld\\n\", ret);\n\t\t\tclosesocket(c);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\t\tthreadhandle.sock = c;\n\t}\n\tif (running_args.mode == 1)\n\t{\n\t\twprintf(L\"[*] Setting up client socket\\n\");\n\t\tif ((ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)\n\t\t{\n\t\t\twprintf(L\"[-] WSAStartup() failed with error: %ld\\n\", ret);\n\t\t\treturn -1;\n\t\t}\n\n\t\tZeroMemory(&hints, sizeof(hints));\n\t\thints.ai_family = AF_INET;\n\t\thints.ai_socktype = SOCK_STREAM;\n\t\thints.ai_protocol = IPPROTO_TCP;\n\t\thints.ai_flags = AI_PASSIVE;\n\n\t\tif ((ret = GetAddrInfoW(running_args.ip, running_args.port, &hints, &result)) != 0) {\n\t\t\twprintf(L\"[-] GetAddrInfoW() failed with error: %ld\\n\", ret);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((c = socket(result->ai_family, result->ai_socktype, result->ai_protocol)) == INVALID_SOCKET) {\n\t\t\twprintf(L\"[-] socket() failed with error: %ld\\n\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\n\t\tif ((ret = connect(c, result->ai_addr, (int)result->ai_addrlen)) == SOCKET_ERROR) {\n\t\t\twprintf(L\"[-] connect() failed with error: %ld\\n\", WSAGetLastError());\n\t\t\tFreeAddrInfoW(result);\n\t\t\tclosesocket(c);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\t\tFreeAddrInfoW(result);\n\t\twprintf(L\"[*] Connected to: %s:%s\\n\", running_args.ip, running_args.port);\n\n\t\tu_long blocking = 0;\n\t\tret = ioctlsocket(c, FIONBIO, &blocking);\n\t\tif (ret != NO_ERROR)\n\t\t{\n\t\t\twprintf(L\"[-] ioctlsocket() failed with error: %ld\\n\", ret);\n\t\t\tclosesocket(c);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\t\tthreadhandle.sock = c;\n\t}\n\tif (running_args.mode == 2)\n\t{\n\t\twprintf(L\"[*] Setting up named pipe\\n\");\n\n\t\tif ((hNamedPipe = CreateNamedPipe(running_args.namedpipename, \n\t\t\tPIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,\n\t\t\tPIPE_TYPE_BYTE | PIPE_WAIT | PIPE_REJECT_REMOTE_CLIENTS, 1, 4096, 4096, \n\t\t\tNMPWAIT_USE_DEFAULT_WAIT, NULL)) == INVALID_HANDLE_VALUE)\n\t\t{\n\t\t\twprintf(L\"[-] CreateNamedPipe() failed with: %ld\", GetLastError());\n\t\t\treturn -1;\n\t\t}\n\n\t\twprintf(L\"[*] Listening on pipe: %s\\n\", running_args.namedpipename);\n\t\tif (!ConnectNamedPipe(hNamedPipe, NULL))\n\t\t{\n\t\t\twprintf(L\"[-] ConnectNamedPipe() failed with: %ld\", GetLastError());\n\t\t\treturn -1;\n\t\t}\n\n\t\tthreadhandle.pipe = hNamedPipe;\n\t\twprintf(L\"[+] Client connected to the pipe.\\n\");\n\t}\n\n\tthreadhandle.hRDP = hFile;\n\n\twprintf(L\"[*] Starting thread RsWc\\n\");\n\tDWORD dwThreadId;\n\tHANDLE hReadThread = CreateThread(\n\t\tNULL,\n\t\t0,\n\t\tRsWcThread,\n\t\t&threadhandle,\n\t\t0,\n\t\t&dwThreadId);\n\n\twprintf(L\"[*] Starting thread RcWs\\n\");\n\tHANDLE hWriteThread = CreateThread(\n\t\tNULL,\n\t\t0,\n\t\tRcWsThread,\n\t\t&threadhandle,\n\t\t0,\n\t\t&dwThreadId);\n\n\tHANDLE ah[] = { hReadThread, hWriteThread };\n\tprintf(\"[*] Waiting for threads to exit...\\n\");\n\tWaitForMultipleObjects(2, ah, TRUE, INFINITE);\n\n\tif (running_args.mode)\n\t{\n\t\tif ((ret = shutdown(c, SD_BOTH)) == SOCKET_ERROR) {\n\t\t\twprintf(L\"[-] shutdown() failed with error: %d\\n\", WSAGetLastError());\n\t\t\tclosesocket(c);\n\t\t\tWSACleanup();\n\t\t\treturn -1;\n\t\t}\n\t\tclosesocket(c);\n\t\tWSACleanup();\n\t}\n\telse\n\t{\n\t\tCloseHandle(hNamedPipe);\n\t}\n\n\tCloseHandle(hReadThread);\n\tCloseHandle(hWriteThread);\n\tCloseHandle(hFile);\n\n\treturn 0;\n}\n\n/*\n*  Open a dynamic channel with the name given in szChannelName.\n*  The output file handle can be used in ReadFile/WriteFile calls.\n*/\nDWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE *phFile)\n{\n\tHANDLE\thWTSHandle = NULL;\n\tHANDLE\thWTSFileHandle;\n\tPVOID\tvcFileHandlePtr = NULL;\n\tDWORD\tlen;\n\tDWORD\trc = ERROR_SUCCESS;\n\tBOOL\tfSucc;\n\n\thWTSHandle = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, (LPSTR)szChannelName,\n\t\tWTS_CHANNEL_OPTION_DYNAMIC | running_args.priority);\n\tif (NULL == hWTSHandle)\n\t{\n\t\trc = GetLastError();\n\t\tgoto exitpt;\n\t}\n\n\tfSucc = WTSVirtualChannelQuery(hWTSHandle, WTSVirtualFileHandle,\n\t\t&vcFileHandlePtr, &len);\n\tif (!fSucc)\n\t{\n\t\trc = GetLastError();\n\t\tgoto exitpt;\n\t}\n\tif (len != sizeof(HANDLE))\n\t{\n\t\trc = ERROR_INVALID_PARAMETER;\n\t\tgoto exitpt;\n\t}\n\n\thWTSFileHandle = *(HANDLE *)vcFileHandlePtr;\n\n\tfSucc = DuplicateHandle(GetCurrentProcess(), hWTSFileHandle, \n\t\tGetCurrentProcess(), phFile, 0, FALSE, DUPLICATE_SAME_ACCESS);\n\n\tif (!fSucc)\n\t{\n\t\trc = GetLastError();\n\t\tgoto exitpt;\n\t}\n\n\trc = ERROR_SUCCESS;\n\nexitpt:\n\tif (vcFileHandlePtr)\n\t{\n\t\tWTSFreeMemory(vcFileHandlePtr);\n\t}\n\tif (hWTSHandle)\n\t{\n\t\tWTSVirtualChannelClose(hWTSHandle);\n\t}\n\n\treturn rc;\n}\n\n/* \n * Thread that reads the socket or named pipe and writes the stream to the \n * RDP virtual channel. \n */\nDWORD WINAPI RsWcThread(PVOID param)\n{\n\tstruct threadhandles *handles = (struct threadhandles *)param;\n\tDWORD   dwWritten;\n\tDWORD\tdw;\n\tBOOL    bSucc;\n\tHANDLE  hEvent_rdp, hEvent_pipe;\n\tchar\t*readBuf;\n\tDWORD\theapsize = 4096;\n\n\tif ((readBuf = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, heapsize)) == NULL)\n\t{\n\t\twprintf(L\"[-] Error allocating heap for read buffer %ld\\n\", GetLastError());\n\t\treturn -1;\n\t}\n\n\thEvent_rdp = CreateEvent(NULL, FALSE, FALSE, NULL);\n\tOVERLAPPED Overlapped = { 0 };\n\tOverlapped.hEvent = hEvent_rdp;\n\n\thEvent_pipe = CreateEvent(NULL, FALSE, FALSE, NULL);\n\tOVERLAPPED Overlapped_pipe = { 0 };\n\tOverlapped_pipe.hEvent = hEvent_pipe;\n\n\twhile (TRUE)\n\t{\t\n\t\tif (handles->sock)\n\t\t{\n\t\t\tif ((dw = recv(handles->sock, readBuf, heapsize, 0)) == SOCKET_ERROR)\n\t\t\t{\n\t\t\t\twprintf(L\"[-] [RsWc] recv() failed with error %d, exiting thread...\\n\", WSAGetLastError());\n\t\t\t\tSetEvent(hEvent_RDP_global);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (dw == 0)\n\t\t\t{\n\t\t\t\twprintf(L\"[-] [RsWc] socket closed, exiting thread...\\n\");\n\t\t\t\tSetEvent(hEvent_RDP_global);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tif (handles->pipe)\n\t\t{\n\t\t\tbSucc = ReadFile(handles->pipe, readBuf, heapsize, &dw, &Overlapped_pipe);\n\t\t\tif (!bSucc)\n\t\t\t{\n\t\t\t\tif (GetLastError() == ERROR_IO_PENDING)\n\t\t\t\t{\n\t\t\t\t\tdw = WaitForSingleObject(Overlapped_pipe.hEvent, INFINITE);\n\t\t\t\t\tbSucc = GetOverlappedResult(handles->pipe, &Overlapped_pipe, &dw, FALSE);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!bSucc)\n\t\t\t{\n\t\t\t\twprintf(L\"[-] [RsWc] ReadFile()/WaitForSingleObject() error: %ld\\n\", GetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\n\t\t\tif (ResetEvent(Overlapped_pipe.hEvent) == FALSE)\n\t\t\t{\n\t\t\t\twprintf(L\"[-] [RsWc] ResetEvent() failed with error = %ld\\n\", GetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\n\t\tbSucc = WriteFile(handles->hRDP, readBuf, dw, &dwWritten, &Overlapped);\n\t\tif (!bSucc)\n\t\t{\n\t\t\tif (GetLastError() == ERROR_IO_PENDING)\n\t\t\t{\n\t\t\t\tdw = WaitForSingleObject(Overlapped.hEvent, INFINITE);\n\t\t\t\tbSucc = GetOverlappedResult(handles->hRDP, &Overlapped, &dwWritten, FALSE);\n\t\t\t}\n\t\t}\n\t\tif (!bSucc)\n\t\t{\n\t\t\twprintf(L\"[-] [RsWc] WriteFile()/WaitForSingleObject() error: %ld\\n\", GetLastError());\n\t\t\treturn -1;\n\t\t}\n\t}\n\treturn 0;\n}\n\n/* \n * Thread that reads the RDP virtual channel and writes the stream to the \n * socket or named pipe. \n */\nDWORD WINAPI RcWsThread(PVOID param)\n{\n\tstruct threadhandles *handles = (struct threadhandles *)param;\n\tBYTE        ReadBuffer[CHANNEL_PDU_LENGTH];\n\tCHANNEL_PDU_HEADER *pHdr = (CHANNEL_PDU_HEADER *)ReadBuffer;\n\tPBYTE\t\tpData;\n\tDWORD       dwRead, ret, Flags, dw;\n\tBOOL        bSucc;\n\tchar\t\t*bufWrite;\n\tDWORD\t\tbufWritelen;\n\n\thEvent_RDP_global = CreateEvent(NULL, FALSE, FALSE, NULL);\n\tOVERLAPPED  Overlapped = { 0 };\n\tDWORD TotalRead = 0;\n\n\tOverlapped.hEvent = hEvent_RDP_global;\n\twhile (TRUE)\n\t{\n\t\tbSucc = ReadFile(handles->hRDP, ReadBuffer, sizeof(ReadBuffer), &dwRead, &Overlapped);\n\t\tif (!bSucc)\n\t\t{\n\t\t\tif (GetLastError() == ERROR_IO_PENDING)\n\t\t\t{\n\t\t\t\tdw = WaitForSingleObject(Overlapped.hEvent, INFINITE);\n\t\t\t\tbSucc = GetOverlappedResult(handles->hRDP, &Overlapped, &dwRead, FALSE);\n\t\t\t}\n\t\t}\n\t\tpData = (PBYTE)(pHdr + 1);\n\n\t\tif (!bSucc)\n\t\t{\n\t\t\twprintf(L\"[-] [RcWs] ReadFile()/WaitForSingleObject() error: %ld\\n\", GetLastError());\n\t\t\tif (handles->sock)\n\t\t\t\tclosesocket(handles->sock);\n\t\t\treturn -1;\n\t\t}\n\n\t\t/*\n\t\t// Event was created with bManualReset FALSE, no need to reset it.\n\t\tif ((ret = ResetEvent(Overlapped.hEvent)) == FALSE)\n\t\t{\n\t\t\twprintf(L\"[-] [RcWs] ResetEvent() failed with error = %ld\\n\", GetLastError());\n\t\t\treturn -1;\n\t\t}*/\n\n\t\t// no need to pass the header.\n\t\tbufWrite = (char *)(pHdr + 1);\n\t\t/*\n\t\tWSAdata.len = pHdr->length;\n\t\tpHdr->length stores the full length of the packet, we only need that \n\t\twas received. Ignoring the header flags as well, we just proxy the \n\t\tbytes. This is not that nice though.\n\t\t*/\n\t\tbufWritelen = dwRead - sizeof(CHANNEL_PDU_HEADER);\n\t\tFlags = 0;\n\n\t\tif (handles->sock)\n\t\t{\n\t\t\tif ((ret = send(handles->sock, bufWrite, bufWritelen, 0)) == SOCKET_ERROR)\n\t\t\t{\n\t\t\t\twprintf(L\"[-] [RsWc] send() failed with error %ld\\n\", WSAGetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\tif (handles->pipe)\n\t\t{\n\t\t\tbSucc = WriteFile(handles->pipe, bufWrite, bufWritelen, &ret, &Overlapped);\n\t\t\tif (!bSucc)\n\t\t\t{\n\t\t\t\tif (GetLastError() == ERROR_IO_PENDING)\n\t\t\t\t{\n\t\t\t\t\tdw = WaitForSingleObject(Overlapped.hEvent, INFINITE);\n\t\t\t\t\tbSucc = GetOverlappedResult(handles->pipe, &Overlapped, &ret, FALSE);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!bSucc)\n\t\t\t{\n\t\t\t\twprintf(L\"[-] [RsWc] WriteFile()/WaitForSingleObject() error: %ld\\n\", GetLastError());\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "UDVC-Server/UDVC-Server.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C7E1D0A7-0ADA-4DF4-99DA-8527E856670F}</ProjectGuid>\n    <Keyword>Win32Proj</Keyword>\n    <RootNamespace>UDVCServer</RootNamespace>\n    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>Application</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v140</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\" Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <LinkIncremental>true</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <LinkIncremental>false</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <LinkIncremental>false</LinkIncremental>\n    <OutDir>$(SolutionDir)$(Configuration)\\$(Platform)\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <WarningLevel>Level3</WarningLevel>\n      <Optimization>Disabled</Optimization>\n      <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <PrecompiledHeader>NotUsing</PrecompiledHeader>\n      <Optimization>MaxSpeed</Optimization>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <SDLCheck>true</SDLCheck>\n    </ClCompile>\n    <Link>\n      <SubSystem>Console</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <Text Include=\"ReadMe.txt\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"targetver.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"UDVC-Server.cpp\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "UDVC-Server/UDVC-Server.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\n      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\n      <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <Text Include=\"ReadMe.txt\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"targetver.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"UDVC-Server.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "UDVC-Server/targetver.h",
    "content": "#pragma once\n\n// Including SDKDDKVer.h defines the highest available Windows platform.\n\n// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and\n// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.\n\n#include <SDKDDKVer.h>\n"
  }
]