ntdll pending some winerror.h fixes
authorSteven Edwards <winehacker@gmail.com>
Sun, 7 Aug 2005 02:16:34 +0000 (02:16 +0000)
committerSteven Edwards <winehacker@gmail.com>
Sun, 7 Aug 2005 02:16:34 +0000 (02:16 +0000)
svn path=/trunk/; revision=17133

16 files changed:
reactos/regtests/winetests/ntdll/atom.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/env.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/error.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/generated.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/info.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/large_int.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/ntdll_test.h [new file with mode: 0755]
reactos/regtests/winetests/ntdll/ntdll_test.xml [new file with mode: 0644]
reactos/regtests/winetests/ntdll/path.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/reg.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/rtl.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/rtlbitmap.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/rtlstr.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/string.c [new file with mode: 0755]
reactos/regtests/winetests/ntdll/testlist.c [new file with mode: 0644]
reactos/regtests/winetests/ntdll/time.c [new file with mode: 0755]

diff --git a/reactos/regtests/winetests/ntdll/atom.c b/reactos/regtests/winetests/ntdll/atom.c
new file mode 100755 (executable)
index 0000000..e008fb6
--- /dev/null
@@ -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 <stdio.h>
+#include <stdarg.h>
+#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 (executable)
index 0000000..ec88957
--- /dev/null
@@ -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 <stdio.h>
+
+#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 (executable)
index 0000000..a912d55
--- /dev/null
@@ -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 <stdarg.h>
+#include <stdio.h>
+
+#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 (executable)
index 0000000..6ac1749
--- /dev/null
@@ -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 (executable)
index 0000000..5992712
--- /dev/null
@@ -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 (executable)
index 0000000..006fda4
--- /dev/null
@@ -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 <stdlib.h>
+
+#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 (executable)
index 0000000..d083729
--- /dev/null
@@ -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 <stdarg.h>
+
+#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 (file)
index 0000000..f8a2925
--- /dev/null
@@ -0,0 +1,18 @@
+<module name="ntdll_test" type="win32cui" installbase="bin" installname="ntdll_test.exe" warnings="true">
+    <include base="ntdll_test">.</include>
+    <define name="__USE_W32API" />
+    <library>ntdll</library>
+    <file>atom.c</file>
+    <file>env.c</file>
+    <file>error.c</file>
+    <file>info.c</file>
+    <file>large_int.c</file>
+    <file>path.c</file>
+    <file>reg.c</file>
+    <file>rtlbitmap.c</file>
+    <file>rtl.c</file>
+    <file>rtlstr.c</file>
+    <file>string.c</file>
+    <file>time.c</file>
+    <file>testlist.c</file>
+</module>
diff --git a/reactos/regtests/winetests/ntdll/path.c b/reactos/regtests/winetests/ntdll/path.c
new file mode 100755 (executable)
index 0000000..d8ba775
--- /dev/null
@@ -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 (executable)
index 0000000..d71e164
--- /dev/null
@@ -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 (executable)
index 0000000..8e31032
--- /dev/null
@@ -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 <stdlib.h>
+
+#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 (executable)
index 0000000..3ab1157
--- /dev/null
@@ -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 (executable)
index 0000000..63346c7
--- /dev/null
@@ -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 <stdlib.h>
+
+#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 (executable)
index 0000000..f7cc799
--- /dev/null
@@ -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 <stdlib.h>
+
+#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 (file)
index 0000000..92b6271
--- /dev/null
@@ -0,0 +1,49 @@
+/* Automatically generated file; DO NOT EDIT!! */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "windef.h"
+#include "winbase.h"
+#include <windows.h>
+
+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 (executable)
index 0000000..5e1070d
--- /dev/null
@@ -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
+}