Changeset 23291 in vbox
- Timestamp:
- Sep 24, 2009 4:08:19 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 52784
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/err.h
r22722 r23291 710 710 /** Too many symbolic links. */ 711 711 #define VERR_TOO_MANY_SYMLINKS (-156) 712 /** The OS does not support setting the time stamps on a symbolic link. */ 713 #define VERR_NS_SYMLINK_SET_TIME (-157) 712 714 /** @} */ 713 715 -
trunk/include/iprt/path.h
r22109 r23291 118 118 119 119 120 /** @name Generic RTPath flags 121 * @{ */ 122 /** Last component: Work on the link. */ 123 #define RTPATH_F_ON_LINK RT_BIT_32(0) 124 /** Last component: Follow if link. */ 125 #define RTPATH_F_FOLLOW_LINK RT_BIT_32(1) 126 /** @} */ 127 128 129 /** Validates a flags parameter containing RTPATH_F_*. 130 * @remarks The parameters will be referneced multiple times. */ 131 #define RTPATH_F_IS_VALID(fFlags, fIgnore) \ 132 ( ((fFlags) & ~(uint32_t)(fIgnore)) == RTPATH_F_ON_LINK \ 133 || ((fFlags) & ~(uint32_t)(fIgnore)) == RTPATH_F_FOLLOW_LINK ) 134 135 120 136 /** 121 137 * Checks if the path exists. 122 138 * 123 * Symbolic links will all be attempted resolved .139 * Symbolic links will all be attempted resolved and broken links means false. 124 140 * 125 141 * @returns true if it exists and false if it doesn't. … … 127 143 */ 128 144 RTDECL(bool) RTPathExists(const char *pszPath); 145 146 /** 147 * Checks if the path exists. 148 * 149 * @returns true if it exists and false if it doesn't. 150 * @param pszPath The path to check. 151 * @param fFlags RTPATH_F_ON_LINK or RPATH_F_FOLLOW_LINK. 152 */ 153 RTDECL(bool) RTPathExistsEx(const char *pszPath, uint32_t fFlags); 129 154 130 155 /** … … 500 525 * Query information about a file system object. 501 526 * 502 * This API will not resolve symbolic links in the last component (just 503 * like unix lstat()). 504 * 505 * @returns VINF_SUCCESS if the object exists, information returned. 506 * @returns VERR_PATH_NOT_FOUND if any but the last component in the specified 527 * This API will resolve NOT symbolic links in the last component (just like 528 * unix lstat()). 529 * 530 * @returns IPRT status code. 531 * @retval VINF_SUCCESS if the object exists, information returned. 532 * @retval VERR_PATH_NOT_FOUND if any but the last component in the specified 507 533 * path was not found or was not a directory. 508 * @ret urnsVERR_FILE_NOT_FOUND if the object does not exist (but path to the534 * @retval VERR_FILE_NOT_FOUND if the object does not exist (but path to the 509 535 * parent directory exists). 510 * @returns some other iprt status code.511 536 * 512 537 * @param pszPath Path to the file system object. … … 519 544 520 545 /** 546 * Query information about a file system object. 547 * 548 * @returns IPRT status code. 549 * @retval VINF_SUCCESS if the object exists, information returned. 550 * @retval VERR_PATH_NOT_FOUND if any but the last component in the specified 551 * path was not found or was not a directory. 552 * @retval VERR_FILE_NOT_FOUND if the object does not exist (but path to the 553 * parent directory exists). 554 * 555 * @param pszPath Path to the file system object. 556 * @param pObjInfo Object information structure to be filled on successful return. 557 * @param enmAdditionalAttribs 558 * Which set of additional attributes to request. 559 * Use RTFSOBJATTRADD_NOTHING if this doesn't matter. 560 * @param fFlags RTPATH_F_ON_LINK or RPATH_F_FOLLOW_LINK. 561 */ 562 RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags); 563 564 /** 521 565 * Changes the mode flags of a file system object. 522 566 * … … 573 617 574 618 /** 619 * Changes one or more of the timestamps associated of file system object. 620 * 621 * @returns iprt status code. 622 * @param pszPath Path to the file system object. 623 * @param pAccessTime Pointer to the new access time. 624 * @param pModificationTime Pointer to the new modification time. 625 * @param pChangeTime Pointer to the new change time. NULL if not to be changed. 626 * @param pBirthTime Pointer to the new time of birth. NULL if not to be changed. 627 * @param fFlags RTPATH_F_ON_LINK or RPATH_F_FOLLOW_LINK. 628 * 629 * @remark The file system might not implement all these time attributes, 630 * the API will ignore the ones which aren't supported. 631 * 632 * @remark The file system might not implement the time resolution 633 * employed by this interface, the time will be chopped to fit. 634 * 635 * @remark The file system may update the change time even if it's 636 * not specified. 637 * 638 * @remark POSIX can only set Access & Modification and will always set both. 639 */ 640 RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 641 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags); 642 643 /** 575 644 * Gets one or more of the timestamps associated of file system object. 576 645 * … … 582 651 * @param pBirthTime Where to store the creation time. NULL is ok. 583 652 * 584 * @remark This is wrapper around RTPathQueryInfo() and exists to complement RTPathSetTimes(). 653 * @remark This is wrapper around RTPathQueryInfo() and exists to complement 654 * RTPathSetTimes(). If the last component is a symbolic link, it will 655 * not be resolved. 585 656 */ 586 657 RTR3DECL(int) RTPathGetTimes(const char *pszPath, PRTTIMESPEC pAccessTime, PRTTIMESPEC pModificationTime, … … 601 672 602 673 /** 674 * Changes the owner and/or group of a file system object. 675 * 676 * @returns iprt status code. 677 * @param pszPath Path to the file system object. 678 * @param uid The new file owner user id. Use -1 (or ~0) to leave this unchanged. 679 * @param gid The new group id. Use -1 (or ~0) to leave this unchanged. 680 * @param fFlags RTPATH_F_ON_LINK or RPATH_F_FOLLOW_LINK. 681 */ 682 RTR3DECL(int) RTPathSetOwnerEx(const char *pszPath, uint32_t uid, uint32_t gid, uint32_t fFlags); 683 684 /** 603 685 * Gets the owner and/or group of a file system object. 604 686 * … … 608 690 * @param pGid Where to store the group id. NULL is ok. 609 691 * 610 * @remark This is wrapper around RTPathQueryInfo() and exists to complement RTPathGetOwner(). 692 * @remark This is wrapper around RTPathQueryInfo() and exists to complement 693 * RTPathGetOwner(). If the last component is a symbolic link, it will 694 * not be resolved. 611 695 */ 612 696 RTR3DECL(int) RTPathGetOwner(const char *pszPath, uint32_t *pUid, uint32_t *pGid); … … 622 706 * Renames a path within a filesystem. 623 707 * 708 * This will rename symbolic links. If RTPATHRENAME_FLAGS_REPLACE is used and 709 * pszDst is a symbolic link, it will be replaced and not its target. 710 * 624 711 * @returns IPRT status code. 625 712 * @param pszSrc The source path. -
trunk/src/VBox/Runtime/r3/posix/path-posix.cpp
r20819 r23291 463 463 RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs) 464 464 { 465 return RTPathQueryInfoEx(pszPath, pObjInfo, enmAdditionalAttribs, RTPATH_F_ON_LINK); 466 } 467 468 469 RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags) 470 { 465 471 /* 466 472 * Validate input. 467 473 */ 468 Assert MsgReturn(VALID_PTR(pszPath), ("%p\n", pszPath), VERR_INVALID_POINTER);474 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 469 475 AssertReturn(*pszPath, VERR_INVALID_PARAMETER); 470 Assert MsgReturn(VALID_PTR(pObjInfo), ("%p\n", pszPath), VERR_INVALID_POINTER);476 AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER); 471 477 AssertMsgReturn( enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING 472 478 && enmAdditionalAttribs <= RTFSOBJATTRADD_LAST, 473 479 ("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs), 474 480 VERR_INVALID_PARAMETER); 481 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 475 482 476 483 /* … … 482 489 { 483 490 struct stat Stat; 484 if (!stat(pszNativePath, &Stat)) 491 if (fFlags & RTPATH_F_FOLLOW_LINK) 492 rc = stat(pszNativePath, &Stat); 493 else 494 rc = lstat(pszNativePath, &Stat); /** @todo how doesn't have lstat again? */ 495 if (!rc) 485 496 { 486 497 rtFsConvertStatToObjInfo(pObjInfo, &Stat, pszPath, 0); … … 517 528 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 518 529 { 530 return RTPathSetTimesEx(pszPath, pAccessTime, pModificationTime, pChangeTime, pBirthTime, RTPATH_F_ON_LINK); 531 } 532 533 534 RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 535 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags) 536 { 519 537 /* 520 538 * Validate input. 521 539 */ 522 AssertMsgReturn(VALID_PTR(pszPath), ("%p\n", pszPath), VERR_INVALID_POINTER); 523 AssertMsgReturn(*pszPath, ("%p\n", pszPath), VERR_INVALID_PARAMETER); 524 AssertMsgReturn(!pAccessTime || VALID_PTR(pAccessTime), ("%p\n", pAccessTime), VERR_INVALID_POINTER); 525 AssertMsgReturn(!pModificationTime || VALID_PTR(pModificationTime), ("%p\n", pModificationTime), VERR_INVALID_POINTER); 526 AssertMsgReturn(!pChangeTime || VALID_PTR(pChangeTime), ("%p\n", pChangeTime), VERR_INVALID_POINTER); 527 AssertMsgReturn(!pBirthTime || VALID_PTR(pBirthTime), ("%p\n", pBirthTime), VERR_INVALID_POINTER); 540 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 541 AssertReturn(*pszPath, VERR_INVALID_PARAMETER); 542 AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER); 543 AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER); 544 AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER); 545 AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER); 546 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 528 547 529 548 /* … … 534 553 if (RT_SUCCESS(rc)) 535 554 { 555 RTFSOBJINFO ObjInfo; 556 536 557 /* 537 558 * If it's a no-op, we'll only verify the existance of the file. 538 559 */ 539 560 if (!pAccessTime && !pModificationTime) 540 { 541 struct stat Stat; 542 if (!stat(pszNativePath, &Stat)) 543 rc = VINF_SUCCESS; 544 else 545 { 546 rc = RTErrConvertFromErrno(errno); 547 Log(("RTPathSetTimes('%s',,,,): failed with %Rrc and errno=%d\n", pszPath, rc, errno)); 548 } 549 } 561 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_NOTHING, fFlags); 550 562 else 551 563 { … … 562 574 else 563 575 { 564 RTFSOBJINFO ObjInfo; 565 int rc = RTPathQueryInfo(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX); 576 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags); 566 577 if (RT_SUCCESS(rc)) 567 578 { … … 575 586 if (RT_SUCCESS(rc)) 576 587 { 577 if ( utimes(pszNativePath, aTimevals))588 if (fFlags & RTPATH_F_FOLLOW_LINK) 578 589 { 579 rc = RTErrConvertFromErrno(errno); 590 if (utimes(pszNativePath, aTimevals)) 591 rc = RTErrConvertFromErrno(errno); 592 } 593 #if defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD) || defined(RT_OS_LINUX) || defined(RT_OS_OS2) /** @todo who really has lutimes? */ 594 else 595 { 596 if (lutimes(pszNativePath, aTimevals)) 597 rc = RTErrConvertFromErrno(errno); 598 } 599 #else 600 else 601 { 602 if (pAccessTime && pModificationTime) 603 rc = RTPathQueryInfoEx(pszPath, &ObjInfo, RTFSOBJATTRADD_UNIX, fFlags); 604 if (RT_SUCCESS(rc) && RTFS_IS_SYMLINK(ObjInfo.Attr.fMode)) 605 rc = VERR_NS_SYMLINK_SET_TIME; 606 else if (RT_SUCCESS(rc)) 607 { 608 if (utimes(pszNativePath, aTimevals)) 609 rc = RTErrConvertFromErrno(errno); 610 } 611 } 612 #endif 613 if (RT_FAILURE(rc)) 580 614 Log(("RTPathSetTimes('%s',%p,%p,,): failed with %Rrc and errno=%d\n", 581 615 pszPath, pAccessTime, pModificationTime, rc, errno)); 582 }583 616 } 584 617 } … … 788 821 RTDECL(bool) RTPathExists(const char *pszPath) 789 822 { 823 return RTPathExistsEx(pszPath, RTPATH_F_FOLLOW_LINK); 824 } 825 826 827 RTDECL(bool) RTPathExistsEx(const char *pszPath, uint32_t fFlags) 828 { 790 829 /* 791 830 * Validate input. … … 793 832 AssertPtrReturn(pszPath, false); 794 833 AssertReturn(*pszPath, false); 834 Assert(RTPATH_F_IS_VALID(fFlags, 0)); 795 835 796 836 /* … … 802 842 { 803 843 struct stat Stat; 804 if (!stat(pszNativePath, &Stat)) 844 if (fFlags & RTPATH_F_FOLLOW_LINK) 845 rc = stat(pszNativePath, &Stat); 846 else 847 rc = lstat(pszNativePath, &Stat); 848 if (!rc) 805 849 rc = VINF_SUCCESS; 806 850 else -
trunk/src/VBox/Runtime/r3/win/path-win.cpp
r21619 r23291 188 188 RTR3DECL(int) RTPathQueryInfo(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs) 189 189 { 190 return RTPathQueryInfoEx(pszPath, pObjInfo, enmAdditionalAttribs, RTPATH_F_ON_LINK); 191 } 192 193 194 RTR3DECL(int) RTPathQueryInfoEx(const char *pszPath, PRTFSOBJINFO pObjInfo, RTFSOBJATTRADD enmAdditionalAttribs, uint32_t fFlags) 195 { 190 196 /* 191 197 * Validate input. 192 198 */ 193 if (!pszPath) 194 { 195 AssertMsgFailed(("Invalid pszPath=%p\n", pszPath)); 196 return VERR_INVALID_PARAMETER; 197 } 198 if (!pObjInfo) 199 { 200 AssertMsgFailed(("Invalid pObjInfo=%p\n", pObjInfo)); 201 return VERR_INVALID_PARAMETER; 202 } 203 if ( enmAdditionalAttribs < RTFSOBJATTRADD_NOTHING 204 || enmAdditionalAttribs > RTFSOBJATTRADD_LAST) 205 { 206 AssertMsgFailed(("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs)); 207 return VERR_INVALID_PARAMETER; 208 } 199 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 200 AssertReturn(*pszPath, VERR_INVALID_PARAMETER); 201 AssertPtrReturn(pObjInfo, VERR_INVALID_POINTER); 202 AssertMsgReturn( enmAdditionalAttribs >= RTFSOBJATTRADD_NOTHING 203 && enmAdditionalAttribs <= RTFSOBJATTRADD_LAST, 204 ("Invalid enmAdditionalAttribs=%p\n", enmAdditionalAttribs), 205 VERR_INVALID_PARAMETER); 206 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 209 207 210 208 /* … … 250 248 { 251 249 /* Fallback to FindFileFirst in case of sharing violation. */ 252 if (GetLastError() == ERROR_SHARING_VIOLATION) 253 { 254 WIN32_FIND_DATAA FindData; 255 HANDLE hDir = FindFirstFileA(pszPath, &FindData); 256 if (hDir == INVALID_HANDLE_VALUE) 257 return RTErrConvertFromWin32(GetLastError()); 258 FindClose(hDir); 259 Data.dwFileAttributes = FindData.dwFileAttributes; 260 Data.ftCreationTime = FindData.ftCreationTime; 261 Data.ftLastAccessTime = FindData.ftLastAccessTime; 262 Data.ftLastWriteTime = FindData.ftLastWriteTime; 263 Data.nFileSizeHigh = FindData.nFileSizeHigh; 264 Data.nFileSizeLow = FindData.nFileSizeLow; 265 } 266 else 250 if (GetLastError() != ERROR_SHARING_VIOLATION) 267 251 return RTErrConvertFromWin32(GetLastError()); 252 WIN32_FIND_DATAA FindData; 253 HANDLE hDir = FindFirstFileA(pszPath, &FindData); 254 if (hDir == INVALID_HANDLE_VALUE) 255 return RTErrConvertFromWin32(GetLastError()); 256 FindClose(hDir); 257 Data.dwFileAttributes = FindData.dwFileAttributes; 258 Data.ftCreationTime = FindData.ftCreationTime; 259 Data.ftLastAccessTime = FindData.ftLastAccessTime; 260 Data.ftLastWriteTime = FindData.ftLastWriteTime; 261 Data.nFileSizeHigh = FindData.nFileSizeHigh; 262 Data.nFileSizeLow = FindData.nFileSizeLow; 268 263 } 269 264 #endif 265 if ( (fFlags & RTPATH_F_FOLLOW_LINK) 266 && (Data.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) 267 { 268 AssertFailed(); 269 /** @todo Symlinks: RTPathQueryInfoEx is not handling symbolic links 270 * correctly on Windows. (Both GetFileAttributesEx and FileFindFirst 271 * will return info about the symlink.) */ 272 } 270 273 271 274 /* … … 323 326 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime) 324 327 { 328 return RTPathSetTimesEx(pszPath, pAccessTime, pModificationTime, pChangeTime, pBirthTime, RTPATH_F_ON_LINK); 329 } 330 331 332 RTR3DECL(int) RTPathSetTimesEx(const char *pszPath, PCRTTIMESPEC pAccessTime, PCRTTIMESPEC pModificationTime, 333 PCRTTIMESPEC pChangeTime, PCRTTIMESPEC pBirthTime, uint32_t fFlags) 334 { 325 335 /* 326 336 * Validate input. 327 337 */ 328 AssertMsgReturn(VALID_PTR(pszPath), ("%p\n", pszPath), VERR_INVALID_POINTER); 329 AssertMsgReturn(*pszPath, ("%p\n", pszPath), VERR_INVALID_PARAMETER); 330 AssertMsgReturn(!pAccessTime || VALID_PTR(pAccessTime), ("%p\n", pAccessTime), VERR_INVALID_POINTER); 331 AssertMsgReturn(!pModificationTime || VALID_PTR(pModificationTime), ("%p\n", pModificationTime), VERR_INVALID_POINTER); 332 AssertMsgReturn(!pChangeTime || VALID_PTR(pChangeTime), ("%p\n", pChangeTime), VERR_INVALID_POINTER); 333 AssertMsgReturn(!pBirthTime || VALID_PTR(pBirthTime), ("%p\n", pBirthTime), VERR_INVALID_POINTER); 338 AssertPtrReturn(pszPath, VERR_INVALID_POINTER); 339 AssertReturn(*pszPath, VERR_INVALID_PARAMETER); 340 AssertPtrNullReturn(pAccessTime, VERR_INVALID_POINTER); 341 AssertPtrNullReturn(pModificationTime, VERR_INVALID_POINTER); 342 AssertPtrNullReturn(pChangeTime, VERR_INVALID_POINTER); 343 AssertPtrNullReturn(pBirthTime, VERR_INVALID_POINTER); 344 AssertMsgReturn(RTPATH_F_IS_VALID(fFlags, 0), ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 334 345 335 346 /* … … 340 351 if (RT_SUCCESS(rc)) 341 352 { 342 HANDLE hFile = CreateFileW(pwszPath, 343 FILE_WRITE_ATTRIBUTES, /* dwDesiredAccess */ 344 FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, /* dwShareMode */ 345 NULL, /* security attribs */ 346 OPEN_EXISTING, /* dwCreationDisposition */ 347 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, 348 NULL); 353 HANDLE hFile; 354 if (fOpen & RTPATH_F_FOLLOW_LINK) 355 hFile = CreateFileW(pwszPath, 356 FILE_WRITE_ATTRIBUTES, /* dwDesiredAccess */ 357 FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, /* dwShareMode */ 358 NULL, /* security attribs */ 359 OPEN_EXISTING, /* dwCreationDisposition */ 360 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, 361 NULL); 362 else 363 { 364 /** @todo Symlink: Test RTPathSetTimesEx on Windows. (The code is disabled 365 * because it's not tested yet.) */ 366 #if 0 //def FILE_FLAG_OPEN_REPARSE_POINT 367 hFile = CreateFileW(pwszPath, 368 FILE_WRITE_ATTRIBUTES, /* dwDesiredAccess */ 369 FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, /* dwShareMode */ 370 NULL, /* security attribs */ 371 OPEN_EXISTING, /* dwCreationDisposition */ 372 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OPEN_REPARSE_POINT, 373 NULL); 374 375 if (hFile == INVALID_HANDLE_VALUE && GetLastError() == ERROR_INVALID_PARAMETER) 376 #endif 377 hFile = CreateFileW(pwszPath, 378 FILE_WRITE_ATTRIBUTES, /* dwDesiredAccess */ 379 FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, /* dwShareMode */ 380 NULL, /* security attribs */ 381 OPEN_EXISTING, /* dwCreationDisposition */ 382 FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_NORMAL, 383 NULL); 384 } 349 385 if (hFile != INVALID_HANDLE_VALUE) 350 386 { … … 485 521 486 522 487 /**488 * Checks if the path exists.489 *490 * Symbolic links will all be attempted resolved.491 *492 * @returns true if it exists and false if it doesn't493 * @param pszPath The path to check.494 */495 523 RTDECL(bool) RTPathExists(const char *pszPath) 524 { 525 return RTPathExistsEx(pszPath, RTPATH_F_FOLLOW_LINK); 526 } 527 528 529 RTDECL(bool) RTPathExistsEx(const char *pszPath, uint32_t fFlags) 496 530 { 497 531 /* … … 500 534 AssertPtrReturn(pszPath, false); 501 535 AssertReturn(*pszPath, false); 536 Assert(RTPATH_F_IS_VALID(fFlags, 0)); 502 537 503 538 /* 504 539 * Try query file info. 505 540 */ 541 DWORD dwAttr; 506 542 #ifndef RT_DONT_CONVERT_FILENAMES 507 543 PRTUTF16 pwszPath; … … 509 545 if (RT_SUCCESS(rc)) 510 546 { 511 if (GetFileAttributesW(pwszPath) == INVALID_FILE_ATTRIBUTES) 512 rc = VERR_GENERAL_FAILURE; 547 dwAttr = GetFileAttributesW(pwszPath); 513 548 RTUtf16Free(pwszPath); 514 549 } 550 else 551 dwAttr = INVALID_FILE_ATTRIBUTES; 515 552 #else 516 int rc = VINF_SUCCESS; 517 if (GetFileAttributesExA(pszPath) == INVALID_FILE_ATTRIBUTES) 518 rc = VERR_GENERAL_FAILURE; 553 dwAttr = GetFileAttributesA(pszPath); 519 554 #endif 520 555 521 return RT_SUCCESS(rc); 556 if (dwAttr == INVALID_FILE_ATTRIBUTES) 557 return false; 558 559 #ifdef FILE_ATTRIBUTE_REPARSE_POINT 560 if ( (fFlags & RTPATH_F_FOLLOW_LINK) 561 && (dwAttr & FILE_ATTRIBUTE_REPARSE_POINT)) 562 { 563 AssertFailed(); 564 /** @todo Symlinks: RTPathExists+RTPathExistsEx is misbehaving on symbolic 565 * links on Windows. */ 566 } 567 #endif 568 569 return true; 522 570 } 523 571
Note:
See TracChangeset
for help on using the changeset viewer.