VirtualBox

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

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

Guest Control:

  • Implemented IGuestSession::DirectoryRemove, IGuestSession::DirectoryRemoveRecursive, IGuestSession::DirectoryRename + IGuestSession::FileRename.
  • Added appropriate commands to VBoxManage (basic support for now).
  • Implemented support for proper guest session process termination via SCM.
  • Implemented support for internal anonymous wait events which are not relying on the public API's VBoxEventType_T.
  • Various bugfixes.
  • 屬性 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;
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 else
472 rc = VINF_SUCCESS;
473
474 return rc;
475 }
476
477 const void* Raw(void) const { return pvData; }
478
479 size_t Size(void) const { return cbData; }
480
481 uint32_t Type(void) const { return uType; }
482
483 void* MutableRaw(void) { return pvData; }
484
485protected:
486
487 /** Type of payload. */
488 uint32_t uType;
489 /** Size (in bytes) of payload. */
490 uint32_t cbData;
491 /** Pointer to actual payload data. */
492 void *pvData;
493};
494
495class GuestWaitEventBase
496{
497
498protected:
499
500 GuestWaitEventBase(void);
501 virtual ~GuestWaitEventBase(void);
502
503public:
504
505 uint32_t ContextID(void) { return mCID; };
506 int GuestResult(void) { return mGuestRc; }
507 int Result(void) { return mRc; }
508 GuestWaitEventPayload & Payload(void) { return mPayload; }
509 int SignalInternal(int rc, int guestRc, const GuestWaitEventPayload *pPayload);
510 int Wait(RTMSINTERVAL uTimeoutMS);
511
512protected:
513
514 int Init(uint32_t uCID);
515
516protected:
517
518 /* Shutdown indicator. */
519 bool mfAborted;
520 /* Associated context ID (CID). */
521 uint32_t mCID;
522 /** The event semaphore for triggering
523 * the actual event. */
524 RTSEMEVENT mEventSem;
525 /** The event's overall result. If
526 * set to VERR_GSTCTL_GUEST_ERROR,
527 * mGuestRc will contain the actual
528 * error code from the guest side. */
529 int mRc;
530 /** The event'S overall result from the
531 * guest side. If used, mRc must be
532 * set to VERR_GSTCTL_GUEST_ERROR. */
533 int mGuestRc;
534 /** The event's payload data. Optional. */
535 GuestWaitEventPayload mPayload;
536};
537
538/** List of public guest event types. */
539typedef std::list < VBoxEventType_T > GuestEventTypes;
540
541class GuestWaitEvent : public GuestWaitEventBase
542{
543
544public:
545
546 GuestWaitEvent(uint32_t uCID);
547 GuestWaitEvent(uint32_t uCID, const GuestEventTypes &lstEvents);
548 virtual ~GuestWaitEvent(void);
549
550public:
551
552 int Cancel(void);
553 const ComPtr<IEvent> Event(void) { return mEvent; }
554 int SignalExternal(IEvent *pEvent);
555 const GuestEventTypes Types(void) { return mEventTypes; }
556 size_t TypeCount(void) { return mEventTypes.size(); }
557
558protected:
559
560 int Init(uint32_t uCID);
561
562protected:
563
564 /** List of public event types this event should
565 * be signalled on. Optional. */
566 GuestEventTypes mEventTypes;
567 /** Pointer to the actual public event, if any. */
568 ComPtr<IEvent> mEvent;
569};
570/** Map of pointers to guest events. The primary key
571 * contains the context ID. */
572typedef std::map < uint32_t, GuestWaitEvent* > GuestWaitEvents;
573/** Map of wait events per public guest event. Nice for
574 * faster lookups when signalling a whole event group. */
575typedef std::map < VBoxEventType_T, GuestWaitEvents > GuestEventGroup;
576
577class GuestBase
578{
579
580public:
581
582 GuestBase(void);
583 virtual ~GuestBase(void);
584
585public:
586
587 /** Signals a wait event using a public guest event; also used for
588 * for external event listeners. */
589 int signalWaitEvent(VBoxEventType_T aType, IEvent *aEvent);
590 /** Signals a wait event using a guest rc. */
591 int signalWaitEventInternal(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int guestRc, const GuestWaitEventPayload *pPayload);
592 /** Signals a wait event without letting public guest events know,
593 * extended director's cut version. */
594 int signalWaitEventInternalEx(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int rc, int guestRc, const GuestWaitEventPayload *pPayload);
595public:
596
597 int baseInit(void);
598 void baseUninit(void);
599 int cancelWaitEvents(void);
600 int dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
601 int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID);
602 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent);
603 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
604 void unregisterWaitEvent(GuestWaitEvent *pEvent);
605 int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent);
606
607protected:
608
609 /** Pointer to the console object. Needed
610 * for HGCM (VMMDev) communication. */
611 Console *mConsole;
612 /** The next upcoming context ID for this object. */
613 uint32_t mNextContextID;
614 /** Local listener for handling the waiting events
615 * internally. */
616 ComPtr<IEventListener> mLocalListener;
617 /** Critical section for wait events access. */
618 RTCRITSECT mWaitEventCritSect;
619 /** Map of registered wait events per event group. */
620 GuestEventGroup mWaitEventGroups;
621 /** Map of registered wait events. */
622 GuestWaitEvents mWaitEvents;
623};
624
625/**
626 * Virtual class (interface) for guest objects (processes, files, ...) --
627 * contains all per-object callback management.
628 */
629class GuestObject : public GuestBase
630{
631
632public:
633
634 GuestObject(void);
635 virtual ~GuestObject(void);
636
637public:
638
639 ULONG getObjectID(void) { return mObjectID; }
640
641protected:
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