但是很明显,GetFileAttributes()就算通过了也能成功
路径无效。
这是错误的。如果路径真的无效 - GetFileAttributes 返回适当的错误(ERROR_INVALID_NAME 或 ERROR_FILE_NOT_FOUND 通常)。也不需要检查ERROR_SHARING_VIOLATION 和ERROR_ACCESS_DENIED,以防GetFileAttributes 返回INVALID_FILE_ATTRIBUTES。因为win32转换为ERROR_ACCESS_DENIED不仅STATUS_ACCESS_DENIED还有许多其他不相关的状态——更正确的使用NtQueryAttributesFile。也存在无证
extern "C" NTSYSAPI BOOLEAN NTAPI RtlDoesFileExists_U( _In_ PWSTR FileName );
执行这项工作(内部调用 NtQueryAttributesFile 并检查 STATUS_SHARING_VIOLATION 和 STATUS_ACCESS_DENIED)
在 api 返回之后 - 文件已经可以被删除(或创建) - 因为结果返回值可能已经是错误的。如果我们需要一些文件/文件夹,那么通常 - 无需尝试检查,而是创建或打开它。或在此操作中出错
但实际上你的问题不在GetFileAttributes,而是在win32到nt路径转换。
您认为路径 D:/test../../../../../../.. 是错误的。但系统认为不是。系统使用的RtlDosPathNameToNtPathName_U_WithStatus(或相关)将win32路径转换为nt。如果用你的路径测试这个 api,这给出:
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:\ 和 \??\<X>:\ 因此系统将其转换为驱动器上的根文件夹。并且这个文件夹存在。