some ntdll functions (5) - part 1: functions

thomas.mertes at gmx.at thomas.mertes at gmx.at
Tue May 6 05:36:48 CDT 2003


Hello

Here are implementations and documentation updates of
some ntdll functions. I have tested some of the functions
a lot on w2k (see part 2: tests).

Changelog:

	* include/winternl.h,
	  dlls/ntdll/ntdll.spec, dlls/ntdll/rtlstr.c:
	Thomas Mertes <thomas.mertes at gmx.at>
	Implement RtlDuplicateUnicodeString,
	  RtlFindCharInUnicodeString, RtlInitUnicodeStringEx.
	Documentation updates for RtlInitAnsiString,
	  RtlInitString, RtlInitUnicodeString,
	  RtlAnsiStringToUnicodeString and
	  RtlOemStringToUnicodeString.



-- 
+++ GMX - Mail, Messaging & more  http://www.gmx.net +++
Bitte lächeln! Fotogalerie online mit GMX ohne eigene Homepage!
-------------- next part --------------
diff -urN wine_cvs_from_20030505/dlls/ntdll/ntdll.spec new_wine-20030408/dlls/ntdll/ntdll.spec
--- wine_cvs_from_20030505/dlls/ntdll/ntdll.spec	Tue May  6 11:50:18 2003
+++ new_wine-20030408/dlls/ntdll/ntdll.spec	Tue May  6 12:02:13 2003
@@ -354,6 +354,7 @@
 @ stdcall RtlDowncaseUnicodeChar(long)
 @ stdcall RtlDowncaseUnicodeString(ptr ptr long)
 @ stdcall RtlDumpResource(ptr)
+@ stdcall RtlDuplicateUnicodeString(long ptr ptr)
 @ stdcall -ret64 RtlEnlargedIntegerMultiply(long long)
 @ stdcall RtlEnlargedUnsignedDivide(long long long ptr)
 @ stdcall -ret64 RtlEnlargedUnsignedMultiply(long long)
@@ -376,6 +377,7 @@
 @ stdcall -ret64 RtlExtendedMagicDivide(long long long long long)
 @ stdcall RtlFillMemory(ptr long long)
 @ stdcall RtlFillMemoryUlong(ptr long long)
+@ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr)
 @ stdcall RtlFindClearBits(ptr long long)
 @ stdcall RtlFindClearBitsAndSet(ptr long long)
 @ stdcall RtlFindClearRuns(ptr ptr long long)
@@ -429,6 +431,7 @@
 @ stub RtlInitNlsTables
 @ stdcall RtlInitString(ptr str)
 @ stdcall RtlInitUnicodeString(ptr wstr)
+@ stdcall RtlInitUnicodeStringEx(ptr wstr)
 @ stdcall RtlInitializeBitMap(ptr long long)
 @ stub RtlInitializeContext
 @ stdcall RtlInitializeCriticalSection(ptr)
