VirtualBox

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

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

added a couple of missing Id headers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 18.4 KB
Line 
1/* $Id: GuestCtrlImplPrivate.h 55401 2015-04-23 10:03:17Z vboxsync $ */
2/** @file
3 *
4 * Internal helpers/structures for guest control functionality.
5 */
6
7/*
8 * Copyright (C) 2011-2013 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#ifndef ____H_GUESTIMPLPRIVATE
20#define ____H_GUESTIMPLPRIVATE
21
22#include "ConsoleImpl.h"
23
24#include <iprt/asm.h>
25#include <iprt/semaphore.h>
26
27#include <VBox/com/com.h>
28#include <VBox/com/ErrorInfo.h>
29#include <VBox/com/string.h>
30#include <VBox/com/VirtualBox.h>
31
32#include <map>
33#include <vector>
34
35using namespace com;
36
37#ifdef VBOX_WITH_GUEST_CONTROL
38# include <VBox/HostServices/GuestControlSvc.h>
39using namespace guestControl;
40#endif
41
42/** Vector holding a process' CPU affinity. */
43typedef std::vector <LONG> ProcessAffinity;
44/** Vector holding process startup arguments. */
45typedef std::vector <Utf8Str> ProcessArguments;
46
47class GuestProcessStreamBlock;
48class GuestSession;
49
50
51/**
52 * Simple structure mantaining guest credentials.
53 */
54struct GuestCredentials
55{
56 Utf8Str mUser;
57 Utf8Str mPassword;
58 Utf8Str mDomain;
59};
60
61
62typedef std::vector <Utf8Str> GuestEnvironmentArray;
63class GuestEnvironment
64{
65public:
66
67 int BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars);
68
69 void Clear(void);
70
71 int CopyFrom(const GuestEnvironmentArray &environment);
72
73 int CopyTo(GuestEnvironmentArray &environment);
74
75 static void FreeEnvironmentBlock(void *pvEnv);
76
77 Utf8Str Get(const Utf8Str &strKey);
78
79 Utf8Str Get(size_t nPos);
80
81 bool Has(const Utf8Str &strKey);
82
83 int Set(const Utf8Str &strKey, const Utf8Str &strValue);
84
85 int Set(const Utf8Str &strPair);
86
87 size_t Size(void);
88
89 int Unset(const Utf8Str &strKey);
90
91public:
92
93 GuestEnvironment& operator=(const GuestEnvironmentArray &that);
94
95 GuestEnvironment& operator=(const GuestEnvironment &that);
96
97protected:
98
99 int appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars);
100
101protected:
102
103 std::map <Utf8Str, Utf8Str> mEnvironment;
104};
105
106
107/**
108 * Structure for keeping all the relevant guest directory
109 * information around.
110 */
111struct GuestDirectoryOpenInfo
112{
113 /** The directory path. */
114 Utf8Str mPath;
115 /** Then open filter. */
116 Utf8Str mFilter;
117 /** Opening flags. */
118 uint32_t mFlags;
119};
120
121
122/**
123 * Structure for keeping all the relevant guest file
124 * information around.
125 */
126struct GuestFileOpenInfo
127{
128 /** The filename. */
129 Utf8Str mFileName;
130 /** Then file's opening mode. */
131 Utf8Str mOpenMode;
132 /** The file's disposition mode. */
133 Utf8Str mDisposition;
134 /** The file's sharing mode.
135 **@todo Not implemented yet.*/
136 Utf8Str mSharingMode;
137 /** Octal creation mode. */
138 uint32_t mCreationMode;
139 /** The initial offset on open. */
140 uint64_t mInitialOffset;
141};
142
143
144/**
145 * Structure representing information of a
146 * file system object.
147 */
148struct GuestFsObjData
149{
150 /** Helper function to extract the data from
151 * a certin VBoxService tool's guest stream block. */
152 int FromLs(const GuestProcessStreamBlock &strmBlk);
153 int FromMkTemp(const GuestProcessStreamBlock &strmBlk);
154 int FromStat(const GuestProcessStreamBlock &strmBlk);
155
156 int64_t mAccessTime;
157 int64_t mAllocatedSize;
158 int64_t mBirthTime;
159 int64_t mChangeTime;
160 uint32_t mDeviceNumber;
161 Utf8Str mFileAttrs;
162 uint32_t mGenerationID;
163 uint32_t mGID;
164 Utf8Str mGroupName;
165 uint32_t mNumHardLinks;
166 int64_t mModificationTime;
167 Utf8Str mName;
168 int64_t mNodeID;
169 uint32_t mNodeIDDevice;
170 int64_t mObjectSize;
171 FsObjType_T mType;
172 uint32_t mUID;
173 uint32_t mUserFlags;
174 Utf8Str mUserName;
175 Utf8Str mACL;
176};
177
178
179/**
180 * Structure for keeping all the relevant guest session
181 * startup parameters around.
182 */
183class GuestSessionStartupInfo
184{
185public:
186
187 GuestSessionStartupInfo(void)
188 : mIsInternal(false /* Non-internal session */),
189 mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */),
190 mOpenFlags(0 /* No opening flags set */) { }
191
192 /** The session's friendly name. Optional. */
193 Utf8Str mName;
194 /** The session's unique ID. Used to encode
195 * a context ID. */
196 uint32_t mID;
197 /** Flag indicating if this is an internal session
198 * or not. Internal session are not accessible by
199 * public API clients. */
200 bool mIsInternal;
201 /** Timeout (in ms) used for opening the session. */
202 uint32_t mOpenTimeoutMS;
203 /** Session opening flags. */
204 uint32_t mOpenFlags;
205};
206
207
208/**
209 * Structure for keeping all the relevant guest process
210 * startup parameters around.
211 */
212class GuestProcessStartupInfo
213{
214public:
215
216 GuestProcessStartupInfo(void)
217 : mFlags(ProcessCreateFlag_None),
218 mTimeoutMS(30 * 1000 /* 30s timeout by default */),
219 mPriority(ProcessPriority_Default) { }
220
221 /** The process' friendly name. */
222 Utf8Str mName;
223 /** The actual command to execute. */
224 Utf8Str mCommand;
225 ProcessArguments mArguments;
226 GuestEnvironment mEnvironment;
227 /** Process creation flags. */
228 uint32_t mFlags;
229 ULONG mTimeoutMS;
230 /** Process priority. */
231 ProcessPriority_T mPriority;
232 /** Process affinity. At the moment we
233 * only support 64 VCPUs. API and
234 * guest can do more already! */
235 uint64_t mAffinity;
236};
237
238
239/**
240 * Class representing the "value" side of a "key=value" pair.
241 */
242class GuestProcessStreamValue
243{
244public:
245
246 GuestProcessStreamValue(void) { }
247 GuestProcessStreamValue(const char *pszValue)
248 : mValue(pszValue) {}
249
250 GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
251 : mValue(aThat.mValue) { }
252
253 Utf8Str mValue;
254};
255
256/** Map containing "key=value" pairs of a guest process stream. */
257typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
258typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
259typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
260typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
261
262/**
263 * Class representing a block of stream pairs (key=value). Each block in a raw guest
264 * output stream is separated by "\0\0", each pair is separated by "\0". The overall
265 * end of a guest stream is marked by "\0\0\0\0".
266 */
267class GuestProcessStreamBlock
268{
269public:
270
271 GuestProcessStreamBlock(void);
272
273 virtual ~GuestProcessStreamBlock(void);
274
275public:
276
277 void Clear(void);
278
279#ifdef DEBUG
280 void DumpToLog(void) const;
281#endif
282
283 int GetInt64Ex(const char *pszKey, int64_t *piVal) const;
284
285 int64_t GetInt64(const char *pszKey) const;
286
287 size_t GetCount(void) const;
288
289 int GetRc(void) const;
290
291 const char* GetString(const char *pszKey) const;
292
293 int GetUInt32Ex(const char *pszKey, uint32_t *puVal) const;
294
295 uint32_t GetUInt32(const char *pszKey) const;
296
297 bool IsEmpty(void) { return mPairs.empty(); }
298
299 int SetValue(const char *pszKey, const char *pszValue);
300
301protected:
302
303 GuestCtrlStreamPairMap mPairs;
304};
305
306/** Vector containing multiple allocated stream pair objects. */
307typedef std::vector< GuestProcessStreamBlock > GuestCtrlStreamObjects;
308typedef std::vector< GuestProcessStreamBlock >::iterator GuestCtrlStreamObjectsIter;
309typedef std::vector< GuestProcessStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
310
311/**
312 * Class for parsing machine-readable guest process output by VBoxService'
313 * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
314 */
315class GuestProcessStream
316{
317
318public:
319
320 GuestProcessStream();
321
322 virtual ~GuestProcessStream();
323
324public:
325
326 int AddData(const BYTE *pbData, size_t cbData);
327
328 void Destroy();
329
330#ifdef DEBUG
331 void Dump(const char *pszFile);
332#endif
333
334 uint32_t GetOffset() { return m_cbOffset; }
335
336 size_t GetSize() { return m_cbSize; }
337
338 int ParseBlock(GuestProcessStreamBlock &streamBlock);
339
340protected:
341
342 /** Currently allocated size of internal stream buffer. */
343 uint32_t m_cbAllocated;
344 /** Currently used size of allocated internal stream buffer. */
345 size_t m_cbSize;
346 /** Current offset within the internal stream buffer. */
347 uint32_t m_cbOffset;
348 /** Internal stream buffer. */
349 BYTE *m_pbBuffer;
350};
351
352class Guest;
353class Progress;
354
355class GuestTask
356{
357
358public:
359
360 enum TaskType
361 {
362 /** Copies a file from host to the guest. */
363 TaskType_CopyFileToGuest = 50,
364 /** Copies a file from guest to the host. */
365 TaskType_CopyFileFromGuest = 55,
366 /** Update Guest Additions by directly copying the required installer
367 * off the .ISO file, transfer it to the guest and execute the installer
368 * with system privileges. */
369 TaskType_UpdateGuestAdditions = 100
370 };
371
372 GuestTask(TaskType aTaskType, Guest *aThat, Progress *aProgress);
373
374 virtual ~GuestTask();
375
376 int startThread();
377
378 static int taskThread(RTTHREAD aThread, void *pvUser);
379 static int uploadProgress(unsigned uPercent, void *pvUser);
380 static HRESULT setProgressSuccess(ComObjPtr<Progress> pProgress);
381 static HRESULT setProgressErrorMsg(HRESULT hr,
382 ComObjPtr<Progress> pProgress, const char * pszText, ...);
383 static HRESULT setProgressErrorParent(HRESULT hr,
384 ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest);
385
386 TaskType taskType;
387 ComObjPtr<Guest> pGuest;
388 ComObjPtr<Progress> pProgress;
389 HRESULT rc;
390
391 /* Task data. */
392 Utf8Str strSource;
393 Utf8Str strDest;
394 Utf8Str strUserName;
395 Utf8Str strPassword;
396 ULONG uFlags;
397};
398
399class GuestWaitEventPayload
400{
401
402public:
403
404 GuestWaitEventPayload(void)
405 : uType(0),
406 cbData(0),
407 pvData(NULL) { }
408
409 GuestWaitEventPayload(uint32_t uTypePayload,
410 const void *pvPayload, uint32_t cbPayload)
411 {
412 if (cbPayload)
413 {
414 pvData = RTMemAlloc(cbPayload);
415 if (pvData)
416 {
417 uType = uTypePayload;
418
419 memcpy(pvData, pvPayload, cbPayload);
420 cbData = cbPayload;
421 }
422 else /* Throw IPRT error. */
423 throw VERR_NO_MEMORY;
424 }
425 else
426 {
427 uType = uTypePayload;
428
429 pvData = NULL;
430 cbData = 0;
431 }
432 }
433
434 virtual ~GuestWaitEventPayload(void)
435 {
436 Clear();
437 }
438
439 GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that)
440 {
441 CopyFromDeep(that);
442 return *this;
443 }
444
445public:
446
447 void Clear(void)
448 {
449 if (pvData)
450 {
451 RTMemFree(pvData);
452 cbData = 0;
453 }
454 uType = 0;
455 }
456
457 int CopyFromDeep(const GuestWaitEventPayload &payload)
458 {
459 Clear();
460
461 int rc = VINF_SUCCESS;
462 if (payload.cbData)
463 {
464 Assert(payload.cbData);
465 pvData = RTMemAlloc(payload.cbData);
466 if (pvData)
467 {
468 memcpy(pvData, payload.pvData, payload.cbData);
469 cbData = payload.cbData;
470 uType = payload.uType;
471 }
472 else
473 rc = VERR_NO_MEMORY;
474 }
475
476 return rc;
477 }
478
479 const void* Raw(void) const { return pvData; }
480
481 size_t Size(void) const { return cbData; }
482
483 uint32_t Type(void) const { return uType; }
484
485 void* MutableRaw(void) { return pvData; }
486
487protected:
488
489 /** Type of payload. */
490 uint32_t uType;
491 /** Size (in bytes) of payload. */
492 uint32_t cbData;
493 /** Pointer to actual payload data. */
494 void *pvData;
495};
496
497class GuestWaitEventBase
498{
499
500protected:
501
502 GuestWaitEventBase(void);
503 virtual ~GuestWaitEventBase(void);
504
505public:
506
507 uint32_t ContextID(void) { return mCID; };
508 int GuestResult(void) { return mGuestRc; }
509 int Result(void) { return mRc; }
510 GuestWaitEventPayload & Payload(void) { return mPayload; }
511 int SignalInternal(int rc, int guestRc, const GuestWaitEventPayload *pPayload);
512 int Wait(RTMSINTERVAL uTimeoutMS);
513
514protected:
515
516 int Init(uint32_t uCID);
517
518protected:
519
520 /* Shutdown indicator. */
521 bool mfAborted;
522 /* Associated context ID (CID). */
523 uint32_t mCID;
524 /** The event semaphore for triggering
525 * the actual event. */
526 RTSEMEVENT mEventSem;
527 /** The event's overall result. If
528 * set to VERR_GSTCTL_GUEST_ERROR,
529 * mGuestRc will contain the actual
530 * error code from the guest side. */
531 int mRc;
532 /** The event'S overall result from the
533 * guest side. If used, mRc must be
534 * set to VERR_GSTCTL_GUEST_ERROR. */
535 int mGuestRc;
536 /** The event's payload data. Optional. */
537 GuestWaitEventPayload mPayload;
538};
539
540/** List of public guest event types. */
541typedef std::list < VBoxEventType_T > GuestEventTypes;
542
543class GuestWaitEvent : public GuestWaitEventBase
544{
545
546public:
547
548 GuestWaitEvent(uint32_t uCID);
549 GuestWaitEvent(uint32_t uCID, const GuestEventTypes &lstEvents);
550 virtual ~GuestWaitEvent(void);
551
552public:
553
554 int Cancel(void);
555 const ComPtr<IEvent> Event(void) { return mEvent; }
556 int SignalExternal(IEvent *pEvent);
557 const GuestEventTypes Types(void) { return mEventTypes; }
558 size_t TypeCount(void) { return mEventTypes.size(); }
559
560protected:
561
562 int Init(uint32_t uCID);
563
564protected:
565
566 /** List of public event types this event should
567 * be signalled on. Optional. */
568 GuestEventTypes mEventTypes;
569 /** Pointer to the actual public event, if any. */
570 ComPtr<IEvent> mEvent;
571};
572/** Map of pointers to guest events. The primary key
573 * contains the context ID. */
574typedef std::map < uint32_t, GuestWaitEvent* > GuestWaitEvents;
575/** Map of wait events per public guest event. Nice for
576 * faster lookups when signalling a whole event group. */
577typedef std::map < VBoxEventType_T, GuestWaitEvents > GuestEventGroup;
578
579class GuestBase
580{
581
582public:
583
584 GuestBase(void);
585 virtual ~GuestBase(void);
586
587public:
588
589 /** Signals a wait event using a public guest event; also used for
590 * for external event listeners. */
591 int signalWaitEvent(VBoxEventType_T aType, IEvent *aEvent);
592 /** Signals a wait event using a guest rc. */
593 int signalWaitEventInternal(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int guestRc, const GuestWaitEventPayload *pPayload);
594 /** Signals a wait event without letting public guest events know,
595 * extended director's cut version. */
596 int signalWaitEventInternalEx(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int rc, int guestRc, const GuestWaitEventPayload *pPayload);
597public:
598
599 int baseInit(void);
600 void baseUninit(void);
601 int cancelWaitEvents(void);
602 int dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
603 int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID);
604 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent);
605 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
606 void unregisterWaitEvent(GuestWaitEvent *pEvent);
607 int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent);
608
609protected:
610
611 /** Pointer to the console object. Needed
612 * for HGCM (VMMDev) communication. */
613 Console *mConsole;
614 /** The next upcoming context ID for this object. */
615 uint32_t mNextContextID;
616 /** Local listener for handling the waiting events
617 * internally. */
618 ComPtr<IEventListener> mLocalListener;
619 /** Critical section for wait events access. */
620 RTCRITSECT mWaitEventCritSect;
621 /** Map of registered wait events per event group. */
622 GuestEventGroup mWaitEventGroups;
623 /** Map of registered wait events. */
624 GuestWaitEvents mWaitEvents;
625};
626
627/**
628 * Virtual class (interface) for guest objects (processes, files, ...) --
629 * contains all per-object callback management.
630 */
631class GuestObject : public GuestBase
632{
633
634public:
635
636 GuestObject(void);
637 virtual ~GuestObject(void);
638
639public:
640
641 ULONG getObjectID(void) { return mObjectID; }
642
643protected:
644
645 virtual int i_onRemove(void) = 0;
646
647 /** Callback dispatcher -- must be implemented by the actual object. */
648 virtual int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) = 0;
649
650protected:
651
652 int bindToSession(Console *pConsole, GuestSession *pSession, uint32_t uObjectID);
653 int registerWaitEvent(const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
654 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
655
656protected:
657
658 /**
659 * Commom parameters for all derived objects, when then have
660 * an own mData structure to keep their specific data around.
661 */
662
663 /** Pointer to parent session. Per definition
664 * this objects *always* lives shorter than the
665 * parent. */
666 GuestSession *mSession;
667 /** The object ID -- must be unique for each guest
668 * object and is encoded into the context ID. Must
669 * be set manually when initializing the object.
670 *
671 * For guest processes this is the internal PID,
672 * for guest files this is the internal file ID. */
673 uint32_t mObjectID;
674};
675#endif // ____H_GUESTIMPLPRIVATE
676
Note: See TracBrowser for help on using the repository browser.

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