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@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!
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();
*/
}