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

201 views Asked by At

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.

2

There are 2 answers

0
xMRi On BEST ANSWER

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.

0
YangXiaoPo-MSFT On

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 <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)
        {
            // File will be deleted upon CloseHandle.
            _tprintf(TEXT("SetFileInformationByHandle marked tempfile for deletion\n"));

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

        CloseHandle(hFile);

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