diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 3b5a1c2e943..5ccb7b45868 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 0ca577821d9..953dd92ba80 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -682,3 +682,50 @@ DWORD WINAPI RtlComputeCrc32(DWORD dwInitial, PBYTE pData, INT iLen) } 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 809e9fcd1c1..b0478d3884c 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1050,6 +1050,7 @@ BOOLEAN WINAPI RtlTimeToSecondsSince1970(const LARGE_INTEGER *,PULONG); 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 @@ inline static BOOLEAN RtlCheckBit(PCRTL_BITMAP lpBits, ULONG ulBit) 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. *