Hramovnik Hramovnik -4 years ago 121
C++ Question

UWP CreateFile2 ERROR_ACCESS_DENIED on "NUL"

I am trying to migrate some old stuff from WP8 to Universal Windows Platform with C++ extentions. The problems starts when I'm trying to use this code

HANDLE h = CreateFile(L"NUL", 0, 0, NULL, OPEN_ALWAYS, 0, NULL);


h is -1, and last error is 5 (ERROR_ACCESS_DENIED)
CreateFile is redefined that way:

HANDLE CreateFile(
_In_ LPCWSTR lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile
)
{
CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extendedParameters.dwFileAttributes = dwFlagsAndAttributes & 0x0003FFF7;
extendedParameters.dwFileFlags = dwFlagsAndAttributes & 0xFF3C0000;
extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParameters.lpSecurityAttributes = lpSecurityAttributes;
extendedParameters.hTemplateFile = hTemplateFile;
return CreateFile2(lpFileName, dwDesiredAccess, dwShareMode,
dwCreationDisposition, &extendedParameters);
}


This code works on Windows Phone 8, but doesn't work on Windows 10. So, the question is - what am I doing wrong.

Answer Source

There are two problems here. Firstly, as it is described in CreateFile2 function:

When called from a Windows Store app, CreateFile2 is simplified. You can open only files or directories inside the ApplicationData.LocalFolder or Package.InstalledLocation directories. You can't open named pipes or mailslots or create encrypted files (FILE_ATTRIBUTE_ENCRYPTED).

So while using CreateFile2 function in UWP, we need to provide a path inside the ApplicationData.LocalFolder or Package.InstalledLocation directories as the lpFileName parameter instead of just a file name like:

Windows::Storage::StorageFolder^ localFolder = Windows::Storage::ApplicationData::Current->LocalFolder;
String^ path = localFolder->Path;
path += L"\\Test.txt";

CREATEFILE2_EXTENDED_PARAMETERS extendedParams;
extendedParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extendedParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
extendedParams.dwFileFlags = FILE_FLAG_SEQUENTIAL_SCAN;
extendedParams.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extendedParams.lpSecurityAttributes = NULL;
extendedParams.hTemplateFile = NULL;

HANDLE fileHandle = CreateFile2(path->Data(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, OPEN_ALWAYS, &extendedParams);

The second one is that we can't use NUL as the file name. See Naming Files, Paths, and Namespaces:

Do not use the following reserved names for the name of a file:

CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, and LPT9.
Also avoid these names followed immediately by an extension; for example, NUL.txt is not recommended. For more information, see Namespaces.

So, you can change your code like the following then there should be no error.

Windows::Storage::StorageFolder^ localFolder = Windows::Storage::ApplicationData::Current->LocalFolder;
String^ path = localFolder->Path;
path += L"\\Test.txt"; //Replace with the name you want to use.

HANDLE h = CreateFile(path->Data(), 0, 0, NULL, OPEN_ALWAYS, 0, NULL);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download