Tests for RtlCompareMemoryUlong, RtlUniform, RtlDowncaseUnicodeString,
RtlAppendUnicodeStringToString.
This commit is contained in:
parent
c83aa0d311
commit
83ee8478d4
|
@ -3,6 +3,7 @@ error.ok
|
||||||
generated.ok
|
generated.ok
|
||||||
large_int.ok
|
large_int.ok
|
||||||
ntdll_test.exe.spec.c
|
ntdll_test.exe.spec.c
|
||||||
|
rtl.ok
|
||||||
rtlbitmap.ok
|
rtlbitmap.ok
|
||||||
rtlstr.ok
|
rtlstr.ok
|
||||||
string.ok
|
string.ok
|
||||||
|
|
|
@ -9,6 +9,7 @@ CTESTS = \
|
||||||
error.c \
|
error.c \
|
||||||
generated.c \
|
generated.c \
|
||||||
large_int.c \
|
large_int.c \
|
||||||
|
rtl.c \
|
||||||
rtlbitmap.c \
|
rtlbitmap.c \
|
||||||
rtlstr.c \
|
rtlstr.c \
|
||||||
string.c
|
string.c
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
|
|
@ -35,9 +35,11 @@ static STRING str;
|
||||||
|
|
||||||
/* Function ptrs for ntdll calls */
|
/* Function ptrs for ntdll calls */
|
||||||
static HMODULE hntdll = 0;
|
static HMODULE hntdll = 0;
|
||||||
|
static NTSTATUS (WINAPI *pRtlAppendUnicodeStringToString)(UNICODE_STRING *, const UNICODE_STRING *);
|
||||||
static NTSTATUS (WINAPI *pRtlCharToInteger)(char *, ULONG, int *);
|
static NTSTATUS (WINAPI *pRtlCharToInteger)(char *, ULONG, int *);
|
||||||
static VOID (WINAPI *pRtlCopyString)(STRING *, const STRING *);
|
static VOID (WINAPI *pRtlCopyString)(STRING *, const STRING *);
|
||||||
static BOOLEAN (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
|
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 BOOLEAN (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);
|
||||||
static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
|
static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING);
|
||||||
static VOID (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR);
|
static VOID (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR);
|
||||||
|
@ -91,9 +93,11 @@ static void InitFunctionPtrs(void)
|
||||||
hntdll = LoadLibraryA("ntdll.dll");
|
hntdll = LoadLibraryA("ntdll.dll");
|
||||||
ok(hntdll != 0, "LoadLibrary failed");
|
ok(hntdll != 0, "LoadLibrary failed");
|
||||||
if (hntdll) {
|
if (hntdll) {
|
||||||
|
pRtlAppendUnicodeStringToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeStringToString");
|
||||||
pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger");
|
pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger");
|
||||||
pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString");
|
pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString");
|
||||||
pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString");
|
pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString");
|
||||||
|
pRtlDowncaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlDowncaseUnicodeString");
|
||||||
pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString");
|
pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString");
|
||||||
pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
|
pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString");
|
||||||
pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
|
pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString");
|
||||||
|
@ -305,6 +309,190 @@ static void test_RtlUpcaseUnicodeString(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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 {
|
typedef struct {
|
||||||
int base;
|
int base;
|
||||||
char *str;
|
char *str;
|
||||||
|
@ -321,6 +509,14 @@ static const str2int_t str2int[] = {
|
||||||
{ 0, "-+214", 0, STATUS_SUCCESS},
|
{ 0, "-+214", 0, STATUS_SUCCESS},
|
||||||
{ 0, "++214", 0, STATUS_SUCCESS},
|
{ 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 \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}, /* Signs can be used after whitespace */
|
||||||
{ 0, " \n \r \t-214", -214, STATUS_SUCCESS},
|
{ 0, " \n \r \t-214", -214, STATUS_SUCCESS},
|
||||||
|
@ -772,9 +968,11 @@ START_TEST(rtlstr)
|
||||||
test_RtlIntegerToChar();
|
test_RtlIntegerToChar();
|
||||||
test_RtlUpperChar();
|
test_RtlUpperChar();
|
||||||
test_RtlUpperString();
|
test_RtlUpperString();
|
||||||
|
test_RtlAppendUnicodeStringToString();
|
||||||
} /* if */
|
} /* if */
|
||||||
/*
|
/*
|
||||||
* test_RtlUpcaseUnicodeChar();
|
* test_RtlUpcaseUnicodeChar();
|
||||||
* test_RtlUpcaseUnicodeString();
|
* test_RtlUpcaseUnicodeString();
|
||||||
|
* test_RtlDowncaseUnicodeString();
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue