【问题标题】:UWP CreateFile2 ERROR_ACCESS_DENIED on "NUL"UWP CreateFile2 ERROR_ACCESS_DENIED on "NUL"
【发布时间】:2017-11-15 09:36:07
【问题描述】:

我正在尝试将一些旧的东西从 WP8 迁移到具有 C++ 扩展的通用 Windows 平台。当我尝试使用此代码时,问题就开始了

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

h 为 -1,最后一个错误为 5 (ERROR_ACCESS_DENIED) CreateFile 是这样重新定义的:

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);
}

此代码适用于 Windows Phone 8,但不适用于 Windows 10。所以,问题是 - 我做错了什么。

【问题讨论】:

  • 您正在请求以独占模式打开文件(dwShareMode 为 0)。这是故意的吗?它是否也会因不那么严格的共享模式而失败?
  • 是的,如果我写 FILE_SHARE_WRITE,或 FILE_SHARE_READ,或 FILE_SHARE_WRITE | 它会做同样的事情FILE_SHARE_READ。我认为,问题隐藏在应用程序的某种权限中,但我根本没有找到任何解决方案。
  • 根据the appx manifest 中请求的功能对设备访问进行严格检查。有点怀疑它们是否涵盖了传统的 MS-Dos 设备,但值得一试。

标签: c++ uwp windows-10-universal createfile


【解决方案1】:

这里有两个问题。首先,正如CreateFile2 function中所述:

当从 Windows 应用商店应用调用时,CreateFile2 被简化。您只能打开 ApplicationData.LocalFolderPackage.InstalledLocation 目录中的文件或目录。您无法打开命名管道或邮槽或创建加密文件 (FILE_ATTRIBUTE_ENCRYPTED)。

因此,在 UWP 中使用 CreateFile2 函数时,我们需要提供 ApplicationData.LocalFolderPackage.InstalledLocation 目录内的路径作为 lpFileName 参数,而不仅仅是像这样的文件名:

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);

第二个是我们不能使用NUL作为文件名。见Naming Files, Paths, and Namespaces

不要使用以下保留名称作为文件名:

CON、PRN、AUX、NUL、COM1、COM2、COM3、COM4、COM5、COM6、COM7、COM8、COM9、LPT1、LPT2、LPT3、LPT4、LPT5、LPT6、LPT7、 LPT8 和 LPT9。
还要避免这些名称后跟扩展名;例如,不推荐使用 NUL.txt。如需更多信息,请参阅Namespaces

所以,你可以像下面这样更改你的代码,那么应该没有错误。

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);

【讨论】:

  • 问题是我需要将文件创建为“NUL”。不过谢谢,您的信息很有帮助。
  • 使用CreateFile2如何打开设备的符号链接(例如“\Device\00000011”)?
  • @RDX 抱歉,我不熟悉硬件或设备开发,建议您提出一个新问题,看看是否有人可以帮助您解决此问题。
猜你喜欢
  • 1970-01-01
  • 2016-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多