none
Is CreateFile with dwDesiredAccess = 0 faster than with dwDesiredAccess = GENERIC_READ, GENERIC_WRITE, etc.? RRS feed

  • Question

  • The documentation for CreateFile says that if the dwDesiredAccess argument is 0, then 

    the application can query certain metadata such as file, directory, or device attributes without accessing that file or device, even if GENERIC_READ access would have been denied.

    Does calling CreateFile that way perform faster than if dwDesiredAccess is set to a read or write flag?

    Sunday, November 3, 2019 10:43 PM

All replies

  • Nope, that is just saying that you don't need to give the handle GENERIC_READ access if you want to read the file metadata.

    An example of this is:

    #include <Windows.h>
    #include <cstdio>
    
    int wmain()
    {
    	HANDLE file1 = nullptr;
    	HANDLE file2 = nullptr;
    
    	file1 = CreateFileW(L"test.txt", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, nullptr);
    
    	//try to open the file with some kind of desired access
    	//this will fail
    	file2 = CreateFileW(L"test.txt", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, nullptr);
    	if (file2 == INVALID_HANDLE_VALUE)
    	{
    		wprintf(L"Failed to open file: %d\n", GetLastError());
    	}
    
    	//try again saying we don't want to access the file
    	//this will succeed
    	file2 = CreateFileW(L"test.txt", 0, 0, nullptr, OPEN_ALWAYS, 0, nullptr);
    	if (file2 == INVALID_HANDLE_VALUE)
    	{
    		wprintf(L"Failed to open file: %d\n", GetLastError());
    	}
    	else
    	{
    		wprintf(L"File opened successfully\n");
    	}
    
    	//since GetFileSize doesn't read the file but instead
    	//the file metadata then this will work
    	LARGE_INTEGER size{};
    	if (!GetFileSizeEx(file2, &size))
    	{
    		wprintf(L"Failed to obtain file size: %d\n", GetLastError());
    	}
    	else
    	{
    		wprintf(L"File is size %lld\n", size.QuadPart);
    	}
    
    	return 0;
    }

    The first file handle opens the file but it is not shared, meaning that any attempts to open the file for reading or writing after that point will fail. The first attempt to open the file for the second handle will fail giving the sharing violation error, however the second attempt to open the file for the second handle will succeed. Notice how we use 0 for the dwDesiredAccess? This is saying that we are opening it but we don't want to access the file itself. Finally the call to GetFileSizeEx will actually get the file size since this is just reading metadata.

    The output that I get on my system is:

    Failed to open file: 32
    File opened successfully
    File is size 0

    Error 32 is ERROR_SHARING_VIOLATION.

    While I use file sharing as the example here, this should also be true if you get denied access by the file's ACL.


    This is a signature. Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.

    • Edited by Darran Rowe Sunday, November 3, 2019 11:28 PM
    Sunday, November 3, 2019 11:27 PM
  • Hello,

    If your issue is solved, please "Mark as answer" or "Vote as helpful" post to the appropriate answer , so that it will help other members to find solution quickly if they faces similar issue.

    Best Regards,

    Suarez Zhou


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, November 11, 2019 7:05 AM