Changeset 3007 for trunk/src/lib/nt/ntstat.c
- Timestamp:
- Nov 6, 2016, 5:46:43 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt/ntstat.c
r3003 r3007 148 148 149 149 150 static unsigned short birdFileInfoToMode(HANDLE hFile, ULONG fAttribs, const char *pszName, 151 const wchar_t *pwszName, size_t cbNameW, __int16 *pfIsDirSymlink) 150 static unsigned short birdFileInfoToMode(ULONG fAttribs, ULONG uReparseTag, 151 const char *pszName, const wchar_t *pwszName, size_t cbNameW, 152 unsigned __int8 *pfIsDirSymlink, unsigned __int8 *pfIsMountPoint) 152 153 { 153 154 unsigned short fMode; 154 155 155 156 /* File type. */ 156 if ( (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT) 157 && hFile != INVALID_HANDLE_VALUE) 158 { 159 MY_FILE_ATTRIBUTE_TAG_INFORMATION TagInfo; 160 MY_IO_STATUS_BLOCK Ios; 161 MY_NTSTATUS rcNt; 162 Ios.Information = 0; 163 Ios.u.Status = -1; 164 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &TagInfo, sizeof(TagInfo), MyFileAttributeTagInformation); 165 if ( !MY_NT_SUCCESS(rcNt) 166 || !MY_NT_SUCCESS(Ios.u.Status) 167 || TagInfo.ReparseTag != IO_REPARSE_TAG_SYMLINK) 168 fAttribs &= ~FILE_ATTRIBUTE_REPARSE_POINT; 169 } 170 171 if (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT) 172 { 173 *pfIsDirSymlink = !!(fAttribs & FILE_ATTRIBUTE_DIRECTORY); 174 fMode = S_IFLNK; 175 } 176 else 177 { 178 *pfIsDirSymlink = 0; 157 *pfIsDirSymlink = 0; 158 *pfIsMountPoint = 0; 159 if (!(fAttribs & FILE_ATTRIBUTE_REPARSE_POINT)) 160 { 179 161 if (fAttribs & FILE_ATTRIBUTE_DIRECTORY) 180 162 fMode = S_IFDIR; 181 163 else 182 164 fMode = S_IFREG; 165 } 166 else 167 { 168 switch (uReparseTag) 169 { 170 case IO_REPARSE_TAG_SYMLINK: 171 *pfIsDirSymlink = !!(fAttribs & FILE_ATTRIBUTE_DIRECTORY); 172 fMode = S_IFLNK; 173 break; 174 175 case IO_REPARSE_TAG_MOUNT_POINT: 176 *pfIsMountPoint = 1; 177 default: 178 if (fAttribs & FILE_ATTRIBUTE_DIRECTORY) 179 fMode = S_IFDIR; 180 else 181 fMode = S_IFREG; 182 break; 183 } 183 184 } 184 185 … … 202 203 * @param pStat The stat structure. 203 204 * @param pBuf The MY_FILE_ID_FULL_DIR_INFORMATION entry. 204 * @param pszPath Optionally, the path for X bit checks.205 205 * @remarks Caller sets st_dev. 206 206 */ 207 void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf , const char *pszPath)208 { 209 pStat->st_mode = birdFileInfoToMode( INVALID_HANDLE_VALUE, pBuf->FileAttributes,210 p szPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink);207 void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf) 208 { 209 pStat->st_mode = birdFileInfoToMode(pBuf->FileAttributes, pBuf->EaSize, NULL /*pszPath*/, pBuf->FileName, 210 pBuf->FileNameLength, &pStat->st_isdirsymlink, &pStat->st_ismountpoint); 211 211 pStat->st_padding0[0] = 0; 212 212 pStat->st_padding0[1] = 0; … … 234 234 * @param pStat The stat structure. 235 235 * @param pBuf The MY_FILE_ID_BOTH_DIR_INFORMATION entry. 236 * @param pszPath Optionally, the path for X bit checks.237 236 * @remarks Caller sets st_dev. 238 237 */ 239 void birdStatFillFromFileIdBothDirInfo(BirdStat_T *pStat, MY_FILE_ID_BOTH_DIR_INFORMATION const *pBuf , const char *pszPath)240 { 241 pStat->st_mode = birdFileInfoToMode( INVALID_HANDLE_VALUE, pBuf->FileAttributes,242 p szPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink);238 void birdStatFillFromFileIdBothDirInfo(BirdStat_T *pStat, MY_FILE_ID_BOTH_DIR_INFORMATION const *pBuf) 239 { 240 pStat->st_mode = birdFileInfoToMode(pBuf->FileAttributes, pBuf->EaSize, NULL /*pszPath*/, pBuf->FileName, 241 pBuf->FileNameLength, &pStat->st_isdirsymlink, &pStat->st_ismountpoint); 243 242 pStat->st_padding0[0] = 0; 244 243 pStat->st_padding0[1] = 0; … … 266 265 * @param pStat The stat structure. 267 266 * @param pBuf The MY_FILE_BOTH_DIR_INFORMATION entry. 268 * @param pszPath Optionally, the path for X bit checks.269 267 * @remarks Caller sets st_dev. 270 268 */ 271 void birdStatFillFromFileBothDirInfo(BirdStat_T *pStat, MY_FILE_BOTH_DIR_INFORMATION const *pBuf , const char *pszPath)272 { 273 pStat->st_mode = birdFileInfoToMode( INVALID_HANDLE_VALUE, pBuf->FileAttributes,274 p szPath, pBuf->FileName, pBuf->FileNameLength, &pStat->st_dirsymlink);269 void birdStatFillFromFileBothDirInfo(BirdStat_T *pStat, MY_FILE_BOTH_DIR_INFORMATION const *pBuf) 270 { 271 pStat->st_mode = birdFileInfoToMode(pBuf->FileAttributes, pBuf->EaSize, NULL /*pszPath*/, pBuf->FileName, 272 pBuf->FileNameLength, &pStat->st_isdirsymlink, &pStat->st_ismountpoint); 275 273 pStat->st_padding0[0] = 0; 276 274 pStat->st_padding0[1] = 0; … … 310 308 if (MY_NT_SUCCESS(rcNt)) 311 309 { 312 pStat->st_mode = birdFileInfoToMode( hFile,pAll->BasicInformation.FileAttributes, pszPath,310 pStat->st_mode = birdFileInfoToMode(pAll->BasicInformation.FileAttributes, pszPath, 313 311 pAll->NameInformation.FileNamepAll->NameInformation.FileNameLength, 314 &pStat->st_dirsymlink);312 hFile, &pStat->st_isdirsymlink, &pStat->st_ismountpoint); 315 313 pStat->st_padding0[0] = 0; 316 314 pStat->st_padding0[1] = 0; … … 354 352 rc = birdSetErrnoToNoMem(); 355 353 #else 356 ULONG cbNameInfo = 0; 357 MY_FILE_NAME_INFORMATION *pNameInfo = NULL; 358 MY_FILE_STANDARD_INFORMATION StdInfo; 359 MY_FILE_BASIC_INFORMATION BasicInfo; 360 MY_FILE_INTERNAL_INFORMATION InternalInfo; 361 MY_IO_STATUS_BLOCK Ios; 354 ULONG cbNameInfo = 0; 355 MY_FILE_NAME_INFORMATION *pNameInfo = NULL; 356 MY_FILE_STANDARD_INFORMATION StdInfo; 357 MY_FILE_BASIC_INFORMATION BasicInfo; 358 MY_FILE_INTERNAL_INFORMATION InternalInfo; 359 MY_FILE_ATTRIBUTE_TAG_INFORMATION TagInfo; 360 MY_IO_STATUS_BLOCK Ios; 362 361 363 362 Ios.Information = 0; … … 366 365 if (MY_NT_SUCCESS(rcNt)) 367 366 rcNt = Ios.u.Status; 367 368 368 if (MY_NT_SUCCESS(rcNt)) 369 369 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation); 370 370 if (MY_NT_SUCCESS(rcNt)) 371 371 rcNt = Ios.u.Status; 372 372 373 if (MY_NT_SUCCESS(rcNt)) 373 374 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &InternalInfo, sizeof(InternalInfo), MyFileInternalInformation); 374 375 if (MY_NT_SUCCESS(rcNt)) 375 376 rcNt = Ios.u.Status; 377 378 if (MY_NT_SUCCESS(rcNt)) 379 { 380 if (!(BasicInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) 381 TagInfo.ReparseTag = 0; 382 else 383 { 384 MY_NTSTATUS rcNt2 = g_pfnNtQueryInformationFile(hFile, &Ios, &TagInfo, sizeof(TagInfo), MyFileAttributeTagInformation); 385 if ( !MY_NT_SUCCESS(rcNt2) 386 || !MY_NT_SUCCESS(Ios.u.Status)) 387 TagInfo.ReparseTag = 0; 388 } 389 } 390 376 391 if (MY_NT_SUCCESS(rcNt) && !pszPath && !pwszPath) 377 392 { … … 385 400 if (MY_NT_SUCCESS(rcNt)) 386 401 { 387 pStat->st_mode = birdFileInfoToMode( hFile, BasicInfo.FileAttributes, pszPath,402 pStat->st_mode = birdFileInfoToMode(BasicInfo.FileAttributes, TagInfo.ReparseTag, pszPath, 388 403 pNameInfo ? pNameInfo->FileName : pwszPath, 389 404 pNameInfo ? pNameInfo->FileNameLength 390 405 : pwszPath ? wcslen(pwszPath) * sizeof(wchar_t) : 0, 391 &pStat->st_ dirsymlink);406 &pStat->st_isdirsymlink, &pStat->st_ismountpoint); 392 407 pStat->st_padding0[0] = 0; 393 408 pStat->st_padding0[1] = 0; … … 506 521 birdCloseFile(hFile); 507 522 523 if (rc || !pStat->st_ismountpoint) 524 { /* very likely */ } 525 else 526 { 527 /* 528 * If we hit a mount point (NTFS volume mounted under an empty NTFS directory), 529 * we should return information about what's mounted there rather than the 530 * directory it is mounted at as this is what UNIX does. 531 */ 532 hFile = birdOpenFileEx(hRoot, pszPath, 533 FILE_READ_ATTRIBUTES, 534 FILE_ATTRIBUTE_NORMAL, 535 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 536 FILE_OPEN, 537 FILE_OPEN_FOR_BACKUP_INTENT, 538 OBJ_CASE_INSENSITIVE); 539 if (hFile != INVALID_HANDLE_VALUE) 540 { 541 rc = birdStatHandle2(hFile, pStat, pszPath, NULL); 542 pStat->st_ismountpoint = 2; 543 birdCloseFile(hFile); 544 } 545 } 546 508 547 #if 0 509 548 { … … 558 597 * Convert the data. 559 598 */ 560 birdStatFillFromFileIdFullDirInfo(pStat, pBuf , pszPath);599 birdStatFillFromFileIdFullDirInfo(pStat, pBuf); 561 600 562 601 /* Get the serial number, reusing the buffer from above. */ … … 597 636 rc = birdStatHandle2(hFile, pStat, NULL, pwszPath); 598 637 birdCloseFile(hFile); 638 639 /* 640 * If we hit a mount point (NTFS volume mounted under an empty NTFS directory), 641 * we should return information about what's mounted there rather than the 642 * directory it is mounted at as this is what UNIX does. 643 */ 644 hFile = birdOpenFileExW(hRoot, pwszPath, 645 FILE_READ_ATTRIBUTES, 646 FILE_ATTRIBUTE_NORMAL, 647 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 648 FILE_OPEN, 649 FILE_OPEN_FOR_BACKUP_INTENT, 650 OBJ_CASE_INSENSITIVE); 651 if (hFile != INVALID_HANDLE_VALUE) 652 { 653 rc = birdStatHandle2(hFile, pStat, NULL, pwszPath); 654 pStat->st_ismountpoint = 2; 655 birdCloseFile(hFile); 656 } 599 657 } 600 658 else … … 636 694 * Convert the data. 637 695 */ 638 birdStatFillFromFileIdFullDirInfo(pStat, pBuf , NULL);696 birdStatFillFromFileIdFullDirInfo(pStat, pBuf); 639 697 640 698 /* Get the serial number, reusing the buffer from above. */
Note:
See TracChangeset
for help on using the changeset viewer.