トップ回答者
ディスクのセクター位置を指定してファイルを新規作成する方法はないでしょうか?

質問
回答
-
「一般的にはできない」が答えになりますが、
本件については、その目的を明らかにすべきだと思います。
目的によって可能な場合と、不可能な場合と、代替案がありえる場合が想定できます。1.ボリュームやパーティションを意識して開くことは可能です。
2.その物理情報(DISK_PARTITION_INFO等)は取得できます。
3.開いたボリュームから特定のバイト数を読むことができます(セクタは指定できませんけど)。
4.書き込みは保護されていてできない場合があります。
SDカードなど外部ドライブには書き込めます。
5.ボリュームのフォーマットによってはできない場合もあります。
6.たとえ書き込めても、OSによって消される場合を想定しなければなりません(禁止できません)。
すべての返信
-
「一般的にはできない」が答えになりますが、
本件については、その目的を明らかにすべきだと思います。
目的によって可能な場合と、不可能な場合と、代替案がありえる場合が想定できます。1.ボリュームやパーティションを意識して開くことは可能です。
2.その物理情報(DISK_PARTITION_INFO等)は取得できます。
3.開いたボリュームから特定のバイト数を読むことができます(セクタは指定できませんけど)。
4.書き込みは保護されていてできない場合があります。
SDカードなど外部ドライブには書き込めます。
5.ボリュームのフォーマットによってはできない場合もあります。
6.たとえ書き込めても、OSによって消される場合を想定しなければなりません(禁止できません)。 -
仲澤様
ご回答ありがとうございます。
Storport配下のminiportドライバを作成するにあたって、特定のLBAへのRead/Writeの挙動を
テストする上でテスト用データとしてテキストファイルを用意して動作確認を行いたいと
考えていました。
わかりやすい例だと、境界値試験などになります。
32bit/64bitに関連した2TByteの壁や、ATAの28bit/BigDrive対応の48bitなどの境界値付近への
ファイルアクセス試験を行う上で、それら境界値付近を狙ってテキストファイルを作成したいと
考えておりました。
ファイルの断片化なども考慮しなければならず、可能であればLBAを直で指定したかったのですが
一般的にはできないのであれば別の方法を考えないといけないですね。
ありがとうございました。
-
ファイルシステムを破壊してでも書き込みたいということでしょうか?
CreateFile()はファイルだけでなくディレクトリなど様々なものを扱えますが、その中にデバイスがあります。 \\.\C: であればC:ドライブを、 \\.\PhysicalDrive0 であれば最初ディスクをそれぞれオープンできます。後は 適切な位置にシークを行った後にread/writeされればいいかと。
# read経験はありますが、破壊してまでのwrite経験はありませんw
-
> ファイルの断片化なども考慮しなければならず、
> 可能であればLBAを直で指定したかったのですが
> 一般的にはできないのであれば別の方法を考えないといけないですね。既にご認識されているようですが、「ファイルの断片化」は常に起こります。
なので「考慮」ではなく「前提」とする必要があり、LBA を直に指定したら確実におかしくなると思います。この手の検証を本格的にやるとなると、非常に難しいですね。。。
とりあえず思いつく方法としては。。。。
ファイル I/O から SCSI コマンドへの変換は disk.sys ドライバ辺りがやっているので、LBA への変換も disk.sys ドライバがやっているんだと思います。
(大昔に調べたけど、詳細はきれいさっぱり忘れました。)
ということは、disk.sys の Lower Filter としてアタッチする検証ドライバを別途作成すれば、(方向性はちょっと違うかもしれないけど) 目的とする検証ができるのでは。。。。という気がします。
既に佐祐理さんがコメントされていますが、ファイルではなく単なる「データ」としての読み書きであれば、CreateFile() / ReadFile() / WriteFile() でも行けますが、ファイル I/O と LBA を関連付けての検証の場合、ユーザ モード側からだけの制御では限界があると思います。
今後発生するであろう不具合対応等のメンテナンス性を向上させる意味でも、ファイル システムやボリューム、ディスク等のデバイス スタックにアタッチする、検証用フィルタ ドライバを別途作成したほうが、将来的にもいいと思います。
(Stor Miniport を開発できるだけのスキルがあるのだから、あともうちょっとだけ根性出せばフィルタ ドライバも作れるのでは?) -
手段に目星はついていたのですがドキュメントが見つけられずに提案できずにいました。が、今更になってドキュメントを見つけたので提案しておきます。
defragユーティリティは実質的にファイルを移動する機能を有していますので、移動させるAPIもどこかで公開されているはずと考えていました。Defragmenting a fileがその解説ですが、これを用いることでファイルを希望するセクターに移動可能かと思います。FSCTL_MOVE_FILEらしいですね。