some ntdll functions (3) - part 1: functions

thomas.mertes at gmx.at thomas.mertes at gmx.at
Fri Mar 21 01:49:22 CST 2003


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 at 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!
-------------- next part --------------
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);


More information about the wine-patches mailing list