diff -urN wine_cvs_from_20030505/dlls/ntdll/rtlstr.c new_wine-20030408/dlls/ntdll/rtlstr.c
--- wine_cvs_from_20030505/dlls/ntdll/rtlstr.c	Tue May  6 09:39:32 2003
+++ new_wine-20030408/dlls/ntdll/rtlstr.c	Tue May  6 12:02:00 2003
@@ -68,11 +68,23 @@
 
 
 /**************************************************************************
- *	RtlInitAnsiString   (NTDLL.@)
- */
-void WINAPI RtlInitAnsiString( PSTRING target, LPCSTR source)
+ *      RtlInitAnsiString   (NTDLL.@)
+ *
+ * Initializes a buffered ansi string.
+ *
+ * RETURNS
+ *  Nothing.
+ *
+ * NOTES
+ *  Assigns source to target->Buffer. The length of source is assigned to
+ *  target->Length and target->MaximumLength. If source is NULL the length
+ *  of source is assumed to be 0.
+ */
+void WINAPI RtlInitAnsiString(
+    PANSI_STRING target, /* [I/O] Buffered ansi string to be initialized */
+    PCSZ source)         /* [I]   '\0' terminated string used to initialize target */
 {
-    if ((target->Buffer = (LPSTR)source))
+    if ((target->Buffer = (PCHAR) source))
     {
         target->Length = strlen(source);
         target->MaximumLength = target->Length + 1;
@@ -82,9 +94,21 @@
 
 
 /**************************************************************************
- *	RtlInitString   (NTDLL.@)
- */
-void WINAPI RtlInitString( PSTRING target, LPCSTR source )
+ *      RtlInitString   (NTDLL.@)
+ *
+ * Initializes a buffered string.
+ *
+ * RETURNS
+ *  Nothing.
+ *
+ * NOTES
+ *  Assigns source to target->Buffer. The length of source is assigned to
+ *  target->Length and target->MaximumLength. If source is NULL the length
+ *  of source is assumed to be 0.
+ */
+void WINAPI RtlInitString(
+    PSTRING target, /* [I/O] Buffered string to be initialized */
+    PCSZ source)    /* [I]   '\0' terminated string used to initialize target */
 {
     RtlInitAnsiString( target, source );
 }
@@ -124,11 +148,23 @@
 
 
 /**************************************************************************
- *	RtlInitUnicodeString   (NTDLL.@)
- */
-void WINAPI RtlInitUnicodeString( PUNICODE_STRING target, LPCWSTR source )
+ *      RtlInitUnicodeString   (NTDLL.@)
+ *
+ * Initializes a buffered unicode string.
+ *
+ * RETURNS
+ *  Nothing.
+ *
+ * NOTES
+ *  Assigns source to target->Buffer. The length of source is assigned to
+ *  target->Length and target->MaximumLength. If source is NULL the length
+ *  of source is assumed to be 0.
+ */
+void WINAPI RtlInitUnicodeString(
+    PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
+    PCWSTR source)          /* [I]   '\0' terminated unicode string used to initialize target */
 {
-    if ((target->Buffer = (LPWSTR)source))
+    if ((target->Buffer = (PWSTR) source))
     {
         target->Length = strlenW(source) * sizeof(WCHAR);
         target->MaximumLength = target->Length + sizeof(WCHAR);
@@ -138,6 +174,43 @@
 
 
 /**************************************************************************
+ *      RtlInitUnicodeStringEx   (NTDLL.@)
+ *
+ * Initializes a buffered unicode string.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. target is initialized.
+ *  Failure: STATUS_NAME_TOO_LONG, if the source string is larger than 65532 bytes.
+ *
+ * NOTES
+ *  Assigns source to target->Buffer. The length of source is assigned to
+ *  target->Length and target->MaximumLength. If source is NULL the length
+ *  of source is assumed to be 0.
+ */
+NTSTATUS WINAPI RtlInitUnicodeStringEx(
+    PUNICODE_STRING target, /* [I/O] Buffered unicode string to be initialized */
+    PCWSTR source)          /* [I]   '\0' terminated unicode string used to initialize target */
+{
+    if (source != NULL) {
+        unsigned int len = strlenW(source) * sizeof(WCHAR);
+
+        if (len > 0xFFFC) {
+            return STATUS_NAME_TOO_LONG;
+        } else {
+            target->Length = len;
+            target->MaximumLength = len + sizeof(WCHAR);
+            target->Buffer = (PWSTR) source;
+        } /* if */
+    } else {
+        target->Length = 0;
+        target->MaximumLength = 0;
+        target->Buffer = NULL;
+    } /* if */
+    return STATUS_SUCCESS;
+}
+
+
+/**************************************************************************
  *	RtlCreateUnicodeString   (NTDLL.@)
  */
 BOOLEAN WINAPI RtlCreateUnicodeString( PUNICODE_STRING target, LPCWSTR src )
@@ -181,7 +254,7 @@
         unsigned int len = min( src->Length, dst->MaximumLength );
         memcpy( dst->Buffer, src->Buffer, len );
         dst->Length = len;
-        /* append terminating NULL if enough space */
+        /* append terminating '\0' if enough space */
         if (len < dst->MaximumLength) dst->Buffer[len / sizeof(WCHAR)] = 0;
     }
     else dst->Length = 0;
@@ -189,6 +262,64 @@
 
 
 /**************************************************************************
+ *      RtlDuplicateUnicodeString   (NTDLL.@)
+ *
+ * Duplicates an unicode string.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. destination contains the duplicated unicode string.
+ *  Failure: STATUS_INVALID_PARAMETER, if one of the parameters is illegal.
+ *           STATUS_NO_MEMORY, if the allocation fails.
+ *
+ * NOTES
+ *  For add_nul there are several possible values:
+ *  0 = destination will not be '\0' terminated,
+ *  1 = destination will be '\0' terminated,
+ *  3 = like 1 but for an empty source string produce '\0' terminated empty
+ *     Buffer instead of assigning NULL to the Buffer.
+ *  Other add_nul values are invalid.
+ */
+NTSTATUS WINAPI RtlDuplicateUnicodeString(
+    int add_nul,                  /* [I] flag */
+    const UNICODE_STRING *source, /* [I] Unicode string to be duplicated */
+    UNICODE_STRING *destination)  /* [O] destination for the duplicated unicode string */
+{
+    if (source == NULL || destination == NULL ||
+        source->Length > source->MaximumLength ||
+        (source->Length == 0 && source->MaximumLength > 0 && source->Buffer == NULL) ||
+        add_nul == 2 || add_nul >= 4 || add_nul < 0) {
+        return STATUS_INVALID_PARAMETER;
+    } else {
+        if (source->Length == 0 && add_nul != 3) {
+            destination->Length = 0;
+            destination->MaximumLength = 0;
+            destination->Buffer = NULL;
+        } else {
+            unsigned int destination_max_len = source->Length;
+
+            if (add_nul) {
+                destination_max_len += sizeof(WCHAR);
+            } /* if */
+            destination->Buffer = RtlAllocateHeap(ntdll_get_process_heap(), 0, destination_max_len);
+            if (destination->Buffer == NULL) {
+                return STATUS_NO_MEMORY;
+            } else {
+                memcpy(destination->Buffer, source->Buffer, source->Length);
+                destination->Length = source->Length;
+                destination->MaximumLength = source->Length;
+                /* append terminating '\0' if enough space */
+                if (add_nul) {
+                    destination->MaximumLength = destination_max_len;
+                    destination->Buffer[destination->Length / sizeof(WCHAR)] = 0;
+                } /* if */
+            } /* if */
+        } /* if */
+    } /* if */
+    return STATUS_SUCCESS;
+}
+
+
+/**************************************************************************
  *	RtlEraseUnicodeString   (NTDLL.@)
  */
 void WINAPI RtlEraseUnicodeString( UNICODE_STRING *str )
@@ -407,34 +538,43 @@
 
 
 /*
-	COPY BETWEEN ANSI_STRING or UNICODE_STRING
-	there is no parameter checking, it just crashes
+        COPY BETWEEN ANSI_STRING or UNICODE_STRING
+        there is no parameter checking, it just crashes
 */
 
 
 /**************************************************************************
- *	RtlAnsiStringToUnicodeString   (NTDLL.@)
+ *      RtlAnsiStringToUnicodeString   (NTDLL.@)
+ *
+ * Converts an ansi string to an unicode string.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. uni contains the converted string
+ *  Failure: STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and ansi is too small.
+ *           STATUS_NO_MEMORY, if doalloc is TRUE and the allocation fails.
+ *           STATUS_INVALID_PARAMETER_2, if the unicode string would be larger than 65535.
  *
  * NOTES
- *  This function always writes a terminating NUL.
+ *  This function always writes a terminating '\0'.
  */
-NTSTATUS WINAPI RtlAnsiStringToUnicodeString( PUNICODE_STRING uni,
-                                              PCANSI_STRING ansi,
-                                              BOOLEAN doalloc )
+NTSTATUS WINAPI RtlAnsiStringToUnicodeString(
+    PUNICODE_STRING uni, /* [I/O] Destination for the unicode string */
+    PCANSI_STRING ansi,  /* [I]   Ansi string to be converted */
+    BOOLEAN doalloc)     /* [I]   TRUE=Allocate new buffer for uni, FALSE=Use existing buffer */
 {
-    DWORD total = RtlAnsiStringToUnicodeSize( ansi );
+    DWORD total = RtlAnsiStringToUnicodeSize(ansi);
 
     if (total > 0xffff) return STATUS_INVALID_PARAMETER_2;
     uni->Length = total - sizeof(WCHAR);
-    if (doalloc)
-    {
+    if (doalloc) {
         uni->MaximumLength = total;
-        if (!(uni->Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, total )))
+        if (!(uni->Buffer = RtlAllocateHeap(ntdll_get_process_heap(), 0, total)))
             return STATUS_NO_MEMORY;
-    }
-    else if (total > uni->MaximumLength) return STATUS_BUFFER_OVERFLOW;
+    } else {
+        if (total > uni->MaximumLength) return STATUS_BUFFER_OVERFLOW;
+    } /* if */
 
-    RtlMultiByteToUnicodeN( uni->Buffer, uni->Length, NULL, ansi->Buffer, ansi->Length );
+    RtlMultiByteToUnicodeN(uni->Buffer, uni->Length, NULL, ansi->Buffer, ansi->Length);
     uni->Buffer[uni->Length / sizeof(WCHAR)] = 0;
     return STATUS_SUCCESS;
 }
@@ -443,27 +583,35 @@
 /**************************************************************************
  *	RtlOemStringToUnicodeString   (NTDLL.@)
  *
+ * Converts an oem string to an unicode string.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. uni contains the converted string
+ *  Failure: STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and oem is too small.
+ *           STATUS_NO_MEMORY, if doalloc is TRUE and the allocation fails.
+ *           STATUS_INVALID_PARAMETER_2, if the unicode string would be larger than 65535.
+ *
  * NOTES
- *  This function always writes a terminating NUL.
- *  If the resulting length > 0xffff it returns STATUS_INVALID_PARAMETER_2
+ *  This function always writes a terminating '\0'.
  */
-NTSTATUS WINAPI RtlOemStringToUnicodeString( UNICODE_STRING *uni,
-                                             const STRING *oem,
-                                             BOOLEAN doalloc )
+NTSTATUS WINAPI RtlOemStringToUnicodeString(
+    UNICODE_STRING *uni, /* [I/O] Destination for the unicode string */
+    const STRING *oem,   /* [I]   Oem string to be converted */
+    BOOLEAN doalloc)     /* [I]   TRUE=Allocate new buffer for uni, FALSE=Use existing buffer */
 {
-    DWORD total = RtlOemStringToUnicodeSize( oem );
+    DWORD total = RtlOemStringToUnicodeSize(oem);
 
     if (total > 0xffff) return STATUS_INVALID_PARAMETER_2;
     uni->Length = total - sizeof(WCHAR);
-    if (doalloc)
-    {
+    if (doalloc) {
         uni->MaximumLength = total;
-        if (!(uni->Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, total )))
+        if (!(uni->Buffer = RtlAllocateHeap(ntdll_get_process_heap(), 0, total)))
             return STATUS_NO_MEMORY;
-    }
-    else if (total > uni->MaximumLength) return STATUS_BUFFER_OVERFLOW;
+    } else {
+        if (total > uni->MaximumLength) return STATUS_BUFFER_OVERFLOW;
+    } /* if */
 
-    RtlOemToUnicodeN( uni->Buffer, uni->Length, NULL, oem->Buffer, oem->Length );
+    RtlOemToUnicodeN(uni->Buffer, uni->Length, NULL, oem->Buffer, oem->Length);
     uni->Buffer[uni->Length / sizeof(WCHAR)] = 0;
     return STATUS_SUCCESS;
 }
@@ -472,19 +620,19 @@
 /**************************************************************************
  *	RtlUnicodeStringToAnsiString   (NTDLL.@)
  *
- * Converts an Unicode string to an Ansi string.
+ * Converts an unicode string to an ansi string.
  *
  * RETURNS
  *  Success: STATUS_SUCCESS. ansi contains the converted string
- *  Failure: STATUS_BUFFER_OVERFLOW if doalloc is FALSE and ansi is too small.
- *           STATUS_NO_MEMORY if doalloc is TRUE and the allocation fails.
+ *  Failure: STATUS_BUFFER_OVERFLOW, if doalloc is FALSE and ansi is too small.
+ *           STATUS_NO_MEMORY, if doalloc is TRUE and the allocation fails.
  *
  * NOTES
  *  This function always writes a terminating '\0'.
  *  It performs a partial copy if ansi is too small.
  */
 NTSTATUS WINAPI RtlUnicodeStringToAnsiString(
-    STRING *ansi,              /* [I/O] Destination for the Ansi string */
+    STRING *ansi,              /* [I/O] Destination for the ansi string */
     const UNICODE_STRING *uni, /* [I]   Unicode string to be converted */
     BOOLEAN doalloc)           /* [I]   TRUE=Allocate new buffer for ansi, FALSE=Use existing buffer */
 {
@@ -528,7 +676,7 @@
  *
  * NOTES
  *   If doalloc is TRUE, the length allocated is uni->Length + 1.
- *   This function always NUL terminates the string returned.
+ *   This function always '\0' terminates the string returned.
  */
 NTSTATUS WINAPI RtlUnicodeStringToOemString( STRING *oem,
                                              const UNICODE_STRING *uni,
@@ -724,12 +872,13 @@
  *           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.
+ *  dest is never '\0' terminated because it may be equal to src, and src
+ *  might not be '\0' terminated. dest->Length is only set upon success.
  */
-NTSTATUS WINAPI RtlUpcaseUnicodeString( UNICODE_STRING *dest,
-                                        const UNICODE_STRING *src,
-                                        BOOLEAN doalloc )
+NTSTATUS WINAPI RtlUpcaseUnicodeString(
+    UNICODE_STRING *dest,
+    const UNICODE_STRING *src,
+    BOOLEAN doalloc)
 {
     DWORD i, len = src->Length;
 
@@ -763,13 +912,13 @@
  *           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.
+ *  dest is never '\0' terminated because it may be equal to src, and src
+ *  might not be '\0' terminated. dest->Length is only set upon success.
  */
 NTSTATUS WINAPI RtlDowncaseUnicodeString(
-	UNICODE_STRING *dest,
-	const UNICODE_STRING *src,
-	BOOLEAN doalloc)
+    UNICODE_STRING *dest,
+    const UNICODE_STRING *src,
+    BOOLEAN doalloc)
 {
     DWORD i;
     DWORD len = src->Length;
@@ -777,14 +926,14 @@
     if (doalloc) {
         dest->MaximumLength = len;
         if (!(dest->Buffer = RtlAllocateHeap( ntdll_get_process_heap(), 0, len ))) {
-	    return STATUS_NO_MEMORY;
-	} /* if */
+            return STATUS_NO_MEMORY;
+        } /* if */
     } else if (len > dest->MaximumLength) {
-	return STATUS_BUFFER_OVERFLOW;
+        return STATUS_BUFFER_OVERFLOW;
     } /* if */
 
     for (i = 0; i < len/sizeof(WCHAR); i++) {
-	dest->Buffer[i] = tolowerW(src->Buffer[i]);
+        dest->Buffer[i] = tolowerW(src->Buffer[i]);
     } /* for */
     dest->Length = len;
     return STATUS_SUCCESS;
@@ -912,7 +1061,7 @@
 
 
 /*
-	STRING SIZE
+        STRING SIZE
 */
 
 
@@ -921,7 +1070,7 @@
  *      RtlxOemStringToUnicodeSize  (NTDLL.@)
  *
  * Calculate the size in bytes necessary for the Unicode conversion of str,
- * including the terminating NUL.
+ * including the terminating '\0'.
  *
  * PARAMS
  *  str [I] String to calculate the size of
@@ -941,7 +1090,7 @@
  *      RtlxAnsiStringToUnicodeSize  (NTDLL.@)
  *
  * Calculate the size in bytes necessary for the Unicode conversion of str,
- * including the terminating NUL.
+ * including the terminating '\0'.
  *
  * PARAMS
  *  str [I] String to calculate the size of
@@ -961,7 +1110,7 @@
  *      RtlMultiByteToUnicodeSize   (NTDLL.@)
  *
  * Compute the size in bytes necessary for the Unicode conversion of str,
- * without the terminating NUL.
+ * without the terminating '\0'.
  *
  * PARAMS
  *  size [O] Destination for size
@@ -982,7 +1131,7 @@
  *      RtlUnicodeToMultiByteSize   (NTDLL.@)
  *
  * Calculate the size in bytes necessary for the multibyte conversion of str,
- * without the terminating NULL.
+ * without the terminating '\0'.
  *
  * PARAMS
  *  size [O] Destination for size
@@ -1004,7 +1153,7 @@
  *      RtlxUnicodeStringToAnsiSize  (NTDLL.@)
  *
  * Calculate the size in bytes necessary for the Ansi conversion of str,
- * including the terminating NUL.
+ * including the terminating '\0'.
  *
  * PARAMS
  *  str [I] String to calculate the size of
@@ -1025,7 +1174,7 @@
  *      RtlxUnicodeStringToOemSize  (NTDLL.@)
  *
  * Calculate the size in bytes necessary for the OEM conversion of str,
- * including the terminating NUL.
+ * including the terminating '\0'.
  *
  * PARAMS
  *  str [I] String to calculate the size of
@@ -1090,11 +1239,11 @@
     const STRING *src)  /* [I]   Buffered character string to be concatenated */
 {
     if (src->Length != 0) {
-	unsigned int dest_len = src->Length + dest->Length;
+        unsigned int dest_len = src->Length + dest->Length;
 
-	if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
-	memcpy(dest->Buffer + dest->Length, src->Buffer, src->Length);
-	dest->Length = dest_len;
+        if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
+        memcpy(dest->Buffer + dest->Length, src->Buffer, src->Length);
+        dest->Length = dest_len;
     } /* if */
     return STATUS_SUCCESS;
 }
@@ -1131,10 +1280,10 @@
         if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
         memcpy(dest->Buffer + dest->Length/sizeof(WCHAR), src, src_len);
         dest->Length = dest_len;
-        /* append terminating NULL if enough space */
+        /* append terminating '\0' if enough space */
         if (dest_len + sizeof(WCHAR) <= dest->MaximumLength) {
-	    dest->Buffer[dest_len / sizeof(WCHAR)] = 0;
-	} /* if */
+            dest->Buffer[dest_len / sizeof(WCHAR)] = 0;
+        } /* if */
     } /* if */
     return STATUS_SUCCESS;
 }
