VirtualBox

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

Last change on this file since 51856 was 50618, checked in by vboxsync, 11 years ago

6813 src-client/GuestFileImpl.cpp

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