some ntdll functions (3) - part 2: tests

thomas.mertes at gmx.at thomas.mertes at gmx.at
Fri Mar 21 01:57:18 CST 2003


Hello

Here are the tests for some ntdll functions.
These tests require the functions implemented in
part 1 of this patch (see part1: functions).

Changelog:

	* dlls/ntdll/tests/Makefile.in,
	  dlls/ntdll/tests/rtlstr.c,
	  dlls/ntdll/tests/rtl.c:
	Thomas Mertes <thomas.mertes at gmx.at>
	- Tests for RtlCompareMemoryUlong,
	  RtlUniform, RtlDowncaseUnicodeString,
	  RtlAppendUnicodeStringToString

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/tests/Makefile.in new_wine-20030318/dlls/ntdll/tests/Makefile.in
--- old_wine-20030318/dlls/ntdll/tests/Makefile.in	Tue Mar 18 19:27:19 2003
+++ new_wine-20030318/dlls/ntdll/tests/Makefile.in	Fri Mar 21 01:59:25 2003
@@ -9,6 +9,7 @@
 	error.c \
 	generated.c \
 	large_int.c \
+	rtl.c \
 	rtlbitmap.c \
 	rtlstr.c \
 	string.c
diff -urN old_wine-20030318/dlls/ntdll/tests/rtl.c new_wine-20030318/dlls/ntdll/tests/rtl.c
--- old_wine-20030318/dlls/ntdll/tests/rtl.c	Thu Jan  1 01:00:00 1970
+++ new_wine-20030318/dlls/ntdll/tests/rtl.c	Fri Mar 21 01:59:08 2003
@@ -0,0 +1,335 @@
+/* Unit test suite for Rtl* API functions
+ *
+ * Copyright 2003 Thomas Mertes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * NOTES
+ * We use function pointers here as there is no import library for NTDLL on
+ * windows.
+ */
+
+#include <stdlib.h>
+
+#include "winbase.h"
+#include "wine/test.h"
+#include "winnt.h"
+#include "winnls.h"
+#include "winternl.h"
+
+/* Function ptrs for ntdll calls */
+static HMODULE hntdll = 0;
+static SIZE_T    (WINAPI *pRtlCompareMemoryUlong)(PULONG, SIZE_T, ULONG);
+static ULONG     (WINAPI *pRtlUniform)(PULONG);
+
+
+static void InitFunctionPtrs(void)
+{
+    hntdll = LoadLibraryA("ntdll.dll");
+    ok(hntdll != 0, "LoadLibrary failed");
+    if (hntdll) {
+	pRtlCompareMemoryUlong = (void *)GetProcAddress(hntdll, "RtlCompareMemoryUlong");
+	pRtlUniform = (void *)GetProcAddress(hntdll, "RtlUniform");
+    } /* if */
+}
+
+
+static void test_RtlCompareMemoryUlong(void)
+{
+    ULONG a[10];
+    ULONG result;
+
+    a[0]= 0x0123;
+    a[1]= 0x4567;
+    a[2]= 0x89ab;
+    a[3]= 0xcdef;
+    result = pRtlCompareMemoryUlong(a, 0, 0x0123);
+    ok(result == 0, "RtlCompareMemoryUlong(%p, 0, 0x0123) returns %lu, expected 0\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 3, 0x0123);
+    ok(result == 0, "RtlCompareMemoryUlong(%p, 3, 0x0123) returns %lu, expected 0\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 4, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 4, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 5, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 5, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 7, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 7, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 8, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 8, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 9, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 9, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 4, 0x0127);
+    ok(result == 0, "RtlCompareMemoryUlong(%p, 4, 0x0127) returns %lu, expected 0\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 4, 0x7123);
+    ok(result == 0, "RtlCompareMemoryUlong(%p, 4, 0x7123) returns %lu, expected 0\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 16, 0x4567);
+    ok(result == 0, "RtlCompareMemoryUlong(%p, 16, 0x4567) returns %lu, expected 0\n", a, result);
+
+    a[1]= 0x0123;
+    result = pRtlCompareMemoryUlong(a, 3, 0x0123);
+    ok(result == 0, "RtlCompareMemoryUlong(%p, 3, 0x0123) returns %lu, expected 0\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 4, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 4, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 5, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 5, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 7, 0x0123);
+    ok(result == 4, "RtlCompareMemoryUlong(%p, 7, 0x0123) returns %lu, expected 4\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 8, 0x0123);
+    ok(result == 8, "RtlCompareMemoryUlong(%p, 8, 0x0123) returns %lu, expected 8\n", a, result);
+    result = pRtlCompareMemoryUlong(a, 9, 0x0123);
+    ok(result == 8, "RtlCompareMemoryUlong(%p, 9, 0x0123) returns %lu, expected 8\n", a, result);
+}
+
+
+static void test_RtlUniform(void)
+{
+    ULONGLONG num;
+    ULONG seed;
+    ULONG seed_bak;
+    ULONG expected;
+    ULONG result;
+
+/*
+ * According to the documentation RtlUniform is using D.H. Lehmer's 1948
+ * algorithm. This algorithm is:
+ *
+ * seed = (seed * const_1 + const_2) % const_3;
+ *
+ * According to the documentation the random number is distributed over
+ * [0..MAXLONG]. Therefore const_3 is MAXLONG + 1:
+ *
+ * seed = (seed * const_1 + const_2) % (MAXLONG + 1);
+ *
+ * Because MAXLONG is 0xfffffff (which is 0x10000000 - 1) the algorithm
+ * can be expressed as:
+ *
+ * seed = (seed * const_1 + const_2) & MAXLONG;
+ *
+ * To find out const_2 we just call RtlUniform with seed set to 0:
+ */
+    seed = 0;
+    expected = 0x7fffffc3;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 0)) returns %lx, expected %lx",
+        result, expected);
+/*
+ * The algorithm is now:
+ *
+ * seed = (seed * const_1 + 0x7fffffc3) & MAXLONG;
+ *
+ * To find out const_1 we can use:
+ *
+ * const_1 = RtlUniform(1) - 0x7fffffc3;
+ *
+ * If that does not work a search loop can try all possible values of
+ * const_1 and compare to the result to RtlUniform(1).
+ * This way we find out that const_1 is 0xffffffed.
+ *
+ * For seed = 1 the const_2 is 0x7fffffc4:
+ */
+    seed = 1;
+    expected = seed * 0xffffffed + 0x7fffffc3 + 1;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 1)) returns %lx, expected %lx",
+        result, expected);
+/*
+ * For seed = 2 the const_2 is 0x7fffffc3:
+ */
+    seed = 2;
+    expected = seed * 0xffffffed + 0x7fffffc3;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 2)) returns %lx, expected %lx",
+        result, expected);
+/*
+ * More tests show that if seed is odd the result must be incremented by 1:
+ */
+    seed = 3;
+    expected = seed * 0xffffffed + 0x7fffffc3 + (seed & 1);
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 2)) returns %lx, expected %lx",
+        result, expected);
+
+    seed = 0x6bca1aa;
+    expected = seed * 0xffffffed + 0x7fffffc3;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 0x6bca1aa)) returns %lx, expected %lx",
+        result, expected);
+
+    seed = 0x6bca1ab;
+    expected = seed * 0xffffffed + 0x7fffffc3 + 1;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 0x6bca1ab)) returns %lx, expected %lx",
+        result, expected);
+/*
+ * When seed is 0x6bca1ac there is an exception:
+ */
+    seed = 0x6bca1ac;
+    expected = seed * 0xffffffed + 0x7fffffc3 + 2;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 0x6bca1ac)) returns %lx, expected %lx",
+        result, expected);
+/*
+ * Note that up to here const_3 is not used
+ * (the highest bit of the result is not set).
+ *
+ * Starting with 0x6bca1ad: If seed is even the result must be incremented by 1:
+ */
+    seed = 0x6bca1ad;
+    expected = (seed * 0xffffffed + 0x7fffffc3) & MAXLONG;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 0x6bca1ad)) returns %lx, expected %lx",
+        result, expected);
+
+    seed = 0x6bca1ae;
+    expected = (seed * 0xffffffed + 0x7fffffc3 + 1) & MAXLONG;
+    result = pRtlUniform(&seed);
+    ok(result == expected,
+        "RtlUniform(&seed (seed == 0x6bca1ae)) returns %lx, expected %lx",
+        result, expected);
+/*
+ * There are several ranges where for odd or even seed the result must be
+ * incremented by 1. You can see this ranges in the following test.
+ *
+ * For a full test use one of the following loop heads:
+ *
+ *  for (num = 0; num <= 0xffffffff; num++) {
+ *      seed = num;
+ *      ...
+ *
+ *  seed = 0;
+ *  for (num = 0; num <= 0xffffffff; num++) {
+ *      ...
+ */
+    seed = 0;
+    for (num = 0; num <= 100000; num++) {
+
+	expected = seed * 0xffffffed + 0x7fffffc3;
+	if (seed < 0x6bca1ac) {
+	    expected = expected + (seed & 1);
+	} else if (seed == 0x6bca1ac) {
+	    expected = (expected + 2) & MAXLONG;
+	} else if (seed < 0xd79435c) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x1435e50b) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x1af286ba) { 
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x21af2869) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x286bca18) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x2f286bc7) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x35e50d77) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x3ca1af26) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x435e50d5) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x4a1af284) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x50d79433) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x579435e2) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x5e50d792) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x650d7941) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x6bca1af0) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x7286bc9f) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x79435e4e) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x7ffffffd) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x86bca1ac) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed == 0x86bca1ac) {
+	    expected = (expected + 1) & MAXLONG;
+	} else if (seed < 0x8d79435c) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0x9435e50b) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0x9af286ba) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xa1af2869) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0xa86bca18) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xaf286bc7) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed == 0xaf286bc7) {
+	    expected = (expected + 2) & MAXLONG;
+	} else if (seed < 0xb5e50d77) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xbca1af26) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0xc35e50d5) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xca1af284) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0xd0d79433) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xd79435e2) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0xde50d792) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xe50d7941) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0xebca1af0) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xf286bc9f) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else if (seed < 0xf9435e4e) {
+	    expected = expected + (seed & 1);
+	} else if (seed < 0xfffffffd) {
+	    expected = (expected + (~seed & 1)) & MAXLONG;
+	} else {
+	    expected = expected + (seed & 1);
+	} /* if */
+        seed_bak = seed;
+        result = pRtlUniform(&seed);
+        ok(result == expected,
+                "test: %llu RtlUniform(&seed (seed == %lx)) returns %lx, expected %lx",
+                num, seed_bak, result, expected);
+        ok(seed == expected,
+                "test: %llu RtlUniform(&seed (seed == %lx)) sets seed to %lx, expected %lx",
+                num, seed_bak, seed, expected);
+    } /* for */
+/*
+ * Further investigation shows: In the different regions the highest bit
+ * is set or cleared when even or odd seeds need an increment by 1.
+ * This leads to the simplified RtlUniform of wine (see dlls/ntdll/rtl.c).
+ */
+}
+
+
+START_TEST(rtl)
+{
+    InitFunctionPtrs();
+
+    test_RtlCompareMemoryUlong();
+    test_RtlUniform();
+}
+
diff -urN old_wine-20030318/dlls/ntdll/tests/rtlstr.c new_wine-20030318/dlls/ntdll/tests/rtlstr.c
--- old_wine-20030318/dlls/ntdll/tests/rtlstr.c	Wed Feb 19 04:40:14 2003
+++ new_wine-20030318/dlls/ntdll/tests/rtlstr.c	Fri Mar 21 01:59:00 2003
@@ -35,9 +35,11 @@
 
 /* Function ptrs for ntdll calls */
 static HMODULE hntdll = 0;
