From f4757bb631fd4f5bd9711094ecc17a9818be2b1b Mon Sep 17 00:00:00 2001 From: Thomas Mertes Date: Wed, 19 Feb 2003 03:39:46 +0000 Subject: [PATCH] - Implement RtlCharToInteger, RtlExtendedMagicDivide, RtlUpperChar, RtlInt64ToUnicodeString, RtlIntegerToChar, RtlIntegerToUnicodeString, RtlLargeIntegerToChar, RtlUnicodeStringToInteger and RtlUpcaseUnicodeChar. - Use toupperW instead of toupper in RtlCompareUnicodeString. --- dlls/ntdll/large_int.c | 172 ++++++++++++++++++- dlls/ntdll/ntdll.spec | 15 +- dlls/ntdll/rtl.c | 7 - dlls/ntdll/rtlstr.c | 366 ++++++++++++++++++++++++++++++++++------- include/winternl.h | 9 +- 5 files changed, 490 insertions(+), 79 deletions(-) diff --git a/dlls/ntdll/large_int.c b/dlls/ntdll/large_int.c index 24d686d325a..f3e6dba9246 100644 --- a/dlls/ntdll/large_int.c +++ b/dlls/ntdll/large_int.c @@ -2,6 +2,7 @@ * Large integer functions * * Copyright 2000 Alexandre Julliard + * Copyright 2003 Thomas Mertes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -191,13 +192,174 @@ LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b ) * 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... + * Parameter b although defined as LONGLONG is used as ULONGLONG. */ -/* 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; + LONGLONG result; + int positive; + + if (a < 0) { + a_high = UPPER_32((ULONGLONG) -a); + a_low = LOWER_32((ULONGLONG) -a); + positive = 0; + } else { + a_high = UPPER_32((ULONGLONG) a); + a_low = LOWER_32((ULONGLONG) a); + positive = 1; + } /* if */ + b_high = UPPER_32((ULONGLONG) b); + b_low = LOWER_32((ULONGLONG) b); + + ah_bl = a_high * b_low; + al_bh = a_low * b_high; + + result = (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 (positive) { + return result; + } else { + return -result; + } /* if */ +} + + +/****************************************************************************** + * RtlLargeIntegerToChar [NTDLL.@] + * + * Convert an unsigned large integer to a character string. + * + * On success assign a string and return STATUS_SUCCESS. + * If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER + * Writes at most length characters to the string str. + * Str is '\0' terminated when length allowes it. + * When str fits exactly in length characters the '\0' is ommitted. + * When str would be larger than length: return STATUS_BUFFER_OVERFLOW + * For str == NULL return STATUS_ACCESS_VIOLATION. + * Do not check for value_ptr != NULL (as native DLL). + * + * Difference: + * - Accept base 0 as 10 instead of crashing as native DLL does. + * - The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for + * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF. */ +NTSTATUS WINAPI RtlLargeIntegerToChar( + const ULONGLONG *value_ptr, + ULONG base, + ULONG length, + PCHAR str) +{ + ULONGLONG value = *value_ptr; + CHAR buffer[65]; + PCHAR pos; + CHAR digit; + ULONG len; + + if (base == 0) { + base = 10; + } else if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } /* if */ + + 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); + + len = &buffer[64] - pos; + if (len > length) { + return STATUS_BUFFER_OVERFLOW; + } else if (str == NULL) { + return STATUS_ACCESS_VIOLATION; + } else if (len == length) { + memcpy(str, pos, len); + } else { + memcpy(str, pos, len + 1); + } /* if */ + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlInt64ToUnicodeString (NTDLL.@) + * + * Convert a large unsigned integer to a NULL terminated unicode string. + * + * On success assign a NULL terminated string and return STATUS_SUCCESS. + * If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER. + * If str is too small to hold the string (with the NULL termination): + * Set str->Length to the length the string would have (which can be + * larger than the MaximumLength) and return STATUS_BUFFER_OVERFLOW. + * Do not check for str != NULL (as native DLL). + * + * Difference: + * - Accept base 0 as 10 instead of crashing as native DLL does. + * - Do not return STATUS_BUFFER_OVERFLOW when the string is long enough. + * The native DLL does this when the string would be longer than 31 + * characters even when the string parameter is long enough. + * - The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for + * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF. + */ +NTSTATUS WINAPI RtlInt64ToUnicodeString( + ULONGLONG value, + ULONG base, + UNICODE_STRING *str) +{ + WCHAR buffer[65]; + PWCHAR pos; + WCHAR digit; + + if (base == 0) { + base = 10; + } else if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } /* if */ + + 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); + + str->Length = (&buffer[64] - pos) * sizeof(WCHAR); + if (str->Length >= str->MaximumLength) { + return STATUS_BUFFER_OVERFLOW; + } else { + memcpy(str->Buffer, pos, str->Length + 1); + } /* if */ + return STATUS_SUCCESS; +} /****************************************************************************** diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index d443821a2ca..9a4e2afd0c5 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -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,9 @@ @ stdcall RtlInitializeResource(ptr) RtlInitializeResource @ stdcall RtlInitializeSid(ptr ptr long) RtlInitializeSid @ stub RtlInsertElementGenericTable -@ stdcall RtlIntegerToChar(long long long long) RtlIntegerToChar -@ stub RtlIntegerToUnicodeString +@ stdcall RtlInt64ToUnicodeString(long long long ptr) RtlInt64ToUnicodeString +@ stdcall RtlIntegerToChar(long long long ptr) RtlIntegerToChar +@ stdcall RtlIntegerToUnicodeString(long long ptr) RtlIntegerToUnicodeString @ stub RtlIsDosDeviceName_U @ stub RtlIsGenericTableEmpty @ stub RtlIsNameLegalDOS8Dot3 @@ -445,7 +446,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(ptr long long ptr) RtlLargeIntegerToChar @ stdcall RtlLeaveCriticalSection(ptr) RtlLeaveCriticalSection @ stdcall RtlLengthRequiredSid(long) RtlLengthRequiredSid @ stdcall RtlLengthSecurityDescriptor(ptr) RtlLengthSecurityDescriptor @@ -540,7 +541,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 +549,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 --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index c5d604aa595..10d5cf0dbc7 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -261,13 +261,6 @@ VOID WINAPI RtlReleasePebLock(void) RtlLeaveCriticalSection( &peb_lock ); } -/****************************************************************************** - * 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; -} /****************************************************************************** * RtlSetEnvironmentVariable [NTDLL.@] */ diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index 2bab2bc8f4a..ce4c2fa4049 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -3,6 +3,7 @@ * * Copyright (C) 1996-1998 Marcus Meissner * Copyright (C) 2000 Alexandre Julliard + * Copyright (C) 2003 Thomas Mertes * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -198,10 +199,12 @@ void WINAPI RtlEraseUnicodeString( UNICODE_STRING *str ) } } + /* COMPARISON FUNCTIONS */ + /****************************************************************************** * RtlCompareString (NTDLL.@) */ @@ -315,7 +318,7 @@ BOOLEAN WINAPI RtlPrefixUnicodeString( const UNICODE_STRING *s1, if (ignore_case) { for (i = 0; i < s1->Length / sizeof(WCHAR); i++) - if (toupper(s1->Buffer[i]) != toupper(s2->Buffer[i])) return FALSE; + if (toupperW(s1->Buffer[i]) != toupperW(s2->Buffer[i])) return FALSE; } else { @@ -515,6 +518,20 @@ NTSTATUS WINAPI RtlUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen, CASE CONVERSIONS */ + +/************************************************************************** + * RtlUpperChar (NTDLL.@) + */ +CHAR WINAPI RtlUpperChar( CHAR ch ) +{ + if (ch >= 'a' && ch <= 'z') { + return ch - 'a' + 'A'; + } else { + return ch; + } +} + + /************************************************************************** * RtlUpperString (NTDLL.@) */ @@ -522,11 +539,20 @@ void WINAPI RtlUpperString( STRING *dst, const STRING *src ) { unsigned int i, len = min(src->Length, dst->MaximumLength); - for (i = 0; i < len; i++) dst->Buffer[i] = toupper(src->Buffer[i]); + for (i = 0; i < len; i++) dst->Buffer[i] = RtlUpperChar(src->Buffer[i]); dst->Length = len; } +/************************************************************************** + * RtlUpcaseUnicodeChar (NTDLL.@) + */ +WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch ) +{ + return toupperW(wch); +} + + /************************************************************************** * RtlUpcaseUnicodeString (NTDLL.@) * @@ -638,6 +664,7 @@ NTSTATUS WINAPI RtlUpcaseUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen, STRING SIZE */ + /************************************************************************** * RtlOemStringToUnicodeSize (NTDLL.@) * RtlxOemStringToUnicodeSize (NTDLL.@) @@ -790,6 +817,7 @@ NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICO MISC */ + /************************************************************************** * RtlIsTextUnicode (NTDLL.@) * @@ -836,75 +864,295 @@ out: return len; } + /************************************************************************** - * RtlUnicodeStringToInteger (NTDLL.@) + * RtlCharToInteger (NTDLL.@) * - * Convert a text buffer into its integer form + * Convert a character string into its integer equivalent. + * + * On success assign an integer value and return STATUS_SUCCESS. + * For base 0 accept: {whitespace} [+|-] [0[x|o|b]] {digits} + * For bases 2, 8, 10 and 16 accept: {whitespace} [+|-] {digits} + * For other bases return STATUS_INVALID_PARAMETER. + * For value == NULL return STATUS_ACCESS_VIOLATION. + * No check of value overflow: Just assign lower 32 bits (as native DLL). + * Do not check for str != NULL (as native DLL). + * + * Difference: + * - Do not read garbage behind '\0' as native DLL does. + */ +NTSTATUS WINAPI RtlCharToInteger( + PCSZ str, + ULONG base, + ULONG *value) +{ + CHAR chCurrent; + int digit; + ULONG RunningTotal = 0; + char bMinus = 0; + + while (*str != '\0' && *str <= ' ') { + str++; + } /* while */ + + if (*str == '+') { + str++; + } else if (*str == '-') { + bMinus = 1; + str++; + } /* if */ + + if (base == 0) { + base = 10; + if (str[0] == '0') { + if (str[1] == 'b') { + str += 2; + base = 2; + } else if (str[1] == 'o') { + str += 2; + base = 8; + } else if (str[1] == 'x') { + str += 2; + base = 16; + } /* if */ + } /* if */ + } else if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } /* if */ + + if (value == NULL) { + return STATUS_ACCESS_VIOLATION; + } /* if */ + + while (*str != '\0') { + chCurrent = *str; + if (chCurrent >= '0' && chCurrent <= '9') { + digit = chCurrent - '0'; + } else if (chCurrent >= 'A' && chCurrent <= 'Z') { + digit = chCurrent - 'A' + 10; + } else if (chCurrent >= 'a' && chCurrent <= 'z') { + digit = chCurrent - 'a' + 10; + } else { + digit = -1; + } /* if */ + if (digit < 0 || digit >= base) { + *value = bMinus ? -RunningTotal : RunningTotal; + return STATUS_SUCCESS; + } /* if */ + + RunningTotal = RunningTotal * base + digit; + str++; + } /* while */ + + *value = bMinus ? -RunningTotal : RunningTotal; + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlIntegerToChar (NTDLL.@) + * + * Convert an unsigned integer to a character string. + * + * On success assign a string and return STATUS_SUCCESS. + * If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER + * Writes at most length characters to the string str. + * Str is '\0' terminated when length allowes it. + * When str fits exactly in length characters the '\0' is ommitted. + * When str would be larger than length: return STATUS_BUFFER_OVERFLOW + * For str == NULL return STATUS_ACCESS_VIOLATION. + */ +NTSTATUS WINAPI RtlIntegerToChar( + ULONG value, + ULONG base, + ULONG length, + PCHAR str) +{ + CHAR buffer[33]; + PCHAR pos; + CHAR digit; + ULONG len; + + if (base == 0) { + base = 10; + } else if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } /* if */ + + 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); + + len = &buffer[32] - pos; + if (len > length) { + return STATUS_BUFFER_OVERFLOW; + } else if (str == NULL) { + return STATUS_ACCESS_VIOLATION; + } else if (len == length) { + memcpy(str, pos, len); + } else { + memcpy(str, pos, len + 1); + } /* if */ + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlUnicodeStringToInteger (NTDLL.@) + * + * Convert an unicode string into its integer equivalent. + * + * On success assign an integer value and return STATUS_SUCCESS. + * For base 0 accept: {whitespace} [+|-] [0[x|o|b]] {digits} + * For bases 2, 8, 10 and 16 accept: {whitespace} [+|-] {digits} + * For other bases return STATUS_INVALID_PARAMETER. + * For value == NULL return STATUS_ACCESS_VIOLATION. + * No check of value overflow: Just assign lower 32 bits (as native DLL). + * Do not check for str != NULL (as native DLL). + * + * Difference: + * - Do not read garbage on string length 0 as native DLL does. */ NTSTATUS WINAPI RtlUnicodeStringToInteger( const UNICODE_STRING *str, - int base, - int * pdest) + ULONG base, + ULONG *value) { - LPWSTR lpwstr = str->Buffer; - WCHAR wchCurrent = 0; - int CharsParsed = 0; - int RunningTotal = 0; - char bMinus = 0; + LPWSTR lpwstr = str->Buffer; + USHORT CharsRemaining = str->Length / sizeof(WCHAR); + WCHAR wchCurrent; + int digit; + ULONG RunningTotal = 0; + char bMinus = 0; - /* no checking done on UNICODE_STRING and int* in native DLL either */ - TRACE("(%p, %d, %p)", str, base, pdest); + while (CharsRemaining >= 1 && *lpwstr <= ' ') { + lpwstr++; + CharsRemaining--; + } /* while */ - switch (base) - { - case 0: - base = 10; - break; - case 2: - case 8: - case 10: - case 16: - break; - default: - return STATUS_INVALID_PARAMETER; - } + if (CharsRemaining >= 1) { + if (*lpwstr == '+') { + lpwstr++; + CharsRemaining--; + } else if (*lpwstr == '-') { + bMinus = 1; + lpwstr++; + CharsRemaining--; + } /* if */ + } /* if */ - if ((str->Length) >= 4 && (base == 10) && (*lpwstr == '0') && (*(lpwstr+1) == 'x')) - { - lpwstr+=2; + if (base == 0) { + base = 10; + if (CharsRemaining >= 2 && lpwstr[0] == '0') { + if (lpwstr[1] == 'b') { + lpwstr += 2; + CharsRemaining -= 2; + base = 2; + } else if (lpwstr[1] == 'o') { + lpwstr += 2; + CharsRemaining -= 2; + base = 8; + } else if (lpwstr[1] == 'x') { + lpwstr += 2; + CharsRemaining -= 2; base = 16; - } + } /* if */ + } /* if */ + } else if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } /* if */ - *pdest = 0; - for (; (CharsParsed*sizeof(WCHAR) < str->Length) && (*lpwstr <= ' '); lpwstr++) - CharsParsed++; + if (value == NULL) { + return STATUS_ACCESS_VIOLATION; + } /* if */ - if (*lpwstr == '+') - lpwstr++; - else if (*lpwstr == '-') - { - bMinus = 1; - lpwstr++; - } + while (CharsRemaining >= 1) { + wchCurrent = *lpwstr; + if (wchCurrent >= '0' && wchCurrent <= '9') { + digit = wchCurrent - '0'; + } else if (wchCurrent >= 'A' && wchCurrent <= 'Z') { + digit = wchCurrent - 'A' + 10; + } else if (wchCurrent >= 'a' && wchCurrent <= 'z') { + digit = wchCurrent - 'a' + 10; + } else { + digit = -1; + } /* if */ + if (digit < 0 || digit >= base) { + *value = bMinus ? -RunningTotal : RunningTotal; + return STATUS_SUCCESS; + } /* if */ - for (; (CharsParsed*sizeof(WCHAR) < str->Length) && (*lpwstr != '\0'); lpwstr++) - { - CharsParsed++; - wchCurrent = *lpwstr; - if (wchCurrent >= 'A') - wchCurrent = '0' + 10 + wchCurrent - 'A'; - if ((wchCurrent - '0') >= base || wchCurrent < '0') - { - *pdest = bMinus ? -RunningTotal: RunningTotal; - return STATUS_SUCCESS; - } - /* - * increase significance of previous digits each time - * we find another valid one and add on this valid one - */ - RunningTotal = wchCurrent - '0' + RunningTotal * base; - } + RunningTotal = RunningTotal * base + digit; + lpwstr++; + CharsRemaining--; + } /* while */ - *pdest = bMinus ? -RunningTotal : RunningTotal; - return STATUS_SUCCESS; + *value = bMinus ? -RunningTotal : RunningTotal; + return STATUS_SUCCESS; +} + + +/************************************************************************** + * RtlIntegerToUnicodeString (NTDLL.@) + * + * Convert an unsigned integer to a NULL terminated unicode string. + * + * On success assign a NULL terminated string and return STATUS_SUCCESS. + * If base is not 0 (=10), 2, 8, 10 or 16 return STATUS_INVALID_PARAMETER. + * If str is too small to hold the string (with the NULL termination): + * Set str->Length to the length the string would have (which can be + * larger than the MaximumLength) and return STATUS_BUFFER_OVERFLOW. + * Do not check for str != NULL (as native DLL). + * + * Difference: + * - Do not return STATUS_BUFFER_OVERFLOW when the string is long enough. + * The native DLL does this when the string would be longer than 16 + * characters even when the string parameter is long enough. + */ +NTSTATUS WINAPI RtlIntegerToUnicodeString( + ULONG value, + ULONG base, + UNICODE_STRING *str) +{ + WCHAR buffer[33]; + PWCHAR pos; + WCHAR digit; + + if (base == 0) { + base = 10; + } else if (base != 2 && base != 8 && base != 10 && base != 16) { + return STATUS_INVALID_PARAMETER; + } /* if */ + + 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); + + str->Length = (&buffer[32] - pos) * sizeof(WCHAR); + if (str->Length >= str->MaximumLength) { + return STATUS_BUFFER_OVERFLOW; + } else { + memcpy(str->Buffer, pos, str->Length + 1); + } /* if */ + return STATUS_SUCCESS; } diff --git a/include/winternl.h b/include/winternl.h index bc7ce48a535..6070cebe956 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -977,7 +977,9 @@ void WINAPI RtlInitializeBitMap(PRTL_BITMAP,LPBYTE,ULONG); void WINAPI RtlInitializeResource(LPRTL_RWLOCK); BOOL WINAPI RtlInitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); -DWORD WINAPI RtlIntegerToChar(DWORD,DWORD,DWORD,DWORD); +NTSTATUS WINAPI RtlInt64ToUnicodeString(ULONGLONG,ULONG,UNICODE_STRING *); +NTSTATUS WINAPI RtlIntegerToChar(ULONG,ULONG,ULONG,PCHAR); +NTSTATUS WINAPI RtlIntegerToUnicodeString(ULONG,ULONG,UNICODE_STRING *); BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3(PUNICODE_STRING,POEM_STRING,PBOOLEAN); DWORD WINAPI RtlIsTextUnicode(LPVOID,DWORD,DWORD *); @@ -988,6 +990,7 @@ LONGLONG WINAPI RtlLargeIntegerNegate(LONGLONG); LONGLONG WINAPI RtlLargeIntegerShiftLeft(LONGLONG,INT); LONGLONG WINAPI RtlLargeIntegerShiftRight(LONGLONG,INT); LONGLONG WINAPI RtlLargeIntegerSubtract(LONGLONG,LONGLONG); +NTSTATUS WINAPI RtlLargeIntegerToChar(const ULONGLONG *,ULONG,ULONG,PCHAR); NTSTATUS WINAPI RtlLeaveCriticalSection(RTL_CRITICAL_SECTION *); DWORD WINAPI RtlLengthRequiredSid(DWORD); ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR); @@ -1045,6 +1048,7 @@ BOOL WINAPI RtlTryEnterCriticalSection(RTL_CRITICAL_SECTION *); DWORD WINAPI RtlUnicodeStringToAnsiSize(const UNICODE_STRING*); NTSTATUS WINAPI RtlUnicodeStringToAnsiString(PANSI_STRING,PCUNICODE_STRING,BOOLEAN); +NTSTATUS WINAPI RtlUnicodeStringToInteger(const UNICODE_STRING *,ULONG,ULONG *); DWORD WINAPI RtlUnicodeStringToOemSize(const UNICODE_STRING*); NTSTATUS WINAPI RtlUnicodeStringToOemString(POEM_STRING,PCUNICODE_STRING,BOOLEAN); NTSTATUS WINAPI RtlUnicodeToMultiByteN(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); @@ -1057,11 +1061,14 @@ void WINAPI RtlUnwind(PVOID,PVOID,PEXCEPTION_RECORD,PVOID); 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); 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); +void WINAPI RtlUpperString(STRING *,const STRING *); NTSTATUS WINAPI RtlValidSecurityDescriptor(PSECURITY_DESCRIPTOR); BOOL WINAPI RtlValidSid(PSID);