VirtualBox

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

Last change on this file since 47148 was 45780, checked in by vboxsync, 12 years ago

Main/GuestCtrl: Use active listeners instead of passive ones because of performance reasons (untested).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.3 KB
Line 
1/** @file
2 *
3 * Internal helpers/structures for guest control functionality.
4 */
5
6/*
7 * Copyright (C) 2011-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_GUESTIMPLPRIVATE
19#define ____H_GUESTIMPLPRIVATE
20
21#include "ConsoleImpl.h"
22
23#include <iprt/asm.h>
24#include <iprt/semaphore.h>
25
26#include <VBox/com/com.h>
27#include <VBox/com/ErrorInfo.h>
28#include <VBox/com/string.h>
29#include <VBox/com/VirtualBox.h>
30
31#include <map>
32#include <vector>
33
34using namespace com;
35
36#ifdef VBOX_WITH_GUEST_CONTROL
37# include <VBox/HostServices/GuestControlSvc.h>
38using namespace guestControl;
39#endif
40
41/** Vector holding a process' CPU affinity. */
42typedef std::vector <LONG> ProcessAffinity;
43/** Vector holding process startup arguments. */
44typedef std::vector <Utf8Str> ProcessArguments;
45
46class GuestProcessStreamBlock;
47class GuestSession;
48
49
50/**
51 * Simple structure mantaining guest credentials.
52 */
53struct GuestCredentials
54{
55 Utf8Str mUser;
56 Utf8Str mPassword;
57 Utf8Str mDomain;
58};
59
60
61typedef std::vector <Utf8Str> GuestEnvironmentArray;
62class GuestEnvironment
63{
64public:
65
66 int BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars);
67
68 void Clear(void);
69
70 int CopyFrom(const GuestEnvironmentArray &environment);
71
72 int CopyTo(GuestEnvironmentArray &environment);
73
74 static void FreeEnvironmentBlock(void *pvEnv);
75
76 Utf8Str Get(const Utf8Str &strKey);
77
78 Utf8Str Get(size_t nPos);
79
80 bool Has(const Utf8Str &strKey);
81
82 int Set(const Utf8Str &strKey, const Utf8Str &strValue);
83
84 int Set(const Utf8Str &strPair);
85
86 size_t Size(void);
87
88 int Unset(const Utf8Str &strKey);
89
90public:
91
92 GuestEnvironment& operator=(const GuestEnvironmentArray &that);
93
94 GuestEnvironment& operator=(const GuestEnvironment &that);
95
96protected:
97
98 int appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars);
99
100protected:
101
102 std::map <Utf8Str, Utf8Str> mEnvironment;
103};
104
105
106/**
107 * Structure for keeping all the relevant guest file
108 * information around.
109 */
110struct GuestFileOpenInfo
111{
112 /** The filename. */
113 Utf8Str mFileName;
114 /** Then file's opening mode. */
115 Utf8Str mOpenMode;
116 /** The file's disposition mode. */
117 Utf8Str mDisposition;
118 /** Octal creation mode. */
119 uint32_t mCreationMode;
120 /** The initial offset on open. */
121 int64_t mInitialOffset;
122};
123
124
125/**
126 * Structure representing information of a
127 * file system object.
128 */
129struct GuestFsObjData
130{
131 /** Helper function to extract the data from
132 * a certin VBoxService tool's guest stream block. */
133 int FromLs(const GuestProcessStreamBlock &strmBlk);
134 int FromStat(const GuestProcessStreamBlock &strmBlk);
135
136 int64_t mAccessTime;
137 int64_t mAllocatedSize;
138 int64_t mBirthTime;
139 int64_t mChangeTime;
140 uint32_t mDeviceNumber;
141 Utf8Str mFileAttrs;
142 uint32_t mGenerationID;
143 uint32_t mGID;
144 Utf8Str mGroupName;
145 uint32_t mNumHardLinks;
146 int64_t mModificationTime;
147 Utf8Str mName;
148 int64_t mNodeID;
149 uint32_t mNodeIDDevice;
150 int64_t mObjectSize;
151 FsObjType_T mType;
152 uint32_t mUID;
153 uint32_t mUserFlags;
154 Utf8Str mUserName;
155 Utf8Str mACL;
156};
157
158
159/**
160 * Structure for keeping all the relevant guest session
161 * startup parameters around.
162 */
163class GuestSessionStartupInfo
164{
165public:
166
167 GuestSessionStartupInfo(void)
168 : mIsInternal(false /* Non-internal session */),
169 mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */),
170 mOpenFlags(0 /* No opening flags set */) { }
171
172 /** The session's friendly name. Optional. */
173 Utf8Str mName;
174 /** The session's unique ID. Used to encode
175 * a context ID. */
176 uint32_t mID;
177 /** Flag indicating if this is an internal session
178 * or not. Internal session are not accessible by
179 * public API clients. */
180 bool mIsInternal;
181 /** Timeout (in ms) used for opening the session. */
182 uint32_t mOpenTimeoutMS;
183 /** Session opening flags. */
184 uint32_t mOpenFlags;
185};
186
187
188/**
189 * Structure for keeping all the relevant guest process
190 * startup parameters around.
191 */
192class GuestProcessStartupInfo
193{
194public:
195
196 GuestProcessStartupInfo(void)
197 : mFlags(ProcessCreateFlag_None),
198 mTimeoutMS(30 * 1000 /* 30s timeout by default */),
199 mPriority(ProcessPriority_Default) { }
200
201 /** The process' friendly name. */
202 Utf8Str mName;
203 /** The actual command to execute. */
204 Utf8Str mCommand;
205 ProcessArguments mArguments;
206 GuestEnvironment mEnvironment;
207 /** Process creation flags. */
208 uint32_t mFlags;
209 ULONG mTimeoutMS;
210 /** Process priority. */
211 ProcessPriority_T mPriority;
212 /** Process affinity. At the moment we
213 * only support 64 VCPUs. API and
214 * guest can do more already! */
215 uint64_t mAffinity;
216};
217
218
219/**
220 * Class representing the "value" side of a "key=value" pair.
221 */
222class GuestProcessStreamValue
223{
224public:
225
226 GuestProcessStreamValue(void) { }
227 GuestProcessStreamValue(const char *pszValue)
228 : mValue(pszValue) {}
229
230 GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
231 : mValue(aThat.mValue) { }
232
233 Utf8Str mValue;
234};
235
236/** Map containing "key=value" pairs of a guest process stream. */
237typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
238typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
239typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
240typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
241
242/**
243 * Class representing a block of stream pairs (key=value). Each block in a raw guest
244 * output stream is separated by "\0\0", each pair is separated by "\0". The overall
245 * end of a guest stream is marked by "\0\0\0\0".
246 */
247class GuestProcessStreamBlock
248{
249public:
250
251 GuestProcessStreamBlock(void);
252
253 virtual ~GuestProcessStreamBlock(void);
254
255public:
256
257 void Clear(void);
258
259#ifdef DEBUG
260 void DumpToLog(void) const;
261#endif
262
263 int GetInt64Ex(const char *pszKey, int64_t *piVal) const;
264
265 int64_t GetInt64(const char *pszKey) const;
266
267 size_t GetCount(void) const;
268
269 const char* GetString(const char *pszKey) const;
270
271 int GetUInt32Ex(const char *pszKey, uint32_t *puVal) const;
272
273 uint32_t GetUInt32(const char *pszKey) const;
274
275 bool IsEmpty(void) { return mPairs.empty(); }
276
277 int SetValue(const char *pszKey, const char *pszValue);
278
279protected:
280
281 GuestCtrlStreamPairMap mPairs;
282};
283
284/** Vector containing multiple allocated stream pair objects. */
285typedef std::vector< GuestProcessStreamBlock > GuestCtrlStreamObjects;
286typedef std::vector< GuestProcessStreamBlock >::iterator GuestCtrlStreamObjectsIter;
287typedef std::vector< GuestProcessStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
288
289/**
290 * Class for parsing machine-readable guest process output by VBoxService'
291 * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
292 */
293class GuestProcessStream
294{
295
296public:
297
298 GuestProcessStream();
299
300 virtual ~GuestProcessStream();
301
302public:
303
304 int AddData(const BYTE *pbData, size_t cbData);
305
306 void Destroy();
307
308#ifdef DEBUG
309 void Dump(const char *pszFile);
310#endif
311
312 uint32_t GetOffset();
313
314 uint32_t GetSize();
315
316 int ParseBlock(GuestProcessStreamBlock &streamBlock);
317
318protected:
319
320 /** Currently allocated size of internal stream buffer. */
321 uint32_t m_cbAllocated;
322 /** Currently used size of allocated internal stream buffer. */
323 uint32_t m_cbSize;
324 /** Current offset within the internal stream buffer. */
325 uint32_t m_cbOffset;
326 /** Internal stream buffer. */
327 BYTE *m_pbBuffer;
328};
329
330class Guest;
331class Progress;
332
333class GuestTask
334{
335
336public:
337
338 enum TaskType
339 {
340 /** Copies a file from host to the guest. */
341 TaskType_CopyFileToGuest = 50,
342 /** Copies a file from guest to the host. */
343 TaskType_CopyFileFromGuest = 55,
344 /** Update Guest Additions by directly copying the required installer
345 * off the .ISO file, transfer it to the guest and execute the installer
346 * with system privileges. */
347 TaskType_UpdateGuestAdditions = 100
348 };
349
350 GuestTask(TaskType aTaskType, Guest *aThat, Progress *aProgress);
351
352 virtual ~GuestTask();
353
354 int startThread();
355
356 static int taskThread(RTTHREAD aThread, void *pvUser);
357 static int uploadProgress(unsigned uPercent, void *pvUser);
358 static HRESULT setProgressSuccess(ComObjPtr<Progress> pProgress);
359 static HRESULT setProgressErrorMsg(HRESULT hr,
360 ComObjPtr<Progress> pProgress, const char * pszText, ...);
361 static HRESULT setProgressErrorParent(HRESULT hr,
362 ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest);
363
364 TaskType taskType;
365 ComObjPtr<Guest> pGuest;
366 ComObjPtr<Progress> pProgress;
367 HRESULT rc;
368
369 /* Task data. */
370 Utf8Str strSource;
371 Utf8Str strDest;
372 Utf8Str strUserName;
373 Utf8Str strPassword;
374 ULONG uFlags;
375};
376
377class GuestWaitEvent
378{
379public:
380
381 GuestWaitEvent(uint32_t mCID, const std::list<VBoxEventType_T> &lstEvents);
382 virtual ~GuestWaitEvent(void);
383
384public:
385
386 uint32_t ContextID(void) { return mCID; };
387 const ComPtr<IEvent> Event(void) { return mEvent; };
388 const std::list<VBoxEventType_T> Types(void) { return mEventTypes; };
389 int Signal(IEvent *pEvent);
390 int Wait(RTMSINTERVAL uTimeoutMS);
391
392protected:
393
394 uint32_t mCID;
395 std::list<VBoxEventType_T> mEventTypes;
396 /** The event semaphore for triggering
397 * the actual event. */
398 RTSEMEVENT mEventSem;
399 /** Pointer to the actual event. */
400 ComPtr<IEvent> mEvent;
401};
402typedef std::list < GuestWaitEvent* > GuestWaitEvents;
403typedef std::map < VBoxEventType_T, GuestWaitEvents > GuestWaitEventTypes;
404
405class GuestBase
406{
407
408public:
409
410 GuestBase(void);
411 virtual ~GuestBase(void);
412
413public:
414
415 /** For external event listeners. */
416 int signalWaitEvents(VBoxEventType_T aType, IEvent *aEvent);
417
418public:
419
420 int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID);
421 int registerEvent(uint32_t uSessionID, uint32_t uObjectID, const std::list<VBoxEventType_T> &lstEvents, GuestWaitEvent **ppEvent);
422 void unregisterEvent(GuestWaitEvent *pEvent);
423 void unregisterEventListener(void);
424 int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent);
425
426protected:
427
428 /** Pointer to the console object. Needed
429 * for HGCM (VMMDev) communication. */
430 Console *mConsole;
431 /** The next upcoming context ID for this object. */
432 uint32_t mNextContextID;
433 /** Local listener for handling the waiting events. */
434 ComPtr<IEventListener> mListener;
435 /** Critical section for wait events access. */
436 RTCRITSECT mWaitEventCritSect;
437 /** Map of internal events to wait for. */
438 GuestWaitEventTypes mWaitEvents;
439};
440
441/**
442 * Virtual class (interface) for guest objects (processes, files, ...) --
443 * contains all per-object callback management.
444 */
445class GuestObject : public GuestBase
446{
447
448public:
449
450 GuestObject(void);
451 virtual ~GuestObject(void);
452
453public:
454
455 ULONG getObjectID(void) { return mObjectID; }
456
457protected:
458
459 /** Callback dispatcher -- must be implemented by the actual object. */
460 virtual int callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) = 0;
461
462protected:
463
464 int bindToSession(Console *pConsole, GuestSession *pSession, uint32_t uObjectID);
465 int registerEvent(const std::list<VBoxEventType_T> &lstEvents, GuestWaitEvent **ppEvent);
466 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
467
468protected:
469
470 /**
471 * Commom parameters for all derived objects, when then have
472 * an own mData structure to keep their specific data around.
473 */
474
475 /** Pointer to parent session. Per definition
476 * this objects *always* lives shorter than the
477 * parent. */
478 GuestSession *mSession;
479 /** The object ID -- must be unique for each guest
480 * object and is encoded into the context ID. Must
481 * be set manually when initializing the object.
482 *
483 * For guest processes this is the internal PID,
484 * for guest files this is the internal file ID. */
485 uint32_t mObjectID;
486};
487#endif // ____H_GUESTIMPLPRIVATE
488
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