VirtualBox

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/src/VBox/Additions/common/VBoxService
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.

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