CreateFile 是否与相同或不同进程打开的同一文件的其他句柄相关?

huangapple go评论46阅读模式
英文:

Is it relevant for CreateFile whether other handles to the same file have been opened by the same or a different process?

问题

在Windows上处理文件系统文件时,特别是使用CreateFile API时:

关于访问共享,即有多个独立的CreateFile调用来打开 相同的文件,可能使用不同的标志和共享模式,是否有任何影响 文件访问是从同一进程内部还是不同进程内部执行

也就是说,一旦有人使用CreateFile(..., FILE_SHARE_READ, ...)打开了一个文件,就不应该能够以GENERIC_WRITE访问权限打开同一个文件。不同的调用是否来自同一进程,还是来自不同的进程,是否重要?

到目前为止,我的印象是,对于独立的CreateFile调用来说,进程边界对于访问同一文件并不重要。 (它们对于句柄继承等方面很重要。)

但是文档中包含了一些如下的信息:

> 为了使一个进程能够在另一个进程打开文件或设备的同时共享文件或设备,使用一个或多个兼容的组合值。有关此参数与dwDesiredAccess参数的有效组合的更多信息,请参阅"Creating and Opening Files"。

这并不一定令人信服。

英文:

When working with filesystem files on Windows, and specifically with the CreateFile API:

With regard to access sharing, that is having multiple, independent, CreateFile calls to open the same file, possibly with different flags and sharing modes, does it matter in any way whether file access is performed from within the same process or from a different process?

That is, once someone has opened a file with CreateFile(..., FILE_SHARE_READ, ...), noone should be able to open the same file with GENERIC_WRITE access. Does it matter whether different calls originate from within the same process, or from different processes?

My impression so far is that process boundaries do not matter for independent CreateFile calls to the same file. (They do matter for handle inheritance, etc.)

But that docs contain such gems as:

> To enable a process to share a file or device while another process
> has the file or device open, use a compatible combination of one or
> more of the following values. For more information about valid
> combinations of this parameter with the dwDesiredAccess parameter, see
> Creating and Opening Files.

which doesn't exactly inspire confidence.

答案1

得分: 3

不。通常,对文件的访问限制不关心它们是从相同的进程还是不同的进程执行的。

文件共享标志始终以相同的方式工作。

英文:

No. In general such access restrictions to files don't care if they are done from the same or different process.

The file sharing flags work always the same way.

答案2

得分: 1

如@xMRi所回答的,无论第二次对CreateFile的有效调用是否在同一进程中都无关紧要。

创建和打开文件

说明了使用不同访问模式和共享模式(dwDesiredAccess、dwShareMode)进行两次CreateFile调用的有效组合。不管CreateFile调用的顺序如何。

以下是一个示例:

#include <Windows.h>
#include <Tchar.h>
int main()
{
    //...
    HANDLE hFile1 = CreateFile(TEXT("tempfile"),
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        CREATE_ALWAYS,
        0,
        NULL);

    HANDLE hFile2 = CreateFile(TEXT("tempfile"),
        GENERIC_READ,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        0,
        NULL);

    if (hFile1 != INVALID_HANDLE_VALUE && hFile2 != INVALID_HANDLE_VALUE)
    {
        HANDLE hFile = hFile1;
        //HANDLE hFile = hFile2;
        FILE_BASIC_INFO fdi{};
        fdi.FileAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_NORMAL;

        BOOL fResult = SetFileInformationByHandle(hFile,
            FileBasicInfo,
            &fdi,
            sizeof(FILE_BASIC_INFO));

        if (fResult)
        {
            // 文件将在CloseHandle时被删除。
            _tprintf(TEXT("SetFileInformationByHandle标记了tempfile以进行删除\n"));

            // ... 
            // 现在可以使用文件存储临时数据,它将在CloseHandle或应用程序终止时自动删除。
            // ...
        }
        else
        {
            _tprintf(TEXT("错误 %lu: SetFileInformationByHandle无法标记tempfile以进行删除\n"),
                GetLastError());
        }

        CloseHandle(hFile);

        // 此时,文件已关闭并由系统删除。
    }
    else
    {
        _tprintf(TEXT("错误 %lu: 无法创建tempfile\n"),
            GetLastError());
    }
    //...
}
英文:

As @xMRi answered, it does not matter if the Valid second call to CreateFile is in the same process or not.
Creating and Opening Files

> illustrates the valid combinations of two calls to CreateFile using
> various access modes and sharing modes (dwDesiredAccess, dwShareMode
> respectively). It does not matter in which order the CreateFile calls
> are made.

An example to illustrate.

#include &lt;Windows.h&gt;
#include &lt;Tchar.h&gt;
int main()
{
    //...
    HANDLE hFile1 = CreateFile(TEXT(&quot;tempfile&quot;),
        GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ,
        NULL,
        CREATE_ALWAYS,
        0,
        NULL);

    HANDLE hFile2 = CreateFile(TEXT(&quot;tempfile&quot;),
        GENERIC_READ,
        FILE_SHARE_READ| FILE_SHARE_WRITE,
        NULL,
        OPEN_ALWAYS,
        0,
        NULL);

    if (hFile1 != INVALID_HANDLE_VALUE &amp;&amp; hFile2 != INVALID_HANDLE_VALUE)
    {
        HANDLE hFile = hFile1;
        //HANDLE hFile = hFile2;
        FILE_BASIC_INFO fdi{};
        fdi.FileAttributes = FILE_ATTRIBUTE_TEMPORARY | FILE_ATTRIBUTE_NORMAL;

        BOOL fResult = SetFileInformationByHandle(hFile,
            FileBasicInfo,
            &amp;fdi,
            sizeof(FILE_BASIC_INFO));

        if (fResult)
        {
            // File will be deleted upon CloseHandle.
            _tprintf(TEXT(&quot;SetFileInformationByHandle marked tempfile for deletion\n&quot;));

            // ... 
            // Now use the file for whatever temp data storage you need,
            // it will automatically be deleted upon CloseHandle or 
            // application termination.
            // ...
        }
        else
        {
            _tprintf(TEXT(&quot;error %lu:  SetFileInformationByHandle could not mark tempfile for deletion\n&quot;),
                GetLastError());
        }

        CloseHandle(hFile);

        // At this point, the file is closed and deleted by the system.
    }
    else
    {
        _tprintf(TEXT(&quot;error %lu:  could not create tempfile\n&quot;),
            GetLastError());
    }
    //...
}

huangapple
  • 本文由 发表于 2023年2月8日 20:30:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385820.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定