diff --git a/dlls/ntdll/large_int.c b/dlls/ntdll/large_int.c index f3e6dba9246..7912111cae0 100644 --- a/dlls/ntdll/large_int.c +++ b/dlls/ntdll/large_int.c @@ -185,21 +185,25 @@ LONGLONG WINAPI RtlExtendedIntegerMultiply( LONGLONG a, INT b ) * * 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. * - * Parameter b although defined as LONGLONG is used as ULONGLONG. + * 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. + * + * 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 @@ LONGLONG WINAPI RtlExtendedMagicDivide( * * 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). + * 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. * - * Difference: - * - Accept base 0 as 10 instead of crashing as native DLL does. - * - The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for + * 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 @@ NTSTATUS WINAPI RtlLargeIntegerToChar( /************************************************************************** * 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). * - * Difference: - * - Accept base 0 as 10 instead of crashing as native DLL does. + * NOTES + * Instead of base 0 it uses 10 as base. + * If str is NULL it crashes, as the native function 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 @@ NTSTATUS WINAPI RtlInt64ToUnicodeString( 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 --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 0a8bdb3c9e8..f97cb719b25 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -351,6 +351,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) @@ -544,7 +545,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) @@ -946,6 +947,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 --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index 90b07c5f266..54088c7ec73 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -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 @@ __ASM_GLOBAL_FUNC(NTDLL_RtlUshortByteSwap, "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 --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c index 87e6b8e8cba..b805c6d51b5 100644 --- a/dlls/ntdll/rtlstr.c +++ b/dlls/ntdll/rtlstr.c @@ -383,6 +383,7 @@ NTSTATUS WINAPI RtlEqualComputerName(const UNICODE_STRING *left, return ret; } + /************************************************************************** * RtlEqualDomainName (NTDLL.@) * @@ -404,6 +405,7 @@ NTSTATUS WINAPI RtlEqualDomainName(const UNICODE_STRING *left, return RtlEqualComputerName(left, right); } + /* COPY BETWEEN ANSI_STRING or UNICODE_STRING there is no parameter checking, it just crashes @@ -504,7 +506,7 @@ NTSTATUS WINAPI RtlUnicodeStringToAnsiString( STRING *ansi, /************************************************************************** * 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 @@ NTSTATUS WINAPI RtlUnicodeToOemN( LPSTR dst, DWORD dstlen, LPDWORD reslen, /************************************************************************** * 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 @@ CHAR WINAPI RtlUpperChar( CHAR ch ) 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 @@ CHAR WINAPI RtlUpperChar( CHAR ch ) * * 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 @@ void WINAPI RtlUpperString( STRING *dst, const STRING *src ) /************************************************************************** * 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 @@ WCHAR WINAPI RtlDowncaseUnicodeChar(WCHAR wch) return tolowerW(wch); } + /************************************************************************** * RtlUpcaseUnicodeString (NTDLL.@) * - * Convert a Unicode string to uppercase. + * Converts an Unicode string to uppercase. * * PARAMS * dest [O] Destination for converted string @@ -717,6 +739,50 @@ NTSTATUS WINAPI RtlUpcaseUnicodeString( UNICODE_STRING *dest, } +/************************************************************************** + * 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.@) * @@ -867,7 +933,7 @@ NTSTATUS WINAPI RtlMultiByteToUnicodeSize( DWORD *size, LPCSTR str, UINT len ) /************************************************************************** * 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 RtlAppendUnicodeToString( UNICODE_STRING *dst, LPCWSTR src ) 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 @@ NTSTATUS WINAPI RtlAppendUnicodeStringToString( UNICODE_STRING *dst, const UNICO MISC */ + /************************************************************************** * RtlIsTextUnicode (NTDLL.@) * @@ -1053,23 +1121,28 @@ out: /************************************************************************** * 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 @@ NTSTATUS WINAPI RtlCharToInteger( /************************************************************************** * 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 @@ NTSTATUS WINAPI RtlIntegerToChar( /************************************************************************** * RtlUnicodeStringToInteger (NTDLL.@) * - * Convert an unicode string into its integer equivalent. + * Converts an unicode string into its integer equivalent. + * + * 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. * * 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). + * 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. * - * Difference: - * - Do not read garbage on string length 0 as native DLL 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 @@ NTSTATUS WINAPI RtlUnicodeStringToInteger( /************************************************************************** * 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). + * Instead of base 0 it uses 10 as base. + * If str is NULL it crashes, as the native function does. * - * 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. + * 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 @@ NTSTATUS WINAPI RtlIntegerToUnicodeString( 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 --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c index e841758ee42..ade983abf15 100644 --- a/dlls/ntdll/string.c +++ b/dlls/ntdll/string.c @@ -74,11 +74,19 @@ LPSTR __cdecl _strlwr( LPSTR str ) * * 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 @@ char * __cdecl _ultoa( unsigned long value, char *str, int radix ) * * 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 @@ char * __cdecl _ltoa( long value, char *str, int radix ) * * 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 @@ char * __cdecl _itoa( int value, char *str, int radix ) * * 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 @@ char * __cdecl _ui64toa( ULONGLONG value, char *str, int radix ) * * 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 @@ char * __cdecl _i64toa( LONGLONG value, char *str, int radix ) * * 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 --git a/dlls/ntdll/wcstring.c b/dlls/ntdll/wcstring.c index 586eeeab96d..7dc7eb10346 100644 --- a/dlls/ntdll/wcstring.c +++ b/dlls/ntdll/wcstring.c @@ -331,10 +331,76 @@ INT __cdecl NTDLL_iswctype( WCHAR wc, WCHAR wct ) /********************************************************************* * 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 @@ INT __cdecl NTDLL_iswalpha( WCHAR wc ) * * 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 @@ LPWSTR __cdecl _ultow( unsigned long value, LPWSTR str, INT radix ) * * 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 @@ LPWSTR __cdecl _ltow( long value, LPWSTR str, INT radix ) * * 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. * - * Difference: - * - The native DLL crashes when the string is longer than 19 chars. + * 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 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 @@ LPWSTR __cdecl _itow( int value, LPWSTR str, INT radix ) * * 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. * - * Difference: + * 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. + * + * 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 @@ LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix ) * * 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 @@ LPWSTR __cdecl _ui64tow( ULONGLONG value, LPWSTR str, INT radix ) * 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 @@ LPWSTR __cdecl _i64tow( LONGLONG value, LPWSTR str, INT radix ) * * 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 @@ LONG __cdecl _wtol( LPWSTR str ) * * 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 @@ int __cdecl _wtoi( LPWSTR string ) * * 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 ) { @@ -628,7 +752,6 @@ LONGLONG __cdecl _wtoi64( LPWSTR str ) } - /*********************************************************************** * _snwprintf (NTDLL.@) */ diff --git a/include/winternl.h b/include/winternl.h index adfc19d2462..cbc48ca294c 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -918,6 +918,7 @@ DWORD WINAPI RtlDestroyEnvironment(DWORD); 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);