From 38198b14777a34312e31eecb883a8966ee7dfe74 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 30 Dec 2020 18:29:58 +1100 Subject: [PATCH] [host] dynamically locate CreateProcesssAsUserA for pre-win 10 --- host/platform/Windows/src/service.c | 52 ++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/host/platform/Windows/src/service.c b/host/platform/Windows/src/service.c index 52f01f54..f148c778 100644 --- a/host/platform/Windows/src/service.c +++ b/host/platform/Windows/src/service.c @@ -38,6 +38,24 @@ Place, Suite 330, Boston, MA 02111-1307 USA #define SVCNAME "Looking Glass (host)" #define SVC_ERROR ((DWORD)0xC0020001L) +/* + * Windows 10 provides this API via kernel32.dll as well as advapi32.dll and + * mingw opts for linking against the kernel32.dll version which is fine + * provided you don't intend to run this on earlier versions of windows. As such + * we need to lookup this method at runtime. */ +typedef WINBOOL WINAPI (*CreateProcessAsUserA_t)(HANDLE hToken, + LPCSTR lpApplicationName, + LPSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + WINBOOL bInheritHandles, + DWORD dwCreationFlags, + LPVOID lpEnvironment, + LPCSTR lpCurrentDirectory, + LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation); +static CreateProcessAsUserA_t f_CreateProcessAsUserA = NULL; + struct Service { FILE * logFile; @@ -55,6 +73,32 @@ void doLog(const char * fmt, ...) va_end(args); } +static bool setupAPI() +{ + /* first look in kernel32.dll */ + HMODULE mod; + + mod = GetModuleHandleA("kernel32.dll"); + if (mod) + { + f_CreateProcessAsUserA = (CreateProcessAsUserA_t) + GetProcAddress(mod, "CreateProcessAsUserA"); + if (f_CreateProcessAsUserA) + return true; + } + + mod = GetModuleHandleA("advapi32.dll"); + if (mod) + { + f_CreateProcessAsUserA = (CreateProcessAsUserA_t) + GetProcAddress(mod, "CreateProcessAsUserA"); + if (f_CreateProcessAsUserA) + return true; + } + + return false; +} + static void setupLogging() { char tempPath[MAX_PATH+1]; @@ -216,6 +260,12 @@ DWORD GetInteractiveSessionID() void Launch() { + if (!setupAPI()) + { + doLog("setupAPI failed\n"); + return; + } + if (!enablePriv(SE_DEBUG_NAME)) return; @@ -283,7 +333,7 @@ void Launch() }; char * exe = strdup(os_getExecutable()); - if (!CreateProcessAsUserA( + if (!f_CreateProcessAsUserA( hToken, NULL, exe,