【问题标题】:Is it possible for a child process to read a file which is locked by parent process?子进程是否可以读取被父进程锁定的文件?
【发布时间】:2021-09-03 10:09:34
【问题描述】:

我有一个父进程,它使用CreateFile() 创建一个文件并将其锁定。下面是代码:

m_hWriterLockFile = ::CreateFile("C:\\Test.txt", 
                             GENERIC_READ | GENERIC_WRITE, 
                             0, // exclusive
                             NULL, // default security
                             OPEN_ALWAYS,
                             FILE_ATTRIBUTE_NORMAL,
                             NULL);

现在,我只想让子进程访问这个锁定的文件。我不希望任何其他进程读取此文件。

我创建了一个子进程。下面是示例代码:

// Initialize a security attributes structure.
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = TRUE;
    if (!CreateProcess("FileReader.exe", // I want to invoke this exe
    "C:\\Test.txt",
    &sa,
    NULL,
    TRUE,
    0,
    NULL,
    NULL,
    &si,
    &pi))
{
    std::cout << "Create Process Faild (%d) " << GetLastError() << '\n';
}

很遗憾,我无法实现我的目标,有没有人可以帮助我?有没有其他方法可以实现这一目标?如果需要,我会分享更多信息(代码)。

注意:我没有分享完整代码以缩短帖子。

【问题讨论】:

  • “还有其他方法可以实现吗?” - 可能。但由于您解释的是您的解决方案,而不是您试图解决的真正问题,我们只能猜测。
  • 谢谢。问题是 ChildProcess 无法读取被其父进程锁定的文件。
  • 文件未以任何方式锁定。它刚刚打开,没有任何共享权限。锁定和共享是不同的概念。无论如何,您仍然没有解释您要解决的问题。这只是要求让您当前的解决方案正常工作(这可能适合也可能不适合您的问题)。
  • 如果您只想阻止用户修改文件,那么为什么不用FILE_SHARE_READ 共享权限打开它呢?如上所述,Duplicating the file handle 仅在您实际通过文件句柄访问文件时才有效。据推测,您将文件 name 传递给 WKIX32.EXE,所以这不是一个选项。
  • 一点都不清楚,你在这里真正想解决什么问题。如果您想阻止用户更改注册表,那么您将如何撤消 Windows 附带 regedit.exe 的事实?如果您想阻止用户更改文件系统,那么您打算如何撤消 Windows 附带文件资源管理器的事实?如果人们想把他们的系统变砖,那么他们有所有可用的工具来做到这一点。

标签: winapi visual-c++


【解决方案1】:

这是我的问题的答案:

创建具有可继承句柄的文件并将该句柄传递给子进程。一种简单的方法是将其作为命令行参数传递。我们必须将一个 SECURITY_ATTRIBUTES 结构为 bInheritHandle 指定 TRUE 传递给 CreateFile,并将 TRUE 传递给 CreateProcess 调用的 bInheritHandles 参数。

创建文件

例如:

    SECURITY_ATTRIBUTES sa{ sizeof sa, nullptr, TRUE };
HANDLE hFile = CreateFileA("C:\\Test.txt",
    GENERIC_READ | GENERIC_WRITE,
    0,
    &sa,
    CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL,
    NULL);

子进程:

UINT_PTR uiHandle = reinterpret_cast<UINT_PTR>(hFile);

        sprintf_s(szCmdLine, "\"%s\" %Iu", szExePath, uiHandle);

        if (CreateProcessA(nullptr,
            szCmdLine,
            nullptr,
            nullptr,
            TRUE,
            CREATE_NEW_CONSOLE,
            nullptr,
            nullptr,
            &si,
            &pi))
        {
           CloseHandle(pi.hThread);
           CloseHandle(pi.hProcess);

        }

【讨论】:

  • 这会起作用,不幸的是,创建可继承句柄是非常糟糕的做法,因为它们与 每个 子进程共享,而不仅仅是您想要共享的那个。最好遵循文档说明“应用程序可以使用带有PROC_THREAD_ATTRIBUTE_HANDLE_LIST 参数的UpdateProcThreadAttributeList 函数来提供由特定进程继承的句柄列表。”并明确列出每个可继承的句柄。
猜你喜欢
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 2011-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多