Changeset 3004 for trunk/src/lib/nt/ntdir.c
- Timestamp:
- Nov 6, 2016, 12:18:51 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt/ntdir.c
r2985 r3004 242 242 /** 243 243 * Implements readdir_r(). 244 * 245 * @remarks birdDirReadReentrantW is a copy of this. Keep them in sync! 244 246 */ 245 247 int birdDirReadReentrant(BirdDir_T *pDir, BirdDirEntry_T *pEntry, BirdDirEntry_T **ppResult) … … 371 373 { 372 374 BirdDirEntry_T *pRet = NULL; 373 birdDirReadReentrant(pDir, &pDir->DirEntry, &pRet); 375 birdDirReadReentrant(pDir, &pDir->u.DirEntry, &pRet); 376 return pRet; 377 } 378 379 380 static int birdDirCopyNameToEntryW(WCHAR const *pwcName, ULONG cbName, BirdDirEntryW_T *pEntry) 381 { 382 ULONG cwcName = cbName / sizeof(wchar_t); 383 if (cwcName < sizeof(pEntry->d_name)) 384 { 385 memcpy(pEntry->d_name, pwcName, cbName); 386 pEntry->d_name[cwcName] = '\0'; 387 pEntry->d_namlen = (unsigned __int16)cwcName; 388 pEntry->d_reclen = (unsigned __int16)((size_t)&pEntry->d_name[cwcName + 1] - (size_t)pEntry); 389 return 0; 390 } 391 return -1; 392 } 393 394 395 /** 396 * Implements readdir_r(), UTF-16 version. 397 * 398 * @remarks This is a copy of birdDirReadReentrant where only the name handling 399 * and entry type differs. Remember to keep them in sync! 400 */ 401 int birdDirReadReentrantW(BirdDir_T *pDir, BirdDirEntryW_T *pEntry, BirdDirEntryW_T **ppResult) 402 { 403 int fSkipEntry; 404 405 *ppResult = NULL; 406 407 if (!pDir || pDir->uMagic != BIRD_DIR_MAGIC) 408 return birdSetErrnoToBadFileNo(); 409 410 do 411 { 412 ULONG offNext; 413 ULONG cbMinCur; 414 415 /* 416 * Read more? 417 */ 418 if (!pDir->fHaveData) 419 { 420 if (birdDirReadMore(pDir) != 0) 421 return -1; 422 if (!pDir->fHaveData) 423 return 0; 424 } 425 426 /* 427 * Convert the NT data to the unixy output structure. 428 */ 429 fSkipEntry = 0; 430 switch (pDir->iInfoClass) 431 { 432 case MyFileNamesInformation: 433 { 434 MY_FILE_NAMES_INFORMATION *pInfo = (MY_FILE_NAMES_INFORMATION *)&pDir->pabBuf[pDir->offBuf]; 435 if ( pDir->offBuf >= pDir->cbBuf - MIN_SIZEOF_MY_FILE_NAMES_INFORMATION 436 || pInfo->FileNameLength >= pDir->cbBuf 437 || pDir->offBuf + pInfo->FileNameLength + MIN_SIZEOF_MY_FILE_NAMES_INFORMATION > pDir->cbBuf) 438 { 439 fSkipEntry = 1; 440 pDir->fHaveData = 0; 441 continue; 442 } 443 444 memset(&pEntry->d_stat, 0, sizeof(pEntry->d_stat)); 445 pEntry->d_stat.st_mode = S_IFMT; 446 pEntry->d_type = DT_UNKNOWN; 447 pEntry->d_reclen = 0; 448 pEntry->d_namlen = 0; 449 if (birdDirCopyNameToEntryW(pInfo->FileName, pInfo->FileNameLength, pEntry) != 0) 450 fSkipEntry = 1; 451 452 cbMinCur = MIN_SIZEOF_MY_FILE_NAMES_INFORMATION + pInfo->FileNameLength; 453 offNext = pInfo->NextEntryOffset; 454 break; 455 } 456 457 case MyFileIdFullDirectoryInformation: 458 { 459 MY_FILE_ID_FULL_DIR_INFORMATION *pInfo = (MY_FILE_ID_FULL_DIR_INFORMATION *)&pDir->pabBuf[pDir->offBuf]; 460 if ( pDir->offBuf >= pDir->cbBuf - MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION 461 || pInfo->FileNameLength >= pDir->cbBuf 462 || pDir->offBuf + pInfo->FileNameLength + MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION > pDir->cbBuf) 463 { 464 fSkipEntry = 1; 465 pDir->fHaveData = 0; 466 continue; 467 } 468 469 pEntry->d_type = DT_UNKNOWN; 470 pEntry->d_reclen = 0; 471 pEntry->d_namlen = 0; 472 if (birdDirCopyNameToEntryW(pInfo->FileName, pInfo->FileNameLength, pEntry) != 0) 473 fSkipEntry = 1; 474 birdStatFillFromFileIdFullDirInfo(&pEntry->d_stat, pInfo, NULL); 475 pEntry->d_stat.st_dev = pDir->uDev; 476 switch (pEntry->d_stat.st_mode & S_IFMT) 477 { 478 case S_IFREG: pEntry->d_type = DT_REG; break; 479 case S_IFDIR: pEntry->d_type = DT_DIR; break; 480 case S_IFLNK: pEntry->d_type = DT_LNK; break; 481 case S_IFIFO: pEntry->d_type = DT_FIFO; break; 482 case S_IFCHR: pEntry->d_type = DT_CHR; break; 483 default: 484 #ifndef NDEBUG 485 __debugbreak(); 486 #endif 487 pEntry->d_type = DT_UNKNOWN; 488 break; 489 } 490 491 cbMinCur = MIN_SIZEOF_MY_FILE_ID_FULL_DIR_INFORMATION + pInfo->FileNameLength; 492 offNext = pInfo->NextEntryOffset; 493 break; 494 } 495 496 default: 497 return birdSetErrnoToBadFileNo(); 498 } 499 500 /* 501 * Advance. 502 */ 503 if ( offNext >= cbMinCur 504 && offNext < pDir->cbBuf) 505 pDir->offBuf += offNext; 506 else 507 { 508 pDir->fHaveData = 0; 509 pDir->offBuf = pDir->cbBuf; 510 } 511 pDir->offPos++; 512 } while (fSkipEntry); 513 514 515 /* 516 * Successful return. 517 */ 518 *ppResult = pEntry; 519 return 0; 520 } 521 522 /** 523 * Implements readdir(). 524 */ 525 BirdDirEntryW_T *birdDirReadW(BirdDir_T *pDir) 526 { 527 BirdDirEntryW_T *pRet = NULL; 528 birdDirReadReentrantW(pDir, &pDir->u.DirEntryW, &pRet); 374 529 return pRet; 375 530 }
Note:
See TracChangeset
for help on using the changeset viewer.