- Implement RtlCharToInteger, RtlExtendedMagicDivide, RtlUpperChar,
RtlInt64ToUnicodeString, RtlIntegerToChar, RtlIntegerToUnicodeString, RtlLargeIntegerToChar, RtlUnicodeStringToInteger and RtlUpcaseUnicodeChar. - Use toupperW instead of toupper in RtlCompareUnicodeString.
This commit is contained in:
parent
8cded56db3
commit
f4757bb631
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.@]
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue