HANDLE StopEvent;
HANDLE AddEvent;
HANDLE RemoveEvent;
+ PTCHAR Executable;
HDEVNOTIFY InterfaceNotification;
PTCHAR DevicePath;
HDEVNOTIFY DeviceNotification;
HANDLE Device;
+ HANDLE ThreadEvent;
+ HANDLE Thread;
} MONITOR_CONTEXT, *PMONITOR_CONTEXT;
MONITOR_CONTEXT MonitorContext;
return FALSE;
}
+DWORD WINAPI
+MonitorThread(
+ IN LPVOID Argument
+ )
+{
+ PMONITOR_CONTEXT Context = &MonitorContext;
+ DWORD CommandLineLength;
+ PTCHAR CommandLine;
+ PROCESS_INFORMATION ProcessInfo;
+ STARTUPINFO StartupInfo;
+ BOOL Success;
+ HANDLE Handle[2];
+ DWORD Object;
+ HRESULT Error;
+
+ UNREFERENCED_PARAMETER(Argument);
+
+ Log("====>");
+
+ CommandLineLength = (DWORD)(_tcslen(Context->Executable) +
+ 2 +
+ _tcslen(Context->DevicePath) +
+ 2) * sizeof (TCHAR);
+
+ CommandLine = calloc(1, CommandLineLength);
+
+ if (CommandLine == NULL)
+ goto fail1;
+
+ (VOID) _sntprintf(CommandLine,
+ CommandLineLength - 1,
+ TEXT("%s \"%s\""),
+ Context->Executable,
+ Context->DevicePath);
+
+again:
+ ZeroMemory(&ProcessInfo, sizeof (ProcessInfo));
+ ZeroMemory(&StartupInfo, sizeof (StartupInfo));
+ StartupInfo.cb = sizeof (StartupInfo);
+
+ Log("Executing: %s", CommandLine);
+
+#pragma warning(suppress:6053) // CommandLine might not be NUL-terminated
+ Success = CreateProcess(NULL,
+ CommandLine,
+ NULL,
+ NULL,
+ FALSE,
+ CREATE_NO_WINDOW |
+ CREATE_NEW_PROCESS_GROUP,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInfo);
+ if (!Success)
+ goto fail2;
+
+ Handle[0] = Context->ThreadEvent;
+ Handle[1] = ProcessInfo.hProcess;
+
+ Object = WaitForMultipleObjects(ARRAYSIZE(Handle),
+ Handle,
+ FALSE,
+ INFINITE);
+
+#define WAIT_OBJECT_1 (WAIT_OBJECT_0 + 1)
+
+ switch (Object) {
+ case WAIT_OBJECT_0:
+ ResetEvent(Context->ThreadEvent);
+
+ TerminateProcess(ProcessInfo.hProcess, 1);
+ CloseHandle(ProcessInfo.hProcess);
+ CloseHandle(ProcessInfo.hThread);
+ break;
+
+ case WAIT_OBJECT_1:
+ CloseHandle(ProcessInfo.hProcess);
+ CloseHandle(ProcessInfo.hThread);
+ goto again;
+
+ default:
+ break;
+ }
+
+//#undef WAIT_OBJECT_1
+
+ free(CommandLine);
+
+ Log("<====");
+
+ return 0;
+
+fail2:
+ Log("fail2");
+
+ free(CommandLine);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return 1;
+}
+
static VOID
PutString(
IN HANDLE Handle,
Context->DevicePath = Path;
+ Context->ThreadEvent = CreateEvent(NULL,
+ TRUE,
+ FALSE,
+ NULL);
+
+ if (Context->ThreadEvent == NULL)
+ goto fail4;
+
+ Context->Thread = CreateThread(NULL,
+ 0,
+ MonitorThread,
+ NULL,
+ 0,
+ NULL);
+
+ if (Context->Thread == INVALID_HANDLE_VALUE)
+ goto fail5;
+
Log("<====");
return;
+fail5:
+ Log("fail5");
+
+ CloseHandle(Context->ThreadEvent);
+ Context->ThreadEvent = NULL;
+
+fail4:
+ Log("fail4");
+
+ free(Context->DevicePath);
+ Context->DevicePath = NULL;
+
+ UnregisterDeviceNotification(Context->DeviceNotification);
+ Context->DeviceNotification = NULL;
+
fail3:
Log("fail3");
Log("====>");
+ SetEvent(Context->ThreadEvent);
+ WaitForSingleObject(Context->Thread, INFINITE);
+
+ CloseHandle(Context->ThreadEvent);
+ Context->ThreadEvent = NULL;
+
free(Context->DevicePath);
Context->DevicePath = NULL;
return ERROR_CALL_NOT_IMPLEMENTED;
}
+static BOOL
+GetExecutable(
+ OUT PTCHAR *Executable
+ )
+{
+ PMONITOR_CONTEXT Context = &MonitorContext;
+ DWORD MaxValueLength;
+ DWORD ExecutableLength;
+ DWORD Type;
+ HRESULT Error;
+
+ Error = RegQueryInfoKey(Context->ParametersKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ ExecutableLength = MaxValueLength + sizeof (TCHAR);
+
+ *Executable = calloc(1, ExecutableLength);
+ if (Executable == NULL)
+ goto fail2;
+
+ Error = RegQueryValueEx(Context->ParametersKey,
+ "Executable",
+ NULL,
+ &Type,
+ (LPBYTE)(*Executable),
+ &ExecutableLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ if (Type != REG_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail4;
+ }
+
+ Log("%s", *Executable);
+
+ return TRUE;
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+ free(*Executable);
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
VOID WINAPI
MonitorMain(
_In_ DWORD argc,
PMONITOR_CONTEXT Context = &MonitorContext;
DEV_BROADCAST_DEVICEINTERFACE Interface;
HRESULT Error;
+ BOOL Success;
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
if (Context->RemoveEvent == NULL)
goto fail6;
+ Success = GetExecutable(&Context->Executable);
+ if (!Success)
+ goto fail7;
+
Context->Device = INVALID_HANDLE_VALUE;
ZeroMemory(&Interface, sizeof (Interface));
&Interface,
DEVICE_NOTIFY_SERVICE_HANDLE);
if (Context->InterfaceNotification == NULL)
- goto fail7;
+ goto fail8;
// The device may already by present
SetEvent(Context->AddEvent);
UnregisterDeviceNotification(Context->InterfaceNotification);
+ free(Context->Executable);
+
CloseHandle(Context->RemoveEvent);
CloseHandle(Context->AddEvent);
return;
+fail8:
+ Log("fail8");
+
+ free(Context->Executable);
+
fail7:
Log("fail7");
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <tchar.h>
+#include <strsafe.h>
+#include <userenv.h>
+
+typedef struct _TTY_STREAM {
+ HANDLE Read;
+ HANDLE Write;
+} TTY_STREAM, *PTTY_STREAM;
+
+#define MAXIMUM_BUFFER_SIZE 1024
+
+typedef struct _TTY_CONTEXT {
+ TTY_STREAM ChildStdIn;
+ TTY_STREAM ChildStdOut;
+ TTY_STREAM Device;
+ TCHAR UserName[MAXIMUM_BUFFER_SIZE];
+ TCHAR Password[MAXIMUM_BUFFER_SIZE];
+ HANDLE Token;
+ PROCESS_INFORMATION ProcessInfo;
+} TTY_CONTEXT, *PTTY_CONTEXT;
+
+TTY_CONTEXT TtyContext;
+
+static BOOL
+CreateChild(
+ VOID
+ )
+{
+ PTTY_CONTEXT Context = &TtyContext;
+ TCHAR CommandLine[] = TEXT("c:\\windows\\system32\\cmd.exe /q /a");
+ PVOID Environment;
+ PROFILEINFO ProfileInfo;
+ DWORD Size;
+ TCHAR ProfileDir[MAXIMUM_BUFFER_SIZE];
+ STARTUPINFO StartupInfo;
+ BOOL Success;
+
+ Success = CreateEnvironmentBlock(&Environment,
+ Context->Token,
+ FALSE);
+ if (!Success)
+ return FALSE;
+
+ ZeroMemory(&ProfileInfo, sizeof (ProfileInfo));
+ ProfileInfo.dwSize = sizeof (ProfileInfo);
+ ProfileInfo.lpUserName = Context->UserName;
+
+ Success = LoadUserProfile(Context->Token, &ProfileInfo);
+ if (!Success)
+ return FALSE;
+
+ Size = sizeof (ProfileDir);
+
+ Success = GetUserProfileDirectory(Context->Token,
+ ProfileDir,
+ &Size);
+ if (!Success)
+ return FALSE;
+
+ Success = ImpersonateLoggedOnUser(Context->Token);
+ if (!Success)
+ return FALSE;
+
+ ZeroMemory(&StartupInfo, sizeof (StartupInfo));
+ StartupInfo.cb = sizeof (StartupInfo);
+
+ StartupInfo.hStdInput = Context->ChildStdIn.Read;
+ StartupInfo.hStdOutput = Context->ChildStdOut.Write;
+ StartupInfo.hStdError = Context->ChildStdOut.Write;
+
+ StartupInfo.dwFlags |= STARTF_USESTDHANDLES;
+
+#pragma warning(suppress:6335) // leaking handle information
+ Success = CreateProcessAsUser(Context->Token,
+ NULL,
+ CommandLine,
+ NULL,
+ NULL,
+ TRUE,
+ CREATE_UNICODE_ENVIRONMENT,
+ Environment,
+ ProfileDir,
+ &StartupInfo,
+ &Context->ProcessInfo);
+
+ DestroyEnvironmentBlock(Environment);
+
+ if (!Success)
+ return FALSE;
+
+ SetConsoleCtrlHandler(NULL, TRUE);
+
+ return TRUE;
+}
+
+static VOID
+PutCharacter(
+ IN PTTY_STREAM Stream,
+ IN TCHAR Character
+ )
+{
+ WriteFile(Stream->Write,
+ &Character,
+ 1,
+ NULL,
+ NULL);
+}
+
+static VOID
+PutString(
+ IN PTTY_STREAM Stream,
+ IN PTCHAR Buffer,
+ IN DWORD Length
+ )
+{
+ DWORD Offset;
+
+ Offset = 0;
+ while (Offset < Length) {
+ DWORD Written;
+ BOOL Success;
+
+ Success = WriteFile(Stream->Write,
+ &Buffer[Offset],
+ Length - Offset,
+ &Written,
+ NULL);
+ if (!Success)
+ break;
+
+ Offset += Written;
+ }
+}
+
+#define ECHO(_Stream, _Buffer) \
+ PutString((_Stream), TEXT(_Buffer), (DWORD)_tcslen(_Buffer))
+
+static BOOL
+GetLine(
+ IN PTTY_STREAM Stream,
+ IN PTCHAR Buffer,
+ IN DWORD NumberOfBytesToRead,
+ OUT LPDWORD NumberOfBytesRead,
+ IN BOOL NoEcho
+ )
+{
+ DWORD Offset;
+ BOOL Success = TRUE;
+
+ Offset = 0;
+ while (Offset < NumberOfBytesToRead) {
+ TCHAR Sequence[MAXIMUM_BUFFER_SIZE];
+ PTCHAR Character;
+ DWORD Read;
+
+ Success = ReadFile(Stream->Read,
+ &Sequence,
+ sizeof (Sequence),
+ &Read,
+ NULL);
+ if (!Success)
+ break;
+
+ Character = &Sequence[0];
+ while (Read-- != 0) {
+ Buffer[Offset] = *Character++;
+
+ if (!iscntrl(Buffer[Offset])) {
+ if (!NoEcho)
+ PutCharacter(Stream, Buffer[Offset]);
+ Offset++;
+ } else {
+ if (Buffer[Offset] == 0x7F && // DEL
+ Offset != 0) {
+ --Offset;
+
+ if (Buffer[Offset] >= 0x00 &&
+ Buffer[Offset] < 0x20)
+ ECHO(Stream, "\b\b \b\b");
+ else if (!NoEcho)
+ ECHO(Stream, "\b \b");
+ } else if (Buffer[Offset] == 0x03 || // ^C
+ Buffer[Offset] == 0x0D) { // ^M
+ Offset++;
+ break;
+ } else if (Buffer[Offset] >= 0x00 &&
+ Buffer[Offset] < 0x20) {
+ ECHO(Stream, "^");
+ PutCharacter(Stream, Buffer[Offset] + 0x40);
+ Offset++;
+ }
+ }
+
+ if (Offset >= NumberOfBytesToRead)
+ break;
+ }
+
+ if (Offset == 0)
+ continue;
+
+ if (Buffer[Offset - 1] == 0x03 || // ^C
+ Buffer[Offset - 1] == 0x0D) // ^M
+ break;
+ }
+
+ ECHO(Stream, "\r\n");
+
+ *NumberOfBytesRead = Offset;
+
+ return Success;
+}
+
+static BOOL
+GetCredentials(
+ VOID
+ )
+{
+ PTTY_CONTEXT Context = &TtyContext;
+ TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+ PTCHAR End;
+ DWORD Size;
+ BOOL Success;
+
+ ZeroMemory(ComputerName, sizeof (ComputerName));
+ Size = sizeof (ComputerName);
+
+ Success = GetComputerName(ComputerName, &Size);
+ if (!Success)
+ return FALSE;
+
+ ECHO(&Context->Device, "\r\n");
+ PutString(&Context->Device, ComputerName, Size);
+ ECHO(&Context->Device, " login: ");
+
+ ZeroMemory(Context->UserName, sizeof (Context->UserName));
+
+ Success = GetLine(&Context->Device,
+ Context->UserName,
+ sizeof (Context->UserName),
+ &Size,
+ FALSE);
+ if (!Success)
+ return FALSE;
+
+ End = _tcschr(Context->UserName, TEXT('\r'));
+ if (End == NULL)
+ return FALSE;
+
+ *End = TEXT('\0');
+
+ if (_tcslen(Context->UserName) == 0)
+ return FALSE;
+
+ ECHO(&Context->Device, "Password: ");
+
+ ZeroMemory(Context->Password, sizeof (Context->Password));
+
+ Success = GetLine(&Context->Device,
+ Context->Password,
+ sizeof (Context->Password),
+ &Size,
+ TRUE);
+ if (!Success)
+ return FALSE;
+
+ End = _tcschr(Context->Password, TEXT('\r'));
+ if (End == NULL)
+ return FALSE;
+
+ *End = TEXT('\0');
+
+ return TRUE;
+}
+
+static DWORD WINAPI
+TtyIn(
+ IN LPVOID Argument
+ )
+{
+ PTTY_CONTEXT Context = &TtyContext;
+
+ UNREFERENCED_PARAMETER(Argument);
+
+ for (;;) {
+ DWORD Read;
+ CHAR Buffer[MAXIMUM_BUFFER_SIZE];
+ BOOL Success;
+
+ Success = GetLine(&Context->Device,
+ Buffer,
+ sizeof (Buffer) - 1,
+ &Read,
+ FALSE);
+ if (!Success)
+ break;
+
+ if (Read == 0)
+ continue;
+
+ if (Buffer[Read - 1] == 0x03) { // ^C
+ GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, 0);
+ continue;
+ } else if (Buffer[Read - 1] == 0x0D) { // ^M
+ Buffer[Read++] = '\n';
+
+ Success = WriteFile(Context->ChildStdIn.Write,
+ Buffer,
+ Read,
+ NULL,
+ NULL);
+ if (!Success)
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static DWORD WINAPI
+TtyOut(
+ IN LPVOID Argument
+ )
+{
+ PTTY_CONTEXT Context = &TtyContext;
+
+ UNREFERENCED_PARAMETER(Argument);
+
+ for (;;) {
+ DWORD Read;
+ DWORD Written;
+ CHAR Buffer[MAXIMUM_BUFFER_SIZE];
+ BOOL Success;
+
+ Success = ReadFile(Context->ChildStdOut.Read,
+ Buffer,
+ sizeof (Buffer),
+ &Read,
+ NULL);
+ if (!Success)
+ break;
+
+ if (Read == 0)
+ continue;
+
+ Success = WriteFile(Context->Device.Write,
+ Buffer,
+ Read,
+ &Written,
+ NULL);
+ if (!Success)
+ break;
+ }
+
+ return 0;
+}
+
+void __cdecl
+_tmain(
+ IN int argc,
+ IN TCHAR *argv[]
+ )
+{
+ PTTY_CONTEXT Context = &TtyContext;
+ PTCHAR DeviceName;
+ SECURITY_ATTRIBUTES Attributes;
+ HANDLE Handle[3];
+ DWORD Index;
+ BOOL Success;
+
+ if (argc != 2)
+ ExitProcess(1);
+
+ DeviceName = argv[1];
+
+ Context->Device.Read = CreateFile(DeviceName,
+ GENERIC_READ,
+ FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (Context->Device.Read == INVALID_HANDLE_VALUE)
+ ExitProcess(1);
+
+ Context->Device.Write = CreateFile(DeviceName,
+ GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (Context->Device.Read == INVALID_HANDLE_VALUE)
+ ExitProcess(1);
+
+ Success = GetCredentials();
+ if (!Success)
+ ExitProcess(1);
+
+ Success = LogonUser(Context->UserName,
+ NULL,
+ Context->Password,
+ LOGON32_LOGON_INTERACTIVE,
+ LOGON32_PROVIDER_DEFAULT,
+ &Context->Token);
+ if (!Success)
+ ExitProcess(1);
+
+ Attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
+ Attributes.bInheritHandle = TRUE;
+ Attributes.lpSecurityDescriptor = NULL;
+
+ Success = CreatePipe(&Context->ChildStdOut.Read,
+ &Context->ChildStdOut.Write,
+ &Attributes,
+ 0);
+ if (!Success)
+ ExitProcess(1);
+
+ Success = SetHandleInformation(Context->ChildStdOut.Read,
+ HANDLE_FLAG_INHERIT,
+ 0);
+ if (!Success)
+ ExitProcess(1);
+
+ Success = CreatePipe(&Context->ChildStdIn.Read,
+ &Context->ChildStdIn.Write,
+ &Attributes,
+ 0);
+ if (!Success)
+ ExitProcess(1);
+
+ Success = SetHandleInformation(Context->ChildStdIn.Write,
+ HANDLE_FLAG_INHERIT,
+ 0);
+ if (!Success)
+ ExitProcess(1);
+
+ Success = CreateChild();
+
+ if (!Success)
+ ExitProcess(1);
+
+ Handle[0] = Context->ProcessInfo.hThread;
+
+ Handle[1] = CreateThread(NULL,
+ 0,
+ TtyIn,
+ NULL,
+ 0,
+ NULL);
+
+ if (Handle[1] == INVALID_HANDLE_VALUE)
+ ExitProcess(1);
+
+ Handle[2] = CreateThread(NULL,
+ 0,
+ TtyOut,
+ NULL,
+ 0,
+ NULL);
+
+ if (Handle[2] == INVALID_HANDLE_VALUE)
+ ExitProcess(1);
+
+ WaitForMultipleObjects(ARRAYSIZE(Handle),
+ Handle,
+ FALSE,
+ INFINITE);
+
+ for (Index = 0; Index < ARRAYSIZE(Handle); Index++)
+ if ( Handle[Index] != 0 )
+ CloseHandle(Handle[Index]);
+
+ CloseHandle(Context->ProcessInfo.hProcess);
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <ntverp.h>
+
+#undef VER_COMPANYNAME_STR
+#undef VER_PRODUCTNAME_STR
+#undef VER_PRODUCTVERSION
+#undef VER_PRODUCTVERSION_STR
+
+#include <version.h>
+
+#define VER_COMPANYNAME_STR VENDOR_NAME_STR
+#define VER_LEGALCOPYRIGHT_STR "Copyright (c) Citrix Systems Inc."
+
+#define VER_PRODUCTNAME_STR "XENCONS"
+#define VER_PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_NUMBER
+#define VER_PRODUCTVERSION_STR MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR
+
+#define VER_INTERNALNAME_STR "XENCONS_TTY.EXE"
+#define VER_FILEDESCRIPTION_STR "XENCONS_TTY"
+
+#define VER_FILETYPE VFT_APP
+#define VER_FILESUBTYPE VFT2_UNKNOWN
+
+#include "common.ver"
DefaultDestDir=12
CoInst_CopyFiles=11
Monitor_CopyFiles=11
+Tty_CopyFiles=11
[SourceDisksNames]
0=%DiskDesc%
xencons_coinst.dll=0,,
xencons_monitor.exe=0,,
xencons_monitor.dll=0,,
+xencons_tty.exe=0,,
[CoInst_CopyFiles]
xencons_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xencons_coinst.dll
xencons_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.exe,xencons_monitor.exe
xencons_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xencons_monitor.dll
+[Tty_CopyFiles]
+xencons_tty_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.exe,xencons_tty.exe
+
[Manufacturer]
%Vendor%=Inst,NT$ARCH$
[XenCons_Inst]
CopyFiles=XenCons_Copyfiles
CopyFiles=Monitor_Copyfiles
+CopyFiles=Tty_Copyfiles
[XenCons_Copyfiles]
xencons.sys
[Monitor_Parameters]
HKR,"Parameters",,0x00000010
+HKR,"Parameters","Executable",0x00000000,"xencons_tty_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.exe"
[Monitor_EventLog]
AddReg=Monitor_EventLog_AddReg
<ProjectReference Include="..\xencons_monitor\xencons_monitor.vcxproj">
<Project>{8991F0A5-408B-43E0-88CC-9550D4AAE616}</Project>
</ProjectReference>
+ <ProjectReference Include="..\xencons_tty\xencons_tty.vcxproj">
+ <Project>{79D98F83-5A2F-4DE6-B62C-530D70B88C3F}</Project>
+ </ProjectReference>
</ItemGroup>
<ItemGroup>
<FilesToPackage Include="$(DPINST_REDIST)\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencons_monitor", "xencons_monitor\xencons_monitor.vcxproj", "{8991F0A5-408B-43E0-88CC-9550D4AAE616}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencons_tty", "xencons_tty\xencons_tty.vcxproj", "{79D98F83-5A2F-4DE6-B62C-530D70B88C3F}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.vcxproj", "{8B5B8F4B-7FF3-4B64-AC4A-5246026217E7}"
ProjectSection(ProjectDependencies) = postProject
{4674B8C2-876B-4F2A-AB71-BAC968A9B529} = {4674B8C2-876B-4F2A-AB71-BAC968A9B529}
{6CC9B8DD-A5AE-427D-8157-E91D21DD7E19} = {6CC9B8DD-A5AE-427D-8157-E91D21DD7E19}
{8991F0A5-408B-43E0-88CC-9550D4AAE616} = {8991F0A5-408B-43E0-88CC-9550D4AAE616}
+ {79D98F83-5A2F-4DE6-B62C-530D70B88C3F} = {79D98F83-5A2F-4DE6-B62C-530D70B88C3F}
EndProjectSection
EndProject
Global
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="..\configs.props" />
+ <PropertyGroup Label="PropertySheets">
+ <CharacterSet>MultiByte</CharacterSet>
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{79D98F83-5A2F-4DE6-B62C-530D70B88C3F}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="..\targets.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <EnableInf2cat>false</EnableInf2cat>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>4127;4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <EnablePREfast>true</EnablePREfast>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>setupapi.lib;userenv.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>__i386__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>__x86_64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\tty\tty.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\src\tty\xencons_tty.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SignMode>TestSign</SignMode>
+ <TestCertificate>..\..\src\xencons.pfx</TestCertificate>
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+ </PropertyGroup>
+</Project>