【问题标题】:ReOpenFile Windows API fails with "error invalid name" when reopening a file in C:\windows\system32在 C:\windows\system32 中重新打开文件时,ReOpenFile Windows API 失败并出现“错误无效名称”
【发布时间】:2020-09-28 21:27:18
【问题描述】:

我想知道当 CreateFile 成功打开文件时,是否有人可以解释 ReOpenFile 失败并显示“error-invalid-name”的原因。

详情如下:

我使用 CreateFile 打开一个文件 C:\Windows\system32\unit_test.txt,它可以正常打开。当我稍后尝试使用 ReOpenFile 更改权限时,失败并显示错误代码 123(十进制),调试器显示为“ERROR_INVALID_NAME:文件名目录名称或卷标语法不正确”。

如果将“unit_test.txt”放在更常规的目录中,ReOpenFile 可以正常工作。 ReOpenFile 不采用文件名参数,而是采用从 CreateFile 返回的句柄。 我写的代码没有请求额外的权限,也没有冲突的权限(这会导致不同的错误),所以我很好奇为什么 CreateFile 会成功而 ReOpenFile 在这种情况下会失败。

诚然,将文件放置在 Windows\System32 中是偶然的,但如果我能偶然做到这一点,那么我们软件的用户可能会偶然发现同样的问题。

我已经使用相同的函数调用创建了这个示例,但我不能让它失败。它基本上显示了产生错误的原因:

int main ()
{
HANDLE h1 = ::CreateFile (_T("c:\\windows\\system32\\test.txt"),
                          GENERIC_READ | GENERIC_WRITE | DELETE,
                          FILE_SHARE_READ,
                          nullptr,
                          CREATE_ALWAYS,
                          FILE_FLAG_SEQUENTIAL_SCAN,
                          NULL);

if (h1 != INVALID_HANDLE_VALUE)
{
    HANDLE h2 = ::ReOpenFile (h1,
                              GENERIC_READ,
                              FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
                              FILE_FLAG_SEQUENTIAL_SCAN);

    ::CloseHandle (h1);

    if (h2 != INVALID_HANDLE_VALUE)
        ::CloseHandle (h2);
}
}

【问题讨论】:

  • 如何提取minimal reproducible example 并将其作为问题的一部分提供?
  • 对某些 Windows 文件夹应用了各种保护和间接方法。当这些文件夹在其他文件夹上正常工作时,这可能会导致 API 调用在这些文件夹中失败。
  • 您是否检查过CreateFile() 没有任何错误?
  • 是 - CreateFile 返回了一个有效的句柄
  • 如果进程可以在“%SystemRoot%\System32”中创建文件,那么它可以相对于句柄重新打开它,除非被数据访问共享模式或文件的删除状态阻止。这里发生了其他事情,但没有重现问题的代码,只有具有神秘力量的人才能帮助您。

标签: c++ windows createfile system32


【解决方案1】:

当我将我的“最小示例”重新编译为 32 位而不是 64 位时,它就开始出现 ReOpenFile 失败的问题。

这让我看到了一篇解释这种情况的文章:Accessing files from System32 directory using 32 bit application on 64 bit machine

引用文章: " 如您所见,在运行 64 位版本的 Windows Server 2003 或 Windows XP 的计算机上,32 位应用程序无法访问以下文件夹:%WinDir%\System32

出现此行为是因为 Windows 64 位 (WOW64) 上的 Windows 提供文件系统重定向。 在 64 位版本的 Windows Server 2003 或 Windows XP 中,%WinDir%\System32 文件夹是为 64 位应用程序保留的。当 32 位应用程序尝试访问 System32 文件夹时,访问被重定向到以下文件夹:

%WinDir%\SysWOW64

默认启用文件系统重定向。

作为一种临时解决方案,32 位应用程序可以通过将 %windir%\Sysnative 替换为 %windir%\System32 来访问本机系统目录。 WOW64 将 Sysnative 识别为用于指示文件系统不应重定向访问的特殊别名。 "

遗憾的是,32 位应用程序无法完全访问该目录这一事实并不能阻止 Microsoft Windows 在某些我不完全了解的情况下将其设置为应用程序的工作目录(可能与沙盒有关) Windows 的最新版本)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-07
    • 1970-01-01
    • 2020-04-22
    • 2013-01-25
    • 1970-01-01
    • 2015-12-14
    • 2013-11-03
    • 1970-01-01
    相关资源
    最近更新 更多