Implemented Rtl*ByteSwap() functions, based on a patch by Jon Griffiths.
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 3b5a1c2..5ccb7b4 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec
@@ -530,6 +530,8 @@ @ stdcall RtlTimeToSecondsSince1970(ptr ptr) RtlTimeToSecondsSince1970 @ stdcall RtlTimeToSecondsSince1980(ptr ptr) RtlTimeToSecondsSince1980 @ stdcall RtlTimeToTimeFields (long long) RtlTimeToTimeFields +@ cdecl -i386 -norelay RtlUlongByteSwap() RtlUlongByteSwap +@ cdecl -ret64 RtlUlonglongByteSwap(long long) RtlUlonglongByteSwap @ stdcall RtlUnicodeStringToAnsiSize(ptr) RtlUnicodeStringToAnsiSize @ stdcall RtlUnicodeStringToAnsiString(ptr ptr long) RtlUnicodeStringToAnsiString @ stub RtlUnicodeStringToCountedOemString @@ -554,6 +556,7 @@ @ stdcall RtlUpperChar(long) RtlUpperChar @ stdcall RtlUpperString(ptr ptr) RtlUpperString @ stub RtlUsageHeap +@ cdecl -i386 -norelay RtlUshortByteSwap() RtlUshortByteSwap @ stub RtlValidAcl @ stdcall RtlValidSecurityDescriptor(ptr) RtlValidSecurityDescriptor @ stdcall RtlValidSid(ptr) RtlValidSid
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 0ca5778..953dd92 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c
@@ -682,3 +682,50 @@ } return ~crc; } + + +/************************************************************************* + * RtlUlonglongByteSwap [NTDLL.@] + * + * Swap the bytes of an unsigned long long value. + * + * PARAMS + * i [I] Value to swap bytes of + * + * RETURNS + * The value with its bytes swapped. + */ +ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG i) +{ + return ((ULONGLONG)RtlUlongByteSwap(i) << 32) | RtlUlongByteSwap(i>>32); +} + +/************************************************************************* + * RtlUlongByteSwap [NTDLL.@] + * + * Swap the bytes of an unsigned int value. + * + * NOTES + * ix86 version takes argument in %ecx. Other systems use the inline version. + */ +#ifdef __i386__ +__ASM_GLOBAL_FUNC(RtlUlongByteSwap, + "movl %ecx,%eax\n\t" + "bswap %eax\n\t" + "ret"); +#endif + +/************************************************************************* + * RtlUshortByteSwap [NTDLL.@] + * + * Swap the bytes of an unsigned short value. + * + * NOTES + * i386 version takes argument in %cx. Other systems use the inline version. + */ +#ifdef __i386__ +__ASM_GLOBAL_FUNC(RtlUshortByteSwap, + "movb %ch,%al\n\t" + "movb %cl,%ah\n\t" + "ret"); +#endif
diff --git a/include/winternl.h b/include/winternl.h index 809e9fc..b0478d3 100644 --- a/include/winternl.h +++ b/include/winternl.h
@@ -1050,6 +1050,7 @@ BOOLEAN WINAPI RtlTimeToSecondsSince1980(const LARGE_INTEGER *,LPDWORD); BOOL WINAPI RtlTryEnterCriticalSection(RTL_CRITICAL_SECTION *); +ULONGLONG __cdecl RtlUlonglongByteSwap(ULONGLONG); DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING*); NTSTATUS WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING,PCUNICODE_STRING,BOOLEAN); NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING *,ULONG,ULONG *); @@ -1134,6 +1135,22 @@ memset(_p->BitMapBuffer,0xff,((_p->SizeOfBitMap + 31) & 0xffffffe0) >> 3); \ } while (0) +/* These are implemented as __fastcall, so we can't let Winelib apps link with them */ +inline static USHORT RtlUshortByteSwap(USHORT s) +{ + return (s >> 8) | (s << 8); +} +inline static ULONG RtlUlongByteSwap(ULONG i) +{ +#if defined(__i386__) && defined(__GNUC__) + ULONG ret; + __asm__("bswap %0" : "=r" (ret) : "0" (i) ); + return ret; +#else + return ((ULONG)RtlUshortByteSwap(i) << 16) | RtlUshortByteSwap(i >> 16); +#endif +} + /************************************************************************* * Loader functions and structures. *