[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Use CreateFile2 in UWP builds
From: |
Steve Lhomme |
Subject: |
[PATCH] Use CreateFile2 in UWP builds |
Date: |
Tue, 16 May 2023 12:07:01 +0200 |
CreateFileA and CreateFileW are forbidden calls in UWP.
CreateFile2 is close enough, some parameters are passed in a structure
and it requires a WCHAR filename. Given the original stat uses the
"multibyte code page currently in use" [1], the char should be converted
using CP_ACP [2].
[1]
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/stat-functions
[2]
https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar#parameters
---
lib/spawni.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
lib/stat.c | 35 +++++++++++++++++++++++++++++++++++
lib/utime.c | 35 +++++++++++++++++++++++++++++++++++
3 files changed, 119 insertions(+)
diff --git a/lib/spawni.c b/lib/spawni.c
index cc9511fdd8..27397cc688 100644
--- a/lib/spawni.c
+++ b/lib/spawni.c
@@ -402,6 +402,7 @@ open_handle (const char *name, int flags, mode_t mode)
sec_attr.nLength = sizeof (SECURITY_ATTRIBUTES);
sec_attr.lpSecurityDescriptor = NULL;
sec_attr.bInheritHandle = TRUE;
+# if !defined WINAPI_FAMILY ||
WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
HANDLE handle =
CreateFile (rname,
((flags & (O_WRONLY | O_RDWR)) != 0
@@ -427,6 +428,54 @@ open_handle (const char *name, int flags, mode_t mode)
| ((flags & O_SEQUENTIAL ) != 0 ? FILE_FLAG_SEQUENTIAL_SCAN :
0)
| ((flags & O_RANDOM) != 0 ? FILE_FLAG_RANDOM_ACCESS : 0),
NULL);
+# else /* ! WINAPI_PARTITION_DESKTOP */
+ /* Only CreateFile2 is available in UWP builds.
+
<https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2>
+
<https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-file-l1-2-1dll>
*/
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ int wlen = MultiByteToWideChar (CP_ACP, 0, rname, -1, NULL, 0);
+ if (wlen > 0)
+ {
+ WCHAR *wrname = malloca (wlen * sizeof (WCHAR));
+ if (wrname != NULL)
+ {
+ MultiByteToWideChar (CP_ACP, 0, rname, -1, wrname, wlen);
+
+ CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+ createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
+ createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+ /* FILE_FLAG_BACKUP_SEMANTICS is useful for opening directories,
+ which is out-of-scope here. */
+ /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only
+ in case as different) makes sense only when applied to *all*
+ filesystem operations. */
+ /* FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS */
+ createExParams.dwFileFlags = 0
+ | ((flags & O_TEMPORARY) != 0 ? FILE_FLAG_DELETE_ON_CLOSE : 0)
+ | ((flags & O_SEQUENTIAL ) != 0 ? FILE_FLAG_SEQUENTIAL_SCAN :
0)
+ | ((flags & O_RANDOM) != 0 ? FILE_FLAG_RANDOM_ACCESS : 0);
+ createExParams.dwSecurityQosFlags = 0;
+ createExParams.lpSecurityAttributes = &sec_attr;
+ createExParams.hTemplateFile = NULL;
+
+ handle =
+ CreateFile2 (wrname,
+ ((flags & (O_WRONLY | O_RDWR)) != 0
+ ? GENERIC_READ | GENERIC_WRITE
+ : GENERIC_READ),
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
+ ((flags & O_CREAT) != 0
+ ? ((flags & O_EXCL) != 0
+ ? CREATE_NEW
+ : ((flags & O_TRUNC) != 0 ? CREATE_ALWAYS :
OPEN_ALWAYS))
+ : ((flags & O_TRUNC) != 0
+ ? TRUNCATE_EXISTING
+ : OPEN_EXISTING)),
+ &createExParams);
+ freea(wrname);
+ }
+ }
+# endif /* ! WINAPI_PARTITION_DESKTOP */
if (handle == INVALID_HANDLE_VALUE)
switch (GetLastError ())
{
diff --git a/lib/stat.c b/lib/stat.c
index 7987e26583..a8fcc84792 100644
--- a/lib/stat.c
+++ b/lib/stat.c
@@ -197,6 +197,7 @@ rpl_stat (char const *name, struct stat *buf)
{
/* Approach based on the file. */
+# if !defined WINAPI_FAMILY ||
WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/* Open a handle to the file.
CreateFile
<https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea>
@@ -212,6 +213,40 @@ rpl_stat (char const *name, struct stat *buf)
filesystem operations. */
FILE_FLAG_BACKUP_SEMANTICS /* | FILE_FLAG_POSIX_SEMANTICS
*/,
NULL);
+# else /* ! WINAPI_PARTITION_DESKTOP */
+ /* Only CreateFile2 is available in UWP builds.
+
<https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2>
+
<https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-file-l1-2-1dll>
*/
+ HANDLE h = INVALID_HANDLE_VALUE;
+ int wlen = MultiByteToWideChar (CP_ACP, 0, rname, -1, NULL, 0);
+ if (wlen > 0)
+ {
+ WCHAR *wrname = malloca (wlen * sizeof (WCHAR));
+ if (wrname != NULL)
+ {
+ MultiByteToWideChar (CP_ACP, 0, rname, -1, wrname, wlen);
+
+ CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+ createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
+ createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+ /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only
+ in case as different) makes sense only when applied to *all*
+ filesystem operations. */
+ createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS /* |
FILE_FLAG_POSIX_SEMANTICS */;
+ createExParams.dwSecurityQosFlags = 0;
+ createExParams.lpSecurityAttributes = NULL;
+ createExParams.hTemplateFile = NULL;
+
+ h =
+ CreateFile2 (wrname,
+ FILE_READ_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
+ OPEN_EXISTING,
+ &createExParams);
+ freea(wrname);
+ }
+ }
+# endif /* ! WINAPI_PARTITION_DESKTOP */
if (h != INVALID_HANDLE_VALUE)
{
ret = _gl_fstat_by_handle (h, rname, buf);
diff --git a/lib/utime.c b/lib/utime.c
index 3cf1840feb..bc3b253d49 100644
--- a/lib/utime.c
+++ b/lib/utime.c
@@ -86,6 +86,7 @@ _gl_utimens_windows (const char *name, struct timespec ts[2])
DWORD error;
+# if !defined WINAPI_FAMILY ||
WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/* Open a handle to the file.
CreateFile
<https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea>
@@ -101,6 +102,40 @@ _gl_utimens_windows (const char *name, struct timespec
ts[2])
filesystem operations. */
FILE_FLAG_BACKUP_SEMANTICS /* | FILE_FLAG_POSIX_SEMANTICS */,
NULL);
+# else /* ! WINAPI_PARTITION_DESKTOP */
+ /* Only CreateFile2 is available in UWP builds.
+
<https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfile2>
+
<https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-file-l1-2-1dll>
*/
+ HANDLE handle = INVALID_HANDLE_VALUE;
+ int wlen = MultiByteToWideChar (CP_ACP, 0, rname, -1, NULL, 0);
+ if (wlen > 0)
+ {
+ WCHAR *wrname = malloca (wlen * sizeof (WCHAR));
+ if (wrname != NULL)
+ {
+ MultiByteToWideChar (CP_ACP, 0, rname, -1, wrname, wlen);
+
+ CREATEFILE2_EXTENDED_PARAMETERS createExParams;
+ createExParams.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
+ createExParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+ /* FILE_FLAG_POSIX_SEMANTICS (treat file names that differ only
+ in case as different) makes sense only when applied to *all*
+ filesystem operations. */
+ createExParams.dwFileFlags = FILE_FLAG_BACKUP_SEMANTICS /* |
FILE_FLAG_POSIX_SEMANTICS */;
+ createExParams.dwSecurityQosFlags = 0;
+ createExParams.lpSecurityAttributes = NULL;
+ createExParams.hTemplateFile = NULL;
+
+ handle =
+ CreateFile2 (wrname,
+ FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
+ OPEN_EXISTING,
+ &createExParams);
+ freea(wrname);
+ }
+ }
+# endif /* ! WINAPI_PARTITION_DESKTOP */
if (handle == INVALID_HANDLE_VALUE)
{
error = GetLastError ();
--
2.39.2
- [PATCH] Use CreateFile2 in UWP builds,
Steve Lhomme <=