Changeset 2985 for trunk/src/lib/nt/ntstat.c
- Timestamp:
- Nov 1, 2016, 7:26:35 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt/ntstat.c
r2880 r2985 93 93 94 94 95 static int birdIsFileExecutableW(WCHAR const *pwcName, ULONG cwcName) 95 /** 96 * @a pwcName could be the full path. 97 */ 98 static int birdIsFileExecutableW(WCHAR const *pwcName, size_t cwcName) 96 99 { 97 100 char szExt[8]; … … 128 131 129 132 static unsigned short birdFileInfoToMode(HANDLE hFile, ULONG fAttribs, const char *pszName, 130 MY_FILE_NAME_INFORMATION *pNameInfo, __int16 *pfIsDirSymlink)133 const wchar_t *pwszName, size_t cbNameW, __int16 *pfIsDirSymlink) 131 134 { 132 135 unsigned short fMode; … … 169 172 || (pszName 170 173 ? birdIsFileExecutable(pszName) 171 : birdIsFileExecutableW(p NameInfo->FileName, pNameInfo->FileNameLength)) )174 : birdIsFileExecutableW(pwszName, cbNameW)) ) 172 175 fMode |= S_IXOTH | S_IXGRP | S_IXUSR; 173 176 … … 186 189 void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf, const char *pszPath) 187 190 { 188 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,189 NULL, &pStat->st_dirsymlink);191 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, 192 pszPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink); 190 193 pStat->st_padding0[0] = 0; 191 194 pStat->st_padding0[1] = 0; … … 218 221 void birdStatFillFromFileIdBothDirInfo(BirdStat_T *pStat, MY_FILE_ID_BOTH_DIR_INFORMATION const *pBuf, const char *pszPath) 219 222 { 220 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,221 NULL, &pStat->st_dirsymlink);223 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, 224 pszPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink); 222 225 pStat->st_padding0[0] = 0; 223 226 pStat->st_padding0[1] = 0; … … 250 253 void birdStatFillFromFileBothDirInfo(BirdStat_T *pStat, MY_FILE_BOTH_DIR_INFORMATION const *pBuf, const char *pszPath) 251 254 { 252 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath,253 NULL, &pStat->st_dirsymlink);255 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, 256 pszPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink); 254 257 pStat->st_padding0[0] = 0; 255 258 pStat->st_padding0[1] = 0; … … 272 275 273 276 274 int birdStatHandle (HANDLE hFile, BirdStat_T *pStat, const char *pszPath)277 int birdStatHandle2(HANDLE hFile, BirdStat_T *pStat, const char *pszPath, const wchar_t *pwszPath) 275 278 { 276 279 int rc; … … 290 293 { 291 294 pStat->st_mode = birdFileInfoToMode(hFile, pAll->BasicInformation.FileAttributes, pszPath, 292 &pAll->NameInformation, &pStat->st_dirsymlink); 295 pAll->NameInformation.FileNamepAll->NameInformation.FileNameLength, 296 &pStat->st_dirsymlink); 293 297 pStat->st_padding0[0] = 0; 294 298 pStat->st_padding0[1] = 0; … … 352 356 if (MY_NT_SUCCESS(rcNt)) 353 357 rcNt = Ios.u.Status; 354 if (MY_NT_SUCCESS(rcNt) && !pszPath )358 if (MY_NT_SUCCESS(rcNt) && !pszPath && !pwszPath) 355 359 { 356 360 cbNameInfo = 0x10020; … … 364 368 { 365 369 pStat->st_mode = birdFileInfoToMode(hFile, BasicInfo.FileAttributes, pszPath, 366 pNameInfo, &pStat->st_dirsymlink); 370 pNameInfo ? pNameInfo->FileName : pwszPath, 371 pNameInfo ? pNameInfo->FileNameLength 372 : pwszPath ? wcslen(pwszPath) * sizeof(wchar_t) : 0, 373 &pStat->st_dirsymlink); 367 374 pStat->st_padding0[0] = 0; 368 375 pStat->st_padding0[1] = 0; … … 413 420 414 421 422 int birdStatHandle(HANDLE hFile, BirdStat_T *pStat, const char *pszPath) 423 { 424 return birdStatHandle2(hFile, pStat, pszPath, NULL); 425 } 426 427 415 428 /** 416 429 * Generates a device number from the volume information. … … 460 473 461 474 462 static int birdStatInternal( const char *pszPath, BirdStat_T *pStat, int fFollow)475 static int birdStatInternal(HANDLE hRoot, const char *pszPath, BirdStat_T *pStat, int fFollow) 463 476 { 464 477 int rc; 465 HANDLE hFile = birdOpenFile (pszPath,466 FILE_READ_ATTRIBUTES,467 FILE_ATTRIBUTE_NORMAL,468 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,469 FILE_OPEN,470 FILE_OPEN_FOR_BACKUP_INTENT | (fFollow ? 0 : FILE_OPEN_REPARSE_POINT),471 OBJ_CASE_INSENSITIVE);478 HANDLE hFile = birdOpenFileEx(hRoot, pszPath, 479 FILE_READ_ATTRIBUTES, 480 FILE_ATTRIBUTE_NORMAL, 481 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 482 FILE_OPEN, 483 FILE_OPEN_FOR_BACKUP_INTENT | (fFollow ? 0 : FILE_OPEN_REPARSE_POINT), 484 OBJ_CASE_INSENSITIVE); 472 485 if (hFile != INVALID_HANDLE_VALUE) 473 486 { 474 rc = birdStatHandle (hFile, pStat, pszPath);487 rc = birdStatHandle2(hFile, pStat, pszPath, NULL); 475 488 birdCloseFile(hFile); 476 489 … … 500 513 { 501 514 MY_UNICODE_STRING NameUniStr; 502 hFile = birdOpenParentDir( pszPath,515 hFile = birdOpenParentDir(hRoot, pszPath, 503 516 FILE_READ_DATA | SYNCHRONIZE, 504 517 FILE_ATTRIBUTE_NORMAL, … … 552 565 553 566 567 static int birdStatInternalW(HANDLE hRoot, const wchar_t *pwszPath, BirdStat_T *pStat, int fFollow) 568 { 569 int rc; 570 HANDLE hFile = birdOpenFileExW(hRoot, pwszPath, 571 FILE_READ_ATTRIBUTES, 572 FILE_ATTRIBUTE_NORMAL, 573 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 574 FILE_OPEN, 575 FILE_OPEN_FOR_BACKUP_INTENT | (fFollow ? 0 : FILE_OPEN_REPARSE_POINT), 576 OBJ_CASE_INSENSITIVE); 577 if (hFile != INVALID_HANDLE_VALUE) 578 { 579 rc = birdStatHandle2(hFile, pStat, NULL, pwszPath); 580 birdCloseFile(hFile); 581 } 582 else 583 { 584 /* 585 * On things like pagefile.sys we may get sharing violation. We fall 586 * back on directory enumeration for dealing with that. 587 */ 588 if ( errno == ETXTBSY 589 && wcschr(pwszPath, '*') == NULL /* Serious paranoia... */ 590 && wcschr(pwszPath, '?') == NULL) 591 { 592 MY_UNICODE_STRING NameUniStr; 593 hFile = birdOpenParentDirW(hRoot, pwszPath, 594 FILE_READ_DATA | SYNCHRONIZE, 595 FILE_ATTRIBUTE_NORMAL, 596 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 597 FILE_OPEN, 598 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, 599 OBJ_CASE_INSENSITIVE, 600 &NameUniStr); 601 if (hFile != INVALID_HANDLE_VALUE) 602 { 603 MY_FILE_ID_FULL_DIR_INFORMATION *pBuf; 604 ULONG cbBuf = sizeof(*pBuf) + NameUniStr.MaximumLength + 1024; 605 MY_IO_STATUS_BLOCK Ios; 606 MY_NTSTATUS rcNt; 607 608 pBuf = (MY_FILE_ID_FULL_DIR_INFORMATION *)alloca(cbBuf); 609 Ios.u.Status = -1; 610 Ios.Information = -1; 611 rcNt = g_pfnNtQueryDirectoryFile(hFile, NULL, NULL, NULL, &Ios, pBuf, cbBuf, 612 MyFileIdFullDirectoryInformation, FALSE, &NameUniStr, TRUE); 613 if (MY_NT_SUCCESS(rcNt)) 614 rcNt = Ios.u.Status; 615 if (MY_NT_SUCCESS(rcNt)) 616 { 617 /* 618 * Convert the data. 619 */ 620 birdStatFillFromFileIdFullDirInfo(pStat, pBuf, NULL); 621 622 /* Get the serial number, reusing the buffer from above. */ 623 rcNt = birdQueryVolumeDeviceNumber(hFile, (MY_FILE_FS_VOLUME_INFORMATION *)pBuf, cbBuf, &pStat->st_dev); 624 if (MY_NT_SUCCESS(rcNt)) 625 rc = 0; 626 else 627 rc = birdSetErrnoFromNt(rcNt); 628 } 629 630 birdFreeNtPath(&NameUniStr); 631 birdCloseFile(hFile); 632 633 if (MY_NT_SUCCESS(rcNt)) 634 return 0; 635 birdSetErrnoFromNt(rcNt); 636 } 637 } 638 rc = -1; 639 } 640 641 return rc; 642 } 643 644 554 645 /** 555 646 * Implements UNIX fstat(). … … 570 661 { 571 662 case FILE_TYPE_DISK: 572 rc = birdStatHandle (hFile, pStat, NULL);663 rc = birdStatHandle2(hFile, pStat, NULL, NULL); 573 664 break; 574 665 … … 657 748 int birdStatFollowLink(const char *pszPath, BirdStat_T *pStat) 658 749 { 659 return birdStatInternal(pszPath, pStat, 1 /*fFollow*/); 750 return birdStatInternal(NULL, pszPath, pStat, 1 /*fFollow*/); 751 } 752 753 754 /** 755 * Implements UNIX stat(). 756 */ 757 int birdStatFollowLinkW(const wchar_t *pwszPath, BirdStat_T *pStat) 758 { 759 return birdStatInternalW(NULL, pwszPath, pStat, 1 /*fFollow*/); 660 760 } 661 761 … … 666 766 int birdStatOnLink(const char *pszPath, BirdStat_T *pStat) 667 767 { 668 return birdStatInternal(pszPath, pStat, 0 /*fFollow*/); 768 return birdStatInternal(NULL, pszPath, pStat, 0 /*fFollow*/); 769 } 770 771 772 /** 773 * Implements UNIX lstat(). 774 */ 775 int birdStatOnLinkW(const wchar_t *pwszPath, BirdStat_T *pStat) 776 { 777 return birdStatInternalW(NULL, pwszPath, pStat, 0 /*fFollow*/); 778 } 779 780 781 /** 782 * Implements an API like UNIX fstatat(). 783 * 784 * @returns 0 on success, -1 and errno on failure. 785 * @param hRoot NT handle pwszPath is relative to. 786 * @param pszPath The path. 787 * @param pStat Where to return stats. 788 * @param fFollowLink Whether to follow links. 789 */ 790 int birdStatAt(HANDLE hRoot, const char *pszPath, BirdStat_T *pStat, int fFollowLink) 791 { 792 return birdStatInternal(hRoot, pszPath, pStat, fFollowLink != 0); 793 } 794 795 796 /** 797 * Implements an API like UNIX fstatat(). 798 * 799 * @returns 0 on success, -1 and errno on failure. 800 * @param hRoot NT handle pwszPath is relative to. 801 * @param pwszPath The path. 802 * @param pStat Where to return stats. 803 * @param fFollowLink Whether to follow links. 804 */ 805 int birdStatAtW(HANDLE hRoot, const wchar_t *pwszPath, BirdStat_T *pStat, int fFollowLink) 806 { 807 return birdStatInternalW(hRoot, pwszPath, pStat, fFollowLink != 0); 669 808 } 670 809
Note:
See TracChangeset
for help on using the changeset viewer.