[PATCH 1/2] stat: use a CHAR instead of TCHAR with GetFinalPathNameByHandleA

2020-05-19 Thread Steve Lhomme
The GetProcAddress uses the ANSI version of the API so the proper type for the
string is LPSTR, as found here:

https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlea
---
 lib/stat-w32.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 296ccf18c..106d25120 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -52,7 +52,7 @@ static GetFileInformationByHandleExFuncType 
GetFileInformationByHandleExFunc = N
 #endif
 /* GetFinalPathNameByHandle was introduced only in Windows Vista.  */
 typedef DWORD (WINAPI * GetFinalPathNameByHandleFuncType) (HANDLE hFile,
-   LPTSTR lpFilePath,
+   LPSTR lpFilePath,
DWORD lenFilePath,
DWORD dwFlags);
 static GetFinalPathNameByHandleFuncType GetFinalPathNameByHandleFunc = NULL;
-- 
2.26.2




[PATCH 2/2] stat: do not use LoadLibrary when built for Windows Store apps

2020-05-19 Thread Steve Lhomme
LoadLibrary is forbidden in such apps (can only load DLLs from within the app
package).
The API entries are available to all apps linking with the Windows API as found
here:
https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis

windowsapp.lib (and mincore.lib for Windows 8) are both available in MinGW as
well.

GetFinalPathNameByHandleA is only allowed in Win10 UWP apps
GetFileInformationByHandleEx is allowed in Win8 and Win10 UWP apps.
---
 lib/stat-w32.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 106d25120..6900dfcf5 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -61,6 +61,15 @@ static BOOL initialized = FALSE;
 static void
 initialize (void)
 {
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+  /* LoadLibrary not allowed but the functions are available with the windows 
runtime */
+#if _GL_WINDOWS_STAT_INODES == 2
+  GetFileInformationByHandleExFunc = GetFileInformationByHandleEx;
+#endif
+#if _WIN32_WINNT >= 0x0A00 /* _WIN32_WINNT_WIN10 */
+  GetFinalPathNameByHandleFunc = GetFinalPathNameByHandleA;
+#endif
+#else /* WINAPI_PARTITION_DESKTOP */
   HMODULE kernel32 = LoadLibrary ("kernel32.dll");
   if (kernel32 != NULL)
 {
@@ -71,6 +80,7 @@ initialize (void)
   GetFinalPathNameByHandleFunc =
 (GetFinalPathNameByHandleFuncType) GetProcAddress (kernel32, 
"GetFinalPathNameByHandleA");
 }
+#endif /* WINAPI_PARTITION_DESKTOP */
   initialized = TRUE;
 }
 
-- 
2.26.2




[PATCH] gettimeofday: do not use LoadLibrary when built for Windows Store apps

2020-05-19 Thread Steve Lhomme
LoadLibrary is forbidden in such apps (can only load DLLs from within the app
package).
The API entries are available to all apps linking with the Windows API as found
here:
https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis

windowsapp.lib (and mincore.lib for Windows 8) are both available in MinGW as
well.

GetSystemTimePreciseAsFileTime is only allowed in Win10 UWP apps.
---
 lib/gettimeofday.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index 19804793a..087f7eada 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -45,12 +45,17 @@ static BOOL initialized = FALSE;
 static void
 initialize (void)
 {
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && _WIN32_WINNT >= 
0x0A00 /* _WIN32_WINNT_WIN10 */
+  /* LoadLibrary not allowed but the functions are available with the windows 
runtime */
+  GetSystemTimePreciseAsFileTimeFunc = GetSystemTimePreciseAsFileTime;
+#else /* WINAPI_PARTITION_DESKTOP */
   HMODULE kernel32 = LoadLibrary ("kernel32.dll");
   if (kernel32 != NULL)
 {
   GetSystemTimePreciseAsFileTimeFunc =
 (GetSystemTimePreciseAsFileTimeFuncType) GetProcAddress (kernel32, 
"GetSystemTimePreciseAsFileTime");
 }
+#endif /* WINAPI_PARTITION_DESKTOP */
   initialized = TRUE;
 }
 
-- 
2.26.2




[PATCH] stat: remove _GL_WINDOWS_STAT_INODES == 2 support

2020-05-19 Thread Steve Lhomme
It may be outdated code, the value is never 2.

sys_types_h.m4 sets it to 0 or via gl_WINDOWS_STAT_INODES.
gl_WINDOWS_STAT_INODES sets it to 1 if compiled via mingw* and 0 otherwise.
---
 lib/stat-w32.c | 107 +++--
 lib/stat.c |   9 
 lib/sys_types.in.h |  25 ---
 3 files changed, 6 insertions(+), 135 deletions(-)

diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 6900dfcf5..2cbcdca8b 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -42,14 +42,6 @@
 #define GetProcAddress \
   (void *) GetProcAddress
 
