在this post中,建议使用GetFileAttributes()
检查目录是否存在。但是显然,GetFileAttributes()
即使传递了无效路径也可以成功。
例如,假设当前目录为D:/test
,但是尽管传递给INVALID_FILE_ATTRIBUTES
的路径显然不存在,但执行以下操作仍不会返回GetFileAttributes()
,因为有办法..
级别过多:
DWORD attrs = GetFileAttributes("../../../../../../..");
那么我该如何检测路径是否确实存在?
答案 0 :(得分:1)
但是显然
GetFileAttributes()
即使成功通过也可以成功 无效的路径。
这是错误的。如果路径确实无效-GetFileAttributes
返回适当的错误(通常是ERROR_INVALID_NAME
或ERROR_FILE_NOT_FOUND
)。也不需要在ERROR_SHARING_VIOLATION
返回ERROR_ACCESS_DENIED
的情况下检查GetFileAttributes
和INVALID_FILE_ATTRIBUTES
。因为win32不仅转换为ERROR_ACCESS_DENIED
,而且转换为许多其他无关的状态-更正确地使用NtQueryAttributesFile
。也存在未记录的
STATUS_ACCESS_DENIED
执行此操作的代码(内部调用NtQueryAttributesFile
,并同时检查extern "C" NTSYSAPI BOOLEAN NTAPI RtlDoesFileExists_U( _In_ PWSTR FileName );
和STATUS_SHARING_VIOLATION
)
也在api返回之后-已经可以删除(或创建)文件-因为返回的结果值可能已经错误。所以通常,如果我们需要一些文件/文件夹-无需尝试检查,但可以创建或打开它。或在此操作中出错
但是实际上您的问题不是在STATUS_ACCESS_DENIED
中,而是在win32到nt路径转换中。
您认为路径GetFileAttributes
是错误的。但是系统认为不是。系统用于将win32路径转换为nt的D:/test../../../../../../..
(或相关)。如果使用您的路径测试此api,则给出:
RtlDosPathNameToNtPathName_U_WithStatus
UNICODE_STRING us;
if (0 <= RtlDosPathNameToNtPathName_U_WithStatus(L"D:/test../../../../../../..", &us, 0, 0))
{
DbgPrint("%wZ\n", &us);
RtlFreeUnicodeString(&us);
}
if (0 <= RtlDosPathNameToNtPathName_U_WithStatus(L"../../../../../../..", &us, 0, 0))
{
DbgPrint("%wZ\n", &us);
RtlFreeUnicodeString(&us);
}
和\??\D:\
,因此系统将其转换为驱动器上的根文件夹。并且该文件夹存在。