我使用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));
答案 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版本中保持兼容。