From 57f56eab33937df69439ad329ff0899f99e6a0f9 Mon Sep 17 00:00:00 2001 From: Steven Edwards Date: Sun, 7 Aug 2005 02:16:34 +0000 Subject: [PATCH] ntdll pending some winerror.h fixes svn path=/trunk/; revision=17133 --- reactos/regtests/winetests/ntdll/atom.c | 402 +++ reactos/regtests/winetests/ntdll/env.c | 298 ++ reactos/regtests/winetests/ntdll/error.c | 950 +++++++ reactos/regtests/winetests/ntdll/generated.c | 2486 +++++++++++++++++ reactos/regtests/winetests/ntdll/info.c | 828 ++++++ reactos/regtests/winetests/ntdll/large_int.c | 423 +++ reactos/regtests/winetests/ntdll/ntdll_test.h | 35 + .../regtests/winetests/ntdll/ntdll_test.xml | 18 + reactos/regtests/winetests/ntdll/path.c | 304 ++ reactos/regtests/winetests/ntdll/reg.c | 380 +++ reactos/regtests/winetests/ntdll/rtl.c | 891 ++++++ reactos/regtests/winetests/ntdll/rtlbitmap.c | 640 +++++ reactos/regtests/winetests/ntdll/rtlstr.c | 1741 ++++++++++++ reactos/regtests/winetests/ntdll/string.c | 1100 ++++++++ reactos/regtests/winetests/ntdll/testlist.c | 49 + reactos/regtests/winetests/ntdll/time.c | 109 + 16 files changed, 10654 insertions(+) create mode 100755 reactos/regtests/winetests/ntdll/atom.c create mode 100755 reactos/regtests/winetests/ntdll/env.c create mode 100755 reactos/regtests/winetests/ntdll/error.c create mode 100755 reactos/regtests/winetests/ntdll/generated.c create mode 100755 reactos/regtests/winetests/ntdll/info.c create mode 100755 reactos/regtests/winetests/ntdll/large_int.c create mode 100755 reactos/regtests/winetests/ntdll/ntdll_test.h create mode 100644 reactos/regtests/winetests/ntdll/ntdll_test.xml create mode 100755 reactos/regtests/winetests/ntdll/path.c create mode 100755 reactos/regtests/winetests/ntdll/reg.c create mode 100755 reactos/regtests/winetests/ntdll/rtl.c create mode 100755 reactos/regtests/winetests/ntdll/rtlbitmap.c create mode 100755 reactos/regtests/winetests/ntdll/rtlstr.c create mode 100755 reactos/regtests/winetests/ntdll/string.c create mode 100644 reactos/regtests/winetests/ntdll/testlist.c create mode 100755 reactos/regtests/winetests/ntdll/time.c diff --git a/reactos/regtests/winetests/ntdll/atom.c b/reactos/regtests/winetests/ntdll/atom.c new file mode 100755 index 00000000000..e008fb6d0ae --- /dev/null +++ b/reactos/regtests/winetests/ntdll/atom.c @@ -0,0 +1,402 @@ +/* Unit test suite for Ntdll atom API functions + * + * Copyright 2003 Gyorgy 'Nog' Jeney + * + * 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. + */ + +#define _WIN32_WINNT 0x0501 + +#include +#include +#include "windows.h" +#include "ntstatus.h" +#include "wine/test.h" +#include "wine/unicode.h" +#include "winternl.h" + +/* Function pointers for ntdll calls */ +static HMODULE hntdll = 0; +static NTSTATUS (WINAPI *pRtlCreateAtomTable)(ULONG,PRTL_ATOM_TABLE); +static NTSTATUS (WINAPI *pRtlDestroyAtomTable)(RTL_ATOM_TABLE); +static NTSTATUS (WINAPI *pRtlEmptyAtomTable)(RTL_ATOM_TABLE,BOOLEAN); +static NTSTATUS (WINAPI *pRtlAddAtomToAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM); +static NTSTATUS (WINAPI *pRtlDeleteAtomFromAtomTable)(RTL_ATOM_TABLE,RTL_ATOM); +static NTSTATUS (WINAPI *pRtlLookupAtomInAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM); +static NTSTATUS (WINAPI *pRtlPinAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM); +static NTSTATUS (WINAPI *pRtlQueryAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM,PULONG,PULONG,PWSTR,PULONG); + +static const WCHAR EmptyAtom[] = {0}; +static const WCHAR testAtom1[] = {'H','e','l','l','o',' ','W','o','r','l','d',0}; +static const WCHAR testAtom2[] = {'H','e','l','l','o',' ','W','o','r','l','d','2',0}; +static const WCHAR testAtom3[] = {'H','e','l','l','o',' ','W','o','r','l','d','3',0}; + +static const WCHAR testAtom1Cap[] = {'H','E','L','L','O',' ','W','O','R','L','D',0}; +static const WCHAR testAtom1Low[] = {'h','e','l','l','o',' ','w','o','r','l','d',0}; + +static const WCHAR testAtomInt[] = {'#','1','3','2',0}; +static const WCHAR testAtomIntInv[] = {'#','2','3','4','z',0}; +static const WCHAR testAtomOTT[] = {'#','1','2','3',0}; + +static void InitFunctionPtr(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + ok(hntdll != 0, "Unable to load ntdll.dll\n"); + + if (hntdll) + { + pRtlCreateAtomTable = (void *)GetProcAddress(hntdll, "RtlCreateAtomTable"); + pRtlDestroyAtomTable = (void *)GetProcAddress(hntdll, "RtlDestroyAtomTable"); + pRtlEmptyAtomTable = (void *)GetProcAddress(hntdll, "RtlEmptyAtomTable"); + pRtlAddAtomToAtomTable = (void *)GetProcAddress(hntdll, "RtlAddAtomToAtomTable"); + pRtlDeleteAtomFromAtomTable = (void *)GetProcAddress(hntdll, "RtlDeleteAtomFromAtomTable"); + pRtlLookupAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlLookupAtomInAtomTable"); + pRtlPinAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlPinAtomInAtomTable"); + pRtlQueryAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlQueryAtomInAtomTable"); + } +} + +static DWORD RtlAtomTestThread(LPVOID Table) +{ + RTL_ATOM_TABLE AtomTable = *(PRTL_ATOM_TABLE)Table; + RTL_ATOM Atom; + NTSTATUS res; + ULONG RefCount = 0, PinCount = 0, Len = 0; + WCHAR Name[64]; + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &Atom); + ok(!res, "Unable to find atom from another thread, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &Atom); + ok(!res, "Unable to lookup pinned atom in table, retval: %lx\n", res); + + res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len); + ok(res == STATUS_BUFFER_TOO_SMALL, "We got wrong retval: %lx\n", res); + + Len = 64; + res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len); + ok(!res, "Failed with longenough buffer, retval: %lx\n", res); + ok(RefCount == 1, "Refcount was not 1 but %lx\n", RefCount); + ok(PinCount == 1, "Pincount was not 1 but %lx\n", PinCount); + ok(!strcmpW(Name, testAtom2), "We found wrong atom!!\n"); + ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + + Len = 64; + res = pRtlQueryAtomInAtomTable(AtomTable, Atom, NULL, NULL, Name, &Len); + ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %lx\n", res); + ok(!strcmpW(Name, testAtom2), "Found Wrong atom!\n"); + ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + + res = pRtlPinAtomInAtomTable(AtomTable, Atom); + ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); + + return 0; +} + +static void test_NtAtom(void) +{ + RTL_ATOM_TABLE AtomTable = NULL; + NTSTATUS res; + RTL_ATOM Atom1, Atom2, Atom3, testEAtom, testAtom; + HANDLE testThread; + ULONG RefCount = 0, PinCount = 0, Len = 0; + WCHAR Name[64]; + + /* If we pass a non-null string to create atom table, then it thinks that we + * have passed it an already allocated atom table */ + res = pRtlCreateAtomTable(0, &AtomTable); + ok(!res, "RtlCreateAtomTable should succeed with an atom table size of 0\n"); + + if (!res) + { + res = pRtlDestroyAtomTable(AtomTable); + ok(!res, "We could create the atom table, but we couldn't destroy it! retval: %lx\n", res); + } + + AtomTable = NULL; + res = pRtlCreateAtomTable(37, &AtomTable); + ok(!res, "We're unable to create an atom table with a valid table size retval: %lx\n", res); + if (!res) + { + res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1); + ok(!res, "We were unable to add a simple atom to the atom table, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Cap, &testAtom); + ok(!res, "We were unable to find capital version of the atom, retval: %lx\n", res); + ok(Atom1 == testAtom, "Found wrong atom in table when querying capital atom\n"); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Low, &testAtom); + ok(!res, "Unable to find lowercase version of the atom, retval: %lx\n", res); + ok(testAtom == Atom1, "Found wrong atom when querying lowercase atom\n"); + + res = pRtlAddAtomToAtomTable(AtomTable, EmptyAtom, &testEAtom); + ok(res == STATUS_OBJECT_NAME_INVALID, "Got wrong retval, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(!res, "Failed to find totally legitimate atom, retval: %lx\n", res); + ok(testAtom == Atom1, "Found wrong atom!\n"); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtom2, &Atom2); + ok(!res, "Unable to add other legitimate atom to table, retval: %lx\n", res); + + res = pRtlPinAtomInAtomTable(AtomTable, Atom2); + ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); + + testThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RtlAtomTestThread, &AtomTable, 0, NULL); + WaitForSingleObject(testThread, INFINITE); + + Len = 64; + res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len); + ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); + ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount); + ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount); + ok(!strcmpW(Name, testAtom2), "We found wrong atom\n"); + ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + + res = pRtlEmptyAtomTable(AtomTable, FALSE); + ok(!res, "Unable to empty atom table, retval %lx\n", res); + + Len = 64; + res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len); + ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %lx\n", res); + ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount); + ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount); + ok(!strcmpW(Name, testAtom2), "We found wrong atom\n"); + ok((strlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom); + ok(!res, "We can't find our pinned atom!! retval: %lx\n", res); + ok(testAtom == Atom2, "We found wrong atom!!!\n"); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "We found the atom in our table eaven though we asked RtlEmptyAtomTable to remove it, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtom3, &Atom3); + ok(!res, "Unable to add atom to table, retval: %lx\n", res); + + res = pRtlEmptyAtomTable(AtomTable, TRUE); + ok(!res, "Unable to empty atom table, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom); + ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "The pinned atom should be removed, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom3, &testAtom); + ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Non pinned atom should also be removed, retval: %lx\n", res); + + res = pRtlDestroyAtomTable(AtomTable); + ok(!res, "Can't destroy atom table, retval: %lx\n", res); + } + + AtomTable = NULL; + res = pRtlCreateAtomTable(37, &AtomTable); + ok(!res, "Unable to create atom table, retval: %lx\n", res); + + if (!res) + { + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Didn't get expected retval with querying an empty atom table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1); + ok(!res, "Unable to add atom to atom table, retval %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(!res, "Can't find previously added atom in table, retval: %lx\n", res); + ok(testAtom == Atom1, "Found wrong atom! retval: %lx\n", res); + + res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1); + ok(!res, "Unable to delete atom from table, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Able to find previously deleted atom in table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1); + ok(!res, "Unable to add atom to atom table, retval: %lx\n", res); + + Len = 0; + res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len); + ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %lx\n", res); + ok((strlenW(testAtom1) * sizeof(WCHAR)) == Len, "Got wrong length %lx\n", Len); + + res = pRtlPinAtomInAtomTable(AtomTable, Atom1); + ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(!res, "Unable to find atom in atom table, retval: %lx\n", res); + ok(testAtom == Atom1, "Wrong atom found\n"); + + res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1); + ok(res == STATUS_WAS_LOCKED, "Unable to delete atom from table, retval: %lx\n", res); + + res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom); + ok(!res, "Able to find deleted atom in table\n"); + + res = pRtlDestroyAtomTable(AtomTable); + ok(!res, "Unable to destroy atom table\n"); + } +} + +/* Test Adding integer atoms to atom table */ +static void test_NtIntAtom(void) +{ + NTSTATUS res; + RTL_ATOM_TABLE AtomTable; + RTL_ATOM testAtom; + ULONG RefCount = 0, PinCount = 0; + int i; + WCHAR Name[64]; + ULONG Len; + + AtomTable = NULL; + res = pRtlCreateAtomTable(37, &AtomTable); + ok(!res, "Unable to create atom table, %lx\n", res); + + if (!res) + { + /* According to the kernel32 functions, integer atoms are only allowd from + * 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */ + res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)0, &testAtom); + ok(res == STATUS_INVALID_PARAMETER, "Didn't get expected result from adding 0 int atom, retval: %lx\n", res); + for (i = 1; i <= 0xbfff; i++) + { + res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)i, &testAtom); + ok(!res, "Unable to add valid integer atom %i, retval: %lx\n", i, res); + } + + for (i = 1; i <= 0xbfff; i++) + { + res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)i, &testAtom); + ok(!res, "Unable to find int atom %i, retval: %lx\n", i, res); + if (!res) + { + res = pRtlPinAtomInAtomTable(AtomTable, testAtom); + ok(!res, "Unable to pin int atom %i, retval: %lx\n", i, res); + } + } + + for (i = 0xc000; i <= 0xffff; i++) + { + res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)i, &testAtom); + ok(res, "Able to illeageal integer atom %i, retval: %lx\n", i, res); + } + + res = pRtlDestroyAtomTable(AtomTable); + ok(!res, "Unable to destroy atom table, retval: %lx\n", res); + } + + AtomTable = NULL; + res = pRtlCreateAtomTable(37, &AtomTable); + ok(!res, "Unable to create atom table, %lx\n", res); + if (!res) + { + res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)123, &testAtom); + ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtomInt, &testAtom); + ok(!res, "Unable to add int atom to table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtomIntInv, &testAtom); + ok(!res, "Unable to add int atom to table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom); + ok(!res, "Unable to add int atom to table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom); + ok(!res, "Unable to re-add int atom to table, retval: %lx\n", res); + + Len = 64; + res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, Name, &Len); + ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); + ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount); + ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount); + ok(!strcmpW(testAtomOTT, Name), "Got wrong atom name\n"); + ok((strlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len); + + res = pRtlPinAtomInAtomTable(AtomTable, testAtom); + ok(!res, "Unable to pin int atom, retval: %lx\n", res); + + res = pRtlPinAtomInAtomTable(AtomTable, testAtom); + ok(!res, "Unable to pin int atom, retval: %lx\n", res); + + res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, NULL, NULL); + ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); + ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount); + ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount); + + res = pRtlDestroyAtomTable(AtomTable); + ok(!res, "Unable to destroy atom table, retval: %lx\n", res); + } +} + +/* Tests to see how the pincount and refcount actually works */ +static void test_NtRefPinAtom(void) +{ + RTL_ATOM_TABLE AtomTable; + RTL_ATOM Atom; + ULONG PinCount = 0, RefCount = 0; + NTSTATUS res; + + AtomTable = NULL; + res = pRtlCreateAtomTable(37, &AtomTable); + ok(!res, "Unable to create atom table, %lx\n", res); + + if (!res) + { + res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom); + ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom); + ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res); + + res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom); + ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res); + + res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL); + ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); + ok(PinCount == 0, "Expected pincount 0 but got %lx\n", PinCount); + ok(RefCount == 3, "Expected refcount 3 but got %lx\n", RefCount); + + res = pRtlPinAtomInAtomTable(AtomTable, Atom); + ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); + + res = pRtlPinAtomInAtomTable(AtomTable, Atom); + ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); + + res = pRtlPinAtomInAtomTable(AtomTable, Atom); + ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res); + + res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL); + ok(!res, "Unable to query atom in atom table, retval: %lx\n", res); + ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount); + ok(RefCount == 3, "Expected refcount 3 but got %lx\n", RefCount); + + res = pRtlDestroyAtomTable(AtomTable); + ok(!res, "Unable to destroy atom table, retval: %lx\n", res); + } +} + +START_TEST(atom) +{ + InitFunctionPtr(); + if (pRtlCreateAtomTable) + { + test_NtAtom(); + test_NtIntAtom(); + test_NtRefPinAtom(); + } +} diff --git a/reactos/regtests/winetests/ntdll/env.c b/reactos/regtests/winetests/ntdll/env.c new file mode 100755 index 00000000000..ec88957b267 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/env.c @@ -0,0 +1,298 @@ +/* + * Unit test suite for ntdll path functions + * + * Copyright 2003 Eric Pouech + * + * 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 + */ + +#include + +#include "ntdll_test.h" +#include "wine/unicode.h" + +static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, + LPCSTR src, DWORD srclen ); +static NTSTATUS (WINAPI *pRtlCreateEnvironment)(BOOLEAN, PWSTR*); +static NTSTATUS (WINAPI *pRtlDestroyEnvironment)(PWSTR); +static NTSTATUS (WINAPI *pRtlQueryEnvironmentVariable_U)(PWSTR, PUNICODE_STRING, PUNICODE_STRING); +static void (WINAPI *pRtlSetCurrentEnvironment)(PWSTR, PWSTR*); +static NTSTATUS (WINAPI *pRtlSetEnvironmentVariable)(PWSTR*, PUNICODE_STRING, PUNICODE_STRING); +static NTSTATUS (WINAPI *pRtlExpandEnvironmentStrings_U)(LPWSTR, PUNICODE_STRING, PUNICODE_STRING, PULONG); + +static WCHAR small_env[] = {'f','o','o','=','t','o','t','o',0, + 'f','o','=','t','i','t','i',0, + 'f','o','o','o','=','t','u','t','u',0, + 's','r','=','a','n','=','o','u','o',0, + 'g','=','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a', + 'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a',0, + '=','o','O','H','=','I','I','I',0, + 'n','u','l','=',0, + 0}; + +static void testQuery(void) +{ + struct test + { + const char *var; + int len; + NTSTATUS status; + const char *val; + }; + + static const struct test tests[] = + { + {"foo", 256, STATUS_SUCCESS, "toto"}, + {"FoO", 256, STATUS_SUCCESS, "toto"}, + {"foo=", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"foo ", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"foo", 1, STATUS_BUFFER_TOO_SMALL, "toto"}, + {"foo", 3, STATUS_BUFFER_TOO_SMALL, "toto"}, + {"foo", 4, STATUS_SUCCESS, "toto"}, + {"fooo", 256, STATUS_SUCCESS, "tutu"}, + {"f", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"g", 256, STATUS_SUCCESS, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, + {"sr=an", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"sr", 256, STATUS_SUCCESS, "an=ouo"}, + {"=oOH", 256, STATUS_SUCCESS, "III"}, + {"", 256, STATUS_VARIABLE_NOT_FOUND, NULL}, + {"nul", 256, STATUS_SUCCESS, ""}, + {NULL, 0, 0, NULL} + }; + + WCHAR bn[257]; + WCHAR bv[257]; + UNICODE_STRING name; + UNICODE_STRING value; + const struct test* test; + NTSTATUS nts; + + for (test = tests; test->var; test++) + { + name.Length = strlen(test->var) * 2; + name.MaximumLength = name.Length + 2; + name.Buffer = bn; + value.Length = 0; + value.MaximumLength = test->len * 2; + value.Buffer = bv; + bv[test->len] = '@'; + + pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->var, strlen(test->var)+1 ); + nts = pRtlQueryEnvironmentVariable_U(small_env, &name, &value); + ok( nts == test->status, "[%d]: Wrong status for '%s', expecting %lx got %lx\n", + test - tests, test->var, test->status, nts ); + if (nts == test->status) switch (nts) + { + case STATUS_SUCCESS: + pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->val, strlen(test->val)+1 ); + ok( value.Length == strlen(test->val) * sizeof(WCHAR), "Wrong length %d/%d for %s\n", + value.Length, strlen(test->val) * sizeof(WCHAR), test->var ); + ok((value.Length == strlen(test->val) * sizeof(WCHAR) && strncmpW(bv, bn, test->len) == 0) || + strcmpW(bv, bn) == 0, + "Wrong result for %s/%d\n", test->var, test->len); + ok(bv[test->len] == '@', "Writing too far away in the buffer for %s/%d\n", test->var, test->len); + break; + case STATUS_BUFFER_TOO_SMALL: + ok( value.Length == strlen(test->val) * sizeof(WCHAR), + "Wrong returned length %d/%d (too small buffer) for %s\n", + value.Length, strlen(test->val) * sizeof(WCHAR), test->var ); + break; + } + } +} + +static void testSetHelper(LPWSTR* env, const char* var, const char* val, NTSTATUS ret) +{ + WCHAR bvar[256], bval1[256], bval2[256]; + UNICODE_STRING uvar; + UNICODE_STRING uval; + NTSTATUS nts; + + uvar.Length = strlen(var) * sizeof(WCHAR); + uvar.MaximumLength = uvar.Length + sizeof(WCHAR); + uvar.Buffer = bvar; + pRtlMultiByteToUnicodeN( bvar, sizeof(bvar), NULL, var, strlen(var)+1 ); + if (val) + { + uval.Length = strlen(val) * sizeof(WCHAR); + uval.MaximumLength = uval.Length + sizeof(WCHAR); + uval.Buffer = bval1; + pRtlMultiByteToUnicodeN( bval1, sizeof(bval1), NULL, val, strlen(val)+1 ); + } + nts = pRtlSetEnvironmentVariable(env, &uvar, val ? &uval : NULL); + ok(nts == ret, "Setting var %s=%s (%lx/%lx)\n", var, val, nts, ret); + if (nts == STATUS_SUCCESS) + { + uval.Length = 0; + uval.MaximumLength = sizeof(bval2); + uval.Buffer = bval2; + nts = pRtlQueryEnvironmentVariable_U(*env, &uvar, &uval); + switch (nts) + { + case STATUS_SUCCESS: + ok(strcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n"); + break; + case STATUS_VARIABLE_NOT_FOUND: + ok(val == NULL, "Couldn't find variable, but didn't delete it. val = %s\n", val); + break; + default: + ok(0, "Wrong ret %lu for %s\n", nts, var); + break; + } + } +} + +static void testSet(void) +{ + LPWSTR env; + char tmp[16]; + int i; + + ok(pRtlCreateEnvironment(FALSE, &env) == STATUS_SUCCESS, "Creating environment\n"); + memmove(env, small_env, sizeof(small_env)); + + testSetHelper(&env, "cat", "dog", STATUS_SUCCESS); + testSetHelper(&env, "cat", "horse", STATUS_SUCCESS); + testSetHelper(&env, "cat", "zz", STATUS_SUCCESS); + testSetHelper(&env, "cat", NULL, STATUS_SUCCESS); + testSetHelper(&env, "cat", NULL, STATUS_VARIABLE_NOT_FOUND); + testSetHelper(&env, "foo", "meouw", STATUS_SUCCESS); + testSetHelper(&env, "me=too", "also", STATUS_INVALID_PARAMETER); + testSetHelper(&env, "me", "too=also", STATUS_SUCCESS); + testSetHelper(&env, "=too", "also", STATUS_SUCCESS); + testSetHelper(&env, "=", "also", STATUS_SUCCESS); + + for (i = 0; i < 128; i++) + { + sprintf(tmp, "zork%03d", i); + testSetHelper(&env, tmp, "is alive", STATUS_SUCCESS); + } + + for (i = 0; i < 128; i++) + { + sprintf(tmp, "zork%03d", i); + testSetHelper(&env, tmp, NULL, STATUS_SUCCESS); + } + testSetHelper(&env, "fOo", NULL, STATUS_SUCCESS); + + ok(pRtlDestroyEnvironment(env) == STATUS_SUCCESS, "Destroying environment\n"); +} + +static void testExpand(void) +{ + static const struct test + { + const char *src; + const char *dst; + } tests[] = + { + {"hello%foo%world", "hellototoworld"}, + {"hello%=oOH%world", "helloIIIworld"}, + {"hello%foo", "hello%foo"}, + {"hello%bar%world", "hello%bar%world"}, + /* + * {"hello%foo%world%=oOH%eeck", "hellototoworldIIIeeck"}, + * Interestingly enough, with a 8 WCHAR buffers, we get on 2k: + * helloIII + * so it seems like strings overflowing the buffer are written + * (troncated) but the write cursor is not advanced :-/ + */ + {NULL, NULL} + }; + + const struct test* test; + NTSTATUS nts; + UNICODE_STRING us_src, us_dst; + WCHAR src[256], dst[256], rst[256]; + ULONG ul; + + for (test = tests; test->src; test++) + { + pRtlMultiByteToUnicodeN(src, sizeof(src), NULL, test->src, strlen(test->src)+1); + pRtlMultiByteToUnicodeN(rst, sizeof(rst), NULL, test->dst, strlen(test->dst)+1); + + us_src.Length = strlen(test->src) * sizeof(WCHAR); + us_src.MaximumLength = us_src.Length + 2; + us_src.Buffer = src; + + us_dst.Length = 0; + us_dst.MaximumLength = 0; + us_dst.Buffer = NULL; + + nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul); + ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR), + "Wrong returned length for %s: %lu <> %u\n", + test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR)); + + us_dst.Length = 0; + us_dst.MaximumLength = sizeof(dst); + us_dst.Buffer = dst; + + nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul); + ok(nts == STATUS_SUCCESS, "Call failed (%lu)\n", nts); + ok(ul == us_dst.Length + sizeof(WCHAR), + "Wrong returned length for %s: %lu <> %u\n", + test->src, ul, us_dst.Length + sizeof(WCHAR)); + ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR), + "Wrong returned length for %s: %lu <> %u\n", + test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR)); + ok(strcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n", + test->src, test->dst); + + us_dst.Length = 0; + us_dst.MaximumLength = 8 * sizeof(WCHAR); + us_dst.Buffer = dst; + dst[8] = '-'; + nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul); + ok(nts == STATUS_BUFFER_TOO_SMALL, "Call failed (%lu)\n", nts); + ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR), + "Wrong returned length for %s (with buffer too small): %lu <> %u\n", + test->src, ul, strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR)); + ok(strncmpW(dst, rst, 8) == 0, + "Wrong result for %s (with buffer too small): expecting %s\n", + test->src, test->dst); + ok(dst[8] == '-', "Writing too far in buffer (got %c/%d)\n", dst[8], dst[8]); + } + +} + +START_TEST(env) +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + + pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN"); + pRtlCreateEnvironment = (void*)GetProcAddress(mod, "RtlCreateEnvironment"); + pRtlDestroyEnvironment = (void*)GetProcAddress(mod, "RtlDestroyEnvironment"); + pRtlQueryEnvironmentVariable_U = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable_U"); + pRtlSetCurrentEnvironment = (void*)GetProcAddress(mod, "RtlSetCurrentEnvironment"); + pRtlSetEnvironmentVariable = (void*)GetProcAddress(mod, "RtlSetEnvironmentVariable"); + pRtlExpandEnvironmentStrings_U = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings_U"); + + if (pRtlQueryEnvironmentVariable_U) + testQuery(); + if (pRtlSetEnvironmentVariable) + testSet(); + if (pRtlExpandEnvironmentStrings_U) + testExpand(); +} diff --git a/reactos/regtests/winetests/ntdll/error.c b/reactos/regtests/winetests/ntdll/error.c new file mode 100755 index 00000000000..a912d5519a8 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/error.c @@ -0,0 +1,950 @@ +/* + * Unit tests for RtlNtStatusToDosError function + * + * Copyright (c) 2002 Andriy Palamarchuk + * + * 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 + */ + +#define _WIN32_WINNT 0x0501 + +#include +#include + +#include "ntstatus.h" +#define WIN32_NO_STATUS + +#include "wine/test.h" + +#include "windows.h" + +#include "windef.h" +#include "winbase.h" +#include "rpcnterr.h" +#include "winreg.h" +#include "winternl.h" + +/* FIXME!!! this test checks only mappings, defined by MSDN: + * http://support.microsoft.com/default.aspx?scid=KB;EN-US;q113996& + * It is necessary to add other mappings and to test them up to Windows XP. + * + * Some Windows platforms don't know about all the mappings, and in such + * cases they return somewhat strange results (Win98) or a generic error + * like ERROR_MR_MID_NOT_FOUND (NT4). Our tests have to know about these to + * not fail, but we would very much prefer Wine not to return such garbage. + * To you can pass the 'strict' option to this test to force it to only check + * results against the first listed value. This test should pass in strict + * mode on the latest Windows platform (currently XP) and in Wine. + * (of course older Windows platforms will fail to pass the strict mode) + */ + +static ULONG (WINAPI *statustodoserror)(NTSTATUS Status); +static int strict; + +static int prepare_test(void) +{ + HMODULE ntdll; + int argc; + char** argv; + + ntdll = LoadLibraryA("ntdll.dll"); + statustodoserror = (void*)GetProcAddress(ntdll, "RtlNtStatusToDosError"); + if (!statustodoserror) + return 0; + + argc = winetest_get_mainargs(&argv); + strict=(argc >= 3 && strcmp(argv[2],"strict")==0); + return 1; +} + +static void cmp_call(NTSTATUS win_nt, ULONG win32, const char* message) +{ + ULONG err; + + err = statustodoserror(win_nt); + ok(err == win32, + "%s (%lx): got %ld, expected %ld\n", + message, win_nt, err, win32); +} + +static void cmp_call2(NTSTATUS win_nt, ULONG win32, const char* message) +{ + ULONG err; + + err = statustodoserror(win_nt); + ok(err == win32 || + (!strict && err == ERROR_MR_MID_NOT_FOUND), + "%s (%lx): got %ld, expected %ld (or MID_NOT_FOUND)\n", + message, win_nt, err, win32); +} + +static void cmp_call3(NTSTATUS win_nt, ULONG win32_1, ULONG win32_2, const char* message) +{ + ULONG err; + + err = statustodoserror(win_nt); + ok(err == win32_1 || (!strict && err == win32_2), + "%s (%lx): got %ld, expected %ld or %ld\n", + message, win_nt, err, win32_1, win32_2); +} + +static void cmp_call4(NTSTATUS win_nt, ULONG win32_1, ULONG win32_2, const char* message) +{ + ULONG err; + + err = statustodoserror(win_nt); + ok(err == win32_1 || + (!strict && (err == win32_2 || err == ERROR_MR_MID_NOT_FOUND)), + "%s (%lx): got %ld, expected %ld or %ld\n", + message, win_nt, err, win32_1, win32_2); +} + +#define cmp(status, error) \ + cmp_call(status, error, #status) +#define cmp2(status, error) \ + cmp_call2(status, error, #status) +#define cmp3(status, error1, error2) \ + cmp_call3(status, error1, error2, #status) +#define cmp4(status, error1, error2) \ + cmp_call4(status, error1, error2, #status) + +static void run_error_tests(void) +{ + cmp(STATUS_DATATYPE_MISALIGNMENT, ERROR_NOACCESS); + cmp(STATUS_ACCESS_VIOLATION, ERROR_NOACCESS); + cmp2(STATUS_DATATYPE_MISALIGNMENT_ERROR, ERROR_NOACCESS); + cmp(STATUS_CTL_FILE_NOT_SUPPORTED, ERROR_NOT_SUPPORTED); + cmp(STATUS_PORT_ALREADY_SET, ERROR_INVALID_PARAMETER); + cmp(STATUS_SECTION_NOT_IMAGE, ERROR_INVALID_PARAMETER); + cmp(STATUS_BAD_WORKING_SET_LIMIT, ERROR_INVALID_PARAMETER); + cmp(STATUS_WORKING_SET_LIMIT_RANGE, ERROR_INVALID_PARAMETER); + cmp(STATUS_INCOMPATIBLE_FILE_MAP, ERROR_INVALID_PARAMETER); + cmp(STATUS_PORT_DISCONNECTED, ERROR_INVALID_HANDLE); + cmp(STATUS_NOT_LOCKED, ERROR_NOT_LOCKED); + cmp(STATUS_NOT_MAPPED_VIEW, ERROR_INVALID_ADDRESS); + cmp(STATUS_UNABLE_TO_FREE_VM, ERROR_INVALID_PARAMETER); + cmp(STATUS_UNABLE_TO_DELETE_SECTION, ERROR_INVALID_PARAMETER); + cmp(STATUS_MORE_PROCESSING_REQUIRED, ERROR_MORE_DATA); + cmp(STATUS_INVALID_CID, ERROR_INVALID_PARAMETER); + cmp(STATUS_STACK_OVERFLOW, ERROR_STACK_OVERFLOW); + cmp(STATUS_BAD_INITIAL_STACK, ERROR_STACK_OVERFLOW); + cmp(STATUS_INVALID_VOLUME_LABEL, ERROR_LABEL_TOO_LONG); + cmp(STATUS_SECTION_NOT_EXTENDED, ERROR_OUTOFMEMORY); + cmp(STATUS_NOT_MAPPED_DATA, ERROR_INVALID_ADDRESS); + cmp2(STATUS_NO_LDT, ERROR_INVALID_THREAD_ID); + cmp(STATUS_INFO_LENGTH_MISMATCH, ERROR_BAD_LENGTH); + cmp(STATUS_INVALID_INFO_CLASS, ERROR_INVALID_PARAMETER); + cmp(STATUS_SUSPEND_COUNT_EXCEEDED, ERROR_SIGNAL_REFUSED); + cmp(STATUS_NOTIFY_ENUM_DIR, ERROR_NOTIFY_ENUM_DIR); + cmp(STATUS_REGISTRY_RECOVERED, ERROR_REGISTRY_RECOVERED); + cmp(STATUS_REGISTRY_IO_FAILED, ERROR_REGISTRY_IO_FAILED); + cmp(STATUS_NOT_REGISTRY_FILE, ERROR_NOT_REGISTRY_FILE); + cmp(STATUS_KEY_DELETED, ERROR_KEY_DELETED); + cmp(STATUS_NO_LOG_SPACE, ERROR_NO_LOG_SPACE); + cmp(STATUS_KEY_HAS_CHILDREN, ERROR_KEY_HAS_CHILDREN); + cmp(STATUS_CHILD_MUST_BE_VOLATILE, ERROR_CHILD_MUST_BE_VOLATILE); + cmp(STATUS_REGISTRY_CORRUPT, ERROR_BADDB); + cmp(STATUS_DLL_NOT_FOUND, ERROR_MOD_NOT_FOUND); + cmp(STATUS_DLL_INIT_FAILED, ERROR_DLL_INIT_FAILED); + cmp2(STATUS_INVALID_IMPORT_OF_NON_DLL, ERROR_INVALID_IMPORT_OF_NON_DLL); + cmp(STATUS_ORDINAL_NOT_FOUND, ERROR_INVALID_ORDINAL); + cmp(STATUS_DRIVER_ORDINAL_NOT_FOUND, ERROR_INVALID_ORDINAL); + cmp2(STATUS_DRIVER_UNABLE_TO_LOAD, ERROR_BAD_DRIVER); + cmp(STATUS_ENTRYPOINT_NOT_FOUND, ERROR_PROC_NOT_FOUND); + cmp(STATUS_DRIVER_ENTRYPOINT_NOT_FOUND, ERROR_PROC_NOT_FOUND); + cmp(STATUS_PENDING, ERROR_IO_PENDING); + cmp(STATUS_MORE_ENTRIES, ERROR_MORE_DATA); + cmp(STATUS_INTEGER_OVERFLOW, ERROR_ARITHMETIC_OVERFLOW); + cmp(STATUS_BUFFER_OVERFLOW, ERROR_MORE_DATA); + cmp(STATUS_NO_MORE_FILES, ERROR_NO_MORE_FILES); + cmp(STATUS_NO_INHERITANCE, ERROR_NO_INHERITANCE); + cmp(STATUS_NO_MORE_EAS, ERROR_NO_MORE_ITEMS); + cmp(STATUS_NO_MORE_ENTRIES, ERROR_NO_MORE_ITEMS); + cmp(STATUS_GUIDS_EXHAUSTED, ERROR_NO_MORE_ITEMS); + cmp(STATUS_AGENTS_EXHAUSTED, ERROR_NO_MORE_ITEMS); + cmp(STATUS_UNSUCCESSFUL, ERROR_GEN_FAILURE); + cmp(STATUS_TOO_MANY_LINKS, ERROR_TOO_MANY_LINKS); + cmp(STATUS_NOT_IMPLEMENTED, ERROR_INVALID_FUNCTION); + cmp(STATUS_ILLEGAL_FUNCTION, ERROR_INVALID_FUNCTION); + cmp(STATUS_IN_PAGE_ERROR, ERROR_SWAPERROR); + cmp(STATUS_PAGEFILE_QUOTA, ERROR_PAGEFILE_QUOTA); + cmp(STATUS_COMMITMENT_LIMIT, ERROR_COMMITMENT_LIMIT); + cmp(STATUS_SECTION_TOO_BIG, ERROR_NOT_ENOUGH_MEMORY); + cmp(RPC_NT_SS_IN_NULL_CONTEXT, ERROR_INVALID_HANDLE); + cmp(RPC_NT_INVALID_BINDING, ERROR_INVALID_HANDLE); + cmp(STATUS_INVALID_HANDLE, ERROR_INVALID_HANDLE); + cmp(STATUS_OBJECT_TYPE_MISMATCH, ERROR_INVALID_HANDLE); + cmp(STATUS_FILE_CLOSED, ERROR_INVALID_HANDLE); + cmp(STATUS_INVALID_PORT_HANDLE, ERROR_INVALID_HANDLE); + cmp(STATUS_HANDLE_NOT_CLOSABLE, ERROR_INVALID_HANDLE); + cmp(STATUS_NOT_COMMITTED, ERROR_INVALID_ADDRESS); + cmp(STATUS_PARTIAL_COPY, ERROR_PARTIAL_COPY); + cmp(STATUS_LPC_REPLY_LOST, ERROR_INTERNAL_ERROR); + cmp(STATUS_INVALID_PARAMETER, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_1, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_2, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_3, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_4, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_5, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_6, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_7, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_8, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_9, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_10, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_11, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_12, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PARAMETER_MIX, ERROR_INVALID_PARAMETER); + cmp(STATUS_INVALID_PAGE_PROTECTION, ERROR_INVALID_PARAMETER); + cmp(STATUS_SECTION_PROTECTION, ERROR_INVALID_PARAMETER); + cmp(STATUS_RESOURCE_DATA_NOT_FOUND, ERROR_RESOURCE_DATA_NOT_FOUND); + cmp(STATUS_RESOURCE_TYPE_NOT_FOUND, ERROR_RESOURCE_TYPE_NOT_FOUND); + cmp(STATUS_RESOURCE_NAME_NOT_FOUND, ERROR_RESOURCE_NAME_NOT_FOUND); + cmp(STATUS_RESOURCE_LANG_NOT_FOUND, ERROR_RESOURCE_LANG_NOT_FOUND); + cmp(STATUS_NO_SUCH_DEVICE, ERROR_FILE_NOT_FOUND); + cmp(STATUS_NO_SUCH_FILE, ERROR_FILE_NOT_FOUND); + cmp(STATUS_INVALID_DEVICE_REQUEST, ERROR_INVALID_FUNCTION); + cmp2(STATUS_VOLUME_NOT_UPGRADED, ERROR_INVALID_FUNCTION); + cmp(STATUS_END_OF_FILE, ERROR_HANDLE_EOF); + cmp(STATUS_FILE_FORCED_CLOSED, ERROR_HANDLE_EOF); + cmp(STATUS_WRONG_VOLUME, ERROR_WRONG_DISK); + cmp(STATUS_NO_MEDIA, ERROR_NO_MEDIA_IN_DRIVE); + cmp(STATUS_NO_MEDIA_IN_DEVICE, ERROR_NOT_READY); + cmp(STATUS_VOLUME_DISMOUNTED, ERROR_NOT_READY); + cmp(STATUS_NONEXISTENT_SECTOR, ERROR_SECTOR_NOT_FOUND); + cmp(STATUS_WORKING_SET_QUOTA, ERROR_WORKING_SET_QUOTA); + cmp(STATUS_NO_MEMORY, ERROR_NOT_ENOUGH_MEMORY); + cmp(STATUS_CONFLICTING_ADDRESSES, ERROR_INVALID_ADDRESS); + cmp(STATUS_INVALID_SYSTEM_SERVICE, ERROR_INVALID_FUNCTION); + cmp(STATUS_THREAD_IS_TERMINATING, ERROR_ACCESS_DENIED); + cmp(STATUS_PROCESS_IS_TERMINATING, ERROR_ACCESS_DENIED); + cmp(STATUS_INVALID_LOCK_SEQUENCE, ERROR_ACCESS_DENIED); + cmp(STATUS_INVALID_VIEW_SIZE, ERROR_ACCESS_DENIED); + cmp(STATUS_ALREADY_COMMITTED, ERROR_ACCESS_DENIED); + cmp(STATUS_ACCESS_DENIED, ERROR_ACCESS_DENIED); + cmp(STATUS_FILE_IS_A_DIRECTORY, ERROR_ACCESS_DENIED); + cmp(STATUS_CANNOT_DELETE, ERROR_ACCESS_DENIED); + cmp(STATUS_INVALID_COMPUTER_NAME, ERROR_INVALID_COMPUTERNAME); + cmp(STATUS_FILE_DELETED, ERROR_ACCESS_DENIED); + cmp2(STATUS_FILE_RENAMED, ERROR_ACCESS_DENIED); + cmp(STATUS_DELETE_PENDING, ERROR_ACCESS_DENIED); + cmp(STATUS_PORT_CONNECTION_REFUSED, ERROR_ACCESS_DENIED); + cmp(STATUS_NO_SUCH_PRIVILEGE, ERROR_NO_SUCH_PRIVILEGE); + cmp(STATUS_PRIVILEGE_NOT_HELD, ERROR_PRIVILEGE_NOT_HELD); + cmp(STATUS_CANNOT_IMPERSONATE, ERROR_CANNOT_IMPERSONATE); + cmp(STATUS_LOGON_FAILURE, ERROR_LOGON_FAILURE); + cmp2(STATUS_MUTUAL_AUTHENTICATION_FAILED, ERROR_MUTUAL_AUTH_FAILED); + cmp2(STATUS_TIME_DIFFERENCE_AT_DC, ERROR_TIME_SKEW); + cmp2(STATUS_PKINIT_FAILURE, ERROR_PKINIT_FAILURE); + cmp2(STATUS_SMARTCARD_SUBSYSTEM_FAILURE, ERROR_SMARTCARD_SUBSYSTEM_FAILURE); + cmp2(STATUS_DOWNGRADE_DETECTED, ERROR_DOWNGRADE_DETECTED); + cmp2(STATUS_SMARTCARD_CERT_REVOKED, SEC_E_SMARTCARD_CERT_REVOKED); + cmp2(STATUS_ISSUING_CA_UNTRUSTED, SEC_E_ISSUING_CA_UNTRUSTED); + cmp2(STATUS_REVOCATION_OFFLINE_C, SEC_E_REVOCATION_OFFLINE_C); + cmp2(STATUS_PKINIT_CLIENT_FAILURE, SEC_E_PKINIT_CLIENT_FAILURE); + cmp2(STATUS_SMARTCARD_CERT_EXPIRED, SEC_E_SMARTCARD_CERT_EXPIRED); + cmp2(STATUS_NO_KERB_KEY, SEC_E_NO_KERB_KEY); + cmp2(STATUS_CURRENT_DOMAIN_NOT_ALLOWED, ERROR_CURRENT_DOMAIN_NOT_ALLOWED); + cmp2(STATUS_SMARTCARD_WRONG_PIN, SCARD_W_WRONG_CHV); + cmp2(STATUS_SMARTCARD_CARD_BLOCKED, SCARD_W_CHV_BLOCKED); + cmp2(STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED,SCARD_W_CARD_NOT_AUTHENTICATED); + cmp2(STATUS_SMARTCARD_NO_CARD, SCARD_E_NO_SMARTCARD); + cmp2(STATUS_SMARTCARD_NO_KEY_CONTAINER, NTE_NO_KEY); + cmp2(STATUS_SMARTCARD_NO_CERTIFICATE, SCARD_E_NO_SUCH_CERTIFICATE); + cmp2(STATUS_SMARTCARD_NO_KEYSET, NTE_BAD_KEYSET); + cmp2(STATUS_SMARTCARD_IO_ERROR, SCARD_E_COMM_DATA_LOST); + cmp(STATUS_ACCOUNT_RESTRICTION, ERROR_ACCOUNT_RESTRICTION); + cmp(STATUS_INVALID_LOGON_HOURS, ERROR_INVALID_LOGON_HOURS); + cmp(STATUS_INVALID_WORKSTATION, ERROR_INVALID_WORKSTATION); + cmp(STATUS_BUFFER_TOO_SMALL, ERROR_INSUFFICIENT_BUFFER); + cmp(STATUS_UNABLE_TO_DECOMMIT_VM, ERROR_INVALID_ADDRESS); + cmp(STATUS_DISK_CORRUPT_ERROR, ERROR_DISK_CORRUPT); + cmp(STATUS_FT_MISSING_MEMBER, ERROR_IO_DEVICE); + cmp(STATUS_FT_ORPHANING, ERROR_IO_DEVICE); + cmp(STATUS_VARIABLE_NOT_FOUND, ERROR_ENVVAR_NOT_FOUND); + cmp(STATUS_OBJECT_NAME_INVALID, ERROR_INVALID_NAME); + cmp(STATUS_OBJECT_NAME_NOT_FOUND, ERROR_FILE_NOT_FOUND); + cmp(STATUS_OBJECT_NAME_COLLISION, ERROR_ALREADY_EXISTS); + cmp(STATUS_OBJECT_PATH_INVALID, ERROR_BAD_PATHNAME); + cmp(STATUS_OBJECT_PATH_NOT_FOUND, ERROR_PATH_NOT_FOUND); + cmp(STATUS_DFS_EXIT_PATH_FOUND, ERROR_PATH_NOT_FOUND); + cmp2(STATUS_DFS_UNAVAILABLE, ERROR_CONNECTION_UNAVAIL); + cmp(STATUS_OBJECT_PATH_SYNTAX_BAD, ERROR_BAD_PATHNAME); + cmp(STATUS_NAME_TOO_LONG, ERROR_FILENAME_EXCED_RANGE); + cmp(STATUS_DATA_OVERRUN, ERROR_IO_DEVICE); + cmp(STATUS_DATA_LATE_ERROR, ERROR_IO_DEVICE); + cmp(STATUS_DATA_ERROR, ERROR_CRC); + cmp(STATUS_CRC_ERROR, ERROR_CRC); + cmp(STATUS_SHARING_VIOLATION, ERROR_SHARING_VIOLATION); + cmp(STATUS_QUOTA_EXCEEDED, ERROR_NOT_ENOUGH_QUOTA); + cmp(STATUS_MUTANT_NOT_OWNED, ERROR_NOT_OWNER); + cmp(STATUS_SEMAPHORE_LIMIT_EXCEEDED, ERROR_TOO_MANY_POSTS); + cmp(STATUS_DISK_FULL, ERROR_DISK_FULL); + cmp(STATUS_LOCK_NOT_GRANTED, ERROR_LOCK_VIOLATION); + cmp(STATUS_FILE_LOCK_CONFLICT, ERROR_LOCK_VIOLATION); + cmp(STATUS_NOT_A_DIRECTORY, ERROR_DIRECTORY); + cmp2(STATUS_CANNOT_MAKE, ERROR_CANNOT_MAKE); + cmp(STATUS_UNKNOWN_REVISION, ERROR_UNKNOWN_REVISION); + cmp(STATUS_REVISION_MISMATCH, ERROR_REVISION_MISMATCH); + cmp(STATUS_INVALID_OWNER, ERROR_INVALID_OWNER); + cmp(STATUS_INVALID_PRIMARY_GROUP, ERROR_INVALID_PRIMARY_GROUP); + cmp(STATUS_NO_IMPERSONATION_TOKEN, ERROR_NO_IMPERSONATION_TOKEN); + cmp(STATUS_CANT_DISABLE_MANDATORY, ERROR_CANT_DISABLE_MANDATORY); + cmp(STATUS_NO_LOGON_SERVERS, ERROR_NO_LOGON_SERVERS); + cmp(STATUS_DOMAIN_CONTROLLER_NOT_FOUND, ERROR_DOMAIN_CONTROLLER_NOT_FOUND); + cmp(STATUS_NO_SUCH_LOGON_SESSION, ERROR_NO_SUCH_LOGON_SESSION); + cmp(STATUS_INVALID_ACCOUNT_NAME, ERROR_INVALID_ACCOUNT_NAME); + cmp(STATUS_USER_EXISTS, ERROR_USER_EXISTS); + cmp(STATUS_NO_SUCH_USER, ERROR_NO_SUCH_USER); + cmp(STATUS_GROUP_EXISTS, ERROR_GROUP_EXISTS); + cmp(STATUS_NO_SUCH_GROUP, ERROR_NO_SUCH_GROUP); + cmp(STATUS_SPECIAL_GROUP, ERROR_SPECIAL_GROUP); + cmp(STATUS_MEMBER_IN_GROUP, ERROR_MEMBER_IN_GROUP); + cmp(STATUS_MEMBER_NOT_IN_GROUP, ERROR_MEMBER_NOT_IN_GROUP); + cmp(STATUS_LAST_ADMIN, ERROR_LAST_ADMIN); + cmp(STATUS_WRONG_PASSWORD, ERROR_INVALID_PASSWORD); + cmp(STATUS_WRONG_PASSWORD_CORE, ERROR_INVALID_PASSWORD); + cmp(STATUS_ILL_FORMED_PASSWORD, ERROR_ILL_FORMED_PASSWORD); + cmp(STATUS_PASSWORD_RESTRICTION, ERROR_PASSWORD_RESTRICTION); + cmp(STATUS_PASSWORD_EXPIRED, ERROR_PASSWORD_EXPIRED); + cmp(STATUS_PASSWORD_MUST_CHANGE, ERROR_PASSWORD_MUST_CHANGE); + cmp(STATUS_ACCOUNT_DISABLED, ERROR_ACCOUNT_DISABLED); + cmp(STATUS_ACCOUNT_LOCKED_OUT, ERROR_ACCOUNT_LOCKED_OUT); + cmp(STATUS_NONE_MAPPED, ERROR_NONE_MAPPED); + cmp(STATUS_TOO_MANY_LUIDS_REQUESTED, ERROR_TOO_MANY_LUIDS_REQUESTED); + cmp(STATUS_LUIDS_EXHAUSTED, ERROR_LUIDS_EXHAUSTED); + cmp(STATUS_INVALID_SUB_AUTHORITY, ERROR_INVALID_SUB_AUTHORITY); + cmp(STATUS_INVALID_ACL, ERROR_INVALID_ACL); + cmp(STATUS_INVALID_SID, ERROR_INVALID_SID); + cmp(STATUS_INVALID_SECURITY_DESCR, ERROR_INVALID_SECURITY_DESCR); + cmp(STATUS_PROCEDURE_NOT_FOUND, ERROR_PROC_NOT_FOUND); + cmp(STATUS_BAD_INITIAL_PC, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_FILE_FOR_SECTION, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_IMAGE_FORMAT, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_IMAGE_MP_UP_MISMATCH, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_IMAGE_NOT_MZ, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_IMAGE_CHECKSUM_MISMATCH, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_IMAGE_PROTECT, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_IMAGE_LE_FORMAT, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_IMAGE_NE_FORMAT, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_INVALID_IMAGE_WIN_16, ERROR_BAD_EXE_FORMAT); + cmp2(STATUS_INVALID_IMAGE_WIN_32, ERROR_BAD_EXE_FORMAT); + cmp2(STATUS_INVALID_IMAGE_WIN_64, ERROR_BAD_EXE_FORMAT); + cmp(STATUS_NO_TOKEN, ERROR_NO_TOKEN); + cmp(STATUS_RANGE_NOT_LOCKED, ERROR_NOT_LOCKED); + cmp(STATUS_SERVER_DISABLED, ERROR_SERVER_DISABLED); + cmp(STATUS_SERVER_NOT_DISABLED, ERROR_SERVER_NOT_DISABLED); + cmp(STATUS_INVALID_ID_AUTHORITY, ERROR_INVALID_ID_AUTHORITY); + cmp(STATUS_ALLOTTED_SPACE_EXCEEDED, ERROR_ALLOTTED_SPACE_EXCEEDED); + cmp(STATUS_TOO_MANY_PAGING_FILES, ERROR_NOT_ENOUGH_MEMORY); + cmp(STATUS_INSUFFICIENT_RESOURCES, ERROR_NO_SYSTEM_RESOURCES); + cmp(STATUS_INSUFF_SERVER_RESOURCES, ERROR_NOT_ENOUGH_SERVER_MEMORY); + cmp(STATUS_FILE_INVALID, ERROR_FILE_INVALID); + cmp(STATUS_MAPPED_FILE_SIZE_ZERO, ERROR_FILE_INVALID); + cmp(STATUS_DEVICE_PAPER_EMPTY, ERROR_OUT_OF_PAPER); + cmp(STATUS_DEVICE_POWERED_OFF, ERROR_NOT_READY); + cmp(STATUS_DEVICE_OFF_LINE, ERROR_NOT_READY); + cmp(STATUS_DEVICE_DATA_ERROR, ERROR_CRC); + cmp(STATUS_DEVICE_NOT_READY, ERROR_NOT_READY); + cmp3(STATUS_DEVICE_NOT_CONNECTED, ERROR_DEVICE_NOT_CONNECTED, ERROR_NOT_READY); + cmp(STATUS_DEVICE_POWER_FAILURE, ERROR_NOT_READY); + cmp2(STATUS_NOT_FOUND, ERROR_NOT_FOUND); + cmp2(STATUS_NO_MATCH, ERROR_NO_MATCH); + cmp2(STATUS_PROPSET_NOT_FOUND, ERROR_SET_NOT_FOUND); + cmp(STATUS_DEVICE_BUSY, ERROR_BUSY); + cmp(STATUS_FREE_VM_NOT_AT_BASE, ERROR_INVALID_ADDRESS); + cmp(STATUS_MEMORY_NOT_ALLOCATED, ERROR_INVALID_ADDRESS); + cmp(STATUS_NOT_SAME_DEVICE, ERROR_NOT_SAME_DEVICE); + cmp(STATUS_NOT_SUPPORTED, ERROR_NOT_SUPPORTED); + cmp(STATUS_REMOTE_NOT_LISTENING, ERROR_REM_NOT_LIST); + cmp(STATUS_DUPLICATE_NAME, ERROR_DUP_NAME); + cmp(STATUS_BAD_NETWORK_PATH, ERROR_BAD_NETPATH); + cmp(STATUS_NETWORK_BUSY, ERROR_NETWORK_BUSY); + cmp2(STATUS_ONLY_IF_CONNECTED, ERROR_ONLY_IF_CONNECTED); + cmp(STATUS_DEVICE_DOES_NOT_EXIST, ERROR_DEV_NOT_EXIST); + cmp(STATUS_TOO_MANY_COMMANDS, ERROR_TOO_MANY_CMDS); + cmp(STATUS_ADAPTER_HARDWARE_ERROR, ERROR_ADAP_HDW_ERR); + cmp(STATUS_REDIRECTOR_NOT_STARTED, ERROR_PATH_NOT_FOUND); + cmp(STATUS_INVALID_EA_NAME, ERROR_INVALID_EA_NAME); + cmp(STATUS_EA_LIST_INCONSISTENT, ERROR_EA_LIST_INCONSISTENT); + cmp(STATUS_EA_TOO_LARGE, ERROR_EA_LIST_INCONSISTENT); + cmp(STATUS_INVALID_EA_FLAG, ERROR_EA_LIST_INCONSISTENT); + cmp2(STATUS_EAS_NOT_SUPPORTED, ERROR_EAS_NOT_SUPPORTED); + cmp(STATUS_FILE_CORRUPT_ERROR, ERROR_FILE_CORRUPT); + cmp(STATUS_EA_CORRUPT_ERROR, ERROR_FILE_CORRUPT); + cmp(STATUS_NONEXISTENT_EA_ENTRY, ERROR_FILE_CORRUPT); + cmp(STATUS_NO_EAS_ON_FILE, ERROR_FILE_CORRUPT); + cmp2(STATUS_NOT_A_REPARSE_POINT, ERROR_NOT_A_REPARSE_POINT); + cmp4(STATUS_IO_REPARSE_TAG_INVALID, ERROR_REPARSE_TAG_INVALID, ERROR_INVALID_PARAMETER); + cmp4(STATUS_IO_REPARSE_TAG_MISMATCH, ERROR_REPARSE_TAG_MISMATCH, ERROR_INVALID_PARAMETER); + cmp2(STATUS_IO_REPARSE_TAG_NOT_HANDLED, ERROR_CANT_ACCESS_FILE); + cmp2(STATUS_REPARSE_POINT_NOT_RESOLVED, ERROR_CANT_RESOLVE_FILENAME); + cmp2(STATUS_DIRECTORY_IS_A_REPARSE_POINT, ERROR_BAD_PATHNAME); + cmp2(STATUS_REPARSE_ATTRIBUTE_CONFLICT, ERROR_REPARSE_ATTRIBUTE_CONFLICT); + cmp4(STATUS_IO_REPARSE_DATA_INVALID, ERROR_INVALID_REPARSE_DATA, ERROR_INVALID_PARAMETER); + cmp2(STATUS_FILE_IS_OFFLINE, ERROR_FILE_OFFLINE); + cmp2(STATUS_REMOTE_STORAGE_NOT_ACTIVE, ERROR_REMOTE_STORAGE_NOT_ACTIVE); + cmp2(STATUS_REMOTE_STORAGE_MEDIA_ERROR, ERROR_REMOTE_STORAGE_MEDIA_ERROR); + cmp2(STATUS_NO_TRACKING_SERVICE, ERROR_NO_TRACKING_SERVICE); + cmp2(STATUS_JOURNAL_DELETE_IN_PROGRESS, ERROR_JOURNAL_DELETE_IN_PROGRESS); + cmp2(STATUS_JOURNAL_NOT_ACTIVE, ERROR_JOURNAL_NOT_ACTIVE); + cmp2(STATUS_JOURNAL_ENTRY_DELETED, ERROR_JOURNAL_ENTRY_DELETED); + cmp(STATUS_INVALID_NETWORK_RESPONSE, ERROR_BAD_NET_RESP); + cmp(STATUS_USER_SESSION_DELETED, ERROR_UNEXP_NET_ERR); + cmp(STATUS_UNEXPECTED_NETWORK_ERROR, ERROR_UNEXP_NET_ERR); + cmp(STATUS_BAD_REMOTE_ADAPTER, ERROR_BAD_REM_ADAP); + cmp(STATUS_PRINT_QUEUE_FULL, ERROR_PRINTQ_FULL); + cmp(STATUS_NO_SPOOL_SPACE, ERROR_NO_SPOOL_SPACE); + cmp(STATUS_PRINT_CANCELLED, ERROR_PRINT_CANCELLED); + cmp(STATUS_NETWORK_NAME_DELETED, ERROR_NETNAME_DELETED); + cmp(STATUS_NETWORK_ACCESS_DENIED, ERROR_NETWORK_ACCESS_DENIED); + cmp(STATUS_BAD_DEVICE_TYPE, ERROR_BAD_DEV_TYPE); + cmp(STATUS_BAD_NETWORK_NAME, ERROR_BAD_NET_NAME); + cmp(STATUS_TOO_MANY_NAMES, ERROR_TOO_MANY_NAMES); + cmp(STATUS_TOO_MANY_GUIDS_REQUESTED, ERROR_TOO_MANY_NAMES); + cmp(STATUS_TOO_MANY_ADDRESSES, ERROR_TOO_MANY_NAMES); + cmp(STATUS_TOO_MANY_NODES, ERROR_TOO_MANY_NAMES); + cmp(STATUS_TOO_MANY_SESSIONS, ERROR_TOO_MANY_SESS); + cmp(STATUS_SHARING_PAUSED, ERROR_SHARING_PAUSED); + cmp(STATUS_REQUEST_NOT_ACCEPTED, ERROR_REQ_NOT_ACCEP); + cmp(STATUS_REDIRECTOR_PAUSED, ERROR_REDIR_PAUSED); + cmp(STATUS_NET_WRITE_FAULT, ERROR_NET_WRITE_FAULT); + cmp(STATUS_VIRTUAL_CIRCUIT_CLOSED, ERROR_VC_DISCONNECTED); + cmp(STATUS_INVALID_PIPE_STATE, ERROR_BAD_PIPE); + cmp(STATUS_INVALID_READ_MODE, ERROR_BAD_PIPE); + cmp(STATUS_PIPE_CLOSING, ERROR_NO_DATA); + cmp(STATUS_PIPE_EMPTY, ERROR_NO_DATA); + cmp(STATUS_PIPE_CONNECTED, ERROR_PIPE_CONNECTED); + cmp(STATUS_PIPE_DISCONNECTED, ERROR_PIPE_NOT_CONNECTED); + cmp(STATUS_PIPE_LISTENING, ERROR_PIPE_LISTENING); + cmp(STATUS_PIPE_NOT_AVAILABLE, ERROR_PIPE_BUSY); + cmp(STATUS_INSTANCE_NOT_AVAILABLE, ERROR_PIPE_BUSY); + cmp(STATUS_PIPE_BUSY, ERROR_PIPE_BUSY); + cmp(STATUS_PIPE_BROKEN, ERROR_BROKEN_PIPE); + cmp(STATUS_DIRECTORY_NOT_EMPTY, ERROR_DIR_NOT_EMPTY); + cmp(STATUS_TOO_MANY_OPENED_FILES, ERROR_TOO_MANY_OPEN_FILES); + cmp(STATUS_IO_TIMEOUT, ERROR_SEM_TIMEOUT); + cmp(STATUS_CANCELLED, ERROR_OPERATION_ABORTED); + cmp(STATUS_UNRECOGNIZED_MEDIA, ERROR_UNRECOGNIZED_MEDIA); + cmp(STATUS_INVALID_LEVEL, ERROR_INVALID_LEVEL); + cmp(STATUS_UNRECOGNIZED_VOLUME, ERROR_UNRECOGNIZED_VOLUME); + cmp(STATUS_MEDIA_WRITE_PROTECTED, ERROR_WRITE_PROTECT); + cmp(STATUS_TOO_LATE, ERROR_WRITE_PROTECT); + cmp(STATUS_SUCCESS, NO_ERROR); + cmp(STATUS_FULLSCREEN_MODE, ERROR_FULLSCREEN_MODE); + cmp(STATUS_END_OF_MEDIA, ERROR_END_OF_MEDIA); + cmp(STATUS_EOM_OVERFLOW, ERROR_EOM_OVERFLOW); + cmp(STATUS_BEGINNING_OF_MEDIA, ERROR_BEGINNING_OF_MEDIA); + cmp(STATUS_MEDIA_CHANGED, ERROR_MEDIA_CHANGED); + cmp(STATUS_BUS_RESET, ERROR_BUS_RESET); + cmp(STATUS_FILEMARK_DETECTED, ERROR_FILEMARK_DETECTED); + cmp(STATUS_SETMARK_DETECTED, ERROR_SETMARK_DETECTED); + cmp(STATUS_NO_DATA_DETECTED, ERROR_NO_DATA_DETECTED); + cmp(STATUS_PARTITION_FAILURE, ERROR_PARTITION_FAILURE); + cmp(STATUS_INVALID_BLOCK_LENGTH, ERROR_INVALID_BLOCK_LENGTH); + cmp(STATUS_DEVICE_NOT_PARTITIONED, ERROR_DEVICE_NOT_PARTITIONED); + cmp(STATUS_UNABLE_TO_LOCK_MEDIA, ERROR_UNABLE_TO_LOCK_MEDIA); + cmp(STATUS_UNABLE_TO_UNLOAD_MEDIA, ERROR_UNABLE_TO_UNLOAD_MEDIA); + cmp(STATUS_UNMAPPABLE_CHARACTER, ERROR_NO_UNICODE_TRANSLATION); + cmp(STATUS_NOT_ALL_ASSIGNED, ERROR_NOT_ALL_ASSIGNED); + cmp(STATUS_SOME_NOT_MAPPED, ERROR_SOME_NOT_MAPPED); + cmp(STATUS_NO_QUOTAS_FOR_ACCOUNT, ERROR_NO_QUOTAS_FOR_ACCOUNT); + cmp(STATUS_LOCAL_USER_SESSION_KEY, ERROR_LOCAL_USER_SESSION_KEY); + cmp(STATUS_NULL_LM_PASSWORD, ERROR_NULL_LM_PASSWORD); + cmp(STATUS_BAD_INHERITANCE_ACL, ERROR_BAD_INHERITANCE_ACL); + cmp(STATUS_INVALID_GROUP_ATTRIBUTES, ERROR_INVALID_GROUP_ATTRIBUTES); + cmp(STATUS_BAD_IMPERSONATION_LEVEL, ERROR_BAD_IMPERSONATION_LEVEL); + cmp(STATUS_CANT_OPEN_ANONYMOUS, ERROR_CANT_OPEN_ANONYMOUS); + cmp(STATUS_BAD_VALIDATION_CLASS, ERROR_BAD_VALIDATION_CLASS); + cmp(STATUS_BAD_TOKEN_TYPE, ERROR_BAD_TOKEN_TYPE); + cmp2(STATUS_BAD_MASTER_BOOT_RECORD, ERROR_INVALID_PARAMETER); + cmp(STATUS_NO_SECURITY_ON_OBJECT, ERROR_NO_SECURITY_ON_OBJECT); + cmp(STATUS_CANT_ACCESS_DOMAIN_INFO, ERROR_CANT_ACCESS_DOMAIN_INFO); + cmp(STATUS_INVALID_SERVER_STATE, ERROR_INVALID_SERVER_STATE); + cmp(STATUS_INVALID_DOMAIN_STATE, ERROR_INVALID_DOMAIN_STATE); + cmp(STATUS_INVALID_DOMAIN_ROLE, ERROR_INVALID_DOMAIN_ROLE); + cmp(STATUS_NO_SUCH_DOMAIN, ERROR_NO_SUCH_DOMAIN); + cmp(STATUS_DOMAIN_EXISTS, ERROR_DOMAIN_EXISTS); + cmp(STATUS_DOMAIN_LIMIT_EXCEEDED, ERROR_DOMAIN_LIMIT_EXCEEDED); + cmp2(STATUS_OPLOCK_NOT_GRANTED, ERROR_OPLOCK_NOT_GRANTED); + cmp2(STATUS_INVALID_OPLOCK_PROTOCOL, ERROR_INVALID_OPLOCK_PROTOCOL); + cmp(STATUS_INTERNAL_DB_CORRUPTION, ERROR_INTERNAL_DB_CORRUPTION); + cmp(STATUS_INTERNAL_ERROR, ERROR_INTERNAL_ERROR); + cmp(STATUS_GENERIC_NOT_MAPPED, ERROR_GENERIC_NOT_MAPPED); + cmp(STATUS_BAD_DESCRIPTOR_FORMAT, ERROR_BAD_DESCRIPTOR_FORMAT); + cmp(STATUS_NOT_LOGON_PROCESS, ERROR_NOT_LOGON_PROCESS); + cmp(STATUS_LOGON_SESSION_EXISTS, ERROR_LOGON_SESSION_EXISTS); + cmp(STATUS_NO_SUCH_PACKAGE, ERROR_NO_SUCH_PACKAGE); + cmp(STATUS_BAD_LOGON_SESSION_STATE, ERROR_BAD_LOGON_SESSION_STATE); + cmp(STATUS_LOGON_SESSION_COLLISION, ERROR_LOGON_SESSION_COLLISION); + cmp(STATUS_INVALID_LOGON_TYPE, ERROR_INVALID_LOGON_TYPE); + cmp(STATUS_RXACT_INVALID_STATE, ERROR_RXACT_INVALID_STATE); + cmp(STATUS_RXACT_COMMIT_FAILURE, ERROR_RXACT_COMMIT_FAILURE); + cmp(STATUS_SPECIAL_ACCOUNT, ERROR_SPECIAL_ACCOUNT); + cmp(STATUS_SPECIAL_USER, ERROR_SPECIAL_USER); + cmp(STATUS_MEMBERS_PRIMARY_GROUP, ERROR_MEMBERS_PRIMARY_GROUP); + cmp(STATUS_TOKEN_ALREADY_IN_USE, ERROR_TOKEN_ALREADY_IN_USE); + cmp(STATUS_NO_SUCH_ALIAS, ERROR_NO_SUCH_ALIAS); + cmp(STATUS_MEMBER_NOT_IN_ALIAS, ERROR_MEMBER_NOT_IN_ALIAS); + cmp(STATUS_MEMBER_IN_ALIAS, ERROR_MEMBER_IN_ALIAS); + cmp(STATUS_ALIAS_EXISTS, ERROR_ALIAS_EXISTS); + cmp(STATUS_LOGON_NOT_GRANTED, ERROR_LOGON_NOT_GRANTED); + cmp(STATUS_TOO_MANY_SECRETS, ERROR_TOO_MANY_SECRETS); + cmp(STATUS_SECRET_TOO_LONG, ERROR_SECRET_TOO_LONG); + cmp(STATUS_INTERNAL_DB_ERROR, ERROR_INTERNAL_DB_ERROR); + cmp(STATUS_TOO_MANY_CONTEXT_IDS, ERROR_TOO_MANY_CONTEXT_IDS); + cmp(STATUS_LOGON_TYPE_NOT_GRANTED, ERROR_LOGON_TYPE_NOT_GRANTED); + cmp(STATUS_NT_CROSS_ENCRYPTION_REQUIRED, ERROR_NT_CROSS_ENCRYPTION_REQUIRED); + cmp(STATUS_NO_SUCH_MEMBER, ERROR_NO_SUCH_MEMBER); + cmp(STATUS_INVALID_MEMBER, ERROR_INVALID_MEMBER); + cmp(STATUS_TOO_MANY_SIDS, ERROR_TOO_MANY_SIDS); + cmp(STATUS_LM_CROSS_ENCRYPTION_REQUIRED, ERROR_LM_CROSS_ENCRYPTION_REQUIRED); + cmp(STATUS_MESSAGE_NOT_FOUND, ERROR_MR_MID_NOT_FOUND); + cmp(STATUS_LOCAL_DISCONNECT, ERROR_NETNAME_DELETED); + cmp(STATUS_REMOTE_DISCONNECT, ERROR_NETNAME_DELETED); + cmp(STATUS_REMOTE_RESOURCES, ERROR_REM_NOT_LIST); + cmp(STATUS_LINK_FAILED, ERROR_UNEXP_NET_ERR); + cmp(STATUS_LINK_TIMEOUT, ERROR_UNEXP_NET_ERR); + cmp(STATUS_INVALID_CONNECTION, ERROR_UNEXP_NET_ERR); + cmp(STATUS_INVALID_ADDRESS, ERROR_UNEXP_NET_ERR); + cmp(STATUS_IO_DEVICE_ERROR, ERROR_IO_DEVICE); + cmp(STATUS_DEVICE_PROTOCOL_ERROR, ERROR_IO_DEVICE); + cmp(STATUS_DRIVER_INTERNAL_ERROR, ERROR_IO_DEVICE); + cmp(STATUS_INVALID_DEVICE_STATE, ERROR_BAD_COMMAND); + cmp(STATUS_DEVICE_CONFIGURATION_ERROR, ERROR_INVALID_PARAMETER); + cmp2(STATUS_SOURCE_ELEMENT_EMPTY, ERROR_SOURCE_ELEMENT_EMPTY); + cmp2(STATUS_DESTINATION_ELEMENT_FULL, ERROR_DESTINATION_ELEMENT_FULL); + cmp2(STATUS_ILLEGAL_ELEMENT_ADDRESS, ERROR_ILLEGAL_ELEMENT_ADDRESS); + cmp2(STATUS_MAGAZINE_NOT_PRESENT, ERROR_MAGAZINE_NOT_PRESENT); + cmp2(STATUS_REINITIALIZATION_NEEDED, ERROR_DEVICE_REINITIALIZATION_NEEDED); + cmp2(STATUS_DEVICE_REQUIRES_CLEANING, ERROR_DEVICE_REQUIRES_CLEANING); + cmp2(STATUS_DEVICE_DOOR_OPEN, ERROR_DEVICE_DOOR_OPEN); + cmp2(STATUS_TRANSPORT_FULL, ERROR_TRANSPORT_FULL); + cmp2(STATUS_CLEANER_CARTRIDGE_INSTALLED, ERROR_CLEANER_CARTRIDGE_INSTALLED); + cmp2(STATUS_REG_NAT_CONSUMPTION, ERROR_REG_NAT_CONSUMPTION); + cmp4(STATUS_ENCRYPTION_FAILED, ERROR_ACCESS_DENIED, ERROR_ENCRYPTION_FAILED); + cmp4(STATUS_DECRYPTION_FAILED, ERROR_ACCESS_DENIED, ERROR_DECRYPTION_FAILED); + cmp4(STATUS_NO_RECOVERY_POLICY, ERROR_ACCESS_DENIED, ERROR_NO_RECOVERY_POLICY); + cmp4(STATUS_NO_EFS, ERROR_ACCESS_DENIED, ERROR_NO_EFS); + cmp4(STATUS_WRONG_EFS, ERROR_ACCESS_DENIED, ERROR_WRONG_EFS); + cmp4(STATUS_NO_USER_KEYS, ERROR_ACCESS_DENIED, ERROR_NO_USER_KEYS); + cmp2(STATUS_FILE_NOT_ENCRYPTED, ERROR_FILE_NOT_ENCRYPTED); + cmp2(STATUS_NOT_EXPORT_FORMAT, ERROR_NOT_EXPORT_FORMAT); + cmp2(STATUS_FILE_ENCRYPTED, ERROR_FILE_ENCRYPTED); + cmp2(STATUS_EFS_ALG_BLOB_TOO_BIG, ERROR_EFS_ALG_BLOB_TOO_BIG); + cmp(STATUS_INVALID_USER_BUFFER, ERROR_INVALID_USER_BUFFER); + cmp(STATUS_SERIAL_NO_DEVICE_INITED, ERROR_SERIAL_NO_DEVICE); + cmp(STATUS_SHARED_IRQ_BUSY, ERROR_IRQ_BUSY); + cmp(STATUS_SERIAL_MORE_WRITES, ERROR_MORE_WRITES); + cmp(STATUS_SERIAL_COUNTER_TIMEOUT, ERROR_COUNTER_TIMEOUT); + cmp(STATUS_FLOPPY_ID_MARK_NOT_FOUND, ERROR_FLOPPY_ID_MARK_NOT_FOUND); + cmp(STATUS_FLOPPY_WRONG_CYLINDER, ERROR_FLOPPY_WRONG_CYLINDER); + cmp(STATUS_FLOPPY_UNKNOWN_ERROR, ERROR_FLOPPY_UNKNOWN_ERROR); + cmp(STATUS_FLOPPY_BAD_REGISTERS, ERROR_FLOPPY_BAD_REGISTERS); + cmp(STATUS_DISK_RECALIBRATE_FAILED, ERROR_DISK_RECALIBRATE_FAILED); + cmp(STATUS_DISK_OPERATION_FAILED, ERROR_DISK_OPERATION_FAILED); + cmp(STATUS_DISK_RESET_FAILED, ERROR_DISK_RESET_FAILED); + cmp(STATUS_EVENTLOG_FILE_CORRUPT, ERROR_EVENTLOG_FILE_CORRUPT); + cmp(STATUS_EVENTLOG_CANT_START, ERROR_EVENTLOG_CANT_START); + cmp(STATUS_NETLOGON_NOT_STARTED, ERROR_NETLOGON_NOT_STARTED); + cmp(STATUS_ACCOUNT_EXPIRED, ERROR_ACCOUNT_EXPIRED); + cmp(STATUS_NETWORK_CREDENTIAL_CONFLICT, ERROR_SESSION_CREDENTIAL_CONFLICT); + cmp(STATUS_REMOTE_SESSION_LIMIT, ERROR_REMOTE_SESSION_LIMIT_EXCEEDED); + cmp(STATUS_INVALID_BUFFER_SIZE, ERROR_INVALID_USER_BUFFER); + cmp(STATUS_INVALID_ADDRESS_COMPONENT, ERROR_INVALID_NETNAME); + cmp(STATUS_INVALID_ADDRESS_WILDCARD, ERROR_INVALID_NETNAME); + cmp(STATUS_ADDRESS_ALREADY_EXISTS, ERROR_DUP_NAME); + cmp(STATUS_ADDRESS_CLOSED, ERROR_NETNAME_DELETED); + cmp(STATUS_CONNECTION_DISCONNECTED, ERROR_NETNAME_DELETED); + cmp(STATUS_CONNECTION_RESET, ERROR_NETNAME_DELETED); + cmp(STATUS_TRANSACTION_ABORTED, ERROR_UNEXP_NET_ERR); + cmp(STATUS_TRANSACTION_TIMED_OUT, ERROR_UNEXP_NET_ERR); + cmp(STATUS_TRANSACTION_NO_RELEASE, ERROR_UNEXP_NET_ERR); + cmp(STATUS_TRANSACTION_NO_MATCH, ERROR_UNEXP_NET_ERR); + cmp(STATUS_TRANSACTION_RESPONDED, ERROR_UNEXP_NET_ERR); + cmp(STATUS_TRANSACTION_INVALID_ID, ERROR_UNEXP_NET_ERR); + cmp(STATUS_TRANSACTION_INVALID_TYPE, ERROR_UNEXP_NET_ERR); + cmp(STATUS_NOT_SERVER_SESSION, ERROR_NOT_SUPPORTED); + cmp(STATUS_NOT_CLIENT_SESSION, ERROR_NOT_SUPPORTED); + cmp(STATUS_USER_MAPPED_FILE, ERROR_USER_MAPPED_FILE); + cmp(STATUS_PLUGPLAY_NO_DEVICE, ERROR_SERVICE_DISABLED); + cmp2(STATUS_WMI_GUID_NOT_FOUND, ERROR_WMI_GUID_NOT_FOUND); + cmp2(STATUS_WMI_INSTANCE_NOT_FOUND, ERROR_WMI_INSTANCE_NOT_FOUND); + cmp2(STATUS_WMI_ITEMID_NOT_FOUND, ERROR_WMI_ITEMID_NOT_FOUND); + cmp2(STATUS_WMI_TRY_AGAIN, ERROR_WMI_TRY_AGAIN); + cmp2(STATUS_WMI_READ_ONLY, ERROR_WMI_READ_ONLY); + cmp2(STATUS_WMI_SET_FAILURE, ERROR_WMI_SET_FAILURE); + cmp2(STATUS_WMI_NOT_SUPPORTED, ERROR_NOT_SUPPORTED); + cmp2(STATUS_WMI_GUID_DISCONNECTED, ERROR_WMI_GUID_DISCONNECTED); + cmp2(STATUS_WMI_ALREADY_DISABLED, ERROR_WMI_ALREADY_DISABLED); + cmp2(STATUS_WMI_ALREADY_ENABLED, ERROR_WMI_ALREADY_ENABLED); + cmp2(STATUS_COPY_PROTECTION_FAILURE, STG_E_STATUS_COPY_PROTECTION_FAILURE); + cmp2(STATUS_CSS_AUTHENTICATION_FAILURE, STG_E_CSS_AUTHENTICATION_FAILURE); + cmp2(STATUS_CSS_KEY_NOT_PRESENT, STG_E_CSS_KEY_NOT_PRESENT); + cmp2(STATUS_CSS_KEY_NOT_ESTABLISHED, STG_E_CSS_KEY_NOT_ESTABLISHED); + cmp2(STATUS_CSS_SCRAMBLED_SECTOR, STG_E_CSS_SCRAMBLED_SECTOR); + cmp2(STATUS_CSS_REGION_MISMATCH, STG_E_CSS_REGION_MISMATCH); + cmp2(STATUS_CSS_RESETS_EXHAUSTED, STG_E_RESETS_EXHAUSTED); + cmp(RPC_NT_SERVER_UNAVAILABLE, RPC_S_SERVER_UNAVAILABLE); + cmp(RPC_NT_INVALID_STRING_BINDING, RPC_S_INVALID_STRING_BINDING); + cmp(RPC_NT_WRONG_KIND_OF_BINDING, RPC_S_WRONG_KIND_OF_BINDING); + cmp(RPC_NT_PROTSEQ_NOT_SUPPORTED, RPC_S_PROTSEQ_NOT_SUPPORTED); + cmp(RPC_NT_INVALID_RPC_PROTSEQ, RPC_S_INVALID_RPC_PROTSEQ); + cmp(RPC_NT_INVALID_STRING_UUID, RPC_S_INVALID_STRING_UUID); + cmp(RPC_NT_INVALID_ENDPOINT_FORMAT, RPC_S_INVALID_ENDPOINT_FORMAT); + cmp(RPC_NT_INVALID_NET_ADDR, RPC_S_INVALID_NET_ADDR); + cmp(RPC_NT_NO_ENDPOINT_FOUND, RPC_S_NO_ENDPOINT_FOUND); + cmp(RPC_NT_INVALID_TIMEOUT, RPC_S_INVALID_TIMEOUT); + cmp(RPC_NT_OBJECT_NOT_FOUND, RPC_S_OBJECT_NOT_FOUND); + cmp(RPC_NT_ALREADY_REGISTERED, RPC_S_ALREADY_REGISTERED); + cmp(RPC_NT_TYPE_ALREADY_REGISTERED, RPC_S_TYPE_ALREADY_REGISTERED); + cmp(RPC_NT_ALREADY_LISTENING, RPC_S_ALREADY_LISTENING); + cmp(RPC_NT_NO_PROTSEQS_REGISTERED, RPC_S_NO_PROTSEQS_REGISTERED); + cmp(RPC_NT_NOT_LISTENING, RPC_S_NOT_LISTENING); + cmp(RPC_NT_UNKNOWN_MGR_TYPE, RPC_S_UNKNOWN_MGR_TYPE); + cmp(RPC_NT_UNKNOWN_IF, RPC_S_UNKNOWN_IF); + cmp(RPC_NT_NO_BINDINGS, RPC_S_NO_BINDINGS); + cmp(RPC_NT_NO_MORE_BINDINGS, RPC_S_NO_MORE_BINDINGS); + cmp(RPC_NT_NO_PROTSEQS, RPC_S_NO_PROTSEQS); + cmp(RPC_NT_CANT_CREATE_ENDPOINT, RPC_S_CANT_CREATE_ENDPOINT); + cmp(RPC_NT_OUT_OF_RESOURCES, RPC_S_OUT_OF_RESOURCES); + cmp(RPC_NT_SERVER_TOO_BUSY, RPC_S_SERVER_TOO_BUSY); + cmp(RPC_NT_INVALID_NETWORK_OPTIONS, RPC_S_INVALID_NETWORK_OPTIONS); + cmp(RPC_NT_NO_CALL_ACTIVE, RPC_S_NO_CALL_ACTIVE); + cmp(RPC_NT_CALL_FAILED, RPC_S_CALL_FAILED); + cmp(RPC_NT_CALL_FAILED_DNE, RPC_S_CALL_FAILED_DNE); + cmp(RPC_NT_PROTOCOL_ERROR, RPC_S_PROTOCOL_ERROR); + cmp(RPC_NT_UNSUPPORTED_TRANS_SYN, RPC_S_UNSUPPORTED_TRANS_SYN); + cmp(RPC_NT_UNSUPPORTED_TYPE, RPC_S_UNSUPPORTED_TYPE); + cmp(RPC_NT_INVALID_TAG, RPC_S_INVALID_TAG); + cmp(RPC_NT_INVALID_BOUND, RPC_S_INVALID_BOUND); + cmp(RPC_NT_NO_ENTRY_NAME, RPC_S_NO_ENTRY_NAME); + cmp(RPC_NT_INVALID_NAME_SYNTAX, RPC_S_INVALID_NAME_SYNTAX); + cmp(RPC_NT_UNSUPPORTED_NAME_SYNTAX, RPC_S_UNSUPPORTED_NAME_SYNTAX); + cmp(RPC_NT_UUID_NO_ADDRESS, RPC_S_UUID_NO_ADDRESS); + cmp(RPC_NT_DUPLICATE_ENDPOINT, RPC_S_DUPLICATE_ENDPOINT); + cmp(RPC_NT_UNKNOWN_AUTHN_TYPE, RPC_S_UNKNOWN_AUTHN_TYPE); + cmp(RPC_NT_MAX_CALLS_TOO_SMALL, RPC_S_MAX_CALLS_TOO_SMALL); + cmp(RPC_NT_STRING_TOO_LONG, RPC_S_STRING_TOO_LONG); + cmp(RPC_NT_PROTSEQ_NOT_FOUND, RPC_S_PROTSEQ_NOT_FOUND); + cmp(RPC_NT_PROCNUM_OUT_OF_RANGE, RPC_S_PROCNUM_OUT_OF_RANGE); + cmp(RPC_NT_BINDING_HAS_NO_AUTH, RPC_S_BINDING_HAS_NO_AUTH); + cmp(RPC_NT_UNKNOWN_AUTHN_SERVICE, RPC_S_UNKNOWN_AUTHN_SERVICE); + cmp(RPC_NT_UNKNOWN_AUTHN_LEVEL, RPC_S_UNKNOWN_AUTHN_LEVEL); + cmp(RPC_NT_INVALID_AUTH_IDENTITY, RPC_S_INVALID_AUTH_IDENTITY); + cmp(RPC_NT_UNKNOWN_AUTHZ_SERVICE, RPC_S_UNKNOWN_AUTHZ_SERVICE); + cmp(EPT_NT_INVALID_ENTRY, EPT_S_INVALID_ENTRY); + cmp(EPT_NT_CANT_PERFORM_OP, EPT_S_CANT_PERFORM_OP); + cmp(EPT_NT_NOT_REGISTERED, EPT_S_NOT_REGISTERED); + cmp(RPC_NT_NOTHING_TO_EXPORT, RPC_S_NOTHING_TO_EXPORT); + cmp(RPC_NT_INCOMPLETE_NAME, RPC_S_INCOMPLETE_NAME); + cmp(RPC_NT_INVALID_VERS_OPTION, RPC_S_INVALID_VERS_OPTION); + cmp(RPC_NT_NO_MORE_MEMBERS, RPC_S_NO_MORE_MEMBERS); + cmp(RPC_NT_NOT_ALL_OBJS_UNEXPORTED, RPC_S_NOT_ALL_OBJS_UNEXPORTED); + cmp(RPC_NT_INTERFACE_NOT_FOUND, RPC_S_INTERFACE_NOT_FOUND); + cmp(RPC_NT_ENTRY_ALREADY_EXISTS, RPC_S_ENTRY_ALREADY_EXISTS); + cmp(RPC_NT_ENTRY_NOT_FOUND, RPC_S_ENTRY_NOT_FOUND); + cmp(RPC_NT_NAME_SERVICE_UNAVAILABLE, RPC_S_NAME_SERVICE_UNAVAILABLE); + cmp(RPC_NT_INVALID_NAF_ID, RPC_S_INVALID_NAF_ID); + cmp(RPC_NT_CANNOT_SUPPORT, RPC_S_CANNOT_SUPPORT); + cmp(RPC_NT_NO_CONTEXT_AVAILABLE, RPC_S_NO_CONTEXT_AVAILABLE); + cmp(RPC_NT_INTERNAL_ERROR, RPC_S_INTERNAL_ERROR); + cmp(RPC_NT_ZERO_DIVIDE, RPC_S_ZERO_DIVIDE); + cmp(RPC_NT_ADDRESS_ERROR, RPC_S_ADDRESS_ERROR); + cmp(RPC_NT_FP_DIV_ZERO, RPC_S_FP_DIV_ZERO); + cmp(RPC_NT_FP_UNDERFLOW, RPC_S_FP_UNDERFLOW); + cmp(RPC_NT_FP_OVERFLOW, RPC_S_FP_OVERFLOW); + cmp(RPC_NT_NO_MORE_ENTRIES, RPC_X_NO_MORE_ENTRIES); + cmp(RPC_NT_SS_CHAR_TRANS_OPEN_FAIL, RPC_X_SS_CHAR_TRANS_OPEN_FAIL); + cmp(RPC_NT_SS_CHAR_TRANS_SHORT_FILE, RPC_X_SS_CHAR_TRANS_SHORT_FILE); + cmp(RPC_NT_SS_CONTEXT_MISMATCH, ERROR_INVALID_HANDLE); + cmp(RPC_NT_SS_CONTEXT_DAMAGED, RPC_X_SS_CONTEXT_DAMAGED); + cmp(RPC_NT_SS_HANDLES_MISMATCH, RPC_X_SS_HANDLES_MISMATCH); + cmp(RPC_NT_SS_CANNOT_GET_CALL_HANDLE, RPC_X_SS_CANNOT_GET_CALL_HANDLE); + cmp(RPC_NT_NULL_REF_POINTER, RPC_X_NULL_REF_POINTER); + cmp(RPC_NT_ENUM_VALUE_OUT_OF_RANGE, RPC_X_ENUM_VALUE_OUT_OF_RANGE); + cmp(RPC_NT_BYTE_COUNT_TOO_SMALL, RPC_X_BYTE_COUNT_TOO_SMALL); + cmp(RPC_NT_BAD_STUB_DATA, RPC_X_BAD_STUB_DATA); + cmp(RPC_NT_INVALID_OBJECT, RPC_S_INVALID_OBJECT); + cmp(STATUS_NO_TRUST_LSA_SECRET, ERROR_NO_TRUST_LSA_SECRET); + cmp(STATUS_NO_TRUST_SAM_ACCOUNT, ERROR_NO_TRUST_SAM_ACCOUNT); + cmp(STATUS_TRUSTED_DOMAIN_FAILURE, ERROR_TRUSTED_DOMAIN_FAILURE); + cmp(STATUS_TRUSTED_RELATIONSHIP_FAILURE, ERROR_TRUSTED_RELATIONSHIP_FAILURE); + cmp(STATUS_TRUST_FAILURE, ERROR_TRUST_FAILURE); + cmp(RPC_NT_CALL_IN_PROGRESS, RPC_S_CALL_IN_PROGRESS); + cmp(STATUS_LOG_FILE_FULL, ERROR_LOG_FILE_FULL); + cmp(STATUS_EVENTLOG_FILE_CHANGED, ERROR_EVENTLOG_FILE_CHANGED); + cmp(STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT, ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT); + cmp(STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT, ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT); + cmp(STATUS_NOLOGON_SERVER_TRUST_ACCOUNT, ERROR_NOLOGON_SERVER_TRUST_ACCOUNT); + cmp(STATUS_DOMAIN_TRUST_INCONSISTENT, ERROR_DOMAIN_TRUST_INCONSISTENT); + cmp(STATUS_NO_USER_SESSION_KEY, ERROR_NO_USER_SESSION_KEY); + cmp(STATUS_POSSIBLE_DEADLOCK, ERROR_POSSIBLE_DEADLOCK); + cmp(STATUS_IMAGE_ALREADY_LOADED, ERROR_SERVICE_ALREADY_RUNNING); + cmp(RPC_NT_GROUP_MEMBER_NOT_FOUND, RPC_S_GROUP_MEMBER_NOT_FOUND); + cmp(RPC_NT_NO_INTERFACES, RPC_S_NO_INTERFACES); + cmp(RPC_NT_CALL_CANCELLED, RPC_S_CALL_CANCELLED); + cmp(RPC_NT_BINDING_INCOMPLETE, RPC_S_BINDING_INCOMPLETE); + cmp(RPC_NT_COMM_FAILURE, RPC_S_COMM_FAILURE); + cmp(RPC_NT_UNSUPPORTED_AUTHN_LEVEL, RPC_S_UNSUPPORTED_AUTHN_LEVEL); + cmp(RPC_NT_NO_PRINC_NAME, RPC_S_NO_PRINC_NAME); + cmp(RPC_NT_NOT_RPC_ERROR, RPC_S_NOT_RPC_ERROR); + cmp(RPC_NT_UUID_LOCAL_ONLY, RPC_S_UUID_LOCAL_ONLY); + cmp(RPC_NT_SEC_PKG_ERROR, RPC_S_SEC_PKG_ERROR); + cmp(RPC_NT_NOT_CANCELLED, RPC_S_NOT_CANCELLED); + cmp(RPC_NT_INVALID_ES_ACTION, RPC_X_INVALID_ES_ACTION); + cmp(RPC_NT_WRONG_ES_VERSION, RPC_X_WRONG_ES_VERSION); + cmp(RPC_NT_WRONG_STUB_VERSION, RPC_X_WRONG_STUB_VERSION); + cmp(RPC_NT_INVALID_PIPE_OBJECT, RPC_X_INVALID_PIPE_OBJECT); + cmp(RPC_NT_INVALID_PIPE_OPERATION, RPC_X_INVALID_PIPE_OPERATION); + cmp(RPC_NT_WRONG_PIPE_VERSION, RPC_X_WRONG_PIPE_VERSION); + cmp(EPT_NT_CANT_CREATE, EPT_S_CANT_CREATE); + cmp(RPC_NT_SEND_INCOMPLETE, RPC_S_SEND_INCOMPLETE); + cmp2(RPC_NT_INVALID_ASYNC_HANDLE, RPC_S_INVALID_ASYNC_HANDLE); + cmp2(RPC_NT_INVALID_ASYNC_CALL, RPC_S_INVALID_ASYNC_CALL); + cmp2(RPC_NT_PIPE_CLOSED, RPC_X_PIPE_CLOSED); + cmp2(RPC_NT_PIPE_EMPTY, RPC_X_PIPE_EMPTY); + cmp2(RPC_NT_PIPE_DISCIPLINE_ERROR, RPC_X_PIPE_DISCIPLINE_ERROR); + cmp(STATUS_NO_BROWSER_SERVERS_FOUND, ERROR_NO_BROWSER_SERVERS_FOUND); + cmp(STATUS_MAPPED_ALIGNMENT, ERROR_MAPPED_ALIGNMENT); + cmp(STATUS_CONNECTION_IN_USE, ERROR_DEVICE_IN_USE); + cmp(STATUS_VERIFY_REQUIRED, ERROR_MEDIA_CHANGED); + cmp(STATUS_ALREADY_DISCONNECTED, ERROR_ACTIVE_CONNECTIONS); + cmp(STATUS_CONNECTION_REFUSED, ERROR_CONNECTION_REFUSED); + cmp(STATUS_GRACEFUL_DISCONNECT, ERROR_GRACEFUL_DISCONNECT); + cmp(STATUS_ADDRESS_ALREADY_ASSOCIATED, ERROR_ADDRESS_ALREADY_ASSOCIATED); + cmp(STATUS_ADDRESS_NOT_ASSOCIATED, ERROR_ADDRESS_NOT_ASSOCIATED); + cmp(STATUS_CONNECTION_INVALID, ERROR_CONNECTION_INVALID); + cmp(STATUS_CONNECTION_ACTIVE, ERROR_CONNECTION_ACTIVE); + cmp(STATUS_NETWORK_UNREACHABLE, ERROR_NETWORK_UNREACHABLE); + cmp(STATUS_HOST_UNREACHABLE, ERROR_HOST_UNREACHABLE); + cmp2(STATUS_HOST_DOWN, ERROR_HOST_DOWN); + cmp(STATUS_PROTOCOL_UNREACHABLE, ERROR_PROTOCOL_UNREACHABLE); + cmp(STATUS_PORT_UNREACHABLE, ERROR_PORT_UNREACHABLE); + cmp(STATUS_REQUEST_ABORTED, ERROR_REQUEST_ABORTED); + cmp(STATUS_CONNECTION_ABORTED, ERROR_CONNECTION_ABORTED); + cmp(STATUS_CONNECTION_COUNT_LIMIT, ERROR_CONNECTION_COUNT_LIMIT); + cmp(STATUS_PATH_NOT_COVERED, ERROR_HOST_UNREACHABLE); + cmp(STATUS_LOGIN_TIME_RESTRICTION, ERROR_LOGIN_TIME_RESTRICTION); + cmp(STATUS_LOGIN_WKSTA_RESTRICTION, ERROR_LOGIN_WKSTA_RESTRICTION); + cmp(STATUS_LICENSE_QUOTA_EXCEEDED, ERROR_LICENSE_QUOTA_EXCEEDED); + cmp(STATUS_RESOURCE_NOT_OWNED, ERROR_NOT_OWNER); + cmp(STATUS_DUPLICATE_OBJECTID, STATUS_DUPLICATE_OBJECTID); + cmp(STATUS_OBJECTID_EXISTS, STATUS_OBJECTID_EXISTS); + cmp2(STATUS_OBJECTID_NOT_FOUND, ERROR_FILE_NOT_FOUND); + cmp2(STATUS_MFT_TOO_FRAGMENTED, ERROR_DISK_TOO_FRAGMENTED); + cmp(SEC_E_INSUFFICIENT_MEMORY, ERROR_NO_SYSTEM_RESOURCES); + cmp(SEC_E_INVALID_HANDLE, ERROR_INVALID_HANDLE); + cmp(SEC_E_UNSUPPORTED_FUNCTION, ERROR_INVALID_FUNCTION); + cmp(SEC_E_TARGET_UNKNOWN, ERROR_BAD_NETPATH); + cmp(SEC_E_INTERNAL_ERROR, ERROR_INTERNAL_ERROR); + cmp(SEC_E_SECPKG_NOT_FOUND, ERROR_NO_SUCH_PACKAGE); + cmp(SEC_E_NOT_OWNER, ERROR_NOT_OWNER); + cmp(SEC_E_CANNOT_INSTALL, ERROR_NO_SUCH_PACKAGE); + cmp(SEC_E_INVALID_TOKEN, ERROR_INVALID_PARAMETER); + cmp(SEC_E_CANNOT_PACK, ERROR_INVALID_PARAMETER); + cmp(SEC_E_QOP_NOT_SUPPORTED, ERROR_NOT_SUPPORTED); + cmp(SEC_E_NO_IMPERSONATION, ERROR_CANNOT_IMPERSONATE); + cmp2(SEC_E_MULTIPLE_ACCOUNTS, ERROR_CANNOT_IMPERSONATE); + cmp(SEC_E_LOGON_DENIED, ERROR_LOGON_FAILURE); + cmp(SEC_E_UNKNOWN_CREDENTIALS, ERROR_INVALID_PARAMETER); + cmp2(SEC_E_INCOMPLETE_CREDENTIALS, ERROR_INVALID_PARAMETER); + cmp(SEC_E_NO_CREDENTIALS, ERROR_NO_SUCH_LOGON_SESSION); + cmp(SEC_E_MESSAGE_ALTERED, ERROR_ACCESS_DENIED); + cmp(SEC_E_OUT_OF_SEQUENCE, ERROR_ACCESS_DENIED); + cmp(SEC_E_NO_AUTHENTICATING_AUTHORITY, ERROR_NO_LOGON_SERVERS); + cmp(SEC_E_BAD_PKGID, ERROR_NO_SUCH_PACKAGE); + cmp4(SEC_E_WRONG_PRINCIPAL, ERROR_WRONG_TARGET_NAME, 1462); + cmp2(SEC_E_INCOMPLETE_MESSAGE, ERROR_INVALID_USER_BUFFER); + cmp2(SEC_E_BUFFER_TOO_SMALL, ERROR_INSUFFICIENT_BUFFER); + cmp2(SEC_E_UNTRUSTED_ROOT, ERROR_TRUST_FAILURE); + cmp2(SEC_E_ILLEGAL_MESSAGE, ERROR_INVALID_PARAMETER); + cmp2(SEC_E_CERT_UNKNOWN, ERROR_INVALID_PARAMETER); + cmp2(SEC_E_CERT_EXPIRED, ERROR_PASSWORD_EXPIRED); + cmp2(SEC_E_ENCRYPT_FAILURE, ERROR_ENCRYPTION_FAILED); + cmp2(SEC_E_DECRYPT_FAILURE, ERROR_DECRYPTION_FAILED); + cmp2(SEC_E_ALGORITHM_MISMATCH, ERROR_INVALID_FUNCTION); + cmp2(SEC_E_CONTEXT_EXPIRED, ERROR_CONTEXT_EXPIRED); + cmp2(STATUS_BAD_BINDINGS, SEC_E_BAD_BINDINGS); + cmp2(TRUST_E_CERT_SIGNATURE, ERROR_MUTUAL_AUTH_FAILED); + cmp2(CRYPT_E_REVOKED, ERROR_MUTUAL_AUTH_FAILED); + cmp2(CRYPT_E_NO_REVOCATION_CHECK, ERROR_MUTUAL_AUTH_FAILED); + cmp2(CRYPT_E_REVOCATION_OFFLINE, ERROR_MUTUAL_AUTH_FAILED); + cmp2(STATUS_SHUTDOWN_IN_PROGRESS, ERROR_SHUTDOWN_IN_PROGRESS); + cmp2(STATUS_SERVER_SHUTDOWN_IN_PROGRESS, ERROR_SERVER_SHUTDOWN_IN_PROGRESS); + cmp4(STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY, ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY, 1922); + cmp4(STATUS_DS_NO_ATTRIBUTE_OR_VALUE, ERROR_DS_NO_ATTRIBUTE_OR_VALUE, 1923); + cmp4(STATUS_DS_INVALID_ATTRIBUTE_SYNTAX, ERROR_DS_INVALID_ATTRIBUTE_SYNTAX, 1924); + cmp4(STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED, ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED, 1925); + cmp4(STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS, ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS, 1926); + cmp4(STATUS_DS_BUSY, ERROR_DS_BUSY, 1927); + cmp4(STATUS_DS_UNAVAILABLE, ERROR_DS_UNAVAILABLE, 1928); + cmp4(STATUS_DS_NO_RIDS_ALLOCATED, ERROR_DS_NO_RIDS_ALLOCATED, 1929); + cmp4(STATUS_DS_NO_MORE_RIDS, ERROR_DS_NO_MORE_RIDS, 1930); + cmp4(STATUS_DS_INCORRECT_ROLE_OWNER, ERROR_DS_INCORRECT_ROLE_OWNER, 1931); + cmp4(STATUS_DS_RIDMGR_INIT_ERROR, ERROR_DS_RIDMGR_INIT_ERROR, 1932); + cmp4(STATUS_DS_OBJ_CLASS_VIOLATION, ERROR_DS_OBJ_CLASS_VIOLATION, 1933); + cmp4(STATUS_DS_CANT_ON_NON_LEAF, ERROR_DS_CANT_ON_NON_LEAF, 1934); + cmp4(STATUS_DS_CANT_ON_RDN, ERROR_DS_CANT_ON_RDN, 1935); + cmp4(STATUS_DS_CROSS_DOM_MOVE_FAILED, ERROR_DS_CROSS_DOM_MOVE_ERROR, 1937); + cmp4(STATUS_DS_GC_NOT_AVAILABLE, ERROR_DS_GC_NOT_AVAILABLE, 1938); + cmp2(STATUS_DS_CANT_MOD_OBJ_CLASS, ERROR_DS_CANT_MOD_OBJ_CLASS); + cmp2(STATUS_DS_ADMIN_LIMIT_EXCEEDED, ERROR_DS_ADMIN_LIMIT_EXCEEDED); + cmp2(STATUS_DIRECTORY_SERVICE_REQUIRED, ERROR_DS_DS_REQUIRED); + cmp2(STATUS_DS_SAM_INIT_FAILURE, ERROR_DS_SAM_INIT_FAILURE); + cmp2(STATUS_DS_CANT_START, ERROR_DS_CANT_START); + cmp2(STATUS_DS_INIT_FAILURE, ERROR_DS_INIT_FAILURE); + cmp2(STATUS_SAM_INIT_FAILURE, ERROR_SAM_INIT_FAILURE); + cmp2(STATUS_DS_SENSITIVE_GROUP_VIOLATION, ERROR_DS_SENSITIVE_GROUP_VIOLATION); + cmp2(STATUS_DS_CANT_MOD_PRIMARYGROUPID, ERROR_DS_CANT_MOD_PRIMARYGROUPID); + cmp2(STATUS_DS_INVALID_GROUP_TYPE, ERROR_DS_INVALID_GROUP_TYPE); + cmp2(STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN, ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN); + cmp2(STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN, ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN); + cmp2(STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER, ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER); + cmp2(STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER, ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER); + cmp2(STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER, ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER); + cmp2(STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER, ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER); + cmp2(STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER, ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER); + cmp2(STATUS_DS_HAVE_PRIMARY_MEMBERS, ERROR_DS_HAVE_PRIMARY_MEMBERS); + cmp2(STATUS_DS_GC_REQUIRED, ERROR_DS_GC_REQUIRED); + cmp2(STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY, ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY); + cmp2(STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS, ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS); + cmp2(STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED,ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED); + cmp2(STATUS_SAM_NEED_BOOTKEY_PASSWORD, ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD); + cmp2(STATUS_SAM_NEED_BOOTKEY_FLOPPY, ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY); + cmp2(STATUS_DS_INIT_FAILURE_CONSOLE, ERROR_DS_INIT_FAILURE_CONSOLE); + cmp2(STATUS_DS_SAM_INIT_FAILURE_CONSOLE, ERROR_DS_SAM_INIT_FAILURE_CONSOLE); + cmp2(STATUS_UNFINISHED_CONTEXT_DELETED, SEC_E_UNFINISHED_CONTEXT_DELETED); + cmp2(STATUS_NO_TGT_REPLY, SEC_E_NO_TGT_REPLY); + cmp2(STATUS_NO_IP_ADDRESSES, SEC_E_NO_IP_ADDRESSES); + cmp2(STATUS_WRONG_CREDENTIAL_HANDLE, SEC_E_WRONG_CREDENTIAL_HANDLE); + cmp2(STATUS_CRYPTO_SYSTEM_INVALID, SEC_E_CRYPTO_SYSTEM_INVALID); + cmp2(STATUS_MAX_REFERRALS_EXCEEDED, SEC_E_MAX_REFERRALS_EXCEEDED); + cmp2(STATUS_MUST_BE_KDC, SEC_E_MUST_BE_KDC); + cmp2(STATUS_STRONG_CRYPTO_NOT_SUPPORTED, SEC_E_STRONG_CRYPTO_NOT_SUPPORTED); + cmp2(STATUS_TOO_MANY_PRINCIPALS, SEC_E_TOO_MANY_PRINCIPALS); + cmp2(STATUS_NO_PA_DATA, SEC_E_NO_PA_DATA); + cmp2(STATUS_PKINIT_NAME_MISMATCH, SEC_E_PKINIT_NAME_MISMATCH); + cmp2(STATUS_SMARTCARD_LOGON_REQUIRED, SEC_E_SMARTCARD_LOGON_REQUIRED); + cmp2(STATUS_KDC_INVALID_REQUEST, SEC_E_KDC_INVALID_REQUEST); + cmp2(STATUS_KDC_UNABLE_TO_REFER, SEC_E_KDC_UNABLE_TO_REFER); + cmp2(STATUS_KDC_UNKNOWN_ETYPE, SEC_E_KDC_UNKNOWN_ETYPE); + cmp2(STATUS_UNSUPPORTED_PREAUTH, SEC_E_UNSUPPORTED_PREAUTH); + cmp4(STATUS_SHARED_POLICY, ERROR_SHARED_POLICY, 1939); + cmp4(STATUS_POLICY_OBJECT_NOT_FOUND, ERROR_POLICY_OBJECT_NOT_FOUND, 1940); + cmp4(STATUS_POLICY_ONLY_IN_DS, ERROR_POLICY_ONLY_IN_DS, 1941); + cmp4(STATUS_DEVICE_REMOVED, ERROR_DEVICE_REMOVED, 617); + cmp2(STATUS_RETRY, ERROR_RETRY); + cmp2(STATUS_NOT_SUPPORTED_ON_SBS, ERROR_NOT_SUPPORTED_ON_SBS); + cmp2(STATUS_DRIVER_BLOCKED_CRITICAL, ERROR_DRIVER_BLOCKED); + cmp2(STATUS_DRIVER_BLOCKED, ERROR_DRIVER_BLOCKED); + cmp2(STATUS_PRENT4_MACHINE_ACCOUNT, ERROR_DS_MACHINE_ACCOUNT_CREATED_PRENT4); + cmp2(STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER,ERROR_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER); + cmp2(STATUS_DS_SHUTTING_DOWN, ERROR_DS_SHUTTING_DOWN); + cmp2(STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT, ERROR_ACCESS_DISABLED_BY_POLICY); + cmp2(STATUS_ACCESS_DISABLED_BY_POLICY_PATH, ERROR_ACCESS_DISABLED_BY_POLICY); + cmp2(STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER, ERROR_ACCESS_DISABLED_BY_POLICY); + cmp2(STATUS_ACCESS_DISABLED_BY_POLICY_OTHER, ERROR_ACCESS_DISABLED_BY_POLICY); + cmp2(STATUS_FAIL_CHECK, ERROR_INVALID_PARAMETER); + cmp2(STATUS_CTX_CLOSE_PENDING, ERROR_CTX_CLOSE_PENDING); + cmp2(STATUS_CTX_NO_OUTBUF, ERROR_CTX_NO_OUTBUF); + cmp2(STATUS_CTX_MODEM_INF_NOT_FOUND, ERROR_CTX_MODEM_INF_NOT_FOUND); + cmp2(STATUS_CTX_INVALID_MODEMNAME, ERROR_CTX_INVALID_MODEMNAME); + cmp2(STATUS_CTX_RESPONSE_ERROR, ERROR_CTX_MODEM_RESPONSE_ERROR); + cmp2(STATUS_CTX_MODEM_RESPONSE_TIMEOUT, ERROR_CTX_MODEM_RESPONSE_TIMEOUT); + cmp2(STATUS_CTX_MODEM_RESPONSE_NO_CARRIER, ERROR_CTX_MODEM_RESPONSE_NO_CARRIER); + cmp2(STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE, ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE); + cmp2(STATUS_CTX_MODEM_RESPONSE_BUSY, ERROR_CTX_MODEM_RESPONSE_BUSY); + cmp2(STATUS_CTX_MODEM_RESPONSE_VOICE, ERROR_CTX_MODEM_RESPONSE_VOICE); + cmp2(STATUS_CTX_TD_ERROR, ERROR_CTX_TD_ERROR); + cmp2(STATUS_CTX_WINSTATION_NAME_INVALID, ERROR_CTX_WINSTATION_NAME_INVALID); + cmp2(STATUS_CTX_WINSTATION_NOT_FOUND, ERROR_CTX_WINSTATION_NOT_FOUND); + cmp2(STATUS_CTX_WINSTATION_NAME_COLLISION, ERROR_CTX_WINSTATION_ALREADY_EXISTS); + cmp2(STATUS_CTX_WINSTATION_BUSY, ERROR_CTX_WINSTATION_BUSY); + cmp2(STATUS_CTX_GRAPHICS_INVALID, ERROR_CTX_GRAPHICS_INVALID); + cmp2(STATUS_CTX_BAD_VIDEO_MODE, ERROR_CTX_BAD_VIDEO_MODE); + cmp2(STATUS_CTX_NOT_CONSOLE, ERROR_CTX_NOT_CONSOLE); + cmp2(STATUS_CTX_CLIENT_QUERY_TIMEOUT, ERROR_CTX_CLIENT_QUERY_TIMEOUT); + cmp2(STATUS_CTX_CONSOLE_DISCONNECT, ERROR_CTX_CONSOLE_DISCONNECT); + cmp2(STATUS_CTX_CONSOLE_CONNECT, ERROR_CTX_CONSOLE_CONNECT); + cmp2(STATUS_CTX_SHADOW_DENIED, ERROR_CTX_SHADOW_DENIED); + cmp2(STATUS_CTX_SHADOW_INVALID, ERROR_CTX_SHADOW_INVALID); + cmp2(STATUS_CTX_SHADOW_DISABLED, ERROR_CTX_SHADOW_DISABLED); + cmp2(STATUS_CTX_WINSTATION_ACCESS_DENIED, ERROR_CTX_WINSTATION_ACCESS_DENIED); + cmp2(STATUS_CTX_INVALID_PD, ERROR_CTX_INVALID_PD); + cmp2(STATUS_CTX_PD_NOT_FOUND, ERROR_CTX_PD_NOT_FOUND); + cmp2(STATUS_CTX_INVALID_WD, ERROR_CTX_INVALID_WD); + cmp2(STATUS_CTX_WD_NOT_FOUND, ERROR_CTX_WD_NOT_FOUND); + cmp2(STATUS_CTX_CLIENT_LICENSE_IN_USE, ERROR_CTX_CLIENT_LICENSE_IN_USE); + cmp2(STATUS_CTX_CLIENT_LICENSE_NOT_SET, ERROR_CTX_CLIENT_LICENSE_NOT_SET); + cmp2(STATUS_CTX_LICENSE_NOT_AVAILABLE, ERROR_CTX_LICENSE_NOT_AVAILABLE); + cmp2(STATUS_CTX_LICENSE_CLIENT_INVALID, ERROR_CTX_LICENSE_CLIENT_INVALID); + cmp2(STATUS_CTX_LICENSE_EXPIRED, ERROR_CTX_LICENSE_EXPIRED); + cmp2(STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE, ERROR_CTX_SHADOW_ENDED_BY_MODE_CHANGE); + cmp2(STATUS_CTX_SHADOW_NOT_RUNNING, ERROR_CTX_SHADOW_NOT_RUNNING); + cmp2(STATUS_LICENSE_VIOLATION, ERROR_CTX_LICENSE_NOT_AVAILABLE); +#if 0 + /* FIXME - unknown STATUS values, see bug 1001 */ + cmp(STATUS_ENDPOINT_CLOSED, ERROR_DEV_NOT_EXIST); + cmp(STATUS_DISCONNECTED, ERROR_DEV_NOT_EXIST); + cmp(STATUS_NONEXISTENT_NET_NAME, ERROR_DEV_NOT_EXIST); +#endif + cmp2(STATUS_NETWORK_SESSION_EXPIRED, ERROR_NO_USER_SESSION_KEY); + cmp2(STATUS_FILES_OPEN, ERROR_OPEN_FILES); + cmp2(STATUS_SXS_SECTION_NOT_FOUND, ERROR_SXS_SECTION_NOT_FOUND); + cmp2(STATUS_SXS_CANT_GEN_ACTCTX, ERROR_SXS_CANT_GEN_ACTCTX); + cmp2(STATUS_SXS_INVALID_ACTCTXDATA_FORMAT, ERROR_SXS_INVALID_ACTCTXDATA_FORMAT); + cmp2(STATUS_SXS_ASSEMBLY_NOT_FOUND, ERROR_SXS_ASSEMBLY_NOT_FOUND); + cmp2(STATUS_SXS_MANIFEST_FORMAT_ERROR, ERROR_SXS_MANIFEST_FORMAT_ERROR); + cmp2(STATUS_SXS_MANIFEST_PARSE_ERROR, ERROR_SXS_MANIFEST_PARSE_ERROR); + cmp2(STATUS_SXS_ACTIVATION_CONTEXT_DISABLED, ERROR_SXS_ACTIVATION_CONTEXT_DISABLED); + cmp2(STATUS_SXS_KEY_NOT_FOUND, ERROR_SXS_KEY_NOT_FOUND); + cmp2(STATUS_SXS_WRONG_SECTION_TYPE, ERROR_SXS_WRONG_SECTION_TYPE); + cmp2(STATUS_SXS_THREAD_QUERIES_DISABLED, ERROR_SXS_THREAD_QUERIES_DISABLED); + cmp2(STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET, ERROR_SXS_PROCESS_DEFAULT_ALREADY_SET); + cmp2(STATUS_REDIRECTOR_STARTED, ERROR_SERVICE_ALREADY_RUNNING); + cmp2(STATUS_AUDITING_DISABLED, ERROR_AUDITING_DISABLED); + cmp2(STATUS_CLUSTER_NODE_ALREADY_UP, ERROR_CLUSTER_NODE_ALREADY_UP); + cmp2(STATUS_CLUSTER_NODE_ALREADY_DOWN, ERROR_CLUSTER_NODE_ALREADY_DOWN); + cmp2(STATUS_CLUSTER_NETWORK_ALREADY_ONLINE, ERROR_CLUSTER_NETWORK_ALREADY_ONLINE); + cmp2(STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE, ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE); + cmp2(STATUS_CLUSTER_NODE_ALREADY_MEMBER, ERROR_CLUSTER_NODE_ALREADY_MEMBER); + cmp2(STATUS_CLUSTER_INVALID_NODE, ERROR_CLUSTER_INVALID_NODE); + cmp2(STATUS_CLUSTER_NODE_EXISTS, ERROR_CLUSTER_NODE_EXISTS); + cmp2(STATUS_CLUSTER_JOIN_IN_PROGRESS, ERROR_CLUSTER_JOIN_IN_PROGRESS); + cmp2(STATUS_CLUSTER_NODE_NOT_FOUND, ERROR_CLUSTER_NODE_NOT_FOUND); + cmp2(STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND, ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND); + cmp2(STATUS_CLUSTER_NETWORK_EXISTS, ERROR_CLUSTER_NETWORK_EXISTS); + cmp2(STATUS_CLUSTER_NETWORK_NOT_FOUND, ERROR_CLUSTER_NETWORK_NOT_FOUND); + cmp2(STATUS_CLUSTER_NETINTERFACE_EXISTS, ERROR_CLUSTER_NETINTERFACE_EXISTS); + cmp2(STATUS_CLUSTER_NETINTERFACE_NOT_FOUND, ERROR_CLUSTER_NETINTERFACE_NOT_FOUND); + cmp2(STATUS_CLUSTER_INVALID_REQUEST, ERROR_CLUSTER_INVALID_REQUEST); + cmp2(STATUS_CLUSTER_INVALID_NETWORK_PROVIDER,ERROR_CLUSTER_INVALID_NETWORK_PROVIDER); + cmp2(STATUS_CLUSTER_NODE_DOWN, ERROR_CLUSTER_NODE_DOWN); + cmp2(STATUS_CLUSTER_NODE_UNREACHABLE, ERROR_CLUSTER_NODE_UNREACHABLE); + cmp2(STATUS_CLUSTER_NODE_NOT_MEMBER, ERROR_CLUSTER_NODE_NOT_MEMBER); + cmp2(STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS, ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS); + cmp2(STATUS_CLUSTER_INVALID_NETWORK, ERROR_CLUSTER_INVALID_NETWORK); + cmp2(STATUS_CLUSTER_NODE_UP, ERROR_CLUSTER_NODE_UP); + cmp2(STATUS_CLUSTER_NODE_PAUSED, ERROR_CLUSTER_NODE_PAUSED); + cmp2(STATUS_CLUSTER_NODE_NOT_PAUSED, ERROR_CLUSTER_NODE_NOT_PAUSED); + cmp2(STATUS_CLUSTER_NO_SECURITY_CONTEXT, ERROR_CLUSTER_NO_SECURITY_CONTEXT); + cmp2(STATUS_CLUSTER_NETWORK_NOT_INTERNAL, ERROR_CLUSTER_NETWORK_NOT_INTERNAL); +} + +START_TEST(error) +{ + if (prepare_test()) + run_error_tests(); +} diff --git a/reactos/regtests/winetests/ntdll/generated.c b/reactos/regtests/winetests/ntdll/generated.c new file mode 100755 index 00000000000..6ac1749d301 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/generated.c @@ -0,0 +1,2486 @@ +/* File generated automatically from tools/winapi/test.dat; do not edit! */ +/* This file can be copied, modified and distributed without restriction. */ + +/* + * Unit tests for data structure packing + */ + +#define WINVER 0x0501 +#define _WIN32_IE 0x0501 +#define _WIN32_WINNT 0x0501 + +#define WINE_NOWINSOCK + +#include "ntdll_test.h" + +#include "wine/test.h" + +/*********************************************************************** + * Compability macros + */ + +#define DWORD_PTR UINT_PTR +#define LONG_PTR INT_PTR +#define ULONG_PTR UINT_PTR + +/*********************************************************************** + * Windows API extension + */ + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus) +# define FIELD_ALIGNMENT(type, field) __alignof(((type*)0)->field) +#elif defined(__GNUC__) +# define FIELD_ALIGNMENT(type, field) __alignof__(((type*)0)->field) +#else +/* FIXME: Not sure if is possible to do without compiler extension */ +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus) +# define _TYPE_ALIGNMENT(type) __alignof(type) +#elif defined(__GNUC__) +# define _TYPE_ALIGNMENT(type) __alignof__(type) +#else +/* + * FIXME: Not sure if is possible to do without compiler extension + * (if type is not just a name that is, if so the normal) + * TYPE_ALIGNMENT can be used) + */ +#endif + +#if defined(TYPE_ALIGNMENT) && defined(_MSC_VER) && _MSC_VER >= 800 && !defined(__cplusplus) +#pragma warning(disable:4116) +#endif + +#if !defined(TYPE_ALIGNMENT) && defined(_TYPE_ALIGNMENT) +# define TYPE_ALIGNMENT _TYPE_ALIGNMENT +#endif + +/*********************************************************************** + * Test helper macros + */ + +#ifdef FIELD_ALIGNMENT +# define TEST_FIELD_ALIGNMENT(type, field, align) \ + ok(FIELD_ALIGNMENT(type, field) == align, \ + "FIELD_ALIGNMENT(" #type ", " #field ") == %d (expected " #align ")\n", \ + (int)FIELD_ALIGNMENT(type, field)) +#else +# define TEST_FIELD_ALIGNMENT(type, field, align) do { } while (0) +#endif + +#define TEST_FIELD_OFFSET(type, field, offset) \ + ok(FIELD_OFFSET(type, field) == offset, \ + "FIELD_OFFSET(" #type ", " #field ") == %ld (expected " #offset ")\n", \ + (long int)FIELD_OFFSET(type, field)) + +#ifdef _TYPE_ALIGNMENT +#define TEST__TYPE_ALIGNMENT(type, align) \ + ok(_TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)_TYPE_ALIGNMENT(type)) +#else +# define TEST__TYPE_ALIGNMENT(type, align) do { } while (0) +#endif + +#ifdef TYPE_ALIGNMENT +#define TEST_TYPE_ALIGNMENT(type, align) \ + ok(TYPE_ALIGNMENT(type) == align, "TYPE_ALIGNMENT(" #type ") == %d (expected " #align ")\n", (int)TYPE_ALIGNMENT(type)) +#else +# define TEST_TYPE_ALIGNMENT(type, align) do { } while (0) +#endif + +#define TEST_TYPE_SIZE(type, size) \ + ok(sizeof(type) == size, "sizeof(" #type ") == %d (expected " #size ")\n", ((int) sizeof(type))) + +/*********************************************************************** + * Test macros + */ + +#define TEST_FIELD(type, field_type, field_name, field_offset, field_size, field_align) \ + TEST_TYPE_SIZE(field_type, field_size); \ + TEST_FIELD_ALIGNMENT(type, field_name, field_align); \ + TEST_FIELD_OFFSET(type, field_name, field_offset); \ + +#define TEST_TYPE(type, size, align) \ + TEST_TYPE_ALIGNMENT(type, align); \ + TEST_TYPE_SIZE(type, size) + +#define TEST_TYPE_POINTER(type, size, align) \ + TEST__TYPE_ALIGNMENT(*(type)0, align); \ + TEST_TYPE_SIZE(*(type)0, size) + +#define TEST_TYPE_SIGNED(type) \ + ok((type) -1 < 0, "(" #type ") -1 < 0\n"); + +#define TEST_TYPE_UNSIGNED(type) \ + ok((type) -1 > 0, "(" #type ") -1 > 0\n"); + +static void test_pack_DWORD32(void) +{ + /* DWORD32 */ + TEST_TYPE(DWORD32, 4, 4); + TEST_TYPE_UNSIGNED(DWORD32); +} + +static void test_pack_DWORD64(void) +{ + /* DWORD64 */ + TEST_TYPE(DWORD64, 8, 8); + TEST_TYPE_UNSIGNED(DWORD64); +} + +static void test_pack_DWORD_PTR(void) +{ + /* DWORD_PTR */ + TEST_TYPE(DWORD_PTR, 4, 4); +} + +static void test_pack_HALF_PTR(void) +{ + /* HALF_PTR */ + TEST_TYPE(HALF_PTR, 2, 2); + TEST_TYPE_SIGNED(HALF_PTR); +} + +static void test_pack_INT16(void) +{ + /* INT16 */ + TEST_TYPE(INT16, 2, 2); + TEST_TYPE_SIGNED(INT16); +} + +static void test_pack_INT32(void) +{ + /* INT32 */ + TEST_TYPE(INT32, 4, 4); + TEST_TYPE_SIGNED(INT32); +} + +static void test_pack_INT64(void) +{ + /* INT64 */ + TEST_TYPE(INT64, 8, 8); + TEST_TYPE_SIGNED(INT64); +} + +static void test_pack_INT8(void) +{ + /* INT8 */ + TEST_TYPE(INT8, 1, 1); + TEST_TYPE_SIGNED(INT8); +} + +static void test_pack_INT_PTR(void) +{ + /* INT_PTR */ + TEST_TYPE(INT_PTR, 4, 4); + TEST_TYPE_SIGNED(INT_PTR); +} + +static void test_pack_LONG32(void) +{ + /* LONG32 */ + TEST_TYPE(LONG32, 4, 4); + TEST_TYPE_SIGNED(LONG32); +} + +static void test_pack_LONG64(void) +{ + /* LONG64 */ + TEST_TYPE(LONG64, 8, 8); + TEST_TYPE_SIGNED(LONG64); +} + +static void test_pack_LONG_PTR(void) +{ + /* LONG_PTR */ + TEST_TYPE(LONG_PTR, 4, 4); + TEST_TYPE_SIGNED(LONG_PTR); +} + +static void test_pack_SIZE_T(void) +{ + /* SIZE_T */ + TEST_TYPE(SIZE_T, 4, 4); +} + +static void test_pack_SSIZE_T(void) +{ + /* SSIZE_T */ + TEST_TYPE(SSIZE_T, 4, 4); +} + +static void test_pack_UHALF_PTR(void) +{ + /* UHALF_PTR */ + TEST_TYPE(UHALF_PTR, 2, 2); + TEST_TYPE_UNSIGNED(UHALF_PTR); +} + +static void test_pack_UINT16(void) +{ + /* UINT16 */ + TEST_TYPE(UINT16, 2, 2); + TEST_TYPE_UNSIGNED(UINT16); +} + +static void test_pack_UINT32(void) +{ + /* UINT32 */ + TEST_TYPE(UINT32, 4, 4); + TEST_TYPE_UNSIGNED(UINT32); +} + +static void test_pack_UINT64(void) +{ + /* UINT64 */ + TEST_TYPE(UINT64, 8, 8); + TEST_TYPE_UNSIGNED(UINT64); +} + +static void test_pack_UINT8(void) +{ + /* UINT8 */ + TEST_TYPE(UINT8, 1, 1); + TEST_TYPE_UNSIGNED(UINT8); +} + +static void test_pack_UINT_PTR(void) +{ + /* UINT_PTR */ + TEST_TYPE(UINT_PTR, 4, 4); + TEST_TYPE_UNSIGNED(UINT_PTR); +} + +static void test_pack_ULONG32(void) +{ + /* ULONG32 */ + TEST_TYPE(ULONG32, 4, 4); + TEST_TYPE_UNSIGNED(ULONG32); +} + +static void test_pack_ULONG64(void) +{ + /* ULONG64 */ + TEST_TYPE(ULONG64, 8, 8); + TEST_TYPE_UNSIGNED(ULONG64); +} + +static void test_pack_ULONG_PTR(void) +{ + /* ULONG_PTR */ + TEST_TYPE(ULONG_PTR, 4, 4); + TEST_TYPE_UNSIGNED(ULONG_PTR); +} + +static void test_pack_ACCESS_ALLOWED_ACE(void) +{ + /* ACCESS_ALLOWED_ACE (pack 4) */ + TEST_TYPE(ACCESS_ALLOWED_ACE, 12, 4); + TEST_FIELD(ACCESS_ALLOWED_ACE, ACE_HEADER, Header, 0, 4, 2); + TEST_FIELD(ACCESS_ALLOWED_ACE, DWORD, Mask, 4, 4, 4); + TEST_FIELD(ACCESS_ALLOWED_ACE, DWORD, SidStart, 8, 4, 4); +} + +static void test_pack_ACCESS_DENIED_ACE(void) +{ + /* ACCESS_DENIED_ACE (pack 4) */ + TEST_TYPE(ACCESS_DENIED_ACE, 12, 4); + TEST_FIELD(ACCESS_DENIED_ACE, ACE_HEADER, Header, 0, 4, 2); + TEST_FIELD(ACCESS_DENIED_ACE, DWORD, Mask, 4, 4, 4); + TEST_FIELD(ACCESS_DENIED_ACE, DWORD, SidStart, 8, 4, 4); +} + +static void test_pack_ACCESS_MASK(void) +{ + /* ACCESS_MASK */ + TEST_TYPE(ACCESS_MASK, 4, 4); + TEST_TYPE_UNSIGNED(ACCESS_MASK); +} + +static void test_pack_ACE_HEADER(void) +{ + /* ACE_HEADER (pack 4) */ + TEST_TYPE(ACE_HEADER, 4, 2); + TEST_FIELD(ACE_HEADER, BYTE, AceType, 0, 1, 1); + TEST_FIELD(ACE_HEADER, BYTE, AceFlags, 1, 1, 1); + TEST_FIELD(ACE_HEADER, WORD, AceSize, 2, 2, 2); +} + +static void test_pack_ACL(void) +{ + /* ACL (pack 4) */ + TEST_TYPE(ACL, 8, 2); + TEST_FIELD(ACL, BYTE, AclRevision, 0, 1, 1); + TEST_FIELD(ACL, BYTE, Sbz1, 1, 1, 1); + TEST_FIELD(ACL, WORD, AclSize, 2, 2, 2); + TEST_FIELD(ACL, WORD, AceCount, 4, 2, 2); + TEST_FIELD(ACL, WORD, Sbz2, 6, 2, 2); +} + +static void test_pack_ACL_REVISION_INFORMATION(void) +{ + /* ACL_REVISION_INFORMATION (pack 4) */ + TEST_TYPE(ACL_REVISION_INFORMATION, 4, 4); + TEST_FIELD(ACL_REVISION_INFORMATION, DWORD, AclRevision, 0, 4, 4); +} + +static void test_pack_ACL_SIZE_INFORMATION(void) +{ + /* ACL_SIZE_INFORMATION (pack 4) */ + TEST_TYPE(ACL_SIZE_INFORMATION, 12, 4); + TEST_FIELD(ACL_SIZE_INFORMATION, DWORD, AceCount, 0, 4, 4); + TEST_FIELD(ACL_SIZE_INFORMATION, DWORD, AclBytesInUse, 4, 4, 4); + TEST_FIELD(ACL_SIZE_INFORMATION, DWORD, AclBytesFree, 8, 4, 4); +} + +static void test_pack_BOOLEAN(void) +{ + /* BOOLEAN */ + TEST_TYPE(BOOLEAN, 1, 1); + TEST_TYPE_UNSIGNED(BOOLEAN); +} + +static void test_pack_CCHAR(void) +{ + /* CCHAR */ + TEST_TYPE(CCHAR, 1, 1); + TEST_TYPE_SIGNED(CCHAR); +} + +static void test_pack_CHAR(void) +{ + /* CHAR */ + TEST_TYPE(CHAR, 1, 1); + TEST_TYPE_SIGNED(CHAR); +} + +static void test_pack_DWORDLONG(void) +{ + /* DWORDLONG */ + TEST_TYPE(DWORDLONG, 8, 8); + TEST_TYPE_UNSIGNED(DWORDLONG); +} + +static void test_pack_EXCEPTION_POINTERS(void) +{ + /* EXCEPTION_POINTERS (pack 4) */ + TEST_TYPE(EXCEPTION_POINTERS, 8, 4); + TEST_FIELD(EXCEPTION_POINTERS, PEXCEPTION_RECORD, ExceptionRecord, 0, 4, 4); + TEST_FIELD(EXCEPTION_POINTERS, PCONTEXT, ContextRecord, 4, 4, 4); +} + +static void test_pack_EXCEPTION_RECORD(void) +{ + /* EXCEPTION_RECORD (pack 4) */ + TEST_TYPE(EXCEPTION_RECORD, 80, 4); + TEST_FIELD(EXCEPTION_RECORD, DWORD, ExceptionCode, 0, 4, 4); + TEST_FIELD(EXCEPTION_RECORD, DWORD, ExceptionFlags, 4, 4, 4); + TEST_FIELD(EXCEPTION_RECORD, struct _EXCEPTION_RECORD *, ExceptionRecord, 8, 4, 4); + TEST_FIELD(EXCEPTION_RECORD, PVOID, ExceptionAddress, 12, 4, 4); + TEST_FIELD(EXCEPTION_RECORD, DWORD, NumberParameters, 16, 4, 4); + TEST_FIELD(EXCEPTION_RECORD, ULONG_PTR[EXCEPTION_MAXIMUM_PARAMETERS], ExceptionInformation, 20, 60, 4); +} + +static void test_pack_EXECUTION_STATE(void) +{ + /* EXECUTION_STATE */ + TEST_TYPE(EXECUTION_STATE, 4, 4); + TEST_TYPE_UNSIGNED(EXECUTION_STATE); +} + +static void test_pack_FLOATING_SAVE_AREA(void) +{ + /* FLOATING_SAVE_AREA (pack 4) */ + TEST_TYPE(FLOATING_SAVE_AREA, 112, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, ControlWord, 0, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, StatusWord, 4, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, TagWord, 8, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, ErrorOffset, 12, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, ErrorSelector, 16, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, DataOffset, 20, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, DataSelector, 24, 4, 4); + TEST_FIELD(FLOATING_SAVE_AREA, BYTE[SIZE_OF_80387_REGISTERS], RegisterArea, 28, 80, 1); + TEST_FIELD(FLOATING_SAVE_AREA, DWORD, Cr0NpxState, 108, 4, 4); +} + +static void test_pack_FPO_DATA(void) +{ + /* FPO_DATA (pack 4) */ + TEST_TYPE(FPO_DATA, 16, 4); + TEST_FIELD(FPO_DATA, DWORD, ulOffStart, 0, 4, 4); + TEST_FIELD(FPO_DATA, DWORD, cbProcSize, 4, 4, 4); + TEST_FIELD(FPO_DATA, DWORD, cdwLocals, 8, 4, 4); + TEST_FIELD(FPO_DATA, WORD, cdwParams, 12, 2, 2); +} + +static void test_pack_GENERIC_MAPPING(void) +{ + /* GENERIC_MAPPING (pack 4) */ + TEST_TYPE(GENERIC_MAPPING, 16, 4); + TEST_FIELD(GENERIC_MAPPING, ACCESS_MASK, GenericRead, 0, 4, 4); + TEST_FIELD(GENERIC_MAPPING, ACCESS_MASK, GenericWrite, 4, 4, 4); + TEST_FIELD(GENERIC_MAPPING, ACCESS_MASK, GenericExecute, 8, 4, 4); + TEST_FIELD(GENERIC_MAPPING, ACCESS_MASK, GenericAll, 12, 4, 4); +} + +static void test_pack_HANDLE(void) +{ + /* HANDLE */ + TEST_TYPE(HANDLE, 4, 4); +} + +static void test_pack_HRESULT(void) +{ + /* HRESULT */ + TEST_TYPE(HRESULT, 4, 4); +} + +static void test_pack_IMAGE_ARCHIVE_MEMBER_HEADER(void) +{ + /* IMAGE_ARCHIVE_MEMBER_HEADER (pack 4) */ + TEST_TYPE(IMAGE_ARCHIVE_MEMBER_HEADER, 60, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[16], Name, 0, 16, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[12], Date, 16, 12, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[6], UserID, 28, 6, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[6], GroupID, 34, 6, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[8], Mode, 40, 8, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[10], Size, 48, 10, 1); + TEST_FIELD(IMAGE_ARCHIVE_MEMBER_HEADER, BYTE[2], EndHeader, 58, 2, 1); +} + +static void test_pack_IMAGE_AUX_SYMBOL(void) +{ + /* IMAGE_AUX_SYMBOL (pack 2) */ +} + +static void test_pack_IMAGE_BASE_RELOCATION(void) +{ + /* IMAGE_BASE_RELOCATION (pack 4) */ + TEST_TYPE(IMAGE_BASE_RELOCATION, 8, 4); + TEST_FIELD(IMAGE_BASE_RELOCATION, DWORD, VirtualAddress, 0, 4, 4); + TEST_FIELD(IMAGE_BASE_RELOCATION, DWORD, SizeOfBlock, 4, 4, 4); +} + +static void test_pack_IMAGE_BOUND_FORWARDER_REF(void) +{ + /* IMAGE_BOUND_FORWARDER_REF (pack 4) */ + TEST_TYPE(IMAGE_BOUND_FORWARDER_REF, 8, 4); + TEST_FIELD(IMAGE_BOUND_FORWARDER_REF, DWORD, TimeDateStamp, 0, 4, 4); + TEST_FIELD(IMAGE_BOUND_FORWARDER_REF, WORD, OffsetModuleName, 4, 2, 2); + TEST_FIELD(IMAGE_BOUND_FORWARDER_REF, WORD, Reserved, 6, 2, 2); +} + +static void test_pack_IMAGE_BOUND_IMPORT_DESCRIPTOR(void) +{ + /* IMAGE_BOUND_IMPORT_DESCRIPTOR (pack 4) */ + TEST_TYPE(IMAGE_BOUND_IMPORT_DESCRIPTOR, 8, 4); + TEST_FIELD(IMAGE_BOUND_IMPORT_DESCRIPTOR, DWORD, TimeDateStamp, 0, 4, 4); + TEST_FIELD(IMAGE_BOUND_IMPORT_DESCRIPTOR, WORD, OffsetModuleName, 4, 2, 2); + TEST_FIELD(IMAGE_BOUND_IMPORT_DESCRIPTOR, WORD, NumberOfModuleForwarderRefs, 6, 2, 2); +} + +static void test_pack_IMAGE_COFF_SYMBOLS_HEADER(void) +{ + /* IMAGE_COFF_SYMBOLS_HEADER (pack 4) */ + TEST_TYPE(IMAGE_COFF_SYMBOLS_HEADER, 32, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, NumberOfSymbols, 0, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, LvaToFirstSymbol, 4, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, NumberOfLinenumbers, 8, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, LvaToFirstLinenumber, 12, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, RvaToFirstByteOfCode, 16, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, RvaToLastByteOfCode, 20, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, RvaToFirstByteOfData, 24, 4, 4); + TEST_FIELD(IMAGE_COFF_SYMBOLS_HEADER, DWORD, RvaToLastByteOfData, 28, 4, 4); +} + +static void test_pack_IMAGE_DATA_DIRECTORY(void) +{ + /* IMAGE_DATA_DIRECTORY (pack 4) */ + TEST_TYPE(IMAGE_DATA_DIRECTORY, 8, 4); + TEST_FIELD(IMAGE_DATA_DIRECTORY, DWORD, VirtualAddress, 0, 4, 4); + TEST_FIELD(IMAGE_DATA_DIRECTORY, DWORD, Size, 4, 4, 4); +} + +static void test_pack_IMAGE_DEBUG_DIRECTORY(void) +{ + /* IMAGE_DEBUG_DIRECTORY (pack 4) */ + TEST_TYPE(IMAGE_DEBUG_DIRECTORY, 28, 4); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, DWORD, Characteristics, 0, 4, 4); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, DWORD, TimeDateStamp, 4, 4, 4); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, WORD, MajorVersion, 8, 2, 2); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, WORD, MinorVersion, 10, 2, 2); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, DWORD, Type, 12, 4, 4); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, DWORD, SizeOfData, 16, 4, 4); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, DWORD, AddressOfRawData, 20, 4, 4); + TEST_FIELD(IMAGE_DEBUG_DIRECTORY, DWORD, PointerToRawData, 24, 4, 4); +} + +static void test_pack_IMAGE_DEBUG_MISC(void) +{ + /* IMAGE_DEBUG_MISC (pack 4) */ + TEST_TYPE(IMAGE_DEBUG_MISC, 16, 4); + TEST_FIELD(IMAGE_DEBUG_MISC, DWORD, DataType, 0, 4, 4); + TEST_FIELD(IMAGE_DEBUG_MISC, DWORD, Length, 4, 4, 4); + TEST_FIELD(IMAGE_DEBUG_MISC, BYTE, Unicode, 8, 1, 1); + TEST_FIELD(IMAGE_DEBUG_MISC, BYTE[ 3 ], Reserved, 9, 3, 1); + TEST_FIELD(IMAGE_DEBUG_MISC, BYTE[ 1 ], Data, 12, 1, 1); +} + +static void test_pack_IMAGE_DOS_HEADER(void) +{ + /* IMAGE_DOS_HEADER (pack 2) */ + TEST_TYPE(IMAGE_DOS_HEADER, 64, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_magic, 0, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_cblp, 2, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_cp, 4, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_crlc, 6, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_cparhdr, 8, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_minalloc, 10, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_maxalloc, 12, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_ss, 14, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_sp, 16, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_csum, 18, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_ip, 20, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_cs, 22, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_lfarlc, 24, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_ovno, 26, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD[4], e_res, 28, 8, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_oemid, 36, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD, e_oeminfo, 38, 2, 2); + TEST_FIELD(IMAGE_DOS_HEADER, WORD[10], e_res2, 40, 20, 2); + TEST_FIELD(IMAGE_DOS_HEADER, DWORD, e_lfanew, 60, 4, 2); +} + +static void test_pack_IMAGE_EXPORT_DIRECTORY(void) +{ + /* IMAGE_EXPORT_DIRECTORY (pack 4) */ + TEST_TYPE(IMAGE_EXPORT_DIRECTORY, 40, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, Characteristics, 0, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, TimeDateStamp, 4, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, WORD, MajorVersion, 8, 2, 2); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, WORD, MinorVersion, 10, 2, 2); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, Name, 12, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, Base, 16, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, NumberOfFunctions, 20, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, NumberOfNames, 24, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, AddressOfFunctions, 28, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, AddressOfNames, 32, 4, 4); + TEST_FIELD(IMAGE_EXPORT_DIRECTORY, DWORD, AddressOfNameOrdinals, 36, 4, 4); +} + +static void test_pack_IMAGE_FILE_HEADER(void) +{ + /* IMAGE_FILE_HEADER (pack 4) */ + TEST_TYPE(IMAGE_FILE_HEADER, 20, 4); + TEST_FIELD(IMAGE_FILE_HEADER, WORD, Machine, 0, 2, 2); + TEST_FIELD(IMAGE_FILE_HEADER, WORD, NumberOfSections, 2, 2, 2); + TEST_FIELD(IMAGE_FILE_HEADER, DWORD, TimeDateStamp, 4, 4, 4); + TEST_FIELD(IMAGE_FILE_HEADER, DWORD, PointerToSymbolTable, 8, 4, 4); + TEST_FIELD(IMAGE_FILE_HEADER, DWORD, NumberOfSymbols, 12, 4, 4); + TEST_FIELD(IMAGE_FILE_HEADER, WORD, SizeOfOptionalHeader, 16, 2, 2); + TEST_FIELD(IMAGE_FILE_HEADER, WORD, Characteristics, 18, 2, 2); +} + +static void test_pack_IMAGE_FUNCTION_ENTRY(void) +{ + /* IMAGE_FUNCTION_ENTRY (pack 4) */ + TEST_TYPE(IMAGE_FUNCTION_ENTRY, 12, 4); + TEST_FIELD(IMAGE_FUNCTION_ENTRY, DWORD, StartingAddress, 0, 4, 4); + TEST_FIELD(IMAGE_FUNCTION_ENTRY, DWORD, EndingAddress, 4, 4, 4); + TEST_FIELD(IMAGE_FUNCTION_ENTRY, DWORD, EndOfPrologue, 8, 4, 4); +} + +static void test_pack_IMAGE_IMPORT_BY_NAME(void) +{ + /* IMAGE_IMPORT_BY_NAME (pack 4) */ + TEST_TYPE(IMAGE_IMPORT_BY_NAME, 4, 2); + TEST_FIELD(IMAGE_IMPORT_BY_NAME, WORD, Hint, 0, 2, 2); + TEST_FIELD(IMAGE_IMPORT_BY_NAME, BYTE[1], Name, 2, 1, 1); +} + +static void test_pack_IMAGE_IMPORT_DESCRIPTOR(void) +{ + /* IMAGE_IMPORT_DESCRIPTOR (pack 4) */ +} + +static void test_pack_IMAGE_LINENUMBER(void) +{ + /* IMAGE_LINENUMBER (pack 2) */ +} + +static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY(void) +{ + /* IMAGE_LOAD_CONFIG_DIRECTORY (pack 4) */ + TEST_TYPE(IMAGE_LOAD_CONFIG_DIRECTORY, 72, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, Size, 0, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, TimeDateStamp, 4, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, WORD, MajorVersion, 8, 2, 2); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, WORD, MinorVersion, 10, 2, 2); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, GlobalFlagsClear, 12, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, GlobalFlagsSet, 16, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, CriticalSectionDefaultTimeout, 20, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, DeCommitFreeBlockThreshold, 24, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, DeCommitTotalFreeThreshold, 28, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, PVOID, LockPrefixTable, 32, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, MaximumAllocationSize, 36, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, VirtualMemoryThreshold, 40, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, ProcessHeapFlags, 44, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, ProcessAffinityMask, 48, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, WORD, CSDVersion, 52, 2, 2); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, WORD, Reserved1, 54, 2, 2); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, PVOID, EditList, 56, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, SecurityCookie, 60, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, SEHandlerTable, 64, 4, 4); + TEST_FIELD(IMAGE_LOAD_CONFIG_DIRECTORY, DWORD, SEHandlerCount, 68, 4, 4); +} + +static void test_pack_IMAGE_NT_HEADERS(void) +{ + /* IMAGE_NT_HEADERS (pack 4) */ + TEST_TYPE(IMAGE_NT_HEADERS, 248, 4); + TEST_FIELD(IMAGE_NT_HEADERS, DWORD, Signature, 0, 4, 4); + TEST_FIELD(IMAGE_NT_HEADERS, IMAGE_FILE_HEADER, FileHeader, 4, 20, 4); + TEST_FIELD(IMAGE_NT_HEADERS, IMAGE_OPTIONAL_HEADER, OptionalHeader, 24, 224, 4); +} + +static void test_pack_IMAGE_OPTIONAL_HEADER(void) +{ + /* IMAGE_OPTIONAL_HEADER (pack 4) */ + TEST_TYPE(IMAGE_OPTIONAL_HEADER, 224, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, Magic, 0, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, BYTE, MajorLinkerVersion, 2, 1, 1); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, BYTE, MinorLinkerVersion, 3, 1, 1); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfCode, 4, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfInitializedData, 8, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfUninitializedData, 12, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, AddressOfEntryPoint, 16, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, BaseOfCode, 20, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, BaseOfData, 24, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, ImageBase, 28, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SectionAlignment, 32, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, FileAlignment, 36, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, MajorOperatingSystemVersion, 40, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, MinorOperatingSystemVersion, 42, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, MajorImageVersion, 44, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, MinorImageVersion, 46, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, MajorSubsystemVersion, 48, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, MinorSubsystemVersion, 50, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, Win32VersionValue, 52, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfImage, 56, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfHeaders, 60, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, CheckSum, 64, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, Subsystem, 68, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, WORD, DllCharacteristics, 70, 2, 2); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfStackReserve, 72, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfStackCommit, 76, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfHeapReserve, 80, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, SizeOfHeapCommit, 84, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, LoaderFlags, 88, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, DWORD, NumberOfRvaAndSizes, 92, 4, 4); + TEST_FIELD(IMAGE_OPTIONAL_HEADER, IMAGE_DATA_DIRECTORY[IMAGE_NUMBEROF_DIRECTORY_ENTRIES], DataDirectory, 96, 128, 4); +} + +static void test_pack_IMAGE_OS2_HEADER(void) +{ + /* IMAGE_OS2_HEADER (pack 2) */ + TEST_TYPE(IMAGE_OS2_HEADER, 64, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_magic, 0, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, BYTE, ne_ver, 2, 1, 1); + TEST_FIELD(IMAGE_OS2_HEADER, BYTE, ne_rev, 3, 1, 1); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_enttab, 4, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_cbenttab, 6, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, LONG, ne_crc, 8, 4, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_flags, 12, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_autodata, 14, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_heap, 16, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_stack, 18, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, DWORD, ne_csip, 20, 4, 2); + TEST_FIELD(IMAGE_OS2_HEADER, DWORD, ne_sssp, 24, 4, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_cseg, 28, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_cmod, 30, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_cbnrestab, 32, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_segtab, 34, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_rsrctab, 36, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_restab, 38, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_modtab, 40, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_imptab, 42, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, DWORD, ne_nrestab, 44, 4, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_cmovent, 48, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_align, 50, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_cres, 52, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, BYTE, ne_exetyp, 54, 1, 1); + TEST_FIELD(IMAGE_OS2_HEADER, BYTE, ne_flagsothers, 55, 1, 1); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_pretthunks, 56, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_psegrefbytes, 58, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_swaparea, 60, 2, 2); + TEST_FIELD(IMAGE_OS2_HEADER, WORD, ne_expver, 62, 2, 2); +} + +static void test_pack_IMAGE_RELOCATION(void) +{ + /* IMAGE_RELOCATION (pack 2) */ +} + +static void test_pack_IMAGE_RESOURCE_DATA_ENTRY(void) +{ + /* IMAGE_RESOURCE_DATA_ENTRY (pack 4) */ + TEST_TYPE(IMAGE_RESOURCE_DATA_ENTRY, 16, 4); + TEST_FIELD(IMAGE_RESOURCE_DATA_ENTRY, DWORD, OffsetToData, 0, 4, 4); + TEST_FIELD(IMAGE_RESOURCE_DATA_ENTRY, DWORD, Size, 4, 4, 4); + TEST_FIELD(IMAGE_RESOURCE_DATA_ENTRY, DWORD, CodePage, 8, 4, 4); + TEST_FIELD(IMAGE_RESOURCE_DATA_ENTRY, DWORD, Reserved, 12, 4, 4); +} + +static void test_pack_IMAGE_RESOURCE_DIRECTORY(void) +{ + /* IMAGE_RESOURCE_DIRECTORY (pack 4) */ + TEST_TYPE(IMAGE_RESOURCE_DIRECTORY, 16, 4); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY, DWORD, Characteristics, 0, 4, 4); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY, DWORD, TimeDateStamp, 4, 4, 4); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY, WORD, MajorVersion, 8, 2, 2); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY, WORD, MinorVersion, 10, 2, 2); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY, WORD, NumberOfNamedEntries, 12, 2, 2); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY, WORD, NumberOfIdEntries, 14, 2, 2); +} + +static void test_pack_IMAGE_RESOURCE_DIRECTORY_ENTRY(void) +{ + /* IMAGE_RESOURCE_DIRECTORY_ENTRY (pack 4) */ +} + +static void test_pack_IMAGE_RESOURCE_DIRECTORY_STRING(void) +{ + /* IMAGE_RESOURCE_DIRECTORY_STRING (pack 4) */ + TEST_TYPE(IMAGE_RESOURCE_DIRECTORY_STRING, 4, 2); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY_STRING, WORD, Length, 0, 2, 2); + TEST_FIELD(IMAGE_RESOURCE_DIRECTORY_STRING, CHAR[ 1 ], NameString, 2, 1, 1); +} + +static void test_pack_IMAGE_RESOURCE_DIR_STRING_U(void) +{ + /* IMAGE_RESOURCE_DIR_STRING_U (pack 4) */ + TEST_TYPE(IMAGE_RESOURCE_DIR_STRING_U, 4, 2); + TEST_FIELD(IMAGE_RESOURCE_DIR_STRING_U, WORD, Length, 0, 2, 2); + TEST_FIELD(IMAGE_RESOURCE_DIR_STRING_U, WCHAR[ 1 ], NameString, 2, 2, 2); +} + +static void test_pack_IMAGE_SECTION_HEADER(void) +{ + /* IMAGE_SECTION_HEADER (pack 4) */ + TEST_FIELD(IMAGE_SECTION_HEADER, BYTE[IMAGE_SIZEOF_SHORT_NAME], Name, 0, 8, 1); +} + +static void test_pack_IMAGE_SEPARATE_DEBUG_HEADER(void) +{ + /* IMAGE_SEPARATE_DEBUG_HEADER (pack 4) */ + TEST_TYPE(IMAGE_SEPARATE_DEBUG_HEADER, 48, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, WORD, Signature, 0, 2, 2); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, WORD, Flags, 2, 2, 2); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, WORD, Machine, 4, 2, 2); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, WORD, Characteristics, 6, 2, 2); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, TimeDateStamp, 8, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, CheckSum, 12, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, ImageBase, 16, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, SizeOfImage, 20, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, NumberOfSections, 24, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, ExportedNamesSize, 28, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, DebugDirectorySize, 32, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD, SectionAlignment, 36, 4, 4); + TEST_FIELD(IMAGE_SEPARATE_DEBUG_HEADER, DWORD[ 2 ], Reserved, 40, 8, 4); +} + +static void test_pack_IMAGE_SYMBOL(void) +{ + /* IMAGE_SYMBOL (pack 2) */ +} + +static void test_pack_IMAGE_THUNK_DATA(void) +{ + /* IMAGE_THUNK_DATA (pack 4) */ +} + +static void test_pack_IMAGE_TLS_DIRECTORY(void) +{ + /* IMAGE_TLS_DIRECTORY (pack 4) */ + TEST_TYPE(IMAGE_TLS_DIRECTORY, 24, 4); + TEST_FIELD(IMAGE_TLS_DIRECTORY, DWORD, StartAddressOfRawData, 0, 4, 4); + TEST_FIELD(IMAGE_TLS_DIRECTORY, DWORD, EndAddressOfRawData, 4, 4, 4); + TEST_FIELD(IMAGE_TLS_DIRECTORY, LPDWORD, AddressOfIndex, 8, 4, 4); + TEST_FIELD(IMAGE_TLS_DIRECTORY, PIMAGE_TLS_CALLBACK *, AddressOfCallBacks, 12, 4, 4); + TEST_FIELD(IMAGE_TLS_DIRECTORY, DWORD, SizeOfZeroFill, 16, 4, 4); + TEST_FIELD(IMAGE_TLS_DIRECTORY, DWORD, Characteristics, 20, 4, 4); +} + +static void test_pack_IMAGE_VXD_HEADER(void) +{ + /* IMAGE_VXD_HEADER (pack 2) */ + TEST_TYPE(IMAGE_VXD_HEADER, 196, 2); + TEST_FIELD(IMAGE_VXD_HEADER, WORD, e32_magic, 0, 2, 2); + TEST_FIELD(IMAGE_VXD_HEADER, BYTE, e32_border, 2, 1, 1); + TEST_FIELD(IMAGE_VXD_HEADER, BYTE, e32_worder, 3, 1, 1); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_level, 4, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, WORD, e32_cpu, 8, 2, 2); + TEST_FIELD(IMAGE_VXD_HEADER, WORD, e32_os, 10, 2, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_ver, 12, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_mflags, 16, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_mpages, 20, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_startobj, 24, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_eip, 28, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_stackobj, 32, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_esp, 36, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_pagesize, 40, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_lastpagesize, 44, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_fixupsize, 48, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_fixupsum, 52, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_ldrsize, 56, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_ldrsum, 60, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_objtab, 64, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_objcnt, 68, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_objmap, 72, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_itermap, 76, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_rsrctab, 80, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_rsrccnt, 84, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_restab, 88, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_enttab, 92, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_dirtab, 96, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_dircnt, 100, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_fpagetab, 104, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_frectab, 108, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_impmod, 112, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_impmodcnt, 116, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_impproc, 120, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_pagesum, 124, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_datapage, 128, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_preload, 132, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_nrestab, 136, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_cbnrestab, 140, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_nressum, 144, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_autodata, 148, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_debuginfo, 152, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_debuglen, 156, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_instpreload, 160, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_instdemand, 164, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_heapsize, 168, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, BYTE[12], e32_res3, 172, 12, 1); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_winresoff, 184, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, DWORD, e32_winreslen, 188, 4, 2); + TEST_FIELD(IMAGE_VXD_HEADER, WORD, e32_devid, 192, 2, 2); + TEST_FIELD(IMAGE_VXD_HEADER, WORD, e32_ddkver, 194, 2, 2); +} + +static void test_pack_IO_COUNTERS(void) +{ + /* IO_COUNTERS (pack 8) */ + TEST_TYPE(IO_COUNTERS, 48, 8); + TEST_FIELD(IO_COUNTERS, ULONGLONG, ReadOperationCount, 0, 8, 8); + TEST_FIELD(IO_COUNTERS, ULONGLONG, WriteOperationCount, 8, 8, 8); + TEST_FIELD(IO_COUNTERS, ULONGLONG, OtherOperationCount, 16, 8, 8); + TEST_FIELD(IO_COUNTERS, ULONGLONG, ReadTransferCount, 24, 8, 8); + TEST_FIELD(IO_COUNTERS, ULONGLONG, WriteTransferCount, 32, 8, 8); + TEST_FIELD(IO_COUNTERS, ULONGLONG, OtherTransferCount, 40, 8, 8); +} + +static void test_pack_LANGID(void) +{ + /* LANGID */ + TEST_TYPE(LANGID, 2, 2); + TEST_TYPE_UNSIGNED(LANGID); +} + +static void test_pack_LARGE_INTEGER(void) +{ + /* LARGE_INTEGER (pack 4) */ +} + +static void test_pack_LCID(void) +{ + /* LCID */ + TEST_TYPE(LCID, 4, 4); + TEST_TYPE_UNSIGNED(LCID); +} + +static void test_pack_LIST_ENTRY(void) +{ + /* LIST_ENTRY (pack 4) */ + TEST_TYPE(LIST_ENTRY, 8, 4); + TEST_FIELD(LIST_ENTRY, struct _LIST_ENTRY *, Flink, 0, 4, 4); + TEST_FIELD(LIST_ENTRY, struct _LIST_ENTRY *, Blink, 4, 4, 4); +} + +static void test_pack_LONG(void) +{ + /* LONG */ + TEST_TYPE(LONG, 4, 4); + TEST_TYPE_SIGNED(LONG); +} + +static void test_pack_LONGLONG(void) +{ + /* LONGLONG */ + TEST_TYPE(LONGLONG, 8, 8); + TEST_TYPE_SIGNED(LONGLONG); +} + +static void test_pack_LPTOP_LEVEL_EXCEPTION_FILTER(void) +{ + /* LPTOP_LEVEL_EXCEPTION_FILTER */ + TEST_TYPE(LPTOP_LEVEL_EXCEPTION_FILTER, 4, 4); +} + +static void test_pack_LUID(void) +{ + /* LUID (pack 4) */ + TEST_TYPE(LUID, 8, 4); + TEST_FIELD(LUID, DWORD, LowPart, 0, 4, 4); + TEST_FIELD(LUID, LONG, HighPart, 4, 4, 4); +} + +static void test_pack_LUID_AND_ATTRIBUTES(void) +{ + /* LUID_AND_ATTRIBUTES (pack 4) */ + TEST_TYPE(LUID_AND_ATTRIBUTES, 12, 4); + TEST_FIELD(LUID_AND_ATTRIBUTES, LUID, Luid, 0, 8, 4); + TEST_FIELD(LUID_AND_ATTRIBUTES, DWORD, Attributes, 8, 4, 4); +} + +static void test_pack_MEMORY_BASIC_INFORMATION(void) +{ + /* MEMORY_BASIC_INFORMATION (pack 4) */ + TEST_TYPE(MEMORY_BASIC_INFORMATION, 28, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, LPVOID, BaseAddress, 0, 4, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, LPVOID, AllocationBase, 4, 4, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, DWORD, AllocationProtect, 8, 4, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, DWORD, RegionSize, 12, 4, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, DWORD, State, 16, 4, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, DWORD, Protect, 20, 4, 4); + TEST_FIELD(MEMORY_BASIC_INFORMATION, DWORD, Type, 24, 4, 4); +} + +static void test_pack_MESSAGE_RESOURCE_BLOCK(void) +{ + /* MESSAGE_RESOURCE_BLOCK (pack 4) */ + TEST_TYPE(MESSAGE_RESOURCE_BLOCK, 12, 4); + TEST_FIELD(MESSAGE_RESOURCE_BLOCK, DWORD, LowId, 0, 4, 4); + TEST_FIELD(MESSAGE_RESOURCE_BLOCK, DWORD, HighId, 4, 4, 4); + TEST_FIELD(MESSAGE_RESOURCE_BLOCK, DWORD, OffsetToEntries, 8, 4, 4); +} + +static void test_pack_MESSAGE_RESOURCE_DATA(void) +{ + /* MESSAGE_RESOURCE_DATA (pack 4) */ + TEST_TYPE(MESSAGE_RESOURCE_DATA, 16, 4); + TEST_FIELD(MESSAGE_RESOURCE_DATA, DWORD, NumberOfBlocks, 0, 4, 4); + TEST_FIELD(MESSAGE_RESOURCE_DATA, MESSAGE_RESOURCE_BLOCK[ 1 ], Blocks, 4, 12, 4); +} + +static void test_pack_MESSAGE_RESOURCE_ENTRY(void) +{ + /* MESSAGE_RESOURCE_ENTRY (pack 4) */ + TEST_TYPE(MESSAGE_RESOURCE_ENTRY, 6, 2); + TEST_FIELD(MESSAGE_RESOURCE_ENTRY, WORD, Length, 0, 2, 2); + TEST_FIELD(MESSAGE_RESOURCE_ENTRY, WORD, Flags, 2, 2, 2); + TEST_FIELD(MESSAGE_RESOURCE_ENTRY, BYTE[1], Text, 4, 1, 1); +} + +static void test_pack_NT_TIB(void) +{ + /* NT_TIB (pack 4) */ + TEST_FIELD(NT_TIB, struct _EXCEPTION_REGISTRATION_RECORD *, ExceptionList, 0, 4, 4); + TEST_FIELD(NT_TIB, PVOID, StackBase, 4, 4, 4); + TEST_FIELD(NT_TIB, PVOID, StackLimit, 8, 4, 4); + TEST_FIELD(NT_TIB, PVOID, SubSystemTib, 12, 4, 4); +} + +static void test_pack_OBJECT_TYPE_LIST(void) +{ + /* OBJECT_TYPE_LIST (pack 4) */ + TEST_TYPE(OBJECT_TYPE_LIST, 8, 4); + TEST_FIELD(OBJECT_TYPE_LIST, WORD, Level, 0, 2, 2); + TEST_FIELD(OBJECT_TYPE_LIST, WORD, Sbz, 2, 2, 2); + TEST_FIELD(OBJECT_TYPE_LIST, GUID *, ObjectType, 4, 4, 4); +} + +static void test_pack_PACCESS_ALLOWED_ACE(void) +{ + /* PACCESS_ALLOWED_ACE */ + TEST_TYPE(PACCESS_ALLOWED_ACE, 4, 4); + TEST_TYPE_POINTER(PACCESS_ALLOWED_ACE, 12, 4); +} + +static void test_pack_PACCESS_DENIED_ACE(void) +{ + /* PACCESS_DENIED_ACE */ + TEST_TYPE(PACCESS_DENIED_ACE, 4, 4); + TEST_TYPE_POINTER(PACCESS_DENIED_ACE, 12, 4); +} + +static void test_pack_PACCESS_TOKEN(void) +{ + /* PACCESS_TOKEN */ + TEST_TYPE(PACCESS_TOKEN, 4, 4); +} + +static void test_pack_PACE_HEADER(void) +{ + /* PACE_HEADER */ + TEST_TYPE(PACE_HEADER, 4, 4); + TEST_TYPE_POINTER(PACE_HEADER, 4, 2); +} + +static void test_pack_PACL(void) +{ + /* PACL */ + TEST_TYPE(PACL, 4, 4); + TEST_TYPE_POINTER(PACL, 8, 2); +} + +static void test_pack_PACL_REVISION_INFORMATION(void) +{ + /* PACL_REVISION_INFORMATION */ + TEST_TYPE(PACL_REVISION_INFORMATION, 4, 4); + TEST_TYPE_POINTER(PACL_REVISION_INFORMATION, 4, 4); +} + +static void test_pack_PACL_SIZE_INFORMATION(void) +{ + /* PACL_SIZE_INFORMATION */ + TEST_TYPE(PACL_SIZE_INFORMATION, 4, 4); + TEST_TYPE_POINTER(PACL_SIZE_INFORMATION, 12, 4); +} + +static void test_pack_PCCH(void) +{ + /* PCCH */ + TEST_TYPE(PCCH, 4, 4); + TEST_TYPE_POINTER(PCCH, 1, 1); +} + +static void test_pack_PCH(void) +{ + /* PCH */ + TEST_TYPE(PCH, 4, 4); + TEST_TYPE_POINTER(PCH, 1, 1); +} + +static void test_pack_PCSTR(void) +{ + /* PCSTR */ + TEST_TYPE(PCSTR, 4, 4); + TEST_TYPE_POINTER(PCSTR, 1, 1); +} + +static void test_pack_PCTSTR(void) +{ + /* PCTSTR */ + TEST_TYPE(PCTSTR, 4, 4); +} + +static void test_pack_PCWCH(void) +{ + /* PCWCH */ + TEST_TYPE(PCWCH, 4, 4); + TEST_TYPE_POINTER(PCWCH, 2, 2); +} + +static void test_pack_PCWSTR(void) +{ + /* PCWSTR */ + TEST_TYPE(PCWSTR, 4, 4); + TEST_TYPE_POINTER(PCWSTR, 2, 2); +} + +static void test_pack_PEXCEPTION_POINTERS(void) +{ + /* PEXCEPTION_POINTERS */ + TEST_TYPE(PEXCEPTION_POINTERS, 4, 4); + TEST_TYPE_POINTER(PEXCEPTION_POINTERS, 8, 4); +} + +static void test_pack_PEXCEPTION_RECORD(void) +{ + /* PEXCEPTION_RECORD */ + TEST_TYPE(PEXCEPTION_RECORD, 4, 4); + TEST_TYPE_POINTER(PEXCEPTION_RECORD, 80, 4); +} + +static void test_pack_PFLOATING_SAVE_AREA(void) +{ + /* PFLOATING_SAVE_AREA */ + TEST_TYPE(PFLOATING_SAVE_AREA, 4, 4); + TEST_TYPE_POINTER(PFLOATING_SAVE_AREA, 112, 4); +} + +static void test_pack_PFPO_DATA(void) +{ + /* PFPO_DATA */ + TEST_TYPE(PFPO_DATA, 4, 4); + TEST_TYPE_POINTER(PFPO_DATA, 16, 4); +} + +static void test_pack_PGENERIC_MAPPING(void) +{ + /* PGENERIC_MAPPING */ + TEST_TYPE(PGENERIC_MAPPING, 4, 4); + TEST_TYPE_POINTER(PGENERIC_MAPPING, 16, 4); +} + +static void test_pack_PHANDLE(void) +{ + /* PHANDLE */ + TEST_TYPE(PHANDLE, 4, 4); + TEST_TYPE_POINTER(PHANDLE, 4, 4); +} + +static void test_pack_PIMAGE_ARCHIVE_MEMBER_HEADER(void) +{ + /* PIMAGE_ARCHIVE_MEMBER_HEADER */ + TEST_TYPE(PIMAGE_ARCHIVE_MEMBER_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_ARCHIVE_MEMBER_HEADER, 60, 1); +} + +static void test_pack_PIMAGE_AUX_SYMBOL(void) +{ + /* PIMAGE_AUX_SYMBOL */ + TEST_TYPE(PIMAGE_AUX_SYMBOL, 4, 4); +} + +static void test_pack_PIMAGE_BASE_RELOCATION(void) +{ + /* PIMAGE_BASE_RELOCATION */ + TEST_TYPE(PIMAGE_BASE_RELOCATION, 4, 4); + TEST_TYPE_POINTER(PIMAGE_BASE_RELOCATION, 8, 4); +} + +static void test_pack_PIMAGE_BOUND_FORWARDER_REF(void) +{ + /* PIMAGE_BOUND_FORWARDER_REF */ + TEST_TYPE(PIMAGE_BOUND_FORWARDER_REF, 4, 4); + TEST_TYPE_POINTER(PIMAGE_BOUND_FORWARDER_REF, 8, 4); +} + +static void test_pack_PIMAGE_BOUND_IMPORT_DESCRIPTOR(void) +{ + /* PIMAGE_BOUND_IMPORT_DESCRIPTOR */ + TEST_TYPE(PIMAGE_BOUND_IMPORT_DESCRIPTOR, 4, 4); + TEST_TYPE_POINTER(PIMAGE_BOUND_IMPORT_DESCRIPTOR, 8, 4); +} + +static void test_pack_PIMAGE_COFF_SYMBOLS_HEADER(void) +{ + /* PIMAGE_COFF_SYMBOLS_HEADER */ + TEST_TYPE(PIMAGE_COFF_SYMBOLS_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_COFF_SYMBOLS_HEADER, 32, 4); +} + +static void test_pack_PIMAGE_DATA_DIRECTORY(void) +{ + /* PIMAGE_DATA_DIRECTORY */ + TEST_TYPE(PIMAGE_DATA_DIRECTORY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_DATA_DIRECTORY, 8, 4); +} + +static void test_pack_PIMAGE_DEBUG_DIRECTORY(void) +{ + /* PIMAGE_DEBUG_DIRECTORY */ + TEST_TYPE(PIMAGE_DEBUG_DIRECTORY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_DEBUG_DIRECTORY, 28, 4); +} + +static void test_pack_PIMAGE_DEBUG_MISC(void) +{ + /* PIMAGE_DEBUG_MISC */ + TEST_TYPE(PIMAGE_DEBUG_MISC, 4, 4); + TEST_TYPE_POINTER(PIMAGE_DEBUG_MISC, 16, 4); +} + +static void test_pack_PIMAGE_DOS_HEADER(void) +{ + /* PIMAGE_DOS_HEADER */ + TEST_TYPE(PIMAGE_DOS_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_DOS_HEADER, 64, 2); +} + +static void test_pack_PIMAGE_EXPORT_DIRECTORY(void) +{ + /* PIMAGE_EXPORT_DIRECTORY */ + TEST_TYPE(PIMAGE_EXPORT_DIRECTORY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_EXPORT_DIRECTORY, 40, 4); +} + +static void test_pack_PIMAGE_FILE_HEADER(void) +{ + /* PIMAGE_FILE_HEADER */ + TEST_TYPE(PIMAGE_FILE_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_FILE_HEADER, 20, 4); +} + +static void test_pack_PIMAGE_FUNCTION_ENTRY(void) +{ + /* PIMAGE_FUNCTION_ENTRY */ + TEST_TYPE(PIMAGE_FUNCTION_ENTRY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_FUNCTION_ENTRY, 12, 4); +} + +static void test_pack_PIMAGE_IMPORT_BY_NAME(void) +{ + /* PIMAGE_IMPORT_BY_NAME */ + TEST_TYPE(PIMAGE_IMPORT_BY_NAME, 4, 4); + TEST_TYPE_POINTER(PIMAGE_IMPORT_BY_NAME, 4, 2); +} + +static void test_pack_PIMAGE_IMPORT_DESCRIPTOR(void) +{ + /* PIMAGE_IMPORT_DESCRIPTOR */ + TEST_TYPE(PIMAGE_IMPORT_DESCRIPTOR, 4, 4); +} + +static void test_pack_PIMAGE_LINENUMBER(void) +{ + /* PIMAGE_LINENUMBER */ + TEST_TYPE(PIMAGE_LINENUMBER, 4, 4); +} + +static void test_pack_PIMAGE_LOAD_CONFIG_DIRECTORY(void) +{ + /* PIMAGE_LOAD_CONFIG_DIRECTORY */ + TEST_TYPE(PIMAGE_LOAD_CONFIG_DIRECTORY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_LOAD_CONFIG_DIRECTORY, 72, 4); +} + +static void test_pack_PIMAGE_NT_HEADERS(void) +{ + /* PIMAGE_NT_HEADERS */ + TEST_TYPE(PIMAGE_NT_HEADERS, 4, 4); + TEST_TYPE_POINTER(PIMAGE_NT_HEADERS, 248, 4); +} + +static void test_pack_PIMAGE_OPTIONAL_HEADER(void) +{ + /* PIMAGE_OPTIONAL_HEADER */ + TEST_TYPE(PIMAGE_OPTIONAL_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_OPTIONAL_HEADER, 224, 4); +} + +static void test_pack_PIMAGE_OS2_HEADER(void) +{ + /* PIMAGE_OS2_HEADER */ + TEST_TYPE(PIMAGE_OS2_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_OS2_HEADER, 64, 2); +} + +static void test_pack_PIMAGE_RELOCATION(void) +{ + /* PIMAGE_RELOCATION */ + TEST_TYPE(PIMAGE_RELOCATION, 4, 4); +} + +static void test_pack_PIMAGE_RESOURCE_DATA_ENTRY(void) +{ + /* PIMAGE_RESOURCE_DATA_ENTRY */ + TEST_TYPE(PIMAGE_RESOURCE_DATA_ENTRY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_RESOURCE_DATA_ENTRY, 16, 4); +} + +static void test_pack_PIMAGE_RESOURCE_DIRECTORY(void) +{ + /* PIMAGE_RESOURCE_DIRECTORY */ + TEST_TYPE(PIMAGE_RESOURCE_DIRECTORY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_RESOURCE_DIRECTORY, 16, 4); +} + +static void test_pack_PIMAGE_RESOURCE_DIRECTORY_ENTRY(void) +{ + /* PIMAGE_RESOURCE_DIRECTORY_ENTRY */ + TEST_TYPE(PIMAGE_RESOURCE_DIRECTORY_ENTRY, 4, 4); +} + +static void test_pack_PIMAGE_RESOURCE_DIRECTORY_STRING(void) +{ + /* PIMAGE_RESOURCE_DIRECTORY_STRING */ + TEST_TYPE(PIMAGE_RESOURCE_DIRECTORY_STRING, 4, 4); + TEST_TYPE_POINTER(PIMAGE_RESOURCE_DIRECTORY_STRING, 4, 2); +} + +static void test_pack_PIMAGE_RESOURCE_DIR_STRING_U(void) +{ + /* PIMAGE_RESOURCE_DIR_STRING_U */ + TEST_TYPE(PIMAGE_RESOURCE_DIR_STRING_U, 4, 4); + TEST_TYPE_POINTER(PIMAGE_RESOURCE_DIR_STRING_U, 4, 2); +} + +static void test_pack_PIMAGE_SECTION_HEADER(void) +{ + /* PIMAGE_SECTION_HEADER */ + TEST_TYPE(PIMAGE_SECTION_HEADER, 4, 4); +} + +static void test_pack_PIMAGE_SEPARATE_DEBUG_HEADER(void) +{ + /* PIMAGE_SEPARATE_DEBUG_HEADER */ + TEST_TYPE(PIMAGE_SEPARATE_DEBUG_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_SEPARATE_DEBUG_HEADER, 48, 4); +} + +static void test_pack_PIMAGE_SYMBOL(void) +{ + /* PIMAGE_SYMBOL */ + TEST_TYPE(PIMAGE_SYMBOL, 4, 4); +} + +static void test_pack_PIMAGE_THUNK_DATA(void) +{ + /* PIMAGE_THUNK_DATA */ + TEST_TYPE(PIMAGE_THUNK_DATA, 4, 4); +} + +static void test_pack_PIMAGE_TLS_CALLBACK(void) +{ + /* PIMAGE_TLS_CALLBACK */ + TEST_TYPE(PIMAGE_TLS_CALLBACK, 4, 4); +} + +static void test_pack_PIMAGE_TLS_DIRECTORY(void) +{ + /* PIMAGE_TLS_DIRECTORY */ + TEST_TYPE(PIMAGE_TLS_DIRECTORY, 4, 4); + TEST_TYPE_POINTER(PIMAGE_TLS_DIRECTORY, 24, 4); +} + +static void test_pack_PIMAGE_VXD_HEADER(void) +{ + /* PIMAGE_VXD_HEADER */ + TEST_TYPE(PIMAGE_VXD_HEADER, 4, 4); + TEST_TYPE_POINTER(PIMAGE_VXD_HEADER, 196, 2); +} + +static void test_pack_PIO_COUNTERS(void) +{ + /* PIO_COUNTERS */ + TEST_TYPE(PIO_COUNTERS, 4, 4); + TEST_TYPE_POINTER(PIO_COUNTERS, 48, 8); +} + +static void test_pack_PISECURITY_DESCRIPTOR(void) +{ + /* PISECURITY_DESCRIPTOR */ + TEST_TYPE(PISECURITY_DESCRIPTOR, 4, 4); + TEST_TYPE_POINTER(PISECURITY_DESCRIPTOR, 20, 4); +} + +static void test_pack_PISECURITY_DESCRIPTOR_RELATIVE(void) +{ + /* PISECURITY_DESCRIPTOR_RELATIVE */ + TEST_TYPE(PISECURITY_DESCRIPTOR_RELATIVE, 4, 4); + TEST_TYPE_POINTER(PISECURITY_DESCRIPTOR_RELATIVE, 20, 4); +} + +static void test_pack_PISID(void) +{ + /* PISID */ + TEST_TYPE(PISID, 4, 4); + TEST_TYPE_POINTER(PISID, 12, 4); +} + +static void test_pack_PLARGE_INTEGER(void) +{ + /* PLARGE_INTEGER */ + TEST_TYPE(PLARGE_INTEGER, 4, 4); +} + +static void test_pack_PLIST_ENTRY(void) +{ + /* PLIST_ENTRY */ + TEST_TYPE(PLIST_ENTRY, 4, 4); + TEST_TYPE_POINTER(PLIST_ENTRY, 8, 4); +} + +static void test_pack_PLUID(void) +{ + /* PLUID */ + TEST_TYPE(PLUID, 4, 4); + TEST_TYPE_POINTER(PLUID, 8, 4); +} + +static void test_pack_PLUID_AND_ATTRIBUTES(void) +{ + /* PLUID_AND_ATTRIBUTES */ + TEST_TYPE(PLUID_AND_ATTRIBUTES, 4, 4); + TEST_TYPE_POINTER(PLUID_AND_ATTRIBUTES, 12, 4); +} + +static void test_pack_PMEMORY_BASIC_INFORMATION(void) +{ + /* PMEMORY_BASIC_INFORMATION */ + TEST_TYPE(PMEMORY_BASIC_INFORMATION, 4, 4); + TEST_TYPE_POINTER(PMEMORY_BASIC_INFORMATION, 28, 4); +} + +static void test_pack_PMESSAGE_RESOURCE_BLOCK(void) +{ + /* PMESSAGE_RESOURCE_BLOCK */ + TEST_TYPE(PMESSAGE_RESOURCE_BLOCK, 4, 4); + TEST_TYPE_POINTER(PMESSAGE_RESOURCE_BLOCK, 12, 4); +} + +static void test_pack_PMESSAGE_RESOURCE_DATA(void) +{ + /* PMESSAGE_RESOURCE_DATA */ + TEST_TYPE(PMESSAGE_RESOURCE_DATA, 4, 4); + TEST_TYPE_POINTER(PMESSAGE_RESOURCE_DATA, 16, 4); +} + +static void test_pack_PMESSAGE_RESOURCE_ENTRY(void) +{ + /* PMESSAGE_RESOURCE_ENTRY */ + TEST_TYPE(PMESSAGE_RESOURCE_ENTRY, 4, 4); + TEST_TYPE_POINTER(PMESSAGE_RESOURCE_ENTRY, 6, 2); +} + +static void test_pack_PNT_TIB(void) +{ + /* PNT_TIB */ + TEST_TYPE(PNT_TIB, 4, 4); +} + +static void test_pack_POBJECT_TYPE_LIST(void) +{ + /* POBJECT_TYPE_LIST */ + TEST_TYPE(POBJECT_TYPE_LIST, 4, 4); + TEST_TYPE_POINTER(POBJECT_TYPE_LIST, 8, 4); +} + +static void test_pack_PPRIVILEGE_SET(void) +{ + /* PPRIVILEGE_SET */ + TEST_TYPE(PPRIVILEGE_SET, 4, 4); + TEST_TYPE_POINTER(PPRIVILEGE_SET, 20, 4); +} + +static void test_pack_PRIVILEGE_SET(void) +{ + /* PRIVILEGE_SET (pack 4) */ + TEST_TYPE(PRIVILEGE_SET, 20, 4); + TEST_FIELD(PRIVILEGE_SET, DWORD, PrivilegeCount, 0, 4, 4); + TEST_FIELD(PRIVILEGE_SET, DWORD, Control, 4, 4, 4); + TEST_FIELD(PRIVILEGE_SET, LUID_AND_ATTRIBUTES[ANYSIZE_ARRAY], Privilege, 8, 12, 4); +} + +static void test_pack_PRLIST_ENTRY(void) +{ + /* PRLIST_ENTRY */ + TEST_TYPE(PRLIST_ENTRY, 4, 4); + TEST_TYPE_POINTER(PRLIST_ENTRY, 8, 4); +} + +static void test_pack_PRTL_CRITICAL_SECTION(void) +{ + /* PRTL_CRITICAL_SECTION */ + TEST_TYPE(PRTL_CRITICAL_SECTION, 4, 4); + TEST_TYPE_POINTER(PRTL_CRITICAL_SECTION, 24, 4); +} + +static void test_pack_PRTL_CRITICAL_SECTION_DEBUG(void) +{ + /* PRTL_CRITICAL_SECTION_DEBUG */ + TEST_TYPE(PRTL_CRITICAL_SECTION_DEBUG, 4, 4); + TEST_TYPE_POINTER(PRTL_CRITICAL_SECTION_DEBUG, 32, 4); +} + +static void test_pack_PRTL_OSVERSIONINFOEXW(void) +{ + /* PRTL_OSVERSIONINFOEXW */ + TEST_TYPE(PRTL_OSVERSIONINFOEXW, 4, 4); + TEST_TYPE_POINTER(PRTL_OSVERSIONINFOEXW, 284, 4); +} + +static void test_pack_PRTL_OSVERSIONINFOW(void) +{ + /* PRTL_OSVERSIONINFOW */ + TEST_TYPE(PRTL_OSVERSIONINFOW, 4, 4); + TEST_TYPE_POINTER(PRTL_OSVERSIONINFOW, 276, 4); +} + +static void test_pack_PRTL_RESOURCE_DEBUG(void) +{ + /* PRTL_RESOURCE_DEBUG */ + TEST_TYPE(PRTL_RESOURCE_DEBUG, 4, 4); + TEST_TYPE_POINTER(PRTL_RESOURCE_DEBUG, 32, 4); +} + +static void test_pack_PSECURITY_DESCRIPTOR(void) +{ + /* PSECURITY_DESCRIPTOR */ + TEST_TYPE(PSECURITY_DESCRIPTOR, 4, 4); +} + +static void test_pack_PSECURITY_QUALITY_OF_SERVICE(void) +{ + /* PSECURITY_QUALITY_OF_SERVICE */ + TEST_TYPE(PSECURITY_QUALITY_OF_SERVICE, 4, 4); +} + +static void test_pack_PSID(void) +{ + /* PSID */ + TEST_TYPE(PSID, 4, 4); +} + +static void test_pack_PSID_IDENTIFIER_AUTHORITY(void) +{ + /* PSID_IDENTIFIER_AUTHORITY */ + TEST_TYPE(PSID_IDENTIFIER_AUTHORITY, 4, 4); + TEST_TYPE_POINTER(PSID_IDENTIFIER_AUTHORITY, 6, 1); +} + +static void test_pack_PSINGLE_LIST_ENTRY(void) +{ + /* PSINGLE_LIST_ENTRY */ + TEST_TYPE(PSINGLE_LIST_ENTRY, 4, 4); + TEST_TYPE_POINTER(PSINGLE_LIST_ENTRY, 4, 4); +} + +static void test_pack_PSTR(void) +{ + /* PSTR */ + TEST_TYPE(PSTR, 4, 4); + TEST_TYPE_POINTER(PSTR, 1, 1); +} + +static void test_pack_PSYSTEM_ALARM_ACE(void) +{ + /* PSYSTEM_ALARM_ACE */ + TEST_TYPE(PSYSTEM_ALARM_ACE, 4, 4); + TEST_TYPE_POINTER(PSYSTEM_ALARM_ACE, 12, 4); +} + +static void test_pack_PSYSTEM_AUDIT_ACE(void) +{ + /* PSYSTEM_AUDIT_ACE */ + TEST_TYPE(PSYSTEM_AUDIT_ACE, 4, 4); + TEST_TYPE_POINTER(PSYSTEM_AUDIT_ACE, 12, 4); +} + +static void test_pack_PTOKEN_GROUPS(void) +{ + /* PTOKEN_GROUPS */ + TEST_TYPE(PTOKEN_GROUPS, 4, 4); + TEST_TYPE_POINTER(PTOKEN_GROUPS, 12, 4); +} + +static void test_pack_PTOKEN_PRIVILEGES(void) +{ + /* PTOKEN_PRIVILEGES */ + TEST_TYPE(PTOKEN_PRIVILEGES, 4, 4); + TEST_TYPE_POINTER(PTOKEN_PRIVILEGES, 16, 4); +} + +static void test_pack_PTOKEN_USER(void) +{ + /* PTOKEN_USER */ + TEST_TYPE(PTOKEN_USER, 4, 4); + TEST_TYPE_POINTER(PTOKEN_USER, 8, 4); +} + +static void test_pack_PTOP_LEVEL_EXCEPTION_FILTER(void) +{ + /* PTOP_LEVEL_EXCEPTION_FILTER */ + TEST_TYPE(PTOP_LEVEL_EXCEPTION_FILTER, 4, 4); +} + +static void test_pack_PTSTR(void) +{ + /* PTSTR */ + TEST_TYPE(PTSTR, 4, 4); +} + +static void test_pack_PULARGE_INTEGER(void) +{ + /* PULARGE_INTEGER */ + TEST_TYPE(PULARGE_INTEGER, 4, 4); +} + +static void test_pack_PVECTORED_EXCEPTION_HANDLER(void) +{ + /* PVECTORED_EXCEPTION_HANDLER */ + TEST_TYPE(PVECTORED_EXCEPTION_HANDLER, 4, 4); +} + +static void test_pack_PVOID(void) +{ + /* PVOID */ + TEST_TYPE(PVOID, 4, 4); +} + +static void test_pack_PWCH(void) +{ + /* PWCH */ + TEST_TYPE(PWCH, 4, 4); + TEST_TYPE_POINTER(PWCH, 2, 2); +} + +static void test_pack_PWSTR(void) +{ + /* PWSTR */ + TEST_TYPE(PWSTR, 4, 4); + TEST_TYPE_POINTER(PWSTR, 2, 2); +} + +static void test_pack_RTL_CRITICAL_SECTION(void) +{ + /* RTL_CRITICAL_SECTION (pack 4) */ + TEST_TYPE(RTL_CRITICAL_SECTION, 24, 4); + TEST_FIELD(RTL_CRITICAL_SECTION, PRTL_CRITICAL_SECTION_DEBUG, DebugInfo, 0, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION, LONG, LockCount, 4, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION, LONG, RecursionCount, 8, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION, HANDLE, OwningThread, 12, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION, HANDLE, LockSemaphore, 16, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION, ULONG_PTR, SpinCount, 20, 4, 4); +} + +static void test_pack_RTL_CRITICAL_SECTION_DEBUG(void) +{ + /* RTL_CRITICAL_SECTION_DEBUG (pack 4) */ + TEST_TYPE(RTL_CRITICAL_SECTION_DEBUG, 32, 4); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, WORD, Type, 0, 2, 2); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, WORD, CreatorBackTraceIndex, 2, 2, 2); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, struct _RTL_CRITICAL_SECTION *, CriticalSection, 4, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, LIST_ENTRY, ProcessLocksList, 8, 8, 4); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, DWORD, EntryCount, 16, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, DWORD, ContentionCount, 20, 4, 4); + TEST_FIELD(RTL_CRITICAL_SECTION_DEBUG, DWORD[ 2 ], Spare, 24, 8, 4); +} + +static void test_pack_RTL_OSVERSIONINFOEXW(void) +{ + /* RTL_OSVERSIONINFOEXW (pack 4) */ + TEST_TYPE(RTL_OSVERSIONINFOEXW, 284, 4); + TEST_FIELD(RTL_OSVERSIONINFOEXW, DWORD, dwOSVersionInfoSize, 0, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOEXW, DWORD, dwMajorVersion, 4, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOEXW, DWORD, dwMinorVersion, 8, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOEXW, DWORD, dwBuildNumber, 12, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOEXW, DWORD, dwPlatformId, 16, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOEXW, WCHAR[128], szCSDVersion, 20, 256, 2); + TEST_FIELD(RTL_OSVERSIONINFOEXW, WORD, wServicePackMajor, 276, 2, 2); + TEST_FIELD(RTL_OSVERSIONINFOEXW, WORD, wServicePackMinor, 278, 2, 2); + TEST_FIELD(RTL_OSVERSIONINFOEXW, WORD, wSuiteMask, 280, 2, 2); + TEST_FIELD(RTL_OSVERSIONINFOEXW, BYTE, wProductType, 282, 1, 1); + TEST_FIELD(RTL_OSVERSIONINFOEXW, BYTE, wReserved, 283, 1, 1); +} + +static void test_pack_RTL_OSVERSIONINFOW(void) +{ + /* RTL_OSVERSIONINFOW (pack 4) */ + TEST_TYPE(RTL_OSVERSIONINFOW, 276, 4); + TEST_FIELD(RTL_OSVERSIONINFOW, DWORD, dwOSVersionInfoSize, 0, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOW, DWORD, dwMajorVersion, 4, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOW, DWORD, dwMinorVersion, 8, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOW, DWORD, dwBuildNumber, 12, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOW, DWORD, dwPlatformId, 16, 4, 4); + TEST_FIELD(RTL_OSVERSIONINFOW, WCHAR[128], szCSDVersion, 20, 256, 2); +} + +static void test_pack_RTL_RESOURCE_DEBUG(void) +{ + /* RTL_RESOURCE_DEBUG (pack 4) */ + TEST_TYPE(RTL_RESOURCE_DEBUG, 32, 4); + TEST_FIELD(RTL_RESOURCE_DEBUG, WORD, Type, 0, 2, 2); + TEST_FIELD(RTL_RESOURCE_DEBUG, WORD, CreatorBackTraceIndex, 2, 2, 2); + TEST_FIELD(RTL_RESOURCE_DEBUG, struct _RTL_CRITICAL_SECTION *, CriticalSection, 4, 4, 4); + TEST_FIELD(RTL_RESOURCE_DEBUG, LIST_ENTRY, ProcessLocksList, 8, 8, 4); + TEST_FIELD(RTL_RESOURCE_DEBUG, DWORD, EntryCount, 16, 4, 4); + TEST_FIELD(RTL_RESOURCE_DEBUG, DWORD, ContentionCount, 20, 4, 4); + TEST_FIELD(RTL_RESOURCE_DEBUG, DWORD[ 2 ], Spare, 24, 8, 4); +} + +static void test_pack_SECURITY_CONTEXT_TRACKING_MODE(void) +{ + /* SECURITY_CONTEXT_TRACKING_MODE */ + TEST_TYPE(SECURITY_CONTEXT_TRACKING_MODE, 1, 1); +} + +static void test_pack_SECURITY_DESCRIPTOR(void) +{ + /* SECURITY_DESCRIPTOR (pack 4) */ + TEST_TYPE(SECURITY_DESCRIPTOR, 20, 4); + TEST_FIELD(SECURITY_DESCRIPTOR, BYTE, Revision, 0, 1, 1); + TEST_FIELD(SECURITY_DESCRIPTOR, BYTE, Sbz1, 1, 1, 1); + TEST_FIELD(SECURITY_DESCRIPTOR, SECURITY_DESCRIPTOR_CONTROL, Control, 2, 2, 2); + TEST_FIELD(SECURITY_DESCRIPTOR, PSID, Owner, 4, 4, 4); + TEST_FIELD(SECURITY_DESCRIPTOR, PSID, Group, 8, 4, 4); + TEST_FIELD(SECURITY_DESCRIPTOR, PACL, Sacl, 12, 4, 4); + TEST_FIELD(SECURITY_DESCRIPTOR, PACL, Dacl, 16, 4, 4); +} + +static void test_pack_SECURITY_DESCRIPTOR_CONTROL(void) +{ + /* SECURITY_DESCRIPTOR_CONTROL */ + TEST_TYPE(SECURITY_DESCRIPTOR_CONTROL, 2, 2); + TEST_TYPE_UNSIGNED(SECURITY_DESCRIPTOR_CONTROL); +} + +static void test_pack_SECURITY_DESCRIPTOR_RELATIVE(void) +{ + /* SECURITY_DESCRIPTOR_RELATIVE (pack 4) */ + TEST_TYPE(SECURITY_DESCRIPTOR_RELATIVE, 20, 4); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, BYTE, Revision, 0, 1, 1); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, BYTE, Sbz1, 1, 1, 1); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, SECURITY_DESCRIPTOR_CONTROL, Control, 2, 2, 2); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, DWORD, Owner, 4, 4, 4); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, DWORD, Group, 8, 4, 4); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, DWORD, Sacl, 12, 4, 4); + TEST_FIELD(SECURITY_DESCRIPTOR_RELATIVE, DWORD, Dacl, 16, 4, 4); +} + +static void test_pack_SECURITY_INFORMATION(void) +{ + /* SECURITY_INFORMATION */ + TEST_TYPE(SECURITY_INFORMATION, 4, 4); + TEST_TYPE_UNSIGNED(SECURITY_INFORMATION); +} + +static void test_pack_SECURITY_QUALITY_OF_SERVICE(void) +{ + /* SECURITY_QUALITY_OF_SERVICE (pack 4) */ + TEST_FIELD(SECURITY_QUALITY_OF_SERVICE, DWORD, Length, 0, 4, 4); +} + +static void test_pack_SHORT(void) +{ + /* SHORT */ + TEST_TYPE(SHORT, 2, 2); + TEST_TYPE_SIGNED(SHORT); +} + +static void test_pack_SID(void) +{ + /* SID (pack 4) */ + TEST_TYPE(SID, 12, 4); + TEST_FIELD(SID, BYTE, Revision, 0, 1, 1); + TEST_FIELD(SID, BYTE, SubAuthorityCount, 1, 1, 1); + TEST_FIELD(SID, SID_IDENTIFIER_AUTHORITY, IdentifierAuthority, 2, 6, 1); + TEST_FIELD(SID, DWORD[1], SubAuthority, 8, 4, 4); +} + +static void test_pack_SID_AND_ATTRIBUTES(void) +{ + /* SID_AND_ATTRIBUTES (pack 4) */ + TEST_TYPE(SID_AND_ATTRIBUTES, 8, 4); + TEST_FIELD(SID_AND_ATTRIBUTES, PSID, Sid, 0, 4, 4); + TEST_FIELD(SID_AND_ATTRIBUTES, DWORD, Attributes, 4, 4, 4); +} + +static void test_pack_SID_IDENTIFIER_AUTHORITY(void) +{ + /* SID_IDENTIFIER_AUTHORITY (pack 4) */ + TEST_TYPE(SID_IDENTIFIER_AUTHORITY, 6, 1); + TEST_FIELD(SID_IDENTIFIER_AUTHORITY, BYTE[6], Value, 0, 6, 1); +} + +static void test_pack_SINGLE_LIST_ENTRY(void) +{ + /* SINGLE_LIST_ENTRY (pack 4) */ + TEST_TYPE(SINGLE_LIST_ENTRY, 4, 4); + TEST_FIELD(SINGLE_LIST_ENTRY, struct _SINGLE_LIST_ENTRY *, Next, 0, 4, 4); +} + +static void test_pack_SYSTEM_ALARM_ACE(void) +{ + /* SYSTEM_ALARM_ACE (pack 4) */ + TEST_TYPE(SYSTEM_ALARM_ACE, 12, 4); + TEST_FIELD(SYSTEM_ALARM_ACE, ACE_HEADER, Header, 0, 4, 2); + TEST_FIELD(SYSTEM_ALARM_ACE, DWORD, Mask, 4, 4, 4); + TEST_FIELD(SYSTEM_ALARM_ACE, DWORD, SidStart, 8, 4, 4); +} + +static void test_pack_SYSTEM_AUDIT_ACE(void) +{ + /* SYSTEM_AUDIT_ACE (pack 4) */ + TEST_TYPE(SYSTEM_AUDIT_ACE, 12, 4); + TEST_FIELD(SYSTEM_AUDIT_ACE, ACE_HEADER, Header, 0, 4, 2); + TEST_FIELD(SYSTEM_AUDIT_ACE, DWORD, Mask, 4, 4, 4); + TEST_FIELD(SYSTEM_AUDIT_ACE, DWORD, SidStart, 8, 4, 4); +} + +static void test_pack_TCHAR(void) +{ + /* TCHAR */ + TEST_TYPE(TCHAR, 1, 1); +} + +static void test_pack_TOKEN_DEFAULT_DACL(void) +{ + /* TOKEN_DEFAULT_DACL (pack 4) */ + TEST_TYPE(TOKEN_DEFAULT_DACL, 4, 4); + TEST_FIELD(TOKEN_DEFAULT_DACL, PACL, DefaultDacl, 0, 4, 4); +} + +static void test_pack_TOKEN_GROUPS(void) +{ + /* TOKEN_GROUPS (pack 4) */ + TEST_TYPE(TOKEN_GROUPS, 12, 4); + TEST_FIELD(TOKEN_GROUPS, DWORD, GroupCount, 0, 4, 4); + TEST_FIELD(TOKEN_GROUPS, SID_AND_ATTRIBUTES[ANYSIZE_ARRAY], Groups, 4, 8, 4); +} + +static void test_pack_TOKEN_OWNER(void) +{ + /* TOKEN_OWNER (pack 4) */ + TEST_TYPE(TOKEN_OWNER, 4, 4); + TEST_FIELD(TOKEN_OWNER, PSID, Owner, 0, 4, 4); +} + +static void test_pack_TOKEN_PRIMARY_GROUP(void) +{ + /* TOKEN_PRIMARY_GROUP (pack 4) */ + TEST_TYPE(TOKEN_PRIMARY_GROUP, 4, 4); + TEST_FIELD(TOKEN_PRIMARY_GROUP, PSID, PrimaryGroup, 0, 4, 4); +} + +static void test_pack_TOKEN_PRIVILEGES(void) +{ + /* TOKEN_PRIVILEGES (pack 4) */ + TEST_TYPE(TOKEN_PRIVILEGES, 16, 4); + TEST_FIELD(TOKEN_PRIVILEGES, DWORD, PrivilegeCount, 0, 4, 4); + TEST_FIELD(TOKEN_PRIVILEGES, LUID_AND_ATTRIBUTES[ANYSIZE_ARRAY], Privileges, 4, 12, 4); +} + +static void test_pack_TOKEN_SOURCE(void) +{ + /* TOKEN_SOURCE (pack 4) */ + TEST_TYPE(TOKEN_SOURCE, 16, 4); + TEST_FIELD(TOKEN_SOURCE, char[TOKEN_SOURCE_LENGTH], SourceName, 0, 8, 1); + TEST_FIELD(TOKEN_SOURCE, LUID, SourceIdentifier, 8, 8, 4); +} + +static void test_pack_TOKEN_STATISTICS(void) +{ + /* TOKEN_STATISTICS (pack 4) */ + TEST_FIELD(TOKEN_STATISTICS, LUID, TokenId, 0, 8, 4); + TEST_FIELD(TOKEN_STATISTICS, LUID, AuthenticationId, 8, 8, 4); + TEST_FIELD(TOKEN_STATISTICS, LARGE_INTEGER, ExpirationTime, 16, 8, 4); +} + +static void test_pack_TOKEN_USER(void) +{ + /* TOKEN_USER (pack 4) */ + TEST_TYPE(TOKEN_USER, 8, 4); + TEST_FIELD(TOKEN_USER, SID_AND_ATTRIBUTES, User, 0, 8, 4); +} + +static void test_pack_ULARGE_INTEGER(void) +{ + /* ULARGE_INTEGER (pack 4) */ +} + +static void test_pack_ULONGLONG(void) +{ + /* ULONGLONG */ + TEST_TYPE(ULONGLONG, 8, 8); + TEST_TYPE_UNSIGNED(ULONGLONG); +} + +static void test_pack_WAITORTIMERCALLBACKFUNC(void) +{ + /* WAITORTIMERCALLBACKFUNC */ + TEST_TYPE(WAITORTIMERCALLBACKFUNC, 4, 4); +} + +static void test_pack_WCHAR(void) +{ + /* WCHAR */ + TEST_TYPE(WCHAR, 2, 2); + TEST_TYPE_UNSIGNED(WCHAR); +} + +static void test_pack_ATOM(void) +{ + /* ATOM */ + TEST_TYPE(ATOM, 2, 2); + TEST_TYPE_UNSIGNED(ATOM); +} + +static void test_pack_BOOL(void) +{ + /* BOOL */ + TEST_TYPE(BOOL, 4, 4); + TEST_TYPE_SIGNED(BOOL); +} + +static void test_pack_BYTE(void) +{ + /* BYTE */ + TEST_TYPE(BYTE, 1, 1); + TEST_TYPE_UNSIGNED(BYTE); +} + +static void test_pack_COLORREF(void) +{ + /* COLORREF */ + TEST_TYPE(COLORREF, 4, 4); + TEST_TYPE_UNSIGNED(COLORREF); +} + +static void test_pack_DWORD(void) +{ + /* DWORD */ + TEST_TYPE(DWORD, 4, 4); + TEST_TYPE_UNSIGNED(DWORD); +} + +static void test_pack_FARPROC(void) +{ + /* FARPROC */ + TEST_TYPE(FARPROC, 4, 4); +} + +static void test_pack_FLOAT(void) +{ + /* FLOAT */ + TEST_TYPE(FLOAT, 4, 4); +} + +static void test_pack_GLOBALHANDLE(void) +{ + /* GLOBALHANDLE */ + TEST_TYPE(GLOBALHANDLE, 4, 4); +} + +static void test_pack_HCURSOR(void) +{ + /* HCURSOR */ + TEST_TYPE(HCURSOR, 4, 4); + TEST_TYPE_UNSIGNED(HCURSOR); +} + +static void test_pack_HFILE(void) +{ + /* HFILE */ + TEST_TYPE(HFILE, 4, 4); + TEST_TYPE_SIGNED(HFILE); +} + +static void test_pack_HGDIOBJ(void) +{ + /* HGDIOBJ */ + TEST_TYPE(HGDIOBJ, 4, 4); +} + +static void test_pack_HGLOBAL(void) +{ + /* HGLOBAL */ + TEST_TYPE(HGLOBAL, 4, 4); +} + +static void test_pack_HLOCAL(void) +{ + /* HLOCAL */ + TEST_TYPE(HLOCAL, 4, 4); +} + +static void test_pack_HMODULE(void) +{ + /* HMODULE */ + TEST_TYPE(HMODULE, 4, 4); + TEST_TYPE_UNSIGNED(HMODULE); +} + +static void test_pack_INT(void) +{ + /* INT */ + TEST_TYPE(INT, 4, 4); + TEST_TYPE_SIGNED(INT); +} + +static void test_pack_LOCALHANDLE(void) +{ + /* LOCALHANDLE */ + TEST_TYPE(LOCALHANDLE, 4, 4); +} + +static void test_pack_LPARAM(void) +{ + /* LPARAM */ + TEST_TYPE(LPARAM, 4, 4); +} + +static void test_pack_LPCRECT(void) +{ + /* LPCRECT */ + TEST_TYPE(LPCRECT, 4, 4); + TEST_TYPE_POINTER(LPCRECT, 16, 4); +} + +static void test_pack_LPCRECTL(void) +{ + /* LPCRECTL */ + TEST_TYPE(LPCRECTL, 4, 4); + TEST_TYPE_POINTER(LPCRECTL, 16, 4); +} + +static void test_pack_LPCVOID(void) +{ + /* LPCVOID */ + TEST_TYPE(LPCVOID, 4, 4); +} + +static void test_pack_LPPOINT(void) +{ + /* LPPOINT */ + TEST_TYPE(LPPOINT, 4, 4); + TEST_TYPE_POINTER(LPPOINT, 8, 4); +} + +static void test_pack_LPPOINTS(void) +{ + /* LPPOINTS */ + TEST_TYPE(LPPOINTS, 4, 4); + TEST_TYPE_POINTER(LPPOINTS, 4, 2); +} + +static void test_pack_LPRECT(void) +{ + /* LPRECT */ + TEST_TYPE(LPRECT, 4, 4); + TEST_TYPE_POINTER(LPRECT, 16, 4); +} + +static void test_pack_LPRECTL(void) +{ + /* LPRECTL */ + TEST_TYPE(LPRECTL, 4, 4); + TEST_TYPE_POINTER(LPRECTL, 16, 4); +} + +static void test_pack_LPSIZE(void) +{ + /* LPSIZE */ + TEST_TYPE(LPSIZE, 4, 4); + TEST_TYPE_POINTER(LPSIZE, 8, 4); +} + +static void test_pack_LRESULT(void) +{ + /* LRESULT */ + TEST_TYPE(LRESULT, 4, 4); +} + +static void test_pack_POINT(void) +{ + /* POINT (pack 4) */ + TEST_TYPE(POINT, 8, 4); + TEST_FIELD(POINT, LONG, x, 0, 4, 4); + TEST_FIELD(POINT, LONG, y, 4, 4, 4); +} + +static void test_pack_POINTL(void) +{ + /* POINTL (pack 4) */ + TEST_TYPE(POINTL, 8, 4); + TEST_FIELD(POINTL, LONG, x, 0, 4, 4); + TEST_FIELD(POINTL, LONG, y, 4, 4, 4); +} + +static void test_pack_POINTS(void) +{ + /* POINTS (pack 4) */ + TEST_TYPE(POINTS, 4, 2); + TEST_FIELD(POINTS, SHORT, x, 0, 2, 2); + TEST_FIELD(POINTS, SHORT, y, 2, 2, 2); +} + +static void test_pack_PPOINT(void) +{ + /* PPOINT */ + TEST_TYPE(PPOINT, 4, 4); + TEST_TYPE_POINTER(PPOINT, 8, 4); +} + +static void test_pack_PPOINTL(void) +{ + /* PPOINTL */ + TEST_TYPE(PPOINTL, 4, 4); + TEST_TYPE_POINTER(PPOINTL, 8, 4); +} + +static void test_pack_PPOINTS(void) +{ + /* PPOINTS */ + TEST_TYPE(PPOINTS, 4, 4); + TEST_TYPE_POINTER(PPOINTS, 4, 2); +} + +static void test_pack_PRECT(void) +{ + /* PRECT */ + TEST_TYPE(PRECT, 4, 4); + TEST_TYPE_POINTER(PRECT, 16, 4); +} + +static void test_pack_PRECTL(void) +{ + /* PRECTL */ + TEST_TYPE(PRECTL, 4, 4); + TEST_TYPE_POINTER(PRECTL, 16, 4); +} + +static void test_pack_PROC(void) +{ + /* PROC */ + TEST_TYPE(PROC, 4, 4); +} + +static void test_pack_PSIZE(void) +{ + /* PSIZE */ + TEST_TYPE(PSIZE, 4, 4); + TEST_TYPE_POINTER(PSIZE, 8, 4); +} + +static void test_pack_PSZ(void) +{ + /* PSZ */ + TEST_TYPE(PSZ, 4, 4); +} + +static void test_pack_RECT(void) +{ + /* RECT (pack 4) */ + TEST_TYPE(RECT, 16, 4); + TEST_FIELD(RECT, LONG, left, 0, 4, 4); + TEST_FIELD(RECT, LONG, top, 4, 4, 4); + TEST_FIELD(RECT, LONG, right, 8, 4, 4); + TEST_FIELD(RECT, LONG, bottom, 12, 4, 4); +} + +static void test_pack_RECTL(void) +{ + /* RECTL (pack 4) */ + TEST_TYPE(RECTL, 16, 4); + TEST_FIELD(RECTL, LONG, left, 0, 4, 4); + TEST_FIELD(RECTL, LONG, top, 4, 4, 4); + TEST_FIELD(RECTL, LONG, right, 8, 4, 4); + TEST_FIELD(RECTL, LONG, bottom, 12, 4, 4); +} + +static void test_pack_SIZE(void) +{ + /* SIZE (pack 4) */ + TEST_TYPE(SIZE, 8, 4); + TEST_FIELD(SIZE, LONG, cx, 0, 4, 4); + TEST_FIELD(SIZE, LONG, cy, 4, 4, 4); +} + +static void test_pack_SIZEL(void) +{ + /* SIZEL */ + TEST_TYPE(SIZEL, 8, 4); +} + +static void test_pack_UCHAR(void) +{ + /* UCHAR */ + TEST_TYPE(UCHAR, 1, 1); + TEST_TYPE_UNSIGNED(UCHAR); +} + +static void test_pack_UINT(void) +{ + /* UINT */ + TEST_TYPE(UINT, 4, 4); + TEST_TYPE_UNSIGNED(UINT); +} + +static void test_pack_ULONG(void) +{ + /* ULONG */ + TEST_TYPE(ULONG, 4, 4); + TEST_TYPE_UNSIGNED(ULONG); +} + +static void test_pack_USHORT(void) +{ + /* USHORT */ + TEST_TYPE(USHORT, 2, 2); + TEST_TYPE_UNSIGNED(USHORT); +} + +static void test_pack_WORD(void) +{ + /* WORD */ + TEST_TYPE(WORD, 2, 2); + TEST_TYPE_UNSIGNED(WORD); +} + +static void test_pack_WPARAM(void) +{ + /* WPARAM */ + TEST_TYPE(WPARAM, 4, 4); +} + +static void test_pack(void) +{ + test_pack_ACCESS_ALLOWED_ACE(); + test_pack_ACCESS_DENIED_ACE(); + test_pack_ACCESS_MASK(); + test_pack_ACE_HEADER(); + test_pack_ACL(); + test_pack_ACL_REVISION_INFORMATION(); + test_pack_ACL_SIZE_INFORMATION(); + test_pack_ATOM(); + test_pack_BOOL(); + test_pack_BOOLEAN(); + test_pack_BYTE(); + test_pack_CCHAR(); + test_pack_CHAR(); + test_pack_COLORREF(); + test_pack_DWORD(); + test_pack_DWORD32(); + test_pack_DWORD64(); + test_pack_DWORDLONG(); + test_pack_DWORD_PTR(); + test_pack_EXCEPTION_POINTERS(); + test_pack_EXCEPTION_RECORD(); + test_pack_EXECUTION_STATE(); + test_pack_FARPROC(); + test_pack_FLOAT(); + test_pack_FLOATING_SAVE_AREA(); + test_pack_FPO_DATA(); + test_pack_GENERIC_MAPPING(); + test_pack_GLOBALHANDLE(); + test_pack_HALF_PTR(); + test_pack_HANDLE(); + test_pack_HCURSOR(); + test_pack_HFILE(); + test_pack_HGDIOBJ(); + test_pack_HGLOBAL(); + test_pack_HLOCAL(); + test_pack_HMODULE(); + test_pack_HRESULT(); + test_pack_IMAGE_ARCHIVE_MEMBER_HEADER(); + test_pack_IMAGE_AUX_SYMBOL(); + test_pack_IMAGE_BASE_RELOCATION(); + test_pack_IMAGE_BOUND_FORWARDER_REF(); + test_pack_IMAGE_BOUND_IMPORT_DESCRIPTOR(); + test_pack_IMAGE_COFF_SYMBOLS_HEADER(); + test_pack_IMAGE_DATA_DIRECTORY(); + test_pack_IMAGE_DEBUG_DIRECTORY(); + test_pack_IMAGE_DEBUG_MISC(); + test_pack_IMAGE_DOS_HEADER(); + test_pack_IMAGE_EXPORT_DIRECTORY(); + test_pack_IMAGE_FILE_HEADER(); + test_pack_IMAGE_FUNCTION_ENTRY(); + test_pack_IMAGE_IMPORT_BY_NAME(); + test_pack_IMAGE_IMPORT_DESCRIPTOR(); + test_pack_IMAGE_LINENUMBER(); + test_pack_IMAGE_LOAD_CONFIG_DIRECTORY(); + test_pack_IMAGE_NT_HEADERS(); + test_pack_IMAGE_OPTIONAL_HEADER(); + test_pack_IMAGE_OS2_HEADER(); + test_pack_IMAGE_RELOCATION(); + test_pack_IMAGE_RESOURCE_DATA_ENTRY(); + test_pack_IMAGE_RESOURCE_DIRECTORY(); + test_pack_IMAGE_RESOURCE_DIRECTORY_ENTRY(); + test_pack_IMAGE_RESOURCE_DIRECTORY_STRING(); + test_pack_IMAGE_RESOURCE_DIR_STRING_U(); + test_pack_IMAGE_SECTION_HEADER(); + test_pack_IMAGE_SEPARATE_DEBUG_HEADER(); + test_pack_IMAGE_SYMBOL(); + test_pack_IMAGE_THUNK_DATA(); + test_pack_IMAGE_TLS_DIRECTORY(); + test_pack_IMAGE_VXD_HEADER(); + test_pack_INT(); + test_pack_INT16(); + test_pack_INT32(); + test_pack_INT64(); + test_pack_INT8(); + test_pack_INT_PTR(); + test_pack_IO_COUNTERS(); + test_pack_LANGID(); + test_pack_LARGE_INTEGER(); + test_pack_LCID(); + test_pack_LIST_ENTRY(); + test_pack_LOCALHANDLE(); + test_pack_LONG(); + test_pack_LONG32(); + test_pack_LONG64(); + test_pack_LONGLONG(); + test_pack_LONG_PTR(); + test_pack_LPARAM(); + test_pack_LPCRECT(); + test_pack_LPCRECTL(); + test_pack_LPCVOID(); + test_pack_LPPOINT(); + test_pack_LPPOINTS(); + test_pack_LPRECT(); + test_pack_LPRECTL(); + test_pack_LPSIZE(); + test_pack_LPTOP_LEVEL_EXCEPTION_FILTER(); + test_pack_LRESULT(); + test_pack_LUID(); + test_pack_LUID_AND_ATTRIBUTES(); + test_pack_MEMORY_BASIC_INFORMATION(); + test_pack_MESSAGE_RESOURCE_BLOCK(); + test_pack_MESSAGE_RESOURCE_DATA(); + test_pack_MESSAGE_RESOURCE_ENTRY(); + test_pack_NT_TIB(); + test_pack_OBJECT_TYPE_LIST(); + test_pack_PACCESS_ALLOWED_ACE(); + test_pack_PACCESS_DENIED_ACE(); + test_pack_PACCESS_TOKEN(); + test_pack_PACE_HEADER(); + test_pack_PACL(); + test_pack_PACL_REVISION_INFORMATION(); + test_pack_PACL_SIZE_INFORMATION(); + test_pack_PCCH(); + test_pack_PCH(); + test_pack_PCSTR(); + test_pack_PCTSTR(); + test_pack_PCWCH(); + test_pack_PCWSTR(); + test_pack_PEXCEPTION_POINTERS(); + test_pack_PEXCEPTION_RECORD(); + test_pack_PFLOATING_SAVE_AREA(); + test_pack_PFPO_DATA(); + test_pack_PGENERIC_MAPPING(); + test_pack_PHANDLE(); + test_pack_PIMAGE_ARCHIVE_MEMBER_HEADER(); + test_pack_PIMAGE_AUX_SYMBOL(); + test_pack_PIMAGE_BASE_RELOCATION(); + test_pack_PIMAGE_BOUND_FORWARDER_REF(); + test_pack_PIMAGE_BOUND_IMPORT_DESCRIPTOR(); + test_pack_PIMAGE_COFF_SYMBOLS_HEADER(); + test_pack_PIMAGE_DATA_DIRECTORY(); + test_pack_PIMAGE_DEBUG_DIRECTORY(); + test_pack_PIMAGE_DEBUG_MISC(); + test_pack_PIMAGE_DOS_HEADER(); + test_pack_PIMAGE_EXPORT_DIRECTORY(); + test_pack_PIMAGE_FILE_HEADER(); + test_pack_PIMAGE_FUNCTION_ENTRY(); + test_pack_PIMAGE_IMPORT_BY_NAME(); + test_pack_PIMAGE_IMPORT_DESCRIPTOR(); + test_pack_PIMAGE_LINENUMBER(); + test_pack_PIMAGE_LOAD_CONFIG_DIRECTORY(); + test_pack_PIMAGE_NT_HEADERS(); + test_pack_PIMAGE_OPTIONAL_HEADER(); + test_pack_PIMAGE_OS2_HEADER(); + test_pack_PIMAGE_RELOCATION(); + test_pack_PIMAGE_RESOURCE_DATA_ENTRY(); + test_pack_PIMAGE_RESOURCE_DIRECTORY(); + test_pack_PIMAGE_RESOURCE_DIRECTORY_ENTRY(); + test_pack_PIMAGE_RESOURCE_DIRECTORY_STRING(); + test_pack_PIMAGE_RESOURCE_DIR_STRING_U(); + test_pack_PIMAGE_SECTION_HEADER(); + test_pack_PIMAGE_SEPARATE_DEBUG_HEADER(); + test_pack_PIMAGE_SYMBOL(); + test_pack_PIMAGE_THUNK_DATA(); + test_pack_PIMAGE_TLS_CALLBACK(); + test_pack_PIMAGE_TLS_DIRECTORY(); + test_pack_PIMAGE_VXD_HEADER(); + test_pack_PIO_COUNTERS(); + test_pack_PISECURITY_DESCRIPTOR(); + test_pack_PISECURITY_DESCRIPTOR_RELATIVE(); + test_pack_PISID(); + test_pack_PLARGE_INTEGER(); + test_pack_PLIST_ENTRY(); + test_pack_PLUID(); + test_pack_PLUID_AND_ATTRIBUTES(); + test_pack_PMEMORY_BASIC_INFORMATION(); + test_pack_PMESSAGE_RESOURCE_BLOCK(); + test_pack_PMESSAGE_RESOURCE_DATA(); + test_pack_PMESSAGE_RESOURCE_ENTRY(); + test_pack_PNT_TIB(); + test_pack_POBJECT_TYPE_LIST(); + test_pack_POINT(); + test_pack_POINTL(); + test_pack_POINTS(); + test_pack_PPOINT(); + test_pack_PPOINTL(); + test_pack_PPOINTS(); + test_pack_PPRIVILEGE_SET(); + test_pack_PRECT(); + test_pack_PRECTL(); + test_pack_PRIVILEGE_SET(); + test_pack_PRLIST_ENTRY(); + test_pack_PROC(); + test_pack_PRTL_CRITICAL_SECTION(); + test_pack_PRTL_CRITICAL_SECTION_DEBUG(); + test_pack_PRTL_OSVERSIONINFOEXW(); + test_pack_PRTL_OSVERSIONINFOW(); + test_pack_PRTL_RESOURCE_DEBUG(); + test_pack_PSECURITY_DESCRIPTOR(); + test_pack_PSECURITY_QUALITY_OF_SERVICE(); + test_pack_PSID(); + test_pack_PSID_IDENTIFIER_AUTHORITY(); + test_pack_PSINGLE_LIST_ENTRY(); + test_pack_PSIZE(); + test_pack_PSTR(); + test_pack_PSYSTEM_ALARM_ACE(); + test_pack_PSYSTEM_AUDIT_ACE(); + test_pack_PSZ(); + test_pack_PTOKEN_GROUPS(); + test_pack_PTOKEN_PRIVILEGES(); + test_pack_PTOKEN_USER(); + test_pack_PTOP_LEVEL_EXCEPTION_FILTER(); + test_pack_PTSTR(); + test_pack_PULARGE_INTEGER(); + test_pack_PVECTORED_EXCEPTION_HANDLER(); + test_pack_PVOID(); + test_pack_PWCH(); + test_pack_PWSTR(); + test_pack_RECT(); + test_pack_RECTL(); + test_pack_RTL_CRITICAL_SECTION(); + test_pack_RTL_CRITICAL_SECTION_DEBUG(); + test_pack_RTL_OSVERSIONINFOEXW(); + test_pack_RTL_OSVERSIONINFOW(); + test_pack_RTL_RESOURCE_DEBUG(); + test_pack_SECURITY_CONTEXT_TRACKING_MODE(); + test_pack_SECURITY_DESCRIPTOR(); + test_pack_SECURITY_DESCRIPTOR_CONTROL(); + test_pack_SECURITY_DESCRIPTOR_RELATIVE(); + test_pack_SECURITY_INFORMATION(); + test_pack_SECURITY_QUALITY_OF_SERVICE(); + test_pack_SHORT(); + test_pack_SID(); + test_pack_SID_AND_ATTRIBUTES(); + test_pack_SID_IDENTIFIER_AUTHORITY(); + test_pack_SINGLE_LIST_ENTRY(); + test_pack_SIZE(); + test_pack_SIZEL(); + test_pack_SIZE_T(); + test_pack_SSIZE_T(); + test_pack_SYSTEM_ALARM_ACE(); + test_pack_SYSTEM_AUDIT_ACE(); + test_pack_TCHAR(); + test_pack_TOKEN_DEFAULT_DACL(); + test_pack_TOKEN_GROUPS(); + test_pack_TOKEN_OWNER(); + test_pack_TOKEN_PRIMARY_GROUP(); + test_pack_TOKEN_PRIVILEGES(); + test_pack_TOKEN_SOURCE(); + test_pack_TOKEN_STATISTICS(); + test_pack_TOKEN_USER(); + test_pack_UCHAR(); + test_pack_UHALF_PTR(); + test_pack_UINT(); + test_pack_UINT16(); + test_pack_UINT32(); + test_pack_UINT64(); + test_pack_UINT8(); + test_pack_UINT_PTR(); + test_pack_ULARGE_INTEGER(); + test_pack_ULONG(); + test_pack_ULONG32(); + test_pack_ULONG64(); + test_pack_ULONGLONG(); + test_pack_ULONG_PTR(); + test_pack_USHORT(); + test_pack_WAITORTIMERCALLBACKFUNC(); + test_pack_WCHAR(); + test_pack_WORD(); + test_pack_WPARAM(); +} + +START_TEST(generated) +{ + test_pack(); +} diff --git a/reactos/regtests/winetests/ntdll/info.c b/reactos/regtests/winetests/ntdll/info.c new file mode 100755 index 00000000000..59927126a01 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/info.c @@ -0,0 +1,828 @@ +/* Unit test suite for *Information* Registry API functions + * + * Copyright 2005 Paul Vriens + * + * 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 + * + */ + +#include "ntdll_test.h" + +static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); +static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); + +static HMODULE hntdll = 0; + +/* one_before_last_pid is used to be able to compare values of a still running process + with the output of the test_query_process_times and test_query_process_handlecount tests. +*/ +static DWORD one_before_last_pid = 0; + +#define NTDLL_GET_PROC(func) \ + p ## func = (void*)GetProcAddress(hntdll, #func); \ + if(!p ## func) { \ + trace("GetProcAddress(%s) failed\n", #func); \ + FreeLibrary(hntdll); \ + return FALSE; \ + } + +static BOOL InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + if(!hntdll) { + trace("Could not load ntdll.dll\n"); + return FALSE; + } + if (hntdll) + { + NTDLL_GET_PROC(NtQuerySystemInformation) + NTDLL_GET_PROC(NtQueryInformationProcess) + } + return TRUE; +} + +static void test_query_basic(void) +{ + DWORD status; + ULONG ReturnLength; + SYSTEM_BASIC_INFORMATION sbi; + + /* This test also covers some basic parameter testing that should be the same for + * every information class + */ + + /* Use a nonexistent info class */ + trace("Check nonexistent info class\n"); + status = pNtQuerySystemInformation(-1, NULL, 0, NULL); + ok( status == STATUS_INVALID_INFO_CLASS, "Expected STATUS_INVALID_INFO_CLASS, got %08lx\n", status); + + /* Use an existing class but with a zero-length buffer */ + trace("Check zero-length buffer\n"); + status = pNtQuerySystemInformation(SystemBasicInformation, NULL, 0, NULL); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + /* Use an existing class, correct length but no SystemInformation buffer */ + trace("Check no SystemInformation buffer\n"); + status = pNtQuerySystemInformation(SystemBasicInformation, NULL, sizeof(sbi), NULL); + ok( status == STATUS_ACCESS_VIOLATION, "Expected STATUS_ACCESS_VIOLATION, got %08lx\n", status); + + /* Use a existing class, correct length, a pointer to a buffer but no ReturnLength pointer */ + trace("Check no ReturnLength pointer\n"); + status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + + /* Check a too large buffer size */ + trace("Check a too large buffer size\n"); + status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi) * 2, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + /* Finally some correct calls */ + trace("Check with correct parameters\n"); + status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(sbi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(sbi), ReturnLength); + + /* Check if we have some return values */ + trace("Number of Processors : %d\n", sbi.NumberOfProcessors); + ok( sbi.NumberOfProcessors > 0, "Expected more than 0 processors, got %d\n", sbi.NumberOfProcessors); +} + +static void test_query_cpu(void) +{ + DWORD status; + ULONG ReturnLength; + SYSTEM_CPU_INFORMATION sci; + + status = pNtQuerySystemInformation(SystemCpuInformation, &sci, sizeof(sci), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(sci) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(sci), ReturnLength); + + /* Check if we have some return values */ + trace("Processor FeatureSet : %08lx\n", sci.FeatureSet); + ok( sci.FeatureSet != 0, "Expected some features for this processor, got %08lx\n", sci.FeatureSet); +} + +static void test_query_performance(void) +{ + DWORD status; + ULONG ReturnLength; + SYSTEM_PERFORMANCE_INFORMATION spi; + + status = pNtQuerySystemInformation(SystemPerformanceInformation, &spi, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + status = pNtQuerySystemInformation(SystemPerformanceInformation, &spi, sizeof(spi), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(spi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(spi), ReturnLength); + + status = pNtQuerySystemInformation(SystemPerformanceInformation, &spi, sizeof(spi) + 2, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(spi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(spi), ReturnLength); + + /* Not return values yet, as struct members are unknown */ +} + +static void test_query_timeofday(void) +{ + DWORD status; + ULONG ReturnLength; + + /* Copy of our winternl.h structure turned into a private one */ + typedef struct _SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE { + LARGE_INTEGER liKeBootTime; + LARGE_INTEGER liKeSystemTime; + LARGE_INTEGER liExpTimeZoneBias; + ULONG uCurrentTimeZoneId; + DWORD dwUnknown1[5]; + } SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE, *PSYSTEM_TIMEOFDAY_INFORMATION_PRIVATE; + + SYSTEM_TIMEOFDAY_INFORMATION_PRIVATE sti; + + /* The struct size for NT (32 bytes) and Win2K/XP (48 bytes) differ. + * + * Windows 2000 and XP return STATUS_INFO_LENGTH_MISMATCH if the given buffer size is greater + * then 48 and 0 otherwise + * Windows NT returns STATUS_INFO_LENGTH_MISMATCH when the given buffer size is not correct + * and 0 otherwise + * + * Windows 2000 and XP copy the given buffer size into the provided buffer, if the return code is STATUS_SUCCESS + * NT only fills the buffer if the return code is STATUS_SUCCESS + * + */ + + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, sizeof(sti), &ReturnLength); + + if (status == STATUS_INFO_LENGTH_MISMATCH) + { + trace("Windows version is NT, we have to cater for differences with W2K/WinXP\n"); + + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%ld)\n", ReturnLength); + + sti.uCurrentTimeZoneId = 0xdeadbeef; + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 28, &ReturnLength); + ok( 0xdeadbeef == sti.uCurrentTimeZoneId, "This part of the buffer should not have been filled\n"); + + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 32, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( 32 == ReturnLength, "ReturnLength should be 0, it is (%ld)\n", ReturnLength); + } + else + { + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 0, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%ld)\n", ReturnLength); + + sti.uCurrentTimeZoneId = 0xdeadbeef; + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 24, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( 24 == ReturnLength, "ReturnLength should be 24, it is (%ld)\n", ReturnLength); + ok( 0xdeadbeef == sti.uCurrentTimeZoneId, "This part of the buffer should not have been filled\n"); + + sti.uCurrentTimeZoneId = 0xdeadbeef; + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 32, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( 32 == ReturnLength, "ReturnLength should be 32, it is (%ld)\n", ReturnLength); + ok( 0xdeadbeef != sti.uCurrentTimeZoneId, "Buffer should have been partially filled\n"); + + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, 49, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( 0 == ReturnLength, "ReturnLength should be 0, it is (%ld)\n", ReturnLength); + + status = pNtQuerySystemInformation(SystemTimeOfDayInformation, &sti, sizeof(sti), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(sti) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(sti), ReturnLength); + } + + /* Check if we have some return values */ + trace("uCurrentTimeZoneId : (%ld)\n", sti.uCurrentTimeZoneId); +} + +static void test_query_process(void) +{ + DWORD status; + DWORD last_pid; + ULONG ReturnLength; + int i = 0, j = 0, k = 0; + int is_nt = 0; + SYSTEM_BASIC_INFORMATION sbi; + + /* Copy of our winternl.h structure turned into a private one */ + typedef struct _SYSTEM_PROCESS_INFORMATION_PRIVATE { + DWORD dwOffset; + DWORD dwThreadCount; + DWORD dwUnknown1[6]; + FILETIME ftCreationTime; + FILETIME ftUserTime; + FILETIME ftKernelTime; + UNICODE_STRING ProcessName; + DWORD dwBasePriority; + DWORD dwProcessID; + DWORD dwParentProcessID; + DWORD dwHandleCount; + DWORD dwUnknown3; + DWORD dwUnknown4; + VM_COUNTERS vmCounters; + IO_COUNTERS ioCounters; + SYSTEM_THREAD_INFORMATION ti[1]; + } SYSTEM_PROCESS_INFORMATION_PRIVATE, *PSYSTEM_PROCESS_INFORMATION_PRIVATE; + + ULONG SystemInformationLength = sizeof(SYSTEM_PROCESS_INFORMATION_PRIVATE); + SYSTEM_PROCESS_INFORMATION_PRIVATE* spi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); + + /* Only W2K3 returns the needed length, the rest returns 0, so we have to loop */ + + for (;;) + { + status = pNtQuerySystemInformation(SystemProcessInformation, spi, SystemInformationLength, &ReturnLength); + + if (status != STATUS_INFO_LENGTH_MISMATCH) break; + + spi = HeapReAlloc(GetProcessHeap(), 0, spi , SystemInformationLength *= 2); + } + + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + + /* Get the first dwOffset, from this we can deduce the OS version we're running + * + * W2K/WinXP/W2K3: + * dwOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) + * NT: + * dwOffset for a process is 136 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) + * Wine (with every windows version): + * dwOffset for a process is 0 if just this test is running + * dwOffset for a process is 184 + (no. of threads) * sizeof(SYSTEM_THREAD_INFORMATION) + + * ProcessName.MaximumLength + * if more wine processes are running + * + * Note : On windows the first process is in fact the Idle 'process' with a thread for every processor + */ + + pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); + + is_nt = ( spi->dwOffset - (sbi.NumberOfProcessors * sizeof(SYSTEM_THREAD_INFORMATION)) == 136); + + if (is_nt) trace("Windows version is NT, we will skip thread tests\n"); + + /* Check if we have some return values + * + * On windows there will be several processes running (Including the always present Idle and System) + * On wine we only have one (if this test is the only wine process running) + */ + + /* Loop through the processes */ + + for (;;) + { + i++; + + last_pid = spi->dwProcessID; + + ok( spi->dwThreadCount > 0, "Expected some threads for this process, got 0\n"); + + /* Loop through the threads, skip NT4 for now */ + + if (!is_nt) + { + for ( j = 0; j < spi->dwThreadCount; j++) + { + k++; + ok ( spi->ti[j].dwOwningPID == spi->dwProcessID, + "The owning pid of the thread (%ld) doesn't equal the pid (%ld) of the process\n", + spi->ti[j].dwOwningPID, spi->dwProcessID); + } + } + + if (!spi->dwOffset) break; + + one_before_last_pid = last_pid; + + spi = (SYSTEM_PROCESS_INFORMATION_PRIVATE*)((char*)spi + spi->dwOffset); + } + trace("Total number of running processes : %d\n", i); + if (!is_nt) trace("Total number of running threads : %d\n", k); + + if (one_before_last_pid == 0) one_before_last_pid = last_pid; + + HeapFree( GetProcessHeap(), 0, spi); +} + +static void test_query_procperf(void) +{ + DWORD status; + ULONG ReturnLength; + ULONG NeededLength; + SYSTEM_BASIC_INFORMATION sbi; + SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; + + /* Find out the number of processors */ + status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); + NeededLength = sbi.NumberOfProcessors * sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION); + + sppi = HeapAlloc(GetProcessHeap(), 0, NeededLength); + + status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + /* Try it for 1 processor */ + status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, + sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) == ReturnLength, + "Inconsistent length (%d) <-> (%ld)\n", sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), ReturnLength); + + /* Try it for all processors */ + status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, NeededLength, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( NeededLength == ReturnLength, "Inconsistent length (%ld) <-> (%ld)\n", NeededLength, ReturnLength); + + /* A too large given buffer size */ + sppi = HeapReAlloc(GetProcessHeap(), 0, sppi , NeededLength + 2); + status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, sppi, NeededLength + 2, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( NeededLength == ReturnLength, "Inconsistent length (%ld) <-> (%ld)\n", NeededLength, ReturnLength); + + HeapFree( GetProcessHeap(), 0, sppi); +} + +static void test_query_module(void) +{ + DWORD status; + ULONG ReturnLength; + DWORD ModuleCount; + int i; + + ULONG SystemInformationLength = sizeof(SYSTEM_MODULE_INFORMATION); + SYSTEM_MODULE_INFORMATION* smi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); + SYSTEM_MODULE* sm; + + /* Request the needed length */ + status = pNtQuerySystemInformation(SystemModuleInformation, smi, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( ReturnLength > 0, "Expected a ReturnLength to show the needed length\n"); + + SystemInformationLength = ReturnLength; + smi = HeapReAlloc(GetProcessHeap(), 0, smi , SystemInformationLength); + status = pNtQuerySystemInformation(SystemModuleInformation, smi, SystemInformationLength, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + + ModuleCount = smi->ModulesCount; + sm = &smi->Modules[0]; + todo_wine{ + /* our implementation is a stub for now */ + ok( ModuleCount > 0, "Expected some modules to be loaded\n"); + } + + /* Loop through all the modules/drivers, Wine doesn't get here (yet) */ + for (i = 0; i < ModuleCount ; i++) + { + ok( i == sm->Id, "Id (%d) should have matched %d\n", sm->Id, i); + sm++; + } + + HeapFree( GetProcessHeap(), 0, smi); +} + +static void test_query_handle(void) +{ + DWORD status; + ULONG ReturnLength; + ULONG SystemInformationLength = sizeof(SYSTEM_HANDLE_INFORMATION); + SYSTEM_HANDLE_INFORMATION* shi = HeapAlloc(GetProcessHeap(), 0, SystemInformationLength); + + /* Request the needed length : a SystemInformationLength greater than one struct sets ReturnLength */ + status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); + + /* The following check assumes more than one handle on any given system */ + todo_wine + { + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + } + ok( ReturnLength > 0, "Expected ReturnLength to be > 0, it was %ld\n", ReturnLength); + + SystemInformationLength = ReturnLength; + shi = HeapReAlloc(GetProcessHeap(), 0, shi , SystemInformationLength); + status = pNtQuerySystemInformation(SystemHandleInformation, shi, SystemInformationLength, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + + /* Check if we have some return values */ + trace("Number of Handles : %ld\n", shi->Count); + todo_wine + { + /* our implementation is a stub for now */ + ok( shi->Count > 1, "Expected more than 1 handles, got (%ld)\n", shi->Count); + } + + HeapFree( GetProcessHeap(), 0, shi); +} + +static void test_query_cache(void) +{ + DWORD status; + ULONG ReturnLength; + SYSTEM_CACHE_INFORMATION sci; + + status = pNtQuerySystemInformation(SystemCacheInformation, &sci, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + status = pNtQuerySystemInformation(SystemCacheInformation, &sci, sizeof(sci), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(sci) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(sci), ReturnLength); + + status = pNtQuerySystemInformation(SystemCacheInformation, &sci, sizeof(sci) + 2, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(sci) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(sci), ReturnLength); +} + +static void test_query_interrupt(void) +{ + DWORD status; + ULONG ReturnLength; + ULONG NeededLength; + SYSTEM_BASIC_INFORMATION sbi; + SYSTEM_INTERRUPT_INFORMATION* sii; + + /* Find out the number of processors */ + status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength); + NeededLength = sbi.NumberOfProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION); + + sii = HeapAlloc(GetProcessHeap(), 0, NeededLength); + + status = pNtQuerySystemInformation(SystemInterruptInformation, sii, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + /* Try it for all processors */ + status = pNtQuerySystemInformation(SystemInterruptInformation, sii, NeededLength, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + + /* Windows XP and W2K3 (and others?) always return 0 for the ReturnLength + * No test added for this as it's highly unlikely that an app depends on this + */ + + HeapFree( GetProcessHeap(), 0, sii); +} + +static void test_query_kerndebug(void) +{ + DWORD status; + ULONG ReturnLength; + SYSTEM_KERNEL_DEBUGGER_INFORMATION skdi; + + status = pNtQuerySystemInformation(SystemKernelDebuggerInformation, &skdi, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + status = pNtQuerySystemInformation(SystemKernelDebuggerInformation, &skdi, sizeof(skdi), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(skdi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(skdi), ReturnLength); + + status = pNtQuerySystemInformation(SystemKernelDebuggerInformation, &skdi, sizeof(skdi) + 2, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(skdi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(skdi), ReturnLength); +} + +static void test_query_regquota(void) +{ + DWORD status; + ULONG ReturnLength; + SYSTEM_REGISTRY_QUOTA_INFORMATION srqi; + + status = pNtQuerySystemInformation(SystemRegistryQuotaInformation, &srqi, 0, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + status = pNtQuerySystemInformation(SystemRegistryQuotaInformation, &srqi, sizeof(srqi), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(srqi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(srqi), ReturnLength); + + status = pNtQuerySystemInformation(SystemRegistryQuotaInformation, &srqi, sizeof(srqi) + 2, &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(srqi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(srqi), ReturnLength); +} + +static void test_query_process_basic(void) +{ + DWORD status; + ULONG ReturnLength; + + typedef struct _PROCESS_BASIC_INFORMATION_PRIVATE { + DWORD ExitStatus; + DWORD PebBaseAddress; + DWORD AffinityMask; + DWORD BasePriority; + ULONG UniqueProcessId; + ULONG InheritedFromUniqueProcessId; + } PROCESS_BASIC_INFORMATION_PRIVATE, *PPROCESS_BASIC_INFORMATION_PRIVATE; + + PROCESS_BASIC_INFORMATION_PRIVATE pbi; + + /* This test also covers some basic parameter testing that should be the same for + * every information class + */ + + /* Use a nonexistent info class */ + trace("Check nonexistent info class\n"); + status = pNtQueryInformationProcess(NULL, -1, NULL, 0, NULL); + ok( status == STATUS_INVALID_INFO_CLASS, "Expected STATUS_INVALID_INFO_CLASS, got %08lx\n", status); + + /* Do not give a handle and buffer */ + trace("Check NULL handle and buffer and zero-length buffersize\n"); + status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, NULL, 0, NULL); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + /* Use a correct info class and buffer size, but still no handle and buffer */ + trace("Check NULL handle and buffer\n"); + status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, NULL, sizeof(pbi), NULL); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status); + + /* Use a correct info class and buffer size, but still no handle */ + trace("Check NULL handle\n"); + status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, &pbi, sizeof(pbi), NULL); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status); + + /* Use a greater buffer size */ + trace("Check NULL handle and too large buffersize\n"); + status = pNtQueryInformationProcess(NULL, ProcessBasicInformation, &pbi, sizeof(pbi) * 2, NULL); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + /* Use no ReturnLength */ + trace("Check NULL ReturnLength\n"); + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + + /* Finally some correct calls */ + trace("Check with correct parameters\n"); + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(pbi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(pbi), ReturnLength); + + /* Everything is correct except a too large buffersize */ + trace("Too large buffersize\n"); + status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi) * 2, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( sizeof(pbi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(pbi), ReturnLength); + + /* Check if we have some return values */ + trace("ProcessID : %ld\n", pbi.UniqueProcessId); + ok( pbi.UniqueProcessId > 0, "Expected a ProcessID > 0, got 0\n"); +} + +static void test_query_process_vm(void) +{ + DWORD status; + ULONG ReturnLength; + VM_COUNTERS pvi; + + status = pNtQueryInformationProcess(NULL, ProcessVmCounters, NULL, sizeof(pvi), NULL); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status); + + status = pNtQueryInformationProcess(NULL, ProcessVmCounters, &pvi, sizeof(pvi), NULL); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status); + + /* Windows XP and W2K3 will report success for a size of 44 AND 48 ! + Windows W2K will only report success for 44. + For now we only care for 44, which is sizeof(VM_COUNTERS) + If an app depends on it, we have to implement this in ntdll/process.c + */ + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, 24, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, sizeof(pvi), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(pvi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(pvi), ReturnLength); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessVmCounters, &pvi, 46, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( sizeof(pvi) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(pvi), ReturnLength); + + /* Check if we have some return values */ + trace("WorkingSetSize : %ld\n", pvi.WorkingSetSize); + todo_wine + { + ok( pvi.WorkingSetSize > 0, "Expected a WorkingSetSize > 0\n"); + } +} + +static void test_query_process_io(void) +{ + DWORD status; + ULONG ReturnLength; + IO_COUNTERS pii; + + /* NT4 doesn't support this information class, so check for it */ + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, sizeof(pii), &ReturnLength); + if (status == STATUS_NOT_SUPPORTED) + { + trace("ProcessIoCounters information class not supported, skipping tests\n"); + return; + } + + status = pNtQueryInformationProcess(NULL, ProcessIoCounters, NULL, sizeof(pii), NULL); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status); + + status = pNtQueryInformationProcess(NULL, ProcessIoCounters, &pii, sizeof(pii), NULL); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, 24, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, sizeof(pii), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(pii) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(pii), ReturnLength); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessIoCounters, &pii, sizeof(pii) * 2, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( sizeof(pii) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(pii), ReturnLength); + + /* Check if we have some return values */ + trace("OtherOperationCount : %lld\n", pii.OtherOperationCount); + todo_wine + { + ok( pii.OtherOperationCount > 0, "Expected an OtherOperationCount > 0\n"); + } +} + +static void test_query_process_times(void) +{ + DWORD status; + ULONG ReturnLength; + HANDLE process; + SYSTEMTIME UTC, Local; + KERNEL_USER_TIMES spti; + + status = pNtQueryInformationProcess(NULL, ProcessTimes, NULL, sizeof(spti), NULL); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status); + + status = pNtQueryInformationProcess(NULL, ProcessTimes, &spti, sizeof(spti), NULL); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes, &spti, 24, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, one_before_last_pid); + if (!process) + { + trace("Could not open process with ID : %ld, error : %08lx. Going to use current one.\n", one_before_last_pid, GetLastError()); + process = GetCurrentProcess(); + trace("ProcessTimes for current process\n"); + } + else + trace("ProcessTimes for process with ID : %ld\n", one_before_last_pid); + + status = pNtQueryInformationProcess( process, ProcessTimes, &spti, sizeof(spti), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(spti) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(spti), ReturnLength); + CloseHandle(process); + + FileTimeToSystemTime((const FILETIME *)&spti.CreateTime, &UTC); + SystemTimeToTzSpecificLocalTime(NULL, &UTC, &Local); + trace("CreateTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local.wMonth, Local.wDay, Local.wYear, + Local.wHour, Local.wMinute, Local.wSecond); + + FileTimeToSystemTime((const FILETIME *)&spti.ExitTime, &UTC); + SystemTimeToTzSpecificLocalTime(NULL, &UTC, &Local); + trace("ExitTime : %02d/%02d/%04d %02d:%02d:%02d\n", Local.wMonth, Local.wDay, Local.wYear, + Local.wHour, Local.wMinute, Local.wSecond); + + FileTimeToSystemTime((const FILETIME *)&spti.KernelTime, &Local); + trace("KernelTime : %02d:%02d:%02d.%03d\n", Local.wHour, Local.wMinute, Local.wSecond, Local.wMilliseconds); + + FileTimeToSystemTime((const FILETIME *)&spti.UserTime, &Local); + trace("UserTime : %02d:%02d:%02d.%03d\n", Local.wHour, Local.wMinute, Local.wSecond, Local.wMilliseconds); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessTimes, &spti, sizeof(spti) * 2, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( sizeof(spti) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(spti), ReturnLength); +} + +static void test_query_process_handlecount(void) +{ + DWORD status; + ULONG ReturnLength; + DWORD handlecount; + HANDLE process; + + status = pNtQueryInformationProcess(NULL, ProcessHandleCount, NULL, sizeof(handlecount), NULL); + ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE, + "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE(W2K3), got %08lx\n", status); + + status = pNtQueryInformationProcess(NULL, ProcessHandleCount, &handlecount, sizeof(handlecount), NULL); + ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08lx\n", status); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount, &handlecount, 2, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + + process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, one_before_last_pid); + trace("Handlecount for process with ID : %ld\n", one_before_last_pid); + status = pNtQueryInformationProcess( process, ProcessHandleCount, &handlecount, sizeof(handlecount), &ReturnLength); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08lx\n", status); + ok( sizeof(handlecount) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(handlecount), ReturnLength); + CloseHandle(process); + + status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessHandleCount, &handlecount, sizeof(handlecount) * 2, &ReturnLength); + ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08lx\n", status); + ok( sizeof(handlecount) == ReturnLength, "Inconsistent length (%d) <-> (%ld)\n", sizeof(handlecount), ReturnLength); + + /* Check if we have some return values */ + trace("HandleCount : %ld\n", handlecount); + todo_wine + { + ok( handlecount > 0, "Expected some handles, got 0\n"); + } +} + +START_TEST(info) +{ + if(!InitFunctionPtrs()) + return; + + /* NtQuerySystemInformation */ + + /* 0x0 SystemBasicInformation */ + trace("Starting test_query_basic()\n"); + test_query_basic(); + + /* 0x1 SystemCpuInformation */ + trace("Starting test_query_cpu()\n"); + test_query_cpu(); + + /* 0x2 SystemPerformanceInformation */ + trace("Starting test_query_performance()\n"); + test_query_performance(); + + /* 0x3 SystemTimeOfDayInformation */ + trace("Starting test_query_timeofday()\n"); + test_query_timeofday(); + + /* 0x5 SystemProcessInformation */ + trace("Starting test_query_process()\n"); + test_query_process(); + + /* 0x8 SystemProcessorPerformanceInformation */ + trace("Starting test_query_procperf()\n"); + test_query_procperf(); + + /* 0xb SystemModuleInformation */ + trace("Starting test_query_module()\n"); + test_query_module(); + + /* 0x10 SystemHandleInformation */ + trace("Starting test_query_handle()\n"); + test_query_handle(); + + /* 0x15 SystemCacheInformation */ + trace("Starting test_query_cache()\n"); + test_query_cache(); + + /* 0x17 SystemInterruptInformation */ + trace("Starting test_query_interrupt()\n"); + test_query_interrupt(); + + /* 0x23 SystemKernelDebuggerInformation */ + trace("Starting test_query_kerndebug()\n"); + test_query_kerndebug(); + + /* 0x25 SystemRegistryQuotaInformation */ + trace("Starting test_query_regquota()\n"); + test_query_regquota(); + + /* NtQueryInformationProcess */ + + /* 0x0 ProcessBasicInformation */ + trace("Starting test_query_process_basic()\n"); + test_query_process_basic(); + + /* 0x2 ProcessIoCounters */ + trace("Starting test_query_process_io()\n"); + test_query_process_io(); + + /* 0x3 ProcessVmCounters */ + trace("Starting test_query_process_vm()\n"); + test_query_process_vm(); + + /* 0x4 ProcessTimes */ + trace("Starting test_query_process_times()\n"); + test_query_process_times(); + + /* 0x14 ProcessHandleCount */ + trace("Starting test_query_process_handlecount()\n"); + test_query_process_handlecount(); + + FreeLibrary(hntdll); +} diff --git a/reactos/regtests/winetests/ntdll/large_int.c b/reactos/regtests/winetests/ntdll/large_int.c new file mode 100755 index 00000000000..006fda407c0 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/large_int.c @@ -0,0 +1,423 @@ +/* Unit test suite for Rtl large integer 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 + +#include "ntdll_test.h" + + +/* Function ptrs for ntdll calls */ +static HMODULE hntdll = 0; +static LONGLONG (WINAPI *pRtlExtendedMagicDivide)(LONGLONG, LONGLONG, INT); +static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING); +static NTSTATUS (WINAPI *pRtlInt64ToUnicodeString)(ULONGLONG, ULONG, UNICODE_STRING *); +static NTSTATUS (WINAPI *pRtlLargeIntegerToChar)(ULONGLONG *, ULONG, ULONG, PCHAR); +static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN); + + +static void InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + ok(hntdll != 0, "LoadLibrary failed\n"); + if (hntdll) { + pRtlExtendedMagicDivide = (void *)GetProcAddress(hntdll, "RtlExtendedMagicDivide"); + pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString"); + pRtlInt64ToUnicodeString = (void *)GetProcAddress(hntdll, "RtlInt64ToUnicodeString"); + pRtlLargeIntegerToChar = (void *)GetProcAddress(hntdll, "RtlLargeIntegerToChar"); + pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString"); + } /* if */ +} + +#define ULL(a,b) (((ULONGLONG)(a) << 32) | (b)) + +typedef struct { + LONGLONG a; + LONGLONG b; + INT shift; + LONGLONG result; +} magic_divide_t; + +static const magic_divide_t magic_divide[] = { + { 3, ULL(0x55555555,0x55555555), 0, 0}, /* 1 */ + { 333333333, ULL(0x55555555,0x55555555), 0, 111111110}, /* 111111111 */ + { ULL(0x7fffffff,0xffffffff), ULL(0x55555555,0x55555555), 0, ULL(0x2aaaaaaa,0xaaaaaaaa)}, + { 3, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* 1 */ + { 333333333, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 111111110}, /* 111111111 */ + { ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaaaaa), 1, ULL(0x2aaaaaaa,0xaaaaaaaa)}, + { -3, ULL(0x55555555,0x55555555), 0, 0}, /* -1 */ + { -333333333, ULL(0x55555555,0x55555555), 0, -111111110}, /* -111111111 */ + {-ULL(0x7fffffff,0xffffffff), ULL(0x55555555,0x55555555), 0, -ULL(0x2aaaaaaa,0xaaaaaaaa)}, + { -3, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */ + { -333333333, ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -111111110}, /* -111111111 */ + {-ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -ULL(0x2aaaaaaa,0xaaaaaaaa)}, + { -3, -ULL(0x55555555,0x55555555), 0, -2}, /* -1 */ + { -333333333, -ULL(0x55555555,0x55555555), 0, -222222222}, /* -111111111 */ + {-ULL(0x7fffffff,0xffffffff), -ULL(0x55555555,0x55555555), 0, -ULL(0x55555555,0x55555554)}, + { -3, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */ + { -333333333, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -55555555}, /* -111111111 */ + {-ULL(0x7fffffff,0xffffffff), -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, -ULL(0x15555555,0x55555555)}, + { 3, -ULL(0x55555555,0x55555555), 0, 2}, /* -1 */ + { 333333333, -ULL(0x55555555,0x55555555), 0, 222222222}, /* -111111111 */ + { ULL(0x7fffffff,0xffffffff), -ULL(0x55555555,0x55555555), 0, ULL(0x55555555,0x55555554)}, + { 3, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 0}, /* -1 */ + { 333333333, -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, 55555555}, /* -111111111 */ + { ULL(0x7fffffff,0xffffffff), -ULL(0xaaaaaaaa,0xaaaaaaaa), 1, ULL(0x15555555,0x55555555)}, + { 3, ULL(0xaaaaaaaa,0xaaaaa800), 1, 0}, /* 1 */ + { 333333333, ULL(0xaaaaaaaa,0xaaaaa800), 1, 111111110}, /* 111111111 */ + { ULL(0x7fffffff,0xffffffff), ULL(0xaaaaaaaa,0xaaaaa800), 1, ULL(0x2aaaaaaa,0xaaaaa9ff)}, /* 0x2aaaaaaaaaaaaaaa */ + { 5, ULL(0x33333333,0x333333ff), 0, 1}, + { 555555555, ULL(0x33333333,0x333333ff), 0, 111111111}, + { ULL(0x7fffffff,0xffffffff), ULL(0x33333333,0x333333ff), 0, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */ + { 5, ULL(0x66666666,0x666667fe), 1, 1}, + { 555555555, ULL(0x66666666,0x666667fe), 1, 111111111}, + { ULL(0x7fffffff,0xffffffff), ULL(0x66666666,0x666667fe), 1, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */ + { 5, ULL(0xcccccccc,0xcccccffd), 2, 1}, + { 555555555, ULL(0xcccccccc,0xcccccffd), 2, 111111111}, + { ULL(0x7fffffff,0xffffffff), ULL(0xcccccccc,0xcccccffd), 2, ULL(0x19999999,0x999999ff)}, /* 0x199999999999999a */ + { ULL(0x00000add,0xcafeface), ULL(0x002f1e28,0xfd1b5cca), 33, 1}, + { ULL(0x081ac1b9,0xc2310a80), ULL(0x002f1e28,0xfd1b5cca), 33, 0xbeef}, + { ULL(0x74ae3b5f,0x1558c800), ULL(0x002f1e28,0xfd1b5cca), 33, 0xabcde}, + { ULL(0x00000add,0xcafeface), ULL(0x2f1e28fd,0x1b5cca00), 41, 1}, + { ULL(0x081ac1b9,0xc2310a80), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xbeef}, + { ULL(0x74ae3b5f,0x1558c800), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xabcde}, + +}; +#define NB_MAGIC_DIVIDE (sizeof(magic_divide)/sizeof(*magic_divide)) + + +static void test_RtlExtendedMagicDivide(void) +{ + int i; + LONGLONG result; + + for (i = 0; i < NB_MAGIC_DIVIDE; i++) { + result = pRtlExtendedMagicDivide(magic_divide[i].a, magic_divide[i].b, magic_divide[i].shift); + ok(result == magic_divide[i].result, + "call failed: RtlExtendedMagicDivide(%lld, %llu, %d) has result %llx, expected %llx\n", + magic_divide[i].a, magic_divide[i].b, magic_divide[i].shift, result, magic_divide[i].result); + } +} + + +#define LARGE_STRI_BUFFER_LENGTH 67 + +typedef struct { + int base; + ULONGLONG value; + USHORT Length; + USHORT MaximumLength; + const char *Buffer; + NTSTATUS result; +} largeint2str_t; + +/* + * The native DLL does produce garbage or STATUS_BUFFER_OVERFLOW for + * base 2, 8 and 16 when the value is larger than 0xFFFFFFFF. + * Therefore these testcases are commented out. + */ + +static const largeint2str_t largeint2str[] = { + {10, 123, 3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS}, + + { 0, 0x80000000U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS}, + { 0, -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS}, + { 0, -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS}, + { 0, 0, 1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 1, 1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 12, 2, 11, "12\0----------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 123, 3, 11, "123\0---------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 1234, 4, 11, "1234\0--------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 12345, 5, 11, "12345\0-------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 123456, 6, 11, "123456\0------------------------------------------------------------", STATUS_SUCCESS}, + { 0, 1234567, 7, 11, "1234567\0-----------------------------------------------------------", STATUS_SUCCESS}, + { 0, 12345678, 8, 11, "12345678\0----------------------------------------------------------", STATUS_SUCCESS}, + { 0, 123456789, 9, 11, "123456789\0---------------------------------------------------------", STATUS_SUCCESS}, + { 0, 2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, 2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, 2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, 2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, 4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, 4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0x2,0xdfdc1c35), 11, 12, "12345678901\0-------------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0xe5,0xf4c8f374), 12, 13, "987654321012\0------------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0x1c0,0xfc161e3e), 13, 14, "1928374656574\0-----------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0xbad,0xcafeface), 14, 15, "12841062955726\0----------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0x5bad,0xcafeface), 15, 16, "100801993177806\0---------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0xaface,0xbeefcafe), 16, 20, "3090515640699646\0--------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0xa5beef,0xabcdcafe), 17, 20, "46653307746110206\0-------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0x1f8cf9b,0xf2df3af1), 18, 20, "142091656963767025\0------------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0x0fffffff,0xffffffff), 19, 20, "1152921504606846975\0-----------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0xffffffff,0xfffffffe), 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS}, + { 0, ULL(0xffffffff,0xffffffff), 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS}, + + { 2, 0x80000000U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS}, +/* + * { 2, -2147483647, 64, 65, "1111111111111111111111111111111110000000000000000000000000000001\0--", STATUS_SUCCESS}, + * { 2, -2, 64, 65, "1111111111111111111111111111111111111111111111111111111111111110\0--", STATUS_SUCCESS}, + * { 2, -1, 64, 65, "1111111111111111111111111111111111111111111111111111111111111111\0--", STATUS_SUCCESS}, + */ + { 2, 0, 1, 33, "0\0-----------------------------------------------------------------", STATUS_SUCCESS}, + { 2, 1, 1, 33, "1\0-----------------------------------------------------------------", STATUS_SUCCESS}, + { 2, 10, 4, 33, "1010\0--------------------------------------------------------------", STATUS_SUCCESS}, + { 2, 100, 7, 33, "1100100\0-----------------------------------------------------------", STATUS_SUCCESS}, + { 2, 1000, 10, 33, "1111101000\0--------------------------------------------------------", STATUS_SUCCESS}, + { 2, 10000, 14, 33, "10011100010000\0----------------------------------------------------", STATUS_SUCCESS}, + { 2, 32767, 15, 33, "111111111111111\0---------------------------------------------------", STATUS_SUCCESS}, + { 2, 32768, 16, 33, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS}, + { 2, 65535, 16, 33, "1111111111111111\0--------------------------------------------------", STATUS_SUCCESS}, + { 2, 100000, 17, 33, "11000011010100000\0-------------------------------------------------", STATUS_SUCCESS}, + { 2, 1000000, 20, 33, "11110100001001000000\0----------------------------------------------", STATUS_SUCCESS}, + { 2, 10000000, 24, 33, "100110001001011010000000\0------------------------------------------", STATUS_SUCCESS}, + { 2, 100000000, 27, 33, "101111101011110000100000000\0---------------------------------------", STATUS_SUCCESS}, + { 2, 1000000000, 30, 33, "111011100110101100101000000000\0------------------------------------", STATUS_SUCCESS}, + { 2, 1073741823, 30, 33, "111111111111111111111111111111\0------------------------------------", STATUS_SUCCESS}, + { 2, 2147483646, 31, 33, "1111111111111111111111111111110\0-----------------------------------", STATUS_SUCCESS}, + { 2, 2147483647, 31, 33, "1111111111111111111111111111111\0-----------------------------------", STATUS_SUCCESS}, + { 2, 2147483648U, 32, 33, "10000000000000000000000000000000\0----------------------------------", STATUS_SUCCESS}, + { 2, 2147483649U, 32, 33, "10000000000000000000000000000001\0----------------------------------", STATUS_SUCCESS}, + { 2, 4294967294U, 32, 33, "11111111111111111111111111111110\0----------------------------------", STATUS_SUCCESS}, + { 2, 0xFFFFFFFF, 32, 33, "11111111111111111111111111111111\0----------------------------------", STATUS_SUCCESS}, +/* + * { 2, 0x1FFFFFFFF, 33, 34, "111111111111111111111111111111111\0---------------------------------", STATUS_SUCCESS}, + * { 2, 0x3FFFFFFFF, 34, 35, "1111111111111111111111111111111111\0--------------------------------", STATUS_SUCCESS}, + * { 2, 0x7FFFFFFFF, 35, 36, "11111111111111111111111111111111111\0-------------------------------", STATUS_SUCCESS}, + * { 2, 0xFFFFFFFFF, 36, 37, "111111111111111111111111111111111111\0------------------------------", STATUS_SUCCESS}, + * { 2, 0x1FFFFFFFFF, 37, 38, "1111111111111111111111111111111111111\0-----------------------------", STATUS_SUCCESS}, + * { 2, 0x3FFFFFFFFF, 38, 39, "11111111111111111111111111111111111111\0----------------------------", STATUS_SUCCESS}, + * { 2, 0x7FFFFFFFFF, 39, 40, "111111111111111111111111111111111111111\0---------------------------", STATUS_SUCCESS}, + * { 2, 0xFFFFFFFFFF, 40, 41, "1111111111111111111111111111111111111111\0--------------------------", STATUS_SUCCESS}, + */ + + { 8, 0x80000000U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS}, +/* + * { 8, -2147483647, 22, 23, "1777777777760000000001\0--------------------------------------------", STATUS_SUCCESS}, + * { 8, -2, 22, 23, "1777777777777777777776\0--------------------------------------------", STATUS_SUCCESS}, + * { 8, -1, 22, 23, "1777777777777777777777\0--------------------------------------------", STATUS_SUCCESS}, + */ + { 8, 0, 1, 12, "0\0-----------------------------------------------------------------", STATUS_SUCCESS}, + { 8, 1, 1, 12, "1\0-----------------------------------------------------------------", STATUS_SUCCESS}, + { 8, 2147483646, 11, 12, "17777777776\0-------------------------------------------------------", STATUS_SUCCESS}, + { 8, 2147483647, 11, 12, "17777777777\0-------------------------------------------------------", STATUS_SUCCESS}, + { 8, 2147483648U, 11, 12, "20000000000\0-------------------------------------------------------", STATUS_SUCCESS}, + { 8, 2147483649U, 11, 12, "20000000001\0-------------------------------------------------------", STATUS_SUCCESS}, + { 8, 4294967294U, 11, 12, "37777777776\0-------------------------------------------------------", STATUS_SUCCESS}, + { 8, 4294967295U, 11, 12, "37777777777\0-------------------------------------------------------", STATUS_SUCCESS}, + + {10, 0x80000000U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS}, + {10, -2147483647, 20, 21, "18446744071562067969\0----------------------------------------------", STATUS_SUCCESS}, + {10, -2, 20, 21, "18446744073709551614\0----------------------------------------------", STATUS_SUCCESS}, + {10, -1, 20, 21, "18446744073709551615\0----------------------------------------------", STATUS_SUCCESS}, + {10, 0, 1, 11, "0\0-----------------------------------------------------------------", STATUS_SUCCESS}, + {10, 1, 1, 11, "1\0-----------------------------------------------------------------", STATUS_SUCCESS}, + {10, 2147483646, 10, 11, "2147483646\0--------------------------------------------------------", STATUS_SUCCESS}, + {10, 2147483647, 10, 11, "2147483647\0--------------------------------------------------------", STATUS_SUCCESS}, + {10, 2147483648U, 10, 11, "2147483648\0--------------------------------------------------------", STATUS_SUCCESS}, + {10, 2147483649U, 10, 11, "2147483649\0--------------------------------------------------------", STATUS_SUCCESS}, + {10, 4294967294U, 10, 11, "4294967294\0--------------------------------------------------------", STATUS_SUCCESS}, + {10, 4294967295U, 10, 11, "4294967295\0--------------------------------------------------------", STATUS_SUCCESS}, + + {16, 0, 1, 9, "0\0-----------------------------------------------------------------", STATUS_SUCCESS}, + {16, 1, 1, 9, "1\0-----------------------------------------------------------------", STATUS_SUCCESS}, + {16, 2147483646, 8, 9, "7FFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS}, + {16, 2147483647, 8, 9, "7FFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS}, + {16, 0x80000000, 8, 9, "80000000\0----------------------------------------------------------", STATUS_SUCCESS}, + {16, 0x80000001, 8, 9, "80000001\0----------------------------------------------------------", STATUS_SUCCESS}, + {16, 0xFFFFFFFE, 8, 9, "FFFFFFFE\0----------------------------------------------------------", STATUS_SUCCESS}, + {16, 0xFFFFFFFF, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS}, +/* + * {16, 0x100000000, 9, 10, "100000000\0---------------------------------------------------------", STATUS_SUCCESS}, + * {16, 0xBADDEADBEEF, 11, 12, "BADDEADBEEF\0-------------------------------------------------------", STATUS_SUCCESS}, + * {16, 0x8000000000000000, 16, 17, "8000000000000000\0--------------------------------------------------", STATUS_SUCCESS}, + * {16, 0xFEDCBA9876543210, 16, 17, "FEDCBA9876543210\0--------------------------------------------------", STATUS_SUCCESS}, + * {16, 0xFFFFFFFF80000001, 16, 17, "FFFFFFFF80000001\0--------------------------------------------------", STATUS_SUCCESS}, + * {16, 0xFFFFFFFFFFFFFFFE, 16, 17, "FFFFFFFFFFFFFFFE\0--------------------------------------------------", STATUS_SUCCESS}, + * {16, 0xFFFFFFFFFFFFFFFF, 16, 17, "FFFFFFFFFFFFFFFF\0--------------------------------------------------", STATUS_SUCCESS}, + */ + + { 2, 32768, 16, 17, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS}, + { 2, 32768, 16, 16, "1000000000000000---------------------------------------------------", STATUS_SUCCESS}, + { 2, 65536, 17, 18, "10000000000000000\0-------------------------------------------------", STATUS_SUCCESS}, + { 2, 65536, 17, 17, "10000000000000000--------------------------------------------------", STATUS_SUCCESS}, + { 2, 131072, 18, 19, "100000000000000000\0------------------------------------------------", STATUS_SUCCESS}, + { 2, 131072, 18, 18, "100000000000000000-------------------------------------------------", STATUS_SUCCESS}, + {16, 0xffffffff, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS}, + {16, 0xffffffff, 8, 8, "FFFFFFFF-----------------------------------------------------------", STATUS_SUCCESS}, + {16, 0xffffffff, 8, 7, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW}, + {16, 0xa, 1, 2, "A\0-----------------------------------------------------------------", STATUS_SUCCESS}, + {16, 0xa, 1, 1, "A------------------------------------------------------------------", STATUS_SUCCESS}, + {16, 0, 1, 0, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW}, + {20, 0xdeadbeef, 0, 9, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER}, + {-8, 07654321, 0, 12, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER}, +}; +#define NB_LARGEINT2STR (sizeof(largeint2str)/sizeof(*largeint2str)) + + +static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t *largeint2str) +{ + int pos; + WCHAR expected_str_Buffer[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING expected_unicode_string; + STRING expected_ansi_str; + WCHAR str_Buffer[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + NTSTATUS result; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_str_Buffer[pos] = largeint2str->Buffer[pos]; + } /* for */ + expected_unicode_string.Length = largeint2str->Length * sizeof(WCHAR); + expected_unicode_string.MaximumLength = largeint2str->MaximumLength * sizeof(WCHAR); + expected_unicode_string.Buffer = expected_str_Buffer; + pRtlUnicodeStringToAnsiString(&expected_ansi_str, &expected_unicode_string, 1); + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + str_Buffer[pos] = '-'; + } /* for */ + unicode_string.Length = 0; + unicode_string.MaximumLength = largeint2str->MaximumLength * sizeof(WCHAR); + unicode_string.Buffer = str_Buffer; + + if (largeint2str->base == 0) { + result = pRtlInt64ToUnicodeString(largeint2str->value, 10, &unicode_string); + } else { + result = pRtlInt64ToUnicodeString(largeint2str->value, largeint2str->base, &unicode_string); + } /* if */ + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + if (result == STATUS_BUFFER_OVERFLOW) { + /* On BUFFER_OVERFLOW the string Buffer should be unchanged */ + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_str_Buffer[pos] = '-'; + } /* for */ + /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */ + /* If the value is too large to convert: The Length is unchanged */ + /* If str is too small to hold the string: Set str->Length to the length */ + /* the string would have (which can be larger than the MaximumLength). */ + /* To allow all this in the tests we do the following: */ + if (expected_unicode_string.Length >= 64) { + /* The value is too large to convert only triggerd when testing native */ + /* Length is not filled with the expected string length (garbage?) */ + expected_unicode_string.Length = unicode_string.Length; + } /* if */ + } else { + ok(result == largeint2str->result, + "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) has result %lx, expected: %lx\n", + test_num, largeint2str->value, largeint2str->base, result, largeint2str->result); + if (result == STATUS_SUCCESS) { + ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0', + "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) string \"%s\" is not NULL terminated\n", + test_num, largeint2str->value, largeint2str->base, ansi_str.Buffer); + } /* if */ + } /* if */ + ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) assigns string \"%s\", expected: \"%s\"\n", + test_num, largeint2str->value, largeint2str->base, ansi_str.Buffer, expected_ansi_str.Buffer); + ok(unicode_string.Length == expected_unicode_string.Length, + "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) string has Length %d, expected: %d\n", + test_num, largeint2str->value, largeint2str->base, unicode_string.Length, expected_unicode_string.Length); + ok(unicode_string.MaximumLength == expected_unicode_string.MaximumLength, + "(test %d): RtlInt64ToUnicodeString(%llu, %d, [out]) string has MaximumLength %d, expected: %d\n", + test_num, largeint2str->value, largeint2str->base, unicode_string.MaximumLength, expected_unicode_string.MaximumLength); + pRtlFreeAnsiString(&expected_ansi_str); + pRtlFreeAnsiString(&ansi_str); +} + + +static void test_RtlInt64ToUnicodeString(void) +{ + int test_num; + + for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) { + one_RtlInt64ToUnicodeString_test(test_num, &largeint2str[test_num]); + } /* for */ +} + + +static void one_RtlLargeIntegerToChar_test(int test_num, const largeint2str_t *largeint2str) +{ + NTSTATUS result; + char dest_str[LARGE_STRI_BUFFER_LENGTH + 1]; + ULONGLONG value; + + memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH); + dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0'; + value = largeint2str->value; + if (largeint2str->base == 0) { + result = pRtlLargeIntegerToChar(&value, 10, largeint2str->MaximumLength, dest_str); + } else { + result = pRtlLargeIntegerToChar(&value, largeint2str->base, largeint2str->MaximumLength, dest_str); + } /* if */ + ok(result == largeint2str->result, + "(test %d): RtlLargeIntegerToChar(%llu, %d, %d, [out]) has result %lx, expected: %lx\n", + test_num, largeint2str->value, largeint2str->base, largeint2str->MaximumLength, result, largeint2str->result); + ok(memcmp(dest_str, largeint2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): RtlLargeIntegerToChar(%llu, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n", + test_num, largeint2str->value, largeint2str->base, largeint2str->MaximumLength, dest_str, largeint2str->Buffer); +} + + +static void test_RtlLargeIntegerToChar(void) +{ + NTSTATUS result; + int test_num; + ULONGLONG value; + + for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) { + one_RtlLargeIntegerToChar_test(test_num, &largeint2str[test_num]); + } /* for */ + + value = largeint2str[0].value; + result = pRtlLargeIntegerToChar(&value, 20, largeint2str[0].MaximumLength, NULL); + ok(result == STATUS_INVALID_PARAMETER, + "(test a): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n", + largeint2str[0].value, 20, largeint2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER); + + result = pRtlLargeIntegerToChar(&value, 20, 0, NULL); + ok(result == STATUS_INVALID_PARAMETER, + "(test b): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n", + largeint2str[0].value, 20, largeint2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER); + + result = pRtlLargeIntegerToChar(&value, largeint2str[0].base, 0, NULL); + ok(result == STATUS_BUFFER_OVERFLOW, + "(test c): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n", + largeint2str[0].value, largeint2str[0].base, 0, result, STATUS_BUFFER_OVERFLOW); + + result = pRtlLargeIntegerToChar(&value, largeint2str[0].base, largeint2str[0].MaximumLength, NULL); + ok(result == STATUS_ACCESS_VIOLATION, + "(test d): RtlLargeIntegerToChar(%llu, %d, %d, NULL) has result %lx, expected: %x\n", + largeint2str[0].value, largeint2str[0].base, largeint2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION); +} + + +START_TEST(large_int) +{ + InitFunctionPtrs(); + + if (pRtlExtendedMagicDivide) + test_RtlExtendedMagicDivide(); + if (pRtlInt64ToUnicodeString) + test_RtlInt64ToUnicodeString(); + if (pRtlLargeIntegerToChar) + test_RtlLargeIntegerToChar(); +} diff --git a/reactos/regtests/winetests/ntdll/ntdll_test.h b/reactos/regtests/winetests/ntdll/ntdll_test.h new file mode 100755 index 00000000000..d083729c03f --- /dev/null +++ b/reactos/regtests/winetests/ntdll/ntdll_test.h @@ -0,0 +1,35 @@ +/* + * Unit test suite for ntdll path functions + * + * Copyright 2003 Eric Pouech + * + * 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 + */ + +#include + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x500 /* For NTSTATUS */ +#endif + +#include "ntstatus.h" +#define WIN32_NO_STATUS +#include "windef.h" +#include "winbase.h" +#include "winnt.h" +#include "winreg.h" +#include "winternl.h" + +#include "wine/test.h" diff --git a/reactos/regtests/winetests/ntdll/ntdll_test.xml b/reactos/regtests/winetests/ntdll/ntdll_test.xml new file mode 100644 index 00000000000..f8a2925890a --- /dev/null +++ b/reactos/regtests/winetests/ntdll/ntdll_test.xml @@ -0,0 +1,18 @@ + + . + + ntdll + atom.c + env.c + error.c + info.c + large_int.c + path.c + reg.c + rtlbitmap.c + rtl.c + rtlstr.c + string.c + time.c + testlist.c + diff --git a/reactos/regtests/winetests/ntdll/path.c b/reactos/regtests/winetests/ntdll/path.c new file mode 100755 index 00000000000..d8ba7751eda --- /dev/null +++ b/reactos/regtests/winetests/ntdll/path.c @@ -0,0 +1,304 @@ +/* + * Unit test suite for ntdll path functions + * + * Copyright 2002 Alexandre Julliard + * + * 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 + */ + +#include "ntdll_test.h" + +static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen, + LPCSTR src, DWORD srclen ); +static NTSTATUS (WINAPI *pRtlUnicodeToMultiByteN)(LPSTR,DWORD,LPDWORD,LPCWSTR,DWORD); +static UINT (WINAPI *pRtlDetermineDosPathNameType_U)( PCWSTR path ); +static ULONG (WINAPI *pRtlIsDosDeviceName_U)( PCWSTR dos_name ); +static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(UNICODE_STRING *, const STRING *, BOOLEAN ); +static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRING,PBOOLEAN); +static DWORD (WINAPI *pRtlGetFullPathName_U)(const WCHAR*,ULONG,WCHAR*,WCHAR**); + + +static void test_RtlDetermineDosPathNameType(void) +{ + struct test + { + const char *path; + UINT ret; + }; + + static const struct test tests[] = + { + { "\\\\foo", 1 }, + { "//foo", 1 }, + { "\\/foo", 1 }, + { "/\\foo", 1 }, + { "\\\\", 1 }, + { "//", 1 }, + { "c:\\foo", 2 }, + { "c:/foo", 2 }, + { "c://foo", 2 }, + { "c:\\", 2 }, + { "c:/", 2 }, + { "c:foo", 3 }, + { "c:f\\oo", 3 }, + { "c:foo/bar", 3 }, + { "\\foo", 4 }, + { "/foo", 4 }, + { "\\", 4 }, + { "/", 4 }, + { "foo", 5 }, + { "", 5 }, + { "\0:foo", 5 }, + { "\\\\.\\foo", 6 }, + { "//./foo", 6 }, + { "/\\./foo", 6 }, + { "\\\\.foo", 1 }, + { "//.foo", 1 }, + { "\\\\.", 7 }, + { "//.", 7 }, + { NULL, 0 } + }; + + const struct test *test; + WCHAR buffer[MAX_PATH]; + UINT ret; + + for (test = tests; test->path; test++) + { + pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 ); + ret = pRtlDetermineDosPathNameType_U( buffer ); + ok( ret == test->ret, "Wrong result %d/%d for %s\n", ret, test->ret, test->path ); + } +} + + +static void test_RtlIsDosDeviceName(void) +{ + struct test + { + const char *path; + WORD pos; + WORD len; + }; + + static const struct test tests[] = + { + { "\\\\.\\CON", 8, 6 }, + { "\\\\.\\con", 8, 6 }, + { "\\\\.\\CON2", 0, 0 }, + { "", 0, 0 }, + { "\\\\foo\\nul", 0, 0 }, + { "c:\\nul:", 6, 6 }, + { "c:\\nul::", 0, 0 }, + { "c:prn ", 4, 6 }, + { "c:prn.......", 4, 6 }, + { "c:prn... ...", 4, 6 }, + { "c:NUL .... ", 0, 0 }, + { "c: . . .", 0, 0 }, + { "c:", 0, 0 }, + { " . . . :", 0, 0 }, + { ":", 0, 0 }, + { "c:nul. . . :", 4, 6 }, + { "c:nul . . :", 0, 0 }, + { "c:nul0", 0, 0 }, + { "c:prn:aaa", 0, 0 }, + { "c:PRN:.txt", 4, 6 }, + { "c:aux:.txt...", 4, 6 }, + { "c:prn:.txt:", 4, 6 }, + { "c:nul:aaa", 0, 0 }, + { "con:", 0, 6 }, + { "lpt1:", 0, 8 }, + { "c:com5:", 4, 8 }, + { "CoM4:", 0, 8 }, + { "lpt9:", 0, 8 }, + { "c:\\lpt0.txt", 0, 0 }, + { "c:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6 }, + { NULL, 0 } + }; + + const struct test *test; + WCHAR buffer[2000]; + ULONG ret; + + for (test = tests; test->path; test++) + { + pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 ); + ret = pRtlIsDosDeviceName_U( buffer ); + ok( ret == MAKELONG( test->len, test->pos ), + "Wrong result (%d,%d)/(%d,%d) for %s\n", + HIWORD(ret), LOWORD(ret), test->pos, test->len, test->path ); + } +} + +static void test_RtlIsNameLegalDOS8Dot3(void) +{ + struct test + { + const char *path; + BOOLEAN result; + BOOLEAN spaces; + }; + + static const struct test tests[] = + { + { "12345678", TRUE, FALSE }, + { "123 5678", TRUE, TRUE }, + { "12345678.", FALSE, 2 /*not set*/ }, + { "1234 678.", FALSE, 2 /*not set*/ }, + { "12345678.a", TRUE, FALSE }, + { "12345678.a ", FALSE, 2 /*not set*/ }, + { "12345678.a c", TRUE, TRUE }, + { " 2345678.a ", FALSE, 2 /*not set*/ }, + { "1 345678.abc", TRUE, TRUE }, + { "1 8.a c", TRUE, TRUE }, + { "1 3 5 7 .abc", FALSE, 2 /*not set*/ }, + { "12345678. c", TRUE, TRUE }, + { "123456789.a", FALSE, 2 /*not set*/ }, + { "12345.abcd", FALSE, 2 /*not set*/ }, + { "12345.ab d", FALSE, 2 /*not set*/ }, + { ".abc", FALSE, 2 /*not set*/ }, + { "12.abc.d", FALSE, 2 /*not set*/ }, + { ".", TRUE, FALSE }, + { "..", TRUE, FALSE }, + { "...", FALSE, 2 /*not set*/ }, + { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", FALSE, 2 /*not set*/ }, + { NULL, 0 } + }; + + const struct test *test; + UNICODE_STRING ustr; + OEM_STRING oem, oem_ret; + WCHAR buffer[200]; + char buff2[12]; + BOOLEAN ret, spaces; + + ustr.MaximumLength = sizeof(buffer); + ustr.Buffer = buffer; + for (test = tests; test->path; test++) + { + char path[100]; + strcpy(path, test->path); + oem.Buffer = path; + oem.Length = strlen(test->path); + oem.MaximumLength = oem.Length + 1; + pRtlOemStringToUnicodeString( &ustr, &oem, FALSE ); + spaces = 2; + oem_ret.Length = oem_ret.MaximumLength = sizeof(buff2); + oem_ret.Buffer = buff2; + ret = pRtlIsNameLegalDOS8Dot3( &ustr, &oem_ret, &spaces ); + ok( ret == test->result, "Wrong result %d/%d for '%s'\n", ret, test->result, test->path ); + ok( spaces == test->spaces, "Wrong spaces value %d/%d for '%s'\n", spaces, test->spaces, test->path ); + if (strlen(test->path) <= 12) + { + char str[13]; + int i; + strcpy( str, test->path ); + for (i = 0; str[i]; i++) str[i] = toupper(str[i]); + ok( oem_ret.Length == strlen(test->path), "Wrong length %d/%d for '%s'\n", + oem_ret.Length, strlen(test->path), test->path ); + ok( !memcmp( oem_ret.Buffer, str, oem_ret.Length ), + "Wrong string '%.*s'/'%s'\n", oem_ret.Length, oem_ret.Buffer, str ); + } + } +} +static void test_RtlGetFullPathName_U(void) +{ + struct test + { + const char *path; + const char *rname; + const char *rfile; + }; + + static const struct test tests[] = + { + { "c:/test", "c:\\test", "test"}, + { "c:/test ", "c:\\test", "test"}, + { "c:/test.", "c:\\test", "test"}, + { "c:/test .... .. ", "c:\\test", "test"}, + { "c:/test/ .... .. ", "c:\\test\\", NULL}, + { "c:/test/..", "c:\\", NULL}, + { "c:/test/.. ", "c:\\test\\", NULL}, + { "c:/TEST", "c:\\test", "test"}, + { "c:/test/file", "c:\\test\\file", "file"}, + { "c:/test./file", "c:\\test\\file", "file"}, + { "c:/test../file", "c:\\test.\\file", "file"}, + { "c:/test.. /file", "c:\\test.. \\file","file"}, + { "c:/test/././file", "c:\\test\\file", "file"}, + { "c:/test\\.\\.\\file", "c:\\test\\file", "file"}, + { "c:/test/\\.\\.\\file", "c:\\test\\file", "file"}, + { "c:/test\\\\.\\.\\file", "c:\\test\\file", "file"}, + { "c:/test\\test1\\..\\.\\file", "c:\\test\\file", "file"}, + { "c:///test\\.\\.\\file//", "c:\\test\\file\\", NULL}, + { "c:///test\\..\\file\\..\\//", "c:\\", NULL}, + { NULL, NULL, NULL} + }; + + const struct test *test; + WCHAR pathbufW[2*MAX_PATH], rbufferW[MAX_PATH]; + CHAR rbufferA[MAX_PATH], rfileA[MAX_PATH]; + ULONG ret; + WCHAR *file_part; + DWORD reslen; + UINT len; + + for (test = tests; test->path; test++) + { + len= strlen(test->rname) * sizeof(WCHAR); + pRtlMultiByteToUnicodeN(pathbufW , sizeof(pathbufW), NULL, test->path, strlen(test->path)+1 ); + ret = pRtlGetFullPathName_U( pathbufW,MAX_PATH, rbufferW, &file_part); + ok( ret == len, "Wrong result %ld/%d for \"%s\"\n", ret, len, test->path ); + ok(pRtlUnicodeToMultiByteN(rbufferA,MAX_PATH,&reslen,rbufferW,MAX_PATH) == STATUS_SUCCESS, + "RtlUnicodeToMultiByteN failed\n"); + ok(lstrcmpiA(rbufferA,test->rname) == 0, "Got \"%s\" expected \"%s\"\n",rbufferA,test->rname); + if (file_part) + { + ok(pRtlUnicodeToMultiByteN(rfileA,MAX_PATH,&reslen,file_part,MAX_PATH) == STATUS_SUCCESS, + "RtlUnicodeToMultiByteN failed\n"); + ok(test->rfile && !lstrcmpiA(rfileA,test->rfile), "Got \"%s\" expected \"%s\"\n",rfileA,test->rfile); + } + else + { + ok( !test->rfile, "Got NULL expected \"%s\"\n", test->rfile ); + } + } + +} + +START_TEST(path) +{ + HMODULE mod = GetModuleHandleA("ntdll.dll"); + pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN"); + pRtlUnicodeToMultiByteN = (void *)GetProcAddress(mod,"RtlUnicodeToMultiByteN"); + pRtlDetermineDosPathNameType_U = (void *)GetProcAddress(mod,"RtlDetermineDosPathNameType_U"); + pRtlIsDosDeviceName_U = (void *)GetProcAddress(mod,"RtlIsDosDeviceName_U"); + pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString"); + pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3"); + pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U"); + if (pRtlDetermineDosPathNameType_U) + test_RtlDetermineDosPathNameType(); + if (pRtlIsDosDeviceName_U) + test_RtlIsDosDeviceName(); + if (pRtlIsNameLegalDOS8Dot3) + test_RtlIsNameLegalDOS8Dot3(); + if (pRtlGetFullPathName_U && pRtlMultiByteToUnicodeN) + test_RtlGetFullPathName_U(); +} diff --git a/reactos/regtests/winetests/ntdll/reg.c b/reactos/regtests/winetests/ntdll/reg.c new file mode 100755 index 00000000000..d71e1645144 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/reg.c @@ -0,0 +1,380 @@ +/* Unit test suite for Rtl* Registry API functions + * + * Copyright 2003 Thomas Mertes + * Copyright 2005 Brad DeMorrow + * + * 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 + * + * NOTE: I don't test every RelativeTo value because it would be redundant, all calls go through + * helper function RTL_GetKeyHandle().--Brad DeMorrow + * + */ + +#include "ntdll_test.h" +#include "winternl.h" +//#include "wine/library.h" +#include "stdio.h" +#include "winnt.h" +#include "winnls.h" +#include "stdlib.h" +#include "wine/unicode.h" + +#ifndef __WINE_WINTERNL_H + +/* RtlQueryRegistryValues structs and defines */ +#define RTL_REGISTRY_ABSOLUTE 0 +#define RTL_REGISTRY_SERVICES 1 +#define RTL_REGISTRY_CONTROL 2 +#define RTL_REGISTRY_WINDOWS_NT 3 +#define RTL_REGISTRY_DEVICEMAP 4 +#define RTL_REGISTRY_USER 5 + +#define RTL_REGISTRY_HANDLE 0x40000000 +#define RTL_REGISTRY_OPTIONAL 0x80000000 + +#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 +#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 +#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 +#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 +#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 +#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 +#define RTL_QUERY_REGISTRY_DELETE 0x00000040 + +typedef NTSTATUS (WINAPI *PRTL_QUERY_REGISTRY_ROUTINE)( PCWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext); + +typedef struct _RTL_QUERY_REGISTRY_TABLE { + PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine; + ULONG Flags; + PWSTR Name; + PVOID EntryContext; + ULONG DefaultType; + PVOID DefaultData; + ULONG DefaultLength; +} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE; + +#endif + +static NTSTATUS (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR); +static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING); +static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING); +static NTSTATUS (WINAPI * pRtlQueryRegistryValues)(IN ULONG, IN PCWSTR,IN PRTL_QUERY_REGISTRY_TABLE, IN PVOID,IN PVOID); +static NTSTATUS (WINAPI * pRtlCheckRegistryKey)(IN ULONG,IN PWSTR); +static NTSTATUS (WINAPI * pRtlOpenCurrentUser)(IN ACCESS_MASK, OUT PHKEY); +static NTSTATUS (WINAPI * pNtOpenKey)(PHANDLE, IN ACCESS_MASK, IN POBJECT_ATTRIBUTES); +static NTSTATUS (WINAPI * pNtClose)(IN HANDLE); +static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING); +static NTSTATUS (WINAPI * pNtDeleteKey)(HKEY); +static NTSTATUS (WINAPI * pNtCreateKey)( PHKEY retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, + ULONG TitleIndex, const UNICODE_STRING *class, ULONG options, + PULONG dispos ); +static NTSTATUS (WINAPI * pNtSetValueKey)( PHKEY, const PUNICODE_STRING, ULONG, + ULONG, const PVOID, ULONG ); +static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(PUNICODE_STRING); +static NTSTATUS (WINAPI * pRtlCreateUnicodeString)( PUNICODE_STRING, LPCWSTR); +static NTSTATUS (WINAPI * pRtlReAllocateHeap)(IN PVOID, IN ULONG, IN PVOID, IN ULONG); +static NTSTATUS (WINAPI * pRtlAppendUnicodeToString)(PUNICODE_STRING, PCWSTR); +static NTSTATUS (WINAPI * pRtlUnicodeStringToAnsiString)(PSTRING, PUNICODE_STRING, BOOL); +static NTSTATUS (WINAPI * pRtlFreeHeap)(PVOID, ULONG, PVOID); +static NTSTATUS (WINAPI * pRtlAllocateHeap)(PVOID,ULONG,ULONG); +static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG); + +static HMODULE hntdll = 0; +static int CurrentTest = 0; +static UNICODE_STRING winetestpath; + +#define NTDLL_GET_PROC(func) \ + p ## func = (void*)GetProcAddress(hntdll, #func); \ + if(!p ## func) { \ + trace("GetProcAddress(%s) failed\n", #func); \ + FreeLibrary(hntdll); \ + return FALSE; \ + } + +static BOOL InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + if(!hntdll) { + trace("Could not load ntdll.dll\n"); + return FALSE; + } + if (hntdll) + { + NTDLL_GET_PROC(RtlCreateUnicodeStringFromAsciiz) + NTDLL_GET_PROC(RtlCreateUnicodeString) + NTDLL_GET_PROC(RtlFreeUnicodeString) + NTDLL_GET_PROC(NtDeleteValueKey) + NTDLL_GET_PROC(RtlQueryRegistryValues) + NTDLL_GET_PROC(RtlCheckRegistryKey) + NTDLL_GET_PROC(RtlOpenCurrentUser) + NTDLL_GET_PROC(NtClose) + NTDLL_GET_PROC(NtDeleteValueKey) + NTDLL_GET_PROC(NtCreateKey) + NTDLL_GET_PROC(NtDeleteKey) + NTDLL_GET_PROC(NtSetValueKey) + NTDLL_GET_PROC(NtOpenKey) + NTDLL_GET_PROC(RtlFormatCurrentUserKeyPath) + NTDLL_GET_PROC(RtlReAllocateHeap) + NTDLL_GET_PROC(RtlAppendUnicodeToString) + NTDLL_GET_PROC(RtlUnicodeStringToAnsiString) + NTDLL_GET_PROC(RtlFreeHeap) + NTDLL_GET_PROC(RtlAllocateHeap) + NTDLL_GET_PROC(RtlZeroMemory) + } + return TRUE; +} +#undef NTDLL_GET_PROC + +static NTSTATUS WINAPI QueryRoutine (IN PCWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, + IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext) +{ + NTSTATUS ret = STATUS_SUCCESS; + int ValueNameLength = 0; + LPSTR ValName = 0; + trace("**Test %d**\n", CurrentTest); + + if(ValueName) + { + ValueNameLength = strlenW(ValueName); + + ValName = (LPSTR)pRtlAllocateHeap(GetProcessHeap(), 0, ValueNameLength); + + WideCharToMultiByte(0, 0, ValueName, ValueNameLength+1,ValName, ValueNameLength, 0, 0); + + trace("ValueName: %s\n", ValName); + } + else + trace("ValueName: (null)\n"); + + switch(ValueType) + { + case REG_NONE: + trace("ValueType: REG_NONE\n"); + trace("ValueData: %d\n", (int)ValueData); + break; + + case REG_BINARY: + trace("ValueType: REG_BINARY\n"); + trace("ValueData: %d\n", (int)ValueData); + break; + + case REG_SZ: + trace("ValueType: REG_SZ\n"); + trace("ValueData: %s\n", (char*)ValueData); + break; + + case REG_MULTI_SZ: + trace("ValueType: REG_MULTI_SZ\n"); + trace("ValueData: %s\n", (char*)ValueData); + break; + + case REG_EXPAND_SZ: + trace("ValueType: REG_EXPAND_SZ\n"); + trace("ValueData: %s\n", (char*)ValueData); + break; + + case REG_DWORD: + trace("ValueType: REG_DWORD\n"); + trace("ValueData: %d\n", (int)ValueData); + break; + }; + trace("ValueLength: %d\n", (int)ValueLength); + + if(CurrentTest == 0) + ok(1, "\n"); /*checks that QueryRoutine is called*/ + if(CurrentTest > 7) + ok(!1, "Invalid Test Specified!\n"); + + CurrentTest++; + + if(ValName) + pRtlFreeHeap(GetProcessHeap(), 0, ValName); + + return ret; +} + +static void test_RtlQueryRegistryValues(void) +{ + + /* + ****************************** + * QueryTable Flags * + ****************************** + *RTL_QUERY_REGISTRY_SUBKEY * Name is the name of a subkey relative to Path + *RTL_QUERY_REGISTRY_TOPKEY * Resets location to original RelativeTo and Path + *RTL_QUERY_REGISTRY_REQUIRED * Key required. returns STATUS_OBJECT_NAME_NOT_FOUND if not present + *RTL_QUERY_REGISTRY_NOVALUE * We just want a call-back + *RTL_QUERY_REGISTRY_NOEXPAND * Don't expand the variables! + *RTL_QUERY_REGISTRY_DIRECT * Results of query will be stored in EntryContext(QueryRoutine ignored) + *RTL_QUERY_REGISTRY_DELETE * Delete value key after query + ****************************** + + + **Test layout(numbered according to CurrentTest value)** + 0)NOVALUE Just make sure call-back works + 1)Null Name See if QueryRoutine is called for every value in current key + 2)SUBKEY See if we can use SUBKEY to change the current path on the fly + 3)REQUIRED Test for value that's not there + 4)NOEXPAND See if it will return multiple strings(no expand should split strings up) + 5)DIRECT Make it store data directly in EntryContext and not call QueryRoutine + 6)DefaultType Test return values when key isn't present + 7)DefaultValue Test Default Value returned with key isn't present(and no REQUIRED flag set) + 8)DefaultLength Test Default Length with DefaultType = REG_SZ + 9)DefaultLength Test Default Length with DefaultType = REG_MULTI_SZ + 10)DefaultLength Test Default Length with DefaultType = REG_EXPAND_SZ + 11)DefaultData Test whether DefaultData is used while DefaltType = REG_NONE(shouldn't be) + 12)Delete Try to delete value key + + */ + NTSTATUS status; + ULONG RelativeTo; + + PRTL_QUERY_REGISTRY_TABLE QueryTable = NULL; + RelativeTo = RTL_REGISTRY_ABSOLUTE;/*Only using absolute - no need to test all relativeto variables*/ + + QueryTable = (PRTL_QUERY_REGISTRY_TABLE)pRtlAllocateHeap(GetProcessHeap(), 0, sizeof(RTL_QUERY_REGISTRY_TABLE)*26); + + pRtlZeroMemory( QueryTable, sizeof(RTL_QUERY_REGISTRY_TABLE) * 26); + + QueryTable[0].QueryRoutine = QueryRoutine; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_NOVALUE; + QueryTable[0].Name = NULL; + QueryTable[0].EntryContext = NULL; + QueryTable[0].DefaultType = REG_BINARY; + QueryTable[0].DefaultData = NULL; + QueryTable[0].DefaultLength = 100; + + QueryTable[1].QueryRoutine = QueryRoutine; + QueryTable[1].Flags = 0; + QueryTable[1].Name = NULL; + QueryTable[1].EntryContext = 0; + QueryTable[1].DefaultType = REG_NONE; + QueryTable[1].DefaultData = NULL; + QueryTable[1].DefaultLength = 0; + + QueryTable[2].QueryRoutine = NULL; + QueryTable[2].Flags = 0; + QueryTable[2].Name = NULL; + QueryTable[2].EntryContext = 0; + QueryTable[2].DefaultType = REG_NONE; + QueryTable[2].DefaultData = NULL; + QueryTable[2].DefaultLength = 0; + + status = pRtlQueryRegistryValues(RelativeTo, winetestpath.Buffer, QueryTable, 0, 0); + ok(status == STATUS_SUCCESS, "RtlQueryRegistryValues return: 0x%08lx\n", status); + + pRtlFreeHeap(GetProcessHeap(), 0, QueryTable); +} + +static void test_NtCreateKey(void) +{ + /*Create WineTest*/ + OBJECT_ATTRIBUTES attr; + UNICODE_STRING ValName; + HKEY key; + ACCESS_MASK am = GENERIC_ALL; + NTSTATUS status; + + InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0); + status = pNtCreateKey(&key, am, &attr, 0, 0, 0, 0); + ok(status == STATUS_SUCCESS, "NtCreateKey Failed: 0x%08lx\n", status); + + pRtlFreeUnicodeString(&ValName); + pNtClose(&key); +} + +static void test_NtSetValueKey(void) +{ + HANDLE key; + NTSTATUS status; + OBJECT_ATTRIBUTES attr; + ACCESS_MASK am = KEY_WRITE; + UNICODE_STRING ValName; + DWORD data = 711; + + pRtlCreateUnicodeStringFromAsciiz(&ValName, "deletetest"); + + InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0); + status = pNtOpenKey(&key, am, &attr); + ok(status == STATUS_SUCCESS, "NtOpenKey Failed: 0x%08lx\n", status); + + status = pNtSetValueKey(key, &ValName, 0, REG_DWORD, &data, sizeof(data)); + ok(status == STATUS_SUCCESS, "NtSetValueKey Failed: 0x%08lx\n", status); + + pRtlFreeUnicodeString(&ValName); + pNtClose(&key); +} + +static void test_RtlOpenCurrentUser(void) +{ + NTSTATUS status; + HKEY handle; + status=pRtlOpenCurrentUser(KEY_READ, &handle); + ok(status == STATUS_SUCCESS, "RtlOpenCurrentUser Failed: 0x%08lx\n", status); + pNtClose(&handle); +} + +static void test_RtlCheckRegistryKey(void) +{ + NTSTATUS status; + + status = pRtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE, winetestpath.Buffer); + ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE: 0x%08lx\n", status); + + status = pRtlCheckRegistryKey((RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL), winetestpath.Buffer); + ok(status == STATUS_SUCCESS, "RtlCheckRegistryKey with RTL_REGISTRY_ABSOLUTE and RTL_REGISTRY_OPTIONAL: 0x%08lx\n", status); +} + +static void test_NtDeleteKey(void) +{ + NTSTATUS status; + HANDLE hkey; + OBJECT_ATTRIBUTES attr; + ACCESS_MASK am = KEY_ALL_ACCESS; + + InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0); + status = pNtOpenKey(&hkey, am, &attr); + + status = pNtDeleteKey(hkey); + ok(status == STATUS_SUCCESS, "NtDeleteKey Failed: 0x%08lx\n", status); +} + +START_TEST(reg) +{ + static const WCHAR winetest[] = {'\\','W','i','n','e','T','e','s','t','\\',0}; + if(!InitFunctionPtrs()) + return; + pRtlFormatCurrentUserKeyPath(&winetestpath); + winetestpath.Buffer = (PWSTR)pRtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, winetestpath.Buffer, + winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR)); + winetestpath.MaximumLength = winetestpath.MaximumLength + sizeof(winetest)*sizeof(WCHAR); + + pRtlAppendUnicodeToString(&winetestpath, winetest); + + test_NtCreateKey(); + test_NtSetValueKey(); + test_RtlCheckRegistryKey(); + test_RtlOpenCurrentUser(); + test_RtlQueryRegistryValues(); + test_NtDeleteKey(); + + pRtlFreeUnicodeString(&winetestpath); + + FreeLibrary(hntdll); +} diff --git a/reactos/regtests/winetests/ntdll/rtl.c b/reactos/regtests/winetests/ntdll/rtl.c new file mode 100755 index 00000000000..8e31032a8ea --- /dev/null +++ b/reactos/regtests/winetests/ntdll/rtl.c @@ -0,0 +1,891 @@ +/* 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 + +#include "ntdll_test.h" + +/* Function ptrs for ntdll calls */ +static HMODULE hntdll = 0; +static SIZE_T (WINAPI *pRtlCompareMemory)(LPCVOID,LPCVOID,SIZE_T); +static SIZE_T (WINAPI *pRtlCompareMemoryUlong)(PULONG, SIZE_T, ULONG); +static VOID (WINAPI *pRtlMoveMemory)(LPVOID,LPCVOID,SIZE_T); +static VOID (WINAPI *pRtlFillMemory)(LPVOID,SIZE_T,BYTE); +static VOID (WINAPI *pRtlFillMemoryUlong)(LPVOID,SIZE_T,ULONG); +static VOID (WINAPI *pRtlZeroMemory)(LPVOID,SIZE_T); +static ULONGLONG (WINAPIV *pRtlUlonglongByteSwap)(ULONGLONG source); +static ULONG (WINAPI *pRtlUniform)(PULONG); +static ULONG (WINAPI *pRtlRandom)(PULONG); +static BOOLEAN (WINAPI *pRtlAreAllAccessesGranted)(ACCESS_MASK, ACCESS_MASK); +static BOOLEAN (WINAPI *pRtlAreAnyAccessesGranted)(ACCESS_MASK, ACCESS_MASK); +static DWORD (WINAPI *pRtlComputeCrc32)(DWORD,const BYTE*,INT); +static void (WINAPI * pRtlInitializeHandleTable)(ULONG, ULONG, RTL_HANDLE_TABLE *); +static BOOLEAN (WINAPI * pRtlIsValidIndexHandle)(const RTL_HANDLE_TABLE *, ULONG, RTL_HANDLE **); +static NTSTATUS (WINAPI * pRtlDestroyHandleTable)(RTL_HANDLE_TABLE *); +static RTL_HANDLE * (WINAPI * pRtlAllocateHandle)(RTL_HANDLE_TABLE *, ULONG *); +static BOOLEAN (WINAPI * pRtlFreeHandle)(RTL_HANDLE_TABLE *, RTL_HANDLE *); +#define LEN 16 +static const char* src_src = "This is a test!"; /* 16 bytes long, incl NUL */ +static ULONG src_aligned_block[4]; +static ULONG dest_aligned_block[32]; +static const char *src = (const char*)src_aligned_block; +static char* dest = (char*)dest_aligned_block; + +static void InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + ok(hntdll != 0, "LoadLibrary failed\n"); + if (hntdll) { + pRtlCompareMemory = (void *)GetProcAddress(hntdll, "RtlCompareMemory"); + pRtlCompareMemoryUlong = (void *)GetProcAddress(hntdll, "RtlCompareMemoryUlong"); + pRtlMoveMemory = (void *)GetProcAddress(hntdll, "RtlMoveMemory"); + pRtlFillMemory = (void *)GetProcAddress(hntdll, "RtlFillMemory"); + pRtlFillMemoryUlong = (void *)GetProcAddress(hntdll, "RtlFillMemoryUlong"); + pRtlZeroMemory = (void *)GetProcAddress(hntdll, "RtlZeroMemory"); + pRtlUlonglongByteSwap = (void *)GetProcAddress(hntdll, "RtlUlonglongByteSwap"); + pRtlUniform = (void *)GetProcAddress(hntdll, "RtlUniform"); + pRtlRandom = (void *)GetProcAddress(hntdll, "RtlRandom"); + pRtlAreAllAccessesGranted = (void *)GetProcAddress(hntdll, "RtlAreAllAccessesGranted"); + pRtlAreAnyAccessesGranted = (void *)GetProcAddress(hntdll, "RtlAreAnyAccessesGranted"); + pRtlComputeCrc32 = (void *)GetProcAddress(hntdll, "RtlComputeCrc32"); + pRtlInitializeHandleTable = (void *)GetProcAddress(hntdll, "RtlInitializeHandleTable"); + pRtlIsValidIndexHandle = (void *)GetProcAddress(hntdll, "RtlIsValidIndexHandle"); + pRtlDestroyHandleTable = (void *)GetProcAddress(hntdll, "RtlDestroyHandleTable"); + pRtlAllocateHandle = (void *)GetProcAddress(hntdll, "RtlAllocateHandle"); + pRtlFreeHandle = (void *)GetProcAddress(hntdll, "RtlFreeHandle"); + } + strcpy((char*)src_aligned_block, src_src); + ok(strlen(src) == 15, "Source must be 16 bytes long!\n"); +} + +#define COMP(str1,str2,cmplen,len) size = pRtlCompareMemory(str1, str2, cmplen); \ + ok(size == len, "Expected %ld, got %ld\n", size, (SIZE_T)len) + +static void test_RtlCompareMemory(void) +{ + SIZE_T size; + + if (!pRtlCompareMemory) + return; + + strcpy(dest, src); + + COMP(src,src,0,0); + COMP(src,src,LEN,LEN); + dest[0] = 'x'; + COMP(src,dest,LEN,0); +} + +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); +} + +#define COPY(len) memset(dest,0,sizeof(dest_aligned_block)); pRtlMoveMemory(dest, src, len) +#define CMP(str) ok(strcmp(dest,str) == 0, "Expected '%s', got '%s'\n", str, dest) + +static void test_RtlMoveMemory(void) +{ + if (!pRtlMoveMemory) + return; + + /* Length should be in bytes and not rounded. Use strcmp to ensure we + * didn't write past the end (it checks for the final NUL left by memset) + */ + COPY(0); CMP(""); + COPY(1); CMP("T"); + COPY(2); CMP("Th"); + COPY(3); CMP("Thi"); + COPY(4); CMP("This"); + COPY(5); CMP("This "); + COPY(6); CMP("This i"); + COPY(7); CMP("This is"); + COPY(8); CMP("This is "); + COPY(9); CMP("This is a"); + + /* Overlapping */ + strcpy(dest, src); pRtlMoveMemory(dest, dest + 1, strlen(src) - 1); + CMP("his is a test!!"); + strcpy(dest, src); pRtlMoveMemory(dest + 1, dest, strlen(src)); + CMP("TThis is a test!"); +} + +#define FILL(len) memset(dest,0,sizeof(dest_aligned_block)); strcpy(dest, src); pRtlFillMemory(dest,len,'x') + +static void test_RtlFillMemory(void) +{ + if (!pRtlFillMemory) + return; + + /* Length should be in bytes and not rounded. Use strcmp to ensure we + * didn't write past the end (the remainder of the string should match) + */ + FILL(0); CMP("This is a test!"); + FILL(1); CMP("xhis is a test!"); + FILL(2); CMP("xxis is a test!"); + FILL(3); CMP("xxxs is a test!"); + FILL(4); CMP("xxxx is a test!"); + FILL(5); CMP("xxxxxis a test!"); + FILL(6); CMP("xxxxxxs a test!"); + FILL(7); CMP("xxxxxxx a test!"); + FILL(8); CMP("xxxxxxxxa test!"); + FILL(9); CMP("xxxxxxxxx test!"); +} + +#define LFILL(len) memset(dest,0,sizeof(dest_aligned_block)); strcpy(dest, src); pRtlFillMemoryUlong(dest,len,val) + +static void test_RtlFillMemoryUlong(void) +{ + ULONG val = ('x' << 24) | ('x' << 16) | ('x' << 8) | 'x'; + if (!pRtlFillMemoryUlong) + return; + + /* Length should be in bytes and not rounded. Use strcmp to ensure we + * didn't write past the end (the remainder of the string should match) + */ + LFILL(0); CMP("This is a test!"); + LFILL(1); CMP("This is a test!"); + LFILL(2); CMP("This is a test!"); + LFILL(3); CMP("This is a test!"); + LFILL(4); CMP("xxxx is a test!"); + LFILL(5); CMP("xxxx is a test!"); + LFILL(6); CMP("xxxx is a test!"); + LFILL(7); CMP("xxxx is a test!"); + LFILL(8); CMP("xxxxxxxxa test!"); + LFILL(9); CMP("xxxxxxxxa test!"); +} + +#define ZERO(len) memset(dest,0,sizeof(dest_aligned_block)); strcpy(dest, src); pRtlZeroMemory(dest,len) +#define MCMP(str) ok(memcmp(dest,str,LEN) == 0, "Memcmp failed\n") + +static void test_RtlZeroMemory(void) +{ + if (!pRtlZeroMemory) + return; + + /* Length should be in bytes and not rounded. */ + ZERO(0); MCMP("This is a test!"); + ZERO(1); MCMP("\0his is a test!"); + ZERO(2); MCMP("\0\0is is a test!"); + ZERO(3); MCMP("\0\0\0s is a test!"); + ZERO(4); MCMP("\0\0\0\0 is a test!"); + ZERO(5); MCMP("\0\0\0\0\0is a test!"); + ZERO(6); MCMP("\0\0\0\0\0\0s a test!"); + ZERO(7); MCMP("\0\0\0\0\0\0\0 a test!"); + ZERO(8); MCMP("\0\0\0\0\0\0\0\0a test!"); + ZERO(9); MCMP("\0\0\0\0\0\0\0\0\0 test!"); +} + +static void test_RtlUlonglongByteSwap(void) +{ + ULONGLONG result; + + result = pRtlUlonglongByteSwap( ((ULONGLONG)0x76543210 << 32) | 0x87654321 ); + ok( (((ULONGLONG)0x21436587 << 32) | 0x10325476) == result, + "RtlUlonglongByteSwap(0x7654321087654321) returns 0x%llx, expected 0x2143658710325476\n", + 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 0x7fffffff (and MAXLONG + 1 is 0x80000000) the + * algorithm can be expressed without division 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\n", + 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\n", + 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\n", + 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\n", + result, expected); + + seed = 0x6bca1aa; + expected = seed * 0xffffffed + 0x7fffffc3; + result = pRtlUniform(&seed); + ok(result == expected, + "RtlUniform(&seed (seed == 0x6bca1aa)) returns %lx, expected %lx\n", + result, expected); + + seed = 0x6bca1ab; + expected = seed * 0xffffffed + 0x7fffffc3 + 1; + result = pRtlUniform(&seed); + ok(result == expected, + "RtlUniform(&seed (seed == 0x6bca1ab)) returns %lx, expected %lx\n", + 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\n", + 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\n", + result, expected); + + seed = 0x6bca1ae; + expected = (seed * 0xffffffed + 0x7fffffc3 + 1) & MAXLONG; + result = pRtlUniform(&seed); + ok(result == expected, + "RtlUniform(&seed (seed == 0x6bca1ae)) returns %lx, expected %lx\n", + 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\n", + num, seed_bak, result, expected); + ok(seed == expected, + "test: %llu RtlUniform(&seed (seed == %lx)) sets seed to %lx, expected %lx\n", + 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 a simplified algorithm: + * + * seed = seed * 0xffffffed + 0x7fffffc3; + * if (seed == 0xffffffff || seed == 0x7ffffffe) { + * seed = (seed + 2) & MAXLONG; + * } else if (seed == 0x7fffffff) { + * seed = 0; + * } else if ((seed & 0x80000000) == 0) { + * seed = seed + (~seed & 1); + * } else { + * seed = (seed + (seed & 1)) & MAXLONG; + * } + * + * This is also the algorithm used for RtlUniform of wine (see dlls/ntdll/rtl.c). + * + * Now comes the funny part: + * It took me one weekend, to find the complicated algorithm and one day more, + * to find the simplified algorithm. Several weeks later I found out: The value + * MAXLONG (=0x7fffffff) is never returned, neither with the native function + * nor with the simplified algorithm. In reality the native function and our + * function return a random number distributed over [0..MAXLONG-1]. Note + * that this is different from what native documentation states [0..MAXLONG]. + * Expressed with D.H. Lehmer's 1948 algorithm it looks like: + * + * seed = (seed * const_1 + const_2) % MAXLONG; + * + * Further investigations show that the real algorithm is: + * + * seed = (seed * 0x7fffffed + 0x7fffffc3) % MAXLONG; + * + * This is checked with the test below: + */ + seed = 0; + for (num = 0; num <= 100000; num++) { + expected = (seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff; + seed_bak = seed; + result = pRtlUniform(&seed); + ok(result == expected, + "test: %llu RtlUniform(&seed (seed == %lx)) returns %lx, expected %lx\n", + num, seed_bak, result, expected); + ok(seed == expected, + "test: %llu RtlUniform(&seed (seed == %lx)) sets seed to %lx, expected %lx\n", + num, seed_bak, seed, expected); + } /* for */ +/* + * More tests show that RtlUniform does not return 0x7ffffffd for seed values + * in the range [0..MAXLONG-1]. Additionally 2 is returned twice. This shows + * that there is more than one cycle of generated randon numbers ... + */ +} + + +static ULONG WINAPI my_RtlRandom(PULONG seed) +{ + static ULONG saved_value[128] = + { /* 0 */ 0x4c8bc0aa, 0x4c022957, 0x2232827a, 0x2f1e7626, 0x7f8bdafb, 0x5c37d02a, 0x0ab48f72, 0x2f0c4ffa, + /* 8 */ 0x290e1954, 0x6b635f23, 0x5d3885c0, 0x74b49ff8, 0x5155fa54, 0x6214ad3f, 0x111e9c29, 0x242a3a09, + /* 16 */ 0x75932ae1, 0x40ac432e, 0x54f7ba7a, 0x585ccbd5, 0x6df5c727, 0x0374dad1, 0x7112b3f1, 0x735fc311, + /* 24 */ 0x404331a9, 0x74d97781, 0x64495118, 0x323e04be, 0x5974b425, 0x4862e393, 0x62389c1d, 0x28a68b82, + /* 32 */ 0x0f95da37, 0x7a50bbc6, 0x09b0091c, 0x22cdb7b4, 0x4faaed26, 0x66417ccd, 0x189e4bfa, 0x1ce4e8dd, + /* 40 */ 0x5274c742, 0x3bdcf4dc, 0x2d94e907, 0x32eac016, 0x26d33ca3, 0x60415a8a, 0x31f57880, 0x68c8aa52, + /* 48 */ 0x23eb16da, 0x6204f4a1, 0x373927c1, 0x0d24eb7c, 0x06dd7379, 0x2b3be507, 0x0f9c55b1, 0x2c7925eb, + /* 56 */ 0x36d67c9a, 0x42f831d9, 0x5e3961cb, 0x65d637a8, 0x24bb3820, 0x4d08e33d, 0x2188754f, 0x147e409e, + /* 64 */ 0x6a9620a0, 0x62e26657, 0x7bd8ce81, 0x11da0abb, 0x5f9e7b50, 0x23e444b6, 0x25920c78, 0x5fc894f0, + /* 72 */ 0x5e338cbb, 0x404237fd, 0x1d60f80f, 0x320a1743, 0x76013d2b, 0x070294ee, 0x695e243b, 0x56b177fd, + /* 80 */ 0x752492e1, 0x6decd52f, 0x125f5219, 0x139d2e78, 0x1898d11e, 0x2f7ee785, 0x4db405d8, 0x1a028a35, + /* 88 */ 0x63f6f323, 0x1f6d0078, 0x307cfd67, 0x3f32a78a, 0x6980796c, 0x462b3d83, 0x34b639f2, 0x53fce379, + /* 96 */ 0x74ba50f4, 0x1abc2c4b, 0x5eeaeb8d, 0x335a7a0d, 0x3973dd20, 0x0462d66b, 0x159813ff, 0x1e4643fd, + /* 104 */ 0x06bc5c62, 0x3115e3fc, 0x09101613, 0x47af2515, 0x4f11ec54, 0x78b99911, 0x3db8dd44, 0x1ec10b9b, + /* 112 */ 0x5b5506ca, 0x773ce092, 0x567be81a, 0x5475b975, 0x7a2cde1a, 0x494536f5, 0x34737bb4, 0x76d9750b, + /* 120 */ 0x2a1f6232, 0x2e49644d, 0x7dddcbe7, 0x500cebdb, 0x619dab9e, 0x48c626fe, 0x1cda3193, 0x52dabe9d }; + ULONG rand; + int pos; + ULONG result; + + rand = (*seed * 0x7fffffed + 0x7fffffc3) % 0x7fffffff; + *seed = (rand * 0x7fffffed + 0x7fffffc3) % 0x7fffffff; + pos = *seed & 0x7f; + result = saved_value[pos]; + saved_value[pos] = rand; + return(result); +} + + +static void test_RtlRandom(void) +{ + ULONGLONG num; + ULONG seed; + ULONG seed_bak; + ULONG seed_expected; + ULONG result; + ULONG result_expected; + +/* + * Unlike RtlUniform, RtlRandom is not documented. We guess that for + * RtlRandom D.H. Lehmer's 1948 algorithm is used like stated in + * the documentation of the RtlUniform function. This algorithm is: + * + * seed = (seed * const_1 + const_2) % const_3; + * + * According to the RtlUniform documentation the random number is + * distributed over [0..MAXLONG], but in reality it is distributed + * over [0..MAXLONG-1]. Therefore const_3 might be MAXLONG + 1 or + * MAXLONG: + * + * seed = (seed * const_1 + const_2) % (MAXLONG + 1); + * + * or + * + * seed = (seed * const_1 + const_2) % MAXLONG; + * + * To find out const_2 we just call RtlRandom with seed set to 0: + */ + seed = 0; + result_expected = 0x320a1743; + seed_expected =0x44b; + result = pRtlRandom(&seed); + ok(result == result_expected, + "pRtlRandom(&seed (seed == 0)) returns %lx, expected %lx\n", + result, result_expected); + ok(seed == seed_expected, + "pRtlRandom(&seed (seed == 0)) sets seed to %lx, expected %lx\n", + seed, seed_expected); +/* + * Seed is not equal to result as with RtlUniform. To see more we + * call RtlRandom aggain with seed set to 0: + */ + seed = 0; + result_expected = 0x7fffffc3; + seed_expected =0x44b; + result = pRtlRandom(&seed); + ok(result == result_expected, + "RtlRandom(&seed (seed == 0)) returns %lx, expected %lx\n", + result, result_expected); + ok(seed == seed_expected, + "RtlRandom(&seed (seed == 0)) sets seed to %lx, expected %lx\n", + seed, seed_expected); +/* + * Seed is set to the same value as before but the result is different. + * To see more we call RtlRandom aggain with seed set to 0: + */ + seed = 0; + result_expected = 0x7fffffc3; + seed_expected =0x44b; + result = pRtlRandom(&seed); + ok(result == result_expected, + "RtlRandom(&seed (seed == 0)) returns %lx, expected %lx\n", + result, result_expected); + ok(seed == seed_expected, + "RtlRandom(&seed (seed == 0)) sets seed to %lx, expected %lx\n", + seed, seed_expected); +/* + * Seed is aggain set to the same value as before. This time we also + * have the same result as before. Interestingly the value of the + * result is 0x7fffffc3 which is the same value used in RtlUniform + * as const_2. If we do + * + * seed = 0; + * result = RtlUniform(&seed); + * + * we get the same result (0x7fffffc3) as with + * + * seed = 0; + * RtlRandom(&seed); + * seed = 0; + * result = RtlRandom(&seed); + * + * And there is another interesting thing. If we do + * + * seed = 0; + * RtlUniform(&seed); + * RtlUniform(&seed); + * + * seed is set to the value 0x44b which ist the same value that + * + * seed = 0; + * RtlRandom(&seed); + * + * assigns to seed. Putting these two findings together leads to + * the concluson that RtlRandom saves the value in some variable, + * like in the following algorithm: + * + * result = saved_value; + * saved_value = RtlUniform(&seed); + * RtlUniform(&seed); + * return(result); + * + * Now we do further tests with seed set to 1: + */ + seed = 1; + result_expected = 0x7a50bbc6; + seed_expected =0x5a1; + result = pRtlRandom(&seed); + ok(result == result_expected, + "RtlRandom(&seed (seed == 1)) returns %lx, expected %lx\n", + result, result_expected); + ok(seed == seed_expected, + "RtlRandom(&seed (seed == 1)) sets seed to %lx, expected %lx\n", + seed, seed_expected); +/* + * If there is just one saved_value the result now would be + * 0x7fffffc3. From this test we can see that there is more than + * one saved_value, like with this algorithm: + * + * result = saved_value[pos]; + * saved_value[pos] = RtlUniform(&seed); + * RtlUniform(&seed); + * return(result); + * + * But how is the value of pos determined? The calls to RtlUniform + * create a sequence of random numbers. Every second random number + * is put into the saved_value array and is used in some later call + * of RtlRandom as result. The only reasonable source to determine + * pos are the random numbers generated by RtlUniform which are not + * put into the saved_value array. This are the values of seed + * between the two calls of RtlUniform as in this algorithm: + * + * rand = RtlUniform(&seed); + * RtlUniform(&seed); + * pos = position(seed); + * result = saved_value[pos]; + * saved_value[pos] = rand; + * return(result); + * + * What remains to be determined is: The size of the saved_value array, + * the initial values of the saved_value array and the function + * position(seed). These tests are not shown here. + * The result of these tests is: The size of the saved_value array + * is 128, the initial values can be seen in the my_RtlRandom + * function and the position(seed) function is (seed & 0x7f). + * + * For a full test of RtlRandom 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++) { + seed_bak = seed; + seed_expected = seed; + result_expected = my_RtlRandom(&seed_expected); + /* The following corrections are necessary because the */ + /* previous tests changed the saved_value array */ + if (num == 0) { + result_expected = 0x7fffffc3; + } else if (num == 81) { + result_expected = 0x7fffffb1; + } /* if */ + result = pRtlRandom(&seed); + ok(result == result_expected, + "test: %llu RtlUniform(&seed (seed == %lx)) returns %lx, expected %lx\n", + num, seed_bak, result, result_expected); + ok(seed == seed_expected, + "test: %llu RtlUniform(&seed (seed == %lx)) sets seed to %lx, expected %lx\n", + num, seed_bak, seed, seed_expected); + } /* for */ +} + + +typedef struct { + ACCESS_MASK GrantedAccess; + ACCESS_MASK DesiredAccess; + BOOLEAN result; +} all_accesses_t; + +static const all_accesses_t all_accesses[] = { + {0xFEDCBA76, 0xFEDCBA76, 1}, + {0x00000000, 0xFEDCBA76, 0}, + {0xFEDCBA76, 0x00000000, 1}, + {0x00000000, 0x00000000, 1}, + {0xFEDCBA76, 0xFEDCBA70, 1}, + {0xFEDCBA70, 0xFEDCBA76, 0}, + {0xFEDCBA76, 0xFEDC8A76, 1}, + {0xFEDC8A76, 0xFEDCBA76, 0}, + {0xFEDCBA76, 0xC8C4B242, 1}, + {0xC8C4B242, 0xFEDCBA76, 0}, +}; +#define NB_ALL_ACCESSES (sizeof(all_accesses)/sizeof(*all_accesses)) + + +static void test_RtlAreAllAccessesGranted(void) +{ + size_t test_num; + BOOLEAN result; + + for (test_num = 0; test_num < NB_ALL_ACCESSES; test_num++) { + result = pRtlAreAllAccessesGranted(all_accesses[test_num].GrantedAccess, + all_accesses[test_num].DesiredAccess); + ok(all_accesses[test_num].result == result, + "(test %d): RtlAreAllAccessesGranted(%08lx, %08lx) returns %d, expected %d\n", + test_num, all_accesses[test_num].GrantedAccess, + all_accesses[test_num].DesiredAccess, + result, all_accesses[test_num].result); + } /* for */ +} + + +typedef struct { + ACCESS_MASK GrantedAccess; + ACCESS_MASK DesiredAccess; + BOOLEAN result; +} any_accesses_t; + +static const any_accesses_t any_accesses[] = { + {0xFEDCBA76, 0xFEDCBA76, 1}, + {0x00000000, 0xFEDCBA76, 0}, + {0xFEDCBA76, 0x00000000, 0}, + {0x00000000, 0x00000000, 0}, + {0xFEDCBA76, 0x01234589, 0}, + {0x00040000, 0xFEDCBA76, 1}, + {0x00040000, 0xFED8BA76, 0}, + {0xFEDCBA76, 0x00040000, 1}, + {0xFED8BA76, 0x00040000, 0}, +}; +#define NB_ANY_ACCESSES (sizeof(any_accesses)/sizeof(*any_accesses)) + + +static void test_RtlAreAnyAccessesGranted(void) +{ + size_t test_num; + BOOLEAN result; + + for (test_num = 0; test_num < NB_ANY_ACCESSES; test_num++) { + result = pRtlAreAnyAccessesGranted(any_accesses[test_num].GrantedAccess, + any_accesses[test_num].DesiredAccess); + ok(any_accesses[test_num].result == result, + "(test %d): RtlAreAnyAccessesGranted(%08lx, %08lx) returns %d, expected %d\n", + test_num, any_accesses[test_num].GrantedAccess, + any_accesses[test_num].DesiredAccess, + result, any_accesses[test_num].result); + } /* for */ +} + +static void test_RtlComputeCrc32(void) +{ + DWORD crc = 0; + + if (!pRtlComputeCrc32) + return; + + crc = pRtlComputeCrc32(crc, src, LEN); + ok(crc == 0x40861dc2,"Expected 0x40861dc2, got %8lx\n", crc); +} + + +typedef struct MY_HANDLE +{ + RTL_HANDLE RtlHandle; + void * MyValue; +} MY_HANDLE; + +static inline void RtlpMakeHandleAllocated(RTL_HANDLE * Handle) +{ + ULONG_PTR *AllocatedBit = (ULONG_PTR *)(&Handle->Next); + *AllocatedBit = *AllocatedBit | 1; +} + +static void test_HandleTables(void) +{ + BOOLEAN result; + NTSTATUS status; + ULONG Index; + MY_HANDLE * MyHandle; + RTL_HANDLE_TABLE HandleTable; + + pRtlInitializeHandleTable(0x3FFF, sizeof(MY_HANDLE), &HandleTable); + MyHandle = (MY_HANDLE *)pRtlAllocateHandle(&HandleTable, &Index); + ok(MyHandle != NULL, "RtlAllocateHandle failed\n"); + RtlpMakeHandleAllocated(&MyHandle->RtlHandle); + MyHandle = NULL; + result = pRtlIsValidIndexHandle(&HandleTable, Index, (RTL_HANDLE **)&MyHandle); + ok(result, "Handle %p wasn't valid\n", MyHandle); + result = pRtlFreeHandle(&HandleTable, &MyHandle->RtlHandle); + ok(result, "Couldn't free handle %p\n", MyHandle); + status = pRtlDestroyHandleTable(&HandleTable); + ok(status == STATUS_SUCCESS, "RtlDestroyHandleTable failed with error 0x%08lx\n", status); +} + +START_TEST(rtl) +{ + InitFunctionPtrs(); + + if (pRtlCompareMemory) + test_RtlCompareMemory(); + if (pRtlCompareMemoryUlong) + test_RtlCompareMemoryUlong(); + if (pRtlMoveMemory) + test_RtlMoveMemory(); + if (pRtlFillMemory) + test_RtlFillMemory(); + if (pRtlFillMemoryUlong) + test_RtlFillMemoryUlong(); + if (pRtlZeroMemory) + test_RtlZeroMemory(); + if (pRtlUlonglongByteSwap) + test_RtlUlonglongByteSwap(); + if (pRtlUniform) + test_RtlUniform(); + if (pRtlRandom) + test_RtlRandom(); + if (pRtlAreAllAccessesGranted) + test_RtlAreAllAccessesGranted(); + if (pRtlAreAnyAccessesGranted) + test_RtlAreAnyAccessesGranted(); + if (pRtlComputeCrc32) + test_RtlComputeCrc32(); + if (pRtlInitializeHandleTable) + test_HandleTables(); +} diff --git a/reactos/regtests/winetests/ntdll/rtlbitmap.c b/reactos/regtests/winetests/ntdll/rtlbitmap.c new file mode 100755 index 00000000000..3ab115782d3 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/rtlbitmap.c @@ -0,0 +1,640 @@ +/* Unit test suite for Rtl bitmap functions + * + * Copyright 2002 Jon Griffiths + * + * 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 some of the bitmap functions exist only + * in later versions of ntdll. + */ + +#include "ntdll_test.h" + +#ifdef __WINE_WINTERNL_H + +/* Function ptrs for ordinal calls */ +static HMODULE hntdll = 0; +static VOID (WINAPI *pRtlInitializeBitMap)(PRTL_BITMAP,LPBYTE,ULONG); +static VOID (WINAPI *pRtlSetAllBits)(PRTL_BITMAP); +static VOID (WINAPI *pRtlClearAllBits)(PRTL_BITMAP); +static VOID (WINAPI *pRtlSetBits)(PRTL_BITMAP,ULONG,ULONG); +static VOID (WINAPI *pRtlClearBits)(PRTL_BITMAP,ULONG,ULONG); +static BOOLEAN (WINAPI *pRtlAreBitsSet)(PRTL_BITMAP,ULONG,ULONG); +static BOOLEAN (WINAPI *pRtlAreBitsClear)(PRTL_BITMAP,ULONG,ULONG); +static ULONG (WINAPI *pRtlFindSetBitsAndClear)(PRTL_BITMAP,ULONG,ULONG); +static ULONG (WINAPI *pRtlFindClearBitsAndSet)(PRTL_BITMAP,ULONG,ULONG); +static CCHAR (WINAPI *pRtlFindMostSignificantBit)(ULONGLONG); +static CCHAR (WINAPI *pRtlFindLeastSignificantBit)(ULONGLONG); +static ULONG (WINAPI *pRtlFindSetRuns)(PRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN); +static ULONG (WINAPI *pRtlFindClearRuns)(PRTL_BITMAP,PRTL_BITMAP_RUN,ULONG,BOOLEAN); +static ULONG (WINAPI *pRtlNumberOfSetBits)(PRTL_BITMAP); +static ULONG (WINAPI *pRtlNumberOfClearBits)(PRTL_BITMAP); +static ULONG (WINAPI *pRtlFindLongestRunSet)(PRTL_BITMAP,PULONG); +static ULONG (WINAPI *pRtlFindLongestRunClear)(PRTL_BITMAP,PULONG); + +static BYTE buff[256]; +static RTL_BITMAP bm; + +static void InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + ok(hntdll != 0, "LoadLibrary failed\n"); + if (hntdll) + { + pRtlInitializeBitMap = (void *)GetProcAddress(hntdll, "RtlInitializeBitMap"); + pRtlSetAllBits = (void *)GetProcAddress(hntdll, "RtlSetAllBits"); + pRtlClearAllBits = (void *)GetProcAddress(hntdll, "RtlClearAllBits"); + pRtlSetBits = (void *)GetProcAddress(hntdll, "RtlSetBits"); + pRtlClearBits = (void *)GetProcAddress(hntdll, "RtlClearBits"); + pRtlAreBitsSet = (void *)GetProcAddress(hntdll, "RtlAreBitsSet"); + pRtlAreBitsClear = (void *)GetProcAddress(hntdll, "RtlAreBitsClear"); + pRtlNumberOfSetBits = (void *)GetProcAddress(hntdll, "RtlNumberOfSetBits"); + pRtlNumberOfClearBits = (void *)GetProcAddress(hntdll, "RtlNumberOfClearBits"); + pRtlFindSetBitsAndClear = (void *)GetProcAddress(hntdll, "RtlFindSetBitsAndClear"); + pRtlFindClearBitsAndSet = (void *)GetProcAddress(hntdll, "RtlFindClearBitsAndSet"); + pRtlFindMostSignificantBit = (void *)GetProcAddress(hntdll, "RtlFindMostSignificantBit"); + pRtlFindLeastSignificantBit = (void *)GetProcAddress(hntdll, "RtlFindLeastSignificantBit"); + pRtlFindSetRuns = (void *)GetProcAddress(hntdll, "RtlFindSetRuns"); + pRtlFindClearRuns = (void *)GetProcAddress(hntdll, "RtlFindClearRuns"); + pRtlFindLongestRunSet = (void *)GetProcAddress(hntdll, "RtlFindLongestRunSet"); + pRtlFindLongestRunClear = (void *)GetProcAddress(hntdll, "RtlFindLongestRunClear"); + } +} + +static void test_RtlInitializeBitMap(void) +{ + bm.SizeOfBitMap = 0; + bm.Buffer = 0; + + memset(buff, 0, sizeof(buff)); + buff[0] = 77; /* Check buffer is not written to during init */ + buff[79] = 77; + + pRtlInitializeBitMap(&bm, buff, 800); + ok(bm.SizeOfBitMap == 800, "size uninitialised\n"); + ok(bm.Buffer == (PULONG)buff,"buffer uninitialised\n"); + ok(buff[0] == 77 && buff[79] == 77, "wrote to buffer\n"); +} + +static void test_RtlSetAllBits(void) +{ + if (!pRtlSetAllBits) + return; + + memset(buff, 0 , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, 1); + + pRtlSetAllBits(&bm); + ok(buff[0] == 0xff && buff[1] == 0xff && buff[2] == 0xff && + buff[3] == 0xff, "didn't round up size\n"); + ok(buff[4] == 0, "set more than rounded size\n"); +} + +static void test_RtlClearAllBits(void) +{ + if (!pRtlClearAllBits) + return; + + memset(buff, 0xff , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, 1); + + pRtlClearAllBits(&bm); + ok(!buff[0] && !buff[1] && !buff[2] && !buff[3], "didn't round up size\n"); + ok(buff[4] == 0xff, "cleared more than rounded size\n"); +} + +static void test_RtlSetBits(void) +{ + if (!pRtlSetBits) + return; + + memset(buff, 0 , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + pRtlSetBits(&bm, 0, 1); + ok(buff[0] == 1, "didn't set 1st bit\n"); + + buff[0] = 0; + pRtlSetBits(&bm, 7, 2); + ok(buff[0] == 0x80 && buff[1] == 1, "didn't span w/len < 8\n"); + + buff[0] = buff[1] = 0; + pRtlSetBits(&bm, 7, 10); + ok(buff[0] == 0x80 && buff[1] == 0xff && buff[2] == 1, "didn't span w/len > 8\n"); + + buff[0] = buff[1] = buff[2] = 0; + pRtlSetBits(&bm, 0, 8); /* 1st byte */ + ok(buff[0] == 0xff, "didn't set all bits\n"); + ok(!buff[1], "set too many bits\n"); + + pRtlSetBits(&bm, sizeof(buff)*8-1, 1); /* last bit */ + ok(buff[sizeof(buff)-1] == 0x80, "didn't set last bit\n"); +} + +static void test_RtlClearBits(void) +{ + if (!pRtlClearBits) + return; + + memset(buff, 0xff , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + pRtlClearBits(&bm, 0, 1); + ok(buff[0] == 0xfe, "didn't clear 1st bit\n"); + + buff[0] = 0xff; + pRtlClearBits(&bm, 7, 2); + ok(buff[0] == 0x7f && buff[1] == 0xfe, "didn't span w/len < 8\n"); + + buff[0] = buff[1] = 0xff; + pRtlClearBits(&bm, 7, 10); + ok(buff[0] == 0x7f && buff[1] == 0 && buff[2] == 0xfe, "didn't span w/len > 8\n"); + + buff[0] = buff[1] = buff[2] = 0xff; + pRtlClearBits(&bm, 0, 8); /* 1st byte */ + ok(!buff[0], "didn't clear all bits\n"); + ok(buff[1] == 0xff, "cleared too many bits\n"); + + pRtlClearBits(&bm, sizeof(buff)*8-1, 1); + ok(buff[sizeof(buff)-1] == 0x7f, "didn't set last bit\n"); +} + +static void test_RtlCheckBit(void) +{ + BOOLEAN bRet; + + memset(buff, 0 , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + pRtlSetBits(&bm, 0, 1); + pRtlSetBits(&bm, 7, 2); + pRtlSetBits(&bm, sizeof(buff)*8-1, 1); + + bRet = RtlCheckBit(&bm, 0); + ok (bRet, "didn't find set bit\n"); + bRet = RtlCheckBit(&bm, 7); + ok (bRet, "didn't find set bit\n"); + bRet = RtlCheckBit(&bm, 8); + ok (bRet, "didn't find set bit\n"); + bRet = RtlCheckBit(&bm, sizeof(buff)*8-1); + ok (bRet, "didn't find set bit\n"); + bRet = RtlCheckBit(&bm, 1); + ok (!bRet, "found non set bit\n"); + bRet = RtlCheckBit(&bm, sizeof(buff)*8-2); + ok (!bRet, "found non set bit\n"); +} + +static void test_RtlAreBitsSet(void) +{ + BOOLEAN bRet; + + if (!pRtlAreBitsSet) + return; + + memset(buff, 0 , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + bRet = pRtlAreBitsSet(&bm, 0, 1); + ok (!bRet, "found set bits after init\n"); + + pRtlSetBits(&bm, 0, 1); + bRet = pRtlAreBitsSet(&bm, 0, 1); + ok (bRet, "didn't find set bits\n"); + + buff[0] = 0; + pRtlSetBits(&bm, 7, 2); + bRet = pRtlAreBitsSet(&bm, 7, 2); + ok(bRet, "didn't find w/len < 8\n"); + bRet = pRtlAreBitsSet(&bm, 6, 3); + ok(!bRet, "found non set bit\n"); + bRet = pRtlAreBitsSet(&bm, 7, 3); + ok(!bRet, "found non set bit\n"); + + buff[0] = buff[1] = 0; + pRtlSetBits(&bm, 7, 10); + bRet = pRtlAreBitsSet(&bm, 7, 10); + ok(bRet, "didn't find w/len < 8\n"); + bRet = pRtlAreBitsSet(&bm, 6, 11); + ok(!bRet, "found non set bit\n"); + bRet = pRtlAreBitsSet(&bm, 7, 11); + ok(!bRet, "found non set bit\n"); + + buff[0] = buff[1] = buff[2] = 0; + pRtlSetBits(&bm, 0, 8); /* 1st byte */ + bRet = pRtlAreBitsSet(&bm, 0, 8); + ok(bRet, "didn't find whole byte\n"); + + pRtlSetBits(&bm, sizeof(buff)*8-1, 1); + bRet = pRtlAreBitsSet(&bm, sizeof(buff)*8-1, 1); + ok(bRet, "didn't find last bit\n"); +} + +static void test_RtlAreBitsClear(void) +{ + BOOLEAN bRet; + + if (!pRtlAreBitsClear) + return; + + memset(buff, 0xff , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + bRet = pRtlAreBitsClear(&bm, 0, 1); + ok (!bRet, "found clear bits after init\n"); + + pRtlClearBits(&bm, 0, 1); + bRet = pRtlAreBitsClear(&bm, 0, 1); + ok (bRet, "didn't find set bits\n"); + + buff[0] = 0xff; + pRtlClearBits(&bm, 7, 2); + bRet = pRtlAreBitsClear(&bm, 7, 2); + ok(bRet, "didn't find w/len < 8\n"); + bRet = pRtlAreBitsClear(&bm, 6, 3); + ok(!bRet, "found non clear bit\n"); + bRet = pRtlAreBitsClear(&bm, 7, 3); + ok(!bRet, "found non clear bit\n"); + + buff[0] = buff[1] = 0xff; + pRtlClearBits(&bm, 7, 10); + bRet = pRtlAreBitsClear(&bm, 7, 10); + ok(bRet, "didn't find w/len < 8\n"); + bRet = pRtlAreBitsClear(&bm, 6, 11); + ok(!bRet, "found non clear bit\n"); + bRet = pRtlAreBitsClear(&bm, 7, 11); + ok(!bRet, "found non clear bit\n"); + + buff[0] = buff[1] = buff[2] = 0xff; + pRtlClearBits(&bm, 0, 8); /* 1st byte */ + bRet = pRtlAreBitsClear(&bm, 0, 8); + ok(bRet, "didn't find whole byte\n"); + + pRtlClearBits(&bm, sizeof(buff)*8-1, 1); + bRet = pRtlAreBitsClear(&bm, sizeof(buff)*8-1, 1); + ok(bRet, "didn't find last bit\n"); +} + +static void test_RtlNumberOfSetBits(void) +{ + ULONG ulCount; + + if (!pRtlNumberOfSetBits) + return; + + memset(buff, 0 , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + ulCount = pRtlNumberOfSetBits(&bm); + ok(ulCount == 0, "set bits after init\n"); + + pRtlSetBits(&bm, 0, 1); /* Set 1st bit */ + ulCount = pRtlNumberOfSetBits(&bm); + ok(ulCount == 1, "count wrong\n"); + + pRtlSetBits(&bm, 7, 8); /* 8 more, spanning bytes 1-2 */ + ulCount = pRtlNumberOfSetBits(&bm); + ok(ulCount == 8+1, "count wrong\n"); + + pRtlSetBits(&bm, 17, 33); /* 33 more crossing ULONG boundary */ + ulCount = pRtlNumberOfSetBits(&bm); + ok(ulCount == 8+1+33, "count wrong\n"); + + pRtlSetBits(&bm, sizeof(buff)*8-1, 1); /* Set last bit */ + ulCount = pRtlNumberOfSetBits(&bm); + ok(ulCount == 8+1+33+1, "count wrong\n"); +} + +static void test_RtlNumberOfClearBits(void) +{ + ULONG ulCount; + + if (!pRtlNumberOfClearBits) + return; + + memset(buff, 0xff , sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + ulCount = pRtlNumberOfClearBits(&bm); + ok(ulCount == 0, "cleared bits after init\n"); + + pRtlClearBits(&bm, 0, 1); /* Set 1st bit */ + ulCount = pRtlNumberOfClearBits(&bm); + ok(ulCount == 1, "count wrong\n"); + + pRtlClearBits(&bm, 7, 8); /* 8 more, spanning bytes 1-2 */ + ulCount = pRtlNumberOfClearBits(&bm); + ok(ulCount == 8+1, "count wrong\n"); + + pRtlClearBits(&bm, 17, 33); /* 33 more crossing ULONG boundary */ + ulCount = pRtlNumberOfClearBits(&bm); + ok(ulCount == 8+1+33, "count wrong\n"); + + pRtlClearBits(&bm, sizeof(buff)*8-1, 1); /* Set last bit */ + ulCount = pRtlNumberOfClearBits(&bm); + ok(ulCount == 8+1+33+1, "count wrong\n"); +} + +/* Note: this tests RtlFindSetBits also */ +static void test_RtlFindSetBitsAndClear(void) +{ + BOOLEAN bRet; + ULONG ulPos; + + if (!pRtlFindSetBitsAndClear) + return; + + memset(buff, 0, sizeof(buff)); + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + pRtlSetBits(&bm, 0, 32); + ulPos = pRtlFindSetBitsAndClear(&bm, 32, 0); + ok (ulPos == 0, "didn't find bits\n"); + if(ulPos == 0) + { + bRet = pRtlAreBitsClear(&bm, 0, 32); + ok (bRet, "found but didn't clear\n"); + } + + memset(buff, 0 , sizeof(buff)); + pRtlSetBits(&bm, 40, 77); + ulPos = pRtlFindSetBitsAndClear(&bm, 77, 0); + ok (ulPos == 40, "didn't find bits\n"); + if(ulPos == 40) + { + bRet = pRtlAreBitsClear(&bm, 40, 77); + ok (bRet, "found but didn't clear\n"); + } +} + +/* Note: this tests RtlFindClearBits also */ +static void test_RtlFindClearBitsAndSet(void) +{ + BOOLEAN bRet; + ULONG ulPos; + + if (!pRtlFindClearBitsAndSet) + return; + + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + memset(buff, 0xff, sizeof(buff)); + pRtlSetBits(&bm, 0, 32); + ulPos = pRtlFindSetBitsAndClear(&bm, 32, 0); + ok (ulPos == 0, "didn't find bits\n"); + if(ulPos == 0) + { + bRet = pRtlAreBitsClear(&bm, 0, 32); + ok (bRet, "found but didn't clear\n"); + } + + memset(buff, 0xff , sizeof(buff)); + pRtlClearBits(&bm, 40, 77); + ulPos = pRtlFindClearBitsAndSet(&bm, 77, 50); + ok (ulPos == 40, "didn't find bits\n"); + if(ulPos == 40) + { + bRet = pRtlAreBitsSet(&bm, 40, 77); + ok (bRet, "found but didn't set\n"); + } +} + +static void test_RtlFindMostSignificantBit(void) +{ + int i; + CCHAR cPos; + ULONGLONG ulLong; + + if (!pRtlFindMostSignificantBit) + return; + + for (i = 0; i < 64; i++) + { + ulLong = 1ul; + ulLong <<= i; + + cPos = pRtlFindMostSignificantBit(ulLong); + ok (cPos == i, "didn't find MSB %llx %d %d\n", ulLong, i, cPos); + + /* Set all bits lower than bit i */ + ulLong = ((ulLong - 1) << 1) | 1; + + cPos = pRtlFindMostSignificantBit(ulLong); + ok (cPos == i, "didn't find MSB %llx %d %d\n", ulLong, i, cPos); + } + cPos = pRtlFindMostSignificantBit(0); + ok (cPos == -1, "found bit when not set\n"); +} + +static void test_RtlFindLeastSignificantBit(void) +{ + int i; + CCHAR cPos; + ULONGLONG ulLong; + + if (!pRtlFindLeastSignificantBit) + return; + + for (i = 0; i < 64; i++) + { + ulLong = (ULONGLONG)1 << i; + + cPos = pRtlFindLeastSignificantBit(ulLong); + ok (cPos == i, "didn't find LSB %llx %d %d\n", ulLong, i, cPos); + + ulLong = ~((ULONGLONG)0) << i; + + cPos = pRtlFindLeastSignificantBit(ulLong); + ok (cPos == i, "didn't find LSB %llx %d %d\n", ulLong, i, cPos); + } + cPos = pRtlFindLeastSignificantBit(0); + ok (cPos == -1, "found bit when not set\n"); +} + +/* Note: Also tests RtlFindLongestRunSet() */ +static void test_RtlFindSetRuns(void) +{ + RTL_BITMAP_RUN runs[16]; + ULONG ulCount; + + if (!pRtlFindSetRuns) + return; + + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + memset(buff, 0, sizeof(buff)); + ulCount = pRtlFindSetRuns(&bm, runs, 16, TRUE); + ok (ulCount == 0, "found set bits in empty bitmap\n"); + + memset(runs, 0, sizeof(runs)); + memset(buff, 0xff, sizeof(buff)); + ulCount = pRtlFindSetRuns(&bm, runs, 16, TRUE); + ok (ulCount == 1, "didn't find set bits\n"); + ok (runs[0].StartingIndex == 0,"bad start\n"); + ok (runs[0].NumberOfBits == sizeof(buff)*8,"bad size\n"); + + /* Set up 3 runs */ + memset(runs, 0, sizeof(runs)); + memset(buff, 0, sizeof(buff)); + pRtlSetBits(&bm, 7, 19); + pRtlSetBits(&bm, 101, 3); + pRtlSetBits(&bm, 1877, 33); + + /* Get first 2 */ + ulCount = pRtlFindSetRuns(&bm, runs, 2, FALSE); + ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101,"bad find\n"); + ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101,"bad find\n"); + ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 19 + 3,"bad size\n"); + ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n"); + ok (runs[2].StartingIndex == 0,"found extra run\n"); + + /* Get longest 3 */ + memset(runs, 0, sizeof(runs)); + ulCount = pRtlFindSetRuns(&bm, runs, 2, TRUE); + ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 1877,"bad find\n"); + ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 1877,"bad find\n"); + ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 33 + 19,"bad size\n"); + ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n"); + ok (runs[2].StartingIndex == 0,"found extra run\n"); + + /* Get all 3 */ + memset(runs, 0, sizeof(runs)); + ulCount = pRtlFindSetRuns(&bm, runs, 3, TRUE); + ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101 || + runs[0].StartingIndex == 1877,"bad find\n"); + ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101 || + runs[1].StartingIndex == 1877,"bad find\n"); + ok (runs[2].StartingIndex == 7 || runs[2].StartingIndex == 101 || + runs[2].StartingIndex == 1877,"bad find\n"); + ok (runs[0].NumberOfBits + runs[1].NumberOfBits + + runs[2].NumberOfBits == 19 + 3 + 33,"bad size\n"); + ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n"); + ok (runs[1].StartingIndex != runs[2].StartingIndex,"found run twice\n"); + ok (runs[3].StartingIndex == 0,"found extra run\n"); + + if (pRtlFindLongestRunSet) + { + ULONG ulStart = 0; + + ulCount = pRtlFindLongestRunSet(&bm, &ulStart); + ok(ulCount == 33 && ulStart == 1877,"didn't find longest %ld %ld\n",ulCount,ulStart); + + memset(buff, 0, sizeof(buff)); + ulCount = pRtlFindLongestRunSet(&bm, &ulStart); + ok(ulCount == 0,"found longest when none set\n"); + } +} + +/* Note: Also tests RtlFindLongestRunClear() */ +static void test_RtlFindClearRuns(void) +{ + RTL_BITMAP_RUN runs[16]; + ULONG ulCount; + + if (!pRtlFindClearRuns) + return; + + pRtlInitializeBitMap(&bm, buff, sizeof(buff)*8); + + memset(buff, 0xff, sizeof(buff)); + ulCount = pRtlFindClearRuns(&bm, runs, 16, TRUE); + ok (ulCount == 0, "found clear bits in full bitmap\n"); + + memset(runs, 0, sizeof(runs)); + memset(buff, 0, sizeof(buff)); + ulCount = pRtlFindClearRuns(&bm, runs, 16, TRUE); + ok (ulCount == 1, "didn't find clear bits\n"); + ok (runs[0].StartingIndex == 0,"bad start\n"); + ok (runs[0].NumberOfBits == sizeof(buff)*8,"bad size\n"); + + /* Set up 3 runs */ + memset(runs, 0, sizeof(runs)); + memset(buff, 0xff, sizeof(buff)); + pRtlClearBits(&bm, 7, 19); + pRtlClearBits(&bm, 101, 3); + pRtlClearBits(&bm, 1877, 33); + + /* Get first 2 */ + ulCount = pRtlFindClearRuns(&bm, runs, 2, FALSE); + ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101,"bad find\n"); + ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101,"bad find\n"); + ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 19 + 3,"bad size\n"); + ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n"); + ok (runs[2].StartingIndex == 0,"found extra run\n"); + + /* Get longest 3 */ + memset(runs, 0, sizeof(runs)); + ulCount = pRtlFindClearRuns(&bm, runs, 2, TRUE); + ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 1877,"bad find\n"); + ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 1877,"bad find\n"); + ok (runs[0].NumberOfBits + runs[1].NumberOfBits == 33 + 19,"bad size\n"); + ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n"); + ok (runs[2].StartingIndex == 0,"found extra run\n"); + + /* Get all 3 */ + memset(runs, 0, sizeof(runs)); + ulCount = pRtlFindClearRuns(&bm, runs, 3, TRUE); + ok (runs[0].StartingIndex == 7 || runs[0].StartingIndex == 101 || + runs[0].StartingIndex == 1877,"bad find\n"); + ok (runs[1].StartingIndex == 7 || runs[1].StartingIndex == 101 || + runs[1].StartingIndex == 1877,"bad find\n"); + ok (runs[2].StartingIndex == 7 || runs[2].StartingIndex == 101 || + runs[2].StartingIndex == 1877,"bad find\n"); + ok (runs[0].NumberOfBits + runs[1].NumberOfBits + + runs[2].NumberOfBits == 19 + 3 + 33,"bad size\n"); + ok (runs[0].StartingIndex != runs[1].StartingIndex,"found run twice\n"); + ok (runs[1].StartingIndex != runs[2].StartingIndex,"found run twice\n"); + ok (runs[3].StartingIndex == 0,"found extra run\n"); + + if (pRtlFindLongestRunClear) + { + ULONG ulStart = 0; + + ulCount = pRtlFindLongestRunClear(&bm, &ulStart); + ok(ulCount == 33 && ulStart == 1877,"didn't find longest\n"); + + memset(buff, 0xff, sizeof(buff)); + ulCount = pRtlFindLongestRunClear(&bm, &ulStart); + ok(ulCount == 0,"found longest when none clear\n"); + } + +} +#endif + +START_TEST(rtlbitmap) +{ +#ifdef __WINE_WINTERNL_H + InitFunctionPtrs(); + + if (pRtlInitializeBitMap) + { + test_RtlInitializeBitMap(); + test_RtlSetAllBits(); + test_RtlClearAllBits(); + test_RtlSetBits(); + test_RtlClearBits(); + test_RtlCheckBit(); + test_RtlAreBitsSet(); + test_RtlAreBitsClear(); + test_RtlNumberOfSetBits(); + test_RtlNumberOfClearBits(); + test_RtlFindSetBitsAndClear(); + test_RtlFindClearBitsAndSet(); + test_RtlFindMostSignificantBit(); + test_RtlFindLeastSignificantBit(); + test_RtlFindSetRuns(); + test_RtlFindClearRuns(); + } +#endif +} diff --git a/reactos/regtests/winetests/ntdll/rtlstr.c b/reactos/regtests/winetests/ntdll/rtlstr.c new file mode 100755 index 00000000000..63346c7a524 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/rtlstr.c @@ -0,0 +1,1741 @@ +/* Unit test suite for Rtl string functions + * + * Copyright 2002 Robert Shearman + * 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 + +#define INITGUID + +#include "ntdll_test.h" +#include "winnls.h" +#include "guiddef.h" + +/* Function ptrs for ntdll calls */ +static HMODULE hntdll = 0; +static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING, PCANSI_STRING, BOOLEAN); +static NTSTATUS (WINAPI *pRtlAppendAsciizToString)(STRING *, LPCSTR); +static NTSTATUS (WINAPI *pRtlAppendStringToString)(STRING *, const STRING *); +static NTSTATUS (WINAPI *pRtlAppendUnicodeStringToString)(UNICODE_STRING *, const UNICODE_STRING *); +static NTSTATUS (WINAPI *pRtlAppendUnicodeToString)(UNICODE_STRING *, LPCWSTR); +static NTSTATUS (WINAPI *pRtlCharToInteger)(PCSZ, ULONG, int *); +static VOID (WINAPI *pRtlCopyString)(STRING *, const STRING *); +static BOOLEAN (WINAPI *pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR); +static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR); +static NTSTATUS (WINAPI *pRtlDowncaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN); +static NTSTATUS (WINAPI *pRtlDuplicateUnicodeString)(long, UNICODE_STRING *, UNICODE_STRING *); +static BOOLEAN (WINAPI *pRtlEqualUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN); +static NTSTATUS (WINAPI *pRtlFindCharInUnicodeString)(int, const UNICODE_STRING *, const UNICODE_STRING *, USHORT *); +static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING); +static VOID (WINAPI *pRtlInitAnsiString)(PSTRING, LPCSTR); +static VOID (WINAPI *pRtlInitString)(PSTRING, LPCSTR); +static VOID (WINAPI *pRtlInitUnicodeString)(PUNICODE_STRING, LPCWSTR); +static NTSTATUS (WINAPI *pRtlInitUnicodeStringEx)(PUNICODE_STRING, LPCWSTR); +static NTSTATUS (WINAPI *pRtlIntegerToChar)(ULONG, ULONG, ULONG, PCHAR); +static NTSTATUS (WINAPI *pRtlIntegerToUnicodeString)(ULONG, ULONG, UNICODE_STRING *); +static NTSTATUS (WINAPI *pRtlMultiAppendUnicodeStringBuffer)(UNICODE_STRING *, long, UNICODE_STRING *); +static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN); +static NTSTATUS (WINAPI *pRtlUnicodeStringToInteger)(const UNICODE_STRING *, int, int *); +static WCHAR (WINAPI *pRtlUpcaseUnicodeChar)(WCHAR); +static NTSTATUS (WINAPI *pRtlUpcaseUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN); +static CHAR (WINAPI *pRtlUpperChar)(CHAR); +static NTSTATUS (WINAPI *pRtlUpperString)(STRING *, const STRING *); +static NTSTATUS (WINAPI *pRtlValidateUnicodeString)(long, UNICODE_STRING *); +static NTSTATUS (WINAPI *pRtlGUIDFromString)(const UNICODE_STRING*,GUID*); +static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*); + +/*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/ +/*static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);*/ +/*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/ +/*static VOID (WINAPI *pRtlEraseUnicodeString)(UNICODE_STRING *);*/ +/*static LONG (WINAPI *pRtlCompareString)(const STRING *,const STRING *,BOOLEAN);*/ +/*static LONG (WINAPI *pRtlCompareUnicodeString)(const UNICODE_STRING *,const UNICODE_STRING *,BOOLEAN);*/ +/*static BOOLEAN (WINAPI *pRtlEqualString)(const STRING *,const STRING *,BOOLEAN);*/ +/*static BOOLEAN (WINAPI *pRtlPrefixString)(const STRING *, const STRING *, BOOLEAN);*/ +/*static BOOLEAN (WINAPI *pRtlPrefixUnicodeString)(const UNICODE_STRING *, const UNICODE_STRING *, BOOLEAN);*/ +/*static NTSTATUS (WINAPI *pRtlOemStringToUnicodeString)(PUNICODE_STRING, const STRING *, BOOLEAN);*/ +/*static NTSTATUS (WINAPI *pRtlUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/ +/*static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/ +/*static NTSTATUS (WINAPI *pRtlOemToUnicodeN)(LPWSTR, DWORD, LPDWORD, LPCSTR, DWORD);*/ +/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/ +/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeStringToOemString)(STRING *, const UNICODE_STRING *, BOOLEAN);*/ +/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToMultiByteN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/ +/*static NTSTATUS (WINAPI *pRtlUpcaseUnicodeToOemN)(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD);*/ +/*static UINT (WINAPI *pRtlOemToUnicodeSize)(const STRING *);*/ +/*static DWORD (WINAPI *pRtlAnsiStringToUnicodeSize)(const STRING *);*/ +/*static DWORD (WINAPI *pRtlIsTextUnicode)(LPVOID, DWORD, DWORD *);*/ + + +static WCHAR* AtoW( const char* p ) +{ + WCHAR* buffer; + DWORD len = MultiByteToWideChar( CP_ACP, 0, p, -1, NULL, 0 ); + buffer = malloc( len * sizeof(WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, p, -1, buffer, len ); + return buffer; +} + + +static void InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + ok(hntdll != 0, "LoadLibrary failed\n"); + if (hntdll) { + pRtlAnsiStringToUnicodeString = (void *)GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString"); + pRtlAppendAsciizToString = (void *)GetProcAddress(hntdll, "RtlAppendAsciizToString"); + pRtlAppendStringToString = (void *)GetProcAddress(hntdll, "RtlAppendStringToString"); + pRtlAppendUnicodeStringToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeStringToString"); + pRtlAppendUnicodeToString = (void *)GetProcAddress(hntdll, "RtlAppendUnicodeToString"); + pRtlCharToInteger = (void *)GetProcAddress(hntdll, "RtlCharToInteger"); + pRtlCopyString = (void *)GetProcAddress(hntdll, "RtlCopyString"); + pRtlCreateUnicodeString = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeString"); + pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); + pRtlDowncaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlDowncaseUnicodeString"); + pRtlDuplicateUnicodeString = (void *)GetProcAddress(hntdll, "RtlDuplicateUnicodeString"); + pRtlEqualUnicodeString = (void *)GetProcAddress(hntdll, "RtlEqualUnicodeString"); + pRtlFindCharInUnicodeString = (void *)GetProcAddress(hntdll, "RtlFindCharInUnicodeString"); + pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString"); + pRtlInitAnsiString = (void *)GetProcAddress(hntdll, "RtlInitAnsiString"); + pRtlInitString = (void *)GetProcAddress(hntdll, "RtlInitString"); + pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString"); + pRtlInitUnicodeStringEx = (void *)GetProcAddress(hntdll, "RtlInitUnicodeStringEx"); + pRtlIntegerToChar = (void *)GetProcAddress(hntdll, "RtlIntegerToChar"); + pRtlIntegerToUnicodeString = (void *)GetProcAddress(hntdll, "RtlIntegerToUnicodeString"); + pRtlMultiAppendUnicodeStringBuffer = (void *)GetProcAddress(hntdll, "RtlMultiAppendUnicodeStringBuffer"); + pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString"); + pRtlUnicodeStringToInteger = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToInteger"); + pRtlUpcaseUnicodeChar = (void *)GetProcAddress(hntdll, "RtlUpcaseUnicodeChar"); + pRtlUpcaseUnicodeString = (void *)GetProcAddress(hntdll, "RtlUpcaseUnicodeString"); + pRtlUpperChar = (void *)GetProcAddress(hntdll, "RtlUpperChar"); + pRtlUpperString = (void *)GetProcAddress(hntdll, "RtlUpperString"); + pRtlValidateUnicodeString = (void *)GetProcAddress(hntdll, "RtlValidateUnicodeString"); + pRtlGUIDFromString = (void *)GetProcAddress(hntdll, "RtlGUIDFromString"); + pRtlStringFromGUID = (void *)GetProcAddress(hntdll, "RtlStringFromGUID"); + } +} + + +static void test_RtlInitString(void) +{ + static const char teststring[] = "Some Wild String"; + STRING str; + + str.Length = 0; + str.MaximumLength = 0; + str.Buffer = (void *)0xdeadbeef; + pRtlInitString(&str, teststring); + ok(str.Length == sizeof(teststring) - sizeof(char), "Length uninitialized\n"); + ok(str.MaximumLength == sizeof(teststring), "MaximumLength uninitialized\n"); + ok(str.Buffer == teststring, "Buffer not equal to teststring\n"); + ok(strcmp(str.Buffer, "Some Wild String") == 0, "Buffer written to\n"); + pRtlInitString(&str, NULL); + ok(str.Length == 0, "Length uninitialized\n"); + ok(str.MaximumLength == 0, "MaximumLength uninitialized\n"); + ok(str.Buffer == NULL, "Buffer not equal to NULL\n"); +/* pRtlInitString(NULL, teststring); */ +} + + +static void test_RtlInitUnicodeString(void) +{ +#define STRINGW {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0} + static const WCHAR teststring[] = STRINGW; + static const WCHAR originalstring[] = STRINGW; +#undef STRINGW + UNICODE_STRING uni; + + uni.Length = 0; + uni.MaximumLength = 0; + uni.Buffer = (void *)0xdeadbeef; + pRtlInitUnicodeString(&uni, teststring); + ok(uni.Length == sizeof(teststring) - sizeof(WCHAR), "Length uninitialized\n"); + ok(uni.MaximumLength == sizeof(teststring), "MaximumLength uninitialized\n"); + ok(uni.Buffer == teststring, "Buffer not equal to teststring\n"); + ok(lstrcmpW(uni.Buffer, originalstring) == 0, "Buffer written to\n"); + pRtlInitUnicodeString(&uni, NULL); + ok(uni.Length == 0, "Length uninitialized\n"); + ok(uni.MaximumLength == 0, "MaximumLength uninitialized\n"); + ok(uni.Buffer == NULL, "Buffer not equal to NULL\n"); +/* pRtlInitUnicodeString(NULL, teststring); */ +} + + +#define TESTSTRING2_LEN 1000000 +/* #define TESTSTRING2_LEN 32766 */ + + +static void test_RtlInitUnicodeStringEx(void) +{ + static const WCHAR teststring[] = {'S','o','m','e',' ','W','i','l','d',' ','S','t','r','i','n','g',0}; + WCHAR *teststring2; + UNICODE_STRING uni; + NTSTATUS result; + + teststring2 = (WCHAR *) malloc((TESTSTRING2_LEN + 1) * sizeof(WCHAR)); + memset(teststring2, 'X', TESTSTRING2_LEN * sizeof(WCHAR)); + teststring2[TESTSTRING2_LEN] = '\0'; + + uni.Length = 12345; + uni.MaximumLength = 12345; + uni.Buffer = (void *) 0xdeadbeef; + result = pRtlInitUnicodeStringEx(&uni, teststring); + ok(result == STATUS_SUCCESS, + "pRtlInitUnicodeStringEx(&uni, 0) returns %lx, expected %x\n", + result, STATUS_SUCCESS); + ok(uni.Length == 32, + "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n", + uni.Length, 32); + ok(uni.MaximumLength == 34, + "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n", + uni.MaximumLength, 34); + ok(uni.Buffer == teststring, + "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p\n", + uni.Buffer, teststring); + + uni.Length = 12345; + uni.MaximumLength = 12345; + uni.Buffer = (void *) 0xdeadbeef; + pRtlInitUnicodeString(&uni, teststring); + ok(uni.Length == 32, + "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n", + uni.Length, 32); + ok(uni.MaximumLength == 34, + "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n", + uni.MaximumLength, 34); + ok(uni.Buffer == teststring, + "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n", + uni.Buffer, teststring); + + uni.Length = 12345; + uni.MaximumLength = 12345; + uni.Buffer = (void *) 0xdeadbeef; + result = pRtlInitUnicodeStringEx(&uni, teststring2); + ok(result == STATUS_NAME_TOO_LONG, + "pRtlInitUnicodeStringEx(&uni, 0) returns %lx, expected %x\n", + result, STATUS_NAME_TOO_LONG); + ok(uni.Length == 12345, + "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n", + uni.Length, 12345); + ok(uni.MaximumLength == 12345, + "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n", + uni.MaximumLength, 12345); + ok(uni.Buffer == (void *) 0xdeadbeef, + "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %x\n", + uni.Buffer, 0xdeadbeef); + + uni.Length = 12345; + uni.MaximumLength = 12345; + uni.Buffer = (void *) 0xdeadbeef; + pRtlInitUnicodeString(&uni, teststring2); + ok(uni.Length == 33920, + "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n", + uni.Length, 33920); + ok(uni.MaximumLength == 33922, + "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n", + uni.MaximumLength, 33922); + ok(uni.Buffer == teststring2, + "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n", + uni.Buffer, teststring2); + ok(memcmp(uni.Buffer, teststring2, (TESTSTRING2_LEN + 1) * sizeof(WCHAR)) == 0, + "pRtlInitUnicodeString(&uni, 0) changes Buffer\n"); + + uni.Length = 12345; + uni.MaximumLength = 12345; + uni.Buffer = (void *) 0xdeadbeef; + result = pRtlInitUnicodeStringEx(&uni, 0); + ok(result == STATUS_SUCCESS, + "pRtlInitUnicodeStringEx(&uni, 0) returns %lx, expected %x\n", + result, STATUS_SUCCESS); + ok(uni.Length == 0, + "pRtlInitUnicodeStringEx(&uni, 0) sets Length to %u, expected %u\n", + uni.Length, 0); + ok(uni.MaximumLength == 0, + "pRtlInitUnicodeStringEx(&uni, 0) sets MaximumLength to %u, expected %u\n", + uni.MaximumLength, 0); + ok(uni.Buffer == NULL, + "pRtlInitUnicodeStringEx(&uni, 0) sets Buffer to %p, expected %p\n", + uni.Buffer, NULL); + + uni.Length = 12345; + uni.MaximumLength = 12345; + uni.Buffer = (void *) 0xdeadbeef; + pRtlInitUnicodeString(&uni, 0); + ok(uni.Length == 0, + "pRtlInitUnicodeString(&uni, 0) sets Length to %u, expected %u\n", + uni.Length, 0); + ok(uni.MaximumLength == 0, + "pRtlInitUnicodeString(&uni, 0) sets MaximumLength to %u, expected %u\n", + uni.MaximumLength, 0); + ok(uni.Buffer == NULL, + "pRtlInitUnicodeString(&uni, 0) sets Buffer to %p, expected %p\n", + uni.Buffer, NULL); +} + + +typedef struct { + int add_nul; + int source_Length; + int source_MaximumLength; + int source_buf_size; + const char *source_buf; + int dest_Length; + int dest_MaximumLength; + int dest_buf_size; + const char *dest_buf; + int res_Length; + int res_MaximumLength; + int res_buf_size; + const char *res_buf; + NTSTATUS result; +} dupl_ustr_t; + +static const dupl_ustr_t dupl_ustr[] = { + { 0, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 32, 32, "This is a string", STATUS_SUCCESS}, + { 0, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 32, 32, "This is a string", STATUS_SUCCESS}, + { 0, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 0, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 32, 32, 32, "This is a string", STATUS_SUCCESS}, + { 0, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 32, 32, 32, "This is a string", STATUS_SUCCESS}, + { 0, 32, 30, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 1, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 1, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 1, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 1, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 1, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 1, 32, 30, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 2, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 32, 30, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 2, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 2, 32, 30, 34, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 3, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 3, 32, 32, 32, "This is a string", 40, 42, 42, "--------------------", 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 3, 32, 30, 32, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 3, 32, 34, 34, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 3, 32, 32, 32, "This is a string", 40, 42, 42, NULL, 32, 34, 34, "This is a string", STATUS_SUCCESS}, + { 3, 32, 30, 32, "This is a string", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 4, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 5, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 6, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 7, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 8, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 9, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {10, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {11, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {12, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {13, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {14, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {15, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {16, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {-1, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {-5, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + {-9, 32, 34, 34, "This is a string", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 0, 0, 2, 2, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS}, + { 0, 0, 0, 0, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS}, + { 0, 0, 2, 2, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS}, + { 0, 0, 0, 0, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS}, + { 0, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 0, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS}, + { 0, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 0, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS}, + { 1, 0, 2, 2, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS}, + { 1, 0, 0, 0, "", 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS}, + { 1, 0, 2, 2, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS}, + { 1, 0, 0, 0, "", 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS}, + { 1, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 1, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 0, 0, 0, NULL, STATUS_SUCCESS}, + { 1, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 1, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 0, 0, NULL, STATUS_SUCCESS}, + { 2, 0, 2, 2, "", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 0, 0, 0, "", 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 0, 2, 2, "", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 2, 0, 0, 0, "", 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 2, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 2, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 2, 0, 0, 0, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 3, 0, 2, 2, "", 40, 42, 42, "--------------------", 0, 2, 2, "", STATUS_SUCCESS}, + { 3, 0, 0, 0, "", 40, 42, 42, "--------------------", 0, 2, 2, "", STATUS_SUCCESS}, + { 3, 0, 2, 2, "", 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS}, + { 3, 0, 0, 0, "", 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS}, + { 3, 0, 2, 2, NULL, 40, 42, 42, "--------------------", 40, 42, 42, "--------------------", STATUS_INVALID_PARAMETER}, + { 3, 0, 0, 0, NULL, 40, 42, 42, "--------------------", 0, 2, 2, "", STATUS_SUCCESS}, + { 3, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER}, + { 3, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS}, +}; +#define NB_DUPL_USTR (sizeof(dupl_ustr)/sizeof(*dupl_ustr)) + + +static void test_RtlDuplicateUnicodeString(void) +{ + size_t pos; + WCHAR source_buf[257]; + WCHAR dest_buf[257]; + WCHAR res_buf[257]; + UNICODE_STRING source_str; + UNICODE_STRING dest_str; + UNICODE_STRING res_str; + CHAR dest_ansi_buf[257]; + STRING dest_ansi_str; + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_DUPL_USTR; test_num++) { + source_str.Length = dupl_ustr[test_num].source_Length; + source_str.MaximumLength = dupl_ustr[test_num].source_MaximumLength; + if (dupl_ustr[test_num].source_buf != NULL) { + for (pos = 0; pos < dupl_ustr[test_num].source_buf_size/sizeof(WCHAR); pos++) { + source_buf[pos] = dupl_ustr[test_num].source_buf[pos]; + } + source_str.Buffer = source_buf; + } else { + source_str.Buffer = NULL; + } + dest_str.Length = dupl_ustr[test_num].dest_Length; + dest_str.MaximumLength = dupl_ustr[test_num].dest_MaximumLength; + if (dupl_ustr[test_num].dest_buf != NULL) { + for (pos = 0; pos < dupl_ustr[test_num].dest_buf_size/sizeof(WCHAR); pos++) { + dest_buf[pos] = dupl_ustr[test_num].dest_buf[pos]; + } + dest_str.Buffer = dest_buf; + } else { + dest_str.Buffer = NULL; + } + res_str.Length = dupl_ustr[test_num].res_Length; + res_str.MaximumLength = dupl_ustr[test_num].res_MaximumLength; + if (dupl_ustr[test_num].res_buf != NULL) { + for (pos = 0; pos < dupl_ustr[test_num].res_buf_size/sizeof(WCHAR); pos++) { + res_buf[pos] = dupl_ustr[test_num].res_buf[pos]; + } + res_str.Buffer = res_buf; + } else { + res_str.Buffer = NULL; + } + result = pRtlDuplicateUnicodeString(dupl_ustr[test_num].add_nul, &source_str, &dest_str); + dest_ansi_str.Length = dest_str.Length / sizeof(WCHAR); + dest_ansi_str.MaximumLength = dest_ansi_str.Length + 1; + for (pos = 0; pos < dest_ansi_str.Length; pos++) { + dest_ansi_buf[pos] = (char)dest_buf[pos]; + } + dest_ansi_buf[dest_ansi_str.Length] = '\0'; + dest_ansi_str.Buffer = dest_ansi_buf; + ok(result == dupl_ustr[test_num].result, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has result %lx, expected %lx\n", + test_num, dupl_ustr[test_num].add_nul, result, dupl_ustr[test_num].result); + ok(dest_str.Length == dupl_ustr[test_num].res_Length, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has Length %d, expected %d\n", + test_num, dupl_ustr[test_num].add_nul, dest_str.Length, dupl_ustr[test_num].res_Length); + ok(dest_str.MaximumLength == dupl_ustr[test_num].res_MaximumLength, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination has MaximumLength %d, expected %d\n", + test_num, dupl_ustr[test_num].add_nul, dest_str.MaximumLength, dupl_ustr[test_num].res_MaximumLength); + if (result == STATUS_INVALID_PARAMETER) { + ok((dest_str.Buffer == NULL && res_str.Buffer == NULL) || + dest_str.Buffer == dest_buf, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) destination buffer changed %p expected %p\n", + test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer, dest_buf); + } else { + ok(dest_str.Buffer != dest_buf, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination buffer unchanged %p\n", + test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer); + } + if (dest_str.Buffer != NULL && dupl_ustr[test_num].res_buf != NULL) { + ok(memcmp(dest_str.Buffer, res_str.Buffer, dupl_ustr[test_num].res_buf_size) == 0, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination \"%s\" expected \"%s\"\n", + test_num, dupl_ustr[test_num].add_nul, dest_ansi_str.Buffer, dupl_ustr[test_num].res_buf); + } else { + ok(dest_str.Buffer == NULL && dupl_ustr[test_num].res_buf == NULL, + "(test %d): RtlDuplicateUnicodeString(%d, source, dest) has destination %p expected %p\n", + test_num, dupl_ustr[test_num].add_nul, dest_str.Buffer, dupl_ustr[test_num].res_buf); + } + } +} + + +static void test_RtlCopyString(void) +{ + static const char teststring[] = "Some Wild String"; + char deststring[] = " "; + STRING str; + STRING deststr; + + pRtlInitString(&str, teststring); + pRtlInitString(&deststr, deststring); + pRtlCopyString(&deststr, &str); + ok(strncmp(str.Buffer, deststring, str.Length) == 0, "String not copied\n"); +} + + +static void test_RtlUpperChar(void) +{ + int ch; + int upper_ch; + int expected_upper_ch; + int byte_ch; + + for (ch = -1; ch <= 1024; ch++) { + upper_ch = pRtlUpperChar(ch); + byte_ch = ch & 0xff; + if (byte_ch >= 'a' && byte_ch <= 'z') { + expected_upper_ch = (CHAR) (byte_ch - 'a' + 'A'); + } else { + expected_upper_ch = (CHAR) byte_ch; + } + ok(upper_ch == expected_upper_ch, + "RtlUpperChar('%c'[=0x%x]) has result '%c'[=0x%x], expected '%c'[=0x%x]\n", + ch, ch, upper_ch, upper_ch, expected_upper_ch, expected_upper_ch); + } +} + + +static void test_RtlUpperString(void) +{ + int i; + CHAR ch; + CHAR upper_ch; + char ascii_buf[257]; + char result_buf[257]; + char upper_buf[257]; + STRING ascii_str; + STRING result_str; + STRING upper_str; + + for (i = 0; i <= 255; i++) { + ch = (CHAR) i; + if (ch >= 'a' && ch <= 'z') { + upper_ch = ch - 'a' + 'A'; + } else { + upper_ch = ch; + } + ascii_buf[i] = ch; + result_buf[i] = '\0'; + upper_buf[i] = upper_ch; + } + ascii_buf[i] = '\0'; + result_buf[i] = '\0'; + upper_buf[i] = '\0'; + ascii_str.Length = 256; + ascii_str.MaximumLength = 256; + ascii_str.Buffer = ascii_buf; + result_str.Length = 256; + result_str.MaximumLength = 256; + result_str.Buffer = result_buf; + upper_str.Length = 256; + upper_str.MaximumLength = 256; + upper_str.Buffer = upper_buf; + + pRtlUpperString(&result_str, &ascii_str); + ok(memcmp(result_str.Buffer, upper_str.Buffer, 256) == 0, + "RtlUpperString does not work as expected\n"); +} + + +static void test_RtlUpcaseUnicodeChar(void) +{ + int i; + WCHAR ch; + WCHAR upper_ch; + WCHAR expected_upper_ch; + + for (i = 0; i <= 255; i++) { + ch = (WCHAR) i; + upper_ch = pRtlUpcaseUnicodeChar(ch); + if (ch >= 'a' && ch <= 'z') { + expected_upper_ch = ch - 'a' + 'A'; + } else if (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7) { + expected_upper_ch = ch - 0x20; + } else if (ch == 0xff) { + expected_upper_ch = 0x178; + } else { + expected_upper_ch = ch; + } + ok(upper_ch == expected_upper_ch, + "RtlUpcaseUnicodeChar('%c'[=0x%x]) has result '%c'[=0x%x], expected: '%c'[=0x%x]\n", + ch, ch, upper_ch, upper_ch, expected_upper_ch, expected_upper_ch); + } +} + + +static void test_RtlUpcaseUnicodeString(void) +{ + int i; + WCHAR ch; + WCHAR upper_ch; + WCHAR ascii_buf[257]; + WCHAR result_buf[257]; + WCHAR upper_buf[257]; + UNICODE_STRING ascii_str; + UNICODE_STRING result_str; + UNICODE_STRING upper_str; + + for (i = 0; i <= 255; i++) { + ch = (WCHAR) i; + if (ch >= 'a' && ch <= 'z') { + upper_ch = ch - 'a' + 'A'; + } else if (ch >= 0xe0 && ch <= 0xfe && ch != 0xf7) { + upper_ch = ch - 0x20; + } else if (ch == 0xff) { + upper_ch = 0x178; + } else { + upper_ch = ch; + } + ascii_buf[i] = ch; + result_buf[i] = '\0'; + upper_buf[i] = upper_ch; + } + ascii_buf[i] = '\0'; + result_buf[i] = '\0'; + upper_buf[i] = '\0'; + ascii_str.Length = 512; + ascii_str.MaximumLength = 512; + ascii_str.Buffer = ascii_buf; + result_str.Length = 512; + result_str.MaximumLength = 512; + result_str.Buffer = result_buf; + upper_str.Length = 512; + upper_str.MaximumLength = 512; + upper_str.Buffer = upper_buf; + + pRtlUpcaseUnicodeString(&result_str, &ascii_str, 0); + for (i = 0; i <= 255; i++) { + ok(result_str.Buffer[i] == upper_str.Buffer[i], + "RtlUpcaseUnicodeString works wrong: '%c'[=0x%x] is converted to '%c'[=0x%x], expected: '%c'[=0x%x]\n", + ascii_str.Buffer[i], ascii_str.Buffer[i], + result_str.Buffer[i], result_str.Buffer[i], + upper_str.Buffer[i], upper_str.Buffer[i]); + } +} + + +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 */ + } + source_buf[i] = ch; + result_buf[i] = '\0'; + lower_buf[i] = lower_ch; + } + 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]\n", + source_str.Buffer[i], source_str.Buffer[i], + result_str.Buffer[i], result_str.Buffer[i], + lower_str.Buffer[i], lower_str.Buffer[i]); + } +} + + +typedef struct { + int ansi_Length; + int ansi_MaximumLength; + int ansi_buf_size; + const char *ansi_buf; + int uni_Length; + int uni_MaximumLength; + int uni_buf_size; + const char *uni_buf; + BOOLEAN doalloc; + int res_Length; + int res_MaximumLength; + int res_buf_size; + const char *res_buf; + NTSTATUS result; +} ustr2astr_t; + +static const ustr2astr_t ustr2astr[] = { + { 10, 12, 12, "------------", 0, 0, 0, "", TRUE, 0, 1, 1, "", STATUS_SUCCESS}, + { 10, 12, 12, "------------", 12, 12, 12, "abcdef", TRUE, 6, 7, 7, "abcdef", STATUS_SUCCESS}, + { 0, 2, 12, "------------", 12, 12, 12, "abcdef", TRUE, 6, 7, 7, "abcdef", STATUS_SUCCESS}, + { 10, 12, 12, NULL, 12, 12, 12, "abcdef", TRUE, 6, 7, 7, "abcdef", STATUS_SUCCESS}, + { 0, 0, 12, "------------", 12, 12, 12, "abcdef", FALSE, 6, 0, 0, "", STATUS_BUFFER_OVERFLOW}, + { 0, 1, 12, "------------", 12, 12, 12, "abcdef", FALSE, 0, 1, 1, "", STATUS_BUFFER_OVERFLOW}, + { 0, 2, 12, "------------", 12, 12, 12, "abcdef", FALSE, 1, 2, 2, "a", STATUS_BUFFER_OVERFLOW}, + { 0, 3, 12, "------------", 12, 12, 12, "abcdef", FALSE, 2, 3, 3, "ab", STATUS_BUFFER_OVERFLOW}, + { 0, 5, 12, "------------", 12, 12, 12, "abcdef", FALSE, 4, 5, 5, "abcd", STATUS_BUFFER_OVERFLOW}, + { 8, 5, 12, "------------", 12, 12, 12, "abcdef", FALSE, 4, 5, 5, "abcd", STATUS_BUFFER_OVERFLOW}, + { 8, 6, 12, "------------", 12, 12, 12, "abcdef", FALSE, 5, 6, 6, "abcde", STATUS_BUFFER_OVERFLOW}, + { 8, 7, 12, "------------", 12, 12, 12, "abcdef", FALSE, 6, 7, 7, "abcdef", STATUS_SUCCESS}, + { 8, 7, 12, "------------", 0, 12, 12, NULL, FALSE, 0, 7, 0, "", STATUS_SUCCESS}, + { 0, 0, 12, NULL, 10, 10, 12, NULL, FALSE, 5, 0, 0, NULL, STATUS_BUFFER_OVERFLOW}, +}; +#define NB_USTR2ASTR (sizeof(ustr2astr)/sizeof(*ustr2astr)) + + +static void test_RtlUnicodeStringToAnsiString(void) +{ + size_t pos; + CHAR ansi_buf[257]; + WCHAR uni_buf[257]; + STRING ansi_str; + UNICODE_STRING uni_str; + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_USTR2ASTR; test_num++) { + ansi_str.Length = ustr2astr[test_num].ansi_Length; + ansi_str.MaximumLength = ustr2astr[test_num].ansi_MaximumLength; + if (ustr2astr[test_num].ansi_buf != NULL) { + memcpy(ansi_buf, ustr2astr[test_num].ansi_buf, ustr2astr[test_num].ansi_buf_size); + ansi_buf[ustr2astr[test_num].ansi_buf_size] = '\0'; + ansi_str.Buffer = ansi_buf; + } else { + ansi_str.Buffer = NULL; + } + uni_str.Length = ustr2astr[test_num].uni_Length; + uni_str.MaximumLength = ustr2astr[test_num].uni_MaximumLength; + if (ustr2astr[test_num].uni_buf != NULL) { + for (pos = 0; pos < ustr2astr[test_num].uni_buf_size/sizeof(WCHAR); pos++) { + uni_buf[pos] = ustr2astr[test_num].uni_buf[pos]; + } + uni_str.Buffer = uni_buf; + } else { + uni_str.Buffer = NULL; + } + result = pRtlUnicodeStringToAnsiString(&ansi_str, &uni_str, ustr2astr[test_num].doalloc); + ok(result == ustr2astr[test_num].result, + "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has result %lx, expected %lx\n", + test_num, ustr2astr[test_num].doalloc, result, ustr2astr[test_num].result); + ok(ansi_str.Length == ustr2astr[test_num].res_Length, + "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has Length %d, expected %d\n", + test_num, ustr2astr[test_num].doalloc, ansi_str.Length, ustr2astr[test_num].res_Length); + ok(ansi_str.MaximumLength == ustr2astr[test_num].res_MaximumLength, + "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) ansi has MaximumLength %d, expected %d\n", + test_num, ustr2astr[test_num].doalloc, ansi_str.MaximumLength, ustr2astr[test_num].res_MaximumLength); + ok(memcmp(ansi_str.Buffer, ustr2astr[test_num].res_buf, ustr2astr[test_num].res_buf_size) == 0, + "(test %d): RtlUnicodeStringToAnsiString(ansi, uni, %d) has ansi \"%s\" expected \"%s\"\n", + test_num, ustr2astr[test_num].doalloc, ansi_str.Buffer, ustr2astr[test_num].res_buf); + } +} + + +typedef struct { + int dest_Length; + int dest_MaximumLength; + int dest_buf_size; + const char *dest_buf; + const char *src; + int res_Length; + int res_MaximumLength; + int res_buf_size; + const char *res_buf; + NTSTATUS result; +} app_asc2str_t; + +static const app_asc2str_t app_asc2str[] = { + { 5, 12, 15, "TestS01234abcde", "tring", 10, 12, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 11, 15, "TestS01234abcde", "tring", 10, 11, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 10, 15, "TestS01234abcde", "tring", 10, 10, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 9, 15, "TestS01234abcde", "tring", 5, 9, 15, "TestS01234abcde", STATUS_BUFFER_TOO_SMALL}, + { 5, 0, 15, "TestS01234abcde", "tring", 5, 0, 15, "TestS01234abcde", STATUS_BUFFER_TOO_SMALL}, + { 5, 14, 15, "TestS01234abcde", "tring", 10, 14, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 14, 15, "TestS01234abcde", NULL, 5, 14, 15, "TestS01234abcde", STATUS_SUCCESS}, + { 5, 14, 15, NULL, NULL, 5, 14, 15, NULL, STATUS_SUCCESS}, + { 5, 12, 15, "Tst\0S01234abcde", "tr\0i", 7, 12, 15, "Tst\0Str234abcde", STATUS_SUCCESS}, +}; +#define NB_APP_ASC2STR (sizeof(app_asc2str)/sizeof(*app_asc2str)) + + +static void test_RtlAppendAsciizToString(void) +{ + CHAR dest_buf[257]; + STRING dest_str; + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_APP_ASC2STR; test_num++) { + dest_str.Length = app_asc2str[test_num].dest_Length; + dest_str.MaximumLength = app_asc2str[test_num].dest_MaximumLength; + if (app_asc2str[test_num].dest_buf != NULL) { + memcpy(dest_buf, app_asc2str[test_num].dest_buf, app_asc2str[test_num].dest_buf_size); + dest_buf[app_asc2str[test_num].dest_buf_size] = '\0'; + dest_str.Buffer = dest_buf; + } else { + dest_str.Buffer = NULL; + } + result = pRtlAppendAsciizToString(&dest_str, app_asc2str[test_num].src); + ok(result == app_asc2str[test_num].result, + "(test %d): RtlAppendAsciizToString(dest, src) has result %lx, expected %lx\n", + test_num, result, app_asc2str[test_num].result); + ok(dest_str.Length == app_asc2str[test_num].res_Length, + "(test %d): RtlAppendAsciizToString(dest, src) dest has Length %d, expected %d\n", + test_num, dest_str.Length, app_asc2str[test_num].res_Length); + ok(dest_str.MaximumLength == app_asc2str[test_num].res_MaximumLength, + "(test %d): RtlAppendAsciizToString(dest, src) dest has MaximumLength %d, expected %d\n", + test_num, dest_str.MaximumLength, app_asc2str[test_num].res_MaximumLength); + if (dest_str.Buffer == dest_buf) { + ok(memcmp(dest_buf, app_asc2str[test_num].res_buf, app_asc2str[test_num].res_buf_size) == 0, + "(test %d): RtlAppendAsciizToString(dest, src) has dest \"%s\" expected \"%s\"\n", + test_num, dest_buf, app_asc2str[test_num].res_buf); + } else { + ok(dest_str.Buffer == app_asc2str[test_num].res_buf, + "(test %d): RtlAppendAsciizToString(dest, src) dest has Buffer %p expected %p\n", + test_num, dest_str.Buffer, app_asc2str[test_num].res_buf); + } + } +} + + +typedef struct { + int dest_Length; + int dest_MaximumLength; + int dest_buf_size; + const char *dest_buf; + int src_Length; + int src_MaximumLength; + int src_buf_size; + const char *src_buf; + int res_Length; + int res_MaximumLength; + int res_buf_size; + const char *res_buf; + NTSTATUS result; +} app_str2str_t; + +static const app_str2str_t app_str2str[] = { + { 5, 12, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 10, 12, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 11, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 10, 11, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 10, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 10, 10, 15, "TestStringabcde", STATUS_SUCCESS}, + { 5, 9, 15, "TestS01234abcde", 5, 5, 7, "tringZY", 5, 9, 15, "TestS01234abcde", STATUS_BUFFER_TOO_SMALL}, + { 5, 0, 15, "TestS01234abcde", 0, 0, 7, "tringZY", 5, 0, 15, "TestS01234abcde", STATUS_SUCCESS}, + { 5, 14, 15, "TestS01234abcde", 0, 0, 7, "tringZY", 5, 14, 15, "TestS01234abcde", STATUS_SUCCESS}, + { 5, 14, 15, "TestS01234abcde", 0, 0, 7, NULL, 5, 14, 15, "TestS01234abcde", STATUS_SUCCESS}, + { 5, 14, 15, NULL, 0, 0, 7, NULL, 5, 14, 15, NULL, STATUS_SUCCESS}, + { 5, 12, 15, "Tst\0S01234abcde", 4, 4, 7, "tr\0iZY", 9, 12, 15, "Tst\0Str\0i4abcde", STATUS_SUCCESS}, +}; +#define NB_APP_STR2STR (sizeof(app_str2str)/sizeof(*app_str2str)) + + +static void test_RtlAppendStringToString(void) +{ + CHAR dest_buf[257]; + CHAR src_buf[257]; + STRING dest_str; + STRING src_str; + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_APP_STR2STR; test_num++) { + dest_str.Length = app_str2str[test_num].dest_Length; + dest_str.MaximumLength = app_str2str[test_num].dest_MaximumLength; + if (app_str2str[test_num].dest_buf != NULL) { + memcpy(dest_buf, app_str2str[test_num].dest_buf, app_str2str[test_num].dest_buf_size); + dest_buf[app_str2str[test_num].dest_buf_size] = '\0'; + dest_str.Buffer = dest_buf; + } else { + dest_str.Buffer = NULL; + } + src_str.Length = app_str2str[test_num].src_Length; + src_str.MaximumLength = app_str2str[test_num].src_MaximumLength; + if (app_str2str[test_num].src_buf != NULL) { + memcpy(src_buf, app_str2str[test_num].src_buf, app_str2str[test_num].src_buf_size); + src_buf[app_str2str[test_num].src_buf_size] = '\0'; + src_str.Buffer = src_buf; + } else { + src_str.Buffer = NULL; + } + result = pRtlAppendStringToString(&dest_str, &src_str); + ok(result == app_str2str[test_num].result, + "(test %d): RtlAppendStringToString(dest, src) has result %lx, expected %lx\n", + test_num, result, app_str2str[test_num].result); + ok(dest_str.Length == app_str2str[test_num].res_Length, + "(test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d\n", + test_num, dest_str.Length, app_str2str[test_num].res_Length); + ok(dest_str.MaximumLength == app_str2str[test_num].res_MaximumLength, + "(test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d\n", + test_num, dest_str.MaximumLength, app_str2str[test_num].res_MaximumLength); + if (dest_str.Buffer == dest_buf) { + ok(memcmp(dest_buf, app_str2str[test_num].res_buf, app_str2str[test_num].res_buf_size) == 0, + "(test %d): RtlAppendStringToString(dest, src) has dest \"%s\" expected \"%s\"\n", + test_num, dest_buf, app_str2str[test_num].res_buf); + } else { + ok(dest_str.Buffer == app_str2str[test_num].res_buf, + "(test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p\n", + test_num, dest_str.Buffer, app_str2str[test_num].res_buf); + } + } +} + + +typedef struct { + int dest_Length; + int dest_MaximumLength; + int dest_buf_size; + const char *dest_buf; + const char *src; + int res_Length; + int res_MaximumLength; + int res_buf_size; + const char *res_buf; + NTSTATUS result; +} app_uni2str_t; + +static const app_uni2str_t app_uni2str[] = { + { 4, 12, 14, "Fake0123abcdef", "Ustr\0", 8, 12, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, + { 4, 11, 14, "Fake0123abcdef", "Ustr\0", 8, 11, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, + { 4, 10, 14, "Fake0123abcdef", "Ustr\0", 8, 10, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, +/* In the following test the native function writes beyond MaximumLength + * { 4, 9, 14, "Fake0123abcdef", "Ustr\0", 8, 9, 14, "FakeUstrabcdef", STATUS_SUCCESS}, + */ + { 4, 8, 14, "Fake0123abcdef", "Ustr\0", 8, 8, 14, "FakeUstrabcdef", STATUS_SUCCESS}, + { 4, 7, 14, "Fake0123abcdef", "Ustr\0", 4, 7, 14, "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL}, + { 4, 0, 14, "Fake0123abcdef", "Ustr\0", 4, 0, 14, "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL}, + { 4, 14, 14, "Fake0123abcdef", "Ustr\0", 8, 14, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, + { 4, 14, 14, "Fake0123abcdef", NULL, 4, 14, 14, "Fake0123abcdef", STATUS_SUCCESS}, + { 4, 14, 14, NULL, NULL, 4, 14, 14, NULL, STATUS_SUCCESS}, + { 4, 14, 14, "Fake0123abcdef", "U\0stri\0", 10, 14, 14, "FakeU\0stri\0\0ef", STATUS_SUCCESS}, + { 6, 14, 16, "Te\0\0stabcdefghij", "St\0\0ri", 8, 14, 16, "Te\0\0stSt\0\0efghij", STATUS_SUCCESS}, +}; +#define NB_APP_UNI2STR (sizeof(app_uni2str)/sizeof(*app_uni2str)) + + +static void test_RtlAppendUnicodeToString(void) +{ + WCHAR dest_buf[257]; + UNICODE_STRING dest_str; + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_APP_UNI2STR; test_num++) { + dest_str.Length = app_uni2str[test_num].dest_Length; + dest_str.MaximumLength = app_uni2str[test_num].dest_MaximumLength; + if (app_uni2str[test_num].dest_buf != NULL) { + memcpy(dest_buf, app_uni2str[test_num].dest_buf, app_uni2str[test_num].dest_buf_size); + dest_buf[app_uni2str[test_num].dest_buf_size/sizeof(WCHAR)] = '\0'; + dest_str.Buffer = dest_buf; + } else { + dest_str.Buffer = NULL; + } + result = pRtlAppendUnicodeToString(&dest_str, (LPCWSTR) app_uni2str[test_num].src); + ok(result == app_uni2str[test_num].result, + "(test %d): RtlAppendUnicodeToString(dest, src) has result %lx, expected %lx\n", + test_num, result, app_uni2str[test_num].result); + ok(dest_str.Length == app_uni2str[test_num].res_Length, + "(test %d): RtlAppendUnicodeToString(dest, src) dest has Length %d, expected %d\n", + test_num, dest_str.Length, app_uni2str[test_num].res_Length); + ok(dest_str.MaximumLength == app_uni2str[test_num].res_MaximumLength, + "(test %d): RtlAppendUnicodeToString(dest, src) dest has MaximumLength %d, expected %d\n", + test_num, dest_str.MaximumLength, app_uni2str[test_num].res_MaximumLength); + if (dest_str.Buffer == dest_buf) { + ok(memcmp(dest_buf, app_uni2str[test_num].res_buf, app_uni2str[test_num].res_buf_size) == 0, + "(test %d): RtlAppendUnicodeToString(dest, src) has dest \"%s\" expected \"%s\"\n", + test_num, (char *) dest_buf, app_uni2str[test_num].res_buf); + } else { + ok(dest_str.Buffer == (WCHAR *) app_uni2str[test_num].res_buf, + "(test %d): RtlAppendUnicodeToString(dest, src) dest has Buffer %p expected %p\n", + test_num, dest_str.Buffer, app_uni2str[test_num].res_buf); + } + } +} + + +typedef struct { + int dest_Length; + int dest_MaximumLength; + int dest_buf_size; + const char *dest_buf; + int src_Length; + int src_MaximumLength; + int src_buf_size; + const char *src_buf; + int res_Length; + int res_MaximumLength; + int res_buf_size; + const char *res_buf; + NTSTATUS result; +} app_ustr2str_t; + +static const app_ustr2str_t app_ustr2str[] = { + { 4, 12, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 12, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, + { 4, 11, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 11, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, + { 4, 10, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 10, 14, "FakeUstr\0\0cdef", STATUS_SUCCESS}, +/* In the following test the native function writes beyond MaximumLength + * { 4, 9, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 9, 14, "FakeUstrabcdef", STATUS_SUCCESS}, + */ + { 4, 8, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 8, 8, 14, "FakeUstrabcdef", STATUS_SUCCESS}, + { 4, 7, 14, "Fake0123abcdef", 4, 6, 8, "UstrZYXW", 4, 7, 14, "Fake0123abcdef", STATUS_BUFFER_TOO_SMALL}, + { 4, 0, 14, "Fake0123abcdef", 0, 0, 8, "UstrZYXW", 4, 0, 14, "Fake0123abcdef", STATUS_SUCCESS}, + { 4, 14, 14, "Fake0123abcdef", 0, 0, 8, "UstrZYXW", 4, 14, 14, "Fake0123abcdef", STATUS_SUCCESS}, + { 4, 14, 14, "Fake0123abcdef", 0, 0, 8, NULL, 4, 14, 14, "Fake0123abcdef", STATUS_SUCCESS}, + { 4, 14, 14, NULL, 0, 0, 8, NULL, 4, 14, 14, NULL, STATUS_SUCCESS}, + { 6, 14, 16, "Te\0\0stabcdefghij", 6, 8, 8, "St\0\0riZY", 12, 14, 16, "Te\0\0stSt\0\0ri\0\0ij", STATUS_SUCCESS}, +}; +#define NB_APP_USTR2STR (sizeof(app_ustr2str)/sizeof(*app_ustr2str)) + + +static void test_RtlAppendUnicodeStringToString(void) +{ + WCHAR dest_buf[257]; + WCHAR src_buf[257]; + UNICODE_STRING dest_str; + UNICODE_STRING src_str; + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_APP_USTR2STR; test_num++) { + dest_str.Length = app_ustr2str[test_num].dest_Length; + dest_str.MaximumLength = app_ustr2str[test_num].dest_MaximumLength; + if (app_ustr2str[test_num].dest_buf != NULL) { + memcpy(dest_buf, app_ustr2str[test_num].dest_buf, app_ustr2str[test_num].dest_buf_size); + dest_buf[app_ustr2str[test_num].dest_buf_size/sizeof(WCHAR)] = '\0'; + dest_str.Buffer = dest_buf; + } else { + dest_str.Buffer = NULL; + } + src_str.Length = app_ustr2str[test_num].src_Length; + src_str.MaximumLength = app_ustr2str[test_num].src_MaximumLength; + if (app_ustr2str[test_num].src_buf != NULL) { + memcpy(src_buf, app_ustr2str[test_num].src_buf, app_ustr2str[test_num].src_buf_size); + src_buf[app_ustr2str[test_num].src_buf_size/sizeof(WCHAR)] = '\0'; + src_str.Buffer = src_buf; + } else { + src_str.Buffer = NULL; + } + result = pRtlAppendUnicodeStringToString(&dest_str, &src_str); + ok(result == app_ustr2str[test_num].result, + "(test %d): RtlAppendStringToString(dest, src) has result %lx, expected %lx\n", + test_num, result, app_ustr2str[test_num].result); + ok(dest_str.Length == app_ustr2str[test_num].res_Length, + "(test %d): RtlAppendStringToString(dest, src) dest has Length %d, expected %d\n", + test_num, dest_str.Length, app_ustr2str[test_num].res_Length); + ok(dest_str.MaximumLength == app_ustr2str[test_num].res_MaximumLength, + "(test %d): RtlAppendStringToString(dest, src) dest has MaximumLength %d, expected %d\n", + test_num, dest_str.MaximumLength, app_ustr2str[test_num].res_MaximumLength); + if (dest_str.Buffer == dest_buf) { + ok(memcmp(dest_buf, app_ustr2str[test_num].res_buf, app_ustr2str[test_num].res_buf_size) == 0, + "(test %d): RtlAppendStringToString(dest, src) has dest \"%s\" expected \"%s\"\n", + test_num, (char *) dest_buf, app_ustr2str[test_num].res_buf); + } else { + ok(dest_str.Buffer == (WCHAR *) app_ustr2str[test_num].res_buf, + "(test %d): RtlAppendStringToString(dest, src) dest has Buffer %p expected %p\n", + test_num, dest_str.Buffer, app_ustr2str[test_num].res_buf); + } + } +} + + +typedef struct { + int flags; + const char *main_str; + const char *search_chars; + USHORT pos; + NTSTATUS result; +} find_ch_in_ustr_t; + +static const find_ch_in_ustr_t find_ch_in_ustr[] = { + { 0, "Some Wild String", "S", 2, STATUS_SUCCESS}, + { 0, "This is a String", "String", 6, STATUS_SUCCESS}, + { 1, "This is a String", "String", 30, STATUS_SUCCESS}, + { 2, "This is a String", "String", 2, STATUS_SUCCESS}, + { 3, "This is a String", "String", 18, STATUS_SUCCESS}, + { 0, "This is a String", "Wild", 6, STATUS_SUCCESS}, + { 1, "This is a String", "Wild", 26, STATUS_SUCCESS}, + { 2, "This is a String", "Wild", 2, STATUS_SUCCESS}, + { 3, "This is a String", "Wild", 30, STATUS_SUCCESS}, + { 0, "abcdefghijklmnopqrstuvwxyz", "", 0, STATUS_NOT_FOUND}, + { 0, "abcdefghijklmnopqrstuvwxyz", "123", 0, STATUS_NOT_FOUND}, + { 0, "abcdefghijklmnopqrstuvwxyz", "a", 2, STATUS_SUCCESS}, + { 0, "abcdefghijklmnopqrstuvwxyz", "12a34", 2, STATUS_SUCCESS}, + { 0, "abcdefghijklmnopqrstuvwxyz", "12b34", 4, STATUS_SUCCESS}, + { 0, "abcdefghijklmnopqrstuvwxyz", "12y34", 50, STATUS_SUCCESS}, + { 0, "abcdefghijklmnopqrstuvwxyz", "12z34", 52, STATUS_SUCCESS}, + { 0, "abcdefghijklmnopqrstuvwxyz", "rvz", 36, STATUS_SUCCESS}, + { 0, "abcdefghijklmmlkjihgfedcba", "egik", 10, STATUS_SUCCESS}, + { 1, "abcdefghijklmnopqrstuvwxyz", "", 0, STATUS_NOT_FOUND}, + { 1, "abcdefghijklmnopqrstuvwxyz", "rvz", 50, STATUS_SUCCESS}, + { 1, "abcdefghijklmnopqrstuvwxyz", "ravy", 48, STATUS_SUCCESS}, + { 1, "abcdefghijklmnopqrstuvwxyz", "raxv", 46, STATUS_SUCCESS}, + { 2, "abcdefghijklmnopqrstuvwxyz", "", 2, STATUS_SUCCESS}, + { 2, "abcdefghijklmnopqrstuvwxyz", "rvz", 2, STATUS_SUCCESS}, + { 2, "abcdefghijklmnopqrstuvwxyz", "vaz", 4, STATUS_SUCCESS}, + { 2, "abcdefghijklmnopqrstuvwxyz", "ravbz", 6, STATUS_SUCCESS}, + { 3, "abcdefghijklmnopqrstuvwxyz", "", 50, STATUS_SUCCESS}, + { 3, "abcdefghijklmnopqrstuvwxyz", "123", 50, STATUS_SUCCESS}, + { 3, "abcdefghijklmnopqrstuvwxyz", "ahp", 50, STATUS_SUCCESS}, + { 3, "abcdefghijklmnopqrstuvwxyz", "rvz", 48, STATUS_SUCCESS}, + { 0, NULL, "abc", 0, STATUS_NOT_FOUND}, + { 1, NULL, "abc", 0, STATUS_NOT_FOUND}, + { 2, NULL, "abc", 0, STATUS_NOT_FOUND}, + { 3, NULL, "abc", 0, STATUS_NOT_FOUND}, + { 0, "abcdefghijklmnopqrstuvwxyz", NULL, 0, STATUS_NOT_FOUND}, + { 1, "abcdefghijklmnopqrstuvwxyz", NULL, 0, STATUS_NOT_FOUND}, + { 2, "abcdefghijklmnopqrstuvwxyz", NULL, 2, STATUS_SUCCESS}, + { 3, "abcdefghijklmnopqrstuvwxyz", NULL, 50, STATUS_SUCCESS}, + { 0, NULL, NULL, 0, STATUS_NOT_FOUND}, + { 1, NULL, NULL, 0, STATUS_NOT_FOUND}, + { 2, NULL, NULL, 0, STATUS_NOT_FOUND}, + { 3, NULL, NULL, 0, STATUS_NOT_FOUND}, + { 0, "abcdabcdabcdabcdabcdabcd", "abcd", 2, STATUS_SUCCESS}, + { 1, "abcdabcdabcdabcdabcdabcd", "abcd", 46, STATUS_SUCCESS}, + { 2, "abcdabcdabcdabcdabcdabcd", "abcd", 0, STATUS_NOT_FOUND}, + { 3, "abcdabcdabcdabcdabcdabcd", "abcd", 0, STATUS_NOT_FOUND}, +}; +#define NB_FIND_CH_IN_USTR (sizeof(find_ch_in_ustr)/sizeof(*find_ch_in_ustr)) + + +static void test_RtlFindCharInUnicodeString(void) +{ + WCHAR main_str_buf[257]; + WCHAR search_chars_buf[257]; + UNICODE_STRING main_str; + UNICODE_STRING search_chars; + USHORT pos; + NTSTATUS result; + size_t idx; + size_t test_num; + + for (test_num = 0; test_num < NB_FIND_CH_IN_USTR; test_num++) { + if (find_ch_in_ustr[test_num].main_str != NULL) { + main_str.Length = strlen(find_ch_in_ustr[test_num].main_str) * sizeof(WCHAR); + main_str.MaximumLength = main_str.Length + sizeof(WCHAR); + for (idx = 0; idx < main_str.Length / sizeof(WCHAR); idx++) { + main_str_buf[idx] = find_ch_in_ustr[test_num].main_str[idx]; + } + main_str.Buffer = main_str_buf; + } else { + main_str.Length = 0; + main_str.MaximumLength = 0; + main_str.Buffer = NULL; + } + if (find_ch_in_ustr[test_num].search_chars != NULL) { + search_chars.Length = strlen(find_ch_in_ustr[test_num].search_chars) * sizeof(WCHAR); + search_chars.MaximumLength = search_chars.Length + sizeof(WCHAR); + for (idx = 0; idx < search_chars.Length / sizeof(WCHAR); idx++) { + search_chars_buf[idx] = find_ch_in_ustr[test_num].search_chars[idx]; + } + search_chars.Buffer = search_chars_buf; + } else { + search_chars.Length = 0; + search_chars.MaximumLength = 0; + search_chars.Buffer = NULL; + } + pos = 12345; + result = pRtlFindCharInUnicodeString(find_ch_in_ustr[test_num].flags, &main_str, &search_chars, &pos); + ok(result == find_ch_in_ustr[test_num].result, + "(test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) has result %lx, expected %lx\n", + test_num, find_ch_in_ustr[test_num].flags, + find_ch_in_ustr[test_num].main_str, find_ch_in_ustr[test_num].search_chars, + result, find_ch_in_ustr[test_num].result); + ok(pos == find_ch_in_ustr[test_num].pos, + "(test %d): RtlFindCharInUnicodeString(%d, %s, %s, [out]) assigns %d to pos, expected %d\n", + test_num, find_ch_in_ustr[test_num].flags, + find_ch_in_ustr[test_num].main_str, find_ch_in_ustr[test_num].search_chars, + pos, find_ch_in_ustr[test_num].pos); + } +} + + +typedef struct { + int base; + const char *str; + int value; + NTSTATUS result; +} str2int_t; + +static const str2int_t str2int[] = { + { 0, "1011101100", 1011101100, STATUS_SUCCESS}, + { 0, "1234567", 1234567, STATUS_SUCCESS}, + { 0, "-214", -214, STATUS_SUCCESS}, + { 0, "+214", 214, STATUS_SUCCESS}, /* The + sign is allowed also */ + { 0, "--214", 0, STATUS_SUCCESS}, /* Do not accept more than one sign */ + { 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}, + { 0, "+214 0", 214, STATUS_SUCCESS}, /* Space terminates the number */ + { 0, " 214.01", 214, STATUS_SUCCESS}, /* Decimal point not accepted */ + { 0, " 214,01", 214, STATUS_SUCCESS}, /* Decimal comma not accepted */ + { 0, "f81", 0, STATUS_SUCCESS}, + { 0, "0x12345", 0x12345, STATUS_SUCCESS}, /* Hex */ + { 0, "00x12345", 0, STATUS_SUCCESS}, + { 0, "0xx12345", 0, STATUS_SUCCESS}, + { 0, "1x34", 1, STATUS_SUCCESS}, + { 0, "-9999999999", -1410065407, STATUS_SUCCESS}, /* Big negative integer */ + { 0, "-2147483649", 2147483647, STATUS_SUCCESS}, /* Too small to fit in 32 Bits */ + { 0, "-2147483648", 0x80000000L, STATUS_SUCCESS}, /* Smallest negative integer */ + { 0, "-2147483647", -2147483647, STATUS_SUCCESS}, + { 0, "-1", -1, STATUS_SUCCESS}, + { 0, "0", 0, STATUS_SUCCESS}, + { 0, "1", 1, STATUS_SUCCESS}, + { 0, "2147483646", 2147483646, STATUS_SUCCESS}, + { 0, "2147483647", 2147483647, STATUS_SUCCESS}, /* Largest signed positive integer */ + { 0, "2147483648", 0x80000000L, STATUS_SUCCESS}, /* Positive int equal to smallest negative int */ + { 0, "2147483649", -2147483647, STATUS_SUCCESS}, + { 0, "4294967294", -2, STATUS_SUCCESS}, + { 0, "4294967295", -1, STATUS_SUCCESS}, /* Largest unsigned integer */ + { 0, "4294967296", 0, STATUS_SUCCESS}, /* Too big to fit in 32 Bits */ + { 0, "9999999999", 1410065407, STATUS_SUCCESS}, /* Big positive integer */ + { 0, "056789", 56789, STATUS_SUCCESS}, /* Leading zero and still decimal */ + { 0, "b1011101100", 0, STATUS_SUCCESS}, /* Binary (b-notation) */ + { 0, "-b1011101100", 0, STATUS_SUCCESS}, /* Negative Binary (b-notation) */ + { 0, "b10123456789", 0, STATUS_SUCCESS}, /* Binary with nonbinary digits (2-9) */ + { 0, "0b1011101100", 748, STATUS_SUCCESS}, /* Binary (0b-notation) */ + { 0, "-0b1011101100", -748, STATUS_SUCCESS}, /* Negative binary (0b-notation) */ + { 0, "0b10123456789", 5, STATUS_SUCCESS}, /* Binary with nonbinary digits (2-9) */ + { 0, "-0b10123456789", -5, STATUS_SUCCESS}, /* Negative binary with nonbinary digits (2-9) */ + { 0, "0b1", 1, STATUS_SUCCESS}, /* one digit binary */ + { 0, "0b2", 0, STATUS_SUCCESS}, /* empty binary */ + { 0, "0b", 0, STATUS_SUCCESS}, /* empty binary */ + { 0, "o1234567", 0, STATUS_SUCCESS}, /* Octal (o-notation) */ + { 0, "-o1234567", 0, STATUS_SUCCESS}, /* Negative Octal (o-notation) */ + { 0, "o56789", 0, STATUS_SUCCESS}, /* Octal with nonoctal digits (8 and 9) */ + { 0, "0o1234567", 01234567, STATUS_SUCCESS}, /* Octal (0o-notation) */ + { 0, "-0o1234567", -01234567, STATUS_SUCCESS}, /* Negative octal (0o-notation) */ + { 0, "0o56789", 0567, STATUS_SUCCESS}, /* Octal with nonoctal digits (8 and 9) */ + { 0, "-0o56789", -0567, STATUS_SUCCESS}, /* Negative octal with nonoctal digits (8 and 9) */ + { 0, "0o7", 7, STATUS_SUCCESS}, /* one digit octal */ + { 0, "0o8", 0, STATUS_SUCCESS}, /* empty octal */ + { 0, "0o", 0, STATUS_SUCCESS}, /* empty octal */ + { 0, "0d1011101100", 0, STATUS_SUCCESS}, /* explizit decimal with 0d */ + { 0, "x89abcdef", 0, STATUS_SUCCESS}, /* Hex with lower case digits a-f (x-notation) */ + { 0, "xFEDCBA00", 0, STATUS_SUCCESS}, /* Hex with upper case digits A-F (x-notation) */ + { 0, "-xFEDCBA00", 0, STATUS_SUCCESS}, /* Negative Hexadecimal (x-notation) */ + { 0, "0x89abcdef", 0x89abcdef, STATUS_SUCCESS}, /* Hex with lower case digits a-f (0x-notation) */ + { 0, "0xFEDCBA00", 0xFEDCBA00, STATUS_SUCCESS}, /* Hex with upper case digits A-F (0x-notation) */ + { 0, "-0xFEDCBA00", 19088896, STATUS_SUCCESS}, /* Negative Hexadecimal (0x-notation) */ + { 0, "0xabcdefgh", 0xabcdef, STATUS_SUCCESS}, /* Hex with illegal lower case digits (g-z) */ + { 0, "0xABCDEFGH", 0xABCDEF, STATUS_SUCCESS}, /* Hex with illegal upper case digits (G-Z) */ + { 0, "0xF", 0xf, STATUS_SUCCESS}, /* one digit hexadecimal */ + { 0, "0xG", 0, STATUS_SUCCESS}, /* empty hexadecimal */ + { 0, "0x", 0, STATUS_SUCCESS}, /* empty hexadecimal */ + { 0, "", 0, STATUS_SUCCESS}, /* empty string */ + { 2, "1011101100", 748, STATUS_SUCCESS}, + { 2, "-1011101100", -748, STATUS_SUCCESS}, + { 2, "2", 0, STATUS_SUCCESS}, + { 2, "0b1011101100", 0, STATUS_SUCCESS}, + { 2, "0o1011101100", 0, STATUS_SUCCESS}, + { 2, "0d1011101100", 0, STATUS_SUCCESS}, + { 2, "0x1011101100", 0, STATUS_SUCCESS}, + { 2, "", 0, STATUS_SUCCESS}, /* empty string */ + { 8, "1011101100", 136610368, STATUS_SUCCESS}, + { 8, "-1011101100", -136610368, STATUS_SUCCESS}, + { 8, "8", 0, STATUS_SUCCESS}, + { 8, "0b1011101100", 0, STATUS_SUCCESS}, + { 8, "0o1011101100", 0, STATUS_SUCCESS}, + { 8, "0d1011101100", 0, STATUS_SUCCESS}, + { 8, "0x1011101100", 0, STATUS_SUCCESS}, + { 8, "", 0, STATUS_SUCCESS}, /* empty string */ + {10, "1011101100", 1011101100, STATUS_SUCCESS}, + {10, "-1011101100", -1011101100, STATUS_SUCCESS}, + {10, "0b1011101100", 0, STATUS_SUCCESS}, + {10, "0o1011101100", 0, STATUS_SUCCESS}, + {10, "0d1011101100", 0, STATUS_SUCCESS}, + {10, "0x1011101100", 0, STATUS_SUCCESS}, + {10, "o12345", 0, STATUS_SUCCESS}, /* Octal although base is 10 */ + {10, "", 0, STATUS_SUCCESS}, /* empty string */ + {16, "1011101100", 286265600, STATUS_SUCCESS}, + {16, "-1011101100", -286265600, STATUS_SUCCESS}, + {16, "G", 0, STATUS_SUCCESS}, + {16, "g", 0, STATUS_SUCCESS}, + {16, "0b1011101100", 286265600, STATUS_SUCCESS}, + {16, "0o1011101100", 0, STATUS_SUCCESS}, + {16, "0d1011101100", 286265600, STATUS_SUCCESS}, + {16, "0x1011101100", 0, STATUS_SUCCESS}, + {16, "", 0, STATUS_SUCCESS}, /* empty string */ + {20, "0", 0xdeadbeef, STATUS_INVALID_PARAMETER}, /* illegal base */ + {-8, "0", 0xdeadbeef, STATUS_INVALID_PARAMETER}, /* Negative base */ +/* { 0, NULL, 0, STATUS_SUCCESS}, */ /* NULL as string */ +}; +#define NB_STR2INT (sizeof(str2int)/sizeof(*str2int)) + + +static void test_RtlUnicodeStringToInteger(void) +{ + size_t test_num; + int value; + NTSTATUS result; + WCHAR *wstr; + UNICODE_STRING uni; + + for (test_num = 0; test_num < NB_STR2INT; test_num++) { + wstr = AtoW(str2int[test_num].str); + value = 0xdeadbeef; + pRtlInitUnicodeString(&uni, wstr); + result = pRtlUnicodeStringToInteger(&uni, str2int[test_num].base, &value); + ok(result == str2int[test_num].result, + "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) has result %lx, expected: %lx\n", + test_num, str2int[test_num].str, str2int[test_num].base, result, str2int[test_num].result); + ok(value == str2int[test_num].value, + "(test %d): RtlUnicodeStringToInteger(\"%s\", %d, [out]) assigns value %d, expected: %d\n", + test_num, str2int[test_num].str, str2int[test_num].base, value, str2int[test_num].value); + free(wstr); + } + + wstr = AtoW(str2int[1].str); + pRtlInitUnicodeString(&uni, wstr); + result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, NULL); + ok(result == STATUS_ACCESS_VIOLATION, + "call failed: RtlUnicodeStringToInteger(\"%s\", %d, NULL) has result %lx\n", + str2int[1].str, str2int[1].base, result); + result = pRtlUnicodeStringToInteger(&uni, 20, NULL); + ok(result == STATUS_INVALID_PARAMETER, + "call failed: RtlUnicodeStringToInteger(\"%s\", 20, NULL) has result %lx\n", + str2int[1].str, result); + + uni.Length = 10; /* Make Length shorter (5 WCHARS instead of 7) */ + result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value); + ok(result == STATUS_SUCCESS, + "call failed: RtlUnicodeStringToInteger(\"12345\", %d, [out]) has result %lx\n", + str2int[1].base, result); + ok(value == 12345, + "didn't return expected value (test a): expected: %d, got: %d\n", + 12345, value); + + uni.Length = 5; /* Use odd Length (2.5 WCHARS) */ + result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value); + ok(result == STATUS_SUCCESS, + "call failed: RtlUnicodeStringToInteger(\"12\", %d, [out]) has result %lx\n", + str2int[1].base, result); + ok(value == 12, + "didn't return expected value (test b): expected: %d, got: %d\n", + 12, value); + + uni.Length = 2; + result = pRtlUnicodeStringToInteger(&uni, str2int[1].base, &value); + ok(result == STATUS_SUCCESS, + "call failed: RtlUnicodeStringToInteger(\"1\", %d, [out]) has result %lx\n", + str2int[1].base, result); + ok(value == 1, + "didn't return expected value (test c): expected: %d, got: %d\n", + 1, value); + /* w2k: uni.Length = 0 returns value 11234567 instead of 0 */ + free(wstr); +} + + +static void test_RtlCharToInteger(void) +{ + size_t test_num; + int value; + NTSTATUS result; + + for (test_num = 0; test_num < NB_STR2INT; test_num++) { + /* w2k skips a leading '\0' and processes the string after */ + if (str2int[test_num].str[0] != '\0') { + value = 0xdeadbeef; + result = pRtlCharToInteger(str2int[test_num].str, str2int[test_num].base, &value); + ok(result == str2int[test_num].result, + "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) has result %lx, expected: %lx\n", + test_num, str2int[test_num].str, str2int[test_num].base, result, str2int[test_num].result); + ok(value == str2int[test_num].value, + "(test %d): call failed: RtlCharToInteger(\"%s\", %d, [out]) assigns value %d, expected: %d\n", + test_num, str2int[test_num].str, str2int[test_num].base, value, str2int[test_num].value); + } + } + + result = pRtlCharToInteger(str2int[1].str, str2int[1].base, NULL); + ok(result == STATUS_ACCESS_VIOLATION, + "call failed: RtlCharToInteger(\"%s\", %d, NULL) has result %lx\n", + str2int[1].str, str2int[1].base, result); + + result = pRtlCharToInteger(str2int[1].str, 20, NULL); + ok(result == STATUS_INVALID_PARAMETER, + "call failed: RtlCharToInteger(\"%s\", 20, NULL) has result %lx\n", + str2int[1].str, result); +} + + +#define STRI_BUFFER_LENGTH 35 + +typedef struct { + int base; + ULONG value; + USHORT Length; + USHORT MaximumLength; + const char *Buffer; + NTSTATUS result; +} int2str_t; + +static const int2str_t int2str[] = { + {10, 123, 3, 11, "123\0-------------------------------", STATUS_SUCCESS}, + + { 0, 0x80000000U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* min signed int */ + { 0, -2147483647, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS}, + { 0, -2, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS}, + { 0, -1, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, + { 0, 0, 1, 11, "0\0---------------------------------", STATUS_SUCCESS}, + { 0, 1, 1, 11, "1\0---------------------------------", STATUS_SUCCESS}, + { 0, 12, 2, 11, "12\0--------------------------------", STATUS_SUCCESS}, + { 0, 123, 3, 11, "123\0-------------------------------", STATUS_SUCCESS}, + { 0, 1234, 4, 11, "1234\0------------------------------", STATUS_SUCCESS}, + { 0, 12345, 5, 11, "12345\0-----------------------------", STATUS_SUCCESS}, + { 0, 123456, 6, 11, "123456\0----------------------------", STATUS_SUCCESS}, + { 0, 1234567, 7, 11, "1234567\0---------------------------", STATUS_SUCCESS}, + { 0, 12345678, 8, 11, "12345678\0--------------------------", STATUS_SUCCESS}, + { 0, 123456789, 9, 11, "123456789\0-------------------------", STATUS_SUCCESS}, + { 0, 2147483646, 10, 11, "2147483646\0------------------------", STATUS_SUCCESS}, + { 0, 2147483647, 10, 11, "2147483647\0------------------------", STATUS_SUCCESS}, /* max signed int */ + { 0, 2147483648U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* uint = -max int */ + { 0, 2147483649U, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS}, + { 0, 4294967294U, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS}, + { 0, 4294967295U, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, /* max unsigned int */ + + { 2, 0x80000000U, 32, 33, "10000000000000000000000000000000\0--", STATUS_SUCCESS}, /* min signed int */ + { 2, -2147483647, 32, 33, "10000000000000000000000000000001\0--", STATUS_SUCCESS}, + { 2, -2, 32, 33, "11111111111111111111111111111110\0--", STATUS_SUCCESS}, + { 2, -1, 32, 33, "11111111111111111111111111111111\0--", STATUS_SUCCESS}, + { 2, 0, 1, 33, "0\0---------------------------------", STATUS_SUCCESS}, + { 2, 1, 1, 33, "1\0---------------------------------", STATUS_SUCCESS}, + { 2, 10, 4, 33, "1010\0------------------------------", STATUS_SUCCESS}, + { 2, 100, 7, 33, "1100100\0---------------------------", STATUS_SUCCESS}, + { 2, 1000, 10, 33, "1111101000\0------------------------", STATUS_SUCCESS}, + { 2, 10000, 14, 33, "10011100010000\0--------------------", STATUS_SUCCESS}, + { 2, 32767, 15, 33, "111111111111111\0-------------------", STATUS_SUCCESS}, + { 2, 32768, 16, 33, "1000000000000000\0------------------", STATUS_SUCCESS}, + { 2, 65535, 16, 33, "1111111111111111\0------------------", STATUS_SUCCESS}, + { 2, 65536, 17, 33, "10000000000000000\0-----------------", STATUS_SUCCESS}, + { 2, 100000, 17, 33, "11000011010100000\0-----------------", STATUS_SUCCESS}, + { 2, 1000000, 20, 33, "11110100001001000000\0--------------", STATUS_SUCCESS}, + { 2, 10000000, 24, 33, "100110001001011010000000\0----------", STATUS_SUCCESS}, + { 2, 100000000, 27, 33, "101111101011110000100000000\0-------", STATUS_SUCCESS}, + { 2, 1000000000, 30, 33, "111011100110101100101000000000\0----", STATUS_SUCCESS}, + { 2, 1073741823, 30, 33, "111111111111111111111111111111\0----", STATUS_SUCCESS}, + { 2, 2147483646, 31, 33, "1111111111111111111111111111110\0---", STATUS_SUCCESS}, + { 2, 2147483647, 31, 33, "1111111111111111111111111111111\0---", STATUS_SUCCESS}, /* max signed int */ + { 2, 2147483648U, 32, 33, "10000000000000000000000000000000\0--", STATUS_SUCCESS}, /* uint = -max int */ + { 2, 2147483649U, 32, 33, "10000000000000000000000000000001\0--", STATUS_SUCCESS}, + { 2, 4294967294U, 32, 33, "11111111111111111111111111111110\0--", STATUS_SUCCESS}, + { 2, 4294967295U, 32, 33, "11111111111111111111111111111111\0--", STATUS_SUCCESS}, /* max unsigned int */ + + { 8, 0x80000000U, 11, 12, "20000000000\0-----------------------", STATUS_SUCCESS}, /* min signed int */ + { 8, -2147483647, 11, 12, "20000000001\0-----------------------", STATUS_SUCCESS}, + { 8, -2, 11, 12, "37777777776\0-----------------------", STATUS_SUCCESS}, + { 8, -1, 11, 12, "37777777777\0-----------------------", STATUS_SUCCESS}, + { 8, 0, 1, 12, "0\0---------------------------------", STATUS_SUCCESS}, + { 8, 1, 1, 12, "1\0---------------------------------", STATUS_SUCCESS}, + { 8, 2147483646, 11, 12, "17777777776\0-----------------------", STATUS_SUCCESS}, + { 8, 2147483647, 11, 12, "17777777777\0-----------------------", STATUS_SUCCESS}, /* max signed int */ + { 8, 2147483648U, 11, 12, "20000000000\0-----------------------", STATUS_SUCCESS}, /* uint = -max int */ + { 8, 2147483649U, 11, 12, "20000000001\0-----------------------", STATUS_SUCCESS}, + { 8, 4294967294U, 11, 12, "37777777776\0-----------------------", STATUS_SUCCESS}, + { 8, 4294967295U, 11, 12, "37777777777\0-----------------------", STATUS_SUCCESS}, /* max unsigned int */ + + {10, 0x80000000U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* min signed int */ + {10, -2147483647, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS}, + {10, -2, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS}, + {10, -1, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, + {10, 0, 1, 11, "0\0---------------------------------", STATUS_SUCCESS}, + {10, 1, 1, 11, "1\0---------------------------------", STATUS_SUCCESS}, + {10, 2147483646, 10, 11, "2147483646\0------------------------", STATUS_SUCCESS}, + {10, 2147483647, 10, 11, "2147483647\0------------------------", STATUS_SUCCESS}, /* max signed int */ + {10, 2147483648U, 10, 11, "2147483648\0------------------------", STATUS_SUCCESS}, /* uint = -max int */ + {10, 2147483649U, 10, 11, "2147483649\0------------------------", STATUS_SUCCESS}, + {10, 4294967294U, 10, 11, "4294967294\0------------------------", STATUS_SUCCESS}, + {10, 4294967295U, 10, 11, "4294967295\0------------------------", STATUS_SUCCESS}, /* max unsigned int */ + + {16, 0x80000000U, 8, 9, "80000000\0--------------------------", STATUS_SUCCESS}, /* min signed int */ + {16, -2147483647, 8, 9, "80000001\0--------------------------", STATUS_SUCCESS}, + {16, -2, 8, 9, "FFFFFFFE\0--------------------------", STATUS_SUCCESS}, + {16, -1, 8, 9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS}, + {16, 0, 1, 9, "0\0---------------------------------", STATUS_SUCCESS}, + {16, 1, 1, 9, "1\0---------------------------------", STATUS_SUCCESS}, + {16, 2147483646, 8, 9, "7FFFFFFE\0--------------------------", STATUS_SUCCESS}, + {16, 2147483647, 8, 9, "7FFFFFFF\0--------------------------", STATUS_SUCCESS}, /* max signed int */ + {16, 2147483648U, 8, 9, "80000000\0--------------------------", STATUS_SUCCESS}, /* uint = -max int */ + {16, 2147483649U, 8, 9, "80000001\0--------------------------", STATUS_SUCCESS}, + {16, 4294967294U, 8, 9, "FFFFFFFE\0--------------------------", STATUS_SUCCESS}, + {16, 4294967295U, 8, 9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS}, /* max unsigned int */ + + { 2, 32768, 16, 17, "1000000000000000\0------------------", STATUS_SUCCESS}, + { 2, 32768, 16, 16, "1000000000000000-------------------", STATUS_SUCCESS}, + { 2, 65536, 17, 18, "10000000000000000\0-----------------", STATUS_SUCCESS}, + { 2, 65536, 17, 17, "10000000000000000------------------", STATUS_SUCCESS}, + { 2, 131072, 18, 19, "100000000000000000\0----------------", STATUS_SUCCESS}, + { 2, 131072, 18, 18, "100000000000000000-----------------", STATUS_SUCCESS}, + {16, 0xffffffff, 8, 9, "FFFFFFFF\0--------------------------", STATUS_SUCCESS}, + {16, 0xffffffff, 8, 8, "FFFFFFFF---------------------------", STATUS_SUCCESS}, /* No \0 term */ + {16, 0xffffffff, 8, 7, "-----------------------------------", STATUS_BUFFER_OVERFLOW}, /* Too short */ + {16, 0xa, 1, 2, "A\0---------------------------------", STATUS_SUCCESS}, + {16, 0xa, 1, 1, "A----------------------------------", STATUS_SUCCESS}, /* No \0 term */ + {16, 0, 1, 0, "-----------------------------------", STATUS_BUFFER_OVERFLOW}, + {20, 0xdeadbeef, 0, 9, "-----------------------------------", STATUS_INVALID_PARAMETER}, /* ill. base */ + {-8, 07654321, 0, 12, "-----------------------------------", STATUS_INVALID_PARAMETER}, /* neg. base */ +}; +#define NB_INT2STR (sizeof(int2str)/sizeof(*int2str)) + + +static void one_RtlIntegerToUnicodeString_test(int test_num, const int2str_t *int2str) +{ + int pos; + WCHAR expected_str_Buffer[STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING expected_unicode_string; + STRING expected_ansi_str; + WCHAR str_Buffer[STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + NTSTATUS result; + + for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) { + expected_str_Buffer[pos] = int2str->Buffer[pos]; + } + expected_unicode_string.Length = int2str->Length * sizeof(WCHAR); + expected_unicode_string.MaximumLength = int2str->MaximumLength * sizeof(WCHAR); + expected_unicode_string.Buffer = expected_str_Buffer; + pRtlUnicodeStringToAnsiString(&expected_ansi_str, &expected_unicode_string, 1); + + for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) { + str_Buffer[pos] = '-'; + } + unicode_string.Length = 0; + unicode_string.MaximumLength = int2str->MaximumLength * sizeof(WCHAR); + unicode_string.Buffer = str_Buffer; + + result = pRtlIntegerToUnicodeString(int2str->value, int2str->base, &unicode_string); + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + if (result == STATUS_BUFFER_OVERFLOW) { + /* On BUFFER_OVERFLOW the string Buffer should be unchanged */ + for (pos = 0; pos < STRI_BUFFER_LENGTH; pos++) { + expected_str_Buffer[pos] = '-'; + } + /* w2k: The native function has two reasons for BUFFER_OVERFLOW: */ + /* If the value is too large to convert: The Length is unchanged */ + /* If str is too small to hold the string: Set str->Length to the length */ + /* the string would have (which can be larger than the MaximumLength). */ + /* To allow all this in the tests we do the following: */ + if (expected_unicode_string.Length > 32 && unicode_string.Length == 0) { + /* The value is too large to convert only triggerd when testing native */ + expected_unicode_string.Length = 0; + } + } else { + ok(result == int2str->result, + "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) has result %lx, expected: %lx\n", + test_num, int2str->value, int2str->base, result, int2str->result); + if (result == STATUS_SUCCESS) { + ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0', + "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) string \"%s\" is not NULL terminated\n", + test_num, int2str->value, int2str->base, ansi_str.Buffer); + } + } + ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) assigns string \"%s\", expected: \"%s\"\n", + test_num, int2str->value, int2str->base, ansi_str.Buffer, expected_ansi_str.Buffer); + ok(unicode_string.Length == expected_unicode_string.Length, + "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) string has Length %d, expected: %d\n", + test_num, int2str->value, int2str->base, unicode_string.Length, expected_unicode_string.Length); + ok(unicode_string.MaximumLength == expected_unicode_string.MaximumLength, + "(test %d): RtlIntegerToUnicodeString(%lu, %d, [out]) string has MaximumLength %d, expected: %d\n", + test_num, int2str->value, int2str->base, unicode_string.MaximumLength, expected_unicode_string.MaximumLength); + pRtlFreeAnsiString(&expected_ansi_str); + pRtlFreeAnsiString(&ansi_str); +} + + +static void test_RtlIntegerToUnicodeString(void) +{ + size_t test_num; + + for (test_num = 0; test_num < NB_INT2STR; test_num++) + one_RtlIntegerToUnicodeString_test(test_num, &int2str[test_num]); +} + + +static void one_RtlIntegerToChar_test(int test_num, const int2str_t *int2str) +{ + NTSTATUS result; + char dest_str[STRI_BUFFER_LENGTH + 1]; + + memset(dest_str, '-', STRI_BUFFER_LENGTH); + dest_str[STRI_BUFFER_LENGTH] = '\0'; + result = pRtlIntegerToChar(int2str->value, int2str->base, int2str->MaximumLength, dest_str); + ok(result == int2str->result, + "(test %d): RtlIntegerToChar(%lu, %d, %d, [out]) has result %lx, expected: %lx\n", + test_num, int2str->value, int2str->base, int2str->MaximumLength, result, int2str->result); + ok(memcmp(dest_str, int2str->Buffer, STRI_BUFFER_LENGTH) == 0, + "(test %d): RtlIntegerToChar(%lu, %d, %d, [out]) assigns string \"%s\", expected: \"%s\"\n", + test_num, int2str->value, int2str->base, int2str->MaximumLength, dest_str, int2str->Buffer); +} + + +static void test_RtlIntegerToChar(void) +{ + NTSTATUS result; + size_t test_num; + + for (test_num = 0; test_num < NB_INT2STR; test_num++) + one_RtlIntegerToChar_test(test_num, &int2str[test_num]); + + result = pRtlIntegerToChar(int2str[0].value, 20, int2str[0].MaximumLength, NULL); + ok(result == STATUS_INVALID_PARAMETER, + "(test a): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %x\n", + int2str[0].value, 20, int2str[0].MaximumLength, result, STATUS_INVALID_PARAMETER); + + result = pRtlIntegerToChar(int2str[0].value, 20, 0, NULL); + ok(result == STATUS_INVALID_PARAMETER, + "(test b): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %x\n", + int2str[0].value, 20, 0, result, STATUS_INVALID_PARAMETER); + + result = pRtlIntegerToChar(int2str[0].value, int2str[0].base, 0, NULL); + ok(result == STATUS_BUFFER_OVERFLOW, + "(test c): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %x\n", + int2str[0].value, int2str[0].base, 0, result, STATUS_BUFFER_OVERFLOW); + + result = pRtlIntegerToChar(int2str[0].value, int2str[0].base, int2str[0].MaximumLength, NULL); + ok(result == STATUS_ACCESS_VIOLATION, + "(test d): RtlIntegerToChar(%lu, %d, %d, NULL) has result %lx, expected: %x\n", + int2str[0].value, int2str[0].base, int2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION); +} + +static const WCHAR szGuid[] = { '{','0','1','0','2','0','3','0','4','-', + '0','5','0','6','-' ,'0','7','0','8','-','0','9','0','A','-', + '0','B','0','C','0','D','0','E','0','F','0','A','}','\0' }; +DEFINE_GUID(IID_Endianess, 0x01020304, 0x0506, 0x0708, 0x09, 0x0A, 0x0B, + 0x0C, 0x0D, 0x0E, 0x0F, 0x0A); + +static void test_RtlGUIDFromString(void) +{ + GUID guid; + UNICODE_STRING str; + NTSTATUS ret; + + str.Length = str.MaximumLength = (sizeof(szGuid) - 1) / sizeof(WCHAR); + str.Buffer = (LPWSTR)szGuid; + + ret = pRtlGUIDFromString(&str, &guid); + ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret); + ok(memcmp(&guid, &IID_Endianess, sizeof(guid)) == 0, "Endianess broken\n"); +} + +static void test_RtlStringFromGUID(void) +{ + UNICODE_STRING str; + NTSTATUS ret; + + str.Length = str.MaximumLength = 0; + str.Buffer = NULL; + + ret = pRtlStringFromGUID(&IID_Endianess, &str); + ok(ret == 0, "expected ret=0, got 0x%0lx\n", ret); + ok(str.Buffer && !lstrcmpW(str.Buffer, szGuid), "Endianess broken\n"); +} + +START_TEST(rtlstr) +{ + InitFunctionPtrs(); + if (pRtlInitAnsiString) { + test_RtlInitString(); + test_RtlInitUnicodeString(); + test_RtlCopyString(); + test_RtlUnicodeStringToInteger(); + test_RtlCharToInteger(); + test_RtlIntegerToUnicodeString(); + test_RtlIntegerToChar(); + test_RtlUpperChar(); + test_RtlUpperString(); + test_RtlUnicodeStringToAnsiString(); + test_RtlAppendAsciizToString(); + test_RtlAppendStringToString(); + test_RtlAppendUnicodeToString(); + test_RtlAppendUnicodeStringToString(); + } + + if (pRtlInitUnicodeStringEx) + test_RtlInitUnicodeStringEx(); + if (pRtlDuplicateUnicodeString) + test_RtlDuplicateUnicodeString(); + if (pRtlFindCharInUnicodeString) + test_RtlFindCharInUnicodeString(); + if (pRtlGUIDFromString) + test_RtlGUIDFromString(); + if (pRtlStringFromGUID) + test_RtlStringFromGUID(); + if(0) + { + test_RtlUpcaseUnicodeChar(); + test_RtlUpcaseUnicodeString(); + test_RtlDowncaseUnicodeString(); + } +} diff --git a/reactos/regtests/winetests/ntdll/string.c b/reactos/regtests/winetests/ntdll/string.c new file mode 100755 index 00000000000..f7cc7994a63 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/string.c @@ -0,0 +1,1100 @@ +/* Unit test suite for string functions and some wcstring 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 + +#include "ntdll_test.h" + + +/* Function ptrs for ntdll calls */ +static HMODULE hntdll = 0; +static NTSTATUS (WINAPI *pRtlUnicodeStringToAnsiString)(STRING *, const UNICODE_STRING *, BOOLEAN); +static VOID (WINAPI *pRtlFreeAnsiString)(PSTRING); +static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING,LPCSTR); +static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING); + +static int (WINAPIV *patoi)(const char *); +static long (WINAPIV *patol)(const char *); +static LONGLONG (WINAPIV *p_atoi64)(const char *); +static LPSTR (WINAPIV *p_itoa)(int, LPSTR, INT); +static LPSTR (WINAPIV *p_ltoa)(long, LPSTR, INT); +static LPSTR (WINAPIV *p_ultoa)(unsigned long, LPSTR, INT); +static LPSTR (WINAPIV *p_i64toa)(LONGLONG, LPSTR, INT); +static LPSTR (WINAPIV *p_ui64toa)(ULONGLONG, LPSTR, INT); + +static int (WINAPIV *p_wtoi)(LPWSTR); +static long (WINAPIV *p_wtol)(LPWSTR); +static LONGLONG (WINAPIV *p_wtoi64)(LPWSTR); +static LPWSTR (WINAPIV *p_itow)(int, LPWSTR, int); +static LPWSTR (WINAPIV *p_ltow)(long, LPWSTR, INT); +static LPWSTR (WINAPIV *p_ultow)(unsigned long, LPWSTR, INT); +static LPWSTR (WINAPIV *p_i64tow)(LONGLONG, LPWSTR, INT); +static LPWSTR (WINAPIV *p_ui64tow)(ULONGLONG, LPWSTR, INT); + +static long (WINAPIV *pwcstol)(LPCWSTR, LPWSTR *, INT); +static ULONG (WINAPIV *pwcstoul)(LPCWSTR, LPWSTR *, INT); + +static LPWSTR (WINAPIV *p_wcschr)(LPCWSTR, WCHAR); +static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR); + +static void InitFunctionPtrs(void) +{ + hntdll = LoadLibraryA("ntdll.dll"); + ok(hntdll != 0, "LoadLibrary failed\n"); + if (hntdll) { + pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString"); + pRtlFreeAnsiString = (void *)GetProcAddress(hntdll, "RtlFreeAnsiString"); + pRtlCreateUnicodeStringFromAsciiz = (void *)GetProcAddress(hntdll, "RtlCreateUnicodeStringFromAsciiz"); + pRtlFreeUnicodeString = (void *)GetProcAddress(hntdll, "RtlFreeUnicodeString"); + + patoi = (void *)GetProcAddress(hntdll, "atoi"); + patol = (void *)GetProcAddress(hntdll, "atol"); + p_atoi64 = (void *)GetProcAddress(hntdll, "_atoi64"); + p_itoa = (void *)GetProcAddress(hntdll, "_itoa"); + p_ltoa = (void *)GetProcAddress(hntdll, "_ltoa"); + p_ultoa = (void *)GetProcAddress(hntdll, "_ultoa"); + p_i64toa = (void *)GetProcAddress(hntdll, "_i64toa"); + p_ui64toa = (void *)GetProcAddress(hntdll, "_ui64toa"); + + p_wtoi = (void *)GetProcAddress(hntdll, "_wtoi"); + p_wtol = (void *)GetProcAddress(hntdll, "_wtol"); + p_wtoi64 = (void *)GetProcAddress(hntdll, "_wtoi64"); + p_itow = (void *)GetProcAddress(hntdll, "_itow"); + p_ltow = (void *)GetProcAddress(hntdll, "_ltow"); + p_ultow = (void *)GetProcAddress(hntdll, "_ultow"); + p_i64tow = (void *)GetProcAddress(hntdll, "_i64tow"); + p_ui64tow = (void *)GetProcAddress(hntdll, "_ui64tow"); + + pwcstol = (void *)GetProcAddress(hntdll, "wcstol"); + pwcstoul = (void *)GetProcAddress(hntdll, "wcstoul"); + + p_wcschr= (void *)GetProcAddress(hntdll, "wcschr"); + p_wcsrchr= (void *)GetProcAddress(hntdll, "wcsrchr"); + } /* if */ +} + + +#define LARGE_STRI_BUFFER_LENGTH 67 + +typedef struct { + int base; + ULONG value; + const char *Buffer; + int mask; /* ntdll/msvcrt: 0x01=itoa, 0x02=ltoa, 0x04=ultoa */ + /* 0x10=itow, 0x20=ltow, 0x40=ultow */ +} ulong2str_t; + +static const ulong2str_t ulong2str[] = { + {10, 123, "123\0---------------------------------------------------------------", 0x77}, + + { 2, 0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x67}, + { 2, -2147483647, "10000000000000000000000000000001\0----------------------------------", 0x67}, + { 2, -65537, "11111111111111101111111111111111\0----------------------------------", 0x67}, + { 2, -65536, "11111111111111110000000000000000\0----------------------------------", 0x67}, + { 2, -65535, "11111111111111110000000000000001\0----------------------------------", 0x67}, + { 2, -32768, "11111111111111111000000000000000\0----------------------------------", 0x67}, + { 2, -32767, "11111111111111111000000000000001\0----------------------------------", 0x67}, + { 2, -2, "11111111111111111111111111111110\0----------------------------------", 0x67}, + { 2, -1, "11111111111111111111111111111111\0----------------------------------", 0x67}, + { 2, 0, "0\0-----------------------------------------------------------------", 0x77}, + { 2, 1, "1\0-----------------------------------------------------------------", 0x77}, + { 2, 10, "1010\0--------------------------------------------------------------", 0x77}, + { 2, 100, "1100100\0-----------------------------------------------------------", 0x77}, + { 2, 1000, "1111101000\0--------------------------------------------------------", 0x77}, + { 2, 10000, "10011100010000\0----------------------------------------------------", 0x77}, + { 2, 32767, "111111111111111\0---------------------------------------------------", 0x77}, + { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x77}, + { 2, 65535, "1111111111111111\0--------------------------------------------------", 0x77}, + { 2, 100000, "11000011010100000\0-------------------------------------------------", 0x77}, + { 2, 234567, "111001010001000111\0------------------------------------------------", 0x77}, + { 2, 300000, "1001001001111100000\0-----------------------------------------------", 0x77}, + { 2, 524287, "1111111111111111111\0-----------------------------------------------", 0x77}, + { 2, 524288, "10000000000000000000\0----------------------------------------------", 0x67}, + { 2, 1000000, "11110100001001000000\0----------------------------------------------", 0x67}, + { 2, 10000000, "100110001001011010000000\0------------------------------------------", 0x67}, + { 2, 100000000, "101111101011110000100000000\0---------------------------------------", 0x67}, + { 2, 1000000000, "111011100110101100101000000000\0------------------------------------", 0x67}, + { 2, 1073741823, "111111111111111111111111111111\0------------------------------------", 0x67}, + { 2, 2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x67}, + { 2, 2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x67}, + { 2, 2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x67}, + { 2, 2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x67}, + { 2, 4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x67}, + { 2, 0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x67}, + + { 8, 0x80000000U, "20000000000\0-------------------------------------------------------", 0x77}, + { 8, -2147483647, "20000000001\0-------------------------------------------------------", 0x77}, + { 8, -2, "37777777776\0-------------------------------------------------------", 0x77}, + { 8, -1, "37777777777\0-------------------------------------------------------", 0x77}, + { 8, 0, "0\0-----------------------------------------------------------------", 0x77}, + { 8, 1, "1\0-----------------------------------------------------------------", 0x77}, + { 8, 2147483646, "17777777776\0-------------------------------------------------------", 0x77}, + { 8, 2147483647, "17777777777\0-------------------------------------------------------", 0x77}, + { 8, 2147483648U, "20000000000\0-------------------------------------------------------", 0x77}, + { 8, 2147483649U, "20000000001\0-------------------------------------------------------", 0x77}, + { 8, 4294967294U, "37777777776\0-------------------------------------------------------", 0x77}, + { 8, 4294967295U, "37777777777\0-------------------------------------------------------", 0x77}, + + {10, 0x80000000U, "-2147483648\0-------------------------------------------------------", 0x33}, + {10, 0x80000000U, "2147483648\0--------------------------------------------------------", 0x44}, + {10, -2147483647, "-2147483647\0-------------------------------------------------------", 0x33}, + {10, -2147483647, "2147483649\0--------------------------------------------------------", 0x44}, + {10, -2, "-2\0----------------------------------------------------------------", 0x33}, + {10, -2, "4294967294\0--------------------------------------------------------", 0x44}, + {10, -1, "-1\0----------------------------------------------------------------", 0x33}, + {10, -1, "4294967295\0--------------------------------------------------------", 0x44}, + {10, 0, "0\0-----------------------------------------------------------------", 0x77}, + {10, 1, "1\0-----------------------------------------------------------------", 0x77}, + {10, 12, "12\0----------------------------------------------------------------", 0x77}, + {10, 123, "123\0---------------------------------------------------------------", 0x77}, + {10, 1234, "1234\0--------------------------------------------------------------", 0x77}, + {10, 12345, "12345\0-------------------------------------------------------------", 0x77}, + {10, 123456, "123456\0------------------------------------------------------------", 0x77}, + {10, 1234567, "1234567\0-----------------------------------------------------------", 0x77}, + {10, 12345678, "12345678\0----------------------------------------------------------", 0x77}, + {10, 123456789, "123456789\0---------------------------------------------------------", 0x77}, + {10, 2147483646, "2147483646\0--------------------------------------------------------", 0x77}, + {10, 2147483647, "2147483647\0--------------------------------------------------------", 0x77}, + {10, 2147483648U, "-2147483648\0-------------------------------------------------------", 0x33}, + {10, 2147483648U, "2147483648\0--------------------------------------------------------", 0x44}, + {10, 2147483649U, "-2147483647\0-------------------------------------------------------", 0x33}, + {10, 2147483649U, "2147483649\0--------------------------------------------------------", 0x44}, + {10, 4294967294U, "-2\0----------------------------------------------------------------", 0x33}, + {10, 4294967294U, "4294967294\0--------------------------------------------------------", 0x44}, + {10, 4294967295U, "-1\0----------------------------------------------------------------", 0x33}, + {10, 4294967295U, "4294967295\0--------------------------------------------------------", 0x44}, + + {16, 0, "0\0-----------------------------------------------------------------", 0x77}, + {16, 1, "1\0-----------------------------------------------------------------", 0x77}, + {16, 2147483646, "7ffffffe\0----------------------------------------------------------", 0x77}, + {16, 2147483647, "7fffffff\0----------------------------------------------------------", 0x77}, + {16, 0x80000000, "80000000\0----------------------------------------------------------", 0x77}, + {16, 0x80000001, "80000001\0----------------------------------------------------------", 0x77}, + {16, 0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x77}, + {16, 0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x77}, + + { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x77}, + { 2, 65536, "10000000000000000\0-------------------------------------------------", 0x77}, + { 2, 131072, "100000000000000000\0------------------------------------------------", 0x77}, + {16, 0xffffffff, "ffffffff\0----------------------------------------------------------", 0x77}, + {16, 0xa, "a\0-----------------------------------------------------------------", 0x77}, + {16, 0, "0\0-----------------------------------------------------------------", 0x77}, + {20, 3368421, "111111\0------------------------------------------------------------", 0x77}, + {36, 62193781, "111111\0------------------------------------------------------------", 0x77}, + {37, 71270178, "111111\0------------------------------------------------------------", 0x77}, +}; +#define NB_ULONG2STR (sizeof(ulong2str)/sizeof(*ulong2str)) + + +static void one_itoa_test(int test_num, const ulong2str_t *ulong2str) +{ + char dest_str[LARGE_STRI_BUFFER_LENGTH + 1]; + int value; + LPSTR result; + + memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH); + dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0'; + value = ulong2str->value; + result = p_itoa(value, dest_str, ulong2str->base); + ok(result == dest_str, + "(test %d): _itoa(%d, [out], %d) has result %p, expected: %p\n", + test_num, value, ulong2str->base, result, dest_str); + ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): _itoa(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, value, ulong2str->base, dest_str, ulong2str->Buffer); +} + + +static void one_ltoa_test(int test_num, const ulong2str_t *ulong2str) +{ + char dest_str[LARGE_STRI_BUFFER_LENGTH + 1]; + long value; + LPSTR result; + + memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH); + dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0'; + value = ulong2str->value; + result = p_ltoa(ulong2str->value, dest_str, ulong2str->base); + ok(result == dest_str, + "(test %d): _ltoa(%ld, [out], %d) has result %p, expected: %p\n", + test_num, value, ulong2str->base, result, dest_str); + ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): _ltoa(%ld, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, value, ulong2str->base, dest_str, ulong2str->Buffer); +} + + +static void one_ultoa_test(int test_num, const ulong2str_t *ulong2str) +{ + char dest_str[LARGE_STRI_BUFFER_LENGTH + 1]; + unsigned long value; + LPSTR result; + + memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH); + dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0'; + value = ulong2str->value; + result = p_ultoa(ulong2str->value, dest_str, ulong2str->base); + ok(result == dest_str, + "(test %d): _ultoa(%lu, [out], %d) has result %p, expected: %p\n", + test_num, value, ulong2str->base, result, dest_str); + ok(memcmp(dest_str, ulong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): _ultoa(%lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, value, ulong2str->base, dest_str, ulong2str->Buffer); +} + + +static void test_ulongtoa(void) +{ + int test_num; + + for (test_num = 0; test_num < NB_ULONG2STR; test_num++) { + if (ulong2str[test_num].mask & 0x01) { + one_itoa_test(test_num, &ulong2str[test_num]); + } /* if */ + if (ulong2str[test_num].mask & 0x02) { + one_ltoa_test(test_num, &ulong2str[test_num]); + } /* if */ + if (ulong2str[test_num].mask & 0x04) { + one_ultoa_test(test_num, &ulong2str[test_num]); + } /* if */ + } /* for */ +} + + +static void one_itow_test(int test_num, const ulong2str_t *ulong2str) +{ + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + int value; + LPWSTR result; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str->Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + dest_wstr[pos] = '-'; + } /* for */ + dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR); + unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR); + unicode_string.Buffer = dest_wstr; + value = ulong2str->value; + result = p_itow(value, dest_wstr, ulong2str->base); + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + ok(result == dest_wstr, + "(test %d): _itow(%d, [out], %d) has result %p, expected: %p\n", + test_num, value, ulong2str->base, result, dest_wstr); + ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): _itow(%d, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer); + pRtlFreeAnsiString(&ansi_str); +} + + +static void one_ltow_test(int test_num, const ulong2str_t *ulong2str) +{ + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + long value; + LPWSTR result; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str->Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + dest_wstr[pos] = '-'; + } /* for */ + dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR); + unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR); + unicode_string.Buffer = dest_wstr; + + value = ulong2str->value; + result = p_ltow(value, dest_wstr, ulong2str->base); + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + ok(result == dest_wstr, + "(test %d): _ltow(%ld, [out], %d) has result %p, expected: %p\n", + test_num, value, ulong2str->base, result, dest_wstr); + ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): _ltow(%ld, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer); + pRtlFreeAnsiString(&ansi_str); +} + + +static void one_ultow_test(int test_num, const ulong2str_t *ulong2str) +{ + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + unsigned long value; + LPWSTR result; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str->Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + dest_wstr[pos] = '-'; + } /* for */ + dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR); + unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR); + unicode_string.Buffer = dest_wstr; + + value = ulong2str->value; + result = p_ultow(value, dest_wstr, ulong2str->base); + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + ok(result == dest_wstr, + "(test %d): _ultow(%lu, [out], %d) has result %p, expected: %p\n", + test_num, value, ulong2str->base, result, dest_wstr); + ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): _ultow(%lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, value, ulong2str->base, ansi_str.Buffer, ulong2str->Buffer); + pRtlFreeAnsiString(&ansi_str); +} + + +static void test_ulongtow(void) +{ + int test_num; + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + LPWSTR result; + + for (test_num = 0; test_num < NB_ULONG2STR; test_num++) { + if (ulong2str[test_num].mask & 0x10) { + one_itow_test(test_num, &ulong2str[test_num]); + } /* if */ + if (ulong2str[test_num].mask & 0x20) { + one_ltow_test(test_num, &ulong2str[test_num]); + } /* if */ + if (ulong2str[test_num].mask & 0x40) { + one_ultow_test(test_num, &ulong2str[test_num]); + } /* if */ + } /* for */ + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str[0].Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_itow(ulong2str[0].value, NULL, 10); + ok(result == NULL, + "(test a): _itow(%ld, NULL, 10) has result %p, expected: NULL\n", + ulong2str[0].value, result); + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str[0].Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_ltow(ulong2str[0].value, NULL, 10); + ok(result == NULL, + "(test b): _ltow(%ld, NULL, 10) has result %p, expected: NULL\n", + ulong2str[0].value, result); + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str[0].Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_ultow(ulong2str[0].value, NULL, 10); + ok(result == NULL, + "(test c): _ultow(%ld, NULL, 10) has result %p, expected: NULL\n", + ulong2str[0].value, result); +} + +#define ULL(a,b) (((ULONGLONG)(a) << 32) | (b)) + +typedef struct { + int base; + ULONGLONG value; + const char *Buffer; + int mask; /* ntdll/msvcrt: 0x01=i64toa, 0x02=ui64toa, 0x04=wrong _i64toa try next example */ + /* 0x10=i64tow, 0x20=ui64tow, 0x40=wrong _i64tow try next example */ +} ulonglong2str_t; + +static const ulonglong2str_t ulonglong2str[] = { + {10, 123, "123\0---------------------------------------------------------------", 0x33}, + + { 2, 0x80000000U, "10000000000000000000000000000000\0----------------------------------", 0x33}, + { 2, -2147483647, "1111111111111111111111111111111110000000000000000000000000000001\0--", 0x33}, + { 2, -65537, "1111111111111111111111111111111111111111111111101111111111111111\0--", 0x33}, + { 2, -65536, "1111111111111111111111111111111111111111111111110000000000000000\0--", 0x33}, + { 2, -65535, "1111111111111111111111111111111111111111111111110000000000000001\0--", 0x33}, + { 2, -32768, "1111111111111111111111111111111111111111111111111000000000000000\0--", 0x33}, + { 2, -32767, "1111111111111111111111111111111111111111111111111000000000000001\0--", 0x33}, + { 2, -2, "1111111111111111111111111111111111111111111111111111111111111110\0--", 0x33}, + { 2, -1, "1111111111111111111111111111111111111111111111111111111111111111\0--", 0x33}, + { 2, 0, "0\0-----------------------------------------------------------------", 0x33}, + { 2, 1, "1\0-----------------------------------------------------------------", 0x33}, + { 2, 10, "1010\0--------------------------------------------------------------", 0x33}, + { 2, 100, "1100100\0-----------------------------------------------------------", 0x33}, + { 2, 1000, "1111101000\0--------------------------------------------------------", 0x33}, + { 2, 10000, "10011100010000\0----------------------------------------------------", 0x33}, + { 2, 32767, "111111111111111\0---------------------------------------------------", 0x33}, + { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x33}, + { 2, 65535, "1111111111111111\0--------------------------------------------------", 0x33}, + { 2, 100000, "11000011010100000\0-------------------------------------------------", 0x33}, + { 2, 234567, "111001010001000111\0------------------------------------------------", 0x33}, + { 2, 300000, "1001001001111100000\0-----------------------------------------------", 0x33}, + { 2, 524287, "1111111111111111111\0-----------------------------------------------", 0x33}, + { 2, 524288, "10000000000000000000\0----------------------------------------------", 0x33}, + { 2, 1000000, "11110100001001000000\0----------------------------------------------", 0x33}, + { 2, 10000000, "100110001001011010000000\0------------------------------------------", 0x33}, + { 2, 100000000, "101111101011110000100000000\0---------------------------------------", 0x33}, + { 2, 1000000000, "111011100110101100101000000000\0------------------------------------", 0x33}, + { 2, 1073741823, "111111111111111111111111111111\0------------------------------------", 0x33}, + { 2, 2147483646, "1111111111111111111111111111110\0-----------------------------------", 0x33}, + { 2, 2147483647, "1111111111111111111111111111111\0-----------------------------------", 0x33}, + { 2, 2147483648U, "10000000000000000000000000000000\0----------------------------------", 0x33}, + { 2, 2147483649U, "10000000000000000000000000000001\0----------------------------------", 0x33}, + { 2, 4294967294U, "11111111111111111111111111111110\0----------------------------------", 0x33}, + { 2, 0xFFFFFFFF, "11111111111111111111111111111111\0----------------------------------", 0x33}, + { 2, ULL(0x1,0xffffffff), "111111111111111111111111111111111\0---------------------------------", 0x33}, + { 2, ((ULONGLONG)100000)*100000, "1001010100000010111110010000000000\0--------------------------------", 0x33}, + { 2, ULL(0x3,0xffffffff), "1111111111111111111111111111111111\0--------------------------------", 0x33}, + { 2, ULL(0x7,0xffffffff), "11111111111111111111111111111111111\0-------------------------------", 0x33}, + { 2, ULL(0xf,0xffffffff), "111111111111111111111111111111111111\0------------------------------", 0x33}, + { 2, ((ULONGLONG)100000)*1000000, "1011101001000011101101110100000000000\0-----------------------------", 0x33}, + { 2, ULL(0x1f,0xffffffff), "1111111111111111111111111111111111111\0-----------------------------", 0x33}, + { 2, ULL(0x3f,0xffffffff), "11111111111111111111111111111111111111\0----------------------------", 0x33}, + { 2, ULL(0x7f,0xffffffff), "111111111111111111111111111111111111111\0---------------------------", 0x33}, + { 2, ULL(0xff,0xffffffff), "1111111111111111111111111111111111111111\0--------------------------", 0x33}, + + { 8, 0x80000000U, "20000000000\0-------------------------------------------------------", 0x33}, + { 8, -2147483647, "1777777777760000000001\0--------------------------------------------", 0x33}, + { 8, -2, "1777777777777777777776\0--------------------------------------------", 0x33}, + { 8, -1, "1777777777777777777777\0--------------------------------------------", 0x33}, + { 8, 0, "0\0-----------------------------------------------------------------", 0x33}, + { 8, 1, "1\0-----------------------------------------------------------------", 0x33}, + { 8, 2147483646, "17777777776\0-------------------------------------------------------", 0x33}, + { 8, 2147483647, "17777777777\0-------------------------------------------------------", 0x33}, + { 8, 2147483648U, "20000000000\0-------------------------------------------------------", 0x33}, + { 8, 2147483649U, "20000000001\0-------------------------------------------------------", 0x33}, + { 8, 4294967294U, "37777777776\0-------------------------------------------------------", 0x33}, + { 8, 4294967295U, "37777777777\0-------------------------------------------------------", 0x33}, + + {10, 0x80000000U, "2147483648\0--------------------------------------------------------", 0x33}, + {10, -2147483647, "-2147483647\0-------------------------------------------------------", 0x55}, + {10, -2147483647, "-18446744071562067969\0---------------------------------------------", 0x00}, + {10, -2147483647, "18446744071562067969\0----------------------------------------------", 0x22}, + {10, -2, "-2\0----------------------------------------------------------------", 0x55}, + {10, -2, "-18446744073709551614\0---------------------------------------------", 0x00}, + {10, -2, "18446744073709551614\0----------------------------------------------", 0x22}, + {10, -1, "-1\0----------------------------------------------------------------", 0x55}, + {10, -1, "-18446744073709551615\0---------------------------------------------", 0x00}, + {10, -1, "18446744073709551615\0----------------------------------------------", 0x22}, + {10, 0, "0\0-----------------------------------------------------------------", 0x33}, + {10, 1, "1\0-----------------------------------------------------------------", 0x33}, + {10, 12, "12\0----------------------------------------------------------------", 0x33}, + {10, 123, "123\0---------------------------------------------------------------", 0x33}, + {10, 1234, "1234\0--------------------------------------------------------------", 0x33}, + {10, 12345, "12345\0-------------------------------------------------------------", 0x33}, + {10, 123456, "123456\0------------------------------------------------------------", 0x33}, + {10, 1234567, "1234567\0-----------------------------------------------------------", 0x33}, + {10, 12345678, "12345678\0----------------------------------------------------------", 0x33}, + {10, 123456789, "123456789\0---------------------------------------------------------", 0x33}, + {10, 2147483646, "2147483646\0--------------------------------------------------------", 0x33}, + {10, 2147483647, "2147483647\0--------------------------------------------------------", 0x33}, + {10, 2147483648U, "2147483648\0--------------------------------------------------------", 0x33}, + {10, 2147483649U, "2147483649\0--------------------------------------------------------", 0x33}, + {10, 4294967294U, "4294967294\0--------------------------------------------------------", 0x33}, + {10, 4294967295U, "4294967295\0--------------------------------------------------------", 0x33}, + {10, ULL(0x2,0xdfdc1c35), "12345678901\0-------------------------------------------------------", 0x33}, + {10, ULL(0xe5,0xf4c8f374), "987654321012\0------------------------------------------------------", 0x33}, + {10, ULL(0x1c0,0xfc161e3e), "1928374656574\0-----------------------------------------------------", 0x33}, + {10, ULL(0xbad,0xcafeface), "12841062955726\0----------------------------------------------------", 0x33}, + {10, ULL(0x5bad,0xcafeface), "100801993177806\0---------------------------------------------------", 0x33}, + {10, ULL(0xaface,0xbeefcafe), "3090515640699646\0--------------------------------------------------", 0x33}, + {10, ULL(0xa5beef,0xabcdcafe), "46653307746110206\0-------------------------------------------------", 0x33}, + {10, ULL(0x1f8cf9b,0xf2df3af1), "142091656963767025\0------------------------------------------------", 0x33}, + {10, ULL(0x0fffffff,0xffffffff), "1152921504606846975\0-----------------------------------------------", 0x33}, + {10, ULL(0x7fffffff,0xffffffff), "9223372036854775807\0-----------------------------------------------", 0x33}, + {10, ULL(0x80000000,0x00000000), "-9223372036854775808\0----------------------------------------------", 0x11}, + {10, ULL(0x80000000,0x00000000), "9223372036854775808\0-----------------------------------------------", 0x22}, + {10, ULL(0x80000000,0x00000001), "-9223372036854775807\0----------------------------------------------", 0x55}, + {10, ULL(0x80000000,0x00000001), "-9223372036854775809\0----------------------------------------------", 0x00}, + {10, ULL(0x80000000,0x00000001), "9223372036854775809\0-----------------------------------------------", 0x22}, + {10, ULL(0x80000000,0x00000002), "-9223372036854775806\0----------------------------------------------", 0x55}, + {10, ULL(0x80000000,0x00000002), "-9223372036854775810\0----------------------------------------------", 0x00}, + {10, ULL(0x80000000,0x00000002), "9223372036854775810\0-----------------------------------------------", 0x22}, + {10, ULL(0xffffffff,0xfffffffe), "-2\0----------------------------------------------------------------", 0x55}, + {10, ULL(0xffffffff,0xfffffffe), "-18446744073709551614\0---------------------------------------------", 0x00}, + {10, ULL(0xffffffff,0xfffffffe), "18446744073709551614\0----------------------------------------------", 0x22}, + {10, ULL(0xffffffff,0xffffffff), "-1\0----------------------------------------------------------------", 0x55}, + {10, ULL(0xffffffff,0xffffffff), "-18446744073709551615\0---------------------------------------------", 0x00}, + {10, ULL(0xffffffff,0xffffffff), "18446744073709551615\0----------------------------------------------", 0x22}, + + {16, 0, "0\0-----------------------------------------------------------------", 0x33}, + {16, 1, "1\0-----------------------------------------------------------------", 0x33}, + {16, 2147483646, "7ffffffe\0----------------------------------------------------------", 0x33}, + {16, 2147483647, "7fffffff\0----------------------------------------------------------", 0x33}, + {16, 0x80000000, "80000000\0----------------------------------------------------------", 0x33}, + {16, 0x80000001, "80000001\0----------------------------------------------------------", 0x33}, + {16, 0xFFFFFFFE, "fffffffe\0----------------------------------------------------------", 0x33}, + {16, 0xFFFFFFFF, "ffffffff\0----------------------------------------------------------", 0x33}, + {16, ULL(0x1,0x00000000), "100000000\0---------------------------------------------------------", 0x33}, + {16, ULL(0xbad,0xdeadbeef), "baddeadbeef\0-------------------------------------------------------", 0x33}, + {16, ULL(0x80000000,0x00000000), "8000000000000000\0--------------------------------------------------", 0x33}, + {16, ULL(0xfedcba98,0x76543210), "fedcba9876543210\0--------------------------------------------------", 0x33}, + {16, ULL(0xffffffff,0x80000001), "ffffffff80000001\0--------------------------------------------------", 0x33}, + {16, ULL(0xffffffff,0xfffffffe), "fffffffffffffffe\0--------------------------------------------------", 0x33}, + {16, ULL(0xffffffff,0xffffffff), "ffffffffffffffff\0--------------------------------------------------", 0x33}, + + { 2, 32768, "1000000000000000\0--------------------------------------------------", 0x33}, + { 2, 65536, "10000000000000000\0-------------------------------------------------", 0x33}, + { 2, 131072, "100000000000000000\0------------------------------------------------", 0x33}, + {16, 0xffffffff, "ffffffff\0----------------------------------------------------------", 0x33}, + {16, 0xa, "a\0-----------------------------------------------------------------", 0x33}, + {16, 0, "0\0-----------------------------------------------------------------", 0x33}, + {20, 3368421, "111111\0------------------------------------------------------------", 0x33}, + {36, 62193781, "111111\0------------------------------------------------------------", 0x33}, + {37, 71270178, "111111\0------------------------------------------------------------", 0x33}, + {99, ULL(0x2,0x3c9e468c), "111111\0------------------------------------------------------------", 0x33}, +}; +#define NB_ULONGLONG2STR (sizeof(ulonglong2str)/sizeof(*ulonglong2str)) + + +static void one_i64toa_test(int test_num, const ulonglong2str_t *ulonglong2str) +{ + LPSTR result; + char dest_str[LARGE_STRI_BUFFER_LENGTH + 1]; + + memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH); + dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_i64toa(ulonglong2str->value, dest_str, ulonglong2str->base); + ok(result == dest_str, + "(test %d): _i64toa(%Lu, [out], %d) has result %p, expected: %p\n", + test_num, ulonglong2str->value, ulonglong2str->base, result, dest_str); + if (ulonglong2str->mask & 0x04) { + if (memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) { + if (memcmp(dest_str, ulonglong2str[1].Buffer, LARGE_STRI_BUFFER_LENGTH) != 0) { + ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): _i64toa(%Lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, ulonglong2str->value, ulonglong2str->base, dest_str, ulonglong2str->Buffer); + } /* if */ + } /* if */ + } else { + ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): _i64toa(%Lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, ulonglong2str->value, ulonglong2str->base, dest_str, ulonglong2str->Buffer); + } /* if */ +} + + +static void one_ui64toa_test(int test_num, const ulonglong2str_t *ulonglong2str) +{ + LPSTR result; + char dest_str[LARGE_STRI_BUFFER_LENGTH + 1]; + + memset(dest_str, '-', LARGE_STRI_BUFFER_LENGTH); + dest_str[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_ui64toa(ulonglong2str->value, dest_str, ulonglong2str->base); + ok(result == dest_str, + "(test %d): _ui64toa(%Lu, [out], %d) has result %p, expected: %p\n", + test_num, ulonglong2str->value, ulonglong2str->base, result, dest_str); + ok(memcmp(dest_str, ulonglong2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0, + "(test %d): _ui64toa(%Lu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, ulonglong2str->value, ulonglong2str->base, dest_str, ulonglong2str->Buffer); +} + + +static void test_ulonglongtoa(void) +{ + int test_num; + + for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) { + if (ulonglong2str[test_num].mask & 0x01) { + one_i64toa_test(test_num, &ulonglong2str[test_num]); + } /* if */ + if (p_ui64toa != NULL) { + if (ulonglong2str[test_num].mask & 0x02) { + one_ui64toa_test(test_num, &ulonglong2str[test_num]); + } /* if */ + } /* if */ + } /* for */ +} + + +static void one_i64tow_test(int test_num, const ulonglong2str_t *ulonglong2str) +{ + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + LPWSTR result; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulonglong2str->Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + dest_wstr[pos] = '-'; + } /* for */ + dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR); + unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR); + unicode_string.Buffer = dest_wstr; + + result = p_i64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base); + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + ok(result == dest_wstr, + "(test %d): _i64tow(%llu, [out], %d) has result %p, expected: %p\n", + test_num, ulonglong2str->value, ulonglong2str->base, result, dest_wstr); + if (ulonglong2str->mask & 0x04) { + if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) { + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulonglong2str[1].Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + if (memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) != 0) { + ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): _i64tow(%llu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, ulonglong2str->value, ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer); + } /* if */ + } /* if */ + } else { + ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): _i64tow(%llu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, ulonglong2str->value, ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer); + } /* if */ + pRtlFreeAnsiString(&ansi_str); +} + + +static void one_ui64tow_test(int test_num, const ulonglong2str_t *ulonglong2str) +{ + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + WCHAR dest_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + UNICODE_STRING unicode_string; + STRING ansi_str; + LPWSTR result; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulonglong2str->Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + dest_wstr[pos] = '-'; + } /* for */ + dest_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + unicode_string.Length = LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR); + unicode_string.MaximumLength = unicode_string.Length + sizeof(WCHAR); + unicode_string.Buffer = dest_wstr; + + result = p_ui64tow(ulonglong2str->value, dest_wstr, ulonglong2str->base); + pRtlUnicodeStringToAnsiString(&ansi_str, &unicode_string, 1); + ok(result == dest_wstr, + "(test %d): _ui64tow(%llu, [out], %d) has result %p, expected: %p\n", + test_num, ulonglong2str->value, ulonglong2str->base, result, dest_wstr); + ok(memcmp(dest_wstr, expected_wstr, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0, + "(test %d): _ui64tow(%llu, [out], %d) assigns string \"%s\", expected: \"%s\"\n", + test_num, ulonglong2str->value, ulonglong2str->base, ansi_str.Buffer, ulonglong2str->Buffer); + pRtlFreeAnsiString(&ansi_str); +} + + +static void test_ulonglongtow(void) +{ + int test_num; + int pos; + WCHAR expected_wstr[LARGE_STRI_BUFFER_LENGTH + 1]; + LPWSTR result; + + for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) { + if (ulonglong2str[test_num].mask & 0x10) { + one_i64tow_test(test_num, &ulonglong2str[test_num]); + } /* if */ + if (p_ui64tow) { + if (ulonglong2str[test_num].mask & 0x20) { + one_ui64tow_test(test_num, &ulonglong2str[test_num]); + } /* if */ + } /* if */ + } /* for */ + + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str[0].Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_i64tow(ulong2str[0].value, NULL, 10); + ok(result == NULL, + "(test d): _i64tow(%llu, NULL, 10) has result %p, expected: NULL\n", + ulonglong2str[0].value, result); + + if (p_ui64tow) { + for (pos = 0; pos < LARGE_STRI_BUFFER_LENGTH; pos++) { + expected_wstr[pos] = ulong2str[0].Buffer[pos]; + } /* for */ + expected_wstr[LARGE_STRI_BUFFER_LENGTH] = '\0'; + result = p_ui64tow(ulong2str[0].value, NULL, 10); + ok(result == NULL, + "(test e): _ui64tow(%llu, NULL, 10) has result %p, expected: NULL\n", + ulonglong2str[0].value, result); + } /* if */ +} + + +typedef struct { + const char *str; + LONG value; +} str2long_t; + +static const str2long_t str2long[] = { + { "1011101100", 1011101100 }, + { "1234567", 1234567 }, + { "-214", -214 }, + { "+214", 214 }, /* The + sign is allowed also */ + { "--214", 0 }, /* Do not accept more than one sign */ + { "-+214", 0 }, + { "++214", 0 }, + { "+-214", 0 }, + { "\00141", 0 }, /* not whitespace char 1 */ + { "\00242", 0 }, /* not whitespace char 2 */ + { "\00343", 0 }, /* not whitespace char 3 */ + { "\00444", 0 }, /* not whitespace char 4 */ + { "\00545", 0 }, /* not whitespace char 5 */ + { "\00646", 0 }, /* not whitespace char 6 */ + { "\00747", 0 }, /* not whitespace char 7 */ + { "\01050", 0 }, /* not whitespace char 8 */ + { "\01151", 51 }, /* is whitespace char 9 (tab) */ + { "\01252", 52 }, /* is whitespace char 10 (lf) */ + { "\01353", 53 }, /* is whitespace char 11 (vt) */ + { "\01454", 54 }, /* is whitespace char 12 (ff) */ + { "\01555", 55 }, /* is whitespace char 13 (cr) */ + { "\01656", 0 }, /* not whitespace char 14 */ + { "\01757", 0 }, /* not whitespace char 15 */ + { "\02060", 0 }, /* not whitespace char 16 */ + { "\02161", 0 }, /* not whitespace char 17 */ + { "\02262", 0 }, /* not whitespace char 18 */ + { "\02363", 0 }, /* not whitespace char 19 */ + { "\02464", 0 }, /* not whitespace char 20 */ + { "\02565", 0 }, /* not whitespace char 21 */ + { "\02666", 0 }, /* not whitespace char 22 */ + { "\02767", 0 }, /* not whitespace char 23 */ + { "\03070", 0 }, /* not whitespace char 24 */ + { "\03171", 0 }, /* not whitespace char 25 */ + { "\03272", 0 }, /* not whitespace char 26 */ + { "\03373", 0 }, /* not whitespace char 27 */ + { "\03474", 0 }, /* not whitespace char 28 */ + { "\03575", 0 }, /* not whitespace char 29 */ + { "\03676", 0 }, /* not whitespace char 30 */ + { "\03777", 0 }, /* not whitespace char 31 */ + { "\04080", 80 }, /* is whitespace char 32 (space) */ + { " \n \r \t214", 214 }, + { " \n \r \t+214", 214 }, /* Signs can be used after whitespace */ + { " \n \r \t-214", -214 }, + { "+214 0", 214 }, /* Space terminates the number */ + { " 214.01", 214 }, /* Decimal point not accepted */ + { " 214,01", 214 }, /* Decimal comma not accepted */ + { "f81", 0 }, + { "0x12345", 0 }, /* Hex not accepted */ + { "00x12345", 0 }, + { "0xx12345", 0 }, + { "1x34", 1 }, + { "-9999999999", -1410065407 }, /* Big negative integer */ + { "-2147483649", 2147483647 }, /* Too small to fit in 32 Bits */ + { "-2147483648", 0x80000000 }, /* Smallest negative integer */ + { "-2147483647", -2147483647 }, + { "-1", -1 }, + { "0", 0 }, + { "1", 1 }, + { "2147483646", 2147483646 }, + { "2147483647", 2147483647 }, /* Largest signed positive integer */ + { "2147483648", 2147483648UL }, /* Positive int equal to smallest negative int */ + { "2147483649", 2147483649UL }, + { "4294967294", 4294967294UL }, + { "4294967295", 4294967295UL }, /* Largest unsigned integer */ + { "4294967296", 0 }, /* Too big to fit in 32 Bits */ + { "9999999999", 1410065407 }, /* Big positive integer */ + { "056789", 56789 }, /* Leading zero and still decimal */ + { "b1011101100", 0 }, /* Binary (b-notation) */ + { "-b1011101100", 0 }, /* Negative Binary (b-notation) */ + { "b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */ + { "0b1011101100", 0 }, /* Binary (0b-notation) */ + { "-0b1011101100", 0 }, /* Negative binary (0b-notation) */ + { "0b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */ + { "-0b10123456789", 0 }, /* Negative binary with nonbinary digits (2-9) */ + { "0b1", 0 }, /* one digit binary */ + { "0b2", 0 }, /* empty binary */ + { "0b", 0 }, /* empty binary */ + { "o1234567", 0 }, /* Octal (o-notation) */ + { "-o1234567", 0 }, /* Negative Octal (o-notation) */ + { "o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */ + { "0o1234567", 0 }, /* Octal (0o-notation) */ + { "-0o1234567", 0 }, /* Negative octal (0o-notation) */ + { "0o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */ + { "-0o56789", 0 }, /* Negative octal with nonoctal digits (8 and 9) */ + { "0o7", 0 }, /* one digit octal */ + { "0o8", 0 }, /* empty octal */ + { "0o", 0 }, /* empty octal */ + { "0d1011101100", 0 }, /* explizit decimal with 0d */ + { "x89abcdef", 0 }, /* Hex with lower case digits a-f (x-notation) */ + { "xFEDCBA00", 0 }, /* Hex with upper case digits A-F (x-notation) */ + { "-xFEDCBA00", 0 }, /* Negative Hexadecimal (x-notation) */ + { "0x89abcdef", 0 }, /* Hex with lower case digits a-f (0x-notation) */ + { "0xFEDCBA00", 0 }, /* Hex with upper case digits A-F (0x-notation) */ + { "-0xFEDCBA00", 0 }, /* Negative Hexadecimal (0x-notation) */ + { "0xabcdefgh", 0 }, /* Hex with illegal lower case digits (g-z) */ + { "0xABCDEFGH", 0 }, /* Hex with illegal upper case digits (G-Z) */ + { "0xF", 0 }, /* one digit hexadecimal */ + { "0xG", 0 }, /* empty hexadecimal */ + { "0x", 0 }, /* empty hexadecimal */ + { "", 0 }, /* empty string */ +/* { NULL, 0 }, */ /* NULL as string */ +}; +#define NB_STR2LONG (sizeof(str2long)/sizeof(*str2long)) + + +static void test_wtoi(void) +{ + int test_num; + UNICODE_STRING uni; + int result; + + for (test_num = 0; test_num < NB_STR2LONG; test_num++) { + pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str); + result = p_wtoi(uni.Buffer); + ok(result == str2long[test_num].value, + "(test %d): call failed: _wtoi(\"%s\") has result %d, expected: %ld\n", + test_num, str2long[test_num].str, result, str2long[test_num].value); + pRtlFreeUnicodeString(&uni); + } /* for */ +} + + +static void test_wtol(void) +{ + int test_num; + UNICODE_STRING uni; + LONG result; + + for (test_num = 0; test_num < NB_STR2LONG; test_num++) { + pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str); + result = p_wtol(uni.Buffer); + ok(result == str2long[test_num].value, + "(test %d): call failed: _wtol(\"%s\") has result %ld, expected: %ld\n", + test_num, str2long[test_num].str, result, str2long[test_num].value); + pRtlFreeUnicodeString(&uni); + } /* for */ +} + + +typedef struct { + const char *str; + LONGLONG value; +} str2longlong_t; + +static const str2longlong_t str2longlong[] = { + { "1011101100", 1011101100 }, + { "1234567", 1234567 }, + { "-214", -214 }, + { "+214", 214 }, /* The + sign is allowed also */ + { "--214", 0 }, /* Do not accept more than one sign */ + { "-+214", 0 }, + { "++214", 0 }, + { "+-214", 0 }, + { "\00141", 0 }, /* not whitespace char 1 */ + { "\00242", 0 }, /* not whitespace char 2 */ + { "\00343", 0 }, /* not whitespace char 3 */ + { "\00444", 0 }, /* not whitespace char 4 */ + { "\00545", 0 }, /* not whitespace char 5 */ + { "\00646", 0 }, /* not whitespace char 6 */ + { "\00747", 0 }, /* not whitespace char 7 */ + { "\01050", 0 }, /* not whitespace char 8 */ + { "\01151", 51 }, /* is whitespace char 9 (tab) */ + { "\01252", 52 }, /* is whitespace char 10 (lf) */ + { "\01353", 53 }, /* is whitespace char 11 (vt) */ + { "\01454", 54 }, /* is whitespace char 12 (ff) */ + { "\01555", 55 }, /* is whitespace char 13 (cr) */ + { "\01656", 0 }, /* not whitespace char 14 */ + { "\01757", 0 }, /* not whitespace char 15 */ + { "\02060", 0 }, /* not whitespace char 16 */ + { "\02161", 0 }, /* not whitespace char 17 */ + { "\02262", 0 }, /* not whitespace char 18 */ + { "\02363", 0 }, /* not whitespace char 19 */ + { "\02464", 0 }, /* not whitespace char 20 */ + { "\02565", 0 }, /* not whitespace char 21 */ + { "\02666", 0 }, /* not whitespace char 22 */ + { "\02767", 0 }, /* not whitespace char 23 */ + { "\03070", 0 }, /* not whitespace char 24 */ + { "\03171", 0 }, /* not whitespace char 25 */ + { "\03272", 0 }, /* not whitespace char 26 */ + { "\03373", 0 }, /* not whitespace char 27 */ + { "\03474", 0 }, /* not whitespace char 28 */ + { "\03575", 0 }, /* not whitespace char 29 */ + { "\03676", 0 }, /* not whitespace char 30 */ + { "\03777", 0 }, /* not whitespace char 31 */ + { "\04080", 80 }, /* is whitespace char 32 (space) */ + { " \n \r \t214", 214 }, + { " \n \r \t+214", 214 }, /* Signs can be used after whitespace */ + { " \n \r \t-214", -214 }, + { "+214 0", 214 }, /* Space terminates the number */ + { " 214.01", 214 }, /* Decimal point not accepted */ + { " 214,01", 214 }, /* Decimal comma not accepted */ + { "f81", 0 }, + { "0x12345", 0 }, /* Hex not accepted */ + { "00x12345", 0 }, + { "0xx12345", 0 }, + { "1x34", 1 }, + { "-99999999999999999999", -ULL(0x6bc75e2d,0x630fffff) }, /* Big negative integer */ + { "-9223372036854775809", ULL(0x7fffffff,0xffffffff) }, /* Too small to fit in 64 bits */ + { "-9223372036854775808", ULL(0x80000000,0x00000000) }, /* Smallest negative 64 bit integer */ + { "-9223372036854775807", -ULL(0x7fffffff,0xffffffff) }, + { "-9999999999", -ULL(0x00000002,0x540be3ff) }, + { "-2147483649", -ULL(0x00000000,0x80000001) }, /* Too small to fit in 32 bits */ + { "-2147483648", -ULL(0x00000000,0x80000000) }, /* Smallest 32 bits negative integer */ + { "-2147483647", -2147483647 }, + { "-1", -1 }, + { "0", 0 }, + { "1", 1 }, + { "2147483646", 2147483646 }, + { "2147483647", 2147483647 }, /* Largest signed positive 32 bit integer */ + { "2147483648", ULL(0x00000000,0x80000000) }, /* Pos int equal to smallest neg 32 bit int */ + { "2147483649", ULL(0x00000000,0x80000001) }, + { "4294967294", ULL(0x00000000,0xfffffffe) }, + { "4294967295", ULL(0x00000000,0xffffffff) }, /* Largest unsigned 32 bit integer */ + { "4294967296", ULL(0x00000001,0x00000000) }, /* Too big to fit in 32 Bits */ + { "9999999999", ULL(0x00000002,0x540be3ff) }, + { "9223372036854775806", ULL(0x7fffffff,0xfffffffe) }, + { "9223372036854775807", ULL(0x7fffffff,0xffffffff) }, /* Largest signed positive 64 bit integer */ + { "9223372036854775808", ULL(0x80000000,0x00000000) }, /* Pos int equal to smallest neg 64 bit int */ + { "9223372036854775809", ULL(0x80000000,0x00000001) }, + { "18446744073709551614", ULL(0xffffffff,0xfffffffe) }, + { "18446744073709551615", ULL(0xffffffff,0xffffffff) }, /* Largest unsigned 64 bit integer */ + { "18446744073709551616", 0 }, /* Too big to fit in 64 bits */ + { "99999999999999999999", ULL(0x6bc75e2d,0x630fffff) }, /* Big positive integer */ + { "056789", 56789 }, /* Leading zero and still decimal */ + { "b1011101100", 0 }, /* Binary (b-notation) */ + { "-b1011101100", 0 }, /* Negative Binary (b-notation) */ + { "b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */ + { "0b1011101100", 0 }, /* Binary (0b-notation) */ + { "-0b1011101100", 0 }, /* Negative binary (0b-notation) */ + { "0b10123456789", 0 }, /* Binary with nonbinary digits (2-9) */ + { "-0b10123456789", 0 }, /* Negative binary with nonbinary digits (2-9) */ + { "0b1", 0 }, /* one digit binary */ + { "0b2", 0 }, /* empty binary */ + { "0b", 0 }, /* empty binary */ + { "o1234567", 0 }, /* Octal (o-notation) */ + { "-o1234567", 0 }, /* Negative Octal (o-notation) */ + { "o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */ + { "0o1234567", 0 }, /* Octal (0o-notation) */ + { "-0o1234567", 0 }, /* Negative octal (0o-notation) */ + { "0o56789", 0 }, /* Octal with nonoctal digits (8 and 9) */ + { "-0o56789", 0 }, /* Negative octal with nonoctal digits (8 and 9) */ + { "0o7", 0 }, /* one digit octal */ + { "0o8", 0 }, /* empty octal */ + { "0o", 0 }, /* empty octal */ + { "0d1011101100", 0 }, /* explizit decimal with 0d */ + { "x89abcdef", 0 }, /* Hex with lower case digits a-f (x-notation) */ + { "xFEDCBA00", 0 }, /* Hex with upper case digits A-F (x-notation) */ + { "-xFEDCBA00", 0 }, /* Negative Hexadecimal (x-notation) */ + { "0x89abcdef", 0 }, /* Hex with lower case digits a-f (0x-notation) */ + { "0xFEDCBA00", 0 }, /* Hex with upper case digits A-F (0x-notation) */ + { "-0xFEDCBA00", 0 }, /* Negative Hexadecimal (0x-notation) */ + { "0xabcdefgh", 0 }, /* Hex with illegal lower case digits (g-z) */ + { "0xABCDEFGH", 0 }, /* Hex with illegal upper case digits (G-Z) */ + { "0xF", 0 }, /* one digit hexadecimal */ + { "0xG", 0 }, /* empty hexadecimal */ + { "0x", 0 }, /* empty hexadecimal */ + { "", 0 }, /* empty string */ +/* { NULL, 0 }, */ /* NULL as string */ +}; +#define NB_STR2LONGLONG (sizeof(str2longlong)/sizeof(*str2longlong)) + + +static void test_atoi64(void) +{ + int test_num; + LONGLONG result; + + for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) { + result = p_atoi64(str2longlong[test_num].str); + ok(result == str2longlong[test_num].value, + "(test %d): call failed: _atoi64(\"%s\") has result %lld, expected: %lld\n", + test_num, str2longlong[test_num].str, result, str2longlong[test_num].value); + } /* for */ +} + + +static void test_wtoi64(void) +{ + int test_num; + UNICODE_STRING uni; + LONGLONG result; + + for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) { + pRtlCreateUnicodeStringFromAsciiz(&uni, str2longlong[test_num].str); + result = p_wtoi64(uni.Buffer); + ok(result == str2longlong[test_num].value, + "(test %d): call failed: _wtoi64(\"%s\") has result %lld, expected: %lld\n", + test_num, str2longlong[test_num].str, result, str2longlong[test_num].value); + pRtlFreeUnicodeString(&uni); + } /* for */ +} + +static void test_wcsfuncs(void) +{ + static const WCHAR testing[] = {'T','e','s','t','i','n','g',0}; + ok (p_wcschr(testing,0)!=NULL, "wcschr Not finding terminating character\n"); + ok (p_wcsrchr(testing,0)!=NULL, "wcsrchr Not finding terminating character\n"); +} + +START_TEST(string) +{ + InitFunctionPtrs(); + + if (p_ultoa) + test_ulongtoa(); + if (p_ui64toa) + test_ulonglongtoa(); + if (p_atoi64) + test_atoi64(); + if (p_ultow) + test_ulongtow(); + if (p_ui64tow) + test_ulonglongtow(); + if (p_wtoi) + test_wtoi(); + if (p_wtol) + test_wtol(); + if (p_wtoi64) + test_wtoi64(); + if (p_wcschr && p_wcsrchr) + test_wcsfuncs(); +} diff --git a/reactos/regtests/winetests/ntdll/testlist.c b/reactos/regtests/winetests/ntdll/testlist.c new file mode 100644 index 00000000000..92b62716921 --- /dev/null +++ b/reactos/regtests/winetests/ntdll/testlist.c @@ -0,0 +1,49 @@ +/* Automatically generated file; DO NOT EDIT!! */ + +#include +#include +#include +#include "windef.h" +#include "winbase.h" +#include + +extern void func_atom(void); +extern void func_env(void); +extern void func_error(void); +extern void func_info(void); +extern void func_large_int(void); +extern void func_path(void); +extern void func_reg(void); +extern void func_rtl(void); +extern void func_rtlbitmap(void); +extern void func_rtlstr(void); +extern void func_string(void); +extern void func_time(void); + +struct test +{ + const char *name; + void (*func)(void); +}; + + +const struct test winetest_testlist[] = +{ + { "atom", func_atom }, + { "env", func_env }, + { "error", func_error }, + { "info", func_info }, + { "large_int", func_large_int }, + { "path", func_path }, + { "reg", func_reg }, + { "rtl", func_rtl }, + { "rtlbitmap", func_rtlbitmap }, + { "rtlstr", func_rtlstr }, + { "string", func_string }, + { "time", func_time }, + { 0, 0 } +}; + +#define WINETEST_WANT_MAIN +#include "wine/test.h" + diff --git a/reactos/regtests/winetests/ntdll/time.c b/reactos/regtests/winetests/ntdll/time.c new file mode 100755 index 00000000000..5e1070ddc1b --- /dev/null +++ b/reactos/regtests/winetests/ntdll/time.c @@ -0,0 +1,109 @@ +/* + * Unit test suite for ntdll time functions + * + * Copyright 2004 Rein Klazes + * + * 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 + */ + +#include "ntdll_test.h" + +#ifdef __WINE_WINTERNL_H + +#define TICKSPERSEC 10000000 +#define TICKSPERMSEC 10000 +#define SECSPERDAY 86400 + +static VOID (WINAPI *pRtlTimeToTimeFields)( const LARGE_INTEGER *liTime, PTIME_FIELDS TimeFields) ; +static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_INTEGER Time) ; + +static const int MonthLengths[2][12] = +{ + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static inline int IsLeapYear(int Year) +{ + return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0; +} + +/* start time of the tests */ +TIME_FIELDS tftest = {1889,12,31,23,59,59,0,0}; + +static void test_pRtlTimeToTimeFields() +{ + LARGE_INTEGER litime , liresult; + TIME_FIELDS tfresult; + int i=0; + litime.QuadPart = ((ULONGLONG)0x0144017a << 32) | 0xf0b0a980; + while( tftest.Year < 2110 ) { + /* test at the last second of the month */ + pRtlTimeToTimeFields( &litime, &tfresult); + ok( tfresult.Year == tftest.Year && tfresult.Month == tftest.Month && + tfresult.Day == tftest.Day && tfresult.Hour == tftest.Hour && + tfresult.Minute == tftest.Minute && tfresult.Second == tftest.Second, + "#%d expected: %d-%d-%d %d:%d:%d got: %d-%d-%d %d:%d:%d\n", ++i, + tftest.Year, tftest.Month, tftest.Day, + tftest.Hour, tftest.Minute,tftest.Second, + tfresult.Year, tfresult.Month, tfresult.Day, + tfresult.Hour, tfresult.Minute, tfresult.Second); + /* test the inverse */ + pRtlTimeFieldsToTime( &tfresult, &liresult); + ok( liresult.QuadPart == litime.QuadPart," TimeFieldsToTime failed on %d-%d-%d %d:%d:%d. Error is %d ticks\n", + tfresult.Year, tfresult.Month, tfresult.Day, + tfresult.Hour, tfresult.Minute, tfresult.Second, + (int) (liresult.QuadPart - litime.QuadPart) ); + /* one second later is beginning of next month */ + litime.QuadPart += TICKSPERSEC ; + pRtlTimeToTimeFields( &litime, &tfresult); + ok( tfresult.Year == tftest.Year + (tftest.Month ==12) && + tfresult.Month == tftest.Month % 12 + 1 && + tfresult.Day == 1 && tfresult.Hour == 0 && + tfresult.Minute == 0 && tfresult.Second == 0, + "#%d expected: %d-%d-%d %d:%d:%d got: %d-%d-%d %d:%d:%d\n", ++i, + tftest.Year + (tftest.Month ==12), + tftest.Month % 12 + 1, 1, 0, 0, 0, + tfresult.Year, tfresult.Month, tfresult.Day, + tfresult.Hour, tfresult.Minute, tfresult.Second); + /* test the inverse */ + pRtlTimeFieldsToTime( &tfresult, &liresult); + ok( liresult.QuadPart == litime.QuadPart," TimeFieldsToTime failed on %d-%d-%d %d:%d:%d. Error is %d ticks\n", + tfresult.Year, tfresult.Month, tfresult.Day, + tfresult.Hour, tfresult.Minute, tfresult.Second, + (int) (liresult.QuadPart - litime.QuadPart) ); + /* advance to the end of the month */ + litime.QuadPart -= TICKSPERSEC ; + if( tftest.Month == 12) { + tftest.Month = 1; + tftest.Year += 1; + } else + tftest.Month += 1; + tftest.Day = MonthLengths[IsLeapYear(tftest.Year)][tftest.Month - 1]; + litime.QuadPart += (LONGLONG) tftest.Day * TICKSPERSEC * SECSPERDAY; + } +} +#endif + +START_TEST(time) +{ +#ifdef __WINE_WINTERNL_H + HMODULE mod = GetModuleHandleA("ntdll.dll"); + pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields"); + pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime"); + if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime) + test_pRtlTimeToTimeFields(); +#endif +}