[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [win-pv-devel] [PATCH 06/14 v2] Make monitor service multi-console aware
From: Owen Smith <owen.smith@xxxxxxxxxx> * Move console specific data to a seperate structure * Make all threads' use the console data * Removes the Add and Remove event in favor of inline add/remove * Convert Win32 calls to explicit narrow/wide character set as appropriate * Removes tchar.h include to force narrow/wide character usage * Renames structures and thread functions * Pipe names are based on console name * INF file stores "Executable" under console's name subkey * Change pipe name tty.exe uses * Add WaitNamedPipe() before connecting to pipes in tty.exe Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx> --- src/monitor/monitor.c | 1445 ++++++++++++++++++++++++++----------------------- src/tty/tty.c | 20 +- src/xencons.inf | 2 +- 3 files changed, 792 insertions(+), 675 deletions(-) diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 08ae0f2..510ba6f 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -32,7 +32,7 @@ #define INITGUID 1 #include <windows.h> -#include <tchar.h> +#include <winioctl.h> #include <stdlib.h> #include <strsafe.h> #include <wtsapi32.h> @@ -50,40 +50,45 @@ #define MONITOR_NAME __MODULE__ #define MONITOR_DISPLAYNAME MONITOR_NAME -typedef struct _MONITOR_PIPE { - HANDLE Pipe; - HANDLE Event; - HANDLE Thread; - LIST_ENTRY ListEntry; -} MONITOR_PIPE, *PMONITOR_PIPE; - typedef struct _MONITOR_CONTEXT { SERVICE_STATUS Status; SERVICE_STATUS_HANDLE Service; - HKEY ParametersKey; HANDLE EventLog; HANDLE StopEvent; - HANDLE AddEvent; - HANDLE RemoveEvent; - PTCHAR Executable; + HKEY ParametersKey; HDEVNOTIFY InterfaceNotification; - PTCHAR DevicePath; + CRITICAL_SECTION CriticalSection; + LIST_ENTRY ListHead; + DWORD ListCount; +} MONITOR_CONTEXT, *PMONITOR_CONTEXT; + +typedef struct _MONITOR_CONSOLE { + LIST_ENTRY ListEntry; + PWCHAR DevicePath; + HANDLE DeviceHandle; HDEVNOTIFY DeviceNotification; - HANDLE Device; - HANDLE MonitorEvent; - HANDLE MonitorThread; - HANDLE DeviceEvent; + PCHAR DeviceName; // protocol and instance? + HANDLE ExecutableThread; + HANDLE ExecutableEvent; HANDLE DeviceThread; - HANDLE ServerEvent; + HANDLE DeviceEvent; HANDLE ServerThread; + HANDLE ServerEvent; CRITICAL_SECTION CriticalSection; LIST_ENTRY ListHead; DWORD ListCount; -} MONITOR_CONTEXT, *PMONITOR_CONTEXT; +} MONITOR_CONSOLE, *PMONITOR_CONSOLE; + +typedef struct _MONITOR_CONNECTION { + PMONITOR_CONSOLE Console; + LIST_ENTRY ListEntry; + HANDLE Pipe; + HANDLE Thread; +} MONITOR_CONNECTION, *PMONITOR_CONNECTION; -MONITOR_CONTEXT MonitorContext; +static MONITOR_CONTEXT MonitorContext; -#define PIPE_NAME TEXT("\\\\.\\pipe\\xencons") +#define PIPE_BASE_NAME "\\\\.\\pipe\\xencons\\" #define MAXIMUM_BUFFER_SIZE 1024 @@ -104,15 +109,15 @@ __Log( { #if DBG PMONITOR_CONTEXT Context = &MonitorContext; - const TCHAR *Strings[1]; + const CHAR *Strings[1]; #endif - TCHAR Buffer[MAXIMUM_BUFFER_SIZE]; + CHAR Buffer[MAXIMUM_BUFFER_SIZE]; va_list Arguments; size_t Length; HRESULT Result; va_start(Arguments, Format); - Result = StringCchVPrintf(Buffer, + Result = StringCchVPrintfA(Buffer, MAXIMUM_BUFFER_SIZE, Format, Arguments); @@ -121,7 +126,7 @@ __Log( if (Result != S_OK && Result != STRSAFE_E_INSUFFICIENT_BUFFER) return; - Result = StringCchLength(Buffer, MAXIMUM_BUFFER_SIZE, &Length); + Result = StringCchLengthA(Buffer, MAXIMUM_BUFFER_SIZE, &Length); if (Result != S_OK) return; @@ -139,7 +144,7 @@ __Log( Strings[0] = Buffer; if (Context->EventLog != NULL) - ReportEvent(Context->EventLog, + ReportEventA(Context->EventLog, EVENTLOG_INFORMATION_TYPE, 0, MONITOR_LOG, @@ -152,23 +157,23 @@ __Log( } #define Log(_Format, ...) \ - __Log(TEXT(__MODULE__ "|" __FUNCTION__ ": " _Format), __VA_ARGS__) + __Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__) -static PTCHAR +static PCHAR GetErrorMessage( IN HRESULT Error ) { - PTCHAR Message; + PCHAR Message; ULONG Index; - if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | + if (!FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, Error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&Message, + (LPSTR)&Message, 0, NULL)) return NULL; @@ -210,7 +215,8 @@ static VOID ReportStatus( IN DWORD CurrentState, IN DWORD Win32ExitCode, - IN DWORD WaitHint) + IN DWORD WaitHint + ) { PMONITOR_CONTEXT Context = &MonitorContext; static DWORD CheckPoint = 1; @@ -249,116 +255,11 @@ fail1: Error = GetLastError(); { - PTCHAR Message; - Message = GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } -} - -static BOOL -MonitorGetPath( - IN const GUID *Guid, - OUT PTCHAR *Path - ) -{ - HDEVINFO DeviceInfoSet; - SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; - PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetail; - DWORD Size; - HRESULT Error; - BOOL Success; - - Log("====>"); - - DeviceInfoSet = SetupDiGetClassDevs(Guid, - NULL, - NULL, - DIGCF_PRESENT | - DIGCF_DEVICEINTERFACE); - if (DeviceInfoSet == INVALID_HANDLE_VALUE) - goto fail1; - - DeviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); - - Success = SetupDiEnumDeviceInterfaces(DeviceInfoSet, - NULL, - Guid, - 0, - &DeviceInterfaceData); - if (!Success) - goto fail2; - - Success = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, - &DeviceInterfaceData, - NULL, - 0, - &Size, - NULL); - if (!Success && GetLastError() != ERROR_INSUFFICIENT_BUFFER) - goto fail3; - - DeviceInterfaceDetail = calloc(1, Size); - if (DeviceInterfaceDetail == NULL) - goto fail4; - - DeviceInterfaceDetail->cbSize = - sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA); - - Success = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, - &DeviceInterfaceData, - DeviceInterfaceDetail, - Size, - NULL, - NULL); - if (!Success) - goto fail5; - - *Path = _tcsdup(DeviceInterfaceDetail->DevicePath); - - if (*Path == NULL) - goto fail6; - - Log("%s", *Path); - - free(DeviceInterfaceDetail); - - SetupDiDestroyDeviceInfoList(DeviceInfoSet); - - Log("<===="); - - return TRUE; - -fail6: - Log("fail6"); - -fail5: - Log("fail5"); - - free(DeviceInterfaceDetail); - -fail4: - Log("fail4"); - -fail3: - Log("fail3"); - -fail2: - Log("fail2"); - - SetupDiDestroyDeviceInfoList(DeviceInfoSet); - -fail1: - Error = GetLastError(); - - { - PTCHAR Message; + PCHAR Message; Message = GetErrorMessage(Error); Log("fail1 (%s)", Message); LocalFree(Message); } - - return FALSE; } static FORCEINLINE VOID @@ -425,22 +326,25 @@ PutString( } } +#define ECHO(_Handle, _Buffer) \ + PutString((_Handle), (PUCHAR)_Buffer, (DWORD)strlen((_Buffer)) * sizeof(CHAR)) + DWORD WINAPI -PipeThread( +ConnectionThread( IN LPVOID Argument ) { - PMONITOR_CONTEXT Context = &MonitorContext; - PMONITOR_PIPE Pipe = (PMONITOR_PIPE)Argument; + PMONITOR_CONNECTION Connection = (PMONITOR_CONNECTION)Argument; + PMONITOR_CONSOLE Console = Connection->Console; UCHAR Buffer[MAXIMUM_BUFFER_SIZE]; OVERLAPPED Overlapped; HANDLE Handle[2]; DWORD Length; DWORD Object; HRESULT Error; - - Log("====>"); - + + Log("====> %s", Console->DeviceName); + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); Overlapped.hEvent = CreateEvent(NULL, TRUE, @@ -448,69 +352,69 @@ PipeThread( NULL); if (Overlapped.hEvent == NULL) goto fail1; - - Handle[0] = Pipe->Event; + + Handle[0] = Console->ServerEvent; Handle[1] = Overlapped.hEvent; - - EnterCriticalSection(&Context->CriticalSection); - __InsertTailList(&Context->ListHead, &Pipe->ListEntry); - ++Context->ListCount; - LeaveCriticalSection(&Context->CriticalSection); - + + EnterCriticalSection(&Console->CriticalSection); + __InsertTailList(&Console->ListHead, &Connection->ListEntry); + ++Console->ListCount; + LeaveCriticalSection(&Console->CriticalSection); + for (;;) { - (VOID) ReadFile(Pipe->Pipe, + (VOID) ReadFile(Connection->Pipe, Buffer, sizeof(Buffer), NULL, &Overlapped); - + Object = WaitForMultipleObjects(ARRAYSIZE(Handle), Handle, FALSE, INFINITE); if (Object == WAIT_OBJECT_0) break; - - if (!GetOverlappedResult(Pipe->Pipe, + + if (!GetOverlappedResult(Connection->Pipe, &Overlapped, &Length, FALSE)) break; - + ResetEvent(Overlapped.hEvent); - - PutString(Context->Device, + + PutString(Console->DeviceHandle, Buffer, Length); } - - EnterCriticalSection(&Context->CriticalSection); - __RemoveEntryList(&Pipe->ListEntry); - --Context->ListCount; - LeaveCriticalSection(&Context->CriticalSection); - + + EnterCriticalSection(&Console->CriticalSection); + __RemoveEntryList(&Connection->ListEntry); + --Console->ListCount; + LeaveCriticalSection(&Console->CriticalSection); + CloseHandle(Overlapped.hEvent); - - FlushFileBuffers(Pipe->Pipe); - DisconnectNamedPipe(Pipe->Pipe); - CloseHandle(Pipe->Pipe); - CloseHandle(Pipe->Thread); - free(Pipe); - - Log("<===="); - + + FlushFileBuffers(Connection->Pipe); + DisconnectNamedPipe(Connection->Pipe); + CloseHandle(Connection->Pipe); + CloseHandle(Connection->Thread); + free(Connection); + + Log("<==== %s", Console->DeviceName); + return 0; - + fail1: Error = GetLastError(); - + { PTCHAR Message; Message = GetErrorMessage(Error); Log("fail1 (%s)", Message); LocalFree(Message); } - + return 1; } @@ -519,18 +423,17 @@ ServerThread( IN LPVOID Argument ) { - PMONITOR_CONTEXT Context = &MonitorContext; + PMONITOR_CONSOLE Console = (PMONITOR_CONSOLE)Argument; + CHAR PipeName[MAXIMUM_BUFFER_SIZE]; OVERLAPPED Overlapped; HANDLE Handle[2]; HANDLE Pipe; DWORD Object; - PMONITOR_PIPE Instance; + PMONITOR_CONNECTION Connection; HRESULT Error; - - UNREFERENCED_PARAMETER(Argument); - - Log("====>"); - + + Log("====> %s", Console->DeviceName); + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); Overlapped.hEvent = CreateEvent(NULL, TRUE, @@ -538,12 +441,22 @@ ServerThread( NULL); if (Overlapped.hEvent == NULL) goto fail1; - - Handle[0] = Context->ServerEvent; + + Handle[0] = Console->ServerEvent; Handle[1] = Overlapped.hEvent; + + Error = StringCchPrintfA(PipeName, + MAXIMUM_BUFFER_SIZE, + "%s%s", + PIPE_BASE_NAME, + Console->DeviceName); + if (Error != S_OK && Error != STRSAFE_E_INSUFFICIENT_BUFFER) + goto fail2; + + Log("%s", PipeName); for (;;) { - Pipe = CreateNamedPipe(PIPE_NAME, + Pipe = CreateNamedPipe(PipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, @@ -552,11 +465,11 @@ ServerThread( 0, NULL); if (Pipe == INVALID_HANDLE_VALUE) - goto fail2; - + goto fail3; + (VOID) ConnectNamedPipe(Pipe, &Overlapped); - + Object = WaitForMultipleObjects(ARRAYSIZE(Handle), Handle, FALSE, @@ -565,146 +478,60 @@ ServerThread( CloseHandle(Pipe); break; } - + ResetEvent(Overlapped.hEvent); - - Instance = (PMONITOR_PIPE)malloc(sizeof(MONITOR_PIPE)); - if (Instance == NULL) - goto fail3; - - __InitializeListHead(&Instance->ListEntry); - Instance->Pipe = Pipe; - Instance->Event = Context->ServerEvent; - Instance->Thread = CreateThread(NULL, - 0, - PipeThread, - Instance, - 0, - NULL); - if (Instance->Thread == INVALID_HANDLE_VALUE) + + Connection = (PMONITOR_CONNECTION)malloc(sizeof(MONITOR_CONNECTION)); + if (Connection == NULL) goto fail4; + + __InitializeListHead(&Connection->ListEntry); + Connection->Console = Console; + Connection->Pipe = Pipe; + Connection->Thread = CreateThread(NULL, + 0, + ConnectionThread, + Connection, + 0, + NULL); + if (Connection->Thread == NULL) + goto fail5; } - + CloseHandle(Overlapped.hEvent); + + Log("<==== %s", Console->DeviceName); + + return 0; - Log("<===="); +fail5: + Log("fail5"); - return 0; + free(Connection); fail4: Log("fail4"); - free(Instance); + CloseHandle(Pipe); fail3: Log("fail3"); - CloseHandle(Pipe); - fail2: Log("fail2"); + + CloseHandle(Overlapped.hEvent); fail1: Error = GetLastError(); - - { - PTCHAR Message; - Message = GetErrorMessage(Error); - Log("fail1 (%s)", Message); - LocalFree(Message); - } - - return 1; -} - -DWORD WINAPI -MonitorThread( - IN LPVOID Argument - ) -{ - PMONITOR_CONTEXT Context = &MonitorContext; - PROCESS_INFORMATION ProcessInfo; - STARTUPINFO StartupInfo; - BOOL Success; - HANDLE Handle[2]; - DWORD Object; - HRESULT Error; - - UNREFERENCED_PARAMETER(Argument); - - Log("====>"); - - // If there is no executable, this thread can finish now. - if (Context->Executable == NULL) - goto done; - -again: - ZeroMemory(&ProcessInfo, sizeof (ProcessInfo)); - ZeroMemory(&StartupInfo, sizeof (StartupInfo)); - StartupInfo.cb = sizeof (StartupInfo); - - Log("Executing: %s", Context->Executable); - -#pragma warning(suppress:6053) // CommandLine might not be NUL-terminated - Success = CreateProcess(NULL, - Context->Executable, - NULL, - NULL, - FALSE, - CREATE_NO_WINDOW | - CREATE_NEW_PROCESS_GROUP, - NULL, - NULL, - &StartupInfo, - &ProcessInfo); - if (!Success) - goto fail1; - - Handle[0] = Context->MonitorEvent; - 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->MonitorEvent); - - 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 - -done: - Log("<===="); - - return 0; - -fail1: - Error = GetLastError(); - + { PTCHAR Message; Message = GetErrorMessage(Error); Log("fail1 (%s)", Message); LocalFree(Message); } - + return 1; } @@ -713,7 +540,7 @@ DeviceThread( IN LPVOID Argument ) { - PMONITOR_CONTEXT Context = &MonitorContext; + PMONITOR_CONSOLE Console = (PMONITOR_CONSOLE)Argument; OVERLAPPED Overlapped; HANDLE Device; UCHAR Buffer[MAXIMUM_BUFFER_SIZE]; @@ -721,11 +548,9 @@ DeviceThread( DWORD Wait; HANDLE Handles[2]; DWORD Error; - - UNREFERENCED_PARAMETER(Argument); - - Log("====>"); - + + Log("====> %s", Console->DeviceName); + ZeroMemory(&Overlapped, sizeof(OVERLAPPED)); Overlapped.hEvent = CreateEvent(NULL, TRUE, @@ -733,72 +558,172 @@ DeviceThread( NULL); if (Overlapped.hEvent == NULL) goto fail1; - - Handles[0] = Context->DeviceEvent; + + Handles[0] = Console->DeviceEvent; Handles[1] = Overlapped.hEvent; - - Device = CreateFile(Context->DevicePath, - GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); + + Device = CreateFileW(Console->DevicePath, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); if (Device == INVALID_HANDLE_VALUE) goto fail2; - + for (;;) { PLIST_ENTRY ListEntry; - + (VOID) ReadFile(Device, Buffer, sizeof(Buffer), NULL, &Overlapped); - + Wait = WaitForMultipleObjects(ARRAYSIZE(Handles), Handles, FALSE, INFINITE); if (Wait == WAIT_OBJECT_0) break; - + if (!GetOverlappedResult(Device, &Overlapped, &Length, FALSE)) break; - + ResetEvent(Overlapped.hEvent); + + EnterCriticalSection(&Console->CriticalSection); + + for (ListEntry = Console->ListHead.Flink; + ListEntry != &Console->ListHead; + ListEntry = ListEntry->Flink) { + PMONITOR_CONNECTION Connection; + + Connection = CONTAINING_RECORD(ListEntry, + MONITOR_CONNECTION, + ListEntry); + + PutString(Connection->Pipe, + Buffer, + Length); + } - EnterCriticalSection(&Context->CriticalSection); + LeaveCriticalSection(&Console->CriticalSection); + } + + CloseHandle(Device); + + CloseHandle(Overlapped.hEvent); + + Log("<==== %s", Console->DeviceName); + + return 0; + +fail2: + Log("fail2\n"); + + CloseHandle(Overlapped.hEvent); + +fail1: + Error = GetLastError(); + + { + PTCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return 1; +} - for (ListEntry = Context->ListHead.Flink; - ListEntry != &Context->ListHead; - ListEntry = ListEntry->Flink) { - PMONITOR_PIPE Instance; +static BOOL +GetExecutable( + IN PCHAR DeviceName, + OUT PCHAR *Executable + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + HKEY Key; + DWORD MaxValueLength; + DWORD ExecutableLength; + DWORD Type; + HRESULT Error; - Instance = CONTAINING_RECORD(ListEntry, MONITOR_PIPE, ListEntry); + Error = RegOpenKeyExA(Context->ParametersKey, + DeviceName, + 0, + KEY_READ, + &Key); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail1; + } - PutString(Instance->Pipe, - Buffer, - Length); - } - LeaveCriticalSection(&Context->CriticalSection); + Error = RegQueryInfoKey(Key, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + &MaxValueLength, + NULL, + NULL); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail2; } - CloseHandle(Device); + ExecutableLength = MaxValueLength; - CloseHandle(Overlapped.hEvent); + *Executable = calloc(1, ExecutableLength); + if (Executable == NULL) + goto fail3; - Log("<===="); + Error = RegQueryValueExA(Key, + "Executable", + NULL, + &Type, + (LPBYTE)(*Executable), + &ExecutableLength); + if (Error != ERROR_SUCCESS) { + SetLastError(Error); + goto fail4; + } - return 0; + if (Type != REG_SZ) { + SetLastError(ERROR_BAD_FORMAT); + goto fail5; + } + + Log("%s = %s", DeviceName, *Executable); + + RegCloseKey(Key); + + return TRUE; + +fail5: + Log("fail5"); + +fail4: + Log("fail4"); + + free(*Executable); + +fail3: + Log("fail3"); fail2: - Log("fail2\n"); + Log("fail2"); - CloseHandle(Overlapped.hEvent); + RegCloseKey(Key); fail1: Error = GetLastError(); @@ -810,278 +735,614 @@ fail1: LocalFree(Message); } - return 1; + return FALSE; } -#define ECHO(_Handle, _Buffer) \ - PutString((_Handle), (PUCHAR)TEXT(_Buffer), (DWORD)_tcslen((_Buffer)) * sizeof(TCHAR)) +DWORD WINAPI +ExecutableThread( + IN LPVOID Argument + ) +{ + PMONITOR_CONSOLE Console = (PMONITOR_CONSOLE)Argument; + PCHAR Executable; + PROCESS_INFORMATION ProcessInfo; + STARTUPINFO StartupInfo; + BOOL Success; + HANDLE Handle[2]; + DWORD Object; + HRESULT Error; + + Log("====> %s", Console->DeviceName); + + // If there is no executable, this thread can finish now. + if (!GetExecutable(Console->DeviceName, + &Executable)) + goto done; + if (Executable == NULL) + goto done; + +again: + ZeroMemory(&ProcessInfo, sizeof (ProcessInfo)); + ZeroMemory(&StartupInfo, sizeof (StartupInfo)); + StartupInfo.cb = sizeof (StartupInfo); + + Log("Executing: %s", Executable); + +#pragma warning(suppress:6053) // CommandLine might not be NUL-terminated + Success = CreateProcess(NULL, + Executable, + NULL, + NULL, + FALSE, + CREATE_NO_WINDOW | + CREATE_NEW_PROCESS_GROUP, + NULL, + NULL, + &StartupInfo, + &ProcessInfo); + if (!Success) + goto fail1; + + Handle[0] = Console->ExecutableEvent; + 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(Console->ExecutableEvent); + + 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(Executable); -static VOID -MonitorAdd( - VOID +done: + Log("<==== %s", Console->DeviceName); + + return 0; + +fail1: + Error = GetLastError(); + + free(Executable); + + { + PTCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return 1; +} + +static PMONITOR_CONSOLE +ConsoleCreate( + IN PWCHAR DevicePath ) { PMONITOR_CONTEXT Context = &MonitorContext; - PTCHAR Path; + PMONITOR_CONSOLE Console; DEV_BROADCAST_HANDLE Handle; - HRESULT Error; + CHAR DeviceName[MAX_PATH]; + DWORD Bytes; BOOL Success; + HRESULT Error; - if (Context->Device != INVALID_HANDLE_VALUE) - return; - - Log("====>"); - - Success = MonitorGetPath(&GUID_XENCONS_DEVICE, &Path); + Log("====> %ws", DevicePath); - if (!Success) + Console = malloc(sizeof(MONITOR_CONSOLE)); + if (Console == NULL) goto fail1; - Context->Device = CreateFile(Path, - GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); + memset(Console, 0, sizeof(MONITOR_CONSOLE)); + __InitializeListHead(&Console->ListHead); + __InitializeListHead(&Console->ListEntry); + InitializeCriticalSection(&Console->CriticalSection); - if (Context->Device == INVALID_HANDLE_VALUE) + Console->DevicePath = _wcsdup(DevicePath); + if (Console->DevicePath == NULL) goto fail2; - ECHO(Context->Device, "\r\n[ATTACHED]\r\n"); - - ZeroMemory(&Handle, sizeof (Handle)); - Handle.dbch_size = sizeof (Handle); - Handle.dbch_devicetype = DBT_DEVTYP_HANDLE; - Handle.dbch_handle = Context->Device; - - Context->DeviceNotification = - RegisterDeviceNotification(Context->Service, - &Handle, - DEVICE_NOTIFY_SERVICE_HANDLE); - if (Context->DeviceNotification == NULL) - goto fail3; - - Context->DevicePath = Path; - __InitializeListHead(&Context->ListHead); - InitializeCriticalSection(&Context->CriticalSection); - - Context->MonitorEvent = CreateEvent(NULL, - TRUE, - FALSE, + Console->DeviceHandle = CreateFileW(DevicePath, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + if (Console->DeviceHandle == INVALID_HANDLE_VALUE) + goto fail3; - if (Context->MonitorEvent == NULL) + Success = DeviceIoControl(Console->DeviceHandle, + IOCTL_XENCONS_GET_NAME, + NULL, + 0, + DeviceName, + sizeof(DeviceName), + &Bytes, + NULL); + if (!Success) goto fail4; - Context->MonitorThread = CreateThread(NULL, - 0, - MonitorThread, - NULL, - 0, - NULL); + DeviceName[MAX_PATH - 1] = '\0'; - if (Context->MonitorThread == INVALID_HANDLE_VALUE) + Console->DeviceName = _strdup(DeviceName); + if (Console->DeviceName == NULL) goto fail5; - Context->DeviceEvent = CreateEvent(NULL, + ECHO(Console->DeviceHandle, "\r\n[ATTACHED]\r\n"); + + ZeroMemory(&Handle, sizeof (Handle)); + Handle.dbch_size = sizeof (Handle); + Handle.dbch_devicetype = DBT_DEVTYP_HANDLE; + Handle.dbch_handle = Console->DeviceHandle; + + Console->DeviceNotification = + RegisterDeviceNotification(Context->Service, + &Handle, + DEVICE_NOTIFY_SERVICE_HANDLE); + if (Console->DeviceNotification == NULL) + goto fail6; + + Console->DeviceEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (Console->DeviceEvent == NULL) + goto fail7; - if (Context->DeviceEvent == NULL) - goto fail6; - - Context->DeviceThread = CreateThread(NULL, + Console->DeviceThread = CreateThread(NULL, 0, DeviceThread, - NULL, + Console, 0, NULL); + if (Console->DeviceThread == NULL) + goto fail8; - if (Context->DeviceThread == INVALID_HANDLE_VALUE) - goto fail7; - - Context->ServerEvent = CreateEvent(NULL, + Console->ServerEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (Context->ServerEvent == NULL) - goto fail8; + if (Console->ServerEvent == NULL) + goto fail9; - Context->ServerThread = CreateThread(NULL, + Console->ServerThread = CreateThread(NULL, 0, ServerThread, - NULL, + Console, 0, NULL); - if (Context->ServerThread == INVALID_HANDLE_VALUE) - goto fail9; + if (Console->ServerThread == NULL) + goto fail10; - Log("<===="); + Console->ExecutableEvent = CreateEvent(NULL, + TRUE, + FALSE, + NULL); + if (Console->ExecutableEvent == NULL) + goto fail11; - return; + Console->ExecutableThread = CreateThread(NULL, + 0, + ExecutableThread, + Console, + 0, + NULL); + if (Console->ExecutableThread == NULL) + goto fail12; + + Log("<==== %s", Console->DeviceName); + + return Console; + +fail12: + Log("fail12"); + + CloseHandle(Console->ExecutableEvent); + Console->ExecutableEvent = NULL; + +fail11: + Log("fail11"); + + SetEvent(Console->ServerEvent); + WaitForSingleObject(Console->ServerThread, INFINITE); + +fail10: + Log("fail10"); + + CloseHandle(Console->ServerEvent); + Console->ServerEvent = NULL; fail9: Log("fail9"); - CloseHandle(Context->ServerEvent); - Context->ServerEvent = NULL; + SetEvent(Console->DeviceEvent); + WaitForSingleObject(Console->DeviceThread, INFINITE); fail8: Log("fail8"); - SetEvent(Context->DeviceEvent); - WaitForSingleObject(Context->DeviceThread, INFINITE); + CloseHandle(Console->DeviceEvent); + Console->DeviceEvent = NULL; fail7: - Log("fail7\n"); + Log("fail7"); - CloseHandle(Context->DeviceEvent); - Context->DeviceEvent = NULL; + UnregisterDeviceNotification(Console->DeviceNotification); + Console->DeviceNotification = NULL; fail6: - Log("fail6\n"); + Log("fail6"); - SetEvent(Context->MonitorThread); - WaitForSingleObject(Context->MonitorThread, INFINITE); + ECHO(Console->DeviceHandle, "\r\n[DETACHED]\r\n"); + + free(Console->DevicePath); + Console->DevicePath = NULL; fail5: Log("fail5"); - CloseHandle(Context->MonitorEvent); - Context->MonitorEvent = NULL; - fail4: Log("fail4"); - DeleteCriticalSection(&Context->CriticalSection); - ZeroMemory(&Context->ListHead, sizeof(LIST_ENTRY)); - - free(Context->DevicePath); - Context->DevicePath = NULL; - - UnregisterDeviceNotification(Context->DeviceNotification); - Context->DeviceNotification = NULL; + CloseHandle(Console->DeviceHandle); + Console->DeviceHandle = INVALID_HANDLE_VALUE; fail3: Log("fail3"); - CloseHandle(Context->Device); - Context->Device = INVALID_HANDLE_VALUE; + free(Console->DevicePath); + Console->DevicePath = NULL; fail2: Log("fail2"); - free(Path); + DeleteCriticalSection(&Console->CriticalSection); + ZeroMemory(&Console->ListHead, sizeof(LIST_ENTRY)); + ZeroMemory(&Console->ListEntry, sizeof(LIST_ENTRY)); + + free(Console); fail1: Error = GetLastError(); { - PTCHAR Message; + PCHAR Message; Message = GetErrorMessage(Error); Log("fail1 (%s)", Message); LocalFree(Message); } + + return NULL; } -static VOID -MonitorWaitForPipeThreads( - VOID +static FORCEINLINE VOID +ConsoleWaitForPipes( + IN PMONITOR_CONSOLE Console ) { - PMONITOR_CONTEXT Context = &MonitorContext; - HANDLE *Handles; - DWORD Index; - PLIST_ENTRY ListEntry; + PLIST_ENTRY ListEntry; + HANDLE *Events; + DWORD Count; + DWORD Index; - EnterCriticalSection(&Context->CriticalSection); + EnterCriticalSection(&Console->CriticalSection); - if (Context->ListCount == 0) + Count = Console->ListCount + 1; + Events = malloc(Count * sizeof(HANDLE)); + if (Events == NULL) goto fail1; - Handles = (HANDLE*)malloc(sizeof(HANDLE) * Context->ListCount); - if (Handles == NULL) - goto fail2; - Index = 0; - for (ListEntry = Context->ListHead.Flink; - ListEntry != &Context->ListHead && Index < Context->ListCount; + for (ListEntry = Console->ListHead.Flink; + ListEntry != &Console->ListHead; ListEntry = ListEntry->Flink) { - PMONITOR_PIPE Pipe = CONTAINING_RECORD(ListEntry, MONITOR_PIPE, ListEntry); - Handles[Index++] = Pipe->Thread; + PMONITOR_CONNECTION Connection; + + Connection = CONTAINING_RECORD(ListEntry, + MONITOR_CONNECTION, + ListEntry); + +#pragma warning(suppress: 6386) // Buffer overflow + Events[Index] = Connection->Thread; + ++Index; } + Events[Count - 1] = Console->ServerThread; - Context->ListCount = 0; + LeaveCriticalSection(&Console->CriticalSection); - LeaveCriticalSection(&Context->CriticalSection); + SetEvent(Console->ServerEvent); + WaitForMultipleObjects(Count, Events, TRUE, INFINITE); -#pragma warning(suppress:6385) // Reading invalid data from 'Handles'... - WaitForMultipleObjects(Index, - Handles, - TRUE, - INFINITE); - free(Handles); return; -fail2: - Log("fail2"); - fail1: - Log("fail1"); + LeaveCriticalSection(&Console->CriticalSection); + + // set the event and wait for the server thread anyway + SetEvent(Console->ServerEvent); + WaitForSingleObject(Console->ServerThread, INFINITE); +} + +static VOID +ConsoleDestroy( + IN PMONITOR_CONSOLE Console + ) +{ + Log("====> %s", Console->DeviceName); + + SetEvent(Console->ExecutableEvent); + WaitForSingleObject(Console->ExecutableThread, INFINITE); + + CloseHandle(Console->ExecutableEvent); + Console->ExecutableEvent = NULL; + + ConsoleWaitForPipes(Console); + + CloseHandle(Console->ServerEvent); + Console->ServerEvent = NULL; + + SetEvent(Console->DeviceEvent); + WaitForSingleObject(Console->DeviceThread, INFINITE); + + CloseHandle(Console->DeviceEvent); + Console->DeviceEvent = NULL; + + UnregisterDeviceNotification(Console->DeviceNotification); + Console->DeviceNotification = NULL; + + ECHO(Console->DeviceHandle, "\r\n[DETACHED]\r\n"); + + free(Console->DevicePath); + Console->DevicePath = NULL; + + CloseHandle(Console->DeviceHandle); + Console->DeviceHandle = INVALID_HANDLE_VALUE; + + free(Console->DevicePath); + Console->DevicePath = NULL; + + DeleteCriticalSection(&Console->CriticalSection); + ZeroMemory(&Console->ListHead, sizeof(LIST_ENTRY)); + ZeroMemory(&Console->ListEntry, sizeof(LIST_ENTRY)); + + free(Console); + Log("<===="); +} + +static BOOL +MonitorAdd( + IN PWCHAR DevicePath + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + PMONITOR_CONSOLE Console; + + Log("=====> %ws", DevicePath); + + Console = ConsoleCreate(DevicePath); + if (Console == NULL) + goto fail1; + + EnterCriticalSection(&Context->CriticalSection); + __InsertTailList(&Context->ListHead, &Console->ListEntry); + ++Context->ListCount; LeaveCriticalSection(&Context->CriticalSection); - return; + Log("<===== %s", Console->DeviceName); + + return TRUE; + +fail1: + Log("fail1"); + + return FALSE; } -static VOID +static BOOL MonitorRemove( - VOID + IN HANDLE DeviceHandle ) { PMONITOR_CONTEXT Context = &MonitorContext; + PMONITOR_CONSOLE Console; + PLIST_ENTRY ListEntry; - if (Context->Device == INVALID_HANDLE_VALUE) - return; + Log("=====> 0x%p", DeviceHandle); + + EnterCriticalSection(&Context->CriticalSection); + for (ListEntry = Context->ListHead.Flink; + ListEntry != &Context->ListHead; + ListEntry = ListEntry->Flink) { + Console = CONTAINING_RECORD(ListEntry, + MONITOR_CONSOLE, + ListEntry); + + if (Console->DeviceHandle == DeviceHandle) + goto found; + } + LeaveCriticalSection(&Context->CriticalSection); + Log("DeviceHandle 0x%p not found", DeviceHandle); + + return FALSE; + +found: + __RemoveEntryList(&Console->ListEntry); + --Context->ListCount; + LeaveCriticalSection(&Context->CriticalSection); + + ConsoleDestroy(Console); + + Log("<====="); + + return TRUE; +} + +static BOOL +MonitorEnumerate( + VOID + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + HDEVINFO DeviceInfoSet; + SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; + PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetail; + PMONITOR_CONSOLE Console; + DWORD Size; + DWORD Index; + HRESULT Error; + BOOL Success; + Log("====>"); + + DeviceInfoSet = SetupDiGetClassDevs(&GUID_XENCONS_DEVICE, + NULL, + NULL, + DIGCF_PRESENT | + DIGCF_DEVICEINTERFACE); + if (DeviceInfoSet == INVALID_HANDLE_VALUE) + goto fail1; + + DeviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA); - SetEvent(Context->ServerEvent); - MonitorWaitForPipeThreads(); - WaitForSingleObject(Context->ServerThread, INFINITE); + for (Index = 0; TRUE; ++Index) { + Success = SetupDiEnumDeviceInterfaces(DeviceInfoSet, + NULL, + &GUID_XENCONS_DEVICE, + Index, + &DeviceInterfaceData); + if (!Success) + break; - CloseHandle(Context->ServerEvent); - Context->ServerEvent = NULL; + Success = SetupDiGetDeviceInterfaceDetailW(DeviceInfoSet, + &DeviceInterfaceData, + NULL, + 0, + &Size, + NULL); + if (!Success && GetLastError() != ERROR_INSUFFICIENT_BUFFER) + goto fail2; + + DeviceInterfaceDetail = calloc(1, Size); + if (DeviceInterfaceDetail == NULL) + goto fail3; + + DeviceInterfaceDetail->cbSize = + sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA_W); + + Success = SetupDiGetDeviceInterfaceDetailW(DeviceInfoSet, + &DeviceInterfaceData, + DeviceInterfaceDetail, + Size, + NULL, + NULL); + if (!Success) + goto fail4; - SetEvent(Context->DeviceEvent); - WaitForSingleObject(Context->DeviceThread, INFINITE); + Console = ConsoleCreate(DeviceInterfaceDetail->DevicePath); + if (Console == NULL) + goto fail5; - CloseHandle(Context->DeviceEvent); - Context->DeviceEvent = NULL; + EnterCriticalSection(&Context->CriticalSection); + __InsertTailList(&Context->ListHead, &Console->ListEntry); + ++Context->ListCount; + LeaveCriticalSection(&Context->CriticalSection); - SetEvent(Context->MonitorEvent); - WaitForSingleObject(Context->MonitorThread, INFINITE); + free(DeviceInterfaceDetail); - CloseHandle(Context->MonitorEvent); - Context->MonitorEvent = NULL; + continue; - DeleteCriticalSection(&Context->CriticalSection); - ZeroMemory(&Context->ListHead, sizeof(LIST_ENTRY)); + fail5: + Log("fail5"); + fail4: + Log("fail4"); - free(Context->DevicePath); - Context->DevicePath = NULL; + free(DeviceInterfaceDetail); - UnregisterDeviceNotification(Context->DeviceNotification); - Context->DeviceNotification = NULL; + fail3: + Log("fail3"); + fail2: + Error = GetLastError(); - ECHO(Context->Device, "\r\n[DETACHED]\r\n"); + { + PCHAR Message; + Message = GetErrorMessage(Error); + Log("fail2 (%s)", Message); + LocalFree(Message); + } + } - CloseHandle(Context->Device); - Context->Device = INVALID_HANDLE_VALUE; + SetupDiDestroyDeviceInfoList(DeviceInfoSet); Log("<===="); + + return TRUE; + +fail1: + Error = GetLastError(); + + { + PCHAR Message; + Message = GetErrorMessage(Error); + Log("fail1 (%s)", Message); + LocalFree(Message); + } + + return FALSE; +} + +static VOID +MonitorRemoveAll( + VOID + ) +{ + PMONITOR_CONTEXT Context = &MonitorContext; + PMONITOR_CONSOLE Console; + + Log("=====>"); + + for (;;) { + EnterCriticalSection(&Context->CriticalSection); + if (Context->ListHead.Flink == &Context->ListHead) + break; + + Console = CONTAINING_RECORD(Context->ListHead.Flink, + MONITOR_CONSOLE, + ListEntry); + + __RemoveEntryList(&Console->ListEntry); + --Context->ListCount; + + LeaveCriticalSection(&Context->CriticalSection); + + ConsoleDestroy(Console); + } + LeaveCriticalSection(&Context->CriticalSection); + + Log("<====="); } DWORD WINAPI @@ -1113,11 +1374,11 @@ MonitorCtrlHandlerEx( switch (EventType) { case DBT_DEVICEARRIVAL: if (Header->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) { - PDEV_BROADCAST_DEVICEINTERFACE Interface = EventData; + PDEV_BROADCAST_DEVICEINTERFACE_W Interface = EventData; if (IsEqualGUID(&Interface->dbcc_classguid, - &GUID_XENCONS_DEVICE)) - SetEvent(Context->AddEvent); + &GUID_XENCONS_DEVICE)) + MonitorAdd(Interface->dbcc_name); } break; @@ -1127,8 +1388,7 @@ MonitorCtrlHandlerEx( if (Header->dbch_devicetype == DBT_DEVTYP_HANDLE) { PDEV_BROADCAST_HANDLE Device = EventData; - if (Device->dbch_handle == Context->Device) - SetEvent(Context->RemoveEvent); + MonitorRemove(Device->dbch_handle); } break; } @@ -1143,84 +1403,6 @@ 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, @@ -1230,14 +1412,13 @@ MonitorMain( PMONITOR_CONTEXT Context = &MonitorContext; DEV_BROADCAST_DEVICEINTERFACE Interface; HRESULT Error; - BOOL Success; UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); Log("====>"); - Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + Error = RegOpenKeyExA(HKEY_LOCAL_MACHINE, PARAMETERS_KEY(__MODULE__), 0, KEY_READ, @@ -1245,13 +1426,13 @@ MonitorMain( if (Error != ERROR_SUCCESS) goto fail1; - Context->Service = RegisterServiceCtrlHandlerEx(MONITOR_NAME, + Context->Service = RegisterServiceCtrlHandlerExA(MONITOR_NAME, MonitorCtrlHandlerEx, NULL); if (Context->Service == NULL) goto fail2; - Context->EventLog = RegisterEventSource(NULL, + Context->EventLog = RegisterEventSourceA(NULL, MONITOR_NAME); if (Context->EventLog == NULL) goto fail3; @@ -1269,28 +1450,6 @@ MonitorMain( if (Context->StopEvent == NULL) goto fail4; - Context->AddEvent = CreateEvent(NULL, - TRUE, - FALSE, - NULL); - - if (Context->AddEvent == NULL) - goto fail5; - - Context->RemoveEvent = CreateEvent(NULL, - TRUE, - FALSE, - NULL); - - if (Context->RemoveEvent == NULL) - goto fail6; - - Success = GetExecutable(&Context->Executable); - if (!Success) - Context->Executable = NULL; - - Context->Device = INVALID_HANDLE_VALUE; - ZeroMemory(&Interface, sizeof (Interface)); Interface.dbcc_size = sizeof (Interface); Interface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; @@ -1301,64 +1460,26 @@ MonitorMain( &Interface, DEVICE_NOTIFY_SERVICE_HANDLE); if (Context->InterfaceNotification == NULL) - goto fail7; - - // The device may already by present - SetEvent(Context->AddEvent); + goto fail5; ReportStatus(SERVICE_RUNNING, NO_ERROR, 0); - for (;;) { - HANDLE Events[3]; - DWORD Object; - - Events[0] = Context->StopEvent; - Events[1] = Context->AddEvent; - Events[2] = Context->RemoveEvent; - - Log("waiting (%u)...", ARRAYSIZE(Events)); - Object = WaitForMultipleObjects(ARRAYSIZE(Events), - Events, - FALSE, - INFINITE); - Log("awake"); - -#define WAIT_OBJECT_1 (WAIT_OBJECT_0 + 1) -#define WAIT_OBJECT_2 (WAIT_OBJECT_0 + 2) - - switch (Object) { - case WAIT_OBJECT_0: - ResetEvent(Context->StopEvent); - goto done; + __InitializeListHead(&Context->ListHead); + InitializeCriticalSection(&Context->CriticalSection); - case WAIT_OBJECT_1: - ResetEvent(Context->AddEvent); - MonitorAdd(); - break; + MonitorEnumerate(); - case WAIT_OBJECT_2: - ResetEvent(Context->RemoveEvent); - MonitorRemove(); + Log("Waiting..."); + WaitForSingleObject(Context->StopEvent, INFINITE); + Log("Wait Complete"); - default: - break; - } - -#undef WAIT_OBJECT_1 -#undef WAIT_OBJECT_2 - } + MonitorRemoveAll(); -done: - MonitorRemove(); + DeleteCriticalSection(&Context->CriticalSection); + ZeroMemory(&Context->ListHead, sizeof(LIST_ENTRY)); UnregisterDeviceNotification(Context->InterfaceNotification); - free(Context->Executable); - - CloseHandle(Context->RemoveEvent); - - CloseHandle(Context->AddEvent); - CloseHandle(Context->StopEvent); ReportStatus(SERVICE_STOPPED, NO_ERROR, 0); @@ -1371,16 +1492,6 @@ done: return; -fail7: - Log("fail7"); - - CloseHandle(Context->RemoveEvent); - -fail6: - Log("fail6"); - - CloseHandle(Context->AddEvent); - fail5: Log("fail5"); @@ -1419,12 +1530,12 @@ MonitorCreate( { SC_HANDLE SCManager; SC_HANDLE Service; - TCHAR Path[MAX_PATH]; + CHAR Path[MAX_PATH]; HRESULT Error; Log("====>"); - if(!GetModuleFileName(NULL, Path, MAX_PATH)) + if(!GetModuleFileNameA(NULL, Path, MAX_PATH)) goto fail1; SCManager = OpenSCManager(NULL, @@ -1589,7 +1700,7 @@ fail1: } int CALLBACK -_tWinMain( +WinMain( _In_ HINSTANCE Current, _In_opt_ HINSTANCE Previous, _In_ LPSTR CmdLine, @@ -1602,10 +1713,10 @@ _tWinMain( UNREFERENCED_PARAMETER(Previous); UNREFERENCED_PARAMETER(CmdShow); - if (_tcslen(CmdLine) != 0) { - if (_tcsicmp(CmdLine, TEXT("create")) == 0) + if (strlen(CmdLine) != 0) { + if (_stricmp(CmdLine, "create") == 0) Success = MonitorCreate(); - else if (_tcsicmp(CmdLine, TEXT("delete")) == 0) + else if (_stricmp(CmdLine, "delete") == 0) Success = MonitorDelete(); else Success = FALSE; diff --git a/src/tty/tty.c b/src/tty/tty.c index 94d4f65..d623c21 100644 --- a/src/tty/tty.c +++ b/src/tty/tty.c @@ -39,7 +39,7 @@ typedef struct _TTY_STREAM { HANDLE Write; } TTY_STREAM, *PTTY_STREAM; -#define PIPE_NAME TEXT("\\\\.\\pipe\\xencons") +#define PIPE_NAME TEXT("\\\\.\\pipe\\xencons\\default") #define MAXIMUM_BUFFER_SIZE 1024 typedef struct _TTY_CONTEXT { @@ -402,17 +402,23 @@ _tmain( UNREFERENCED_PARAMETER(argc); UNREFERENCED_PARAMETER(argv); + if (!WaitNamedPipe(PIPE_NAME, NMPWAIT_USE_DEFAULT_WAIT)) + ExitProcess(1); + Context->Device.Read = CreateFile(PIPE_NAME, - GENERIC_READ, - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - NULL); + GENERIC_READ, + FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); if (Context->Device.Read == INVALID_HANDLE_VALUE) ExitProcess(1); + if (!WaitNamedPipe(PIPE_NAME, NMPWAIT_USE_DEFAULT_WAIT)) + ExitProcess(1); + Context->Device.Write = CreateFile(PIPE_NAME, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, diff --git a/src/xencons.inf b/src/xencons.inf index 3cbdd96..37bc628 100644 --- a/src/xencons.inf +++ b/src/xencons.inf @@ -113,7 +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" +HKR,"Parameters\default","Executable",0x00000000,"xencons_tty_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.exe" [Monitor_EventLog] AddReg=Monitor_EventLog_AddReg -- 2.8.3 _______________________________________________ win-pv-devel mailing list win-pv-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/win-pv-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |