|
[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 |