- Timestamp:
- Nov 6, 2016, 5:46:43 PM (9 years ago)
- Location:
- trunk/src/lib/nt
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt/kFsCache.c
r3005 r3007 1569 1569 #ifdef KFSCACHE_CFG_SHORT_NAMES 1570 1570 if (enmInfoClass == enmInfoClassWithId) 1571 birdStatFillFromFileIdBothDirInfo(&pCur->Stats, uPtr.pWithId , pCur->pszName);1571 birdStatFillFromFileIdBothDirInfo(&pCur->Stats, uPtr.pWithId); 1572 1572 else 1573 birdStatFillFromFileBothDirInfo(&pCur->Stats, uPtr.pNoId , pCur->pszName);1573 birdStatFillFromFileBothDirInfo(&pCur->Stats, uPtr.pNoId); 1574 1574 #else 1575 1575 if (enmInfoClass == enmInfoClassWithId) 1576 birdStatFillFromFileIdFullDirInfo(&pCur->Stats, uPtr.pWithId , pCur->pszName);1576 birdStatFillFromFileIdFullDirInfo(&pCur->Stats, uPtr.pWithId); 1577 1577 else 1578 birdStatFillFromFileFullDirInfo(&pCur->Stats, uPtr.pNoId , pCur->pszName);1578 birdStatFillFromFileFullDirInfo(&pCur->Stats, uPtr.pNoId); 1579 1579 #endif 1580 1580 pCur->Stats.st_dev = pDir->uDevNo; … … 1602 1602 #ifdef KFSCACHE_CFG_SHORT_NAMES 1603 1603 if (enmInfoClass == enmInfoClassWithId) 1604 birdStatFillFromFileIdBothDirInfo(&pDir->Obj.Stats, uPtr.pWithId , pDir->Obj.pszName);1604 birdStatFillFromFileIdBothDirInfo(&pDir->Obj.Stats, uPtr.pWithId); 1605 1605 else 1606 birdStatFillFromFileBothDirInfo(&pDir->Obj.Stats, uPtr.pNoId , pDir->Obj.pszName);1606 birdStatFillFromFileBothDirInfo(&pDir->Obj.Stats, uPtr.pNoId); 1607 1607 #else 1608 1608 if (enmInfoClass == enmInfoClassWithId) 1609 birdStatFillFromFileIdFullDirInfo(&pDir->Obj.Stats, uPtr.pWithId , pDir->Obj.pszName);1609 birdStatFillFromFileIdFullDirInfo(&pDir->Obj.Stats, uPtr.pWithId); 1610 1610 else 1611 birdStatFillFromFileFullDirInfo(&pDir->Obj.Stats, uPtr.pNoId , pDir->Obj.pszName);1611 birdStatFillFromFileFullDirInfo(&pDir->Obj.Stats, uPtr.pNoId); 1612 1612 #endif 1613 1613 } -
trunk/src/lib/nt/ntdir.c
r3005 r3007 293 293 294 294 295 /** 296 * Deals with mount points. 297 * 298 * @param pDir The directory handle. 299 * @param pInfo The NT entry information. 300 * @param pEntryStat The stats for the mount point directory that needs 301 * updating (a d_stat member). 302 */ 303 static void birdDirUpdateMountPointInfo(BirdDir_T *pDir, MY_FILE_ID_FULL_DIR_INFORMATION *pInfo, 304 BirdStat_T *pEntryStat) 305 { 306 /* 307 * Try open the root directory of the mount. 308 * (Can't use birdStatAtW here because the name isn't terminated.) 309 */ 310 HANDLE hRoot = INVALID_HANDLE_VALUE; 311 MY_NTSTATUS rcNt; 312 MY_UNICODE_STRING Name; 313 Name.Buffer = pInfo->FileName; 314 Name.Length = Name.MaximumLength = (USHORT)pInfo->FileNameLength; 315 316 rcNt = birdOpenFileUniStr((HANDLE)pDir->pvHandle, &Name, 317 FILE_READ_ATTRIBUTES, 318 FILE_ATTRIBUTE_NORMAL, 319 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 320 FILE_OPEN, 321 FILE_OPEN_FOR_BACKUP_INTENT, 322 OBJ_CASE_INSENSITIVE, 323 &hRoot); 324 if (MY_NT_SUCCESS(rcNt)) 325 { 326 int iSavedErrno = errno; 327 BirdStat_T RootStat; 328 if (birdStatHandle(hRoot, &RootStat, NULL) == 0) 329 { 330 RootStat.st_ismountpoint = 2; 331 *pEntryStat = RootStat; 332 } 333 birdCloseFile(hRoot); 334 errno = iSavedErrno; 335 } 336 /* else: don't mind failures, we've got some info. */ 337 } 338 295 339 296 340 /** … … 372 416 if (birdDirCopyNameToEntry(pInfo->FileName, pInfo->FileNameLength, pEntry) != 0) 373 417 fSkipEntry = 1; 374 birdStatFillFromFileIdFullDirInfo(&pEntry->d_stat, pInfo , pEntry->d_name);418 birdStatFillFromFileIdFullDirInfo(&pEntry->d_stat, pInfo); 375 419 pEntry->d_stat.st_dev = pDir->uDev; 376 420 switch (pEntry->d_stat.st_mode & S_IFMT) … … 389 433 } 390 434 435 if (pEntry->d_stat.st_ismountpoint != 1) 436 { /* likely. */ } 437 else 438 birdDirUpdateMountPointInfo(pDir, pInfo, &pEntry->d_stat); 439 391 440 cbMinCur = MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION + pInfo->FileNameLength; 392 441 offNext = pInfo->NextEntryOffset; … … 526 575 if (birdDirCopyNameToEntryW(pInfo->FileName, pInfo->FileNameLength, pEntry) != 0) 527 576 fSkipEntry = 1; 528 birdStatFillFromFileIdFullDirInfo(&pEntry->d_stat, pInfo , NULL);577 birdStatFillFromFileIdFullDirInfo(&pEntry->d_stat, pInfo); 529 578 pEntry->d_stat.st_dev = pDir->uDev; 530 579 switch (pEntry->d_stat.st_mode & S_IFMT) … … 543 592 } 544 593 594 if (pEntry->d_stat.st_ismountpoint != 1) 595 { /* likely. */ } 596 else 597 birdDirUpdateMountPointInfo(pDir, pInfo, &pEntry->d_stat); 598 545 599 cbMinCur = MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION + pInfo->FileNameLength; 546 600 offNext = pInfo->NextEntryOffset; -
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. */ -
trunk/src/lib/nt/ntstat.h
r2985 r3007 50 50 { 51 51 unsigned __int16 st_mode; 52 unsigned __int16 st_dirsymlink; 52 unsigned __int8 st_isdirsymlink; /**< Set if directory symlink. */ 53 unsigned __int8 st_ismountpoint; /**< Set if mount point; 1 if not followed, 2 if followed (lstat & readdir only). */ 53 54 unsigned __int16 st_padding0[2]; 54 55 __int64 st_size; … … 87 88 #ifdef ___nt_ntstuff_h 88 89 int birdStatHandle(HANDLE hFile, BirdStat_T *pStat, const char *pszPath); 89 void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf , const char *pszPath);90 void birdStatFillFromFileIdBothDirInfo(BirdStat_T *pStat, MY_FILE_ID_BOTH_DIR_INFORMATION const *pBuf , const char *pszPath);91 void birdStatFillFromFileBothDirInfo(BirdStat_T *pStat, MY_FILE_BOTH_DIR_INFORMATION const *pBuf , const char *pszPath);90 void birdStatFillFromFileIdFullDirInfo(BirdStat_T *pStat, MY_FILE_ID_FULL_DIR_INFORMATION const *pBuf); 91 void birdStatFillFromFileIdBothDirInfo(BirdStat_T *pStat, MY_FILE_ID_BOTH_DIR_INFORMATION const *pBuf); 92 void birdStatFillFromFileBothDirInfo(BirdStat_T *pStat, MY_FILE_BOTH_DIR_INFORMATION const *pBuf); 92 93 MY_NTSTATUS birdQueryVolumeDeviceNumber(HANDLE hFile, MY_FILE_FS_VOLUME_INFORMATION *pVolInfo, size_t cbVolInfo, 93 94 unsigned __int64 *puDevNo); -
trunk/src/lib/nt/tstNtStat.c
r2702 r3007 131 131 printf("%s:\n", argv[i]); 132 132 printf(" st_mode: %o\n", st.st_mode); 133 printf(" st_dirsymlink: %d\n", st.st_dirsymlink); 133 printf(" st_isdirsymlink: %d\n", st.st_isdirsymlink); 134 printf(" st_ismountpoint: %d\n", st.st_ismountpoint); 134 135 printf(" st_size: %I64u (%#I64x)\n", st.st_size, st.st_size); 135 136 printf(" st_atim: %s\n", FormatTimeSpec(szBuf, &st.st_atim));
Note:
See TracChangeset
for help on using the changeset viewer.