- 時間撮記:
- 2015-5-11 下午03:00:35 (10 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/GuestHost/DragAndDrop/DnDURIList.cpp
r55744 r55805 24 24 #include <iprt/fs.h> 25 25 #include <iprt/path.h> 26 #include <iprt/symlink.h> 26 27 #include <iprt/uri.h> 27 28 … … 44 45 } 45 46 46 int DnDURIList::appendPathRecursive(const char *pcszPath, size_t cbBaseLen, 47 uint32_t fFlags) 48 { 49 AssertPtrReturn(pcszPath, VERR_INVALID_POINTER); 47 int DnDURIList::addEntry(const char *pcszSource, const char *pcszTarget, uint32_t fFlags) 48 { 49 AssertPtrReturn(pcszSource, VERR_INVALID_POINTER); 50 AssertPtrReturn(pcszTarget, VERR_INVALID_POINTER); 51 52 LogFlowFunc(("pcszSource=%s, pcszTarget=%s\n", pcszSource, pcszTarget)); 50 53 51 54 RTFSOBJINFO objInfo; 52 int rc = RTPathQueryInfo(pcszPath, &objInfo, RTFSOBJATTRADD_NOTHING); 53 if (RT_FAILURE(rc)) 54 return rc; 55 56 /* 57 * These are the types we currently support. Symlinks are not directly 58 * supported. First the guest could be an OS which doesn't support it and 59 * second the symlink could point to a file which is out of the base tree. 60 * Both things are hard to support. For now we just copy the target file in 61 * this case. 62 */ 63 if (!( RTFS_IS_DIRECTORY(objInfo.Attr.fMode) 64 || RTFS_IS_FILE(objInfo.Attr.fMode) 65 || RTFS_IS_SYMLINK(objInfo.Attr.fMode))) 66 return VINF_SUCCESS; 67 68 uint64_t cbSize = 0; 69 rc = RTFileQuerySize(pcszPath, &cbSize); 70 if (rc == VERR_IS_A_DIRECTORY) 71 rc = VINF_SUCCESS; 72 73 if (RT_FAILURE(rc)) 74 return rc; 75 76 m_lstTree.append(DnDURIObject( RTFS_IS_DIRECTORY(objInfo.Attr.fMode) 77 ? DnDURIObject::Directory 78 : DnDURIObject::File, 79 pcszPath, &pcszPath[cbBaseLen], 80 objInfo.Attr.fMode, cbSize)); 81 m_cTotal++; 82 m_cbTotal += cbSize; 83 #ifdef DEBUG_andy 84 LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cTotal=%RU32, cbTotal=%zu\n", 85 pcszPath, &pcszPath[cbBaseLen], objInfo.Attr.fMode, cbSize, m_cTotal, m_cbTotal)); 86 #endif 87 88 /* We have to try to open even symlinks, cause they could 89 * be symlinks to directories. */ 90 PRTDIR hDir; 91 rc = RTDirOpen(&hDir, pcszPath); 92 93 /* The following error happens when this was a symlink 94 * to a file or a regular file. */ 95 if ( rc == VERR_PATH_NOT_FOUND 96 || rc == VERR_NOT_A_DIRECTORY) 97 return VINF_SUCCESS; 98 if (RT_FAILURE(rc)) 99 return rc; 100 101 while (RT_SUCCESS(rc)) 102 { 103 RTDIRENTRY DirEntry; 104 rc = RTDirRead(hDir, &DirEntry, NULL); 105 if (RT_FAILURE(rc)) 106 { 107 if (rc == VERR_NO_MORE_FILES) 108 rc = VINF_SUCCESS; 109 break; 110 } 111 switch (DirEntry.enmType) 112 { 113 case RTDIRENTRYTYPE_DIRECTORY: 55 int rc = RTPathQueryInfo(pcszSource, &objInfo, RTFSOBJATTRADD_NOTHING); 56 if (RT_SUCCESS(rc)) 57 { 58 if (RTFS_IS_FILE(objInfo.Attr.fMode)) 59 { 60 LogFlowFunc(("File '%s' -> '%s'\n", pcszSource, pcszTarget)); 61 62 m_lstTree.append(DnDURIObject(DnDURIObject::File, pcszSource, pcszTarget, 63 objInfo.Attr.fMode, (uint64_t)objInfo.cbObject)); 64 m_cTotal++; 65 m_cbTotal += (uint64_t)objInfo.cbObject; 66 } 67 else if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) 68 { 69 LogFlowFunc(("Directory '%s' -> '%s' \n", pcszSource, pcszTarget)); 70 71 m_lstTree.append(DnDURIObject(DnDURIObject::Directory, pcszSource, pcszTarget, 72 objInfo.Attr.fMode, 0 /* Size */)); 73 m_cTotal++; 74 } 75 /* Note: Symlinks already should have been resolved at this point. */ 76 else 77 rc = VERR_NOT_SUPPORTED; 78 } 79 80 LogFlowFuncLeaveRC(rc); 81 return rc; 82 } 83 84 int DnDURIList::appendPathRecursive(const char *pcszSrcPath, 85 const char *pcszDstPath, const char *pcszDstBase, size_t cchDstBase, uint32_t fFlags) 86 { 87 AssertPtrReturn(pcszSrcPath, VERR_INVALID_POINTER); 88 AssertPtrReturn(pcszDstBase, VERR_INVALID_POINTER); 89 AssertPtrReturn(pcszDstPath, VERR_INVALID_POINTER); 90 91 LogFlowFunc(("pcszSrcPath=%s, pcszDstPath=%s, pcszDstBase=%s, cchDstBase=%zu\n", 92 pcszSrcPath, pcszDstPath, pcszDstBase, cchDstBase)); 93 94 RTFSOBJINFO objInfo; 95 int rc = RTPathQueryInfo(pcszSrcPath, &objInfo, RTFSOBJATTRADD_NOTHING); 96 if (RT_SUCCESS(rc)) 97 { 98 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) 99 { 100 rc = addEntry(pcszSrcPath, &pcszDstPath[cchDstBase], fFlags); 101 102 PRTDIR hDir; 103 if (RT_SUCCESS(rc)) 104 rc = RTDirOpen(&hDir, pcszSrcPath); 105 if (RT_SUCCESS(rc)) 106 { 107 do 108 { 109 RTDIRENTRY DirEntry; 110 rc = RTDirRead(hDir, &DirEntry, NULL); 111 if (RT_FAILURE(rc)) 112 { 113 if (rc == VERR_NO_MORE_FILES) 114 rc = VINF_SUCCESS; 115 break; 116 } 117 118 switch (DirEntry.enmType) 119 { 120 case RTDIRENTRYTYPE_DIRECTORY: 121 { 122 /* Skip "." and ".." entries. */ 123 if ( RTStrCmp(DirEntry.szName, ".") == 0 124 || RTStrCmp(DirEntry.szName, "..") == 0) 125 break; 126 127 char *pszSrc = RTPathJoinA(pcszSrcPath, DirEntry.szName); 128 if (pszSrc) 129 { 130 char *pszDst = RTPathJoinA(pcszDstPath, DirEntry.szName); 131 if (pszDst) 132 { 133 rc = appendPathRecursive(pszSrc, pszDst, pcszDstBase, cchDstBase, fFlags); 134 RTStrFree(pszDst); 135 } 136 else 137 rc = VERR_NO_MEMORY; 138 139 RTStrFree(pszSrc); 140 } 141 else 142 rc = VERR_NO_MEMORY; 143 break; 144 } 145 146 case RTDIRENTRYTYPE_FILE: 147 { 148 char *pszSrc = RTPathJoinA(pcszSrcPath, DirEntry.szName); 149 if (pszSrc) 150 { 151 char *pszDst = RTPathJoinA(pcszDstPath, DirEntry.szName); 152 if (pszDst) 153 { 154 rc = addEntry(pszSrc, &pszDst[cchDstBase], fFlags); 155 RTStrFree(pszDst); 156 } 157 else 158 rc = VERR_NO_MEMORY; 159 RTStrFree(pszSrc); 160 } 161 else 162 rc = VERR_NO_MEMORY; 163 break; 164 } 165 case RTDIRENTRYTYPE_SYMLINK: 166 { 167 if (fFlags & DNDURILIST_FLAGS_RESOLVE_SYMLINKS) 168 { 169 char *pszSrc = RTPathRealDup(pcszDstBase); 170 if (pszSrc) 171 { 172 rc = RTPathQueryInfo(pszSrc, &objInfo, RTFSOBJATTRADD_NOTHING); 173 if (RT_SUCCESS(rc)) 174 { 175 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) 176 { 177 LogFlowFunc(("Directory entry is symlink to directory\n")); 178 rc = appendPathRecursive(pszSrc, pcszDstPath, pcszDstBase, cchDstBase, fFlags); 179 } 180 else if (RTFS_IS_FILE(objInfo.Attr.fMode)) 181 { 182 LogFlowFunc(("Directory entry is symlink to file\n")); 183 rc = addEntry(pszSrc, &pcszDstPath[cchDstBase], fFlags); 184 } 185 else 186 rc = VERR_NOT_SUPPORTED; 187 } 188 189 RTStrFree(pszSrc); 190 } 191 else 192 rc = VERR_NO_MEMORY; 193 } 194 break; 195 } 196 197 default: 198 break; 199 } 200 201 } while (RT_SUCCESS(rc)); 202 203 RTDirClose(hDir); 204 } 205 } 206 else if (RTFS_IS_FILE(objInfo.Attr.fMode)) 207 { 208 rc = addEntry(pcszSrcPath, &pcszDstPath[cchDstBase], fFlags); 209 } 210 else if (RTFS_IS_SYMLINK(objInfo.Attr.fMode)) 211 { 212 if (fFlags & DNDURILIST_FLAGS_RESOLVE_SYMLINKS) 114 213 { 115 /* Skip "." and ".." entries. */ 116 if ( RTStrCmp(DirEntry.szName, ".") == 0 117 || RTStrCmp(DirEntry.szName, "..") == 0) 118 break; 119 120 char *pszRecDir = RTPathJoinA(pcszPath, DirEntry.szName); 121 if (pszRecDir) 214 char *pszSrc = RTPathRealDup(pcszSrcPath); 215 if (pszSrc) 122 216 { 123 rc = appendPathRecursive(pszRecDir, cbBaseLen, fFlags); 124 RTStrFree(pszRecDir); 125 } 217 rc = RTPathQueryInfo(pszSrc, &objInfo, RTFSOBJATTRADD_NOTHING); 218 if (RT_SUCCESS(rc)) 219 { 220 if (RTFS_IS_DIRECTORY(objInfo.Attr.fMode)) 221 { 222 LogFlowFunc(("Symlink to directory\n")); 223 rc = appendPathRecursive(pszSrc, pcszDstPath, pcszDstBase, cchDstBase, fFlags); 224 } 225 else if (RTFS_IS_FILE(objInfo.Attr.fMode)) 226 { 227 LogFlowFunc(("Symlink to file\n")); 228 rc = addEntry(pszSrc, &pcszDstPath[cchDstBase], fFlags); 229 } 230 else 231 rc = VERR_NOT_SUPPORTED; 232 } 233 234 RTStrFree(pszSrc); 235 } 126 236 else 127 rc = VERR_NO_MEMORY; 128 break; 129 } 130 case RTDIRENTRYTYPE_SYMLINK: 131 case RTDIRENTRYTYPE_FILE: 132 { 133 char *pszNewFile = RTPathJoinA(pcszPath, DirEntry.szName); 134 if (pszNewFile) 135 { 136 /* We need the size and the mode of the file. */ 137 RTFSOBJINFO objInfo1; 138 rc = RTPathQueryInfo(pszNewFile, &objInfo1, RTFSOBJATTRADD_NOTHING); 139 if (RT_FAILURE(rc)) 140 return rc; 141 rc = RTFileQuerySize(pszNewFile, &cbSize); 142 if (rc == VERR_IS_A_DIRECTORY) /* Happens for symlinks. */ 143 rc = VINF_SUCCESS; 144 145 if (RT_FAILURE(rc)) 146 break; 147 148 if (RTFS_IS_FILE(objInfo.Attr.fMode)) 149 { 150 m_lstTree.append(DnDURIObject(DnDURIObject::File, 151 pszNewFile, &pszNewFile[cbBaseLen], 152 objInfo1.Attr.fMode, cbSize)); 153 m_cTotal++; 154 m_cbTotal += cbSize; 155 #ifdef DEBUG_andy 156 LogFlowFunc(("strSrcPath=%s, strDstPath=%s, fMode=0x%x, cbSize=%RU64, cTotal=%RU32, cbTotal=%zu\n", 157 pszNewFile, &pszNewFile[cbBaseLen], objInfo1.Attr.fMode, cbSize, m_cTotal, m_cbTotal)); 158 #endif 159 } 160 else /* Handle symlink directories. */ 161 rc = appendPathRecursive(pszNewFile, cbBaseLen, fFlags); 162 163 RTStrFree(pszNewFile); 164 } 165 else 166 rc = VERR_NO_MEMORY; 167 break; 168 } 169 170 default: 171 /* Just ignore the rest. */ 172 break; 173 } 174 } 175 176 RTDirClose(hDir); 237 rc = VERR_NO_MEMORY; 238 } 239 } 240 else 241 rc = VERR_NOT_SUPPORTED; 242 } 243 244 LogFlowFuncLeaveRC(rc); 177 245 return rc; 178 246 } … … 246 314 /* Query the path component of a file URI. If this hasn't a 247 315 * file scheme NULL is returned. */ 248 char *psz FilePath = RTUriFilePath(pszURI, URI_FILE_FORMAT_AUTO);249 if (psz FilePath)316 char *pszSrcPath = RTUriFilePath(pszURI, URI_FILE_FORMAT_AUTO); 317 if (pszSrcPath) 250 318 { 251 319 /* Add the path to our internal file list (recursive in 252 320 * the case of a directory). */ 253 size_t cbPathLen = RTPathStripTrailingSlash(psz FilePath);321 size_t cbPathLen = RTPathStripTrailingSlash(pszSrcPath); 254 322 if (cbPathLen) 255 323 { 256 char *pszFileName = RTPathFilename(psz FilePath);324 char *pszFileName = RTPathFilename(pszSrcPath); 257 325 if (pszFileName) 258 326 { 259 Assert(pszFileName >= psz FilePath);260 size_t c bBase = (fFlags & DNDURILIST_FLAGS_ABSOLUTE_PATHS)261 ? 0 /* Use start of path as root. */262 : pszFileName - pszFilePath;263 char *psz Root = &pszFilePath[cbBase];264 m_lstRoot.append(psz Root);265 #ifdef DEBUG_andy 327 Assert(pszFileName >= pszSrcPath); 328 size_t cchDstBase = (fFlags & DNDURILIST_FLAGS_ABSOLUTE_PATHS) 329 ? 0 /* Use start of path as root. */ 330 : pszFileName - pszSrcPath; 331 char *pszDstPath = &pszSrcPath[cchDstBase]; 332 m_lstRoot.append(pszDstPath); 333 266 334 LogFlowFunc(("pszFilePath=%s, pszFileName=%s, pszRoot=%s\n", 267 psz FilePath, pszFileName, pszRoot));268 #endif 269 rc = appendPathRecursive(psz FilePath, cbBase, fFlags);335 pszSrcPath, pszFileName, pszDstPath)); 336 337 rc = appendPathRecursive(pszSrcPath, pszSrcPath, pszSrcPath, cchDstBase, fFlags); 270 338 } 271 339 else 272 rc = VERR_ NOT_FOUND;340 rc = VERR_PATH_NOT_FOUND; 273 341 } 274 342 else 275 343 rc = VERR_INVALID_PARAMETER; 276 344 277 RTStrFree(psz FilePath);345 RTStrFree(pszSrcPath); 278 346 } 279 347 else
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器