VirtualBox

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

Last change on this file since 102608 was 99740, checked in by vboxsync, 13 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void). [scm fixes]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 53.2 KB
Line 
1/* $Id: GuestCtrlImplPrivate.h 99740 2023-05-11 01:11:15Z vboxsync $ */
2/** @file
3 * Internal helpers/structures for guest control functionality.
4 */
5
6/*
7 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef MAIN_INCLUDED_GuestCtrlImplPrivate_h
29#define MAIN_INCLUDED_GuestCtrlImplPrivate_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include "ConsoleImpl.h"
35#include "Global.h"
36
37#include <iprt/asm.h>
38#include <iprt/env.h>
39#include <iprt/semaphore.h>
40#include <iprt/cpp/utils.h>
41
42#include <VBox/com/com.h>
43#include <VBox/com/ErrorInfo.h>
44#include <VBox/com/string.h>
45#include <VBox/com/VirtualBox.h>
46#include <VBox/err.h> /* VERR_GSTCTL_GUEST_ERROR */
47
48#include <map>
49#include <vector>
50
51using namespace com;
52
53#ifdef VBOX_WITH_GUEST_CONTROL
54# include <VBox/GuestHost/GuestControl.h>
55# include <VBox/HostServices/GuestControlSvc.h>
56using namespace guestControl;
57#endif
58
59/** Vector holding a process' CPU affinity. */
60typedef std::vector<LONG> ProcessAffinity;
61/** Vector holding process startup arguments. */
62typedef std::vector<Utf8Str> ProcessArguments;
63
64class GuestToolboxStreamBlock;
65class GuestSession;
66
67
68/**
69 * Simple structure mantaining guest credentials.
70 */
71struct GuestCredentials
72{
73 Utf8Str mUser;
74 Utf8Str mPassword;
75 Utf8Str mDomain;
76};
77
78
79/**
80 * Wrapper around the RTEnv API, unusable base class.
81 *
82 * @remarks Feel free to elevate this class to iprt/cpp/env.h as RTCEnv.
83 */
84class GuestEnvironmentBase
85{
86public:
87 /**
88 * Default constructor.
89 *
90 * The user must invoke one of the init methods before using the object.
91 */
92 GuestEnvironmentBase(void)
93 : m_hEnv(NIL_RTENV)
94 , m_cRefs(1)
95 , m_fFlags(0)
96 { }
97
98 /**
99 * Destructor.
100 */
101 virtual ~GuestEnvironmentBase(void)
102 {
103 Assert(m_cRefs <= 1);
104 int vrc = RTEnvDestroy(m_hEnv); AssertRC(vrc);
105 m_hEnv = NIL_RTENV;
106 }
107
108 /**
109 * Retains a reference to this object.
110 * @returns New reference count.
111 * @remarks Sharing an object is currently only safe if no changes are made to
112 * it because RTENV does not yet implement any locking. For the only
113 * purpose we need this, implementing IGuestProcess::environment by
114 * using IGuestSession::environmentBase, that's fine as the session
115 * base environment is immutable.
116 */
117 uint32_t retain(void)
118 {
119 uint32_t cRefs = ASMAtomicIncU32(&m_cRefs);
120 Assert(cRefs > 1); Assert(cRefs < _1M);
121 return cRefs;
122
123 }
124 /** Useful shortcut. */
125 uint32_t retainConst(void) const { return unconst(this)->retain(); }
126
127 /**
128 * Releases a reference to this object, deleting the object when reaching zero.
129 * @returns New reference count.
130 */
131 uint32_t release(void)
132 {
133 uint32_t cRefs = ASMAtomicDecU32(&m_cRefs);
134 Assert(cRefs < _1M);
135 if (cRefs == 0)
136 delete this;
137 return cRefs;
138 }
139
140 /** Useful shortcut. */
141 uint32_t releaseConst(void) const { return unconst(this)->retain(); }
142
143 /**
144 * Checks if the environment has been successfully initialized or not.
145 *
146 * @returns @c true if initialized, @c false if not.
147 */
148 bool isInitialized(void) const
149 {
150 return m_hEnv != NIL_RTENV;
151 }
152
153 /**
154 * Returns the variable count.
155 * @return Number of variables.
156 * @sa RTEnvCountEx
157 */
158 uint32_t count(void) const
159 {
160 return RTEnvCountEx(m_hEnv);
161 }
162
163 /**
164 * Deletes the environment change record entirely.
165 *
166 * The count() method will return zero after this call.
167 *
168 * @sa RTEnvReset
169 */
170 void reset(void)
171 {
172 int vrc = RTEnvReset(m_hEnv);
173 AssertRC(vrc);
174 }
175
176 /**
177 * Exports the environment change block as an array of putenv style strings.
178 *
179 *
180 * @returns VINF_SUCCESS or VERR_NO_MEMORY.
181 * @param pArray The output array.
182 */
183 int queryPutEnvArray(std::vector<com::Utf8Str> *pArray) const
184 {
185 uint32_t cVars = RTEnvCountEx(m_hEnv);
186 try
187 {
188 pArray->resize(cVars);
189 for (uint32_t iVar = 0; iVar < cVars; iVar++)
190 {
191 const char *psz = RTEnvGetByIndexRawEx(m_hEnv, iVar);
192 AssertReturn(psz, VERR_INTERNAL_ERROR_3); /* someone is racing us! */
193 (*pArray)[iVar] = psz;
194 }
195 return VINF_SUCCESS;
196 }
197 catch (std::bad_alloc &)
198 {
199 return VERR_NO_MEMORY;
200 }
201 }
202
203 /**
204 * Applies an array of putenv style strings.
205 *
206 * @returns IPRT status code.
207 * @param rArray The array with the putenv style strings.
208 * @param pidxError Where to return the index causing trouble on
209 * failure. Optional.
210 * @sa RTEnvPutEx
211 */
212 int applyPutEnvArray(const std::vector<com::Utf8Str> &rArray, size_t *pidxError = NULL)
213 {
214 size_t const cArray = rArray.size();
215 for (size_t i = 0; i < cArray; i++)
216 {
217 int vrc = RTEnvPutEx(m_hEnv, rArray[i].c_str());
218 if (RT_FAILURE(vrc))
219 {
220 if (pidxError)
221 *pidxError = i;
222 return vrc;
223 }
224 }
225 return VINF_SUCCESS;
226 }
227
228 /**
229 * Applies the changes from another environment to this.
230 *
231 * @returns IPRT status code.
232 * @param rChanges Reference to an environment which variables will be
233 * imported and, if it's a change record, schedule
234 * variable unsets will be applied.
235 * @sa RTEnvApplyChanges
236 */
237 int applyChanges(const GuestEnvironmentBase &rChanges)
238 {
239 return RTEnvApplyChanges(m_hEnv, rChanges.m_hEnv);
240 }
241
242 /**
243 * See RTEnvQueryUtf8Block for details.
244 * @returns IPRT status code.
245 * @param ppszzBlock Where to return the block pointer.
246 * @param pcbBlock Where to optionally return the block size.
247 * @sa RTEnvQueryUtf8Block
248 */
249 int queryUtf8Block(char **ppszzBlock, size_t *pcbBlock)
250 {
251 return RTEnvQueryUtf8Block(m_hEnv, true /*fSorted*/, ppszzBlock, pcbBlock);
252 }
253
254 /**
255 * Frees what queryUtf8Block returned, NULL ignored.
256 * @sa RTEnvFreeUtf8Block
257 */
258 static void freeUtf8Block(char *pszzBlock)
259 {
260 return RTEnvFreeUtf8Block(pszzBlock);
261 }
262
263 /**
264 * Applies a block on the format returned by queryUtf8Block.
265 *
266 * @returns IPRT status code.
267 * @param pszzBlock Pointer to the block.
268 * @param cbBlock The size of the block.
269 * @param fNoEqualMeansUnset Whether the lack of a '=' (equal) sign in a
270 * string means it should be unset (@c true), or if
271 * it means the variable should be defined with an
272 * empty value (@c false, the default).
273 * @todo move this to RTEnv!
274 */
275 int copyUtf8Block(const char *pszzBlock, size_t cbBlock, bool fNoEqualMeansUnset = false)
276 {
277 int vrc = VINF_SUCCESS;
278 while (cbBlock > 0 && *pszzBlock != '\0')
279 {
280 const char *pszEnd = (const char *)memchr(pszzBlock, '\0', cbBlock);
281 if (!pszEnd)
282 return VERR_BUFFER_UNDERFLOW;
283 int vrc2;
284 if (fNoEqualMeansUnset || strchr(pszzBlock, '='))
285 vrc2 = RTEnvPutEx(m_hEnv, pszzBlock);
286 else
287 vrc2 = RTEnvSetEx(m_hEnv, pszzBlock, "");
288 if (RT_FAILURE(vrc2) && RT_SUCCESS(vrc))
289 vrc = vrc2;
290
291 /* Advance. */
292 cbBlock -= pszEnd - pszzBlock;
293 if (cbBlock < 2)
294 return VERR_BUFFER_UNDERFLOW;
295 cbBlock--;
296 pszzBlock = pszEnd + 1;
297 }
298
299 /* The remainder must be zero padded. */
300 if (RT_SUCCESS(vrc))
301 {
302 if (ASMMemIsZero(pszzBlock, cbBlock))
303 return VINF_SUCCESS;
304 return VERR_TOO_MUCH_DATA;
305 }
306 return vrc;
307 }
308
309 /**
310 * Get an environment variable.
311 *
312 * @returns IPRT status code.
313 * @param rName The variable name.
314 * @param pValue Where to return the value.
315 * @sa RTEnvGetEx
316 */
317 int getVariable(const com::Utf8Str &rName, com::Utf8Str *pValue) const
318 {
319 size_t cchNeeded;
320 int vrc = RTEnvGetEx(m_hEnv, rName.c_str(), NULL, 0, &cchNeeded);
321 if ( RT_SUCCESS(vrc)
322 || vrc == VERR_BUFFER_OVERFLOW)
323 {
324 try
325 {
326 pValue->reserve(cchNeeded + 1);
327 vrc = RTEnvGetEx(m_hEnv, rName.c_str(), pValue->mutableRaw(), pValue->capacity(), NULL);
328 pValue->jolt();
329 }
330 catch (std::bad_alloc &)
331 {
332 vrc = VERR_NO_STR_MEMORY;
333 }
334 }
335 return vrc;
336 }
337
338 /**
339 * Checks if the given variable exists.
340 *
341 * @returns @c true if it exists, @c false if not or if it's an scheduled unset
342 * in a environment change record.
343 * @param rName The variable name.
344 * @sa RTEnvExistEx
345 */
346 bool doesVariableExist(const com::Utf8Str &rName) const
347 {
348 return RTEnvExistEx(m_hEnv, rName.c_str());
349 }
350
351 /**
352 * Set an environment variable.
353 *
354 * @returns IPRT status code.
355 * @param rName The variable name.
356 * @param rValue The value of the variable.
357 * @sa RTEnvSetEx
358 */
359 int setVariable(const com::Utf8Str &rName, const com::Utf8Str &rValue)
360 {
361 return RTEnvSetEx(m_hEnv, rName.c_str(), rValue.c_str());
362 }
363
364 /**
365 * Unset an environment variable.
366 *
367 * @returns IPRT status code.
368 * @param rName The variable name.
369 * @sa RTEnvUnsetEx
370 */
371 int unsetVariable(const com::Utf8Str &rName)
372 {
373 return RTEnvUnsetEx(m_hEnv, rName.c_str());
374 }
375
376protected:
377 /**
378 * Copy constructor.
379 * @throws HRESULT
380 */
381 GuestEnvironmentBase(const GuestEnvironmentBase &rThat, bool fChangeRecord, uint32_t fFlags = 0)
382 : m_hEnv(NIL_RTENV)
383 , m_cRefs(1)
384 , m_fFlags(fFlags)
385 {
386 int vrc = cloneCommon(rThat, fChangeRecord);
387 if (RT_FAILURE(vrc))
388 throw Global::vboxStatusCodeToCOM(vrc);
389 }
390
391 /**
392 * Common clone/copy method with type conversion abilities.
393 *
394 * @returns IPRT status code.
395 * @param rThat The object to clone.
396 * @param fChangeRecord Whether the this instance is a change record (true)
397 * or normal (false) environment.
398 */
399 int cloneCommon(const GuestEnvironmentBase &rThat, bool fChangeRecord)
400 {
401 int vrc = VINF_SUCCESS;
402 RTENV hNewEnv = NIL_RTENV;
403 if (rThat.m_hEnv != NIL_RTENV)
404 {
405 /*
406 * Clone it.
407 */
408 if (RTEnvIsChangeRecord(rThat.m_hEnv) == fChangeRecord)
409 vrc = RTEnvClone(&hNewEnv, rThat.m_hEnv);
410 else
411 {
412 /* Need to type convert it. */
413 if (fChangeRecord)
414 vrc = RTEnvCreateChangeRecordEx(&hNewEnv, rThat.m_fFlags);
415 else
416 vrc = RTEnvCreateEx(&hNewEnv, rThat.m_fFlags);
417 if (RT_SUCCESS(vrc))
418 {
419 vrc = RTEnvApplyChanges(hNewEnv, rThat.m_hEnv);
420 if (RT_FAILURE(vrc))
421 RTEnvDestroy(hNewEnv);
422 }
423 }
424 }
425 else
426 {
427 /*
428 * Create an empty one so the object works smoothly.
429 * (Relevant for GuestProcessStartupInfo and internal commands.)
430 */
431 if (fChangeRecord)
432 vrc = RTEnvCreateChangeRecordEx(&hNewEnv, rThat.m_fFlags);
433 else
434 vrc = RTEnvCreateEx(&hNewEnv, rThat.m_fFlags);
435 }
436 if (RT_SUCCESS(vrc))
437 {
438 RTEnvDestroy(m_hEnv);
439 m_hEnv = hNewEnv;
440 m_fFlags = rThat.m_fFlags;
441 }
442 return vrc;
443 }
444
445
446 /** The environment change record. */
447 RTENV m_hEnv;
448 /** Reference counter. */
449 uint32_t volatile m_cRefs;
450 /** RTENV_CREATE_F_XXX. */
451 uint32_t m_fFlags;
452};
453
454class GuestEnvironmentChanges;
455
456
457/**
458 * Wrapper around the RTEnv API for a normal environment.
459 */
460class GuestEnvironment : public GuestEnvironmentBase
461{
462public:
463 /**
464 * Default constructor.
465 *
466 * The user must invoke one of the init methods before using the object.
467 */
468 GuestEnvironment(void)
469 : GuestEnvironmentBase()
470 { }
471
472 /**
473 * Copy operator.
474 * @param rThat The object to copy.
475 * @throws HRESULT
476 */
477 GuestEnvironment(const GuestEnvironment &rThat)
478 : GuestEnvironmentBase(rThat, false /*fChangeRecord*/)
479 { }
480
481 /**
482 * Copy operator.
483 * @param rThat The object to copy.
484 * @throws HRESULT
485 */
486 GuestEnvironment(const GuestEnvironmentBase &rThat)
487 : GuestEnvironmentBase(rThat, false /*fChangeRecord*/)
488 { }
489
490 /**
491 * Initialize this as a normal environment block.
492 * @returns IPRT status code.
493 * @param fFlags RTENV_CREATE_F_XXX
494 */
495 int initNormal(uint32_t fFlags)
496 {
497 AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
498 m_fFlags = fFlags;
499 return RTEnvCreateEx(&m_hEnv, fFlags);
500 }
501
502 /**
503 * Replaces this environemnt with that in @a rThat.
504 *
505 * @returns IPRT status code
506 * @param rThat The environment to copy. If it's a different type
507 * we'll convert the data to a normal environment block.
508 */
509 int copy(const GuestEnvironmentBase &rThat)
510 {
511 return cloneCommon(rThat, false /*fChangeRecord*/);
512 }
513
514 /**
515 * @copydoc GuestEnvironment::copy()
516 */
517 GuestEnvironment &operator=(const GuestEnvironmentBase &rThat)
518 {
519 int vrc = copy(rThat);
520 if (RT_FAILURE(vrc))
521 throw Global::vboxStatusCodeToCOM(vrc);
522 return *this;
523 }
524
525 /** @copydoc GuestEnvironment::copy() */
526 GuestEnvironment &operator=(const GuestEnvironment &rThat)
527 { return operator=((const GuestEnvironmentBase &)rThat); }
528
529 /** @copydoc GuestEnvironment::copy() */
530 GuestEnvironment &operator=(const GuestEnvironmentChanges &rThat)
531 { return operator=((const GuestEnvironmentBase &)rThat); }
532
533};
534
535
536/**
537 * Wrapper around the RTEnv API for a environment change record.
538 *
539 * This class is used as a record of changes to be applied to a different
540 * environment block (in VBoxService before launching a new process).
541 */
542class GuestEnvironmentChanges : public GuestEnvironmentBase
543{
544public:
545 /**
546 * Default constructor.
547 *
548 * The user must invoke one of the init methods before using the object.
549 */
550 GuestEnvironmentChanges(void)
551 : GuestEnvironmentBase()
552 { }
553
554 /**
555 * Copy operator.
556 * @param rThat The object to copy.
557 * @throws HRESULT
558 */
559 GuestEnvironmentChanges(const GuestEnvironmentChanges &rThat)
560 : GuestEnvironmentBase(rThat, true /*fChangeRecord*/)
561 { }
562
563 /**
564 * Copy operator.
565 * @param rThat The object to copy.
566 * @throws HRESULT
567 */
568 GuestEnvironmentChanges(const GuestEnvironmentBase &rThat)
569 : GuestEnvironmentBase(rThat, true /*fChangeRecord*/)
570 { }
571
572 /**
573 * Initialize this as a environment change record.
574 * @returns IPRT status code.
575 * @param fFlags RTENV_CREATE_F_XXX
576 */
577 int initChangeRecord(uint32_t fFlags)
578 {
579 AssertReturn(m_hEnv == NIL_RTENV, VERR_WRONG_ORDER);
580 m_fFlags = fFlags;
581 return RTEnvCreateChangeRecordEx(&m_hEnv, fFlags);
582 }
583
584 /**
585 * Replaces this environemnt with that in @a rThat.
586 *
587 * @returns IPRT status code
588 * @param rThat The environment to copy. If it's a different type
589 * we'll convert the data to a set of changes.
590 */
591 int copy(const GuestEnvironmentBase &rThat)
592 {
593 return cloneCommon(rThat, true /*fChangeRecord*/);
594 }
595
596 /**
597 * @copydoc GuestEnvironmentChanges::copy()
598 * @throws HRESULT
599 */
600 GuestEnvironmentChanges &operator=(const GuestEnvironmentBase &rThat)
601 {
602 int vrc = copy(rThat);
603 if (RT_FAILURE(vrc))
604 throw Global::vboxStatusCodeToCOM(vrc);
605 return *this;
606 }
607
608 /** @copydoc GuestEnvironmentChanges::copy()
609 * @throws HRESULT */
610 GuestEnvironmentChanges &operator=(const GuestEnvironmentChanges &rThat)
611 { return operator=((const GuestEnvironmentBase &)rThat); }
612
613 /** @copydoc GuestEnvironmentChanges::copy()
614 * @throws HRESULT */
615 GuestEnvironmentChanges &operator=(const GuestEnvironment &rThat)
616 { return operator=((const GuestEnvironmentBase &)rThat); }
617};
618
619/**
620 * Class for keeping guest error information.
621 */
622class GuestErrorInfo
623{
624public:
625
626 /**
627 * Enumeration for specifying the guest error type.
628 */
629 enum Type
630 {
631 /** Guest error is anonymous. Avoid this. */
632 Type_Anonymous = 0,
633 /** Guest error is from a guest session. */
634 Type_Session,
635 /** Guest error is from a guest process. */
636 Type_Process,
637 /** Guest error is from a guest file object. */
638 Type_File,
639 /** Guest error is from a guest directory object. */
640 Type_Directory,
641 /** Guest error is from a file system operation. */
642 Type_Fs,
643#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
644 /** Guest error is from a the built-in toolbox "vbox_ls" command. */
645 Type_ToolLs,
646 /** Guest error is from a the built-in toolbox "vbox_rm" command. */
647 Type_ToolRm,
648 /** Guest error is from a the built-in toolbox "vbox_mkdir" command. */
649 Type_ToolMkDir,
650 /** Guest error is from a the built-in toolbox "vbox_mktemp" command. */
651 Type_ToolMkTemp,
652 /** Guest error is from a the built-in toolbox "vbox_stat" command. */
653 Type_ToolStat,
654#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
655 /** The usual 32-bit hack. */
656 Type_32BIT_HACK = 0x7fffffff
657 };
658
659 /**
660 * Initialization constructor.
661 *
662 * @param eType Error type to use.
663 * @param vrc VBox status code to use.
664 * @param pcszWhat Subject to use.
665 */
666 GuestErrorInfo(GuestErrorInfo::Type eType, int vrc, const char *pcszWhat)
667 {
668 int vrc2 = setV(eType, vrc, pcszWhat);
669 if (RT_FAILURE(vrc2))
670 throw vrc2;
671 }
672
673 /**
674 * Returns the VBox status code for this error.
675 *
676 * @returns VBox status code.
677 */
678 int getVrc(void) const { return mVrc; }
679
680 /**
681 * Returns the type of this error.
682 *
683 * @returns Error type.
684 */
685 Type getType(void) const { return mType; }
686
687 /**
688 * Returns the subject of this error.
689 *
690 * @returns Subject as a string.
691 */
692 Utf8Str getWhat(void) const { return mWhat; }
693
694 /**
695 * Sets the error information using a variable arguments list (va_list).
696 *
697 * @returns VBox status code.
698 * @param eType Error type to use.
699 * @param vrc VBox status code to use.
700 * @param pcszWhat Subject to use.
701 */
702 int setV(GuestErrorInfo::Type eType, int vrc, const char *pcszWhat)
703 {
704 mType = eType;
705 mVrc = vrc;
706 mWhat = pcszWhat;
707
708 return VINF_SUCCESS;
709 }
710
711protected:
712
713 /** Error type. */
714 Type mType;
715 /** VBox status (error) code. */
716 int mVrc;
717 /** Subject string related to this error. */
718 Utf8Str mWhat;
719};
720
721/**
722 * Structure for keeping all the relevant guest directory
723 * information around.
724 */
725struct GuestDirectoryOpenInfo
726{
727 GuestDirectoryOpenInfo(void)
728 : menmFilter(GSTCTLDIRFILTER_NONE)
729 , mFlags(0) { }
730
731 /** The directory path. */
732 Utf8Str mPath;
733 /** The filter to use (wildcard style). */
734 Utf8Str mFilter;
735 /** The filter option to use. */
736 GSTCTLDIRFILTER menmFilter;
737 /** Opening flags (of type GSTCTLDIRFILTER_XXX). */
738 uint32_t mFlags;
739};
740
741
742/**
743 * Structure for keeping all the relevant guest file
744 * information around.
745 */
746struct GuestFileOpenInfo
747{
748 GuestFileOpenInfo(void)
749 : mAccessMode((FileAccessMode_T)0)
750 , mOpenAction((FileOpenAction_T)0)
751 , mSharingMode((FileSharingMode_T)0)
752 , mCreationMode(0)
753 , mfOpenEx(0) { }
754
755 /**
756 * Validates a file open info.
757 *
758 * @returns \c true if valid, \c false if not.
759 */
760 bool IsValid(void) const
761 {
762 if (mfOpenEx) /** @todo Open flags not implemented yet. */
763 return false;
764
765 switch (mOpenAction)
766 {
767 case FileOpenAction_OpenExisting:
768 break;
769 case FileOpenAction_OpenOrCreate:
770 break;
771 case FileOpenAction_CreateNew:
772 break;
773 case FileOpenAction_CreateOrReplace:
774 break;
775 case FileOpenAction_OpenExistingTruncated:
776 {
777 if ( mAccessMode == FileAccessMode_ReadOnly
778 || mAccessMode == FileAccessMode_AppendOnly
779 || mAccessMode == FileAccessMode_AppendRead)
780 return false;
781 break;
782 }
783 case FileOpenAction_AppendOrCreate: /* Deprecated, do not use. */
784 break;
785 default:
786 AssertFailedReturn(false);
787 break;
788 }
789
790 return true; /** @todo Do we need more checks here? */
791 }
792
793 /** The filename. */
794 Utf8Str mFilename;
795 /** The file access mode. */
796 FileAccessMode_T mAccessMode;
797 /** The file open action. */
798 FileOpenAction_T mOpenAction;
799 /** The file sharing mode. */
800 FileSharingMode_T mSharingMode;
801 /** Octal creation mode. */
802 uint32_t mCreationMode;
803 /** Extended open flags (currently none defined). */
804 uint32_t mfOpenEx;
805};
806
807
808/**
809 * Helper class for guest file system operations.
810 */
811class GuestFs
812{
813 DECLARE_TRANSLATE_METHODS(GuestFs)
814
815private:
816
817 /* Not directly instantiable. */
818 GuestFs(void) { }
819
820public:
821
822 static Utf8Str guestErrorToString(const GuestErrorInfo &guestErrorInfo);
823};
824
825
826/**
827 * Structure representing information of a
828 * file system object.
829 */
830struct GuestFsObjData
831{
832 GuestFsObjData(const Utf8Str &strName = "")
833 : mType(FsObjType_Unknown)
834 , mObjectSize(0)
835 , mAllocatedSize(0)
836 , mAccessTime(0)
837 , mBirthTime(0)
838 , mChangeTime(0)
839 , mModificationTime(0)
840 , mUID(0)
841 , mGID(0)
842 , mNodeID(0)
843 , mNodeIDDevice(0)
844 , mNumHardLinks(0)
845 , mDeviceNumber(0)
846 , mGenerationID(0)
847 , mUserFlags(0) { mName = strName; }
848
849 void Init(const Utf8Str &strName) { mName = strName; }
850
851#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
852 int FromGuestDirEntryEx(PCGSTCTLDIRENTRYEX pDirEntryEx, const Utf8Str &strUser = "", const Utf8Str &strGroups = "");
853 int FromGuestFsObjInfo(PCGSTCTLFSOBJINFO pFsObjInfo, const Utf8Str &strUser = "", const Utf8Str &strGroups = "");
854#endif
855
856#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
857 /** @name Helper functions to extract the data from a certin VBoxService tool's guest stream block.
858 * @{ */
859 int FromToolboxLs(const GuestToolboxStreamBlock &strmBlk, bool fLong);
860 int FromToolboxRm(const GuestToolboxStreamBlock &strmBlk);
861 int FromToolboxStat(const GuestToolboxStreamBlock &strmBlk);
862 int FromToolboxMkTemp(const GuestToolboxStreamBlock &strmBlk);
863 /** @} */
864#endif
865
866#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
867 /** @name Static helper functions to work with time from stream block keys.
868 * @{ */
869 static PRTTIMESPEC TimeSpecFromKey(const GuestToolboxStreamBlock &strmBlk, const Utf8Str &strKey, PRTTIMESPEC pTimeSpec);
870 static int64_t UnixEpochNsFromKey(const GuestToolboxStreamBlock &strmBlk, const Utf8Str &strKey);
871 /** @} */
872#endif
873
874 /** @name helper functions to work with IPRT stuff.
875 * @{ */
876 RTFMODE GetFileMode(void) const;
877 /** @} */
878
879 Utf8Str mName;
880 FsObjType_T mType;
881 Utf8Str mFileAttrs;
882 int64_t mObjectSize;
883 int64_t mAllocatedSize;
884 int64_t mAccessTime;
885 int64_t mBirthTime;
886 int64_t mChangeTime;
887 int64_t mModificationTime;
888 Utf8Str mUserName;
889 int32_t mUID;
890 int32_t mGID;
891 Utf8Str mGroupName;
892 Utf8Str mACL;
893 int64_t mNodeID;
894 uint32_t mNodeIDDevice;
895 uint32_t mNumHardLinks;
896 uint32_t mDeviceNumber;
897 uint32_t mGenerationID;
898 uint32_t mUserFlags;
899};
900
901
902/**
903 * Structure for keeping all the relevant guest session
904 * startup parameters around.
905 */
906class GuestSessionStartupInfo
907{
908public:
909
910 GuestSessionStartupInfo(void)
911 : mID(UINT32_MAX)
912 , mIsInternal(false /* Non-internal session */)
913 , mOpenTimeoutMS(30 * 1000 /* 30s opening timeout */)
914 , mOpenFlags(0 /* No opening flags set */) { }
915
916 /** The session's friendly name. Optional. */
917 Utf8Str mName;
918 /** The session's unique ID. Used to encode a context ID.
919 * UINT32_MAX if not initialized. */
920 uint32_t mID;
921 /** Flag indicating if this is an internal session
922 * or not. Internal session are not accessible by
923 * public API clients. */
924 bool mIsInternal;
925 /** Timeout (in ms) used for opening the session. */
926 uint32_t mOpenTimeoutMS;
927 /** Session opening flags. */
928 uint32_t mOpenFlags;
929};
930
931
932/**
933 * Structure for keeping all the relevant guest process
934 * startup parameters around.
935 */
936class GuestProcessStartupInfo
937{
938public:
939
940 GuestProcessStartupInfo(void)
941 : mFlags(ProcessCreateFlag_None)
942 , mTimeoutMS(UINT32_MAX /* No timeout by default */)
943 , mPriority(ProcessPriority_Default)
944 , mAffinity(0) { }
945
946 /** The process' friendly name. */
947 Utf8Str mName;
948 /** The executable. */
949 Utf8Str mExecutable;
950 /** The working directory. Optional, can be empty if not used. */
951 Utf8Str mCwd;
952 /** Arguments vector (starting with argument \#0). */
953 ProcessArguments mArguments;
954 /** The process environment change record. */
955 GuestEnvironmentChanges mEnvironmentChanges;
956 /** Process creation flags. */
957 uint32_t mFlags;
958 /** Timeout (in ms) the process is allowed to run.
959 * Specify UINT32_MAX if no timeout (unlimited run time) is given. */
960 ULONG mTimeoutMS;
961 /** Process priority. */
962 ProcessPriority_T mPriority;
963 /** Process affinity. At the moment we
964 * only support 64 VCPUs. API and
965 * guest can do more already! */
966 uint64_t mAffinity;
967};
968
969
970/**
971 * Class representing the "value" side of a "key=value" pair.
972 */
973class GuestToolboxStreamValue
974{
975public:
976
977 GuestToolboxStreamValue(void) { }
978 GuestToolboxStreamValue(const char *pszValue, size_t cwcValue = RTSTR_MAX)
979 : mValue(pszValue, cwcValue) {}
980
981 GuestToolboxStreamValue(const GuestToolboxStreamValue& aThat)
982 : mValue(aThat.mValue) { }
983
984 /** Copy assignment operator. */
985 GuestToolboxStreamValue &operator=(GuestToolboxStreamValue const &a_rThat) RT_NOEXCEPT
986 {
987 mValue = a_rThat.mValue;
988
989 return *this;
990 }
991
992 Utf8Str mValue;
993};
994
995/** Map containing "key=value" pairs of a guest process stream. */
996typedef std::pair< Utf8Str, GuestToolboxStreamValue > GuestCtrlStreamPair;
997typedef std::map < Utf8Str, GuestToolboxStreamValue > GuestCtrlStreamPairMap;
998typedef std::map < Utf8Str, GuestToolboxStreamValue >::iterator GuestCtrlStreamPairMapIter;
999typedef std::map < Utf8Str, GuestToolboxStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
1000
1001class GuestToolboxStream;
1002
1003/**
1004 * Class representing a block of stream pairs (key=value). Each block in a raw guest
1005 * output stream is separated by "\0\0", each pair is separated by "\0". The overall
1006 * end of a guest stream is marked by "\0\0\0\0".
1007 *
1008 * An empty stream block will be treated as being incomplete.
1009 *
1010 * Only used for the busybox-like toolbox commands within VBoxService.
1011 * Deprecated, do not use anymore.
1012 */
1013class GuestToolboxStreamBlock
1014{
1015 friend GuestToolboxStream;
1016
1017public:
1018
1019 GuestToolboxStreamBlock(void);
1020
1021 virtual ~GuestToolboxStreamBlock(void);
1022
1023public:
1024
1025 void Clear(void);
1026
1027#ifdef DEBUG
1028 void DumpToLog(void) const;
1029#endif
1030
1031 const char *GetString(const char *pszKey) const;
1032 size_t GetCount(void) const;
1033 int GetVrc(bool fSucceedIfNotFound = false) const;
1034 int GetInt64Ex(const char *pszKey, int64_t *piVal) const;
1035 int64_t GetInt64(const char *pszKey) const;
1036 int GetUInt32Ex(const char *pszKey, uint32_t *puVal) const;
1037 uint32_t GetUInt32(const char *pszKey, uint32_t uDefault = 0) const;
1038 int32_t GetInt32(const char *pszKey, int32_t iDefault = 0) const;
1039
1040 bool IsComplete(void) const { return !m_mapPairs.empty() && m_fComplete; }
1041 bool IsEmpty(void) const { return m_mapPairs.empty(); }
1042
1043 int SetValueEx(const char *pszKey, size_t cwcKey, const char *pszValue, size_t cwcValue, bool fOverwrite = false);
1044 int SetValue(const char *pszKey, const char *pszValue);
1045
1046protected:
1047
1048 /** Wheter the stream block is marked as complete.
1049 * An empty stream block is considered as incomplete. */
1050 bool m_fComplete;
1051 /** Map of stream pairs this block contains.*/
1052 GuestCtrlStreamPairMap m_mapPairs;
1053};
1054
1055/** Vector containing multiple allocated stream pair objects. */
1056typedef std::vector< GuestToolboxStreamBlock > GuestCtrlStreamObjects;
1057typedef std::vector< GuestToolboxStreamBlock >::iterator GuestCtrlStreamObjectsIter;
1058typedef std::vector< GuestToolboxStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
1059
1060/** Defines a single terminator as a single char. */
1061#define GUESTTOOLBOX_STRM_TERM '\0'
1062/** Defines a single terminator as a string. */
1063#define GUESTTOOLBOX_STRM_TERM_STR "\0"
1064/** Defines the termination sequence for a single key/value pair. */
1065#define GUESTTOOLBOX_STRM_TERM_PAIR_STR GUESTTOOLBOX_STRM_TERM_STR
1066/** Defines the termination sequence for a single stream block. */
1067#define GUESTTOOLBOX_STRM_TERM_BLOCK_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR
1068/** Defines the termination sequence for the stream. */
1069#define GUESTTOOLBOX_STRM_TERM_STREAM_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR GUESTTOOLBOX_STRM_TERM_STR
1070/** Defines how many consequtive terminators a key/value pair has. */
1071#define GUESTTOOLBOX_STRM_PAIR_TERM_CNT 1
1072/** Defines how many consequtive terminators a stream block has. */
1073#define GUESTTOOLBOX_STRM_BLK_TERM_CNT 2
1074/** Defines how many consequtive terminators a stream has. */
1075#define GUESTTOOLBOX_STRM_TERM_CNT 4
1076
1077/**
1078 * Class for parsing machine-readable guest process output by VBoxService'
1079 * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
1080 *
1081 * Deprecated, do not use anymore.
1082 */
1083class GuestToolboxStream
1084{
1085
1086public:
1087
1088 GuestToolboxStream();
1089
1090 virtual ~GuestToolboxStream();
1091
1092public:
1093
1094 int AddData(const BYTE *pbData, size_t cbData);
1095
1096 void Destroy();
1097
1098#ifdef DEBUG
1099 void Dump(const char *pszFile);
1100#endif
1101
1102 size_t GetOffset(void) const { return m_offBuf; }
1103
1104 size_t GetSize(void) const { return m_cbUsed; }
1105
1106 size_t GetBlocks(void) const { return m_cBlocks; }
1107
1108 int ParseBlock(GuestToolboxStreamBlock &streamBlock);
1109
1110protected:
1111
1112 /** Maximum allowed size the stream buffer can grow to.
1113 * Defaults to 32 MB. */
1114 size_t m_cbMax;
1115 /** Currently allocated size of internal stream buffer. */
1116 size_t m_cbAllocated;
1117 /** Currently used size at m_offBuffer. */
1118 size_t m_cbUsed;
1119 /** Current byte offset within the internal stream buffer. */
1120 size_t m_offBuf;
1121 /** Internal stream buffer. */
1122 BYTE *m_pbBuffer;
1123 /** How many completed stream blocks already were processed. */
1124 size_t m_cBlocks;
1125};
1126
1127class Guest;
1128class Progress;
1129
1130class GuestWaitEventPayload
1131{
1132
1133public:
1134
1135 GuestWaitEventPayload(void)
1136 : uType(0)
1137 , cbData(0)
1138 , pvData(NULL)
1139 { }
1140
1141 /**
1142 * Initialization constructor.
1143 *
1144 * @throws VBox status code (vrc).
1145 *
1146 * @param uTypePayload Payload type to set.
1147 * @param pvPayload Pointer to payload data to set (deep copy).
1148 * @param cbPayload Size (in bytes) of payload data to set.
1149 */
1150 GuestWaitEventPayload(uint32_t uTypePayload, const void *pvPayload, uint32_t cbPayload)
1151 : uType(0)
1152 , cbData(0)
1153 , pvData(NULL)
1154 {
1155 int vrc = copyFrom(uTypePayload, pvPayload, cbPayload);
1156 if (RT_FAILURE(vrc))
1157 throw vrc;
1158 }
1159
1160 virtual ~GuestWaitEventPayload(void)
1161 {
1162 Clear();
1163 }
1164
1165 GuestWaitEventPayload& operator=(const GuestWaitEventPayload &that)
1166 {
1167 CopyFromDeep(that);
1168 return *this;
1169 }
1170
1171public:
1172
1173 void Clear(void)
1174 {
1175 if (pvData)
1176 {
1177 Assert(cbData);
1178 RTMemFree(pvData);
1179 cbData = 0;
1180 pvData = NULL;
1181 }
1182 uType = 0;
1183 }
1184
1185 int CopyFromDeep(const GuestWaitEventPayload &payload)
1186 {
1187 return copyFrom(payload.uType, payload.pvData, payload.cbData);
1188 }
1189
1190 const void* Raw(void) const { return pvData; }
1191
1192 size_t Size(void) const { return cbData; }
1193
1194 uint32_t Type(void) const { return uType; }
1195
1196 void* MutableRaw(void) { return pvData; }
1197
1198 Utf8Str ToString(void)
1199 {
1200 const char *pszStr = (const char *)pvData;
1201 size_t cbStr = cbData;
1202
1203 if (RT_FAILURE(RTStrValidateEncodingEx(pszStr, cbStr,
1204 RTSTR_VALIDATE_ENCODING_ZERO_TERMINATED | RTSTR_VALIDATE_ENCODING_EXACT_LENGTH)))
1205 {
1206 AssertFailed();
1207 return "";
1208 }
1209
1210 return Utf8Str(pszStr, cbStr);
1211 }
1212
1213protected:
1214
1215 int copyFrom(uint32_t uTypePayload, const void *pvPayload, uint32_t cbPayload)
1216 {
1217 if (cbPayload > _64K) /* Paranoia. */
1218 return VERR_TOO_MUCH_DATA;
1219
1220 Clear();
1221
1222 int vrc = VINF_SUCCESS;
1223 if (cbPayload)
1224 {
1225 pvData = RTMemAlloc(cbPayload);
1226 if (pvData)
1227 {
1228 uType = uTypePayload;
1229
1230 memcpy(pvData, pvPayload, cbPayload);
1231 cbData = cbPayload;
1232 }
1233 else
1234 vrc = VERR_NO_MEMORY;
1235 }
1236 else
1237 {
1238 uType = uTypePayload;
1239
1240 pvData = NULL;
1241 cbData = 0;
1242 }
1243
1244 return vrc;
1245 }
1246
1247protected:
1248
1249 /** Type of payload. */
1250 uint32_t uType;
1251 /** Size (in bytes) of payload. */
1252 uint32_t cbData;
1253 /** Pointer to actual payload data. */
1254 void *pvData;
1255};
1256
1257class GuestWaitEventBase
1258{
1259
1260protected:
1261
1262 GuestWaitEventBase(void);
1263 virtual ~GuestWaitEventBase(void);
1264
1265public:
1266
1267 uint32_t ContextID(void) const { return mCID; };
1268 int GuestResult(void) const { return mGuestRc; }
1269 bool HasGuestError(void) const { return mVrc == VERR_GSTCTL_GUEST_ERROR; }
1270 int Result(void) const { return mVrc; }
1271 GuestWaitEventPayload &Payload(void) { return mPayload; }
1272 int SignalInternal(int vrc, int vrcGuest, const GuestWaitEventPayload *pPayload);
1273 int Wait(RTMSINTERVAL uTimeoutMS);
1274
1275protected:
1276
1277 int Init(uint32_t uCID);
1278
1279protected:
1280
1281 /** Shutdown indicator. */
1282 bool mfAborted;
1283 /** Associated context ID (CID). */
1284 uint32_t mCID;
1285 /** The event semaphore for triggering the actual event. */
1286 RTSEMEVENT mEventSem;
1287 /** The event's overall result.
1288 * If set to VERR_GSTCTL_GUEST_ERROR, mGuestRc will contain the actual
1289 * error code from the guest side. */
1290 int mVrc;
1291 /** The event'S overall result from the guest side.
1292 * If used, mVrc must be set to VERR_GSTCTL_GUEST_ERROR. */
1293 int mGuestRc;
1294 /** The event's payload data. Optional. */
1295 GuestWaitEventPayload mPayload;
1296};
1297
1298/** List of public guest event types. */
1299typedef std::list < VBoxEventType_T > GuestEventTypes;
1300
1301class GuestWaitEvent : public GuestWaitEventBase
1302{
1303
1304public:
1305
1306 GuestWaitEvent(void);
1307 virtual ~GuestWaitEvent(void);
1308
1309public:
1310
1311 int Init(uint32_t uCID);
1312 int Init(uint32_t uCID, const GuestEventTypes &lstEvents);
1313 int Cancel(void);
1314 const ComPtr<IEvent> Event(void) const { return mEvent; }
1315 int SignalExternal(IEvent *pEvent);
1316 const GuestEventTypes &Types(void) const { return mEventTypes; }
1317 size_t TypeCount(void) const { return mEventTypes.size(); }
1318
1319protected:
1320
1321 /** List of public event types this event should
1322 * be signalled on. Optional. */
1323 GuestEventTypes mEventTypes;
1324 /** Pointer to the actual public event, if any. */
1325 ComPtr<IEvent> mEvent;
1326};
1327/** Map of pointers to guest events. The primary key
1328 * contains the context ID. */
1329typedef std::map < uint32_t, GuestWaitEvent* > GuestWaitEvents;
1330/** Map of wait events per public guest event. Nice for
1331 * faster lookups when signalling a whole event group. */
1332typedef std::map < VBoxEventType_T, GuestWaitEvents > GuestEventGroup;
1333
1334class GuestBase
1335{
1336
1337public:
1338
1339 GuestBase(void);
1340 virtual ~GuestBase(void);
1341
1342public:
1343
1344 /** Signals a wait event using a public guest event; also used for
1345 * for external event listeners. */
1346 int signalWaitEvent(VBoxEventType_T aType, IEvent *aEvent);
1347 /** Signals a wait event using a guest vrc. */
1348 int signalWaitEventInternal(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int vrcGuest, const GuestWaitEventPayload *pPayload);
1349 /** Signals a wait event without letting public guest events know,
1350 * extended director's cut version. */
1351 int signalWaitEventInternalEx(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, int vrc, int vrcGuest, const GuestWaitEventPayload *pPayload);
1352
1353public:
1354
1355 int baseInit(void);
1356 void baseUninit(void);
1357 int cancelWaitEvents(void);
1358 int dispatchGeneric(PVBOXGUESTCTRLHOSTCBCTX pCtxCb, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb);
1359 int generateContextID(uint32_t uSessionID, uint32_t uObjectID, uint32_t *puContextID);
1360 int registerWaitEvent(uint32_t uSessionID, uint32_t uObjectID, GuestWaitEvent **ppEvent);
1361 int registerWaitEventEx(uint32_t uSessionID, uint32_t uObjectID, const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
1362 int unregisterWaitEvent(GuestWaitEvent *pEvent);
1363 int waitForEvent(GuestWaitEvent *pEvent, uint32_t uTimeoutMS, VBoxEventType_T *pType, IEvent **ppEvent);
1364
1365public:
1366
1367 static FsObjType_T fileModeToFsObjType(RTFMODE fMode);
1368 static const char *fsObjTypeToStr(FsObjType_T enmType);
1369 static const char *pathStyleToStr(PathStyle_T enmPathStyle);
1370 static Utf8Str getErrorAsString(const Utf8Str &strAction, const GuestErrorInfo& guestErrorInfo);
1371 static Utf8Str getErrorAsString(const GuestErrorInfo &guestErrorInfo);
1372
1373protected:
1374
1375 /** Pointer to the console object. Needed
1376 * for HGCM (VMMDev) communication. */
1377 Console *mConsole;
1378 /** The next context ID counter component for this object. */
1379 uint32_t mNextContextID;
1380 /** Local listener for handling the waiting events
1381 * internally. */
1382 ComPtr<IEventListener> mLocalListener;
1383 /** Critical section for wait events access. */
1384 RTCRITSECT mWaitEventCritSect;
1385 /** Map of registered wait events per event group. */
1386 GuestEventGroup mWaitEventGroups;
1387 /** Map of registered wait events. */
1388 GuestWaitEvents mWaitEvents;
1389};
1390
1391/**
1392 * Virtual class (interface) for guest objects (processes, files, ...) --
1393 * contains all per-object callback management.
1394 */
1395class GuestObject : public GuestBase
1396{
1397 friend class GuestSession;
1398
1399public:
1400
1401 GuestObject(void);
1402 virtual ~GuestObject(void);
1403
1404public:
1405
1406 ULONG getObjectID(void) { return mObjectID; }
1407
1408protected:
1409
1410 /**
1411 * Called by IGuestSession when the session status has been changed.
1412 *
1413 * @returns VBox status code.
1414 * @param enmSessionStatus New session status.
1415 */
1416 virtual int i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus) = 0;
1417
1418 /**
1419 * Called by IGuestSession right before this object gets
1420 * unregistered (removed) from the public object list.
1421 */
1422 virtual int i_onUnregister(void) = 0;
1423
1424 /** Callback dispatcher -- must be implemented by the actual object. */
1425 virtual int i_callbackDispatcher(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCb) = 0;
1426
1427protected:
1428
1429 int bindToSession(Console *pConsole, GuestSession *pSession, uint32_t uObjectID);
1430 int registerWaitEvent(const GuestEventTypes &lstEvents, GuestWaitEvent **ppEvent);
1431 int sendMessage(uint32_t uFunction, uint32_t cParms, PVBOXHGCMSVCPARM paParms);
1432
1433protected:
1434
1435 /** @name Common parameters for all derived objects. They have their own
1436 * mData structure to keep their specific data around.
1437 * @{ */
1438 /** Pointer to parent session. Per definition
1439 * this objects *always* lives shorter than the
1440 * parent.
1441 * @todo r=bird: When wanting to use mSession in the
1442 * IGuestProcess::getEnvironment() implementation I wanted to access
1443 * GuestSession::mData::mpBaseEnvironment. Seeing the comment in
1444 * GuestProcess::terminate() saying:
1445 * "Now only API clients still can hold references to it."
1446 * and recalling seeing similar things in VirtualBox.xidl or some such place,
1447 * I'm wondering how this "per definition" behavior is enforced. Is there any
1448 * GuestProcess:uninit() call or similar magic that invalidates objects that
1449 * GuestSession loses track of in place like GuestProcess::terminate() that I've
1450 * failed to spot?
1451 *
1452 * Please enlighten me.
1453 */
1454 GuestSession *mSession;
1455 /** The object ID -- must be unique for each guest
1456 * object and is encoded into the context ID. Must
1457 * be set manually when initializing the object.
1458 *
1459 * For guest processes this is the internal PID,
1460 * for guest files this is the internal file ID. */
1461 uint32_t mObjectID;
1462 /** @} */
1463};
1464
1465/** Returns the path separator based on \a a_enmPathStyle as a C-string. */
1466#define PATH_STYLE_SEP_STR(a_enmPathStyle) (a_enmPathStyle == PathStyle_DOS ? "\\" : "/")
1467#if defined(RT_OS_WINDOWS) || defined(RT_OS_OS2)
1468# define PATH_STYLE_NATIVE PathStyle_DOS
1469#else
1470# define PATH_STYLE_NATIVE PathStyle_UNIX
1471#endif
1472
1473/**
1474 * Class for handling guest / host path functions.
1475 */
1476class GuestPath
1477{
1478private:
1479
1480 /**
1481 * Default constructor.
1482 *
1483 * Not directly instantiable (yet).
1484 */
1485 GuestPath(void) { }
1486
1487public:
1488
1489 /** @name Static helper functions.
1490 * @{ */
1491 static int BuildDestinationPath(const Utf8Str &strSrcPath, PathStyle_T enmSrcPathStyle, Utf8Str &strDstPath, PathStyle_T enmDstPathStyle);
1492 static int Translate(Utf8Str &strPath, PathStyle_T enmSrcPathStyle, PathStyle_T enmDstPathStyle, bool fForce = false);
1493 /** @} */
1494};
1495
1496
1497/*********************************************************************************************************************************
1498 * Callback data structures. *
1499 * *
1500 * These structures make up the actual low level HGCM callback data sent from *
1501 * the guest back to the host. *
1502 ********************************************************************************************************************************/
1503
1504/**
1505 * The guest control callback data header. Must come first
1506 * on each callback structure defined below this struct.
1507 */
1508typedef struct CALLBACKDATA_HEADER
1509{
1510 /** Context ID to identify callback data. This is
1511 * and *must* be the very first parameter in this
1512 * structure to still be backwards compatible. */
1513 uint32_t uContextID;
1514} CALLBACKDATA_HEADER;
1515/** Pointer to a CALLBACKDATA_HEADER struct. */
1516typedef CALLBACKDATA_HEADER *PCALLBACKDATA_HEADER;
1517
1518/**
1519 * Host service callback data when a HGCM client disconnected.
1520 */
1521typedef struct CALLBACKDATA_CLIENT_DISCONNECTED
1522{
1523 /** Callback data header. */
1524 CALLBACKDATA_HEADER hdr;
1525} CALLBACKDATA_CLIENT_DISCONNECTED;
1526/** Pointer to a CALLBACKDATA_CLIENT_DISCONNECTED struct. */
1527typedef CALLBACKDATA_CLIENT_DISCONNECTED *PCALLBACKDATA_CLIENT_DISCONNECTED;
1528
1529/**
1530 * Host service callback data for a generic guest reply.
1531 */
1532typedef struct CALLBACKDATA_MSG_REPLY
1533{
1534 /** Callback data header. */
1535 CALLBACKDATA_HEADER hdr;
1536 /** Notification type. */
1537 uint32_t uType;
1538 /** Notification result. Note: int vs. uint32! */
1539 uint32_t rc;
1540 /** Pointer to optional payload. */
1541 void *pvPayload;
1542 /** Payload size (in bytes). */
1543 uint32_t cbPayload;
1544} CALLBACKDATA_MSG_REPLY;
1545/** Pointer to a CALLBACKDATA_MSG_REPLY struct. */
1546typedef CALLBACKDATA_MSG_REPLY *PCALLBACKDATA_MSG_REPLY;
1547
1548/**
1549 * Host service callback data for guest session notifications.
1550 */
1551typedef struct CALLBACKDATA_SESSION_NOTIFY
1552{
1553 /** Callback data header. */
1554 CALLBACKDATA_HEADER hdr;
1555 /** Notification type. */
1556 uint32_t uType;
1557 /** Notification result. Note: int vs. uint32! */
1558 uint32_t uResult;
1559} CALLBACKDATA_SESSION_NOTIFY;
1560/** Pointer to a CALLBACKDATA_SESSION_NOTIFY struct. */
1561typedef CALLBACKDATA_SESSION_NOTIFY *PCALLBACKDATA_SESSION_NOTIFY;
1562
1563/**
1564 * Host service callback data for guest process status notifications.
1565 */
1566typedef struct CALLBACKDATA_PROC_STATUS
1567{
1568 /** Callback data header. */
1569 CALLBACKDATA_HEADER hdr;
1570 /** The process ID (PID). */
1571 uint32_t uPID;
1572 /** The process status. */
1573 uint32_t uStatus;
1574 /** Optional flags, varies, based on u32Status. */
1575 uint32_t uFlags;
1576 /** Optional data buffer (not used atm). */
1577 void *pvData;
1578 /** Size of optional data buffer (not used atm). */
1579 uint32_t cbData;
1580} CALLBACKDATA_PROC_STATUS;
1581/** Pointer to a CALLBACKDATA_PROC_OUTPUT struct. */
1582typedef CALLBACKDATA_PROC_STATUS* PCALLBACKDATA_PROC_STATUS;
1583
1584/**
1585 * Host service callback data for guest process output notifications.
1586 */
1587typedef struct CALLBACKDATA_PROC_OUTPUT
1588{
1589 /** Callback data header. */
1590 CALLBACKDATA_HEADER hdr;
1591 /** The process ID (PID). */
1592 uint32_t uPID;
1593 /** The handle ID (stdout/stderr). */
1594 uint32_t uHandle;
1595 /** Optional flags (not used atm). */
1596 uint32_t uFlags;
1597 /** Optional data buffer. */
1598 void *pvData;
1599 /** Size (in bytes) of optional data buffer. */
1600 uint32_t cbData;
1601} CALLBACKDATA_PROC_OUTPUT;
1602/** Pointer to a CALLBACKDATA_PROC_OUTPUT struct. */
1603typedef CALLBACKDATA_PROC_OUTPUT *PCALLBACKDATA_PROC_OUTPUT;
1604
1605/**
1606 * Host service callback data guest process input notifications.
1607 */
1608typedef struct CALLBACKDATA_PROC_INPUT
1609{
1610 /** Callback data header. */
1611 CALLBACKDATA_HEADER hdr;
1612 /** The process ID (PID). */
1613 uint32_t uPID;
1614 /** Current input status. */
1615 uint32_t uStatus;
1616 /** Optional flags. */
1617 uint32_t uFlags;
1618 /** Size (in bytes) of processed input data. */
1619 uint32_t uProcessed;
1620} CALLBACKDATA_PROC_INPUT;
1621/** Pointer to a CALLBACKDATA_PROC_INPUT struct. */
1622typedef CALLBACKDATA_PROC_INPUT *PCALLBACKDATA_PROC_INPUT;
1623
1624/**
1625 * General guest file notification callback.
1626 */
1627typedef struct CALLBACKDATA_FILE_NOTIFY
1628{
1629 /** Callback data header. */
1630 CALLBACKDATA_HEADER hdr;
1631 /** Notification type. */
1632 uint32_t uType;
1633 /** IPRT result of overall operation. */
1634 uint32_t rc;
1635 union
1636 {
1637 struct
1638 {
1639 /** Guest file handle. */
1640 uint32_t uHandle;
1641 } open;
1642 /** Note: Close does not have any additional data (yet). */
1643 struct
1644 {
1645 /** How much data (in bytes) have been read. */
1646 uint32_t cbData;
1647 /** Actual data read (if any). */
1648 void *pvData;
1649 } read;
1650 struct
1651 {
1652 /** How much data (in bytes) have been successfully written. */
1653 uint32_t cbWritten;
1654 } write;
1655 struct
1656 {
1657 /** New file offset after successful seek. */
1658 uint64_t uOffActual;
1659 } seek;
1660 struct
1661 {
1662 /** New file offset after successful tell. */
1663 uint64_t uOffActual;
1664 } tell;
1665 struct
1666 {
1667 /** The new file siz.e */
1668 uint64_t cbSize;
1669 } SetSize;
1670 } u;
1671} CALLBACKDATA_FILE_NOTIFY;
1672/** Pointer to a CALLBACKDATA_FILE_NOTIFY, struct. */
1673typedef CALLBACKDATA_FILE_NOTIFY *PCALLBACKDATA_FILE_NOTIFY;
1674
1675/**
1676 * Callback data for a single GSTCTLDIRENTRYEX entry.
1677 */
1678typedef struct CALLBACKDATA_DIR_ENTRY
1679{
1680 /** Pointer to directory entry information. */
1681 PGSTCTLDIRENTRYEX pDirEntryEx;
1682 /** Size (in bytes) of directory entry information. */
1683 uint32_t cbDirEntryEx;
1684 /** Resolved user name.
1685 * This is the object owner for UNIX-y Oses. */
1686 char *pszUser;
1687 /** Size (in bytes) of \a pszUser. */
1688 uint32_t cbUser;
1689 /** Resolved user group(s). */
1690 char *pszGroups;
1691 /** Size (in bytes) of \a pszGroups. */
1692 uint32_t cbGroups;
1693} CALLBACKDATA_DIR_ENTRY;
1694/** Pointer to a CALLBACKDATA_DIR_ENTRY struct. */
1695typedef CALLBACKDATA_DIR_ENTRY *PCALLBACKDATA_DIR_ENTRY;
1696
1697/**
1698 * Callback data for guest directory operations.
1699 */
1700typedef struct CALLBACKDATA_DIR_NOTIFY
1701{
1702 /** Callback data header. */
1703 CALLBACKDATA_HEADER hdr;
1704 /** Notification type. */
1705 uint32_t uType;
1706 /** IPRT result of overall operation. */
1707 uint32_t rc;
1708 union
1709 {
1710 struct
1711 {
1712 /** Pointer to directory information. */
1713 PGSTCTLFSOBJINFO pObjInfo;
1714 } info;
1715 struct
1716 {
1717 /** Guest directory handle. */
1718 uint32_t uHandle;
1719 } open;
1720 /** Note: Close does not have any additional data (yet). */
1721 struct
1722 {
1723 /** Single entry read. */
1724 CALLBACKDATA_DIR_ENTRY Entry;
1725 } read;
1726 struct
1727 {
1728 /** Number of entries in \a paEntries. */
1729 uint32_t cEntries;
1730 /** Array of entries read. */
1731 CALLBACKDATA_DIR_ENTRY **paEntries;
1732 } list;
1733 } u;
1734} CALLBACKDATA_DIR_NOTIFY;
1735/** Pointer to a CALLBACKDATA_DIR_NOTIFY struct. */
1736typedef CALLBACKDATA_DIR_NOTIFY *PCALLBACKDATA_DIR_NOTIFY;
1737
1738/**
1739 * Callback data for guest file system operations.
1740 */
1741typedef struct CALLBACKDATA_FS_NOTIFY
1742{
1743 /** Callback data header. */
1744 CALLBACKDATA_HEADER hdr;
1745 /** Notification type (of type GUEST_FS_NOTIFYTYPE_XXX). */
1746 uint32_t uType;
1747 /** IPRT result of overall operation. */
1748 uint32_t rc;
1749 union
1750 {
1751 /** Holds information for GUEST_FS_NOTIFYTYPE_CREATE_TEMP. */
1752 struct
1753 {
1754 /** Path of created temporary file / directory. */
1755 char *pszPath;
1756 /** Size (in bytes) of \a pszPath. */
1757 uint32_t cbPath;
1758 } CreateTemp;
1759 /** Holds information for GUEST_FS_NOTIFYTYPE_QUERY_OBJ_INFO. */
1760 struct
1761 {
1762 GSTCTLFSOBJINFO objInfo;
1763 /** Resolved user name. */
1764 char *pszUser;
1765 /** Size (in bytes) of \a pszUser. */
1766 uint32_t cbUser;
1767 /** Resolved user group(s). */
1768 char *pszGroups;
1769 /** Size (in bytes) of \a pszGroups. */
1770 uint32_t cbGroups;
1771 } QueryObjInfo;
1772 /** Holds information for GUEST_FS_NOTIFYTYPE_QUERY_INFO. */
1773 struct
1774 {
1775 /** The actual filesystem information. */
1776 GSTCTLFSINFO fsInfo;
1777 } QueryInfo;
1778 } u;
1779} CALLBACKDATA_FS_NOTIFY;
1780/** Pointer to a CALLBACKDATA_FS_NOTIFY struct. */
1781typedef CALLBACKDATA_FS_NOTIFY *PCALLBACKDATA_FS_NOTIFY;
1782#endif /* !MAIN_INCLUDED_GuestCtrlImplPrivate_h */
1783
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use