From: Rémi Bernon rbernon@codeweavers.com
--- include/msvcrt/ctype.h | 7 +++++++ include/msvcrt/stdlib.h | 3 +++ 2 files changed, 10 insertions(+)
diff --git a/include/msvcrt/ctype.h b/include/msvcrt/ctype.h index 88e79411f64..5cfe312ea6d 100644 --- a/include/msvcrt/ctype.h +++ b/include/msvcrt/ctype.h @@ -50,6 +50,13 @@ _ACRTIMP int __cdecl isxdigit(int); _ACRTIMP int __cdecl tolower(int); _ACRTIMP int __cdecl toupper(int);
+#ifndef MB_CUR_MAX +_ACRTIMP int __cdecl ___mb_cur_max_func(void); +_ACRTIMP int __cdecl ___mb_cur_max_l_func(_locale_t); +#define __mb_cur_max ___mb_cur_max_func() +#define MB_CUR_MAX ___mb_cur_max_func() +#endif /* MB_CUR_MAX */ + #ifdef __cplusplus } #endif diff --git a/include/msvcrt/stdlib.h b/include/msvcrt/stdlib.h index 9cb8ccb110a..8d64246c0b5 100644 --- a/include/msvcrt/stdlib.h +++ b/include/msvcrt/stdlib.h @@ -121,10 +121,13 @@ extern unsigned int _fmode;
#endif /* __i386__ */
+#ifndef MB_CUR_MAX _ACRTIMP int __cdecl ___mb_cur_max_func(void); _ACRTIMP int __cdecl ___mb_cur_max_l_func(_locale_t); #define __mb_cur_max ___mb_cur_max_func() #define MB_CUR_MAX ___mb_cur_max_func() +#endif /* MB_CUR_MAX */ + _ACRTIMP __msvcrt_ulong* __cdecl __doserrno(void); #define _doserrno (*__doserrno()) _ACRTIMP int* __cdecl _errno(void);
From: Rémi Bernon rbernon@codeweavers.com
_FILE_DISPOSITION_INFO has a DeleteFile member which gets replaced. --- include/winbase.h | 1 - 1 file changed, 1 deletion(-)
diff --git a/include/winbase.h b/include/winbase.h index c775ab71694..236b29b93b0 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1993,7 +1993,6 @@ WINBASEAPI void WINAPI DeleteCriticalSection(CRITICAL_SECTION *lpCrit); WINBASEAPI void WINAPI DeleteFiber(LPVOID); WINBASEAPI BOOL WINAPI DeleteFileA(LPCSTR); WINBASEAPI BOOL WINAPI DeleteFileW(LPCWSTR); -#define DeleteFile WINELIB_NAME_AW(DeleteFile) WINBASEAPI void WINAPI DeleteProcThreadAttributeList(struct _PROC_THREAD_ATTRIBUTE_LIST*); WINBASEAPI BOOL WINAPI DeleteTimerQueue(HANDLE); WINBASEAPI BOOL WINAPI DeleteTimerQueueEx(HANDLE,HANDLE);
From: Rémi Bernon rbernon@codeweavers.com
--- include/msvcrt/intrin.h | 4 ++++ include/winnt.h | 14 ++++++++++++++ 2 files changed, 18 insertions(+)
diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h index ba825b7b09e..03d856c5933 100644 --- a/include/msvcrt/intrin.h +++ b/include/msvcrt/intrin.h @@ -90,6 +90,10 @@ unsigned __int64 __getReg(int);
#endif
+#if defined(_MSC_VER) && defined(__x86_64__) +unsigned __int64 _umul128(unsigned __int64,unsigned __int64,unsigned __int64*); +#endif + #ifdef __cplusplus } #endif diff --git a/include/winnt.h b/include/winnt.h index c810830b2b3..794970a35f5 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -7397,6 +7397,20 @@ static FORCEINLINE void YieldProcessor(void) #endif }
+#if defined(_MSC_VER) && !defined(__arm64ec__) && (!defined(__clang__) || __has_builtin(_umul128)) +#define UnsignedMultiply128 _umul128 +DWORD64 _umul128(DWORD64,DWORD64,DWORD64*); +#pragma intrinsic(_umul128) +#elif !defined(__i386__) +static FORCEINLINE DWORD64 UnsignedMultiply128( DWORD64 a, DWORD64 b, DWORD64 *hi ) +{ + unsigned __int128 v = (unsigned __int128)a * b; + *hi = v >> 64; + return (DWORD64)v; +} +#define _umul128 UnsignedMultiply128 +#endif + #ifdef __cplusplus } #endif
From: Rémi Bernon rbernon@codeweavers.com
--- include/msvcrt/intrin.h | 4 ++++ include/winnt.h | 12 ++++++++++++ 2 files changed, 16 insertions(+)
diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h index 03d856c5933..1be630b5753 100644 --- a/include/msvcrt/intrin.h +++ b/include/msvcrt/intrin.h @@ -94,6 +94,10 @@ unsigned __int64 __getReg(int); unsigned __int64 _umul128(unsigned __int64,unsigned __int64,unsigned __int64*); #endif
+#if defined(_MSC_VER) && defined(__x86_64__) +unsigned __int64 __shiftright128(unsigned __int64,unsigned __int64,unsigned char); +#endif + #ifdef __cplusplus } #endif diff --git a/include/winnt.h b/include/winnt.h index 794970a35f5..667be50b17f 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -7411,6 +7411,18 @@ static FORCEINLINE DWORD64 UnsignedMultiply128( DWORD64 a, DWORD64 b, DWORD64 *h #define _umul128 UnsignedMultiply128 #endif
+#if defined(_MSC_VER) && !defined(__arm64ec__) && (!defined(__clang__) || __has_builtin(__shiftright128)) +#define ShiftRight128 __shiftright128 +DWORD64 __shiftright128(DWORD64,DWORD64,BYTE); +#pragma intrinsic(__shiftright128) +#elif !defined(__i386__) +static FORCEINLINE DWORD64 ShiftRight128( DWORD64 lo, DWORD64 hi, BYTE shift ) +{ + return ((unsigned __int128)hi << 64 | lo) >> shift; +} +#define __shiftright128 ShiftRight128 +#endif + #ifdef __cplusplus } #endif
From: Rémi Bernon rbernon@codeweavers.com
--- include/msvcrt/intrin.h | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h index 1be630b5753..2a5de49fc73 100644 --- a/include/msvcrt/intrin.h +++ b/include/msvcrt/intrin.h @@ -98,6 +98,14 @@ unsigned __int64 _umul128(unsigned __int64,unsigned __int64,unsigned __int64*); unsigned __int64 __shiftright128(unsigned __int64,unsigned __int64,unsigned char); #endif
+#if defined(_MSC_VER) +unsigned char _BitScanForward(unsigned long*,unsigned long); +#endif + +#if defined(_MSC_VER) && defined(__x86_64__) || defined(__aarch64__) || defined(__arm64ec__) +unsigned char _BitScanForward64(unsigned long*,unsigned __int64); +#endif + #ifdef __cplusplus } #endif
From: Rémi Bernon rbernon@codeweavers.com
--- include/guiddef.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/guiddef.h b/include/guiddef.h index 0837ed34ad7..06a4495ca99 100644 --- a/include/guiddef.h +++ b/include/guiddef.h @@ -158,10 +158,10 @@ typedef GUID FMTID,*LPFMTID; #define IsEqualGUID(rguid1, rguid2) (!memcmp(&(rguid1), &(rguid2), sizeof(GUID))) inline int InlineIsEqualGUID(REFGUID rguid1, REFGUID rguid2) { - return (((unsigned int *)&rguid1)[0] == ((unsigned int *)&rguid2)[0] && - ((unsigned int *)&rguid1)[1] == ((unsigned int *)&rguid2)[1] && - ((unsigned int *)&rguid1)[2] == ((unsigned int *)&rguid2)[2] && - ((unsigned int *)&rguid1)[3] == ((unsigned int *)&rguid2)[3]); + return (((const UINT *)&rguid1)[0] == ((const UINT *)&rguid2)[0] && + ((const UINT *)&rguid1)[1] == ((const UINT *)&rguid2)[1] && + ((const UINT *)&rguid1)[2] == ((const UINT *)&rguid2)[2] && + ((const UINT *)&rguid1)[3] == ((const UINT *)&rguid2)[3]); } #else #define IsEqualGUID(rguid1, rguid2) (!memcmp(rguid1, rguid2, sizeof(GUID)))
From: Rémi Bernon rbernon@codeweavers.com
--- include/msvcrt/corecrt.h | 9 +++++++++ include/msvcrt/wchar.h | 12 ++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/include/msvcrt/corecrt.h b/include/msvcrt/corecrt.h index 65357a13403..ae926394ad9 100644 --- a/include/msvcrt/corecrt.h +++ b/include/msvcrt/corecrt.h @@ -250,6 +250,15 @@ typedef int errno_t; #define _ERRNO_T_DEFINED #endif
+#ifndef _CONST_RETURN +# ifdef __cplusplus +# define _CONST_RETURN const +# define _CRT_CONST_CORRECT_OVERLOADS +# else +# define _CONST_RETURN +# endif +#endif + struct threadlocaleinfostruct; struct threadmbcinfostruct; typedef struct threadlocaleinfostruct *pthreadlocinfo; diff --git a/include/msvcrt/wchar.h b/include/msvcrt/wchar.h index 4ca189bd2c7..98167b59076 100644 --- a/include/msvcrt/wchar.h +++ b/include/msvcrt/wchar.h @@ -45,14 +45,22 @@ int __cdecl wctob(wint_t);
_ACRTIMP errno_t __cdecl wmemcpy_s(wchar_t *, size_t, const wchar_t *, size_t);
-static inline wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) +static inline _CONST_RETURN wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n) { const wchar_t *end; for (end = s + n; s < end; s++) - if (*s == c) return (wchar_t*)s; + if (*s == c) return (_CONST_RETURN wchar_t *)s; return NULL; }
+#ifdef __cplusplus +extern "C++" inline wchar_t *wmemchr(wchar_t *s, wchar_t c, size_t n) +{ + wchar_t const* s_const = s; + return const_cast<wchar_t *>(wmemchr(s_const, c, n)); +} +#endif + static inline int wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) { size_t i;
Alfred Agrell (@Alcaro) commented about include/winbase.h:
WINBASEAPI void WINAPI DeleteFiber(LPVOID); WINBASEAPI BOOL WINAPI DeleteFileA(LPCSTR); WINBASEAPI BOOL WINAPI DeleteFileW(LPCWSTR); -#define DeleteFile WINELIB_NAME_AW(DeleteFile)
While I agree that that define is trouble (dlls/kernel32/tests/file.c already has a workaround), I feel that deleting it yields a high regression risk from code trying to call the actual function.
Perhaps you should instead move the define higher, so the struct's member gets renamed alongside the accessors. That's what the official headers do. https://godbolt.org/z/4a3fjsqTx
(Alternatively, create an inline function that calls the appropriate A/W version. I don't think anyone cares whether that name is a macro or a define, as long as it's callable.)
On Thu Oct 31 10:19:00 2024 +0000, Alfred Agrell wrote:
While I agree that that define is trouble (dlls/kernel32/tests/file.c already has a workaround), I feel that deleting it yields a high regression risk from code trying to call the actual function. Perhaps you should instead move the define higher, so the struct's member gets renamed alongside the accessors. That's what the official headers do. https://godbolt.org/z/4a3fjsqTx (Alternatively, create an inline function that calls the appropriate A/W version. I don't think anyone cares whether that name is a macro or a define, as long as it's callable.)
I don't know the reason behind these macros but given their "WINELIB" prefix I feel like there are there for historical reasons but that it became a bit less relevant now. For instance I don't think there's any "risk" of trying the call the function, it doesn't exist. So instead of a compilation error from the #define you would probably get a warning and -if it didn't fail before- a link error.
On Thu Oct 31 10:47:16 2024 +0000, Rémi Bernon wrote:
I don't know the reason behind these macros but given their "WINELIB" prefix I feel like there are there for historical reasons but that it became a bit less relevant now. For instance I don't think there's any "risk" of trying the call the function, it doesn't exist. So instead of a compilation error from the #define you would probably get a warning and -if it didn't fail before- a link error.
Eh sorry, the macro actually does the redirection when not building Wine source, so I guess they are relevant.