Changeset 78111 in vbox
- Timestamp:
- Apr 11, 2019 2:10:07 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp
r77069 r78111 121 121 122 122 123 /** 124 * Recursion worker for vgsvcGstCtrlSessionHandleDirRemove. 125 * Only (recursively) removes directory structures which are not empty. Will fail if not empty. 126 * 127 * @returns IPRT status code. 128 * @param pszDir The directory buffer. Contains the abs path to the 129 * directory to recurse into. Trailing slash. 130 * @param cchDir The length of the directory we're recursing into, 131 * including the trailing slash. 132 * @param pDirEntry The dir entry buffer. (Shared to save stack.) 133 * @param pObjInfo The object info buffer. (ditto) 134 */ 135 static int vgsvcGstCtrlSessionHandleDirRemoveSub(char *pszDir, size_t cchDir, PRTDIRENTRY pDirEntry, PRTFSOBJINFO pObjInfo) 136 { 137 RTDIR hDir; 138 int rc = RTDirOpen(&hDir, pszDir); 139 if (RT_FAILURE(rc)) 140 return rc; 141 142 while (RT_SUCCESS(rc = RTDirRead(hDir, pDirEntry, NULL))) 143 { 144 if (!RTDirEntryIsStdDotLink(pDirEntry)) 145 { 146 /* Construct the full name of the entry. */ 147 if (cchDir + pDirEntry->cbName + 1 /* dir slash */ >= RTPATH_MAX) 148 { 149 rc = VERR_FILENAME_TOO_LONG; 150 break; 151 } 152 memcpy(&pszDir[cchDir], pDirEntry->szName, pDirEntry->cbName + 1); 153 154 /* Deal with the unknown type. */ 155 if (pDirEntry->enmType == RTDIRENTRYTYPE_UNKNOWN) 156 { 157 rc = RTPathQueryInfoEx(pszDir, pObjInfo, RTFSOBJATTRADD_NOTHING, RTPATH_F_ON_LINK); 158 if (RT_SUCCESS(rc) && RTFS_IS_DIRECTORY(pObjInfo->Attr.fMode)) 159 pDirEntry->enmType = RTDIRENTRYTYPE_DIRECTORY; 160 else if (RT_SUCCESS(rc) && RTFS_IS_FILE(pObjInfo->Attr.fMode)) 161 pDirEntry->enmType = RTDIRENTRYTYPE_FILE; 162 else if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(pObjInfo->Attr.fMode)) 163 pDirEntry->enmType = RTDIRENTRYTYPE_SYMLINK; 164 } 165 166 /* Try the delete the fs object. */ 167 switch (pDirEntry->enmType) 168 { 169 case RTDIRENTRYTYPE_DIRECTORY: 170 { 171 size_t cchSubDir = cchDir + pDirEntry->cbName; 172 pszDir[cchSubDir++] = '/'; 173 pszDir[cchSubDir] = '\0'; 174 rc = vgsvcGstCtrlSessionHandleDirRemoveSub(pszDir, cchSubDir, pDirEntry, pObjInfo); 175 if (RT_SUCCESS(rc)) 176 { 177 pszDir[cchSubDir] = '\0'; 178 rc = RTDirRemove(pszDir); 179 } 180 break; 181 } 182 183 /** @todo Implement deleting symlinks? Play safe for now. */ 184 185 default: 186 rc = VERR_DIR_NOT_EMPTY; 187 break; 188 } 189 if (RT_FAILURE(rc)) 190 break; 191 } 192 } 193 if (rc == VERR_NO_MORE_FILES) 194 rc = VINF_SUCCESS; 195 RTDirClose(hDir); 196 return rc; 197 } 198 199 123 200 static int vgsvcGstCtrlSessionHandleDirRemove(PVBOXSERVICECTRLSESSION pSession, PVBGLR3GUESTCTRLCMDCTX pHostCtx) 124 201 { … … 141 218 if (fFlags & DIRREMOVEREC_FLAG_RECURSIVE) 142 219 { 143 uint32_t fFlagsRemRec = RTDIRRMREC_F_CONTENT_AND_DIR; /* Set default. */ 144 if (fFlags & DIRREMOVEREC_FLAG_CONTENT_ONLY) 145 fFlagsRemRec |= RTDIRRMREC_F_CONTENT_ONLY; 146 rc = RTDirRemoveRecursive(szDir, fFlagsRemRec); 220 if ( fFlags & DIRREMOVEREC_FLAG_CONTENT_AND_DIR 221 || fFlags & DIRREMOVEREC_FLAG_CONTENT_ONLY) 222 { 223 uint32_t fFlagsRemRec = 0; 224 if (fFlags & DIRREMOVEREC_FLAG_CONTENT_AND_DIR) 225 fFlagsRemRec |= RTDIRRMREC_F_CONTENT_AND_DIR; 226 else if (fFlags & DIRREMOVEREC_FLAG_CONTENT_ONLY) 227 fFlagsRemRec |= RTDIRRMREC_F_CONTENT_ONLY; 228 rc = RTDirRemoveRecursive(szDir, fFlagsRemRec); 229 } 230 else /* Only remove empty directory structures. Will fail if non-empty. */ 231 { 232 RTDIRENTRY dirEntry; 233 RTFSOBJINFO objInfo; 234 rc = vgsvcGstCtrlSessionHandleDirRemoveSub(szDir, strlen(szDir), &dirEntry, &objInfo); 235 } 147 236 VGSvcVerbose(4, "[Dir %s]: rmdir /s (%#x) -> rc=%Rrc\n", szDir, fFlags, rc); 148 237 }
Note:
See TracChangeset
for help on using the changeset viewer.