FSCTL_GET_NTFS_VOLUME_DATAを使用して、MFTのバイト単位の長さを取得できます。これを、選択した代表的なボリュームのレコード数と比較すると、単一のMFTレコードの平均長を推定し、これを使用して特定のボリュームのレコード数の推定値を計算できます。
MFTには(たとえば)すべてのファイルのセキュリティ情報が含まれているため、平均の長さはボリュームごとに大きく異なります。したがって、桁違いの精度しか得られないと思いますが、ほとんどの場合は十分です。 。
別のアプローチは、ファイル参照番号が直線的に増加すると仮定することです。これはほぼ真実です。FSCTL_ENUM_USN_DATAを使用して、特定の推測を超える参照番号を持つファイルがあるかどうかを確認できます。実際の最大参照数を決定するために必要な推測は128以下です。これにより、少なくとも任意の時点で0から100までの完了率が得られます。完全に均一ではありませんが、プログレスバーが均一になることはありません。:-)
追加:
さらに詳しく見ると、Windows 7 x64では、FSCTL_ENUM_USN_DATAによって返される「次のID」フィールド(最初のUSN_RECORD構造の前に返されるクワッドワード)は、結局のところファイル参照番号ではなく、ファイルレコードセグメント番号です。したがって、観察したように、返される最後のID番号にBytesPerFileRecordSegment(1024)を掛けると、MftValidDataLengthに等しくなります。
ファイル参照番号は2つの部分で構成されているように見えます。下位6バイトには、ファイルレコードのセグメント番号が含まれています。各リクエストから返される最初のレコードには、StartFileReferenceNumberがゼロの場合の最初の呼び出しを除いて、常にStartFileReferenceNumberに入力される「次のID」と同じセグメント番号のFRNが含まれます。上位2バイトには、ゼロになることのない不特定の追加情報が含まれています。
FSCTL_ENUM_USN_DATAは、ファイルレコードセグメント番号(この場合、上位2バイトはゼロ)またはファイル参照番号(この場合、上位2バイトは非ゼロ)のいずれかを受け入れるようです。
奇妙なことに、同じレコードセグメント番号を持つ2つのレコードが見つかりません。これは、各ファイルレコードがMFTで少なくとも1Kを使用していることを示していますが、これは合理的ではないようです。
とにかく、結果として、「次のID」にBytesPerFileRecordSegmentを掛け、それをMftValidDataLengthで割って完了率を得るのは、無意味な結果が返された場合に適切に対処する限り、おそらく賢明です。