mirror of
https://github.com/gnif/LookingGlass.git
synced 2025-01-03 11:17:10 +00:00
[host] Windows: Implemented service to launch LG as the SYSTEM user
Experimental, use at your own peril! This commit adds the ability for the LG host to install and launch with Windows as a system service. To install simply run `looking-glass-host.exe InstallService` or conversely to uninstall `looking-glass-host.exe UninstallService`.
This commit is contained in:
parent
d9a80b16f0
commit
9a6b598438
2 changed files with 54 additions and 33 deletions
|
@ -7,6 +7,7 @@ include_directories(
|
||||||
|
|
||||||
add_library(platform_Windows STATIC
|
add_library(platform_Windows STATIC
|
||||||
src/platform.c
|
src/platform.c
|
||||||
|
src/service.c
|
||||||
src/mousehook.c
|
src/mousehook.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,6 +24,9 @@ target_link_libraries(platform_Windows
|
||||||
"${PROJECT_BINARY_DIR}/resource.o"
|
"${PROJECT_BINARY_DIR}/resource.o"
|
||||||
lg_common
|
lg_common
|
||||||
capture
|
capture
|
||||||
|
|
||||||
|
userenv
|
||||||
|
wtsapi32
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(platform_Windows
|
target_include_directories(platform_Windows
|
||||||
|
|
|
@ -18,6 +18,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "service.h"
|
||||||
#include "windows/mousehook.h"
|
#include "windows/mousehook.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -42,9 +43,11 @@ struct AppState
|
||||||
int argc;
|
int argc;
|
||||||
char ** argv;
|
char ** argv;
|
||||||
|
|
||||||
char executable[MAX_PATH + 1];
|
char executable[MAX_PATH + 1];
|
||||||
HWND messageWnd;
|
HWND messageWnd;
|
||||||
HMENU trayMenu;
|
NOTIFYICONDATA iconData;
|
||||||
|
UINT trayRestartMsg;
|
||||||
|
HMENU trayMenu;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct AppState app = {0};
|
static struct AppState app = {0};
|
||||||
|
@ -54,6 +57,21 @@ HWND MessageHWND;
|
||||||
typedef NTSTATUS (__stdcall *ZwSetTimerResolution_t)(ULONG RequestedResolution, BOOLEAN Set, PULONG ActualResolution);
|
typedef NTSTATUS (__stdcall *ZwSetTimerResolution_t)(ULONG RequestedResolution, BOOLEAN Set, PULONG ActualResolution);
|
||||||
static ZwSetTimerResolution_t ZwSetTimerResolution = NULL;
|
static ZwSetTimerResolution_t ZwSetTimerResolution = NULL;
|
||||||
|
|
||||||
|
static void RegisterTrayIcon()
|
||||||
|
{
|
||||||
|
// register our TrayIcon
|
||||||
|
if (!app.iconData.cbSize)
|
||||||
|
{
|
||||||
|
app.iconData.cbSize = sizeof(NOTIFYICONDATA);
|
||||||
|
app.iconData.hWnd = app.messageWnd;
|
||||||
|
app.iconData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
|
||||||
|
app.iconData.uCallbackMessage = WM_TRAYICON;
|
||||||
|
strncpy(app.iconData.szTip, "Looking Glass (host)", sizeof(app.iconData.szTip));
|
||||||
|
app.iconData.hIcon = LoadIcon(app.hInst, IDI_APPLICATION);
|
||||||
|
}
|
||||||
|
Shell_NotifyIcon(NIM_ADD, &app.iconData);
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
switch(msg)
|
switch(msg)
|
||||||
|
@ -99,28 +117,20 @@ LRESULT CALLBACK DummyWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
if (msg == app.trayRestartMsg)
|
||||||
|
RegisterTrayIcon();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int appThread(void * opaque)
|
static int appThread(void * opaque)
|
||||||
{
|
{
|
||||||
// register our TrayIcon
|
RegisterTrayIcon();
|
||||||
NOTIFYICONDATA iconData =
|
|
||||||
{
|
|
||||||
.cbSize = sizeof(NOTIFYICONDATA),
|
|
||||||
.hWnd = app.messageWnd,
|
|
||||||
.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP,
|
|
||||||
.uCallbackMessage = WM_TRAYICON,
|
|
||||||
.szTip = "Looking Glass (host)"
|
|
||||||
};
|
|
||||||
iconData.hIcon = LoadIcon(app.hInst, IDI_APPLICATION);
|
|
||||||
Shell_NotifyIcon(NIM_ADD, &iconData);
|
|
||||||
|
|
||||||
int result = app_main(app.argc, app.argv);
|
int result = app_main(app.argc, app.argv);
|
||||||
|
|
||||||
Shell_NotifyIcon(NIM_DELETE, &iconData);
|
Shell_NotifyIcon(NIM_DELETE, &app.iconData);
|
||||||
mouseHook_remove();
|
mouseHook_remove();
|
||||||
SendMessage(app.messageWnd, WM_DESTROY, 0, 0);
|
SendMessage(app.messageWnd, WM_DESTROY, 0, 0);
|
||||||
return result;
|
return result;
|
||||||
|
@ -144,6 +154,21 @@ static BOOL WINAPI CtrlHandler(DWORD dwCtrlType)
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
{
|
{
|
||||||
|
// convert the command line to the standard argc and argv
|
||||||
|
LPWSTR * wargv = CommandLineToArgvW(GetCommandLineW(), &app.argc);
|
||||||
|
app.argv = malloc(sizeof(char *) * app.argc);
|
||||||
|
for(int i = 0; i < app.argc; ++i)
|
||||||
|
{
|
||||||
|
const size_t s = (wcslen(wargv[i])+1) * 2;
|
||||||
|
app.argv[i] = malloc(s);
|
||||||
|
wcstombs(app.argv[i], wargv[i], s);
|
||||||
|
}
|
||||||
|
LocalFree(wargv);
|
||||||
|
|
||||||
|
GetModuleFileName(NULL, app.executable, sizeof(app.executable));
|
||||||
|
if (HandleService(app.argc, app.argv))
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* this is a bit of a hack but without this --help will produce no output in a windows command prompt */
|
/* this is a bit of a hack but without this --help will produce no output in a windows command prompt */
|
||||||
if (!IsDebuggerPresent() && AttachConsole(ATTACH_PARENT_PROCESS))
|
if (!IsDebuggerPresent() && AttachConsole(ATTACH_PARENT_PROCESS))
|
||||||
{
|
{
|
||||||
|
@ -183,19 +208,6 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
option_register(options);
|
option_register(options);
|
||||||
free(logFilePath);
|
free(logFilePath);
|
||||||
|
|
||||||
// convert the command line to the standard argc and argv
|
|
||||||
LPWSTR * wargv = CommandLineToArgvW(GetCommandLineW(), &app.argc);
|
|
||||||
app.argv = malloc(sizeof(char *) * app.argc);
|
|
||||||
for(int i = 0; i < app.argc; ++i)
|
|
||||||
{
|
|
||||||
const size_t s = (wcslen(wargv[i])+1) * 2;
|
|
||||||
app.argv[i] = malloc(s);
|
|
||||||
wcstombs(app.argv[i], wargv[i], s);
|
|
||||||
}
|
|
||||||
LocalFree(wargv);
|
|
||||||
|
|
||||||
GetModuleFileName(NULL, app.executable, sizeof(app.executable));
|
|
||||||
|
|
||||||
// setup a handler for ctrl+c
|
// setup a handler for ctrl+c
|
||||||
SetConsoleCtrlHandler(CtrlHandler, TRUE);
|
SetConsoleCtrlHandler(CtrlHandler, TRUE);
|
||||||
|
|
||||||
|
@ -209,13 +221,18 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||||
wx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
wx.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
wx.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wx.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
wx.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
|
wx.hbrBackground = (HBRUSH)COLOR_APPWORKSPACE;
|
||||||
if (!RegisterClassEx(&wx))
|
ATOM class;
|
||||||
|
if (!(class = RegisterClassEx(&wx)))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("Failed to register message window class");
|
DEBUG_ERROR("Failed to register message window class");
|
||||||
result = -1;
|
result = -1;
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
app.messageWnd = CreateWindowEx(0, "DUMMY_CLASS", "DUMMY_NAME", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
|
|
||||||
|
app.trayRestartMsg = RegisterWindowMessage("TaskbarCreated");
|
||||||
|
|
||||||
|
app.messageWnd = CreateWindowEx(0, MAKEINTATOM(class), NULL, 0, 0, 0, 0, 0, NULL, NULL, hInstance, NULL);
|
||||||
|
ChangeWindowMessageFilterEx(app.messageWnd, app.trayRestartMsg, MSGFLT_ALLOW, NULL);
|
||||||
|
|
||||||
// set the global
|
// set the global
|
||||||
MessageHWND = app.messageWnd;
|
MessageHWND = app.messageWnd;
|
||||||
|
|
Loading…
Reference in a new issue