-#if _GL_WINDOWS_STAT_INODES == 2
-/* GetFileInformationByHandleEx was introduced only in Windows Vista.  */
-typedef DWORD (WINAPI * GetFileInformationByHandleExFuncType) (HANDLE hFile,
-   
FILE_INFO_BY_HANDLE_CLASS fiClass,
-   LPVOID lpBuffer,
-   DWORD 
dwBufferSize);
-static GetFileInformationByHandleExFuncType GetFileInformationByHandleExFunc = 
NULL;
-#endif
 /* GetFinalPathNameByHandle was introduced only in Windows Vista.  */
 typedef DWORD (WINAPI * GetFinalPathNameByHandleFuncType) (HANDLE hFile,
LPSTR lpFilePath,
@@ -63,9 +55,6 @@ initialize (void)
 {
 #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
   /* LoadLibrary not allowed but the functions are available with the windows 
runtime */
-#if _GL_WINDOWS_STAT_INODES == 2
-  GetFileInformationByHandleExFunc = GetFileInformationByHandleEx;
-#endif
 #if _WIN32_WINNT >= 0x0A00 /* _WIN32_WINNT_WIN10 */
   GetFinalPathNameByHandleFunc = GetFinalPathNameByHandleA;
 #endif
@@ -73,10 +62,6 @@ initialize (void)
   HMODULE kernel32 = LoadLibrary ("kernel32.dll");
   if (kernel32 != NULL)
 {
-#if _GL_WINDOWS_STAT_INODES == 2
-  GetFileInformationByHandleExFunc =
-(GetFileInformationByHandleExFuncType) GetProcAddress (kernel32, 
"GetFileInformationByHandleEx");
-#endif
   GetFinalPathNameByHandleFunc =
 (GetFinalPathNameByHandleFuncType) GetProcAddress (kernel32, 
"GetFinalPathNameByHandleA");
 }
@@ -152,12 +137,7 @@ _gl_fstat_by_handle (HANDLE h, const char *path, struct 
stat *buf)
  or through
  GetFileInformationByHandle
  

- 

- or through
- GetFileInformationByHandleEx with argument FileBasicInfo
- 

- 

- The latter requires -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher.  */
+ 

 */
   BY_HANDLE_FILE_INFORMATION info;
   if (! GetFileInformationByHandle (h, ))
 goto failed;
@@ -174,60 +154,9 @@ _gl_fstat_by_handle (HANDLE h, const char *path, struct 
stat *buf)
  GetFileInformationByHandle
  

  

- as 64 bits, or through
- GetFileInformationByHandleEx with argument FileIdInfo
- 

- 

- as 128 bits.
- The latter requires -D_WIN32_WINNT=_WIN32_WINNT_WIN8 or higher.  */
-  /* Experiments show that GetFileInformationByHandleEx does not provide
- much more information than GetFileInformationByHandle:
-   * The dwVolumeSerialNumber from GetFileInformationByHandle is equal
- to the low 32 bits of the 64-bit VolumeSerialNumber from
- GetFileInformationByHandleEx, and is apparently sufficient for
- identifying the device.
-   * The nFileIndex from GetFileInformationByHandle is equal to the low
- 64 bits of the 128-bit FileId from GetFileInformationByHandleEx,
- and the high 64 bits of this 128-bit FileId are zero.
-   * On a FAT file system, GetFileInformationByHandleEx fails with 
error
- ERROR_INVALID_PARAMETER, whereas GetFileInformationByHandle
- succeeds.
-   * On a CIFS/SMB file system, GetFileInformationByHandleEx fails with
- error ERROR_INVALID_LEVEL, whereas GetFileInformationByHandle
- succeeds.  */
-# if 

[PATCH] stat: implement GetFileInformationByHandle with Winstore apps restrictions

2020-05-19 Thread Steve Lhomme
GetFileInformationByHandle() cannot be called. But the same information can be
gathered via calls to GetFileInformationByHandleEx() which is allowed.

A function pointer is used to pick between the local version using
GetFileInformationByHandleEx() and the system one.

If WINSTORECOMPAT is defined that means the app is built with mingw including
the compatibility library which also includes an GetFileInformationByHandle()
implementation, so no need to redefine it.
---
 lib/stat-w32.c | 44 +++-
 1 file changed, 43 insertions(+), 1 deletion(-)

diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 6900dfcf5..6699b9560 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -58,6 +58,48 @@ typedef DWORD (WINAPI * GetFinalPathNameByHandleFuncType) 
(HANDLE hFile,
 static GetFinalPathNameByHandleFuncType GetFinalPathNameByHandleFunc = NULL;
 static BOOL initialized = FALSE;
 
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && 
!defined(WINSTORECOMPAT)
+WINBOOL _GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION 
lpInfo)
+{
+FILE_ID_INFO id_info;
+FILE_STANDARD_INFO standard_info;
+FILE_BASIC_INFO basic_info;
+if (!GetFileInformationByHandleEx(hFile, FileIdInfo, _info, sizeof 
(id_info)) ||
+!GetFileInformationByHandleEx(hFile, FileStandardInfo, _info, 
sizeof (standard_info)) ||
+!GetFileInformationByHandleEx(hFile, FileBasicInfo, _info, 
sizeof (basic_info)))
+{
+return FALSE;
+}
+
+lpInfo->dwFileAttributes = basic_info.FileAttributes;
+
+lpInfo->ftCreationTime.dwHighDateTime   = basic_info.CreationTime.HighPart;
+lpInfo->ftCreationTime.dwLowDateTime= basic_info.CreationTime.LowPart;
+lpInfo->ftLastAccessTime.dwHighDateTime = 
basic_info.LastAccessTime.HighPart;
+lpInfo->ftLastAccessTime.dwLowDateTime  = 
basic_info.LastAccessTime.LowPart;
+lpInfo->ftLastWriteTime.dwHighDateTime  = 
basic_info.LastWriteTime.HighPart;
+lpInfo->ftLastWriteTime.dwLowDateTime   = basic_info.LastWriteTime.LowPart;
+
+lpInfo->dwVolumeSerialNumber = id_info.VolumeSerialNumber;
+
+lpInfo->nFileSizeHigh = standard_info.EndOfFile.HighPart;
+lpInfo->nFileSizeLow  = standard_info.EndOfFile.LowPart;
+
+lpInfo->nNumberOfLinks = standard_info.NumberOfLinks;
+
+/* The nFileIndex from GetFileInformationByHandle is equal to the low
+ 64 bits of the 128-bit FileId from GetFileInformationByHandleEx,
+ and the high 64 bits of this 128-bit FileId are zero. */
+lpInfo->nFileIndexLow  = (id_info.FileId.Identifier[12] << 24) | 
(id_info.FileId.Identifier[13] << 16) | (id_info.FileId.Identifier[14] << 8) | 
id_info.FileId.Identifier[15];
+lpInfo->nFileIndexHigh = (id_info.FileId.Identifier[ 8] << 24) | 
(id_info.FileId.Identifier[ 9] << 16) | (id_info.FileId.Identifier[10] << 8) | 
id_info.FileId.Identifier[11];
+
+return TRUE;
+}
+static WINBOOL (*GetFileInformationByHandleFunc)(HANDLE hFile, 
LPBY_HANDLE_FILE_INFORMATION lpInfo) = _GetFileInformationByHandle;
+#else /* WINAPI_PARTITION_DESKTOP */
+static WINBOOL (WINAPI *GetFileInformationByHandleFunc)(HANDLE hFile, 
LPBY_HANDLE_FILE_INFORMATION lpInfo) = GetFileInformationByHandle;
+#endif /* WINAPI_PARTITION_DESKTOP */
+
 static void
 initialize (void)
 {
@@ -159,7 +201,7 @@ _gl_fstat_by_handle (HANDLE h, const char *path, struct 
stat *buf)
  

  The latter requires -D_WIN32_WINNT=_WIN32_WINNT_VISTA or higher.  */
   BY_HANDLE_FILE_INFORMATION info;
-  if (! GetFileInformationByHandle (h, ))
+  if (! GetFileInformationByHandleFunc (h, ))
 goto failed;
 
   /* Test for error conditions before starting to fill *buf.  */
-- 
2.26.2




Re: [PATCH v2] win32: don't force _WIN32_WINNT to a lower version

2020-05-27 Thread Steve Lhomme

On 2020-05-28 2:12, Bruno Haible wrote:

Hi Steve,


Hi Bruno,


When building for UWP it's particularly important as a lot of APIs may
be hidden if you use the proper values and they are hidden because you
shouldn't use them. Forcing to use them when they shouldn't will lead to
apps that don't run.


Oh, so Microsoft is not only adding new APIs from one version to the next,
but sometimes also removing APIs. Indeed, the Microsoft doc says this:

   "Over the years, Windows APIs and data types have been added, and
sometimes changed or removed."

<https://docs.microsoft.com/en-us/cpp/porting/overview-of-potential-upgrade-issues-visual-cpp>


I've never been hit by an API removal. But with UWP and win10 variants 
they made a set of API's available on all devices but not all of them 
(the full API set is left on Desktop, for now). So apps targeting *all* 
win10 devices should restrict to these API's.


https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis


Applied like this. (I couldn't take your patch as-is, because in Gnulib
we indent preprocessor lines in a particular way.)


Thanks a lot.


2020-05-27  Bruno Haible  

Improve pattern for defining _WIN32_WINNT.
Newer versions of the Windows API may not only add, but also remove API
functions. Therefore, when the user is e.g. building for Windows 10, we
should not set _WIN32_WINNT to e.g. Windows 8, as this may enable the
use of APIs that were present in Windows 8 but removed in Windows 10.
    Suggested by Steve Lhomme  in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00318.html>.
* lib/ftruncate.c (_WIN32_WINNT): Don't set to a smaller value.
* lib/sethostname.c (_WIN32_WINNT): Likewise.
* lib/stat-w32.c (_WIN32_WINNT): Likewise.

diff --git a/lib/ftruncate.c b/lib/ftruncate.c
index a185637..2514075 100644
--- a/lib/ftruncate.c
+++ b/lib/ftruncate.c
@@ -30,8 +30,10 @@
 argument.  So, define a 64-bit safe SetFileSize function ourselves.  */
  
  /* Ensure that  declares GetFileSizeEx.  */

-#  undef _WIN32_WINNT
-#  define _WIN32_WINNT _WIN32_WINNT_WIN2K
+#  if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+#   undef _WIN32_WINNT
+#   define _WIN32_WINNT _WIN32_WINNT_WIN2K
+#  endif
  
  /* Get declarations of the native Windows API functions.  */

  #  define WIN32_LEAN_AND_MEAN
diff --git a/lib/sethostname.c b/lib/sethostname.c
index 1be69be..96318fb 100644
--- a/lib/sethostname.c
+++ b/lib/sethostname.c
@@ -23,11 +23,11 @@
  /* Unix API.  */
  
  /* Specification.  */

-#include 
+# include 
  
-#include 

-#include 
-#include 
+# include 
+# include 
+# include 
  
  /* Set up to LEN chars of NAME as system hostname.

 Return 0 if ok, set errno and return -1 on error. */
@@ -43,7 +43,7 @@ sethostname (const char *name, size_t len)
return -1;
  }
  
-#ifdef __minix /* Minix */

+# ifdef __minix /* Minix */
{
  FILE *hostf;
  int r = 0;
@@ -76,38 +76,40 @@ sethostname (const char *name, size_t len)
  
  return r;

}
-#else
+# else
/* For platforms that we don't have a better option for, simply bail
   out.  */
errno = ENOSYS;
return -1;
-#endif
+# endif
  }
  
  #else

  /* Native Windows API.  Also used on Cygwin.  */
  
  /* Ensure that  declares SetComputerNameEx.  */

-#undef _WIN32_WINNT
-#define _WIN32_WINNT _WIN32_WINNT_WIN2K
+# if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN2K)
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT _WIN32_WINNT_WIN2K
+# endif
  
-#define WIN32_LEAN_AND_MEAN

+# define WIN32_LEAN_AND_MEAN
  
  /* Specification.  */

-#include 
+# include 
  
-#include 

-#include 
-#include 
+# include 
+# include 
+# include 
  
-#include 

+# include 
  /* The mingw header files don't define GetComputerNameEx, SetComputerNameEx.  
*/
-#ifndef GetComputerNameEx
-# define GetComputerNameEx GetComputerNameExA
-#endif
-#ifndef SetComputerNameEx
-# define SetComputerNameEx SetComputerNameExA
-#endif
+# ifndef GetComputerNameEx
+#  define GetComputerNameEx GetComputerNameExA
+# endif
+# ifndef SetComputerNameEx
+#  define SetComputerNameEx SetComputerNameExA
+# endif
  
  /* Set up to LEN chars of NAME as system hostname.

 Return 0 if ok, set errno and return -1 on error. */
diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 296ccf1..c4b5de9 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -21,8 +21,10 @@
  #if defined _WIN32 && ! defined __CYGWIN__
  
  /* Ensure that  defines FILE_ID_INFO.  */

-#undef _WIN32_WINNT
-#define _WIN32_WINNT _WIN32_WINNT_WIN8
+#if !defined _WIN32_WINNT || (_WIN32_WINNT < _WIN32_WINNT_WIN8)
+# undef _WIN32_WINNT
+# define _WIN32_WINNT _WIN32_WINNT_WIN8
+#endif
  
  #include 

  #include 





Re: [PATCH 2/2] stat: do not use LoadLibrary when built for Windows Store apps

2020-05-28 Thread Steve Lhomme

Any update on this ?

Just as in gettimeofday, one cannot use LoadLibrary to load system DLLs 
in UWP builds. But they are available by static linking with windowsapp 
and are guaranteed to be there.


On 2020-05-19 8:26, Steve Lhomme wrote:

LoadLibrary is forbidden in such apps (can only load DLLs from within the app
package).
The API entries are available to all apps linking with the Windows API as found
here:
https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis

windowsapp.lib (and mincore.lib for Windows 8) are both available in MinGW as
well.

GetFinalPathNameByHandleA is only allowed in Win10 UWP apps
GetFileInformationByHandleEx is allowed in Win8 and Win10 UWP apps.
---
  lib/stat-w32.c | 10 ++
  1 file changed, 10 insertions(+)

diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 106d25120..6900dfcf5 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -61,6 +61,15 @@ static BOOL initialized = FALSE;
  static void
  initialize (void)
  {
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+  /* LoadLibrary not allowed but the functions are available with the windows 
runtime */
+#if _GL_WINDOWS_STAT_INODES == 2
+  GetFileInformationByHandleExFunc = GetFileInformationByHandleEx;
+#endif
+#if _WIN32_WINNT >= 0x0A00 /* _WIN32_WINNT_WIN10 */
+  GetFinalPathNameByHandleFunc = GetFinalPathNameByHandleA;
+#endif
+#else /* WINAPI_PARTITION_DESKTOP */
HMODULE kernel32 = LoadLibrary ("kernel32.dll");
if (kernel32 != NULL)
  {
@@ -71,6 +80,7 @@ initialize (void)
GetFinalPathNameByHandleFunc =
  (GetFinalPathNameByHandleFuncType) GetProcAddress (kernel32, 
"GetFinalPathNameByHandleA");
  }
+#endif /* WINAPI_PARTITION_DESKTOP */
initialized = TRUE;
  }
  
--

2.26.2






Re: [PATCH] gettimeofday: do not use LoadLibrary when built for Windows Store apps

2020-05-28 Thread Steve Lhomme

Any update on this patch ?

On Dekstop it's better to use kernel32.dll as it's loaded with every 
process, so the LoadLibrary is not loading any new DLL.


On Winstore/UWP apps you cannot use LoadLibrary, only LoadLibraryFromApp 
which cannot be used to load system DLLs. Static linking in necessary in 
this case. Any app targeting UWP is already using the windowsapp.lib 
(replacing the kernel32 lib they used to link with) so no need to fore 
linking with it via pkg-config, libtool, etc.


For example in CLang you either link with windowsapp or kernel32:
https://github.com/llvm-project/clang/blob/master/lib/Driver/ToolChains/MinGW.cpp#L269

On 2020-05-19 8:24, Steve Lhomme wrote:

LoadLibrary is forbidden in such apps (can only load DLLs from within the app
package).
The API entries are available to all apps linking with the Windows API as found
here:
https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis

windowsapp.lib (and mincore.lib for Windows 8) are both available in MinGW as
well.

GetSystemTimePreciseAsFileTime is only allowed in Win10 UWP apps.
---
  lib/gettimeofday.c | 5 +
  1 file changed, 5 insertions(+)

diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index 19804793a..087f7eada 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -45,12 +45,17 @@ static BOOL initialized = FALSE;
  static void
  initialize (void)
  {
+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && _WIN32_WINNT >= 
0x0A00 /* _WIN32_WINNT_WIN10 */
+  /* LoadLibrary not allowed but the functions are available with the windows 
runtime */
+  GetSystemTimePreciseAsFileTimeFunc = GetSystemTimePreciseAsFileTime;
+#else /* WINAPI_PARTITION_DESKTOP */
HMODULE kernel32 = LoadLibrary ("kernel32.dll");
if (kernel32 != NULL)
  {
GetSystemTimePreciseAsFileTimeFunc =
  (GetSystemTimePreciseAsFileTimeFuncType) GetProcAddress (kernel32, 
"GetSystemTimePreciseAsFileTime");
  }
+#endif /* WINAPI_PARTITION_DESKTOP */
initialized = TRUE;
  }
  
--

2.26.2






Re: [PATCH] gettimeofday: do not use LoadLibrary when built for Windows Store apps

2020-05-29 Thread Steve Lhomme

On 2020-05-29 2:04, Bruno Haible wrote:

Hi,

Steve Lhomme wrote:

LoadLibrary is forbidden in such apps (can only load DLLs from within the app
package).
The API entries are available to all apps linking with the Windows API as found
here:
https://docs.microsoft.com/en-us/uwp/win32-and-com/win32-apis


Thanks for these infos.


+#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && _WIN32_WINNT >= 
0x0A00 /* _WIN32_WINNT_WIN10 */


The GetSystemTimePreciseAsFileTime function is available starting with Windows 
8,
therefore
   - the condition with WINAPI_FAMILY_PARTITION is not necessary,
   - the condition _WIN32_WINNT >= 0x0A00 is overly restrictive;
 _WIN32_WINNT >= _WIN32_WINNT_WIN8 will work just as well.


OK. I thought GetSystemTimePreciseAsFileTime was not available in Win8 
UWP apps. But it seems it was: 
https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-81-api-sets



I have added a page about the native Windows APIs at
https://gitlab.com/ghwiki/gnow-how/-/wikis/Platforms/Native_Windows

Then here is a patch to avoid LoadLibrary when possible.


2020-05-28  Bruno Haible  

Avoid dynamic loading of Windows API functions when possible.
    Reported by Steve Lhomme  in
<https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00182.html>.
* lib/gettimeofday.c (GetProcAddress,
GetSystemTimePreciseAsFileTimeFuncType,
GetSystemTimePreciseAsFileTimeFunc, initialized, initialize): Don't
define in a build for Windows 8 or higher.
* lib/isatty.c (GetProcAddress, GetNamedPipeClientProcessIdFuncType,
GetNamedPipeClientProcessIdFunc, QueryFullProcessImageNameFuncType,
QueryFullProcessImageNameFunc, initialized, initialize): Don't define
in a build for Windows Vista or higher.
* lib/stat-w32.c (GetProcAddress, GetFileInformationByHandleExFuncType,
GetFileInformationByHandleExFunc, GetFinalPathNameByHandleFuncType,
GetFinalPathNameByHandleFunc, initialized, initialize): Likewise.

diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index 1980479..3d53115 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -33,9 +33,11 @@
  
  #ifdef WINDOWS_NATIVE
  
+# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8)

+
  /* Avoid warnings from gcc -Wcast-function-type.  */
-# define GetProcAddress \
-   (void *) GetProcAddress
+#  define GetProcAddress \
+(void *) GetProcAddress
  
  /* GetSystemTimePreciseAsFileTime was introduced only in Windows 8.  */

  typedef void (WINAPI * GetSystemTimePreciseAsFileTimeFuncType) (FILETIME 
*lpTime);
@@ -54,6 +56,8 @@ initialize (void)
initialized = TRUE;
  }
  
