[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [win-pv-devel] [PATCH 06/14 v2] Make monitor service multi-console aware
> -----Original Message----- > From: win-pv-devel [mailto:win-pv-devel-bounces@xxxxxxxxxxxxxxxxxxxx] On > Behalf Of owen.smith@xxxxxxxxxx > Sent: 23 February 2018 14:22 > To: win-pv-devel@xxxxxxxxxxxxxxxxxxxx > Cc: Owen Smith <owen.smith@xxxxxxxxxx> > Subject: [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> Acked-by: Paul Durrant <paul.durrant@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_VERSI > ON@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.ex > e" > +HKR,"Parameters\default","Executable",0x00000000,"xencons_tty_@MAJ > OR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NU > MBER@.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 _______________________________________________ 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 |