[44863] | 1 | /* $Id: VBoxServiceControl.h 99085 2023-03-21 12:15:00Z vboxsync $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * VBoxServiceControl.h - Internal guest control definitions.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2013-2023 Oracle and/or its affiliates.
|
---|
[44863] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
[44863] | 26 | */
|
---|
| 27 |
|
---|
[76563] | 28 | #ifndef GA_INCLUDED_SRC_common_VBoxService_VBoxServiceControl_h
|
---|
| 29 | #define GA_INCLUDED_SRC_common_VBoxService_VBoxServiceControl_h
|
---|
[76533] | 30 | #ifndef RT_WITHOUT_PRAGMA_ONCE
|
---|
| 31 | # pragma once
|
---|
| 32 | #endif
|
---|
[44863] | 33 |
|
---|
[47545] | 34 | #include <iprt/critsect.h>
|
---|
[98824] | 35 | #ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
|
---|
| 36 | # include <iprt/dir.h>
|
---|
| 37 | #endif
|
---|
[44863] | 38 | #include <iprt/list.h>
|
---|
[47545] | 39 | #include <iprt/req.h>
|
---|
[44863] | 40 |
|
---|
| 41 | #include <VBox/VBoxGuestLib.h>
|
---|
[60622] | 42 | #include <VBox/GuestHost/GuestControl.h>
|
---|
[44863] | 43 | #include <VBox/HostServices/GuestControlSvc.h>
|
---|
| 44 |
|
---|
[98709] | 45 | #include "VBoxServiceUtils.h" /* For VGSVCIDCACHE. */
|
---|
[44863] | 46 |
|
---|
[98709] | 47 |
|
---|
[44863] | 48 | /**
|
---|
| 49 | * Pipe IDs for handling the guest process poll set.
|
---|
| 50 | */
|
---|
| 51 | typedef enum VBOXSERVICECTRLPIPEID
|
---|
| 52 | {
|
---|
| 53 | VBOXSERVICECTRLPIPEID_UNKNOWN = 0,
|
---|
| 54 | VBOXSERVICECTRLPIPEID_STDIN = 10,
|
---|
| 55 | VBOXSERVICECTRLPIPEID_STDIN_WRITABLE = 11,
|
---|
| 56 | /** Pipe for reading from guest process' stdout. */
|
---|
| 57 | VBOXSERVICECTRLPIPEID_STDOUT = 40,
|
---|
| 58 | /** Pipe for reading from guest process' stderr. */
|
---|
| 59 | VBOXSERVICECTRLPIPEID_STDERR = 50,
|
---|
| 60 | /** Notification pipe for waking up the guest process
|
---|
| 61 | * control thread. */
|
---|
| 62 | VBOXSERVICECTRLPIPEID_IPC_NOTIFY = 100
|
---|
| 63 | } VBOXSERVICECTRLPIPEID;
|
---|
| 64 |
|
---|
[98526] | 65 | #ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
|
---|
[44863] | 66 | /**
|
---|
[98526] | 67 | * Structure for one (opened) guest directory.
|
---|
| 68 | */
|
---|
| 69 | typedef struct VBOXSERVICECTRLDIR
|
---|
| 70 | {
|
---|
| 71 | /** Pointer to list archor of following list node.
|
---|
| 72 | * @todo Would be nice to have a RTListGetAnchor(). */
|
---|
| 73 | PRTLISTANCHOR pAnchor;
|
---|
| 74 | /** Node to global guest control directory list. */
|
---|
| 75 | /** @todo Use a map later? */
|
---|
| 76 | RTLISTNODE Node;
|
---|
| 77 | /** The (absolute) directory path. */
|
---|
| 78 | char *pszPathAbs;
|
---|
| 79 | /** The directory handle on the guest. */
|
---|
| 80 | RTDIR hDir;
|
---|
| 81 | /** Directory handle to identify this directory. */
|
---|
| 82 | uint32_t uHandle;
|
---|
| 83 | /** Context ID. */
|
---|
| 84 | uint32_t uContextID;
|
---|
[98818] | 85 | /** Flags for reading directory entries. */
|
---|
| 86 | uint32_t fRead;
|
---|
| 87 | /** Additional attributes enumeration to use for reading directory entries. */
|
---|
| 88 | GSTCTLFSOBJATTRADD enmReadAttrAdd;
|
---|
[99085] | 89 | /** Scratch buffer for holding the directory reading entry.
|
---|
| 90 | * Currently NOT serialized, i.e. only can be used for one read at a time. */
|
---|
| 91 | PRTDIRENTRYEX pDirEntryEx;
|
---|
| 92 | /** Size (in bytes) of \a pDirEntryEx. */
|
---|
| 93 | size_t cbDirEntryEx;
|
---|
[98526] | 94 | } VBOXSERVICECTRLDIR;
|
---|
| 95 | /** Pointer to a guest directory. */
|
---|
| 96 | typedef VBOXSERVICECTRLDIR *PVBOXSERVICECTRLDIR;
|
---|
| 97 | #endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
|
---|
| 98 |
|
---|
| 99 | /**
|
---|
[44963] | 100 | * Structure for one (opened) guest file.
|
---|
| 101 | */
|
---|
| 102 | typedef struct VBOXSERVICECTRLFILE
|
---|
| 103 | {
|
---|
[98526] | 104 | /** Pointer to list archor of following list node.
|
---|
[44963] | 105 | * @todo Would be nice to have a RTListGetAnchor(). */
|
---|
| 106 | PRTLISTANCHOR pAnchor;
|
---|
| 107 | /** Node to global guest control file list. */
|
---|
| 108 | /** @todo Use a map later? */
|
---|
| 109 | RTLISTNODE Node;
|
---|
| 110 | /** The file name. */
|
---|
[84149] | 111 | char *pszName;
|
---|
[44963] | 112 | /** The file handle on the guest. */
|
---|
| 113 | RTFILE hFile;
|
---|
| 114 | /** File handle to identify this file. */
|
---|
| 115 | uint32_t uHandle;
|
---|
| 116 | /** Context ID. */
|
---|
| 117 | uint32_t uContextID;
|
---|
[79296] | 118 | /** RTFILE_O_XXX flags. */
|
---|
| 119 | uint64_t fOpen;
|
---|
[44963] | 120 | } VBOXSERVICECTRLFILE;
|
---|
[98526] | 121 | /** Pointer to a guest file. */
|
---|
[44963] | 122 | typedef VBOXSERVICECTRLFILE *PVBOXSERVICECTRLFILE;
|
---|
| 123 |
|
---|
| 124 | /**
|
---|
| 125 | * Structure for a guest session thread to
|
---|
[45415] | 126 | * observe/control the forked session instance from
|
---|
| 127 | * the VBoxService main executable.
|
---|
[44963] | 128 | */
|
---|
| 129 | typedef struct VBOXSERVICECTRLSESSIONTHREAD
|
---|
| 130 | {
|
---|
| 131 | /** Node to global guest control session list. */
|
---|
| 132 | /** @todo Use a map later? */
|
---|
| 133 | RTLISTNODE Node;
|
---|
| 134 | /** The sessions's startup info. */
|
---|
[84215] | 135 | PVBGLR3GUESTCTRLSESSIONSTARTUPINFO
|
---|
[84147] | 136 | pStartupInfo;
|
---|
[75807] | 137 | /** Critical section for thread-safe use. */
|
---|
| 138 | RTCRITSECT CritSect;
|
---|
[44963] | 139 | /** The worker thread. */
|
---|
| 140 | RTTHREAD Thread;
|
---|
| 141 | /** Process handle for forked child. */
|
---|
| 142 | RTPROCESS hProcess;
|
---|
| 143 | /** Shutdown indicator; will be set when the thread
|
---|
| 144 | * needs (or is asked) to shutdown. */
|
---|
| 145 | bool volatile fShutdown;
|
---|
| 146 | /** Indicator set by the service thread exiting. */
|
---|
| 147 | bool volatile fStopped;
|
---|
| 148 | /** Whether the thread was started or not. */
|
---|
| 149 | bool fStarted;
|
---|
| 150 | #if 0 /* Pipe IPC not used yet. */
|
---|
| 151 | /** Pollset containing all the pipes. */
|
---|
| 152 | RTPOLLSET hPollSet;
|
---|
| 153 | RTPIPE hStdInW;
|
---|
| 154 | RTPIPE hStdOutR;
|
---|
| 155 | RTPIPE hStdErrR;
|
---|
| 156 | struct StdPipe
|
---|
| 157 | {
|
---|
| 158 | RTHANDLE hChild;
|
---|
| 159 | PRTHANDLE phChild;
|
---|
| 160 | } StdIn,
|
---|
| 161 | StdOut,
|
---|
| 162 | StdErr;
|
---|
| 163 | /** The notification pipe associated with this guest session.
|
---|
| 164 | * This is NIL_RTPIPE for output pipes. */
|
---|
| 165 | RTPIPE hNotificationPipeW;
|
---|
| 166 | /** The other end of hNotificationPipeW. */
|
---|
| 167 | RTPIPE hNotificationPipeR;
|
---|
| 168 | #endif
|
---|
[75807] | 169 | /** Pipe for handing the secret key to the session process. */
|
---|
| 170 | RTPIPE hKeyPipe;
|
---|
| 171 | /** Secret key. */
|
---|
| 172 | uint8_t abKey[_4K];
|
---|
[44963] | 173 | } VBOXSERVICECTRLSESSIONTHREAD;
|
---|
| 174 | /** Pointer to thread data. */
|
---|
| 175 | typedef VBOXSERVICECTRLSESSIONTHREAD *PVBOXSERVICECTRLSESSIONTHREAD;
|
---|
| 176 |
|
---|
[83409] | 177 | /** Defines the prefix being used for telling our service executable that we're going
|
---|
| 178 | * to spawn a new (Guest Control) user session. */
|
---|
| 179 | #define VBOXSERVICECTRLSESSION_GETOPT_PREFIX "guestsession"
|
---|
| 180 |
|
---|
[57659] | 181 | /** Flag indicating that this session has been spawned from
|
---|
[45010] | 182 | * the main executable. */
|
---|
[57659] | 183 | #define VBOXSERVICECTRLSESSION_FLAG_SPAWN RT_BIT(0)
|
---|
[45010] | 184 | /** Flag indicating that this session is anonymous, that is,
|
---|
| 185 | * it will run start guest processes with the same credentials
|
---|
| 186 | * as the main executable. */
|
---|
| 187 | #define VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS RT_BIT(1)
|
---|
[47551] | 188 | /** Flag indicating that started guest processes will dump their
|
---|
[45010] | 189 | * stdout output to a separate file on disk. For debugging. */
|
---|
| 190 | #define VBOXSERVICECTRLSESSION_FLAG_DUMPSTDOUT RT_BIT(2)
|
---|
[47551] | 191 | /** Flag indicating that started guest processes will dump their
|
---|
[45010] | 192 | * stderr output to a separate file on disk. For debugging. */
|
---|
| 193 | #define VBOXSERVICECTRLSESSION_FLAG_DUMPSTDERR RT_BIT(3)
|
---|
[44963] | 194 |
|
---|
| 195 | /**
|
---|
[47334] | 196 | * Structure for maintaining a guest session. This also
|
---|
[44963] | 197 | * contains all started threads (e.g. for guest processes).
|
---|
| 198 | *
|
---|
| 199 | * This structure can act in two different ways:
|
---|
| 200 | * - For legacy guest control handling (protocol version < 2)
|
---|
| 201 | * this acts as a per-guest process structure containing all
|
---|
| 202 | * the information needed to get a guest process up and running.
|
---|
| 203 | * - For newer guest control protocols (>= 2) this structure is
|
---|
| 204 | * part of the forked session child, maintaining all guest
|
---|
| 205 | * control objects under it.
|
---|
| 206 | */
|
---|
| 207 | typedef struct VBOXSERVICECTRLSESSION
|
---|
| 208 | {
|
---|
[45415] | 209 | /* The session's startup information. */
|
---|
[84215] | 210 | VBGLR3GUESTCTRLSESSIONSTARTUPINFO
|
---|
[44963] | 211 | StartupInfo;
|
---|
[47545] | 212 | /** List of active guest process threads
|
---|
| 213 | * (VBOXSERVICECTRLPROCESS). */
|
---|
| 214 | RTLISTANCHOR lstProcesses;
|
---|
[83286] | 215 | /** Number of guest processes in the process list. */
|
---|
| 216 | uint32_t cProcesses;
|
---|
[98526] | 217 | #ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
|
---|
| 218 | /** List of guest control files (VBOXSERVICECTRLDIR). */
|
---|
| 219 | RTLISTANCHOR lstDirs;
|
---|
| 220 | /** Number of guest directories in \a lstDirs. */
|
---|
| 221 | uint32_t cDirs;
|
---|
| 222 | #endif
|
---|
[44963] | 223 | /** List of guest control files (VBOXSERVICECTRLFILE). */
|
---|
| 224 | RTLISTANCHOR lstFiles;
|
---|
[98526] | 225 | /** Number of guest files in \a lstFiles. */
|
---|
[83286] | 226 | uint32_t cFiles;
|
---|
[45415] | 227 | /** The session's critical section. */
|
---|
| 228 | RTCRITSECT CritSect;
|
---|
[47551] | 229 | /** Internal session flags, not related
|
---|
| 230 | * to StartupInfo stuff.
|
---|
| 231 | * @sa VBOXSERVICECTRLSESSION_FLAG_* flags. */
|
---|
[57659] | 232 | uint32_t fFlags;
|
---|
[44963] | 233 | /** How many processes do we allow keeping around at a time? */
|
---|
| 234 | uint32_t uProcsMaxKept;
|
---|
[98824] | 235 | #ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
|
---|
[98817] | 236 | /** The uid cache for this session. */
|
---|
| 237 | VGSVCIDCACHE UidCache;
|
---|
| 238 | /** The gid cache for this session. */
|
---|
| 239 | VGSVCIDCACHE GidCache;
|
---|
[98824] | 240 | #endif
|
---|
[44963] | 241 | } VBOXSERVICECTRLSESSION;
|
---|
| 242 | /** Pointer to guest session. */
|
---|
| 243 | typedef VBOXSERVICECTRLSESSION *PVBOXSERVICECTRLSESSION;
|
---|
| 244 |
|
---|
| 245 | /**
|
---|
[44863] | 246 | * Structure for holding data for one (started) guest process.
|
---|
| 247 | */
|
---|
[45010] | 248 | typedef struct VBOXSERVICECTRLPROCESS
|
---|
[44863] | 249 | {
|
---|
| 250 | /** Node. */
|
---|
| 251 | RTLISTNODE Node;
|
---|
[47545] | 252 | /** Process handle. */
|
---|
| 253 | RTPROCESS hProcess;
|
---|
[45697] | 254 | /** Number of references using this struct. */
|
---|
| 255 | uint32_t cRefs;
|
---|
[44863] | 256 | /** The worker thread. */
|
---|
| 257 | RTTHREAD Thread;
|
---|
[44963] | 258 | /** The session this guest process
|
---|
| 259 | * is bound to. */
|
---|
| 260 | PVBOXSERVICECTRLSESSION pSession;
|
---|
[44863] | 261 | /** Shutdown indicator; will be set when the thread
|
---|
| 262 | * needs (or is asked) to shutdown. */
|
---|
| 263 | bool volatile fShutdown;
|
---|
[70390] | 264 | /** Whether the guest process thread was stopped or not. */
|
---|
[44863] | 265 | bool volatile fStopped;
|
---|
[70390] | 266 | /** Whether the guest process thread was started or not. */
|
---|
[44863] | 267 | bool fStarted;
|
---|
| 268 | /** Context ID. */
|
---|
| 269 | uint32_t uContextID;
|
---|
| 270 | /** Critical section for thread-safe use. */
|
---|
| 271 | RTCRITSECT CritSect;
|
---|
[45415] | 272 | /** Process startup information. */
|
---|
[84215] | 273 | PVBGLR3GUESTCTRLPROCSTARTUPINFO
|
---|
[84147] | 274 | pStartupInfo;
|
---|
[45415] | 275 | /** The process' PID assigned by the guest OS. */
|
---|
[44863] | 276 | uint32_t uPID;
|
---|
[47545] | 277 | /** The process' request queue to handle requests
|
---|
| 278 | * from the outside, e.g. the session. */
|
---|
| 279 | RTREQQUEUE hReqQueue;
|
---|
| 280 | /** Our pollset, used for accessing the process'
|
---|
| 281 | * std* pipes + the notification pipe. */
|
---|
| 282 | RTPOLLSET hPollSet;
|
---|
[44863] | 283 | /** StdIn pipe for addressing writes to the
|
---|
| 284 | * guest process' stdin.*/
|
---|
[47545] | 285 | RTPIPE hPipeStdInW;
|
---|
| 286 | /** StdOut pipe for addressing reads from
|
---|
| 287 | * guest process' stdout.*/
|
---|
| 288 | RTPIPE hPipeStdOutR;
|
---|
| 289 | /** StdOut pipe for addressing reads from
|
---|
[83286] | 290 | * guest process' stderr.*/
|
---|
[47545] | 291 | RTPIPE hPipeStdErrR;
|
---|
[70390] | 292 |
|
---|
| 293 | /** The write end of the notification pipe that is used to poke the thread
|
---|
| 294 | * monitoring the process.
|
---|
[44863] | 295 | * This is NIL_RTPIPE for output pipes. */
|
---|
| 296 | RTPIPE hNotificationPipeW;
|
---|
[70390] | 297 | /** The other end of hNotificationPipeW, read by vgsvcGstCtrlProcessProcLoop(). */
|
---|
[44863] | 298 | RTPIPE hNotificationPipeR;
|
---|
[45010] | 299 | } VBOXSERVICECTRLPROCESS;
|
---|
[44863] | 300 | /** Pointer to thread data. */
|
---|
[45010] | 301 | typedef VBOXSERVICECTRLPROCESS *PVBOXSERVICECTRLPROCESS;
|
---|
[44863] | 302 |
|
---|
| 303 | RT_C_DECLS_BEGIN
|
---|
| 304 |
|
---|
[58029] | 305 | extern RTLISTANCHOR g_lstControlSessionThreads;
|
---|
| 306 | extern VBOXSERVICECTRLSESSION g_Session;
|
---|
[75807] | 307 | extern uint32_t g_idControlSvcClient;
|
---|
[79296] | 308 | extern uint64_t g_fControlHostFeatures0;
|
---|
[75807] | 309 | extern bool g_fControlSupportsOptimizations;
|
---|
[44863] | 310 |
|
---|
| 311 |
|
---|
[58029] | 312 | /** @name Guest session thread handling.
|
---|
| 313 | * @{ */
|
---|
[84215] | 314 | extern int VGSvcGstCtrlSessionThreadCreate(PRTLISTANCHOR pList, const PVBGLR3GUESTCTRLSESSIONSTARTUPINFO pSessionStartupInfo, PVBOXSERVICECTRLSESSIONTHREAD *ppSessionThread);
|
---|
[58029] | 315 | extern int VGSvcGstCtrlSessionThreadDestroy(PVBOXSERVICECTRLSESSIONTHREAD pSession, uint32_t uFlags);
|
---|
| 316 | extern int VGSvcGstCtrlSessionThreadDestroyAll(PRTLISTANCHOR pList, uint32_t uFlags);
|
---|
| 317 | extern int VGSvcGstCtrlSessionThreadTerminate(PVBOXSERVICECTRLSESSIONTHREAD pSession);
|
---|
| 318 | extern RTEXITCODE VGSvcGstCtrlSessionSpawnInit(int argc, char **argv);
|
---|
| 319 | /** @} */
|
---|
| 320 | /** @name Per-session functions.
|
---|
| 321 | * @{ */
|
---|
| 322 | extern PVBOXSERVICECTRLPROCESS VGSvcGstCtrlSessionRetainProcess(PVBOXSERVICECTRLSESSION pSession, uint32_t uPID);
|
---|
| 323 | extern int VGSvcGstCtrlSessionClose(PVBOXSERVICECTRLSESSION pSession);
|
---|
| 324 | extern int VGSvcGstCtrlSessionDestroy(PVBOXSERVICECTRLSESSION pSession);
|
---|
| 325 | extern int VGSvcGstCtrlSessionInit(PVBOXSERVICECTRLSESSION pSession, uint32_t uFlags);
|
---|
| 326 | extern int VGSvcGstCtrlSessionHandler(PVBOXSERVICECTRLSESSION pSession, uint32_t uMsg, PVBGLR3GUESTCTRLCMDCTX pHostCtx, void *pvScratchBuf, size_t cbScratchBuf, volatile bool *pfShutdown);
|
---|
| 327 | extern int VGSvcGstCtrlSessionProcessAdd(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pProcess);
|
---|
| 328 | extern int VGSvcGstCtrlSessionProcessRemove(PVBOXSERVICECTRLSESSION pSession, PVBOXSERVICECTRLPROCESS pProcess);
|
---|
[83286] | 329 | extern int VGSvcGstCtrlSessionProcessStartAllowed(const PVBOXSERVICECTRLSESSION pSession, bool *pfAllowed);
|
---|
[58029] | 330 | extern int VGSvcGstCtrlSessionReapProcesses(PVBOXSERVICECTRLSESSION pSession);
|
---|
| 331 | /** @} */
|
---|
| 332 | /** @name Per-guest process functions.
|
---|
| 333 | * @{ */
|
---|
| 334 | extern int VGSvcGstCtrlProcessFree(PVBOXSERVICECTRLPROCESS pProcess);
|
---|
| 335 | extern int VGSvcGstCtrlProcessHandleInput(PVBOXSERVICECTRLPROCESS pProcess, PVBGLR3GUESTCTRLCMDCTX pHostCtx, bool fPendingClose, void *pvBuf, uint32_t cbBuf);
|
---|
| 336 | extern int VGSvcGstCtrlProcessHandleOutput(PVBOXSERVICECTRLPROCESS pProcess, PVBGLR3GUESTCTRLCMDCTX pHostCtx, uint32_t uHandle, uint32_t cbToRead, uint32_t uFlags);
|
---|
| 337 | extern int VGSvcGstCtrlProcessHandleTerm(PVBOXSERVICECTRLPROCESS pProcess);
|
---|
| 338 | extern void VGSvcGstCtrlProcessRelease(PVBOXSERVICECTRLPROCESS pProcess);
|
---|
[84215] | 339 | extern int VGSvcGstCtrlProcessStart(const PVBOXSERVICECTRLSESSION pSession, const PVBGLR3GUESTCTRLPROCSTARTUPINFO pStartupInfo, uint32_t uContext);
|
---|
[58029] | 340 | extern int VGSvcGstCtrlProcessStop(PVBOXSERVICECTRLPROCESS pProcess);
|
---|
| 341 | extern int VGSvcGstCtrlProcessWait(const PVBOXSERVICECTRLPROCESS pProcess, RTMSINTERVAL msTimeout, int *pRc);
|
---|
| 342 | /** @} */
|
---|
| 343 |
|
---|
[44863] | 344 | RT_C_DECLS_END
|
---|
| 345 |
|
---|
[76563] | 346 | #endif /* !GA_INCLUDED_SRC_common_VBoxService_VBoxServiceControl_h */
|
---|
[44863] | 347 |
|
---|