+# endif

+
  #endif
  
  /* This is a wrapper for gettimeofday.  It is used only on systems

@@ -84,8 +88,10 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz)
   <http://www.windowstimestamp.com/description>.  */
FILETIME current_time;
  
+# if !(_WIN32_WINNT >= _WIN32_WINNT_WIN8)

if (!initialized)
  initialize ();
+# endif
if (GetSystemTimePreciseAsFileTimeFunc != NULL)
  GetSystemTimePreciseAsFileTimeFunc (_time);
else
diff --git a/lib/isatty.c b/lib/isatty.c
index 6cdc0fb..fc771d1 100644
--- a/lib/isatty.c
+++ b/lib/isatty.c
@@ -39,9 +39,11 @@
  # include 
  #endif
  
+#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)

+
  /* Avoid warnings from gcc -Wcast-function-type.  */
-#define GetProcAddress \
-  (void *) GetProcAddress
+# define GetProcAddress \
+   (void *) GetProcAddress
  
  /* GetNamedPipeClientProcessId was introduced only in Windows Vista.  */

  typedef BOOL (WINAPI * GetNamedPipeClientProcessIdFuncType) (HANDLE hPipe,
@@ -69,6 +71,8 @@ initialize (void)
initialized = TRUE;
  }
  
+#endif

