1
/* $Id: VBoxServicePageSharing.cpp $ */
3
* VBoxService - Guest page sharing.
7
* Copyright (C) 2006-2012 Oracle Corporation
9
* This file is part of VirtualBox Open Source Edition (OSE), as
10
* available from http://www.virtualbox.org. This file is free software;
11
* you can redistribute it and/or modify it under the terms of the GNU
12
* General Public License (GPL) as published by the Free Software
13
* Foundation, in version 2 as it comes in the "COPYING" file of the
14
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19
/*******************************************************************************
21
*******************************************************************************/
22
#include <iprt/assert.h>
27
#include <iprt/process.h>
29
#include <iprt/stream.h>
30
#include <iprt/file.h>
31
#include <iprt/string.h>
32
#include <iprt/semaphore.h>
33
#include <iprt/system.h>
34
#include <iprt/thread.h>
35
#include <iprt/time.h>
36
#include <VBox/VBoxGuestLib.h>
37
#include "VBoxServiceInternal.h"
38
#include "VBoxServiceUtils.h"
41
/*******************************************************************************
43
*******************************************************************************/
45
/** The semaphore we're blocking on. */
46
static RTSEMEVENTMULTI g_PageSharingEvent = NIL_RTSEMEVENTMULTI;
48
#if defined(RT_OS_WINDOWS) && !defined(TARGET_NT4)
57
char szFileVersion[16];
59
} KNOWN_MODULE, *PKNOWN_MODULE;
61
#define SystemModuleInformation 11
63
typedef struct _RTL_PROCESS_MODULE_INFORMATION
70
USHORT LoadOrderIndex;
71
USHORT InitOrderIndex;
73
USHORT OffsetToFileName;
74
CHAR FullPathName[256];
75
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
77
typedef struct _RTL_PROCESS_MODULES
79
ULONG NumberOfModules;
80
RTL_PROCESS_MODULE_INFORMATION Modules[1];
81
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
83
typedef NTSTATUS (WINAPI *PFNZWQUERYSYSTEMINFORMATION)(ULONG, PVOID, ULONG, PULONG);
84
static PFNZWQUERYSYSTEMINFORMATION g_pfnZwQuerySystemInformation = NULL;
87
static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE pNode, void *pvUser);
89
static PAVLPVNODECORE g_pKnownModuleTree = NULL;
90
static uint64_t g_idSession = 0;
93
* Registers a new module with the VMM
94
* @param pModule Module ptr
95
* @param fValidateMemory Validate/touch memory pages or not
97
void VBoxServicePageSharingRegisterModule(PKNOWN_MODULE pModule, bool fValidateMemory)
99
VMMDEVSHAREDREGIONDESC aRegions[VMMDEVSHAREDREGIONDESC_MAX];
100
DWORD dwModuleSize = pModule->Info.modBaseSize;
101
BYTE *pBaseAddress = pModule->Info.modBaseAddr;
102
DWORD cbVersionSize, dummy;
105
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule\n");
107
cbVersionSize = GetFileVersionInfoSize(pModule->Info.szExePath, &dummy);
110
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: GetFileVersionInfoSize failed with %d\n", GetLastError());
113
pVersionInfo = (BYTE *)RTMemAlloc(cbVersionSize);
117
if (!GetFileVersionInfo(pModule->Info.szExePath, 0, cbVersionSize, pVersionInfo))
119
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: GetFileVersionInfo failed with %d\n", GetLastError());
123
/* Fetch default code page. */
124
struct LANGANDCODEPAGE {
130
BOOL ret = VerQueryValue(pVersionInfo, TEXT("\\VarFileInfo\\Translation"), (LPVOID *)&lpTranslate, &cbTranslate);
134
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VerQueryValue failed with %d (cb=%d)\n", GetLastError(), cbTranslate);
140
char *lpszFileVersion;
141
unsigned cTranslationBlocks = cbTranslate/sizeof(struct LANGANDCODEPAGE);
143
for(i = 0; i < cTranslationBlocks; i++)
145
/* Fetch file version string. */
146
char szFileVersionLocation[256];
148
sprintf(szFileVersionLocation, TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"), lpTranslate[i].wLanguage, lpTranslate[i].wCodePage);
149
ret = VerQueryValue(pVersionInfo, szFileVersionLocation, (LPVOID *)&lpszFileVersion, &cbFileVersion);
153
if (i == cTranslationBlocks)
155
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: no file version found!\n");
159
_snprintf(pModule->szFileVersion, sizeof(pModule->szFileVersion), "%s", lpszFileVersion);
160
pModule->szFileVersion[RT_ELEMENTS(pModule->szFileVersion) - 1] = 0;
162
unsigned idxRegion = 0;
168
MEMORY_BASIC_INFORMATION MemInfo;
170
SIZE_T ret = VirtualQuery(pBaseAddress, &MemInfo, sizeof(MemInfo));
174
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VirtualQueryEx failed with %d\n", GetLastError());
178
if ( MemInfo.State == MEM_COMMIT
179
&& MemInfo.Type == MEM_IMAGE)
181
switch (MemInfo.Protect)
184
case PAGE_EXECUTE_READ:
187
char *pRegion = (char *)MemInfo.BaseAddress;
189
/* Skip the first region as it only contains the image file header. */
190
if (pRegion != (char *)pModule->Info.modBaseAddr)
192
/* Touch all pages. */
193
while (pRegion < (char *)MemInfo.BaseAddress + MemInfo.RegionSize)
195
/* Try to trick the optimizer to leave the page touching code in place. */
196
ASMProbeReadByte(pRegion);
197
pRegion += PAGE_SIZE;
201
aRegions[idxRegion].GCRegionAddr = (RTGCPTR32)MemInfo.BaseAddress;
203
aRegions[idxRegion].GCRegionAddr = (RTGCPTR64)MemInfo.BaseAddress;
205
aRegions[idxRegion].cbRegion = MemInfo.RegionSize;
216
pBaseAddress = (BYTE *)MemInfo.BaseAddress + MemInfo.RegionSize;
217
if (dwModuleSize > MemInfo.RegionSize)
219
dwModuleSize -= MemInfo.RegionSize;
227
if (idxRegion >= RT_ELEMENTS(aRegions))
228
break; /* out of room */
230
while (dwModuleSize);
234
/* We can't probe kernel memory ranges, so pretend it's one big region. */
236
aRegions[idxRegion].GCRegionAddr = (RTGCPTR32)pBaseAddress;
238
aRegions[idxRegion].GCRegionAddr = (RTGCPTR64)pBaseAddress;
240
aRegions[idxRegion].cbRegion = dwModuleSize;
243
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VbglR3RegisterSharedModule %s %s base=%p size=%x cregions=%d\n", pModule->Info.szModule, pModule->szFileVersion, pModule->Info.modBaseAddr, pModule->Info.modBaseSize, idxRegion);
244
int rc = VbglR3RegisterSharedModule(pModule->Info.szModule, pModule->szFileVersion, (uintptr_t)pModule->Info.modBaseAddr,
245
pModule->Info.modBaseSize, idxRegion, aRegions);
247
VBoxServiceVerbose(3, "VBoxServicePageSharingRegisterModule: VbglR3RegisterSharedModule failed with %Rrc\n", rc);
250
RTMemFree(pVersionInfo);
255
* Inspect all loaded modules for the specified process
256
* @param dwProcessId Process id
258
void VBoxServicePageSharingInspectModules(DWORD dwProcessId, PAVLPVNODECORE *ppNewTree)
260
HANDLE hProcess, hSnapshot;
262
/* Get a list of all the modules in this process. */
263
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
264
FALSE /* no child process handle inheritance */, dwProcessId);
265
if (hProcess == NULL)
267
VBoxServiceVerbose(3, "VBoxServicePageSharingInspectModules: OpenProcess %x failed with %d\n", dwProcessId, GetLastError());
271
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
272
if (hSnapshot == INVALID_HANDLE_VALUE)
274
VBoxServiceVerbose(3, "VBoxServicePageSharingInspectModules: CreateToolhelp32Snapshot failed with %d\n", GetLastError());
275
CloseHandle(hProcess);
279
VBoxServiceVerbose(3, "VBoxServicePageSharingInspectModules\n");
281
MODULEENTRY32 ModuleInfo;
284
ModuleInfo.dwSize = sizeof(ModuleInfo);
285
bRet = Module32First(hSnapshot, &ModuleInfo);
288
/** @todo when changing this make sure VBoxService.exe is excluded! */
289
char *pszDot = strrchr(ModuleInfo.szModule, '.');
291
&& (pszDot[1] == 'e' || pszDot[1] == 'E'))
292
continue; /* ignore executables for now. */
294
/* Found it before? */
295
PAVLPVNODECORE pRec = RTAvlPVGet(ppNewTree, ModuleInfo.modBaseAddr);
298
pRec = RTAvlPVRemove(&g_pKnownModuleTree, ModuleInfo.modBaseAddr);
301
/* New module; register it. */
302
PKNOWN_MODULE pModule = (PKNOWN_MODULE)RTMemAllocZ(sizeof(*pModule));
307
pModule->Info = ModuleInfo;
308
pModule->Core.Key = ModuleInfo.modBaseAddr;
309
pModule->hModule = LoadLibraryEx(ModuleInfo.szExePath, 0, DONT_RESOLVE_DLL_REFERENCES);
310
if (pModule->hModule)
311
VBoxServicePageSharingRegisterModule(pModule, true /* validate pages */);
313
VBoxServiceVerbose(3, "\n\n MODULE NAME: %s", ModuleInfo.szModule );
314
VBoxServiceVerbose(3, "\n executable = %s", ModuleInfo.szExePath );
315
VBoxServiceVerbose(3, "\n process ID = 0x%08X", ModuleInfo.th32ProcessID );
316
VBoxServiceVerbose(3, "\n base address = 0x%08X", (DWORD) ModuleInfo.modBaseAddr );
317
VBoxServiceVerbose(3, "\n base size = %d", ModuleInfo.modBaseSize );
319
pRec = &pModule->Core;
321
bool ret = RTAvlPVInsert(ppNewTree, pRec);
322
Assert(ret); NOREF(ret);
325
while (Module32Next(hSnapshot, &ModuleInfo));
327
CloseHandle(hSnapshot);
328
CloseHandle(hProcess);
332
* Inspect all running processes for executables and dlls that might be worth sharing
336
void VBoxServicePageSharingInspectGuest()
339
PAVLPVNODECORE pNewTree = NULL;
340
DWORD dwProcessId = GetCurrentProcessId();
342
VBoxServiceVerbose(3, "VBoxServicePageSharingInspectGuest\n");
344
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
345
if (hSnapshot == INVALID_HANDLE_VALUE)
347
VBoxServiceVerbose(3, "VBoxServicePageSharingInspectGuest: CreateToolhelp32Snapshot failed with %d\n", GetLastError());
351
/* Check loaded modules for all running processes. */
352
PROCESSENTRY32 ProcessInfo;
354
ProcessInfo.dwSize = sizeof(ProcessInfo);
355
Process32First(hSnapshot, &ProcessInfo);
359
/* Skip our own process. */
360
if (ProcessInfo.th32ProcessID != dwProcessId)
361
VBoxServicePageSharingInspectModules(ProcessInfo.th32ProcessID, &pNewTree);
363
while (Process32Next(hSnapshot, &ProcessInfo));
365
CloseHandle(hSnapshot);
367
/* Check all loaded kernel modules. */
368
if (g_pfnZwQuerySystemInformation)
371
PVOID pBuffer = NULL;
372
PRTL_PROCESS_MODULES pSystemModules;
374
NTSTATUS ret = g_pfnZwQuerySystemInformation(SystemModuleInformation, (PVOID)&cbBuffer, 0, &cbBuffer);
377
VBoxServiceVerbose(1, "ZwQuerySystemInformation returned length 0\n");
378
goto skipkernelmodules;
381
pBuffer = RTMemAllocZ(cbBuffer);
383
goto skipkernelmodules;
385
ret = g_pfnZwQuerySystemInformation(SystemModuleInformation, pBuffer, cbBuffer, &cbBuffer);
386
if (ret != STATUS_SUCCESS)
388
VBoxServiceVerbose(1, "ZwQuerySystemInformation returned %x (1)\n", ret);
389
goto skipkernelmodules;
392
pSystemModules = (PRTL_PROCESS_MODULES)pBuffer;
393
for (unsigned i = 0; i < pSystemModules->NumberOfModules; i++)
395
VBoxServiceVerbose(4, "\n\n KERNEL MODULE NAME: %s", pSystemModules->Modules[i].FullPathName[pSystemModules->Modules[i].OffsetToFileName] );
396
VBoxServiceVerbose(4, "\n executable = %s", pSystemModules->Modules[i].FullPathName );
397
VBoxServiceVerbose(4, "\n flags = 0x%08X\n", pSystemModules->Modules[i].Flags);
399
/* User-mode modules seem to have no flags set; skip them as we detected them above. */
400
if (pSystemModules->Modules[i].Flags == 0)
403
/* Found it before? */
404
PAVLPVNODECORE pRec = RTAvlPVGet(&pNewTree, pSystemModules->Modules[i].ImageBase);
407
pRec = RTAvlPVRemove(&g_pKnownModuleTree, pSystemModules->Modules[i].ImageBase);
410
/* New module; register it. */
411
char szFullFilePath[512];
412
PKNOWN_MODULE pModule = (PKNOWN_MODULE)RTMemAllocZ(sizeof(*pModule));
417
strcpy(pModule->Info.szModule, &pSystemModules->Modules[i].FullPathName[pSystemModules->Modules[i].OffsetToFileName]);
418
GetSystemDirectoryA(szFullFilePath, sizeof(szFullFilePath));
420
/* skip \Systemroot\system32 */
421
char *lpPath = strchr(&pSystemModules->Modules[i].FullPathName[1], '\\');
424
/* Seen just file names in XP; try to locate the file in the system32 and system32\drivers directories. */
425
strcat(szFullFilePath, "\\");
426
strcat(szFullFilePath, pSystemModules->Modules[i].FullPathName);
427
VBoxServiceVerbose(3, "Unexpected kernel module name try %s\n", szFullFilePath);
428
if (RTFileExists(szFullFilePath) == false)
430
GetSystemDirectoryA(szFullFilePath, sizeof(szFullFilePath));
431
strcat(szFullFilePath, "\\drivers\\");
432
strcat(szFullFilePath, pSystemModules->Modules[i].FullPathName);
433
VBoxServiceVerbose(3, "Unexpected kernel module name try %s\n", szFullFilePath);
434
if (RTFileExists(szFullFilePath) == false)
436
VBoxServiceVerbose(1, "Unexpected kernel module name %s\n", pSystemModules->Modules[i].FullPathName);
444
lpPath = strchr(lpPath+1, '\\');
447
VBoxServiceVerbose(1, "Unexpected kernel module name %s (2)\n", pSystemModules->Modules[i].FullPathName);
452
strcat(szFullFilePath, lpPath);
455
strcpy(pModule->Info.szExePath, szFullFilePath);
456
pModule->Info.modBaseAddr = (BYTE *)pSystemModules->Modules[i].ImageBase;
457
pModule->Info.modBaseSize = pSystemModules->Modules[i].ImageSize;
459
pModule->Core.Key = pSystemModules->Modules[i].ImageBase;
460
VBoxServicePageSharingRegisterModule(pModule, false /* don't check memory pages */);
462
VBoxServiceVerbose(3, "\n\n KERNEL MODULE NAME: %s", pModule->Info.szModule );
463
VBoxServiceVerbose(3, "\n executable = %s", pModule->Info.szExePath );
464
VBoxServiceVerbose(3, "\n base address = 0x%08X", (DWORD) pModule->Info.modBaseAddr );
465
VBoxServiceVerbose(3, "\n flags = 0x%08X", pSystemModules->Modules[i].Flags);
466
VBoxServiceVerbose(3, "\n base size = %d", pModule->Info.modBaseSize );
468
pRec = &pModule->Core;
470
bool ret = RTAvlPVInsert(&pNewTree, pRec);
471
Assert(ret); NOREF(ret);
479
/* Delete leftover modules in the old tree. */
480
RTAvlPVDestroy(&g_pKnownModuleTree, VBoxServicePageSharingEmptyTreeCallback, NULL);
482
/* Check all registered modules. */
483
VbglR3CheckSharedModules();
485
/* Activate new module tree. */
486
g_pKnownModuleTree = pNewTree;
490
* RTAvlPVDestroy callback.
492
static DECLCALLBACK(int) VBoxServicePageSharingEmptyTreeCallback(PAVLPVNODECORE pNode, void *pvUser)
494
PKNOWN_MODULE pModule = (PKNOWN_MODULE)pNode;
495
bool *pfUnregister = (bool *)pvUser;
497
VBoxServiceVerbose(3, "VBoxServicePageSharingEmptyTreeCallback %s %s\n", pModule->Info.szModule, pModule->szFileVersion);
499
/* Dereference module in the hypervisor. */
503
int rc = VbglR3UnregisterSharedModule(pModule->Info.szModule, pModule->szFileVersion,
504
(uintptr_t)pModule->Info.modBaseAddr, pModule->Info.modBaseSize);
508
if (pModule->hModule)
509
FreeLibrary(pModule->hModule);
516
void VBoxServicePageSharingInspectGuest()
518
/* not implemented */
521
void VBoxServicePageSharingInspectGuest()
523
/* @todo other platforms */
527
/** @copydoc VBOXSERVICE::pfnInit */
528
static DECLCALLBACK(int) VBoxServicePageSharingInit(void)
530
VBoxServiceVerbose(3, "VBoxServicePageSharingInit\n");
532
int rc = RTSemEventMultiCreate(&g_PageSharingEvent);
533
AssertRCReturn(rc, rc);
535
#if defined(RT_OS_WINDOWS) && !defined(TARGET_NT4)
536
g_pfnZwQuerySystemInformation = (PFNZWQUERYSYSTEMINFORMATION)RTLdrGetSystemSymbol("ntdll.dll", "ZwQuerySystemInformation");
538
rc = VbglR3GetSessionId(&g_idSession);
541
if (rc == VERR_IO_GEN_FAILURE)
542
VBoxServiceVerbose(0, "PageSharing: Page sharing support is not available by the host\n");
544
VBoxServiceError("VBoxServicePageSharingInit: Failed with rc=%Rrc\n", rc);
546
rc = VERR_SERVICE_DISABLED;
548
RTSemEventMultiDestroy(g_PageSharingEvent);
549
g_PageSharingEvent = NIL_RTSEMEVENTMULTI;
557
/** @copydoc VBOXSERVICE::pfnWorker */
558
DECLCALLBACK(int) VBoxServicePageSharingWorker(bool volatile *pfShutdown)
561
* Tell the control thread that it can continue
564
RTThreadUserSignal(RTThreadSelf());
567
* Now enter the loop retrieving runtime data continuously.
571
BOOL fEnabled = VbglR3PageSharingIsEnabled();
573
VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: enabled=%d\n", fEnabled);
576
VBoxServicePageSharingInspectGuest();
579
* Block for a minute.
581
* The event semaphore takes care of ignoring interruptions and it
582
* allows us to implement service wakeup later.
586
int rc = RTSemEventMultiWait(g_PageSharingEvent, 60000);
589
if (rc != VERR_TIMEOUT && RT_FAILURE(rc))
591
VBoxServiceError("VBoxServicePageSharingWorker: RTSemEventMultiWait failed; rc=%Rrc\n", rc);
594
#if defined(RT_OS_WINDOWS) && !defined(TARGET_NT4)
595
uint64_t idNewSession = g_idSession;
596
rc = VbglR3GetSessionId(&idNewSession);
599
if (idNewSession != g_idSession)
601
bool fUnregister = false;
603
VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: VM was restored!!\n");
604
/* The VM was restored, so reregister all modules the next time. */
605
RTAvlPVDestroy(&g_pKnownModuleTree, VBoxServicePageSharingEmptyTreeCallback, &fUnregister);
606
g_pKnownModuleTree = NULL;
608
g_idSession = idNewSession;
613
RTSemEventMultiDestroy(g_PageSharingEvent);
614
g_PageSharingEvent = NIL_RTSEMEVENTMULTI;
616
VBoxServiceVerbose(3, "VBoxServicePageSharingWorker: finished thread\n");
623
* This gets control when VBoxService is launched with -pagefusionfork by
624
* VBoxServicePageSharingWorkerProcess().
626
* @returns RTEXITCODE_SUCCESS.
628
* @remarks It won't normally return since the parent drops the shutdown hint
629
* via RTProcTerminate().
631
RTEXITCODE VBoxServicePageSharingInitFork(void)
633
VBoxServiceVerbose(3, "VBoxServicePageSharingInitFork\n");
635
bool fShutdown = false;
636
VBoxServicePageSharingInit();
637
VBoxServicePageSharingWorker(&fShutdown);
639
return RTEXITCODE_SUCCESS;
642
/** @copydoc VBOXSERVICE::pfnWorker */
643
DECLCALLBACK(int) VBoxServicePageSharingWorkerProcess(bool volatile *pfShutdown)
645
RTPROCESS hProcess = NIL_RTPROCESS;
649
* Tell the control thread that it can continue
652
RTThreadUserSignal(RTThreadSelf());
655
* Now enter the loop retrieving runtime data continuously.
659
BOOL fEnabled = VbglR3PageSharingIsEnabled();
660
VBoxServiceVerbose(3, "VBoxServicePageSharingWorkerProcess: enabled=%d\n", fEnabled);
663
* Start a 2nd VBoxService process to deal with page fusion as we do
664
* not wish to dummy load dlls into this process. (First load with
665
* DONT_RESOLVE_DLL_REFERENCES, 2nd normal -> dll init routines not called!)
668
&& hProcess == NIL_RTPROCESS)
671
char *pszExeName = RTProcGetExecutablePath(szExeName, sizeof(szExeName));
674
char const *papszArgs[3];
675
papszArgs[0] = pszExeName;
676
papszArgs[1] = "pagefusion";
678
rc = RTProcCreate(pszExeName, papszArgs, RTENV_DEFAULT, 0 /* normal child */, &hProcess);
680
VBoxServiceError("VBoxServicePageSharingWorkerProcess: RTProcCreate %s failed; rc=%Rrc\n", pszExeName, rc);
685
* Block for a minute.
687
* The event semaphore takes care of ignoring interruptions and it
688
* allows us to implement service wakeup later.
692
rc = RTSemEventMultiWait(g_PageSharingEvent, 60000);
695
if (rc != VERR_TIMEOUT && RT_FAILURE(rc))
697
VBoxServiceError("VBoxServicePageSharingWorkerProcess: RTSemEventMultiWait failed; rc=%Rrc\n", rc);
702
if (hProcess != NIL_RTPROCESS)
703
RTProcTerminate(hProcess);
705
RTSemEventMultiDestroy(g_PageSharingEvent);
706
g_PageSharingEvent = NIL_RTSEMEVENTMULTI;
708
VBoxServiceVerbose(3, "VBoxServicePageSharingWorkerProcess: finished thread\n");
712
#endif /* RT_OS_WINDOWS */
714
/** @copydoc VBOXSERVICE::pfnStop */
715
static DECLCALLBACK(void) VBoxServicePageSharingStop(void)
717
RTSemEventMultiSignal(g_PageSharingEvent);
722
* The 'pagesharing' service description.
724
VBOXSERVICE g_PageSharing =
728
/* pszDescription. */
735
VBoxServiceDefaultPreInit,
736
VBoxServiceDefaultOption,
737
VBoxServicePageSharingInit,
739
VBoxServicePageSharingWorkerProcess,
741
VBoxServicePageSharingWorker,
743
VBoxServicePageSharingStop,
744
VBoxServiceDefaultTerm