From: Paul Durrant Date: Fri, 5 May 2017 15:02:26 +0000 (+0100) Subject: Add a TTY utility X-Git-Tag: 9.0.0-rc1~48 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=982a41920a03698eb99faead74e8c7b1a9dbfa7c;p=pvdrivers%2Fwin%2Fxencons.git Add a TTY utility This patch adds a new TTY utility which will open the console device and pipe it to a command shell (cmd.exe) process. It also provides login functionality for a local user such that the command shell is invoked as that user. Signed-off-by: Paul Durrant --- diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index fabca77..a8ae21b 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -58,10 +58,13 @@ typedef struct _MONITOR_CONTEXT { 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; @@ -342,6 +345,117 @@ fail1: 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, @@ -419,10 +533,43 @@ MonitorAdd( 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"); @@ -457,6 +604,12 @@ MonitorRemove( Log("====>"); + SetEvent(Context->ThreadEvent); + WaitForSingleObject(Context->Thread, INFINITE); + + CloseHandle(Context->ThreadEvent); + Context->ThreadEvent = NULL; + free(Context->DevicePath); Context->DevicePath = NULL; @@ -528,6 +681,84 @@ MonitorCtrlHandlerEx( 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, @@ -537,6 +768,7 @@ MonitorMain( PMONITOR_CONTEXT Context = &MonitorContext; DEV_BROADCAST_DEVICEINTERFACE Interface; HRESULT Error; + BOOL Success; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); @@ -591,6 +823,10 @@ MonitorMain( if (Context->RemoveEvent == NULL) goto fail6; + Success = GetExecutable(&Context->Executable); + if (!Success) + goto fail7; + Context->Device = INVALID_HANDLE_VALUE; ZeroMemory(&Interface, sizeof (Interface)); @@ -603,7 +839,7 @@ MonitorMain( &Interface, DEVICE_NOTIFY_SERVICE_HANDLE); if (Context->InterfaceNotification == NULL) - goto fail7; + goto fail8; // The device may already by present SetEvent(Context->AddEvent); @@ -655,6 +891,8 @@ done: UnregisterDeviceNotification(Context->InterfaceNotification); + free(Context->Executable); + CloseHandle(Context->RemoveEvent); CloseHandle(Context->AddEvent); @@ -671,6 +909,11 @@ done: return; +fail8: + Log("fail8"); + + free(Context->Executable); + fail7: Log("fail7"); diff --git a/src/tty/tty.c b/src/tty/tty.c new file mode 100644 index 0000000..c47634c --- /dev/null +++ b/src/tty/tty.c @@ -0,0 +1,509 @@ +/* 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 +#include +#include +#include + +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); +} diff --git a/src/tty/xencons_tty.rc b/src/tty/xencons_tty.rc new file mode 100644 index 0000000..2a72104 --- /dev/null +++ b/src/tty/xencons_tty.rc @@ -0,0 +1,55 @@ +/* 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 +#include + +#undef VER_COMPANYNAME_STR +#undef VER_PRODUCTNAME_STR +#undef VER_PRODUCTVERSION +#undef VER_PRODUCTVERSION_STR + +#include + +#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" diff --git a/src/xencons.inf b/src/xencons.inf index dbff121..3cbdd96 100644 --- a/src/xencons.inf +++ b/src/xencons.inf @@ -42,6 +42,7 @@ DriverPackageDisplayName=%DiskDesc% DefaultDestDir=12 CoInst_CopyFiles=11 Monitor_CopyFiles=11 +Tty_CopyFiles=11 [SourceDisksNames] 0=%DiskDesc% @@ -51,6 +52,7 @@ xencons.sys=0,, 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 @@ -59,6 +61,9 @@ xencons_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dl 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$ @@ -73,6 +78,7 @@ xencons_monitor_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.d [XenCons_Inst] CopyFiles=XenCons_Copyfiles CopyFiles=Monitor_Copyfiles +CopyFiles=Tty_Copyfiles [XenCons_Copyfiles] xencons.sys @@ -107,6 +113,7 @@ AddReg = Monitor_Parameters [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 diff --git a/vs2015/package/package.vcxproj b/vs2015/package/package.vcxproj index 65f9125..2e5c0eb 100644 --- a/vs2015/package/package.vcxproj +++ b/vs2015/package/package.vcxproj @@ -42,6 +42,9 @@ {8991F0A5-408B-43E0-88CC-9550D4AAE616} + + {79D98F83-5A2F-4DE6-B62C-530D70B88C3F} + diff --git a/vs2015/xencons.sln b/vs2015/xencons.sln index 6801b45..7f55d78 100644 --- a/vs2015/xencons.sln +++ b/vs2015/xencons.sln @@ -8,11 +8,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xencons_coinst", "xencons_c 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 diff --git a/vs2015/xencons_tty/xencons_tty.vcxproj b/vs2015/xencons_tty/xencons_tty.vcxproj new file mode 100644 index 0000000..135126c --- /dev/null +++ b/vs2015/xencons_tty/xencons_tty.vcxproj @@ -0,0 +1,60 @@ + + + + + MultiByte + WindowsApplicationForDrivers10.0 + Application + + + + {79D98F83-5A2F-4DE6-B62C-530D70B88C3F} + + + + + $(IncludePath) + true + false + + + + $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + EnableAllWarnings + 4127;4711;4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings) + true + true + MultiThreadedDebug + MultiThreaded + + + setupapi.lib;userenv.lib;%(AdditionalDependencies) + + + $(SolutionDir)..\include;%(AdditionalIncludeDirectories) + + + + + __i386__;%(PreprocessorDefinitions) + + + + + __x86_64__;%(PreprocessorDefinitions) + + + + + + + + + + + + + + + diff --git a/vs2015/xencons_tty/xencons_tty.vcxproj.user b/vs2015/xencons_tty/xencons_tty.vcxproj.user new file mode 100644 index 0000000..a427c80 --- /dev/null +++ b/vs2015/xencons_tty/xencons_tty.vcxproj.user @@ -0,0 +1,8 @@ + + + + TestSign + ..\..\src\xencons.pfx + http://timestamp.verisign.com/scripts/timstamp.dll + +