0

Windows で、WIN32API ファイル処理呼び出しを使用せずに raw バイトをファイルに書き込むことができるオプションがあるかどうか、またその場合はどのように正確かを知りたいです。

x86asm の直接ファイル呼び出しを使用して簡単なアプローチを使用しようとしましたが、その間は成功しませんでした。

4

2 に答える 2

2

You can try using the native API from ntdll or even direct syscalls (int 2eh or systenter instruction), but it's quite tricky - you need to use kernel-style filenames, for one.

于 2012-06-27T16:13:18.077 に答える
1

あなたの質問に答える前に、Windows で API を使用してファイルに書き込むことは、次の (簡略化された) 段階で構成されていることを述べておきます。

  1. WriteFileあなたは(kernel32.dll)を呼び出します
  2. WriteFile呼び出しNtWriteFile(ntdll.dll)
  3. NtWriteFile呼び出しSYSENTERと操作はカーネル モードに進みます
  4. カーネル モードNtWriteFileでは、Ntoskrnl.exe の関数が呼び出されます
  5. IRP_MJ_WRITEこれにより、ファイル システム ドライバーに送信されます
  6. ファイル システム ドライバーは、書き込みが必要なセクターを決定し、ストレージ ドライバーに渡します。
  7. ストレージドライバーは、指定されたセクターに実際にデータを書き込むコマンドをハードドライブに送信します
  8. ハードドライブはデータを書き込みます

1 から 7 までのすべての操作は、8 に比べて非常に高速です (RAM ドライブまたは非常に高速な SSD を使用している場合を除く)。

方法 1 - ステップ 1 は ( を呼び出すことによりNtWriteFile) 簡単にスキップでき、ステップ 2 (を呼び出すことによりSYSENTER- 簡単ではありません) をスキップできます。ただし、パフォーマンスの向上は得られないため、それを行う意味はありません。それらの単なるラッパーを検討してくださいWriteFile(余分な関数呼び出しを1つ削除した後ではないと思います)。

方法 2 - ファイルが占有しているセクターを見つけて直接書き込むことができます (事実上、手順 7 までのすべての手順をスキップします)。FSCTL_GET_RETRIEVAL_POINTERSこれを行うには、ボリュームを開いてロックし、呼び出しによってターゲット ファイルが占有するクラスターを見つけ、WriteFileボリューム ハンドルを呼び出す必要があります。ただし、ファイル システム ドライバーはデータ セクターに書き込むだけでなく、WriteFile を呼び出すとファイル システム メタデータも更新するため、不公平な比較になります。

要するに、「win32 API でのテスト効率」はあまり意味がありません。OS が行う処理の一部をスキップすることもできますが、速度に違いがないか (方法 1)、不公平な比較が行われます (方法 2)。

于 2012-06-28T20:09:30.220 に答える