VirtualBox

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

Last change on this file since 55594 was 55592, checked in by vboxsync, 10 years ago

Sketched out how the base environment would be received by the guest session code.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.9 KB
Line 
1/* $Id: GuestSessionImpl.h 55592 2015-05-02 02:36:57Z vboxsync $ */
2/** @file
3 * VirtualBox Main - Guest session handling.
4 */
5
6/*
7 * Copyright (C) 2012-2013 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 ____H_GUESTSESSIONIMPL
19#define ____H_GUESTSESSIONIMPL
20
21#include "GuestSessionWrap.h"
22#include "EventImpl.h"
23
24#include "GuestCtrlImplPrivate.h"
25#include "GuestProcessImpl.h"
26#include "GuestDirectoryImpl.h"
27#include "GuestFileImpl.h"
28#include "GuestFsObjInfoImpl.h"
29
30#include <iprt/isofs.h> /* For UpdateAdditions. */
31
32class Guest;
33
34/**
35 * Abstract base class for a lenghtly per-session operation which
36 * runs in a Main worker thread.
37 */
38class GuestSessionTask
39{
40public:
41
42 GuestSessionTask(GuestSession *pSession);
43
44 virtual ~GuestSessionTask(void);
45
46public:
47
48 virtual int Run(void) = 0;
49 virtual int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress) = 0;
50
51protected:
52
53 int getGuestProperty(const ComObjPtr<Guest> &pGuest,
54 const Utf8Str &strPath, Utf8Str &strValue);
55 int setProgress(ULONG uPercent);
56 int setProgressSuccess(void);
57 HRESULT setProgressErrorMsg(HRESULT hr, const Utf8Str &strMsg);
58
59protected:
60
61 Utf8Str mDesc;
62 GuestSession *mSession;
63 /** Progress object for getting updated when running
64 * asynchronously. Optional. */
65 ComObjPtr<Progress> mProgress;
66};
67
68/**
69 * Task for opening a guest session.
70 */
71class SessionTaskOpen : public GuestSessionTask
72{
73public:
74
75 SessionTaskOpen(GuestSession *pSession,
76 uint32_t uFlags,
77 uint32_t uTimeoutMS);
78
79 virtual ~SessionTaskOpen(void);
80
81public:
82
83 int Run(int *pGuestRc);
84 int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
85 static int taskThread(RTTHREAD Thread, void *pvUser);
86
87protected:
88
89 /** Session creation flags. */
90 uint32_t mFlags;
91 /** Session creation timeout (in ms). */
92 uint32_t mTimeoutMS;
93};
94
95/**
96 * Task for copying files from host to the guest.
97 */
98class SessionTaskCopyTo : public GuestSessionTask
99{
100public:
101
102 SessionTaskCopyTo(GuestSession *pSession,
103 const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags);
104
105 SessionTaskCopyTo(GuestSession *pSession,
106 PRTFILE pSourceFile, size_t cbSourceOffset, uint64_t cbSourceSize,
107 const Utf8Str &strDest, uint32_t uFlags);
108
109 virtual ~SessionTaskCopyTo(void);
110
111public:
112
113 int Run(void);
114 int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
115 static int taskThread(RTTHREAD Thread, void *pvUser);
116
117protected:
118
119 Utf8Str mSource;
120 PRTFILE mSourceFile;
121 size_t mSourceOffset;
122 uint64_t mSourceSize;
123 Utf8Str mDest;
124 uint32_t mCopyFileFlags;
125};
126
127/**
128 * Task for copying files from guest to the host.
129 */
130class SessionTaskCopyFrom : public GuestSessionTask
131{
132public:
133
134 SessionTaskCopyFrom(GuestSession *pSession,
135 const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags);
136
137 virtual ~SessionTaskCopyFrom(void);
138
139public:
140
141 int Run(void);
142 int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
143 static int taskThread(RTTHREAD Thread, void *pvUser);
144
145protected:
146
147 Utf8Str mSource;
148 Utf8Str mDest;
149 uint32_t mFlags;
150};
151
152/**
153 * Task for automatically updating the Guest Additions on the guest.
154 */
155class SessionTaskUpdateAdditions : public GuestSessionTask
156{
157public:
158
159 SessionTaskUpdateAdditions(GuestSession *pSession,
160 const Utf8Str &strSource, const ProcessArguments &aArguments,
161 uint32_t uFlags);
162
163 virtual ~SessionTaskUpdateAdditions(void);
164
165public:
166
167 int Run(void);
168 int RunAsync(const Utf8Str &strDesc, ComObjPtr<Progress> &pProgress);
169 static int taskThread(RTTHREAD Thread, void *pvUser);
170
171protected:
172
173 /**
174 * Suported OS types for automatic updating.
175 */
176 enum eOSType
177 {
178 eOSType_Unknown = 0,
179 eOSType_Windows = 1,
180 eOSType_Linux = 2,
181 eOSType_Solaris = 3
182 };
183
184 /**
185 * Structure representing a file to
186 * get off the .ISO, copied to the guest.
187 */
188 struct InstallerFile
189 {
190 InstallerFile(const Utf8Str &aSource,
191 const Utf8Str &aDest,
192 uint32_t aFlags = 0)
193 : strSource(aSource),
194 strDest(aDest),
195 fFlags(aFlags) { }
196
197 InstallerFile(const Utf8Str &aSource,
198 const Utf8Str &aDest,
199 uint32_t aFlags,
200 GuestProcessStartupInfo startupInfo)
201 : strSource(aSource),
202 strDest(aDest),
203 fFlags(aFlags),
204 mProcInfo(startupInfo)
205 {
206 mProcInfo.mExecutable = strDest;
207 if (mProcInfo.mName.isEmpty())
208 mProcInfo.mName = strDest;
209 }
210
211 /** Source file on .ISO. */
212 Utf8Str strSource;
213 /** Destination file on the guest. */
214 Utf8Str strDest;
215 /** File flags. */
216 uint32_t fFlags;
217 /** Optional arguments if this file needs to be
218 * executed. */
219 GuestProcessStartupInfo mProcInfo;
220 };
221
222 int i_addProcessArguments(ProcessArguments &aArgumentsDest,
223 const ProcessArguments &aArgumentsSource);
224 int i_copyFileToGuest(GuestSession *pSession, PRTISOFSFILE pISO,
225 Utf8Str const &strFileSource, const Utf8Str &strFileDest,
226 bool fOptional, uint32_t *pcbSize);
227 int i_runFileOnGuest(GuestSession *pSession, GuestProcessStartupInfo &procInfo);
228
229 /** Files to handle. */
230 std::vector<InstallerFile> mFiles;
231 /** The (optionally) specified Guest Additions .ISO on the host
232 * which will be used for the updating process. */
233 Utf8Str mSource;
234 /** (Optional) installer command line arguments. */
235 ProcessArguments mArguments;
236 /** Update flags. */
237 uint32_t mFlags;
238};
239
240/**
241 * Guest session implementation.
242 */
243class ATL_NO_VTABLE GuestSession :
244 public GuestSessionWrap,
245 public GuestBase
246{
247public:
248 /** @name COM and internal init/term/mapping cruft.
249 * @{ */
250 DECLARE_EMPTY_CTOR_DTOR(GuestSession)
251
252 int init(Guest *pGuest, const GuestSessionStartupInfo &ssInfo, const GuestCredentials &guestCreds);
253 void uninit(void);
254 HRESULT FinalConstruct(void);
255 void FinalRelease(void);
256 /** @} */
257
258private:
259
260 /** Wrapped @name IGuestSession properties.
261 * @{ */
262 HRESULT getUser(com::Utf8Str &aUser);
263 HRESULT getDomain(com::Utf8Str &aDomain);
264 HRESULT getName(com::Utf8Str &aName);
265 HRESULT getId(ULONG *aId);
266 HRESULT getTimeout(ULONG *aTimeout);
267 HRESULT setTimeout(ULONG aTimeout);
268 HRESULT getProtocolVersion(ULONG *aProtocolVersion);
269 HRESULT getStatus(GuestSessionStatus_T *aStatus);
270 HRESULT getEnvironmentChanges(std::vector<com::Utf8Str> &aEnvironmentChanges);
271 HRESULT setEnvironmentChanges(const std::vector<com::Utf8Str> &aEnvironmentChanges);
272 HRESULT getEnvironmentBase(std::vector<com::Utf8Str> &aEnvironmentBase);
273 HRESULT getProcesses(std::vector<ComPtr<IGuestProcess> > &aProcesses);
274 HRESULT getDirectories(std::vector<ComPtr<IGuestDirectory> > &aDirectories);
275 HRESULT getFiles(std::vector<ComPtr<IGuestFile> > &aFiles);
276 HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
277 /** @} */
278
279 /** Wrapped @name IGuestSession methods.
280 * @{ */
281 HRESULT close();
282 HRESULT copyFrom(const com::Utf8Str &aSource,
283 const com::Utf8Str &aDest,
284 const std::vector<CopyFileFlag_T> &aFlags,
285 ComPtr<IProgress> &aProgress);
286 HRESULT copyTo(const com::Utf8Str &aSource,
287 const com::Utf8Str &aDest,
288 const std::vector<CopyFileFlag_T> &aFlags,
289 ComPtr<IProgress> &aProgress);
290 HRESULT directoryCreate(const com::Utf8Str &aPath,
291 ULONG aMode,
292 const std::vector<DirectoryCreateFlag_T> &aFlags);
293 HRESULT directoryCreateTemp(const com::Utf8Str &aTemplateName,
294 ULONG aMode,
295 const com::Utf8Str &aPath,
296 BOOL aSecure,
297 com::Utf8Str &aDirectory);
298 HRESULT directoryExists(const com::Utf8Str &aPath,
299 BOOL *aExists);
300 HRESULT directoryOpen(const com::Utf8Str &aPath,
301 const com::Utf8Str &aFilter,
302 const std::vector<DirectoryOpenFlag_T> &aFlags,
303 ComPtr<IGuestDirectory> &aDirectory);
304 HRESULT directoryQueryInfo(const com::Utf8Str &aPath,
305 ComPtr<IGuestFsObjInfo> &aInfo);
306 HRESULT directoryRemove(const com::Utf8Str &aPath);
307 HRESULT directoryRemoveRecursive(const com::Utf8Str &aPath,
308 const std::vector<DirectoryRemoveRecFlag_T> &aFlags,
309 ComPtr<IProgress> &aProgress);
310 HRESULT directoryRename(const com::Utf8Str &aSource,
311 const com::Utf8Str &aDest,
312 const std::vector<PathRenameFlag_T> &aFlags);
313 HRESULT directorySetACL(const com::Utf8Str &aPath,
314 const com::Utf8Str &aAcl);
315 HRESULT environmentScheduleSet(const com::Utf8Str &aName,
316 const com::Utf8Str &aValue);
317 HRESULT environmentScheduleUnset(const com::Utf8Str &aName);
318 HRESULT environmentGetBaseVariable(const com::Utf8Str &aName,
319 com::Utf8Str &aValue);
320 HRESULT environmentDoesBaseVariableExist(const com::Utf8Str &aName,
321 BOOL *aExists);
322 HRESULT fileCreateTemp(const com::Utf8Str &aTemplateName,
323 ULONG aMode,
324 const com::Utf8Str &aPath,
325 BOOL aSecure,
326 ComPtr<IGuestFile> &aFile);
327 HRESULT fileExists(const com::Utf8Str &aPath,
328 BOOL *aExists);
329 HRESULT fileRemove(const com::Utf8Str &aPath);
330 HRESULT fileOpen(const com::Utf8Str &aPath,
331 const com::Utf8Str &aOpenMode,
332 const com::Utf8Str &aDisposition,
333 ULONG aCreationMode,
334 ComPtr<IGuestFile> &aFile);
335 HRESULT fileOpenEx(const com::Utf8Str &aPath,
336 const com::Utf8Str &aOpenMode,
337 const com::Utf8Str &aDisposition,
338 const com::Utf8Str &aSharingMode,
339 ULONG aCreationMode,
340 LONG64 aOffset,
341 ComPtr<IGuestFile> &aFile);
342 HRESULT fileQueryInfo(const com::Utf8Str &aPath,
343 ComPtr<IGuestFsObjInfo> &aInfo);
344 HRESULT fileQuerySize(const com::Utf8Str &aPath,
345 LONG64 *aSize);
346 HRESULT fileRename(const com::Utf8Str &aSource,
347 const com::Utf8Str &aDest,
348 const std::vector<PathRenameFlag_T> &aFlags);
349 HRESULT fileSetACL(const com::Utf8Str &aFile,
350 const com::Utf8Str &aAcl);
351 HRESULT processCreate(const com::Utf8Str &aCommand,
352 const std::vector<com::Utf8Str> &aArguments,
353 const std::vector<com::Utf8Str> &aEnvironment,
354 const std::vector<ProcessCreateFlag_T> &aFlags,
355 ULONG aTimeoutMS,
356 ComPtr<IGuestProcess> &aGuestProcess);
357 HRESULT processCreateEx(const com::Utf8Str &aCommand,
358 const std::vector<com::Utf8Str> &aArguments,
359 const std::vector<com::Utf8Str> &aEnvironment,
360 const std::vector<ProcessCreateFlag_T> &aFlags,
361 ULONG aTimeoutMS,
362 ProcessPriority_T aPriority,
363 const std::vector<LONG> &aAffinity,
364 ComPtr<IGuestProcess> &aGuestProcess);
365 HRESULT processGet(ULONG aPid,
366 ComPtr<IGuestProcess> &aGuestProcess);
367 HRESULT symlinkCreate(const com::Utf8Str &aSource,
368 const com::Utf8Str &aTarget,
369 SymlinkType_T aType);
370 HRESULT symlinkExists(const com::Utf8Str &aSymlink,
371 BOOL *aExists);
372 HRESULT symlinkRead(const com::Utf8Str &aSymlink,
373 const std::vector<SymlinkReadFlag_T> &aFlags,
374 com::Utf8Str &aTarget);
375 HRESULT symlinkRemoveDirectory(const com::Utf8Str &aPath);
376 HRESULT symlinkRemoveFile(const com::Utf8Str &aFile);
377 HRESULT waitFor(ULONG aWaitFor,
378 ULONG aTimeoutMS,
379 GuestSessionWaitResult_T *aReason);
380 HRESULT waitForArray(const std::vector<GuestSessionWaitForFlag_T> &aWaitFor,
381 ULONG aTimeoutMS,
382 GuestSessionWaitResult_T *aReason);
383 /** @} */
384
385 /** Map of guest directories. The key specifies the internal directory ID. */
386 typedef std::map <uint32_t, ComObjPtr<GuestDirectory> > SessionDirectories;
387 /** Map of guest files. The key specifies the internal file ID. */
388 typedef std::map <uint32_t, ComObjPtr<GuestFile> > SessionFiles;
389 /** Map of guest processes. The key specifies the internal process number.
390 * To retrieve the process' guest PID use the Id() method of the IProcess interface. */
391 typedef std::map <uint32_t, ComObjPtr<GuestProcess> > SessionProcesses;
392
393public:
394 /** @name Public internal methods.
395 * @todo r=bird: Most of these are public for no real reason...
396 * @{ */
397 int i_closeSession(uint32_t uFlags, uint32_t uTimeoutMS, int *pGuestRc);
398 inline bool i_directoryExists(uint32_t uDirID, ComObjPtr<GuestDirectory> *pDir);
399 int i_directoryRemoveFromList(GuestDirectory *pDirectory);
400 int i_directoryRemoveInternal(const Utf8Str &strPath, uint32_t uFlags, int *pGuestRc);
401 int i_directoryCreateInternal(const Utf8Str &strPath, uint32_t uMode, uint32_t uFlags, int *pGuestRc);
402 int i_objectCreateTempInternal(const Utf8Str &strTemplate, const Utf8Str &strPath, bool fDirectory,
403 Utf8Str &strName, int *pGuestRc);
404 int i_directoryOpenInternal(const GuestDirectoryOpenInfo &openInfo,
405 ComObjPtr<GuestDirectory> &pDirectory, int *pGuestRc);
406 int i_directoryQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
407 int i_dispatchToDirectory(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
408 int i_dispatchToFile(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
409 int i_dispatchToObject(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
410 int i_dispatchToProcess(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
411 int i_dispatchToThis(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
412 inline bool i_fileExists(uint32_t uFileID, ComObjPtr<GuestFile> *pFile);
413 int i_fileRemoveFromList(GuestFile *pFile);
414 int i_fileRemoveInternal(const Utf8Str &strPath, int *pGuestRc);
415 int i_fileOpenInternal(const GuestFileOpenInfo &openInfo, ComObjPtr<GuestFile> &pFile, int *pGuestRc);
416 int i_fileQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
417 int i_fileQuerySizeInternal(const Utf8Str &strPath, int64_t *pllSize, int *pGuestRc);
418 int i_fsQueryInfoInternal(const Utf8Str &strPath, GuestFsObjData &objData, int *pGuestRc);
419 const GuestCredentials &i_getCredentials(void);
420 EventSource *i_getEventSource(void) { return mEventSource; }
421 Utf8Str i_getName(void);
422 ULONG i_getId(void) { return mData.mSession.mID; }
423 static Utf8Str i_guestErrorToString(int guestRc);
424 HRESULT i_isReadyExternal(void);
425 int i_onRemove(void);
426 int i_onSessionStatusChange(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
427 int i_startSessionInternal(int *pGuestRc);
428 int i_startSessionAsync(void);
429 static DECLCALLBACK(int)
430 i_startSessionThread(RTTHREAD Thread, void *pvUser);
431 Guest *i_getParent(void) { return mParent; }
432 uint32_t i_getProtocolVersion(void) { return mData.mProtocolVersion; }
433 int i_pathRenameInternal(const Utf8Str &strSource, const Utf8Str &strDest, uint32_t uFlags,
434 int *pGuestRc);
435 int i_processRemoveFromList(GuestProcess *pProcess);
436 int i_processCreateExInternal(GuestProcessStartupInfo &procInfo, ComObjPtr<GuestProcess> &pProgress);
437 inline bool i_processExists(uint32_t uProcessID, ComObjPtr<GuestProcess> *pProcess);
438 inline int i_processGetByPID(ULONG uPID, ComObjPtr<GuestProcess> *pProcess);
439 int i_sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
440 static HRESULT i_setErrorExternal(VirtualBoxBase *pInterface, int guestRc);
441 int i_setSessionStatus(GuestSessionStatus_T sessionStatus, int sessionRc);
442 int i_signalWaiters(GuestSessionWaitResult_T enmWaitResult, int rc /*= VINF_SUCCESS */);
443 int i_startTaskAsync(const Utf8Str &strTaskDesc, GuestSessionTask *pTask,
444 ComObjPtr<Progress> &pProgress);
445 int i_determineProtocolVersion(void);
446 int i_waitFor(uint32_t fWaitFlags, ULONG uTimeoutMS, GuestSessionWaitResult_T &waitResult, int *pGuestRc);
447 int i_waitForStatusChange(GuestWaitEvent *pEvent, uint32_t fWaitFlags, uint32_t uTimeoutMS,
448 GuestSessionStatus_T *pSessionStatus, int *pGuestRc);
449 /** @} */
450
451private:
452
453 /** Pointer to the parent (Guest). */
454 Guest *mParent;
455 /**
456 * The session's event source. This source is used for
457 * serving the internal listener as well as all other
458 * external listeners that may register to it.
459 *
460 * Note: This can safely be used without holding any locks.
461 * An AutoCaller suffices to prevent it being destroy while in use and
462 * internally there is a lock providing the necessary serialization.
463 */
464 const ComObjPtr<EventSource> mEventSource;
465
466 struct Data
467 {
468 /** The session credentials. */
469 GuestCredentials mCredentials;
470 /** The session's startup info. */
471 GuestSessionStartupInfo mSession;
472 /** The session's current status. */
473 GuestSessionStatus_T mStatus;
474 /** The set of environment changes for the session for use when
475 * creating new guest processes. */
476 GuestEnvironmentChanges mEnvironmentChanges;
477 /** Pointer to the immutable base environment for the session.
478 * @note This is not allocated until the guest reports it to the host. It is
479 * also shared with child processes. */
480 GuestEnvironment const *mpBaseEnvironment;
481 /** Directory objects bound to this session. */
482 SessionDirectories mDirectories;
483 /** File objects bound to this session. */
484 SessionFiles mFiles;
485 /** Process objects bound to this session. */
486 SessionProcesses mProcesses;
487 /** Guest control protocol version to be used.
488 * Guest Additions < VBox 4.3 have version 1,
489 * any newer version will have version 2. */
490 uint32_t mProtocolVersion;
491 /** Session timeout (in ms). */
492 uint32_t mTimeout;
493 /** Total number of session objects (processes,
494 * files, ...). */
495 uint32_t mNumObjects;
496 /** The last returned session status
497 * returned from the guest side. */
498 int mRC;
499
500 Data(void)
501 : mpBaseEnvironment(NULL)
502 { }
503 Data(const Data &rThat)
504 : mCredentials(rThat.mCredentials)
505 , mSession(rThat.mSession)
506 , mStatus(rThat.mStatus)
507 , mEnvironmentChanges(rThat.mEnvironmentChanges)
508 , mpBaseEnvironment(NULL)
509 , mDirectories(rThat.mDirectories)
510 , mFiles(rThat.mFiles)
511 , mProcesses(rThat.mProcesses)
512 , mProtocolVersion(rThat.mProtocolVersion)
513 , mTimeout(rThat.mTimeout)
514 , mNumObjects(rThat.mNumObjects)
515 , mRC(rThat.mRC)
516 { }
517 ~Data(void)
518 {
519 if (mpBaseEnvironment)
520 {
521 mpBaseEnvironment->releaseConst();
522 mpBaseEnvironment = NULL;
523 }
524 }
525 } mData;
526};
527
528#endif /* !____H_GUESTSESSIONIMPL */
529
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