CreateFile和长设备名称

时间:2014-06-18 21:11:45

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

我使用CreateFile打开设备。一切都很好,直到设备名称太长。

在文件中说:

  

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

我尝试使用CreateFileW并预先添加" \\?\"到路径,但得到无效的句柄和

  

系统找不到指定的路径。

GetLastError()中的

那么,这个技巧是仅对文件名有效,而不是对设备名有效吗?还有其他方法可以避免这个问题吗?

UPD1: 没有前置的设备名称如下所示:

  

\\?\设备名\ 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));

2 个答案:

答案 0 :(得分:3)

\\?前缀直接将路径发送到文件系统而不进行预处理。

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

它们有不同的目的,不能混合在一起。

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

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

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

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

答案 1 :(得分:2)

有些事情要尝试:

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

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

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

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

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