2017-02-22 70 views
0

我有一个扫描硬盘内容的Windows程序。我想在显示有意义的进度栏的同时显示。是否有快速获取磁盘上文件总数的方法?这个数字不一定是确切的 - 一个近似值应该在10%左右。有没有一种快速获取磁盘上文件数的方法?

+0

您是否拥有管理员权限? [阅读MFT的内容](http://stackoverflow.com/a/7459109/886887)提供了一种更快捷的方式来扫描磁盘的内容,如果你这样做了,你可以通过保留一个进度条跟踪[您已经处理了多少MFT百分比](http://stackoverflow.com/a/11337898/886887)。 –

+0

不幸的是 - 这个程序需要能够在尽可能广泛的环境下运行。 – Mark

回答

0

这对于NTFS卷是可能的。作为Harry Johnston的一种方式write。也可能有其他方式,通过迭代文件记录也足够快:

struct NTFS_RECORD_HEADER 
{ 
    enum { 
     FILE = 'ELIF', 
     INDX = 'XDNI', 
     BAAD = 'DAAB', 
     HOLE = 'ELOH', 
     CHKD = 'DKHC' 
    } Type; 
    USHORT UsaOffset; 
    USHORT UsaCount; 
    USN Usn; 
}; 

struct NTFS_FILE_RECORD_HEADER : public NTFS_RECORD_HEADER 
{ 
    USHORT SequenceNumber; 
    USHORT LinkCount; 
    USHORT AttributesOffset; 
    USHORT Flags; 
    ULONG BytesInUse; 
    ULONG BytesAllocated; 
    ULONGLONG BaseFileRecord; 
    USHORT NextAttributeNumber; 

    enum{ 
     flgInUse = 1, flgDirectory = 2 
    }; 
}; 

ULONG GetFileCount(HANDLE hVolume, PULONG FileCount) 
{ 
    NTFS_VOLUME_DATA_BUFFER nvdb; 

    ULONG cb, BytesReturned; 
    if (!DeviceIoControl(hVolume, FSCTL_GET_NTFS_VOLUME_DATA, NULL, 0, &nvdb, sizeof(nvdb), &BytesReturned, NULL)) 
    { 
     return GetLastError(); 
    } 

    NTFS_FILE_RECORD_INPUT_BUFFER nfrib; 

    cb = FIELD_OFFSET(NTFS_FILE_RECORD_OUTPUT_BUFFER, FileRecordBuffer[nvdb.BytesPerFileRecordSegment]); 

    PNTFS_FILE_RECORD_OUTPUT_BUFFER pnfrob = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)alloca(cb); 

    union { 
     PVOID FileRecordBuffer; 
     NTFS_RECORD_HEADER* pnrh; 
     NTFS_FILE_RECORD_HEADER* pnfrh; 
    }; 

    FileRecordBuffer = pnfrob->FileRecordBuffer; 

    // get maximum valid FileReferenceNumber 
    ULONG a = 0, b = MAXLONG, N; 
    do 
    { 
     nfrib.FileReferenceNumber.QuadPart = N = (a + b) >> 1; 

     DeviceIoControl(hVolume, FSCTL_GET_NTFS_FILE_RECORD, 
      &nfrib, sizeof nfrib, pnfrob, cb, &BytesReturned, 0) ? a = N + 1 : b = N; 

    } while(a < b); 

    if (!b) 
    { 
     return ERROR_GEN_FAILURE; 
    } 

    N = 0; 
    nfrib.FileReferenceNumber.QuadPart = b - 1; 

    // itterate [0, nfrib.FileReferenceNumber.QuadPart) 
    do 
    { 
     if (DeviceIoControl(hVolume, FSCTL_GET_NTFS_FILE_RECORD, 
      &nfrib, sizeof nfrib, pnfrob, cb, &BytesReturned, 0)) 
     { 
      // are really file 
      if (
       pnrh->Type == NTFS_RECORD_HEADER::FILE && 
       pnfrh->Flags & NTFS_FILE_RECORD_HEADER::flgInUse && 
       !pnfrh->BaseFileRecord 
       ) 
      { 
       N++; 
      } 
     } 
     else 
     { 
      pnfrob->FileReferenceNumber.QuadPart = nfrib.FileReferenceNumber.QuadPart; 
     } 

    } while (0 <= (nfrib.FileReferenceNumber.QuadPart = pnfrob->FileReferenceNumber.QuadPart - 1)); 

    *FileCount = N; 

    return NOERROR; 
} 
相关问题