【问题标题】:Why does `ReadFile()` return error 87?为什么 `ReadFile()` 返回错误 87?
【发布时间】:2015-07-09 17:01:10
【问题描述】:

下面是Java代码。

HANDLE h = kernel32.CreateFile("\\\\.\\d:",
                               kernel32.GENERIC_READ 
                               | kernel32.GENERIC_WRITE, 
                               0, null, kernel32.OPEN_EXISTING,
                               0, null);

IntByReference nbread = new IntByReference();   

ByteBuffer b = ByteBuffer.allocate(48);

boolean result = kernel32.ReadFile(h, b, b.capacity(), nbread, null);

System.out.println(kernel32.GetLastError());

它给出了错误87 (Invalid parameter)

可能是什么问题?

【问题讨论】:

  • 第 87 行是哪一行?
  • 无效参数很可能是第一个参数。如果您尝试打开 D: 驱动器的根目录,请改用 "D:/",并在 that 调用之后检查错误代码。您还应该确保 48 字节足以读取您正在阅读的任何文件的内容。
  • 调用GetLastError() 是无效的,除非您确实遇到了错误,并且这里没有证据表明您这样做了。
  • @technomage: "\\\\.\\d:" 是CreateFile() 的完全有效的路径字符串:"打开卷或可移动媒体驱动器(例如,软盘驱动器或闪存拇指驱动器)时),lpFileName 字符串应为以下形式:"\\.\X:"。不要使用尾部反斜杠 (),它表示驱动器的根目录。"更有可能发生的是CreateFile() 失败并且无效的HANDLE 被传递给ReadFile()。假设 ReadFile() 甚至首先失败(根据 EJP 的评论),因为此代码中没有错误检查。

标签: java winapi jna


【解决方案1】:

您没有检查错误。你必须把它说对。该文档解释了如何。阅读文档是无可替代的。

检查返回值。比较 h 和 INVALID_HANDLE_VALUE。该值表示失败,如果是这样,并且只有这样,请致电GetLastError。

文档说明了有关打开卷以供直接访问的内容:

必须满足以下要求才能使此类调用成功:

  • 调用者必须具有管理权限。有关详细信息,请参阅以特殊权限运行。
  • dwCreationDisposition 参数必须具有 OPEN_EXISTING 标志。
  • 打开卷或软盘时,dwShareMode 参数必须具有 FILE_SHARE_WRITE 标志。

您没有达到最终要求。而且可能不是第一个。

至于对ReadFile 的调用,您没有检查返回值。文档说:

返回值

如果函数成功,则返回值非零 (TRUE)。

如果函数失败或异步完成,则返回值为零 (FALSE)。要获取扩展错误信息,请调用 GetLastError 函数。

您还需要确保执行扇区对齐读取。你没有这样做。

您对GetLastError 的调用也是错误的。它们需要修复。看到这个问题:How to make GetLastError reliably work with JNA?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-24
    • 1970-01-01
    相关资源
    最近更新 更多