+
  static BOOL IsConsoleHandle (HANDLE h)
  {
DWORD mode;
@@ -84,8 +88,10 @@ static BOOL IsCygwinConsoleHandle (HANDLE h)
BOOL result = FALSE;
ULONG processId;
  
+#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)

if (!initialized)
  initialize ();
+#endif
  
/* GetNamedPipeClientProcessId

   
<https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-getnamedpipeclientprocessid>
diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index b9163f5..02ad9ab 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -40,18 +40,20 @@
  #include "pathmax.h"
  #include "verify.h"
  
+#if !(_WIN32_WINNT >= _WIN32_WINNT_VISTA)

+
  /* Avoid warnings from gcc -Wcast-function-type.  */
-#define GetProcAddress \
-  (void *) GetProcAddress
+# define GetProcAddress \
+   (void *) GetProcAddress
  
-#if _GL_WINDOWS_STAT_INODES == 2

+# if _GL_WINDOWS_STAT_INODES == 2
  /* GetFileInformationByHandleEx was introduced only in Windows Vista.  */
  typedef DWORD (WINAPI * GetFileInformationByHandleExFuncType) (HANDLE hFile,
 
FILE_INFO_BY_HANDLE_CLASS fiClass,
   

Re: Don't assume that UNICODE is not defined

2020-05-30 Thread Steve Lhomme
I think that's the other way around.

_UNICODE is meant to be used with tchar.h. I found 41 instances in a recent SDK.
UNICODE is the more generic term to chose between ANSI or WIDE API calls (if 
you don't force them directly). I found 4123 instances in the same SDK.

So IMO the proper way is to use UNICODE, especially if you never use tchar.h.

> On May 30, 2020 12:57 PM Jeffrey Walton  wrote:
> 
>  
> On Sat, May 30, 2020 at 5:16 AM Bruno Haible  wrote:
> >
> > I wrote:
> > > some types depend on
> > > whether UNICODE is defined or not [1].
> >
> > Some functions also depend whether UNICODE is defined or not.
> >
> > Since UWP applications are meant to defined the macro UNICODE, but we want
> > Gnulib to produce the same code, regardless whether UNICODE is defined or 
> > not,
> > we need to either explicitly use the functions with 'A' suffix (which is 
> > ugly)
> > or use #defines for redirection.
> >
> > Fortunately, packages that use gnulib don't need to do this stuff; nor do we
> > need to do it in the tests/ directory. Only the gnulib/lib/ directory may
> > reasonably be used with -DUNICODE, therefore only the gnulib/lib/ directory
> > needs this workaround.
> 
> In case it matters, I believe Microsoft keys on _UNICODE, not UNICODE.
> 
> Microsoft source files often have something like this (or is it vice-versa):
> 
> #ifdef UNICODE
> #  ifndef _UNICODE
> #define _UNICODE
> #  endif
> #endif
> 
> Also see 
> https://docs.microsoft.com/en-us/cpp/text/generic-text-mappings-in-tchar-h.
> 
> Jeff



Re: Don't assume that UNICODE is not defined

2020-05-30 Thread Steve Lhomme
Why not use the proper call in the first place rather than use a define ?
It could be useful in a generic header used by all to make sure everyone uses 
the right thing. But since you need to edit each file it would be cleaner not 
to use any define at all and use the proper functions and structures directly.

> On May 30, 2020 11:16 AM Bruno Haible  wrote:
> 
>  
> I wrote:
> > some types depend on
> > whether UNICODE is defined or not [1].
> 
> Some functions also depend whether UNICODE is defined or not.
> 
> Since UWP applications are meant to defined the macro UNICODE, but we want
> Gnulib to produce the same code, regardless whether UNICODE is defined or not,
> we need to either explicitly use the functions with 'A' suffix (which is ugly)
> or use #defines for redirection.
> 
> Fortunately, packages that use gnulib don't need to do this stuff; nor do we
> need to do it in the tests/ directory. Only the gnulib/lib/ directory may
> reasonably be used with -DUNICODE, therefore only the gnulib/lib/ directory
> needs this workaround.
> 
> 
> 2020-05-30  Bruno Haible  
> 
>   Don't assume that UNICODE is not defined.
>   Many Windows API functions are defined differently (redirecting to a
>   function with suffix 'W') if the application defines the macro UNICODE
>   than by default (redirecting to a function with suffix 'A').
>   * lib/clean-temp.c (OSVERSIONINFO, GetVersionEx): Redirect to the
>   variant with suffix 'A'.
>   * lib/dirent-private.h (WIN32_FIND_DATA): Likewise.
>   * lib/gc-gnulib.c (CryptAcquireContext): Likewise.
>   * lib/getaddrinfo.c (GetModuleHandle): Likewise.
>   * lib/getlogin.c (GetUserName): Likewise.
>   * lib/getlogin_r.c (GetUserName): Likewise.
>   * lib/gettimeofday.c (LoadLibrary): Likewise.
>   * lib/isatty.c (LoadLibrary, QueryFullProcessImageName): Likewise.
>   * lib/link.c (GetModuleHandle, CreateHardLink): Likewise.
>   * lib/localename.c (GetLocaleInfo, EnumSystemLocales): Likewise.
>   * lib/mountlist.c (GetDriveType): Likewise.
>   * lib/nonblocking.c (GetNamedPipeHandleState): Likewise.
>   * lib/opendir.c (WIN32_FIND_DATA, GetFullPathName, FindFirstFile):
>   Likewise.
>   * lib/physmem.c (GetModuleHandle): Likewise.
>   * lib/poll.c (GetModuleHandle, PeekConsoleInput, CreateEvent,
>   PeekMessage, DispatchMessage): Likewise.
>   * lib/progreloc.c (GetModuleFileName): Likewise.
>   * lib/putenv.c (SetEnvironmentVariable): Likewise.
>   * lib/read.c (GetNamedPipeHandleState): Likewise.
>   * lib/readdir.c (FindNextFile): Likewise.
>   * lib/relocatable.c (GetModuleFileName): Likewise.
>   * lib/rename.c (MoveFileEx): Likewise.
>   * lib/rewinddir.c (FindFirstFile): Likewise.
>   * lib/select.c (GetModuleHandle, PeekConsoleInput, CreateEvent,
>   PeekMessage, DispatchMessage): Likewise.
>   * lib/sethostname.c (GetComputerNameEx, SetComputerNameEx): Likewise.
>   * lib/socket.c (WSASocket): Likewise.
>   * lib/stat-w32.c (LoadLibrary, GetFinalPathNameByHandle): Likewise.
>   * lib/stat.c (WIN32_FIND_DATA, CreateFile, FindFirstFile): Likewise.
>   * lib/stdio-read.c (GetNamedPipeHandleState): Likewise.
>   * lib/stdio-write.c (GetNamedPipeHandleState): Likewise.
>   * lib/tmpdir.c (GetTempPath): Likewise.
>   * lib/tmpfile.c (OSVERSIONINFO, GetVersionEx, GetTempPath): Likewise.
>   * lib/uname.c (OSVERSIONINFO, GetVersionEx): Likewise.
>   * lib/utime.c (CreateFile, GetFileAttributes): Likewise.
>   * lib/windows-cond.c (CreateEvent): Likewise.
>   * lib/windows-rwlock.c (CreateEvent): Likewise.
>   * lib/windows-timedmutex.c (CreateEvent): Likewise.
>   * lib/windows-timedrecmutex.c (CreateEvent): Likewise.
>   * lib/windows-timedrwlock.c (CreateEvent): Likewise.
>   * lib/write.c (GetNamedPipeHandleState): Likewise.
> 
> diff --git a/lib/clean-temp.c b/lib/clean-temp.c
> index 8d3cbd9..c57d658 100644
> --- a/lib/clean-temp.c
> +++ b/lib/clean-temp.c
> @@ -66,6 +66,14 @@
>  # define PATH_MAX 1024
>  #endif
>  
> +#if defined _WIN32 && ! defined __CYGWIN__
> +/* Don't assume that UNICODE is not defined.  */
> +# undef OSVERSIONINFO
> +# define OSVERSIONINFO OSVERSIONINFOA
> +# undef GetVersionEx
> +# define GetVersionEx GetVersionExA
> +#endif
> +
>  
>  /* The use of 'volatile' in the types below (and ISO C 99 section 
> 5.1.2.3.(5))
> ensure that while constructing or modifying the data structures, the field
> diff --git a/lib/dirent-private.h b/lib/dirent-private.h
> index 4b4eba4..a3c6844 100644
> --- a/lib/dirent-private.h
> +++ b/lib/dirent-private.h
> @@ -20,6 +20,10 @@
>  #define WIN32_LEAN_AND_MEAN
>  #include 
>  
> +/* Don't assume that UNICODE is not defined.  */
> +#undef WIN32_FIND_DATA
> +#define WIN32_FIND_DATA WIN32_FIND_DATAA
> +
>  struct gl_directory
>  {
>/* Status, or error code to produce in next readdir() call.
> diff --git a/lib/gc-gnulib.c 

Re: [PATCH] stat: implement GetFileInformationByHandle with Winstore apps restrictions

2020-05-30 Thread Steve Lhomme
> On May 30, 2020 11:41 AM Bruno Haible  wrote:
> 
>  
> Hi,
> 
> Steve Lhomme wrote:
> > GetFileInformationByHandle() cannot be called. But the same information can 
> > be
> > gathered via calls to GetFileInformationByHandleEx() which is allowed.
> 
> I am understanding from [1] that Microsoft is augmenting the list of allowed
> functions in UWP over time, and that ultimately most Windows API functions 
> will
> be allowed in UWP in the end, because "developers want the Windows API".

Yes, they did add a lot of allowed API's between Win8 and Win10. But it's far 
from the full API. A lot of API's are deprecated and they use that opportunity 
to get rid of some old stuff. That's the same deal with the Universal C Runtime 
which removed a lot of insecure calls. I think it's more likely some of the old 
API's will not work in the future rather than allowing more and more people to 
use it.
This API set is the one to use on Xbox for example. And it's not going away, 
nor are they going to add some more old stuff.
 
> So, it makes sense to put your code into a separate library, that implements
> Windows API on top of UWP API. Gnulib focuses (partially) on providing the
> POSIX and glibc API on top of the Windows API.

That's the case in mingw-w64 which has winstorecompat to mimick some of the 
forbidden APIs without having to recompile the code:
https://github.com/mirror/mingw-w64/tree/master/mingw-w64-libraries/winstorecompat

You can see one of the last commit is adding GetFileInformationByHandle() for 
example. But that means anyone building with an older version of winstorecompat 
cannot rely on this helper.

> The two, that is the Windows API emulation on top of UWP API and Gnulib, ought
> to work seamlessly together (assuming that other library does not have GPL-
> incompatible license terms).
> 
> Bruno
> 
> [1] 
> https://www.thurrott.com/dev/206351/microsoft-confirms-uwp-is-not-the-future-of-windows-apps



Re: [PATCH] stat: implement GetFileInformationByHandle with Winstore apps restrictions

2020-05-30 Thread Steve Lhomme
> On May 30, 2020 4:35 PM Bruno Haible  wrote:
> 
>  
> Steve Lhomme wrote:
> > > So, it makes sense to put your code into a separate library, that 
> > > implements
> > > Windows API on top of UWP API. Gnulib focuses (partially) on providing the
> > > POSIX and glibc API on top of the Windows API.
> > 
> > That's the case in mingw-w64 which has winstorecompat to mimick some of the 
> > forbidden APIs without having to recompile the code:
> > https://github.com/mirror/mingw-w64/tree/master/mingw-w64-libraries/winstorecompat
> 
> Thanks for confirming that such a library already exists!
> 
> > You can see one of the last commit is adding GetFileInformationByHandle() 
> > for example. But that means anyone building with an older version of 
> > winstorecompat cannot rely on this helper.
> 
> That's not a good enough reason for adding this code to gnulib.

I agree. But there should be a way to compile gnulib without calling the 
forbidden/old/deprecated API's. That's currently not possible. For example in 
stat-w32.c the "_GL_WINDOWS_STAT_INODES == 2" mode is not enabled yet. And even 
then it would still do a call GetFileInformationByHandle() which will not link 
in the end. (in mingw-w64 it will because they don't builds libs for 
UWP/not-UWP)



Re: Don't assume that UNICODE is not defined

2020-05-30 Thread Steve Lhomme
> On May 30, 2020 4:31 PM Bruno Haible  wrote:
> 
>  
> Steve Lhomme wrote:
> > Why not use the proper call in the first place rather than use a define ?
> > It could be useful in a generic header used by all to make sure everyone
> > uses the right thing. But since you need to edit each file it would be
> > cleaner not to use any define at all and use the proper functions and
> > structures directly.
> 
> It would be possible. But
>   - It is ugly.
>   - The correct search term on microsoft.com, stackoverflow.com, etc. is
> 'LoadLibrary', not 'LoadLibraryA'. Let's speak the same language as
> everyone else is speaking.

Microsoft.com doesn't document the function as LoadLibrary anymore. There is 
LoadLibraryA and LoadLibraryW.
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya
https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryw

It even says the following:
The libloaderapi.h header defines LoadLibrary as an alias which automatically 
selects the ANSI or Unicode version of this function based on the definition of 
the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias 
with code that not encoding-neutral can lead to mismatches that result in 
compilation or runtime errors. For more information, see Conventions for 
Function Prototypes.

Given the name of the header that's not what should be used from now on. Using 
the old names gives a sense of safety you don't actually have. Looking at the 
code I would assume, like any currently maintained code, that the default is to 
call UNICODE API's. But I don't find any mention of WideCharToMultiByte or 
CP_UTF8 in the code. And from the patch you did it's quite the opposite.



Re: [PATCH] stat: implement GetFileInformationByHandle with Winstore apps restrictions

2020-05-30 Thread Steve Lhomme
> On May 30, 2020 5:47 PM Bruno Haible  wrote:
> 
>  
> Steve Lhomme wrote:
> > > > You can see one of the last commit is adding 
> > > > GetFileInformationByHandle() for example. But that means anyone 
> > > > building with an older version of winstorecompat cannot rely on this 
> > > > helper.
> > > 
> > > That's not a good enough reason for adding this code to gnulib.
> > 
> > I agree. But there should be a way to compile gnulib without calling the 
> > forbidden/old/deprecated API's. That's currently not possible. For example 
> > in stat-w32.c the "_GL_WINDOWS_STAT_INODES == 2" mode is not enabled yet. 
> > And even then it would still do a call GetFileInformationByHandle() which 
> > will not link in the end. (in mingw-w64 it will because they don't builds 
> > libs for UWP/not-UWP)
> 
> It should link fine if you use the 'winstorecompat' library that you 
> mentioned.
> If it doesn't, it's a problem with that library, not with Gnulib.

It wouldn't until a few days ago before I patched it. Anyone using mingw 7.0 
(ie all current Linux distros) will not be able to use it until there's a 
release.

And this library exists for legacy code that cannot be changed. I don't think 
gnulib falls in this category. And ultimately that library should not be used 
at all.



[PATCH v2] win32: don't force _WIN32_WINNT to a lower version

2020-05-26 Thread Steve Lhomme
---
 lib/ftruncate.c   | 2 ++
 lib/sethostname.c | 6 --
 lib/stat-w32.c| 6 --
 3 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/lib/ftruncate.c b/lib/ftruncate.c
index a1856374e..990b71dbb 100644
--- a/lib/ftruncate.c
+++ b/lib/ftruncate.c
@@ -30,8 +30,10 @@
argument.  So, define a 64-bit safe SetFileSize function ourselves.  */
 
 /* Ensure that  declares GetFileSizeEx.  */
+#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500
 #  undef _WIN32_WINNT
 #  define _WIN32_WINNT _WIN32_WINNT_WIN2K
+#endif
 
 /* Get declarations of the native Windows API functions.  */
 #  define WIN32_LEAN_AND_MEAN
diff --git a/lib/sethostname.c b/lib/sethostname.c
index 87b3af958..379e6ca13 100644
--- a/lib/sethostname.c
+++ b/lib/sethostname.c
@@ -88,8 +88,10 @@ sethostname (const char *name, size_t len)
 /* Native Windows API.  Also used on Cygwin.  */
 
 /* Ensure that  declares SetComputerNameEx.  */
-#undef _WIN32_WINNT
-#define _WIN32_WINNT _WIN32_WINNT_WIN2K
+#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT _WIN32_WINNT_WIN2K
+#endif
 
 #define WIN32_LEAN_AND_MEAN
 
diff --git a/lib/stat-w32.c b/lib/stat-w32.c
index 5048093e6..69b06740f 100644
--- a/lib/stat-w32.c
+++ b/lib/stat-w32.c
@@ -21,8 +21,10 @@
 #if defined _WIN32 && ! defined __CYGWIN__
 
 /* Ensure that  defines FILE_ID_INFO.  */
-#undef _WIN32_WINNT
-#define _WIN32_WINNT _WIN32_WINNT_WIN8
+#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0602
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT _WIN32_WINNT_WIN8
+#endif
 
 #include 
 #include 
-- 
2.26.2




Re: [PATCH v2] win32: don't force _WIN32_WINNT to a lower version

2020-05-27 Thread Steve Lhomme

Hi,

On 2020-05-26 22:38, Bruno Haible wrote:

Hi Steve,

  
  /* Ensure that  declares GetFileSizeEx.  */

+#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0500
  #  undef _WIN32_WINNT
  #  define _WIN32_WINNT _WIN32_WINNT_WIN2K
+#endif
  


What do you gain by this? What does it bring to compile this code
with a higher _WIN32_WINNT value?


It's general good practice. In another file I modified I did not 
understand why I was still getting the old APIs when I was selecting 
Win10. So I modified the places where the value is enforced. It's future 
proof when editing files.


When building for UWP it's particularly important as a lot of APIs may 
be hidden if you use the proper values and they are hidden because you 
shouldn't use them. Forcing to use them when they shouldn't will lead to 
apps that don't run.




[PATCH] Use CreateFile2 in UWP builds

2023-05-16 Thread Steve Lhomme
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.
+  

+  

  */
+  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 = _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)),
+  );
+  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
  

@@ -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.
+ 

+ 

  

[PATCH] do not call GetHandleInformation() in Winstore apps

2023-05-16 Thread Steve Lhomme
The API is forbidden [1] and HANDLE_FLAG_INHERIT would never be set as exec()
is not allowed either [2].

[1] 
https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation
[2] 
https://docs.microsoft.com/en-us/cpp/cppcx/crt-functions-not-supported-in-universal-windows-platform-apps
---
 lib/fcntl.c | 13 +
 lib/windows-spawn.c | 13 +
 2 files changed, 26 insertions(+)

diff --git a/lib/fcntl.c b/lib/fcntl.c
index e220800845..39f5402b30 100644
--- a/lib/fcntl.c
+++ b/lib/fcntl.c
@@ -45,6 +45,19 @@
 #  include 
 # endif
 
+# if defined WINAPI_FAMILY && 
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+/* GetHandleInformation is not available in UWP, the flags it would provide
+   are also not available, so we just return 0.
+   

+    */
+static inline BOOL GetHandleInformation(HANDLE h, DWORD *pf)
+{
+  *pf = 0;
+  return TRUE;
+}
+#  define HANDLE_FLAG_INHERIT  (1)
+# endif /*  WINAPI_PARTITION_DESKTOP */
+
 /* Upper bound on getdtablesize().  See lib/getdtablesize.c.  */
 # define OPEN_MAX_MAX 0x1
 
diff --git a/lib/windows-spawn.c b/lib/windows-spawn.c
index f864db1317..1eb0052e8d 100644
--- a/lib/windows-spawn.c
+++ b/lib/windows-spawn.c
@@ -39,6 +39,19 @@
 
 #include "findprog.h"
 
+#if defined WINAPI_FAMILY && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+/* GetHandleInformation is not available in UWP, the flags it would provide
+   are also not available, so we just return 0.
+   

+    */
+static inline BOOL GetHandleInformation(HANDLE h, DWORD *pf)
+{
+  *pf = 0;
+  return TRUE;
+}
+# define HANDLE_FLAG_INHERIT  (1)
+#endif /*  WINAPI_PARTITION_DESKTOP */
+
 /* Don't assume that UNICODE is not defined.  */
 #undef STARTUPINFO
 #define STARTUPINFO STARTUPINFOA
-- 
2.39.2




Re: [PATCH] Use CreateFile2 in UWP builds

2023-05-16 Thread Steve Lhomme

Hi,

On 2023-05-16 16:52, Bruno Haible wrote:

Steve Lhomme wrote:

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.


CreateFileW has an emulation in mingw's winstorecompat:
https://github.com/mirror/mingw-w64/blob/master/mingw-w64-libraries/winstorecompat/src/CreateFileW.c

Can you suggest to the mingw people to add a CreateFileA emulation as well?
That's IMO the better place for emulating CreateFileA on top of CreateFile2,
rather than Gnulib.


That would be OK if gnulib was restricted to mingw64 on Windows. But it 
can be compiled by MSVC as well which doesn't have the winstorecompat 
library. And it needs an extra define when compiling the code to 
"enable" this library. I'm not sure that's a practical solution for gnulib.


Also There are 2 versions of the library depending if you target the 
original UWP (Win8 = winstorecompat) or the more relaxed UWP (Win10 = 
windowsappcompat). That would need some extra checks in the gnulib build 
system to pick the right one.


IMO it's better to go for a solution that follows the Windows API's. 
CreateFile2 is available on all Windows versions since Win8.



Bruno







Re: [PATCH] do not call GetHandleInformation() in Winstore apps

2023-05-16 Thread Steve Lhomme

On 2023-05-16 16:48, Bruno Haible wrote:

Hi,

This thread is obviously related to what we discussed three years ago:
https://lists.gnu.org/archive/html/bug-gnulib/2020-05/msg00376.html


It is.

For the same reason as the previous email, I think 
winstorecompat/windowsappcompat is not the right solution for gnulib 
(extra global define, picking the right lib to link with). I even think 
it's not a good solution in general, even though I contributed to it 
heavily. It it good to be able to compile unmaintained projects. In 
general the code returns an error or try more or less to do what the 
original code did.


GetHandleInformation() is trickier to implement because it won't be the 
same between winstorecompat and windowsappcompat. It even depends on the 
actual Windows 10 the code is running on as CreateProcess() was only 
allowed since 10.0.16299 [1]. In all cases before that should it return 
FALSE (code failed as we can't tell the properties of the HANDLE) or 
TRUE (we can't tell the properties, we just assume it doesn't have what 
you want) ? For the gnulib usage, it's OK to return TRUE and the code go 
through, assuming HANDLE_FLAG_INHERIT is not set.


In other cases, where knowing about HANDLE_FLAG_PROTECT_FROM_CLOSE for 
example, it can't be simulated properly. And if the HANDLE is invalid or 
became unusable/closed it needs some extra checks that may even be 
impossible.


So not only winstorecompat is cumbersome, but it may not be reliable 
enough. In this case it's much better to go with local assumptions.


[1] 
https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis#apis-from-api-ms-win-core-processthreads-l1-1-0dll



At that time, we discussed the function GetFileInformationByHandle,
and it is implemented in mingw's winstorecompat library:
https://github.com/mirror/mingw-w64/blob/master/mingw-w64-libraries/winstorecompat/src/GetFileInformationByHandle.c

Steve Lhomme wrote:

The API is forbidden [1] and HANDLE_FLAG_INHERIT would never be set as exec()
is not allowed either [2].

[1] 
https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation


Ah, you mean the marker "[desktop apps only]" in that page?


+# if defined WINAPI_FAMILY && 
!WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+/* GetHandleInformation is not available in UWP, the flags it would provide
+   are also not available, so we just return 0.
+   
<https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-gethandleinformation>
+   <https://learn.microsoft.com/en-us/uwp/win32-and-com/win32-apis> */
+static inline BOOL GetHandleInformation(HANDLE h, DWORD *pf)
+{
+  *pf = 0;
+  return TRUE;
+}


I think the proper place for such code is mingw's winstorecompat library,
not Gnulib. Can you try to submit it there?

Bruno