【问题标题】:CreateFile and long device nameCreateFile 和长设备名称
【发布时间】:2014-08-09 07:28:15
【问题描述】:

我正在使用CreateFile 打开设备。一切正常,直到设备名称太长。

在文档中说:

在此函数的 ANSI 版本中,名称仅限于 MAX_PATH 个字符。要将此限制扩展到 32,767 个宽字符,请调用函数的 Unicode 版本并在路径前添加“\\?\”。有关详细信息,请参阅命名文件、路径和命名空间。

我正在尝试使用 CreateFileW 并将“\\?\”添加到路径中,但是得到了无效的句柄和

系统找不到指定的路径。

在 GetLastError() 中。

那么,这个技巧是否只对文件名有效,对设备名无效?有没有其他方法可以避免这个问题?

UPD1: 不带前缀的设备名称如下所示:

\\.\devicename\EndsBy:\name1.exe|EndsBy:\name2.exe。

代码:

CreateFileW(path.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0));

【问题讨论】:

  • 你是在字面上加上"\\?\",还是实际上在前面加上"\\\\?\\"
  • 设备名称实际上是什么样的?你的代码是什么样的?
  • @ghostofstandardspast 实际上我在前面加上“\\\\?\\”,还尝试在前面加上“”\\\\?”和其他一些。
  • 有一点要记住,"\\?\" 需要遵循绝对路径。它还将跳过一些规范化步骤,例如处理 ...,或删除尾随的点和空格。
  • 请编辑您的问题并在那里包含您的代码和其他相关信息,而不是在评论中。

标签: c++ winapi visual-c++ file-io


【解决方案1】:

\\? 前缀将路径直接发送到文件系统,无需预处理。

\\. 前缀绕过文件命名空间并使用 Win32 设备命名空间。

它们有不同的用途,不能混在一起。

您可以自己尝试一下。例如,这将打开空设备:

HANDLE hDevice = ::CreateFileW(L"\\\\.\\NUL", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

但如果你将路径更改为L"\\\\?\\\\.\\NUL",它会失败。

要回答您的问题,是的,带有 \\? 前缀的路径仅对文件系统路径有效。

【讨论】:

  • 请注意,您可以打开\\?\NUL 而不是\\.\NUL(或者至少它可以在我的系统上运行);当你可以或不能用问号替换点时,你是否碰巧知道规则是什么?
  • @HarryJohnston 我一直认为这是为了向后兼容。在 DOS 中可以被视为文件的设备(NUL、COM1、LPT1 等)也可以在 NT 中被视为文件。不过,我从未对此进行过详细调查,因此我不知道文件系统驱动程序是否能够识别旧 DOS 设备的硬编码列表,或更通用的设备类别。
【解决方案2】:

一些尝试:

  • 您通常可以替换 \\.\\\?\ ;据我了解,这并不总是有效,但我不知道规则是什么。

  • 如果您使用的是 Windows 8,请尝试使用 CreateFile2\\.\ 格式;该文档没有提到路径长度限制。

  • 尝试联系设备驱动程序的供应商,他们应该已经意识到这将是一个问题,并希望有一个解决方法。

  • 尝试使用DefineDosDevice 为您的长路径创建别名,并使用CreateFile 打开\\.\myalias。我不确定您使用别名的路径的正确语法,但您可以使用QueryDosDevice 查看现有别名以获得指导。我相信你会想要使用DDD_RAW_TARGET_PATH 标志。

  • 如果做不到这一切,您可能需要求助于NtCreateFile。您应该能够使用CreateFile 打开\\.\devicename,然后将该句柄用作调用NtCreateFile 的根目录。缺点是 API 不能保证在未来的 Windows 版本中保持兼容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多