VirtualBox

Changeset 98526 in vbox


Ignore:
Timestamp:
Feb 10, 2023 3:10:50 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155802
Message:

Guest Control: Initial commit (work in progress, disabled by default). bugref:9783

IGuestDirectory:

Added new attributes id + status + an own event source. Also added for rewind support via rewind().

New event types for guest directory [un]registration, state changes and entry reads.

Location:
trunk
Files:
1 added
27 edited

Legend:

Unmodified
Added
Removed
  • trunk/Config.kmk

    r98511 r98526  
    898898if1of ($(KBUILD_TARGET), darwin freebsd linux solaris win)
    899899 VBOX_WITH_GUEST_CONTROL = 1
     900 # Enables support for handling certain commands via the built-in (busybox-like) toolbox in VBoxService. See @bugref{9783}
     901 # This is for supporting Guest Additions < 7.1.
     902 VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT = 1
     903 # Enables treating the toolbox as built-in commands. Requires 7.1 Guest Additions. See @bugref{9783}
     904 VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS =
    900905endif
    901906# Enable ballooning
  • trunk/include/VBox/GuestHost/GuestControl.h

    r98103 r98526  
    4343#endif
    4444
     45#include <iprt/time.h>
    4546#include <iprt/types.h>
    4647
     
    142143/** @} */
    143144
     145/** @name GSTCTL_CREATETEMP_F_XXX - Guest temporary directory/file creation flags.
     146 * @{
     147 */
     148/** Does not specify anything. */
     149#define GSTCTL_CREATETEMP_F_NONE            UINT32_C(0)
     150/** Creates a directory instead of a file. */
     151#define GSTCTL_CREATETEMP_F_DIRECTORY       RT_BIT(0)
     152/** Creates a secure temporary file / directory.
     153 *  Might not be supported on all (guest) OSes.
     154 *
     155 *  @sa IPRT's implementation of RTDirCreateTempSecure() / RTFileCreateTempSecumre(). */
     156#define GSTCTL_CREATETEMP_F_SECURE          RT_BIT(1)
     157/** Mask of valid flags. */
     158#define GSTCTL_CREATETEMP_F_VALID_MASK      UINT32_C(0x00000003)
     159/** @} */
     160
     161/** @name GSTCTL_CREATEDIRECTORY_F_XXX - Guest directory creation flags.
     162 * @{
     163 */
     164/** Does not specify anything. */
     165#define GSTCTL_CREATEDIRECTORY_F_NONE       UINT32_C(0)
     166/** Also creates parent directories if they don't exist yet. */
     167#define GSTCTL_CREATEDIRECTORY_F_PARENTS    RT_BIT(0)
     168/** Mask of valid flags. */
     169#define GSTCTL_CREATEDIRECTORY_F_VALID_MASK UINT32_C(0x00000001)
     170/** @} */
     171
    144172/** @name GUEST_SHUTDOWN_FLAG_XXX - Guest shutdown flags.
    145173 * Must match Main's GuestShutdownFlag_ definitions.
     
    229257};
    230258
    231 
     259/**
     260 * Guest file system object -- additional information in a GSTCTLFSOBJATTR object.
     261 */
     262enum GSTCTLFSOBJATTRADD
     263{
     264    /** No additional information is available / requested. */
     265    GSTCTLFSOBJATTRADD_NOTHING = 1,
     266    /** The additional unix attributes (RTFSOBJATTR::u::Unix) are available /
     267     *  requested. */
     268    GSTCTLFSOBJATTRADD_UNIX,
     269    /** The additional unix attributes (RTFSOBJATTR::u::UnixOwner) are
     270     * available / requested. */
     271    GSTCTLFSOBJATTRADD_UNIX_OWNER,
     272    /** The additional unix attributes (RTFSOBJATTR::u::UnixGroup) are
     273     * available / requested. */
     274    GSTCTLFSOBJATTRADD_UNIX_GROUP,
     275    /** The additional extended attribute size (RTFSOBJATTR::u::EASize) is available / requested. */
     276    GSTCTLFSOBJATTRADD_EASIZE,
     277    /** The last valid item (inclusive).
     278     * The valid range is RTFSOBJATTRADD_NOTHING thru RTFSOBJATTRADD_LAST.  */
     279    GSTCTLFSOBJATTRADD_LAST = GSTCTLFSOBJATTRADD_EASIZE,
     280
     281    /** The usual 32-bit hack. */
     282    GSTCTLFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
     283};
     284
     285/** The number of bytes reserved for the additional attribute union. */
     286#define GSTCTLFSOBJATTRUNION_MAX_SIZE       128
     287
     288/**
     289 * Additional Unix Attributes (GSTCTLFSOBJATTRADD_UNIX).
     290 */
     291typedef struct GSTCTLFSOBJATTRUNIX
     292{
     293    /** The user owning the filesystem object (st_uid).
     294     * This field is NIL_RTUID if not supported. */
     295    RTUID           uid;
     296
     297    /** The group the filesystem object is assigned (st_gid).
     298     * This field is NIL_RTGID if not supported. */
     299    RTGID           gid;
     300
     301    /** Number of hard links to this filesystem object (st_nlink).
     302     * This field is 1 if the filesystem doesn't support hardlinking or
     303     * the information isn't available.
     304     */
     305    uint32_t        cHardlinks;
     306
     307    /** The device number of the device which this filesystem object resides on (st_dev).
     308     * This field is 0 if this information is not available. */
     309    RTDEV           INodeIdDevice;
     310
     311    /** The unique identifier (within the filesystem) of this filesystem object (st_ino).
     312     * Together with INodeIdDevice, this field can be used as a OS wide unique id
     313     * when both their values are not 0.
     314     * This field is 0 if the information is not available.
     315     *
     316     * @remarks  The special '..' dir always shows up with 0 on NTFS/Windows. */
     317    RTINODE         INodeId;
     318
     319    /** User flags (st_flags).
     320     * This field is 0 if this information is not available. */
     321    uint32_t        fFlags;
     322
     323    /** The current generation number (st_gen).
     324     * This field is 0 if this information is not available. */
     325    uint32_t        GenerationId;
     326
     327    /** The device number of a character or block device type object (st_rdev).
     328     * This field is 0 if the file isn't of a character or block device type and
     329     * when the OS doesn't subscribe to the major+minor device idenfication scheme. */
     330    RTDEV           Device;
     331} GSTCTLFSOBJATTRUNIX;
     332
     333/**
     334 * Additional guest Unix attributes (GSTCTLFSOBJATTRADD_UNIX_OWNER).
     335 */
     336typedef struct GSTCTLFSOBJATTRUNIXOWNER
     337{
     338    /** The user owning the filesystem object (st_uid).
     339     * This field is NIL_RTUID if not supported. */
     340    RTUID           uid;
     341    /** The user name.
     342     * Empty if not available or not supported, truncated if too long. */
     343    char            szName[GSTCTLFSOBJATTRUNION_MAX_SIZE - sizeof(RTUID)];
     344} GSTCTLFSOBJATTRUNIXOWNER;
     345
     346/**
     347 * Additional guest Unix attributes (GSTCTLFSOBJATTRADD_UNIX_GROUP).
     348 */
     349typedef struct GSTCTLFSOBJATTRUNIXGROUP
     350{
     351    /** The user owning the filesystem object (st_uid).
     352     * This field is NIL_RTUID if not supported. */
     353    RTGID           gid;
     354    /** The group name.
     355     * Empty if not available or not supported, truncated if too long. */
     356    char            szName[GSTCTLFSOBJATTRUNION_MAX_SIZE - sizeof(RTGID)];
     357} GSTCTLFSOBJATTRUNIXGROUP;
     358
     359/**
     360 * Guest filesystem object attributes.
     361 */
     362#pragma pack(1)
     363typedef struct GSTCTLFSOBJATTR
     364{
     365    /** Mode flags (st_mode). RTFS_UNIX_*, RTFS_TYPE_*, and RTFS_DOS_*. */
     366    RTFMODE                     fMode;
     367
     368    /** The additional attributes available. */
     369    GSTCTLFSOBJATTRADD          enmAdditional;
     370
     371    /**
     372     * Additional attributes.
     373     *
     374     * Unless explicitly specified to an API, the API can provide additional
     375     * data as it is provided by the underlying OS.
     376     */
     377    union GSTCTLFSOBJATTRUNION
     378    {
     379        /** Additional Unix Attributes - GUEST_FSOBJATTRADD_UNIX. */
     380        GSTCTLFSOBJATTRUNIX         Unix;
     381        /** Additional Unix Owner Attributes - GUEST_FSOBJATTRADD_UNIX_OWNER. */
     382        GSTCTLFSOBJATTRUNIXOWNER    UnixOwner;
     383        /** Additional Unix Group Attributes - GUEST_FSOBJATTRADD_UNIX_GROUP. */
     384        GSTCTLFSOBJATTRUNIXGROUP    UnixGroup;
     385
     386        /**
     387         * Extended attribute size is available when RTFS_DOS_HAVE_EA_SIZE is set.
     388         */
     389        struct GSTCTLFSOBJATTREASIZE
     390        {
     391            /** Size of EAs. */
     392            RTFOFF          cb;
     393        } EASize;
     394        /** Reserved space. */
     395        uint8_t         abReserveSpace[128];
     396    } u;
     397} GSTCTLFSOBJATTR;
     398#pragma pack()
     399/** Pointer to a guest filesystem object attributes structure. */
     400typedef GSTCTLFSOBJATTR *PGSTCTLFSOBJATTR;
     401/** Pointer to a const guest filesystem object attributes structure. */
     402typedef const GSTCTLFSOBJATTR *PCGSTCTLFSOBJATTR;
     403
     404/** @name GSTCTL_QUERYINFO_F_XXX - Generic flags for querying guest file system information.
     405 * @{ */
     406/** No guest stat flags specified. */
     407#define GSTCTL_QUERYINFO_F_NONE               UINT32_C(0)
     408/** Last component: Work on the link. */
     409#define GSTCTL_QUERYINFO_F_ON_LINK            RT_BIT_32(0)
     410/** Last component: Follow if link. */
     411#define GSTCTL_QUERYINFO_F_FOLLOW_LINK        RT_BIT_32(1)
     412/** Don't allow symbolic links as part of the path.
     413 * @remarks this flag is currently not implemented and will be ignored. */
     414#define GSTCTL_QUERYINFO_F_NO_SYMLINKS        RT_BIT_32(2)
     415/** GSTCTL_QUERYINFO_F_XXX flag valid mask. */
     416#define GSTCTL_QUERYINFO_F_VALID_MASK         UINT32_C(0x00000007)
     417/** @} */
     418
     419/**
     420 * Filter option for HOST_MSG_DIR_OPEN.
     421 */
     422typedef enum GSTCTLDIRFILTER
     423{
     424    /** The usual invalid 0 entry. */
     425    GSTCTLDIRFILTER_INVALID = 0,
     426    /** No filter should be applied (and none was specified). */
     427    GSTCTLDIRFILTER_NONE,
     428    /** The Windows NT filter.
     429     * The following wildcard chars: *, ?, <, > and "
     430     * The matching is done on the uppercased strings.  */
     431    GSTCTLDIRFILTER_WINNT,
     432    /** The UNIX filter.
     433     * The following wildcard chars: *, ?, [..]
     434     * The matching is done on exact case. */
     435    GSTCTLDIRFILTER_UNIX,
     436    /** The UNIX filter, uppercased matching.
     437     * Same as GSTCTLDIRFILTER_UNIX except that the strings are uppercased before comparing. */
     438    GSTCTLDIRFILTER_UNIX_UPCASED,
     439
     440    /** The usual full 32-bit value. */
     441    GSTCTLDIRFILTER_32BIT_HACK = 0x7fffffff
     442} GSTCTLDIRFILTER;
     443
     444/** @name GSTCTLDIR_F_XXX - Directory flags for HOST_MSG_DIR_OPEN.
     445 * @{ */
     446/** Don't allow symbolic links as part of the path.
     447 * @remarks this flag is currently not implemented and will be ignored. */
     448#define GSTCTLDIR_F_NO_SYMLINKS     RT_BIT_32(0)
     449/** Deny relative opening of anything above this directory. */
     450#define GSTCTLDIR_F_DENY_ASCENT     RT_BIT_32(1)
     451/** Don't follow symbolic links in the final component. */
     452#define GSTCTLDIR_F_NO_FOLLOW       RT_BIT_32(2)
     453/** Long path hack: Don't apply RTPathAbs to the path. */
     454#define GSTCTLDIR_F_NO_ABS_PATH     RT_BIT_32(3)
     455/** Valid flag mask.   */
     456#define GSTCTLDIR_F_VALID_MASK      UINT32_C(0x0000000f)
     457
     458/**
     459 * Guest filesystem object information structure.
     460 *
     461 * This is returned by
     462 *     - GUEST_FS_NOTIFYTYPE_QUERY_INFO
     463 *     - GUEST_DIR_NOTIFYTYPE_READ
     464 */
     465#pragma pack(1)
     466typedef struct GSTCTLFSOBJINFO
     467{
     468   /** Logical size (st_size).
     469    * For normal files this is the size of the file.
     470    * For symbolic links, this is the length of the path name contained
     471    * in the symbolic link.
     472    * For other objects this fields needs to be specified.
     473    */
     474   RTFOFF           cbObject;
     475
     476   /** Disk allocation size (st_blocks * DEV_BSIZE). */
     477   RTFOFF           cbAllocated;
     478
     479   /** Time of last access (st_atime). */
     480   RTTIMESPEC       AccessTime;
     481
     482   /** Time of last data modification (st_mtime). */
     483   RTTIMESPEC       ModificationTime;
     484
     485   /** Time of last status change (st_ctime).
     486    * If not available this is set to ModificationTime.
     487    */
     488   RTTIMESPEC       ChangeTime;
     489
     490   /** Time of file birth (st_birthtime).
     491    * If not available this is set to ChangeTime.
     492    */
     493   RTTIMESPEC       BirthTime;
     494
     495   /** Attributes. */
     496   GSTCTLFSOBJATTR  Attr;
     497
     498} GSTCTLFSOBJINFO;
     499#pragma pack()
     500/** Pointer to a guest filesystem object information structure. */
     501typedef GSTCTLFSOBJINFO *PGSTCTLFSOBJINFO;
     502/** Pointer to a const guest filesystem object information structure. */
     503typedef const GSTCTLFSOBJINFO *PCGSTCTLFSOBJINFO;
     504
     505/**
     506 * Guest directory entry with extended information.
     507 *
     508 * This is inspired by IPRT + the PC interfaces.
     509 */
     510#pragma pack(1)
     511typedef struct GSTCTLDIRENTRYEX
     512{
     513    /** Full information about the guest object. */
     514    GSTCTLFSOBJINFO  Info;
     515    /** The length of the short field (number of RTUTF16 entries (not chars)).
     516     * It is 16-bit for reasons of alignment. */
     517    uint16_t        cwcShortName;
     518    /** The short name for 8.3 compatibility.
     519     * Empty string if not available.
     520     * Since the length is a bit tricky for a UTF-8 encoded name, and since this
     521     * is practically speaking only a windows thing, it is encoded as UCS-2. */
     522    RTUTF16         wszShortName[14];
     523    /** The length of the filename. */
     524    uint16_t        cbName;
     525    /** The filename. (no path)
     526     * Using the pcbDirEntry parameter of RTDirReadEx makes this field variable in size. */
     527    char            szName[260];
     528} GSTCTLDIRENTRYEX;
     529#pragma pack()
     530/** Pointer to a guest directory entry. */
     531typedef GSTCTLDIRENTRYEX *PGSTCTLDIRENTRYEX;
     532/** Pointer to a const guest directory entry. */
     533typedef GSTCTLDIRENTRYEX const *PCGSTCTLDIRENTRYEX;
    232534
    233535} /* namespace guestControl */
  • trunk/include/VBox/HostServices/GuestControlSvc.h

    r98103 r98526  
    4141#endif
    4242
     43#include <iprt/assert.h>
     44#include <VBox/hgcmsvc.h>
     45
    4346#include <VBox/VMMDevCoreTypes.h>
     47#include <VBox/GuestHost/GuestControl.h>
    4448#include <VBox/VBoxGuestCoreTypes.h>
    45 #include <VBox/hgcmsvc.h>
    46 #include <iprt/assert.h>
    4749
    4850/* Everything defined in this file lives in this namespace. */
     
    200202     * Gets the current file position of an opened guest file.
    201203     */
    202     HOST_MSG_FILE_TELL,
     204    HOST_MSG_FILE_TELL = 271,
    203205    /**
    204206     * Changes the file size.
    205207     */
    206     HOST_MSG_FILE_SET_SIZE,
     208    HOST_MSG_FILE_SET_SIZE = 272,
     209#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     210    /**
     211     * Removes a file on the guest.
     212     */
     213    HOST_MSG_FILE_REMOVE = 273,
     214    /**
     215     * Opens (creates) a directory on the guest.
     216     */
     217    HOST_MSG_DIR_OPEN = 310,
     218    /**
     219     * Closes a directory on the guest.
     220     */
     221    HOST_MSG_DIR_CLOSE = 311,
     222    /**
     223     * Reads the next directory entry on the guest.
     224     */
     225    HOST_MSG_DIR_READ = 312,
     226    /**
     227     * Rewinds and restarts the directory reading on the guest.
     228     */
     229    HOST_MSG_DIR_REWIND = 313,
     230    /**
     231     * Creates a directory on the guest.
     232     */
     233    HOST_MSG_DIR_CREATE = 314,
     234#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    207235    /**
    208236     * Removes a directory on the guest.
     
    216244     * Retrieves the user's documents directory.
    217245     */
    218     HOST_MSG_PATH_USER_DOCUMENTS,
     246    HOST_MSG_PATH_USER_DOCUMENTS = 331,
    219247    /**
    220248     * Retrieves the user's home directory.
    221249     */
    222     HOST_MSG_PATH_USER_HOME,
     250    HOST_MSG_PATH_USER_HOME = 332,
    223251    /**
    224252     * Issues a shutdown / reboot of the guest OS.
    225253     */
    226     HOST_MSG_SHUTDOWN,
    227 
     254    HOST_MSG_SHUTDOWN = 333,
     255#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     256    /**
     257     * Retrieves information about a file system object.
     258     */
     259    HOST_MSG_FS_QUERY_INFO = 334,
     260    /**
     261     * Creates a temporary file or directory.
     262     */
     263    HOST_MSG_FS_CREATE_TEMP = 335,
     264#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    228265    /** Blow the type up to 32-bits. */
    229266    HOST_MSG_32BIT_HACK = 0x7fffffff
     
    258295        RT_CASE_RET_STR(HOST_MSG_FILE_TELL);
    259296        RT_CASE_RET_STR(HOST_MSG_FILE_SET_SIZE);
     297#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     298        RT_CASE_RET_STR(HOST_MSG_FILE_REMOVE);
     299        RT_CASE_RET_STR(HOST_MSG_DIR_OPEN);
     300        RT_CASE_RET_STR(HOST_MSG_DIR_CLOSE);
     301        RT_CASE_RET_STR(HOST_MSG_DIR_READ);
     302        RT_CASE_RET_STR(HOST_MSG_DIR_REWIND);
     303        RT_CASE_RET_STR(HOST_MSG_DIR_CREATE);
     304#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    260305        RT_CASE_RET_STR(HOST_MSG_DIR_REMOVE);
    261306        RT_CASE_RET_STR(HOST_MSG_PATH_RENAME);
     
    263308        RT_CASE_RET_STR(HOST_MSG_PATH_USER_HOME);
    264309        RT_CASE_RET_STR(HOST_MSG_SHUTDOWN);
     310#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     311        RT_CASE_RET_STR(HOST_MSG_FS_QUERY_INFO);
     312        RT_CASE_RET_STR(HOST_MSG_FS_CREATE_TEMP);
     313#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    265314        RT_CASE_RET_STR(HOST_MSG_32BIT_HACK);
    266315    }
     
    579628     * @todo proper docs.
    580629     */
    581     GUEST_MSG_FILE_NOTIFY = 240
     630    GUEST_MSG_FILE_NOTIFY = 240,
     631#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     632    /**
     633     *  Guest notifies the host about some file system event.
     634     *
     635     * @retval  VINF_SUCCESS on success.
     636     * @retval  VERR_INVALID_CLIENT_ID
     637     * @retval  VERR_WRONG_PARAMETER_COUNT
     638     * @retval  VERR_WRONG_PARAMETER_TYPE
     639     * @since   7.1
     640     */
     641    GUEST_MSG_FS_NOTIFY  = 241
     642#endif
    582643};
    583644
     
    618679        RT_CASE_RET_STR(GUEST_MSG_DIR_NOTIFY);
    619680        RT_CASE_RET_STR(GUEST_MSG_FILE_NOTIFY);
     681#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     682        RT_CASE_RET_STR(GUEST_MSG_FS_NOTIFY);
     683#endif
    620684    }
    621685    return "Unknown";
    622686}
    623 
    624687
    625688/**
     
    650713/**
    651714 * Guest directory notification types.
    652  * @sa HGCMMsgDirNotify.
     715 * @sa HGCMMsgReplyDirNotify.
    653716 */
    654717enum GUEST_DIR_NOTIFYTYPE
     
    661724    /** Guest directory closed. */
    662725    GUEST_DIR_NOTIFYTYPE_CLOSE = 20,
     726#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     727    /** Guest directory read. */
     728    GUEST_DIR_NOTIFYTYPE_READ = 21,
     729    /** Guest directory was rewind. */
     730    GUEST_DIR_NOTIFYTYPE_REWIND = 22,
     731#endif
    663732    /** Information about an open guest directory. */
    664733    GUEST_DIR_NOTIFYTYPE_INFO = 40,
     
    686755    GUEST_FILE_NOTIFYTYPE_TELL = 60,
    687756    GUEST_FILE_NOTIFYTYPE_SET_SIZE
     757};
     758
     759/**
     760 * Guest file system notification types.
     761 */
     762enum GUEST_FS_NOTIFYTYPE
     763{
     764    /** Unknown fs notification type; do not use. */
     765    GUEST_FS_NOTIFYTYPE_UNKNOWN     = 0,
     766    /** File system query information notification from the guest.
     767     *  @since 7.1 */
     768    GUEST_FS_NOTIFYTYPE_QUERY_INFO  = 2,
     769    /** Temporary directory creation notification from the guest.
     770     *  @since 7.1 */
     771    GUEST_FS_NOTIFYTYPE_CREATE_TEMP = 1,
    688772};
    689773
     
    716800/** Supports shutting down / rebooting the guest. */
    717801#define VBOX_GUESTCTRL_GF_0_SHUTDOWN                RT_BIT_64(3)
     802/** VBoxService' toolbox commands (vbox_rm, vbox_stat, ++) are supported by
     803 * dedicated built-in HGCM commands.
     804 *
     805 * The toolbox commands now are being marked as deprecated.
     806 * @since 7.1 */
     807# define VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS        RT_BIT_64(4)
    718808/** Bit that must be set in the 2nd parameter, will be cleared if the host reponds
    719809 * correctly (old hosts might not). */
     
    804894} HGCMMsgCancelPendingWaits;
    805895
    806 typedef struct HGCMMsgReply
     896/**
     897 * Generic reply header for reply-based messages.
     898 *
     899 * @note Be careful when changing this, as older Guest Additions might depend on this
     900 *       and other stuff can break, too. So better leave this alone.
     901 */
     902typedef struct HGCMReplyHdr
    807903{
    808904    VBGLIOCHGCMCALL hdr;
     
    813909    /** IPRT result of overall operation. */
    814910    HGCMFunctionParameter rc;
    815     /** Optional payload to this reply. */
     911} HGCMReplyHdr;
     912
     913/** Number of HGCM parameters the HGCMReplyHdr has. */
     914#define GSTCTL_HGCM_REPLY_HDR_PARMS     3
     915
     916/**
     917 * Generic reply message from guest to the host.
     918 */
     919typedef struct HGCMMsgReply
     920{
     921    VBGLIOCHGCMCALL hdr;
     922    /** Context ID. */
     923    HGCMFunctionParameter context;
     924    /** Message type. */
     925    HGCMFunctionParameter type;
     926    /** IPRT result of overall operation. */
     927    HGCMFunctionParameter rc;
     928    /** Optional payload to this reply
     929     *  Uses the REPLY_PAYLOAD_XXX structs. */
    816930    HGCMFunctionParameter payload;
    817931} HGCMMsgReply;
     932
     933#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     934/**
     935 * Creates a temporary directory / file on the guest.
     936 */
     937typedef struct HGCMMsgFsCreateTemp
     938{
     939    VBGLIOCHGCMCALL hdr;
     940    /** Context ID. */
     941    HGCMFunctionParameter context;
     942    /** Template name to use for file/directory creation.
     943     *  If \a tmpdir is set, this path will be relative to \a tmpdir and  must not be an absolute path. */
     944    HGCMFunctionParameter template_name;
     945    /** Temporary directory to use.
     946     *  If empty, the guest OS' temporary directory will be determined via IPRT on the guest side. */
     947    HGCMFunctionParameter tmpdir;
     948    /** Creation flags.
     949     *  See GSTCTL_CREATETEMP_F_XXX. */
     950    HGCMFunctionParameter flags;
     951    /** File mode to use for creation (ignored if GSTCTL_CREATETEMP_F_SECURE is defined).
     952     *  See GSTCTL_CREATETEMP_F_XXX. */
     953    HGCMFunctionParameter mode;
     954} HGCMMsgFsCreateTemp;
     955
     956/**
     957 * Queries information for a file system object on the guest.
     958 */
     959typedef struct HGCMMsgFsQueryInfo
     960{
     961    VBGLIOCHGCMCALL hdr;
     962    /** Context ID. */
     963    HGCMFunctionParameter context;
     964    /** Path to query information for. */
     965    HGCMFunctionParameter path;
     966    /** Additional file system attributes to lookup (GSTCTLFSOBJATTRADD). */
     967    HGCMFunctionParameter add_attributes;
     968    /** Flags (GSTCTL_QUERYINFO_F_XXX). */
     969    HGCMFunctionParameter flags;
     970} HGCMMsgFsQueryInfo;
     971#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    818972
    819973/**
     
    8631017    HGCMFunctionParameter result;
    8641018} HGCMMsgSessionNotify;
     1019
     1020#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1021/**
     1022 * Opens a guest directory.
     1023 */
     1024typedef struct HGCMMsgDirOpen
     1025{
     1026    VBGLIOCHGCMCALL hdr;
     1027    /** Context ID. */
     1028    HGCMFunctionParameter context;
     1029    /** Path of directory to open. */
     1030    HGCMFunctionParameter path;
     1031    /** Filter string to use (wildcard style). */
     1032    HGCMFunctionParameter filter;
     1033    /** Filter type to use when walking the directory (GSTCTLDIRFILTER). */
     1034    HGCMFunctionParameter filter_type;
     1035    /** Directory open flags (GSTCTLDIR_F_XXX). */
     1036    HGCMFunctionParameter flags;
     1037} HGCMMsgDirOpen;
     1038
     1039/**
     1040 * Closes a guest directory.
     1041 */
     1042typedef struct HGCMMsgDirClose
     1043{
     1044    VBGLIOCHGCMCALL hdr;
     1045    /** Context ID. */
     1046    HGCMFunctionParameter context;
     1047    /** Directory handle to close. */
     1048    HGCMFunctionParameter handle;
     1049} HGCMMsgDirClose;
     1050
     1051/**
     1052 * Reads the next entry of a guest directory.
     1053 */
     1054typedef struct HGCMMsgDirRead
     1055{
     1056    VBGLIOCHGCMCALL hdr;
     1057    /** Context ID. */
     1058    HGCMFunctionParameter context;
     1059    /** Handle of directory listing to read the next entry for. */
     1060    HGCMFunctionParameter handle;
     1061    /** Custom directory entry size (in bytes) to use. */
     1062    HGCMFunctionParameter entry_size;
     1063    /** Additional directory attributes to use (GSTCTLFSOBJATTRADD). */
     1064    HGCMFunctionParameter add_attributes;
     1065    /** Directory reading flags. */
     1066    HGCMFunctionParameter flags;
     1067} HGCMMsgDirRead;
     1068
     1069/**
     1070 * Rewinds the listing of a guest directory.
     1071 */
     1072typedef struct HGCMMsgDirRewind
     1073{
     1074    VBGLIOCHGCMCALL hdr;
     1075    /** Context ID. */
     1076    HGCMFunctionParameter context;
     1077    /** Handle of directory listing to rewind. */
     1078    HGCMFunctionParameter handle;
     1079} HGCMMsgDirRewind;
     1080
     1081/**
     1082 * Creates a directory on the guest.
     1083 */
     1084typedef struct HGCMMsgDirCreate
     1085{
     1086    VBGLIOCHGCMCALL hdr;
     1087    /** Context ID. */
     1088    HGCMFunctionParameter context;
     1089    /** Path of directory to create. */
     1090    HGCMFunctionParameter path;
     1091    /** Creation mode. */
     1092    HGCMFunctionParameter mode;
     1093    /** Creation flags (GSTCTL_CREATEDIRECTORY_F_XXX). */
     1094    HGCMFunctionParameter flags;
     1095} HGCMMsgDirCreate;
     1096#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    8651097
    8661098typedef struct HGCMMsgPathRename
     
    12141446} HGCMMsgFileSetSize;
    12151447
     1448/**
     1449 * Removes (deletes) a guest file.
     1450 *
     1451 * @since 7.1
     1452 */
     1453typedef struct HGCMMsgFileRemove
     1454{
     1455    VBGLIOCHGCMCALL       hdr;
     1456    /** UInt32: Context ID. */
     1457    HGCMFunctionParameter context;
     1458    /** File to open. */
     1459    HGCMFunctionParameter filename;
     1460} HGCMMsgFileRemove;
     1461
    12161462
    12171463/******************************************************************************
     
    12781524typedef struct HGCMReplyDirNotify
    12791525{
    1280     VBGLIOCHGCMCALL hdr;
    1281     /** Context ID. */
    1282     HGCMFunctionParameter context;
    1283     /** Notification type. */
    1284     HGCMFunctionParameter type;
    1285     /** IPRT result of overall operation. */
    1286     HGCMFunctionParameter rc;
     1526    /** The generic reply header. */
     1527    HGCMReplyHdr reply_hdr;
     1528    /** Union based on \a reply_hdr.type. */
    12871529    union
    12881530    {
    1289         struct
    1290         {
    1291             /** Directory information. */
    1292             HGCMFunctionParameter objInfo;
    1293         } info;
     1531        /**
     1532         * Parameters used for \a type GUEST_DIR_NOTIFYTYPE_OPEN.
     1533         *
     1534         * @since 7.1
     1535         */
    12941536        struct
    12951537        {
     
    12971539            HGCMFunctionParameter handle;
    12981540        } open;
    1299         struct
    1300         {
    1301             /** Current read directory entry. */
     1541        /**
     1542         * Parameters used for \a type GUEST_DIR_NOTIFYTYPE_READ.
     1543         *
     1544         * @since 7.1
     1545         */
     1546        struct
     1547        {
     1548            /** Current read directory entry (GSTCTLDIRENTRYEX). */
    13021549            HGCMFunctionParameter entry;
    1303             /** Extended entry object information. Optional. */
    1304             HGCMFunctionParameter objInfo;
     1550            /** Resolved user ID as a string (uid). */
     1551            HGCMFunctionParameter user;
     1552            /** Resolved group IDs as a string.
     1553             *
     1554             *  Multiple groups are delimited by "\r\n", whereas
     1555             *  the first group always is the primary group. */
     1556            HGCMFunctionParameter groups;
     1557            /** @todo ACL; not implemented yet.
     1558             * Windows ACL, defined in SDDL. */
     1559            HGCMFunctionParameter acl;
    13051560        } read;
    13061561    } u;
    13071562} HGCMReplyDirNotify;
    13081563
     1564/**
     1565 * Reply to a HOST_MSG_FS_QUERY_INFO or HOST_MSG_FS_CREATE_TEMP message.
     1566 *
     1567 * @since 7.1
     1568 */
     1569typedef struct HGCMReplyFsNotify
     1570{
     1571    /** The generic reply header. */
     1572    HGCMReplyHdr reply_hdr;
     1573    /** Union based on \a reply_hdr.type. */
     1574    union
     1575    {
     1576        /**
     1577         * Parameters used for \a type GUEST_FS_NOTIFYTYPE_QUERY_INFO.
     1578         *
     1579         * @since 7.1
     1580         */
     1581        struct
     1582        {
     1583            /** File system object information (GSTCTLFSOBJINFO). */
     1584            HGCMFunctionParameter obj_info;
     1585            /** Resolved user ID as a string (uid). */
     1586            HGCMFunctionParameter user;
     1587            /** Resolved group IDs as a string.
     1588             *
     1589             *  Multiple groups are delimited by "\r\n", whereas
     1590             *  the first group always is the primary group. */
     1591            HGCMFunctionParameter groups;
     1592            /** @todo ACL; not implemented yet.
     1593             * Windows ACL, defined in SDDL. */
     1594            HGCMFunctionParameter acl;
     1595        } queryinfo;
     1596        /**
     1597         * Parameters used for \a type GUEST_FS_NOTIFYTYPE_CREATE_TEMP.
     1598         *
     1599         * @since 7.1
     1600         */
     1601        struct
     1602        {
     1603            /** The create temporary file / directory when \a rc
     1604             *  indicates success. */
     1605            HGCMFunctionParameter path;
     1606        } createtemp;
     1607    } u;
     1608} HGCMReplyFsNotify;
    13091609#pragma pack ()
     1610
    13101611
    13111612/******************************************************************************
     
    14211722        struct
    14221723        {
    1423             /** Size (in bytes) of directory information. */
    1424             uint32_t cbObjInfo;
    14251724            /** Pointer to directory information. */
    1426             void *pvObjInfo;
     1725            PGSTCTLFSOBJINFO pObjInfo;
    14271726        } info;
    14281727        struct
     
    14351734        {
    14361735            /** Size (in bytes) of directory entry information. */
    1437             uint32_t cbEntry;
     1736            uint32_t          cbEntry;
    14381737            /** Pointer to directory entry information. */
    1439             void *pvEntry;
    1440             /** Size (in bytes) of directory entry object information. */
    1441             uint32_t cbObjInfo;
    1442             /** Pointer to directory entry object information. */
    1443             void *pvObjInfo;
     1738            GSTCTLDIRENTRYEX *pEntry;
    14441739        } read;
    14451740    } u;
     
    14951790} CALLBACKDATA_FILE_NOTIFY, *PCALLBACKDATA_FILE_NOTIFY;
    14961791
     1792
     1793/*******************************************************************************
     1794* Payload structures for the generic reply message (HGCMMsgReply).             *
     1795*                                                                              *
     1796* The name suffix must match the host command name, e.g.                       *
     1797*     Host command HOST_MSG_FOO_BAR -> REPLY_PAYLOAD_FOO_BAR                   *
     1798*******************************************************************************/
     1799
     1800typedef struct REPLY_PAYLOAD_FS_QUERY_INFO
     1801{
     1802    GSTCTLFSOBJINFO objInfo;
     1803
     1804} REPLY_PAYLOAD_FS_QUERY_INFO;
    14971805} /* namespace guestControl */
    14981806
  • trunk/include/VBox/VBoxGuestLib.h

    r98472 r98526  
    4040#  include <VBox/GuestHost/DragAndDrop.h>
    4141#  include <VBox/GuestHost/DragAndDropDefs.h>
     42# endif
     43# ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     44#  include <VBox/GuestHost/GuestControl.h>
     45   using namespace guestControl;
    4246# endif
    4347# ifdef VBOX_WITH_SHARED_CLIPBOARD
     
    10791083VBGLR3DECL(int) VbglR3GuestCtrlSessionGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, PVBGLR3GUESTCTRLSESSIONSTARTUPINFO *ppStartupInfo);
    10801084VBGLR3DECL(int) VbglR3GuestCtrlSessionGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfFlags, uint32_t *pidSession);
     1085VBGLR3DECL(int) VbglR3GuestCtrlFileGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
     1086VBGLR3DECL(int) VbglR3GuestCtrlFileGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *puToRead);
    10811087/* Guest path handling. */
    10821088VBGLR3DECL(int) VbglR3GuestCtrlPathGetRename(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszSource, uint32_t cbSource, char *pszDest,
     
    10841090VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserDocuments(PVBGLR3GUESTCTRLCMDCTX pCtx);
    10851091VBGLR3DECL(int) VbglR3GuestCtrlPathGetUserHome(PVBGLR3GUESTCTRLCMDCTX pCtx);
     1092#  ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1093/** @name Guest Control file system functions.
     1094 * @{
     1095 */
     1096VBGLR3DECL(int) VbglR3GuestCtrlFsGetQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, GSTCTLFSOBJATTRADD *penmAddAttrib, uint32_t *pfFlags);
     1097VBGLR3DECL(int) VbglR3GuestCtrlFsGetCreateTemp(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszTemplate, uint32_t cbTemplate, char *pszPath, uint32_t cbPath, uint32_t *pfFlags, uint32_t *pfMode);
     1098/** @} */
     1099#  endif
    10861100VBGLR3DECL(int) VbglR3GuestCtrlGetShutdown(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *pfAction);
    10871101/* Guest process execution. */
     
    10991113                                              uint32_t *puTimeoutMS);
    11001114/* Guest native directory handling. */
     1115#  ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1116/** @name Guest Control directory functions.
     1117 * @{
     1118 */
     1119VBGLR3DECL(int) VbglR3GuestCtrlDirGetCreate(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfMode, uint32_t *pfFlags);
     1120VBGLR3DECL(int) VbglR3GuestCtrlDirGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfFlags, GSTCTLDIRFILTER *penmFilter);
     1121VBGLR3DECL(int) VbglR3GuestCtrlDirGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
     1122VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *pcbDirEntry, uint32_t *penmAddAttrib, uint32_t *pfFlags);
     1123VBGLR3DECL(int) VbglR3GuestCtrlDirGetRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
     1124/** @} */
     1125#  endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    11011126VBGLR3DECL(int) VbglR3GuestCtrlDirGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfFlags);
    11021127/* Guest native file handling. */
     
    11161141VBGLR3DECL(int) VbglR3GuestCtrlFileGetTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle);
    11171142VBGLR3DECL(int) VbglR3GuestCtrlFileGetSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint64_t *pcbNew);
     1143#  ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1144VBGLR3DECL(int) VbglR3GuestCtrlFileGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszFileName, uint32_t cbFileName);
     1145#  endif
    11181146
    11191147/* Guest -> Host. */
     1148#  ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1149/** @name Guest Control directory callbacks.
     1150 * @{
     1151 */
     1152VBGLR3DECL(int) VbglR3GuestCtrlDirCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uFileHandle);
     1153VBGLR3DECL(int) VbglR3GuestCtrlDirCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc);
     1154VBGLR3DECL(int) VbglR3GuestCtrlDirCbReadEx(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLDIRENTRYEX pEntry, uint32_t cbSize, char *pszUser, char *pszGroups, void *pvACL, size_t cbACL);
     1155VBGLR3DECL(int) VbglR3GuestCtrlDirCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLDIRENTRYEX pEntry, uint32_t cbSize);
     1156VBGLR3DECL(int) VbglR3GuestCtrlDirCbRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc);
     1157/** @} */
     1158#  endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1159
    11201160VBGLR3DECL(int) VbglR3GuestCtrlFileCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uFileHandle);
    11211161VBGLR3DECL(int) VbglR3GuestCtrlFileCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc);
    11221162VBGLR3DECL(int) VbglR3GuestCtrlFileCbError(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc);
    11231163VBGLR3DECL(int) VbglR3GuestCtrlFileCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, void *pvData, uint32_t cbData);
    1124 VBGLR3DECL(int) VbglR3GuestCtrlFileCbReadOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc,
    1125                                                 void *pvData, uint32_t cbData, int64_t offNew);
     1164VBGLR3DECL(int) VbglR3GuestCtrlFileCbReadOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, void *pvData, uint32_t cbData, int64_t offNew);
    11261165VBGLR3DECL(int) VbglR3GuestCtrlFileCbWrite(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten);
    11271166VBGLR3DECL(int) VbglR3GuestCtrlFileCbWriteOffset(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t cbWritten, int64_t offNew);
     
    11301169VBGLR3DECL(int) VbglR3GuestCtrlFileCbTell(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t offCurrent);
    11311170VBGLR3DECL(int) VbglR3GuestCtrlFileCbSetSize(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint64_t cbNew);
    1132 VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uStatus, uint32_t fFlags,
    1133                                             void *pvData, uint32_t cbData);
    1134 VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uHandle, uint32_t fFlags,
    1135                                             void *pvData, uint32_t cbData);
    1136 VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t u32PID, uint32_t uStatus,
    1137                                                  uint32_t fFlags, uint32_t cbWritten);
    1138 
    1139 /** @}  */
     1171
     1172#  ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1173/** @name Guest Control file system callbacks.
     1174 * @{
     1175 */
     1176VBGLR3DECL(int) VbglR3GuestCtrlFsCbQueryInfoEx(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSOBJINFO pObjInfo, char *pszUser, char *pszGroups, void *pvACL, uint32_t cbACL);
     1177VBGLR3DECL(int) VbglR3GuestCtrlFsCbQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSOBJINFO pObjInfo);
     1178VBGLR3DECL(int) VbglR3GuestCtrlFsCbCreateTemp(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, const char *pszPath);
     1179/** @} */
     1180#  endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1181
     1182VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatus(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uStatus, uint32_t fFlags, void *pvData, uint32_t cbData);
     1183VBGLR3DECL(int) VbglR3GuestCtrlProcCbOutput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uPID, uint32_t uHandle, uint32_t fFlags, void *pvData, uint32_t cbData);
     1184VBGLR3DECL(int) VbglR3GuestCtrlProcCbStatusInput(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t u32PID, uint32_t uStatus, uint32_t fFlags, uint32_t cbWritten);
    11401185# endif /* VBOX_WITH_GUEST_CONTROL defined */
    11411186
  • trunk/include/VBox/log.h

    r98103 r98526  
    491491    /** Main group, IGuestDirectory. */
    492492    LOG_GROUP_MAIN_GUESTDIRECTORY,
     493    /** Main group, IGuestDirectoryEvent. */
     494    LOG_GROUP_MAIN_GUESTDIRECTORYEVENT,
    493495    /** Main group, IGuestDnDSource. */
    494496    LOG_GROUP_MAIN_GUESTDNDSOURCE,
     
    10631065    "MAIN_GUESTDEBUGCONTROL", \
    10641066    "MAIN_GUESTDIRECTORY", \
     1067    "MAIN_GUESTDIRECTORYEVENT", \
    10651068    "MAIN_GUESTDNDSOURCE", \
    10661069    "MAIN_GUESTDNDTARGET", \
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/Makefile.kmk

    r98416 r98526  
    121121        $(if $(VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS),VBOX_WITH_SHARED_CLIPBOARD_TRANSFERS,) \
    122122        $(if $(VBOX_WITH_SHARED_FOLDERS),VBOX_WITH_SHARED_FOLDERS,) \
    123         $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,)
     123        $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,) \
     124        $(if $(VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS),VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS,)
    124125VBoxGuestR3Lib_SOURCES     = \
    125126        VBoxGuestR3Lib.cpp \
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp

    r98103 r98526  
    980980
    981981
     982#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     983/**
     984 * Retrieves a HOST_MSG_DIR_OPEN message.
     985 *
     986 * @returns VBox status code.
     987 * @param   pCtx                Guest control command context to use.
     988 * @param   pszPath             Where to return the directory path to open.
     989 * @param   cbPath              Size (in bytes) of \a pszPath.
     990 * @param   pfFlags             Where to return the directory listing flags.
     991 * @param   enmFilter           Where to return the directory filter type.
     992 */
     993VBGLR3DECL(int) VbglR3GuestCtrlDirGetOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfFlags,
     994                                          GSTCTLDIRFILTER *penmFilter)
     995{
     996    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     997    AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
     998
     999    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     1000    AssertReturn(cbPath, VERR_INVALID_PARAMETER);
     1001    AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
     1002    AssertPtrReturn(penmFilter, VERR_INVALID_POINTER);
     1003
     1004    int rc;
     1005    do
     1006    {
     1007        HGCMMsgDirOpen Msg;
     1008        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1009        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_OPEN);
     1010        VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
     1011        VbglHGCMParmUInt64Set(&Msg.flags, 0);
     1012        VbglHGCMParmUInt64Set(&Msg.filter, 0);
     1013
     1014        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1015        if (RT_SUCCESS(rc))
     1016        {
     1017            Msg.context.GetUInt32(&pCtx->uContextID);
     1018            Msg.flags.GetUInt32(pfFlags);
     1019            Msg.filter.GetUInt32((uint32_t *)penmFilter);
     1020        }
     1021    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1022    return rc;
     1023}
     1024
     1025
     1026/**
     1027 * Retrieves a HOST_MSG_DIR_CLOSE message.
     1028 *
     1029 * @returns VBox status code.
     1030 * @param   pCtx                Guest control command context to use.
     1031 * @param   puHandle            Where to return the handle of the guest directory to close.
     1032 */
     1033VBGLR3DECL(int) VbglR3GuestCtrlDirGetClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
     1034{
     1035    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1036    AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
     1037
     1038    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
     1039
     1040    int rc;
     1041    do
     1042    {
     1043        HGCMMsgDirClose Msg;
     1044        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1045        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_CLOSE);
     1046        VbglHGCMParmUInt64Set(&Msg.handle, 0);
     1047
     1048        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1049        if (RT_SUCCESS(rc))
     1050        {
     1051            Msg.context.GetUInt32(&pCtx->uContextID);
     1052            Msg.handle.GetUInt32(puHandle);
     1053        }
     1054    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1055    return rc;
     1056}
     1057
     1058
     1059/**
     1060 * Retrieves a HOST_MSG_DIR_READ message.
     1061 *
     1062 * @returns VBox status code.
     1063 * @param   pCtx                Guest control command context to use.
     1064 * @param   puHandle            Where to return the directory handle to rewind.
     1065 * @param   pcbDirEntry         Where to return the directory entry size.
     1066 * @param   penmAddAttrib       Where to return the additional attributes enumeration.
     1067 * @param   pfFlags             Where to return the directory reading flags..
     1068 */
     1069VBGLR3DECL(int) VbglR3GuestCtrlDirGetRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle, uint32_t *pcbDirEntry,
     1070                                          uint32_t *penmAddAttrib, uint32_t *pfFlags)
     1071{
     1072    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1073    AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
     1074
     1075    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
     1076    AssertPtrReturn(pcbDirEntry, VERR_INVALID_POINTER);
     1077    AssertPtrReturn(penmAddAttrib, VERR_INVALID_POINTER);
     1078    AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
     1079
     1080    int rc;
     1081    do
     1082    {
     1083        HGCMMsgDirRead Msg;
     1084        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1085        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_READ);
     1086        VbglHGCMParmUInt64Set(&Msg.handle, 0);
     1087        VbglHGCMParmUInt32Set(&Msg.entry_size, 0);
     1088        VbglHGCMParmUInt32Set(&Msg.add_attributes, 0);
     1089        VbglHGCMParmUInt32Set(&Msg.flags, 0);
     1090
     1091        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1092        if (RT_SUCCESS(rc))
     1093        {
     1094            Msg.context.GetUInt32(&pCtx->uContextID);
     1095            Msg.handle.GetUInt32(puHandle);
     1096            Msg.entry_size.GetUInt32(pcbDirEntry);
     1097            Msg.add_attributes.GetUInt32(penmAddAttrib);
     1098            Msg.flags.GetUInt32(pfFlags);
     1099        }
     1100    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1101    return rc;
     1102}
     1103
     1104
     1105/**
     1106 * Retrieves a HOST_MSG_DIR_REWIND message.
     1107 *
     1108 * @returns VBox status code.
     1109 * @param   pCtx                Guest control command context to use.
     1110 * @param   puHandle            Where to return the directory handle to rewind.
     1111 */
     1112VBGLR3DECL(int) VbglR3GuestCtrlDirGetRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t *puHandle)
     1113{
     1114    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1115    AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
     1116
     1117    AssertPtrReturn(puHandle, VERR_INVALID_POINTER);
     1118
     1119    int rc;
     1120    do
     1121    {
     1122        HGCMMsgDirRewind Msg;
     1123        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1124        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_REWIND);
     1125        VbglHGCMParmUInt64Set(&Msg.handle, 0);
     1126
     1127        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1128        if (RT_SUCCESS(rc))
     1129        {
     1130            Msg.context.GetUInt32(&pCtx->uContextID);
     1131            Msg.handle.GetUInt32(puHandle);
     1132        }
     1133    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1134    return rc;
     1135}
     1136#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1137
     1138
    9821139/**
    9831140 * Retrieves a HOST_PATH_RENAME message.
     
    10631220    return rc;
    10641221}
     1222
     1223
     1224#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1225/**
     1226 * Retrieves a HOST_MSG_FS_QUERY_INFO message.
     1227 *
     1228 * @returns VBox status code.
     1229 * @param   pCtx                Guest control command context to use.
     1230 * @param   pszPath             Where to return the path of the file system object to query.
     1231 * @param   cbPath              Size (in bytes) of \a pszPath.
     1232 * @param   penmAddAttrib       Where to return the additional attributes enumeration.
     1233 * @param   pfFlags             Where to return the flags for .
     1234 */
     1235VBGLR3DECL(int) VbglR3GuestCtrlFsGetQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx,
     1236                                              char *pszPath, uint32_t cbPath, GSTCTLFSOBJATTRADD *penmAddAttrib, uint32_t *pfFlags)
     1237{
     1238    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1239    AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
     1240
     1241    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     1242    AssertReturn(cbPath, VERR_INVALID_PARAMETER);
     1243    AssertPtrReturn(penmAddAttrib, VERR_INVALID_POINTER);
     1244    AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
     1245
     1246    int rc;
     1247    do
     1248    {
     1249        HGCMMsgFsQueryInfo Msg;
     1250        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1251        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FS_QUERY_INFO);
     1252        VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
     1253        VbglHGCMParmUInt32Set(&Msg.add_attributes, 0);
     1254        VbglHGCMParmUInt32Set(&Msg.flags, 0);
     1255
     1256        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1257        if (RT_SUCCESS(rc))
     1258        {
     1259            Msg.context.GetUInt32(&pCtx->uContextID);
     1260            Msg.add_attributes.GetUInt32((uint32_t *)penmAddAttrib);
     1261            Msg.flags.GetUInt32(pfFlags);
     1262        }
     1263
     1264    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1265    return rc;
     1266}
     1267
     1268
     1269/**
     1270 * Retrieves a HOST_MSG_FS_CREATE_TEMP message.
     1271 *
     1272 * @returns VBox status code.
     1273 * @param   pCtx                Guest control command context to use.
     1274 * @param   pszTemplate         Where to return the template name.
     1275 * @param   cbTemplate          Size (in bytes) of \a pszTemplate.
     1276 * @param   pszPath             Where to return the temporary directory path.
     1277 * @param   cbTemplate          Size (in bytes) of \a pszPath.
     1278 * @param   pfFlags             Where to return the creation flags.
     1279 * @param   pfMode              Where to return the creation mode.
     1280 */
     1281VBGLR3DECL(int) VbglR3GuestCtrlFsGetCreateTemp(PVBGLR3GUESTCTRLCMDCTX pCtx,
     1282                                               char *pszTemplate, uint32_t cbTemplate, char *pszPath, uint32_t cbPath,
     1283                                               uint32_t *pfFlags, uint32_t *pfMode)
     1284{
     1285    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1286    AssertReturn(pCtx->uNumParms == 5, VERR_INVALID_PARAMETER);
     1287
     1288    AssertPtrReturn(pszTemplate, VERR_INVALID_POINTER);
     1289    AssertReturn(cbTemplate, VERR_INVALID_PARAMETER);
     1290    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     1291    AssertReturn(cbPath, VERR_INVALID_PARAMETER);
     1292    AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
     1293    AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
     1294
     1295    int rc;
     1296    do
     1297    {
     1298        HGCMMsgFsCreateTemp Msg;
     1299        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1300        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FS_CREATE_TEMP);
     1301        VbglHGCMParmPtrSet(&Msg.template_name, pszTemplate, cbTemplate);
     1302        VbglHGCMParmPtrSet(&Msg.tmpdir, pszPath, cbPath);
     1303        VbglHGCMParmUInt32Set(&Msg.flags, 0);
     1304        VbglHGCMParmUInt32Set(&Msg.mode, 0);
     1305
     1306        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1307        if (RT_SUCCESS(rc))
     1308        {
     1309            Msg.context.GetUInt32(&pCtx->uContextID);
     1310            Msg.flags.GetUInt32(pfFlags);
     1311            Msg.mode.GetUInt32(pfMode);
     1312        }
     1313
     1314    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1315    return rc;
     1316}
     1317#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1318
    10651319
    10661320/**
     
    14691723
    14701724
     1725#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1726/**
     1727 * Retrieves a HOST_MSG_DIR_CREATE message.
     1728 *
     1729 * @returns VBox status code.
     1730 * @param   pCtx                Guest control command context to use.
     1731 * @param   pszPath             Where to return the path.
     1732 * @param   cbPath              Size (in bytes) of \a pszPath.
     1733 * @param   pfMode              Where to return the creation mode.
     1734 * @param   pfFlags             Where to return the creation flags (GSTCTL_CREATEDIRECTORY_F_XXX).
     1735 */
     1736VBGLR3DECL(int) VbglR3GuestCtrlDirGetCreate(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszPath, uint32_t cbPath, uint32_t *pfMode, uint32_t *pfFlags)
     1737{
     1738    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     1739    AssertReturn(pCtx->uNumParms == 4, VERR_INVALID_PARAMETER);
     1740
     1741    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     1742    AssertReturn(cbPath, VERR_INVALID_PARAMETER);
     1743    AssertPtrReturn(pfFlags, VERR_INVALID_POINTER);
     1744    AssertPtrReturn(pfMode, VERR_INVALID_POINTER);
     1745
     1746    int rc;
     1747    do
     1748    {
     1749        HGCMMsgDirCreate Msg;
     1750        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     1751        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_DIR_CREATE);
     1752        VbglHGCMParmPtrSet(&Msg.path, pszPath, cbPath);
     1753        VbglHGCMParmUInt32Set(&Msg.mode, 0);
     1754        VbglHGCMParmUInt32Set(&Msg.flags, 0);
     1755
     1756        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     1757        if (RT_SUCCESS(rc))
     1758        {
     1759            Msg.context.GetUInt32(&pCtx->uContextID);
     1760            Msg.flags.GetUInt32(pfFlags);
     1761            Msg.mode.GetUInt32(pfMode);
     1762        }
     1763
     1764    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     1765    return rc;
     1766}
     1767#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1768
     1769
    14711770/**
    14721771 * Retrieves a HOST_DIR_REMOVE message.
     
    18282127
    18292128
     2129#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2130VBGLR3DECL(int) VbglR3GuestCtrlFileGetRemove(PVBGLR3GUESTCTRLCMDCTX pCtx, char *pszFileName, uint32_t cbFileName)
     2131{
     2132    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2133
     2134    AssertReturn(pCtx->uNumParms == 2, VERR_INVALID_PARAMETER);
     2135    AssertPtrReturn(pszFileName, VERR_INVALID_POINTER);
     2136    AssertReturn(cbFileName, VERR_INVALID_PARAMETER);
     2137
     2138    int rc;
     2139    do
     2140    {
     2141        HGCMMsgFileRemove Msg;
     2142        VBGL_HGCM_HDR_INIT(&Msg.hdr, pCtx->uClientID, vbglR3GuestCtrlGetMsgFunctionNo(pCtx->uClientID), pCtx->uNumParms);
     2143        VbglHGCMParmUInt32Set(&Msg.context, HOST_MSG_FILE_REMOVE);
     2144        VbglHGCMParmPtrSet(&Msg.filename, pszFileName, cbFileName);
     2145
     2146        rc = VbglR3HGCMCall(&Msg.hdr, sizeof(Msg));
     2147        if (RT_SUCCESS(rc))
     2148        {
     2149            Msg.context.GetUInt32(&pCtx->uContextID);
     2150        }
     2151    } while (rc == VERR_INTERRUPTED && g_fVbglR3GuestCtrlHavePeekGetCancel);
     2152    return rc;
     2153}
     2154#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     2155
     2156
    18302157/**
    18312158 * Retrieves a HOST_EXEC_TERMINATE message.
     
    18902217}
    18912218
     2219
     2220/*********************************************************************************************************************************
     2221 * Directory callbacks                                                                                                           *
     2222 ********************************************************************************************************************************/
     2223
     2224#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2225/**
     2226 * Replies to a HOST_MSG_DIR_OPEN message.
     2227 *
     2228 * @returns VBox status code.
     2229 * @param   pCtx                Guest control command context to use.
     2230 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2231 * @param   uDirHandle          Directory handle of opened directory.
     2232 */
     2233VBGLR3DECL(int) VbglR3GuestCtrlDirCbOpen(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, uint32_t uDirHandle)
     2234{
     2235    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2236
     2237    HGCMReplyDirNotify Msg;
     2238    VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY,
     2239                       RT_SUCCESS((int)uRc) ? GSTCTL_HGCM_REPLY_HDR_PARMS + 1 : GSTCTL_HGCM_REPLY_HDR_PARMS);
     2240    VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
     2241    VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_OPEN);
     2242    VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
     2243
     2244    if (RT_SUCCESS((int)uRc))
     2245        VbglHGCMParmUInt32Set(&Msg.u.open.handle, uDirHandle);
     2246
     2247    return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u.open));
     2248}
     2249
     2250
     2251/**
     2252 * Replies to a HOST_MSG_DIR_CLOSE message.
     2253 *
     2254 * @returns VBox status code.
     2255 * @param   pCtx                Guest control command context to use.
     2256 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2257 */
     2258VBGLR3DECL(int) VbglR3GuestCtrlDirCbClose(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
     2259{
     2260    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2261
     2262    HGCMReplyDirNotify Msg;
     2263    VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS);
     2264    VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
     2265    VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_CLOSE);
     2266    VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
     2267
     2268    return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u));
     2269}
     2270
     2271
     2272/**
     2273 * Replies to a HOST_MSG_DIR_READ message, extended version.
     2274 *
     2275 * @returns VBox status code.
     2276 * @param   pCtx                Guest control command context to use.
     2277 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2278 * @param   pEntry              Directory entry to send.
     2279 * @param   cbSize              Size (in bytes) of \a pDirEntry to send.
     2280 *                              This might be needed as the size can be bigger than GSTCTLDIRENTRYEX.
     2281 *                              See RTDirReadEx() for more information.
     2282 * @param   pszUser             Associated user ID (owner, uid) as a string.
     2283 * @param   pszGroups           Associated user groups as a string.
     2284 *                              Multiple groups are delimited by "\r\n", whereas the first group always is the primary group.
     2285 * @param   pvACL               ACL block to send.
     2286 * @param   cbACL               Size (in bytes) of ACL block to send.
     2287 */
     2288VBGLR3DECL(int) VbglR3GuestCtrlDirCbReadEx(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLDIRENTRYEX pEntry, uint32_t cbSize,
     2289                                           char *pszUser, char *pszGroups, void *pvACL, size_t cbACL)
     2290{
     2291    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2292    AssertReturn(RT_FAILURE((int)uRc) || pszUser, VERR_INVALID_POINTER);
     2293    AssertReturn(RT_FAILURE((int)uRc) || pszGroups, VERR_INVALID_POINTER);
     2294    AssertReturn(RT_FAILURE((int)uRc) || pvACL, VERR_INVALID_POINTER);
     2295    AssertReturn(RT_FAILURE((int)uRc) || cbACL, VERR_INVALID_PARAMETER);
     2296
     2297    HGCMReplyDirNotify Msg;
     2298    VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY,
     2299                       RT_SUCCESS((int)uRc) ? GSTCTL_HGCM_REPLY_HDR_PARMS + 4 : GSTCTL_HGCM_REPLY_HDR_PARMS);
     2300    VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
     2301    VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_READ);
     2302    VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
     2303
     2304    if (RT_SUCCESS((int)uRc))
     2305    {
     2306        VbglHGCMParmPtrSet(&Msg.u.read.entry, pEntry, cbSize);
     2307        VbglHGCMParmPtrSetString(&Msg.u.read.user,   pszUser);
     2308        VbglHGCMParmPtrSetString(&Msg.u.read.groups, pszGroups);
     2309        VbglHGCMParmPtrSet      (&Msg.u.read.acl,    pvACL, cbACL);
     2310    }
     2311
     2312    return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u.read));
     2313}
     2314
     2315
     2316/**
     2317 * Replies to a HOST_MSG_DIR_READ message.
     2318 *
     2319 * @returns VBox status code.
     2320 * @param   pCtx                Guest control command context to use.
     2321 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2322 * @param   pEntry              Directory entry to send.
     2323 * @param   cbSize              Size (in bytes) of \a pDirEntry to send.
     2324 *                              This might be needed as the size can be bigger than GSTCTLDIRENTRYEX.
     2325 *                              See RTDirReadEx() for more information.
     2326 */
     2327VBGLR3DECL(int) VbglR3GuestCtrlDirCbRead(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLDIRENTRYEX pEntry, uint32_t cbSize)
     2328{
     2329    char szIgnored[1];
     2330    return VbglR3GuestCtrlDirCbReadEx(pCtx, uRc, pEntry, cbSize, szIgnored /* pszUser */, szIgnored /* pszGroups */,
     2331                                      szIgnored /* pvACL */, sizeof(szIgnored) /* cbACL */);
     2332}
     2333
     2334
     2335/**
     2336 * Replies to a HOST_MSG_DIR_REWIND message.
     2337 *
     2338 * @returns VBox status code.
     2339 * @param   pCtx                Guest control command context to use.
     2340 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2341 */
     2342VBGLR3DECL(int) VbglR3GuestCtrlDirCbRewind(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc)
     2343{
     2344    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2345
     2346    HGCMReplyDirNotify Msg;
     2347    VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_DIR_NOTIFY, GSTCTL_HGCM_REPLY_HDR_PARMS);
     2348    VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
     2349    VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_DIR_NOTIFYTYPE_REWIND);
     2350    VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
     2351
     2352    return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u));
     2353}
     2354#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     2355
     2356
     2357/*********************************************************************************************************************************
     2358 * File callbacks                                                                                                                *
     2359 ********************************************************************************************************************************/
    18922360
    18932361/**
     
    21282596
    21292597
     2598/*********************************************************************************************************************************
     2599 * File system callbacks                                                                                                         *
     2600 ********************************************************************************************************************************/
     2601
     2602#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2603/**
     2604 * Replies to a HOST_MSG_FS_QUERY_INFO message, extended version.
     2605 *
     2606 * @returns VBox status code.
     2607 * @param   pCtx                Guest control command context to use.
     2608 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2609 * @param   pFsObjInfo          Guest file system object information to send.
     2610 * @param   pszUser             Associated user ID (owner, uid) as a string.
     2611 * @param   pszGroups           Associated user groups as a string.
     2612 *                              Multiple groups are delimited by "\r\n", whereas the first group always is the primary group.
     2613 * @param   pvACL               ACL block to send.
     2614 * @param   cbACL               Size (in bytes) of ACL block to send.
     2615 */
     2616VBGLR3DECL(int) VbglR3GuestCtrlFsCbQueryInfoEx(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSOBJINFO pFsObjInfo,
     2617                                               char *pszUser, char *pszGroups, void *pvACL, uint32_t cbACL)
     2618{
     2619    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2620    AssertPtrReturn(pFsObjInfo, VERR_INVALID_POINTER);
     2621    AssertPtrReturn(pszUser, VERR_INVALID_POINTER);
     2622    AssertPtrReturn(pszGroups, VERR_INVALID_POINTER);
     2623    AssertPtrReturn(pvACL, VERR_INVALID_POINTER);
     2624    AssertReturn(cbACL, VERR_INVALID_PARAMETER);
     2625
     2626    HGCMReplyFsNotify Msg;
     2627    VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_FS_NOTIFY, 4);
     2628    VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
     2629    VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_FS_NOTIFYTYPE_QUERY_INFO);
     2630    VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
     2631    VbglHGCMParmPtrSet      (&Msg.u.queryinfo.obj_info, pFsObjInfo, sizeof(GSTCTLFSOBJINFO));
     2632    VbglHGCMParmPtrSetString(&Msg.u.queryinfo.user,   pszUser);
     2633    VbglHGCMParmPtrSetString(&Msg.u.queryinfo.groups, pszGroups);
     2634    VbglHGCMParmPtrSet      (&Msg.u.queryinfo.acl,    pvACL, cbACL);
     2635
     2636    return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyDirNotify, u.read));
     2637}
     2638
     2639
     2640/**
     2641 * Replies to a HOST_MSG_FS_QUERY_INFO message.
     2642 *
     2643 * @returns VBox status code.
     2644 * @param   pCtx                Guest control command context to use.
     2645 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2646 * @param   pFsObjInfo          Guest file system object information to send.
     2647 */
     2648VBGLR3DECL(int) VbglR3GuestCtrlFsCbQueryInfo(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, PGSTCTLFSOBJINFO pFsObjInfo)
     2649{
     2650    char szIgnored[1];
     2651    return VbglR3GuestCtrlFsCbQueryInfoEx(pCtx, uRc, pFsObjInfo, szIgnored /* pszUser */, szIgnored /* pszGroups */,
     2652                                          szIgnored /* pvACL */, sizeof(szIgnored) /* cbACL */);
     2653}
     2654
     2655
     2656/**
     2657 * Replies to a HOST_MSG_FS_CREATE_TEMP message.
     2658 *
     2659 * @returns VBox status code.
     2660 * @param   pCtx                Guest control command context to use.
     2661 * @param   uRc                 Guest rc of operation (note: IPRT-style signed int).
     2662 * @param   pszPath             Path of created temporary file / directory, if \a uRc marks a success.
     2663 *                              Specify an empty path on failure -- NULL is not allowed!
     2664 */
     2665VBGLR3DECL(int) VbglR3GuestCtrlFsCbCreateTemp(PVBGLR3GUESTCTRLCMDCTX pCtx, uint32_t uRc, const char *pszPath)
     2666{
     2667    AssertPtrReturn(pCtx, VERR_INVALID_POINTER);
     2668    AssertPtrReturn(pszPath, VERR_INVALID_POINTER);
     2669
     2670    HGCMReplyFsNotify Msg;
     2671    VBGL_HGCM_HDR_INIT(&Msg.reply_hdr.hdr, pCtx->uClientID, GUEST_MSG_FS_NOTIFY, 4);
     2672    VbglHGCMParmUInt32Set(&Msg.reply_hdr.context, pCtx->uContextID);
     2673    VbglHGCMParmUInt32Set(&Msg.reply_hdr.type, GUEST_FS_NOTIFYTYPE_CREATE_TEMP);
     2674    VbglHGCMParmUInt32Set(&Msg.reply_hdr.rc, uRc);
     2675    VbglHGCMParmPtrSetString(&Msg.u.createtemp.path, pszPath);
     2676
     2677    return VbglR3HGCMCall(&Msg.reply_hdr.hdr, RT_UOFFSET_AFTER(HGCMReplyFsNotify, u.createtemp));
     2678}
     2679#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     2680
     2681
     2682/*********************************************************************************************************************************
     2683 * Process callbacks                                                                                                             *
     2684 ********************************************************************************************************************************/
     2685
    21302686/**
    21312687 * Callback for reporting a guest process status (along with some other stuff) to the host.
  • trunk/src/VBox/Additions/common/VBoxService/Makefile.kmk

    r98416 r98526  
    4848
    4949# Busybox-like toolbox, embedded into VBoxService.
    50 VBOX_WITH_VBOXSERVICE_TOOLBOX       := 1
     50ifndef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     51 VBOX_WITH_VBOXSERVICE_TOOLBOX      := 1
     52endif
    5153
    5254# VM-management functions, like memory ballooning and statistics.
     
    101103        $(if $(VBOX_WITH_GUEST_CONTROL),VBOX_WITH_GUEST_CONTROL,) \
    102104        $(if $(VBOX_WITH_GUEST_PROPS),VBOX_WITH_GUEST_PROPS,) \
    103         $(if $(VBOX_WITH_HGCM),VBOX_WITH_HGCM,)
     105        $(if $(VBOX_WITH_HGCM),VBOX_WITH_HGCM,) \
     106        $(if $(VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT),VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT,) \
     107        $(if $(VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS),VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS,)
    104108ifdef VBOX_WITH_AUTOMATIC_DEFS_QUOTING
    105109 VBoxService_DEFS        += VBOX_BUILD_TARGET="$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)"
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.cpp

    r98103 r98526  
    258258                                      | VBOX_GUESTCTRL_GF_0_PROCESS_ARGV0
    259259                                      | VBOX_GUESTCTRL_GF_0_PROCESS_DYNAMIC_SIZES
     260#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     261                                      | VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS
     262#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    260263                                      | VBOX_GUESTCTRL_GF_0_SHUTDOWN;
    261 
    262264        rc = VbglR3GuestCtrlReportFeatures(g_idControlSvcClient, fGuestFeatures, &g_fControlHostFeatures0);
    263265        if (RT_SUCCESS(rc))
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h

    r98103 r98526  
    5858} VBOXSERVICECTRLPIPEID;
    5959
     60#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     61/**
     62 * Structure for one (opened) guest directory.
     63 */
     64typedef struct VBOXSERVICECTRLDIR
     65{
     66    /** Pointer to list archor of following list node.
     67     *  @todo Would be nice to have a RTListGetAnchor(). */
     68    PRTLISTANCHOR                   pAnchor;
     69    /** Node to global guest control directory list. */
     70    /** @todo Use a map later? */
     71    RTLISTNODE                      Node;
     72    /** The (absolute) directory path. */
     73    char                           *pszPathAbs;
     74    /** The directory handle on the guest. */
     75    RTDIR                           hDir;
     76    /** Directory handle to identify this directory. */
     77    uint32_t                        uHandle;
     78    /** Context ID. */
     79    uint32_t                        uContextID;
     80} VBOXSERVICECTRLDIR;
     81/** Pointer to a guest directory. */
     82typedef VBOXSERVICECTRLDIR *PVBOXSERVICECTRLDIR;
     83#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     84
    6085/**
    6186 * Structure for one (opened) guest file.
     
    6388typedef struct VBOXSERVICECTRLFILE
    6489{
    65     /** Pointer to list archor of following
    66      *  list node.
     90    /** Pointer to list archor of following list node.
    6791     *  @todo Would be nice to have a RTListGetAnchor(). */
    6892    PRTLISTANCHOR                   pAnchor;
     
    81105    uint64_t                        fOpen;
    82106} VBOXSERVICECTRLFILE;
    83 /** Pointer to thread data. */
     107/** Pointer to a guest file. */
    84108typedef VBOXSERVICECTRLFILE *PVBOXSERVICECTRLFILE;
    85109
     
    177201    /** Number of guest processes in the process list. */
    178202    uint32_t                        cProcesses;
     203#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     204    /** List of guest control files (VBOXSERVICECTRLDIR). */
     205    RTLISTANCHOR                    lstDirs;
     206    /** Number of guest directories in \a lstDirs. */
     207    uint32_t                        cDirs;
     208#endif
    179209    /** List of guest control files (VBOXSERVICECTRLFILE). */
    180210    RTLISTANCHOR                    lstFiles;
    181     /** Number of guest files in the file list. */
     211    /** Number of guest files in \a lstFiles. */
    182212    uint32_t                        cFiles;
    183213    /** The session's critical section. */
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp

    r98103 r98526  
    100100}
    101101
     102
     103#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     104/**
     105 * Free's a guest directory entry.
     106 *
     107 * @returns VBox status code.
     108 * @param   pDir                Directory entry to free.
     109 *                              The pointer will be invalid on success.
     110 */
     111static int vgsvcGstCtrlSessionDirFree(PVBOXSERVICECTRLDIR pDir)
     112{
     113    if (!pDir)
     114        return VINF_SUCCESS;
     115
     116    int rc;
     117    if (pDir->hDir != NIL_RTDIR)
     118    {
     119        rc = RTDirClose(pDir->hDir);
     120        pDir->hDir = NIL_RTDIR;
     121    }
     122    else
     123        rc = VINF_SUCCESS;
     124
     125    if (RT_SUCCESS(rc))
     126    {
     127        RTStrFree(pDir->pszPathAbs);
     128        RTListNodeRemove(&pDir->Node);
     129        RTMemFree(pDir);
     130    }
     131
     132    return rc;
     133}
     134
     135
     136/**
     137 * Acquires an internal guest directory.
     138 *
     139 * Must be released via vgsvcGstCtrlSessionDirRelease().
     140 *
     141 * @returns VBox status code.
     142 * @param   pSession            Guest control session to acquire guest directory for.
     143 * @param   uHandle             Handle of directory to acquire.
     144 *
     145 * @note    No locking done yet.
     146 */
     147static PVBOXSERVICECTRLDIR vgsvcGstCtrlSessionDirAcquire(const PVBOXSERVICECTRLSESSION pSession, uint32_t uHandle)
     148{
     149    AssertPtrReturn(pSession, NULL);
     150
     151    /** @todo Use a map later! */
     152    PVBOXSERVICECTRLDIR pDirCur;
     153    RTListForEach(&pSession->lstDirs, pDirCur, VBOXSERVICECTRLDIR, Node)
     154    {
     155        if (pDirCur->uHandle == uHandle)
     156            return pDirCur;
     157    }
     158
     159    return NULL;
     160}
     161
     162
     163/**
     164 * Releases a formerly acquired guest directory.
     165 *
     166 * @param   pDir                Directory to release.
     167 */
     168static void vgsvcGstCtrlSessionDirRelease(PVBOXSERVICECTRLDIR pDir)
     169{
     170    RT_NOREF(pDir);
     171}
     172#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    102173
    103174
     
    390461            else
    391462            {
    392                 VGSvcError("[File %s] empty filename!\n", szFile);
     463                VGSvcError("Opening file failed: Empty filename!\n");
    393464                rc = VERR_INVALID_NAME;
    394465            }
     
    902973
    903974
     975#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     976static int vgsvcGstCtrlSessionHandleFileRemove(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     977{
     978    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     979    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     980
     981    /*
     982     * Retrieve the request.
     983     */
     984    char szPath[RTPATH_MAX];
     985    int rc = VbglR3GuestCtrlFileGetRemove(pHostCtx, szPath, sizeof(szPath));
     986    if (RT_SUCCESS(rc))
     987    {
     988        VGSvcVerbose(4, "Deleting file szPath=%s\n", szPath);
     989        rc = RTFileDelete(szPath);
     990
     991        /*
     992         * Report result back to host.
     993         */
     994        int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc);
     995        if (RT_FAILURE(rc2))
     996        {
     997            VGSvcError("Failed to report file deletion status, rc=%Rrc\n", rc2);
     998            if (RT_SUCCESS(rc))
     999                rc = rc2;
     1000        }
     1001    }
     1002    else
     1003    {
     1004        VGSvcError("Error fetching parameters for file deletion operation: %Rrc\n", rc);
     1005        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1006    }
     1007    VGSvcVerbose(5, "Deleting file returned rc=%Rrc\n", rc);
     1008    return rc;
     1009}
     1010
     1011
     1012static int vgsvcGstCtrlSessionHandleDirOpen(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1013{
     1014    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1015    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1016
     1017    char            szPath[RTPATH_MAX];
     1018    uint32_t        fFlags;
     1019    GSTCTLDIRFILTER enmFilter;
     1020    uint32_t        uHandle = 0;
     1021    int rc = VbglR3GuestCtrlDirGetOpen(pHostCtx, szPath, sizeof(szPath), &fFlags, &enmFilter);
     1022    VGSvcVerbose(4, "[Dir %s]: fFlags=%#x, enmFilter=%#x, rc=%Rrc\n", szPath, enmFilter, rc);
     1023    if (RT_SUCCESS(rc))
     1024    {
     1025        PVBOXSERVICECTRLDIR pDir = (PVBOXSERVICECTRLDIR)RTMemAllocZ(sizeof(VBOXSERVICECTRLDIR));
     1026        AssertPtrReturn(pDir, VERR_NO_MEMORY);
     1027        pDir->hDir = NIL_RTDIR; /* Not zero or NULL! */
     1028        if (szPath[0])
     1029        {
     1030            pDir->pszPathAbs = RTStrDup(szPath);
     1031            if (!pDir->pszPathAbs)
     1032                rc = VERR_NO_MEMORY;
     1033
     1034            if (RT_SUCCESS(rc))
     1035            {
     1036                rc = RTDirOpenFiltered(&pDir->hDir, pDir->pszPathAbs, (RTDIRFILTER)enmFilter, fFlags);
     1037                if (RT_SUCCESS(rc))
     1038                {
     1039                    uHandle = VBOX_GUESTCTRL_CONTEXTID_GET_OBJECT(pHostCtx->uContextID);
     1040                    pDir->uHandle = uHandle;
     1041                    RTListAppend(&pSession->lstDirs, &pDir->Node);
     1042                    VGSvcVerbose(2, "[Dir %s] Opened (ID=%RU32)\n", pDir->pszPathAbs, pDir->uHandle);
     1043                }
     1044            }
     1045        }
     1046        else
     1047        {
     1048            VGSvcError("Opening directory failed: Empty path!\n");
     1049            rc = VERR_INVALID_NAME;
     1050        }
     1051
     1052        /* Clean up if we failed. */
     1053        if (RT_FAILURE(rc))
     1054        {
     1055            RTStrFree(pDir->pszPathAbs);
     1056            if (pDir->hDir != NIL_RTDIR)
     1057                RTDirClose(pDir->hDir);
     1058            RTMemFree(pDir);
     1059        }
     1060
     1061        /*
     1062         * Report result back to host.
     1063         */
     1064        int rc2 = VbglR3GuestCtrlDirCbOpen(pHostCtx, rc, uHandle);
     1065        if (RT_FAILURE(rc2))
     1066        {
     1067            VGSvcError("[Dir %s]: Failed to report directory open status, rc=%Rrc\n", szPath, rc2);
     1068            if (RT_SUCCESS(rc))
     1069                rc = rc2;
     1070        }
     1071    }
     1072    else
     1073    {
     1074        VGSvcError("Error fetching parameters for directory open operation: %Rrc\n", rc);
     1075        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1076    }
     1077
     1078    VGSvcVerbose(4, "[Dir %s] Opening (flags=%#x, filter flags=%#x) returned rc=%Rrc\n",
     1079                 szPath, fFlags, enmFilter, rc);
     1080    return rc;
     1081}
     1082
     1083
     1084static int vgsvcGstCtrlSessionHandleDirClose(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1085{
     1086    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1087    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1088
     1089    /*
     1090     * Retrieve the message.
     1091     */
     1092    uint32_t uHandle = 0;
     1093    int rc = VbglR3GuestCtrlDirGetClose(pHostCtx, &uHandle /* Dir handle to close */);
     1094    if (RT_SUCCESS(rc))
     1095    {
     1096        PVBOXSERVICECTRLDIR pDir = vgsvcGstCtrlSessionDirAcquire(pSession, uHandle);
     1097        if (pDir)
     1098        {
     1099            VGSvcVerbose(2, "[Dir %s] Closing (handle=%RU32)\n", pDir ? pDir->pszPathAbs : "<Not found>", uHandle);
     1100            rc = vgsvcGstCtrlSessionDirFree(pDir);
     1101
     1102            vgsvcGstCtrlSessionDirRelease(pDir);
     1103        }
     1104        else
     1105        {
     1106            VGSvcError("Directory %u (%#x) not found!\n", uHandle, uHandle);
     1107            rc = VERR_NOT_FOUND;
     1108        }
     1109
     1110        /*
     1111         * Report result back to host.
     1112         */
     1113        int rc2 = VbglR3GuestCtrlDirCbClose(pHostCtx, rc);
     1114        if (RT_FAILURE(rc2))
     1115        {
     1116            VGSvcError("Failed to report directory close status, rc=%Rrc\n", rc2);
     1117            if (RT_SUCCESS(rc))
     1118                rc = rc2;
     1119        }
     1120    }
     1121    else
     1122    {
     1123        VGSvcError("Error fetching parameters for directory close operation: %Rrc\n", rc);
     1124        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1125    }
     1126    return rc;
     1127}
     1128
     1129
     1130static int vgsvcGstCtrlSessionHandleDirRead(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1131{
     1132    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1133    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1134
     1135    /*
     1136     * Retrieve the message.
     1137     */
     1138    uint32_t           uHandle;
     1139    size_t             cbDirEntry;
     1140    GSTCTLFSOBJATTRADD enmAttrAdd;
     1141    uint32_t           fFlags;
     1142    GSTCTLDIRENTRYEX   DirEntryEx;
     1143    int rc = VbglR3GuestCtrlDirGetRead(pHostCtx, &uHandle, (uint32_t *)&cbDirEntry, (uint32_t *)&enmAttrAdd, &fFlags);
     1144    if (RT_SUCCESS(rc))
     1145    {
     1146        PVBOXSERVICECTRLDIR pDir = vgsvcGstCtrlSessionDirAcquire(pSession, uHandle);
     1147        if (pDir)
     1148        {
     1149            VGSvcVerbose(2, "[Dir %s] Reading next entry (handle=%RU32)\n", pDir ? pDir->pszPathAbs : "<Not found>", uHandle);
     1150
     1151            /*
     1152             * For now we ASSUME that RTDIRENTRYEX == GSTCTLDIRENTRYEX, which implies that we simply can cast RTDIRENTRYEX
     1153             * to GSTCTLDIRENTRYEX. This might change in the future, however, so be extra cautious here.
     1154             *
     1155             * Ditto for RTFSOBJATTRADD == GSTCTLFSOBJATTRADD.
     1156             */
     1157            AssertCompileSize(DirEntryEx, sizeof(RTDIRENTRYEX));
     1158            AssertCompile    (RT_OFFSETOF(GSTCTLDIRENTRYEX, Info)   == RT_OFFSETOF(RTDIRENTRYEX, Info));
     1159            AssertCompile    (RT_OFFSETOF(GSTCTLDIRENTRYEX, szName) == RT_OFFSETOF(RTDIRENTRYEX, szName));
     1160            AssertCompile    (RT_OFFSETOF(GSTCTLFSOBJINFO,  Attr)   == RT_OFFSETOF(RTFSOBJINFO,  Attr));
     1161
     1162            PRTDIRENTRYEX pDirEntryExRuntime = (PRTDIRENTRYEX)&DirEntryEx;
     1163
     1164            rc = RTDirReadEx(pDir->hDir, pDirEntryExRuntime, &cbDirEntry, (RTFSOBJATTRADD)enmAttrAdd, fFlags);
     1165
     1166            /* Paranoia. */
     1167            AssertStmt(cbDirEntry <= _256K, rc = VERR_BUFFER_OVERFLOW);
     1168
     1169            if (RT_SUCCESS(rc))
     1170            {
     1171                int rc2 = VbglR3GuestCtrlDirCbRead(pHostCtx, rc, &DirEntryEx, (uint32_t)cbDirEntry);
     1172                if (RT_FAILURE(rc2))
     1173                    VGSvcError("Failed to report directory read status, rc=%Rrc\n", rc2);
     1174            }
     1175
     1176            vgsvcGstCtrlSessionDirRelease(pDir);
     1177        }
     1178        else
     1179        {
     1180            VGSvcError("Directory %u (%#x) not found!\n", uHandle, uHandle);
     1181            rc = VERR_NOT_FOUND;
     1182        }
     1183
     1184        if (RT_FAILURE(rc))
     1185        {
     1186            /* On failure we send a simply reply to save bandwidth. */
     1187            int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc);
     1188            if (RT_FAILURE(rc2))
     1189            {
     1190                VGSvcError("Failed to report directory read error %Rrc, rc=%Rrc\n", rc, rc2);
     1191                if (RT_SUCCESS(rc))
     1192                    rc = rc2;
     1193            }
     1194        }
     1195    }
     1196    else
     1197    {
     1198        VGSvcError("Error fetching parameters for directory read operation: %Rrc\n", rc);
     1199        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1200    }
     1201    return rc;
     1202}
     1203
     1204
     1205static int vgsvcGstCtrlSessionHandleDirRewind(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1206{
     1207    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1208    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1209
     1210    /*
     1211     * Retrieve the message.
     1212     */
     1213    uint32_t uHandle = 0;
     1214    int rc = VbglR3GuestCtrlDirGetRewind(pHostCtx, &uHandle);
     1215    if (RT_SUCCESS(rc))
     1216    {
     1217        PVBOXSERVICECTRLDIR pDir = vgsvcGstCtrlSessionDirAcquire(pSession, uHandle);
     1218        if (pDir)
     1219        {
     1220            VGSvcVerbose(2, "[Dir %s] Rewinding (handle=%RU32)\n", pDir ? pDir->pszPathAbs : "<Not found>", uHandle);
     1221
     1222            rc = RTDirRewind(pDir->hDir);
     1223
     1224            vgsvcGstCtrlSessionDirRelease(pDir);
     1225        }
     1226        else
     1227        {
     1228            VGSvcError("Directory %u (%#x) not found!\n", uHandle, uHandle);
     1229            rc = VERR_NOT_FOUND;
     1230        }
     1231
     1232        /*
     1233         * Report result back to host.
     1234         */
     1235        int rc2 = VbglR3GuestCtrlDirCbRewind(pHostCtx, rc);
     1236        if (RT_FAILURE(rc2))
     1237        {
     1238            VGSvcError("Failed to report directory rewind status, rc=%Rrc\n", rc2);
     1239            if (RT_SUCCESS(rc))
     1240                rc = rc2;
     1241        }
     1242    }
     1243    else
     1244    {
     1245        VGSvcError("Error fetching parameters for directory rewind operation: %Rrc\n", rc);
     1246        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1247    }
     1248    return rc;
     1249}
     1250
     1251
     1252static int vgsvcGstCtrlSessionHandleDirCreate(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1253{
     1254    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1255    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1256
     1257    /*
     1258     * Retrieve the request.
     1259     */
     1260    char     szPath[RTPATH_MAX];
     1261    RTFMODE  fMode;
     1262    uint32_t fCreate;
     1263    int rc = VbglR3GuestCtrlDirGetCreate(pHostCtx, szPath, sizeof(szPath), &fMode, &fCreate);
     1264    if (RT_SUCCESS(rc))
     1265    {
     1266        if (!(fCreate & ~GSTCTL_CREATEDIRECTORY_F_VALID_MASK))
     1267        {
     1268            VGSvcVerbose(4, "Creating directory (szPath='%s', fMode=%#x, fCreate=%#x), rc=%Rrc\n", szPath, fMode, fCreate, rc);
     1269            rc = RTDirCreate(szPath, fMode, fCreate);
     1270        }
     1271        else
     1272        {
     1273            VGSvcError("Invalid directory creation flags: %#x\n", fCreate);
     1274            rc = VERR_NOT_SUPPORTED;
     1275        }
     1276
     1277        /*
     1278         * Report result back to host.
     1279         */
     1280        int rc2 = VbglR3GuestCtrlMsgReply(pHostCtx, rc);
     1281        if (RT_FAILURE(rc2))
     1282        {
     1283            VGSvcError("Failed to report directory creation status, rc=%Rrc\n", rc2);
     1284            if (RT_SUCCESS(rc))
     1285                rc = rc2;
     1286        }
     1287    }
     1288    else
     1289    {
     1290        VGSvcError("Error fetching parameters for directory creation operation: %Rrc\n", rc);
     1291        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1292    }
     1293    VGSvcVerbose(5, "Creating directory returned rc=%Rrc\n", rc);
     1294    return rc;
     1295}
     1296#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1297
     1298
    9041299static int vgsvcGstCtrlSessionHandlePathRename(PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
    9051300{
     
    13681763
    13691764
     1765#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1766static int vgsvcGstCtrlSessionHandleFsQueryInfo(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1767{
     1768    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1769    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1770
     1771    /*
     1772     * Retrieve the request.
     1773     */
     1774    char               szPath[RTPATH_MAX];
     1775    GSTCTLFSOBJATTRADD enmAttrAdd;
     1776    uint32_t           fFlags;
     1777    RTFSOBJINFO        objInfoRuntime;
     1778
     1779    int rc = VbglR3GuestCtrlFsGetQueryInfo(pHostCtx, szPath, sizeof(szPath), &enmAttrAdd, &fFlags);
     1780    if (RT_SUCCESS(rc))
     1781    {
     1782        if (!(fFlags & ~GSTCTL_QUERYINFO_F_VALID_MASK))
     1783        {
     1784            uint32_t fFlagsRuntime = 0;
     1785            if (fFlags & GSTCTL_QUERYINFO_F_ON_LINK)
     1786                fFlagsRuntime |= RTPATH_F_ON_LINK;
     1787            if (fFlags & GSTCTL_QUERYINFO_F_FOLLOW_LINK)
     1788                fFlagsRuntime |= RTPATH_F_FOLLOW_LINK;
     1789            if (fFlags & GSTCTL_QUERYINFO_F_NO_SYMLINKS)
     1790                fFlagsRuntime |= RTPATH_F_NO_SYMLINKS;
     1791
     1792#define CASE_ATTR_ADD_VAL(a_Val) \
     1793            case GSTCTL##a_Val: enmAttrRuntime = RT##a_Val; break;
     1794
     1795            RTFSOBJATTRADD enmAttrRuntime;
     1796            switch (enmAttrAdd)
     1797            {
     1798                CASE_ATTR_ADD_VAL(FSOBJATTRADD_NOTHING);
     1799                CASE_ATTR_ADD_VAL(FSOBJATTRADD_UNIX);
     1800                CASE_ATTR_ADD_VAL(FSOBJATTRADD_UNIX_OWNER);
     1801                CASE_ATTR_ADD_VAL(FSOBJATTRADD_UNIX_GROUP);
     1802                CASE_ATTR_ADD_VAL(FSOBJATTRADD_EASIZE);
     1803                default:
     1804                    enmAttrRuntime = RTFSOBJATTRADD_NOTHING;
     1805                    break;
     1806            }
     1807
     1808#undef CASE_ATTR_ADD_VAL
     1809
     1810            /*
     1811             * For now we ASSUME that RTFSOBJINFO == GSTCTLFSOBJINFO, which implies that we simply can cast RTFSOBJINFO
     1812             * to GSTCTLFSOBJINFO. This might change in the future, however, so be extra cautious here.
     1813             *
     1814             * Ditto for RTFSOBJATTR == GSTCTLFSOBJATTR.
     1815             */
     1816            AssertCompileSize(objInfoRuntime, sizeof(GSTCTLFSOBJINFO));
     1817            AssertCompile    (RT_OFFSETOF(GSTCTLFSOBJINFO, cbObject) == RT_OFFSETOF(GSTCTLFSOBJINFO, cbObject));
     1818            AssertCompile    (RT_OFFSETOF(GSTCTLFSOBJINFO, Attr)     == RT_OFFSETOF(GSTCTLFSOBJINFO, Attr));
     1819            AssertCompileSize(RTFSOBJATTR, sizeof(GSTCTLFSOBJATTR));
     1820
     1821            rc = RTPathQueryInfoEx(szPath, &objInfoRuntime, enmAttrRuntime, fFlagsRuntime);
     1822        }
     1823        else
     1824        {
     1825            VGSvcError("Invalid stat flags: %#x\n", fFlags);
     1826            rc = VERR_NOT_SUPPORTED;
     1827        }
     1828
     1829        PGSTCTLFSOBJINFO pObjInfo = (PGSTCTLFSOBJINFO)&objInfoRuntime;
     1830
     1831        /** @todo Implement lookups! */
     1832        char  szNotImplemented[] = "<not-implemented>";
     1833        char *pszUser   = szNotImplemented;
     1834        char *pszGroups = szNotImplemented;
     1835        int rc2 = VbglR3GuestCtrlFsCbQueryInfoEx(pHostCtx, rc, pObjInfo, pszUser, pszGroups,
     1836                                                 szNotImplemented, sizeof(szNotImplemented));
     1837        if (RT_FAILURE(rc2))
     1838        {
     1839            VGSvcError("Failed to reply to fsqueryinfo request %Rrc, rc=%Rrc\n", rc, rc2);
     1840            if (RT_SUCCESS(rc))
     1841                rc = rc2;
     1842        }
     1843    }
     1844    else
     1845    {
     1846        VGSvcError("Error fetching parameters for fsqueryinfo operation: %Rrc\n", rc);
     1847        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1848    }
     1849    return rc;
     1850}
     1851
     1852
     1853static int vgsvcGstCtrlSessionHandleFsCreateTemp(const PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx)
     1854{
     1855    AssertPtrReturn(pSession, VERR_INVALID_POINTER);
     1856    AssertPtrReturn(pHostCtx, VERR_INVALID_POINTER);
     1857
     1858    /*
     1859     * Retrieve the request.
     1860     */
     1861    char     szTemplate[RTPATH_MAX];
     1862    char     szPath[RTPATH_MAX];
     1863    uint32_t fFlags = GSTCTL_CREATETEMP_F_NONE;
     1864    RTFMODE  fMode  = 0700;
     1865    int rc = VbglR3GuestCtrlFsGetCreateTemp(pHostCtx, szTemplate, sizeof(szTemplate), szPath, sizeof(szPath), &fFlags, &fMode);
     1866    if (RT_SUCCESS(rc))
     1867    {
     1868        if (!(fFlags & ~GSTCTL_CREATETEMP_F_VALID_MASK))
     1869        {
     1870            const char *pszWhat = fMode & GSTCTL_CREATETEMP_F_DIRECTORY ? "directory" : "file";
     1871            VGSvcVerbose(4, "Creating temporary %s (szTemplate='%s', fFlags=%#x), rc=%Rrc\n", pszWhat, szTemplate, fFlags, rc);
     1872
     1873            bool const fSecure = RT_BOOL(fMode & GSTCTL_CREATETEMP_F_SECURE);
     1874            if (fMode & GSTCTL_CREATETEMP_F_DIRECTORY)
     1875            {
     1876                if (fSecure)
     1877                    rc = RTDirCreateTempSecure(szTemplate); /* File mode is fixed to 0700. */
     1878                else
     1879                    rc = RTDirCreateTemp(szTemplate, fMode);
     1880            }
     1881            else /* File */
     1882            {
     1883                if (fSecure)
     1884                    rc = RTFileCreateTempSecure(szTemplate); /* File mode is fixed to 0700. */
     1885                else
     1886                    rc = RTFileCreateTemp(szTemplate, fMode);
     1887            }
     1888        }
     1889        else
     1890        {
     1891            VGSvcError("Invalid temporary directory/file creation flags: %#x\n", fFlags);
     1892            rc = VERR_NOT_SUPPORTED;
     1893        }
     1894
     1895        /*
     1896         * Report result back to host.
     1897         */
     1898        int rc2 = VbglR3GuestCtrlFsCbCreateTemp(pHostCtx, rc, szTemplate);
     1899        if (RT_FAILURE(rc2))
     1900        {
     1901            VGSvcError("Failed to report temporary file/directory creation status, rc=%Rrc\n", rc2);
     1902            if (RT_SUCCESS(rc))
     1903                rc = rc2;
     1904        }
     1905    }
     1906    else
     1907    {
     1908        VGSvcError("Error fetching parameters for file/directory creation operation: %Rrc\n", rc);
     1909        VbglR3GuestCtrlMsgSkip(pHostCtx->uClientID, rc, UINT32_MAX);
     1910    }
     1911    VGSvcVerbose(5, "Creating temporary file/directory returned rc=%Rrc\n", rc);
     1912    return rc;
     1913}
     1914#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1915
     1916
    13701917int VGSvcGstCtrlSessionHandler(PVBOXSERVICECTRLSESSION pSession, uint32_t uMsg, PVBGLR3GUESTCTRLCMDCTX pHostCtx,
    13711918                               void **ppvScratchBuf, uint32_t *pcbScratchBuf, volatile bool *pfShutdown)
     
    13941941            break;
    13951942
     1943        case HOST_MSG_EXEC_CMD:
     1944            rc = vgsvcGstCtrlSessionHandleProcExec(pSession, pHostCtx);
     1945            break;
     1946
     1947        case HOST_MSG_EXEC_SET_INPUT:
     1948            rc = vgsvcGstCtrlSessionHandleProcInput(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
     1949            break;
     1950
     1951        case HOST_MSG_EXEC_GET_OUTPUT:
     1952            rc = vgsvcGstCtrlSessionHandleProcOutput(pSession, pHostCtx);
     1953            break;
     1954
     1955        case HOST_MSG_EXEC_TERMINATE:
     1956            rc = vgsvcGstCtrlSessionHandleProcTerminate(pSession, pHostCtx);
     1957            break;
     1958
     1959        case HOST_MSG_EXEC_WAIT_FOR:
     1960            rc = vgsvcGstCtrlSessionHandleProcWaitFor(pSession, pHostCtx);
     1961            break;
     1962
     1963#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1964        case HOST_MSG_FS_QUERY_INFO:
     1965            if (fImpersonated)
     1966                rc = vgsvcGstCtrlSessionHandleFsQueryInfo(pSession, pHostCtx);
     1967            break;
     1968
     1969        case HOST_MSG_FS_CREATE_TEMP:
     1970            if (fImpersonated)
     1971                rc = vgsvcGstCtrlSessionHandleFsCreateTemp(pSession, pHostCtx);
     1972            break;
     1973#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1974
     1975        case HOST_MSG_FILE_OPEN:
     1976            if (fImpersonated)
     1977                rc = vgsvcGstCtrlSessionHandleFileOpen(pSession, pHostCtx);
     1978            break;
     1979
     1980        case HOST_MSG_FILE_CLOSE:
     1981            if (fImpersonated)
     1982                rc = vgsvcGstCtrlSessionHandleFileClose(pSession, pHostCtx);
     1983            break;
     1984
     1985        case HOST_MSG_FILE_READ:
     1986            if (fImpersonated)
     1987                rc = vgsvcGstCtrlSessionHandleFileRead(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
     1988            break;
     1989
     1990        case HOST_MSG_FILE_READ_AT:
     1991            if (fImpersonated)
     1992                rc = vgsvcGstCtrlSessionHandleFileReadAt(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
     1993            break;
     1994
     1995        case HOST_MSG_FILE_WRITE:
     1996            if (fImpersonated)
     1997                rc = vgsvcGstCtrlSessionHandleFileWrite(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
     1998            break;
     1999
     2000        case HOST_MSG_FILE_WRITE_AT:
     2001            if (fImpersonated)
     2002                rc = vgsvcGstCtrlSessionHandleFileWriteAt(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
     2003            break;
     2004
     2005        case HOST_MSG_FILE_SEEK:
     2006            if (fImpersonated)
     2007                rc = vgsvcGstCtrlSessionHandleFileSeek(pSession, pHostCtx);
     2008            break;
     2009
     2010        case HOST_MSG_FILE_TELL:
     2011            if (fImpersonated)
     2012                rc = vgsvcGstCtrlSessionHandleFileTell(pSession, pHostCtx);
     2013            break;
     2014
     2015        case HOST_MSG_FILE_SET_SIZE:
     2016            if (fImpersonated)
     2017                rc = vgsvcGstCtrlSessionHandleFileSetSize(pSession, pHostCtx);
     2018            break;
     2019
     2020#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2021        case HOST_MSG_FILE_REMOVE:
     2022            if (fImpersonated)
     2023                rc = vgsvcGstCtrlSessionHandleFileRemove(pSession, pHostCtx);
     2024            break;
     2025
     2026        case HOST_MSG_DIR_OPEN:
     2027            if (fImpersonated)
     2028                rc = vgsvcGstCtrlSessionHandleDirOpen(pSession, pHostCtx);
     2029            break;
     2030
     2031        case HOST_MSG_DIR_CLOSE:
     2032            if (fImpersonated)
     2033                rc = vgsvcGstCtrlSessionHandleDirClose(pSession, pHostCtx);
     2034            break;
     2035
     2036        case HOST_MSG_DIR_READ:
     2037            if (fImpersonated)
     2038                rc = vgsvcGstCtrlSessionHandleDirRead(pSession, pHostCtx);
     2039            break;
     2040
     2041        case HOST_MSG_DIR_REWIND:
     2042            if (fImpersonated)
     2043                rc = vgsvcGstCtrlSessionHandleDirRewind(pSession, pHostCtx);
     2044            break;
     2045
     2046        case HOST_MSG_DIR_CREATE:
     2047            if (fImpersonated)
     2048                rc = vgsvcGstCtrlSessionHandleDirCreate(pSession, pHostCtx);
     2049            break;
     2050#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     2051
    13962052        case HOST_MSG_DIR_REMOVE:
    13972053            if (fImpersonated)
     
    13992055            break;
    14002056
    1401         case HOST_MSG_EXEC_CMD:
    1402             rc = vgsvcGstCtrlSessionHandleProcExec(pSession, pHostCtx);
    1403             break;
    1404 
    1405         case HOST_MSG_EXEC_SET_INPUT:
    1406             rc = vgsvcGstCtrlSessionHandleProcInput(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
    1407             break;
    1408 
    1409         case HOST_MSG_EXEC_GET_OUTPUT:
    1410             rc = vgsvcGstCtrlSessionHandleProcOutput(pSession, pHostCtx);
    1411             break;
    1412 
    1413         case HOST_MSG_EXEC_TERMINATE:
    1414             rc = vgsvcGstCtrlSessionHandleProcTerminate(pSession, pHostCtx);
    1415             break;
    1416 
    1417         case HOST_MSG_EXEC_WAIT_FOR:
    1418             rc = vgsvcGstCtrlSessionHandleProcWaitFor(pSession, pHostCtx);
    1419             break;
    1420 
    1421         case HOST_MSG_FILE_OPEN:
    1422             if (fImpersonated)
    1423                 rc = vgsvcGstCtrlSessionHandleFileOpen(pSession, pHostCtx);
    1424             break;
    1425 
    1426         case HOST_MSG_FILE_CLOSE:
    1427             if (fImpersonated)
    1428                 rc = vgsvcGstCtrlSessionHandleFileClose(pSession, pHostCtx);
    1429             break;
    1430 
    1431         case HOST_MSG_FILE_READ:
    1432             if (fImpersonated)
    1433                 rc = vgsvcGstCtrlSessionHandleFileRead(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
    1434             break;
    1435 
    1436         case HOST_MSG_FILE_READ_AT:
    1437             if (fImpersonated)
    1438                 rc = vgsvcGstCtrlSessionHandleFileReadAt(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
    1439             break;
    1440 
    1441         case HOST_MSG_FILE_WRITE:
    1442             if (fImpersonated)
    1443                 rc = vgsvcGstCtrlSessionHandleFileWrite(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
    1444             break;
    1445 
    1446         case HOST_MSG_FILE_WRITE_AT:
    1447             if (fImpersonated)
    1448                 rc = vgsvcGstCtrlSessionHandleFileWriteAt(pSession, pHostCtx, ppvScratchBuf, pcbScratchBuf);
    1449             break;
    1450 
    1451         case HOST_MSG_FILE_SEEK:
    1452             if (fImpersonated)
    1453                 rc = vgsvcGstCtrlSessionHandleFileSeek(pSession, pHostCtx);
    1454             break;
    1455 
    1456         case HOST_MSG_FILE_TELL:
    1457             if (fImpersonated)
    1458                 rc = vgsvcGstCtrlSessionHandleFileTell(pSession, pHostCtx);
    1459             break;
    1460 
    1461         case HOST_MSG_FILE_SET_SIZE:
    1462             if (fImpersonated)
    1463                 rc = vgsvcGstCtrlSessionHandleFileSetSize(pSession, pHostCtx);
    1464             break;
    1465 
    14662057        case HOST_MSG_PATH_RENAME:
    14672058            if (fImpersonated)
     
    14892080    { /* likely */ }
    14902081    else if (rc != VERR_NOT_SUPPORTED) /* Note: Reply to host must must be sent by above handler. */
    1491         VGSvcError("Error while handling message (uMsg=%RU32, cParms=%RU32), rc=%Rrc\n", uMsg, pHostCtx->uNumParms, rc);
     2082        VGSvcError("Error while handling message %s (%#x, cParms=%RU32), rc=%Rrc\n",
     2083                   GstCtrlHostMsgtoStr((eHostMsg)uMsg), uMsg, pHostCtx->uNumParms, rc);
    14922084    else
    14932085    {
     
    15002092        rc = VINF_SUCCESS;
    15012093    }
    1502 
    1503     if (RT_FAILURE(rc))
    1504         VGSvcError("Error while handling message (uMsg=%RU32, cParms=%RU32), rc=%Rrc\n", uMsg, pHostCtx->uNumParms, rc);
    15052094
    15062095    return rc;
     
    20362625        }
    20372626
     2627#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2628        AssertMsg(pSession->cDirs == 0,
     2629                  ("Session directory list still contains %RU32 when it should not\n", pSession->cDirs));
     2630        AssertMsg(RTListIsEmpty(&pSession->lstDirs),
     2631                  ("Session directory list is not empty when it should\n"));
     2632#endif
    20382633        AssertMsg(pSession->cFiles == 0,
    20392634                  ("Session file list still contains %RU32 when it should not\n", pSession->cFiles));
     
    20682663
    20692664    RTListInit(&pSession->lstProcesses);
     2665#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2666    RTListInit(&pSession->lstDirs);
     2667#endif
    20702668    RTListInit(&pSession->lstFiles);
    20712669
  • trunk/src/VBox/HostServices/GuestControl/Makefile.kmk

    r98133 r98526  
    3939VBoxGuestControlSvc_NAME.os2  = VBoxGCTL
    4040VBoxGuestControlSvc_DEFS      = VBOX_WITH_HGCM
     41ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     42 VBoxGuestControlSvc_DEFS    += VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     43endif
    4144VBoxGuestControlSvc_INCS      = $(PATH_ROOT)/src/VBox/Main/include
    4245VBoxGuestControlSvc_INCS.win  = \
  • trunk/src/VBox/HostServices/GuestControl/VBoxGuestControlSvc.cpp

    r98103 r98526  
    7373#include <VBox/HostServices/GuestControlSvc.h>
    7474#include <VBox/GuestHost/GuestControl.h> /** @todo r=bird: Why two headers??? */
     75
     76#include "VBoxGuestControlSvc-internal.h"
    7577
    7678#include <VBox/err.h>
     
    16261628                        break;
    16271629                    case HOST_MSG_FILE_READ:
     1630                        RT_FALL_THROUGH();
    16281631                    case HOST_MSG_FILE_READ_AT:
    16291632                        HGCMSvcSetU32(&aReplyParams[1], GUEST_FILE_NOTIFYTYPE_READ);  /* type */
     
    16331636                        break;
    16341637                    case HOST_MSG_FILE_WRITE:
     1638                        RT_FALL_THROUGH();
    16351639                    case HOST_MSG_FILE_WRITE_AT:
    16361640                        HGCMSvcSetU32(&aReplyParams[1], GUEST_FILE_NOTIFYTYPE_WRITE); /* type */
     
    16571661                        hostCallback(GUEST_MSG_FILE_NOTIFY, 4, aReplyParams);
    16581662                        break;
    1659 
    1660                     case HOST_MSG_EXEC_GET_OUTPUT: /** @todo This can't be right/work. */
    1661                     case HOST_MSG_EXEC_TERMINATE:  /** @todo This can't be right/work. */
    1662                     case HOST_MSG_EXEC_WAIT_FOR:   /** @todo This can't be right/work. */
     1663#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1664                    case HOST_MSG_FS_QUERY_INFO:
     1665                        RT_FALL_THROUGH();
     1666                    case HOST_MSG_FS_CREATE_TEMP:
     1667                        RT_FALL_THROUGH();
     1668                    case HOST_MSG_FILE_REMOVE:
     1669                        RT_FALL_THROUGH();
     1670                    case HOST_MSG_DIR_OPEN:
     1671                        RT_FALL_THROUGH();
     1672                    case HOST_MSG_DIR_CLOSE:
     1673                        RT_FALL_THROUGH();
     1674                    case HOST_MSG_DIR_READ:
     1675                        RT_FALL_THROUGH();
     1676                    case HOST_MSG_DIR_REWIND:
     1677                        RT_FALL_THROUGH();
     1678                    case HOST_MSG_DIR_CREATE:
     1679                        RT_FALL_THROUGH();
     1680#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1681                    case HOST_MSG_EXEC_GET_OUTPUT: /** @todo BUGBUG This can't be right/work. */
     1682                    case HOST_MSG_EXEC_TERMINATE:  /** @todo BUGBUG This can't be right/work. */
     1683                    case HOST_MSG_EXEC_WAIT_FOR:   /** @todo BUGBUG This can't be right/work. */
     1684                        break;
     1685                    case HOST_MSG_DIR_REMOVE:
     1686                        RT_FALL_THROUGH();
     1687                    case HOST_MSG_PATH_RENAME:
     1688                        RT_FALL_THROUGH();
    16631689                    case HOST_MSG_PATH_USER_DOCUMENTS:
     1690                        RT_FALL_THROUGH();
    16641691                    case HOST_MSG_PATH_USER_HOME:
    1665                     case HOST_MSG_PATH_RENAME:
    1666                     case HOST_MSG_DIR_REMOVE:
     1692                        RT_FALL_THROUGH();
    16671693                    default:
    16681694                        HGCMSvcSetU32(&aReplyParams[1], pFirstMsg->mType);
     
    26102636    return rc;
    26112637}
    2612 
  • trunk/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk

    r98415 r98526  
    3131if defined(VBOX_WITH_TESTCASES) && !defined(VBOX_ONLY_ADDITIONS) && !defined(VBOX_ONLY_SDK)
    3232
     33 #
     34 # Testcase which mocks HGCM to also test the VbglR3-side of Guest Control.
     35 #
     36 # Goal is to use and test as much guest side code as possible as a self-contained
     37 # binary on the host here.
     38 #
     39 # Note: No #ifdef TESTCASE hacks or similar allowed, has to run
     40 #       without #ifdef modifications to the core code!
     41 #
     42 PROGRAMS += tstGuestControlMockHGCM
     43
     44 tstGuestControlMockHGCM_TEMPLATE = VBoxR3TstExe
     45 tstGuestControlMockHGCM_DEFS     = VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL
     46 tstGuestControlMockHGCM_SOURCES  = \
     47        ../VBoxGuestControlSvc.cpp \
     48        $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGuestCtrl.cpp \
     49        $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibMisc.cpp \
     50        $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3Lib.cpp \
     51        $(PATH_ROOT)/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR3LibGR.cpp \
     52        $(PATH_ROOT)/src/VBox/HostServices/common/message.cpp \
     53        tstGuestControlMockHGCM.cpp
     54 tstGuestControlMockHGCM_LIBS     = $(LIB_RUNTIME)
     55 tstGuestControlMockHGCM_CLEAN    = $(tstGuestControlMockHGCM_0_OUTDIR)/tstGuestControlMockHGCM.run
     56
     57 if 0 # Enable this if you want automatic runs after compilation.
     58  $$(tstGuestControlMockHGCM_0_OUTDIR)/tstGuestControlMockHGCM.run: $$(tstGuestControlMockHGCM_1_STAGE_TARGET)
     59        export VBOX_LOG_DEST=nofile; $(tstGuestControlMockHGCM_1_STAGE_TARGET) quiet
     60        $(QUIET)$(APPEND) -t "$@" "done"
     61  OTHERS += $(tstGuestControlMockHGCM_0_OUTDIR)/tstGuestControlMockHGCM.run
     62 endif
     63
     64
    3365 # Set this in LocalConfig.kmk if you are working on the guest property
    3466 # service to automatically run the testcase at build time.
     
    5385endif
    5486
     87#
     88# List of above testcases that will be included in the ValKit.
     89#
     90ifdef VBOX_WITH_VALIDATIONKIT_UNITTESTS_PACKING
     91 if1of ($(KBUILD_TARGET), linux solaris win)
     92  VALKIT_UNITTESTS_WHITELIST_GUEST_ADDITIONS += \
     93        tstGuestControlMockHGCM
     94 endif
     95endif # VBOX_WITH_VALIDATIONKIT_UNITTESTS_PACKING
     96
    5597include $(FILE_KBUILD_SUB_FOOTER)
    56 
  • trunk/src/VBox/Main/Makefile.kmk

    r98431 r98526  
    200200ifdef VBOX_WITH_MAIN_NLS
    201201 VBOX_MAIN_DEFS += VBOX_WITH_MAIN_NLS
     202endif
     203ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     204 VBOX_MAIN_DEFS += VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     205endif
     206ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     207 VBOX_MAIN_DEFS += VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
    202208endif
    203209# Unconditionally enable the new semaphore key generation code
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r98352 r98526  
    1424514245
    1424614246  <enum
     14247    name="DirectoryStatus"
     14248    uuid="a50ca1fc-85a9-4a7a-b755-68c3db01caf1"
     14249    >
     14250    <desc>
     14251      Directory statuses.
     14252    </desc>
     14253
     14254    <const name="Undefined"             value="0">
     14255      <desc>Directory is in an undefined state.</desc>
     14256    </const>
     14257    <const name="Open"                  value="1">
     14258      <desc>Guest directory has been successfully opened.</desc>
     14259    </const>
     14260    <const name="Close"                 value="2">
     14261      <desc>Guest directory has been closed.</desc>
     14262    </const>
     14263    <const name="Rewind"                value="3">
     14264      <desc>Guest directory reading was rewound.</desc>
     14265    </const>
     14266    <const name="Down"                  value="4">
     14267      <desc>Service/OS is stopping, guest directory was closed.</desc>
     14268    </const>
     14269    <const name="Error"                 value="5">
     14270      <desc>Something went wrong.</desc>
     14271    </const>
     14272  </enum>
     14273
     14274  <enum
    1424714275    name="FileAccessMode"
    1424814276    uuid="231a578f-47fb-ea30-3b3e-8489558227f0"
     
    1638016408  <interface
    1638116409    name="IDirectory" extends="$unknown"
    16382     uuid="758d7eac-e4b1-486a-8f2e-747ae346c3e9"
     16410    uuid="c7b24ad6-dba7-486c-b1ed-5f16d8d6da22"
    1638316411    wsmap="managed"
    1638416412    reservedMethods="4" reservedAttributes="8"
     
    1639216420    </attribute>
    1639316421
     16422    <attribute name="eventSource" type="IEventSource" readonly="yes">
     16423      <desc>
     16424        Event source for directory events.
     16425      </desc>
     16426    </attribute>
     16427
    1639416428    <attribute name="filter" type="wstring" readonly="yes">
    1639516429      <desc>Directory listing filter to (specified when opening the directory).</desc>
     16430    </attribute>
     16431
     16432    <attribute name="id" type="unsigned long" readonly="yes">
     16433      <desc>
     16434        The ID VirtualBox internally assigned to the open directory.
     16435      </desc>
     16436    </attribute>
     16437
     16438    <attribute name="status" type="DirectoryStatus" readonly="yes">
     16439      <desc>
     16440        Current directory status.
     16441      </desc>
    1639616442    </attribute>
    1639716443
     
    1641416460          <link to="IFsObjInfo"/>.</desc>
    1641516461      </param>
     16462    </method>
     16463
     16464    <method name="rewind">
     16465      <desc>
     16466        Rewinds the directory reading.
     16467      </desc>
    1641616468    </method>
    1641716469
     
    1679916851    <attribute name="fileAttributes" type="wstring" readonly="yes">
    1680016852      <desc>
    16801         File attributes. Not implemented yet.
     16853        File attributes.
    1680216854      </desc>
    1680316855    </attribute>
     
    2626026312  <enum
    2626126313    name="VBoxEventType"
    26262     uuid="e4c5252d-7d1a-4051-8cfb-5b2d7a73d992"
     26314    uuid="03b0e6ea-28fe-4f0a-a3ec-1a21703da6f7"
    2626326315    >
    2626426316
     
    2675926811      </desc>
    2676026812    </const>
     26813    <const name="OnGuestDirectoryRegistered" value="119">
     26814      <desc>
     26815        See <link to="IGuestDirectoryRegisteredEvent">IGuestDirectoryRegisteredEvent</link>.
     26816      </desc>
     26817    </const>
     26818    <const name="OnGuestDirectoryStateChanged" value="120">
     26819      <desc>
     26820        See <link to="IGuestDirectoryStateChangedEvent">IGuestDirectoryStateChangedEvent</link>.
     26821      </desc>
     26822    </const>
     26823    <const name="OnGuestDirectoryRead" value="121">
     26824      <desc>
     26825        See <link to="IGuestDirectoryReadEvent">IGuestDirectoryReadEvent</link>.
     26826        <note internal="yes">For performance reasons this is a separate event to
     26827          not unnecessarily overflow the event queue.</note>
     26828      </desc>
     26829    </const>
    2676126830    <!-- End event marker -->
    26762     <const name="End" value="119">
     26831    <const name="End" value="122">
    2676326832      <desc>
    2676426833        Must be last event, used for iterations and structures relying on numerical event values.
     
    2797928048        Actual output data.
    2798028049      </desc>
     28050    </attribute>
     28051
     28052  </interface>
     28053
     28054  <interface
     28055    name="IGuestDirectoryEvent" extends="IGuestSessionEvent"
     28056    uuid="02b69798-7cc2-4005-ac57-1ad7ff7a0997"
     28057    wsmap="managed"
     28058    >
     28059    <desc>Base abstract interface for all guest directory events.</desc>
     28060
     28061    <attribute name="directory" type="IGuestDirectory" readonly="yes">
     28062      <desc>
     28063        Guest directory object which is related to this event.
     28064      </desc>
     28065    </attribute>
     28066
     28067  </interface>
     28068
     28069  <interface
     28070    name="IGuestDirectoryRegisteredEvent" extends="IGuestDirectoryEvent"
     28071    uuid="926baa39-cfc9-462e-a1a1-c439e28f7f89"
     28072    wsmap="managed" autogen="VBoxEvent" id="OnGuestDirectoryRegistered"
     28073    >
     28074    <desc>
     28075      Notification when a guest directory was registered or unregistered.
     28076    </desc>
     28077
     28078    <attribute name="registered" type="boolean" readonly="yes">
     28079      <desc>
     28080        If @c true, the guest directory was registered, otherwise it was
     28081        unregistered.
     28082      </desc>
     28083    </attribute>
     28084
     28085  </interface>
     28086
     28087  <interface
     28088    name="IGuestDirectoryStateChangedEvent" extends="IGuestDirectoryEvent"
     28089    uuid="c32bce60-d69d-4eb7-a02a-411ecbab6a18"
     28090    wsmap="managed" autogen="VBoxEvent" id="OnGuestDirectoryStateChanged"
     28091    >
     28092    <desc>
     28093      Notification when a guest directory changed its state.
     28094    </desc>
     28095
     28096    <attribute name="status" type="DirectoryStatus" readonly="yes">
     28097      <desc>
     28098        New guest directory status.
     28099      </desc>
     28100    </attribute>
     28101    <attribute name="error" type="IVirtualBoxErrorInfo" readonly="yes">
     28102      <desc>
     28103        Error information in case of new session status is indicating an error.
     28104
     28105        The attribute <link to="IVirtualBoxErrorInfo::resultDetail"/> will contain
     28106        the runtime (IPRT) error code from the guest. See include/iprt/err.h and
     28107        include/VBox/err.h for details.
     28108      </desc>
     28109    </attribute>
     28110    <!-- Note: No events for reads for performance reasons.
     28111               See dedicated event IGuestDirectoryReadEvent. -->
     28112
     28113  </interface>
     28114
     28115  <interface
     28116    name="IGuestDirectoryReadEvent" extends="IGuestDirectoryEvent"
     28117    uuid="6eef78d9-51d6-495b-8f91-807654a189a2"
     28118    wsmap="managed" autogen="VBoxEvent" id="OnGuestDirectoryRead"
     28119    >
     28120    <desc>
     28121      Notification when a directory entry has been read.
     28122    </desc>
     28123
     28124    <attribute name="objInfo" type="IFsObjInfo" readonly="yes">
     28125      <desc>Object information of the current directory entry read. Also see
     28126        <link to="IFsObjInfo"/>.</desc>
    2798128127    </attribute>
    2798228128
  • trunk/src/VBox/Main/include/GuestCtrlImplPrivate.h

    r98272 r98526  
    6262typedef std::vector <Utf8Str> ProcessArguments;
    6363
    64 class GuestProcessStreamBlock;
     64class GuestToolboxStreamBlock;
    6565class GuestSession;
    6666
     
    636636        /** Guest error is from a guest directory object. */
    637637        Type_Directory,
    638         /** Guest error is from a the built-in toolbox "vbox_cat" command. */
    639         Type_ToolCat,
     638        /** Guest error is from a file system operation. */
     639        Type_Fs,
     640#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    640641        /** Guest error is from a the built-in toolbox "vbox_ls" command. */
    641642        Type_ToolLs,
     
    648649        /** Guest error is from a the built-in toolbox "vbox_stat" command. */
    649650        Type_ToolStat,
     651#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    650652        /** The usual 32-bit hack. */
    651653        Type_32BIT_HACK = 0x7fffffff
     
    721723{
    722724    GuestDirectoryOpenInfo(void)
    723         : mFlags(0) { }
     725        : menmFilter(GSTCTLDIRFILTER_NONE)
     726        , mFlags(0) { }
    724727
    725728    /** The directory path. */
    726729    Utf8Str                 mPath;
    727     /** Then open filter. */
     730    /** The filter to use (wildcard style). */
    728731    Utf8Str                 mFilter;
    729     /** Opening flags. */
     732    /** The filter option to use. */
     733    GSTCTLDIRFILTER         menmFilter;
     734    /** Opening flags (of type GSTCTLDIRFILTER_XXX). */
    730735    uint32_t                mFlags;
    731736};
     
    799804
    800805/**
     806 * Helper class for guest file system operations.
     807 */
     808class GuestFs
     809{
     810    DECLARE_TRANSLATE_METHODS(GuestFs)
     811
     812private:
     813
     814    /* Not directly instantiable. */
     815    GuestFs(void) { }
     816
     817public:
     818
     819    static Utf8Str guestErrorToString(const GuestErrorInfo &guestErrorInfo);
     820};
     821
     822
     823/**
    801824 * Structure representing information of a
    802825 * file system object.
     
    804827struct GuestFsObjData
    805828{
    806     GuestFsObjData(void)
     829    GuestFsObjData(const Utf8Str &strName = "")
    807830        : mType(FsObjType_Unknown)
    808831        , mObjectSize(0)
     
    819842        , mDeviceNumber(0)
    820843        , mGenerationID(0)
    821         , mUserFlags(0) { }
    822 
     844        , mUserFlags(0) { mName = strName; }
     845
     846    void Init(const Utf8Str &strName) { mName = strName; }
     847
     848#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     849    int FromGuestFsObjInfo(PCGSTCTLFSOBJINFO pFsObjInfo, const Utf8Str &strUser = "", const Utf8Str &strGroups = "",
     850                           const void *pvACL = NULL, size_t cbACL = 0);
     851#endif
     852
     853#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    823854    /** @name Helper functions to extract the data from a certin VBoxService tool's guest stream block.
    824855     * @{ */
    825     int FromLs(const GuestProcessStreamBlock &strmBlk, bool fLong);
    826     int FromRm(const GuestProcessStreamBlock &strmBlk);
    827     int FromStat(const GuestProcessStreamBlock &strmBlk);
    828     int FromMkTemp(const GuestProcessStreamBlock &strmBlk);
     856    int FromToolboxLs(const GuestToolboxStreamBlock &strmBlk, bool fLong);
     857    int FromToolboxRm(const GuestToolboxStreamBlock &strmBlk);
     858    int FromToolboxStat(const GuestToolboxStreamBlock &strmBlk);
     859    int FromToolboxMkTemp(const GuestToolboxStreamBlock &strmBlk);
    829860    /** @}  */
    830 
     861#endif
     862
     863#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    831864    /** @name Static helper functions to work with time from stream block keys.
    832865     * @{ */
    833     static PRTTIMESPEC TimeSpecFromKey(const GuestProcessStreamBlock &strmBlk, const Utf8Str &strKey, PRTTIMESPEC pTimeSpec);
    834     static int64_t UnixEpochNsFromKey(const GuestProcessStreamBlock &strmBlk, const Utf8Str &strKey);
     866    static PRTTIMESPEC TimeSpecFromKey(const GuestToolboxStreamBlock &strmBlk, const Utf8Str &strKey, PRTTIMESPEC pTimeSpec);
     867    static int64_t UnixEpochNsFromKey(const GuestToolboxStreamBlock &strmBlk, const Utf8Str &strKey);
    835868    /** @}  */
     869#endif
    836870
    837871    /** @name helper functions to work with IPRT stuff.
     
    932966 * Class representing the "value" side of a "key=value" pair.
    933967 */
    934 class GuestProcessStreamValue
    935 {
    936 public:
    937 
    938     GuestProcessStreamValue(void) { }
    939     GuestProcessStreamValue(const char *pszValue)
     968class GuestToolboxStreamValue
     969{
     970public:
     971
     972    GuestToolboxStreamValue(void) { }
     973    GuestToolboxStreamValue(const char *pszValue)
    940974        : mValue(pszValue) {}
    941975
    942     GuestProcessStreamValue(const GuestProcessStreamValue& aThat)
     976    GuestToolboxStreamValue(const GuestToolboxStreamValue& aThat)
    943977           : mValue(aThat.mValue) { }
    944978
    945979    /** Copy assignment operator. */
    946     GuestProcessStreamValue &operator=(GuestProcessStreamValue const &a_rThat) RT_NOEXCEPT
     980    GuestToolboxStreamValue &operator=(GuestToolboxStreamValue const &a_rThat) RT_NOEXCEPT
    947981    {
    948982        mValue = a_rThat.mValue;
     
    955989
    956990/** Map containing "key=value" pairs of a guest process stream. */
    957 typedef std::pair< Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPair;
    958 typedef std::map < Utf8Str, GuestProcessStreamValue > GuestCtrlStreamPairMap;
    959 typedef std::map < Utf8Str, GuestProcessStreamValue >::iterator GuestCtrlStreamPairMapIter;
    960 typedef std::map < Utf8Str, GuestProcessStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
     991typedef std::pair< Utf8Str, GuestToolboxStreamValue > GuestCtrlStreamPair;
     992typedef std::map < Utf8Str, GuestToolboxStreamValue > GuestCtrlStreamPairMap;
     993typedef std::map < Utf8Str, GuestToolboxStreamValue >::iterator GuestCtrlStreamPairMapIter;
     994typedef std::map < Utf8Str, GuestToolboxStreamValue >::const_iterator GuestCtrlStreamPairMapIterConst;
    961995
    962996/**
     
    964998 * output stream is separated by "\0\0", each pair is separated by "\0". The overall
    965999 * end of a guest stream is marked by "\0\0\0\0".
    966  */
    967 class GuestProcessStreamBlock
    968 {
    969 public:
    970 
    971     GuestProcessStreamBlock(void);
    972 
    973     virtual ~GuestProcessStreamBlock(void);
     1000 *
     1001 * Only used for the busybox-like toolbox commands within VBoxService.
     1002 * Deprecated, do not use anymore.
     1003 */
     1004class GuestToolboxStreamBlock
     1005{
     1006public:
     1007
     1008    GuestToolboxStreamBlock(void);
     1009
     1010    virtual ~GuestToolboxStreamBlock(void);
    9741011
    9751012public:
     
    10001037
    10011038/** Vector containing multiple allocated stream pair objects. */
    1002 typedef std::vector< GuestProcessStreamBlock > GuestCtrlStreamObjects;
    1003 typedef std::vector< GuestProcessStreamBlock >::iterator GuestCtrlStreamObjectsIter;
    1004 typedef std::vector< GuestProcessStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
     1039typedef std::vector< GuestToolboxStreamBlock > GuestCtrlStreamObjects;
     1040typedef std::vector< GuestToolboxStreamBlock >::iterator GuestCtrlStreamObjectsIter;
     1041typedef std::vector< GuestToolboxStreamBlock >::const_iterator GuestCtrlStreamObjectsIterConst;
    10051042
    10061043/**
    10071044 * Class for parsing machine-readable guest process output by VBoxService'
    10081045 * toolbox commands ("vbox_ls", "vbox_stat" etc), aka "guest stream".
    1009  */
    1010 class GuestProcessStream
    1011 {
    1012 
    1013 public:
    1014 
    1015     GuestProcessStream();
    1016 
    1017     virtual ~GuestProcessStream();
     1046 *
     1047 * Deprecated, do not use anymore.
     1048 */
     1049class GuestToolboxStream
     1050{
     1051
     1052public:
     1053
     1054    GuestToolboxStream();
     1055
     1056    virtual ~GuestToolboxStream();
    10181057
    10191058public:
     
    10311070    size_t GetSize() { return m_cbUsed; }
    10321071
    1033     int ParseBlock(GuestProcessStreamBlock &streamBlock);
     1072    int ParseBlock(GuestToolboxStreamBlock &streamBlock);
    10341073
    10351074protected:
  • trunk/src/VBox/Main/include/GuestDirectoryImpl.h

    r98272 r98526  
    6868    /** @name Public internal methods.
    6969     * @{ */
    70     int            i_closeInternal(int *pvrcGuest);
     70    int            i_open(int *pvrcGuest);
     71    int            i_close(int *pvrcGuest);
     72    EventSource   *i_getEventSource(void) { return mEventSource; }
     73    int            i_onDirNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData);
    7174    int            i_read(ComObjPtr<GuestFsObjInfo> &fsObjInfo, int *pvrcGuest);
    72     int            i_readInternal(GuestFsObjData &objData, int *prcGuest);
     75    int            i_readInternal(GuestFsObjData &objData, int *pvrcGuest);
     76    int            i_rewind(uint32_t uTimeoutMS, int *pvrcGuest);
     77    int            i_setStatus(DirectoryStatus_T enmStatus, int vrcDir);
    7378    /** @}  */
     79
     80#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     81    int            i_openViaToolbox(int *pvrcGuest);
     82    int            i_closeViaToolbox(int *pvrcGuest);
     83    int            i_readInternalViaToolbox(GuestFsObjData &objData, int *pvrcGuest);
     84#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    7485
    7586public:
     
    90101     * @{ */
    91102    HRESULT close();
     103    HRESULT getEventSource(ComPtr<IEventSource> &aEventSource);
     104    HRESULT getId(ULONG *aId);
     105    HRESULT getStatus(DirectoryStatus_T *aStatus);
    92106    HRESULT read(ComPtr<IFsObjInfo> &aObjInfo);
     107    HRESULT rewind(void);
    93108    /** @}  */
     109
     110    /** This can safely be used without holding any locks.
     111     * An AutoCaller suffices to prevent it being destroy while in use and
     112     * internally there is a lock providing the necessary serialization. */
     113    const ComObjPtr<EventSource> mEventSource;
    94114
    95115    struct Data
     
    97117        /** The directory's open info. */
    98118        GuestDirectoryOpenInfo     mOpenInfo;
     119        /** The current directory status. */
     120        DirectoryStatus_T          mStatus;
     121        /** The last returned directory error returned from the guest side. */
     122        int                        mLastError;
     123# ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    99124        /** The process tool instance to use. */
    100         GuestProcessTool           mProcessTool;
     125        GuestProcessToolbox        mProcessTool;
     126# endif
    101127        /** Object data cache.
    102128         *  Its mName attribute acts as a beacon if the cache is valid or not. */
  • trunk/src/VBox/Main/include/GuestProcessImpl.h

    r98272 r98526  
    229229 *       This class has to be kept to guarantee backwards-compatibility.
    230230 */
    231 class GuestProcessTool
     231class GuestProcessToolbox
    232232{
    233233public:
    234234    DECLARE_TRANSLATE_METHODS(GuestProcessTool)
    235235
    236     GuestProcessTool(void);
    237 
    238     virtual ~GuestProcessTool(void);
     236    GuestProcessToolbox(void);
     237
     238    virtual ~GuestProcessToolbox(void);
    239239
    240240public:
     
    244244    void uninit(void);
    245245
    246     int getCurrentBlock(uint32_t uHandle, GuestProcessStreamBlock &strmBlock);
     246    int getCurrentBlock(uint32_t uHandle, GuestToolboxStreamBlock &strmBlock);
    247247
    248248    int getRc(void) const;
    249249
    250250    /** Returns the stdout output from the guest process tool. */
    251     GuestProcessStream &getStdOut(void) { return mStdOut; }
     251    GuestToolboxStream &getStdOut(void) { return mStdOut; }
    252252
    253253    /** Returns the stderr output from the guest process tool. */
    254     GuestProcessStream &getStdErr(void) { return mStdErr; }
     254    GuestToolboxStream &getStdErr(void) { return mStdErr; }
    255255
    256256    int wait(uint32_t fToolWaitFlags, int *pvrcGuest);
    257257
    258     int waitEx(uint32_t fToolWaitFlags, GuestProcessStreamBlock *pStreamBlock, int *pvrcGuest);
     258    int waitEx(uint32_t fToolWaitFlags, GuestToolboxStreamBlock *pStreamBlock, int *pvrcGuest);
    259259
    260260    bool isRunning(void);
     
    302302    GuestProcessStartupInfo     mStartupInfo;
    303303    /** Stream object for handling the toolbox' stdout data. */
    304     GuestProcessStream          mStdOut;
     304    GuestToolboxStream          mStdOut;
    305305    /** Stream object for handling the toolbox' stderr data. */
    306     GuestProcessStream          mStdErr;
     306    GuestToolboxStream          mStdErr;
    307307};
    308308
  • trunk/src/VBox/Main/src-client/GuestCtrlPrivate.cpp

    r98278 r98526  
    5353
    5454
     55#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     56/**
     57 * Returns a stringyfied error of a guest fs error.
     58 *
     59 * @returns Stringyfied error.
     60 * @param   guestErrorInfo      Guest error info to get stringyfied error for.
     61 */
     62/* static */
     63Utf8Str GuestFs::guestErrorToString(const GuestErrorInfo &guestErrorInfo)
     64{
     65    Utf8Str strErr;
     66
     67    /** @todo pData->u32Flags: int vs. uint32 -- IPRT errors are *negative* !!! */
     68    switch (guestErrorInfo.getVrc())
     69    {
     70        case VERR_ACCESS_DENIED:
     71            strErr.printf(tr("Access to \"%s\" denied"), guestErrorInfo.getWhat().c_str());
     72            break;
     73
     74        case VERR_FILE_NOT_FOUND: /* This is the most likely error. */
     75            RT_FALL_THROUGH();
     76        case VERR_PATH_NOT_FOUND:
     77            strErr.printf(tr("No such file or directory \"%s\""), guestErrorInfo.getWhat().c_str());
     78            break;
     79
     80        case VERR_INVALID_VM_HANDLE:
     81            strErr.printf(tr("VMM device is not available (is the VM running?)"));
     82            break;
     83
     84        case VERR_HGCM_SERVICE_NOT_FOUND:
     85            strErr.printf(tr("The guest execution service is not available"));
     86            break;
     87
     88        case VERR_BAD_EXE_FORMAT:
     89            strErr.printf(tr("The file \"%s\" is not an executable format"), guestErrorInfo.getWhat().c_str());
     90            break;
     91
     92        case VERR_AUTHENTICATION_FAILURE:
     93            strErr.printf(tr("The user \"%s\" was not able to logon"), guestErrorInfo.getWhat().c_str());
     94            break;
     95
     96        case VERR_INVALID_NAME:
     97            strErr.printf(tr("The file \"%s\" is an invalid name"), guestErrorInfo.getWhat().c_str());
     98            break;
     99
     100        case VERR_TIMEOUT:
     101            strErr.printf(tr("The guest did not respond within time"));
     102            break;
     103
     104        case VERR_CANCELLED:
     105            strErr.printf(tr("The execution operation was canceled"));
     106            break;
     107
     108        case VERR_GSTCTL_MAX_CID_OBJECTS_REACHED:
     109            strErr.printf(tr("Maximum number of concurrent guest processes has been reached"));
     110            break;
     111
     112        case VERR_NOT_FOUND:
     113            strErr.printf(tr("The guest execution service is not ready (yet)"));
     114            break;
     115
     116        default:
     117            strErr.printf(tr("Unhandled error %Rrc for \"%s\" occurred on guest -- please file a bug report"),
     118                          guestErrorInfo.getVrc(), guestErrorInfo.getWhat().c_str());
     119            break;
     120    }
     121
     122    return strErr;
     123}
     124
     125
     126/**
     127 * Set the file system object data from a given GSTCTLFSOBJINFO struct.
     128 *
     129 * @returns VBox status code.
     130 * @param   pFsObjInfo          Pointer to GSTCTLFSOBJINFO struct to use.
     131 * @param   strUser             Resolved user name owning the object on the guest.
     132 * @param   strGroups           Resolved user group(s) the object on the guest is associated with.
     133 *                              On Windows there can be multiple groups assigned. The groups are separated with ";"
     134 *                              The first group found is always the primary group.
     135 * @param   pvACL               ACL data associated with the object.
     136 * @param   cbACL               Size of ACL data (in bytes) associated with the object.
     137 */
     138int GuestFsObjData::FromGuestFsObjInfo(PCGSTCTLFSOBJINFO pFsObjInfo,
     139                                       const Utf8Str &strUser /* = "" */, const Utf8Str &strGroups /* = "" */, const void *pvACL /* = NULL */, size_t cbACL /* = 0 */)
     140{
     141    RT_NOREF(pvACL, cbACL);
     142
     143    int rc;
     144
     145    mType = GuestBase::fileModeToFsObjType(pFsObjInfo->Attr.fMode);
     146
     147    mFileAttrs = "";
     148    switch (mType)
     149    {
     150        case FsObjType_File:      mFileAttrs += '-'; break;
     151        case FsObjType_Directory: mFileAttrs += 'd'; break;
     152        case FsObjType_Symlink:   mFileAttrs += 'l'; break;
     153        case FsObjType_DevChar:   mFileAttrs += 'c'; break;
     154        case FsObjType_DevBlock:  mFileAttrs += 'b'; break;
     155        case FsObjType_Fifo:      mFileAttrs += 'f'; break;
     156        case FsObjType_Socket:    mFileAttrs += 's'; break;
     157        case FsObjType_WhiteOut:  mFileAttrs += 'w'; break;
     158        default:
     159            mFileAttrs += '?';
     160            AssertFailedStmt(rc = VERR_NOT_SUPPORTED);
     161            break;
     162    }
     163
     164#define ADD_ATTR(a_Flag, a_Set, a_Clear) \
     165    mFileAttrs += pFsObjInfo->Attr.fMode & a_Flag ? a_Set : a_Clear
     166
     167    ADD_ATTR(RTFS_UNIX_IRUSR, 'r', '-');
     168    ADD_ATTR(RTFS_UNIX_IWUSR, 'w', '-');
     169    ADD_ATTR(RTFS_UNIX_IXUSR, 'x', '-');
     170
     171    ADD_ATTR(RTFS_UNIX_IRGRP, 'r', '-');
     172    ADD_ATTR(RTFS_UNIX_IWGRP, 'w', '-');
     173    ADD_ATTR(RTFS_UNIX_IXGRP, 'x', '-');
     174
     175    ADD_ATTR(RTFS_UNIX_IROTH, 'r', '-');
     176    ADD_ATTR(RTFS_UNIX_IWOTH, 'w', '-');
     177    ADD_ATTR(RTFS_UNIX_IXOTH, 'x', '-');
     178
     179    /** @todo Implement sticky bits. */
     180    mFileAttrs += "   "; /* Reserve 3 chars for sticky bits. */
     181
     182    mFileAttrs += " "; /* Separator. */
     183
     184    ADD_ATTR(RTFS_DOS_READONLY              , 'R', '-');
     185    ADD_ATTR(RTFS_DOS_HIDDEN                , 'H', '-');
     186    ADD_ATTR(RTFS_DOS_SYSTEM                , 'S', '-');
     187    ADD_ATTR(RTFS_DOS_DIRECTORY             , 'D', '-');
     188    ADD_ATTR(RTFS_DOS_ARCHIVED              , 'A', '-');
     189    ADD_ATTR(RTFS_DOS_NT_DEVICE             , 'd', '-');
     190    ADD_ATTR(RTFS_DOS_NT_NORMAL             , 'N', '-');
     191    ADD_ATTR(RTFS_DOS_NT_TEMPORARY          , 'T', '-');
     192    ADD_ATTR(RTFS_DOS_NT_SPARSE_FILE        , 'P', '-');
     193    ADD_ATTR(RTFS_DOS_NT_REPARSE_POINT      , 'J', '-');
     194    ADD_ATTR(RTFS_DOS_NT_COMPRESSED         , 'C', '-');
     195    ADD_ATTR(RTFS_DOS_NT_OFFLINE            , 'O', '-');
     196    ADD_ATTR(RTFS_DOS_NT_NOT_CONTENT_INDEXED, 'I', '-');
     197    ADD_ATTR(RTFS_DOS_NT_ENCRYPTED          , 'E', '-');
     198
     199#undef ADD_ATTR
     200
     201    mObjectSize       = pFsObjInfo->cbObject;
     202    mAllocatedSize    = pFsObjInfo->cbAllocated;
     203    mAccessTime       = pFsObjInfo->AccessTime.i64NanosecondsRelativeToUnixEpoch;
     204    mBirthTime        = pFsObjInfo->BirthTime.i64NanosecondsRelativeToUnixEpoch;
     205    mChangeTime       = pFsObjInfo->ChangeTime.i64NanosecondsRelativeToUnixEpoch;
     206    mModificationTime = pFsObjInfo->ModificationTime.i64NanosecondsRelativeToUnixEpoch;
     207    mUserName         = strUser;
     208    mUID              = pFsObjInfo->Attr.u.Unix.uid;
     209    mGID              = pFsObjInfo->Attr.u.Unix.gid;
     210    mGroupName        = strGroups; /** @todo Separate multiple group. */
     211    mNumHardLinks     = pFsObjInfo->Attr.u.Unix.cHardlinks;
     212    mNodeIDDevice     = pFsObjInfo->Attr.u.Unix.INodeIdDevice;
     213    mNodeID           = pFsObjInfo->Attr.u.Unix.INodeId;
     214    mDeviceNumber     =    RTFS_IS_DEV_BLOCK(pFsObjInfo->Attr.fMode)
     215                        || RTFS_IS_DEV_CHAR (pFsObjInfo->Attr.fMode) ? pFsObjInfo->Attr.u.Unix.Device : 0;
     216    mGenerationID     = pFsObjInfo->Attr.u.Unix.GenerationId;
     217    mUserFlags        = 0;
     218
     219    mACL              = ""; /** @todo Implement ACL handling. */
     220
     221    return VINF_SUCCESS;
     222}
     223#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     224
     225#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    55226/**
    56227 * Extracts the timespec from a given stream block key.
     
    62233 */
    63234/* static */
    64 PRTTIMESPEC GuestFsObjData::TimeSpecFromKey(const GuestProcessStreamBlock &strmBlk, const Utf8Str &strKey, PRTTIMESPEC pTimeSpec)
     235PRTTIMESPEC GuestFsObjData::TimeSpecFromKey(const GuestToolboxStreamBlock &strmBlk, const Utf8Str &strKey, PRTTIMESPEC pTimeSpec)
    65236{
    66237    AssertPtrReturn(pTimeSpec, NULL);
     
    84255 */
    85256/* static */
    86 int64_t GuestFsObjData::UnixEpochNsFromKey(const GuestProcessStreamBlock &strmBlk, const Utf8Str &strKey)
     257int64_t GuestFsObjData::UnixEpochNsFromKey(const GuestToolboxStreamBlock &strmBlk, const Utf8Str &strKey)
    87258{
    88259    RTTIMESPEC TimeSpec;
     
    103274 * @param  fLong                Whether the stream block contains long (detailed) information or not.
    104275 */
    105 int GuestFsObjData::FromLs(const GuestProcessStreamBlock &strmBlk, bool fLong)
     276int GuestFsObjData::FromToolboxLs(const GuestToolboxStreamBlock &strmBlk, bool fLong)
    106277{
    107278    LogFlowFunc(("\n"));
     
    253424 * @param   strmBlk             Stream block output data to parse.
    254425 */
    255 int GuestFsObjData::FromRm(const GuestProcessStreamBlock &strmBlk)
     426int GuestFsObjData::FromToolboxRm(const GuestToolboxStreamBlock &strmBlk)
    256427{
    257428#ifdef DEBUG
     
    272443 * @param   strmBlk             Stream block output data to parse.
    273444 */
    274 int GuestFsObjData::FromStat(const GuestProcessStreamBlock &strmBlk)
     445int GuestFsObjData::FromToolboxStat(const GuestToolboxStreamBlock &strmBlk)
    275446{
    276447    /* Should be identical output. */
    277     return GuestFsObjData::FromLs(strmBlk, true /*fLong*/);
     448    return GuestFsObjData::FromToolboxLs(strmBlk, true /*fLong*/);
    278449}
    279450
     
    285456 * @param   strmBlk             Stream block output data to parse.
    286457 */
    287 int GuestFsObjData::FromMkTemp(const GuestProcessStreamBlock &strmBlk)
     458int GuestFsObjData::FromToolboxMkTemp(const GuestToolboxStreamBlock &strmBlk)
    288459{
    289460    LogFlowFunc(("\n"));
     
    302473}
    303474
     475#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     476
    304477/**
    305478 * Returns the IPRT-compatible file mode.
     
    337510///////////////////////////////////////////////////////////////////////////////
    338511
     512#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    339513/** @todo *NOT* thread safe yet! */
    340514/** @todo Add exception handling for STL stuff! */
    341515
    342 GuestProcessStreamBlock::GuestProcessStreamBlock(void)
    343 {
    344 
    345 }
    346 
    347 GuestProcessStreamBlock::~GuestProcessStreamBlock()
     516GuestToolboxStreamBlock::GuestToolboxStreamBlock(void)
     517{
     518
     519}
     520
     521GuestToolboxStreamBlock::~GuestToolboxStreamBlock()
    348522{
    349523    Clear();
     
    353527 * Clears (destroys) the currently stored stream pairs.
    354528 */
    355 void GuestProcessStreamBlock::Clear(void)
     529void GuestToolboxStreamBlock::Clear(void)
    356530{
    357531    mPairs.clear();
     
    362536 * Dumps the currently stored stream pairs to the (debug) log.
    363537 */
    364 void GuestProcessStreamBlock::DumpToLog(void) const
     538void GuestToolboxStreamBlock::DumpToLog(void) const
    365539{
    366540    LogFlowFunc(("Dumping contents of stream block=0x%p (%ld items):\n",
     
    382556 * @param  piVal                Pointer to value to return.
    383557 */
    384 int GuestProcessStreamBlock::GetInt64Ex(const char *pszKey, int64_t *piVal) const
     558int GuestToolboxStreamBlock::GetInt64Ex(const char *pszKey, int64_t *piVal) const
    385559{
    386560    AssertPtrReturn(pszKey, VERR_INVALID_POINTER);
     
    401575 * @param   pszKey              Name of key to get the value for.
    402576 */
    403 int64_t GuestProcessStreamBlock::GetInt64(const char *pszKey) const
     577int64_t GuestToolboxStreamBlock::GetInt64(const char *pszKey) const
    404578{
    405579    int64_t iVal;
     
    414588 * @return  uint32_t            Current number of stream pairs.
    415589 */
    416 size_t GuestProcessStreamBlock::GetCount(void) const
     590size_t GuestToolboxStreamBlock::GetCount(void) const
    417591{
    418592    return mPairs.size();
     
    425599 * @retval  VERR_NOT_FOUND if the return code string ("rc") was not found.
    426600 */
    427 int GuestProcessStreamBlock::GetVrc(void) const
     601int GuestToolboxStreamBlock::GetVrc(void) const
    428602{
    429603    const char *pszValue = GetString("rc");
     
    440614 * @param   pszKey              Name of key to get the value for.
    441615 */
    442 const char *GuestProcessStreamBlock::GetString(const char *pszKey) const
     616const char *GuestToolboxStreamBlock::GetString(const char *pszKey) const
    443617{
    444618    AssertPtrReturn(pszKey, NULL);
     
    464638 * @param   puVal               Pointer to value to return.
    465639 */
    466 int GuestProcessStreamBlock::GetUInt32Ex(const char *pszKey, uint32_t *puVal) const
     640int GuestToolboxStreamBlock::GetUInt32Ex(const char *pszKey, uint32_t *puVal) const
    467641{
    468642    const char *pszValue = GetString(pszKey);
     
    482656 * @param   iDefault            The default to return on error if not found.
    483657 */
    484 int32_t GuestProcessStreamBlock::GetInt32(const char *pszKey, int32_t iDefault) const
     658int32_t GuestToolboxStreamBlock::GetInt32(const char *pszKey, int32_t iDefault) const
    485659{
    486660    const char *pszValue = GetString(pszKey);
     
    503677 * @param   uDefault            The default value to return.
    504678 */
    505 uint32_t GuestProcessStreamBlock::GetUInt32(const char *pszKey, uint32_t uDefault /*= 0*/) const
     679uint32_t GuestToolboxStreamBlock::GetUInt32(const char *pszKey, uint32_t uDefault /*= 0*/) const
    506680{
    507681    uint32_t uVal;
     
    518692 * @param   pszValue            Value to set. Set NULL for deleting the key.
    519693 */
    520 int GuestProcessStreamBlock::SetValue(const char *pszKey, const char *pszValue)
     694int GuestToolboxStreamBlock::SetValue(const char *pszKey, const char *pszValue)
    521695{
    522696    AssertPtrReturn(pszKey, VERR_INVALID_POINTER);
     
    538712        if (pszValue)
    539713        {
    540             GuestProcessStreamValue val(pszValue);
     714            GuestToolboxStreamValue val(pszValue);
    541715            mPairs[strKey] = val;
    542716        }
     
    551725///////////////////////////////////////////////////////////////////////////////
    552726
    553 GuestProcessStream::GuestProcessStream(void)
     727GuestToolboxStream::GuestToolboxStream(void)
    554728    : m_cbMax(_32M)
    555729    , m_cbAllocated(0)
     
    558732    , m_pbBuffer(NULL) { }
    559733
    560 GuestProcessStream::~GuestProcessStream(void)
     734GuestToolboxStream::~GuestToolboxStream(void)
    561735{
    562736    Destroy();
     
    571745 * @param   cbData              Size (in bytes) of data to add.
    572746 */
    573 int GuestProcessStream::AddData(const BYTE *pbData, size_t cbData)
     747int GuestToolboxStream::AddData(const BYTE *pbData, size_t cbData)
    574748{
    575749    AssertPtrReturn(pbData, VERR_INVALID_POINTER);
     
    642816 * Destroys the internal data buffer.
    643817 */
    644 void GuestProcessStream::Destroy(void)
     818void GuestToolboxStream::Destroy(void)
    645819{
    646820    if (m_pbBuffer)
     
    662836 * @param   pszFile             Absolute path to host file to dump the output to.
    663837 */
    664 void GuestProcessStream::Dump(const char *pszFile)
     838void GuestToolboxStream::Dump(const char *pszFile)
    665839{
    666840    LogFlowFunc(("Dumping contents of stream=0x%p (cbAlloc=%u, cbSize=%u, cbOff=%u) to %s\n",
     
    694868 * @param streamBlock               Reference to guest stream block to fill.
    695869 */
    696 int GuestProcessStream::ParseBlock(GuestProcessStreamBlock &streamBlock)
     870int GuestToolboxStream::ParseBlock(GuestToolboxStreamBlock &streamBlock)
    697871{
    698872    if (   !m_pbBuffer
     
    749923    return vrc;
    750924}
     925#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    751926
    752927GuestBase::GuestBase(void)
     
    13521527    Utf8Str strErr;
    13531528
    1354 #define CASE_TOOL_ERROR(a_eType, a_strTool) \
     1529#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     1530# define CASE_TOOL_ERROR(a_eType, a_strTool) \
    13551531    case a_eType: \
    13561532    { \
    1357         strErr = GuestProcessTool::guestErrorToString(a_strTool, guestErrorInfo); \
     1533        strErr = GuestProcessToolbox::guestErrorToString(a_strTool, guestErrorInfo); \
    13581534        break; \
    13591535    }
     1536#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    13601537
    13611538    switch (guestErrorInfo.getType())
     
    13771554            break;
    13781555
    1379         CASE_TOOL_ERROR(GuestErrorInfo::Type_ToolCat,    VBOXSERVICE_TOOL_CAT);
     1556        case GuestErrorInfo::Type_Fs:
     1557            strErr = GuestFs::guestErrorToString(guestErrorInfo);
     1558            break;
     1559
     1560#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    13801561        CASE_TOOL_ERROR(GuestErrorInfo::Type_ToolLs,     VBOXSERVICE_TOOL_LS);
    13811562        CASE_TOOL_ERROR(GuestErrorInfo::Type_ToolMkDir,  VBOXSERVICE_TOOL_MKDIR);
     
    13831564        CASE_TOOL_ERROR(GuestErrorInfo::Type_ToolRm,     VBOXSERVICE_TOOL_RM);
    13841565        CASE_TOOL_ERROR(GuestErrorInfo::Type_ToolStat,   VBOXSERVICE_TOOL_STAT);
    1385 
     1566#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    13861567        default:
    13871568            AssertMsgFailed(("Type not implemented (type=%RU32, vrc=%Rrc)\n", guestErrorInfo.getType(), guestErrorInfo.getVrc()));
     
    14051586FsObjType_T GuestBase::fileModeToFsObjType(RTFMODE fMode)
    14061587{
    1407     if (RTFS_IS_FILE(fMode))           return FsObjType_File;
     1588         if (RTFS_IS_FIFO(fMode))      return FsObjType_Fifo;
     1589    else if (RTFS_IS_DEV_CHAR(fMode))  return FsObjType_DevChar;
    14081590    else if (RTFS_IS_DIRECTORY(fMode)) return FsObjType_Directory;
     1591    else if (RTFS_IS_DEV_BLOCK(fMode)) return FsObjType_DevBlock;
     1592    else if (RTFS_IS_FILE(fMode))      return FsObjType_File;
    14091593    else if (RTFS_IS_SYMLINK(fMode))   return FsObjType_Symlink;
     1594    else if (RTFS_IS_SOCKET(fMode))    return FsObjType_Socket;
     1595    else if (RTFS_IS_WHITEOUT(fMode))  return FsObjType_WhiteOut;
    14101596
    14111597    return FsObjType_Unknown;
  • trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp

    r98272 r98526  
    3636# error "VBOX_WITH_GUEST_CONTROL must defined in this file"
    3737#endif
     38#include "GuestImpl.h"
    3839#include "GuestDirectoryImpl.h"
    3940#include "GuestSessionImpl.h"
    4041#include "GuestCtrlImplPrivate.h"
     42#include "VirtualBoxErrorInfoImpl.h"
    4143
    4244#include "Global.h"
    4345#include "AutoCaller.h"
     46#include "VBoxEvents.h"
    4447
    4548#include <VBox/com/array.h>
     49#include <VBox/AssertGuest.h>
    4650
    4751
     
    7074int GuestDirectory::init(Console *pConsole, GuestSession *pSession, ULONG aObjectID, const GuestDirectoryOpenInfo &openInfo)
    7175{
    72     LogFlowThisFunc(("pConsole=%p, pSession=%p, aObjectID=%RU32, strPath=%s, strFilter=%s, uFlags=%x\n",
    73                      pConsole, pSession, aObjectID, openInfo.mPath.c_str(), openInfo.mFilter.c_str(), openInfo.mFlags));
     76    LogFlowThisFunc(("pConsole=%p, pSession=%p, aObjectID=%RU32, strPath=%s, enmFilter=%#x, fFlags=%x\n",
     77                     pConsole, pSession, aObjectID, openInfo.mPath.c_str(), openInfo.menmFilter, openInfo.mFlags));
    7478
    7579    AssertPtrReturn(pConsole, VERR_INVALID_POINTER);
     
    8690        mObjectID = aObjectID;
    8791
    88         mData.mOpenInfo = openInfo;
    89     }
    90 
    91     if (RT_SUCCESS(vrc))
    92     {
    93         /* Start the directory process on the guest. */
    94         GuestProcessStartupInfo procInfo;
    95         procInfo.mName.printf(tr("Opening directory \"%s\""), openInfo.mPath.c_str());
    96         procInfo.mTimeoutMS = 5 * 60 * 1000; /* 5 minutes timeout. */
    97         procInfo.mFlags     = ProcessCreateFlag_WaitForStdOut;
    98         procInfo.mExecutable= Utf8Str(VBOXSERVICE_TOOL_LS);
    99 
    100         procInfo.mArguments.push_back(procInfo.mExecutable);
    101         procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
    102         /* We want the long output format which contains all the object details. */
    103         procInfo.mArguments.push_back(Utf8Str("-l"));
    104 #if 0 /* Flags are not supported yet. */
    105         if (uFlags & DirectoryOpenFlag_NoSymlinks)
    106             procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */
    107 #endif
    108         /** @todo Recursion support? */
    109         procInfo.mArguments.push_back(openInfo.mPath); /* The directory we want to open. */
    110 
    111         /*
    112          * Start the process synchronously and keep it around so that we can use
    113          * it later in subsequent read() calls.
    114          */
    115         vrc = mData.mProcessTool.init(mSession, procInfo, false /*fAsync*/, NULL /*pvrcGuest*/);
    116         if (RT_SUCCESS(vrc))
    117         {
    118             /* As we need to know if the directory we were about to open exists and and is accessible,
    119              * do the first read here in order to return a meaningful status here. */
    120             int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    121             vrc = i_readInternal(mData.mObjData, &vrcGuest);
    122             if (RT_FAILURE(vrc))
    123             {
    124                 /*
    125                  * We need to actively terminate our process tool in case of an error here,
    126                  * as this otherwise would be done on (directory) object destruction implicitly.
    127                  * This in turn then will run into a timeout, as the directory object won't be
    128                  * around anymore at that time. Ugly, but that's how it is for the moment.
    129                  */
    130                 int vrcTerm = mData.mProcessTool.terminate(30 * RT_MS_1SEC, NULL /* prcGuest */);
    131                 AssertRC(vrcTerm);
    132 
    133                 if (vrc == VERR_GSTCTL_GUEST_ERROR)
    134                     vrc = vrcGuest;
    135             }
    136         }
     92        mData.mOpenInfo  = openInfo;
     93        mData.mStatus    = DirectoryStatus_Undefined;
     94        mData.mLastError = VINF_SUCCESS;
     95
     96        unconst(mEventSource).createObject();
     97        HRESULT hr = mEventSource->init();
     98        if (FAILED(hr))
     99            vrc = VERR_COM_UNEXPECTED;
    137100    }
    138101
     
    177140}
    178141
     142HRESULT GuestDirectory::getEventSource(ComPtr<IEventSource> &aEventSource)
     143{
     144    /* No need to lock - lifetime constant. */
     145    mEventSource.queryInterfaceTo(aEventSource.asOutParam());
     146
     147    return S_OK;
     148}
     149
    179150HRESULT GuestDirectory::getFilter(com::Utf8Str &aFilter)
    180151{
     
    184155
    185156    aFilter = mData.mOpenInfo.mFilter;
     157
     158    return S_OK;
     159}
     160
     161HRESULT GuestDirectory::getId(ULONG *aId)
     162{
     163    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     164
     165    *aId = mObjectID;
     166
     167    return S_OK;
     168}
     169
     170HRESULT GuestDirectory::getStatus(DirectoryStatus_T *aStatus)
     171{
     172    LogFlowThisFuncEnter();
     173
     174    AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     175
     176    *aStatus = mData.mStatus;
    186177
    187178    return S_OK;
     
    209200    switch (pCbCtx->uMessage)
    210201    {
     202        case GUEST_MSG_DISCONNECTED:
     203            /** @todo vrc = i_onGuestDisconnected(pCbCtx, pSvcCb); */
     204            vrc = VINF_SUCCESS; // TODO
     205            break;
     206
    211207        case GUEST_MSG_DIR_NOTIFY:
    212208        {
    213             int idx = 1; /* Current parameter index. */
    214             CALLBACKDATA_DIR_NOTIFY dataCb;
    215             /* pSvcCb->mpaParms[0] always contains the context ID. */
    216             HGCMSvcGetU32(&pSvcCb->mpaParms[idx++], &dataCb.uType);
    217             HGCMSvcGetU32(&pSvcCb->mpaParms[idx++], &dataCb.rc);
    218 
    219             LogFlowFunc(("uType=%RU32, vrcGguest=%Rrc\n", dataCb.uType, (int)dataCb.rc));
    220 
    221             switch (dataCb.uType)
    222             {
    223                 /* Nothing here yet, nothing to dispatch further. */
    224 
    225                 default:
    226                     vrc = VERR_NOT_SUPPORTED;
    227                     break;
    228             }
     209            vrc = i_onDirNotify(pCbCtx, pSvcCb);
    229210            break;
    230211        }
     
    238219    LogFlowFuncLeaveRC(vrc);
    239220    return vrc;
     221}
     222
     223/**
     224 * Opens the directory on the guest side.
     225 *
     226 * @return VBox status code.
     227 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     228 */
     229int GuestDirectory::i_open(int *pvrcGuest)
     230{
     231    int vrc;
     232#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     233    if ((mSession->i_getParent()->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS))
     234    {
     235        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     236
     237        GuestWaitEvent *pEvent = NULL;
     238        GuestEventTypes eventTypes;
     239        try
     240        {
     241            eventTypes.push_back(VBoxEventType_OnGuestDirectoryStateChanged);
     242
     243            vrc = registerWaitEvent(eventTypes, &pEvent);
     244        }
     245        catch (std::bad_alloc &)
     246        {
     247            vrc = VERR_NO_MEMORY;
     248        }
     249
     250        /* Prepare HGCM call. */
     251        VBOXHGCMSVCPARM paParms[8];
     252        int i = 0;
     253        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     254        HGCMSvcSetPv(&paParms[i++], (void *)mData.mOpenInfo.mPath.c_str(), (ULONG)mData.mOpenInfo.mPath.length() + 1);
     255        HGCMSvcSetPv(&paParms[i++], (void *)mData.mOpenInfo.mFilter.c_str(), (ULONG)mData.mOpenInfo.mFilter.length() + 1);
     256        HGCMSvcSetU32(&paParms[i++], mData.mOpenInfo.menmFilter);
     257        HGCMSvcSetU32(&paParms[i++], mData.mOpenInfo.mFlags);
     258
     259        alock.release(); /* Drop lock before sending. */
     260
     261        vrc = sendMessage(HOST_MSG_DIR_OPEN, i, paParms);
     262        if (RT_SUCCESS(vrc))
     263        {
     264            vrc = pEvent->Wait(30 * 1000);
     265            if (RT_SUCCESS(vrc))
     266            {
     267            }
     268        }
     269    }
     270    else
     271    {
     272#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     273#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     274        vrc = i_openViaToolbox(pvrcGuest);
     275#else
     276        RT_NOREF(pvrcGuest);
     277        vrc = VERR_NOT_SUPPORTED;
     278#endif
     279#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     280    }
     281#endif
     282
     283    return vrc;
     284}
     285
     286#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     287/**
     288 * Opens the directory on the guest side (legacy version).
     289 *
     290 * @returns VBox status code.
     291 * @param   pvrcGuest           Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     292 *
     293 * @note This uses an own guest process via the built-in toolbox in VBoxSerivce.
     294 */
     295int GuestDirectory::i_openViaToolbox(int *pvrcGuest)
     296{
     297    /* Start the directory process on the guest. */
     298    GuestProcessStartupInfo procInfo;
     299    procInfo.mName.printf(tr("Opening directory \"%s\""), mData.mOpenInfo.mPath.c_str());
     300    procInfo.mTimeoutMS = 5 * 60 * 1000; /* 5 minutes timeout. */
     301    procInfo.mFlags     = ProcessCreateFlag_WaitForStdOut;
     302    procInfo.mExecutable= Utf8Str(VBOXSERVICE_TOOL_LS);
     303
     304    procInfo.mArguments.push_back(procInfo.mExecutable);
     305    procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     306    /* We want the long output format which contains all the object details. */
     307    procInfo.mArguments.push_back(Utf8Str("-l"));
     308# if 0 /* Flags are not supported yet. */
     309    if (uFlags & DirectoryOpenFlag_NoSymlinks)
     310        procInfo.mArguments.push_back(Utf8Str("--nosymlinks")); /** @todo What does GNU here? */
     311# endif
     312    /** @todo Recursion support? */
     313    procInfo.mArguments.push_back(mData.mOpenInfo.mPath); /* The directory we want to open. */
     314
     315    /*
     316     * Start the process synchronously and keep it around so that we can use
     317     * it later in subsequent read() calls.
     318     */
     319    int vrc = mData.mProcessTool.init(mSession, procInfo, false /*fAsync*/, NULL /*pvrcGuest*/);
     320    if (RT_SUCCESS(vrc))
     321    {
     322        /* As we need to know if the directory we were about to open exists and and is accessible,
     323         * do the first read here in order to return a meaningful status here. */
     324        int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     325        vrc = i_readInternal(mData.mObjData, &vrcGuest);
     326        if (RT_FAILURE(vrc))
     327        {
     328            /*
     329             * We need to actively terminate our process tool in case of an error here,
     330             * as this otherwise would be done on (directory) object destruction implicitly.
     331             * This in turn then will run into a timeout, as the directory object won't be
     332             * around anymore at that time. Ugly, but that's how it is for the moment.
     333             */
     334            /* ignore rc */ mData.mProcessTool.terminate(30 * RT_MS_1SEC, NULL /* pvrcGuest */);
     335        }
     336
     337        if (pvrcGuest)
     338            *pvrcGuest = vrcGuest;
     339    }
     340
     341    return vrc;
     342}
     343#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     344
     345/**
     346 * Called when the guest side notifies the host of a directory event.
     347 *
     348 * @returns VBox status code.
     349 * @param   pCbCtx              Host callback context.
     350 * @param   pSvcCbData          Host callback data.
     351 */
     352int GuestDirectory::i_onDirNotify(PVBOXGUESTCTRLHOSTCBCTX pCbCtx, PVBOXGUESTCTRLHOSTCALLBACK pSvcCbData)
     353{
     354#ifndef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     355    RT_NOREF(pCbCtx, pSvcCbData);
     356    return VERR_NOT_SUPPORTED;
     357#else
     358    AssertPtrReturn(pCbCtx, VERR_INVALID_POINTER);
     359    AssertPtrReturn(pSvcCbData, VERR_INVALID_POINTER);
     360
     361    LogFlowThisFuncEnter();
     362
     363    if (pSvcCbData->mParms < 3)
     364        return VERR_INVALID_PARAMETER;
     365
     366    int idx = 1; /* Current parameter index. */
     367    CALLBACKDATA_DIR_NOTIFY dataCb;
     368    RT_ZERO(dataCb);
     369    /* pSvcCb->mpaParms[0] always contains the context ID. */
     370    HGCMSvcGetU32(&pSvcCbData->mpaParms[idx++], &dataCb.uType);
     371    HGCMSvcGetU32(&pSvcCbData->mpaParms[idx++], &dataCb.rc);
     372
     373    int vrcGuest = (int)dataCb.rc; /* uint32_t vs. int. */
     374
     375    LogFlowThisFunc(("uType=%RU32, vrcGuest=%Rrc\n", dataCb.uType, vrcGuest));
     376
     377    if (RT_FAILURE(vrcGuest))
     378    {
     379        /** @todo Set status? */
     380
     381        /* Ignore return code, as the event to signal might not be there (anymore). */
     382        signalWaitEventInternal(pCbCtx, vrcGuest, NULL /* pPayload */);
     383        return VINF_SUCCESS; /* Report to the guest. */
     384    }
     385
     386    int vrc = VERR_NOT_SUPPORTED; /* Play safe by default. */
     387
     388    ComObjPtr<VirtualBoxErrorInfo> errorInfo;
     389    HRESULT hrc = errorInfo.createObject();
     390    ComAssertComRCRet(hrc, VERR_COM_UNEXPECTED);
     391    if (RT_FAILURE(vrcGuest))
     392    {
     393        hrc = errorInfo->initEx(VBOX_E_GSTCTL_GUEST_ERROR, vrcGuest,
     394                                COM_IIDOF(IGuestFile), getComponentName(),
     395                                i_guestErrorToString(vrcGuest, mData.mOpenInfo.mPath.c_str()));
     396        ComAssertComRCRet(hrc, VERR_COM_UNEXPECTED);
     397    }
     398
     399    switch (dataCb.uType)
     400    {
     401        case GUEST_DIR_NOTIFYTYPE_ERROR:
     402        {
     403            vrc = i_setStatus(DirectoryStatus_Error, vrcGuest);
     404            break;
     405        }
     406
     407        case GUEST_DIR_NOTIFYTYPE_OPEN:
     408        {
     409            vrc = i_setStatus(DirectoryStatus_Open, vrcGuest);
     410            break;
     411        }
     412
     413        case GUEST_DIR_NOTIFYTYPE_CLOSE:
     414        {
     415            vrc = i_setStatus(DirectoryStatus_Close, vrcGuest);
     416            break;
     417        }
     418
     419        case GUEST_DIR_NOTIFYTYPE_READ:
     420        {
     421            ASSERT_GUEST_MSG_STMT_BREAK(pSvcCbData->mParms == 7, ("mParms=%u\n", pSvcCbData->mParms),
     422                                        vrc = VERR_WRONG_PARAMETER_COUNT);
     423            ASSERT_GUEST_MSG_STMT_BREAK(pSvcCbData->mpaParms[idx].type == VBOX_HGCM_SVC_PARM_PTR,
     424                                        ("type=%u\n", pSvcCbData->mpaParms[idx].type),
     425                                        vrc = VERR_WRONG_PARAMETER_TYPE);
     426
     427            PGSTCTLFSOBJINFO pObjInfo;
     428            uint32_t         cbObjInfo;
     429            vrc = HGCMSvcGetPv(&pSvcCbData->mpaParms[idx++], (void **)&pObjInfo, &cbObjInfo);
     430            AssertRCBreak(vrc);
     431            AssertBreakStmt(cbObjInfo == sizeof(GSTCTLFSOBJINFO), VERR_INVALID_PARAMETER);
     432
     433            GuestFsObjData fsObjData(mData.mOpenInfo.mPath);
     434            vrc = fsObjData.FromGuestFsObjInfo(pObjInfo);
     435            AssertRCBreak(vrc);
     436            ComObjPtr<GuestFsObjInfo> ptrFsObjInfo;
     437            hrc = ptrFsObjInfo.createObject();
     438            ComAssertComRCBreak(hrc, VERR_COM_UNEXPECTED);
     439            vrc = ptrFsObjInfo->init(fsObjData);
     440            AssertRCBreak(vrc);
     441
     442            ::FireGuestDirectoryReadEvent(mEventSource, mSession, this, ptrFsObjInfo);
     443            break;
     444        }
     445
     446        case GUEST_DIR_NOTIFYTYPE_REWIND:
     447        {
     448            /* Note: This does not change the overall status of the directory (i.e. open). */
     449            ::FireGuestDirectoryStateChangedEvent(mEventSource, mSession, this, DirectoryStatus_Rewind, errorInfo);
     450            break;
     451        }
     452
     453        default:
     454            AssertFailed();
     455            break;
     456    }
     457
     458    try
     459    {
     460        if (RT_SUCCESS(vrc))
     461        {
     462            GuestWaitEventPayload payload(dataCb.uType, &dataCb, sizeof(dataCb));
     463
     464            /* Ignore return code, as the event to signal might not be there (anymore). */
     465            signalWaitEventInternal(pCbCtx, vrcGuest, &payload);
     466        }
     467        else /* OOM situation, wrong HGCM parameters or smth. not expected. */
     468        {
     469            /* Ignore return code, as the event to signal might not be there (anymore). */
     470            signalWaitEventInternalEx(pCbCtx, vrc, 0 /* guestRc */, NULL /* pPayload */);
     471        }
     472    }
     473    catch (int vrcEx) /* Thrown by GuestWaitEventPayload constructor. */
     474    {
     475        /* Also try to signal the waiter, to let it know of the OOM situation.
     476         * Ignore return code, as the event to signal might not be there (anymore). */
     477        signalWaitEventInternalEx(pCbCtx, vrcEx, 0 /* guestRc */, NULL /* pPayload */);
     478        vrc = vrcEx;
     479    }
     480
     481    LogFlowThisFunc(("uType=%RU32, rcGuest=%Rrc, vrc=%Rrc\n", dataCb.uType, vrcGuest, vrc));
     482    return vrc;
     483#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    240484}
    241485
     
    302546 *
    303547 * @return VBox status code.
    304  * @param  prcGuest             Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
    305  */
    306 int GuestDirectory::i_closeInternal(int *prcGuest)
    307 {
    308     AssertPtrReturn(prcGuest, VERR_INVALID_POINTER);
    309 
    310     int vrc = mData.mProcessTool.terminate(30 * 1000 /* 30s timeout */, prcGuest);
    311     if (RT_FAILURE(vrc))
    312         return vrc;
     548 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     549 */
     550int GuestDirectory::i_close(int *pvrcGuest)
     551{
     552    int vrc;
     553#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     554    if (mSession->i_getParent()->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     555    {
     556        // TODO
     557        vrc = VERR_NOT_IMPLEMENTED;
     558    }
     559    else
     560    {
     561#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     562#ifndef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     563        RT_NOREF(pvrcGuest);
     564        vrc = VINF_SUCCESS; /* Nothing to do here. */
     565#else
     566        vrc = i_closeViaToolbox(pvrcGuest);
     567#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     568#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     569    }
     570#endif
    313571
    314572    AssertPtr(mSession);
     
    321579}
    322580
     581#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     582/**
     583 * Closes this guest directory and removes it from the guest session's directory list (legacy version).
     584 *
     585 * @return VBox status code.
     586 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     587 *
     588 * @note This uses an own guest process via the built-in toolbox in VBoxSerivce.
     589 */
     590int GuestDirectory::i_closeViaToolbox(int *pvrcGuest)
     591{
     592    return mData.mProcessTool.terminate(30 * 1000 /* 30s timeout */, pvrcGuest);
     593}
     594#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     595
    323596/**
    324597 * Reads the next directory entry, internal version.
     
    326599 * @return VBox status code. Will return VERR_NO_MORE_FILES if no more entries are available.
    327600 * @param  objData              Where to store the read directory entry as internal object data.
    328  * @param  prcGuest             Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
    329  */
    330 int GuestDirectory::i_readInternal(GuestFsObjData &objData, int *prcGuest)
    331 {
    332     AssertPtrReturn(prcGuest, VERR_INVALID_POINTER);
    333 
    334     GuestProcessStreamBlock curBlock;
    335     int vrc = mData.mProcessTool.waitEx(GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK, &curBlock, prcGuest);
     601 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     602 */
     603int GuestDirectory::i_readInternal(GuestFsObjData &objData, int *pvrcGuest)
     604{
     605    AssertPtrReturn(pvrcGuest, VERR_INVALID_POINTER);
     606
     607    int vrc;
     608#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     609    if (mSession->i_getParent()->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     610    {
     611        // TODO
     612        RT_NOREF(objData, pvrcGuest);
     613        vrc = 0;
     614    }
     615    else
     616    {
     617#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     618#ifndef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     619        RT_NOREF(objData);
     620        vrc = VERR_NOT_SUPPORTED;
     621#else  /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     622        vrc = i_readInternalViaToolbox(objData, pvrcGuest);
     623#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     624#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     625    }
     626#endif
     627
     628    LogFlowThisFunc(("Returning vrc=%Rrc\n", vrc));
     629    return vrc;
     630}
     631
     632#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     633/**
     634 * Reads the next directory entry, internal version (legacy version).
     635 *
     636 * @return VBox status code. Will return VERR_NO_MORE_FILES if no more entries are available.
     637 * @param  objData              Where to store the read directory entry as internal object data.
     638 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     639 *
     640 * @note This uses an own guest process via the built-in toolbox in VBoxSerivce.
     641 */
     642int GuestDirectory::i_readInternalViaToolbox(GuestFsObjData &objData, int *pvrcGuest)
     643{
     644    GuestToolboxStreamBlock curBlock;
     645    int vrc = mData.mProcessTool.waitEx(GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK, &curBlock, pvrcGuest);
    336646    if (RT_SUCCESS(vrc))
    337647    {
     
    349659                if (curBlock.GetString("name"))
    350660                {
    351                     vrc = objData.FromLs(curBlock, true /* fLong */);
     661                    vrc = objData.FromToolboxLs(curBlock, true /* fLong */);
    352662                }
    353663                else
     
    362672    }
    363673
    364     LogFlowThisFunc(("Returning vrc=%Rrc\n", vrc));
    365     return vrc;
    366 }
     674    return vrc;
     675}
     676#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
    367677
    368678/**
     
    371681 * @return VBox status code. Will return VERR_NO_MORE_FILES if no more entries are available.
    372682 * @param  fsObjInfo            Where to store the read directory entry.
    373  * @param  prcGuest             Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
    374  */
    375 int GuestDirectory::i_read(ComObjPtr<GuestFsObjInfo> &fsObjInfo, int *prcGuest)
    376 {
    377     AssertPtrReturn(prcGuest, VERR_INVALID_POINTER);
     683 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     684 */
     685int GuestDirectory::i_read(ComObjPtr<GuestFsObjInfo> &fsObjInfo, int *pvrcGuest)
     686{
     687    AssertPtrReturn(pvrcGuest, VERR_INVALID_POINTER);
    378688
    379689    /* Create the FS info object. */
     
    393703        }
    394704    }
    395     else /* Otherwise ask the guest for the next object data (block). */
     705    else /* Otherwise ask the guest for the next object data. */
    396706    {
    397707
    398708        GuestFsObjData objData;
    399         vrc = i_readInternal(objData, prcGuest);
     709        vrc = i_readInternal(objData, pvrcGuest);
    400710        if (RT_SUCCESS(vrc))
    401711            vrc = fsObjInfo->init(objData);
     
    404714    LogFlowThisFunc(("Returning vrc=%Rrc\n", vrc));
    405715    return vrc;
     716}
     717
     718/**
     719 * Rewinds the directory reading.
     720 *
     721 * @returns VBox status code.
     722 * @retval  VERR_GSTCTL_GUEST_ERROR when an error from the guest side has been received.
     723 * @param  uTimeoutMS           Timeout (in ms) to wait.
     724 * @param  pvrcGuest            Where to store the guest result code in case VERR_GSTCTL_GUEST_ERROR is returned.
     725 */
     726int GuestDirectory::i_rewind(uint32_t uTimeoutMS, int *pvrcGuest)
     727{
     728    RT_NOREF(pvrcGuest);
     729#ifndef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     730    RT_NOREF(uTimeoutMS, pvrcGuest);
     731#else
     732    /* Only available for Guest Additions 7.1+. */
     733    if (mSession->i_getParent()->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     734    {
     735        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     736
     737        int vrc;
     738
     739        GuestWaitEvent *pEvent = NULL;
     740        GuestEventTypes eventTypes;
     741        try
     742        {
     743            eventTypes.push_back(VBoxEventType_OnGuestDirectoryStateChanged);
     744            vrc = registerWaitEvent(eventTypes, &pEvent);
     745        }
     746        catch (std::bad_alloc &)
     747        {
     748            vrc = VERR_NO_MEMORY;
     749        }
     750
     751        if (RT_FAILURE(vrc))
     752            return vrc;
     753
     754        /* Prepare HGCM call. */
     755        VBOXHGCMSVCPARM paParms[4];
     756        int i = 0;
     757        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     758        HGCMSvcSetU32(&paParms[i++], mObjectID /* Directory handle */);
     759
     760        alock.release(); /* Drop lock before sending. */
     761
     762        vrc = sendMessage(HOST_MSG_DIR_REWIND, i, paParms);
     763        if (RT_SUCCESS(vrc))
     764        {
     765            VBoxEventType_T evtType;
     766            ComPtr<IEvent> pIEvent;
     767            vrc = waitForEvent(pEvent, uTimeoutMS, &evtType, pIEvent.asOutParam());
     768            if (RT_SUCCESS(vrc))
     769            {
     770                if (evtType == VBoxEventType_OnGuestDirectoryStateChanged)
     771                {
     772                    ComPtr<IGuestDirectoryStateChangedEvent> pEvt = pIEvent;
     773                    Assert(!pEvt.isNull());
     774                }
     775                else
     776                    vrc = VWRN_GSTCTL_OBJECTSTATE_CHANGED;
     777            }
     778            else if (pEvent->HasGuestError()) /* Return guest vrc if available. */
     779                vrc = pEvent->GetGuestError();
     780        }
     781
     782        unregisterWaitEvent(pEvent);
     783        return vrc;
     784    }
     785#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     786
     787    return VERR_NOT_SUPPORTED;
     788}
     789
     790/**
     791 * Sets the current internal directory object status.
     792 *
     793 * @returns VBox status code.
     794 * @param   enmStatus           New directory status to set.
     795 * @param   vrcDir              New result code to set.
     796 *
     797 * @note    Takes the write lock.
     798 */
     799int GuestDirectory::i_setStatus(DirectoryStatus_T enmStatus, int vrcDir)
     800{
     801    LogFlowThisFuncEnter();
     802
     803    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     804
     805    LogFlowThisFunc(("oldStatus=%RU32, newStatus=%RU32, vrcDir=%Rrc\n", mData.mStatus, enmStatus, vrcDir));
     806
     807#ifdef VBOX_STRICT
     808    if (enmStatus == DirectoryStatus_Error)
     809        AssertMsg(RT_FAILURE(vrcDir), ("Guest vrc must be an error (%Rrc)\n", vrcDir));
     810    else
     811        AssertMsg(RT_SUCCESS(vrcDir), ("Guest vrc must not be an error (%Rrc)\n", vrcDir));
     812#endif
     813
     814    if (mData.mStatus != enmStatus)
     815    {
     816        mData.mStatus    = enmStatus;
     817        mData.mLastError = vrcDir;
     818
     819        ComObjPtr<VirtualBoxErrorInfo> errorInfo;
     820        HRESULT hrc = errorInfo.createObject();
     821        ComAssertComRCRet(hrc, VERR_COM_UNEXPECTED);
     822        if (RT_FAILURE(vrcDir))
     823        {
     824            hrc = errorInfo->initEx(VBOX_E_GSTCTL_GUEST_ERROR, vrcDir,
     825                                    COM_IIDOF(IGuestDirectory), getComponentName(),
     826                                    i_guestErrorToString(vrcDir, mData.mOpenInfo.mPath.c_str()));
     827            ComAssertComRCRet(hrc, VERR_COM_UNEXPECTED);
     828        }
     829        /* Note: On vrcDir success, errorInfo is set to S_OK and also sent via the event below. */
     830
     831        alock.release(); /* Release lock before firing off event. */
     832
     833        ::FireGuestDirectoryStateChangedEvent(mEventSource, mSession, this, enmStatus, errorInfo);
     834    }
     835
     836    return VINF_SUCCESS;
    406837}
    407838
     
    418849
    419850    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    420     int vrc = i_closeInternal(&vrcGuest);
     851    int vrc = i_close(&vrcGuest);
    421852    if (RT_FAILURE(vrc))
    422853    {
     
    468899            case VERR_GSTCTL_GUEST_ERROR:
    469900            {
    470                 GuestErrorInfo ge(GuestErrorInfo::Type_ToolLs, vrcGuest, mData.mOpenInfo.mPath.c_str());
     901                GuestErrorInfo ge(
     902#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     903                                  GuestErrorInfo::Type_ToolLs
     904#else
     905                                  GuestErrorInfo::Type_Fs
     906#endif
     907                , vrcGuest, mData.mOpenInfo.mPath.c_str());
    471908                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Reading guest directory failed: %s"),
    472909                                   GuestBase::getErrorAsString(ge).c_str());
    473910                break;
    474911            }
     912
     913#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
    475914            case VERR_GSTCTL_PROCESS_EXIT_CODE:
    476915                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Reading guest directory \"%s\" failed: %Rrc"),
    477916                                   mData.mOpenInfo.mPath.c_str(), mData.mProcessTool.getRc());
    478917                break;
    479 
     918#endif
    480919            case VERR_PATH_NOT_FOUND:
    481920                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Reading guest directory \"%s\" failed: Path not found"),
     
    490929
    491930            default:
    492                 hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Reading guest directory \"%s\" returned error: %Rrc\n"),
     931                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrc, tr("Reading guest directory \"%s\" returned unhandled error: %Rrc\n"),
    493932                                   mData.mOpenInfo.mPath.c_str(), vrc);
    494933                break;
     
    500939}
    501940
     941HRESULT GuestDirectory::rewind(void)
     942{
     943    AutoCaller autoCaller(this);
     944    if (FAILED(autoCaller.hrc())) return autoCaller.hrc();
     945
     946    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     947    int vrc = i_rewind(30 * 1000 /* Timeout in ms */, &vrcGuest);
     948    if (RT_SUCCESS(vrc))
     949        return S_OK;
     950
     951    GuestErrorInfo ge(GuestErrorInfo::Type_Directory, vrcGuest, mData.mOpenInfo.mPath.c_str());
     952    return setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Rewinding guest directory failed: %s"),
     953                       GuestBase::getErrorAsString(ge).c_str());
     954}
     955
  • trunk/src/VBox/Main/src-client/GuestFileImpl.cpp

    r98284 r98526  
    900900int GuestFile::i_queryInfo(GuestFsObjData &objData, int *prcGuest)
    901901{
    902     AssertPtr(mSession);
     902    AssertPtrReturn(mSession, VERR_OBJECT_DESTROYED);
    903903    return mSession->i_fsQueryInfo(mData.mOpenInfo.mFilename, FALSE /* fFollowSymlinks */, objData, prcGuest);
    904904}
     
    15761576        if (GuestProcess::i_isGuestError(vrc))
    15771577        {
    1578             GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, mData.mOpenInfo.mFilename.c_str());
     1578            GuestErrorInfo ge(
     1579#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     1580                              GuestErrorInfo::Type_ToolStat,
     1581#else
     1582                              GuestErrorInfo::Type_File,
     1583#endif
     1584                              vrcGuest, mData.mOpenInfo.mFilename.c_str());
    15791585            hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying guest file information failed: %s"),
    15801586                               GuestBase::getErrorAsString(ge).c_str());
     
    16091615        if (GuestProcess::i_isGuestError(vrc))
    16101616        {
    1611             GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, mData.mOpenInfo.mFilename.c_str());
     1617            GuestErrorInfo ge(
     1618#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     1619                              GuestErrorInfo::Type_ToolStat,
     1620#else
     1621                              GuestErrorInfo::Type_File,
     1622#endif
     1623                              vrcGuest, mData.mOpenInfo.mFilename.c_str());
    16121624            hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying guest file size failed: %s"),
    16131625                               GuestBase::getErrorAsString(ge).c_str());
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r98272 r98526  
    22532253///////////////////////////////////////////////////////////////////////////////
    22542254
    2255 GuestProcessTool::GuestProcessTool(void)
     2255GuestProcessToolbox::GuestProcessToolbox(void)
    22562256    : pSession(NULL),
    22572257      pProcess(NULL)
     
    22592259}
    22602260
    2261 GuestProcessTool::~GuestProcessTool(void)
     2261GuestProcessToolbox::~GuestProcessToolbox(void)
    22622262{
    22632263    uninit();
     
    22742274 *                              VERR_GSTCTL_GUEST_ERROR was returned. Optional.
    22752275 */
    2276 int GuestProcessTool::init(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
    2277                            bool fAsync, int *pvrcGuest)
     2276int GuestProcessToolbox::init(GuestSession *pGuestSession, const GuestProcessStartupInfo &startupInfo,
     2277                              bool fAsync, int *pvrcGuest)
    22782278{
    22792279    LogFlowThisFunc(("pGuestSession=%p, exe=%s, fAsync=%RTbool\n",
     
    23162316 * Unitializes a guest process tool by terminating it on the guest.
    23172317 */
    2318 void GuestProcessTool::uninit(void)
     2318void GuestProcessToolbox::uninit(void)
    23192319{
    23202320    /* Make sure the process is terminated and unregistered from the guest session. */
     
    23392339 * @param   strmBlock           Where to return the stream block on success.
    23402340 */
    2341 int GuestProcessTool::getCurrentBlock(uint32_t uHandle, GuestProcessStreamBlock &strmBlock)
    2342 {
    2343     const GuestProcessStream *pStream = NULL;
     2341int GuestProcessToolbox::getCurrentBlock(uint32_t uHandle, GuestToolboxStreamBlock &strmBlock)
     2342{
     2343    const GuestToolboxStream *pStream = NULL;
    23442344    if (uHandle == GUEST_PROC_OUT_H_STDOUT)
    23452345        pStream = &mStdOut;
     
    23702370 * @returns Result code from guest process tool.
    23712371 */
    2372 int GuestProcessTool::getRc(void) const
     2372int GuestProcessToolbox::getRc(void) const
    23732373{
    23742374    LONG exitCode = -1;
     
    23762376    AssertComRC(hrc);
    23772377
    2378     return GuestProcessTool::exitCodeToRc(mStartupInfo, exitCode);
     2378    return GuestProcessToolbox::exitCodeToRc(mStartupInfo, exitCode);
    23792379}
    23802380
     
    23842384 * @returns \c true if running, or \c false if not.
    23852385 */
    2386 bool GuestProcessTool::isRunning(void)
     2386bool GuestProcessToolbox::isRunning(void)
    23872387{
    23882388    AssertReturn(!pProcess.isNull(), false);
     
    24092409 *         occurred (exit status <> 0 or wrong process state).
    24102410 */
    2411 bool GuestProcessTool::isTerminatedOk(void)
     2411bool GuestProcessToolbox::isTerminatedOk(void)
    24122412{
    24132413    return getTerminationStatus() == VINF_SUCCESS ? true : false;
     
    24282428 */
    24292429/* static */
    2430 int GuestProcessTool::run(      GuestSession              *pGuestSession,
    2431                           const GuestProcessStartupInfo   &startupInfo,
    2432                                 int                       *pvrcGuest /* = NULL */)
     2430int GuestProcessToolbox::run(      GuestSession              *pGuestSession,
     2431                             const GuestProcessStartupInfo   &startupInfo,
     2432                                   int                       *pvrcGuest /* = NULL */)
    24332433{
    24342434    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     
    24422442        {
    24432443            if (errorInfo.vrcGuest == VERR_GSTCTL_PROCESS_EXIT_CODE) /* Translate exit code to a meaningful error code. */
    2444                 vrcGuest = GuestProcessTool::exitCodeToRc(startupInfo, errorInfo.iExitCode);
     2444                vrcGuest = GuestProcessToolbox::exitCodeToRc(startupInfo, errorInfo.iExitCode);
    24452445            else /* At least return something. */
    24462446                vrcGuest = errorInfo.vrcGuest;
     
    24672467 */
    24682468/* static */
    2469 int GuestProcessTool::runErrorInfo(GuestSession                    *pGuestSession,
    2470                                    GuestProcessStartupInfo const  &startupInfo,
    2471                                    GuestProcessToolErrorInfo       &errorInfo)
     2469int GuestProcessToolbox::runErrorInfo(GuestSession                 *pGuestSession,
     2470                                      GuestProcessStartupInfo const &startupInfo,
     2471                                      GuestProcessToolErrorInfo     &errorInfo)
    24722472{
    24732473    return runExErrorInfo(pGuestSession, startupInfo, NULL /* paStrmOutObjects */, 0 /* cStrmOutObjects */, errorInfo);
     
    24862486 */
    24872487/* static */
    2488 int GuestProcessTool::runEx(GuestSession                   *pGuestSession,
    2489                             GuestProcessStartupInfo const &startupInfo,
    2490                             GuestCtrlStreamObjects         *paStrmOutObjects,
    2491                             uint32_t                        cStrmOutObjects,
    2492                             int                            *pvrcGuest /* = NULL */)
     2488int GuestProcessToolbox::runEx(GuestSession                  *pGuestSession,
     2489                               GuestProcessStartupInfo const &startupInfo,
     2490                               GuestCtrlStreamObjects        *paStrmOutObjects,
     2491                               uint32_t                       cStrmOutObjects,
     2492                               int                           *pvrcGuest /* = NULL */)
    24932493{
    24942494    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    24952495
    24962496    GuestProcessToolErrorInfo errorInfo = { VERR_IPE_UNINITIALIZED_STATUS, INT32_MAX };
    2497     int vrc = GuestProcessTool::runExErrorInfo(pGuestSession, startupInfo, paStrmOutObjects, cStrmOutObjects, errorInfo);
     2497    int vrc = GuestProcessToolbox::runExErrorInfo(pGuestSession, startupInfo, paStrmOutObjects, cStrmOutObjects, errorInfo);
    24982498    if (RT_SUCCESS(vrc))
    24992499    {
     
    25022502        {
    25032503            if (errorInfo.vrcGuest == VERR_GSTCTL_PROCESS_EXIT_CODE) /* Translate exit code to a meaningful error code. */
    2504                 vrcGuest = GuestProcessTool::exitCodeToRc(startupInfo, errorInfo.iExitCode);
     2504                vrcGuest = GuestProcessToolbox::exitCodeToRc(startupInfo, errorInfo.iExitCode);
    25052505            else /* At least return something. */
    25062506                vrcGuest = errorInfo.vrcGuest;
     
    25332533 */
    25342534/* static */
    2535 int GuestProcessTool::runExErrorInfo(GuestSession                  *pGuestSession,
    2536                                      GuestProcessStartupInfo const &startupInfo,
    2537                                      GuestCtrlStreamObjects        *paStrmOutObjects,
    2538                                      uint32_t                       cStrmOutObjects,
    2539                                      GuestProcessToolErrorInfo     &errorInfo)
     2535int GuestProcessToolbox::runExErrorInfo(GuestSession                  *pGuestSession,
     2536                                        GuestProcessStartupInfo const &startupInfo,
     2537                                        GuestCtrlStreamObjects        *paStrmOutObjects,
     2538                                        uint32_t                       cStrmOutObjects,
     2539                                        GuestProcessToolErrorInfo     &errorInfo)
    25402540{
    25412541    AssertPtrReturn(pGuestSession, VERR_INVALID_POINTER);
     
    25442544    /** @todo Check if this is a valid toolbox. */
    25452545
    2546     GuestProcessTool procTool;
     2546    GuestProcessToolbox procTool;
    25472547    int vrc = procTool.init(pGuestSession, startupInfo, false /* Async */, &errorInfo.vrcGuest);
    25482548    if (RT_SUCCESS(vrc))
     
    25522552            try
    25532553            {
    2554                 GuestProcessStreamBlock strmBlk;
     2554                GuestToolboxStreamBlock strmBlk;
    25552555                vrc = procTool.waitEx(  paStrmOutObjects
    25562556                                        ? GUESTPROCESSTOOL_WAIT_FLAG_STDOUT_BLOCK
     
    25902590 * @param   piExitCode      Exit code of the tool. Optional.
    25912591 */
    2592 int GuestProcessTool::getTerminationStatus(int32_t *piExitCode /* = NULL */)
     2592int GuestProcessToolbox::getTerminationStatus(int32_t *piExitCode /* = NULL */)
    25932593{
    25942594    Assert(!pProcess.isNull());
     
    26222622 *                              VERR_GSTCTL_GUEST_ERROR was returned. Optional.
    26232623 */
    2624 int GuestProcessTool::wait(uint32_t fToolWaitFlags, int *pvrcGuest)
     2624int GuestProcessToolbox::wait(uint32_t fToolWaitFlags, int *pvrcGuest)
    26252625{
    26262626    return waitEx(fToolWaitFlags, NULL /* pStrmBlkOut */, pvrcGuest);
     
    26362636 *                              VERR_GSTCTL_GUEST_ERROR was returned. Optional.
    26372637 */
    2638 int GuestProcessTool::waitEx(uint32_t fToolWaitFlags, GuestProcessStreamBlock *pStrmBlkOut, int *pvrcGuest)
     2638int GuestProcessToolbox::waitEx(uint32_t fToolWaitFlags, GuestToolboxStreamBlock *pStrmBlkOut, int *pvrcGuest)
    26392639{
    26402640    LogFlowThisFunc(("fToolWaitFlags=0x%x, pStreamBlock=%p, pvrcGuest=%p\n", fToolWaitFlags, pStrmBlkOut, pvrcGuest));
     
    28302830 *                              VERR_GSTCTL_GUEST_ERROR was returned. Optional.
    28312831 */
    2832 int GuestProcessTool::terminate(uint32_t uTimeoutMS, int *pvrcGuest)
     2832int GuestProcessToolbox::terminate(uint32_t uTimeoutMS, int *pvrcGuest)
    28332833{
    28342834    LogFlowThisFuncEnter();
     
    28522852 */
    28532853/* static */
    2854 int GuestProcessTool::exitCodeToRc(const GuestProcessStartupInfo &startupInfo, int32_t iExitCode)
     2854int GuestProcessToolbox::exitCodeToRc(const GuestProcessStartupInfo &startupInfo, int32_t iExitCode)
    28552855{
    28562856    if (startupInfo.mArguments.size() == 0)
     
    28712871 */
    28722872/* static */
    2873 int GuestProcessTool::exitCodeToRc(const char *pszTool, int32_t iExitCode)
     2873int GuestProcessToolbox::exitCodeToRc(const char *pszTool, int32_t iExitCode)
    28742874{
    28752875    AssertPtrReturn(pszTool, VERR_INVALID_POINTER);
     
    29532953 */
    29542954/* static */
    2955 Utf8Str GuestProcessTool::guestErrorToString(const char *pszTool, const GuestErrorInfo &guestErrorInfo)
     2955Utf8Str GuestProcessToolbox::guestErrorToString(const char *pszTool, const GuestErrorInfo &guestErrorInfo)
    29562956{
    29572957    Utf8Str strErr;
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r98272 r98526  
    952952    int vrc = VINF_SUCCESS;
    953953
    954     GuestProcessStartupInfo procInfo;
    955     procInfo.mFlags      = ProcessCreateFlag_Hidden;
    956     procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_MKDIR);
    957 
    958     try
    959     {
    960         procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
    961 
    962         /* Construct arguments. */
    963         if (uFlags)
    964         {
    965             if (uFlags & DirectoryCreateFlag_Parents)
    966                 procInfo.mArguments.push_back(Utf8Str("--parents")); /* We also want to create the parent directories. */
    967             else
    968                 vrc = VERR_INVALID_PARAMETER;
    969         }
    970 
    971         if (   RT_SUCCESS(vrc)
    972             && uMode)
    973         {
    974             procInfo.mArguments.push_back(Utf8Str("--mode")); /* Set the creation mode. */
    975 
    976             char szMode[16];
    977             if (RTStrPrintf(szMode, sizeof(szMode), "%o", uMode))
     954#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     955    if (mParent->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     956    {
     957        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     958
     959        GuestWaitEvent *pEvent = NULL;
     960        vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
     961        if (RT_FAILURE(vrc))
     962            return vrc;
     963
     964        uint32_t fFlags = GSTCTL_CREATEDIRECTORY_F_NONE;
     965        if (uFlags & DirectoryCreateFlag_Parents)
     966            fFlags |= GSTCTL_CREATEDIRECTORY_F_PARENTS;
     967        Assert(!(fFlags & ~GSTCTL_CREATEDIRECTORY_F_VALID_MASK));
     968
     969        /* Prepare HGCM call. */
     970        VBOXHGCMSVCPARM paParms[4];
     971        int i = 0;
     972        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     973        HGCMSvcSetPv (&paParms[i++], (void*)strPath.c_str(), (ULONG)strPath.length() + 1);
     974        HGCMSvcSetU32(&paParms[i++], fFlags);
     975        HGCMSvcSetU32(&paParms[i++], uMode);
     976
     977        alock.release(); /* Drop lock before sending. */
     978
     979        vrc = i_sendMessage(HOST_MSG_DIR_CREATE, i, paParms);
     980        if (RT_SUCCESS(vrc))
     981        {
     982            vrc = pEvent->Wait(30 * 1000);
     983            if (RT_SUCCESS(vrc))
    978984            {
    979                 procInfo.mArguments.push_back(Utf8Str(szMode));
     985                // TODO
    980986            }
    981             else
    982                 vrc = VERR_BUFFER_OVERFLOW;
    983         }
    984 
    985         procInfo.mArguments.push_back("--");    /* '--version' is a valid directory name. */
    986         procInfo.mArguments.push_back(strPath); /* The directory we want to create. */
    987     }
    988     catch (std::bad_alloc &)
    989     {
    990         vrc = VERR_NO_MEMORY;
    991     }
    992 
    993     if (RT_SUCCESS(vrc))
    994         vrc = GuestProcessTool::run(this, procInfo, pvrcGuest);
     987        }
     988    }
     989    else
     990    {
     991#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     992#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     993        GuestProcessStartupInfo procInfo;
     994        procInfo.mFlags      = ProcessCreateFlag_Hidden;
     995        procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_MKDIR);
     996
     997        try
     998        {
     999            procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
     1000
     1001            /* Construct arguments. */
     1002            if (uFlags)
     1003            {
     1004                if (uFlags & DirectoryCreateFlag_Parents)
     1005                    procInfo.mArguments.push_back(Utf8Str("--parents")); /* We also want to create the parent directories. */
     1006                else
     1007                    vrc = VERR_INVALID_PARAMETER;
     1008            }
     1009
     1010            if (   RT_SUCCESS(vrc)
     1011                && uMode)
     1012            {
     1013                procInfo.mArguments.push_back(Utf8Str("--mode")); /* Set the creation mode. */
     1014
     1015                char szMode[16];
     1016                if (RTStrPrintf(szMode, sizeof(szMode), "%o", uMode))
     1017                {
     1018                    procInfo.mArguments.push_back(Utf8Str(szMode));
     1019                }
     1020                else
     1021                    vrc = VERR_BUFFER_OVERFLOW;
     1022            }
     1023
     1024            procInfo.mArguments.push_back("--");    /* '--version' is a valid directory name. */
     1025            procInfo.mArguments.push_back(strPath); /* The directory we want to create. */
     1026        }
     1027        catch (std::bad_alloc &)
     1028        {
     1029            vrc = VERR_NO_MEMORY;
     1030        }
     1031
     1032        if (RT_SUCCESS(vrc))
     1033            vrc = GuestProcessToolbox::run(this, procInfo, pvrcGuest);
     1034#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     1035#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1036    }
     1037#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    9951038
    9961039    LogFlowFuncLeaveRC(vrc);
     
    11811224                     strTemplate.c_str(), strPath.c_str(), fDirectory, fMode, fSecure));
    11821225
    1183     GuestProcessStartupInfo procInfo;
    1184     procInfo.mFlags = ProcessCreateFlag_WaitForStdOut;
    1185     try
    1186     {
    1187         procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_MKTEMP);
    1188         procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
    1189         procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     1226    int vrc;
     1227    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     1228#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1229    if (mParent->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     1230    {
     1231        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1232
     1233        GuestWaitEvent *pEvent = NULL;
     1234        vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
     1235        if (RT_FAILURE(vrc))
     1236            return vrc;
     1237
     1238        uint32_t fFlags = GSTCTL_CREATETEMP_F_NONE;
    11901239        if (fDirectory)
    1191             procInfo.mArguments.push_back(Utf8Str("-d"));
    1192         if (strPath.length()) /* Otherwise use /tmp or equivalent. */
    1193         {
    1194             procInfo.mArguments.push_back(Utf8Str("-t"));
    1195             procInfo.mArguments.push_back(strPath);
    1196         }
    1197         /* Note: Secure flag and mode cannot be specified at the same time. */
     1240            fFlags |= GSTCTL_CREATETEMP_F_DIRECTORY;
    11981241        if (fSecure)
    1199         {
    1200             procInfo.mArguments.push_back(Utf8Str("--secure"));
    1201         }
    1202         else
    1203         {
    1204             procInfo.mArguments.push_back(Utf8Str("--mode"));
    1205 
    1206             /* Note: Pass the mode unmodified down to the guest. See @ticketref{21394}. */
    1207             char szMode[16];
    1208             int vrc2 = RTStrPrintf2(szMode, sizeof(szMode), "%d", fMode);
    1209             AssertRCReturn(vrc2, vrc2);
    1210             procInfo.mArguments.push_back(szMode);
    1211         }
    1212         procInfo.mArguments.push_back("--"); /* strTemplate could be '--help'. */
    1213         procInfo.mArguments.push_back(strTemplate);
    1214     }
    1215     catch (std::bad_alloc &)
    1216     {
    1217         Log(("Out of memory!\n"));
    1218         return VERR_NO_MEMORY;
    1219     }
    1220 
    1221     /** @todo Use an internal HGCM command for this operation, since
    1222      *        we now can run in a user-dedicated session. */
    1223     int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    1224     GuestCtrlStreamObjects stdOut;
    1225     int vrc = GuestProcessTool::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
    1226     if (!GuestProcess::i_isGuestError(vrc))
    1227     {
    1228         GuestFsObjData objData;
    1229         if (!stdOut.empty())
    1230         {
    1231             vrc = objData.FromMkTemp(stdOut.at(0));
    1232             if (RT_FAILURE(vrc))
     1242            fFlags |= GSTCTL_CREATETEMP_F_SECURE;
     1243        Assert(!(fFlags & ~GSTCTL_CREATETEMP_F_VALID_MASK));
     1244
     1245        /* Prepare HGCM call. */
     1246        VBOXHGCMSVCPARM paParms[8];
     1247        int i = 0;
     1248        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     1249        HGCMSvcSetStr(&paParms[i++], strTemplate.c_str());
     1250        HGCMSvcSetStr(&paParms[i++], strPath.c_str());
     1251        HGCMSvcSetU32(&paParms[i++], fFlags);
     1252        HGCMSvcSetU32(&paParms[i++], fMode);
     1253
     1254        alock.release(); /* Drop lock before sending. */
     1255
     1256        vrc = i_sendMessage(HOST_MSG_FS_CREATE_TEMP, i, paParms);
     1257        if (RT_SUCCESS(vrc))
     1258        {
     1259            vrc = pEvent->Wait(30 * 1000);
     1260            if (RT_SUCCESS(vrc))
    12331261            {
    1234                 vrcGuest = vrc;
    1235                 if (pvrcGuest)
    1236                     *pvrcGuest = vrcGuest;
    1237                 vrc = VERR_GSTCTL_GUEST_ERROR;
     1262                // TODO
    12381263            }
    12391264        }
    1240         else
    1241             vrc = VERR_BROKEN_PIPE;
    1242 
    1243         if (RT_SUCCESS(vrc))
    1244             strName = objData.mName;
    1245     }
    1246     else if (pvrcGuest)
    1247         *pvrcGuest = vrcGuest;
     1265    }
     1266    else
     1267    {
     1268#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1269#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     1270        GuestProcessStartupInfo procInfo;
     1271        procInfo.mFlags = ProcessCreateFlag_WaitForStdOut;
     1272        try
     1273        {
     1274            procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_MKTEMP);
     1275            procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
     1276            procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     1277            if (fDirectory)
     1278                procInfo.mArguments.push_back(Utf8Str("-d"));
     1279            if (strPath.length()) /* Otherwise use /tmp or equivalent. */
     1280            {
     1281                procInfo.mArguments.push_back(Utf8Str("-t"));
     1282                procInfo.mArguments.push_back(strPath);
     1283            }
     1284            /* Note: Secure flag and mode cannot be specified at the same time. */
     1285            if (fSecure)
     1286            {
     1287                procInfo.mArguments.push_back(Utf8Str("--secure"));
     1288            }
     1289            else
     1290            {
     1291                procInfo.mArguments.push_back(Utf8Str("--mode"));
     1292
     1293                /* Note: Pass the mode unmodified down to the guest. See @ticketref{21394}. */
     1294                char szMode[16];
     1295                vrc = RTStrPrintf2(szMode, sizeof(szMode), "%d", fMode);
     1296                AssertRCReturn(vrc, vrc);
     1297                procInfo.mArguments.push_back(szMode);
     1298            }
     1299            procInfo.mArguments.push_back("--"); /* strTemplate could be '--help'. */
     1300            procInfo.mArguments.push_back(strTemplate);
     1301        }
     1302        catch (std::bad_alloc &)
     1303        {
     1304            Log(("Out of memory!\n"));
     1305            return VERR_NO_MEMORY;
     1306        }
     1307
     1308        GuestCtrlStreamObjects stdOut;
     1309        vrc = GuestProcessToolbox::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
     1310        if (!GuestProcess::i_isGuestError(vrc))
     1311        {
     1312            GuestFsObjData objData;
     1313            if (!stdOut.empty())
     1314            {
     1315                vrc = objData.FromToolboxMkTemp(stdOut.at(0));
     1316                if (RT_FAILURE(vrc))
     1317                {
     1318                    vrcGuest = vrc;
     1319                    if (pvrcGuest)
     1320                        *pvrcGuest = vrcGuest;
     1321                    vrc = VERR_GSTCTL_GUEST_ERROR;
     1322                }
     1323            }
     1324            else
     1325                vrc = VERR_BROKEN_PIPE;
     1326
     1327            if (RT_SUCCESS(vrc))
     1328                strName = objData.mName;
     1329        }
     1330        else if (pvrcGuest)
     1331            *pvrcGuest = vrcGuest;
     1332#else
     1333        RT_NOREF(strName);
     1334        vrc = VERR_NOT_SUPPORTED;
     1335#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     1336#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1337    }
     1338#endif
    12481339
    12491340    LogFlowThisFunc(("Returning vrc=%Rrc, vrcGuest=%Rrc\n", vrc, vrcGuest));
     
    12851376    }
    12861377
    1287     /* We need to release the write lock first before initializing the directory object below,
     1378    /**
     1379     * If VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT is enabled:
     1380     *
     1381     * We need to release the write lock first before opening the directory object below,
    12881382     * as we're starting a guest process as part of it. This in turn will try to acquire the session's
    12891383     * write lock. */
     
    12941388
    12951389    vrc = pDirectory->init(pConsole, this /* Parent */, idObject, openInfo);
     1390    if (RT_SUCCESS(vrc))
     1391        vrc = pDirectory->i_open(pvrcGuest);
     1392
    12961393    if (RT_FAILURE(vrc))
    12971394    {
     
    15881685    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
    15891686
    1590     GuestProcessStartupInfo procInfo;
    1591     GuestProcessStream      streamOut;
    1592 
    1593     procInfo.mFlags      = ProcessCreateFlag_WaitForStdOut;
    1594     procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_RM);
    1595 
    1596     try
    1597     {
    1598         procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
    1599         procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
    1600         procInfo.mArguments.push_back("--"); /* strPath could be '--help', which is a valid filename. */
    1601         procInfo.mArguments.push_back(strPath); /* The file we want to remove. */
    1602     }
    1603     catch (std::bad_alloc &)
    1604     {
    1605         return VERR_NO_MEMORY;
    1606     }
    1607 
     1687    int vrc;
    16081688    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    1609     GuestCtrlStreamObjects stdOut;
    1610     int vrc = GuestProcessTool::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
    1611     if (GuestProcess::i_isGuestError(vrc))
    1612     {
    1613         if (!stdOut.empty())
    1614         {
    1615             GuestFsObjData objData;
    1616             vrc = objData.FromRm(stdOut.at(0));
    1617             if (RT_FAILURE(vrc))
     1689#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1690    if (mParent->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     1691    {
     1692        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1693
     1694        GuestWaitEvent *pEvent = NULL;
     1695        vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
     1696        if (RT_FAILURE(vrc))
     1697            return vrc;
     1698
     1699        /* Prepare HGCM call. */
     1700        VBOXHGCMSVCPARM paParms[4];
     1701        int i = 0;
     1702        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     1703        HGCMSvcSetPv (&paParms[i++], (void*)strPath.c_str(), (ULONG)strPath.length() + 1);
     1704
     1705        alock.release(); /* Drop lock before sending. */
     1706
     1707        vrc = i_sendMessage(HOST_MSG_FILE_REMOVE, i, paParms);
     1708        if (RT_SUCCESS(vrc))
     1709        {
     1710            vrc = pEvent->Wait(30 * 1000);
     1711            if (RT_SUCCESS(vrc))
    16181712            {
    1619                 vrcGuest = vrc;
    1620                 if (pvrcGuest)
    1621                     *pvrcGuest = vrcGuest;
    1622                 vrc = VERR_GSTCTL_GUEST_ERROR;
     1713                // TODO
    16231714            }
    16241715        }
    1625         else
    1626             vrc = VERR_BROKEN_PIPE;
    1627     }
    1628     else if (pvrcGuest)
    1629         *pvrcGuest = vrcGuest;
     1716    }
     1717    else
     1718    {
     1719#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     1720#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     1721        GuestProcessStartupInfo procInfo;
     1722        GuestToolboxStream  streamOut;
     1723
     1724        procInfo.mFlags      = ProcessCreateFlag_WaitForStdOut;
     1725        procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_RM);
     1726
     1727        try
     1728        {
     1729            procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
     1730            procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     1731            procInfo.mArguments.push_back("--"); /* strPath could be '--help', which is a valid filename. */
     1732            procInfo.mArguments.push_back(strPath); /* The file we want to remove. */
     1733        }
     1734        catch (std::bad_alloc &)
     1735        {
     1736            return VERR_NO_MEMORY;
     1737        }
     1738
     1739        GuestCtrlStreamObjects stdOut;
     1740        vrc = GuestProcessToolbox::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
     1741        if (GuestProcess::i_isGuestError(vrc))
     1742        {
     1743            if (!stdOut.empty())
     1744            {
     1745                GuestFsObjData objData;
     1746                vrc = objData.FromToolboxRm(stdOut.at(0));
     1747                if (RT_FAILURE(vrc))
     1748                {
     1749                    vrcGuest = vrc;
     1750                    if (pvrcGuest)
     1751                        *pvrcGuest = vrcGuest;
     1752                    vrc = VERR_GSTCTL_GUEST_ERROR;
     1753                }
     1754            }
     1755            else
     1756                vrc = VERR_BROKEN_PIPE;
     1757        }
     1758        else if (pvrcGuest)
     1759            *pvrcGuest = vrcGuest;
     1760#else
     1761        RT_NOREF(pvrcGuest);
     1762        vrc = VERR_NOT_SUPPORTED;
     1763#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     1764#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1765    }
     1766#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    16301767
    16311768    LogFlowThisFunc(("Returning vrc=%Rrc, vrcGuest=%Rrc\n", vrc, vrcGuest));
     
    18211958    LogFlowThisFunc(("strPath=%s\n", strPath.c_str()));
    18221959
    1823     /** @todo Merge this with IGuestFile::queryInfo(). */
    1824     GuestProcessStartupInfo procInfo;
    1825     procInfo.mFlags      = ProcessCreateFlag_WaitForStdOut;
    1826     try
    1827     {
    1828         procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_STAT);
    1829         procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
    1830         procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     1960    int vrc;
     1961    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
     1962
     1963#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     1964    if (mParent->i_getGuestControlFeatures0() & VBOX_GUESTCTRL_GF_0_TOOLBOX_AS_CMDS)
     1965    {
     1966        AutoReadLock alock(this COMMA_LOCKVAL_SRC_POS);
     1967
     1968        GuestWaitEvent *pEvent = NULL;
     1969        vrc = registerWaitEvent(mData.mSession.mID, mData.mObjectID, &pEvent);
     1970        if (RT_FAILURE(vrc))
     1971            return vrc;
     1972
     1973        uint32_t fFlags = GSTCTL_QUERYINFO_F_NONE;
    18311974        if (fFollowSymlinks)
    1832             procInfo.mArguments.push_back(Utf8Str("-L"));
    1833         procInfo.mArguments.push_back("--"); /* strPath could be '--help', which is a valid filename. */
    1834         procInfo.mArguments.push_back(strPath);
    1835     }
    1836     catch (std::bad_alloc &)
    1837     {
    1838         Log(("Out of memory!\n"));
    1839         return VERR_NO_MEMORY;
    1840     }
    1841 
    1842     int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    1843     GuestCtrlStreamObjects stdOut;
    1844     int vrc = GuestProcessTool::runEx(this, procInfo,
    1845                                         &stdOut, 1 /* cStrmOutObjects */,
    1846                                         &vrcGuest);
    1847     if (!GuestProcess::i_isGuestError(vrc))
    1848     {
    1849         if (!stdOut.empty())
    1850         {
    1851             vrc = objData.FromStat(stdOut.at(0));
    1852             if (RT_FAILURE(vrc))
     1975            fFlags |= GSTCTL_QUERYINFO_F_FOLLOW_LINK;
     1976
     1977        /* Prepare HGCM call. */
     1978        VBOXHGCMSVCPARM paParms[4];
     1979        int i = 0;
     1980        HGCMSvcSetU32(&paParms[i++], pEvent->ContextID());
     1981        HGCMSvcSetPv (&paParms[i++], (void*)strPath.c_str(), (ULONG)strPath.length() + 1);
     1982        HGCMSvcSetU32(&paParms[i++], GSTCTLFSOBJATTRADD_UNIX /* Implicit */);
     1983        HGCMSvcSetU32(&paParms[i++], fFlags);
     1984
     1985        alock.release(); /* Drop lock before sending. */
     1986
     1987        vrc = i_sendMessage(HOST_MSG_FS_QUERY_INFO, i, paParms);
     1988        if (RT_SUCCESS(vrc))
     1989        {
     1990            vrc = pEvent->Wait(30 * 1000);
     1991            if (RT_SUCCESS(vrc))
    18531992            {
    1854                 vrcGuest = vrc;
    1855                 if (pvrcGuest)
    1856                     *pvrcGuest = vrcGuest;
    1857                 vrc = VERR_GSTCTL_GUEST_ERROR;
     1993                // TODO
     1994            #if 0
     1995                const ComPtr<IEvent> pThisEvent = pEvent->Event();
     1996                if (pThisEvent.isNotNull()) /* Make sure that we actually have an event associated. */
     1997                {
     1998                    if (pType)
     1999                    {
     2000                        HRESULT hrc = pThisEvent->COMGETTER(Type)(pType);
     2001                        if (FAILED(hrc))
     2002                            vrc = VERR_COM_UNEXPECTED;
     2003                    }
     2004                    if (   RT_SUCCESS(vrc)
     2005                        && ppEvent)
     2006                        pThisEvent.queryInterfaceTo(ppEvent);
     2007
     2008                    unconst(pThisEvent).setNull();
     2009                }
     2010
     2011                if (pEvent->Payload().Size() == sizeof(GSTCTLFSOBJINFO))
     2012                {
     2013                    HRESULT hrc1 = pFileEvent->COMGETTER(Data)(ComSafeArrayAsOutParam(data));
     2014                    ComAssertComRC(hrc1);
     2015
     2016                    objData.Init(strPath);
     2017
     2018                    PGSTCTLFSOBJINFO
     2019
     2020                    objData.FromGuestFsObjInfo((PGSTCTLFSOBJINFO)pEvent->Payload().Raw());
     2021                }
     2022                else
     2023                    vrc = VERR_INVALID_PARAMETER;
     2024            #endif
    18582025            }
    1859         }
    1860         else
    1861             vrc = VERR_BROKEN_PIPE;
    1862     }
    1863     else if (pvrcGuest)
    1864         *pvrcGuest = vrcGuest;
     2026            else
     2027            {
     2028                if (vrc == VERR_GSTCTL_GUEST_ERROR)
     2029                {
     2030                    if (pvrcGuest)
     2031                        *pvrcGuest = pEvent->GuestResult();
     2032                }
     2033            }
     2034        }
     2035        unregisterWaitEvent(pEvent);
     2036    }
     2037    else
     2038    {
     2039#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
     2040#ifdef VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT
     2041        /** @todo Merge this with IGuestFile::queryInfo(). */
     2042        GuestProcessStartupInfo procInfo;
     2043        procInfo.mFlags = ProcessCreateFlag_WaitForStdOut;
     2044        try
     2045        {
     2046            procInfo.mExecutable = Utf8Str(VBOXSERVICE_TOOL_STAT);
     2047            procInfo.mArguments.push_back(procInfo.mExecutable); /* Set argv0. */
     2048            procInfo.mArguments.push_back(Utf8Str("--machinereadable"));
     2049            if (fFollowSymlinks)
     2050                procInfo.mArguments.push_back(Utf8Str("-L"));
     2051            procInfo.mArguments.push_back("--"); /* strPath could be '--help', which is a valid filename. */
     2052            procInfo.mArguments.push_back(strPath);
     2053        }
     2054        catch (std::bad_alloc &)
     2055        {
     2056            Log(("Out of memory!\n"));
     2057            return VERR_NO_MEMORY;
     2058        }
     2059
     2060        GuestCtrlStreamObjects stdOut;
     2061        vrc = GuestProcessToolbox::runEx(this, procInfo, &stdOut, 1 /* cStrmOutObjects */, &vrcGuest);
     2062        if (!GuestProcess::i_isGuestError(vrc))
     2063        {
     2064            if (!stdOut.empty())
     2065            {
     2066                vrc = objData.FromToolboxStat(stdOut.at(0));
     2067                if (RT_FAILURE(vrc))
     2068                {
     2069                    vrcGuest = vrc;
     2070                    if (pvrcGuest)
     2071                        *pvrcGuest = vrcGuest;
     2072                    vrc = VERR_GSTCTL_GUEST_ERROR;
     2073                }
     2074            }
     2075            else
     2076                vrc = VERR_BROKEN_PIPE;
     2077        }
     2078        else if (pvrcGuest)
     2079            *pvrcGuest = vrcGuest;
     2080#else
     2081        RT_NOREF(fFollowSymlinks, objData, pvrcGuest);
     2082        vrc = VERR_NOT_SUPPORTED;
     2083#endif /* VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT */
     2084#ifdef VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS
     2085    }
     2086#endif /* VBOX_WITH_GSTCTL_TOOLBOX_AS_CMDS */
    18652087
    18662088    LogFlowThisFunc(("Returning vrc=%Rrc, vrcGuest=%Rrc\n", vrc, vrcGuest));
     
    38024024            case VERR_GSTCTL_GUEST_ERROR:
    38034025            {
    3804                 GuestErrorInfo ge(GuestErrorInfo::Type_ToolMkTemp, vrcGuest, aPath.c_str());
     4026                GuestErrorInfo ge(GuestErrorInfo::Type_Fs, vrcGuest, aPath.c_str());
    38054027                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Temporary guest directory creation failed: %s"),
    38064028                                   GuestBase::getErrorAsString(ge).c_str());
     
    38474069                    default:
    38484070                    {
    3849                         GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, aPath.c_str());
     4071                        GuestErrorInfo ge(GuestErrorInfo::Type_Fs, vrcGuest, aPath.c_str());
    38504072                        hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying directory existence failed: %s"),
    38514073                                           GuestBase::getErrorAsString(ge).c_str());
     
    41904412                default:
    41914413                {
    4192                     GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, aPath.c_str());
     4414                    GuestErrorInfo ge(GuestErrorInfo::Type_Fs, vrcGuest, aPath.c_str());
    41934415                    hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying guest file existence failed: %s"),
    41944416                                       GuestBase::getErrorAsString(ge).c_str());
     
    43434565        if (GuestProcess::i_isGuestError(vrc))
    43444566        {
    4345             GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, aPath.c_str());
     4567            GuestErrorInfo ge(GuestErrorInfo::Type_Fs, vrcGuest, aPath.c_str());
    43464568            hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying guest file size failed: %s"),
    43474569                               GuestBase::getErrorAsString(ge).c_str());
     
    43984620            else
    43994621            {
    4400                 GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, aPath.c_str());
     4622                GuestErrorInfo ge(GuestErrorInfo::Type_Fs, vrcGuest, aPath.c_str());
    44014623                hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying guest file existence information failed: %s"),
    44024624                                   GuestBase::getErrorAsString(ge).c_str());
     
    44214643    LogFlowThisFunc(("aPath=%s, aFollowSymlinks=%RTbool\n", aPath.c_str(), RT_BOOL(aFollowSymlinks)));
    44224644
    4423     GuestFsObjData Info;
     4645    GuestFsObjData objData;
    44244646    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    4425     int vrc = i_fsQueryInfo(aPath, aFollowSymlinks != FALSE, Info, &vrcGuest);
     4647    int vrc = i_fsQueryInfo(aPath, aFollowSymlinks != FALSE, objData, &vrcGuest);
    44264648    if (RT_SUCCESS(vrc))
    44274649    {
     
    44304652        if (SUCCEEDED(hrc))
    44314653        {
    4432             vrc = ptrFsObjInfo->init(Info);
     4654            vrc = ptrFsObjInfo->init(objData);
    44334655            if (RT_SUCCESS(vrc))
    44344656                hrc = ptrFsObjInfo.queryInterfaceTo(aInfo.asOutParam());
     
    44414663        if (GuestProcess::i_isGuestError(vrc))
    44424664        {
    4443             GuestErrorInfo ge(GuestErrorInfo::Type_ToolStat, vrcGuest, aPath.c_str());
     4665            GuestErrorInfo ge(GuestErrorInfo::Type_Fs, vrcGuest, aPath.c_str());
    44444666            hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Querying guest file information failed: %s"),
    44454667                               GuestBase::getErrorAsString(ge).c_str());
     
    44694691        if (GuestProcess::i_isGuestError(vrc))
    44704692        {
    4471             GuestErrorInfo ge(GuestErrorInfo::Type_ToolRm, vrcGuest, aPath.c_str());
     4693            GuestErrorInfo ge(GuestErrorInfo::Type_File, vrcGuest, aPath.c_str());
    44724694            hrc = setErrorBoth(VBOX_E_IPRT_ERROR, vrcGuest, tr("Removing guest file failed: %s"),
    44734695                               GuestBase::getErrorAsString(ge).c_str());
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r98272 r98526  
    550550        if (vrc == VERR_GSTCTL_GUEST_ERROR)
    551551            setProgressErrorMsg(VBOX_E_IPRT_ERROR, tr("Guest file lookup failed"),
    552                                 GuestErrorInfo(GuestErrorInfo::Type_ToolStat, vrcGuest, strSrc.c_str()));
     552                                GuestErrorInfo(GuestErrorInfo::Type_Fs, vrcGuest, strSrc.c_str()));
    553553        else
    554554            setProgressErrorMsg(VBOX_E_IPRT_ERROR,
     
    12471247    }
    12481248
    1249     int vrc2 = pDir->i_closeInternal(&vrcGuest);
     1249    int vrc2 = pDir->i_close(&vrcGuest);
    12501250    if (RT_SUCCESS(vrc))
    12511251        vrc = vrc2;
     
    15441544                if (vrc == VERR_GSTCTL_GUEST_ERROR)
    15451545                    strErrorInfo = GuestBase::getErrorAsString(tr("Guest source lookup failed"),
    1546                                                                GuestErrorInfo(GuestErrorInfo::Type_ToolStat, vrcGuest, strSrc.c_str()));
     1546                                                               GuestErrorInfo(GuestErrorInfo::Type_Fs, vrcGuest, strSrc.c_str()));
    15471547                else
    15481548                    strErrorInfo.printf(tr("Guest source lookup for \"%s\" failed: %Rrc"),
     
    26302630    LogRel(("Running %s ...\n", procInfo.mName.c_str()));
    26312631
    2632     GuestProcessTool procTool;
     2632    GuestProcessToolbox procToRun;
    26332633    int vrcGuest = VERR_IPE_UNINITIALIZED_STATUS;
    2634     int vrc = procTool.init(pSession, procInfo, false /* Async */, &vrcGuest);
     2634    int vrc = procToRun.init(pSession, procInfo, false /* Async */, &vrcGuest);
    26352635    if (RT_SUCCESS(vrc))
    26362636    {
    26372637        if (RT_SUCCESS(vrcGuest))
    2638             vrc = procTool.wait(GUESTPROCESSTOOL_WAIT_FLAG_NONE, &vrcGuest);
     2638            vrc = procToRun.wait(GUESTPROCESSTOOL_WAIT_FLAG_NONE, &vrcGuest);
    26392639        if (RT_SUCCESS(vrc))
    2640             vrc = procTool.getTerminationStatus();
     2640            vrc = procToRun.getTerminationStatus();
    26412641    }
    26422642
     
    26482648                setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    26492649                                    Utf8StrFmt(tr("Running update file \"%s\" on guest failed: %Rrc"),
    2650                                                procInfo.mExecutable.c_str(), procTool.getRc()));
     2650                                               procInfo.mExecutable.c_str(), procToRun.getRc()));
    26512651                break;
    26522652
  • trunk/src/VBox/Main/testcase/Makefile.kmk

    r98431 r98526  
    225225tstGuestCtrlParseBuffer_TEMPLATE = VBoxMainClientTstExe
    226226tstGuestCtrlParseBuffer_INTERMEDIATES   = $(VBOX_MAIN_APIWRAPPER_GEN_HDRS)
    227 tstGuestCtrlParseBuffer_DEFS    += VBOX_WITH_HGCM VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE
     227tstGuestCtrlParseBuffer_DEFS    += VBOX_WITH_HGCM VBOX_WITH_GSTCTL_TOOLBOX_SUPPORT VBOX_WITH_GUEST_CONTROL VBOX_GUESTCTRL_TEST_CASE
    228228tstGuestCtrlParseBuffer_SOURCES  = \
    229229        tstGuestCtrlParseBuffer.cpp \
  • trunk/src/VBox/Main/testcase/tstGuestCtrlParseBuffer.cpp

    r98103 r98526  
    164164        RTTestIPrintf(RTTESTLVL_DEBUG, "Manual test #%d\n", iTest);
    165165
    166         GuestProcessStream stream;
     166        GuestToolboxStream stream;
    167167        rc = stream.AddData((BYTE *)s_aTest[iTest].pbData, s_aTest[iTest].cbData);
    168168
    169169        for (;;)
    170170        {
    171             GuestProcessStreamBlock block;
     171            GuestToolboxStreamBlock block;
    172172            rc = stream.ParseBlock(block);
    173173            RTTestIPrintf(RTTESTLVL_DEBUG, "\tReturned with rc=%Rrc, numItems=%ld\n",
     
    213213        RTTestIPrintf(RTTESTLVL_DEBUG, "=> Test #%u\n", iTest);
    214214
    215         GuestProcessStream stream;
     215        GuestToolboxStream stream;
    216216        if (RT_FAILURE(g_aTestBlocks[iTest].iResult))
    217217            RTTestDisableAssertions(hTest);
     
    221221        if (RT_SUCCESS(iResult))
    222222        {
    223             GuestProcessStreamBlock curBlock;
     223            GuestToolboxStreamBlock curBlock;
    224224            iResult = stream.ParseBlock(curBlock);
    225225            if (iResult != g_aTestBlocks[iTest].iResult)
     
    257257        RTTestIPrintf(RTTESTLVL_DEBUG, "=> Block test #%u\n", iTest);
    258258
    259         GuestProcessStream stream;
     259        GuestToolboxStream stream;
    260260        int iResult = stream.AddData((BYTE*)g_aTestStream[iTest].pbData, g_aTestStream[iTest].cbData);
    261261        if (RT_SUCCESS(iResult))
     
    265265            do
    266266            {
    267                 GuestProcessStreamBlock curBlock;
     267                GuestToolboxStreamBlock curBlock;
    268268                iResult = stream.ParseBlock(curBlock);
    269269                RTTestIPrintf(RTTESTLVL_DEBUG, "Block #%u: Returned with %Rrc", iTest, iResult);
Note: See TracChangeset for help on using the changeset viewer.

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