VirtualBox

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

最後變更 在這個檔案從49504是 49504,由 vboxsync 提交於 11 年 前

Main/GuestCtrl: Reference counting bugfixes, handle more directoryCreate errors.

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

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