@@ -1164,22 +1313,96 @@
     const UNICODE_STRING *src) /* [I]   Buffered unicode string to be concatenated */
 {
     if (src->Length != 0) {
-	unsigned int dest_len = src->Length + dest->Length;
+        unsigned int dest_len = src->Length + dest->Length;
 
-	if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
-	memcpy(dest->Buffer + dest->Length/sizeof(WCHAR), src->Buffer, src->Length);
-	dest->Length = dest_len;
-	/* append terminating NULL if enough space */
-	if (dest_len + sizeof(WCHAR) <= dest->MaximumLength) {
-	    dest->Buffer[dest_len / sizeof(WCHAR)] = 0;
-	} /* if */
+        if (dest_len > dest->MaximumLength) return STATUS_BUFFER_TOO_SMALL;
+        memcpy(dest->Buffer + dest->Length/sizeof(WCHAR), src->Buffer, src->Length);
+        dest->Length = dest_len;
+        /* append terminating '\0' if enough space */
+        if (dest_len + sizeof(WCHAR) <= dest->MaximumLength) {
+            dest->Buffer[dest_len / sizeof(WCHAR)] = 0;
+        } /* if */
     } /* if */
     return STATUS_SUCCESS;
 }
 
 
+/**************************************************************************
+ *      RtlFindCharInUnicodeString   (NTDLL.@)
+ *
+ * Searches for one of several unicode characters in an unicode string.
+ *
+ * RETURNS
+ *  Success: STATUS_SUCCESS. pos contains the position after the character found.
+ *  Failure: STATUS_NOT_FOUND, if none of the search_chars are in main_str.
+ */
+NTSTATUS WINAPI RtlFindCharInUnicodeString(
+    int flags,                          /* [I] Flags */
+    const UNICODE_STRING *main_str,     /* [I] Unicode string in which one or more characters are searched */
+    const UNICODE_STRING *search_chars, /* [I] Unicode string which contains the characters to search for */
+    USHORT *pos)                        /* [O] Position of the first character found + 2 */
+{
+    int main_idx;
+    unsigned int search_idx;
+
+    switch (flags) {
+        case 0:
+            for (main_idx = 0; main_idx < main_str->Length / sizeof(WCHAR); main_idx++) {
+                for (search_idx = 0; search_idx < search_chars->Length / sizeof(WCHAR); search_idx++) {
+                    if (main_str->Buffer[main_idx] == search_chars->Buffer[search_idx]) {
+                        *pos = (main_idx + 1) * sizeof(WCHAR);
+                        return STATUS_SUCCESS;
+                    } /* if */
+                } /* if */
+            } /* if */
+            *pos = 0;
+            return STATUS_NOT_FOUND;
+        case 1:
+            for (main_idx = main_str->Length / sizeof(WCHAR) - 1; main_idx >= 0; main_idx--) {
+                for (search_idx = 0; search_idx < search_chars->Length / sizeof(WCHAR); search_idx++) {
+                    if (main_str->Buffer[main_idx] == search_chars->Buffer[search_idx]) {
+                        *pos = main_idx * sizeof(WCHAR);
+                        return STATUS_SUCCESS;
+                    } /* if */
+                } /* if */
+            } /* if */
+            *pos = 0;
+            return STATUS_NOT_FOUND;
+        case 2:
+            for (main_idx = 0; main_idx < main_str->Length / sizeof(WCHAR); main_idx++) {
+                search_idx = 0;
+                while (search_idx < search_chars->Length / sizeof(WCHAR) &&
+                         main_str->Buffer[main_idx] != search_chars->Buffer[search_idx]) {
+                    search_idx++;
+                } /* if */
+                if (search_idx >= search_chars->Length / sizeof(WCHAR)) {
+                    *pos = (main_idx + 1) * sizeof(WCHAR);
+                    return STATUS_SUCCESS;
+                } /* if */
+            } /* if */
+            *pos = 0;
+            return STATUS_NOT_FOUND;
+        case 3:
+            for (main_idx = main_str->Length / sizeof(WCHAR) - 1; main_idx >= 0; main_idx--) {
+                search_idx = 0;
+                while (search_idx < search_chars->Length / sizeof(WCHAR) &&
+                         main_str->Buffer[main_idx] != search_chars->Buffer[search_idx]) {
+                    search_idx++;
+                } /* if */
+                if (search_idx >= search_chars->Length / sizeof(WCHAR)) {
+                    *pos = main_idx * sizeof(WCHAR);
+                    return STATUS_SUCCESS;
+                } /* if */
+            } /* if */
+            *pos = 0;
+            return STATUS_NOT_FOUND;
+    } /* switch */
+    return STATUS_NOT_FOUND;
+}
+
+
 /*
-	MISC
+        MISC
 */
 
 
