VirtualBox

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

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

GuestCtrl: More code for guest session infrastructure handling (untested, work in progress).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.8 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 * Base class for a all guest control callbacks/events.
52 */
53class GuestCtrlEvent
54{
55public:
56
57 GuestCtrlEvent(void);
58
59 virtual ~GuestCtrlEvent(void);
60
61 /** @todo Copy/comparison operator? */
62
63public:
64
65 int Cancel(void);
66
67 bool Canceled(void);
68
69 virtual void Destroy(void);
70
71 int Init(void);
72
73 virtual int Signal(int rc = VINF_SUCCESS);
74
75 int GetResultCode(void) { return mRC; }
76
77 int Wait(ULONG uTimeoutMS);
78
79protected:
80
81 /** Was the callback canceled? */
82 bool fCanceled;
83 /** Did the callback complete? */
84 bool fCompleted;
85 /** The event semaphore for triggering
86 * the actual event. */
87 RTSEMEVENT hEventSem;
88 /** The waiting mutex. */
89 RTSEMMUTEX hEventMutex;
90 /** Overall result code. */
91 int mRC;
92};
93
94
95/*
96 * Enumeration holding the host callback types.
97 */
98enum CALLBACKTYPE
99{
100 CALLBACKTYPE_UNKNOWN = 0,
101 /** Guest session status. */
102 CALLBACKTYPE_SESSION_NOTIFY = 10,
103 /** Guest process status. */
104 CALLBACKTYPE_PROC_STATUS = 100,
105 /** Guest process output notification. */
106 CALLBACKTYPE_PROC_OUTPUT = 105,
107 /** Guest process input notification. */
108 CALLBACKTYPE_PROC_INPUT = 106,
109 /** @todo Docs! */
110 CALLBACKTYPE_FILE_OPEN = 210,
111 CALLBACKTYPE_FILE_CLOSE = 215,
112 CALLBACKTYPE_FILE_READ = 230,
113 CALLBACKTYPE_FILE_WRITE = 240,
114 CALLBACKTYPE_FILE_SEEK = 250,
115 CALLBACKTYPE_FILE_TELL = 260
116};
117
118
119/*
120 * Class representing a guest control callback.
121 */
122class GuestCtrlCallback : public GuestCtrlEvent
123{
124
125public:
126
127 GuestCtrlCallback(void);
128
129 GuestCtrlCallback(CALLBACKTYPE enmType);
130
131 virtual ~GuestCtrlCallback(void);
132
133public:
134
135 void Destroy(void);
136
137 int Init(CALLBACKTYPE enmType);
138
139 CALLBACKTYPE GetCallbackType(void) { return mType; }
140
141 const void* GetDataRaw(void) const { return pvData; }
142
143 size_t GetDataSize(void) { return cbData; }
144
145 const void* GetPayloadRaw(void) const { return pvPayload; }
146
147 size_t GetPayloadSize(void) { return cbPayload; }
148
149 int SetData(const void *pvCallback, size_t cbCallback);
150
151 int SetPayload(const void *pvToWrite, size_t cbToWrite);
152
153protected:
154
155 /** Pointer to actual callback data. */
156 void *pvData;
157 /** Size of user-supplied data. */
158 size_t cbData;
159 /** The callback type. */
160 CALLBACKTYPE mType;
161 /** Callback flags. */
162 uint32_t uFlags;
163 /** Payload which will be available on successful
164 * waiting (optional). */
165 void *pvPayload;
166 /** Size of the payload (optional). */
167 size_t cbPayload;
168};
169typedef std::map < uint32_t, GuestCtrlCallback* > GuestCtrlCallbacks;
170
171
172/*
173 * Class representing a guest control process waiting
174 * event.
175 */
176class GuestProcessWaitEvent : public GuestCtrlEvent
177{
178public:
179
180 GuestProcessWaitEvent(void);
181
182 GuestProcessWaitEvent(uint32_t uWaitFlags);
183
184 virtual ~GuestProcessWaitEvent(void);
185
186public:
187
188 void Destroy(void);
189
190 int Init(uint32_t uWaitFlags);
191
192 uint32_t GetWaitFlags(void) { return ASMAtomicReadU32(&mFlags); }
193
194 ProcessWaitResult_T GetWaitResult(void) { return mResult; }
195
196 int GetWaitRc(void) { return mRC; }
197
198 int Signal(ProcessWaitResult_T enmResult, int rc = VINF_SUCCESS);
199
200protected:
201
202 /** The waiting flag(s). The specifies what to
203 * wait for. See ProcessWaitFlag_T. */
204 uint32_t mFlags;
205 /** Structure containing the overall result. */
206 ProcessWaitResult_T mResult;
207};
208
209
210/*
211 * Class representing a guest control session waiting
212 * event.
213 */
214class GuestSessionWaitEvent : public GuestCtrlEvent
215{
216public:
217
218 GuestSessionWaitEvent(void);
219
220 GuestSessionWaitEvent(uint32_t uWaitFlags);
221
222 virtual ~GuestSessionWaitEvent(void);
223
224public:
225
226 void Destroy(void);
227
228 int Init(uint32_t uWaitFlags);
229
230 uint32_t GetWaitFlags(void) { return ASMAtomicReadU32(&mFlags); }
231
232 GuestSessionWaitResult_T GetWaitResult(void) { return mResult; }
233
234 int GetWaitRc(void) { return mRC; }
235
236 int Signal(GuestSessionWaitResult_T enmResult, int rc = VINF_SUCCESS);
237
238protected:
239
240 /** The waiting flag(s). The specifies what to
241 * wait for. See GuestSessionWaitFlag_T. */
242 uint32_t mFlags;
243 /** Structure containing the overall result. */
244 GuestSessionWaitResult_T mResult;
245};
246
247
248/**
249 * Simple structure mantaining guest credentials.
250 */
251struct GuestCredentials
252{
253 Utf8Str mUser;
254 Utf8Str mPassword;
255 Utf8Str mDomain;
256};
257
258
259typedef std::vector <Utf8Str> GuestEnvironmentArray;
260class GuestEnvironment
261{
262public:
263
264 int BuildEnvironmentBlock(void **ppvEnv, size_t *pcbEnv, uint32_t *pcEnvVars);
265
266 void Clear(void);
267
268 int CopyFrom(const GuestEnvironmentArray &environment);
269
270 int CopyTo(GuestEnvironmentArray &environment);
271
272 static void FreeEnvironmentBlock(void *pvEnv);
273
274 Utf8Str Get(const Utf8Str &strKey);
275
276 Utf8Str Get(size_t nPos);
277
278 bool Has(const Utf8Str &strKey);
279
280 int Set(const Utf8Str &strKey, const Utf8Str &strValue);
281
282 int Set(const Utf8Str &strPair);
283
284 size_t Size(void);
285
286 int Unset(const Utf8Str &strKey);
287
288public:
289
290 GuestEnvironment& operator=(const GuestEnvironmentArray &that);
291
292 GuestEnvironment& operator=(const GuestEnvironment &that);
293
294protected:
295
296 int appendToEnvBlock(const char *pszEnv, void **ppvList, size_t *pcbList, uint32_t *pcEnvVars);
297
298protected:
299
300 std::map <Utf8Str, Utf8Str> mEnvironment;
301};
302
303
304/**
305 * Structure for keeping all the relevant guest file
306 * information around.
307 */
308struct GuestFileOpenInfo
309{
310 /** The filename. */
311 Utf8Str mFileName;
312 /** Then file's opening mode. */
313 Utf8Str mOpenMode;
314 /** The file's disposition mode. */
315 Utf8Str mDisposition;
316 /** Octal creation mode. */
317 uint32_t mCreationMode;
318 /** The initial offset on open. */
319 int64_t mInitialOffset;
320};
321
322
323/**
324 * Structure representing information of a
325 * file system object.
326 */
327struct GuestFsObjData
328{
329 /** Helper function to extract the data from
330 * a certin VBoxService tool's guest stream block. */
331 int FromLs(const GuestProcessStreamBlock &strmBlk);
332 int FromStat(const GuestProcessStreamBlock &strmBlk);
333
334 int64_t mAccessTime;
335 int64_t mAllocatedSize;
336 int64_t mBirthTime;
337 int64_t mChangeTime;
338 uint32_t mDeviceNumber;
339 Utf8Str mFileAttrs;
340 uint32_t mGenerationID;
341 uint32_t mGID;
342 Utf8Str mGroupName;
343 uint32_t mNumHardLinks;
344 int64_t mModificationTime;
345 Utf8Str mName;
346 int64_t mNodeID;
347 uint32_t mNodeIDDevice;
348 int64_t mObjectSize;
349 FsObjType_T mType;
350 uint32_t mUID;
351 uint32_t mUserFlags;
352 Utf8Str mUserName;
353 Utf8Str mACL;
354};
355
356
357/**
358 * Structure for keeping all the relevant guest session
359 * startup parameters around.
360 */
361class GuestSessionStartupInfo
362{
363public:
364
365 GuestSessionStartupInfo(void)
366 : mIsInternal(false /* Non-internal session */),
367 mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */),
368 mOpenFlags(0 /* No opening flags set */) { }
369
370 /** The session's friendly name. Optional. */
371 Utf8Str mName;
372 /** The session's unique ID. Used to encode
373 * a context ID. */
374 uint32_t mID;
375 /** Flag indicating if this is an internal session
376 * or not. Internal session are not accessible by
377 * public API clients. */
378 bool mIsInternal;
379 /** Timeout (in ms) used for opening the session. */
380 uint32_t mOpenTimeoutMS;
381 /** Session opening flags. */
382 uint32_t mOpenFlags;
383};
384
385
386/**
387 * Structure for keeping all the relevant guest process
388 * startup parameters around.
389 */
390class GuestProcessStartupInfo
391{
392public:
393
394 GuestProcessStartupInfo(void)
395 : mFlags(ProcessCreateFlag_None),
396 mTimeoutMS(30 * 1000 /* 30s timeout by default */),
397 mPriority(ProcessPriority_Default) { }
398
399 /** The process' friendly name. */
400 Utf8Str mName;
401 /** The actual command to execute. */
402 Utf8Str mCommand;
403 ProcessArguments mArguments;
404 GuestEnvironment mEnvironment;
405 /** Process creation flags. */
406 uint32_t mFlags;
407 ULONG mTimeoutMS;
408 /** Process priority. */
409 ProcessPriority_T mPriority;
410 /** Process affinity. At the moment we
411 * only support 64 VCPUs. API and
412 * guest can do more already! */
413 uint64_t mAffinity;
414};
415
416
417/**
418 * Class representing the "value" side of a "key=value" pair.
419 */
420class GuestProcessStreamValue
421{
422public:
423
424 GuestProcessStreamValue(void) { }
425 GuestProcessStreamValue(const char *pszValue)
426 : mValue(pszValue) {}
427
428 GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
429 : mValue(aThat.mValue) { }
430
431 Utf8Str mValue;
432};
433
434/** Map containing "key=value" pairs of a guest process stream. */
435typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
436typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
437typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
438typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
439
440/**
441 * Class representing a block of stream pairs (key=value). Each block in a raw guest
442 * output stream is separated by "\0\0", each pair is separated by "\0". The overall
443 * end of a guest stream is marked by "\0\0\0\0".
444 */
445class GuestProcessStreamBlock
446{
447public:
448
449 GuestProcessStreamBlock(void);
450
451 virtual ~GuestProcessStreamBlock(void);
452
453public:
454
455 void Clear(void);
456
457#ifdef DEBUG
458 void DumpToLog(void) const;
459#endif
460
461 int GetInt64Ex(const char *pszKey, int64_t *piVal) const;
462
463 int64_t GetInt64(const char *pszKey) const;
464
465 size_t GetCount(void) const;
466
467 const char* GetString(const char *pszKey) const;
468
469 int GetUInt32Ex(const char *pszKey, uint32_t *puVal) const;
470
471 uint32_t GetUInt32(const char *pszKey) const;
472
473 bool IsEmpty(void) { return mPairs.empty(); }
474
475 int SetValue(const char *pszKey, const char *pszValue);
476
477protected:
478
479 GuestCtrlStreamPairMap mPairs;
480};
481
482/** Vector containing multiple allocated stream pair objects. */
483typedef std::vector< GuestProcessStreamBlock > GuestCtrlStreamObjects;
484typedef std::vector< GuestProcessStreamBlock >::iterator GuestCtrlStreamObjectsIter;
485typedef std::vector< GuestProcessStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
486
487/**
488 * Class for parsing machine-readable guest process output by VBoxService'
489 * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
490 */
491class GuestProcessStream
492{
493
494public:
495
496 GuestProcessStream();
497
498 virtual ~GuestProcessStream();
499
500public:
501
502 int AddData(const BYTE *pbData, size_t cbData);
503
504 void Destroy();
505
506#ifdef DEBUG
507 void Dump(const char *pszFile);
508#endif
509
510 uint32_t GetOffset();
511
512 uint32_t GetSize();
513
514 int ParseBlock(GuestProcessStreamBlock &streamBlock);
515
516protected:
517
518 /** Currently allocated size of internal stream buffer. */
519 uint32_t m_cbAllocated;
520 /** Currently used size of allocated internal stream buffer. */
521 uint32_t m_cbSize;
522 /** Current offset within the internal stream buffer. */
523 uint32_t m_cbOffset;
524 /** Internal stream buffer. */
525 BYTE *m_pbBuffer;
526};
527
528class Guest;
529class Progress;
530
531class GuestTask
532{
533
534public:
535
536 enum TaskType
537 {
538 /** Copies a file from host to the guest. */
539 TaskType_CopyFileToGuest = 50,
540 /** Copies a file from guest to the host. */
541 TaskType_CopyFileFromGuest = 55,
542 /** Update Guest Additions by directly copying the required installer
543 * off the .ISO file, transfer it to the guest and execute the installer
544 * with system privileges. */
545 TaskType_UpdateGuestAdditions = 100
546 };
547
548 GuestTask(TaskType aTaskType, Guest *aThat, Progress *aProgress);
549
550 virtual ~GuestTask();
551
552 int startThread();
553
554 static int taskThread(RTTHREAD aThread, void *pvUser);
555 static int uploadProgress(unsigned uPercent, void *pvUser);
556 static HRESULT setProgressSuccess(ComObjPtr<Progress> pProgress);
557 static HRESULT setProgressErrorMsg(HRESULT hr,
558 ComObjPtr<Progress> pProgress, const char * pszText, ...);
559 static HRESULT setProgressErrorParent(HRESULT hr,
560 ComObjPtr<Progress> pProgress, ComObjPtr<Guest> pGuest);
561
562 TaskType taskType;
563 ComObjPtr<Guest> pGuest;
564 ComObjPtr<Progress> pProgress;
565 HRESULT rc;
566
567 /* Task data. */
568 Utf8Str strSource;
569 Utf8Str strDest;
570 Utf8Str strUserName;
571 Utf8Str strPassword;
572 ULONG uFlags;
573};
574
575/**
576 * Pure virtual class (interface) for guest objects (processes, files, ...) --
577 * contains all per-object callback management.
578 */
579class GuestObject
580{
581
582public:
583
584 ULONG getObjectID(void) { return mObject.mObjectID; }
585
586protected:
587
588 /** Callback dispatcher -- must be implemented by the actual object. */
589 virtual int callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) = 0;
590
591protected:
592
593 int bindToSession(Console *pConsole, GuestSession *pSession, uint32_t uObjectID);
594 int callbackAdd(GuestCtrlCallback *pCallback, uint32_t *puContextID);
595 bool callbackExists(uint32_t uContextID);
596 int callbackRemove(uint32_t uContextID);
597 int callbackRemoveAll(void);
598 int sendCommand(uint32_t uFunction, uint32_t uParms, PVBOXHGCMSVCPARM paParms);
599
600protected:
601
602 /**
603 * Commom structure for all derived objects, when then have
604 * an own mData structure to keep their specific data around.
605 */
606 struct Object
607 {
608 /** Pointer to parent session. Per definition
609 * this objects *always* lives shorter than the
610 * parent. */
611 GuestSession *mSession;
612 /** Pointer to the console object. Needed
613 * for HGCM (VMMDev) communication. */
614 Console *mConsole;
615 /** All related callbacks to this object. */
616 GuestCtrlCallbacks mCallbacks;
617 /** The next upcoming context ID for this object. */
618 ULONG mNextContextID;
619 /** The object ID -- must be unique for each guest
620 * session and is encoded into the context ID. Must
621 * be set manually when initializing the object.
622 *
623 * For guest processes this is the internal PID,
624 * for guest files this is the internal file ID. */
625 uint32_t mObjectID;
626 } mObject;
627};
628
629#if 0
630/*
631 * Guest (HGCM) callbacks. All classes will throw
632 * an exception on misuse.
633 */
634
635/** Callback class for guest process status. */
636class GuestCbProcessStatus : public GuestCtrlCallback
637{
638
639public:
640
641 int Init(uint32_t uProtocol, uint32_t uFunction,
642 PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
643 {
644 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
645
646 int rc = GuestCtrlCallback::Init();
647 if (RT_FAILURE(rc))
648 return rc;
649
650 if ( uFunction != GUEST_EXEC_SEND_STATUS
651 || pSvcCb->mParms < 5)
652 return VERR_INVALID_PARAMETER;
653
654 /* pSvcCb->mpaParms[0] always contains the context ID. */
655 pSvcCb->mpaParms[1].getUInt32(&mPID);
656 pSvcCb->mpaParms[2].getUInt32(&mStatus);
657 pSvcCb->mpaParms[3].getUInt32(&mFlags); /* Can contain an IPRT error, which is a signed int. */
658 pSvcCb->mpaParms[4].getPointer(&mData, &mcbData);
659
660 return VINF_SUCCESS;
661 }
662
663 void Destroy(void) { }
664
665 uint32_t mPID;
666 uint32_t mStatus;
667 uint32_t mFlags;
668 void *mData;
669 uint32_t mcbData;
670};
671
672/** Callback class for guest process input. */
673class GuestCbProcessInput : public GuestCtrlCallback
674{
675
676public:
677
678 int Init(uint32_t uProtocol, uint32_t uFunction,
679 PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
680 {
681 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
682
683 int rc = GuestCtrlCallback::Init();
684 if (RT_FAILURE(rc))
685 return rc;
686
687 if ( uFunction != GUEST_EXEC_SEND_INPUT_STATUS
688 || pSvcCb->mParms < 5)
689 return VERR_INVALID_PARAMETER;
690
691 /* pSvcCb->mpaParms[0] always contains the context ID. */
692 pSvcCb->mpaParms[1].getUInt32(&mPID);
693 /* Associated file handle. */
694 pSvcCb->mpaParms[2].getUInt32(&mStatus);
695 pSvcCb->mpaParms[3].getUInt32(&mFlags);
696 pSvcCb->mpaParms[4].getUInt32(&mProcessed);
697
698 return VINF_SUCCESS;
699 }
700
701 void Destroy(void) { }
702
703 GuestCbProcessInput& operator=(const GuestCbProcessInput &that)
704 {
705 mPID = that.mPID;
706 mStatus = that.mStatus;
707 mFlags = that.mFlags;
708 mProcessed = that.mProcessed;
709 return *this;
710 }
711
712 uint32_t mPID;
713 uint32_t mStatus;
714 uint32_t mFlags;
715 uint32_t mProcessed;
716};
717
718/** Callback class for guest process output. */
719class GuestCbProcessOutput : public GuestCtrlCallback
720{
721
722public:
723
724 int Init(uint32_t uProtocol, uint32_t uFunction,
725 PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
726 {
727 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
728
729 int rc = GuestCtrlCallback::Init();
730 if (RT_FAILURE(rc))
731 return rc;
732
733 if ( uFunction != GUEST_EXEC_SEND_OUTPUT
734 || pSvcCb->mParms < 5)
735 return VERR_INVALID_PARAMETER;
736
737 /* pSvcCb->mpaParms[0] always contains the context ID. */
738 pSvcCb->mpaParms[1].getUInt32(&mPID);
739 /* Associated file handle. */
740 pSvcCb->mpaParms[2].getUInt32(&mHandle);
741 pSvcCb->mpaParms[3].getUInt32(&mFlags);
742
743 void *pbData; uint32_t cbData;
744 rc = pSvcCb->mpaParms[4].getPointer(&pbData, &cbData);
745 if (RT_SUCCESS(rc))
746 {
747 Assert(cbData);
748 mData = RTMemAlloc(cbData);
749 AssertPtrReturn(mData, VERR_NO_MEMORY);
750 memcpy(mData, pbData, cbData);
751 mcbData = cbData;
752 }
753
754 return rc;
755 }
756
757 void Destroy(void)
758 {
759 if (mData)
760 {
761 RTMemFree(mData);
762 mData = NULL;
763 mcbData = 0;
764 }
765 }
766
767 GuestCbProcessOutput& operator=(const GuestCbProcessOutput &that)
768 {
769 mPID = that.mPID;
770 mHandle = that.mHandle;
771 mFlags = that.mFlags;
772
773 Destroy();
774 if (that.mcbData)
775 {
776 void *pvData = RTMemAlloc(that.mcbData);
777 if (pvData)
778 {
779 AssertPtr(pvData);
780 memcpy(pvData, that.mData, that.mcbData);
781 mData = pvData;
782 mcbData = that.mcbData;
783 }
784 }
785
786 return *this;
787 }
788
789 uint32_t mPID;
790 uint32_t mHandle;
791 uint32_t mFlags;
792 void *mData;
793 size_t mcbData;
794};
795
796/** Callback class for guest process IO notifications. */
797class GuestCbProcessIO : public GuestCtrlCallback
798{
799
800public:
801
802 int Init(uint32_t uProtocol, uint32_t uFunction,
803 PVBOXGUESTCTRLHOSTCALLBACK pSvcCb)
804 {
805 AssertPtrReturn(pSvcCb, VERR_INVALID_POINTER);
806
807 int rc = GuestCtrlCallback::Init();
808 if (RT_FAILURE(rc))
809 return rc;
810
811 return VERR_NOT_IMPLEMENTED;
812 }
813
814 void Destroy(void) { GuestCtrlCallback::Destroy(); }
815
816 GuestCbProcessIO& operator=(const GuestCbProcessIO &that)
817 {
818 return *this;
819 }
820};
821#endif
822#endif // ____H_GUESTIMPLPRIVATE
823
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