Hello Here are implementations of some ntdll functions. Greetings Thomas Mertes Changelog: * dlls/ntdll/ntdll.spec, dlls/ntdll/large_int.c, dlls/ntdll/rtl.c, dlls/ntdll/rtlstr.c, include/winternl.h: Thomas Mertes <thomas.mertes@t-mobile.at> Implement RtlExtendedMagicDivide, RtlUpperChar, RtlIntegerToChar, RtlUpcaseUnicodeChar, RtlIntegerToUnicodeString and RtlLargeIntegerToChar diff -urN old_wine-20030115/dlls/ntdll/large_int.c new_wine-20030115/dlls/ntdll/large_int.c --- old_wine-20030115/dlls/ntdll/large_int.c Tue Dec 10 23:56:45 2002 +++ new_wine-20030115/dlls/ntdll/large_int.c Mon Jan 27 00:05:30 2003 @@ -191,14 +191,93 @@ * must be chosen such that b = 2^(64+shift) / c. * Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c. * - * I'm too lazy to implement it right now... + * FIXME: should the division be signed or unsigned? */ -/* LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift ) - * { - * return 0; - * } +#define LOWER_32(A) ((A) & 0xffffffff) +#define UPPER_32(A) ((A) >> 32) +LONGLONG WINAPI RtlExtendedMagicDivide( LONGLONG a, LONGLONG b, INT shift ) +{ + ULONGLONG a_high; + ULONGLONG a_low; + ULONGLONG b_high; + ULONGLONG b_low; + ULONGLONG ah_bl; + ULONGLONG al_bh; + int sign; + + if (a < 0) { + a_high = UPPER_32((ULONGLONG) -a); + a_low = LOWER_32((ULONGLONG) -a); + sign = -1; + } else { + a_high = UPPER_32((ULONGLONG) a); + a_low = LOWER_32((ULONGLONG) a); + sign = 1; + } /* if */ + if (b < 0) { + b_high = UPPER_32((ULONGLONG) -b); + b_low = LOWER_32((ULONGLONG) -b); + sign = -sign; + } else { + b_high = UPPER_32((ULONGLONG) b); + b_low = LOWER_32((ULONGLONG) b); + } /* if */ + + ah_bl = a_high * b_low; + al_bh = a_low * b_high; + + if (sign == 1) { + return((LONGLONG) ((a_high * b_high + + UPPER_32(ah_bl) + + UPPER_32(al_bh) + + UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) + UPPER_32(a_low * b_low))) >> shift)); + } else { + return(- (LONGLONG) ((a_high * b_high + + UPPER_32(ah_bl) + + UPPER_32(al_bh) + + UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) + UPPER_32(a_low * b_low))) >> shift)); + } /* if */ +} + + +/****************************************************************************** + * RtlLargeIntegerToChar [NTDLL.@] */ +NTSTATUS WINAPI RtlLargeIntegerToChar(ULONGLONG value, ULONG base, ULONG length, PCHAR str) +{ + CHAR buffer[65]; + PCHAR pos; + CHAR digit; + + if (base == 0) { + base = 10; + } + + if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } + + pos = &buffer[64]; + *pos = '\0'; + + do { + pos--; + digit = value % base; + value = value / base; + if (digit < 10) { + *pos = '0' + digit; + } else { + *pos = 'a' + digit - 10; + } /* if */ + } while (value != 0L); + + if (&buffer[64] - pos >= length) { + return STATUS_BUFFER_TOO_SMALL; + } + memcpy(str, pos, (&buffer[64] - pos + 1) * sizeof(CHAR)); + return STATUS_SUCCESS; +} /****************************************************************************** * _alldiv (NTDLL.@) diff -urN old_wine-20030115/dlls/ntdll/ntdll.spec new_wine-20030115/dlls/ntdll/ntdll.spec --- old_wine-20030115/dlls/ntdll/ntdll.spec Mon Jan 13 21:44:14 2003 +++ new_wine-20030115/dlls/ntdll/ntdll.spec Mon Jan 27 00:05:13 2003 @@ -289,7 +289,7 @@ @ stdcall RtlAreBitsSet(ptr long long) RtlAreBitsSet @ stdcall RtlAssert(ptr ptr long long) RtlAssert @ stub RtlCaptureStackBackTrace -@ stub RtlCharToInteger +@ stdcall RtlCharToInteger(ptr long ptr) RtlCharToInteger @ stub RtlCheckRegistryKey @ stdcall RtlClearAllBits(ptr) RtlClearAllBits @ stdcall RtlClearBits(ptr long long) RtlClearBits @@ -367,7 +367,7 @@ @ stub RtlExtendHeap @ stdcall -ret64 RtlExtendedIntegerMultiply(long long long) RtlExtendedIntegerMultiply @ stdcall -ret64 RtlExtendedLargeIntegerDivide(long long long ptr) RtlExtendedLargeIntegerDivide -@ stub RtlExtendedMagicDivide +@ stdcall -ret64 RtlExtendedMagicDivide(long long long long long) RtlExtendedMagicDivide @ stdcall RtlFillMemory(ptr long long) RtlFillMemory @ stdcall RtlFillMemoryUlong(ptr long long) RtlFillMemoryUlong @ stdcall RtlFindClearBits(ptr long long) RtlFindClearBits @@ -432,8 +432,8 @@ @ stdcall RtlInitializeResource(ptr) RtlInitializeResource @ stdcall RtlInitializeSid(ptr ptr long) RtlInitializeSid @ stub RtlInsertElementGenericTable -@ stdcall RtlIntegerToChar(long long long long) RtlIntegerToChar -@ stub RtlIntegerToUnicodeString +@ stdcall RtlIntegerToChar(long long long ptr) RtlIntegerToChar +@ stdcall RtlIntegerToUnicodeString(long long ptr) RtlIntegerToUnicodeString @ stub RtlIsDosDeviceName_U @ stub RtlIsGenericTableEmpty @ stub RtlIsNameLegalDOS8Dot3 @@ -445,7 +445,7 @@ @ stdcall -ret64 RtlLargeIntegerShiftLeft(long long long) RtlLargeIntegerShiftLeft @ stdcall -ret64 RtlLargeIntegerShiftRight(long long long) RtlLargeIntegerShiftRight @ stdcall -ret64 RtlLargeIntegerSubtract(long long long long) RtlLargeIntegerSubtract -@ stub RtlLargeIntegerToChar +@ stdcall RtlLargeIntegerToChar(long long long long ptr) RtlLargeIntegerToChar @ stdcall RtlLeaveCriticalSection(ptr) RtlLeaveCriticalSection @ stdcall RtlLengthRequiredSid(long) RtlLengthRequiredSid @ stdcall RtlLengthSecurityDescriptor(ptr) RtlLengthSecurityDescriptor @@ -540,7 +540,7 @@ @ stub RtlUniform @ stdcall RtlUnlockHeap(long) RtlUnlockHeap @ stdcall RtlUnwind(ptr ptr ptr long) RtlUnwind -@ stub RtlUpcaseUnicodeChar +@ stdcall RtlUpcaseUnicodeChar(long) RtlUpcaseUnicodeChar @ stdcall RtlUpcaseUnicodeString(ptr ptr long) RtlUpcaseUnicodeString @ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long) RtlUpcaseUnicodeStringToAnsiString @ stub RtlUpcaseUnicodeStringToCountedOemString @@ -548,7 +548,7 @@ @ stub RtlUpcaseUnicodeToCustomCPN @ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr ptr long) RtlUpcaseUnicodeToMultiByteN @ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long) RtlUpcaseUnicodeToOemN -@ stub RtlUpperChar +@ stdcall RtlUpperChar(long) RtlUpperChar @ stdcall RtlUpperString(ptr ptr) RtlUpperString @ stub RtlUsageHeap @ stub RtlValidAcl diff -urN old_wine-20030115/dlls/ntdll/rtl.c new_wine-20030115/dlls/ntdll/rtl.c --- old_wine-20030115/dlls/ntdll/rtl.c Thu Nov 21 04:45:03 2002 +++ new_wine-20030115/dlls/ntdll/rtl.c Sun Jan 26 00:02:40 2003 @@ -262,12 +262,53 @@ } /****************************************************************************** + * RtlCharToInteger [NTDLL.@] + */ +NTSTATUS WINAPI RtlCharToInteger(PCSZ str, ULONG base, ULONG *value) +{ + FIXME("(%s,%lu,%p),stub!\n",str,base,value); + return 0; +} + +/****************************************************************************** * RtlIntegerToChar [NTDLL.@] */ -DWORD WINAPI RtlIntegerToChar(DWORD x1,DWORD x2,DWORD x3,DWORD x4) { - FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx),stub!\n",x1,x2,x3,x4); - return 0; +NTSTATUS WINAPI RtlIntegerToChar(ULONG value, ULONG base, ULONG length, PCHAR str) +{ + CHAR buffer[33]; + PCHAR pos; + CHAR digit; + + if (base == 0) { + base = 10; + } + + if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } + + pos = &buffer[32]; + *pos = '\0'; + + do { + pos--; + digit = value % base; + value = value / base; + if (digit < 10) { + *pos = '0' + digit; + } else { + *pos = 'a' + digit - 10; + } /* if */ + } while (value != 0L); + + if (&buffer[32] - pos >= length) { + return STATUS_BUFFER_TOO_SMALL; + } + + memcpy(str, pos, (&buffer[32] - pos + 1) * sizeof(CHAR)); + return STATUS_SUCCESS; } + /****************************************************************************** * RtlSetEnvironmentVariable [NTDLL.@] */ diff -urN old_wine-20030115/dlls/ntdll/rtlstr.c new_wine-20030115/dlls/ntdll/rtlstr.c --- old_wine-20030115/dlls/ntdll/rtlstr.c Tue Nov 12 03:17:34 2002 +++ new_wine-20030115/dlls/ntdll/rtlstr.c Sun Jan 26 00:03:56 2003 @@ -516,6 +516,15 @@ */ /************************************************************************** + * RtlUpperChar (NTDLL.@) + */ +CHAR WINAPI RtlUpperChar( CHAR ch ) +{ + return toupper(ch); +} + + +/************************************************************************** * RtlUpperString (NTDLL.@) */ void WINAPI RtlUpperString( STRING *dst, const STRING *src ) @@ -528,6 +537,15 @@ /************************************************************************** + * RtlUpcaseUnicodeChar (NTDLL.@) + */ +WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch ) +{ + return toupperW(wch); +} + + +/************************************************************************** * RtlUpcaseUnicodeString (NTDLL.@) * * NOTES: @@ -836,6 +854,7 @@ return len; } + /************************************************************************** * RtlUnicodeStringToInteger (NTDLL.@) * @@ -907,4 +926,50 @@ *pdest = bMinus ? -RunningTotal : RunningTotal; return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlIntegerToUnicodeString (NTDLL.@) + * + * Convert an integer to its text form + */ +NTSTATUS WINAPI RtlIntegerToUnicodeString( + ULONG value, + ULONG base, + const UNICODE_STRING *str) +{ + WCHAR buffer[33]; + PWCHAR pos; + WCHAR digit; + + if (base == 0) { + base = 10; + } + + if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } + + pos = &buffer[32]; + *pos = '\0'; + + do { + pos--; + digit = value % base; + value = value / base; + if (digit < 10) { + *pos = '0' + digit; + } else { + *pos = 'a' + digit - 10; + } /* if */ + } while (value != 0L); + + if (&buffer[32] - pos > str->MaximumLength) { + return STATUS_BUFFER_TOO_SMALL; + } + + memcpy(str, pos, (&buffer[32] - pos) * sizeof(WCHAR)); + str->Length = &buffer[32] - pos; + return STATUS_SUCCESS; } diff -urN old_wine-20030115/include/winternl.h new_wine-20030115/include/winternl.h --- old_wine-20030115/include/winternl.h Sat Jan 4 01:52:19 2003 +++ new_wine-20030115/include/winternl.h Mon Jan 27 22:28:51 2003 @@ -977,7 +977,8 @@ void WINAPI RtlInitializeResource(LPRTL_RWLOCK); BOOL WINAPI RtlInitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); -DWORD WINAPI RtlIntegerToChar(DWORD,DWORD,DWORD,DWORD); +NTSTATUS WINAPI RtlIntegerToChar(ULONG,ULONG,ULONG,PCHAR); +NTSTATUS WINAPI RtlIntegerToUnicodeString(ULONG value, ULONG base,const UNICODE_STRING *str); BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(PUNICODE_STRING,POEM_STRING,PBOOLEAN); DWORD WINAPI RtlIsTextUnicode(LPVOID,DWORD,DWORD *); @@ -988,6 +989,7 @@ LONGLONG WINAPI RtlLargeIntegerShiftLeft(LONGLONG,INT); LONGLONG WINAPI RtlLargeIntegerShiftRight(LONGLONG,INT); LONGLONG WINAPI RtlLargeIntegerSubtract(LONGLONG,LONGLONG); +NTSTATUS WINAPI RtlLargeIntegerToChar(ULONGLONG value, ULONG base, ULONG length, PCHAR str); NTSTATUS WINAPI RtlLeaveCriticalSection(RTL_CRITICAL_SECTION *); DWORD WINAPI RtlLengthRequiredSid(DWORD); ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR); @@ -1057,11 +1059,14 @@ void WINAPI RtlUnwind2(FRAME_POINTERS,PVOID,PEXCEPTION_RECORD,PVOID,PCONTEXT); void WINAPI RtlUnwindEx(FRAME_POINTERS,PVOID,PEXCEPTION_RECORD,PVOID,PCONTEXT,PUNWIND_HISTORY_TABLE); #endif +WCHAR WINAPI RtlUpcaseUnicodeChar(WCHAR wch); NTSTATUS WINAPI RtlUpcaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING *,BOOLEAN); NTSTATUS WINAPI RtlUpcaseUnicodeStringToAnsiString(STRING*,const UNICODE_STRING*,BOOLEAN); NTSTATUS WINAPI RtlUpcaseUnicodeStringToOemString(STRING*,const UNICODE_STRING*,BOOLEAN); NTSTATUS WINAPI RtlUpcaseUnicodeToMultiByteN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); NTSTATUS WINAPI RtlUpcaseUnicodeToOemN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); +CHAR WINAPI RtlUpperChar(CHAR ch); +void WINAPI RtlUpperString(STRING *dst, const STRING *src); NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR); BOOL WINAPI RtlValidSid(PSID);