Hello
Here are implementations of some ntdll functions.
I have tested some of the functions a lot on w2k
(see part2: tests).
Changelog:
* dlls/ntdll/ntdll.spec, dlls/ntdll/string.c,
dlls/ntdll/wcstring.c, dlls/ntdll/rtlstr.c,
dlls/ntdll/large_int.c, dlls/ntdll/rtl.c,
include/winternl.h
Thomas Mertes <thomas.mertes@gmx.at>
- Implement RtlDowncaseUnicodeString,
RtlUniform, iswdigit, iswlower, iswspace,
iswxdigit
- Fixed RtlInt64ToUnicodeString and
RtlIntegerToUnicodeString
- According to tests
RtlAppendUnicodeStringToString leaves
the destination unchanged when the
source length is 0 (FIXED).
- Documentation updates in
RtlExtendedMagicDivide,
RtlLargeIntegerToChar,
RtlInt64ToUnicodeString, RtlUpperChar,
RtlUpperString, RtlUpcaseUnicodeChar,
RtlCharToInteger, RtlIntegerToChar,
RtlUnicodeStringToInteger,
RtlIntegerToUnicodeString, _ultoa,
_ltoa, _itoa, _ui64toa, _i64toa, _atoi64,
_ultow, _ltow, _itow, _ui64tow, _i64tow,
_wtol, _wtoi, _wtoi64
Greetings
Thomas Mertes
--
+++ GMX - Mail, Messaging & more http://www.gmx.net +++
Bitte lächeln! Fotogalerie online mit GMX ohne eigene Homepage!
diff -urN old_wine-20030318/dlls/ntdll/large_int.c new_wine-20030318/dlls/ntdll/large_int.c
--- old_wine-20030318/dlls/ntdll/large_int.c Wed Feb 19 04:39:46 2003
+++ new_wine-20030318/dlls/ntdll/large_int.c Fri Mar 21 01:39:51 2003
@@ -185,21 +185,25 @@
*
* This function computes (a * b) >> (64 + shift)
*
- * This allows replacing a division by a longlong constant
- * by a multiplication by the inverse constant.
+ * RETURNS
+ * (a * b) >> (64 + shift)
*
- * If 'c' is the constant divisor, the constants 'b' and 'shift'
- * must be chosen such that b = 2^(64+shift) / c.
- * Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
+ * NOTES
+ * This allows replacing a division by a longlong constant
+ * by a multiplication by the inverse constant.
+ *
+ * If 'c' is the constant divisor, the constants 'b' and 'shift'
+ * must be chosen such that b = 2^(64+shift) / c.
+ * Then we have RtlExtendedMagicDivide(a,b,shift) == a * b / 2^(64+shift) == a / c.
*
- * Parameter b although defined as LONGLONG is used as ULONGLONG.
+ * The Parameter b although defined as LONGLONG is used as ULONGLONG.
*/
#define LOWER_32(A) ((A) & 0xffffffff)
#define UPPER_32(A) ((A) >> 32)
LONGLONG WINAPI RtlExtendedMagicDivide(
- LONGLONG a,
- LONGLONG b,
- INT shift)
+ LONGLONG a, /* [I] Dividend to be divided by the constant divisor */
+ LONGLONG b, /* [I] Constant computed manually as 2^(64+shift) / divisor */
+ INT shift) /* [I] Constant shift chosen to make b as big as possible for 64 bits */
{
ULONGLONG a_high;
ULONGLONG a_low;
@@ -243,25 +247,29 @@
*
* 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
+ * RETURNS
+ * Success: STATUS_SUCCESS. str contains the converted number
+ * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ * STATUS_BUFFER_OVERFLOW, if str would be larger than length.
+ * STATUS_ACCESS_VIOLATION, if str is NULL.
+ *
+ * NOTES
+ * Instead of base 0 it uses 10 as base.
+ * 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.
+ * If value_ptr is NULL it crashes, as the native function does.
+ *
+ * DIFFERENCES
+ * - Accept base 0 as 10 instead of crashing as native function does.
+ * - The native function 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)
+ const ULONGLONG *value_ptr, /* [I] Pointer to the value to be converted */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ ULONG length, /* [I] Length of the str buffer in bytes */
+ PCHAR str) /* [O] Destination for the converted value */
{
ULONGLONG value = *value_ptr;
CHAR buffer[65];
@@ -306,27 +314,32 @@
/**************************************************************************
* RtlInt64ToUnicodeString (NTDLL.@)
*
- * Convert a large unsigned integer to a NULL terminated unicode string.
+ * Convert a large unsigned integer to a '\0' 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).
+ * RETURNS
+ * Success: STATUS_SUCCESS. str contains the converted number
+ * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ * STATUS_BUFFER_OVERFLOW, if str is too small to hold the string
+ * (with the '\0' termination). In this case str->Length
+ * is set to the length, the string would have (which can
+ * be larger than the MaximumLength).
+ *
+ * NOTES
+ * Instead of base 0 it uses 10 as base.
+ * If str is NULL it crashes, as the native function does.
*
- * Difference:
- * - Accept base 0 as 10 instead of crashing as native DLL does.
+ * DIFFERENCES
+ * - Accept base 0 as 10 instead of crashing as native function 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
+ * The native function 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
+ * - The native function 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)
+ ULONGLONG value, /* [I] Value to be converted */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ UNICODE_STRING *str) /* [O] Destination for the converted value */
{
WCHAR buffer[65];
PWCHAR pos;
@@ -356,7 +369,7 @@
if (str->Length >= str->MaximumLength) {
return STATUS_BUFFER_OVERFLOW;
} else {
- memcpy(str->Buffer, pos, str->Length + 1);
+ memcpy(str->Buffer, pos, str->Length + sizeof(WCHAR));
} /* if */
return STATUS_SUCCESS;
}
diff -urN old_wine-20030318/dlls/ntdll/ntdll.spec new_wine-20030318/dlls/ntdll/ntdll.spec
--- old_wine-20030318/dlls/ntdll/ntdll.spec Wed Mar 19 01:09:57 2003
+++ new_wine-20030318/dlls/ntdll/ntdll.spec Fri Mar 21 01:40:16 2003
@@ -349,6 +349,7 @@
@ stdcall RtlDosPathNameToNtPathName_U(ptr ptr long long)
@ stub RtlDosSearchPath_U
@ stdcall RtlDowncaseUnicodeChar(long)
+@ stdcall RtlDowncaseUnicodeString(ptr ptr long)
@ stdcall RtlDumpResource(ptr)
@ stdcall -ret64 RtlEnlargedIntegerMultiply(long long)
@ stdcall RtlEnlargedUnsignedDivide(long long long ptr)
@@ -542,7 +543,7 @@
@ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long)
@ stdcall RtlUnicodeToMultiByteSize(ptr wstr long)
@ stdcall RtlUnicodeToOemN(ptr long ptr ptr long)
-@ stub RtlUniform
+@ stdcall RtlUniform(ptr)
@ stdcall RtlUnlockHeap(long)
@ stdcall RtlUnwind(ptr ptr ptr long)
@ stdcall RtlUpcaseUnicodeChar(long)
@@ -944,6 +945,10 @@
@ cdecl isupper(long)
@ cdecl iswalpha(long) NTDLL_iswalpha
@ cdecl iswctype(long long) NTDLL_iswctype
+@ cdecl iswdigit(long) NTDLL_iswdigit
+@ cdecl iswlower(long) NTDLL_iswlower
+@ cdecl iswspace(long) NTDLL_iswspace
+@ cdecl iswxdigit(long) NTDLL_iswxdigit
@ cdecl isxdigit(long)
@ cdecl labs(long)
@ cdecl log(double)
diff -urN old_wine-20030318/dlls/ntdll/rtl.c new_wine-20030318/dlls/ntdll/rtl.c
--- old_wine-20030318/dlls/ntdll/rtl.c Wed Mar 19 01:09:57 2003
+++ new_wine-20030318/dlls/ntdll/rtl.c Fri Mar 21 01:40:01 2003
@@ -4,7 +4,8 @@
* This file contains the Rtl* API functions. These should be implementable.
*
* Copyright 1996-1998 Marcus Meissner
- * 1999 Alex Korobka
+ * Copyright 1999 Alex Korobka
+ * Copyright 2003 Thomas Mertes
* Crc32 code Copyright 1986 Gary S. Brown (Public domain)
*
* This library is free software; you can redistribute it and/or
@@ -729,3 +730,40 @@
"movb %cl,%ah\n\t"
"ret");
#endif
+
+
+/*************************************************************************
+ * RtlUniform [NTDLL.@]
+ *
+ * Generates an uniform random number
+ *
+ * PARAMS
+ * seed [O] The seed of the Random function
+ *
+ * RETURNS
+ * It returns a random number uniformly distributed over [0..MAXLONG].
+ *
+ * NOTES
+ * Generates an uniform random number using a modified version of
+ * D.H. Lehmer's 1948 algorithm. The original algorithm would be:
+ *
+ * result = *seed * 0xffffffed + 0x7fffffc3;
+ * *seed = result;
+ */
+ULONG WINAPI RtlUniform (PULONG seed)
+{
+ ULONG result;
+
+ result = *seed * 0xffffffed + 0x7fffffc3;
+ if (result == 0xffffffff || result == 0x7ffffffe) {
+ result = (result + 2) & MAXLONG;
+ } else if (result == 0x7fffffff) {
+ result = (result + 1) & MAXLONG;
+ } else if ((result & 0x80000000) == 0) {
+ result = result + (~result & 1);
+ } else {
+ result = (result + (result & 1)) & MAXLONG;
+ } /* if */
+ *seed = result;
+ return result;
+}
diff -urN old_wine-20030318/dlls/ntdll/rtlstr.c new_wine-20030318/dlls/ntdll/rtlstr.c
--- old_wine-20030318/dlls/ntdll/rtlstr.c Sat Mar 15 20:42:11 2003
+++ new_wine-20030318/dlls/ntdll/rtlstr.c Fri Mar 21 01:39:26 2003
@@ -383,6 +383,7 @@
return ret;
}
+
/**************************************************************************
* RtlEqualDomainName (NTDLL.@)
*
@@ -404,6 +405,7 @@
return RtlEqualComputerName(left, right);
}
+
/*
COPY BETWEEN ANSI_STRING or UNICODE_STRING
there is no parameter checking, it just crashes
@@ -504,7 +506,7 @@
/**************************************************************************
* RtlUnicodeStringToOemString (NTDLL.@)
*
- * Convert a Rtl Unicode string to an OEM string.
+ * Converts a Rtl Unicode string to an OEM string.
*
* PARAMS
* oem [O] Destination for OEM string
@@ -613,13 +615,18 @@
/**************************************************************************
* RtlUpperChar (NTDLL.@)
*
- * Convert an Ascii character to uppercase.
+ * Converts an Ascii character to uppercase.
*
* PARAMS
* ch [I] Character to convert
*
* RETURNS
* The uppercase character value.
+ *
+ * NOTES
+ * For the input characters from 'a' .. 'z' it returns 'A' .. 'Z'.
+ * All other input characters are returned unchanged. The locale and
+ * multibyte characters are not taken into account (as native DLL).
*/
CHAR WINAPI RtlUpperChar( CHAR ch )
{
@@ -627,14 +634,14 @@
return ch - 'a' + 'A';
} else {
return ch;
- }
+ } /* if */
}
/**************************************************************************
* RtlUpperString (NTDLL.@)
*
- * Convert an Ascii string to uppercase.
+ * Converts an Ascii string to uppercase.
*
* PARAMS
* dst [O] Destination for converted string
@@ -642,6 +649,13 @@
*
* RETURNS
* Nothing.
+ *
+ * NOTES
+ * For the src characters from 'a' .. 'z' it assigns 'A' .. 'Z' to dst.
+ * All other src characters are copied unchanged to dst. The locale and
+ * multibyte characters are not taken into account (as native DLL).
+ * The number of character copied is the minimum of src->Length and
+ * the dst->MaximumLength.
*/
void WINAPI RtlUpperString( STRING *dst, const STRING *src )
{
@@ -655,17 +669,24 @@
/**************************************************************************
* RtlUpcaseUnicodeChar (NTDLL.@)
*
- * Unicode version of of RtlUpperChar.
+ * Converts an Unicode character to uppercase.
+ *
+ * PARAMS
+ * wch [I] Character to convert
+ *
+ * RETURNS
+ * The uppercase character value.
*/
WCHAR WINAPI RtlUpcaseUnicodeChar( WCHAR wch )
{
return toupperW(wch);
}
+
/**************************************************************************
* RtlDowncaseUnicodeChar (NTDLL.@)
*
- * Convert a Unicode character to lowercase.
+ * Converts an Unicode character to lowercase.
*
* PARAMS
* wch [I] Character to convert
@@ -678,10 +699,11 @@
return tolowerW(wch);
}
+
/**************************************************************************
* RtlUpcaseUnicodeString (NTDLL.@)
*
- * Convert a Unicode string to uppercase.
+ * Converts an Unicode string to uppercase.
*
* PARAMS
* dest [O] Destination for converted string
@@ -718,6 +740,50 @@
/**************************************************************************
+ * RtlDowncaseUnicodeString (NTDLL.@)
+ *
+ * Converts an Unicode string to lowercase.
+ *
+ * PARAMS
+ * dest [O] Destination for converted string
+ * src [I] Source string to convert
+ * doalloc [I] TRUE=Allocate a buffer for dest if it doesn't have one
+ *
+ * RETURNS
+ * Success: STATUS_SUCCESS. dest contains the converted string.
+ * Failure: STATUS_NO_MEMORY, if doalloc is TRUE and memory allocation fails, or
+ * STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and dest is too small.
+ *
+ * NOTES
+ * dest is never NUL terminated because it may be equal to src, and src
+ * might not be NUL terminated. dest->Length is only set upon success.
+ */
+NTSTATUS WINAPI RtlDowncaseUnicodeString(
+ UNICODE_STRING *dest,
+ const UNICODE_STRING *src,
+ BOOLEAN doalloc)
+{
+ DWORD i;
+ DWORD len = src->Length;
+
+ if (doalloc) {
+ dest->MaximumLength = len;
+ if (!(dest->Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, len ))) {
+ return STATUS_NO_MEMORY;
+ } /* if */
+ } else if (len > dest->MaximumLength) {
+ return STATUS_BUFFER_OVERFLOW;
+ } /* if */
+
+ for (i = 0; i < len/sizeof(WCHAR); i++) {
+ dest->Buffer[i] = tolowerW(src->Buffer[i]);
+ } /* for */
+ dest->Length = len;
+ return STATUS_SUCCESS;
+}
+
+
+/**************************************************************************
* RtlUpcaseUnicodeStringToAnsiString (NTDLL.@)
*
* NOTES
@@ -867,7 +933,7 @@
/**************************************************************************
* RtlUnicodeToMultiByteSize (NTDLL.@)
*
- * Calculate the size necessary for the multibyte conversion of str,
+ * Calculate the size in bytes necessary for the multibyte conversion of str,
* without the terminating NULL.
*
* PARAMS
@@ -981,6 +1047,7 @@
NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICODE_STRING *src )
{
unsigned int len = src->Length + dst->Length;
+ if (src->Length == 0) return STATUS_SUCCESS;
if (len > dst->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
memcpy( dst->Buffer + dst->Length/sizeof(WCHAR), src->Buffer, src->Length );
dst->Length = len;
@@ -994,6 +1061,7 @@
MISC
*/
+
/**************************************************************************
* RtlIsTextUnicode (NTDLL.@)
*
@@ -1053,23 +1121,28 @@
/**************************************************************************
* RtlCharToInteger (NTDLL.@)
*
- * Convert a character string into its integer equivalent.
+ * Converts 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).
+ * RETURNS
+ * Success: STATUS_SUCCESS. value contains the converted number
+ * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ * STATUS_ACCESS_VIOLATION, if value is NULL.
*
- * Difference:
- * - Do not read garbage behind '\0' as native DLL does.
+ * NOTES
+ * For base 0 it uses 10 as base and the string should be in the format
+ * "{whitespace} [+|-] [0[x|o|b]] {digits}".
+ * For other bases the string should be in the format
+ * "{whitespace} [+|-] {digits}".
+ * No check is made for value overflow, only the lower 32 bits are assigned.
+ * If str is NULL it crashes, as the native function does.
+ *
+ * DIFFERENCES
+ * This function does not read garbage behind '\0' as the native version does.
*/
NTSTATUS WINAPI RtlCharToInteger(
- PCSZ str,
- ULONG base,
- ULONG *value)
+ PCSZ str, /* [I] '\0' terminated single-byte string containing a number */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ ULONG *value) /* [O] Destination for the converted value */
{
CHAR chCurrent;
int digit;
@@ -1137,22 +1210,25 @@
/**************************************************************************
* RtlIntegerToChar (NTDLL.@)
*
- * Convert an unsigned integer to a character string.
+ * Converts an unsigned integer to a character string.
+ *
+ * RETURNS
+ * Success: STATUS_SUCCESS. str contains the converted number
+ * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ * STATUS_BUFFER_OVERFLOW, if str would be larger than length.
+ * STATUS_ACCESS_VIOLATION, if str is NULL.
*
* NOTES
- * 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.
+ * Instead of base 0 it uses 10 as base.
+ * 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.
*/
NTSTATUS WINAPI RtlIntegerToChar(
- ULONG value,
- ULONG base,
- ULONG length,
- PCHAR str)
+ ULONG value, /* [I] Value to be converted */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ ULONG length, /* [I] Length of the str buffer in bytes */
+ PCHAR str) /* [O] Destination for the converted value */
{
CHAR buffer[33];
PCHAR pos;
@@ -1196,24 +1272,29 @@
/**************************************************************************
* RtlUnicodeStringToInteger (NTDLL.@)
*
- * Convert an unicode string into its integer equivalent.
+ * Converts an unicode string into its integer equivalent.
*
- * NOTES
- * 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).
+ * RETURNS
+ * Success: STATUS_SUCCESS. value contains the converted number
+ * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ * STATUS_ACCESS_VIOLATION, if value is NULL.
*
- * Difference:
- * - Do not read garbage on string length 0 as native DLL does.
+ * NOTES
+ * For base 0 it uses 10 as base and the string should be in the format
+ * "{whitespace} [+|-] [0[x|o|b]] {digits}".
+ * For other bases the string should be in the format
+ * "{whitespace} [+|-] {digits}".
+ * No check is made for value overflow, only the lower 32 bits are assigned.
+ * If str is NULL it crashes, as the native function does.
+ *
+ * DIFFERENCES
+ * This function does not read garbage on string length 0 as the native
+ * version does.
*/
NTSTATUS WINAPI RtlUnicodeStringToInteger(
- const UNICODE_STRING *str,
- ULONG base,
- ULONG *value)
+ const UNICODE_STRING *str, /* [I] Unicode string to be converted */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ ULONG *value) /* [O] Destination for the converted value */
{
LPWSTR lpwstr = str->Buffer;
USHORT CharsRemaining = str->Length / sizeof(WCHAR);
@@ -1292,25 +1373,29 @@
/**************************************************************************
* RtlIntegerToUnicodeString (NTDLL.@)
*
- * Convert an unsigned integer to a NULL terminated unicode string.
+ * Converts an unsigned integer to a '\0' terminated unicode string.
+ *
+ * RETURNS
+ * Success: STATUS_SUCCESS. str contains the converted number
+ * Failure: STATUS_INVALID_PARAMETER, if base is not 0, 2, 8, 10 or 16.
+ * STATUS_BUFFER_OVERFLOW, if str is too small to hold the string
+ * (with the '\0' termination). In this case str->Length
+ * is set to the length, the string would have (which can
+ * be larger than the MaximumLength).
*
* NOTES
- * 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.
+ * Instead of base 0 it uses 10 as base.
+ * If str is NULL it crashes, as the native function does.
+ *
+ * DIFFERENCES
+ * Do not return STATUS_BUFFER_OVERFLOW when the string is long enough.
+ * The native function 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)
+ ULONG value, /* [I] Value to be converted */
+ ULONG base, /* [I] Number base for conversion (allowed 0, 2, 8, 10 or 16) */
+ UNICODE_STRING *str) /* [O] Destination for the converted value */
{
WCHAR buffer[33];
PWCHAR pos;
@@ -1340,7 +1425,7 @@
if (str->Length >= str->MaximumLength) {
return STATUS_BUFFER_OVERFLOW;
} else {
- memcpy(str->Buffer, pos, str->Length + 1);
+ memcpy(str->Buffer, pos, str->Length + sizeof(WCHAR));
} /* if */
return STATUS_SUCCESS;
}
diff -urN old_wine-20030318/dlls/ntdll/string.c new_wine-20030318/dlls/ntdll/string.c
--- old_wine-20030318/dlls/ntdll/string.c Wed Mar 12 21:16:07 2003
+++ new_wine-20030318/dlls/ntdll/string.c Fri Mar 21 01:39:12 2003
@@ -74,11 +74,19 @@
*
* Converts an unsigned long integer to a string.
*
- * Assigns a '\0' terminated string to str and returns str.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just crashes (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated string which is copied to str.
+ * The maximum length of the copied str is 33 bytes.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _ultoa( unsigned long value, char *str, int radix )
+char * __cdecl _ultoa(
+ unsigned long value, /* [I] Value to be converted */
+ char *str, /* [O] Destination for the converted value */
+ int radix) /* [I] Number base for conversion */
{
char buffer[33];
char *pos;
@@ -107,12 +115,20 @@
*
* Converts a long integer to a string.
*
- * Assigns a '\0' terminated string to str and returns str. If radix
- * is 10 and value is negative, the value is converted with sign.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just crashes (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated string which is copied to str.
+ * The maximum length of the copied str is 33 bytes. If radix
+ * is 10 and value is negative, the value is converted with sign.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _ltoa( long value, char *str, int radix )
+char * __cdecl _ltoa(
+ long value, /* [I] Value to be converted */
+ char *str, /* [O] Destination for the converted value */
+ int radix) /* [I] Number base for conversion */
{
unsigned long val;
int negative;
@@ -155,12 +171,20 @@
*
* Converts an integer to a string.
*
- * Assigns a '\0' terminated wstring to str and returns str. If radix
- * is 10 and value is negative, the value is converted with sign.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just crashes (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated string which is copied to str.
+ * The maximum length of the copied str is 33 bytes. If radix
+ * is 10 and value is negative, the value is converted with sign.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _itoa( int value, char *str, int radix )
+char * __cdecl _itoa(
+ int value, /* [I] Value to be converted */
+ char *str, /* [O] Destination for the converted value */
+ int radix) /* [I] Number base for conversion */
{
return _ltoa(value, str, radix);
}
@@ -171,11 +195,19 @@
*
* Converts a large unsigned integer to a string.
*
- * Assigns a '\0' terminated string to str and returns str.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just crashes (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated string which is copied to str.
+ * The maximum length of the copied str is 65 bytes.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _ui64toa( ULONGLONG value, char *str, int radix )
+char * __cdecl _ui64toa(
+ ULONGLONG value, /* [I] Value to be converted */
+ char *str, /* [O] Destination for the converted value */
+ int radix) /* [I] Number base for conversion */
{
char buffer[65];
char *pos;
@@ -204,21 +236,29 @@
*
* Converts a large integer to a string.
*
- * Assigns a '\0' terminated string to str and returns str. If radix
- * is 10 and value is negative, the value is converted with sign.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just crashes (as native DLL).
+ * RETURNS
+ * Always returns str.
*
- * Difference:
+ * NOTES
+ * Converts value to a '\0' terminated string which is copied to str.
+ * The maximum length of the copied str is 65 bytes. If radix
+ * is 10 and value is negative, the value is converted with sign.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it crashes, as the native function does.
+ *
+ * DIFFERENCES
* - The native DLL converts negative values (for base 10) wrong:
* -1 is converted to -18446744073709551615
* -2 is converted to -18446744073709551614
* -9223372036854775807 is converted to -9223372036854775809
* -9223372036854775808 is converted to -9223372036854775808
- * The native msvcrt _i64toa function and our ntdll function do
- * not have this bug.
+ * The native msvcrt _i64toa function and our ntdll _i64toa function
+ * do not have this bug.
*/
-char * __cdecl _i64toa( LONGLONG value, char *str, int radix )
+char * __cdecl _i64toa(
+ LONGLONG value, /* [I] Value to be converted */
+ char *str, /* [O] Destination for the converted value */
+ int radix) /* [I] Number base for conversion */
{
ULONGLONG val;
int negative;
@@ -261,10 +301,16 @@
*
* Converts a string to a large integer.
*
- * On success it returns the integer value otherwise it returns 0.
- * Accepts: {whitespace} [+|-] {digits}
- * No check of overflow: Just assigns lower 64 bits (as native DLL).
- * Does not check for str != NULL (as native DLL).
+ * PARAMS
+ * str [I] Wstring to be converted
+ *
+ * RETURNS
+ * On success it returns the integer value otherwise it returns 0.
+ *
+ * NOTES
+ * Accepts: {whitespace} [+|-] {digits}
+ * No check is made for value overflow, only the lower 64 bits are assigned.
+ * If str is NULL it crashes, as the native function does.
*/
LONGLONG __cdecl _atoi64( char *str )
{
diff -urN old_wine-20030318/dlls/ntdll/wcstring.c new_wine-20030318/dlls/ntdll/wcstring.c
--- old_wine-20030318/dlls/ntdll/wcstring.c Wed Mar 12 23:30:16 2003
+++ new_wine-20030318/dlls/ntdll/wcstring.c Fri Mar 21 01:39:17 2003
@@ -331,10 +331,76 @@
/*********************************************************************
* iswalpha (NTDLL.@)
+ *
+ * Checks if an unicode char wc is a letter
+ *
+ * RETURNS
+ * TRUE: The unicode char wc is a letter.
+ * FALSE: Otherwise
*/
INT __cdecl NTDLL_iswalpha( WCHAR wc )
{
- return get_char_typeW(wc) & C1_ALPHA;
+ return isalphaW(wc);
+}
+
+
+/*********************************************************************
+ * iswdigit (NTDLL.@)
+ *
+ * Checks if an unicode char wc is a digit
+ *
+ * RETURNS
+ * TRUE: The unicode char wc is a digit.
+ * FALSE: Otherwise
+ */
+INT __cdecl NTDLL_iswdigit( WCHAR wc )
+{
+ return isdigitW(wc);
+}
+
+
+/*********************************************************************
+ * iswlower (NTDLL.@)
+ *
+ * Checks if an unicode char wc is a lower case letter
+ *
+ * RETURNS
+ * TRUE: The unicode char wc is a lower case letter.
+ * FALSE: Otherwise
+ */
+INT __cdecl NTDLL_iswlower( WCHAR wc )
+{
+ return islowerW(wc);
+}
+
+
+/*********************************************************************
+ * iswspace (NTDLL.@)
+ *
+ * Checks if an unicode char wc is a white space character
+ *
+ * RETURNS
+ * TRUE: The unicode char wc is a white space character.
+ * FALSE: Otherwise
+ */
+INT __cdecl NTDLL_iswspace( WCHAR wc )
+{
+ return isspaceW(wc);
+}
+
+
+/*********************************************************************
+ * iswxdigit (NTDLL.@)
+ *
+ * Checks if an unicode char wc is an extended digit
+ *
+ * RETURNS
+ * TRUE: The unicode char wc is an extended digit.
+ * FALSE: Otherwise
+ */
+INT __cdecl NTDLL_iswxdigit( WCHAR wc )
+{
+ return isxdigitW(wc);
}
@@ -343,11 +409,19 @@
*
* Converts an unsigned long integer to an unicode string.
*
- * Assigns a '\0' terminated string to str and returns str.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just returns NULL (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated wstring which is copied to str.
+ * The maximum length of the copied str is 33 bytes.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it just returns NULL.
*/
-LPWSTR __cdecl _ultow( unsigned long value, LPWSTR str, INT radix )
+LPWSTR __cdecl _ultow(
+ unsigned long value, /* [I] Value to be converted */
+ LPWSTR str, /* [O] Destination for the converted value */
+ INT radix) /* [I] Number base for conversion */
{
WCHAR buffer[33];
PWCHAR pos;
@@ -378,12 +452,20 @@
*
* Converts a long integer to an unicode string.
*
- * Assigns a '\0' terminated string to str and returns str. If radix
- * is 10 and value is negative, the value is converted with sign.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just returns NULL (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated wstring which is copied to str.
+ * The maximum length of the copied str is 33 bytes. If radix
+ * is 10 and value is negative, the value is converted with sign.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it just returns NULL.
*/
-LPWSTR __cdecl _ltow( long value, LPWSTR str, INT radix )
+LPWSTR __cdecl _ltow(
+ long value, /* [I] Value to be converted */
+ LPWSTR str, /* [O] Destination for the converted value */
+ INT radix) /* [I] Number base for conversion */
{
unsigned long val;
int negative;
@@ -428,16 +510,24 @@
*
* Converts an integer to an unicode string.
*
- * Assigns a '\0' terminated wstring to str and returns str. If radix
- * is 10 and value is negative, the value is converted with sign.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just returns NULL (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated wstring which is copied to str.
+ * The maximum length of the copied str is 33 bytes. If radix
+ * is 10 and value is negative, the value is converted with sign.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it just returns NULL.
*
- * Difference:
- * - The native DLL crashes when the string is longer than 19 chars.
+ * DIFFERENCES
+ * - The native function crashes when the string is longer than 19 chars.
* This function does not have this bug.
*/
-LPWSTR __cdecl _itow( int value, LPWSTR str, INT radix )
+LPWSTR __cdecl _itow(
+ int value, /* [I] Value to be converted */
+ LPWSTR str, /* [O] Destination for the converted value */
+ INT radix) /* [I] Number base for conversion */
{
return _ltow(value, str, radix);
}
@@ -448,16 +538,24 @@
*
* Converts a large unsigned integer to an unicode string.
*
- * Assigns a '\0' terminated wstring to str and returns str.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just returns NULL (as native DLL).
+ * RETURNS
+ * Always returns str.
+ *
+ * NOTES
+ * Converts value to a '\0' terminated wstring which is copied to str.
+ * The maximum length of the copied str is 33 bytes.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it just returns NULL.
*
- * Difference:
+ * DIFFERENCES
* - This function does not exist in the native DLL (but in msvcrt).
* But since the maintenance of all these functions is better done
* in one place we implement it here.
*/
-LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix )
+LPWSTR __cdecl _ui64tow(
+ ULONGLONG value, /* [I] Value to be converted */
+ LPWSTR str, /* [O] Destination for the converted value */
+ INT radix) /* [I] Number base for conversion */
{
WCHAR buffer[65];
PWCHAR pos;
@@ -488,12 +586,17 @@
*
* Converts a large integer to an unicode string.
*
- * Assigns a '\0' terminated wstring to str and returns str. If radix
- * is 10 and value is negative, the value is converted with sign.
- * Does not check if radix is in the range of 2 to 36 (as native DLL).
- * For str == NULL just returns NULL (as native DLL).
+ * RETURNS
+ * Always returns str.
*
- * Difference:
+ * NOTES
+ * Converts value to a '\0' terminated wstring which is copied to str.
+ * The maximum length of the copied str is 33 bytes. If radix
+ * is 10 and value is negative, the value is converted with sign.
+ * Does not check if radix is in the range of 2 to 36.
+ * If str is NULL it just returns NULL.
+ *
+ * DIFFERENCES
* - The native DLL converts negative values (for base 10) wrong:
* -1 is converted to -18446744073709551615
* -2 is converted to -18446744073709551614
@@ -502,7 +605,10 @@
* The native msvcrt _i64tow function and our ntdll function do
* not have this bug.
*/
-LPWSTR __cdecl _i64tow( LONGLONG value, LPWSTR str, INT radix )
+LPWSTR __cdecl _i64tow(
+ LONGLONG value, /* [I] Value to be converted */
+ LPWSTR str, /* [O] Destination for the converted value */
+ INT radix) /* [I] Number base for conversion */
{
ULONGLONG val;
int negative;
@@ -547,10 +653,16 @@
*
* Converts an unicode string to a long integer.
*
- * On success it returns the integer value otherwise it returns 0.
- * Accepts: {whitespace} [+|-] {digits}
- * No check of overflow: Just assigns lower 32 bits (as native DLL).
- * Does not check for str != NULL (as native DLL).
+ * PARAMS
+ * str [I] Wstring to be converted
+ *
+ * RETURNS
+ * On success it returns the integer value otherwise it returns 0.
+ *
+ * NOTES
+ * Accepts: {whitespace} [+|-] {digits}
+ * No check is made for value overflow, only the lower 32 bits are assigned.
+ * If str is NULL it crashes, as the native function does.
*/
LONG __cdecl _wtol( LPWSTR str )
{
@@ -582,14 +694,20 @@
*
* Converts an unicode string to an integer.
*
- * On success it returns the integer value otherwise it returns 0.
- * Accepts: {whitespace} [+|-] {digits}
- * No check of overflow: Just assigns lower 32 bits (as native DLL).
- * Does not check for str != NULL (as native DLL).
+ * PARAMS
+ * str [I] Wstring to be converted
+ *
+ * RETURNS
+ * On success it returns the integer value otherwise it returns 0.
+ *
+ * NOTES
+ * Accepts: {whitespace} [+|-] {digits}
+ * No check is made for value overflow, only the lower 32 bits are assigned.
+ * If str is NULL it crashes, as the native function does.
*/
-int __cdecl _wtoi( LPWSTR string )
+int __cdecl _wtoi( LPWSTR str )
{
- return _wtol(string);
+ return _wtol(str);
}
@@ -598,10 +716,16 @@
*
* Converts an unicode string to a large integer.
*
- * On success it returns the integer value otherwise it returns 0.
- * Accepts: {whitespace} [+|-] {digits}
- * No check of overflow: Just assigns lower 64 bits (as native DLL).
- * Does not check for str != NULL (as native DLL).
+ * PARAMS
+ * str [I] Wstring to be converted
+ *
+ * RETURNS
+ * On success it returns the integer value otherwise it returns 0.
+ *
+ * NOTES
+ * Accepts: {whitespace} [+|-] {digits}
+ * No check is made for value overflow, only the lower 64 bits are assigned.
+ * If str is NULL it crashes, as the native function does.
*/
LONGLONG __cdecl _wtoi64( LPWSTR str )
{
@@ -626,7 +750,6 @@
return bMinus ? -RunningTotal : RunningTotal;
}
-
/***********************************************************************
diff -urN old_wine-20030318/include/winternl.h new_wine-20030318/include/winternl.h
--- old_wine-20030318/include/winternl.h Wed Mar 19 01:09:57 2003
+++ new_wine-20030318/include/winternl.h Fri Mar 21 01:50:59 2003
@@ -918,6 +918,7 @@
HANDLE WINAPI RtlDestroyHeap(HANDLE);
BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,DWORD,DWORD);
WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR);
+NTSTATUS WINAPI RtlDowncaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
void WINAPI RtlDumpResource(LPRTL_RWLOCK);
LONGLONG WINAPI RtlEnlargedIntegerMultiply(INT,INT);