2017-02-22 4 views
0

私は、ハードディスクの内容をスキャンするWindowsプログラムを持っています。意味のあるプログレスバーを表示したいと思います。ディスク上のファイルの総数を取得する簡単な方法はありますか?その数は正確である必要はありません - 10%程度の近似が必要です。ディスク上のファイル数をすばやく取得する方法はありますか?

+0

管理者特権はありますか? [MFTの内容を読む](http://stackoverflow.com/a/7459109/886887)は、ディスクの内容をより高速にスキャンする方法を提供します。そうした場合は、あなたが処理した[MFTの何パーセント](http://stackoverflow.com/a/11337898/886887)のトラック。 –

+0

それには運がない - このプログラムは、できるだけ広い範囲で実行できる必要があります。 – Mark

答えて

0

これはNTFSボリュームで可能です。片道ハリー・ジョンストン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; 
} 
関連する問題