bug-gnulib
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]