【问题标题】:How to check if relative path exists如何检查相对路径是否存在
【发布时间】:2020-02-28 23:51:47
【问题描述】:

this post 中建议使用GetFileAttributes() 来检查目录是否存在。但显然,GetFileAttributes() 即便传递了无效路径也能成功。

例如,假设当前目录是D:/test,但执行以下操作仍然不会返回INVALID_FILE_ATTRIBUTES,尽管传递给GetFileAttributes() 的路径显然不存在,因为@987654327 的级别太多了@:

DWORD attrs = GetFileAttributes("../../../../../../..");

那么如何检测路径是否真的存在呢?

【问题讨论】:

  • 问题问错了。 GetFileAttributes 工作正常,这里是检查的最佳解决方案。但是如何将相对名称转换为 nt-path ?这里的问题不在GetFileAttributes 中,而是在路径对话中。试试RtlDosPathNameToNtPathName_U_WithStatus,看看是什么转换了你的"../../../../../../.."。到 \??\D:\ 无论如何

标签: winapi


【解决方案1】:

但是很明显,GetFileAttributes()就算通过了也能成功 路径无效。

这是错误的。如果路径真的无效 - GetFileAttributes 返回适当的错误(ERROR_INVALID_NAMEERROR_FILE_NOT_FOUND 通常)。也不需要检查ERROR_SHARING_VIOLATIONERROR_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_VIOLATIONSTATUS_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:\\??\&lt;X&gt;:\ 因此系统将其转换为驱动器上的根文件夹。并且这个文件夹存在。

【讨论】:

  • 所以我必须手动检查.. 的级别是否对当前目录有效,因为Windows 显然选择忽略根卷之外的所有.. 并将其视为有效路径?
  • @Andreas - 我不这么认为。在这种情况下,您的转换将与提供的系统冲突。你的最终目标是什么?
  • 对,操作系统之间似乎有某种约定,即忽略多余的 ..,并且这样的构造不是无效路径,因为 Linux 和 macOS 显示与 Windows 相同的行为所以这似乎是我不知道的某种约定。我认为超出范围的.. 会构建一条非法路径,但显然情况并非如此,所以我可以保持原样。
猜你喜欢
  • 2020-05-08
  • 1970-01-01
  • 1970-01-01
  • 2014-03-09
  • 2011-10-16
  • 1970-01-01
  • 2011-11-25
  • 2011-02-04
  • 1970-01-01
相关资源
最近更新 更多