【问题标题】:(windows) raw write to file without involving win32api(windows)原始写入文件而不涉及win32api
【发布时间】:2012-06-29 02:03:49
【问题描述】:

我想知道是否有一个选项,如果有的话 - 在 Windows 中,如何在不使用 WIN32API 文件处理调用的情况下将原始字节写入文件。

我尝试使用 x86asm 直接文件调用的直接方法,但在此期间没有成功。

【问题讨论】:

  • 你使用什么编程语言?
  • 不管你做什么,它最终都会调用一个win32 API。
  • 我看到的唯一方法是调用适当的系统调用,但请参阅this answer
  • @MarkRansom:不完全正确,它实际上是所有东西(包括 Win32 API)都使用的 NT API。见伊戈尔的回答。在大多数情况下,区别无关紧要,但 FWIW。
  • “x86asm 直接文件调用”是指 IBM PC BIOS 调用,int 13h,还是 MS-DOS 调用,int 21h?您不能在 Windows 应用程序中执行类似的操作。

标签: windows winapi assembly file-io


【解决方案1】:

您可以尝试使用来自 ntdll 的 native API 甚至直接系统调用(int 2eh 或 systenter 指令),但这非常棘手 - 您需要使用内核样式的文件名。

【讨论】:

  • +1,但 OP 应该注意,使用本机 API 而不是 Win32 API 通常不会为您带来任何非常有用的东西。例如,应用相同的锁定和安全规则。
  • Igor,@HarryJohnston 谢谢,原生api是在后台通过win32api还是用自己的方式进行文件写入?
  • 反之亦然:Win32 API (kernel32) 使用本机 API (ntdll) 来完成工作。但最终,一切都在内核中结束。
  • “内核样式文件名”是什么样的?
【解决方案2】:

在回答您的问题之前,让我提一下,在 Windows 中使用 API 写入文件包括以下(简化的)阶段:

  1. 你调用WriteFile (kernel32.dll)
  2. WriteFile 调用 NtWriteFile (ntdll.dll)
  3. NtWriteFile 调用SYSENTER 并且操作进入内核模式
  4. 在内核模式下调用 Ntoskrnl.exe 的 NtWriteFile 函数
  5. 这会将IRP_MJ_WRITE 发送到文件系统驱动程序
  6. 文件系统驱动程序确定应写入哪些扇区并传递给存储驱动程序
  7. 存储驱动程序向硬盘驱动器发送命令以实际将数据写入指定扇区
  8. 硬盘写入数据

与 8 相比,1 到 7 的所有操作都非常快(除非您使用的是 RAM 驱动器或极快的 SSD)

方法 1 - 您可以轻松跳过第 1 步(通过调用NtWriteFile)和第2 步(通过调用SYSENTER - 不容易)。但是,您不会获得任何性能改进,因此没有必要这样做。考虑WriteFile 只是这些的包装器(我认为您不会在消除一个额外的函数调用之后)。

方法 2 - 您可以找出文件占用的扇区并直接写入它们(有效地跳过所有步骤到第 7 步)。为此,您需要打开并锁定卷,通过FSCTL_GET_RETRIEVAL_POINTERS 调用找到目标文件占用的集群,然后在卷句柄上调用WriteFile。 但是这样比较是不公平的,因为文件系统驱动程序不仅会写入数据扇区,还会在调用 WriteFile 时更新文件系统元数据。

底线是 - “测试 win32 API 的效率”没有多大意义。您可以跳过操作系统所做的一些事情,但要么不会给您带来任何速度差异(方法 1),要么会有不公平的比较(方法 2)。

【讨论】:

  • +1。另一组选项涉及编写设备驱动程序,以便您的代码在内核模式下运行。还有一组涉及为 BIOS 编写代码(或其中的一部分)并在 Windows 之外完全运行它。但是,我怀疑这些选项中的任何一个都可以让任何人衡量任何非常有用的东西。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 2012-03-28
  • 1970-01-01
相关资源
最近更新 更多