On Saturday 13 December 2025 00:31:22 Martin Storsjö wrote:
> On Thu, 4 Dec 2025, Pali Rohár wrote:
> 
> > These two 32-bit DLL libraries do not provide those wide stat and find
> > functions. Enable mingw-w64 emulation of them in import libraries.
> > For 32-bit builds these functions have also alternative names without
> > the "*32" suffix. Add also those symbol aliases.
> > ---
> > mingw-w64-crt/Makefile.am           |  3 ++
> > mingw-w64-crt/stdio/_wfindfirst32.c |  6 +++
> > mingw-w64-crt/stdio/_wfindnext32.c  |  6 +++
> > mingw-w64-crt/stdio/_wstat32.c      | 58 ++++++++++++++++++++++++++++-
> > 4 files changed, 72 insertions(+), 1 deletion(-)
> > 
> > diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am
> > index 6f6ac57fc60d..599cf21adea2 100644
> > --- a/mingw-w64-crt/Makefile.am
> > +++ b/mingw-w64-crt/Makefile.am
> > @@ -893,6 +893,9 @@ src_pre_msvcrt20=\
> >   misc/__timezone.c \
> >   misc/__tzname.c \
> >   stdio/_telli64.c \
> > +  stdio/_wfindfirst32.c \
> > +  stdio/_wfindnext32.c \
> > +  stdio/_wstat32.c \
> >   stdio/fgetws.c \
> >   stdio/fputws.c \
> >   stdio/iob_func.c
> > diff --git a/mingw-w64-crt/stdio/_wfindfirst32.c 
> > b/mingw-w64-crt/stdio/_wfindfirst32.c
> > index d46f26c4d665..28443c73771a 100644
> > --- a/mingw-w64-crt/stdio/_wfindfirst32.c
> > +++ b/mingw-w64-crt/stdio/_wfindfirst32.c
> > @@ -17,3 +17,9 @@ intptr_t __cdecl _wfindfirst32(const wchar_t 
> > *_Filename,struct _wfinddata32_t *_
> >   return ret;
> > }
> > intptr_t (__cdecl *__MINGW_IMP_SYMBOL(_wfindfirst32))(const wchar_t *, 
> > struct _wfinddata32_t *) = _wfindfirst32;
> > +
> > +#ifndef _WIN64
> > +#undef _wfindfirst
> > +intptr_t __attribute__ ((alias ("_wfindfirst32"))) __cdecl 
> > _wfindfirst(const char *, struct _wfinddata32_t *);
> > +extern intptr_t __attribute__ ((alias 
> > (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_wfindfirst32))))) (__cdecl 
> > *__MINGW_IMP_SYMBOL(_wfindfirst))(const char *, struct _wfinddata32_t *);
> > +#endif
> > diff --git a/mingw-w64-crt/stdio/_wfindnext32.c 
> > b/mingw-w64-crt/stdio/_wfindnext32.c
> > index 1846a0f06855..d10c9f897a76 100644
> > --- a/mingw-w64-crt/stdio/_wfindnext32.c
> > +++ b/mingw-w64-crt/stdio/_wfindnext32.c
> > @@ -17,3 +17,9 @@ int __cdecl _wfindnext32(intptr_t _FindHandle,struct 
> > _wfinddata32_t *_FindData)
> >   return 0;
> > }
> > int (__cdecl *__MINGW_IMP_SYMBOL(_wfindnext32))(intptr_t, struct 
> > _wfinddata32_t *) = _wfindnext32;
> > +
> > +#ifndef _WIN64
> > +#undef _wfindnext
> > +int __attribute__ ((alias ("_wfindnext32"))) __cdecl _wfindnext(intptr_t, 
> > struct _wfinddata32_t *);
> > +extern int __attribute__ ((alias 
> > (__MINGW64_STRINGIFY(__MINGW_IMP_SYMBOL(_wfindnext32))))) (__cdecl 
> > *__MINGW_IMP_SYMBOL(_wfindnext))(intptr_t, struct _wfinddata32_t *);
> > +#endif
> > diff --git a/mingw-w64-crt/stdio/_wstat32.c b/mingw-w64-crt/stdio/_wstat32.c
> > index 8ef681a429c1..f9be2336bdef 100644
> > --- a/mingw-w64-crt/stdio/_wstat32.c
> > +++ b/mingw-w64-crt/stdio/_wstat32.c
> > @@ -8,6 +8,11 @@
> > #include <stdint.h>
> > #include <errno.h>
> > 
> > +#ifndef _WIN64
> > +#include <fcntl.h>
> > +#include <windows.h>
> > +#endif
> > +
> > /* When the file time does not fit into the st_Xtime field:
> >  *           crtdll-msvcr71   msvcr80+
> >  * st_Xtime       -1             -1
> > @@ -20,12 +25,12 @@
> >  * errno       no change     no change   EOVERFLOW
> >  * returns         0            -1          -1
> >  *
> > - * This file is used only for 64-bit msvcrt.dll builds.
> >  * The stat function on 32-bit system os msvcrt.dll behaves
> >  * like the msvcr80/msvcr90, so use this behavior.
> >  */
> > int __cdecl _wstat32(const wchar_t *_Name,struct _stat32 *_Stat)
> > {
> > +#ifdef _WIN64
> >   struct _stat64 st;
> >   int ret=_wstat64(_Name,&st);
> >   if (ret != 0)
> > @@ -44,5 +49,56 @@ int __cdecl _wstat32(const wchar_t *_Name,struct _stat32 
> > *_Stat)
> >   if (_Stat->st_atime == -1 || _Stat->st_mtime == -1 || _Stat->st_ctime == 
> > -1)
> >     errno = EINVAL;
> >   return 0;
> > +#else
> > +  /* mingw-w64 _wstat64() on 32-bit systems is implemented as wrapper 
> > around the _wstat32().
> > +   * Therefore mingw-w64 _wstat32() implementation cannot call _wstat64().
> > +   * This _wstat32 implementation uses _fstat32() with handle obtained 
> > from CreateFileW().
> > +   * _fstat requires only FILE_READ_ATTRIBUTES access and 
> > FILE_FLAG_BACKUP_SEMANTICS is
> > +   * required for opening directory via CreateFileW().
> > +   * Using just FILE_READ_ATTRIBUTES access allows to open also path which 
> > is was denied for
> > +   * reading by another process. msvcrt.dll _wstat32() also allows to be 
> > called on such path.
> > +   */
> > +  int fd;
> > +  int ret;
> > +  int err;
> > +  HANDLE handle;
> > +  handle = CreateFileW(_Name, FILE_READ_ATTRIBUTES, 
> > FILE_SHARE_VALID_FLAGS, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 
> > NULL);
> > +  if (handle == INVALID_HANDLE_VALUE) {
> > +    switch (GetLastError()) {
> > +    case ERROR_PATH_NOT_FOUND:
> > +    case ERROR_FILE_NOT_FOUND:
> > +      errno = ENOENT;
> > +      break;
> > +    case ERROR_ACCESS_DENIED:
> > +    case ERROR_WRITE_PROTECT...ERROR_SHARING_BUFFER_EXCEEDED:
> 
> FWIW I wasn't familiar with this language extension. It's probably fine (and
> Clang seems to support it as well), but maybe it'd be worth pointing out
> that this isn't proper C in itself?
> 
> // Martin

I used this syntax so many times without spotting any problem and I did
not know that this is not proper C, but rather gcc extension. I will add
a comment for it.


_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to