diff -urN wine_cvs_from_20030505/include/winternl.h new_wine-20030408/include/winternl.h
--- wine_cvs_from_20030505/include/winternl.h	Tue May  6 09:36:02 2003
+++ new_wine-20030408/include/winternl.h	Tue May  6 12:01:02 2003
@@ -967,6 +967,7 @@
 WCHAR     WINAPI RtlDowncaseUnicodeChar(WCHAR);
 NTSTATUS  WINAPI RtlDowncaseUnicodeString(UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
 void      WINAPI RtlDumpResource(LPRTL_RWLOCK);
+NTSTATUS  WINAPI RtlDuplicateUnicodeString(int,const UNICODE_STRING*,UNICODE_STRING*);
 
 LONGLONG  WINAPI RtlEnlargedIntegerMultiply(INT,INT);
 ULONGLONG WINAPI RtlEnlargedUnsignedMultiply(UINT,UINT);
@@ -984,6 +985,7 @@
 LONGLONG  WINAPI RtlExtendedIntegerMultiply(LONGLONG,INT);
 LONGLONG  WINAPI RtlExtendedLargeIntegerDivide(LONGLONG,INT,INT *);
 
+NTSTATUS  WINAPI RtlFindCharInUnicodeString(int,const UNICODE_STRING*,const UNICODE_STRING*,USHORT*);
 ULONG     WINAPI RtlFindClearBits(PCRTL_BITMAP,ULONG,ULONG);
 ULONG     WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP,ULONG,ULONG);
 ULONG     WINAPI RtlFindClearRuns(PCRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN);
@@ -1026,6 +1028,7 @@
 void      WINAPI RtlInitString(PSTRING,PCSZ);
 void      WINAPI RtlInitAnsiString(PANSI_STRING,PCSZ);
 void      WINAPI RtlInitUnicodeString(PUNICODE_STRING,PCWSTR);
+NTSTATUS  WINAPI RtlInitUnicodeStringEx(PUNICODE_STRING,PCWSTR);
 NTSTATUS  WINAPI RtlInitializeCriticalSection(RTL_CRITICAL_SECTION *);
 NTSTATUS  WINAPI RtlInitializeCriticalSectionAndSpinCount(RTL_CRITICAL_SECTION *,DWORD);
 void      WINAPI RtlInitializeBitMap(PRTL_BITMAP,LPBYTE,ULONG);


More information about the wine-patches mailing list