+static NTSTATUS (WINAPI *pRtlAppendUnicodeStringToString)(UNICODE_STRING *, const UNICODE_STRING *);
 static NTSTATUS (WINAPI *pRtlCharToInteger)(char *, ULONG, int *);
 static VOID     (WINAPI *pRtlCopyString)(STRING *, const STRING *);
 static BOOLEAN  (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
+static NTSTATUS (WINAPI *pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
 static BOOLEAN  (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
 static VOID     (WINAPI *pRtlFreeAnsiString)(PSTRING);
 static VOID     (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR);
@@ -91,9 +93,11 @@
     hntdll = LoadLibraryA("ntdll.dll");
     ok(hntdll != 0, "LoadLibrary failed");
     if (hntdll) {
+	pRtlAppendUnicodeStringToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeStringToString");
 	pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger");
 	pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString");
 	pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString");
+	pRtlDowncaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlDowncaseUnicodeString");
 	pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString");
 	pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
 	pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
@@ -305,6 +309,190 @@
 }
 
 
+static void test_RtlDowncaseUnicodeString(void)
+{
+    int i;
+    WCHAR ch;
+    WCHAR lower_ch;
+    WCHAR source_buf[1025];
+    WCHAR result_buf[1025];
+    WCHAR lower_buf[1025];
+    UNICODE_STRING source_str;
+    UNICODE_STRING result_str;
+    UNICODE_STRING lower_str;
+
+    for (i = 0; i <= 1024; i++) {
+	ch = (WCHAR) i;
+	if (ch >= 'A' && ch <= 'Z') {
+	    lower_ch = ch - 'A' + 'a';
+	} else if (ch >= 0xc0 && ch <= 0xde && ch != 0xd7) {
+	    lower_ch = ch + 0x20;
+	} else if (ch >= 0x391 && ch <= 0x3ab && ch != 0x3a2) {
+	    lower_ch = ch + 0x20;
+	} else {
+	    switch (ch) {
+		case 0x178: lower_ch = 0xff; break;
+		case 0x181: lower_ch = 0x253; break;
+		case 0x186: lower_ch = 0x254; break;
+		case 0x189: lower_ch = 0x256; break;
+		case 0x18a: lower_ch = 0x257; break;
+		case 0x18e: lower_ch = 0x1dd; break;
+		case 0x18f: lower_ch = 0x259; break;
+		case 0x190: lower_ch = 0x25b; break;
+		case 0x193: lower_ch = 0x260; break;
+		case 0x194: lower_ch = 0x263; break;
+		case 0x196: lower_ch = 0x269; break;
+		case 0x197: lower_ch = 0x268; break;
+		case 0x19c: lower_ch = 0x26f; break;
+		case 0x19d: lower_ch = 0x272; break;
+		case 0x19f: lower_ch = 0x275; break;
+		case 0x1a9: lower_ch = 0x283; break;
+		case 0x1ae: lower_ch = 0x288; break;
+		case 0x1b1: lower_ch = 0x28a; break;
+		case 0x1b2: lower_ch = 0x28b; break;
+		case 0x1b7: lower_ch = 0x292; break;
+		case 0x1c4: lower_ch = 0x1c6; break;
+		case 0x1c7: lower_ch = 0x1c9; break;
+		case 0x1ca: lower_ch = 0x1cc; break;
+		case 0x1f1: lower_ch = 0x1f3; break;
+		case 0x386: lower_ch = 0x3ac; break;
+		case 0x388: lower_ch = 0x3ad; break;
+		case 0x389: lower_ch = 0x3ae; break;
+		case 0x38a: lower_ch = 0x3af; break;
+		case 0x38c: lower_ch = 0x3cc; break;
+		case 0x38e: lower_ch = 0x3cd; break;
+		case 0x38f: lower_ch = 0x3ce; break;
+		case 0x400: lower_ch = 0x0; break;
+		default: lower_ch = ch; break;
+	    } /* switch */
+	} /* if */
+	source_buf[i] = ch;
+	result_buf[i] = '\0';
+	lower_buf[i] = lower_ch;
+    } /* for */
+    source_buf[i] = '\0';
+    result_buf[i] = '\0';
+    lower_buf[i] = '\0';
+    source_str.Length = 2048;
+    source_str.MaximumLength = 2048;
+    source_str.Buffer = source_buf;
+    result_str.Length = 2048;
+    result_str.MaximumLength = 2048;
+    result_str.Buffer = result_buf;
+    lower_str.Length = 2048;
+    lower_str.MaximumLength = 2048;
+    lower_str.Buffer = lower_buf;
+
+    pRtlDowncaseUnicodeString(&result_str, &source_str, 0);
+    for (i = 0; i <= 1024; i++) {
+	ok(result_str.Buffer[i] == lower_str.Buffer[i] || result_str.Buffer[i] == source_str.Buffer[i] + 1,
+	   "RtlDowncaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x]",
+	   source_str.Buffer[i], source_str.Buffer[i],
+	   result_str.Buffer[i], result_str.Buffer[i],
+	   lower_str.Buffer[i], lower_str.Buffer[i]);
+    } /* for */
+}
+
+
+static void test_RtlAppendUnicodeStringToString(void)
+{
+    CHAR dest_buf[257];
+    CHAR src_buf[257];
+    UNICODE_STRING dest_str;
+    UNICODE_STRING src_str;
+    NTSTATUS result;
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    strcpy(src_buf, "nicodeStringZYXWVUTS");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 26;
+    dest_str.Buffer = (WCHAR *) dest_buf;
+    src_str.Length = 12;
+    src_str.MaximumLength = 12;
+    src_str.Buffer = (WCHAR *) src_buf;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_SUCCESS,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeUnicodeString\0\0efghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 25;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_SUCCESS,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeUnicodeString\0\0efghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 24;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_SUCCESS,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeUnicodeStringcdefghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 23;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_BUFFER_TOO_SMALL,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeU0123456789abcdefghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 0;
+    src_str.Length = 0;
+    src_str.MaximumLength = 0;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_SUCCESS,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeU0123456789abcdefghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 22;
+    src_str.Length = 0;
+    src_str.MaximumLength = 0;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_SUCCESS,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeU0123456789abcdefghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+
+    strcpy(dest_buf, "ThisisafakeU0123456789abcdefghij");
+    dest_str.Length = 12;
+    dest_str.MaximumLength = 22;
+    src_str.Length = 0;
+    src_str.MaximumLength = 0;
+    src_str.Buffer = NULL;
+    result = pRtlAppendUnicodeStringToString(&dest_str, &src_str);
+    ok(result == STATUS_SUCCESS,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has result %lx",
+       result);
+    ok(memcmp(dest_buf, "ThisisafakeU0123456789abcdefghij", 32) == 0,
+       "call failed: RtlAppendUnicodeStringToString(dest, src) has dest \"%s\"",
+       dest_buf);
+}
+
+
 typedef struct {
     int base;
     char *str;
@@ -321,6 +509,14 @@
     { 0, "-+214",                 0, STATUS_SUCCESS},
     { 0, "++214",                 0, STATUS_SUCCESS},
     { 0, "+-214",                 0, STATUS_SUCCESS},
+    { 0, "\001\002\003\00411",   11, STATUS_SUCCESS}, /* whitespace char  1 to  4 */
+    { 0, "\005\006\007\01012",   12, STATUS_SUCCESS}, /* whitespace char  5 to  8 */
+    { 0, "\011\012\013\01413",   13, STATUS_SUCCESS}, /* whitespace char  9 to 12 */
+    { 0, "\015\016\017\02014",   14, STATUS_SUCCESS}, /* whitespace char 13 to 16 */
+    { 0, "\021\022\023\02415",   15, STATUS_SUCCESS}, /* whitespace char 17 to 20 */
+    { 0, "\025\026\027\03016",   16, STATUS_SUCCESS}, /* whitespace char 21 to 24 */
+    { 0, "\031\032\033\03417",   17, STATUS_SUCCESS}, /* whitespace char 25 to 28 */
+    { 0, "\035\036\037\04018",   18, STATUS_SUCCESS}, /* whitespace char 29 to 32 */
     { 0, " \n \r \t214",        214, STATUS_SUCCESS},
     { 0, " \n \r \t+214",       214, STATUS_SUCCESS}, /* Signs can be used after whitespace */
     { 0, " \n \r \t-214",      -214, STATUS_SUCCESS},
@@ -772,9 +968,11 @@
 	test_RtlIntegerToChar();
 	test_RtlUpperChar();
 	test_RtlUpperString();
+	test_RtlAppendUnicodeStringToString();
     } /* if */
 	/*
 	 * test_RtlUpcaseUnicodeChar();
 	 * test_RtlUpcaseUnicodeString();
+	 * test_RtlDowncaseUnicodeString();
 	 */
 }


More information about the wine-patches mailing list