VirtualBox

source: vbox/trunk/src/VBox/Main/include/GuestSessionImpl.h@ 85574

Last change on this file since 85574 was 84648, checked in by vboxsync, 5 years ago

Guest Control/Main: Big guest error information revamp, to show more information about the actual context in which an error occurred. bugref:9320

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.8 KB
Line 
1/* $Id: GuestSessionImpl.h 84648 2020-06-03 08:11:04Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Guest session handling.
4 */
5
6/*
7 * Copyright (C) 2012-2020 Oracle Corporation
8 *
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.
16 */
17
18#ifndef MAIN_INCLUDED_GuestSessionImpl_h
19#define MAIN_INCLUDED_GuestSessionImpl_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include "GuestSessionWrap.h"
25#include "EventImpl.h"
26
27#include "GuestCtrlImplPrivate.h"
28#include "GuestProcessImpl.h"
29#include "GuestDirectoryImpl.h"
30#include "GuestFileImpl.h"
31#include "GuestFsObjInfoImpl.h"
32#include "GuestSessionImplTasks.h"
33
34#include <iprt/asm.h> /** @todo r=bird: Needed for ASMBitSet() in GuestSession::Data constructor. Removed when
35 * that is moved into the class implementation file as it should be. */
36#include <deque>
37
38class GuestSessionTaskInternalStart; /* Needed for i_startSessionThreadTask(). */
39
40/**
41 * Guest session implementation.
42 */
43class ATL_NO_VTABLE GuestSession
44 : public GuestSessionWrap
45 , public GuestBase
46{
47public:
48 /** @name COM and internal init/term/mapping cruft.
49 * @{ */
50 DECLARE_EMPTY_CTOR_DTOR(GuestSession)
51
52 int init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds);
53 void uninit(void);
54 HRESULT FinalConstruct(void);
55 void FinalRelease(void);
56 /** @} */
57
58private:
59
60 /** Wrapped @name IGuestSession properties.
61 * @{ */
62 HRESULT getUser(com::Utf8Str &aUser);
63 HRESULT getDomain(com::Utf8Str &aDomain);
64 HRESULT getName(com::Utf8Str &aName);
65 HRESULT getId(ULONG *aId);
66 HRESULT getTimeout(ULONG *aTimeout);
67 HRESULT setTimeout(ULONG aTimeout);
68 HRESULT getProtocolVersion(ULONG *aProtocolVersion);
69 HRESULT getStatus(GuestSessionStatus_T *aStatus);
70 HRESULT getEnvironmentChanges(std::vector<com::Utf8Str> &aEnvironmentChanges);
71 HRESULT setEnvironmentChanges(const std::vector<com::Utf8Str> &aEnvironmentChanges);
72 HRESULT getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase);
73 HRESULT getProcesses(std::vector<ComPtr<IGuestProcess> > &aProcesses);
74 HRESULT getPathStyle(PathStyle_T *aPathStyle);
75 HRESULT getCurrentDirectory(com::Utf8Str &aCurrentDirectory);
76 HRESULT setCurrentDirectory(const com::Utf8Str &aCurrentDirectory);
77 HRESULT getUserDocuments(com::Utf8Str &aUserDocuments);
78 HRESULT getUserHome(com::Utf8Str &aUserHome);
79 HRESULT getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories);
80 HRESULT getFiles(std::vector<ComPtr<IGuestFile> > &aFiles);
81 HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
82 /** @} */
83
84 /** Wrapped @name IGuestSession methods.
85 * @{ */
86 HRESULT close();
87
88 HRESULT copyFromGuest(const std::vector<com::Utf8Str> &aSources,
89 const std::vector<com::Utf8Str> &aFilters,
90 const std::vector<com::Utf8Str> &aFlags,
91 const com::Utf8Str &aDestination,
92 ComPtr<IProgress> &aProgress);
93 HRESULT copyToGuest(const std::vector<com::Utf8Str> &aSources,
94 const std::vector<com::Utf8Str> &aFilters,
95 const std::vector<com::Utf8Str> &aFlags,
96 const com::Utf8Str &aDestination,
97 ComPtr<IProgress> &aProgress);
98
99 HRESULT directoryCopy(const com::Utf8Str &aSource,
100 const com::Utf8Str &aDestination,
101 const std::vector<DirectoryCopyFlag_T> &aFlags,
102 ComPtr<IProgress> &aProgress);
103 HRESULT directoryCopyFromGuest(const com::Utf8Str &aSource,
104 const com::Utf8Str &aDestination,
105 const std::vector<DirectoryCopyFlag_T> &aFlags,
106 ComPtr<IProgress> &aProgress);
107 HRESULT directoryCopyToGuest(const com::Utf8Str &aSource,
108 const com::Utf8Str &aDestination,
109 const std::vector<DirectoryCopyFlag_T> &aFlags,
110 ComPtr<IProgress> &aProgress);
111 HRESULT directoryCreate(const com::Utf8Str &aPath,
112 ULONG aMode,
113 const std::vector<DirectoryCreateFlag_T> &aFlags);
114 HRESULT directoryCreateTemp(const com::Utf8Str &aTemplateName,
115 ULONG aMode,
116 const com::Utf8Str &aPath,
117 BOOL aSecure,
118 com::Utf8Str &aDirectory);
119 HRESULT directoryExists(const com::Utf8Str &aPath,
120 BOOL aFollowSymlinks,
121 BOOL *aExists);
122 HRESULT directoryOpen(const com::Utf8Str &aPath,
123 const com::Utf8Str &aFilter,
124 const std::vector<DirectoryOpenFlag_T> &aFlags,
125 ComPtr<IGuestDirectory> &aDirectory);
126 HRESULT directoryRemove(const com::Utf8Str &aPath);
127 HRESULT directoryRemoveRecursive(const com::Utf8Str &aPath,
128 const std::vector<DirectoryRemoveRecFlag_T> &aFlags,
129 ComPtr<IProgress> &aProgress);
130 HRESULT environmentScheduleSet(const com::Utf8Str &aName,
131 const com::Utf8Str &aValue);
132 HRESULT environmentScheduleUnset(const com::Utf8Str &aName);
133 HRESULT environmentGetBaseVariable(const com::Utf8Str &aName,
134 com::Utf8Str &aValue);
135 HRESULT environmentDoesBaseVariableExist(const com::Utf8Str &aName,
136 BOOL *aExists);
137
138 HRESULT fileCopy(const com::Utf8Str &aSource,
139 const com::Utf8Str &aDestination,
140 const std::vector<FileCopyFlag_T> &aFlags,
141 ComPtr<IProgress> &aProgress);
142 HRESULT fileCopyToGuest(const com::Utf8Str &aSource,
143 const com::Utf8Str &aDestination,
144 const std::vector<FileCopyFlag_T> &aFlags,
145 ComPtr<IProgress> &aProgress);
146 HRESULT fileCopyFromGuest(const com::Utf8Str &aSource,
147 const com::Utf8Str &aDestination,
148 const std::vector<FileCopyFlag_T> &aFlags,
149 ComPtr<IProgress> &aProgress);
150 HRESULT fileCreateTemp(const com::Utf8Str &aTemplateName,
151 ULONG aMode,
152 const com::Utf8Str &aPath,
153 BOOL aSecure,
154 ComPtr<IGuestFile> &aFile);
155 HRESULT fileExists(const com::Utf8Str &aPath,
156 BOOL aFollowSymlinks,
157 BOOL *aExists);
158 HRESULT fileOpen(const com::Utf8Str &aPath,
159 FileAccessMode_T aAccessMode,
160 FileOpenAction_T aOpenAction,
161 ULONG aCreationMode,
162 ComPtr<IGuestFile> &aFile);
163 HRESULT fileOpenEx(const com::Utf8Str &aPath,
164 FileAccessMode_T aAccessMode,
165 FileOpenAction_T aOpenAction,
166 FileSharingMode_T aSharingMode,
167 ULONG aCreationMode,
168 const std::vector<FileOpenExFlag_T> &aFlags,
169 ComPtr<IGuestFile> &aFile);
170 HRESULT fileQuerySize(const com::Utf8Str &aPath,
171 BOOL aFollowSymlinks,
172 LONG64 *aSize);
173 HRESULT fsObjExists(const com::Utf8Str &aPath,
174 BOOL aFollowSymlinks,
175 BOOL *pfExists);
176 HRESULT fsObjQueryInfo(const com::Utf8Str &aPath,
177 BOOL aFollowSymlinks,
178 ComPtr<IGuestFsObjInfo> &aInfo);
179 HRESULT fsObjRemove(const com::Utf8Str &aPath);
180 HRESULT fsObjRemoveArray(const std::vector<com::Utf8Str> &aPaths,
181 ComPtr<IProgress> &aProgress);
182 HRESULT fsObjRename(const com::Utf8Str &aOldPath,
183 const com::Utf8Str &aNewPath,
184 const std::vector<FsObjRenameFlag_T> &aFlags);
185 HRESULT fsObjMove(const com::Utf8Str &aSource,
186 const com::Utf8Str &aDestination,
187 const std::vector<FsObjMoveFlag_T> &aFlags,
188 ComPtr<IProgress> &aProgress);
189 HRESULT fsObjMoveArray(const std::vector<com::Utf8Str> &aSource,
190 const com::Utf8Str &aDestination,
191 const std::vector<FsObjMoveFlag_T> &aFlags,
192 ComPtr<IProgress> &aProgress);
193 HRESULT fsObjCopyArray(const std::vector<com::Utf8Str> &aSource,
194 const com::Utf8Str &aDestination,
195 const std::vector<FileCopyFlag_T> &aFlags,
196 ComPtr<IProgress> &aProgress);
197 HRESULT fsObjSetACL(const com::Utf8Str &aPath,
198 BOOL aFollowSymlinks,
199 const com::Utf8Str &aAcl,
200 ULONG aMode);
201 HRESULT processCreate(const com::Utf8Str &aCommand,
202 const std::vector<com::Utf8Str> &aArguments,
203 const std::vector<com::Utf8Str> &aEnvironment,
204 const std::vector<ProcessCreateFlag_T> &aFlags,
205 ULONG aTimeoutMS,
206 ComPtr<IGuestProcess> &aGuestProcess);
207 HRESULT processCreateEx(const com::Utf8Str &aCommand,
208 const std::vector<com::Utf8Str> &aArguments,
209 const std::vector<com::Utf8Str> &aEnvironment,
210 const std::vector<ProcessCreateFlag_T> &aFlags,
211 ULONG aTimeoutMS,
212 ProcessPriority_T aPriority,
213 const std::vector<LONG> &aAffinity,
214 ComPtr<IGuestProcess> &aGuestProcess);
215 HRESULT processGet(ULONG aPid,
216 ComPtr<IGuestProcess> &aGuestProcess);
217 HRESULT symlinkCreate(const com::Utf8Str &aSource,
218 const com::Utf8Str &aTarget,
219 SymlinkType_T aType);
220 HRESULT symlinkExists(const com::Utf8Str &aSymlink,
221 BOOL *aExists);
222 HRESULT symlinkRead(const com::Utf8Str &aSymlink,
223 const std::vector<SymlinkReadFlag_T> &aFlags,
224 com::Utf8Str &aTarget);
225 HRESULT waitFor(ULONG aWaitFor,
226 ULONG aTimeoutMS,
227 GuestSessionWaitResult_T *aReason);
228 HRESULT waitForArray(const std::vector<GuestSessionWaitForFlag_T> &aWaitFor,
229 ULONG aTimeoutMS,
230 GuestSessionWaitResult_T *aReason);
231 /** @} */
232
233 /** Map of guest directories. The key specifies the internal directory ID. */
234 typedef std::map <uint32_t, ComObjPtr<GuestDirectory> > SessionDirectories;
235 /** Map of guest files. The key specifies the internal file ID. */
236 typedef std::map <uint32_t, ComObjPtr<GuestFile> > SessionFiles;
237 /** Map of guest processes. The key specifies the internal process number.
238 * To retrieve the process' guest PID use the Id() method of the IProcess interface. */
239 typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
240
241 /** Guest session object type enumeration. */
242 enum SESSIONOBJECTTYPE
243 {
244 /** Anonymous object. */
245 SESSIONOBJECTTYPE_ANONYMOUS = 0,
246 /** Session object. */
247 SESSIONOBJECTTYPE_SESSION = 1,
248 /** Directory object. */
249 SESSIONOBJECTTYPE_DIRECTORY = 2,
250 /** File object. */
251 SESSIONOBJECTTYPE_FILE = 3,
252 /** Process object. */
253 SESSIONOBJECTTYPE_PROCESS = 4,
254 /** The usual 32-bit hack. */
255 SESSIONOBJECTTYPE_32BIT_HACK = 0x7fffffff
256 };
257
258 struct SessionObject
259 {
260 /** Creation timestamp (in ms).
261 * @note not used by anyone at the moment. */
262 uint64_t msBirth;
263 /** The object type. */
264 SESSIONOBJECTTYPE enmType;
265 /** Weak pointer to the object itself. */
266 GuestObject *pObject;
267 };
268
269 /** Map containing all objects bound to a guest session.
270 * The key specifies the (global) context ID. */
271 typedef std::map <uint32_t, SessionObject> SessionObjects;
272
273public:
274 /** @name Public internal methods.
275 * @todo r=bird: Most of these are public for no real reason...
276 * @{ */
277 HRESULT i_copyFromGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
278 ComPtr<IProgress> &pProgress);
279 HRESULT i_copyToGuest(const GuestSessionFsSourceSet &SourceSet, const com::Utf8Str &strDestination,
280 ComPtr<IProgress> &pProgress);
281 int i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
282 HRESULT i_directoryCopyFlagFromStr(const com::Utf8Str &strFlags, DirectoryCopyFlag_T *pfFlags);
283 bool i_directoryExists(const Utf8Str &strPath);
284 inline bool i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
285 int i_directoryUnregister(GuestDirectory *pDirectory);
286 int i_directoryRemove(const Utf8Str &strPath, uint32_t fFlags, int *pGuestRc);
287 int i_directoryCreate(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, int *pGuestRc);
288 int i_directoryOpen(const GuestDirectoryOpenInfo &openInfo,
289 ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc);
290 int i_directoryQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
291 int i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
292 int i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
293 HRESULT i_fileCopyFlagFromStr(const com::Utf8Str &strFlags, FileCopyFlag_T *pfFlags);
294 inline bool i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
295 int i_fileUnregister(GuestFile *pFile);
296 int i_fileRemove(const Utf8Str &strPath, int *pGuestRc);
297 int i_fileOpenEx(const com::Utf8Str &aPath, FileAccessMode_T aAccessMode, FileOpenAction_T aOpenAction,
298 FileSharingMode_T aSharingMode, ULONG aCreationMode,
299 const std::vector<FileOpenExFlag_T> &aFlags,
300 ComObjPtr<GuestFile> &pFile, int *prcGuest);
301 int i_fileOpen(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pGuestRc);
302 int i_fileQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
303 int i_fileQuerySize(const Utf8Str &strPath, bool fFollowSymlinks, int64_t *pllSize, int *pGuestRc);
304 int i_fsCreateTemp(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,
305 Utf8Str &strName, int *pGuestRc);
306 int i_fsQueryInfo(const Utf8Str &strPath, bool fFollowSymlinks, GuestFsObjData &objData, int *pGuestRc);
307 const GuestCredentials &i_getCredentials(void);
308 EventSource *i_getEventSource(void) { return mEventSource; }
309 Utf8Str i_getName(void);
310 ULONG i_getId(void) { return mData.mSession.mID; }
311 bool i_isStarted(void) const;
312 HRESULT i_isStartedExternal(void);
313 bool i_isTerminated(void) const;
314 int i_onRemove(void);
315 int i_onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
316 PathStyle_T i_getPathStyle(void);
317 int i_startSession(int *pGuestRc);
318 int i_startSessionAsync(void);
319 Guest *i_getParent(void) { return mParent; }
320 uint32_t i_getProtocolVersion(void) { return mData.mProtocolVersion; }
321 int i_objectRegister(GuestObject *pObject, SESSIONOBJECTTYPE enmType, uint32_t *pidObject);
322 int i_objectUnregister(uint32_t uObjectID);
323 int i_objectsUnregister(void);
324 int i_objectsNotifyAboutStatusChange(GuestSessionStatus_T enmSessionStatus);
325 int i_pathRename(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags, int *pGuestRc);
326 int i_pathUserDocuments(Utf8Str &strPath, int *prcGuest);
327 int i_pathUserHome(Utf8Str &strPath, int *prcGuest);
328 int i_processUnregister(GuestProcess *pProcess);
329 int i_processCreateEx(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
330 inline bool i_processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess);
331 inline int i_processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
332 int i_sendMessage(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms,
333 uint64_t fDst = VBOX_GUESTCTRL_DST_SESSION);
334 int i_setSessionStatus(GuestSessionStatus_T sessionStatus, int sessionRc);
335 int i_signalWaiters(GuestSessionWaitResult_T enmWaitResult, int rc /*= VINF_SUCCESS */);
336 int i_shutdown(uint32_t fFlags, int *prcGuest);
337 int i_determineProtocolVersion(void);
338 int i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestSessionWaitResult_T &waitResult, int *pGuestRc);
339 int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_t uTimeoutMS,
340 GuestSessionStatus_T *pSessionStatus, int *pGuestRc);
341 /** @} */
342
343public:
344
345 /** @name Static helper methods.
346 * @{ */
347 static Utf8Str i_guestErrorToString(int guestRc);
348 static bool i_isTerminated(GuestSessionStatus_T enmStatus);
349 static int i_startSessionThreadTask(GuestSessionTaskInternalStart *pTask);
350 /** @} */
351
352private:
353
354 /** Pointer to the parent (Guest). */
355 Guest *mParent;
356 /**
357 * The session's event source. This source is used for
358 * serving the internal listener as well as all other
359 * external listeners that may register to it.
360 *
361 * Note: This can safely be used without holding any locks.
362 * An AutoCaller suffices to prevent it being destroy while in use and
363 * internally there is a lock providing the necessary serialization.
364 */
365 const ComObjPtr<EventSource> mEventSource;
366
367 /** @todo r=bird: One of the core points of the DATA sub-structures in Main is
368 * hinding implementation details and stuff that requires including iprt/asm.h.
369 * The way it's used here totally defeats that purpose. You need to make it
370 * a pointer to a anynmous Data struct and define that structure in
371 * GuestSessionImpl.cpp and allocate it in the Init() function.
372 */
373 struct Data
374 {
375 /** The session credentials. */
376 GuestCredentials mCredentials;
377 /** The session's startup info. */
378 GuestSessionStartupInfo mSession;
379 /** The session's object ID.
380 * Needed for registering wait events which are bound directly to this session. */
381 uint32_t mObjectID;
382 /** The session's current status. */
383 GuestSessionStatus_T mStatus;
384 /** The set of environment changes for the session for use when
385 * creating new guest processes. */
386 GuestEnvironmentChanges mEnvironmentChanges;
387 /** Pointer to the immutable base environment for the session.
388 * @note This is not allocated until the guest reports it to the host. It is
389 * also shared with child processes. */
390 GuestEnvironment const *mpBaseEnvironment;
391 /** Directory objects bound to this session. */
392 SessionDirectories mDirectories;
393 /** File objects bound to this session. */
394 SessionFiles mFiles;
395 /** Process objects bound to this session. */
396 SessionProcesses mProcesses;
397 /** Map of registered session objects (files, directories, ...). */
398 SessionObjects mObjects;
399 /** Guest control protocol version to be used.
400 * Guest Additions < VBox 4.3 have version 1,
401 * any newer version will have version 2. */
402 uint32_t mProtocolVersion;
403 /** Session timeout (in ms). */
404 uint32_t mTimeout;
405 /** The last returned session status
406 * returned from the guest side. */
407 int mRC;
408 /** Object ID allocation bitmap; clear bits are free, set bits are busy. */
409 uint64_t bmObjectIds[VBOX_GUESTCTRL_MAX_OBJECTS / sizeof(uint64_t) / 8];
410
411 Data(void)
412 : mpBaseEnvironment(NULL)
413 {
414 RT_ZERO(bmObjectIds);
415 ASMBitSet(&bmObjectIds, VBOX_GUESTCTRL_MAX_OBJECTS - 1); /* Reserved for the session itself? */
416 ASMBitSet(&bmObjectIds, 0); /* Let's reserve this too. */
417 }
418 Data(const Data &rThat)
419 : mCredentials(rThat.mCredentials)
420 , mSession(rThat.mSession)
421 , mStatus(rThat.mStatus)
422 , mEnvironmentChanges(rThat.mEnvironmentChanges)
423 , mpBaseEnvironment(NULL)
424 , mDirectories(rThat.mDirectories)
425 , mFiles(rThat.mFiles)
426 , mProcesses(rThat.mProcesses)
427 , mObjects(rThat.mObjects)
428 , mProtocolVersion(rThat.mProtocolVersion)
429 , mTimeout(rThat.mTimeout)
430 , mRC(rThat.mRC)
431 {
432 memcpy(&bmObjectIds, &rThat.bmObjectIds, sizeof(bmObjectIds));
433 }
434 ~Data(void)
435 {
436 if (mpBaseEnvironment)
437 {
438 mpBaseEnvironment->releaseConst();
439 mpBaseEnvironment = NULL;
440 }
441 }
442 } mData;
443};
444
445#endif /* !MAIN_INCLUDED_GuestSessionImpl_h */
446
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette