Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the purpose of the win32 CreateFile2 api call?

They have added a new API call in windows 8 called CreateFile2 which as far as I can tell does exactly the same as the existing CreateFile function only it packages up its parameters somewhat differently.

What has been added to make this necessary, as I can't see anything in the documentation.

like image 771
jcoder Avatar asked Nov 08 '12 11:11

jcoder


People also ask

What is CreateFile?

CreateFile provides for creating a file or device handle that is either synchronous or asynchronous.

Which of the following functions retrieves the file attributes of a given file?

An application can retrieve the file attributes by using the GetFileAttributes or GetFileAttributesEx function. The CreateFile and SetFileAttributes functions can set many of the attributes.


2 Answers

CreateFile actually can do a lot more than just open a file. CreateFile2 was created to both restrict the 'surface area' of the function to just the functionality allowed for UWP apps, -and- because the WACK tool can't really distinguish between 'good' use and 'bad' use of an import function, just that it is being used at all.

The typical pattern I use in my C++ libraries is as follows. I use an RAII pattern for the file handle to support when C++ Exception Handling is used (in addition to just being good modern C++ coding practice):

#include <assert.h>
#include <memory>

struct handle_closer
    { void operator()(HANDLE h) noexcept { assert(h != INVALID_HANDLE_VALUE); if (h) CloseHandle(h); } };

using ScopedHandle = std::unique_ptr<void, handle_closer>;

inline HANDLE safe_handle(HANDLE h) noexcept { return (h == INVALID_HANDLE_VALUE) ? nullptr : h; }

The reason I have safe_handle is because CreateFile and CreateFile2 are defined to return INVALID_HANDLE_VALUE (-1) instead of returning 0 for a failure. Most other Win32 functions that return handles return 0 for a failure, and I've confirmed that there's no case where a '0' is a valid Win32 handle.

For reading I use:

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(
    CreateFile2(szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr)));
#else
ScopedHandle hFile(safe_handle(
    CreateFileW(szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
    FILE_FLAG_SEQUENTIAL_SCAN, nullptr)));
#endif
if (!hFile)
   // Error

It is important to use FILE_SHARE_READ instead of 0 for the dwShareMode parameter for reading. UWP apps don't have exclusive read access to existing files, so calls would fail if you used 'exclusive' share mode (i.e. 0).

And for writing a file:

#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)
ScopedHandle hFile(safe_handle(
    CreateFile2(szFile, GENERIC_WRITE | DELETE, 0, CREATE_ALWAYS, nullptr)));
#else
ScopedHandle hFile(safe_handle(
    CreateFileW(szFile, GENERIC_WRITE | DELETE, 0, nullptr, CREATE_ALWAYS, 0, nullptr)));
#endif
if (!hFile)
    // Error!

For writing I request the DELETE permission because I use SetFileInformationByHandle with FILE_DISPOSITION_INFO to clean up if the file output process fails. See scoped.h.

See Dual-use Coding Techniques for Games for more information.

like image 57
Chuck Walbourn Avatar answered Oct 02 '22 00:10

Chuck Walbourn


Due to the multiplexing of file creation flags, file attribute flags and security QoS flags into a single DWORD (dwFlagsAndAttributes) parameter for CreateFile, there is no way to add any more flags to CreateFile. Additional flags for the create operation must be added to CreateFile2 only. For example FILE_FLAG_OPEN_REQUIRING_OPLOCK flag. This flag is documented FltCreateFile - kernel mode

like image 32
Brans Ds Avatar answered Oct 02 '22 00:10

Brans Ds