VirtualBox

source: vbox/trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h@ 43507

Last change on this file since 43507 was 43162, checked in by vboxsync, 12 years ago

Main/Guest Control 2.0: Cleanup, separated guest error handling.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.4 KB
Line 
1/** @file
2 *
3 * Internal helpers/structures for guest control functionality.
4 */
5
6/*
7 * Copyright (C) 2011-2012 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_GUESTIMPLPRIVATE
19#define ____H_GUESTIMPLPRIVATE
20
21#include <iprt/asm.h>
22#include <iprt/semaphore.h>
23
24#include <VBox/com/com.h>
25#include <VBox/com/ErrorInfo.h>
26#include <VBox/com/string.h>
27#include <VBox/com/VirtualBox.h>
28
29#include <map>
30#include <vector>
31
32using namespace com;
33
34#ifdef VBOX_WITH_GUEST_CONTROL
35# include <VBox/HostServices/GuestControlSvc.h>
36using namespace guestControl;
37#endif
38
39/** Maximum number of guest sessions a VM can have. */
40#define VBOX_GUESTCTRL_MAX_SESSIONS 32
41/** Maximum number of guest objects (processes, files, ...)
42 * a guest session can have. */
43#define VBOX_GUESTCTRL_MAX_OBJECTS _2K
44/** Maximum of callback contexts a guest process can have. */
45#define VBOX_GUESTCTRL_MAX_CONTEXTS _64K
46
47/** Builds a context ID out of the session ID, object ID and an
48 * increasing count. */
49#define VBOX_GUESTCTRL_CONTEXTID_MAKE(uSession, uObject, uCount) \
50 ( (uint32_t)((uSession) & 0x1f) << 27 \
51 | (uint32_t)((uObject) & 0x7ff) << 16 \
52 | (uint32_t)((uCount) & 0xffff) \
53 )
54/** Gets the session ID out of a context ID. */
55#define VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(uContextID) \
56 ((uContextID) >> 27)
57/** Gets the process ID out of a context ID. */
58#define VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(uContextID) \
59 (((uContextID) >> 16) & 0x7ff)
60/** Gets the conext count of a process out of a context ID. */
61#define VBOX_GUESTCTRL_CONTEXTID_GET_COUNT(uContextID) \
62 ((uContextID) & 0xffff)
63
64/** Vector holding a process' CPU affinity. */
65typedef std::vector <LONG> ProcessAffinity;
66/** Vector holding process startup arguments. */
67typedef std::vector <Utf8Str> ProcessArguments;
68
69class GuestProcessStreamBlock;
70
71
72/**
73 * Base class for a all guest control callbacks/events.
74 */
75class GuestCtrlEvent
76{
77public:
78
79 GuestCtrlEvent(void);
80
81 virtual ~GuestCtrlEvent(void);
82
83 /** @todo Copy/comparison operator? */
84
85public:
86
87 int Cancel(void);
88
89 bool Canceled(void);
90
91 virtual void Destroy(void);
92
93 int Init(void);
94
95 virtual int Signal(int rc = VINF_SUCCESS);
96
97 int GetResultCode(void) { return mRC; }
98
99 int Wait(ULONG uTimeoutMS);
100
101protected:
102
103 /** Was the callback canceled? */
104 bool fCanceled;
105 /** Did the callback complete? */
106 bool fCompleted;
107 /** The event semaphore for triggering
108 * the actual event. */
109 RTSEMEVENT hEventSem;
110 /** The waiting mutex. */
111 RTSEMMUTEX hEventMutex;
112 /** Overall result code. */
113 int mRC;
114};
115
116
117/*
118 * Class representing a guest control callback.
119 */
120class GuestCtrlCallback : public GuestCtrlEvent
121{
122public:
123
124 GuestCtrlCallback(void);
125
126 GuestCtrlCallback(eVBoxGuestCtrlCallbackType enmType);
127
128 virtual ~GuestCtrlCallback(void);
129
130public:
131
132 void Destroy(void);
133
134 int Init(eVBoxGuestCtrlCallbackType enmType);
135
136 eVBoxGuestCtrlCallbackType GetCallbackType(void) { return mType; }
137
138 const void* GetDataRaw(void) const { return pvData; }
139
140 size_t GetDataSize(void) { return cbData; }
141
142 const void* GetPayloadRaw(void) const { return pvPayload; }
143
144 size_t GetPayloadSize(void) { return cbPayload; }
145
146 int SetData(const void *pvCallback, size_t cbCallback);
147
148 int SetPayload(const void *pvToWrite, size_t cbToWrite);
149
150protected:
151
152 /** Pointer to actual callback data. */
153 void *pvData;
154 /** Size of user-supplied data. */
155 size_t cbData;
156 /** The callback type. */
157 eVBoxGuestCtrlCallbackType mType;
158 /** Callback flags. */
159 uint32_t uFlags;
160 /** Payload which will be available on successful
161 * waiting (optional). */
162 void *pvPayload;
163 /** Size of the payload (optional). */
164 size_t cbPayload;
165};
166typedef std::map < uint32_t, GuestCtrlCallback* > GuestCtrlCallbacks;
167
168
169/*
170 * Class representing a guest control process waiting
171 * event.
172 */
173class GuestProcessWaitEvent : public GuestCtrlEvent
174{
175public:
176
177 GuestProcessWaitEvent(void);
178
179 GuestProcessWaitEvent(uint32_t uWaitFlags);
180
181 virtual ~GuestProcessWaitEvent(void);
182
183public:
184
185 void Destroy(void);
186
187 int Init(uint32_t uWaitFlags);
188
189 uint32_t GetWaitFlags(void) { return ASMAtomicReadU32(&mFlags); }
190
191 ProcessWaitResult_T GetWaitResult(void) { return mResult; }
192
193 int GetWaitRc(void) { return mRC; }
194
195 int Signal(ProcessWaitResult_T enmResult, int rc = VINF_SUCCESS);
196
197protected:
198
199 /** The waiting flag(s). The specifies what to
200 * wait for. See ProcessWaitFlag_T. */
201 uint32_t mFlags;
202 /** Structure containing the overall result. */
203 ProcessWaitResult_T mResult;
204};
205
206
207/**
208 * Simple structure mantaining guest credentials.
209 */
210struct GuestCredentials
211{
212 Utf8Str mUser;
213 Utf8Str mPassword;
214 Utf8Str mDomain;
215};
216
217
218typedef std::vector <Utf8Str> GuestEnvironmentArray;
219class GuestEnvironment
220{
221public:
222
223 int BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars);
224
225 void Clear(void);
226
227 int CopyFrom(const GuestEnvironmentArray &environment);
228
229 int CopyTo(GuestEnvironmentArray &environment);
230
231 static void FreeEnvironmentBlock(void *pvEnv);
232
233 Utf8Str Get(const Utf8Str &strKey);
234
235 Utf8Str Get(size_t nPos);
236
237 bool Has(const Utf8Str &strKey);
238
239 int Set(const Utf8Str &strKey, const Utf8Str &strValue);
240
241 int Set(const Utf8Str &strPair);
242
243 size_t Size(void);
244
245 int Unset(const Utf8Str &strKey);
246
247public:
248
249 GuestEnvironment& operator=(const GuestEnvironmentArray &that);
250
251 GuestEnvironment& operator=(const GuestEnvironment &that);
252
253protected:
254
255 int appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars);
256
257protected:
258
259 std::map <Utf8Str, Utf8Str> mEnvironment;
260};
261
262
263/**
264 * Structure representing information of a
265 * file system object.
266 */
267struct GuestFsObjData
268{
269 /** Helper function to extract the data from
270 * a certin VBoxService tool's guest stream block. */
271 int FromLs(const GuestProcessStreamBlock &strmBlk);
272 int FromStat(const GuestProcessStreamBlock &strmBlk);
273
274 int64_t mAccessTime;
275 int64_t mAllocatedSize;
276 int64_t mBirthTime;
277 int64_t mChangeTime;
278 uint32_t mDeviceNumber;
279 Utf8Str mFileAttrs;
280 uint32_t mGenerationID;
281 uint32_t mGID;
282 Utf8Str mGroupName;
283 uint32_t mNumHardLinks;
284 int64_t mModificationTime;
285 Utf8Str mName;
286 int64_t mNodeID;
287 uint32_t mNodeIDDevice;
288 int64_t mObjectSize;
289 FsObjType_T mType;
290 uint32_t mUID;
291 uint32_t mUserFlags;
292 Utf8Str mUserName;
293 Utf8Str mACL;
294};
295
296
297/**
298 * Structure for keeping all the relevant process
299 * starting parameters around.
300 */
301class GuestProcessStartupInfo
302{
303public:
304
305 GuestProcessStartupInfo(void)
306 : mFlags(ProcessCreateFlag_None),
307 mTimeoutMS(30 * 1000 /* 30s timeout by default */),
308 mPriority(ProcessPriority_Default) { }
309
310 /** The process' friendly name. */
311 Utf8Str mName;
312 /** The actual command to execute. */
313 Utf8Str mCommand;
314 ProcessArguments mArguments;
315 GuestEnvironment mEnvironment;
316 /** Process creation flags. */
317 uint32_t mFlags;
318 ULONG mTimeoutMS;
319 ProcessPriority_T mPriority;
320 ProcessAffinity mAffinity;
321};
322
323
324/**
325 * Class representing the "value" side of a "key=value" pair.
326 */
327class GuestProcessStreamValue
328{
329public:
330
331 GuestProcessStreamValue(void) { }
332 GuestProcessStreamValue(const char *pszValue)
333 : mValue(pszValue) {}
334
335 GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
336 : mValue(aThat.mValue) { }
337
338 Utf8Str mValue;
339};
340
341/** Map containing "key=value" pairs of a guest process stream. */
342typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
343typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
344typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
345typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
346
347/**
348 * Class representing a block of stream pairs (key=value). Each block in a raw guest
349 * output stream is separated by "\0\0", each pair is separated by "\0". The overall
350 * end of a guest stream is marked by "\0\0\0\0".
351 */
352class GuestProcessStreamBlock
353{
354public:
355
356 GuestProcessStreamBlock(void);
357
358 virtual ~GuestProcessStreamBlock(void);
359
360public:
361
362 void Clear(void);
363
364#ifdef DEBUG
365 void DumpToLog(void) const;
366#endif
367
368 int GetInt64Ex(const char *pszKey, int64_t *piVal) const;
369
370 int64_t GetInt64(const char *pszKey) const;
371
372 size_t GetCount(void) const;
373
374 const char* GetString(const char *pszKey) const;
375
376 int GetUInt32Ex(const char *pszKey, uint32_t *puVal) const;
377
378 uint32_t GetUInt32(const char *pszKey) const;
379
380 bool IsEmpty(void) { return m_mapPairs.empty(); }
381
382 int SetValue(const char *pszKey, const char *pszValue);
383
384protected:
385
386 GuestCtrlStreamPairMap m_mapPairs;
387};
388
389/** Vector containing multiple allocated stream pair objects. */
390typedef std::vector< GuestProcessStreamBlock > GuestCtrlStreamObjects;
391typedef std::vector< GuestProcessStreamBlock >::iterator GuestCtrlStreamObjectsIter;
392typedef std::vector< GuestProcessStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
393
394/**
395 * Class for parsing machine-readable guest process output by VBoxService'
396 * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
397 */
398class GuestProcessStream
399{
400
401public:
402
403 GuestProcessStream();
404
405 virtual ~GuestProcessStream();
406
407public:
408
409 int AddData(const BYTE *pbData, size_t cbData);
410
411 void Destroy();
412
413#ifdef DEBUG
414 void Dump(const char *pszFile);
415#endif
416
417 uint32_t GetOffset();
418
419 uint32_t GetSize();
420
421 int ParseBlock(GuestProcessStreamBlock &streamBlock);
422
423protected:
424
425 /** Currently allocated size of internal stream buffer. */
426 uint32_t m_cbAllocated;
427 /** Currently used size of allocated internal stream buffer. */
428 uint32_t m_cbSize;
429 /** Current offset within the internal stream buffer. */
430 uint32_t m_cbOffset;
431 /** Internal stream buffer. */
432 BYTE *m_pbBuffer;
433};
434
435class Guest;
436class Progress;
437
438class GuestTask
439{
440
441public:
442
443 enum TaskType
444 {
445 /** Copies a file from host to the guest. */
446 TaskType_CopyFileToGuest = 50,
447 /** Copies a file from guest to the host. */
448 TaskType_CopyFileFromGuest = 55,
449 /** Update Guest Additions by directly copying the required installer
450 * off the .ISO file, transfer it to the guest and execute the installer
451 * with system privileges. */
452 TaskType_UpdateGuestAdditions = 100
453 };
454
455 GuestTask(TaskType aTaskType, Guest *aThat, Progress *aProgress);
456
457 virtual ~GuestTask();
458
459 int startThread();
460
461 static int taskThread(RTTHREAD aThread, void *pvUser);
462 static int uploadProgress(unsigned uPercent, void *pvUser);
463 static HRESULT setProgressSuccess(ComObjPtr<Progress> pProgress);
464 static HRESULT setProgressErrorMsg(HRESULT hr,
465 ComObjPtr<Progress> pProgress, const char * pszText, ...);
466 static HRESULT setProgressErrorParent(HRESULT hr,
467 ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest);
468
469 TaskType taskType;
470 ComObjPtr<Guest> pGuest;
471 ComObjPtr<Progress> pProgress;
472 HRESULT rc;
473
474 /* Task data. */
475 Utf8Str strSource;
476 Utf8Str strDest;
477 Utf8Str strUserName;
478 Utf8Str strPassword;
479 ULONG uFlags;
480};
481#endif // ____H_GUESTIMPLPRIVATE
482
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