[NTDLL_WINETEST] Sync to wine-10.0

Co-authored-by: Carl J. Bialorucki <[email protected]>
This commit is contained in:
Timo Kreuzer
2026-05-05 07:44:54 +00:00
co-authored by Carl J. Bialorucki
parent ed173870e8
commit 35bd6f97b5
31 changed files with 39403 additions and 7848 deletions
@@ -1,7 +1,15 @@
include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/wine)
remove_definitions(-D_CRT_NON_CONFORMING_SWPRINTFS)
add_definitions(-D__WINESRC__ -DWINETEST_USE_DBGSTR_LONGLONG)
remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502)
add_definitions(-D_WIN32_WINNT=0x601)
if(_WINKD_)
add_definitions(-D_WINKD_)
endif()
list(APPEND SOURCE
atom.c
change.c
@@ -10,25 +18,31 @@ list(APPEND SOURCE
error.c
exception.c
file.c
generated.c
info.c
large_int.c
om.c
path.c
pipe.c
port.c
process.c
reg.c
rtl.c
rtlbitmap.c
rtlstr.c
string.c
sync.c
testlist.c
thread.c
threadpool.c
time.c)
time.c
unwind.c
virtual.c
wow64.c
)
if(ARCH STREQUAL "i386")
list(APPEND SOURCE
generated.c)
if(MSVC AND ARCH STREQUAL "amd64")
add_asm_files(ntdll_winetest_asm msvc-x64.asm)
list(APPEND SOURCE ${ntdll_winetest_asm})
endif()
add_executable(ntdll_winetest
@@ -36,15 +50,23 @@ add_executable(ntdll_winetest
target_link_libraries(ntdll_winetest pseh)
if(MSVC AND ARCH STREQUAL "amd64")
# warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
target_compile_options(ntdll_winetest PRIVATE /wd4334)
if(MSVC)
target_compile_options(ntdll_winetest PRIVATE
/wd4024 # warning C4024: 'function': different types for formal and actual parameter 1
/wd4047 # warning C4047: 'function': 'type' differs in levels of indirection from 'type'
/wd4101 # warning C4101: 'variable': unreferenced local variable
/wd4319 # warning C4319: '~': zero extending 'unsigned int' to 'UINT_PTR' of greater size
/wd4334 # warning C4334: '<<': result of 32-bit shift implicitly converted to 64 bits (was 64-bit shift intended?)
)
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_compile_options(ntdll_winetest PRIVATE "-Wno-format")
target_compile_options(ntdll_winetest PRIVATE "-Wno-int-conversion")
target_compile_options(ntdll_winetest PRIVATE "-Wno-unused-variable")
endif()
set_module_type(ntdll_winetest win32cui)
add_importlibs(ntdll_winetest user32 ole32 advapi32 msvcrt kernel32 ntdll)
add_rostests_file(TARGET ntdll_winetest)
target_compile_definitions(ntdll_winetest PRIVATE wcsnicmp=_wcsnicmp)
+94 -92
View File
@@ -100,30 +100,30 @@ static DWORD WINAPI RtlAtomTestThread(LPVOID Table)
WCHAR Name[64];
res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &Atom);
ok(!res, "Unable to find atom from another thread, retval: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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 long enough buffer, retval: %x\n", res);
ok(RefCount == 1, "Refcount was not 1 but %x\n", RefCount);
ok(PinCount == 1, "Pincount was not 1 but %x\n", PinCount);
ok(!res, "Failed with long enough 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(!lstrcmpW(Name, testAtom2), "We found wrong atom!!\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
ok((lstrlenW(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: %x\n", res);
ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %lx\n", res);
ok(!lstrcmpW(Name, testAtom2), "Found Wrong atom!\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
res = pRtlPinAtomInAtomTable(AtomTable, Atom);
ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
return 0;
}
@@ -145,37 +145,39 @@ static void test_NtAtom(void)
if (!res)
{
res = pRtlDestroyAtomTable(AtomTable);
ok(!res, "We could create the atom table, but we couldn't destroy it! retval: %x\n", res);
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: %x\n", res);
ok(!res, "We're unable to create an atom table with a valid table size retval: %lx\n", res);
if (!res)
{
ok( *(DWORD *)AtomTable == 0x6d6f7441, "wrong signature %lx\n", *(DWORD *)AtomTable );
res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
ok(!res, "We were unable to add a simple atom to the atom table, retval: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);
testThread = CreateThread(NULL, 0, RtlAtomTestThread, &AtomTable, 0, NULL);
WaitForSingleObject(testThread, INFINITE);
@@ -183,28 +185,28 @@ static void test_NtAtom(void)
Len = 64;
res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
ok(!res, "Unable to query atom in atom table, retval: %x\n", res);
ok(RefCount == 1, "RefCount is not 1 but %x\n", RefCount);
ok(PinCount == 1, "PinCount is not 1 but %x\n", PinCount);
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(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
res = pRtlEmptyAtomTable(AtomTable, FALSE);
ok(!res, "Unable to empty atom table, retval %x\n", res);
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: %x\n", res);
ok(RefCount == 1, "RefCount is not 1 but %x\n", RefCount);
ok(PinCount == 1, "PinCount is not 1 but %x\n", PinCount);
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(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %d\n", Len);
ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);
Len = 8;
Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x1337;
res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, NULL, NULL, Name, &Len);
ok(!res, "query atom %x\n", res);
ok(Len == 6, "wrong length %u\n", Len);
ok(!res, "query atom %lx\n", res);
ok(Len == 6, "wrong length %lu\n", Len);
ok(!memcmp(Name, testAtom2, Len), "wrong atom string\n");
ok(!Name[3], "wrong string termination\n");
ok(Name[4] == 0x1337, "buffer overwrite\n");
@@ -212,75 +214,75 @@ static void test_NtAtom(void)
Len = lstrlenW(testAtom2) * sizeof(WCHAR);
memset(Name, '.', sizeof(Name));
res = pRtlQueryAtomInAtomTable( AtomTable, Atom2, NULL, NULL, Name, &Len );
ok(!res, "query atom %x\n", res);
ok(Len == (lstrlenW(testAtom2) - 1) * sizeof(WCHAR), "wrong length %u\n", Len);
ok(!res, "query atom %lx\n", res);
ok(Len == (lstrlenW(testAtom2) - 1) * sizeof(WCHAR), "wrong length %lu\n", Len);
ok(!memcmp(testAtom2, Name, (lstrlenW(testAtom2) - 1) * sizeof(WCHAR)), "wrong atom name\n");
ok(Name[lstrlenW(testAtom2) - 1] == '\0', "wrong char\n");
ok(Name[lstrlenW(testAtom2)] == ('.' << 8) + '.', "wrong char\n");
res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
ok(!res, "We can't find our pinned atom!! retval: %x\n", res);
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: %x\n", res);
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: %x\n", res);
ok(!res, "Unable to add atom to table, retval: %lx\n", res);
res = pRtlEmptyAtomTable(AtomTable, TRUE);
ok(!res, "Unable to empty atom table, retval: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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 %x\n", res);
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: %x\n", res);
ok(testAtom == Atom1, "Found wrong atom! retval: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len || broken(!Len) /* nt4 */, "Got wrong length %x\n", Len);
ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %lx\n", res);
ok((lstrlenW(testAtom1) * sizeof(WCHAR)) == Len || broken(!Len) /* nt4 */, "Got wrong length %lx\n", Len);
if (!Len) pNtAddAtomNT4 = (void *)pNtAddAtom;
res = pRtlPinAtomInAtomTable(AtomTable, Atom1);
ok(!res, "Unable to pin atom in atom table, retval: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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");
@@ -303,82 +305,82 @@ static void test_NtIntAtom(void)
AtomTable = NULL;
res = pRtlCreateAtomTable(37, &AtomTable);
ok(!res, "Unable to create atom table, %x\n", res);
ok(!res, "Unable to create atom table, %lx\n", res);
if (!res)
{
/* According to the kernel32 functions, integer atoms are only allowed from
* 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */
res = pRtlAddAtomToAtomTable(AtomTable, NULL, &testAtom);
ok(res == STATUS_INVALID_PARAMETER, "Didn't get expected result from adding 0 int atom, retval: %x\n", res);
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, (LPWSTR)i, &testAtom);
ok(!res, "Unable to add valid integer atom %li, retval: %x\n", i, res);
ok(!res, "Unable to add valid integer atom %Ii, retval: %lx\n", i, res);
}
for (i = 1; i <= 0xbfff; i++)
{
res = pRtlLookupAtomInAtomTable(AtomTable, (LPWSTR)i, &testAtom);
ok(!res, "Unable to find int atom %li, retval: %x\n", i, res);
ok(!res, "Unable to find int atom %Ii, retval: %lx\n", i, res);
if (!res)
{
res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
ok(!res, "Unable to pin int atom %li, retval: %x\n", i, res);
ok(!res, "Unable to pin int atom %Ii, retval: %lx\n", i, res);
}
}
for (i = 0xc000; i <= 0xffff; i++)
{
res = pRtlAddAtomToAtomTable(AtomTable, (LPWSTR)i, &testAtom);
ok(res, "Able to illeageal integer atom %li, retval: %x\n", i, res);
ok(res, "Able to illeageal integer atom %Ii, retval: %lx\n", i, res);
}
res = pRtlDestroyAtomTable(AtomTable);
ok(!res, "Unable to destroy atom table, retval: %x\n", res);
ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
}
AtomTable = NULL;
res = pRtlCreateAtomTable(37, &AtomTable);
ok(!res, "Unable to create atom table, %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
ok(RefCount == 1, "Expected refcount 1 but got %x\n", RefCount);
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(!lstrcmpW(testAtomOTT, Name), "Got wrong atom name\n");
ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %d\n", Len);
ok((lstrlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len);
res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
ok(!res, "Unable to pin int atom, retval: %x\n", res);
ok(!res, "Unable to pin int atom, retval: %lx\n", res);
res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
ok(!res, "Unable to pin int atom, retval: %x\n", res);
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: %x\n", res);
ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
ok(RefCount == 1, "Expected refcount 1 but got %x\n", RefCount);
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: %x\n", res);
ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
}
}
@@ -392,40 +394,40 @@ static void test_NtRefPinAtom(void)
AtomTable = NULL;
res = pRtlCreateAtomTable(37, &AtomTable);
ok(!res, "Unable to create atom table, %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
ok(PinCount == 0, "Expected pincount 0 but got %x\n", PinCount);
ok(RefCount == 3, "Expected refcount 3 but got %x\n", RefCount);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
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: %x\n", res);
ok(PinCount == 1, "Expected pincount 1 but got %x\n", PinCount);
ok(RefCount == 3, "Expected refcount 3 but got %x\n", RefCount);
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: %x\n", res);
ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
}
}
@@ -442,7 +444,7 @@ static void test_Global(void)
else
res = pNtAddAtom(testAtom1, lstrlenW(testAtom1) * sizeof(WCHAR), &atom);
ok(!res, "Added atom (%x)\n", res);
ok(!res, "Added atom (%lx)\n", res);
memset( ptr, 0xcc, sizeof(ptr) );
res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
@@ -454,14 +456,14 @@ static void test_Global(void)
ptr_size = sizeof(ATOM_BASIC_INFORMATION);
res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
ok(res == STATUS_BUFFER_TOO_SMALL, "wrong return status (%x)\n", res);
ok(res == STATUS_BUFFER_TOO_SMALL, "wrong return status (%lx)\n", res);
ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR) || broken(abi->NameLength == sizeof(WCHAR)), /* nt4 */
"string length %u\n",abi->NameLength);
memset( ptr, 0xcc, sizeof(ptr) );
ptr_size = sizeof(ATOM_BASIC_INFORMATION) + lstrlenW(testAtom1) * sizeof(WCHAR);
res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
ok(!res, "atom lookup %x\n", res);
ok(!res, "atom lookup %lx\n", res);
ok(!lstrcmpW(abi->Name, testAtom1), "strings don't match\n");
ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
ok(abi->Name[lstrlenW(testAtom1)] == 0, "buffer overwrite %x\n", abi->Name[lstrlenW(testAtom1)]);
+34 -27
View File
@@ -86,15 +86,15 @@ static void test_ntncdf(void)
filter |= FILE_NOTIFY_CHANGE_CREATION;
filter |= FILE_NOTIFY_CHANGE_SECURITY;
U(iosb).Status = 1;
iosb.Status = 1;
iosb.Information = 1;
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,-1,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
ok( U(iosb).Status == 1, "information wrong\n");
ok( iosb.Status == 1, "information wrong\n");
ok( iosb.Information == 1, "information wrong\n");
U(iosb).Status = 1;
iosb.Status = 1;
iosb.Information = 0;
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should return status pending\n");
@@ -114,7 +114,7 @@ static void test_ntncdf(void)
r = WaitForSingleObject( hEvent, 100 );
ok( r == WAIT_OBJECT_0, "event should be ready\n" );
ok( U(iosb).Status == STATUS_SUCCESS, "information wrong\n");
ok( iosb.Status == STATUS_SUCCESS, "information wrong\n");
ok( iosb.Information == 0x12, "information wrong\n");
pfni = (PFILE_NOTIFY_INFORMATION) buffer;
@@ -131,12 +131,12 @@ static void test_ntncdf(void)
filter = FILE_NOTIFY_CHANGE_SIZE;
U(iosb).Status = 1;
iosb.Status = 1;
iosb.Information = 1;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
ok( U(iosb).Status == 1, "information wrong\n");
ok( iosb.Status == 1, "information wrong\n");
ok( iosb.Information == 1, "information wrong\n");
r = WaitForSingleObject( hdir, 0 );
@@ -151,7 +151,7 @@ static void test_ntncdf(void)
r = WaitForSingleObject( hdir, 100 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok( U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "information wrong\n");
ok( iosb.Status == STATUS_NOTIFY_ENUM_DIR, "information wrong\n");
ok( iosb.Information == 0, "information wrong\n");
CloseHandle(hdir);
@@ -168,7 +168,7 @@ static void test_ntncdf_async(void)
HANDLE hdir, hEvent;
char buffer[0x1000];
DWORD fflags, filter = 0;
IO_STATUS_BLOCK iosb, iosb2;
IO_STATUS_BLOCK iosb, iosb2, iosb3;
WCHAR path[MAX_PATH], subdir[MAX_PATH];
static const WCHAR szBoo[] = { '\\','b','o','o',0 };
static const WCHAR szHoo[] = { '\\','h','o','o',0 };
@@ -209,11 +209,11 @@ static void test_ntncdf_async(void)
filter |= FILE_NOTIFY_CHANGE_SECURITY;
U(iosb).Status = 0x01234567;
iosb.Status = 0x01234567;
iosb.Information = 0x12345678;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
ok(U(iosb).Status == 0x01234567, "status set too soon\n");
ok(iosb.Status == 0x01234567, "status set too soon\n");
ok(iosb.Information == 0x12345678, "info set too soon\n");
r = CreateDirectoryW( subdir, NULL );
@@ -222,7 +222,7 @@ static void test_ntncdf_async(void)
r = WaitForSingleObject( hdir, 100 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Information == 0x12, "info not set\n");
pfni = (PFILE_NOTIFY_INFORMATION) buffer;
@@ -240,7 +240,7 @@ static void test_ntncdf_async(void)
r = WaitForSingleObject( hdir, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Information == 0x12, "info not set\n");
ok( pfni->NextEntryOffset == 0, "offset wrong\n" );
@@ -249,7 +249,7 @@ static void test_ntncdf_async(void)
ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
/* check APCs */
U(iosb).Status = 0;
iosb.Status = 0;
iosb.Information = 0;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,NULL,0,filter,0);
@@ -261,10 +261,10 @@ static void test_ntncdf_async(void)
r = WaitForSingleObject( hdir, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_NOTIFY_ENUM_DIR, "status not successful\n");
ok(iosb.Status == STATUS_NOTIFY_ENUM_DIR, "status not successful\n");
ok(iosb.Information == 0, "info not set\n");
U(iosb).Status = 0;
iosb.Status = 0;
iosb.Information = 0;
r = pNtNotifyChangeDirectoryFile(hdir,hEvent,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
@@ -276,33 +276,45 @@ static void test_ntncdf_async(void)
r = WaitForSingleObject( hEvent, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n" );
ok(U(iosb).Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Status == STATUS_SUCCESS, "status not successful\n");
ok(iosb.Information == 0x12, "info not set\n");
U(iosb).Status = 0x01234567;
iosb.Status = 0x01234567;
iosb.Information = 0x12345678;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
U(iosb2).Status = 0x01234567;
iosb2.Status = 0x01234567;
iosb2.Information = 0x12345678;
r = pNtNotifyChangeDirectoryFile(hdir,0,NULL,NULL,&iosb2,buffer,sizeof buffer,filter,0);
ok(r==STATUS_PENDING, "should status pending\n");
ok(U(iosb).Status == 0x01234567, "status set too soon\n");
ok(iosb.Status == 0x01234567, "status set too soon\n");
ok(iosb.Information == 0x12345678, "info set too soon\n");
r = pNtCancelIoFile(hdir, &iosb);
iosb3.Status = 0x111111;
iosb3.Information = 0x222222;
r = pNtCancelIoFile(hdir, &iosb3);
ok( r == STATUS_SUCCESS, "cancel failed\n");
CloseHandle(hdir);
ok(U(iosb).Status == STATUS_SUCCESS, "status wrong\n");
ok(U(iosb2).Status == STATUS_CANCELLED, "status wrong %x\n",U(iosb2).Status);
ok(iosb.Status == STATUS_CANCELLED, "status wrong %lx\n",iosb.Status);
ok(iosb2.Status == STATUS_CANCELLED, "status wrong %lx\n",iosb2.Status);
ok(iosb3.Status == STATUS_SUCCESS, "status wrong %lx\n",iosb3.Status);
ok(iosb.Information == 0, "info wrong\n");
ok(iosb2.Information == 0, "info wrong\n");
ok(iosb3.Information == 0, "info wrong\n");
iosb3.Status = 0x111111;
iosb3.Information = 0x222222;
r = pNtCancelIoFile(hdir, &iosb3);
ok( r == STATUS_INVALID_HANDLE, "cancel failed %lx\n", r);
ok(iosb3.Status == 0x111111, "status wrong %lx\n",iosb3.Status);
ok(iosb3.Information == 0x222222, "info wrong\n");
r = RemoveDirectoryW( path );
ok( r == TRUE, "failed to remove directory\n");
@@ -313,11 +325,6 @@ static void test_ntncdf_async(void)
START_TEST(change)
{
HMODULE hntdll = GetModuleHandleA("ntdll");
if (!hntdll)
{
win_skip("not running on NT, skipping test\n");
return;
}
pNtNotifyChangeDirectoryFile = (void *)GetProcAddress(hntdll, "NtNotifyChangeDirectoryFile");
pNtCancelIoFile = (void *)GetProcAddress(hntdll, "NtCancelIoFile");
+430 -174
View File
@@ -70,11 +70,19 @@ static struct testfile_s {
{ 0, FILE_ATTRIBUTE_NORMAL, {0xe9,'a','.','t','m','p'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {0xc9,'b','.','t','m','p'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'e','a'}, "normal" },
{ 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
{ 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" }
{ 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p','.','t','m','p'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'.','a'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'.','a','.','a'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'a','.'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'.','.','a'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'.','a','a'}, "normal" },
{ 0, FILE_ATTRIBUTE_NORMAL, {'a','.', '.'}, "normal" },
};
static const int test_dir_count = sizeof(testfiles) / sizeof(testfiles[0]);
static const int max_test_dir_size = sizeof(testfiles) / sizeof(testfiles[0]) + 5; /* size of above plus some for .. etc */
static const int test_dir_count = ARRAY_SIZE(testfiles);
static const int max_test_dir_size = ARRAY_SIZE(testfiles) + 5; /* size of above plus some for .. etc */
static const WCHAR dummyW[] = {'d','u','m','m','y',0};
static const WCHAR dotW[] = {'.',0};
@@ -88,19 +96,20 @@ static void set_up_attribute_test(const WCHAR *testdir)
BOOL ret;
ret = CreateDirectoryW(testdir, NULL);
ok(ret, "couldn't create dir %s, error %d\n", wine_dbgstr_w(testdir), GetLastError());
ok(ret, "couldn't create dir %s, error %ld\n", wine_dbgstr_w(testdir), GetLastError());
for (i=0; i < test_dir_count; i++) {
WCHAR buf[MAX_PATH];
if (lstrcmpW(testfiles[i].name, dotW) == 0 || lstrcmpW(testfiles[i].name, dotdotW) == 0)
continue;
lstrcpyW( buf, testdir );
lstrcpyW( buf, L"\\\\?\\" );
lstrcatW( buf, testdir );
lstrcatW( buf, backslashW );
lstrcatW( buf, testfiles[i].name );
if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
ret = CreateDirectoryW(buf, NULL);
ok(ret, "couldn't create dir %s, error %d\n", wine_dbgstr_w(buf), GetLastError());
ok(ret, "couldn't create dir %s, error %ld\n", wine_dbgstr_w(buf), GetLastError());
} else {
HANDLE h = CreateFileW(buf,
GENERIC_READ|GENERIC_WRITE,
@@ -130,17 +139,18 @@ static void tear_down_attribute_test(const WCHAR *testdir)
WCHAR buf[MAX_PATH];
if (lstrcmpW(testfiles[i].name, dotW) == 0 || lstrcmpW(testfiles[i].name, dotdotW) == 0)
continue;
lstrcpyW( buf, testdir );
lstrcpyW( buf, L"\\\\?\\" );
lstrcatW( buf, testdir );
lstrcatW( buf, backslashW );
lstrcatW( buf, testfiles[i].name );
if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
ret = RemoveDirectoryW(buf);
ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
"Failed to rmdir %s, error %d\n", wine_dbgstr_w(buf), GetLastError());
"Failed to rmdir %s, error %ld\n", wine_dbgstr_w(buf), GetLastError());
} else {
ret = DeleteFileW(buf);
ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
"Failed to rm %s, error %d\n", wine_dbgstr_w(buf), GetLastError());
"Failed to rm %s, error %ld\n", wine_dbgstr_w(buf), GetLastError());
}
}
RemoveDirectoryW(testdir);
@@ -161,7 +171,8 @@ static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
if (namelen != len || memcmp(nameW, testfiles[i].name, len*sizeof(WCHAR)))
continue;
if (!testfiles[i].attr_done) {
ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib);
ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%lx), got %lx\n",
wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib);
testfiles[i].attr_done = TRUE;
}
testfiles[i].nfound++;
@@ -172,7 +183,7 @@ static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char *testdirA,
UNICODE_STRING *mask,
BOOLEAN single_entry, BOOLEAN restart_flag)
BOOLEAN single_entry, BOOLEAN restart_flag, BOOLEAN expect_empty)
{
UNICODE_STRING dummy_mask;
HANDLE dirh, new_dirh;
@@ -193,17 +204,23 @@ static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char
/* Read the directory and note which files are found */
status = pNtOpenFile( &dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, attr, &io, FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_FOR_BACKUP_INTENT|FILE_DIRECTORY_FILE);
ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdirA, status, GetLastError());
ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdirA, status, GetLastError());
if (status != STATUS_SUCCESS) {
skip("can't test if we can't open the directory\n");
return;
}
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile( dirh, NULL, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, single_entry, mask, restart_flag );
ok (status == STATUS_SUCCESS, "failed to query directory; status %x\n", status);
ok (U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
if (expect_empty)
{
ok( status == STATUS_NO_SUCH_FILE, "got %#lx.\n", status );
pNtClose( dirh );
return;
}
ok (status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status);
ok (io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status);
data_len = io.Information;
ok (data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n");
@@ -219,12 +236,12 @@ static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char
tally_test_file(dir_info);
if (dir_info->NextEntryOffset == 0) {
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile( new_dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, single_entry, &dummy_mask, FALSE );
ok (U(io).Status == status, "wrong status %x / %x\n", status, U(io).Status);
ok (io.Status == status, "wrong status %lx / %lx\n", status, io.Status);
if (status == STATUS_NO_MORE_FILES) break;
ok (status == STATUS_SUCCESS, "failed to query directory; status %x\n", status);
ok (status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status);
data_len = io.Information;
if (data_len < sizeof(FILE_BOTH_DIRECTORY_INFORMATION))
break;
@@ -236,13 +253,13 @@ static void test_flags_NtQueryDirectoryFile(OBJECT_ATTRIBUTES *attr, const char
}
ok(numfiles < max_test_dir_size, "too many loops\n");
if (mask)
if (mask && !wcspbrk( mask->Buffer, L"*?<\">" ))
for (i = 0; i < test_dir_count; i++)
ok(testfiles[i].nfound == (testfiles[i].name == mask->Buffer),
"Wrong number %d of %s files found (single_entry=%d,mask=%s)\n",
testfiles[i].nfound, testfiles[i].description, single_entry,
wine_dbgstr_wn(mask->Buffer, mask->Length/sizeof(WCHAR) ));
else
else if (!mask)
for (i = 0; i < test_dir_count; i++)
ok(testfiles[i].nfound == 1, "Wrong number %d of %s files found (single_entry=%d,restart=%d)\n",
testfiles[i].nfound, testfiles[i].description, single_entry, restart_flag);
@@ -273,11 +290,11 @@ static void test_directory_sort( const WCHAR *testdir )
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE );
ok(status == STATUS_SUCCESS, "failed to open dir %s\n", wine_dbgstr_w(testdir) );
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile( handle, NULL, NULL, NULL, &io, data, sizeof(data),
FileBothDirectoryInformation, FALSE, NULL, TRUE );
ok( status == STATUS_SUCCESS, "failed to query directory; status %x\n", status );
ok( U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status );
ok( status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status );
ok( io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status );
data_len = io.Information;
ok( data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n" );
data_pos = 0;
@@ -311,12 +328,12 @@ static void test_directory_sort( const WCHAR *testdir )
if (info->NextEntryOffset == 0)
{
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, sizeof(data),
FileBothDirectoryInformation, FALSE, NULL, FALSE );
ok (U(io).Status == status, "wrong status %x / %x\n", status, U(io).Status);
ok (io.Status == status, "wrong status %lx / %lx\n", status, io.Status);
if (status == STATUS_NO_MORE_FILES) break;
ok( status == STATUS_SUCCESS, "failed to query directory; status %x\n", status );
ok( status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status );
data_len = io.Information;
data_pos = 0;
}
@@ -337,16 +354,16 @@ static void test_NtQueryDirectoryFile_classes( HANDLE handle, UNICODE_STRING *ma
for (class = 0; class < FileMaximumInformation; class++)
{
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
data_size = 0;
memset( data, 0x55, sizeof(data) );
status = pNtQueryDirectoryFile( handle, 0, NULL, NULL, &io, data, data_size,
class, FALSE, mask, TRUE );
ok( U(io).Status == 0xdeadbeef, "%u: wrong status %x\n", class, U(io).Status );
ok( U(io).Information == 0xdeadbeef, "%u: wrong info %lx\n", class, U(io).Information );
ok(data[0] == 0x55555555, "%u: wrong offset %x\n", class, data[0] );
ok( io.Status == 0xdeadbeef, "%u: wrong status %lx\n", class, io.Status );
ok( io.Information == 0xdeadbeef, "%u: wrong info %Ix\n", class, io.Information );
ok(data[0] == 0x55555555, "%u: wrong offset %lx\n", class, data[0] );
switch (class)
{
@@ -364,11 +381,11 @@ static void test_NtQueryDirectoryFile_classes( HANDLE handle, UNICODE_STRING *ma
case FileObjectIdInformation:
case FileQuotaInformation:
case FileReparsePointInformation:
ok( status == STATUS_INFO_LENGTH_MISMATCH, "%u: wrong status %x\n", class, status );
ok( status == STATUS_INFO_LENGTH_MISMATCH, "%u: wrong status %lx\n", class, status );
break;
default:
ok( status == STATUS_INVALID_INFO_CLASS || status == STATUS_NOT_IMPLEMENTED,
"%u: wrong status %x\n", class, status );
"%u: wrong status %lx\n", class, status );
continue;
}
@@ -378,15 +395,16 @@ static void test_NtQueryDirectoryFile_classes( HANDLE handle, UNICODE_STRING *ma
class, FALSE, mask, TRUE );
if (status == STATUS_BUFFER_OVERFLOW)
{
ok( U(io).Status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, U(io).Status );
ok( U(io).Information == data_size, "%u: wrong info %lx\n", class, U(io).Information );
ok(data[0] == 0, "%u: wrong offset %x\n", class, data[0] );
ok( io.Status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, io.Status );
ok( io.Information == data_size || broken(!io.Information), /* win10 1709 */
"%u: wrong info %Ix\n", class, io.Information );
if (io.Information) ok(data[0] == 0, "%u: wrong offset %lx\n", class, data[0] );
}
else
{
ok( U(io).Status == 0xdeadbeef, "%u: wrong status %x\n", class, U(io).Status );
ok( U(io).Information == 0xdeadbeef, "%u: wrong info %lx\n", class, U(io).Information );
ok(data[0] == 0x55555555, "%u: wrong offset %x\n", class, data[0] );
ok( io.Status == 0xdeadbeef || io.Status == status, "%u: wrong status %lx\n", class, io.Status );
ok( io.Information == (io.Status == 0xdeadbeef ? 0xdeadbeef : 0), "%u: wrong info %Ix\n", class, io.Information );
ok(data[0] == 0x55555555, "%u: wrong offset %lx\n", class, data[0] );
}
if (status != STATUS_INFO_LENGTH_MISMATCH) break;
}
@@ -394,50 +412,50 @@ static void test_NtQueryDirectoryFile_classes( HANDLE handle, UNICODE_STRING *ma
switch (class)
{
case FileDirectoryInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileFullDirectoryInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_FULL_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileBothDirectoryInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileNamesInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileIdBothDirectoryInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_ID_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileIdFullDirectoryInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_ID_FULL_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileIdGlobalTxDirectoryInformation:
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %x\n", class, status );
ok( status == STATUS_BUFFER_OVERFLOW, "%u: wrong status %lx\n", class, status );
ok( data_size == ((offsetof( FILE_ID_GLOBAL_TX_DIR_INFORMATION, FileName[1] ) + 7) & ~7),
"%u: wrong size %u\n", class, data_size );
break;
case FileObjectIdInformation:
ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %x\n", class, status );
ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %lx\n", class, status );
ok( data_size == sizeof(FILE_OBJECTID_INFORMATION), "%u: wrong size %u\n", class, data_size );
break;
case FileQuotaInformation:
ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %x\n", class, status );
ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %lx\n", class, status );
ok( data_size == sizeof(FILE_QUOTA_INFORMATION), "%u: wrong size %u\n", class, data_size );
break;
case FileReparsePointInformation:
ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %x\n", class, status );
ok( status == STATUS_INVALID_INFO_CLASS, "%u: wrong status %lx\n", class, status );
ok( data_size == sizeof(FILE_REPARSE_POINT_INFORMATION), "%u: wrong size %u\n", class, data_size );
break;
}
@@ -446,11 +464,97 @@ static void test_NtQueryDirectoryFile_classes( HANDLE handle, UNICODE_STRING *ma
static void test_NtQueryDirectoryFile(void)
{
static const struct
{
const WCHAR *mask;
int found[ARRAY_SIZE(testfiles)];
}
mask_tests[] =
{
{L"*.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}},
{L"*. ", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"* .", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L" *.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"*.*", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"* *", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"*.**", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"*", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"**", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"?", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
{L"?.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}},
{L"?..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
{L"??", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0}},
{L"??.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
{L"??.???", {0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"<", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1}},
{L"*<a", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0}},
{L"<.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}},
{L"<..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
{L"<.\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}},
{L".<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0}},
{L"..<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
{L"..*", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
{L"*..*", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1}},
{L"*..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
{L"..?", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
{L"..\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
{L"\"\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
{L"\"\"\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
{L"a.<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1}},
{L"ea.tmp.tmp<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
{L"<tmp", {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
{L"<.tmp", {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
{L"<name.tmp", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"<nam<tmp", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"<name.<", {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"<name<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"<\"", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1}},
{L"*\"", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"*\"tmp\"tmp\"", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
{L"n\"tmp", {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"ea\"", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"\"a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}},
{L"\"\"a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
{L"e\"a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"*\"tmp", {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}},
{L"<.<", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<\"<", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<\"<\"", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<\"<.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
{L"<.<\"", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<<", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<a", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0}},
{L"*a", {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0}},
{L"<aa", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}},
{L"<.a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0}},
{L"<..a", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}},
{L"<.<.<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1}},
{L".<.<", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0}},
{L"<<.<", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<.<<", {1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"<<<", {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
{L"< ..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"< .", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L"<\"\"", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1}},
{L">", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0}},
{L">.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
{L">..", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
{L">>", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
{L">>.", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
{L">>>", {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0}},
{L">>.>>>", {0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1}},
{L">.>", {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1}},
{L">>.tmp", {0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L">>tmp", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{L">>>tmp", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
};
OBJECT_ATTRIBUTES attr;
UNICODE_STRING ntdirname, mask;
char testdirA[MAX_PATH];
char testdirA[MAX_PATH], buffer[MAX_PATH];
WCHAR testdirW[MAX_PATH];
int i;
int i, j;
IO_STATUS_BLOCK io;
WCHAR short_name[12];
UINT data_size;
@@ -459,8 +563,9 @@ static void test_NtQueryDirectoryFile(void)
FILE_POSITION_INFORMATION pos_info;
FILE_NAMES_INFORMATION *names;
const WCHAR *filename = fbdi->FileName;
BOOLEAN expect_empty;
NTSTATUS status;
HANDLE dirh;
HANDLE dirh, h;
/* Clean up from prior aborted run, if any, then set up test files */
ok(GetTempPathA(MAX_PATH, testdirA), "couldn't get temp dir\n");
@@ -476,20 +581,39 @@ static void test_NtQueryDirectoryFile(void)
}
InitializeObjectAttributes(&attr, &ntdirname, OBJ_CASE_INSENSITIVE, 0, NULL);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, TRUE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, TRUE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, TRUE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, FALSE, FALSE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, TRUE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, NULL, TRUE, FALSE, FALSE);
for (i = 0; i < test_dir_count; i++)
{
if (testfiles[i].name[0] == '.') continue; /* . and .. as masks are broken on Windows */
mask.Buffer = testfiles[i].name;
mask.Length = mask.MaximumLength = lstrlenW(testfiles[i].name) * sizeof(WCHAR);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, TRUE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, FALSE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, TRUE, FALSE);
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, TRUE, FALSE, FALSE);
}
for (i = 0; i < ARRAY_SIZE(mask_tests); ++i)
{
winetest_push_context("mask %s", debugstr_w(mask_tests[i].mask));
RtlInitUnicodeString(&mask, mask_tests[i].mask);
expect_empty = TRUE;
for (j = 0; j < ARRAY_SIZE(mask_tests[i].found); ++j)
{
if (mask_tests[i].found[j])
{
expect_empty = FALSE;
break;
}
}
test_flags_NtQueryDirectoryFile(&attr, testdirA, &mask, FALSE, TRUE, expect_empty);
for (j = 0; j < test_dir_count; j++)
ok(testfiles[j].nfound == mask_tests[i].found[j], "%S, got %d.\n", testfiles[j].name, testfiles[j].nfound);
winetest_pop_context();
}
/* short path passed as mask */
@@ -501,84 +625,88 @@ static void test_NtQueryDirectoryFile(void)
return;
}
status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
ok( pos_info.CurrentByteOffset.QuadPart == 0, "wrong pos %s\n",
wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart));
pos_info.CurrentByteOffset.QuadPart = 0xbeef;
status = pNtSetInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n",
wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart));
mask.Buffer = testfiles[0].name;
mask.Length = mask.MaximumLength = lstrlenW(testfiles[0].name) * sizeof(WCHAR);
data_size = offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[256]);
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, &mask, FALSE);
ok(status == STATUS_SUCCESS, "failed to query directory; status %x\n", status);
ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
ok(status == STATUS_SUCCESS, "failed to query directory; status %lx\n", status);
ok(io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status);
ok(fbdi->ShortName[0], "ShortName is empty\n");
status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n",
wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart) );
mask.Length = mask.MaximumLength = fbdi->ShortNameLength;
memcpy(short_name, fbdi->ShortName, mask.Length);
mask.Buffer = short_name;
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, &mask, TRUE);
ok(status == STATUS_SUCCESS, "failed to query directory status %x\n", status);
ok(U(io).Status == STATUS_SUCCESS, "failed to query directory status %x\n", U(io).Status);
ok(U(io).Information == offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[lstrlenW(testfiles[0].name)]),
"wrong info %lx\n", U(io).Information);
ok(status == STATUS_SUCCESS, "failed to query directory status %lx\n", status);
ok(io.Status == STATUS_SUCCESS, "failed to query directory status %lx\n", io.Status);
ok(io.Information == offsetof(FILE_BOTH_DIRECTORY_INFORMATION, FileName[lstrlenW(testfiles[0].name)]),
"wrong info %Ix\n", io.Information);
ok(fbdi->FileNameLength == lstrlenW(testfiles[0].name)*sizeof(WCHAR) &&
!memcmp(fbdi->FileName, testfiles[0].name, fbdi->FileNameLength),
"incorrect long file name: %s\n", wine_dbgstr_wn(fbdi->FileName,
fbdi->FileNameLength/sizeof(WCHAR)));
status = pNtQueryInformationFile( dirh, &io, &pos_info, sizeof(pos_info), FilePositionInformation );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %x\n", status );
ok( status == STATUS_SUCCESS, "NtQueryInformationFile failed %lx\n", status );
ok( pos_info.CurrentByteOffset.QuadPart == 0xbeef, "wrong pos %s\n",
wine_dbgstr_longlong(pos_info.CurrentByteOffset.QuadPart) );
/* tests with short buffer */
memset( data, 0x55, data_size );
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
data_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] );
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, &mask, TRUE);
ok( status == STATUS_BUFFER_OVERFLOW, "wrong status %x\n", status );
ok( U(io).Status == STATUS_BUFFER_OVERFLOW, "wrong status %x\n", U(io).Status );
ok( U(io).Information == data_size || broken( U(io).Information == 0),
"wrong info %lx\n", U(io).Information );
ok( fbdi->NextEntryOffset == 0, "wrong offset %x\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name) * sizeof(WCHAR),
"wrong length %x\n", fbdi->FileNameLength );
ok( filename[0] == testfiles[0].name[0], "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
ok( filename[1] == 0x5555, "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
ok( status == STATUS_BUFFER_OVERFLOW, "wrong status %lx\n", status );
ok( io.Status == STATUS_BUFFER_OVERFLOW, "wrong status %lx\n", io.Status );
ok( io.Information == data_size || broken( io.Information == 0),
"wrong info %Ix\n", io.Information );
ok( fbdi->NextEntryOffset == 0 || fbdi->NextEntryOffset == 0x55555555, /* win10 >= 1709 */
"wrong offset %lx\n", fbdi->NextEntryOffset );
if (!fbdi->NextEntryOffset)
{
ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name) * sizeof(WCHAR),
"wrong length %lx\n", fbdi->FileNameLength );
ok( filename[0] == testfiles[0].name[0], "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
ok( filename[1] == 0x5555, "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
}
test_NtQueryDirectoryFile_classes( dirh, &mask );
/* mask may or may not be ignored when restarting the search */
pRtlInitUnicodeString( &mask, dummyW );
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
data_size = offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[256] );
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, &mask, TRUE);
ok( status == STATUS_SUCCESS || status == STATUS_NO_MORE_FILES, "wrong status %x\n", status );
ok( U(io).Status == status, "wrong status %x / %x\n", U(io).Status, status );
ok( status == STATUS_SUCCESS || status == STATUS_NO_MORE_FILES, "wrong status %lx\n", status );
ok( io.Status == status, "wrong status %lx / %lx\n", io.Status, status );
if (!status)
ok( fbdi->FileNameLength == lstrlenW(testfiles[0].name)*sizeof(WCHAR) &&
!memcmp(fbdi->FileName, testfiles[0].name, fbdi->FileNameLength),
@@ -593,73 +721,74 @@ static void test_NtQueryDirectoryFile(void)
memset( data, 0x55, data_size );
data_size = sizeof(data);
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, FALSE, NULL, TRUE);
ok(status == STATUS_SUCCESS, "wrong status %x\n", status);
ok(U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status);
ok(U(io).Information > 0 && U(io).Information < data_size, "wrong info %lx\n", U(io).Information);
ok(status == STATUS_SUCCESS, "wrong status %lx\n", status);
ok(io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status);
ok(io.Information > 0 && io.Information < data_size, "wrong info %Ix\n", io.Information);
ok( fbdi->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"wrong offset %x\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %x\n", fbdi->FileNameLength );
"wrong offset %lx\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", fbdi->FileNameLength );
ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
next = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + fbdi->NextEntryOffset);
ok( next->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] ) + 7) & ~7),
"wrong offset %x\n", next->NextEntryOffset );
ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %x\n", next->FileNameLength );
"wrong offset %lx\n", next->NextEntryOffset );
ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %lx\n", next->FileNameLength );
filename = next->FileName;
ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(next->FileName, next->FileNameLength/sizeof(WCHAR)));
data_size = fbdi->NextEntryOffset + offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ),
data_size = fbdi->NextEntryOffset + offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] );
memset( data, 0x55, data_size );
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, FALSE, NULL, TRUE );
ok( status == STATUS_SUCCESS, "wrong status %x\n", status );
ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status );
ok( U(io).Information == offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ),
"wrong info %lx\n", U(io).Information );
ok( fbdi->NextEntryOffset == 0, "wrong offset %x\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %x\n", fbdi->FileNameLength );
ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
ok( io.Information == offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ),
"wrong info %Ix\n", io.Information );
ok( fbdi->NextEntryOffset == 0, "wrong offset %lx\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", fbdi->FileNameLength );
ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
next = (FILE_BOTH_DIRECTORY_INFORMATION *)&fbdi->FileName[1];
ok( next->NextEntryOffset == 0x55555555, "wrong offset %x\n", next->NextEntryOffset );
ok( next->NextEntryOffset == 0x55555555, "wrong offset %lx\n", next->NextEntryOffset );
data_size = fbdi->NextEntryOffset + offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] ),
data_size = fbdi->NextEntryOffset + offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] );
memset( data, 0x55, data_size );
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, FALSE, NULL, TRUE );
ok( status == STATUS_SUCCESS, "wrong status %x\n", status );
ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status );
ok( U(io).Information == offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ),
"wrong info %lx\n", U(io).Information );
ok( fbdi->NextEntryOffset == 0, "wrong offset %x\n", fbdi->NextEntryOffset );
ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
ok( io.Information == offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ),
"wrong info %Ix\n", io.Information );
ok( fbdi->NextEntryOffset == 0, "wrong offset %lx\n", fbdi->NextEntryOffset );
data_size = ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7) +
offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[2] );
memset( data, 0x55, data_size );
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size + 32,
FileBothDirectoryInformation, FALSE, NULL, TRUE );
ok( status == STATUS_SUCCESS, "wrong status %x\n", status );
ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status );
ok( U(io).Information == data_size, "wrong info %lx / %x\n", U(io).Information, data_size );
ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
ok( io.Information == data_size || io.Information == ((data_size + 7) & ~7),
"wrong info %Ix / %x\n", io.Information, data_size );
ok( fbdi->NextEntryOffset == ((offsetof( FILE_BOTH_DIRECTORY_INFORMATION, FileName[1] ) + 7) & ~7),
"wrong offset %x\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %x\n", fbdi->FileNameLength );
"wrong offset %lx\n", fbdi->NextEntryOffset );
ok( fbdi->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", fbdi->FileNameLength );
ok( fbdi->FileName[0] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(fbdi->FileName, fbdi->FileNameLength/sizeof(WCHAR)));
next = (FILE_BOTH_DIRECTORY_INFORMATION *)(data + fbdi->NextEntryOffset);
ok( next->NextEntryOffset == 0, "wrong offset %x\n", next->NextEntryOffset );
ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %x\n", next->FileNameLength );
ok( next->NextEntryOffset == 0, "wrong offset %lx\n", next->NextEntryOffset );
ok( next->FileNameLength == 2 * sizeof(WCHAR), "wrong length %lx\n", next->FileNameLength );
filename = next->FileName;
ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(next->FileName, next->FileNameLength/sizeof(WCHAR)));
@@ -667,22 +796,22 @@ static void test_NtQueryDirectoryFile(void)
data_size = ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7) +
offsetof( FILE_NAMES_INFORMATION, FileName[2] );
memset( data, 0x55, data_size );
U(io).Status = 0xdeadbeef;
U(io).Information = 0xdeadbeef;
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
status = pNtQueryDirectoryFile( dirh, 0, NULL, NULL, &io, data, data_size,
FileNamesInformation, FALSE, NULL, TRUE );
ok( status == STATUS_SUCCESS, "wrong status %x\n", status );
ok( U(io).Status == STATUS_SUCCESS, "wrong status %x\n", U(io).Status );
ok( U(io).Information == data_size, "wrong info %lx / %x\n", U(io).Information, data_size );
ok( status == STATUS_SUCCESS, "wrong status %lx\n", status );
ok( io.Status == STATUS_SUCCESS, "wrong status %lx\n", io.Status );
ok( io.Information == data_size, "wrong info %Ix / %x\n", io.Information, data_size );
names = (FILE_NAMES_INFORMATION *)data;
ok( names->NextEntryOffset == ((offsetof( FILE_NAMES_INFORMATION, FileName[1] ) + 7) & ~7),
"wrong offset %x\n", names->NextEntryOffset );
ok( names->FileNameLength == sizeof(WCHAR), "wrong length %x\n", names->FileNameLength );
"wrong offset %lx\n", names->NextEntryOffset );
ok( names->FileNameLength == sizeof(WCHAR), "wrong length %lx\n", names->FileNameLength );
ok( names->FileName[0] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(names->FileName, names->FileNameLength/sizeof(WCHAR)));
names = (FILE_NAMES_INFORMATION *)(data + names->NextEntryOffset);
ok( names->NextEntryOffset == 0, "wrong offset %x\n", names->NextEntryOffset );
ok( names->FileNameLength == 2 * sizeof(WCHAR), "wrong length %x\n", names->FileNameLength );
ok( names->NextEntryOffset == 0, "wrong offset %lx\n", names->NextEntryOffset );
ok( names->FileNameLength == 2 * sizeof(WCHAR), "wrong length %lx\n", names->FileNameLength );
filename = names->FileName;
ok( filename[0] == '.' && filename[1] == '.', "incorrect long file name: %s\n",
wine_dbgstr_wn(names->FileName, names->FileNameLength/sizeof(WCHAR)));
@@ -695,32 +824,44 @@ static void test_NtQueryDirectoryFile(void)
ok(status == STATUS_SUCCESS, "failed to open dir '%s'\n", testdirA);
pRtlInitUnicodeString( &mask, dummyW );
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
data_size = sizeof(data);
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, &mask, TRUE);
ok(status == STATUS_NO_SUCH_FILE, "wrong status %x\n", status);
ok(U(io).Status == 0xdeadbeef, "wrong status %x\n", U(io).Status);
ok(status == STATUS_NO_SUCH_FILE, "wrong status %lx\n", status);
ok(io.Status == 0xdeadbeef, "wrong status %lx\n", io.Status);
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, NULL, FALSE);
ok(status == STATUS_NO_MORE_FILES, "wrong status %x\n", status);
ok(U(io).Status == STATUS_NO_MORE_FILES, "wrong status %x\n", U(io).Status);
ok(status == STATUS_NO_MORE_FILES, "wrong status %lx\n", status);
ok(io.Status == STATUS_NO_MORE_FILES, "wrong status %lx\n", io.Status);
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile(dirh, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, NULL, TRUE);
ok(status == STATUS_NO_MORE_FILES, "wrong status %x\n", status);
ok(U(io).Status == STATUS_NO_MORE_FILES, "wrong status %x\n", U(io).Status);
ok(status == STATUS_NO_MORE_FILES, "wrong status %lx\n", status);
ok(io.Status == STATUS_NO_MORE_FILES, "wrong status %lx\n", io.Status);
pNtClose(dirh);
U(io).Status = 0xdeadbeef;
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile( (HANDLE)0xbeef, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, NULL, TRUE );
ok(status == STATUS_INVALID_HANDLE, "wrong status %x\n", status);
ok(U(io).Status == 0xdeadbeef, "wrong status %x\n", U(io).Status);
ok(status == STATUS_INVALID_HANDLE, "wrong status %lx\n", status);
ok(io.Status == 0xdeadbeef, "wrong status %lx\n", io.Status);
GetModuleFileNameA( 0, buffer, sizeof(buffer) );
h = CreateFileA( buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
if (h != INVALID_HANDLE_VALUE)
{
io.Status = 0xdeadbeef;
status = pNtQueryDirectoryFile( h, 0, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, NULL, TRUE );
ok(status == STATUS_INVALID_PARAMETER, "wrong status %lx\n", status);
ok(io.Status == 0xdeadbeef, "wrong status %lx\n", io.Status);
CloseHandle ( h );
}
done:
test_directory_sort( testdirW );
@@ -731,11 +872,11 @@ done:
static void set_up_case_test(const char *testdir)
{
BOOL ret;
char buf[MAX_PATH];
char buf[MAX_PATH + 5];
HANDLE h;
ret = CreateDirectoryA(testdir, NULL);
ok(ret, "couldn't create dir '%s', error %d\n", testdir, GetLastError());
ok(ret, "couldn't create dir '%s', error %ld\n", testdir, GetLastError());
sprintf(buf, "%s\\%s", testdir, "TesT");
h = CreateFileA(buf, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
@@ -752,7 +893,7 @@ static void tear_down_case_test(const char *testdir)
sprintf(buf, "%s\\%s", testdir, "TesT");
ret = DeleteFileA(buf);
ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
"Failed to rm %s, error %d\n", buf, GetLastError());
"Failed to rm %s, error %ld\n", buf, GetLastError());
RemoveDirectoryA(testdir);
}
@@ -794,7 +935,7 @@ static void test_NtQueryDirectoryFile_case(void)
status = pNtOpenFile(&dirh, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io, FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE);
ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%x, error %d\n", testdir, status, GetLastError());
ok (status == STATUS_SUCCESS, "failed to open dir '%s', ret 0x%lx, error %ld\n", testdir, status, GetLastError());
if (status != STATUS_SUCCESS)
{
skip("can't test if we can't open the directory\n");
@@ -805,14 +946,14 @@ static void test_NtQueryDirectoryFile_case(void)
mask.Length = mask.MaximumLength = sizeof(testmask);
pNtQueryDirectoryFile(dirh, NULL, NULL, NULL, &io, data, data_size,
FileBothDirectoryInformation, TRUE, &mask, FALSE);
ok(U(io).Status == STATUS_SUCCESS, "failed to query directory; status %x\n", U(io).Status);
ok(io.Status == STATUS_SUCCESS, "failed to query directory; status %lx\n", io.Status);
data_len = io.Information;
ok(data_len >= sizeof(FILE_BOTH_DIRECTORY_INFORMATION), "not enough data in directory\n");
name = dir_info->FileName;
name_len = dir_info->FileNameLength / sizeof(WCHAR);
ok(name_len == testfile_len, "unexpected filename length %u\n", name_len);
ok(name_len == testfile_len, "unexpected filename length %lu\n", name_len);
ok(!memcmp(name, testfile_w, testfile_len * sizeof(WCHAR)), "unexpected filename %s\n",
wine_dbgstr_wn(name, name_len));
@@ -823,10 +964,45 @@ done:
pRtlFreeUnicodeString(&ntdirname);
}
static NTSTATUS get_file_id( FILE_INTERNAL_INFORMATION *info, const WCHAR *root, const WCHAR *name )
{
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
InitializeObjectAttributes( &attr, &nameW, OBJ_CASE_INSENSITIVE, 0, NULL );
if (root)
{
RtlInitUnicodeString( &nameW, root );
status = pNtOpenFile( &attr.RootDirectory, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT |
FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE );
if (status) return status;
}
if (name)
{
RtlInitUnicodeString( &nameW, name );
status = pNtOpenFile( &handle, FILE_GENERIC_READ, &attr, &io, FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE );
if (attr.RootDirectory) NtClose( attr.RootDirectory );
}
else handle = attr.RootDirectory;
if (!status)
{
status = pNtQueryInformationFile( handle, &io, info, sizeof(*info), FileInternalInformation );
NtClose( handle );
}
return status;
}
static void test_redirection(void)
{
ULONG old, cur;
NTSTATUS status;
ULONGLONG *tls64 = NULL;
if (!pRtlWow64EnableFsRedirection || !pRtlWow64EnableFsRedirectionEx)
{
@@ -839,37 +1015,122 @@ static void test_redirection(void)
skip( "Wow64 redirection not supported\n" );
return;
}
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
#ifndef _WIN64
if (NtCurrentTeb()->GdiBatchCount)
tls64 = ((TEB64 *)NtCurrentTeb()->GdiBatchCount)->TlsSlots + WOW64_TLS_FILESYSREDIR;
#endif
status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
ok( !cur, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
if (tls64) ok( *tls64 == FALSE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
if (tls64) ok( *tls64 == TRUE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirection( TRUE );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
status = pRtlWow64EnableFsRedirectionEx( TRUE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !cur, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
ok( !cur, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
if (tls64) ok( *tls64 == TRUE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( 123, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
ok( cur == TRUE, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
if (tls64) ok( *tls64 == 123, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( 0xdeadbeef, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
ok( cur == 123, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
if (tls64) ok( *tls64 == 0xdeadbeef, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
status = pRtlWow64EnableFsRedirectionEx( TRUE, NULL );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %lx\n", status );
status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)1 );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %lx\n", status );
status = pRtlWow64EnableFsRedirectionEx( TRUE, (void*)0xDEADBEEF );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %x\n", status );
ok( status == STATUS_ACCESS_VIOLATION, "RtlWow64EnableFsRedirectionEx failed with status %lx\n", status );
status = pRtlWow64EnableFsRedirection( FALSE );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
status = pRtlWow64EnableFsRedirectionEx( FALSE, &cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %x\n", status );
ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %u\n", cur );
ok( !status, "RtlWow64EnableFsRedirectionEx failed status %lx\n", status );
ok( cur == 1, "RtlWow64EnableFsRedirectionEx got %lu\n", cur );
if (tls64) ok( *tls64 == FALSE, "wrong tls %s\n", wine_dbgstr_longlong(*tls64) );
if (tls64)
{
static const struct
{
const WCHAR *root, *name;
NTSTATUS expect;
BOOL redirected;
NTSTATUS alt;
} tests[] =
{
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, TRUE },
{ NULL, L"\\??\\C:\\\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE },
{ L"\\??\\C:\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS, TRUE },
{ L"\\??\\C:\\\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS, TRUE, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\system32", L"kernel32.dll", STATUS_SUCCESS, TRUE },
{ L"\\??\\C:\\windows\\system32", NULL, STATUS_SUCCESS, TRUE },
{ L"\\??\\C:\\windows\\system32", L"drivers\\ndis.sys", STATUS_OBJECT_NAME_NOT_FOUND, FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows\\system32", L"drivers\\etc\\hosts", STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows\\system32\\drivers", NULL, STATUS_SUCCESS, TRUE, STATUS_OBJECT_NAME_NOT_FOUND },
{ L"\\??\\C:\\windows\\system32\\drivers\\etc", L"hosts", STATUS_SUCCESS, FALSE },
{ NULL, L"\\DosDevices\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE },
{ L"\\DosDevices\\C:\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS, FALSE },
{ L"\\DosDevices\\C:\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS, TRUE },
{ L"\\DosDevices\\C:\\windows\\system32", L"kernel32.dll", STATUS_SUCCESS, TRUE },
{ L"\\DosDevices\\C:\\windows\\system32", NULL, STATUS_SUCCESS, FALSE },
{ L"\\DosDevices\\C:\\windows\\system32", L"drivers\\ndis.sys", STATUS_OBJECT_NAME_NOT_FOUND, FALSE, STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\DosDevices\\C:\\windows\\system32", L"drivers\\etc\\hosts", STATUS_SUCCESS, FALSE },
{ L"\\DosDevices\\C:\\windows\\system32\\drivers", NULL, STATUS_SUCCESS, FALSE },
{ L"\\DosDevices\\C:\\windows\\system32\\drivers\\etc", NULL, STATUS_SUCCESS, FALSE },
{ NULL, L"\\??\\C:\\windows\\sysnative\\kernel32.dll", STATUS_SUCCESS, FALSE },
{ L"\\??\\C:\\", L"windows\\sysnative\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows", L"sysnative\\kernel32.dll", STATUS_SUCCESS, FALSE },
{ L"\\??\\C:\\windows\\sysnative", L"kernel32.dll" , STATUS_SUCCESS, TRUE },
{ L"\\??\\C:\\windows\\sysnative", NULL, STATUS_SUCCESS, FALSE },
{ NULL, L"\\DosDevices\\C:\\windows\\sysnative\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\DosDevices\\C:\\", L"windows\\sysnative\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\DosDevices\\C:\\windows", L"sysnative\\kernel32.dll", STATUS_SUCCESS, FALSE },
{ L"\\DosDevices\\C:\\windows\\sysnative", L"kernel32.dll" , STATUS_OBJECT_NAME_NOT_FOUND },
{ L"\\DosDevices\\C:\\windows\\sysnative", NULL, STATUS_OBJECT_NAME_NOT_FOUND },
};
FILE_INTERNAL_INFORMATION info, info_redir;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
pRtlWow64EnableFsRedirection( FALSE );
status = get_file_id( &info, tests[i].root, tests[i].name );
ok( !status || status == tests[i].expect || (tests[i].alt && status == tests[i].alt),
"%u: got %lx / %lx for %s + %s without redirect\n", i, status, tests[i].expect,
debugstr_w( tests[i].root ), debugstr_w( tests[i].name ));
if (status) memset( &info, 0xcc, sizeof(info) );
pRtlWow64EnableFsRedirection( TRUE );
status = get_file_id( &info_redir, tests[i].root, tests[i].name );
ok( status == tests[i].expect || (tests[i].alt && status == tests[i].alt),
"%u: got %lx / %lx for %s + %s\n", i, status, tests[i].expect,
debugstr_w( tests[i].root ), debugstr_w( tests[i].name ));
if (!status)
{
BOOL redirected = memcmp( &info_redir, &info, sizeof(info) );
ok( !redirected == !tests[i].redirected,
"%u: was %sredirected for %s + %s\n", i, redirected ? "" : "not ",
debugstr_w( tests[i].root ), debugstr_w( tests[i].name ));
}
}
}
pRtlWow64EnableFsRedirectionEx( old, &cur );
}
@@ -877,11 +1138,6 @@ START_TEST(directory)
{
WCHAR sysdir[MAX_PATH];
HMODULE hntdll = GetModuleHandleA("ntdll.dll");
if (!hntdll)
{
skip("not running on NT, skipping test\n");
return;
}
pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
+545 -102
View File
@@ -1,5 +1,5 @@
/*
* Unit test suite for ntdll path functions
* Unit test suite for ntdll env functions
*
* Copyright 2003 Eric Pouech
*
@@ -19,17 +19,29 @@
*/
#include <stdio.h>
#include <stdarg.h>
#include "ntdll_test.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.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* pRtlQueryEnvironmentVariable)(WCHAR*, WCHAR*, SIZE_T, WCHAR*, SIZE_T, SIZE_T*);
static NTSTATUS (WINAPI *pRtlExpandEnvironmentStrings)(WCHAR*, WCHAR*, SIZE_T, WCHAR*, SIZE_T, SIZE_T*);
static NTSTATUS (WINAPI *pRtlExpandEnvironmentStrings_U)(LPWSTR, PUNICODE_STRING, PUNICODE_STRING, PULONG);
static NTSTATUS (WINAPI *pRtlCreateProcessParameters)(RTL_USER_PROCESS_PARAMETERS**,
const UNICODE_STRING*, const UNICODE_STRING*,
const UNICODE_STRING*, const UNICODE_STRING*,
PWSTR, const UNICODE_STRING*, const UNICODE_STRING*,
const UNICODE_STRING*, const UNICODE_STRING*);
static void (WINAPI *pRtlDestroyProcessParameters)(RTL_USER_PROCESS_PARAMETERS *);
static void *initial_env;
static WCHAR small_env[] = {'f','o','o','=','t','o','t','o',0,
'f','o','=','t','i','t','i',0,
@@ -87,6 +99,9 @@ static void testQuery(void)
UNICODE_STRING name;
UNICODE_STRING value;
NTSTATUS nts;
SIZE_T name_length;
SIZE_T value_length;
SIZE_T return_length;
unsigned int i;
for (i = 0; tests[i].var; i++)
@@ -103,7 +118,7 @@ static void testQuery(void)
pRtlMultiByteToUnicodeN( bn, sizeof(bn), NULL, test->var, strlen(test->var)+1 );
nts = pRtlQueryEnvironmentVariable_U(small_env, &name, &value);
ok( nts == test->status || (test->alt && nts == test->alt),
"[%d]: Wrong status for '%s', expecting %x got %x\n",
"[%d]: Wrong status for '%s', expecting %lx got %lx\n",
i, test->var, test->status, nts );
if (nts == test->status) switch (nts)
{
@@ -122,84 +137,39 @@ static void testQuery(void)
break;
}
}
}
static void testSetHelper(LPWSTR* env, const char* var, const char* val, NTSTATUS ret, NTSTATUS alt)
{
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)
if (pRtlQueryEnvironmentVariable)
{
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 || (alt && nts == alt), "Setting var %s=%s (%x/%x)\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)
for (i = 0; tests[i].var; i++)
{
case STATUS_SUCCESS:
ok(lstrcmpW(bval1, bval2) == 0, "Cannot get value written to environment\n");
break;
case STATUS_VARIABLE_NOT_FOUND:
ok(val == NULL ||
broken(strchr(var,'=') != NULL), /* variable containing '=' may be set but not found again on NT4 */
"Couldn't find variable, but didn't delete it. val = %s\n", val);
break;
default:
ok(0, "Wrong ret %u for %s\n", nts, var);
break;
const struct test* test = &tests[i];
name_length = strlen(test->var);
value_length = test->len;
value.Buffer = bv;
bv[test->len] = '@';
pRtlMultiByteToUnicodeN(bn, sizeof(bn), NULL, test->var, strlen(test->var) + 1);
nts = pRtlQueryEnvironmentVariable(small_env, bn, name_length, bv, value_length, &return_length);
ok(nts == test->status || (test->alt && nts == test->alt),
"[%d]: Wrong status for '%s', expecting %lx got %lx\n",
i, 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(return_length == strlen(test->val), "Wrong length %Id for %s\n",
return_length, test->var);
ok(!memcmp(bv, bn, return_length), "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(return_length == (strlen(test->val) + 1),
"Wrong returned length %Id (too small buffer) for %s\n", return_length, test->var);
break;
}
}
}
}
static void testSet(void)
{
LPWSTR env;
char tmp[16];
int i;
ok(pRtlCreateEnvironment(FALSE, &env) == STATUS_SUCCESS, "Creating environment\n");
testSetHelper(&env, "cat", "dog", STATUS_SUCCESS, 0);
testSetHelper(&env, "cat", "horse", STATUS_SUCCESS, 0);
testSetHelper(&env, "cat", "zz", STATUS_SUCCESS, 0);
testSetHelper(&env, "cat", NULL, STATUS_SUCCESS, 0);
testSetHelper(&env, "cat", NULL, STATUS_SUCCESS, STATUS_VARIABLE_NOT_FOUND);
testSetHelper(&env, "foo", "meouw", STATUS_SUCCESS, 0);
testSetHelper(&env, "me=too", "also", STATUS_SUCCESS, STATUS_INVALID_PARAMETER);
testSetHelper(&env, "me", "too=also", STATUS_SUCCESS, 0);
testSetHelper(&env, "=too", "also", STATUS_SUCCESS, 0);
testSetHelper(&env, "=", "also", STATUS_SUCCESS, 0);
for (i = 0; i < 128; i++)
{
sprintf(tmp, "zork%03d", i);
testSetHelper(&env, tmp, "is alive", STATUS_SUCCESS, 0);
}
for (i = 0; i < 128; i++)
{
sprintf(tmp, "zork%03d", i);
testSetHelper(&env, tmp, NULL, STATUS_SUCCESS, 0);
}
testSetHelper(&env, "fOo", NULL, STATUS_SUCCESS, 0);
ok(pRtlDestroyEnvironment(env) == STATUS_SUCCESS, "Destroying environment\n");
else win_skip("RtlQueryEnvironmentVariable not available, skipping tests\n");
}
static void testExpand(void)
@@ -244,20 +214,20 @@ static void testExpand(void)
us_dst.Buffer = NULL;
nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul);
ok(nts == STATUS_BUFFER_TOO_SMALL, "Call failed (%u)\n", nts);
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: %u\n", test->src, ul );
"Wrong returned length for %s: %lu\n", test->src, ul );
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 (%u)\n", nts);
ok(nts == STATUS_SUCCESS, "Call failed (%lu)\n", nts);
ok(ul == us_dst.Length + sizeof(WCHAR),
"Wrong returned length for %s: %u\n", test->src, ul);
"Wrong returned length for %s: %lu\n", test->src, ul);
ok(ul == strlen(test->dst) * sizeof(WCHAR) + sizeof(WCHAR),
"Wrong returned length for %s: %u\n", test->src, ul);
"Wrong returned length for %s: %lu\n", test->src, ul);
ok(lstrcmpW(dst, rst) == 0, "Wrong result for %s: expecting %s\n",
test->src, test->dst);
@@ -266,35 +236,508 @@ static void testExpand(void)
us_dst.Buffer = dst;
dst[8] = '-';
nts = pRtlExpandEnvironmentStrings_U(small_env, &us_src, &us_dst, &ul);
ok(nts == STATUS_BUFFER_TOO_SMALL, "Call failed (%u)\n", nts);
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): %u\n", test->src, ul);
"Wrong returned length for %s (with buffer too small): %lu\n", test->src, ul);
ok(dst[8] == '-', "Writing too far in buffer (got %c/%d)\n", dst[8], dst[8]);
}
}
static void test_RtlExpandEnvironmentStrings(void)
{
int i;
WCHAR buf[256];
HRESULT status;
UNICODE_STRING us_src, us_dst, us_name, us_value;
static const struct test_info
{
const WCHAR *input;
const WCHAR *expected_str;
int count_in;
int expected_count_out;
} tests[] =
{
/* 0 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 0, 16 },
/* 1 */ { L"Long long value", L"abcdefghijklmnopqrstuv", 1, 16 },
/* 2 */ { L"Long long value", L"Lbcdefghijklmnopqrstuv", 2, 16 },
/* 3 */ { L"Long long value", L"Locdefghijklmnopqrstuv", 3, 16 },
/* 4 */ { L"Long long value", L"Long long valuopqrstuv", 15, 16 },
/* 5 */ { L"Long long value", L"Long long value", 16, 16 },
/* 6 */ { L"Long long value", L"Long long value", 17, 16 },
/* 7 */ { L"%TVAR% long long", L"abcdefghijklmnopqrstuv", 0, 15 },
/* 8 */ { L"%TVAR% long long", L"", 1, 15 },
/* 9 */ { L"%TVAR% long long", L"", 2, 15 },
/* 10 */ { L"%TVAR% long long", L"", 4, 15 },
/* 11 */ { L"%TVAR% long long", L"WINE", 5, 15 },
/* 12 */ { L"%TVAR% long long", L"WINE fghijklmnopqrstuv", 6, 15 },
/* 13 */ { L"%TVAR% long long", L"WINE lghijklmnopqrstuv", 7, 15 },
/* 14 */ { L"%TVAR% long long", L"WINE long long", 15, 15 },
/* 15 */ { L"%TVAR% long long", L"WINE long long", 16, 15 },
/* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14 },
/* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14 },
/* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14 },
/* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14 },
/* 20 */ { L"%TVAR%%TVAR% long", L"WINEWINE", 9, 14 },
/* 21 */ { L"%TVAR%%TVAR% long", L"WINEWINE jklmnopqrstuv", 10, 14 },
/* 22 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 14, 14 },
/* 23 */ { L"%TVAR%%TVAR% long", L"WINEWINE long", 15, 14 },
/* 24 */ { L"%TVAR% %TVAR% long", L"WINE", 5, 15 },
/* 25 */ { L"%TVAR% %TVAR% long", L"WINE ", 6, 15 },
/* 26 */ { L"%TVAR% %TVAR% long", L"WINE ", 8, 15 },
/* 27 */ { L"%TVAR% %TVAR% long", L"WINE ", 9, 15 },
/* 28 */ { L"%TVAR% %TVAR% long", L"WINE WINE", 10, 15 },
/* 29 */ { L"%TVAR% %TVAR% long", L"WINE WINE klmnopqrstuv", 11, 15 },
/* 30 */ { L"%TVAR% %TVAR% long", L"WINE WINE llmnopqrstuv", 12, 15 },
/* 31 */ { L"%TVAR% %TVAR% long", L"WINE WINE lonnopqrstuv", 14, 15 },
/* 32 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 15, 15 },
/* 33 */ { L"%TVAR% %TVAR% long", L"WINE WINE long", 16, 15 },
/* 34 */ { L"%TVAR2% long long", L"abcdefghijklmnopqrstuv", 1, 18 },
/* 35 */ { L"%TVAR2% long long", L"%bcdefghijklmnopqrstuv", 2, 18 },
/* 36 */ { L"%TVAR2% long long", L"%TVdefghijklmnopqrstuv", 4, 18 },
/* 37 */ { L"%TVAR2% long long", L"%TVAR2ghijklmnopqrstuv", 7, 18 },
/* 38 */ { L"%TVAR2% long long", L"%TVAR2%hijklmnopqrstuv", 8, 18 },
/* 39 */ { L"%TVAR2% long long", L"%TVAR2% ijklmnopqrstuv", 9, 18 },
/* 40 */ { L"%TVAR2% long long", L"%TVAR2% ljklmnopqrstuv", 10, 18 },
/* 41 */ { L"%TVAR2% long long", L"%TVAR2% long long", 18, 18 },
/* 42 */ { L"%TVAR2% long long", L"%TVAR2% long long", 19, 18 },
/* 43 */ { L"%TVAR long long", L"abcdefghijklmnopqrstuv", 1, 16 },
/* 44 */ { L"%TVAR long long", L"%bcdefghijklmnopqrstuv", 2, 16 },
/* 45 */ { L"%TVAR long long", L"%Tcdefghijklmnopqrstuv", 3, 16 },
/* 46 */ { L"%TVAR long long", L"%TVAR long lonopqrstuv", 15, 16 },
/* 47 */ { L"%TVAR long long", L"%TVAR long long", 16, 16 },
/* 48 */ { L"%TVAR long long", L"%TVAR long long", 17, 16 },
};
RtlInitUnicodeString(&us_name, L"TVAR");
RtlInitUnicodeString(&us_value, L"WINE");
status = RtlSetEnvironmentVariable(NULL, &us_name, &us_value);
ok(status == STATUS_SUCCESS, "RtlSetEnvironmentVariable failed with %lx\n", status);
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
const struct test_info *test = &tests[i];
SIZE_T out_len;
HRESULT expected_status = test->count_in >= test->expected_count_out ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
wcscpy(buf, L"abcdefghijklmnopqrstuv");
status = pRtlExpandEnvironmentStrings(NULL, (WCHAR*)test->input, wcslen(test->input), buf, test->count_in, &out_len);
ok(out_len == test->expected_count_out, "Test %d: got %Iu\n", i, out_len);
ok(status == expected_status, "Test %d: Expected status %lx, got %lx\n", i, expected_status, status);
ok(!wcscmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_w(buf));
}
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
const struct test_info *test = &tests[i];
DWORD out_len;
HRESULT expected_status = test->count_in >= test->expected_count_out ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
us_src.Length = wcslen(test->input) * sizeof(WCHAR);
us_src.MaximumLength = us_src.Length;
us_src.Buffer = (WCHAR*)test->input;
us_dst.Length = test->count_in * sizeof(WCHAR);
us_dst.MaximumLength = us_dst.Length;
us_dst.Buffer = buf;
wcscpy(buf, L"abcdefghijklmnopqrstuv");
status = pRtlExpandEnvironmentStrings_U(NULL, &us_src, &us_dst, &out_len);
ok(out_len / sizeof(WCHAR) == test->expected_count_out, "Test %d: got %lu\n", i, out_len);
ok(status == expected_status, "Test %d: Expected status %lx, got %lx\n", i, expected_status, status);
ok(!wcscmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_w(buf));
}
status = RtlSetEnvironmentVariable(NULL, &us_name, NULL);
ok(status == STATUS_SUCCESS, "RtlSetEnvironmentVariable failed with %lx\n", status);
}
static WCHAR *get_params_string( RTL_USER_PROCESS_PARAMETERS *params, UNICODE_STRING *str )
{
if (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED) return str->Buffer;
return (WCHAR *)((char *)params + (UINT_PTR)str->Buffer);
}
static SIZE_T get_env_length( const WCHAR *env )
{
const WCHAR *end = env;
while (*end) end += wcslen(end) + 1;
return end + 1 - env;
}
static UINT_PTR align(UINT_PTR size, unsigned int alignment)
{
return (size + (alignment - 1)) & ~(alignment - 1);
}
static UINT_PTR check_string_( int line, RTL_USER_PROCESS_PARAMETERS *params, UNICODE_STRING *str,
const UNICODE_STRING *expect, UINT_PTR pos )
{
if (expect)
{
ok_(__FILE__,line)( str->Length == expect->Length, "wrong length %u/%u\n",
str->Length, expect->Length );
ok_(__FILE__,line)( str->MaximumLength == expect->MaximumLength,
"wrong maxlength %u/%u\n", str->MaximumLength, expect->MaximumLength );
}
if (!str->MaximumLength)
{
ok_(__FILE__,line)( str->Buffer == NULL, "buffer not null %p\n", str->Buffer );
return pos;
}
if (expect)
ok_(__FILE__,line)( (UINT_PTR)str->Buffer == align(pos, sizeof(void *)) ||
broken( (UINT_PTR)str->Buffer == align(pos, 4) ), /* win7 */
"wrong buffer %Ix/%Ix\n", (UINT_PTR)str->Buffer, pos );
else /* initial params are not aligned */
ok_(__FILE__,line)( (UINT_PTR)str->Buffer == pos,
"wrong buffer %Ix/%Ix\n", (UINT_PTR)str->Buffer, pos );
if (str->Length < str->MaximumLength)
{
WCHAR *ptr = get_params_string( params, str );
ok_(__FILE__,line)( !ptr[str->Length / sizeof(WCHAR)], "string not null-terminated %s\n",
wine_dbgstr_wn( ptr, str->MaximumLength / sizeof(WCHAR) ));
}
return (UINT_PTR)str->Buffer + str->MaximumLength;
}
#define check_string(params,str,expect,pos) check_string_(__LINE__,params,str,expect,pos)
static void test_process_params(void)
{
static WCHAR empty[] = {0};
static const UNICODE_STRING empty_str = { 0, sizeof(empty), empty };
static const UNICODE_STRING null_str = { 0, 0, NULL };
static WCHAR exeW[] = {'c',':','\\','f','o','o','.','e','x','e',0};
static WCHAR dummyW[] = {'d','u','m','m','y','1',0};
static WCHAR dummy_dirW[MAX_PATH] = {'d','u','m','m','y','2',0};
static WCHAR dummy_env[] = {'a','=','b',0,'c','=','d',0,0};
UNICODE_STRING image = { sizeof(exeW) - sizeof(WCHAR), sizeof(exeW), exeW };
UNICODE_STRING dummy = { sizeof(dummyW) - sizeof(WCHAR), sizeof(dummyW), dummyW };
UNICODE_STRING dummy_dir = { 6*sizeof(WCHAR), sizeof(dummy_dirW), dummy_dirW };
RTL_USER_PROCESS_PARAMETERS *params = NULL;
RTL_USER_PROCESS_PARAMETERS *cur_params = NtCurrentTeb()->Peb->ProcessParameters;
SIZE_T size;
WCHAR *str;
UINT_PTR pos;
NTSTATUS status = pRtlCreateProcessParameters( &params, &image, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL );
ok( !status, "failed %lx\n", status );
size = HeapSize( GetProcessHeap(), 0, params );
ok( size != ~(SIZE_T)0, "not a heap block %p\n", params );
ok( params->AllocationSize == params->Size,
"wrong AllocationSize %lx/%lx\n", params->AllocationSize, params->Size );
ok( params->Size < size, "wrong Size %lx/%Ix\n", params->Size, size );
ok( params->Flags == 0, "wrong Flags %lu\n", params->Flags );
ok( params->DebugFlags == 0, "wrong Flags %lu\n", params->DebugFlags );
ok( params->ConsoleHandle == 0, "wrong ConsoleHandle %p\n", params->ConsoleHandle );
ok( params->ConsoleFlags == 0, "wrong ConsoleFlags %lu\n", params->ConsoleFlags );
ok( params->hStdInput == 0, "wrong hStdInput %p\n", params->hStdInput );
ok( params->hStdOutput == 0, "wrong hStdOutput %p\n", params->hStdOutput );
ok( params->hStdError == 0, "wrong hStdError %p\n", params->hStdError );
ok( params->dwX == 0, "wrong dwX %lu\n", params->dwX );
ok( params->dwY == 0, "wrong dwY %lu\n", params->dwY );
ok( params->dwXSize == 0, "wrong dwXSize %lu\n", params->dwXSize );
ok( params->dwYSize == 0, "wrong dwYSize %lu\n", params->dwYSize );
ok( params->dwXCountChars == 0, "wrong dwXCountChars %lu\n", params->dwXCountChars );
ok( params->dwYCountChars == 0, "wrong dwYCountChars %lu\n", params->dwYCountChars );
ok( params->dwFillAttribute == 0, "wrong dwFillAttribute %lu\n", params->dwFillAttribute );
ok( params->dwFlags == 0, "wrong dwFlags %lu\n", params->dwFlags );
ok( params->wShowWindow == 0, "wrong wShowWindow %lu\n", params->wShowWindow );
pos = (UINT_PTR)params->CurrentDirectory.DosPath.Buffer;
ok( params->CurrentDirectory.DosPath.MaximumLength == MAX_PATH * sizeof(WCHAR),
"wrong length %x\n", params->CurrentDirectory.DosPath.MaximumLength );
pos = check_string( params, &params->CurrentDirectory.DosPath,
&cur_params->CurrentDirectory.DosPath, pos );
if (params->DllPath.MaximumLength)
pos = check_string( params, &params->DllPath, &cur_params->DllPath, pos );
else
pos = check_string( params, &params->DllPath, &null_str, pos );
pos = check_string( params, &params->ImagePathName, &image, pos );
pos = check_string( params, &params->CommandLine, &image, pos );
pos = check_string( params, &params->WindowTitle, &empty_str, pos );
pos = check_string( params, &params->Desktop, &empty_str, pos );
pos = check_string( params, &params->ShellInfo, &empty_str, pos );
pos = check_string( params, &params->RuntimeInfo, &null_str, pos );
pos = align(pos, 4);
ok( pos == params->Size || pos + 4 == params->Size,
"wrong pos %Ix/%lx\n", pos, params->Size );
pos = params->Size;
ok( (char *)params->Environment - (char *)params == (UINT_PTR)pos,
"wrong env %Ix/%Ix\n", (UINT_PTR)((char *)params->Environment - (char *)params), pos);
pos += get_env_length(params->Environment) * sizeof(WCHAR);
ok( align(pos, sizeof(void *)) == size ||
broken( align(pos, 4) == size ), "wrong size %Ix/%Ix\n", pos, size );
ok( params->EnvironmentSize == size - ((char *)params->Environment - (char *)params),
"wrong len %Ix/%Ix\n", params->EnvironmentSize,
size - ((char *)params->Environment - (char *)params) );
pRtlDestroyProcessParameters( params );
status = pRtlCreateProcessParameters( &params, &image, &dummy, &dummy, &dummy, dummy_env,
&dummy, &dummy, &dummy, &dummy );
ok( !status, "failed %lx\n", status );
size = HeapSize( GetProcessHeap(), 0, params );
ok( size != ~(SIZE_T)0, "not a heap block %p\n", params );
ok( params->AllocationSize == params->Size,
"wrong AllocationSize %lx/%lx\n", params->AllocationSize, params->Size );
ok( params->Size < size, "wrong Size %lx/%Ix\n", params->Size, size );
pos = (UINT_PTR)params->CurrentDirectory.DosPath.Buffer;
if (params->CurrentDirectory.DosPath.Length == dummy_dir.Length + sizeof(WCHAR))
{
/* win10 appends a backslash */
dummy_dirW[dummy_dir.Length / sizeof(WCHAR)] = '\\';
dummy_dir.Length += sizeof(WCHAR);
}
pos = check_string( params, &params->CurrentDirectory.DosPath, &dummy_dir, pos );
pos = check_string( params, &params->DllPath, &dummy, pos );
pos = check_string( params, &params->ImagePathName, &image, pos );
pos = check_string( params, &params->CommandLine, &dummy, pos );
pos = check_string( params, &params->WindowTitle, &dummy, pos );
pos = check_string( params, &params->Desktop, &dummy, pos );
pos = check_string( params, &params->ShellInfo, &dummy, pos );
pos = check_string( params, &params->RuntimeInfo, &dummy, pos );
pos = align(pos, 4);
ok( pos == params->Size || pos + 4 == params->Size,
"wrong pos %Ix/%lx\n", pos, params->Size );
pos = params->Size;
ok( (char *)params->Environment - (char *)params == pos,
"wrong env %Ix/%Ix\n", (UINT_PTR)((char *)params->Environment - (char *)params), pos);
pos += get_env_length(params->Environment) * sizeof(WCHAR);
ok( align(pos, sizeof(void *)) == size ||
broken( align(pos, 4) == size ), "wrong size %Ix/%Ix\n", pos, size );
ok( params->EnvironmentSize == size - ((char *)params->Environment - (char *)params),
"wrong len %Ix/%Ix\n", params->EnvironmentSize,
size - ((char *)params->Environment - (char *)params) );
pRtlDestroyProcessParameters( params );
/* also test the actual parameters of the current process */
ok( cur_params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED, "current params not normalized\n" );
size = HeapSize( GetProcessHeap(), 0, cur_params );
ok( size != ~(SIZE_T)0, "not a heap block %p\n", cur_params );
ok( cur_params->AllocationSize == cur_params->Size,
"wrong AllocationSize %lx/%lx\n", cur_params->AllocationSize, cur_params->Size );
ok( cur_params->Size == size, "wrong Size %lx/%Ix\n", cur_params->Size, size );
/* CurrentDirectory points outside the params, and DllPath may be null */
pos = (UINT_PTR)cur_params->DllPath.Buffer;
if (!pos) pos = (UINT_PTR)cur_params->ImagePathName.Buffer;
pos = check_string( cur_params, &cur_params->DllPath, NULL, pos );
pos = check_string( cur_params, &cur_params->ImagePathName, NULL, pos );
pos = check_string( cur_params, &cur_params->CommandLine, NULL, pos );
pos = check_string( cur_params, &cur_params->WindowTitle, NULL, pos );
pos = check_string( cur_params, &cur_params->Desktop, NULL, pos );
pos = check_string( cur_params, &cur_params->ShellInfo, NULL, pos );
pos = check_string( cur_params, &cur_params->RuntimeInfo, NULL, pos );
/* environment may follow */
str = (WCHAR *)pos;
if (pos - (UINT_PTR)cur_params < cur_params->Size) str += get_env_length(str);
ok( (char *)str == (char *)cur_params + cur_params->Size,
"wrong end ptr %p/%p\n", str, (char *)cur_params + cur_params->Size );
/* initial environment is a separate block */
ok( (char *)initial_env < (char *)cur_params || (char *)initial_env >= (char *)cur_params + size,
"initial environment inside block %p / %p\n", cur_params, initial_env );
size = HeapSize( GetProcessHeap(), 0, initial_env );
ok( size != ~(SIZE_T)0, "env is not a heap block %p / %p\n", cur_params, initial_env );
ok( cur_params->EnvironmentSize == size,
"wrong len %Ix/%Ix\n", cur_params->EnvironmentSize, size );
}
static NTSTATUS set_env_var(WCHAR **env, const WCHAR *var, const WCHAR *value)
{
UNICODE_STRING var_string, value_string;
RtlInitUnicodeString(&var_string, var);
if (value) RtlInitUnicodeString(&value_string, value);
return RtlSetEnvironmentVariable(env, &var_string, value ? &value_string : NULL);
}
static void check_env_var_(int line, const char *var, const char *value)
{
char buffer[20];
DWORD size = GetEnvironmentVariableA(var, buffer, sizeof(buffer));
if (value)
{
ok_(__FILE__, line)(size == strlen(value), "wrong size %lu\n", size);
ok_(__FILE__, line)(!strcmp(buffer, value), "wrong value %s\n", debugstr_a(buffer));
}
else
{
ok_(__FILE__, line)(!size, "wrong size %lu\n", size);
ok_(__FILE__, line)(GetLastError() == ERROR_ENVVAR_NOT_FOUND, "got error %lu\n", GetLastError());
}
}
#define check_env_var(a, b) check_env_var_(__LINE__, a, b)
static void test_RtlSetCurrentEnvironment(void)
{
NTSTATUS status;
WCHAR *old_env, *env, *prev;
BOOL ret;
SIZE_T size;
status = RtlCreateEnvironment(FALSE, &env);
ok(!status, "got %#lx\n", status);
ret = SetEnvironmentVariableA("testenv1", "heis");
ok(ret, "got error %lu\n", GetLastError());
ret = SetEnvironmentVariableA("testenv2", "dyo");
ok(ret, "got error %lu\n", GetLastError());
status = set_env_var(&env, L"testenv1", L"unus");
ok(!status, "got %#lx\n", status);
status = set_env_var(&env, L"testenv3", L"tres");
ok(!status, "got %#lx\n", status);
old_env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == get_env_length(old_env) * sizeof(WCHAR),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, old_env ),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
RtlSetCurrentEnvironment(env, &prev);
ok(prev == old_env, "got wrong previous env %p\n", prev);
ok(NtCurrentTeb()->Peb->ProcessParameters->Environment == env, "got wrong current env\n");
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == get_env_length(env) * sizeof(WCHAR),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
check_env_var("testenv1", "unus");
check_env_var("testenv2", NULL);
check_env_var("testenv3", "tres");
check_env_var("PATH", NULL);
env = HeapReAlloc( GetProcessHeap(), 0, env, HeapSize( GetProcessHeap(), 0, env) + 120 );
RtlSetCurrentEnvironment(env, &prev);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
RtlSetCurrentEnvironment(old_env, NULL);
ok(NtCurrentTeb()->Peb->ProcessParameters->Environment == old_env, "got wrong current env\n");
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == get_env_length(old_env) * sizeof(WCHAR),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, old_env ),
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
check_env_var("testenv1", "heis");
check_env_var("testenv2", "dyo");
check_env_var("testenv3", NULL);
env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
size = get_env_length(env) * sizeof(WCHAR);
ok( NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == size,
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize );
ok( size == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %Iu / %Iu\n", size, HeapSize( GetProcessHeap(), 0, env ));
SetEnvironmentVariableA("testenv1", NULL);
SetEnvironmentVariableA("testenv2", NULL);
env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
ok( NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == size,
"got wrong size %Iu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize );
ok( size == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %Iu / %Iu\n", size, HeapSize( GetProcessHeap(), 0, env ));
ok( size > get_env_length(env) * sizeof(WCHAR), "got wrong size %Iu\n", size );
}
static void query_env_var_(int line, WCHAR *env, const WCHAR *var, const WCHAR *value)
{
UNICODE_STRING var_string, value_string;
WCHAR value_buffer[9];
NTSTATUS status;
RtlInitUnicodeString(&var_string, var);
value_string.Buffer = value_buffer;
value_string.MaximumLength = sizeof(value_buffer);
status = RtlQueryEnvironmentVariable_U(env, &var_string, &value_string);
if (value)
{
ok_(__FILE__, line)(!status, "got %#lx\n", status);
ok_(__FILE__, line)(value_string.Length/sizeof(WCHAR) == wcslen(value),
"wrong size %Iu\n", value_string.Length/sizeof(WCHAR));
ok_(__FILE__, line)(!wcscmp(value_string.Buffer, value), "wrong value %s\n", debugstr_w(value_string.Buffer));
}
else
ok_(__FILE__, line)(status == STATUS_VARIABLE_NOT_FOUND, "got %#lx\n", status);
}
#define query_env_var(a, b, c) query_env_var_(__LINE__, a, b, c)
static void test_RtlSetEnvironmentVariable(void)
{
NTSTATUS status;
WCHAR *env;
status = RtlCreateEnvironment(FALSE, &env);
ok(!status, "got %#lx\n", status);
status = set_env_var(&env, L"cat", L"dog");
ok(!status, "got %#lx\n", status);
query_env_var(env, L"cat", L"dog");
status = set_env_var(&env, L"cat", L"horse");
ok(!status, "got %#lx\n", status);
query_env_var(env, L"cat", L"horse");
status = set_env_var(&env, L"cat", NULL);
ok(!status, "got %#lx\n", status);
query_env_var(env, L"cat", NULL);
status = set_env_var(&env, L"cat", NULL);
ok(!status, "got %#lx\n", status);
status = set_env_var(&env, L"foo", L"meouw");
ok(!status, "got %#lx\n", status);
query_env_var(env, L"foo", L"meouw");
status = set_env_var(&env, L"fOo", NULL);
ok(!status, "got %#lx\n", status);
query_env_var(env, L"foo", NULL);
status = set_env_var(&env, L"horse", NULL);
ok(!status, "got %#lx\n", status);
query_env_var(env, L"horse", NULL);
status = set_env_var(&env, L"me=too", L"also");
ok(status == STATUS_INVALID_PARAMETER, "got %#lx\n", status);
status = set_env_var(&env, L"me", L"too=also");
ok(!status, "got %#lx\n", status);
query_env_var(env, L"me", L"too=also");
status = set_env_var(&env, L"=too", L"also");
ok(!status, "got %#lx\n", status);
query_env_var(env, L"=too", L"also");
status = set_env_var(&env, L"=", L"also");
ok(!status, "got %#lx\n", status);
query_env_var(env, L"=", L"also");
status = RtlDestroyEnvironment(env);
ok(!status, "got %#lx\n", status);
}
START_TEST(env)
{
HMODULE mod = GetModuleHandleA("ntdll.dll");
if (!mod)
{
win_skip("Not running on NT, skipping tests\n");
return;
}
initial_env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
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");
pRtlQueryEnvironmentVariable = (void*)GetProcAddress(mod, "RtlQueryEnvironmentVariable");
pRtlExpandEnvironmentStrings = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings");
pRtlExpandEnvironmentStrings_U = (void*)GetProcAddress(mod, "RtlExpandEnvironmentStrings_U");
pRtlCreateProcessParameters = (void*)GetProcAddress(mod, "RtlCreateProcessParameters");
pRtlDestroyProcessParameters = (void*)GetProcAddress(mod, "RtlDestroyProcessParameters");
if (pRtlQueryEnvironmentVariable_U)
testQuery();
if (pRtlSetEnvironmentVariable)
testSet();
if (pRtlExpandEnvironmentStrings_U)
testExpand();
testQuery();
testExpand();
test_process_params();
test_RtlSetCurrentEnvironment();
test_RtlSetEnvironmentVariable();
test_RtlExpandEnvironmentStrings();
}
+445 -5
View File
@@ -47,6 +47,10 @@
* (of course older Windows platforms will fail to pass the strict mode)
*/
#ifdef __REACTOS__
/* This isn't defined in the Windows SDK but Wine needs it anyways. */
#define STATUS_VRF_CFG_ENABLED ((NTSTATUS)0xC000049F)
#endif
static ULONG (WINAPI *pRtlNtStatusToDosError)(NTSTATUS Status);
static int strict;
@@ -75,7 +79,7 @@ static void cmp_call(NTSTATUS win_nt, ULONG win32, const char* message)
err = pRtlNtStatusToDosError(win_nt);
ok(err == win32,
"%s (%x): got %u, expected %u\n",
"%s (%lx): got %lu, expected %lu\n",
message, win_nt, err, win32);
}
@@ -86,7 +90,7 @@ static void cmp_call2(NTSTATUS win_nt, ULONG win32, const char* message)
err = pRtlNtStatusToDosError(win_nt);
ok(err == win32 ||
(!strict && err == ERROR_MR_MID_NOT_FOUND),
"%s (%x): got %u, expected %u (or MID_NOT_FOUND)\n",
"%s (%lx): got %lu, expected %lu (or MID_NOT_FOUND)\n",
message, win_nt, err, win32);
}
@@ -96,7 +100,7 @@ static void cmp_call3(NTSTATUS win_nt, ULONG win32_1, ULONG win32_2, const char*
err = pRtlNtStatusToDosError(win_nt);
ok(err == win32_1 || (!strict && err == win32_2),
"%s (%x): got %u, expected %u or %u\n",
"%s (%lx): got %lu, expected %lu or %lu\n",
message, win_nt, err, win32_1, win32_2);
}
@@ -107,7 +111,7 @@ static void cmp_call4(NTSTATUS win_nt, ULONG win32_1, ULONG win32_2, const char*
err = pRtlNtStatusToDosError(win_nt);
ok(err == win32_1 ||
(!strict && (err == win32_2 || err == ERROR_MR_MID_NOT_FOUND)),
"%s (%x): got %u, expected %u or %u\n",
"%s (%lx): got %lu, expected %lu or %lu\n",
message, win_nt, err, win32_1, win32_2);
}
@@ -247,7 +251,7 @@ static void run_error_tests(void)
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);
cmp3(STATUS_NO_SUCH_DEVICE, ERROR_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);
@@ -542,6 +546,8 @@ static void run_error_tests(void)
cmp2(STATUS_WAKE_SYSTEM_DEBUGGER, ERROR_WAKE_SYSTEM_DEBUGGER);
cmp2(DBG_EXCEPTION_HANDLED, ERROR_DBG_EXCEPTION_HANDLED);
cmp2(DBG_CONTINUE, ERROR_DBG_CONTINUE);
cmp2(DBG_REPLY_LATER, ERROR_DBG_REPLY_LATER);
cmp2(DBG_UNABLE_TO_PROVIDE_HANDLE, ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE);
cmp2(DBG_TERMINATE_THREAD, ERROR_DBG_TERMINATE_THREAD);
cmp2(DBG_TERMINATE_PROCESS, ERROR_DBG_TERMINATE_PROCESS);
cmp2(DBG_CONTROL_C, ERROR_DBG_CONTROL_C);
@@ -549,6 +555,7 @@ static void run_error_tests(void)
cmp2(DBG_RIPEXCEPTION, ERROR_DBG_RIPEXCEPTION);
cmp2(DBG_CONTROL_BREAK, ERROR_DBG_CONTROL_BREAK);
cmp2(DBG_COMMAND_EXCEPTION, ERROR_DBG_COMMAND_EXCEPTION);
cmp2(DBG_PRINTEXCEPTION_WIDE_C, ERROR_DBG_PRINTEXCEPTION_C);
cmp2(DBG_EXCEPTION_NOT_HANDLED, ERROR_DBG_EXCEPTION_NOT_HANDLED);
cmp2(STATUS_DEBUG_ATTACH_FAILED, ERROR_DEBUG_ATTACH_FAILED);
cmp2(STATUS_VALIDATE_CONTINUE, ERROR_VALIDATE_CONTINUE);
@@ -1134,6 +1141,439 @@ static void run_error_tests(void)
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);
cmp2(STATUS_NOTHING_TO_TERMINATE, ERROR_NOTHING_TO_TERMINATE);
cmp2(STATUS_PROCESS_NOT_IN_JOB, ERROR_PROCESS_NOT_IN_JOB);
cmp2(STATUS_PROCESS_IN_JOB, ERROR_PROCESS_IN_JOB);
cmp2(STATUS_VOLSNAP_HIBERNATE_READY, ERROR_VOLSNAP_HIBERNATE_READY);
cmp2(STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY, ERROR_FSFILTER_OP_COMPLETED_SUCCESSFULLY);
cmp2(STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED, ERROR_INTERRUPT_VECTOR_ALREADY_CONNECTED);
cmp2(STATUS_INTERRUPT_STILL_CONNECTED, ERROR_INTERRUPT_STILL_CONNECTED);
cmp2(STATUS_WX86_UNSIMULATE, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_CONTINUE, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_SINGLE_STEP, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_BREAKPOINT, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_EXCEPTION_CONTINUE, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_EXCEPTION_LASTCHANCE, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_EXCEPTION_CHAIN, ERROR_WX86_WARNING);
cmp2(STATUS_WX86_CREATEWX86TIB, ERROR_WX86_WARNING);
cmp2(STATUS_DRIVERS_LEAKING_LOCKED_PAGES, ERROR_DRIVERS_LEAKING_LOCKED_PAGES);
cmp2(STATUS_MESSAGE_RETRIEVED, ERROR_INTERNAL_ERROR);
cmp2(STATUS_SYSTEM_POWERSTATE_TRANSITION, ERROR_SYSTEM_POWERSTATE_TRANSITION);
cmp2(STATUS_ALPC_CHECK_COMPLETION_LIST, ERROR_INTERNAL_ERROR);
cmp2(STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION, ERROR_SYSTEM_POWERSTATE_COMPLEX_TRANSITION);
cmp2(STATUS_ACCESS_AUDIT_BY_POLICY, ERROR_ACCESS_AUDIT_BY_POLICY);
cmp2(STATUS_ABANDON_HIBERFILE, ERROR_ABANDON_HIBERFILE);
cmp2(STATUS_BIZRULES_NOT_ENABLED, ERROR_BIZRULES_NOT_ENABLED);
cmp2(STATUS_IMAGE_AT_DIFFERENT_BASE, ERROR_IMAGE_AT_DIFFERENT_BASE);
cmp2(STATUS_STOPPED_ON_SYMLINK, ERROR_STOPPED_ON_SYMLINK);
cmp2(STATUS_CANNOT_GRANT_REQUESTED_OPLOCK, ERROR_CANNOT_GRANT_REQUESTED_OPLOCK);
cmp2(STATUS_NO_ACE_CONDITION, ERROR_NO_ACE_CONDITION);
cmp2(STATUS_DEVICE_SUPPORT_IN_PROGRESS, ERROR_DEVICE_SUPPORT_IN_PROGRESS);
cmp2(STATUS_DEVICE_POWER_CYCLE_REQUIRED, STG_S_POWER_CYCLE_REQUIRED);
cmp2(STATUS_NO_WORK_DONE, ERROR_NO_WORK_DONE);
cmp2(SEC_E_UNFINISHED_CONTEXT_DELETED, ERROR_CONTEXT_EXPIRED);
cmp2(SEC_E_SHUTDOWN_IN_PROGRESS, ERROR_SHUTDOWN_IN_PROGRESS);
cmp2(SEC_E_CERT_WRONG_USAGE, ERROR_BAD_TOKEN_TYPE);
cmp2(SEC_E_INVALID_PARAMETER, ERROR_INVALID_PARAMETER);
cmp2(SEC_E_DELEGATION_POLICY, ERROR_ACCESS_DENIED);
cmp2(SEC_E_POLICY_NLTM_ONLY, ERROR_ACCESS_DENIED);
cmp2(SEC_E_MUTUAL_AUTH_FAILED, ERROR_MUTUAL_AUTH_FAILED);
cmp2(SEC_E_APPLICATION_PROTOCOL_MISMATCH, ERROR_NOT_SUPPORTED);
cmp2(STATUS_TIMER_NOT_CANCELED, ERROR_TIMER_NOT_CANCELED);
cmp2(STATUS_ILLEGAL_INSTRUCTION, STATUS_ILLEGAL_INSTRUCTION);
cmp2(STATUS_UNWIND, ERROR_UNWIND);
cmp2(STATUS_BAD_STACK, ERROR_BAD_STACK);
cmp2(STATUS_INVALID_UNWIND_TARGET, ERROR_INVALID_UNWIND_TARGET);
cmp2(STATUS_INVALID_PORT_ATTRIBUTES, ERROR_INVALID_PORT_ATTRIBUTES);
cmp2(STATUS_PORT_MESSAGE_TOO_LONG, ERROR_PORT_MESSAGE_TOO_LONG);
cmp2(STATUS_INVALID_QUOTA_LOWER, ERROR_INVALID_QUOTA_LOWER);
cmp2(STATUS_PORT_DO_NOT_DISTURB, RPC_S_DO_NOT_DISTURB);
cmp2(STATUS_DEVICE_ALREADY_ATTACHED, ERROR_DEVICE_ALREADY_ATTACHED);
cmp2(STATUS_INSTRUCTION_MISALIGNMENT, ERROR_INSTRUCTION_MISALIGNMENT);
cmp2(STATUS_PROFILING_NOT_STARTED, ERROR_PROFILING_NOT_STARTED);
cmp2(STATUS_PROFILING_NOT_STOPPED, ERROR_PROFILING_NOT_STOPPED);
cmp2(STATUS_COULD_NOT_INTERPRET, ERROR_COULD_NOT_INTERPRET);
cmp2(STATUS_PROFILING_AT_LIMIT, ERROR_PROFILING_AT_LIMIT);
cmp2(STATUS_CANT_WAIT, ERROR_CANT_WAIT);
cmp2(STATUS_CANT_TERMINATE_SELF, ERROR_CANT_TERMINATE_SELF);
cmp2(STATUS_UNEXPECTED_IO_ERROR, ERROR_IO_DEVICE);
cmp2(STATUS_UNEXPECTED_MM_CREATE_ERR, ERROR_UNEXPECTED_MM_CREATE_ERR);
cmp2(STATUS_UNEXPECTED_MM_MAP_ERROR, ERROR_UNEXPECTED_MM_MAP_ERROR);
cmp2(STATUS_UNEXPECTED_MM_EXTEND_ERR, ERROR_UNEXPECTED_MM_EXTEND_ERR);
cmp2(STATUS_BAD_FUNCTION_TABLE, ERROR_BAD_FUNCTION_TABLE);
cmp2(STATUS_NO_GUID_TRANSLATION, ERROR_NO_GUID_TRANSLATION);
cmp2(STATUS_ABIOS_NOT_PRESENT, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_LID_NOT_EXIST, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_LID_ALREADY_OWNED, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_NOT_LID_OWNER, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_INVALID_COMMAND, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_INVALID_LID, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_SELECTOR_NOT_AVAILABLE, ERROR_ABIOS_ERROR);
cmp2(STATUS_ABIOS_INVALID_SELECTOR, ERROR_ABIOS_ERROR);
cmp2(STATUS_ILL_FORMED_SERVICE_ENTRY, ERROR_SERVICE_NOT_FOUND);
cmp2(STATUS_IMAGE_ALREADY_LOADED_AS_DLL, ERROR_SERVICE_ALREADY_RUNNING);
cmp2(STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING, ERROR_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING);
cmp2(STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME, ERROR_SHORT_NAMES_NOT_ENABLED_ON_VOLUME);
cmp2(STATUS_SECURITY_STREAM_IS_INCONSISTENT, ERROR_SECURITY_STREAM_IS_INCONSISTENT);
cmp2(STATUS_INVALID_LOCK_RANGE, ERROR_INVALID_LOCK_RANGE);
cmp2(STATUS_INVALID_ACE_CONDITION, ERROR_INVALID_ACE_CONDITION);
cmp2(STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT, ERROR_IMAGE_SUBSYSTEM_NOT_PRESENT);
cmp2(STATUS_NOTIFICATION_GUID_ALREADY_DEFINED, ERROR_NOTIFICATION_GUID_ALREADY_DEFINED);
cmp2(STATUS_INVALID_EXCEPTION_HANDLER, ERROR_INVALID_EXCEPTION_HANDLER);
cmp2(STATUS_DUPLICATE_PRIVILEGES, ERROR_DUPLICATE_PRIVILEGES);
cmp2(STATUS_NOT_ALLOWED_ON_SYSTEM_FILE, ERROR_NOT_ALLOWED_ON_SYSTEM_FILE);
cmp2(STATUS_REPAIR_NEEDED, ERROR_DATA_LOST_REPAIR);
cmp2(STATUS_QUOTA_NOT_ENABLED, ERROR_NOT_SUPPORTED);
cmp2(STATUS_NO_APPLICATION_PACKAGE, APPMODEL_ERROR_NO_PACKAGE);
cmp2(STATUS_FILE_METADATA_OPTIMIZATION_IN_PROGRESS, ERROR_FILE_METADATA_OPTIMIZATION_IN_PROGRESS);
cmp2(STATUS_NOT_SAME_OBJECT, ERROR_NOT_SAME_OBJECT);
cmp2(STATUS_FATAL_MEMORY_EXHAUSTION, ERROR_NOT_ENOUGH_MEMORY);
cmp2(STATUS_ERROR_PROCESS_NOT_IN_JOB, ERROR_PROCESS_NOT_IN_JOB);
cmp2(STATUS_CPU_SET_INVALID, ERROR_CPU_SET_INVALID);
cmp2(STATUS_NETWORK_OPEN_RESTRICTION, ERROR_NETWORK_ACCESS_DENIED);
cmp2(STATUS_RECOVERY_FAILURE, ERROR_RECOVERY_FAILURE);
cmp2(STATUS_WX86_INTERNAL_ERROR, ERROR_WX86_ERROR);
cmp2(STATUS_WX86_FLOAT_STACK_CHECK, ERROR_WX86_ERROR);
cmp2(STATUS_PWD_TOO_LONG, ERROR_PWD_TOO_LONG);
cmp2(STATUS_STOWED_EXCEPTION, ERROR_INTERNAL_ERROR);
cmp2(STATUS_CONTEXT_STOWED_EXCEPTION, ERROR_INTERNAL_ERROR);
cmp2(STATUS_DS_RIDMGR_DISABLED, ERROR_DS_RIDMGR_DISABLED);
cmp2(STATUS_POWER_STATE_INVALID, ERROR_NOT_READY);
cmp2(STATUS_PASSWORD_CHANGE_REQUIRED, ERROR_PASSWORD_CHANGE_REQUIRED);
cmp2(STATUS_LOST_MODE_LOGON_RESTRICTION, ERROR_LOST_MODE_LOGON_RESTRICTION);
cmp2(STATUS_DEBUGGER_INACTIVE, ERROR_DEBUGGER_INACTIVE);
cmp2(STATUS_APPHELP_BLOCK, ERROR_APPHELP_BLOCK);
cmp2(STATUS_NO_SECRETS, ERROR_NO_SECRETS);
cmp2(STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY, ERROR_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY);
cmp2(STATUS_FAILED_STACK_SWITCH, ERROR_NOT_ENOUGH_MEMORY);
cmp2(STATUS_HEAP_CORRUPTION, ERROR_INTERNAL_ERROR);
cmp2(STATUS_DRIVER_FAILED_PRIOR_UNLOAD, ERROR_DRIVER_FAILED_PRIOR_UNLOAD);
cmp2(STATUS_SMARTCARD_SILENT_CONTEXT, NTE_SILENT_CONTEXT);
cmp2(STATUS_PER_USER_TRUST_QUOTA_EXCEEDED, ERROR_PER_USER_TRUST_QUOTA_EXCEEDED);
cmp2(STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED, ERROR_ALL_USER_TRUST_QUOTA_EXCEEDED);
cmp2(STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED, ERROR_USER_DELETE_TRUST_QUOTA_EXCEEDED);
cmp2(STATUS_DS_NAME_NOT_UNIQUE, ERROR_DS_NAME_NOT_UNIQUE);
cmp2(STATUS_DS_DUPLICATE_ID_FOUND, ERROR_DS_DUPLICATE_ID_FOUND);
cmp2(STATUS_DS_GROUP_CONVERSION_ERROR, ERROR_DS_GROUP_CONVERSION_ERROR);
cmp2(STATUS_VOLSNAP_PREPARE_HIBERNATE, ERROR_VOLSNAP_PREPARE_HIBERNATE);
cmp2(STATUS_USER2USER_REQUIRED, ERROR_LOGON_FAILURE);
cmp2(STATUS_STACK_BUFFER_OVERRUN, ERROR_STACK_BUFFER_OVERRUN);
cmp2(STATUS_NO_S4U_PROT_SUPPORT, SEC_E_NO_S4U_PROT_SUPPORT);
cmp2(STATUS_CROSSREALM_DELEGATION_FAILURE, SEC_E_CROSSREALM_DELEGATION_FAILURE);
cmp2(STATUS_REVOCATION_OFFLINE_KDC, SEC_E_REVOCATION_OFFLINE_KDC);
cmp2(STATUS_ISSUING_CA_UNTRUSTED_KDC, SEC_E_ISSUING_CA_UNTRUSTED_KDC);
cmp2(STATUS_KDC_CERT_EXPIRED, SEC_E_KDC_CERT_EXPIRED);
cmp2(STATUS_KDC_CERT_REVOKED, SEC_E_KDC_CERT_REVOKED);
cmp2(STATUS_PARAMETER_QUOTA_EXCEEDED, ERROR_PARAMETER_QUOTA_EXCEEDED);
cmp2(STATUS_HIBERNATION_FAILURE, ERROR_HIBERNATION_FAILURE);
cmp2(STATUS_DELAY_LOAD_FAILED, ERROR_DELAY_LOAD_FAILED);
cmp2(STATUS_AUTHENTICATION_FIREWALL_FAILED, ERROR_AUTHENTICATION_FIREWALL_FAILED);
cmp2(STATUS_VDM_DISALLOWED, ERROR_VDM_DISALLOWED);
cmp2(STATUS_HUNG_DISPLAY_DRIVER_THREAD, ERROR_HUNG_DISPLAY_DRIVER_THREAD);
cmp2(STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE, ERROR_NOT_ENOUGH_MEMORY);
cmp2(STATUS_INVALID_CRUNTIME_PARAMETER, ERROR_INVALID_CRUNTIME_PARAMETER);
cmp2(STATUS_NTLM_BLOCKED, ERROR_NTLM_BLOCKED);
cmp2(STATUS_DS_SRC_SID_EXISTS_IN_FOREST, ERROR_DS_SRC_SID_EXISTS_IN_FOREST);
cmp2(STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST, ERROR_DS_DOMAIN_NAME_EXISTS_IN_FOREST);
cmp2(STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST, ERROR_DS_FLAT_NAME_EXISTS_IN_FOREST);
cmp2(STATUS_INVALID_USER_PRINCIPAL_NAME, ERROR_INVALID_USER_PRINCIPAL_NAME);
cmp2(STATUS_FATAL_USER_CALLBACK_EXCEPTION, ERROR_FATAL_APP_EXIT);
cmp2(STATUS_ASSERTION_FAILURE, ERROR_ASSERTION_FAILURE);
cmp2(STATUS_VERIFIER_STOP, ERROR_VERIFIER_STOP);
cmp2(STATUS_CALLBACK_POP_STACK, ERROR_CALLBACK_POP_STACK);
cmp2(STATUS_INCOMPATIBLE_DRIVER_BLOCKED, ERROR_DRIVER_BLOCKED);
cmp2(STATUS_HIVE_UNLOADED, ERROR_KEY_DELETED);
cmp2(STATUS_COMPRESSION_DISABLED, ERROR_COMPRESSION_DISABLED);
cmp2(STATUS_FILE_SYSTEM_LIMITATION, ERROR_FILE_SYSTEM_LIMITATION);
cmp2(STATUS_INVALID_IMAGE_HASH, ERROR_INVALID_IMAGE_HASH);
cmp2(STATUS_NOT_CAPABLE, ERROR_NOT_CAPABLE);
cmp2(STATUS_REQUEST_OUT_OF_SEQUENCE, ERROR_REQUEST_OUT_OF_SEQUENCE);
cmp2(STATUS_IMPLEMENTATION_LIMIT, ERROR_IMPLEMENTATION_LIMIT);
cmp2(STATUS_NO_SECURITY_CONTEXT, SEC_E_NO_CONTEXT);
cmp2(STATUS_PKU2U_CERT_FAILURE, SEC_E_PKU2U_CERT_FAILURE);
cmp2(STATUS_BEYOND_VDL, ERROR_BEYOND_VDL);
cmp2(STATUS_ENCOUNTERED_WRITE_IN_PROGRESS, ERROR_BUSY);
cmp2(STATUS_PTE_CHANGED, ERROR_BUSY);
cmp2(STATUS_PURGE_FAILED, ERROR_USER_MAPPED_FILE);
cmp2(STATUS_CRED_REQUIRES_CONFIRMATION, ERROR_CRED_REQUIRES_CONFIRMATION);
cmp2(STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE, ERROR_CS_ENCRYPTION_INVALID_SERVER_RESPONSE);
cmp2(STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER, ERROR_CS_ENCRYPTION_UNSUPPORTED_SERVER);
cmp2(STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE, ERROR_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE);
cmp2(STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE, ERROR_CS_ENCRYPTION_NEW_ENCRYPTED_FILE);
cmp2(STATUS_CS_ENCRYPTION_FILE_NOT_CSE, ERROR_CS_ENCRYPTION_FILE_NOT_CSE);
cmp2(STATUS_INVALID_LABEL, ERROR_INVALID_LABEL);
cmp2(STATUS_DRIVER_PROCESS_TERMINATED, ERROR_DRIVER_PROCESS_TERMINATED);
cmp2(STATUS_AMBIGUOUS_SYSTEM_DEVICE, ERROR_AMBIGUOUS_SYSTEM_DEVICE);
cmp2(STATUS_SYSTEM_DEVICE_NOT_FOUND, ERROR_SYSTEM_DEVICE_NOT_FOUND);
cmp2(STATUS_RESTART_BOOT_APPLICATION, ERROR_RESTART_APPLICATION);
cmp2(STATUS_INSUFFICIENT_NVRAM_RESOURCES, ERROR_NO_NVRAM_RESOURCES);
cmp2(STATUS_INVALID_SESSION, ERROR_INVALID_HANDLE);
cmp2(STATUS_THREAD_ALREADY_IN_SESSION, ERROR_INVALID_PARAMETER);
cmp2(STATUS_THREAD_NOT_IN_SESSION, ERROR_INVALID_PARAMETER);
cmp2(STATUS_INVALID_WEIGHT, ERROR_INVALID_PARAMETER);
cmp2(STATUS_REQUEST_PAUSED, ERROR_REQUEST_PAUSED);
cmp2(STATUS_NO_RANGES_PROCESSED, ERROR_NO_RANGES_PROCESSED);
cmp2(STATUS_DISK_RESOURCES_EXHAUSTED, ERROR_DISK_RESOURCES_EXHAUSTED);
cmp2(STATUS_NEEDS_REMEDIATION, ERROR_NEEDS_REMEDIATION);
cmp2(STATUS_DEVICE_FEATURE_NOT_SUPPORTED, ERROR_DEVICE_FEATURE_NOT_SUPPORTED);
cmp2(STATUS_DEVICE_UNREACHABLE, ERROR_DEVICE_UNREACHABLE);
cmp2(STATUS_INVALID_TOKEN, ERROR_INVALID_TOKEN);
cmp2(STATUS_SERVER_UNAVAILABLE, ERROR_NETNAME_DELETED);
cmp2(STATUS_FILE_NOT_AVAILABLE, ERROR_SHARING_VIOLATION);
cmp2(STATUS_DEVICE_INSUFFICIENT_RESOURCES, ERROR_DEVICE_NO_RESOURCES);
cmp2(STATUS_PACKAGE_UPDATING, ERROR_PACKAGE_UPDATING);
cmp2(STATUS_NOT_READ_FROM_COPY, ERROR_NOT_READ_FROM_COPY);
cmp2(STATUS_FT_WRITE_FAILURE, ERROR_FT_WRITE_FAILURE);
cmp2(STATUS_FT_DI_SCAN_REQUIRED, ERROR_FT_DI_SCAN_REQUIRED);
cmp2(STATUS_OBJECT_NOT_EXTERNALLY_BACKED, ERROR_OBJECT_NOT_EXTERNALLY_BACKED);
cmp2(STATUS_EXTERNAL_BACKING_PROVIDER_UNKNOWN, ERROR_EXTERNAL_BACKING_PROVIDER_UNKNOWN);
cmp2(STATUS_COMPRESSION_NOT_BENEFICIAL, ERROR_COMPRESSION_NOT_BENEFICIAL);
cmp2(STATUS_DATA_CHECKSUM_ERROR, ERROR_DATA_CHECKSUM_ERROR);
cmp2(STATUS_INTERMIXED_KERNEL_EA_OPERATION, ERROR_INTERMIXED_KERNEL_EA_OPERATION);
cmp2(STATUS_TRIM_READ_ZERO_NOT_SUPPORTED, ERROR_FILE_LEVEL_TRIM_NOT_SUPPORTED);
cmp2(STATUS_TOO_MANY_SEGMENT_DESCRIPTORS, ERROR_TOO_MANY_DESCRIPTORS);
cmp2(STATUS_INVALID_OFFSET_ALIGNMENT, ERROR_OFFSET_ALIGNMENT_VIOLATION);
cmp2(STATUS_INVALID_FIELD_IN_PARAMETER_LIST, ERROR_INVALID_FIELD_IN_PARAMETER_LIST);
cmp2(STATUS_OPERATION_IN_PROGRESS, ERROR_OPERATION_IN_PROGRESS);
cmp2(STATUS_INVALID_INITIATOR_TARGET_PATH, ERROR_BAD_DEVICE_PATH);
cmp2(STATUS_SCRUB_DATA_DISABLED, ERROR_SCRUB_DATA_DISABLED);
cmp2(STATUS_NOT_REDUNDANT_STORAGE, ERROR_NOT_REDUNDANT_STORAGE);
cmp2(STATUS_RESIDENT_FILE_NOT_SUPPORTED, ERROR_RESIDENT_FILE_NOT_SUPPORTED);
cmp2(STATUS_COMPRESSED_FILE_NOT_SUPPORTED, ERROR_COMPRESSED_FILE_NOT_SUPPORTED);
cmp2(STATUS_DIRECTORY_NOT_SUPPORTED, ERROR_DIRECTORY_NOT_SUPPORTED);
cmp2(STATUS_IO_OPERATION_TIMEOUT, ERROR_TIMEOUT);
cmp2(STATUS_SYSTEM_NEEDS_REMEDIATION, ERROR_SYSTEM_NEEDS_REMEDIATION);
cmp2(STATUS_APPX_INTEGRITY_FAILURE_CLR_NGEN, ERROR_APPX_INTEGRITY_FAILURE_CLR_NGEN);
cmp2(STATUS_SHARE_UNAVAILABLE, ERROR_NETNAME_DELETED);
cmp2(STATUS_APISET_NOT_HOSTED, ERROR_MOD_NOT_FOUND);
cmp2(STATUS_APISET_NOT_PRESENT, ERROR_MOD_NOT_FOUND);
cmp2(STATUS_DEVICE_HARDWARE_ERROR, ERROR_DEVICE_HARDWARE_ERROR);
cmp2(STATUS_FIRMWARE_SLOT_INVALID, STG_E_FIRMWARE_SLOT_INVALID);
cmp2(STATUS_FIRMWARE_IMAGE_INVALID, STG_E_FIRMWARE_IMAGE_INVALID);
cmp2(STATUS_STORAGE_TOPOLOGY_ID_MISMATCH, ERROR_STORAGE_TOPOLOGY_ID_MISMATCH);
cmp2(STATUS_WIM_NOT_BOOTABLE, ERROR_GEN_FAILURE);
cmp2(STATUS_BLOCKED_BY_PARENTAL_CONTROLS, ERROR_BLOCKED_BY_PARENTAL_CONTROLS);
cmp2(STATUS_NEEDS_REGISTRATION, ERROR_NEEDS_REGISTRATION);
cmp2(STATUS_QUOTA_ACTIVITY, ERROR_QUOTA_ACTIVITY);
cmp2(STATUS_CALLBACK_INVOKE_INLINE, ERROR_CALLBACK_INVOKE_INLINE);
cmp2(STATUS_BLOCK_TOO_MANY_REFERENCES, ERROR_BLOCK_TOO_MANY_REFERENCES);
cmp2(STATUS_MARKED_TO_DISALLOW_WRITES, ERROR_MARKED_TO_DISALLOW_WRITES);
cmp2(STATUS_NETWORK_ACCESS_DENIED_EDP, ERROR_NETWORK_ACCESS_DENIED_EDP);
cmp2(STATUS_ENCLAVE_FAILURE, ERROR_ENCLAVE_FAILURE);
cmp2(STATUS_PNP_NO_COMPAT_DRIVERS, ERROR_NO_MATCH);
cmp2(STATUS_PNP_DRIVER_PACKAGE_NOT_FOUND, ERROR_FILE_NOT_FOUND);
cmp2(STATUS_PNP_DRIVER_CONFIGURATION_NOT_FOUND, ERROR_NOT_FOUND);
cmp2(STATUS_PNP_DRIVER_CONFIGURATION_INCOMPLETE, ERROR_SET_NOT_FOUND);
cmp2(STATUS_PNP_FUNCTION_DRIVER_REQUIRED, ERROR_NOT_CAPABLE);
cmp2(STATUS_PNP_DEVICE_CONFIGURATION_PENDING, ERROR_NOT_READY);
cmp2(STATUS_DEVICE_HINT_NAME_BUFFER_TOO_SMALL, ERROR_DEVICE_HINT_NAME_BUFFER_TOO_SMALL);
cmp2(STATUS_PACKAGE_NOT_AVAILABLE, APPMODEL_ERROR_PACKAGE_NOT_AVAILABLE);
cmp2(STATUS_DEVICE_IN_MAINTENANCE, ERROR_DEVICE_IN_MAINTENANCE);
cmp2(STATUS_NOT_SUPPORTED_ON_DAX, ERROR_NOT_SUPPORTED_ON_DAX);
cmp2(STATUS_FREE_SPACE_TOO_FRAGMENTED, ERROR_DISK_TOO_FRAGMENTED);
cmp2(STATUS_DAX_MAPPING_EXISTS, ERROR_DAX_MAPPING_EXISTS);
cmp2(STATUS_CHILD_PROCESS_BLOCKED, ERROR_CHILD_PROCESS_BLOCKED);
cmp2(STATUS_STORAGE_LOST_DATA_PERSISTENCE, ERROR_STORAGE_LOST_DATA_PERSISTENCE);
cmp2(STATUS_VRF_CFG_ENABLED, ERROR_VRF_CFG_ENABLED);
cmp2(STATUS_PARTITION_TERMINATING, ERROR_PARTITION_TERMINATING);
cmp2(STATUS_EXTERNAL_SYSKEY_NOT_SUPPORTED, ERROR_EXTERNAL_SYSKEY_NOT_SUPPORTED);
cmp2(STATUS_FAIL_FAST_EXCEPTION, ERROR_FAIL_FAST_EXCEPTION);
cmp2(STATUS_IMAGE_CERT_REVOKED, CERT_E_REVOKED);
cmp2(STATUS_DYNAMIC_CODE_BLOCKED, ERROR_DYNAMIC_CODE_BLOCKED);
cmp2(STATUS_IMAGE_CERT_EXPIRED, CERT_E_EXPIRED);
cmp2(STATUS_STRICT_CFG_VIOLATION, ERROR_STRICT_CFG_VIOLATION);
cmp2(STATUS_SET_CONTEXT_DENIED, ERROR_SET_CONTEXT_DENIED);
cmp2(STATUS_CROSS_PARTITION_VIOLATION, ERROR_CROSS_PARTITION_VIOLATION);
cmp2(STATUS_PORT_CLOSED, ERROR_INTERNAL_ERROR);
cmp2(STATUS_MESSAGE_LOST, ERROR_INTERNAL_ERROR);
cmp2(STATUS_INVALID_MESSAGE, ERROR_INVALID_PARAMETER);
cmp2(STATUS_REQUEST_CANCELED, ERROR_INTERNAL_ERROR);
cmp2(STATUS_RECURSIVE_DISPATCH, ERROR_NOT_SUPPORTED);
cmp2(STATUS_LPC_RECEIVE_BUFFER_EXPECTED, ERROR_INVALID_PARAMETER);
cmp2(STATUS_LPC_INVALID_CONNECTION_USAGE, ERROR_INVALID_PARAMETER);
cmp2(STATUS_LPC_REQUESTS_NOT_ALLOWED, ERROR_NOT_SUPPORTED);
cmp2(STATUS_RESOURCE_IN_USE, ERROR_INTERNAL_ERROR);
cmp2(STATUS_HARDWARE_MEMORY_ERROR, ERROR_MEMORY_HARDWARE);
cmp2(STATUS_THREADPOOL_HANDLE_EXCEPTION, ERROR_INVALID_HANDLE);
cmp2(STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED, ERROR_INVALID_HANDLE);
cmp2(STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED, ERROR_INVALID_HANDLE);
cmp2(STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED, ERROR_INVALID_HANDLE);
cmp2(STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED, ERROR_INVALID_HANDLE);
cmp2(STATUS_THREADPOOL_RELEASED_DURING_OPERATION, ERROR_INVALID_HANDLE);
cmp2(STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING, ERROR_INVALID_FUNCTION);
cmp2(STATUS_APC_RETURNED_WHILE_IMPERSONATING, ERROR_INVALID_FUNCTION);
cmp2(STATUS_PROCESS_IS_PROTECTED, ERROR_PROCESS_IS_PROTECTED);
cmp2(STATUS_MCA_EXCEPTION, ERROR_MCA_EXCEPTION);
cmp2(STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE, ERROR_LOGON_FAILURE);
cmp2(STATUS_SYMLINK_CLASS_DISABLED, ERROR_SYMLINK_CLASS_DISABLED);
cmp2(STATUS_INVALID_IDN_NORMALIZATION, ERROR_INVALID_NAME);
cmp2(STATUS_NO_UNICODE_TRANSLATION, ERROR_NO_UNICODE_TRANSLATION);
cmp2(STATUS_ALREADY_REGISTERED, ERROR_INTERNAL_ERROR);
cmp2(STATUS_CONTEXT_MISMATCH, ERROR_INTERNAL_ERROR);
cmp2(STATUS_PORT_ALREADY_HAS_COMPLETION_LIST, ERROR_INTERNAL_ERROR);
cmp2(STATUS_CALLBACK_RETURNED_THREAD_PRIORITY, ERROR_INVALID_FUNCTION);
cmp2(STATUS_INVALID_THREAD, ERROR_INVALID_PARAMETER);
cmp2(STATUS_CALLBACK_RETURNED_TRANSACTION, ERROR_INVALID_FUNCTION);
cmp2(STATUS_CALLBACK_RETURNED_LDR_LOCK, ERROR_INVALID_FUNCTION);
cmp2(STATUS_CALLBACK_RETURNED_LANG, ERROR_INVALID_FUNCTION);
cmp2(STATUS_CALLBACK_RETURNED_PRI_BACK, ERROR_INVALID_FUNCTION);
cmp2(STATUS_CALLBACK_RETURNED_THREAD_AFFINITY, ERROR_INVALID_FUNCTION);
cmp2(STATUS_LPC_HANDLE_COUNT_EXCEEDED, RPC_S_SYSTEM_HANDLE_COUNT_EXCEEDED);
cmp2(STATUS_EXECUTABLE_MEMORY_WRITE, ERROR_GEN_FAILURE);
cmp2(STATUS_KERNEL_EXECUTABLE_MEMORY_WRITE, ERROR_GEN_FAILURE);
cmp2(STATUS_ATTACHED_EXECUTABLE_MEMORY_WRITE, ERROR_GEN_FAILURE);
cmp2(STATUS_TRIGGERED_EXECUTABLE_MEMORY_WRITE, ERROR_GEN_FAILURE);
cmp2(STATUS_DISK_REPAIR_DISABLED, ERROR_DISK_REPAIR_DISABLED);
cmp2(STATUS_DS_DOMAIN_RENAME_IN_PROGRESS, ERROR_DS_DOMAIN_RENAME_IN_PROGRESS);
cmp2(STATUS_DISK_QUOTA_EXCEEDED, ERROR_DISK_QUOTA_EXCEEDED);
cmp2(STATUS_CONTENT_BLOCKED, ERROR_CONTENT_BLOCKED);
cmp2(STATUS_BAD_CLUSTERS, ERROR_BAD_CLUSTERS);
cmp2(STATUS_VOLUME_DIRTY, ERROR_VOLUME_DIRTY);
cmp2(STATUS_DISK_REPAIR_UNSUCCESSFUL, ERROR_DISK_REPAIR_UNSUCCESSFUL);
cmp2(STATUS_CORRUPT_LOG_OVERFULL, ERROR_CORRUPT_LOG_OVERFULL);
cmp2(STATUS_CORRUPT_LOG_CORRUPTED, ERROR_CORRUPT_LOG_CORRUPTED);
cmp2(STATUS_CORRUPT_LOG_UNAVAILABLE, ERROR_CORRUPT_LOG_UNAVAILABLE);
cmp2(STATUS_CORRUPT_LOG_DELETED_FULL, ERROR_CORRUPT_LOG_DELETED_FULL);
cmp2(STATUS_CORRUPT_LOG_CLEARED, ERROR_CORRUPT_LOG_CLEARED);
cmp2(STATUS_ORPHAN_NAME_EXHAUSTED, ERROR_ORPHAN_NAME_EXHAUSTED);
cmp2(STATUS_PROACTIVE_SCAN_IN_PROGRESS, ERROR_RETRY);
cmp2(STATUS_ENCRYPTED_IO_NOT_POSSIBLE, ERROR_ENCRYPTED_IO_NOT_POSSIBLE);
cmp2(STATUS_CORRUPT_LOG_UPLEVEL_RECORDS, ERROR_INTERNAL_ERROR);
cmp2(STATUS_FILE_CHECKED_OUT, ERROR_FILE_CHECKED_OUT);
cmp2(STATUS_CHECKOUT_REQUIRED, ERROR_CHECKOUT_REQUIRED);
cmp2(STATUS_BAD_FILE_TYPE, ERROR_BAD_FILE_TYPE);
cmp2(STATUS_FILE_TOO_LARGE, ERROR_FILE_TOO_LARGE);
cmp2(STATUS_FORMS_AUTH_REQUIRED, ERROR_FORMS_AUTH_REQUIRED);
cmp2(STATUS_VIRUS_INFECTED, ERROR_VIRUS_INFECTED);
cmp2(STATUS_VIRUS_DELETED, ERROR_VIRUS_DELETED);
cmp2(STATUS_BAD_MCFG_TABLE, ERROR_BAD_MCFG_TABLE);
cmp2(STATUS_CANNOT_BREAK_OPLOCK, ERROR_CANNOT_BREAK_OPLOCK);
cmp2(STATUS_BAD_KEY, NTE_BAD_KEY);
cmp2(STATUS_BAD_DATA, NTE_BAD_DATA);
cmp2(STATUS_NO_KEY, NTE_NO_KEY);
cmp2(STATUS_FILE_HANDLE_REVOKED, ERROR_FILE_HANDLE_REVOKED);
cmp2(RPC_NT_PROXY_ACCESS_DENIED, RPC_S_PROXY_ACCESS_DENIED);
cmp2(RPC_NT_COOKIE_AUTH_FAILED, RPC_S_COOKIE_AUTH_FAILED);
cmp2(STATUS_RDP_PROTOCOL_ERROR, ERROR_RDP_PROTOCOL_ERROR);
cmp2(STATUS_CTX_LOGON_DISABLED, ERROR_CTX_LOGON_DISABLED);
cmp2(STATUS_CTX_SECURITY_LAYER_ERROR, ERROR_CTX_SECURITY_LAYER_ERROR);
cmp2(STATUS_TS_INCOMPATIBLE_SESSIONS, ERROR_TS_INCOMPATIBLE_SESSIONS);
cmp2(STATUS_TS_VIDEO_SUBSYSTEM_ERROR, ERROR_TS_VIDEO_SUBSYSTEM_ERROR);
cmp2(STATUS_MUI_FILE_NOT_FOUND, ERROR_MUI_FILE_NOT_FOUND);
cmp2(STATUS_MUI_INVALID_FILE, ERROR_MUI_INVALID_FILE);
cmp2(STATUS_MUI_INVALID_RC_CONFIG, ERROR_MUI_INVALID_RC_CONFIG);
cmp2(STATUS_MUI_INVALID_LOCALE_NAME, ERROR_MUI_INVALID_LOCALE_NAME);
cmp2(STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME, ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME);
cmp2(STATUS_MUI_FILE_NOT_LOADED, ERROR_MUI_FILE_NOT_LOADED);
cmp2(STATUS_RESOURCE_ENUM_USER_STOP, ERROR_RESOURCE_ENUM_USER_STOP);
cmp2(STATUS_CLUSTER_NO_NET_ADAPTERS, ERROR_CLUSTER_NO_NET_ADAPTERS);
cmp2(STATUS_CLUSTER_POISONED, ERROR_CLUSTER_POISONED);
cmp2(STATUS_CLUSTER_NON_CSV_PATH, ERROR_NON_CSV_PATH);
cmp2(STATUS_CLUSTER_CSV_VOLUME_NOT_LOCAL, ERROR_CSV_VOLUME_NOT_LOCAL);
cmp2(STATUS_CLUSTER_CSV_READ_OPLOCK_BREAK_IN_PROGRESS, ERROR_RETRY);
cmp2(STATUS_CLUSTER_CSV_AUTO_PAUSE_ERROR, ERROR_RETRY);
cmp2(STATUS_CLUSTER_CSV_REDIRECTED, ERROR_NOT_SUPPORTED);
cmp2(STATUS_CLUSTER_CSV_NOT_REDIRECTED, ERROR_NOT_SUPPORTED);
cmp2(STATUS_CLUSTER_CSV_VOLUME_DRAINING, ERROR_NOT_SUPPORTED);
cmp2(STATUS_CLUSTER_CSV_SNAPSHOT_CREATION_IN_PROGRESS, ERROR_RETRY);
cmp2(STATUS_CLUSTER_CSV_VOLUME_DRAINING_SUCCEEDED_DOWNLEVEL, ERROR_NOT_SUPPORTED);
cmp2(STATUS_CLUSTER_CSV_NO_SNAPSHOTS, ERROR_RETRY);
cmp2(STATUS_CSV_IO_PAUSE_TIMEOUT, ERROR_CLUSTER_CSV_IO_PAUSE_TIMEOUT);
cmp2(STATUS_CLUSTER_CSV_INVALID_HANDLE, ERROR_CLUSTER_CSV_INVALID_HANDLE);
cmp2(STATUS_CLUSTER_CSV_SUPPORTED_ONLY_ON_COORDINATOR, ERROR_CLUSTER_CSV_SUPPORTED_ONLY_ON_COORDINATOR);
cmp2(STATUS_CLUSTER_CAM_TICKET_REPLAY_DETECTED, ERROR_ACCESS_DENIED);
cmp2(STATUS_VOLMGR_DATABASE_FULL, ERROR_VOLMGR_DATABASE_FULL);
cmp2(STATUS_VOLMGR_DISK_CONFIGURATION_CORRUPTED, ERROR_VOLMGR_DISK_CONFIGURATION_CORRUPTED);
cmp2(STATUS_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC, ERROR_VOLMGR_DISK_CONFIGURATION_NOT_IN_SYNC);
cmp2(STATUS_VOLMGR_PACK_CONFIG_UPDATE_FAILED, ERROR_VOLMGR_PACK_CONFIG_UPDATE_FAILED);
cmp2(STATUS_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME, ERROR_VOLMGR_DISK_CONTAINS_NON_SIMPLE_VOLUME);
cmp2(STATUS_VOLMGR_DISK_DUPLICATE, ERROR_VOLMGR_DISK_DUPLICATE);
cmp2(STATUS_VOLMGR_DISK_DYNAMIC, ERROR_VOLMGR_DISK_DYNAMIC);
cmp2(STATUS_VOLMGR_DISK_ID_INVALID, ERROR_VOLMGR_DISK_ID_INVALID);
cmp2(STATUS_VOLMGR_DISK_INVALID, ERROR_VOLMGR_DISK_INVALID);
cmp2(STATUS_VOLMGR_DISK_LAST_VOTER, ERROR_VOLMGR_DISK_LAST_VOTER);
cmp2(STATUS_VOLMGR_DISK_LAYOUT_INVALID, ERROR_VOLMGR_DISK_LAYOUT_INVALID);
cmp2(STATUS_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS, ERROR_VOLMGR_DISK_LAYOUT_NON_BASIC_BETWEEN_BASIC_PARTITIONS);
cmp2(STATUS_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED, ERROR_VOLMGR_DISK_LAYOUT_NOT_CYLINDER_ALIGNED);
cmp2(STATUS_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL, ERROR_VOLMGR_DISK_LAYOUT_PARTITIONS_TOO_SMALL);
cmp2(STATUS_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS, ERROR_VOLMGR_DISK_LAYOUT_PRIMARY_BETWEEN_LOGICAL_PARTITIONS);
cmp2(STATUS_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS, ERROR_VOLMGR_DISK_LAYOUT_TOO_MANY_PARTITIONS);
cmp2(STATUS_VOLMGR_DISK_MISSING, ERROR_VOLMGR_DISK_MISSING);
cmp2(STATUS_VOLMGR_DISK_NOT_EMPTY, ERROR_VOLMGR_DISK_NOT_EMPTY);
cmp2(STATUS_VOLMGR_DISK_NOT_ENOUGH_SPACE, ERROR_VOLMGR_DISK_NOT_ENOUGH_SPACE);
cmp2(STATUS_VOLMGR_DISK_REVECTORING_FAILED, ERROR_VOLMGR_DISK_REVECTORING_FAILED);
cmp2(STATUS_VOLMGR_DISK_SECTOR_SIZE_INVALID, ERROR_VOLMGR_DISK_SECTOR_SIZE_INVALID);
cmp2(STATUS_VOLMGR_DISK_SET_NOT_CONTAINED, ERROR_VOLMGR_DISK_SET_NOT_CONTAINED);
cmp2(STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS, ERROR_VOLMGR_DISK_USED_BY_MULTIPLE_MEMBERS);
cmp2(STATUS_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES, ERROR_VOLMGR_DISK_USED_BY_MULTIPLE_PLEXES);
cmp2(STATUS_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED, ERROR_VOLMGR_DYNAMIC_DISK_NOT_SUPPORTED);
cmp2(STATUS_VOLMGR_EXTENT_ALREADY_USED, ERROR_VOLMGR_EXTENT_ALREADY_USED);
cmp2(STATUS_VOLMGR_EXTENT_NOT_CONTIGUOUS, ERROR_VOLMGR_EXTENT_NOT_CONTIGUOUS);
cmp2(STATUS_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION, ERROR_VOLMGR_EXTENT_NOT_IN_PUBLIC_REGION);
cmp2(STATUS_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED, ERROR_VOLMGR_EXTENT_NOT_SECTOR_ALIGNED);
cmp2(STATUS_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION, ERROR_VOLMGR_EXTENT_OVERLAPS_EBR_PARTITION);
cmp2(STATUS_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH, ERROR_VOLMGR_EXTENT_VOLUME_LENGTHS_DO_NOT_MATCH);
cmp2(STATUS_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED, ERROR_VOLMGR_FAULT_TOLERANT_NOT_SUPPORTED);
cmp2(STATUS_VOLMGR_INTERLEAVE_LENGTH_INVALID, ERROR_VOLMGR_INTERLEAVE_LENGTH_INVALID);
cmp2(STATUS_VOLMGR_MAXIMUM_REGISTERED_USERS, ERROR_VOLMGR_MAXIMUM_REGISTERED_USERS);
cmp2(STATUS_VOLMGR_MEMBER_IN_SYNC, ERROR_VOLMGR_MEMBER_IN_SYNC);
cmp2(STATUS_VOLMGR_MEMBER_INDEX_DUPLICATE, ERROR_VOLMGR_MEMBER_INDEX_DUPLICATE);
cmp2(STATUS_VOLMGR_MEMBER_INDEX_INVALID, ERROR_VOLMGR_MEMBER_INDEX_INVALID);
cmp2(STATUS_VOLMGR_MEMBER_MISSING, ERROR_VOLMGR_MEMBER_MISSING);
cmp2(STATUS_VOLMGR_MEMBER_NOT_DETACHED, ERROR_VOLMGR_MEMBER_NOT_DETACHED);
cmp2(STATUS_VOLMGR_MEMBER_REGENERATING, ERROR_VOLMGR_MEMBER_REGENERATING);
cmp2(STATUS_VOLMGR_ALL_DISKS_FAILED, ERROR_VOLMGR_ALL_DISKS_FAILED);
cmp2(STATUS_VOLMGR_NO_REGISTERED_USERS, ERROR_VOLMGR_NO_REGISTERED_USERS);
cmp2(STATUS_VOLMGR_NO_SUCH_USER, ERROR_VOLMGR_NO_SUCH_USER);
cmp2(STATUS_VOLMGR_NOTIFICATION_RESET, ERROR_VOLMGR_NOTIFICATION_RESET);
cmp2(STATUS_VOLMGR_NUMBER_OF_MEMBERS_INVALID,ERROR_VOLMGR_NUMBER_OF_MEMBERS_INVALID);
cmp2(STATUS_VOLMGR_NUMBER_OF_PLEXES_INVALID, ERROR_VOLMGR_NUMBER_OF_PLEXES_INVALID);
cmp2(STATUS_VOLMGR_PACK_DUPLICATE, ERROR_VOLMGR_PACK_DUPLICATE);
cmp2(STATUS_VOLMGR_PACK_ID_INVALID, ERROR_VOLMGR_PACK_ID_INVALID);
cmp2(STATUS_VOLMGR_PACK_INVALID, ERROR_VOLMGR_PACK_INVALID);
cmp2(STATUS_VOLMGR_PACK_NAME_INVALID, ERROR_VOLMGR_PACK_NAME_INVALID);
cmp2(STATUS_VOLMGR_PACK_OFFLINE, ERROR_VOLMGR_PACK_OFFLINE);
cmp2(STATUS_VOLMGR_PACK_HAS_QUORUM, ERROR_VOLMGR_PACK_HAS_QUORUM);
cmp2(STATUS_VOLMGR_PACK_WITHOUT_QUORUM, ERROR_VOLMGR_PACK_WITHOUT_QUORUM);
cmp2(STATUS_VOLMGR_PARTITION_STYLE_INVALID, ERROR_VOLMGR_PARTITION_STYLE_INVALID);
cmp2(STATUS_VOLMGR_PARTITION_UPDATE_FAILED, ERROR_VOLMGR_PARTITION_UPDATE_FAILED);
cmp2(STATUS_VOLMGR_PLEX_IN_SYNC, ERROR_VOLMGR_PLEX_IN_SYNC);
cmp2(STATUS_VOLMGR_PLEX_INDEX_DUPLICATE, ERROR_VOLMGR_PLEX_INDEX_DUPLICATE);
cmp2(STATUS_VOLMGR_PLEX_INDEX_INVALID, ERROR_VOLMGR_PLEX_INDEX_INVALID);
cmp2(STATUS_VOLMGR_PLEX_LAST_ACTIVE, ERROR_VOLMGR_PLEX_LAST_ACTIVE);
cmp2(STATUS_VOLMGR_PLEX_MISSING, ERROR_VOLMGR_PLEX_MISSING);
cmp2(STATUS_VOLMGR_PLEX_REGENERATING, ERROR_VOLMGR_PLEX_REGENERATING);
cmp2(STATUS_VOLMGR_PLEX_TYPE_INVALID, ERROR_VOLMGR_PLEX_TYPE_INVALID);
cmp2(STATUS_VOLMGR_PLEX_NOT_RAID5, ERROR_VOLMGR_PLEX_NOT_RAID5);
cmp2(STATUS_VOLMGR_PLEX_NOT_SIMPLE, ERROR_VOLMGR_PLEX_NOT_SIMPLE);
cmp2(STATUS_VOLMGR_STRUCTURE_SIZE_INVALID, ERROR_VOLMGR_STRUCTURE_SIZE_INVALID);
cmp2(STATUS_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS, ERROR_VOLMGR_TOO_MANY_NOTIFICATION_REQUESTS);
cmp2(STATUS_VOLMGR_TRANSACTION_IN_PROGRESS, ERROR_VOLMGR_TRANSACTION_IN_PROGRESS);
cmp2(STATUS_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE, ERROR_VOLMGR_UNEXPECTED_DISK_LAYOUT_CHANGE);
cmp2(STATUS_VOLMGR_VOLUME_CONTAINS_MISSING_DISK, ERROR_VOLMGR_VOLUME_CONTAINS_MISSING_DISK);
cmp2(STATUS_VOLMGR_VOLUME_ID_INVALID, ERROR_VOLMGR_VOLUME_ID_INVALID);
cmp2(STATUS_VOLMGR_VOLUME_LENGTH_INVALID, ERROR_VOLMGR_VOLUME_LENGTH_INVALID);
cmp2(STATUS_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE, ERROR_VOLMGR_VOLUME_LENGTH_NOT_SECTOR_SIZE_MULTIPLE);
cmp2(STATUS_VOLMGR_VOLUME_NOT_MIRRORED, ERROR_VOLMGR_VOLUME_NOT_MIRRORED);
cmp2(STATUS_VOLMGR_VOLUME_NOT_RETAINED, ERROR_VOLMGR_VOLUME_NOT_RETAINED);
cmp2(STATUS_VOLMGR_VOLUME_OFFLINE, ERROR_VOLMGR_VOLUME_OFFLINE);
cmp2(STATUS_VOLMGR_VOLUME_RETAINED, ERROR_VOLMGR_VOLUME_RETAINED);
cmp2(STATUS_VOLMGR_NUMBER_OF_EXTENTS_INVALID, ERROR_VOLMGR_NUMBER_OF_EXTENTS_INVALID);
cmp2(STATUS_VOLMGR_DIFFERENT_SECTOR_SIZE, ERROR_VOLMGR_DIFFERENT_SECTOR_SIZE);
cmp2(STATUS_VOLMGR_BAD_BOOT_DISK, ERROR_VOLMGR_BAD_BOOT_DISK);
cmp2(STATUS_VOLMGR_PACK_CONFIG_OFFLINE, ERROR_VOLMGR_PACK_CONFIG_OFFLINE);
cmp2(STATUS_VOLMGR_PACK_CONFIG_ONLINE, ERROR_VOLMGR_PACK_CONFIG_ONLINE);
cmp2(STATUS_VOLMGR_NOT_PRIMARY_PACK, ERROR_VOLMGR_NOT_PRIMARY_PACK);
cmp2(STATUS_VOLMGR_PACK_LOG_UPDATE_FAILED, ERROR_VOLMGR_PACK_LOG_UPDATE_FAILED);
cmp2(STATUS_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID, ERROR_VOLMGR_NUMBER_OF_DISKS_IN_PLEX_INVALID);
cmp2(STATUS_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID, ERROR_VOLMGR_NUMBER_OF_DISKS_IN_MEMBER_INVALID);
cmp2(STATUS_VOLMGR_VOLUME_MIRRORED, ERROR_VOLMGR_VOLUME_MIRRORED);
cmp2(STATUS_VOLMGR_PLEX_NOT_SIMPLE_SPANNED, ERROR_VOLMGR_PLEX_NOT_SIMPLE_SPANNED);
cmp2(STATUS_VOLMGR_NO_VALID_LOG_COPIES, ERROR_VOLMGR_NO_VALID_LOG_COPIES);
cmp2(STATUS_VOLMGR_PRIMARY_PACK_PRESENT, ERROR_VOLMGR_PRIMARY_PACK_PRESENT);
cmp2(STATUS_VOLMGR_NUMBER_OF_DISKS_INVALID, ERROR_VOLMGR_NUMBER_OF_DISKS_INVALID);
cmp2(STATUS_VOLMGR_MIRROR_NOT_SUPPORTED, ERROR_VOLMGR_MIRROR_NOT_SUPPORTED);
cmp2(STATUS_VOLMGR_RAID5_NOT_SUPPORTED, ERROR_VOLMGR_RAID5_NOT_SUPPORTED);
}
START_TEST(error)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+96 -69
View File
@@ -7,8 +7,13 @@
#define WINE_NOWINSOCK
#include "ntdll_test.h"
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.h"
/***********************************************************************
@@ -25,7 +30,7 @@
#if defined(_MSC_VER) && (_MSC_VER >= 1300) && defined(__cplusplus)
# define _TYPE_ALIGNMENT(type) __alignof(type)
#elif defined(__GNUC__)
#elif defined(__GNUC__) || defined(__clang__)
# define _TYPE_ALIGNMENT(type) __alignof__(type)
#else
/*
@@ -47,23 +52,23 @@
* Test helper macros
*/
#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size);
#define TEST_TYPE_SIZE(type, size) C_ASSERT(sizeof(type) == size);
#ifdef TYPE_ALIGNMENT
# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align);
# define TEST_TYPE_ALIGN(type, align) C_ASSERT(TYPE_ALIGNMENT(type) == align);
#else
# define TEST_TYPE_ALIGN(type, align)
#endif
#ifdef _TYPE_ALIGNMENT
# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align);
# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align);
# define TEST_TARGET_ALIGN(type, align) C_ASSERT(_TYPE_ALIGNMENT(*(type)0) == align);
# define TEST_FIELD_ALIGN(type, field, align) C_ASSERT(_TYPE_ALIGNMENT(((type*)0)->field) == align);
#else
# define TEST_TARGET_ALIGN(type, align)
# define TEST_FIELD_ALIGN(type, field, align)
#endif
#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset);
#define TEST_FIELD_OFFSET(type, field, offset) C_ASSERT(FIELD_OFFSET(type, field) == offset);
#define TEST_TARGET_SIZE(type, size) TEST_TYPE_SIZE(*(type)0, size)
#define TEST_FIELD_SIZE(type, field, size) TEST_TYPE_SIZE((((type*)0)->field), size)
@@ -94,6 +99,7 @@ static void test_pack_DWORD_PTR(void)
/* DWORD_PTR */
TEST_TYPE_SIZE (DWORD_PTR, 8)
TEST_TYPE_ALIGN (DWORD_PTR, 8)
TEST_TYPE_UNSIGNED(DWORD_PTR)
}
static void test_pack_HALF_PTR(void)
@@ -101,7 +107,7 @@ static void test_pack_HALF_PTR(void)
/* HALF_PTR */
TEST_TYPE_SIZE (HALF_PTR, 4)
TEST_TYPE_ALIGN (HALF_PTR, 4)
TEST_TYPE_SIGNED(HALF_PTR)
TEST_TYPE_SIGNED (HALF_PTR)
}
static void test_pack_INT16(void)
@@ -109,7 +115,7 @@ static void test_pack_INT16(void)
/* INT16 */
TEST_TYPE_SIZE (INT16, 2)
TEST_TYPE_ALIGN (INT16, 2)
TEST_TYPE_SIGNED(INT16)
TEST_TYPE_SIGNED (INT16)
}
static void test_pack_INT32(void)
@@ -117,7 +123,7 @@ static void test_pack_INT32(void)
/* INT32 */
TEST_TYPE_SIZE (INT32, 4)
TEST_TYPE_ALIGN (INT32, 4)
TEST_TYPE_SIGNED(INT32)
TEST_TYPE_SIGNED (INT32)
}
static void test_pack_INT64(void)
@@ -125,7 +131,7 @@ static void test_pack_INT64(void)
/* INT64 */
TEST_TYPE_SIZE (INT64, 8)
TEST_TYPE_ALIGN (INT64, 8)
TEST_TYPE_SIGNED(INT64)
TEST_TYPE_SIGNED (INT64)
}
static void test_pack_INT8(void)
@@ -133,7 +139,7 @@ static void test_pack_INT8(void)
/* INT8 */
TEST_TYPE_SIZE (INT8, 1)
TEST_TYPE_ALIGN (INT8, 1)
TEST_TYPE_SIGNED(INT8)
TEST_TYPE_SIGNED (INT8)
}
static void test_pack_INT_PTR(void)
@@ -141,7 +147,7 @@ static void test_pack_INT_PTR(void)
/* INT_PTR */
TEST_TYPE_SIZE (INT_PTR, 8)
TEST_TYPE_ALIGN (INT_PTR, 8)
TEST_TYPE_SIGNED(INT_PTR)
TEST_TYPE_SIGNED (INT_PTR)
}
static void test_pack_LONG32(void)
@@ -149,7 +155,7 @@ static void test_pack_LONG32(void)
/* LONG32 */
TEST_TYPE_SIZE (LONG32, 4)
TEST_TYPE_ALIGN (LONG32, 4)
TEST_TYPE_SIGNED(LONG32)
TEST_TYPE_SIGNED (LONG32)
}
static void test_pack_LONG64(void)
@@ -157,7 +163,7 @@ static void test_pack_LONG64(void)
/* LONG64 */
TEST_TYPE_SIZE (LONG64, 8)
TEST_TYPE_ALIGN (LONG64, 8)
TEST_TYPE_SIGNED(LONG64)
TEST_TYPE_SIGNED (LONG64)
}
static void test_pack_LONG_PTR(void)
@@ -165,7 +171,7 @@ static void test_pack_LONG_PTR(void)
/* LONG_PTR */
TEST_TYPE_SIZE (LONG_PTR, 8)
TEST_TYPE_ALIGN (LONG_PTR, 8)
TEST_TYPE_SIGNED(LONG_PTR)
TEST_TYPE_SIGNED (LONG_PTR)
}
static void test_pack_SIZE_T(void)
@@ -173,6 +179,7 @@ static void test_pack_SIZE_T(void)
/* SIZE_T */
TEST_TYPE_SIZE (SIZE_T, 8)
TEST_TYPE_ALIGN (SIZE_T, 8)
TEST_TYPE_UNSIGNED(SIZE_T)
}
static void test_pack_SSIZE_T(void)
@@ -180,6 +187,7 @@ static void test_pack_SSIZE_T(void)
/* SSIZE_T */
TEST_TYPE_SIZE (SSIZE_T, 8)
TEST_TYPE_ALIGN (SSIZE_T, 8)
TEST_TYPE_SIGNED (SSIZE_T)
}
static void test_pack_UHALF_PTR(void)
@@ -484,6 +492,7 @@ static void test_pack_HRESULT(void)
/* HRESULT */
TEST_TYPE_SIZE (HRESULT, 4)
TEST_TYPE_ALIGN (HRESULT, 4)
TEST_TYPE_SIGNED (HRESULT)
}
static void test_pack_IMAGE_ARCHIVE_MEMBER_HEADER(void)
@@ -835,15 +844,17 @@ static void test_pack_IMAGE_LINENUMBER(void)
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY */
TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, 112)
/* size varies depending on Windows version */
/* TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, 112) */
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, 8)
}
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY32(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY32 */
TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, 88)
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, 8)
/* size varies depending on Windows version */
/* TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, 72) */
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, 4)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, Size, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, Size, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, Size, 0)
@@ -871,45 +882,46 @@ static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY32(void)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, DeCommitTotalFreeThreshold, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, DeCommitTotalFreeThreshold, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, DeCommitTotalFreeThreshold, 28)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, LockPrefixTable, 8)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, LockPrefixTable, 8)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, LockPrefixTable, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, LockPrefixTable, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, LockPrefixTable, 32)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, MaximumAllocationSize, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, MaximumAllocationSize, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, MaximumAllocationSize, 40)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, MaximumAllocationSize, 36)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, VirtualMemoryThreshold, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, VirtualMemoryThreshold, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, VirtualMemoryThreshold, 44)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, VirtualMemoryThreshold, 40)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessHeapFlags, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessHeapFlags, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessHeapFlags, 48)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessHeapFlags, 44)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessAffinityMask, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessAffinityMask, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessAffinityMask, 52)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, ProcessAffinityMask, 48)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 56)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, Reserved1, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, Reserved1, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, Reserved1, 58)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 8)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 8)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 64)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 52)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, DependentLoadFlags, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, DependentLoadFlags, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, DependentLoadFlags, 54)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 56)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, SecurityCookie, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, SecurityCookie, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SecurityCookie, 72)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SecurityCookie, 60)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerTable, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerTable, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerTable, 76)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerTable, 64)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount, 80)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, SEHandlerCount, 68)
}
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY64(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY64 */
TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, 112)
/* size varies depending on Windows version */
/* TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, 112) */
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, 8)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, Size, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, Size, 4)
@@ -956,9 +968,9 @@ static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY64(void)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, CSDVersion, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, CSDVersion, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, CSDVersion, 76)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, Reserved1, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, Reserved1, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, Reserved1, 78)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, DependentLoadFlags, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, DependentLoadFlags, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, DependentLoadFlags, 78)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, EditList, 8)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, EditList, 8)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, EditList, 80)
@@ -1738,7 +1750,7 @@ static void test_pack_LONG(void)
/* LONG */
TEST_TYPE_SIZE (LONG, 4)
TEST_TYPE_ALIGN (LONG, 4)
TEST_TYPE_SIGNED(LONG)
TEST_TYPE_SIGNED (LONG)
}
static void test_pack_LONGLONG(void)
@@ -1746,7 +1758,7 @@ static void test_pack_LONGLONG(void)
/* LONGLONG */
TEST_TYPE_SIZE (LONGLONG, 8)
TEST_TYPE_ALIGN (LONGLONG, 8)
TEST_TYPE_SIGNED(LONGLONG)
TEST_TYPE_SIGNED (LONGLONG)
}
static void test_pack_LUID(void)
@@ -2809,6 +2821,7 @@ static void test_pack_SECURITY_CONTEXT_TRACKING_MODE(void)
/* SECURITY_CONTEXT_TRACKING_MODE */
TEST_TYPE_SIZE (SECURITY_CONTEXT_TRACKING_MODE, 1)
TEST_TYPE_ALIGN (SECURITY_CONTEXT_TRACKING_MODE, 1)
TEST_TYPE_UNSIGNED(SECURITY_CONTEXT_TRACKING_MODE)
}
static void test_pack_SECURITY_DESCRIPTOR(void)
@@ -2896,7 +2909,7 @@ static void test_pack_SHORT(void)
/* SHORT */
TEST_TYPE_SIZE (SHORT, 2)
TEST_TYPE_ALIGN (SHORT, 2)
TEST_TYPE_SIGNED(SHORT)
TEST_TYPE_SIGNED (SHORT)
}
static void test_pack_SID(void)
@@ -3117,7 +3130,7 @@ static void test_pack_BOOL(void)
/* BOOL */
TEST_TYPE_SIZE (BOOL, 4)
TEST_TYPE_ALIGN (BOOL, 4)
TEST_TYPE_SIGNED(BOOL)
TEST_TYPE_SIGNED (BOOL)
}
static void test_pack_BYTE(void)
@@ -3177,7 +3190,7 @@ static void test_pack_HFILE(void)
/* HFILE */
TEST_TYPE_SIZE (HFILE, 4)
TEST_TYPE_ALIGN (HFILE, 4)
TEST_TYPE_SIGNED(HFILE)
TEST_TYPE_SIGNED (HFILE)
}
static void test_pack_HGDIOBJ(void)
@@ -3213,7 +3226,7 @@ static void test_pack_INT(void)
/* INT */
TEST_TYPE_SIZE (INT, 4)
TEST_TYPE_ALIGN (INT, 4)
TEST_TYPE_SIGNED(INT)
TEST_TYPE_SIGNED (INT)
}
static void test_pack_LOCALHANDLE(void)
@@ -3228,6 +3241,7 @@ static void test_pack_LPARAM(void)
/* LPARAM */
TEST_TYPE_SIZE (LPARAM, 8)
TEST_TYPE_ALIGN (LPARAM, 8)
TEST_TYPE_SIGNED (LPARAM)
}
static void test_pack_LPCRECT(void)
@@ -3296,6 +3310,7 @@ static void test_pack_LRESULT(void)
/* LRESULT */
TEST_TYPE_SIZE (LRESULT, 8)
TEST_TYPE_ALIGN (LRESULT, 8)
TEST_TYPE_SIGNED (LRESULT)
}
static void test_pack_POINT(void)
@@ -3486,6 +3501,7 @@ static void test_pack_WPARAM(void)
/* WPARAM */
TEST_TYPE_SIZE (WPARAM, 8)
TEST_TYPE_ALIGN (WPARAM, 8)
TEST_TYPE_UNSIGNED(WPARAM)
}
#else /* _WIN64 */
@@ -3511,6 +3527,7 @@ static void test_pack_DWORD_PTR(void)
/* DWORD_PTR */
TEST_TYPE_SIZE (DWORD_PTR, 4)
TEST_TYPE_ALIGN (DWORD_PTR, 4)
TEST_TYPE_UNSIGNED(DWORD_PTR)
}
static void test_pack_HALF_PTR(void)
@@ -3518,7 +3535,7 @@ static void test_pack_HALF_PTR(void)
/* HALF_PTR */
TEST_TYPE_SIZE (HALF_PTR, 2)
TEST_TYPE_ALIGN (HALF_PTR, 2)
TEST_TYPE_SIGNED(HALF_PTR)
TEST_TYPE_SIGNED (HALF_PTR)
}
static void test_pack_INT16(void)
@@ -3526,7 +3543,7 @@ static void test_pack_INT16(void)
/* INT16 */
TEST_TYPE_SIZE (INT16, 2)
TEST_TYPE_ALIGN (INT16, 2)
TEST_TYPE_SIGNED(INT16)
TEST_TYPE_SIGNED (INT16)
}
static void test_pack_INT32(void)
@@ -3534,7 +3551,7 @@ static void test_pack_INT32(void)
/* INT32 */
TEST_TYPE_SIZE (INT32, 4)
TEST_TYPE_ALIGN (INT32, 4)
TEST_TYPE_SIGNED(INT32)
TEST_TYPE_SIGNED (INT32)
}
static void test_pack_INT64(void)
@@ -3542,7 +3559,7 @@ static void test_pack_INT64(void)
/* INT64 */
TEST_TYPE_SIZE (INT64, 8)
TEST_TYPE_ALIGN (INT64, 8)
TEST_TYPE_SIGNED(INT64)
TEST_TYPE_SIGNED (INT64)
}
static void test_pack_INT8(void)
@@ -3550,7 +3567,7 @@ static void test_pack_INT8(void)
/* INT8 */
TEST_TYPE_SIZE (INT8, 1)
TEST_TYPE_ALIGN (INT8, 1)
TEST_TYPE_SIGNED(INT8)
TEST_TYPE_SIGNED (INT8)
}
static void test_pack_INT_PTR(void)
@@ -3558,7 +3575,7 @@ static void test_pack_INT_PTR(void)
/* INT_PTR */
TEST_TYPE_SIZE (INT_PTR, 4)
TEST_TYPE_ALIGN (INT_PTR, 4)
TEST_TYPE_SIGNED(INT_PTR)
TEST_TYPE_SIGNED (INT_PTR)
}
static void test_pack_LONG32(void)
@@ -3566,7 +3583,7 @@ static void test_pack_LONG32(void)
/* LONG32 */
TEST_TYPE_SIZE (LONG32, 4)
TEST_TYPE_ALIGN (LONG32, 4)
TEST_TYPE_SIGNED(LONG32)
TEST_TYPE_SIGNED (LONG32)
}
static void test_pack_LONG64(void)
@@ -3574,7 +3591,7 @@ static void test_pack_LONG64(void)
/* LONG64 */
TEST_TYPE_SIZE (LONG64, 8)
TEST_TYPE_ALIGN (LONG64, 8)
TEST_TYPE_SIGNED(LONG64)
TEST_TYPE_SIGNED (LONG64)
}
static void test_pack_LONG_PTR(void)
@@ -3582,7 +3599,7 @@ static void test_pack_LONG_PTR(void)
/* LONG_PTR */
TEST_TYPE_SIZE (LONG_PTR, 4)
TEST_TYPE_ALIGN (LONG_PTR, 4)
TEST_TYPE_SIGNED(LONG_PTR)
TEST_TYPE_SIGNED (LONG_PTR)
}
static void test_pack_SIZE_T(void)
@@ -3590,6 +3607,7 @@ static void test_pack_SIZE_T(void)
/* SIZE_T */
TEST_TYPE_SIZE (SIZE_T, 4)
TEST_TYPE_ALIGN (SIZE_T, 4)
TEST_TYPE_UNSIGNED(SIZE_T)
}
static void test_pack_SSIZE_T(void)
@@ -3597,6 +3615,7 @@ static void test_pack_SSIZE_T(void)
/* SSIZE_T */
TEST_TYPE_SIZE (SSIZE_T, 4)
TEST_TYPE_ALIGN (SSIZE_T, 4)
TEST_TYPE_SIGNED (SSIZE_T)
}
static void test_pack_UHALF_PTR(void)
@@ -3901,6 +3920,7 @@ static void test_pack_HRESULT(void)
/* HRESULT */
TEST_TYPE_SIZE (HRESULT, 4)
TEST_TYPE_ALIGN (HRESULT, 4)
TEST_TYPE_SIGNED (HRESULT)
}
static void test_pack_IMAGE_ARCHIVE_MEMBER_HEADER(void)
@@ -4252,14 +4272,16 @@ static void test_pack_IMAGE_LINENUMBER(void)
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY */
TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, 72)
/* size varies depending on Windows version */
/* TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, 72) */
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, 4)
}
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY32(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY32 */
TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, 72)
/* size varies depending on Windows version */
/* TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, 72) */
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, 4)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, Size, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, Size, 4)
@@ -4306,9 +4328,9 @@ static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY32(void)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, CSDVersion, 52)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, Reserved1, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, Reserved1, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, Reserved1, 54)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, DependentLoadFlags, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, DependentLoadFlags, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, DependentLoadFlags, 54)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY32, EditList, 56)
@@ -4326,7 +4348,8 @@ static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY32(void)
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY64(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY64 */
TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, 112)
/* size varies depending on Windows version */
/* TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, 112) */
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, 8)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, Size, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, Size, 4)
@@ -4373,9 +4396,9 @@ static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY64(void)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, CSDVersion, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, CSDVersion, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, CSDVersion, 76)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, Reserved1, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, Reserved1, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, Reserved1, 78)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, DependentLoadFlags, 2)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, DependentLoadFlags, 2)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, DependentLoadFlags, 78)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY64, EditList, 8)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY64, EditList, 8)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY64, EditList, 80)
@@ -5155,7 +5178,7 @@ static void test_pack_LONG(void)
/* LONG */
TEST_TYPE_SIZE (LONG, 4)
TEST_TYPE_ALIGN (LONG, 4)
TEST_TYPE_SIGNED(LONG)
TEST_TYPE_SIGNED (LONG)
}
static void test_pack_LONGLONG(void)
@@ -5163,7 +5186,7 @@ static void test_pack_LONGLONG(void)
/* LONGLONG */
TEST_TYPE_SIZE (LONGLONG, 8)
TEST_TYPE_ALIGN (LONGLONG, 8)
TEST_TYPE_SIGNED(LONGLONG)
TEST_TYPE_SIGNED (LONGLONG)
}
static void test_pack_LUID(void)
@@ -6226,6 +6249,7 @@ static void test_pack_SECURITY_CONTEXT_TRACKING_MODE(void)
/* SECURITY_CONTEXT_TRACKING_MODE */
TEST_TYPE_SIZE (SECURITY_CONTEXT_TRACKING_MODE, 1)
TEST_TYPE_ALIGN (SECURITY_CONTEXT_TRACKING_MODE, 1)
TEST_TYPE_UNSIGNED(SECURITY_CONTEXT_TRACKING_MODE)
}
static void test_pack_SECURITY_DESCRIPTOR(void)
@@ -6313,7 +6337,7 @@ static void test_pack_SHORT(void)
/* SHORT */
TEST_TYPE_SIZE (SHORT, 2)
TEST_TYPE_ALIGN (SHORT, 2)
TEST_TYPE_SIGNED(SHORT)
TEST_TYPE_SIGNED (SHORT)
}
static void test_pack_SID(void)
@@ -6534,7 +6558,7 @@ static void test_pack_BOOL(void)
/* BOOL */
TEST_TYPE_SIZE (BOOL, 4)
TEST_TYPE_ALIGN (BOOL, 4)
TEST_TYPE_SIGNED(BOOL)
TEST_TYPE_SIGNED (BOOL)
}
static void test_pack_BYTE(void)
@@ -6594,7 +6618,7 @@ static void test_pack_HFILE(void)
/* HFILE */
TEST_TYPE_SIZE (HFILE, 4)
TEST_TYPE_ALIGN (HFILE, 4)
TEST_TYPE_SIGNED(HFILE)
TEST_TYPE_SIGNED (HFILE)
}
static void test_pack_HGDIOBJ(void)
@@ -6630,7 +6654,7 @@ static void test_pack_INT(void)
/* INT */
TEST_TYPE_SIZE (INT, 4)
TEST_TYPE_ALIGN (INT, 4)
TEST_TYPE_SIGNED(INT)
TEST_TYPE_SIGNED (INT)
}
static void test_pack_LOCALHANDLE(void)
@@ -6645,6 +6669,7 @@ static void test_pack_LPARAM(void)
/* LPARAM */
TEST_TYPE_SIZE (LPARAM, 4)
TEST_TYPE_ALIGN (LPARAM, 4)
TEST_TYPE_SIGNED (LPARAM)
}
static void test_pack_LPCRECT(void)
@@ -6713,6 +6738,7 @@ static void test_pack_LRESULT(void)
/* LRESULT */
TEST_TYPE_SIZE (LRESULT, 4)
TEST_TYPE_ALIGN (LRESULT, 4)
TEST_TYPE_SIGNED (LRESULT)
}
static void test_pack_POINT(void)
@@ -6903,6 +6929,7 @@ static void test_pack_WPARAM(void)
/* WPARAM */
TEST_TYPE_SIZE (WPARAM, 4)
TEST_TYPE_ALIGN (WPARAM, 4)
TEST_TYPE_UNSIGNED(WPARAM)
}
#endif /* _WIN64 */
File diff suppressed because it is too large Load Diff
+160 -83
View File
@@ -22,8 +22,14 @@
*/
#include <stdlib.h>
#include <stdarg.h>
#include "ntdll_test.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.h"
/* Function ptrs for ntdll calls */
@@ -33,9 +39,13 @@ 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 (WINAPI *p_alldvrm)(LONGLONG, LONGLONG);
static void (WINAPI *p_aulldvrm)(ULONGLONG, ULONGLONG);
static LONGLONG (WINAPI *p_alldiv)( LONGLONG a, LONGLONG b );
static LONGLONG (WINAPI *p_allrem)( LONGLONG a, LONGLONG b );
static LONGLONG (WINAPI *p_allmul)( LONGLONG a, LONGLONG b );
static ULONGLONG (WINAPI *p_aulldiv)( ULONGLONG a, ULONGLONG b );
static ULONGLONG (WINAPI *p_aullrem)( ULONGLONG a, ULONGLONG b );
static void *p_allshl, *p_allshr, *p_aullshr;
static void InitFunctionPtrs(void)
{
@@ -47,8 +57,15 @@ static void InitFunctionPtrs(void)
pRtlInt64ToUnicodeString = (void *)GetProcAddress(hntdll, "RtlInt64ToUnicodeString");
pRtlLargeIntegerToChar = (void *)GetProcAddress(hntdll, "RtlLargeIntegerToChar");
pRtlUnicodeStringToAnsiString = (void *)GetProcAddress(hntdll, "RtlUnicodeStringToAnsiString");
p_alldvrm = (void *)GetProcAddress(hntdll, "_alldvrm");
p_aulldvrm = (void *)GetProcAddress(hntdll, "_aulldvrm");
p_alldiv = (void *)GetProcAddress(hntdll, "_alldiv");
p_allrem = (void *)GetProcAddress(hntdll, "_allrem");
p_allmul = (void *)GetProcAddress(hntdll, "_allmul");
p_allshl = (void *)GetProcAddress(hntdll, "_allshl");
p_allshr = (void *)GetProcAddress(hntdll, "_allshr");
p_aulldiv = (void *)GetProcAddress(hntdll, "_aulldiv");
p_aullrem = (void *)GetProcAddress(hntdll, "_aullrem");
p_aullshr = (void *)GetProcAddress(hntdll, "_aullshr");
} /* if */
}
@@ -106,7 +123,6 @@ static const magic_divide_t magic_divide[] = {
{ ULL(0x74ae3b5f,0x1558c800), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xabcde},
};
#define NB_MAGIC_DIVIDE (sizeof(magic_divide)/sizeof(*magic_divide))
static void test_RtlExtendedMagicDivide(void)
@@ -114,7 +130,7 @@ static void test_RtlExtendedMagicDivide(void)
int i;
LONGLONG result;
for (i = 0; i < NB_MAGIC_DIVIDE; i++) {
for (i = 0; i < ARRAY_SIZE(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(0x%s, 0x%s, %d) has result 0x%s, expected 0x%s\n",
@@ -133,6 +149,7 @@ typedef struct {
USHORT MaximumLength;
const char *Buffer;
NTSTATUS result;
int broken_len;
} largeint2str_t;
/*
@@ -261,21 +278,20 @@ static const largeint2str_t largeint2str[] = {
*/
{ 2, 32768, 16, 17, "1000000000000000\0--------------------------------------------------", STATUS_SUCCESS},
{ 2, 32768, 16, 16, "1000000000000000---------------------------------------------------", STATUS_SUCCESS},
{ 2, 32768, 16, 16, "1000000000000000---------------------------------------------------", STATUS_SUCCESS, 1},
{ 2, 65536, 17, 18, "10000000000000000\0-------------------------------------------------", STATUS_SUCCESS},
{ 2, 65536, 17, 17, "10000000000000000--------------------------------------------------", STATUS_SUCCESS},
{ 2, 65536, 17, 17, "10000000000000000--------------------------------------------------", STATUS_SUCCESS, 1},
{ 2, 131072, 18, 19, "100000000000000000\0------------------------------------------------", STATUS_SUCCESS},
{ 2, 131072, 18, 18, "100000000000000000-------------------------------------------------", STATUS_SUCCESS},
{ 2, 131072, 18, 18, "100000000000000000-------------------------------------------------", STATUS_SUCCESS, 1},
{16, 0xffffffff, 8, 9, "FFFFFFFF\0----------------------------------------------------------", STATUS_SUCCESS},
{16, 0xffffffff, 8, 8, "FFFFFFFF-----------------------------------------------------------", STATUS_SUCCESS},
{16, 0xffffffff, 8, 7, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW},
{16, 0xffffffff, 8, 8, "FFFFFFFF-----------------------------------------------------------", STATUS_SUCCESS, 1},
{16, 0xffffffff, 8, 7, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW, 1},
{16, 0xa, 1, 2, "A\0-----------------------------------------------------------------", STATUS_SUCCESS},
{16, 0xa, 1, 1, "A------------------------------------------------------------------", STATUS_SUCCESS},
{16, 0, 1, 0, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW},
{16, 0xa, 1, 1, "A------------------------------------------------------------------", STATUS_SUCCESS, 1},
{16, 0, 1, 0, "-------------------------------------------------------------------", STATUS_BUFFER_OVERFLOW, 1},
{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)
@@ -292,7 +308,7 @@ static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t
#ifdef _WIN64
if (largeint2str->value >> 32 == 0xffffffff) /* this crashes on 64-bit Vista */
{
skip( "Value ffffffff%08x broken on 64-bit windows\n", (DWORD)largeint2str->value );
skip( "Value ffffffff%08lx broken on 64-bit windows\n", (DWORD)largeint2str->value );
return;
}
#endif
@@ -335,7 +351,7 @@ static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t
} /* if */
} else {
ok(result == largeint2str->result,
"(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) has result %x, expected: %x\n",
"(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) has result %lx, expected: %lx\n",
test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base, result, largeint2str->result);
if (result == STATUS_SUCCESS) {
ok(unicode_string.Buffer[unicode_string.Length/sizeof(WCHAR)] == '\0',
@@ -344,10 +360,10 @@ static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t
} /* if */
} /* if */
ok(memcmp(unicode_string.Buffer, expected_unicode_string.Buffer, LARGE_STRI_BUFFER_LENGTH * sizeof(WCHAR)) == 0,
"(test %d): RtlInt64ToUnicodeString(0x%x%08x, %d, [out]) assigns string \"%s\", expected: \"%s\"\n",
test_num, (DWORD)(largeint2str->value >>32), (DWORD)largeint2str->value, largeint2str->base,
ansi_str.Buffer, expected_ansi_str.Buffer);
ok(unicode_string.Length == expected_unicode_string.Length,
"(test %d): RtlInt64ToUnicodeString(0x%I64x, %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 ||
broken(largeint2str->broken_len && !unicode_string.Length) /* win11 */,
"(test %d): RtlInt64ToUnicodeString(0x%s, %d, [out]) string has Length %d, expected: %d\n",
test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base,
unicode_string.Length, expected_unicode_string.Length);
@@ -364,7 +380,7 @@ static void test_RtlInt64ToUnicodeString(void)
{
int test_num;
for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
for (test_num = 0; test_num < ARRAY_SIZE(largeint2str); test_num++) {
one_RtlInt64ToUnicodeString_test(test_num, &largeint2str[test_num]);
} /* for */
}
@@ -379,7 +395,7 @@ static void one_RtlLargeIntegerToChar_test(int test_num, const largeint2str_t *l
#ifdef _WIN64
if (largeint2str->value >> 32 == 0xffffffff) /* this crashes on 64-bit Vista */
{
skip( "Value ffffffff%08x broken on 64-bit windows\n", (DWORD)largeint2str->value );
skip( "Value ffffffff%08lx broken on 64-bit windows\n", (DWORD)largeint2str->value );
return;
}
#endif
@@ -393,7 +409,7 @@ static void one_RtlLargeIntegerToChar_test(int test_num, const largeint2str_t *l
result = pRtlLargeIntegerToChar(&value, largeint2str->base, largeint2str->MaximumLength, dest_str);
} /* if */
ok(result == largeint2str->result,
"(test %d): RtlLargeIntegerToChar(0x%s, %d, %d, [out]) has result %x, expected: %x\n",
"(test %d): RtlLargeIntegerToChar(0x%s, %d, %d, [out]) has result %lx, expected: %lx\n",
test_num, wine_dbgstr_longlong(largeint2str->value), largeint2str->base,
largeint2str->MaximumLength, result, largeint2str->result);
ok(memcmp(dest_str, largeint2str->Buffer, LARGE_STRI_BUFFER_LENGTH) == 0,
@@ -409,95 +425,159 @@ static void test_RtlLargeIntegerToChar(void)
int test_num;
ULONGLONG value;
for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
for (test_num = 0; test_num < ARRAY_SIZE(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(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
"(test a): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
wine_dbgstr_longlong(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(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
"(test b): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
wine_dbgstr_longlong(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(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
"(test c): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
wine_dbgstr_longlong(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(0x%s, %d, %d, NULL) has result %x, expected: %x\n",
"(test d): RtlLargeIntegerToChar(0x%s, %d, %d, NULL) has result %lx, expected: %lx\n",
wine_dbgstr_longlong(largeint2str[0].value),
largeint2str[0].base, largeint2str[0].MaximumLength, result, STATUS_ACCESS_VIOLATION);
}
static void test_builtins(void)
{
#ifdef __i386__
void *code_mem;
ULONGLONG u;
LONGLONG l;
#include "pshpack1.h"
struct lldvrm_thunk
{
BYTE push_ebx; /* pushl %ebx */
DWORD push_esp1; /* pushl 24(%esp) */
DWORD push_esp2; /* pushl 24(%esp) */
DWORD push_esp3; /* pushl 24(%esp) */
DWORD push_esp4; /* pushl 24(%esp) */
DWORD call; /* call 24(%esp) */
WORD mov_ecx_eax; /* movl %ecx,%eax */
WORD mov_ebx_edx; /* movl %ebx,%edx */
BYTE pop_ebx; /* popl %ebx */
BYTE ret; /* ret */
};
#include "poppack.h"
static const BYTE call_shift_code[] =
{
0x55, /* pushl %ebp */
0x89, 0xe5, /* movl %esp,%ebp */
0x31, 0xc0, /* xorl %eax,%eax */
0x31, 0xd2, /* xorl %edx,%edx */
0x31, 0xc9, /* xorl %ecx,%ecx */
0x87, 0x45, 0x0c, /* xchgl 12(%ebp),%eax */
0x87, 0x55, 0x10, /* xchgl 16(%ebp),%edx */
0x87, 0x4d, 0x14, /* xchgl 20(%ebp),%ecx */
0xff, 0x55, 0x08, /* call *8(%ebp) */
0x39, 0xe5, /* cmpl %esp,%ebp */
0x74, 0x05, /* je 1f */
0xb8, 0xef, 0xbe, 0xad, 0xde, /* movl $0xdeadbeef,%eax */
0xc9, /* leave */
0xc3, /* ret */
};
LONGLONG (__cdecl *call_shift_func)(void *func, LONGLONG a, LONG b);
static void test__alldvrm(void)
{
struct lldvrm_thunk *thunk = VirtualAlloc(NULL, sizeof(*thunk), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
ULONGLONG (CDECL *call_lldvrm_func)(void *func, ULONGLONG, ULONGLONG) = (void *)thunk;
ULONGLONG ret;
code_mem = VirtualAlloc(NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memset(thunk, 0x90, sizeof(*thunk));
thunk->push_ebx = 0x53; /* pushl %ebx */
thunk->push_esp1 = 0x182474ff; /* pushl 24(%esp) */
thunk->push_esp2 = 0x182474ff; /* pushl 24(%esp) */
thunk->push_esp3 = 0x182474ff; /* pushl 24(%esp) */
thunk->push_esp4 = 0x182474ff; /* pushl 24(%esp) */
thunk->call = 0x182454ff; /* call 24(%esp) */
thunk->pop_ebx = 0x5b; /* popl %ebx */
thunk->ret = 0xc3; /* ret */
l = p_alldiv(100, 7);
ok(l == 14, "_alldiv returned %s\n", wine_dbgstr_longlong(l));
ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, 3);
ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, -3);
ok(ret == 0xff9ee8ddaa499389ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
l = p_alldiv(-100, 7);
ok(l == -14, "_alldiv returned %s\n", wine_dbgstr_longlong(l));
ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, 3);
ok(ret == 0x61172255b66c77ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, -3);
ok(ret == 0, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
l = p_alldiv(0x2000000040ll, 0x100000007ll);
ok(l == 0x1f, "_alldiv returned %s\n", wine_dbgstr_longlong(l));
thunk->mov_ecx_eax = 0xc889;
thunk->mov_ebx_edx = 0xda89;
u = p_aulldiv(100, 7);
ok(u == 14, "_aulldiv returned %s\n", wine_dbgstr_longlong(u));
ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, 3);
ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
ret = call_lldvrm_func(p_alldvrm, 0x0123456701234567ULL, -3);
ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
u = p_aulldiv(-100, 7);
ok(u == 0x2492492492492484ull, "_alldiv returned %s\n", wine_dbgstr_longlong(u));
ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, 3);
ok(ret == 2, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
ret = call_lldvrm_func(p_aulldvrm, 0x0123456701234567ULL, -3);
ok(ret == 0x123456701234567ULL, "got %x%08x\n", (DWORD)(ret >> 32), (DWORD)ret);
u = p_aulldiv(0x2000000040ull, 0x100000007ull);
ok(u == 0x1f, "_aulldiv returned %s\n", wine_dbgstr_longlong(u));
l = p_allrem(100, 7);
ok(l == 2, "_allrem returned %s\n", wine_dbgstr_longlong(l));
l = p_allrem(-100, 7);
ok(l == -2, "_allrem returned %s\n", wine_dbgstr_longlong(l));
l = p_allrem(0x2000000040ll, 0x100000007ll);
ok(l == 0xffffff67, "_allrem returned %s\n", wine_dbgstr_longlong(l));
u = p_aullrem(100, 7);
ok(u == 2, "_aullrem returned %s\n", wine_dbgstr_longlong(u));
u = p_aullrem(-100, 7);
ok(u == 0, "_allrem returned %s\n", wine_dbgstr_longlong(u));
u = p_aullrem(0x2000000040ull, 0x100000007ull);
ok(u == 0xffffff67, "_aullrem returned %s\n", wine_dbgstr_longlong(u));
l = p_allmul(3, 4);
ok(l == 12, "_allmul = %s\n", wine_dbgstr_longlong(l));
l = p_allmul(0x300000001ll, 4);
ok(l == 0xc00000004, "_allmul = %s\n", wine_dbgstr_longlong(l));
memcpy(code_mem, call_shift_code, sizeof(call_shift_code));
call_shift_func = code_mem;
l = call_shift_func(p_allshl, 0x0123456789abcdefll, 12);
ok(l == 0x3456789abcdef000ll, "got %#I64x\n", l);
l = call_shift_func(p_allshl, 0x0123456789abcdefll, 44);
ok(l == 0xbcdef00000000000ll, "got %#I64x\n", l);
l = call_shift_func(p_allshl, 0x0123456789abcdefll, 88);
ok(!l, "got %#I64x\n", l);
l = call_shift_func(p_allshl, 0x0123456789abcdefll, 0x88);
ok(!l, "got %#I64x\n", l);
l = call_shift_func(p_allshl, 0x0123456789abcdefll, 0x108);
ok(l == 0x23456789abcdef00ll, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x0123456789abcdefll, 12);
ok(l == 0x0123456789abcll, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x0123456789abcdefll, 44);
ok(l == 0x01234ll, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x0123456789abcdefll, 88);
ok(!l, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x8123456789abcdefll, 12);
ok(l == 0xfff8123456789abcll, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x8123456789abcdefll, 44);
ok(l == 0xfffffffffff81234ll, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x8123456789abcdefll, 88);
ok(l == -1ll, "got %#I64x\n", l);
l = call_shift_func(p_allshr, 0x8123456789abcdefll, 0x108);
ok(l == 0xff8123456789abcdll, "got %#I64x\n", l);
l = call_shift_func(p_aullshr, 0x8123456789abcdefll, 12);
ok(l == 0x8123456789abcll, "got %#I64x\n", l);
l = call_shift_func(p_aullshr, 0x8123456789abcdefll, 44);
ok(l == 0x81234ll, "got %#I64x\n", l);
l = call_shift_func(p_aullshr, 0x8123456789abcdefll, 88);
ok(!l, "got %#I64x\n", l);
l = call_shift_func(p_aullshr, 0x8123456789abcdefll, 0x108);
ok(l == 0x8123456789abcdll, "got %#I64x\n", l);
VirtualFree(code_mem, 0, MEM_RELEASE);
#endif /* __i386__ */
}
#endif /* __i386__ */
START_TEST(large_int)
{
@@ -509,8 +589,5 @@ START_TEST(large_int)
test_RtlInt64ToUnicodeString();
if (pRtlLargeIntegerToChar)
test_RtlLargeIntegerToChar();
#ifdef __i386__
test__alldvrm();
#endif /* __i386__ */
test_builtins();
}
@@ -0,0 +1,55 @@
.code
; USHORT __readsegds();
PUBLIC __readsegds
__readsegds PROC
mov ax, ds
ret
__readsegds ENDP
; USHORT __readseges();
PUBLIC __readseges
__readseges PROC
mov ax, es
ret
__readseges ENDP
; USHORT __readsegfs();
PUBLIC __readsegfs
__readsegfs PROC
mov ax, fs
ret
__readsegfs ENDP
; USHORT __readseggs();
PUBLIC __readseggs
__readseggs PROC
mov ax, gs
ret
__readseggs ENDP
; USHORT __readsegss();
PUBLIC __readsegss
__readsegss PROC
mov ax, ss
ret
__readsegss ENDP
; void __cld(void);
PUBLIC __cld
__cld PROC
cld
ret
__cld ENDP
; void Call_NtRaiseException(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context, BOOLEAN FirstChance, PVOID pNtRaiseException);
PUBLIC Call_NtRaiseException
Call_NtRaiseException PROC
mov r12, 0DEADCAFEh
call r9
ret
Call_NtRaiseException ENDP
END
File diff suppressed because it is too large Load Diff
+419 -55
View File
@@ -18,7 +18,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "ntdll_test.h"
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winnls.h"
#include "ddk/ntddk.h"
#include "wine/test.h"
static NTSTATUS (WINAPI *pRtlMultiByteToUnicodeN)( LPWSTR dst, DWORD dstlen, LPDWORD reslen,
LPCSTR src, DWORD srclen );
@@ -28,7 +37,9 @@ 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 BOOLEAN (WINAPI *pRtlDosPathNameToNtPathName_U)(const WCHAR*, UNICODE_STRING*, WCHAR**, CURDIR*);
static NTSTATUS (WINAPI *pRtlDosPathNameToNtPathName_U_WithStatus)(const WCHAR*, UNICODE_STRING*, WCHAR**, CURDIR*);
static NTSTATUS (WINAPI *pNtOpenFile)( HANDLE*, ACCESS_MASK, OBJECT_ATTRIBUTES*, IO_STATUS_BLOCK*, ULONG, ULONG );
static void test_RtlDetermineDosPathNameType_U(void)
{
@@ -68,6 +79,18 @@ static void test_RtlDetermineDosPathNameType_U(void)
{ "//.foo", 1 },
{ "\\\\.", 7 },
{ "//.", 7 },
{ "\\\\?\\foo", 6 },
{ "//?/foo", 6 },
{ "/\\?/foo", 6 },
{ "\\\\?foo", 1 },
{ "//?foo", 1 },
{ "\\\\?", 7 },
{ "//?", 7 },
{ "CONIN$", 5 },
{ "CONOUT$", 5 },
{ "CONERR$", 5 },
{ "\\\\.\\CONIN$", 6 },
{ "\\\\.\\CONOUT$", 6 },
{ NULL, 0 }
};
@@ -105,44 +128,53 @@ static void test_RtlIsDosDeviceName_U(void)
{ "\\\\.\\CON", 8, 6, TRUE }, /* fails on win8 */
{ "\\\\.\\con", 8, 6, TRUE }, /* fails on win8 */
{ "\\\\.\\CON2", 0, 0 },
{ "\\\\.\\CONIN$", 0, 0 },
{ "\\\\.\\CONOUT$",0, 0 },
{ "", 0, 0 },
{ "\\\\foo\\nul", 0, 0 },
{ "c:\\nul:", 6, 6 },
{ "c:\\nul\\", 0, 0 },
{ "c:\\nul\\foo", 0, 0 },
{ "c:\\nul::", 6, 6, TRUE }, /* fails on nt4 */
{ "c:\\nul::::::", 6, 6, TRUE }, /* fails on nt4 */
{ "c:prn ", 4, 6 },
{ "c:prn.......", 4, 6 },
{ "c:prn... ...", 4, 6 },
{ "c:NUL .... ", 4, 6, TRUE }, /* fails on nt4 */
{ "c:\\nul::", 6, 6 },
{ "c:\\nul::::::", 6, 6, TRUE }, /* fails on win11 */
{ "c:prn ", 4, 6, TRUE }, /* fails on win11 */
{ "c:prn.......", 4, 6, TRUE }, /* fails on win11 */
{ "c:prn... ...", 4, 6, TRUE }, /* fails on win11 */
{ "c:NUL .... ", 4, 6 },
{ "c: . . .", 0, 0 },
{ "c:", 0, 0 },
{ " . . . :", 0, 0 },
{ ":", 0, 0 },
{ "c:nul. . . :", 4, 6 },
{ "c:nul . . :", 4, 6, TRUE }, /* fails on nt4 */
{ "c:nul . . :", 4, 6 },
{ "c:nul0", 0, 0 },
{ "c:prn:aaa", 4, 6, TRUE }, /* fails on win9x */
{ "c:PRN:.txt", 4, 6 },
{ "c:aux:.txt...", 4, 6 },
{ "c:prn:.txt:", 4, 6 },
{ "c:nul:aaa", 4, 6, TRUE }, /* fails on win9x */
{ "c:prn:aaa", 4, 6, TRUE }, /* fails on win11 */
{ "c:PRN:.txt", 4, 6, TRUE }, /* fails on win11 */
{ "c:aux:.txt...", 4, 6, TRUE }, /* fails on win11 */
{ "c:prn:.txt:", 4, 6, TRUE }, /* fails on win11 */
{ "c:nul:aaa", 4, 6, TRUE }, /* fails on win11 */
{ "con:", 0, 6 },
{ "lpt1:", 0, 8 },
{ "c:com5:", 4, 8 },
{ "c:com5:", 4, 8, TRUE }, /* fails on win11 */
{ "CoM4:", 0, 8 },
{ "lpt9:", 0, 8 },
{ "c:\\lpt0.txt", 0, 0 },
{ "CONIN$", 0, 12, TRUE }, /* fails on win7 */
{ "CONOUT$", 0, 14, TRUE }, /* fails on win7 */
{ "CONERR$", 0, 0 },
{ "CON", 0, 6 },
{ "PIPE", 0, 0 },
{ "\\??\\CONIN$", 8, 12, TRUE }, /* fails on win7 */
{ "\\??\\CONOUT$", 8, 14, TRUE }, /* fails on win7 */
{ "\\??\\CONERR$", 0, 0 },
{ "\\??\\CON", 8, 6, TRUE }, /* fails on win11 */
{ "c:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6 },
// ReactOS r54114
{ "c:\\nul", 6, 6 },
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\nul.txt", 1000, 6, TRUE }, /* fails on win11 */
{ NULL, 0 }
};
@@ -233,14 +265,13 @@ static void test_RtlIsNameLegalDOS8Dot3(void)
ok( spaces == test->spaces, "Wrong spaces value %d/%d for '%s'\n", spaces, test->spaces, test->path );
if (strlen(test->path) <= 12)
{
STRING test_str;
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, lstrlenA(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 );
RtlInitString( &test_str, str );
RtlUpperString( &test_str, &test_str );
ok( !RtlCompareString(&oem_ret, &test_str, FALSE),
"Wrong string '%.*s'/'%s'\n", oem_ret.Length, oem_ret.Buffer, test->path );
}
}
}
@@ -261,6 +292,7 @@ static void test_RtlGetFullPathName_U(void)
static const struct test tests[] =
{
{ "c:/test", "c:\\test", "test"},
{ "c:/test/", "c:\\test\\", NULL},
{ "c:/test ", "c:\\test", "test"},
{ "c:/test.", "c:\\test", "test"},
{ "c:/test .... .. ", "c:\\test", "test"},
@@ -282,27 +314,80 @@ static void test_RtlGetFullPathName_U(void)
{ "c:/test../file", "c:\\test.\\file", "file",
"c:\\test..\\file", "file"}, /* vista */
{ "c:\\test", "c:\\test", "test"},
{ NULL, NULL, NULL}
{ "c:\\test\\*.", "c:\\test\\*", "*"},
{ "c:\\test\\a*b.*", "c:\\test\\a*b.*", "a*b.*"},
{ "c:\\test\\a*b*.", "c:\\test\\a*b*", "a*b*"},
{ "C:\\test", "C:\\test", "test"},
{ "c:/", "c:\\", NULL},
{ "c:.", "C:\\windows", "windows"},
{ "c:foo", "C:\\windows\\foo", "foo"},
{ "c:foo/bar", "C:\\windows\\foo\\bar", "bar"},
{ "c:./foo", "C:\\windows\\foo", "foo"},
{ "\\foo", "C:\\foo", "foo"},
{ "foo", "C:\\windows\\foo", "foo"},
{ ".", "C:\\windows", "windows"},
{ "..", "C:\\", NULL},
{ "...", "C:\\windows\\", NULL},
{ "./foo", "C:\\windows\\foo", "foo"},
{ "foo/..", "C:\\windows", "windows"},
{ "\\windows\\nul", "\\\\.\\nul", NULL},
{ "C:\\nonexistent\\nul", "\\\\.\\nul", NULL},
{ "C:\\con\\con", "\\\\.\\con", NULL,
"C:\\con\\con", "con"}, /* win11 */
{ "C:NUL.", "\\\\.\\NUL", NULL},
{ "C:NUL", "\\\\.\\NUL", NULL},
{ "AUX", "\\\\.\\AUX", NULL},
{ "COM1", "\\\\.\\COM1", NULL},
{ "?<>*\"|:", "C:\\windows\\?<>*\"|:", "?<>*\"|:"},
{ "\\\\foo", "\\\\foo", NULL},
{ "//foo", "\\\\foo", NULL},
{ "\\/foo", "\\\\foo", NULL},
{ "//", "\\\\", NULL},
{ "//foo/", "\\\\foo\\", NULL},
{ "//.", "\\\\.\\", NULL},
{ "//./", "\\\\.\\", NULL},
{ "//.//", "\\\\.\\", NULL},
{ "//./foo", "\\\\.\\foo", "foo"},
{ "//./foo/", "\\\\.\\foo\\", NULL},
{ "//./foo/bar", "\\\\.\\foo\\bar", "bar"},
{ "//./foo/.", "\\\\.\\foo", "foo"},
{ "//./foo/..", "\\\\.\\", NULL},
{ "//?/", "\\\\?\\", NULL},
{ "//?//", "\\\\?\\", NULL},
{ "//?/foo", "\\\\?\\foo", "foo"},
{ "//?/foo/", "\\\\?\\foo\\", NULL},
{ "//?/foo/bar", "\\\\?\\foo\\bar", "bar"},
{ "//?/foo/.", "\\\\?\\foo", "foo"},
{ "//?/foo/..", "\\\\?\\", NULL},
{ "CONIN$", "\\\\.\\CONIN$", NULL,
"C:\\windows\\CONIN$", "CONIN$"},
{ "CONOUT$", "\\\\.\\CONOUT$", NULL,
"C:\\windows\\CONOUT$", "CONOUT$"},
/* RtlGetFullPathName_U() can't understand the global namespace prefix */
{ "\\??\\foo", "C:\\??\\foo", "foo"},
{ 0 }
};
const struct test *test;
WCHAR pathbufW[2*MAX_PATH], rbufferW[MAX_PATH];
CHAR rbufferA[MAX_PATH], rfileA[MAX_PATH];
char rbufferA[MAX_PATH], rfileA[MAX_PATH], curdir[MAX_PATH];
ULONG ret;
WCHAR *file_part;
DWORD reslen;
UINT len;
if (!pRtlGetFullPathName_U)
{
win_skip("RtlGetFullPathName_U is not available\n");
return;
}
GetCurrentDirectoryA(sizeof(curdir), curdir);
SetCurrentDirectoryA("C:\\windows\\");
file_part = (WCHAR *)0xdeadbeef;
lstrcpyW(rbufferW, deadbeefW);
ret = pRtlGetFullPathName_U(NULL, MAX_PATH, rbufferW, &file_part);
ok(!ret, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret);
ok(!ret, "Expected RtlGetFullPathName_U to return 0, got %lu\n", ret);
ok(!lstrcmpW(rbufferW, deadbeefW),
"Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW));
ok(file_part == (WCHAR *)0xdeadbeef ||
@@ -312,7 +397,7 @@ static void test_RtlGetFullPathName_U(void)
file_part = (WCHAR *)0xdeadbeef;
lstrcpyW(rbufferW, deadbeefW);
ret = pRtlGetFullPathName_U(emptyW, MAX_PATH, rbufferW, &file_part);
ok(!ret, "Expected RtlGetFullPathName_U to return 0, got %u\n", ret);
ok(!ret, "Expected RtlGetFullPathName_U to return 0, got %lu\n", ret);
ok(!lstrcmpW(rbufferW, deadbeefW),
"Expected the output buffer to be untouched, got %s\n", wine_dbgstr_w(rbufferW));
ok(file_part == (WCHAR *)0xdeadbeef ||
@@ -325,7 +410,7 @@ static void test_RtlGetFullPathName_U(void)
pRtlMultiByteToUnicodeN(pathbufW , sizeof(pathbufW), NULL, test->path, strlen(test->path)+1 );
ret = pRtlGetFullPathName_U( pathbufW,MAX_PATH, rbufferW, &file_part);
ok( ret == len || (test->alt_rname && ret == strlen(test->alt_rname)*sizeof(WCHAR)),
"Wrong result %d/%d for \"%s\"\n", ret, len, test->path );
"Wrong result %ld/%d for \"%s\"\n", ret, len, test->path );
ok(pRtlUnicodeToMultiByteN(rbufferA,MAX_PATH,&reslen,rbufferW,(lstrlenW(rbufferW) + 1) * sizeof(WCHAR)) == STATUS_SUCCESS,
"RtlUnicodeToMultiByteN failed\n");
ok(!lstrcmpA(rbufferA,test->rname) || (test->alt_rname && !lstrcmpA(rbufferA,test->alt_rname)),
@@ -343,45 +428,321 @@ static void test_RtlGetFullPathName_U(void)
ok( !test->rfile, "Got NULL expected \"%s\"\n", test->rfile );
}
}
SetCurrentDirectoryA(curdir);
}
static void test_RtlDosPathNameToNtPathName_U_WithStatus(void)
static void test_RtlDosPathNameToNtPathName_U(void)
{
static const WCHAR emptyW[] = { 0 };
WCHAR path[MAX_PATH];
char curdir[MAX_PATH];
UNICODE_STRING nameW;
WCHAR *file_part;
NTSTATUS status;
BOOL ret;
int i;
if (!pRtlDosPathNameToNtPathName_U_WithStatus)
static const struct
{
win_skip("RtlDosPathNameToNtPathName_U_WithStatus() is not supported.\n");
return;
const WCHAR *dos;
const WCHAR *nt;
int file_offset; /* offset to file part */
const WCHAR *alt_nt;
BOOL may_fail;
}
tests[] =
{
{L"c:\\", L"\\??\\c:\\", -1},
{L"c:\\test\\*.", L"\\??\\c:\\test\\*", 12},
{L"c:/", L"\\??\\c:\\", -1},
{L"c:/foo", L"\\??\\c:\\foo", 7},
{L"c:/foo.", L"\\??\\c:\\foo", 7},
{L"c:/foo ", L"\\??\\c:\\foo", 7},
{L"c:/foo . .", L"\\??\\c:\\foo", 7},
{L"c:/foo.a", L"\\??\\c:\\foo.a", 7},
{L"c:/foo a", L"\\??\\c:\\foo a", 7},
{L"c:/foo*", L"\\??\\c:\\foo*", 7},
{L"c:/foo*a", L"\\??\\c:\\foo*a", 7},
{L"c:/foo?", L"\\??\\c:\\foo?", 7},
{L"c:/foo?a", L"\\??\\c:\\foo?a", 7},
{L"c:/foo<", L"\\??\\c:\\foo<", 7},
{L"c:/foo<a", L"\\??\\c:\\foo<a", 7},
{L"c:/foo>", L"\\??\\c:\\foo>", 7},
{L"c:/foo>a", L"\\??\\c:\\foo>a", 7},
{L"c:/foo/", L"\\??\\c:\\foo\\", -1},
{L"c:/foo//", L"\\??\\c:\\foo\\", -1},
{L"C:/foo", L"\\??\\C:\\foo", 7},
{L"C:/foo/bar", L"\\??\\C:\\foo\\bar", 11},
{L"C:/foo/bar", L"\\??\\C:\\foo\\bar", 11},
{L"c:.", L"\\??\\C:\\windows", 7},
{L"c:foo", L"\\??\\C:\\windows\\foo", 15},
{L"c:foo/bar", L"\\??\\C:\\windows\\foo\\bar", 19},
{L"c:./foo", L"\\??\\C:\\windows\\foo", 15},
{L"c:/./foo", L"\\??\\c:\\foo", 7},
{L"c:/..", L"\\??\\c:\\", -1},
{L"c:/foo/.", L"\\??\\c:\\foo", 7},
{L"c:/foo/./bar", L"\\??\\c:\\foo\\bar", 11},
{L"c:/foo/../bar", L"\\??\\c:\\bar", 7},
{L"\\foo", L"\\??\\C:\\foo", 7},
{L"foo", L"\\??\\C:\\windows\\foo", 15},
{L".", L"\\??\\C:\\windows", 7},
{L"./", L"\\??\\C:\\windows\\", -1},
{L"..", L"\\??\\C:\\", -1},
{L"...", L"\\??\\C:\\windows\\", -1},
{L"./foo", L"\\??\\C:\\windows\\foo", 15},
{L"foo/..", L"\\??\\C:\\windows", 7},
{L"\\windows\\nul", L"\\??\\nul", -1},
{L"C:NUL.", L"\\??\\NUL", -1},
{L"C:NUL", L"\\??\\NUL", -1},
{L"AUX" , L"\\??\\AUX", -1},
{L"COM1" , L"\\??\\COM1", -1},
{L"?<>*\"|:", L"\\??\\C:\\windows\\?<>*\"|:", 15},
{L"?:", L"\\??\\?:\\", -1},
{L"\\\\foo", L"\\??\\UNC\\foo", -1},
{L"//foo", L"\\??\\UNC\\foo", -1},
{L"\\/foo", L"\\??\\UNC\\foo", -1},
{L"//", L"\\??\\UNC\\", -1},
{L"//foo/", L"\\??\\UNC\\foo\\", -1},
{L"//.", L"\\??\\", -1},
{L"//./", L"\\??\\", -1},
{L"//.//", L"\\??\\", -1},
{L"//./foo", L"\\??\\foo", 4},
{L"//./foo/", L"\\??\\foo\\", -1},
{L"//./foo/bar", L"\\??\\foo\\bar", 8},
{L"//./foo/.", L"\\??\\foo", 4},
{L"//./foo/..", L"\\??\\", -1},
{L"//./foo. . ", L"\\??\\foo", 4},
{L"//?", L"\\??\\", -1},
{L"//?/", L"\\??\\", -1},
{L"//?//", L"\\??\\", -1},
{L"//?/foo", L"\\??\\foo", 4},
{L"//?/foo/", L"\\??\\foo\\", -1},
{L"//?/foo/bar", L"\\??\\foo\\bar", 8},
{L"//?/foo/.", L"\\??\\foo", 4},
{L"//?/foo/..", L"\\??\\", -1},
{L"//?/foo. . ", L"\\??\\foo", 4},
{L"\\\\.", L"\\??\\", -1},
{L"\\\\.\\", L"\\??\\", -1},
{L"\\\\.\\/", L"\\??\\", -1},
{L"\\\\.\\foo", L"\\??\\foo", 4},
{L"\\\\.\\foo/", L"\\??\\foo\\", -1},
{L"\\\\.\\foo/bar", L"\\??\\foo\\bar", 8},
{L"\\\\.\\foo/.", L"\\??\\foo", 4},
{L"\\\\.\\foo/..", L"\\??\\", -1},
{L"\\\\.\\foo. . ", L"\\??\\foo", 4},
{L"\\\\.\\CON", L"\\??\\CON", 4, NULL, TRUE}, /* broken on win7 */
{L"\\\\.\\CONIN$", L"\\??\\CONIN$", 4},
{L"\\\\.\\CONOUT$", L"\\??\\CONOUT$", 4},
{L"\\\\?", L"\\??\\", -1},
{L"\\\\?\\", L"\\??\\", -1},
{L"\\\\?\\/", L"\\??\\/", 4},
{L"\\\\?\\foo", L"\\??\\foo", 4},
{L"\\\\?\\foo/", L"\\??\\foo/", 4},
{L"\\\\?\\foo/bar", L"\\??\\foo/bar", 4},
{L"\\\\?\\foo/.", L"\\??\\foo/.", 4},
{L"\\\\?\\foo/..", L"\\??\\foo/..", 4},
{L"\\\\?\\\\", L"\\??\\\\", -1},
{L"\\\\?\\\\\\", L"\\??\\\\\\", -1},
{L"\\\\?\\foo\\", L"\\??\\foo\\", -1},
{L"\\\\?\\foo\\bar",L"\\??\\foo\\bar", 8},
{L"\\\\?\\foo\\.", L"\\??\\foo\\.", 8},
{L"\\\\?\\foo\\..", L"\\??\\foo\\..", 8},
{L"\\\\?\\foo. . ", L"\\??\\foo. . ", 4},
{L"\\??", L"\\??\\C:\\??", 7},
{L"\\??\\", L"\\??\\C:\\??\\", -1},
{L"\\??\\/", L"\\??\\/", 4},
{L"\\??\\foo", L"\\??\\foo", 4},
{L"\\??\\foo/", L"\\??\\foo/", 4},
{L"\\??\\foo/bar", L"\\??\\foo/bar", 4},
{L"\\??\\foo/.", L"\\??\\foo/.", 4},
{L"\\??\\foo/..", L"\\??\\foo/..", 4},
{L"\\??\\\\", L"\\??\\\\", -1},
{L"\\??\\\\\\", L"\\??\\\\\\", -1},
{L"\\??\\foo\\", L"\\??\\foo\\", -1},
{L"\\??\\foo\\bar", L"\\??\\foo\\bar", 8},
{L"\\??\\foo\\.", L"\\??\\foo\\.", 8},
{L"\\??\\foo\\..", L"\\??\\foo\\..", 8},
{L"\\??\\foo. . ", L"\\??\\foo. . ", 4},
{L"CONIN$", L"\\??\\CONIN$", -1, L"\\??\\C:\\windows\\CONIN$" /* win7 */ },
{L"CONOUT$", L"\\??\\CONOUT$", -1, L"\\??\\C:\\windows\\CONOUT$" /* win7 */ },
{L"cOnOuT$", L"\\??\\cOnOuT$", -1, L"\\??\\C:\\windows\\cOnOuT$" /* win7 */ },
{L"CONERR$", L"\\??\\C:\\windows\\CONERR$", 15},
};
static const WCHAR *error_paths[] = {
NULL, L"", L" ", L"C:\\nonexistent\\nul"
};
GetCurrentDirectoryA(sizeof(curdir), curdir);
SetCurrentDirectoryA("C:\\windows\\");
for (i = 0; i < ARRAY_SIZE(error_paths); ++i)
{
winetest_push_context("%s", debugstr_w(error_paths[i]));
ret = pRtlDosPathNameToNtPathName_U(error_paths[i], &nameW, &file_part, NULL);
ok(!ret, "Got %d.\n", ret);
if (pRtlDosPathNameToNtPathName_U_WithStatus)
{
status = pRtlDosPathNameToNtPathName_U_WithStatus(error_paths[i], &nameW, &file_part, NULL);
ok(status == STATUS_OBJECT_NAME_INVALID, "Got status %#lx.\n", status);
}
winetest_pop_context();
}
GetCurrentDirectoryW( MAX_PATH, path );
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
ret = pRtlDosPathNameToNtPathName_U(tests[i].dos, &nameW, &file_part, NULL);
if (!ret && tests[i].may_fail)
{
win_skip("skipping broken %s\n", debugstr_w(tests[i].dos));
continue;
}
ok(ret == TRUE, "%s: Got %d.\n", debugstr_w(tests[i].dos), ret);
status = pRtlDosPathNameToNtPathName_U_WithStatus( path, &nameW, NULL, NULL );
ok(!status, "Failed convert to nt path, %#x.\n", status);
if (pRtlDosPathNameToNtPathName_U_WithStatus)
{
RtlFreeUnicodeString(&nameW);
status = pRtlDosPathNameToNtPathName_U_WithStatus(tests[i].dos, &nameW, &file_part, NULL);
ok(status == STATUS_SUCCESS, "%s: Got status %#lx.\n", debugstr_w(tests[i].dos), status);
}
status = pRtlDosPathNameToNtPathName_U_WithStatus( NULL, &nameW, NULL, NULL );
ok(status == STATUS_OBJECT_NAME_INVALID || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* W2k3 */,
"Unexpected status %#x.\n", status);
ok(!wcscmp(nameW.Buffer, tests[i].nt)
|| (tests[i].alt_nt && broken(!wcscmp(nameW.Buffer, tests[i].alt_nt))),
"%s: Expected %s, got %s.\n", debugstr_w(tests[i].dos),
debugstr_w(tests[i].nt), debugstr_w(nameW.Buffer));
status = pRtlDosPathNameToNtPathName_U_WithStatus( emptyW, &nameW, NULL, NULL );
ok(status == STATUS_OBJECT_NAME_INVALID || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* W2k3 */,
"Unexpected status %#x.\n", status);
if (!wcscmp(nameW.Buffer, tests[i].nt))
{
if (tests[i].file_offset > 0)
ok(file_part == nameW.Buffer + tests[i].file_offset,
"%s: Expected file part %s, got %s.\n", debugstr_w(tests[i].dos),
debugstr_w(nameW.Buffer + tests[i].file_offset), debugstr_w(file_part));
else
ok(file_part == NULL, "%s: Expected NULL file part, got %s.\n",
debugstr_w(tests[i].dos), debugstr_w(file_part));
}
RtlFreeUnicodeString( &nameW );
RtlFreeUnicodeString(&nameW);
}
SetCurrentDirectoryA(curdir);
}
static void test_nt_names(void)
{
static const struct { const WCHAR *root, *name; NTSTATUS expect, broken; } tests[] =
{
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll", STATUS_SUCCESS },
{ NULL, L"\\??\\C:\\\\windows\\system32\\kernel32.dll", STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32\\", STATUS_FILE_IS_A_DIRECTORY },
{ NULL, L"\\??\\C:\\\\\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32\\.\\kernel32.dll", STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\system32\\..\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\.\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll ", STATUS_OBJECT_NAME_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll..", STATUS_OBJECT_NAME_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows \\system32 \\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows.\\system32.\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows/system32/kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll*", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32?\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"C:\\windows\\system32?\\kernel32.dll", STATUS_OBJECT_PATH_SYNTAX_BAD },
{ NULL, L"/??\\C:\\windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_SYNTAX_BAD },
{ NULL, L"\\??" L"/C:\\windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:/windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\system32\\", STATUS_FILE_IS_A_DIRECTORY },
{ NULL, L"\\??\\C:\\windows\\SyStEm32\\", STATUS_FILE_IS_A_DIRECTORY },
{ NULL, L"\\??\\C:\\windows\\system32\\\\", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32\\foobar\\", STATUS_OBJECT_NAME_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\system32\\Kernel32.Dll\\", STATUS_OBJECT_NAME_INVALID },
{ NULL, L"\\??\\C:\\windows\\system32\\Kernel32.Dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
{ NULL, L"\\??\\C:\\windows\\sys\001", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\", NULL, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\", NULL, STATUS_SUCCESS },
{ L"\\??\\C:\\\\", NULL, STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
{ L"/??\\C:\\", NULL, STATUS_OBJECT_PATH_SYNTAX_BAD },
{ L"\\??\\C:/", NULL, STATUS_OBJECT_NAME_NOT_FOUND },
{ L"\\??" L"/C:", NULL, STATUS_OBJECT_NAME_NOT_FOUND },
{ L"\\??" L"/C:\\", NULL, STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows", NULL, STATUS_SUCCESS },
{ L"\\??\\C:\\windows\\", NULL, STATUS_SUCCESS },
{ L"\\??\\C:\\windows\\.", NULL, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\.\\", NULL, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\..", NULL, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\..\\", NULL, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS },
{ L"\\??\\C:\\\\", L"windows\\system32\\kernel32.dll", STATUS_SUCCESS, STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows", L"system32\\kernel32.dll", STATUS_SUCCESS },
{ L"\\??\\C:\\windows\\", L"system32\\kernel32.dll", STATUS_SUCCESS },
{ L"\\??\\C:\\windows\\", L"system32\\", STATUS_FILE_IS_A_DIRECTORY },
{ L"\\??\\C:\\windows\\", L"SyStEm32\\", STATUS_FILE_IS_A_DIRECTORY },
{ L"\\??\\C:\\windows\\", L"system32\\\\", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L"system32\\foobar\\", STATUS_OBJECT_NAME_NOT_FOUND },
{ L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L"system32\\kernel32.dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows\\", L"system32\\Kernel32.Dll\\", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L"system32\\Kernel32.Dll\\foo", STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows\\", L"\\system32\\kernel32.dll", STATUS_INVALID_PARAMETER },
{ L"\\??\\C:\\windows\\", L"/system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L".\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID, STATUS_OBJECT_PATH_NOT_FOUND },
{ L"\\??\\C:\\windows\\", L"..\\windows\\system32\\kernel32.dll", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L".", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L"..", STATUS_OBJECT_NAME_INVALID },
{ L"\\??\\C:\\windows\\", L"sys\001", STATUS_OBJECT_NAME_INVALID },
{ L"C:\\", L"windows\\system32\\kernel32.dll", STATUS_OBJECT_PATH_SYNTAX_BAD },
};
unsigned int i;
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
IO_STATUS_BLOCK io;
NTSTATUS status;
HANDLE handle;
InitializeObjectAttributes( &attr, &nameW, OBJ_CASE_INSENSITIVE, 0, NULL );
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
attr.RootDirectory = 0;
handle = 0;
status = STATUS_SUCCESS;
if (tests[i].root)
{
RtlInitUnicodeString( &nameW, tests[i].root );
status = pNtOpenFile( &attr.RootDirectory, SYNCHRONIZE | FILE_LIST_DIRECTORY, &attr, &io,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT |
FILE_OPEN_FOR_BACKUP_INTENT | FILE_DIRECTORY_FILE );
}
if (!status && tests[i].name)
{
RtlInitUnicodeString( &nameW, tests[i].name );
status = pNtOpenFile( &handle, FILE_GENERIC_READ, &attr, &io, FILE_SHARE_READ,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE );
}
if (attr.RootDirectory) NtClose( attr.RootDirectory );
if (handle) NtClose( handle );
ok( status == tests[i].expect || broken( tests[i].broken && status == tests[i].broken ),
"%u: got %lx / %lx for %s + %s\n", i, status, tests[i].expect,
debugstr_w( tests[i].root ), debugstr_w( tests[i].name ));
}
}
START_TEST(path)
{
HMODULE mod = GetModuleHandleA("ntdll.dll");
if (!mod)
{
win_skip("Not running on NT, skipping tests\n");
return;
}
pRtlMultiByteToUnicodeN = (void *)GetProcAddress(mod,"RtlMultiByteToUnicodeN");
pRtlUnicodeToMultiByteN = (void *)GetProcAddress(mod,"RtlUnicodeToMultiByteN");
@@ -390,11 +751,14 @@ START_TEST(path)
pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString");
pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3");
pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U");
pRtlDosPathNameToNtPathName_U = (void *)GetProcAddress(mod, "RtlDosPathNameToNtPathName_U");
pRtlDosPathNameToNtPathName_U_WithStatus = (void *)GetProcAddress(mod, "RtlDosPathNameToNtPathName_U_WithStatus");
pNtOpenFile = (void *)GetProcAddress(mod, "NtOpenFile");
test_RtlDetermineDosPathNameType_U();
test_RtlIsDosDeviceName_U();
test_RtlIsNameLegalDOS8Dot3();
test_RtlGetFullPathName_U();
test_RtlDosPathNameToNtPathName_U_WithStatus();
test_RtlDosPathNameToNtPathName_U();
test_nt_names();
}
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -155,7 +155,7 @@ static BOOL init_function_ptrs(void)
!pNtRequestPort || !pNtRegisterThreadTerminatePort ||
!pNtConnectPort || !pRtlInitUnicodeString)
{
win_skip("Needed port functions are not available\n");
todo_wine win_skip("Needed port functions are not available\n");
FreeLibrary(hntdll);
return FALSE;
}
@@ -183,10 +183,10 @@ static void ProcessConnectionRequest(union lpc_message *LpcMessage, PHANDLE pAcc
}
status = pNtAcceptConnectPort(pAcceptPortHandle, 0, &LpcMessage->msg, 1, NULL, NULL);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
status = pNtCompleteConnectPort(*pAcceptPortHandle);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
}
static void ProcessLpcRequest(HANDLE PortHandle, union lpc_message *LpcMessage)
@@ -202,7 +202,7 @@ static void ProcessLpcRequest(HANDLE PortHandle, union lpc_message *LpcMessage)
strcpy((LPSTR)LpcMessage->msg64.Data, REPLY);
status = pNtReplyPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
ok(LpcMessage->msg64.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType);
ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REPLY),
@@ -217,7 +217,7 @@ static void ProcessLpcRequest(HANDLE PortHandle, union lpc_message *LpcMessage)
strcpy((LPSTR)LpcMessage->msg.Data, REPLY);
status = pNtReplyPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
ok(LpcMessage->msg.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType);
ok(!strcmp((LPSTR)LpcMessage->msg.Data, REPLY),
@@ -239,11 +239,11 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
sqos.EffectiveOnly = TRUE;
status = pNtConnectPort(&PortHandle, &port, &sqos, 0, 0, &len, NULL, NULL);
todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
if (status != STATUS_SUCCESS) return 1;
status = pNtRegisterThreadTerminatePort(PortHandle);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
if (is_wow64)
{
@@ -256,7 +256,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
strcpy((LPSTR)LpcMessage->msg64.Data, REQUEST1);
status = pNtRequestPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
ok(LpcMessage->msg64.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg64.MessageType);
ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data);
@@ -269,7 +269,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
ok(!strcmp((LPSTR)out->msg64.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg64.Data);
ok(out->msg64.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg64.MessageType);
}
@@ -284,7 +284,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
strcpy((LPSTR)LpcMessage->msg.Data, REQUEST1);
status = pNtRequestPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
ok(LpcMessage->msg.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg.MessageType);
ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data);
@@ -297,7 +297,7 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %lx\n", status);
ok(!strcmp((LPSTR)out->msg.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg.Data);
ok(out->msg.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg.MessageType);
}
@@ -324,7 +324,7 @@ static void test_ports_server( HANDLE PortHandle )
status = pNtReplyWaitReceivePort(PortHandle, NULL, NULL, &LpcMessage->msg);
todo_wine
{
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d(%x)\n", status, status);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld(%lx)\n", status, status);
}
/* STATUS_INVALID_HANDLE: win2k without admin rights will perform an
* endless loop here
@@ -384,7 +384,7 @@ START_TEST(port)
status = pNtCreatePort(&port_handle, &obj, 100, 100, 0);
if (status == STATUS_ACCESS_DENIED) skip("Not enough rights\n");
else todo_wine ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %d\n", status);
else ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %ld\n", status);
if (status == STATUS_SUCCESS)
{
-209
View File
@@ -1,209 +0,0 @@
/*
* Unit test suite for process functions
*
* Copyright 2017 Michael Müller
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <stdio.h>
#include "ntdll_test.h"
#include "windef.h"
#include "winbase.h"
static NTSTATUS (WINAPI *pNtResumeProcess)(HANDLE);
static NTSTATUS (WINAPI *pNtSuspendProcess)(HANDLE);
static NTSTATUS (WINAPI *pNtSuspendThread)(HANDLE,PULONG);
static NTSTATUS (WINAPI *pNtResumeThread)(HANDLE);
static void test_NtSuspendProcess(char *process_name)
{
PROCESS_INFORMATION info;
DEBUG_EVENT ev;
STARTUPINFOA startup;
NTSTATUS status;
HANDLE event;
char buffer[MAX_PATH];
ULONG count;
DWORD ret;
status = pNtResumeProcess(GetCurrentProcess());
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
event = CreateEventA(NULL, TRUE, FALSE, "wine_suspend_event");
ok(!!event, "Failed to create event: %u\n", GetLastError());
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
sprintf(buffer, "%s tests/process.c dummy_process wine_suspend_event", process_name);
ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
ok(ret, "CreateProcess failed with error %u\n", GetLastError());
ret = WaitForSingleObject(event, 500);
ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
status = pNtSuspendProcess(info.hProcess);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ResetEvent(event);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
status = NtResumeThread(info.hThread, &count);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ok(count == 1, "Expected count 1, got %d\n", count);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
status = pNtResumeProcess(info.hProcess);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
status = pNtSuspendThread(info.hThread, &count);
ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
ok(count == 0, "Expected count 0, got %d\n", count);
ResetEvent(event);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
status = pNtResumeProcess(info.hProcess);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
status = pNtSuspendThread(info.hThread, &count);
ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
ok(count == 0, "Expected count 0, got %d\n", count);
status = pNtSuspendThread(info.hThread, &count);
ok(status == STATUS_SUCCESS, "NtSuspendThread failed: %x\n", status);
ok(count == 1, "Expected count 1, got %d\n", count);
ResetEvent(event);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
status = pNtResumeProcess(info.hProcess);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
status = pNtResumeProcess(info.hProcess);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
ret = DebugActiveProcess(info.dwProcessId);
ok(ret, "Failed to debug process: %d\n", GetLastError());
ResetEvent(event);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
disable_success_count
for (;;)
{
ret = WaitForDebugEvent(&ev, INFINITE);
ok(ret, "WaitForDebugEvent failed, last error %#x.\n", GetLastError());
if (!ret) break;
if (ev.dwDebugEventCode == OUTPUT_DEBUG_STRING_EVENT) break;
ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
if (!ret) break;
}
ResetEvent(event);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
status = pNtResumeProcess(info.hProcess);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
status = NtResumeThread(info.hThread, &count);
ok(status == STATUS_SUCCESS, "NtResumeProcess failed: %x\n", status);
ok(count == 0, "Expected count 0, got %d\n", count);
ret = WaitForSingleObject(event, 200);
ok(ret == WAIT_TIMEOUT, "Expected timeout, got: %d\n", ret);
ret = ContinueDebugEvent(ev.dwProcessId, ev.dwThreadId, DBG_CONTINUE);
ok(ret, "ContinueDebugEvent failed, last error %#x.\n", GetLastError());
ret = WaitForSingleObject(event, 200);
ros_skip_flaky
ok(ret == WAIT_OBJECT_0, "Event was not signaled: %d\n", ret);
TerminateProcess(info.hProcess, 0);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
}
static void dummy_process(char *event_name)
{
HANDLE event = OpenEventA(EVENT_ALL_ACCESS, FALSE, event_name);
while (TRUE)
{
SetEvent(event);
OutputDebugStringA("test");
Sleep(5);
}
}
START_TEST(process)
{
HMODULE mod;
char **argv;
int argc;
argc = winetest_get_mainargs(&argv);
if (argc >= 4 && strcmp(argv[2], "dummy_process") == 0)
{
dummy_process(argv[3]);
return;
}
mod = GetModuleHandleA("ntdll.dll");
if (!mod)
{
win_skip("Not running on NT, skipping tests\n");
return;
}
pNtResumeProcess = (void*)GetProcAddress(mod, "NtResumeProcess");
pNtSuspendProcess = (void*)GetProcAddress(mod, "NtSuspendProcess");
pNtResumeThread = (void*)GetProcAddress(mod, "NtResumeThread");
pNtSuspendThread = (void*)GetProcAddress(mod, "NtSuspendThread");
test_NtSuspendProcess(argv[0]);
}
File diff suppressed because it is too large Load Diff
@@ -1,69 +0,0 @@
Index: generated.c
===================================================================
--- generated.c (Revision 48052)
+++ generated.c (Arbeitskopie)
@@ -442,6 +442,7 @@
static void test_pack_FLOATING_SAVE_AREA(void)
{
+#if 0
/* FLOATING_SAVE_AREA */
TEST_TYPE_SIZE (FLOATING_SAVE_AREA, 112)
TEST_TYPE_ALIGN (FLOATING_SAVE_AREA, 4)
@@ -472,6 +473,7 @@
TEST_FIELD_SIZE (FLOATING_SAVE_AREA, Cr0NpxState, 4)
TEST_FIELD_ALIGN (FLOATING_SAVE_AREA, Cr0NpxState, 4)
TEST_FIELD_OFFSET(FLOATING_SAVE_AREA, Cr0NpxState, 108)
+#endif
}
static void test_pack_FPO_DATA(void)
@@ -875,7 +877,7 @@
static void test_pack_IMAGE_LOAD_CONFIG_DIRECTORY(void)
{
/* IMAGE_LOAD_CONFIG_DIRECTORY */
- TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, 88)
+// TEST_TYPE_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, 88)
TEST_TYPE_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, 8)
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, Size, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, Size, 4)
@@ -898,6 +900,7 @@
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, CriticalSectionDefaultTimeout, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, CriticalSectionDefaultTimeout, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, CriticalSectionDefaultTimeout, 20)
+#if 0 // wine headers are broken
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, DeCommitFreeBlockThreshold, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, DeCommitFreeBlockThreshold, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, DeCommitFreeBlockThreshold, 24)
@@ -937,6 +940,7 @@
TEST_FIELD_SIZE (IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerCount, 4)
TEST_FIELD_ALIGN (IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerCount, 4)
TEST_FIELD_OFFSET(IMAGE_LOAD_CONFIG_DIRECTORY, SEHandlerCount, 80)
+#endif
}
static void test_pack_IMAGE_NT_HEADERS(void)
@@ -1980,11 +1984,13 @@
static void test_pack_PFLOATING_SAVE_AREA(void)
{
+#if 0
/* PFLOATING_SAVE_AREA */
TEST_TYPE_SIZE (PFLOATING_SAVE_AREA, 8)
TEST_TYPE_ALIGN (PFLOATING_SAVE_AREA, 8)
TEST_TARGET_SIZE (PFLOATING_SAVE_AREA, 112)
TEST_TARGET_ALIGN(PFLOATING_SAVE_AREA, 4)
+#endif
}
static void test_pack_PFPO_DATA(void)
@@ -2157,7 +2163,9 @@
/* PIMAGE_LOAD_CONFIG_DIRECTORY */
TEST_TYPE_SIZE (PIMAGE_LOAD_CONFIG_DIRECTORY, 8)
TEST_TYPE_ALIGN (PIMAGE_LOAD_CONFIG_DIRECTORY, 8)
+#if 0// wine headers are broken
TEST_TARGET_SIZE (PIMAGE_LOAD_CONFIG_DIRECTORY, 88)
+#endif
TEST_TARGET_ALIGN(PIMAGE_LOAD_CONFIG_DIRECTORY, 8)
}
File diff suppressed because it is too large Load Diff
+50 -8
View File
@@ -21,7 +21,14 @@
* in later versions of ntdll.
*/
#include "ntdll_test.h"
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.h"
#ifdef __WINE_WINTERNL_H
@@ -40,6 +47,8 @@ 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 *pRtlFindNextForwardRunSet)(PRTL_BITMAP,ULONG,PULONG);
static ULONG (WINAPI *pRtlFindNextForwardRunClear)(PRTL_BITMAP,ULONG,PULONG);
static ULONG (WINAPI *pRtlNumberOfSetBits)(PRTL_BITMAP);
static ULONG (WINAPI *pRtlNumberOfClearBits)(PRTL_BITMAP);
static ULONG (WINAPI *pRtlFindLongestRunSet)(PRTL_BITMAP,PULONG);
@@ -69,6 +78,8 @@ static void InitFunctionPtrs(void)
pRtlFindLeastSignificantBit = (void *)GetProcAddress(hntdll, "RtlFindLeastSignificantBit");
pRtlFindSetRuns = (void *)GetProcAddress(hntdll, "RtlFindSetRuns");
pRtlFindClearRuns = (void *)GetProcAddress(hntdll, "RtlFindClearRuns");
pRtlFindNextForwardRunSet = (void *)GetProcAddress(hntdll, "RtlFindNextForwardRunSet");
pRtlFindNextForwardRunClear = (void *)GetProcAddress(hntdll, "RtlFindNextForwardRunClear");
pRtlFindLongestRunSet = (void *)GetProcAddress(hntdll, "RtlFindLongestRunSet");
pRtlFindLongestRunClear = (void *)GetProcAddress(hntdll, "RtlFindLongestRunClear");
}
@@ -497,7 +508,7 @@ static void test_RtlFindSetRuns(void)
/* Get first 2 */
ulCount = pRtlFindSetRuns(&bm, runs, 2, FALSE);
ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
ok(ulCount == 2, "RtlFindClearRuns returned %ld, expected 2\n", ulCount);
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");
@@ -507,7 +518,7 @@ static void test_RtlFindSetRuns(void)
/* Get longest 3 */
memset(runs, 0, sizeof(runs));
ulCount = pRtlFindSetRuns(&bm, runs, 2, TRUE);
ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
ok(ulCount == 2, "RtlFindClearRuns returned %ld, expected 2\n", ulCount);
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");
@@ -517,7 +528,7 @@ static void test_RtlFindSetRuns(void)
/* Get all 3 */
memset(runs, 0, sizeof(runs));
ulCount = pRtlFindSetRuns(&bm, runs, 3, TRUE);
ok(ulCount == 3, "RtlFindClearRuns returned %d, expected 3\n", ulCount);
ok(ulCount == 3, "RtlFindClearRuns returned %ld, expected 3\n", ulCount);
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 ||
@@ -535,7 +546,7 @@ static void test_RtlFindSetRuns(void)
ULONG ulStart = 0;
ulCount = pRtlFindLongestRunSet(&bm, &ulStart);
ok(ulCount == 33 && ulStart == 1877,"didn't find longest %d %d\n",ulCount,ulStart);
ok(ulCount == 33 && ulStart == 1877,"didn't find longest %ld %ld\n",ulCount,ulStart);
memset(buff, 0, sizeof(buff));
ulCount = pRtlFindLongestRunSet(&bm, &ulStart);
@@ -574,7 +585,7 @@ static void test_RtlFindClearRuns(void)
/* Get first 2 */
ulCount = pRtlFindClearRuns(&bm, runs, 2, FALSE);
ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
ok(ulCount == 2, "RtlFindClearRuns returned %ld, expected 2\n", ulCount);
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");
@@ -584,7 +595,7 @@ static void test_RtlFindClearRuns(void)
/* Get longest 3 */
memset(runs, 0, sizeof(runs));
ulCount = pRtlFindClearRuns(&bm, runs, 2, TRUE);
ok(ulCount == 2, "RtlFindClearRuns returned %d, expected 2\n", ulCount);
ok(ulCount == 2, "RtlFindClearRuns returned %ld, expected 2\n", ulCount);
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");
@@ -594,7 +605,7 @@ static void test_RtlFindClearRuns(void)
/* Get all 3 */
memset(runs, 0, sizeof(runs));
ulCount = pRtlFindClearRuns(&bm, runs, 3, TRUE);
ok(ulCount == 3, "RtlFindClearRuns returned %d, expected 3\n", ulCount);
ok(ulCount == 3, "RtlFindClearRuns returned %ld, expected 3\n", ulCount);
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 ||
@@ -620,6 +631,35 @@ static void test_RtlFindClearRuns(void)
}
}
static void test_RtlFindNextForwardRunSet(void)
{
BYTE mask[8] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff };
ULONG ulStart = 0;
ULONG ulCount, lpPos;
if (!pRtlFindNextForwardRunSet)
return;
pRtlInitializeBitMap(&bm, mask, 62);
ulCount = pRtlFindNextForwardRunSet(&bm, ulStart, &lpPos);
ok(ulCount == 6, "Invalid length of found set run: %ld, expected 6\n", ulCount);
ok(lpPos == 56, "Invalid position of found set run: %ld, expected 56\n", lpPos);
}
static void test_RtlFindNextForwardRunClear(void)
{
BYTE mask[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
ULONG ulStart = 0;
ULONG ulCount, lpPos;
if (!pRtlFindNextForwardRunClear)
return;
pRtlInitializeBitMap(&bm, mask, 62);
ulCount = pRtlFindNextForwardRunClear(&bm, ulStart, &lpPos);
ok(ulCount == 6, "Invalid length of found clear run: %ld, expected 6\n", ulCount);
ok(lpPos == 56, "Invalid position of found clear run: %ld, expected 56\n", lpPos);
}
#endif
START_TEST(rtlbitmap)
@@ -645,6 +685,8 @@ START_TEST(rtlbitmap)
test_RtlFindLeastSignificantBit();
test_RtlFindSetRuns();
test_RtlFindClearRuns();
test_RtlFindNextForwardRunSet();
test_RtlFindNextForwardRunClear();
}
#endif
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+11 -4
View File
@@ -23,8 +23,13 @@ extern void func_rtl(void);
extern void func_rtlbitmap(void);
extern void func_rtlstr(void);
extern void func_string(void);
extern void func_sync(void);
extern void func_thread(void);
extern void func_threadpool(void);
extern void func_time(void);
extern void func_unwind(void);
extern void func_virtual(void);
extern void func_wow64(void);
const struct test winetest_testlist[] =
{
@@ -35,22 +40,24 @@ const struct test winetest_testlist[] =
{ "error", func_error },
{ "exception", func_exception },
{ "file", func_file },
#ifdef _M_IX86
{ "generated", func_generated },
#endif
{ "info", func_info },
{ "large_int", func_large_int },
{ "om", func_om },
{ "path", func_path },
{ "pipe", func_pipe },
{ "port", func_port },
{ "process", func_process },
{ "reg", func_reg },
{ "rtl", func_rtl },
{ "rtlbitmap", func_rtlbitmap },
{ "rtlstr", func_rtlstr },
{ "string", func_string },
{ "threadpool", func_threadpool},
{ "sync", func_sync },
{ "thread", func_thread },
{ "threadpool", func_threadpool },
{ "time", func_time },
{ "unwind", func_unwind },
{ "virtual", func_virtual },
{ "wow64", func_wow64 },
{ 0, 0 }
};
+216
View File
@@ -0,0 +1,216 @@
/*
* Unit test suite for ntdll thread functions
*
* Copyright 2021 Paul Gofman for CodeWeavers
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.h"
static NTSTATUS (WINAPI *pNtCreateThreadEx)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *,
HANDLE, PRTL_THREAD_START_ROUTINE, void *,
ULONG, ULONG_PTR, SIZE_T, SIZE_T, PS_ATTRIBUTE_LIST * );
static int * (CDECL *p_errno)(void);
static void init_function_pointers(void)
{
HMODULE hntdll = GetModuleHandleA( "ntdll.dll" );
#define GET_FUNC(name) p##name = (void *)GetProcAddress( hntdll, #name );
GET_FUNC( NtCreateThreadEx );
GET_FUNC( _errno );
#undef GET_FUNC
}
static void CALLBACK test_NtCreateThreadEx_proc(void *param)
{
}
static void test_dbg_hidden_thread_creation(void)
{
RTL_USER_PROCESS_PARAMETERS *params;
PS_CREATE_INFO create_info;
PS_ATTRIBUTE_LIST ps_attr;
WCHAR path[MAX_PATH + 4];
HANDLE process, thread;
UNICODE_STRING imageW;
BOOLEAN dbg_hidden;
NTSTATUS status;
if (!pNtCreateThreadEx)
{
win_skip( "NtCreateThreadEx is not available.\n" );
return;
}
status = pNtCreateThreadEx( &thread, THREAD_ALL_ACCESS, NULL, GetCurrentProcess(), test_NtCreateThreadEx_proc,
NULL, THREAD_CREATE_FLAGS_CREATE_SUSPENDED, 0, 0, 0, NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
dbg_hidden = 0xcc;
status = NtQueryInformationThread( thread, ThreadHideFromDebugger, &dbg_hidden, sizeof(dbg_hidden), NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
ok( !dbg_hidden, "Got unexpected dbg_hidden %#x.\n", dbg_hidden );
status = NtResumeThread( thread, NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
WaitForSingleObject( thread, INFINITE );
CloseHandle( thread );
status = pNtCreateThreadEx( &thread, THREAD_ALL_ACCESS, NULL, GetCurrentProcess(), test_NtCreateThreadEx_proc,
NULL, THREAD_CREATE_FLAGS_CREATE_SUSPENDED | THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER,
0, 0, 0, NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
dbg_hidden = 0xcc;
status = NtQueryInformationThread( thread, ThreadHideFromDebugger, &dbg_hidden, sizeof(dbg_hidden), NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
ok( dbg_hidden == 1, "Got unexpected dbg_hidden %#x.\n", dbg_hidden );
status = NtResumeThread( thread, NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
WaitForSingleObject( thread, INFINITE );
CloseHandle( thread );
lstrcpyW( path, L"\\??\\" );
GetModuleFileNameW( NULL, path + 4, MAX_PATH );
RtlInitUnicodeString( &imageW, path );
memset( &ps_attr, 0, sizeof(ps_attr) );
ps_attr.Attributes[0].Attribute = PS_ATTRIBUTE_IMAGE_NAME;
ps_attr.Attributes[0].Size = lstrlenW(path) * sizeof(WCHAR);
ps_attr.Attributes[0].ValuePtr = path;
ps_attr.TotalLength = sizeof(ps_attr);
#if !defined (__REACTOS__) || (DLL_EXPORT_VERSION >= 0x601)
status = RtlCreateProcessParametersEx( &params, &imageW, NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, NULL, PROCESS_PARAMS_FLAG_NORMALIZED );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
/* NtCreateUserProcess() may return STATUS_INVALID_PARAMETER with some uninitialized data in create_info. */
memset( &create_info, 0, sizeof(create_info) );
create_info.Size = sizeof(create_info);
status = NtCreateUserProcess( &process, &thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
NULL, NULL, 0, THREAD_CREATE_FLAGS_CREATE_SUSPENDED
| THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER, params,
&create_info, &ps_attr );
ok( status == STATUS_INVALID_PARAMETER, "Got unexpected status %#lx.\n", status );
status = NtCreateUserProcess( &process, &thread, PROCESS_ALL_ACCESS, THREAD_ALL_ACCESS,
NULL, NULL, 0, THREAD_CREATE_FLAGS_CREATE_SUSPENDED, params,
&create_info, &ps_attr );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
status = NtTerminateProcess( process, 0 );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
CloseHandle( process );
CloseHandle( thread );
#endif
}
struct unique_teb_thread_args
{
TEB *teb;
HANDLE running_event;
HANDLE quit_event;
};
static void CALLBACK test_unique_teb_proc(void *param)
{
struct unique_teb_thread_args *args = param;
args->teb = NtCurrentTeb();
SetEvent( args->running_event );
WaitForSingleObject( args->quit_event, INFINITE );
}
static void test_unique_teb(void)
{
HANDLE threads[2], running_events[2];
struct unique_teb_thread_args args1, args2;
NTSTATUS status;
if (!pNtCreateThreadEx)
{
win_skip( "NtCreateThreadEx is not available.\n" );
return;
}
args1.running_event = running_events[0] = CreateEventW( NULL, FALSE, FALSE, NULL );
ok( args1.running_event != NULL, "CreateEventW failed %lu.\n", GetLastError() );
args2.running_event = running_events[1] = CreateEventW( NULL, FALSE, FALSE, NULL );
ok( args2.running_event != NULL, "CreateEventW failed %lu.\n", GetLastError() );
args1.quit_event = args2.quit_event = CreateEventW( NULL, TRUE, FALSE, NULL );
ok( args1.quit_event != NULL, "CreateEventW failed %lu.\n", GetLastError() );
status = pNtCreateThreadEx( &threads[0], THREAD_ALL_ACCESS, NULL, GetCurrentProcess(), test_unique_teb_proc,
&args1, 0, 0, 0, 0, NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
status = pNtCreateThreadEx( &threads[1], THREAD_ALL_ACCESS, NULL, GetCurrentProcess(), test_unique_teb_proc,
&args2, 0, 0, 0, 0, NULL );
ok( status == STATUS_SUCCESS, "Got unexpected status %#lx.\n", status );
WaitForMultipleObjects( 2, running_events, TRUE, INFINITE );
SetEvent( args1.quit_event );
WaitForMultipleObjects( 2, threads, TRUE, INFINITE );
CloseHandle( threads[0] );
CloseHandle( threads[1] );
CloseHandle( args1.running_event );
CloseHandle( args2.running_event );
CloseHandle( args1.quit_event );
ok( NtCurrentTeb() != args1.teb, "Multiple threads have TEB %p.\n", args1.teb );
ok( NtCurrentTeb() != args2.teb, "Multiple threads have TEB %p.\n", args2.teb );
ok( args1.teb != args2.teb, "Multiple threads have TEB %p.\n", args1.teb );
}
static void test_errno(void)
{
int val;
if (!p_errno)
{
win_skip( "_errno not available\n" );
return;
}
ok( NtCurrentTeb()->Peb->TlsBitmap->Buffer[0] & (1 << 16), "TLS entry 16 not allocated\n" );
*p_errno() = 0xdead;
val = PtrToLong( TlsGetValue( 16 ));
ok( val == 0xdead, "wrong value %x\n", val );
*p_errno() = 0xbeef;
val = PtrToLong( TlsGetValue( 16 ));
ok( val == 0xbeef, "wrong value %x\n", val );
}
START_TEST(thread)
{
init_function_pointers();
test_dbg_hidden_thread_creation();
test_unique_teb();
test_errno();
}
+9 -14
View File
@@ -18,11 +18,14 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "ntdll_test.h"
#include <stdarg.h>
#ifdef __REACTOS__
typedef void (CALLBACK *PTP_IO_CALLBACK)(PTP_CALLBACK_INSTANCE,void*,void*,IO_STATUS_BLOCK*,PTP_IO);
#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "wine/test.h"
static NTSTATUS (WINAPI *pTpAllocCleanupGroup)(TP_CLEANUP_GROUP **);
static NTSTATUS (WINAPI *pTpAllocIoCompletion)(TP_IO **,HANDLE,PTP_IO_CALLBACK,void *,TP_CALLBACK_ENVIRON *);
@@ -584,7 +587,7 @@ static void test_tp_simple(void)
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( NtCurrentTeb()->Peb->ImageBaseAddress );
TP_POOL_STACK_INFORMATION stack_info;
TP_CALLBACK_ENVIRON environment;
#ifndef __REACTOS__
#if !defined(__REACTOS__) || _WIN32_WINNT >= _WIN32_WINNT_WIN7
TP_CALLBACK_ENVIRON_V3 environment3;
#endif
TP_CLEANUP_GROUP *group;
@@ -622,8 +625,8 @@ static void test_tp_simple(void)
result = WaitForSingleObject(semaphore, 1000);
ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", result);
#ifndef __REACTOS__ // Windows 7
/* test with environment version 3 */
#if !defined(__REACTOS__) || _WIN32_WINNT >= _WIN32_WINNT_WIN7
memset(&environment3, 0, sizeof(environment3));
environment3.Version = 3;
environment3.Pool = pool;
@@ -2039,11 +2042,7 @@ static DWORD WINAPI io_wait_thread(void *arg)
static void test_tp_io(void)
{
TP_CALLBACK_ENVIRON environment = {.Version = 1};
#ifdef __REACTOS__
OVERLAPPED ovl = {0}, ovl2 = {0};
#else
OVERLAPPED ovl = {}, ovl2 = {};
#endif
HANDLE client, server, thread;
struct io_cb_ctx userdata;
char in[1], in2[1];
@@ -2263,11 +2262,7 @@ static void CALLBACK kernel32_io_cb(TP_CALLBACK_INSTANCE *instance, void *userda
static void test_kernel32_tp_io(void)
{
TP_CALLBACK_ENVIRON environment = {.Version = 1};
#ifdef __REACTOS__
OVERLAPPED ovl = {0}, ovl2 = {0};
#else
OVERLAPPED ovl = {}, ovl2 = {};
#endif
HANDLE client, server, thread;
struct io_cb_ctx userdata;
char in[1], in2[1];
+343 -111
View File
@@ -18,84 +18,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __REACTOS__
#define NONAMELESSUNION
#endif
#include "ntdll_test.h"
#ifndef __REACTOS__
#include <stdarg.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "ddk/wdm.h"
#else /* FIXME: Inspect */
typedef struct _KSYSTEM_TIME {
ULONG LowPart;
LONG High1Time;
LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;
typedef enum _NT_PRODUCT_TYPE {
NtProductWinNt = 1,
NtProductLanManNt,
NtProductServer
} NT_PRODUCT_TYPE, *PNT_PRODUCT_TYPE;
#define PROCESSOR_FEATURE_MAX 64
typedef enum _ALTERNATIVE_ARCHITECTURE_TYPE
{
StandardDesign,
NEC98x86,
EndAlternatives
} ALTERNATIVE_ARCHITECTURE_TYPE;
#define MAX_WOW64_SHARED_ENTRIES 16
typedef struct _KUSER_SHARED_DATA {
ULONG TickCountLowDeprecated;
ULONG TickCountMultiplier;
volatile KSYSTEM_TIME InterruptTime;
volatile KSYSTEM_TIME SystemTime;
volatile KSYSTEM_TIME TimeZoneBias;
USHORT ImageNumberLow;
USHORT ImageNumberHigh;
WCHAR NtSystemRoot[260];
ULONG MaxStackTraceDepth;
ULONG CryptoExponent;
ULONG TimeZoneId;
ULONG LargePageMinimum;
ULONG Reserved2[7];
NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
ULONG NtMajorVersion;
ULONG NtMinorVersion;
BOOLEAN ProcessorFeatures[PROCESSOR_FEATURE_MAX];
ULONG Reserved1;
ULONG Reserved3;
volatile ULONG TimeSlip;
ALTERNATIVE_ARCHITECTURE_TYPE AlternativeArchitecture;
LARGE_INTEGER SystemExpirationDate;
ULONG SuiteMask;
BOOLEAN KdDebuggerEnabled;
UCHAR NXSupportPolicy;
volatile ULONG ActiveConsoleId;
volatile ULONG DismountCount;
ULONG ComPlusPackage;
ULONG LastSystemRITEventTickCount;
ULONG NumberOfPhysicalPages;
BOOLEAN SafeBootMode;
ULONG TraceLogging;
ULONGLONG TestRetInstruction;
ULONG SystemCall;
ULONG SystemCallReturn;
ULONGLONG SystemCallPad[3];
union {
volatile KSYSTEM_TIME TickCount;
volatile ULONG64 TickCountQuad;
} DUMMYUNIONNAME;
ULONG Cookie;
ULONG Wow64SharedInformation[MAX_WOW64_SHARED_ENTRIES];
} KSHARED_USER_DATA, *PKSHARED_USER_DATA;
#endif /* !__REACTOS__ */
#include "intrin.h"
#include "wine/test.h"
#define TICKSPERSEC 10000000
#define TICKSPERMSEC 10000
@@ -104,9 +36,14 @@ typedef struct _KUSER_SHARED_DATA {
static VOID (WINAPI *pRtlTimeToTimeFields)( const LARGE_INTEGER *liTime, PTIME_FIELDS TimeFields) ;
static VOID (WINAPI *pRtlTimeFieldsToTime)( PTIME_FIELDS TimeFields, PLARGE_INTEGER Time) ;
static NTSTATUS (WINAPI *pNtQueryPerformanceCounter)( LARGE_INTEGER *counter, LARGE_INTEGER *frequency );
static NTSTATUS (WINAPI *pNtQuerySystemInformation)( SYSTEM_INFORMATION_CLASS class,
void *info, ULONG size, ULONG *ret_size );
static NTSTATUS (WINAPI *pRtlQueryTimeZoneInformation)( RTL_TIME_ZONE_INFORMATION *);
static NTSTATUS (WINAPI *pRtlQueryDynamicTimeZoneInformation)( RTL_DYNAMIC_TIME_ZONE_INFORMATION *);
static ULONG (WINAPI *pNtGetTickCount)(void);
static BOOL (WINAPI *pRtlQueryUnbiasedInterruptTime)( ULONGLONG *time );
static BOOL (WINAPI *pRtlQueryPerformanceCounter)(LARGE_INTEGER*);
static BOOL (WINAPI *pRtlQueryPerformanceFrequency)(LARGE_INTEGER*);
static const int MonthLengths[2][12] =
{
@@ -181,77 +118,365 @@ static void test_NtQueryPerformanceCounter(void)
NTSTATUS status;
status = pNtQueryPerformanceCounter(NULL, NULL);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08lx\n", status);
status = pNtQueryPerformanceCounter(NULL, &frequency);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08lx\n", status);
status = pNtQueryPerformanceCounter(&counter, (void *)0xdeadbee0);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08lx\n", status);
status = pNtQueryPerformanceCounter((void *)0xdeadbee0, &frequency);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
ok(status == STATUS_ACCESS_VIOLATION, "expected STATUS_ACCESS_VIOLATION, got %08lx\n", status);
status = pNtQueryPerformanceCounter(&counter, NULL);
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
status = pNtQueryPerformanceCounter(&counter, &frequency);
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08x\n", status);
ok(status == STATUS_SUCCESS, "expected STATUS_SUCCESS, got %08lx\n", status);
}
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arm64ec__)
struct hypervisor_shared_data
{
UINT64 unknown;
UINT64 QpcMultiplier;
UINT64 QpcBias;
};
/* 128-bit multiply a by b and return the high 64 bits, same as __umulh */
static UINT64 multiply_tsc(UINT64 a, UINT64 b)
{
UINT64 ah = a >> 32, al = (UINT32)a, bh = b >> 32, bl = (UINT32)b, m;
m = (ah * bl) + (bh * al) + ((al * bl) >> 32);
return (ah * bh) + (m >> 32);
}
static void test_RtlQueryPerformanceCounter(void)
{
struct hypervisor_shared_data *hsd;
KSHARED_USER_DATA *usd = (void *)0x7ffe0000;
LARGE_INTEGER frequency, counter;
NTSTATUS status;
UINT64 tsc0, tsc1;
ULONG len;
BOOL ret;
if (!pRtlQueryPerformanceCounter || !pRtlQueryPerformanceFrequency)
{
win_skip( "RtlQueryPerformanceCounter/Frequency not available, skipping tests\n" );
return;
}
if (!(usd->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED))
{
todo_wine win_skip("QpcBypassEnabled is not set, skipping tests\n");
return;
}
if ((usd->QpcBypassEnabled & SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_HV_PAGE))
{
ok( usd->QpcBypassEnabled == (SHARED_GLOBAL_FLAGS_QPC_BYPASS_ENABLED|SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_HV_PAGE|SHARED_GLOBAL_FLAGS_QPC_BYPASS_USE_RDTSCP),
"unexpected QpcBypassEnabled %x, expected 0x83\n", usd->QpcBypassEnabled );
ok( usd->QpcFrequency == 10000000, "unexpected QpcFrequency %I64d, expected 10000000\n", usd->QpcFrequency );
ok( !usd->QpcShift, "unexpected QpcShift %d, expected 0\n", usd->QpcShift );
hsd = NULL;
status = pNtQuerySystemInformation( SystemHypervisorSharedPageInformation, &hsd, sizeof(void *), &len );
ok( !status, "NtQuerySystemInformation returned %lx\n", status );
ok( len == sizeof(void *), "unexpected SystemHypervisorSharedPageInformation length %lu\n", len );
ok( !!hsd, "unexpected SystemHypervisorSharedPageInformation address %p\n", hsd );
tsc0 = __rdtsc();
ret = pRtlQueryPerformanceCounter( &counter );
tsc1 = __rdtsc();
ok( ret, "RtlQueryPerformanceCounter failed\n" );
tsc0 = multiply_tsc(tsc0, hsd->QpcMultiplier) + hsd->QpcBias + usd->QpcBias;
tsc1 = multiply_tsc(tsc1, hsd->QpcMultiplier) + hsd->QpcBias + usd->QpcBias;
ok( tsc0 <= counter.QuadPart, "rdtscp %I64d and RtlQueryPerformanceCounter %I64d are out of order\n", tsc0, counter.QuadPart );
ok( counter.QuadPart <= tsc1, "RtlQueryPerformanceCounter %I64d and rdtscp %I64d are out of order\n", counter.QuadPart, tsc1 );
}
else
{
ok( usd->QpcShift == 10, "unexpected QpcShift %d, expected 10\n", usd->QpcShift );
tsc0 = __rdtsc();
ret = pRtlQueryPerformanceCounter( &counter );
tsc1 = __rdtsc();
ok( ret, "RtlQueryPerformanceCounter failed\n" );
tsc0 += usd->QpcBias;
tsc0 >>= usd->QpcShift;
tsc1 += usd->QpcBias;
tsc1 >>= usd->QpcShift;
ok( tsc0 <= counter.QuadPart, "rdtscp %I64d and RtlQueryPerformanceCounter %I64d are out of order\n", tsc0, counter.QuadPart );
ok( counter.QuadPart <= tsc1, "RtlQueryPerformanceCounter %I64d and rdtscp %I64d are out of order\n", counter.QuadPart, tsc1 );
}
ret = pRtlQueryPerformanceFrequency( &frequency );
ok( ret, "RtlQueryPerformanceFrequency failed\n" );
ok( frequency.QuadPart == usd->QpcFrequency,
"RtlQueryPerformanceFrequency returned %I64d, expected USD QpcFrequency %I64d\n",
frequency.QuadPart, usd->QpcFrequency );
}
#endif
#define TIMER_LEEWAY 10
#define CHECK_CURRENT_TIMER(expected) \
do { \
ok(status == STATUS_SUCCESS, "NtSetTimerResolution failed %lx\n", status); \
ok(cur2 == (expected) || broken(abs((int)((expected) - cur2)) <= TIMER_LEEWAY), "expected new timer resolution %lu, got %lu\n", (expected), cur2); \
set = cur2; \
min2 = min + 20000; \
cur2 = min2 + 1; \
max2 = cur2 + 1; \
status = NtQueryTimerResolution(&min2, &max2, &cur2); \
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed %lx\n", status); \
ok(min2 == min, "NtQueryTimerResolution() expected min=%lu, got %lu\n", min, min2); \
ok(max2 == max, "NtQueryTimerResolution() expected max=%lu, got %lu\n", max, max2); \
ok(cur2 == set, "NtQueryTimerResolution() expected timer resolution %lu, got %lu\n", set, cur2); \
} while (0)
static void test_TimerResolution(void)
{
ULONG min, max, cur, min2, max2, cur2, set;
NTSTATUS status;
status = NtQueryTimerResolution(NULL, &max, &cur);
ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(NULL,,) success\n");
status = NtQueryTimerResolution(&min, NULL, &cur);
ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,NULL,) success\n");
status = NtQueryTimerResolution(&min, &max, NULL);
ok(status == STATUS_ACCESS_VIOLATION, "NtQueryTimerResolution(,,NULL) success\n");
min = 212121;
cur = min + 1;
max = cur + 1;
status = NtQueryTimerResolution(&min, &max, &cur);
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%lx)\n", status);
ok(min == 156250 /* 1/64s HPET */ || min == 156001 /* RTC */,
"unexpected minimum timer resolution %lu\n", min);
ok(0 < max, "invalid maximum timer resolution, should be 0 < %lu\n", max);
ok(max <= cur || broken(max - TIMER_LEEWAY <= cur), "invalid timer resolutions, should be %lu <= %lu\n", max, cur);
ok(cur <= min || broken(cur <= min + TIMER_LEEWAY), "invalid timer resolutions, should be %lu <= %lu\n", cur, min);
status = NtSetTimerResolution(0, FALSE, NULL);
ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution(,,NULL) success\n");
/* Nothing happens if that pointer is not good */
status = NtSetTimerResolution(cur - 1, TRUE, NULL);
ok(status == STATUS_ACCESS_VIOLATION, "NtSetTimerResolution() failed %lx\n", status);
min2 = min + 10000;
cur2 = min2 + 1;
max2 = cur2 + 1;
status = NtQueryTimerResolution(&min2, &max2, &cur2);
ok(status == STATUS_SUCCESS, "NtQueryTimerResolution() failed (%lx)\n", status);
ok(min2 == min, "NtQueryTimerResolution() expected min=%lu, got %lu\n", min, min2);
ok(max2 == max, "NtQueryTimerResolution() expected max=%lu, got %lu\n", max, max2);
ok(cur2 == cur, "NtQueryTimerResolution() expected timer resolution %lu, got %lu\n", cur, cur2);
/* 'fails' until the first valid timer resolution request */
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %lx\n", status);
/* and returns the current timer resolution */
ok(cur2 == cur, "expected requested timer resolution %lu, got %lu\n", cur, cur2);
cur2 = 7654321;
status = NtSetTimerResolution(max - 1, TRUE, &cur2);
CHECK_CURRENT_TIMER(max);
/* Rescinds our timer resolution request */
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %lx\n", status);
/* -> the timer resolution was reset to its initial value */
ok(cur2 == cur, "expected requested timer resolution %lu, got %lu\n", min, cur2);
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
ok(status == STATUS_TIMER_RESOLUTION_NOT_SET, "NtSetTimerResolution() failed %lx\n", status);
ok(cur2 == cur, "expected requested timer resolution %lu, got %lu\n", cur, cur2);
cur2 = 7654321;
status = NtSetTimerResolution(min + 1, TRUE, &cur2);
ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %lx\n", status);
/* This works because:
* - Either cur is the minimum (15.6 ms) resolution already, i.e. the
* closest valid value 'set' is rounded to.
* - Or some other application requested a higher timer resolution, cur,
* and any attempt to lower the resolution has no effect until that
* request is rescinded (hopefully after this test is done).
*/
CHECK_CURRENT_TIMER(cur);
/* The requested resolution may (win7) or may not be rounded */
cur2 = 7654321;
set = max < cur ? cur - 1 : max;
status = NtSetTimerResolution(set, TRUE, &cur2);
ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %lx\n", status);
ok(cur2 <= set || broken(cur2 <= set + TIMER_LEEWAY), "expected new timer resolution %lu <= %lu\n", cur2, set);
trace("timer resolution: %lu(max) <= %lu(cur) <= %lu(prev) <= %lu(min)\n", max, cur2, cur, min);
cur2 = 7654321;
status = NtSetTimerResolution(cur + 1, TRUE, &cur2);
CHECK_CURRENT_TIMER(cur); /* see min + 1 test */
/* Cleanup by rescinding the last request */
cur2 = 7654321;
status = NtSetTimerResolution(0, FALSE, &cur2);
ok(status == STATUS_SUCCESS, "NtSetTimerResolution() failed %lx\n", status);
ok(cur2 == cur, "expected requested timer resolution %lu, got %lu\n", set, cur2);
}
static void test_RtlQueryTimeZoneInformation(void)
{
RTL_DYNAMIC_TIME_ZONE_INFORMATION tzinfo;
RTL_DYNAMIC_TIME_ZONE_INFORMATION tzinfo, tzinfo2;
NTSTATUS status;
ULONG len;
/* test RtlQueryTimeZoneInformation returns an indirect string,
e.g. @tzres.dll,-32 (Vista or later) */
if (!pRtlQueryTimeZoneInformation || !pRtlQueryDynamicTimeZoneInformation)
{
win_skip("Time zone name tests requires Vista or later\n");
win_skip("Time zone name tests require Vista or later\n");
return;
}
memset(&tzinfo, 0, sizeof(tzinfo));
memset(&tzinfo, 0xcc, sizeof(tzinfo));
status = pRtlQueryDynamicTimeZoneInformation(&tzinfo);
ok(status == STATUS_SUCCESS,
"RtlQueryDynamicTimeZoneInformation failed, got %08x\n", status);
todo_wine ok(tzinfo.StandardName[0] == '@',
"RtlQueryDynamicTimeZoneInformation failed, got %08lx\n", status);
ok(tzinfo.StandardName[0] == '@' ||
broken(tzinfo.StandardName[0]), /* some win10 2004 */
"standard time zone name isn't an indirect string, got %s\n",
wine_dbgstr_w(tzinfo.StandardName));
todo_wine ok(tzinfo.DaylightName[0] == '@',
ok(tzinfo.DaylightName[0] == '@' ||
broken(tzinfo.DaylightName[0]), /* some win10 2004 */
"daylight time zone name isn't an indirect string, got %s\n",
wine_dbgstr_w(tzinfo.DaylightName));
memset(&tzinfo, 0, sizeof(tzinfo));
memset(&tzinfo2, 0xcc, sizeof(tzinfo2));
status = pNtQuerySystemInformation( SystemDynamicTimeZoneInformation, &tzinfo2, sizeof(tzinfo2), &len );
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
ok( len == sizeof(tzinfo2), "wrong len %lu\n", len );
ok( !memcmp( &tzinfo, &tzinfo2, sizeof(tzinfo2) ), "tz data is different\n" );
memset(&tzinfo, 0xcc, sizeof(tzinfo));
status = pRtlQueryTimeZoneInformation((RTL_TIME_ZONE_INFORMATION *)&tzinfo);
ok(status == STATUS_SUCCESS,
"RtlQueryTimeZoneInformation failed, got %08x\n", status);
todo_wine ok(tzinfo.StandardName[0] == '@',
"RtlQueryTimeZoneInformation failed, got %08lx\n", status);
ok(tzinfo.StandardName[0] == '@' ||
broken(tzinfo.StandardName[0]), /* some win10 2004 */
"standard time zone name isn't an indirect string, got %s\n",
wine_dbgstr_w(tzinfo.StandardName));
todo_wine ok(tzinfo.DaylightName[0] == '@',
ok(tzinfo.DaylightName[0] == '@' ||
broken(tzinfo.DaylightName[0]), /* some win10 2004 */
"daylight time zone name isn't an indirect string, got %s\n",
wine_dbgstr_w(tzinfo.DaylightName));
memset(&tzinfo, 0xcc, sizeof(tzinfo));
status = pRtlQueryTimeZoneInformation((RTL_TIME_ZONE_INFORMATION *)&tzinfo);
ok(status == STATUS_SUCCESS,
"RtlQueryTimeZoneInformation failed, got %08lx\n", status);
ok(tzinfo.StandardName[0] == '@' ||
broken(tzinfo.StandardName[0]), /* some win10 2004 */
"standard time zone name isn't an indirect string, got %s\n",
wine_dbgstr_w(tzinfo.StandardName));
ok(tzinfo.DaylightName[0] == '@' ||
broken(tzinfo.DaylightName[0]), /* some win10 2004 */
"daylight time zone name isn't an indirect string, got %s\n",
wine_dbgstr_w(tzinfo.DaylightName));
memset(&tzinfo2, 0xcc, sizeof(tzinfo2));
status = pNtQuerySystemInformation( SystemCurrentTimeZoneInformation, &tzinfo2,
sizeof(RTL_TIME_ZONE_INFORMATION), &len );
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
ok( len == sizeof(RTL_TIME_ZONE_INFORMATION), "wrong len %lu\n", len );
ok( !memcmp( &tzinfo, &tzinfo2, sizeof(RTL_TIME_ZONE_INFORMATION) ), "tz data is different\n" );
}
static void test_NtGetTickCount(void)
static ULONGLONG read_ksystem_time(volatile KSYSTEM_TIME *time)
{
ULONGLONG high, low;
do
{
high = time->High1Time;
low = time->LowPart;
}
while (high != time->High2Time);
return high << 32 | low;
}
static void test_user_shared_data_time(void)
{
#ifndef _WIN64
KSHARED_USER_DATA *user_shared_data = (void *)0x7ffe0000;
LONG diff;
int i;
SYSTEM_TIMEOFDAY_INFORMATION timeofday;
ULONGLONG t1, t2, t3;
NTSTATUS status;
int i = 0;
if (!pNtGetTickCount)
i = 0;
do
{
win_skip("NtGetTickCount is not available\n");
return;
t1 = GetTickCount();
if (user_shared_data->NtMajorVersion <= 5 && user_shared_data->NtMinorVersion <= 1)
t2 = (DWORD)((*(volatile ULONG*)&user_shared_data->TickCountLowDeprecated * (ULONG64)user_shared_data->TickCountMultiplier) >> 24);
else
t2 = (DWORD)((read_ksystem_time(&user_shared_data->TickCount) * user_shared_data->TickCountMultiplier) >> 24);
t3 = GetTickCount();
} while(t3 < t1 && i++ < 1); /* allow for wrap, but only once */
ok(t1 <= t2, "USD TickCount / GetTickCount are out of order: %s %s\n",
wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
ok(t2 <= t3, "USD TickCount / GetTickCount are out of order: %s %s\n",
wine_dbgstr_longlong(t2), wine_dbgstr_longlong(t3));
i = 0;
do
{
LARGE_INTEGER system_time;
NtQuerySystemTime(&system_time);
t1 = system_time.QuadPart;
t2 = read_ksystem_time(&user_shared_data->SystemTime);
NtQuerySystemTime(&system_time);
t3 = system_time.QuadPart;
} while(t3 < t1 && i++ < 1); /* allow for wrap, but only once */
/* FIXME: not always in order, but should be close */
todo_wine_if(t1 > t2 && t1 - t2 < 50 * TICKSPERMSEC)
ok(t1 <= t2, "USD SystemTime / NtQuerySystemTime are out of order %s %s\n",
wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
ok(t2 <= t3, "USD SystemTime / NtQuerySystemTime are out of order %s %s\n",
wine_dbgstr_longlong(t2), wine_dbgstr_longlong(t3));
if (!pRtlQueryUnbiasedInterruptTime)
win_skip("skipping RtlQueryUnbiasedInterruptTime tests\n");
else
{
i = 0;
do
{
pRtlQueryUnbiasedInterruptTime(&t1);
t2 = read_ksystem_time(&user_shared_data->InterruptTime) - user_shared_data->InterruptTimeBias;
pRtlQueryUnbiasedInterruptTime(&t3);
} while(t3 < t1 && i++ < 1); /* allow for wrap, but only once */
ok(t1 <= t2, "USD InterruptTime / RtlQueryUnbiasedInterruptTime are out of order %s %s\n",
wine_dbgstr_longlong(t1), wine_dbgstr_longlong(t2));
ok(t2 <= t3, "USD InterruptTime / RtlQueryUnbiasedInterruptTime are out of order %s %s\n",
wine_dbgstr_longlong(t2), wine_dbgstr_longlong(t3));
}
for (i = 0; i < 5; ++i)
{
diff = (user_shared_data->TickCountQuad * user_shared_data->TickCountMultiplier) >> 24;
diff = pNtGetTickCount() - diff;
ok(diff < 32, "NtGetTickCount - TickCountQuad too high, expected < 32 got %d\n", diff);
Sleep(50);
}
#endif
t1 = read_ksystem_time(&user_shared_data->TimeZoneBias);
status = NtQuerySystemInformation(SystemTimeOfDayInformation, &timeofday, sizeof(timeofday), NULL);
ok(!status, "failed to query time of day, status %#lx\n", status);
ok(timeofday.TimeZoneBias.QuadPart == t1, "got USD bias %I64u, ntdll bias %I64u\n",
t1, timeofday.TimeZoneBias.QuadPart);
}
START_TEST(time)
@@ -260,17 +485,24 @@ START_TEST(time)
pRtlTimeToTimeFields = (void *)GetProcAddress(mod,"RtlTimeToTimeFields");
pRtlTimeFieldsToTime = (void *)GetProcAddress(mod,"RtlTimeFieldsToTime");
pNtQueryPerformanceCounter = (void *)GetProcAddress(mod, "NtQueryPerformanceCounter");
pNtGetTickCount = (void *)GetProcAddress(mod,"NtGetTickCount");
pNtQuerySystemInformation = (void *)GetProcAddress(mod, "NtQuerySystemInformation");
pRtlQueryTimeZoneInformation =
(void *)GetProcAddress(mod, "RtlQueryTimeZoneInformation");
pRtlQueryDynamicTimeZoneInformation =
(void *)GetProcAddress(mod, "RtlQueryDynamicTimeZoneInformation");
pRtlQueryUnbiasedInterruptTime = (void *)GetProcAddress(mod, "RtlQueryUnbiasedInterruptTime");
pRtlQueryPerformanceCounter = (void *)GetProcAddress(mod, "RtlQueryPerformanceCounter");
pRtlQueryPerformanceFrequency = (void *)GetProcAddress(mod, "RtlQueryPerformanceFrequency");
if (pRtlTimeToTimeFields && pRtlTimeFieldsToTime)
test_pRtlTimeToTimeFields();
else
win_skip("Required time conversion functions are not available\n");
test_NtQueryPerformanceCounter();
test_NtGetTickCount();
test_RtlQueryTimeZoneInformation();
test_user_shared_data_time();
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arm64ec__)
test_RtlQueryPerformanceCounter();
#endif
test_TimerResolution();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff