Changeset 56962 in vbox for trunk/src/VBox/HostServices/SharedFolders
- Timestamp:
- Jul 17, 2015 9:43:26 AM (9 years ago)
- Location:
- trunk/src/VBox/HostServices/SharedFolders
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostServices/SharedFolders/Makefile.kmk
r56301 r56962 41 41 shflhandle.cpp \ 42 42 vbsf.cpp \ 43 vbsfpath.cpp \ 43 44 mappings.cpp 44 45 VBoxSharedFolders_SOURCES.win = \ -
trunk/src/VBox/HostServices/SharedFolders/mappings.cpp
r51250 r56962 322 322 return NULL; 323 323 return pFolderMapping->pszFolderName; 324 } 325 326 int vbsfMappingsQueryHostRootEx(SHFLROOT hRoot, const char **ppszRoot, uint32_t *pcbRootLen) 327 { 328 MAPPING *pFolderMapping = vbsfMappingGetByRoot(hRoot); 329 AssertReturn(pFolderMapping, VERR_INVALID_PARAMETER); 330 if (pFolderMapping->fMissing) 331 return VERR_NOT_FOUND; 332 if ( pFolderMapping->pszFolderName == NULL 333 || pFolderMapping->pszFolderName[0] == 0) 334 return VERR_NOT_FOUND; 335 *ppszRoot = pFolderMapping->pszFolderName; 336 *pcbRootLen = strlen(pFolderMapping->pszFolderName); 337 return VINF_SUCCESS; 324 338 } 325 339 -
trunk/src/VBox/HostServices/SharedFolders/mappings.h
r44528 r56962 57 57 58 58 const char* vbsfMappingsQueryHostRoot(SHFLROOT root); 59 int vbsfMappingsQueryHostRootEx(SHFLROOT hRoot, const char **ppszRoot, uint32_t *pcbRootLen); 59 60 bool vbsfIsGuestMappingCaseSensitive(SHFLROOT root); 60 61 bool vbsfIsHostMappingCaseSensitive(SHFLROOT root); -
trunk/src/VBox/HostServices/SharedFolders/testcase/Makefile.kmk
r56301 r56962 64 64 ../service.cpp \ 65 65 ../shflhandle.cpp \ 66 ../vbsfpath.cpp \ 66 67 ../vbsf.cpp 67 68 tstSharedFolderService_LDFLAGS.darwin = \ -
trunk/src/VBox/HostServices/SharedFolders/vbsf.cpp
r51250 r56962 5 5 6 6 /* 7 * Copyright (C) 2006-201 3Oracle Corporation7 * Copyright (C) 2006-2015 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 20 20 #endif 21 21 22 #include "vbsfpath.h" 22 23 #include "mappings.h" 23 24 #include "vbsf.h" … … 26 27 #include <iprt/alloc.h> 27 28 #include <iprt/assert.h> 29 #include <iprt/asm.h> 28 30 #include <iprt/fs.h> 29 31 #include <iprt/dir.h> … … 107 109 } 108 110 109 /**110 * Corrects the casing of the final component111 *112 * @returns113 * @param pClient .114 * @param pszFullPath .115 * @param pszStartComponent .116 */117 static int vbsfCorrectCasing(SHFLCLIENTDATA *pClient, char *pszFullPath, char *pszStartComponent)118 {119 Log2(("vbsfCorrectCasing: %s %s\n", pszFullPath, pszStartComponent));120 121 AssertReturn((uintptr_t)pszFullPath < (uintptr_t)pszStartComponent - 1U, VERR_INTERNAL_ERROR_2);122 AssertReturn(pszStartComponent[-1] == RTPATH_DELIMITER, VERR_INTERNAL_ERROR_5);123 124 /*125 * Allocate a buffer that can hold really long file name entries as well as126 * the initial search pattern.127 */128 size_t cchComponent = strlen(pszStartComponent);129 size_t cchParentDir = pszStartComponent - pszFullPath;130 size_t cchFullPath = cchParentDir + cchComponent;131 Assert(strlen(pszFullPath) == cchFullPath);132 133 size_t cbDirEntry = 4096;134 if (cchFullPath + 4 > cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName))135 cbDirEntry = RT_OFFSETOF(RTDIRENTRYEX, szName) + cchFullPath + 4;136 137 PRTDIRENTRYEX pDirEntry = (PRTDIRENTRYEX)RTMemAlloc(cbDirEntry);138 if (pDirEntry == NULL)139 return VERR_NO_MEMORY;140 141 /*142 * Construct the search criteria in the szName member of pDirEntry.143 */144 /** @todo This is quite inefficient, especially for directories with many145 * files. If any of the typically case sensitive host systems start146 * supporting opendir wildcard filters, it would make sense to build147 * one here with '?' for case foldable charaters. */148 /** @todo Use RTDirOpen here and drop the whole uncessary path copying? */149 int rc = RTPathJoinEx(pDirEntry->szName, cbDirEntry - RT_OFFSETOF(RTDIRENTRYEX, szName),150 pszFullPath, cchParentDir,151 RT_STR_TUPLE("*"));152 AssertRC(rc);153 if (RT_SUCCESS(rc))154 {155 PRTDIR hSearch = NULL;156 rc = RTDirOpenFiltered(&hSearch, pDirEntry->szName, RTDIRFILTER_WINNT, 0);157 if (RT_SUCCESS(rc))158 {159 for (;;)160 {161 size_t cbDirEntrySize = cbDirEntry;162 163 rc = RTDirReadEx(hSearch, pDirEntry, &cbDirEntrySize, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));164 if (rc == VERR_NO_MORE_FILES)165 break;166 167 if ( rc != VINF_SUCCESS168 && rc != VWRN_NO_DIRENT_INFO)169 {170 AssertFailed();171 if ( rc == VERR_NO_TRANSLATION172 || rc == VERR_INVALID_UTF8_ENCODING)173 continue;174 break;175 }176 177 Log2(("vbsfCorrectCasing: found %s\n", &pDirEntry->szName[0]));178 if ( pDirEntry->cbName == cchComponent179 && !RTStrICmp(pszStartComponent, &pDirEntry->szName[0]))180 {181 Log(("Found original name %s (%s)\n", &pDirEntry->szName[0], pszStartComponent));182 strcpy(pszStartComponent, &pDirEntry->szName[0]);183 rc = VINF_SUCCESS;184 break;185 }186 }187 188 RTDirClose(hSearch);189 }190 }191 192 if (RT_FAILURE(rc))193 Log(("vbsfCorrectCasing %s failed with %Rrc\n", pszStartComponent, rc));194 195 RTMemFree(pDirEntry);196 197 return rc;198 }199 200 /* Temporary stand-in for RTPathExistEx. */201 static int vbsfQueryExistsEx(const char *pszPath, uint32_t fFlags)202 {203 #if 0 /** @todo Fix the symlink issue on windows! */204 return RTPathExistsEx(pszPath, fFlags);205 #else206 RTFSOBJINFO IgnInfo;207 return RTPathQueryInfoEx(pszPath, &IgnInfo, RTFSOBJATTRADD_NOTHING, fFlags);208 #endif209 }210 211 /**212 * Helper for vbsfBuildFullPath that performs case corrections on the path213 * that's being build.214 *215 * @returns VINF_SUCCESS at the moment.216 * @param pClient The client data.217 * @param pszFullPath Pointer to the full path. This is the path218 * which may need case corrections. The219 * corrections will be applied in place.220 * @param cchFullPath The length of the full path.221 * @param fWildCard Whether the last component may contain222 * wildcards and thus might require exclusion223 * from the case correction.224 * @param fPreserveLastComponent Always exclude the last component from case225 * correction if set.226 */227 static int vbsfCorrectPathCasing(SHFLCLIENTDATA *pClient, char *pszFullPath, size_t cchFullPath,228 bool fWildCard, bool fPreserveLastComponent)229 {230 /*231 * Hide the last path component if it needs preserving. This is required232 * in the following cases:233 * - Contains the wildcard(s).234 * - Is a 'rename' target.235 */236 char *pszLastComponent = NULL;237 if (fWildCard || fPreserveLastComponent)238 {239 char *pszSrc = pszFullPath + cchFullPath - 1;240 Assert(strchr(pszFullPath, '\0') == pszSrc + 1);241 while ((uintptr_t)pszSrc > (uintptr_t)pszFullPath)242 {243 if (*pszSrc == RTPATH_DELIMITER)244 break;245 pszSrc--;246 }247 if (*pszSrc == RTPATH_DELIMITER)248 {249 if ( fPreserveLastComponent250 /* Or does it really have wildcards? */251 || strchr(pszSrc + 1, '*') != NULL252 || strchr(pszSrc + 1, '?') != NULL253 || strchr(pszSrc + 1, '>') != NULL254 || strchr(pszSrc + 1, '<') != NULL255 || strchr(pszSrc + 1, '"') != NULL )256 {257 pszLastComponent = pszSrc;258 *pszLastComponent = '\0';259 }260 }261 }262 263 /*264 * If the path/file doesn't exist, we need to attempt case correcting it.265 */266 /** @todo Don't check when creating files or directories; waste of time. */267 int rc = vbsfQueryExistsEx(pszFullPath, SHFL_RT_LINK(pClient));268 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)269 {270 Log(("Handle case insensitive guest fs on top of host case sensitive fs for %s\n", pszFullPath));271 272 /*273 * Work from the end of the path to find a partial path that's valid.274 */275 char *pszSrc = pszLastComponent ? pszLastComponent - 1 : pszFullPath + cchFullPath - 1;276 Assert(strchr(pszFullPath, '\0') == pszSrc + 1);277 278 while ((uintptr_t)pszSrc > (uintptr_t)pszFullPath)279 {280 if (*pszSrc == RTPATH_DELIMITER)281 {282 *pszSrc = '\0';283 rc = vbsfQueryExistsEx(pszFullPath, SHFL_RT_LINK(pClient));284 *pszSrc = RTPATH_DELIMITER;285 if (RT_SUCCESS(rc))286 {287 #ifdef DEBUG288 *pszSrc = '\0';289 Log(("Found valid partial path %s\n", pszFullPath));290 *pszSrc = RTPATH_DELIMITER;291 #endif292 break;293 }294 }295 296 pszSrc--;297 }298 Assert(*pszSrc == RTPATH_DELIMITER && RT_SUCCESS(rc));299 if ( *pszSrc == RTPATH_DELIMITER300 && RT_SUCCESS(rc))301 {302 /*303 * Turn around and work the other way case correcting the components.304 */305 pszSrc++;306 for (;;)307 {308 bool fEndOfString = true;309 310 /* Find the end of the component. */311 char *pszEnd = pszSrc;312 while (*pszEnd)313 {314 if (*pszEnd == RTPATH_DELIMITER)315 break;316 pszEnd++;317 }318 319 if (*pszEnd == RTPATH_DELIMITER)320 {321 fEndOfString = false;322 *pszEnd = '\0';323 #if 0 /** @todo Please, double check this. The original code is in the #if 0, what I hold as correct is in the #else. */324 rc = RTPathQueryInfoEx(pszSrc, &info, RTFSOBJATTRADD_NOTHING, SHFL_RT_LINK(pClient));325 #else326 rc = vbsfQueryExistsEx(pszFullPath, SHFL_RT_LINK(pClient));327 #endif328 Assert(rc == VINF_SUCCESS || rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND);329 }330 else if (pszEnd == pszSrc)331 rc = VINF_SUCCESS; /* trailing delimiter */332 else333 rc = VERR_FILE_NOT_FOUND;334 335 if (rc == VERR_FILE_NOT_FOUND || rc == VERR_PATH_NOT_FOUND)336 {337 /* Path component is invalid; try to correct the casing. */338 rc = vbsfCorrectCasing(pClient, pszFullPath, pszSrc);339 if (RT_FAILURE(rc))340 {341 /* Failed, so don't bother trying any further components. */342 if (!fEndOfString)343 *pszEnd = RTPATH_DELIMITER; /* Restore the original full path. */344 break;345 }346 }347 348 /* Next (if any). */349 if (fEndOfString)350 break;351 352 *pszEnd = RTPATH_DELIMITER;353 pszSrc = pszEnd + 1;354 }355 if (RT_FAILURE(rc))356 Log(("Unable to find suitable component rc=%d\n", rc));357 }358 else359 rc = VERR_FILE_NOT_FOUND;360 361 }362 363 /* Restore the final component if it was dropped. */364 if (pszLastComponent)365 *pszLastComponent = RTPATH_DELIMITER;366 367 /* might be a new file so don't fail here! */368 return VINF_SUCCESS;369 }370 371 372 /** @def VBSF_IS_PATH_SLASH373 * Checks if @a a_ch is a path delimiter (slash, not volume spearator) for the374 * guest or the host.375 * @param a_pClient Pointer to the client data (SHFLCLIENTDATA).376 * @param a_ch The character to inspect.377 */378 #if 1379 # define VBSF_IS_PATH_SLASH(a_pClient, a_ch) ( (a_ch) == '\\' || (a_ch) == '/' || RTPATH_IS_SLASH(a_ch) )380 #else381 # define VBSF_IS_PATH_SLASH(a_pClient, a_ch) ( (RTUTF16)(a_ch) == (a_pClient)->PathDelimiter || RTPATH_IS_SLASH(a_ch) )382 #endif383 384 385 /**386 * Check the given UTF-8 path for root escapes.387 *388 * Verify that the path is within the root directory of the mapping. Count '..'389 * and other path components and check that we do not go over the root.390 *391 * @returns VBox status code.392 * @retval VINF_SUCCESS393 * @retval VERR_INVALID_NAME394 *395 * @param pszPath The (UTF-8) path to check. Slashes has been convert396 * to host slashes by this time.397 *398 * @remarks This function assumes that the path will be appended to the root399 * directory of the shared folder mapping. Keep that in mind when400 * checking absolute paths!401 */402 static int vbsfPathCheck(const char *pszPath)403 {404 /*405 * Walk the path, component by component and check for escapes.406 */407 408 int cComponents = 0; /* How many normal path components. */409 int cParentDirs = 0; /* How many '..' components. */410 411 for (;;)412 {413 char ch;414 415 /* Skip leading path delimiters. */416 do417 ch = *pszPath++;418 while (RTPATH_IS_SLASH(ch));419 if (ch == '\0')420 return VINF_SUCCESS;421 422 /* Check if that is a dot component. */423 int cDots = 0;424 while (ch == '.')425 {426 cDots++;427 ch = *pszPath++;428 }429 430 if ( cDots >= 1431 && (ch == '\0' || RTPATH_IS_SLASH(ch)) )432 {433 if (cDots >= 2) /* Consider all multidots sequences as a 'parent dir'. */434 {435 cParentDirs++;436 437 /* Escaping? */438 if (cParentDirs > cComponents)439 return VERR_INVALID_NAME;440 }441 /* else: Single dot, nothing changes. */442 }443 else444 {445 /* Not a dot component, skip to the end of it. */446 while (ch != '\0' && !RTPATH_IS_SLASH(ch))447 ch = *pszPath++;448 cComponents++;449 }450 Assert(cComponents >= cParentDirs);451 452 /* The end? */453 Assert(ch == '\0' || RTPATH_IS_SLASH(ch));454 if (ch == '\0')455 return VINF_SUCCESS;456 }457 }458 459 111 static int vbsfBuildFullPath(SHFLCLIENTDATA *pClient, SHFLROOT root, PSHFLSTRING pPath, 460 112 uint32_t cbPath, char **ppszFullPath, uint32_t *pcbFullPathRoot, 461 113 bool fWildCard = false, bool fPreserveLastComponent = false) 462 114 { 463 /* Resolve the root prefix into a string. */ 464 const char *pszRoot = vbsfMappingsQueryHostRoot(root); 465 if ( !pszRoot 466 || !*pszRoot) 467 { 468 Log(("vbsfBuildFullPath: invalid root!\n")); 469 return VERR_INVALID_PARAMETER; 470 } 471 uint32_t cchRoot = (uint32_t)strlen(pszRoot); 472 #if RTPATH_STYLE == RTPATH_STR_F_STYLE_DOS 473 Assert(!strchr(pszRoot, '/')); 474 #endif 475 476 /* 477 * Combine the root prefix with the guest path into a full UTF-8 path in a 478 * buffer pointed to by pszFullPath. cchRoot may be adjusted in the process. 479 */ 480 int rc; 481 size_t cchFullPath; 482 char *pszFullPath = NULL; 115 char *pszHostPath = NULL; 116 uint32_t fu32PathFlags = 0; 117 int rc = vbsfPathGuestToHost(pClient, root, pPath, cbPath, 118 &pszHostPath, pcbFullPathRoot, fWildCard, fPreserveLastComponent, &fu32PathFlags); 483 119 if (BIT_FLAG(pClient->fu32Flags, SHFL_CF_UTF8)) 484 120 { 485 /* Strip leading slashes from the path the guest specified. */ 486 uint32_t cchSrc = pPath->u16Length; 487 const char *pszSrc = (char *)&pPath->String.utf8[0]; 488 Log(("Root %s path %.*s\n", pszRoot, cchSrc, pszSrc)); 489 490 while ( cchSrc > 0 491 && VBSF_IS_PATH_SLASH(pClient, *pszSrc)) 492 { 493 pszSrc++; 494 cchSrc--; 495 } 496 497 /* Allocate a buffer that will be able to contain the root prefix and 498 the path specified by the guest. */ 499 cchFullPath = cchRoot + cchSrc; 500 pszFullPath = (char *)RTMemAlloc(cchFullPath + 1 + 1); 501 if (RT_LIKELY(pszFullPath != NULL)) 502 { 503 memcpy(pszFullPath, pszRoot, cchRoot); 504 if (!RTPATH_IS_SLASH(pszRoot[-1])) 505 { 506 pszFullPath[cchRoot++] = RTPATH_DELIMITER; 507 cchFullPath++; 508 } 509 510 if (cchSrc) 511 memcpy(&pszFullPath[cchRoot], pszSrc, cchSrc); 512 513 /* Terminate the string. */ 514 pszFullPath[cchRoot + cchSrc] = '\0'; 515 rc = VINF_SUCCESS; 516 } 517 else 518 { 519 Log(("RTMemAlloc %x failed!!\n", cchFullPath + 1)); 520 rc = VERR_NO_MEMORY; 521 } 522 } 523 else /* Client speaks UTF-16. */ 524 { 525 #ifdef RT_OS_DARWIN /* Misplaced hack! See todo! */ 526 /** @todo This belongs in rtPathToNative or in the windows shared folder file system driver... 527 * The question is simply whether the NFD normalization is actually applied on a (virtual) file 528 * system level in darwin, or just by the user mode application libs. */ 529 SHFLSTRING *pPathParameter = pPath; 530 size_t cbPathLength; 531 CFMutableStringRef inStr = ::CFStringCreateMutable(NULL, 0); 532 uint16_t ucs2Length; 533 CFRange rangeCharacters; 534 535 // Is 8 times length enough for decomposed in worst case...? 536 cbPathLength = sizeof(SHFLSTRING) + pPathParameter->u16Length * 8 + 2; 537 pPath = (SHFLSTRING *)RTMemAllocZ(cbPathLength); 538 if (!pPath) 539 { 540 rc = VERR_NO_MEMORY; 541 Log(("RTMemAllocZ %x failed!!\n", cbPathLength)); 542 return rc; 543 } 544 545 ::CFStringAppendCharacters(inStr, (UniChar*)pPathParameter->String.ucs2, 546 pPathParameter->u16Length / sizeof(pPathParameter->String.ucs2[0])); 547 ::CFStringNormalize(inStr, kCFStringNormalizationFormD); 548 ucs2Length = ::CFStringGetLength(inStr); 549 550 rangeCharacters.location = 0; 551 rangeCharacters.length = ucs2Length; 552 ::CFStringGetCharacters(inStr, rangeCharacters, pPath->String.ucs2); 553 pPath->String.ucs2[ucs2Length] = 0x0000; // NULL terminated 554 pPath->u16Length = ucs2Length * sizeof(pPath->String.ucs2[0]); 555 pPath->u16Size = pPath->u16Length + sizeof(pPath->String.ucs2[0]); 556 557 CFRelease(inStr); 558 #endif 559 560 /* Strip leading slashes and calculate the UTF-8 length. */ 561 size_t cwcSrc = pPath->u16Length / sizeof(RTUTF16); 562 PRTUTF16 pwszSrc = &pPath->String.ucs2[0]; 563 Log(("Root %s path %.*ls\n", pszRoot, cwcSrc, pwszSrc)); 564 565 while ( cwcSrc > 0 566 && *pwszSrc < 0x80 567 && VBSF_IS_PATH_SLASH(pClient, (char)*pwszSrc)) 568 { 569 pwszSrc++; 570 cwcSrc--; 571 } 572 573 size_t cchPathAsUtf8 = RTUtf16CalcUtf8Len(pwszSrc); 574 #ifdef RT_OS_DARWIN 575 AssertReturnStmt(cchPathAsUtf8 >= cwcSrc, RTMemFree(pPath), VERR_INTERNAL_ERROR_3); 576 #else 577 AssertReturn(cchPathAsUtf8 >= cwcSrc, VERR_INTERNAL_ERROR_3); 578 #endif 579 580 /* Allocate buffer that will be able to contain the root prefix and 581 * the pPath converted to UTF-8. */ 582 cchFullPath = cchRoot + cchPathAsUtf8; 583 pszFullPath = (char *)RTMemAlloc(cchFullPath + 1 + 1); 584 if (RT_LIKELY(pszFullPath != NULL)) 585 { 586 /* Copy the root prefix into the result buffer and make sure it 587 ends with a path separator. */ 588 memcpy(pszFullPath, pszRoot, cchRoot); 589 if (!RTPATH_IS_SLASH(pszFullPath[cchRoot - 1])) 590 { 591 pszFullPath[cchRoot++] = RTPATH_DELIMITER; 592 cchFullPath++; 593 } 594 595 /* Append the path specified by the guest (if any). */ 596 if (cchPathAsUtf8) 597 { 598 size_t cchActual; 599 char *pszDst = &pszFullPath[cchRoot]; 600 rc = RTUtf16ToUtf8Ex(pwszSrc, cwcSrc, &pszDst, cchFullPath - cchRoot + 1, &cchActual); 601 AssertRC(rc); 602 AssertStmt(RT_FAILURE(rc) || cchActual == cchPathAsUtf8, rc = VERR_INTERNAL_ERROR_4); 603 Assert(strlen(pszDst) == cchPathAsUtf8); 604 } 605 else 606 rc = VINF_SUCCESS; 607 608 /* Terminate the string. */ 609 pszFullPath[cchRoot + cchPathAsUtf8] = '\0'; 610 } 611 else 612 { 613 Log(("RTMemAlloc %x failed!!\n", cchFullPath + 1)); 614 rc = VERR_NO_MEMORY; 615 } 616 617 #ifdef RT_OS_DARWIN 618 RTMemFree(pPath); 619 pPath = pPathParameter; 620 #endif 621 } 121 LogRel2(("SharedFolders: GuestToHost 0x%RX32 [%.*s]->[%s] %Rrc\n", fu32PathFlags, pPath->u16Length, &pPath->String.utf8[0], pszHostPath, rc)); 122 } 123 else 124 { 125 LogRel2(("SharedFolders: GuestToHost 0x%RX32 [%.*ls]->[%s] %Rrc\n", fu32PathFlags, pPath->u16Length / 2, &pPath->String.ucs2[0], pszHostPath, rc)); 126 } 127 622 128 if (RT_SUCCESS(rc)) 623 129 { 624 Assert(strlen(pszFullPath) == cchFullPath); 625 Assert(RTPATH_IS_SLASH(pszFullPath[cchRoot - 1])); /* includes delimiter. */ 626 627 if (pcbFullPathRoot) 628 *pcbFullPathRoot = cchRoot - 1; /* Must index the path delimiter. */ 629 630 /* 631 * Convert guest path delimiters into host ones and check for attempts 632 * to escape the shared folder root directory. 633 * 634 * After this, there will only be RTPATH_DELIMITER slashes in the path! 635 * 636 * ASSUMES that the root path only has RTPATH_DELIMITER as well. 637 */ 638 char ch; 639 char *pszTmp = &pszFullPath[cchRoot]; 640 while ((ch = *pszTmp) != '\0') 641 { 642 if (VBSF_IS_PATH_SLASH(pClient, ch)) 643 *pszTmp = RTPATH_DELIMITER; 644 pszTmp++; 645 } 646 LogFlow(("Corrected string %s\n", pszFullPath)); 647 648 rc = vbsfPathCheck(&pszFullPath[cchRoot]); 649 if (RT_SUCCESS(rc)) 650 { 651 /* 652 * When the host file system is case sensitive and the guest expects 653 * a case insensitive fs, then problems can occur. 654 */ 655 if ( vbsfIsHostMappingCaseSensitive(root) 656 && !vbsfIsGuestMappingCaseSensitive(root)) 657 rc = vbsfCorrectPathCasing(pClient, pszFullPath, cchFullPath, fWildCard, fPreserveLastComponent); 658 if (RT_SUCCESS(rc)) 659 { 660 /* 661 * We're good. 662 */ 663 *ppszFullPath = pszFullPath; 664 LogFlow(("vbsfBuildFullPath: %s rc=%Rrc\n", pszFullPath, rc)); 665 return rc; 666 } 667 668 /* Failed, clean up. */ 669 Log(("vbsfBuildFullPath: %s rc=%Rrc\n", pszFullPath, rc)); 670 } 671 else 672 Log(("vbsfBuildPath: Caught escape attempt: (%.*s) '%s'\n", cchRoot, pszFullPath, &pszFullPath[cchRoot])); 673 } 674 675 if (pszFullPath) 676 RTMemFree(pszFullPath); 677 *ppszFullPath = NULL; 130 if (ppszFullPath) 131 *ppszFullPath = pszHostPath; 132 } 678 133 return rc; 679 134 } … … 681 136 static void vbsfFreeFullPath(char *pszFullPath) 682 137 { 683 RTMemFree(pszFullPath);138 vbsfFreeHostPath(pszFullPath); 684 139 } 685 140 … … 1653 1108 Assert(pHandle->dir.pLastValidEntry == 0); 1654 1109 1655 rc = vbsfBuildFullPath(pClient, root, pPath, pPath->u16Size , &pszFullPath, NULL, true);1110 rc = vbsfBuildFullPath(pClient, root, pPath, pPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullPath, NULL, true); 1656 1111 1657 1112 if (RT_SUCCESS(rc)) … … 2057 1512 ShflStringInitBuffer(&dummy, sizeof(dummy)); 2058 1513 dummy.String.ucs2[0] = '\0'; 2059 rc = vbsfBuildFullPath(pClient, root, &dummy, 0, &pszFullPath, NULL);1514 rc = vbsfBuildFullPath(pClient, root, &dummy, sizeof(dummy), &pszFullPath, NULL); 2060 1515 2061 1516 if (RT_SUCCESS(rc)) … … 2335 1790 char *pszFullPathDest = NULL; 2336 1791 2337 rc = vbsfBuildFullPath(pClient, root, pSrc, pSrc->u16Size , &pszFullPathSrc, NULL);1792 rc = vbsfBuildFullPath(pClient, root, pSrc, pSrc->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullPathSrc, NULL); 2338 1793 if (rc != VINF_SUCCESS) 2339 1794 return rc; 2340 1795 2341 rc = vbsfBuildFullPath(pClient, root, pDest, pDest->u16Size , &pszFullPathDest, NULL, false, true);1796 rc = vbsfBuildFullPath(pClient, root, pDest, pDest->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullPathDest, NULL, false, true); 2342 1797 if (RT_SUCCESS (rc)) 2343 1798 { … … 2403 1858 return VERR_WRITE_PROTECT; /* XXX or VERR_TOO_MANY_SYMLINKS? */ 2404 1859 2405 rc = vbsfBuildFullPath(pClient, root, pNewPath, pNewPath->u16Size , &pszFullNewPath, NULL);1860 rc = vbsfBuildFullPath(pClient, root, pNewPath, pNewPath->u16Size + SHFLSTRING_HEADER_SIZE, &pszFullNewPath, NULL); 2406 1861 AssertRCReturn(rc, rc); 2407 1862
Note:
See TracChangeset
for help on using the changeset viewer.