[KERNEL32_WINETEST] Sync kernel32 winetest to wine-10.0

- [KERNEL32_WINETEST] Sync to wine-10.0
- [KERNEL32_WINETEST] Define out tests we can't yet build, fix test failures for WS03-Win 10 1607.
- [KERNEL32_WINETEST] Consolidate header hacks needed for the winesync in winehacks.h. This documents what incompatibilities we need to work around in our and Wine headers in one place.
This commit is contained in:
Carl J. Bialorucki
2026-01-09 08:54:58 -08:00
parent c20ec94409
commit ddfdb0de7a
41 changed files with 36260 additions and 12017 deletions
@@ -1,13 +1,19 @@
add_definitions(-D__ROS_LONG64__)
include_directories(BEFORE ${REACTOS_SOURCE_DIR}/sdk/include/wine)
remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502)
add_definitions(-DWINVER=0x600 -D_WIN32_WINNT=0x601)
remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502 -D_CRT_NON_CONFORMING_SWPRINTFS)
add_definitions(-DWINVER=0x0A00 -D_WIN32_WINNT=0x0A00 -DNTDDI_VERSION=0x0A000007)
add_definitions(
-Dstrcasecmp=_stricmp
)
# Comment this block out if you want to debug the heap issue with these tests on ROS x64. ROSTESTS-415
if(ARCH STREQUAL "amd64")
add_definitions(-DSKIPBADHEAP_K32_WINETEST=1)
endif()
spec2def(dummy.dll dummy.spec)
add_library(kernel32_winetest_dummy MODULE dummy.c ${CMAKE_CURRENT_BINARY_DIR}/dummy.def)
set_target_properties(kernel32_winetest_dummy PROPERTIES OUTPUT_NAME "dummy")
set_module_type(kernel32_winetest_dummy win32dll)
add_importlibs(kernel32_winetest_dummy msvcrt kernel32)
add_rostests_file(TARGET kernel32_winetest_dummy)
list(APPEND SOURCE
actctx.c
@@ -31,6 +37,7 @@ list(APPEND SOURCE
module.c
path.c
pipe.c
power.c
process.c
profile.c
resource.c
@@ -46,28 +53,57 @@ list(APPEND SOURCE
list(APPEND PCH_SKIP_SOURCE
testlist.c)
if (MSVC AND ARCH STREQUAL "amd64")
list(APPEND SOURCE
get_fpu_cw.asm)
endif()
add_executable(kernel32_winetest
${SOURCE}
${PCH_SKIP_SOURCE}
resource.rc)
if(MSVC)
# Disable warning C4477 (printf format warnings)
remove_target_compile_option(kernel32_winetest "/we4477")
# CMake 3.9 and higher requires to specify this dependency manually
# see https://gitlab.kitware.com/cmake/cmake/issues/19933
set_property(SOURCE resource.rc PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/dummy.dll ${CMAKE_CURRENT_BINARY_DIR}/dummy.dll)
if(ARCH STREQUAL "amd64")
# error C4101: 'is_wow64': unreferenced local variable
remove_target_compile_option(kernel32_winetest "/we4101")
target_compile_options(kernel32_winetest PRIVATE /wd4101)
endif()
# resource.rc: let rc.exe find the dlls in their subdirectory, i.e. Debug.
if (MSVC_IDE)
target_include_directories(kernel32_winetest PRIVATE
$<$<COMPILE_LANGUAGE:RC>:$<TARGET_FILE_DIR:kernel32_winetest_dummy>>)
endif()
if (MSVC)
# error C4101: unreferenced local variable
target_compile_options(kernel32_winetest PRIVATE /wd4101)
# Approximates a __FILE__ macro with forward slashes instead of back slashes
# and defines it as __FILE_FW_SLASH__.
foreach(source_file ${SOURCE})
get_filename_component(abs_source_file "${source_file}" ABSOLUTE)
file(RELATIVE_PATH rel_path "${CMAKE_SOURCE_DIR}" "${abs_source_file}")
string(REPLACE "\\" "/" rel_path_forward "${rel_path}")
set_source_files_properties(${source_file} PROPERTIES
COMPILE_DEFINITIONS "__FILE_FW_SLASH__=\"../${rel_path_forward}\""
)
endforeach()
endif()
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
target_compile_options(kernel32_winetest PRIVATE "-Wno-format")
target_compile_options(kernel32_winetest PRIVATE
-Wno-format
-Wno-int-conversion
-Wno-old-style-declaration
-Wno-unused)
endif()
set_module_type(kernel32_winetest win32cui)
target_link_libraries(kernel32_winetest pseh)
target_link_libraries(kernel32_winetest pseh oldnames)
add_importlibs(kernel32_winetest user32 advapi32 msvcrt kernel32 ntdll)
add_pch(kernel32_winetest precomp.h "${PCH_SKIP_SOURCE}")
add_rostests_file(TARGET kernel32_winetest)
target_compile_definitions(kernel32_winetest PRIVATE
WINETEST_USE_DBGSTR_LONGLONG
__WINESRC__
strncasecmp=_strnicmp
strcasecmp=_stricmp)
File diff suppressed because it is too large Load Diff
+20 -20
View File
@@ -86,7 +86,7 @@ static void test_add_atom(void)
if (unicode_OS)
{
ok( w_atom == atom, "Unicode atom does not match ASCII\n" );
ok( w_atom == atom, "Unicode atom does not match ANSI one\n" );
ok( GetLastError() == 0xdeadbeef, "GlobalAddAtomW set last error\n" );
}
@@ -115,20 +115,20 @@ static void test_add_atom(void)
{
SetLastError( 0xdeadbeef );
ok( GlobalAddAtomA((LPCSTR)i) == i && GetLastError() == 0xdeadbeef,
"failed to add atom %lx\n", i );
"failed to add atom %Ix\n", i );
if (unicode_OS)
{
SetLastError( 0xdeadbeef );
ok( GlobalAddAtomW((LPCWSTR)i) == i && GetLastError() == 0xdeadbeef,
"failed to add atom %lx\n", i );
"failed to add atom %Ix\n", i );
}
}
for (i = 0xc000; i <= 0xffff; i++)
{
ok( !GlobalAddAtomA((LPCSTR)i), "succeeded adding %lx\n", i );
ok( !GlobalAddAtomA((LPCSTR)i), "succeeded adding %Ix\n", i );
if (unicode_OS)
ok( !GlobalAddAtomW((LPCWSTR)i), "succeeded adding %lx\n", i );
ok( !GlobalAddAtomW((LPCWSTR)i), "succeeded adding %Ix\n", i );
}
}
@@ -196,7 +196,7 @@ static void test_get_atom_name(void)
len = GlobalGetAtomNameA( (ATOM)i, buf, 2);
ok(!len, "bad length %d\n", len);
ok(GetLastError() == ERROR_MORE_DATA || GetLastError() == ERROR_INVALID_PARAMETER,
"wrong error conditions %u for %u\n", GetLastError(), i);
"wrong error conditions %lu for %u\n", GetLastError(), i);
}
memset( buf, '.', sizeof(buf) );
@@ -229,7 +229,7 @@ static void test_get_atom_name(void)
SetLastError(0xdeadbeef);
len = GlobalGetAtomNameA(atom, out, 10);
ok(!len, "bad length %d\n", len);
ok(GetLastError() == ERROR_MORE_DATA, "wrong error code (%u instead of %u)\n", GetLastError(), ERROR_MORE_DATA);
ok(GetLastError() == ERROR_MORE_DATA, "wrong error code (%lu instead of %u)\n", GetLastError(), ERROR_MORE_DATA);
for (i = 0; i < 9; i++)
{
ok(out[i] == "abcdefghij"[i % 10], "wrong string at %i (%c instead of %c)\n", i, out[i], "abcdefghij"[i % 10]);
@@ -266,7 +266,7 @@ static void test_get_atom_name(void)
{
/* len == 0 with ERROR_MORE_DATA is on NT3.51 */
ok(len == 1 || (len == 0 && GetLastError() == ERROR_MORE_DATA),
"0x%04x: got %u with %d (expected '1' or '0' with "
"0x%04x: got %u with %ld (expected '1' or '0' with "
"ERROR_MORE_DATA)\n", i, len, GetLastError());
ok(outW[1] == DOUBLE('.'), "buffer overwrite\n");
}
@@ -276,7 +276,7 @@ static void test_get_atom_name(void)
do_initW(inW, "abcdefghij", 255);
atom = GlobalAddAtomW(inW);
ok(atom, "couldn't add atom for %s\n", in);
len = GlobalGetAtomNameW(atom, outW, sizeof(outW)/sizeof(outW[0]));
len = GlobalGetAtomNameW(atom, outW, ARRAY_SIZE(outW));
ok(len == 255, "length mismatch (%u instead of 255)\n", len);
for (i = 0; i < 255; i++)
{
@@ -344,7 +344,7 @@ static void test_local_add_atom(void)
if (unicode_OS)
{
ok( w_atom == atom, "Unicode atom does not match ASCII\n" );
ok( w_atom == atom, "Unicode atom does not match ANSI one\n" );
ok( GetLastError() == 0xdeadbeef, "AddAtomW set last error\n" );
}
@@ -373,20 +373,20 @@ static void test_local_add_atom(void)
{
SetLastError( 0xdeadbeef );
ok( AddAtomA((LPCSTR)i) == i && GetLastError() == 0xdeadbeef,
"failed to add atom %lx\n", i );
"failed to add atom %Ix\n", i );
if (unicode_OS)
{
SetLastError( 0xdeadbeef );
ok( AddAtomW((LPCWSTR)i) == i && GetLastError() == 0xdeadbeef,
"failed to add atom %lx\n", i );
"failed to add atom %Ix\n", i );
}
}
for (i = 0xc000; i <= 0xffff; i++)
{
ok( !AddAtomA((LPCSTR)i), "succeeded adding %lx\n", i );
ok( !AddAtomA((LPCSTR)i), "succeeded adding %Ix\n", i );
if (unicode_OS)
ok( !AddAtomW((LPCWSTR)i), "succeeded adding %lx\n", i );
ok( !AddAtomW((LPCWSTR)i), "succeeded adding %Ix\n", i );
}
}
@@ -472,11 +472,11 @@ static void test_local_get_atom_name(void)
if (i)
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
GetLastError() == ERROR_MORE_DATA,
"wrong error conditions %u for %u\n", GetLastError(), i);
"wrong error conditions %lu for %u\n", GetLastError(), i);
else
ok(GetLastError() == ERROR_INVALID_PARAMETER ||
GetLastError() == ERROR_MORE_DATA,
"wrong error conditions %u for %u\n", GetLastError(), i);
"wrong error conditions %lu for %u\n", GetLastError(), i);
}
/* test string limits & overflow */
do_initA(in, "abcdefghij", 255);
@@ -505,7 +505,7 @@ static void test_local_get_atom_name(void)
/* ERROR_MORE_DATA is on nt3.51 sp5 */
ok(GetLastError() == ERROR_INVALID_PARAMETER ||
GetLastError() == ERROR_MORE_DATA,
"wrong error code (%u)\n", GetLastError());
"wrong error code (%lu)\n", GetLastError());
if (unicode_OS)
{
@@ -532,12 +532,12 @@ static void test_local_get_atom_name(void)
/* ERROR_MORE_DATA is on nt3.51 sp5 */
ok(GetLastError() == ERROR_MORE_DATA ||
GetLastError() == (i ? ERROR_INSUFFICIENT_BUFFER : ERROR_INVALID_PARAMETER),
"wrong error conditions %u for %u\n", GetLastError(), i);
"wrong error conditions %lu for %u\n", GetLastError(), i);
}
do_initW(inW, "abcdefghij", 255);
atom = AddAtomW(inW);
ok(atom, "couldn't add atom for %s\n", in);
len = GetAtomNameW(atom, outW, sizeof(outW)/sizeof(outW[0]));
len = GetAtomNameW(atom, outW, ARRAY_SIZE(outW));
ok(len == 255, "length mismatch (%u instead of 255)\n", len);
for (i = 0; i < 255; i++)
{
@@ -560,7 +560,7 @@ static void test_local_get_atom_name(void)
/* ERROR_MORE_DATA is on nt3.51 sp5 */
ok(GetLastError() == ERROR_INVALID_PARAMETER ||
GetLastError() == ERROR_MORE_DATA,
"wrong error code (%u)\n", GetLastError());
"wrong error code (%lu)\n", GetLastError());
}
}
+172 -200
View File
@@ -51,7 +51,7 @@ static DWORD CALLBACK NotificationThread(LPVOID arg)
}
ret = FindCloseChangeNotification(change);
ok( ret, "FindCloseChangeNotification error: %d\n",
ok( ret, "FindCloseChangeNotification error: %ld\n",
GetLastError());
ExitThread((DWORD)notified);
@@ -63,10 +63,10 @@ static HANDLE StartNotificationThread(LPCSTR path, BOOL subtree, DWORD flags)
DWORD threadId;
change = FindFirstChangeNotificationA(path, subtree, flags);
ok(change != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %d\n", GetLastError());
ok(change != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %ld\n", GetLastError());
thread = CreateThread(NULL, 0, NotificationThread, change, 0, &threadId);
ok(thread != NULL, "CreateThread error: %d\n", GetLastError());
ok(thread != NULL, "CreateThread error: %ld\n", GetLastError());
return thread;
}
@@ -76,7 +76,7 @@ static DWORD FinishNotificationThread(HANDLE thread)
DWORD status, exitcode;
status = WaitForSingleObject(thread, 5000);
ok(status == WAIT_OBJECT_0, "WaitForSingleObject status %d error %d\n", status, GetLastError());
ok(status == WAIT_OBJECT_0, "WaitForSingleObject status %ld error %ld\n", status, GetLastError());
ok(GetExitCodeThread(thread, &exitcode), "Could not retrieve thread exit code\n");
CloseHandle(thread);
@@ -99,47 +99,47 @@ static void test_FindFirstChangeNotification(void)
change = FindFirstChangeNotificationA("not-a-file", FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
ok(change == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %p\n", change);
ok(GetLastError() == ERROR_FILE_NOT_FOUND ||
GetLastError() == ERROR_NO_MORE_FILES, /* win95 */
"FindFirstChangeNotification error: %d\n", GetLastError());
ok(GetLastError() == ERROR_FILE_NOT_FOUND,
"FindFirstChangeNotification error: %ld\n", GetLastError());
if (0) /* This documents win2k behavior. It crashes on win98. */
{
change = FindFirstChangeNotificationA(NULL, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
ok(change == NULL && GetLastError() == ERROR_PATH_NOT_FOUND,
"FindFirstChangeNotification error: %d\n", GetLastError());
}
change = FindFirstChangeNotificationA(NULL, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
ok(change == INVALID_HANDLE_VALUE || broken(change == NULL) /* < win7 */,
"Expected INVALID_HANDLE_VALUE, got %p\n", change);
ok(GetLastError() == ERROR_PATH_NOT_FOUND,
"FindFirstChangeNotification error: %lu\n", GetLastError());
ret = FindNextChangeNotification(NULL);
ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindNextChangeNotification error: %d\n",
ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindNextChangeNotification error: %ld\n",
GetLastError());
ret = FindCloseChangeNotification(NULL);
ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindCloseChangeNotification error: %d\n",
ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "FindCloseChangeNotification error: %ld\n",
GetLastError());
ret = GetTempPathA(MAX_PATH, workdir);
ok(ret, "GetTempPathA error: %d\n", GetLastError());
ret = GetTempPathA(MAX_PATH, dirname1);
ok(ret, "GetTempPathA error: %ld\n", GetLastError());
lstrcatA(workdir, "testFileChangeNotification");
ret = GetTempFileNameA(dirname1, "ffc", 0, workdir);
ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
DeleteFileA( workdir );
ret = CreateDirectoryA(workdir, NULL);
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
ret = GetTempFileNameA(workdir, prefix, 0, filename1);
ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
file = CreateFileA(filename1, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
ret = CloseHandle(file);
ok( ret, "CloseHandle error: %d\n", GetLastError());
ok( ret, "CloseHandle error: %ld\n", GetLastError());
/* Try to register notification for a file. win98 and win2k behave differently here */
/* Try to register notification for a file */
change = FindFirstChangeNotificationA(filename1, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
ok(change == INVALID_HANDLE_VALUE && (GetLastError() == ERROR_DIRECTORY ||
GetLastError() == ERROR_FILE_NOT_FOUND),
"FindFirstChangeNotification error: %d\n", GetLastError());
ok(change == INVALID_HANDLE_VALUE, "Expected INVALID_HANDLE_VALUE, got %p\n", change);
ok(GetLastError() == ERROR_DIRECTORY,
"FindFirstChangeNotification error: %ld\n", GetLastError());
lstrcpyA(dirname1, filename1);
lstrcatA(dirname1, "dir");
@@ -148,40 +148,39 @@ static void test_FindFirstChangeNotification(void)
lstrcatA(dirname2, "new");
ret = CreateDirectoryA(dirname1, NULL);
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
/* What if we move the directory we registered notification for? */
thread = StartNotificationThread(dirname1, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
ret = MoveFileA(dirname1, dirname2);
ok(ret, "MoveFileA error: %d\n", GetLastError());
/* win9x and win2k behave differently here, don't check result */
FinishNotificationThread(thread);
ok(ret, "MoveFileA error: %ld\n", GetLastError());
ok(!FinishNotificationThread(thread), "Got notification\n");
/* What if we remove the directory we registered notification for? */
thread = StartNotificationThread(dirname2, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
ret = RemoveDirectoryA(dirname2);
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
/* win9x and win2k behave differently here, don't check result */
FinishNotificationThread(thread);
ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
ret = FinishNotificationThread(thread);
todo_wine ok(ret, "Missed notification\n");
/* functional checks */
/* Create a directory */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
ret = CreateDirectoryA(dirname1, NULL);
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* Rename a directory */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
ret = MoveFileA(dirname1, dirname2);
ok(ret, "MoveFileA error: %d\n", GetLastError());
ok(ret, "MoveFileA error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* Delete a directory */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_DIR_NAME);
ret = RemoveDirectoryA(dirname2);
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
lstrcpyA(filename2, filename1);
@@ -190,91 +189,87 @@ static void test_FindFirstChangeNotification(void)
/* Rename a file */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
ret = MoveFileA(filename1, filename2);
ok(ret, "MoveFileA error: %d\n", GetLastError());
ok(ret, "MoveFileA error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* Delete a file */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
ret = DeleteFileA(filename2);
ok(ret, "DeleteFileA error: %d\n", GetLastError());
ok(ret, "DeleteFileA error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* Create a file */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_FILE_NAME);
file = CreateFileA(filename2, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
ret = CloseHandle(file);
ok( ret, "CloseHandle error: %d\n", GetLastError());
ok( ret, "CloseHandle error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
attributes = GetFileAttributesA(filename2);
ok(attributes != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA error: %d\n", GetLastError());
ok(attributes != INVALID_FILE_ATTRIBUTES, "GetFileAttributesA error: %ld\n", GetLastError());
attributes &= FILE_ATTRIBUTE_READONLY;
/* Change file attributes */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_ATTRIBUTES);
ret = SetFileAttributesA(filename2, attributes);
ok(ret, "SetFileAttributesA error: %d\n", GetLastError());
ok(ret, "SetFileAttributesA error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* Change last write time by writing to a file */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE);
file = CreateFileA(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
memset(buffer, 0, sizeof(buffer));
ret = WriteFile(file, buffer, sizeof(buffer), &count, NULL);
ok(ret && count == sizeof(buffer), "WriteFile error: %d\n", GetLastError());
ok(ret && count == sizeof(buffer), "WriteFile error: %ld\n", GetLastError());
ret = CloseHandle(file);
ok( ret, "CloseHandle error: %d\n", GetLastError());
ok( ret, "CloseHandle error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* Change file size by truncating a file */
thread = StartNotificationThread(workdir, FALSE, FILE_NOTIFY_CHANGE_SIZE);
file = CreateFileA(filename2, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, 0);
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %d\n", GetLastError());
ok(file != INVALID_HANDLE_VALUE, "CreateFileA error: %ld\n", GetLastError());
ret = WriteFile(file, buffer, sizeof(buffer) / 2, &count, NULL);
ok(ret && count == sizeof(buffer) / 2, "WriteFileA error: %d\n", GetLastError());
ok(ret && count == sizeof(buffer) / 2, "WriteFileA error: %ld\n", GetLastError());
ret = CloseHandle(file);
ok( ret, "CloseHandle error: %d\n", GetLastError());
ok( ret, "CloseHandle error: %ld\n", GetLastError());
ok(FinishNotificationThread(thread), "Missed notification\n");
/* clean up */
ret = DeleteFileA(filename2);
ok(ret, "DeleteFileA error: %d\n", GetLastError());
ok(ret, "DeleteFileA error: %ld\n", GetLastError());
ret = RemoveDirectoryA(workdir);
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
}
/* this test concentrates more on the wait behaviour of the handle */
static void test_ffcn(void)
{
DWORD filter;
HANDLE handle;
HANDLE handle, file;
LONG r;
WCHAR path[MAX_PATH], subdir[MAX_PATH];
WCHAR path[MAX_PATH], subdir[MAX_PATH], filename[MAX_PATH];
static const WCHAR szBoo[] = { '\\','b','o','o',0 };
static const WCHAR szHoo[] = { '\\','h','o','o',0 };
static const WCHAR szZoo[] = { '\\','z','o','o',0 };
SetLastError(0xdeadbeef);
r = GetTempPathW( MAX_PATH, path );
if (!r && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetTempPathW is not implemented\n");
return;
}
ok( r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW( path, szBoo );
lstrcpyW( subdir, path );
lstrcatW( subdir, szHoo );
lstrcpyW( filename, path );
lstrcatW( filename, szZoo );
RemoveDirectoryW( subdir );
RemoveDirectoryW( path );
@@ -290,10 +285,42 @@ static void test_ffcn(void)
r = WaitForSingleObject( handle, 0 );
ok( r == STATUS_TIMEOUT, "should time out\n");
file = CreateFileW( filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0 );
ok( file != INVALID_HANDLE_VALUE, "CreateFile error %lu\n", GetLastError() );
CloseHandle(file);
r = WaitForSingleObject( handle, 1000 );
ok( r == WAIT_OBJECT_0, "should be ready\n");
r = WaitForSingleObject( handle, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n");
r = FindNextChangeNotification(handle);
ok( r == TRUE, "find next failed\n");
r = WaitForSingleObject( handle, 0 );
ok( r == STATUS_TIMEOUT, "should time out\n");
r = DeleteFileW( filename );
ok( r == TRUE, "failed to remove file\n");
r = WaitForSingleObject( handle, 1000 );
ok( r == WAIT_OBJECT_0, "should be ready\n");
r = WaitForSingleObject( handle, 0 );
ok( r == WAIT_OBJECT_0, "should be ready\n");
r = FindNextChangeNotification(handle);
ok( r == TRUE, "find next failed\n");
r = WaitForSingleObject( handle, 0 );
ok( r == STATUS_TIMEOUT, "should time out\n");
r = CreateDirectoryW( subdir, NULL );
ok( r == TRUE, "failed to create subdir\n");
r = WaitForSingleObject( handle, 0 );
r = WaitForSingleObject( handle, 1000 );
ok( r == WAIT_OBJECT_0, "should be ready\n");
r = WaitForSingleObject( handle, 0 );
@@ -308,7 +335,7 @@ static void test_ffcn(void)
r = RemoveDirectoryW( subdir );
ok( r == TRUE, "failed to remove subdir\n");
r = WaitForSingleObject( handle, 0 );
r = WaitForSingleObject( handle, 1000 );
ok( r == WAIT_OBJECT_0, "should be ready\n");
r = WaitForSingleObject( handle, 0 );
@@ -334,23 +361,23 @@ static void test_ffcnMultipleThreads(void)
LONG r;
DWORD filter, threadId, status, exitcode;
HANDLE handles[2];
char path[MAX_PATH];
char tmp[MAX_PATH], path[MAX_PATH];
r = GetTempPathA(MAX_PATH, path);
ok(r, "GetTempPathA error: %d\n", GetLastError());
r = GetTempPathA(MAX_PATH, tmp);
ok(r, "GetTempPathA error: %ld\n", GetLastError());
lstrcatA(path, "ffcnTestMultipleThreads");
RemoveDirectoryA(path);
r = GetTempFileNameA(tmp, "ffc", 0, path);
ok(r, "GetTempFileNameA error: %ld\n", GetLastError());
DeleteFileA( path );
r = CreateDirectoryA(path, NULL);
ok(r, "CreateDirectoryA error: %d\n", GetLastError());
ok(r, "CreateDirectoryA error: %ld\n", GetLastError());
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
handles[0] = FindFirstChangeNotificationA(path, FALSE, filter);
ok(handles[0] != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %d\n", GetLastError());
ok(handles[0] != INVALID_HANDLE_VALUE, "FindFirstChangeNotification error: %ld\n", GetLastError());
/* Test behavior if a waiting thread holds the last reference to a change
* directory object with an empty wine user APC queue for this thread (bug #7286) */
@@ -358,10 +385,10 @@ static void test_ffcnMultipleThreads(void)
/* Create our notification thread */
handles[1] = CreateThread(NULL, 0, NotificationThread, handles[0], 0,
&threadId);
ok(handles[1] != NULL, "CreateThread error: %d\n", GetLastError());
ok(handles[1] != NULL, "CreateThread error: %ld\n", GetLastError());
status = WaitForMultipleObjects(2, handles, FALSE, 5000);
ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %d error %d\n", status, GetLastError());
ok(status == WAIT_OBJECT_0 || status == WAIT_OBJECT_0+1, "WaitForMultipleObjects status %ld error %ld\n", status, GetLastError());
ok(GetExitCodeThread(handles[1], &exitcode), "Could not retrieve thread exit code\n");
/* Clean up */
@@ -369,9 +396,6 @@ static void test_ffcnMultipleThreads(void)
ok( r == TRUE, "failed to remove dir\n");
}
static BOOL (WINAPI *pReadDirectoryChangesW)(HANDLE,LPVOID,DWORD,BOOL,DWORD,
LPDWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
static void test_readdirectorychanges(void)
{
HANDLE hdir;
@@ -385,22 +409,8 @@ static void test_readdirectorychanges(void)
PFILE_NOTIFY_INFORMATION pfni;
BOOL got_subdir_change = FALSE;
if (!pReadDirectoryChangesW)
{
win_skip("ReadDirectoryChangesW is not available\n");
return;
}
SetLastError(0xdeadbeef);
r = GetTempPathW( MAX_PATH, path );
if (!r && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetTempPathW is not implemented\n");
return;
}
ok( r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW( path, szBoo );
lstrcpyW( subdir, path );
@@ -417,7 +427,7 @@ static void test_readdirectorychanges(void)
ok( r == TRUE, "failed to create directory\n");
SetLastError(0xd0b00b00);
r = pReadDirectoryChangesW(NULL,NULL,0,FALSE,0,NULL,NULL,NULL);
r = ReadDirectoryChangesW(NULL,NULL,0,FALSE,0,NULL,NULL,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
@@ -430,12 +440,12 @@ static void test_readdirectorychanges(void)
ov.hEvent = CreateEventW( NULL, 1, 0, NULL );
SetLastError(0xd0b00b00);
r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,NULL,NULL);
r = ReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,NULL,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
SetLastError(0xd0b00b00);
r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,NULL,0,FALSE,0,NULL,&ov,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
@@ -453,15 +463,15 @@ static void test_readdirectorychanges(void)
ov.InternalHigh = 0;
memset( buffer, 0, sizeof buffer );
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,-1,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,-1,NULL,&ov,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,TRUE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,TRUE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = WaitForSingleObject( ov.hEvent, 10 );
@@ -484,11 +494,11 @@ static void test_readdirectorychanges(void)
ResetEvent(ov.hEvent);
SetLastError(0xd0b00b00);
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,NULL,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,NULL,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,0,NULL,&ov,NULL);
ok(GetLastError()==ERROR_INVALID_PARAMETER,"last error wrong\n");
ok(r==FALSE, "should return false\n");
@@ -497,10 +507,10 @@ static void test_readdirectorychanges(void)
SetEvent(ov.hEvent);
ov.Internal = 1;
ov.InternalHigh = 1;
S(U(ov)).Offset = 0;
S(U(ov)).OffsetHigh = 0;
ov.Offset = 0;
ov.OffsetHigh = 0;
memset( buffer, 0, sizeof buffer );
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
ok( (NTSTATUS)ov.Internal == STATUS_PENDING, "ov.Internal wrong\n");
@@ -532,7 +542,7 @@ static void test_readdirectorychanges(void)
ok( !memcmp(pfni->FileName,&szHoo[1],6), "name wrong\n" );
/* what happens if the buffer is too small? */
r = pReadDirectoryChangesW(hdir,buffer,0x10,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,0x10,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = CreateDirectoryW( subdir, NULL );
@@ -545,7 +555,7 @@ static void test_readdirectorychanges(void)
ok( ov.InternalHigh == 0, "ov.InternalHigh wrong\n");
/* test the recursive watch */
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = CreateDirectoryW( subsubdir, NULL );
@@ -581,7 +591,7 @@ static void test_readdirectorychanges(void)
if (got_subdir_change) break;
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
}
ok(got_subdir_change, "didn't get subdir change\n");
@@ -591,7 +601,7 @@ static void test_readdirectorychanges(void)
ov.Internal = 1;
ov.InternalHigh = 1;
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = RemoveDirectoryW( subdir );
@@ -604,18 +614,18 @@ static void test_readdirectorychanges(void)
/* we may get a notification for the parent dir too */
if (pfni->Action == FILE_ACTION_MODIFIED && pfni->NextEntryOffset)
{
ok( pfni->FileNameLength == 3*sizeof(WCHAR), "len wrong %u\n", pfni->FileNameLength );
ok( pfni->FileNameLength == 3*sizeof(WCHAR), "len wrong %lu\n", pfni->FileNameLength );
ok( !memcmp(pfni->FileName,&szGa[1],3*sizeof(WCHAR)), "name wrong\n" );
pfni = (PFILE_NOTIFY_INFORMATION)((char *)pfni + pfni->NextEntryOffset);
}
ok( pfni->NextEntryOffset == 0, "offset wrong %u\n", pfni->NextEntryOffset );
ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong %u\n", pfni->Action );
ok( pfni->FileNameLength == 6*sizeof(WCHAR), "len wrong %u\n", pfni->FileNameLength );
ok( pfni->NextEntryOffset == 0, "offset wrong %lu\n", pfni->NextEntryOffset );
ok( pfni->Action == FILE_ACTION_REMOVED, "action wrong %lu\n", pfni->Action );
ok( pfni->FileNameLength == 6*sizeof(WCHAR), "len wrong %lu\n", pfni->FileNameLength );
ok( !memcmp(pfni->FileName,&szGa[1],6*sizeof(WCHAR)), "name wrong\n" );
ok( (NTSTATUS)ov.Internal == STATUS_SUCCESS, "ov.Internal wrong\n");
dwCount = (char *)&pfni->FileName[pfni->FileNameLength/sizeof(WCHAR)] - buffer;
ok( ov.InternalHigh == dwCount, "ov.InternalHigh wrong %lu/%u\n",ov.InternalHigh, dwCount );
ok( ov.InternalHigh == dwCount, "ov.InternalHigh wrong %Iu/%lu\n",ov.InternalHigh, dwCount );
CloseHandle(hdir);
@@ -636,21 +646,8 @@ static void test_readdirectorychanges_null(void)
static const WCHAR szHoo[] = { '\\','h','o','o',0 };
PFILE_NOTIFY_INFORMATION pfni;
if (!pReadDirectoryChangesW)
{
win_skip("ReadDirectoryChangesW is not available\n");
return;
}
SetLastError(0xdeadbeef);
r = GetTempPathW( MAX_PATH, path );
if (!r && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetTempPathW is not implemented\n");
return;
}
ok( r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW( path, szBoo );
lstrcpyW( subdir, path );
@@ -678,7 +675,7 @@ static void test_readdirectorychanges_null(void)
ov.InternalHigh = 0;
memset( buffer, 0, sizeof buffer );
r = pReadDirectoryChangesW(hdir,NULL,0,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,NULL,0,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = WaitForSingleObject( ov.hEvent, 0 );
@@ -695,11 +692,11 @@ static void test_readdirectorychanges_null(void)
ov.Internal = 0;
ov.InternalHigh = 0;
S(U(ov)).Offset = 0;
S(U(ov)).OffsetHigh = 0;
ov.Offset = 0;
ov.OffsetHigh = 0;
memset( buffer, 0, sizeof buffer );
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,FALSE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = WaitForSingleObject( ov.hEvent, 0 );
@@ -736,16 +733,8 @@ static void test_readdirectorychanges_filedir(void)
static const WCHAR szFoo[] = { '\\','f','o','o',0 };
PFILE_NOTIFY_INFORMATION pfni;
SetLastError(0xdeadbeef);
r = GetTempPathW( MAX_PATH, path );
if (!r && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetTempPathW is not implemented\n");
return;
}
ok( r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW( path, szBoo );
lstrcpyW( subdir, path );
@@ -771,7 +760,7 @@ static void test_readdirectorychanges_filedir(void)
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
r = pReadDirectoryChangesW(hdir,buffer,sizeof buffer,TRUE,filter,NULL,&ov,NULL);
r = ReadDirectoryChangesW(hdir,buffer,sizeof buffer,TRUE,filter,NULL,&ov,NULL);
ok(r==TRUE, "should return true\n");
r = WaitForSingleObject( ov.hEvent, 10 );
@@ -810,7 +799,7 @@ static void test_readdirectorychanges_filedir(void)
static void CALLBACK readdirectorychanges_cr(DWORD error, DWORD len, LPOVERLAPPED ov)
{
ok(error == 0, "ReadDirectoryChangesW error %d\n", error);
ok(error == 0, "ReadDirectoryChangesW error %ld\n", error);
ok(ov->hEvent == (void*)0xdeadbeef, "hEvent should not have changed\n");
}
@@ -827,22 +816,8 @@ static void test_readdirectorychanges_cr(void)
HANDLE hdir, hfile;
NTSTATUS r;
if (!pReadDirectoryChangesW)
{
win_skip("ReadDirectoryChangesW is not available\n");
return;
}
SetLastError(0xdeadbeef);
r = GetTempPathW(MAX_PATH, path);
if (!r && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
{
win_skip("GetTempPathW is not implemented\n");
return;
}
ok(r != 0, "temp path failed\n");
if (!r)
return;
lstrcatW(path, szBoo);
lstrcpyW(dir, path);
@@ -867,9 +842,9 @@ static void test_readdirectorychanges_cr(void)
memset(&ov, 0, sizeof(ov));
ov.hEvent = (void*)0xdeadbeef;
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
hfile = CreateFileW(file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
ok(hfile != INVALID_HANDLE_VALUE, "failed to create file\n");
@@ -878,15 +853,15 @@ static void test_readdirectorychanges_cr(void)
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive file creation event\n");
ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
ok(fni->Action == FILE_ACTION_ADDED, "Action = %d\n", fni->Action);
ok(fni->Action == FILE_ACTION_ADDED, "Action = %ld\n", fni->Action);
ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
"FileNameLength = %d\n", fni->FileNameLength);
"FileNameLength = %ld\n", fni->FileNameLength);
ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
/* This event will not be reported */
r = CreateDirectoryW(dir, NULL);
@@ -898,15 +873,15 @@ static void test_readdirectorychanges_cr(void)
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive file move event\n");
ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
ok(fni->Action == FILE_ACTION_REMOVED, "Action = %d\n", fni->Action);
ok(fni->Action == FILE_ACTION_REMOVED, "Action = %ld\n", fni->Action);
ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
"FileNameLength = %d\n", fni->FileNameLength);
"FileNameLength = %ld\n", fni->FileNameLength);
ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
r = MoveFileW(sub_file, file);
ok(r == TRUE, "failed to move file\n");
@@ -914,15 +889,15 @@ static void test_readdirectorychanges_cr(void)
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive file move event\n");
ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
ok(fni->Action == FILE_ACTION_ADDED, "Action = %d\n", fni->Action);
ok(fni->Action == FILE_ACTION_ADDED, "Action = %ld\n", fni->Action);
ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
"FileNameLength = %d\n", fni->FileNameLength);
"FileNameLength = %ld\n", fni->FileNameLength);
ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
r = DeleteFileW(file);
ok(r == TRUE, "failed to delete file\n");
@@ -930,9 +905,9 @@ static void test_readdirectorychanges_cr(void)
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive file removal event\n");
ok(fni->NextEntryOffset == 0, "there should be no more events in buffer\n");
ok(fni->Action == FILE_ACTION_REMOVED, "Action = %d\n", fni->Action);
ok(fni->Action == FILE_ACTION_REMOVED, "Action = %ld\n", fni->Action);
ok(fni->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
"FileNameLength = %d\n", fni->FileNameLength);
"FileNameLength = %ld\n", fni->FileNameLength);
ok(!memcmp(fni->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
@@ -943,9 +918,9 @@ static void test_readdirectorychanges_cr(void)
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL);
ok(hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_DIR_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
r = MoveFileW(dir, file);
ok(r == TRUE, "failed to move directory\n");
@@ -954,17 +929,17 @@ static void test_readdirectorychanges_cr(void)
ok(r != 0, "failed to receive directory move event\n");
if (fni->Action == FILE_ACTION_RENAMED_OLD_NAME)
{
ok(fni->Action == FILE_ACTION_RENAMED_OLD_NAME, "Action = %d\n", fni->Action);
ok(fni->Action == FILE_ACTION_RENAMED_OLD_NAME, "Action = %ld\n", fni->Action);
ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
"FileNameLength = %d\n", fni->FileNameLength);
"FileNameLength = %ld\n", fni->FileNameLength);
ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
ok(fni->NextEntryOffset != 0, "no next entry in movement event\n");
fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset);
ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n");
ok(fni_next->Action == FILE_ACTION_RENAMED_NEW_NAME, "Action = %d\n", fni_next->Action);
ok(fni_next->Action == FILE_ACTION_RENAMED_NEW_NAME, "Action = %ld\n", fni_next->Action);
ok(fni_next->FileNameLength == lstrlenW(szFile)*sizeof(WCHAR),
"FileNameLength = %d\n", fni_next->FileNameLength);
"FileNameLength = %ld\n", fni_next->FileNameLength);
ok(!memcmp(fni_next->FileName, szFile, lstrlenW(szFile)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR)));
}
@@ -974,9 +949,9 @@ static void test_readdirectorychanges_cr(void)
if (fni->NextEntryOffset == 0)
{
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_DIR_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive directory move event\n");
@@ -989,33 +964,33 @@ static void test_readdirectorychanges_cr(void)
r = RemoveDirectoryW(dir);
ok(r == TRUE, "failed to remove directory\n");
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_DIR_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive directory creation event\n");
ok(fni->Action == FILE_ACTION_ADDED, "Action = %d\n", fni->Action);
ok(fni->Action == FILE_ACTION_ADDED, "Action = %ld\n", fni->Action);
ok(fni->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
"FileNameLength = %d\n", fni->FileNameLength);
"FileNameLength = %ld\n", fni->FileNameLength);
ok(!memcmp(fni->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni->FileName, fni->FileNameLength/sizeof(WCHAR)));
if (fni->NextEntryOffset)
fni_next = (FILE_NOTIFY_INFORMATION*)((char*)fni+fni->NextEntryOffset);
else
{
r = pReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
r = ReadDirectoryChangesW(hdir, fni, sizeof(fni), FALSE,
FILE_NOTIFY_CHANGE_DIR_NAME, NULL, &ov, readdirectorychanges_cr);
ok(r == TRUE, "pReadDirectoryChangesW failed\n");
ok(r == TRUE, "ReadDirectoryChangesW failed\n");
r = SleepEx(1000, TRUE);
ok(r != 0, "failed to receive directory removal event\n");
fni_next = fni;
}
ok(fni_next->NextEntryOffset == 0, "there should be no more events in buffer\n");
ok(fni_next->Action == FILE_ACTION_REMOVED, "Action = %d\n", fni_next->Action);
ok(fni_next->Action == FILE_ACTION_REMOVED, "Action = %ld\n", fni_next->Action);
ok(fni_next->FileNameLength == lstrlenW(szDir)*sizeof(WCHAR),
"FileNameLength = %d\n", fni_next->FileNameLength);
"FileNameLength = %ld\n", fni_next->FileNameLength);
ok(!memcmp(fni_next->FileName, szDir, lstrlenW(szDir)*sizeof(WCHAR)),
"FileName = %s\n", wine_dbgstr_wn(fni_next->FileName, fni_next->FileNameLength/sizeof(WCHAR)));
@@ -1035,21 +1010,21 @@ static void test_ffcn_directory_overlap(void)
/* Setup directory hierarchy */
ret = GetTempPathA(MAX_PATH, workdir);
ok((ret > 0) && (ret <= MAX_PATH),
"GetTempPathA error: %d\n", GetLastError());
"GetTempPathA error: %ld\n", GetLastError());
ret = GetTempFileNameA(workdir, "fcn", 0, tempfile);
ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
ret = DeleteFileA(tempfile);
ok(ret, "DeleteFileA error: %d\n", GetLastError());
ok(ret, "DeleteFileA error: %ld\n", GetLastError());
lstrcpyA(parentdir, tempfile);
ret = CreateDirectoryA(parentdir, NULL);
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
lstrcpyA(childdir, parentdir);
lstrcatA(childdir, "\\c");
ret = CreateDirectoryA(childdir, NULL);
ok(ret, "CreateDirectoryA error: %d\n", GetLastError());
ok(ret, "CreateDirectoryA error: %ld\n", GetLastError());
/* When recursively watching overlapping directories, changes in child
@@ -1061,7 +1036,7 @@ static void test_ffcn_directory_overlap(void)
/* Create a file in child */
ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
/* Both watches should trigger */
ret = FinishNotificationThread(parent_thread);
@@ -1070,7 +1045,7 @@ static void test_ffcn_directory_overlap(void)
ok(ret, "Missed child notification\n");
ret = DeleteFileA(tempfile);
ok(ret, "DeleteFileA error: %d\n", GetLastError());
ok(ret, "DeleteFileA error: %ld\n", GetLastError());
/* Removing a recursive parent watch should not affect child watches. Doing
@@ -1078,22 +1053,22 @@ static void test_ffcn_directory_overlap(void)
parent_watch = FindFirstChangeNotificationA(parentdir, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME);
ok(parent_watch != INVALID_HANDLE_VALUE,
"FindFirstChangeNotification error: %d\n", GetLastError());
"FindFirstChangeNotification error: %ld\n", GetLastError());
child_watch = FindFirstChangeNotificationA(childdir, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME);
ok(child_watch != INVALID_HANDLE_VALUE,
"FindFirstChangeNotification error: %d\n", GetLastError());
"FindFirstChangeNotification error: %ld\n", GetLastError());
ret = FindCloseChangeNotification(parent_watch);
ok(ret, "FindCloseChangeNotification error: %d\n", GetLastError());
ok(ret, "FindCloseChangeNotification error: %ld\n", GetLastError());
child_thread = CreateThread(NULL, 0, NotificationThread, child_watch, 0,
&threadId);
ok(child_thread != NULL, "CreateThread error: %d\n", GetLastError());
ok(child_thread != NULL, "CreateThread error: %ld\n", GetLastError());
/* Create a file in child */
ret = GetTempFileNameA(childdir, "fcn", 0, tempfile);
ok(ret, "GetTempFileNameA error: %d\n", GetLastError());
ok(ret, "GetTempFileNameA error: %ld\n", GetLastError());
/* Child watch should trigger */
ret = FinishNotificationThread(child_thread);
@@ -1101,20 +1076,17 @@ static void test_ffcn_directory_overlap(void)
/* clean up */
ret = DeleteFileA(tempfile);
ok(ret, "DeleteFileA error: %d\n", GetLastError());
ok(ret, "DeleteFileA error: %ld\n", GetLastError());
ret = RemoveDirectoryA(childdir);
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
ret = RemoveDirectoryA(parentdir);
ok(ret, "RemoveDirectoryA error: %d\n", GetLastError());
ok(ret, "RemoveDirectoryA error: %ld\n", GetLastError());
}
START_TEST(change)
{
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
pReadDirectoryChangesW = (void *)GetProcAddress(hkernel32, "ReadDirectoryChangesW");
test_ffcnMultipleThreads();
/* The above function runs a test that must occur before FindCloseChangeNotification is run in the
current thread to preserve the emptiness of the wine user APC queue. To ensure this it should be
+204 -140
View File
@@ -40,7 +40,7 @@ static void test_destination_buffer(void)
SetLastError(0xdeadbeef);
needed = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
ok( (needed > 0), "returned %d with %u (expected '> 0')\n",
ok( (needed > 0), "returned %d with %lu (expected '> 0')\n",
needed, GetLastError());
maxsize = needed*2;
@@ -52,41 +52,47 @@ static void test_destination_buffer(void)
buffer[maxsize] = '\0';
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, needed+1, NULL, NULL);
ok( (len > 0), "returned %d with %u and '%s' (expected '> 0')\n",
ok( (len > 0), "returned %d with %lu and '%s' (expected '> 0')\n",
len, GetLastError(), buffer);
ok(!lstrcmpA(buffer, "foobar"), "expected \"foobar\" got \"%s\"\n", buffer);
memset(buffer, 'x', maxsize);
buffer[maxsize] = '\0';
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, needed, NULL, NULL);
ok( (len > 0), "returned %d with %u and '%s' (expected '> 0')\n",
ok( (len > 0), "returned %d with %lu and '%s' (expected '> 0')\n",
len, GetLastError(), buffer);
ok(!lstrcmpA(buffer, "foobar"), "expected \"foobar\" got \"%s\"\n", buffer);
memset(buffer, 'x', maxsize);
buffer[maxsize] = '\0';
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, needed-1, NULL, NULL);
ok( !len && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
"returned %d with %u and '%s' (expected '0' with "
"returned %d with %lu and '%s' (expected '0' with "
"ERROR_INSUFFICIENT_BUFFER)\n", len, GetLastError(), buffer);
ok(!strncmp(buffer, "foobar", 6), "expected \"foobar\" got \"%s\"\n", buffer);
ok(buffer[6] == 'x', "expected buf[5]=='x', got \"%s\"\n", buffer);
memset(buffer, 'x', maxsize);
buffer[maxsize] = '\0';
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, 1, NULL, NULL);
ok( !len && (GetLastError() == ERROR_INSUFFICIENT_BUFFER),
"returned %d with %u and '%s' (expected '0' with "
"returned %d with %lu and '%s' (expected '0' with "
"ERROR_INSUFFICIENT_BUFFER)\n", len, GetLastError(), buffer);
ok(buffer[0] == 'f', "expected buf[1]=='f', got \"%s\"\n", buffer);
ok(buffer[1] == 'x', "expected buf[1]=='x', got \"%s\"\n", buffer);
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, 0, NULL, NULL);
ok( (len > 0), "returned %d with %u (expected '> 0')\n",
ok( (len > 0), "returned %d with %lu (expected '> 0')\n",
len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, needed, NULL, NULL);
ok( !len && (GetLastError() == ERROR_INVALID_PARAMETER),
"returned %d with %u (expected '0' with "
"returned %d with %lu (expected '0' with "
"ERROR_INVALID_PARAMETER)\n", len, GetLastError());
HeapFree(GetProcessHeap(), 0, buffer);
@@ -102,14 +108,14 @@ static void test_null_source(void)
len = WideCharToMultiByte(CP_ACP, 0, NULL, 0, NULL, 0, NULL, NULL);
GLE = GetLastError();
ok(!len && GLE == ERROR_INVALID_PARAMETER,
"WideCharToMultiByte returned %d with GLE=%u (expected 0 with ERROR_INVALID_PARAMETER)\n",
"WideCharToMultiByte returned %d with GLE=%lu (expected 0 with ERROR_INVALID_PARAMETER)\n",
len, GLE);
SetLastError(0);
len = WideCharToMultiByte(CP_ACP, 0, NULL, -1, NULL, 0, NULL, NULL);
GLE = GetLastError();
ok(!len && GLE == ERROR_INVALID_PARAMETER,
"WideCharToMultiByte returned %d with GLE=%u (expected 0 with ERROR_INVALID_PARAMETER)\n",
"WideCharToMultiByte returned %d with GLE=%lu (expected 0 with ERROR_INVALID_PARAMETER)\n",
len, GLE);
}
@@ -124,7 +130,7 @@ static void test_negative_source_length(void)
memset(buf,'x',sizeof(buf));
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -2002, buf, 10, NULL, NULL);
ok(len == 7 && GetLastError() == 0xdeadbeef,
"WideCharToMultiByte(-2002): len=%d error=%u\n", len, GetLastError());
"WideCharToMultiByte(-2002): len=%d error=%lu\n", len, GetLastError());
ok(!lstrcmpA(buf, "foobar"),
"WideCharToMultiByte(-2002): expected \"foobar\" got \"%s\"\n", buf);
@@ -132,13 +138,13 @@ static void test_negative_source_length(void)
memset(bufW,'x',sizeof(bufW));
len = MultiByteToWideChar(CP_ACP, 0, "foobar", -2002, bufW, 10);
ok(len == 7 && !lstrcmpW(bufW, foobarW) && GetLastError() == 0xdeadbeef,
"MultiByteToWideChar(-2002): len=%d error=%u\n", len, GetLastError());
"MultiByteToWideChar(-2002): len=%d error=%lu\n", len, GetLastError());
SetLastError(0xdeadbeef);
memset(bufW, 'x', sizeof(bufW));
len = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, bufW, 6);
ok(len == 0 && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"MultiByteToWideChar(-1): len=%d error=%u\n", len, GetLastError());
"MultiByteToWideChar(-1): len=%d error=%lu\n", len, GetLastError());
}
#define LONGBUFLEN 100000
@@ -156,33 +162,33 @@ static void test_negative_dest_length(void)
memset(bufA,'x',sizeof(bufA));
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
"WideCharToMultiByte(destlen -1): len=%d error=%x\n", len, GetLastError());
"WideCharToMultiByte(destlen -1): len=%d error=%lx\n", len, GetLastError());
SetLastError( 0xdeadbeef );
memset(bufW,'x',sizeof(bufW));
len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1, bufW, -1);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
"MultiByteToWideChar(destlen -1): len=%d error=%x\n", len, GetLastError());
"MultiByteToWideChar(destlen -1): len=%d error=%lx\n", len, GetLastError());
/* Test return on -1000 dest length */
SetLastError( 0xdeadbeef );
memset(bufA,'x',sizeof(bufA));
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1000, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
"WideCharToMultiByte(destlen -1000): len=%d error=%x\n", len, GetLastError());
"WideCharToMultiByte(destlen -1000): len=%d error=%lx\n", len, GetLastError());
SetLastError( 0xdeadbeef );
memset(bufW,'x',sizeof(bufW));
len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1000, bufW, -1);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
"MultiByteToWideChar(destlen -1000): len=%d error=%x\n", len, GetLastError());
"MultiByteToWideChar(destlen -1000): len=%d error=%lx\n", len, GetLastError());
/* Test return on INT_MAX dest length */
SetLastError( 0xdeadbeef );
memset(bufA,'x',sizeof(bufA));
len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, INT_MAX, NULL, NULL);
ok(len == 7 && !lstrcmpA(bufA, "foobar") && GetLastError() == 0xdeadbeef,
"WideCharToMultiByte(destlen INT_MAX): len=%d error=%x\n", len, GetLastError());
"WideCharToMultiByte(destlen INT_MAX): len=%d error=%lx\n", len, GetLastError());
/* Test return on INT_MAX dest length and very long input */
SetLastError( 0xdeadbeef );
@@ -196,7 +202,7 @@ static void test_negative_dest_length(void)
len = WideCharToMultiByte(CP_ACP, 0, originalW, -1, bufA, INT_MAX, NULL, NULL);
theError = GetLastError();
ok(len == LONGBUFLEN && !lstrcmpA(bufA, originalA) && theError == 0xdeadbeef,
"WideCharToMultiByte(srclen %d, destlen INT_MAX): len %d error=%x\n", LONGBUFLEN, len, theError);
"WideCharToMultiByte(srclen %d, destlen INT_MAX): len %d error=%lx\n", LONGBUFLEN, len, theError);
}
@@ -205,92 +211,94 @@ static void test_other_invalid_parameters(void)
char c_string[] = "Hello World";
size_t c_string_len = sizeof(c_string);
WCHAR w_string[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
size_t w_string_len = sizeof(w_string) / sizeof(WCHAR);
size_t w_string_len = ARRAY_SIZE(w_string);
BOOL used;
INT len;
/* Unrecognized flag => ERROR_INVALID_FLAGS */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0x100, w_string, -1, c_string, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0x800, w_string, -1, c_string, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_ACP, 0x10, c_string, -1, w_string, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%lx\n", len, GetLastError());
/* Unrecognized flag and invalid codepage => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(0xdeadbeef, 0x100, w_string, w_string_len, c_string, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(0xdeadbeef, 0x10, c_string, c_string_len, w_string, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* Unrecognized flag and src is NULL => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0x100, NULL, -1, c_string, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_ACP, 0x10, NULL, -1, w_string, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* srclen=0 => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, w_string, 0, c_string, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_ACP, 0, c_string, 0, w_string, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* dst=NULL but dstlen not 0 => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, w_string, w_string_len, NULL, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_ACP, 0, c_string, c_string_len, NULL, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* CP_UTF7, CP_UTF8, or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
/* CP_SYMBOL's behavior here is undocumented */
/* CP_UTF7 or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
/* CP_UTF8 allows it since win10 1709 */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 12 || broken(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER),
"len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* CP_UTF7, CP_UTF8, or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
/* CP_SYMBOL's behavior here is undocumented */
/* CP_UTF7 or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
/* CP_UTF8 allows it since win10 1709 */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 12 || broken(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER),
"len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* CP_UTF7, flags not 0 and used not NULL => ERROR_INVALID_PARAMETER */
@@ -299,12 +307,14 @@ static void test_other_invalid_parameters(void)
instead except on Windows NT4 */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF7, 1, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
/* CP_UTF8, unrecognized flag and used not NULL => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF8, 0x100, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
ok(len == 0, "wrong ret %d\n", len);
ok(GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_FLAGS /* Win10 1709+ */, "wrong error %lu\n", GetLastError());
}
static void test_overlapped_buffers(void)
@@ -314,12 +324,22 @@ static void test_overlapped_buffers(void)
char buf[256];
int ret;
/* limit such that strA's NUL terminator overlaps strW's NUL */
size_t overlap_limit = (sizeof(strW)-sizeof(strA)) - (sizeof(strW[0])-sizeof(strA[0]));
SetLastError(0xdeadbeef);
memcpy(buf + 1, strW, sizeof(strW));
ret = WideCharToMultiByte(CP_ACP, 0, (WCHAR *)(buf + 1), -1, buf, sizeof(buf), NULL, NULL);
ok(ret == sizeof(strA), "unexpected ret %d\n", ret);
ok(!memcmp(buf, strA, sizeof(strA)), "conversion failed: %s\n", buf);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
memcpy(buf + overlap_limit, strA, sizeof(strA));
ret = MultiByteToWideChar(CP_ACP, 0, buf + overlap_limit, -1, (WCHAR *)buf, sizeof(buf) / sizeof(WCHAR));
ok(ret == ARRAY_SIZE(strW), "unexpected ret %d\n", ret);
ok(!memcmp(buf, strW, sizeof(strW)), "conversion failed: %s\n", wine_dbgstr_wn((WCHAR *)buf, ARRAY_SIZE(strW)));
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
}
static void test_string_conversion(LPBOOL bUsedDefaultChar)
@@ -339,14 +359,14 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(ret == 1, "ret is %d\n", ret);
ok(mbc == '\xe4', "mbc is %d\n", mbc);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(1252, 0, &wc2, 1, &mbc, 1, NULL, bUsedDefaultChar);
ok(ret == 1, "ret is %d\n", ret);
ok(mbc == 63, "mbc is %d\n", mbc);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
if (IsValidCodePage(1251))
{
@@ -357,14 +377,14 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef ||
broken(GetLastError() == 0), /* win95 */
"GetLastError() is %u\n", GetLastError());
"GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(1251, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar);
ok(ret == 1, "ret is %d\n", ret);
ok(mbc == 97, "mbc is %d\n", mbc);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
}
else
skip("Codepage 1251 not available\n");
@@ -375,14 +395,14 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(ret == 0, "ret is %d\n", ret);
ok(mbc == 84, "mbc is %d\n", mbc);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(1252, 0, wcs, -1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
ok(ret == 5, "ret is %d\n", ret);
ok(!strcmp(mbs, "Th?i"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
mbs[0] = 0;
/* WideCharToMultiByte mustn't add any null character automatically.
@@ -392,7 +412,7 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(ret == 3, "ret is %d\n", ret);
ok(!strcmp(mbs, "Th?i"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
ZeroMemory(mbs, 5);
/* Now this shouldn't be the case like above as we zeroed the complete string buffer. */
@@ -401,7 +421,7 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(ret == 3, "ret is %d\n", ret);
ok(!strcmp(mbs, "Th?"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
/* Double-byte tests */
ret = WideCharToMultiByte(1252, 0, dbwcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
@@ -414,18 +434,35 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(!strcmp(mbs, "\xf3\xe7\x3d\xa3\xbf\xa3\xbf\xa3\xbf"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
/* Show that characters are not truncated */
ZeroMemory(mbs, 5);
ret = WideCharToMultiByte(936, 0, dbwcs2, -1, mbs, 1, (const char *)default_char, bUsedDefaultChar);
ok(!ret, "ret is %d\n", ret);
ok(mbs[0] == '\0', "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %lu\n", GetLastError());
/* And destination is not null-terminated even when too short */
FillMemory(mbs, 5, 'x');
mbs[5] = '\0';
ret = WideCharToMultiByte(936, 0, dbwcs2, -1, mbs, 2, (const char *)default_char, bUsedDefaultChar);
ok(!ret, "ret is %d\n", ret);
ok(!strcmp(mbs, "\xf3\xe7""xxx"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %lu\n", GetLastError());
/* Length-only tests */
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(1252, 0, &wc2, 1, NULL, 0, NULL, bUsedDefaultChar);
ok(ret == 1, "ret is %d\n", ret);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(1252, 0, wcs, -1, NULL, 0, NULL, bUsedDefaultChar);
ok(ret == 5, "ret is %d\n", ret);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
if (!IsValidCodePage(950))
{
@@ -439,13 +476,13 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(ret == 5, "ret is %d\n", ret);
ok(!strcmp(mbs, "\xb5H\xa9\xd2"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(950, 0, dbwcs, 1, &mbc, 1, NULL, bUsedDefaultChar);
ok(ret == 0, "ret is %d\n", ret);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %lu\n", GetLastError());
ZeroMemory(mbs, 5);
SetLastError(0xdeadbeef);
@@ -453,20 +490,20 @@ static void test_string_conversion(LPBOOL bUsedDefaultChar)
ok(ret == 2, "ret is %d\n", ret);
ok(!strcmp(mbs, "\xb5H"), "mbs is %s\n", mbs);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
/* Length-only tests */
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(950, 0, dbwcs, 1, NULL, 0, NULL, bUsedDefaultChar);
ok(ret == 2, "ret is %d\n", ret);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = WideCharToMultiByte(950, 0, dbwcs, -1, NULL, 0, NULL, bUsedDefaultChar);
ok(ret == 5, "ret is %d\n", ret);
if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
ok(GetLastError() == 0xdeadbeef, "GetLastError() is %lu\n", GetLastError());
}
static void test_utf7_encoding(void)
@@ -531,12 +568,20 @@ static void test_utf7_encoding(void)
/* tests dry run with dst=NULL and dstlen=0 */
{
{0x4F60,0x597D,0x5417,0}, -1, NULL, 0,
#if defined(__REACTOS__) && defined(_MSC_VER)
{0}, 0, 11
#else
{}, 0, 11
#endif
},
/* tests dry run with dst!=NULL and dstlen=0 */
{
{0x4F60,0x597D,0x5417,0}, -1, output, 0,
#if defined(__REACTOS__) && defined(_MSC_VER)
{0}, 0, 11
#else
{}, 0, 11
#endif
},
/* tests srclen < strlenW(src) with directly encodable chars */
{
@@ -683,7 +728,7 @@ static void test_utf7_encoding(void)
i, expected_len, expected_len, output[expected_len]);
}
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
memset(output, '#', sizeof(output) - 1);
output[sizeof(output) - 1] = 0;
@@ -695,7 +740,7 @@ static void test_utf7_encoding(void)
if (!tests[i].len)
{
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"tests[%i]: expected error=0x%x, got error=0x%x\n",
"tests[%i]: expected error=0x%x, got error=0x%lx\n",
i, ERROR_INSUFFICIENT_BUFFER, GetLastError());
}
ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len);
@@ -746,12 +791,12 @@ static void test_utf7_decoding(void)
{
/* tests string conversion with srclen=-1 */
{
"+T2BZfQ-", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2BZfQ-", -1, output, ARRAY_SIZE(output) - 1,
{0x4F60,0x597D,0}, 3, 3
},
/* tests string conversion with srclen=-2 */
{
"+T2BZfQ-", -2, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2BZfQ-", -2, output, ARRAY_SIZE(output) - 1,
{0x4F60,0x597D,0}, 3, 3
},
/* tests string conversion with dstlen=strlen(expected_dst) */
@@ -772,81 +817,93 @@ static void test_utf7_decoding(void)
/* tests dry run with dst=NULL and dstlen=0 */
{
"+T2BZfQ-", -1, NULL, 0,
#if defined(__REACTOS__) && defined(_MSC_VER)
{0}, 0, 3
#else
{}, 0, 3
#endif
},
/* tests dry run with dst!=NULL and dstlen=0 */
{
"+T2BZfQ-", -1, output, 0,
#if defined(__REACTOS__) && defined(_MSC_VER)
{0}, 0, 3
#else
{}, 0, 3
#endif
},
/* tests ill-formed UTF-7: 6 bits, not enough for a byte pair */
{
"+T-+T-+T-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T-+T-+T-hello", -1, output, ARRAY_SIZE(output) - 1,
{'h','e','l','l','o',0}, 6, 6
},
/* tests ill-formed UTF-7: 12 bits, not enough for a byte pair */
{
"+T2-+T2-+T2-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2-+T2-+T2-hello", -1, output, ARRAY_SIZE(output) - 1,
{'h','e','l','l','o',0}, 6, 6
},
/* tests ill-formed UTF-7: 18 bits, not a multiple of 16 and the last bit is a 1 */
{
"+T2B-+T2B-+T2B-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2B-+T2B-+T2B-hello", -1, output, ARRAY_SIZE(output) - 1,
{0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9
},
/* tests ill-formed UTF-7: 24 bits, a multiple of 8 but not a multiple of 16 */
{
"+T2BZ-+T2BZ-+T2BZ-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2BZ-+T2BZ-+T2BZ-hello", -1, output, ARRAY_SIZE(output) - 1,
{0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9
},
/* tests UTF-7 followed by characters that should be encoded but aren't */
{
"+T2BZ-\x82\xFE", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2BZ-\x82\xFE", -1, output, ARRAY_SIZE(output) - 1,
{0x4F60,0x0082,0x00FE,0}, 4, 4
},
/* tests srclen > strlen(src) */
{
"a\0b", 4, output, sizeof(output) / sizeof(WCHAR) - 1,
"a\0b", 4, output, ARRAY_SIZE(output) - 1,
{'a',0,'b',0}, 4, 4
},
/* tests srclen < strlen(src) outside of a UTF-7 sequence */
{
"hello", 2, output, sizeof(output) / sizeof(WCHAR) - 1,
"hello", 2, output, ARRAY_SIZE(output) - 1,
{'h','e'}, 2, 2
},
/* tests srclen < strlen(src) inside of a UTF-7 sequence */
{
"+T2BZfQ-", 4, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2BZfQ-", 4, output, ARRAY_SIZE(output) - 1,
{0x4F60}, 1, 1
},
/* tests srclen < strlen(src) right at the beginning of a UTF-7 sequence */
{
"hi+T2A-", 3, output, sizeof(output) / sizeof(WCHAR) - 1,
"hi+T2A-", 3, output, ARRAY_SIZE(output) - 1,
{'h','i'}, 2, 2
},
/* tests srclen < strlen(src) right at the end of a UTF-7 sequence */
{
"+T2A-hi", 5, output, sizeof(output) / sizeof(WCHAR) - 1,
"+T2A-hi", 5, output, ARRAY_SIZE(output) - 1,
{0x4F60}, 1, 1
},
/* tests srclen < strlen(src) at the beginning of an escaped + sign */
{
"hi+-", 3, output, sizeof(output) / sizeof(WCHAR) - 1,
"hi+-", 3, output, ARRAY_SIZE(output) - 1,
{'h','i'}, 2, 2
},
/* tests srclen < strlen(src) at the end of an escaped + sign */
{
"+-hi", 2, output, sizeof(output) / sizeof(WCHAR) - 1,
"+-hi", 2, output, ARRAY_SIZE(output) - 1,
{'+'}, 1, 1
},
/* tests len=0 but no error */
{
"+", 1, output, sizeof(output) / sizeof(WCHAR) - 1,
"+", 1, output, ARRAY_SIZE(output) - 1,
#if defined(__REACTOS__) && defined(_MSC_VER)
{0}, 0, 0
#else
{}, 0, 0
#endif
},
/* tests a single null char */
{
"", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
"", -1, output, ARRAY_SIZE(output) - 1,
{0}, 1, 1
},
/* tests a buffer that runs out while not decoding a UTF-7 sequence */
@@ -867,9 +924,9 @@ static void test_utf7_decoding(void)
sprintf(input, "+%c+AAA", i);
memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
output[ARRAY_SIZE(output) - 1] = 0;
len = MultiByteToWideChar(CP_UTF7, 0, input, 7, output, sizeof(output) / sizeof(WCHAR) - 1);
len = MultiByteToWideChar(CP_UTF7, 0, input, 7, output, ARRAY_SIZE(output) - 1);
if (i == '-')
{
@@ -909,9 +966,9 @@ static void test_utf7_decoding(void)
sprintf(input, "+B%c+AAA", i);
memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
output[ARRAY_SIZE(output) - 1] = 0;
len = MultiByteToWideChar(CP_UTF7, 0, input, 8, output, sizeof(output) / sizeof(WCHAR) - 1);
len = MultiByteToWideChar(CP_UTF7, 0, input, 8, output, ARRAY_SIZE(output) - 1);
if (i == '-')
{
@@ -955,10 +1012,10 @@ static void test_utf7_decoding(void)
i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1));
}
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
output[ARRAY_SIZE(output) - 1] = 0;
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_UTF7, 0, tests[i].src, tests[i].srclen,
@@ -969,7 +1026,7 @@ static void test_utf7_decoding(void)
if (!tests[i].len && tests[i].chars_written)
{
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"tests[%i]: expected error=0x%x, got error=0x%x\n",
"tests[%i]: expected error=0x%x, got error=0x%lx\n",
i, ERROR_INSUFFICIENT_BUFFER, GetLastError());
}
ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len);
@@ -987,24 +1044,28 @@ static void test_utf7_decoding(void)
static void test_undefined_byte_char(void)
{
static const struct tag_testset {
INT codepage;
UINT codepage;
LPCSTR str;
BOOL is_error;
} testset[] = {
{ 37, "\x6f", FALSE },
{ 874, "\xdd", TRUE },
{ 932, "\xfe", TRUE },
{ 932, "\x80", FALSE },
{ 932, "\x81\x45", FALSE },
{ 936, "\xff", TRUE },
{ 949, "\xff", TRUE },
{ 950, "\xff", TRUE },
{ 1252, "?", FALSE },
{ 1252, "\x90", FALSE },
{ 1253, "\xaa", TRUE },
{ 1255, "\xff", TRUE },
{ 1257, "\xa5", TRUE },
};
INT i, ret;
DWORD err;
for (i = 0; i < (sizeof(testset) / sizeof(testset[0])); i++) {
for (i = 0; i < ARRAY_SIZE(testset); i++) {
if (! IsValidCodePage(testset[i].codepage))
{
skip("Codepage %d not available\n", testset[i].codepage);
@@ -1014,23 +1075,22 @@ static void test_undefined_byte_char(void)
SetLastError(0xdeadbeef);
ret = MultiByteToWideChar(testset[i].codepage, MB_ERR_INVALID_CHARS,
testset[i].str, -1, NULL, 0);
err = GetLastError();
if (testset[i].is_error) {
ok(ret == 0 && GetLastError() == ERROR_NO_UNICODE_TRANSLATION,
"ret is %d, GetLastError is %u (cp %d)\n",
ret, GetLastError(), testset[i].codepage);
ok(err == ERROR_NO_UNICODE_TRANSLATION, "Test %u: err is %lu\n", i, err);
ok(ret == 0, "Test %u: ret is %d\n", i, ret);
}
else {
ok(ret == strlen(testset[i].str)+1 && GetLastError() == 0xdeadbeef,
"ret is %d, GetLastError is %u (cp %d)\n",
ret, GetLastError(), testset[i].codepage);
ok(err == 0xdeadbeef, "Test %u: err is %lu\n", i, err);
ok(ret == 2, "Test %u: ret is %d\n", i, ret);
}
SetLastError(0xdeadbeef);
ret = MultiByteToWideChar(testset[i].codepage, 0,
testset[i].str, -1, NULL, 0);
ok(ret == strlen(testset[i].str)+1 && GetLastError() == 0xdeadbeef,
"ret is %d, GetLastError is %u (cp %d)\n",
ret, GetLastError(), testset[i].codepage);
err = GetLastError();
ok(err == 0xdeadbeef, "Test %u: err is %lu\n", i, err);
ok(ret == 2, "Test %u: ret is %d\n", i, ret);
}
}
@@ -1043,7 +1103,7 @@ static void test_threadcp(void)
static const LCID JAPANESE = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN), SORT_DEFAULT);
static const LCID CHINESE = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);
BOOL islead, islead_acp;
BOOL islead, islead_default;
CPINFOEXA cpi;
UINT cp, acp;
int i, num;
@@ -1106,69 +1166,73 @@ static void test_threadcp(void)
last = GetThreadLocale();
acp = GetACP();
for (i = 0; i < sizeof(lcids)/sizeof(lcids[0]); i++)
for (i = 0; i < ARRAY_SIZE(lcids); i++)
{
SetThreadLocale(lcids[i].lcid);
cp = 0xdeadbeef;
GetLocaleInfoA(lcids[i].lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER, (LPSTR)&cp, sizeof(cp));
ok(cp == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n", cp, lcids[i].threadcp, cp);
ok(cp == lcids[i].threadcp, "wrong codepage %u for lcid %04lx, should be %u\n", cp, lcids[i].lcid, lcids[i].threadcp);
/* GetCPInfoEx/GetCPInfo - CP_ACP */
SetLastError(0xdeadbeef);
memset(&cpi, 0, sizeof(cpi));
ret = GetCPInfoExA(CP_ACP, 0, &cpi);
ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);
ok(ret, "GetCPInfoExA failed for lcid %04lx, error %ld\n", lcids[i].lcid, GetLastError());
ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04lx, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);
/* WideCharToMultiByte - CP_ACP */
num = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
ok(num == 7, "ret is %d (%04lx)\n", num, lcids[i].lcid);
/* MultiByteToWideChar - CP_ACP */
num = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, NULL, 0);
ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
ok(num == 7, "ret is %d (%04lx)\n", num, lcids[i].lcid);
/* GetCPInfoEx/GetCPInfo - CP_THREAD_ACP */
SetLastError(0xdeadbeef);
memset(&cpi, 0, sizeof(cpi));
ret = GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
ok(ret, "GetCPInfoExA failed for lcid %04lx, error %ld\n", lcids[i].lcid, GetLastError());
if (lcids[i].threadcp)
ok(cpi.CodePage == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n",
ok(cpi.CodePage == lcids[i].threadcp || cpi.CodePage == CP_UTF8 /* Win10 1809+ */,
"wrong codepage %u for lcid %04lx, should be %u\n",
cpi.CodePage, lcids[i].lcid, lcids[i].threadcp);
else
ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n",
cpi.CodePage, lcids[i].lcid, acp);
ok(cpi.CodePage == acp || cpi.CodePage == CP_UTF8 /* Win10 1809+ */,
"wrong codepage %u for lcid %04lx, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);
/* WideCharToMultiByte - CP_THREAD_ACP */
num = WideCharToMultiByte(CP_THREAD_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
ok(num == 7, "ret is %d (%04lx)\n", num, lcids[i].lcid);
/* MultiByteToWideChar - CP_THREAD_ACP */
num = MultiByteToWideChar(CP_THREAD_ACP, 0, "foobar", -1, NULL, 0);
ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
ok(num == 7, "ret is %d (%04lx)\n", num, lcids[i].lcid);
}
/* IsDBCSLeadByteEx - locales without codepage */
for (i = 0; i < sizeof(isleads_nocp)/sizeof(isleads_nocp[0]); i++)
for (i = 0; i < ARRAY_SIZE(isleads_nocp); i++)
{
SetThreadLocale(isleads_nocp[i].lcid);
islead_acp = IsDBCSLeadByteEx(CP_ACP, isleads_nocp[i].testchar);
islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads_nocp[i].testchar);
GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
islead_default = IsDBCSLeadByteEx(cpi.CodePage, isleads_nocp[i].testchar);
islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads_nocp[i].testchar);
ok(islead == islead_acp, "wrong islead %i for test char %x in lcid %04x. should be %i\n",
islead, isleads_nocp[i].testchar, isleads_nocp[i].lcid, islead_acp);
ok(islead == islead_default, "wrong islead %i for test char %x in lcid %04lx. should be %i\n",
islead, isleads_nocp[i].testchar, isleads_nocp[i].lcid, islead_default);
}
/* IsDBCSLeadByteEx - locales with codepage */
for (i = 0; i < sizeof(isleads)/sizeof(isleads[0]); i++)
for (i = 0; i < ARRAY_SIZE(isleads); i++)
{
SetThreadLocale(isleads[i].lcid);
GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads[i].testchar);
ok(islead == isleads[i].islead, "wrong islead %i for test char %x in lcid %04x. should be %i\n",
ok(islead == isleads[i].islead || (cpi.CodePage == CP_UTF8 && !islead),
"wrong islead %i for test char %x in lcid %04lx. should be %i\n",
islead, isleads[i].testchar, isleads[i].lcid, isleads[i].islead);
}
@@ -1194,19 +1258,19 @@ static void test_dbcs_to_widechar(void)
MB_COMPOSITE |MB_ERR_INVALID_CHARS|MB_USEGLYPHCHARS,
};
for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
for (i = 0; i < ARRAY_SIZE(flags); ++i)
{
memset(wbuf, 0xff, sizeof(wbuf));
count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 2, NULL, 0);
count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 2, wbuf, count);
ok(count == 1, "%04x: returned %d (expected 1)\n", flags[i], count);
ok(count2 == 1, "%04x: returned %d (expected 1)\n", flags[i], count2);
ok(wbuf[0] == 0x770b, "%04x: returned %04x (expected 770b)\n", flags[i], wbuf[0]);
ok(wbuf[1] == 0xffff, "%04x: returned %04x (expected ffff)\n", flags[i], wbuf[1]);
ok(count == 1, "%04lx: returned %d (expected 1)\n", flags[i], count);
ok(count2 == 1, "%04lx: returned %d (expected 1)\n", flags[i], count2);
ok(wbuf[0] == 0x770b, "%04lx: returned %04x (expected 770b)\n", flags[i], wbuf[0]);
ok(wbuf[1] == 0xffff, "%04lx: returned %04x (expected ffff)\n", flags[i], wbuf[1]);
}
for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
for (i = 0; i < ARRAY_SIZE(flags); ++i)
{
memset(wbuf, 0xff, sizeof(wbuf));
count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 3, NULL, 0);
@@ -1215,35 +1279,35 @@ static void test_dbcs_to_widechar(void)
if (flags[i] & MB_ERR_INVALID_CHARS)
{
ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], count);
ok(count2 == 0, "%04x: returned %d (expected 0)\n", flags[i], count2);
ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned %d (expected %d)\n",
ok(count == 0, "%04lx: returned %d (expected 0)\n", flags[i], count);
ok(count2 == 0, "%04lx: returned %d (expected 0)\n", flags[i], count2);
ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04lx: returned %ld (expected %d)\n",
flags[i], GetLastError(), ERROR_NO_UNICODE_TRANSLATION);
}
else
{
ok(count == 2, "%04x: returned %d (expected 2)\n", flags[i], count);
ok(count2 == 2, "%04x: returned %d (expected 2)\n", flags[i], count2);
ok(wbuf[0] == 0x770b, "%04x: returned %04x (expected 770b)\n", flags[i], wbuf[0]);
ok(count == 2, "%04lx: returned %d (expected 2)\n", flags[i], count);
ok(count2 == 2, "%04lx: returned %d (expected 2)\n", flags[i], count2);
ok(wbuf[0] == 0x770b, "%04lx: returned %04x (expected 770b)\n", flags[i], wbuf[0]);
ok(wbuf[1] == 0x003f || broken(wbuf[1] == 0), /*windows xp*/
"%04x: wrong wide char: %04x\n", flags[i], wbuf[1]);
ok(wbuf[2] == 0xffff, "%04x: returned %04x (expected ffff)\n", flags[i], wbuf[2]);
"%04lx: wrong wide char: %04x\n", flags[i], wbuf[1]);
ok(wbuf[2] == 0xffff, "%04lx: returned %04x (expected ffff)\n", flags[i], wbuf[2]);
}
}
/* src ends with null character */
for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
for (i = 0; i < ARRAY_SIZE(flags); ++i)
{
memset(wbuf, 0xff, sizeof(wbuf));
count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 4, NULL, 0);
SetLastError( 0xdeadbeef );
count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 4, wbuf, count);
ok(count == count2, "%04x: returned %d (expected %d)\n", flags[i], count2, count);
ok(count == count2, "%04lx: returned %d (expected %d)\n", flags[i], count2, count);
if (flags[i] & MB_ERR_INVALID_CHARS)
{
ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], count);
ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned %d (expected %d)\n",
ok(count == 0, "%04lx: returned %d (expected 0)\n", flags[i], count);
ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04lx: returned %ld (expected %d)\n",
flags[i], GetLastError(), ERROR_NO_UNICODE_TRANSLATION);
}
else
@@ -1251,28 +1315,28 @@ static void test_dbcs_to_widechar(void)
WCHAR wbuf_ok[] = { 0x770b, 0x003f, '\0', 0xffff };
WCHAR wbuf_broken[] = { 0x770b, '\0', 0xffff, 0xffff };
ok(count == 3 || broken(count == 2 /*windows xp*/),
"%04x: returned %d (expected 3)\n", flags[i], count);
"%04lx: returned %d (expected 3)\n", flags[i], count);
ok(!memcmp(wbuf, wbuf_ok, sizeof(wbuf_ok))
|| broken(!memcmp(wbuf, wbuf_broken, sizeof(wbuf_broken))),
"%04x: returned %04x %04x %04x %04x (expected %04x %04x %04x %04x)\n",
"%04lx: returned %04x %04x %04x %04x (expected %04x %04x %04x %04x)\n",
flags[i], wbuf[0], wbuf[1], wbuf[2], wbuf[3],
wbuf_ok[0], wbuf_ok[1], wbuf_ok[2], wbuf_ok[3]);
}
}
/* src has null character, but not ends with it */
for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
for (i = 0; i < ARRAY_SIZE(flags); ++i)
{
memset(wbuf, 0xff, sizeof(wbuf));
count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 5, NULL, 0);
SetLastError( 0xdeadbeef );
count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 5, wbuf, count);
ok(count == count2, "%04x: returned %d (expected %d)\n", flags[i], count2, count);
ok(count == count2, "%04lx: returned %d (expected %d)\n", flags[i], count2, count);
if (flags[i] & MB_ERR_INVALID_CHARS)
{
ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], count);
ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned %d (expected %d)\n",
ok(count == 0, "%04lx: returned %d (expected 0)\n", flags[i], count);
ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04lx: returned %ld (expected %d)\n",
flags[i], GetLastError(), ERROR_NO_UNICODE_TRANSLATION);
}
else
@@ -1280,10 +1344,10 @@ static void test_dbcs_to_widechar(void)
WCHAR wbuf_ok[] = { 0x770b, 0x003f, '\0', 'x', 0xffff };
WCHAR wbuf_broken[] = { 0x770b, '\0', 'x', 0xffff, 0xffff };
ok(count == 4 || broken(count == 3),
"%04x: returned %d (expected 4)\n", flags[i], count);
"%04lx: returned %d (expected 4)\n", flags[i], count);
ok(!memcmp(wbuf, wbuf_ok, sizeof(wbuf_ok))
|| broken(!memcmp(wbuf, wbuf_broken, sizeof(wbuf_broken))),
"%04x: returned %04x %04x %04x %04x %04x (expected %04x %04x %04x %04x %04x)\n",
"%04lx: returned %04x %04x %04x %04x %04x (expected %04x %04x %04x %04x %04x)\n",
flags[i], wbuf[0], wbuf[1], wbuf[2], wbuf[3], wbuf[4],
wbuf_ok[0], wbuf_ok[1], wbuf_ok[2], wbuf_ok[3], wbuf_ok[4]);
}
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
+90 -47
View File
@@ -42,9 +42,9 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access, int line)
status = pNtQueryObject(handle, ObjectBasicInformation, &obj_info,
sizeof(obj_info), NULL);
ok_(__FILE__, line)(!status, "NtQueryObject with err: %08x\n", status);
ok_(__FILE__, line)(!status, "NtQueryObject with err: %08lx\n", status);
ok_(__FILE__, line)(obj_info.GrantedAccess == access, "Granted access should "
"be 0x%08x, instead of 0x%08x\n", access, obj_info.GrantedAccess);
"be 0x%08lx, instead of 0x%08lx\n", access, obj_info.GrantedAccess);
}
/* If you change something in these tests, please do the same
@@ -185,12 +185,12 @@ static void test_CreateDirectoryA(void)
ret = CreateDirectoryA(NULL, NULL);
ok(ret == FALSE && (GetLastError() == ERROR_PATH_NOT_FOUND ||
GetLastError() == ERROR_INVALID_PARAMETER),
"CreateDirectoryA(NULL): ret=%d err=%d\n", ret, GetLastError());
"CreateDirectoryA(NULL): ret=%d err=%ld\n", ret, GetLastError());
ret = CreateDirectoryA("", NULL);
ok(ret == FALSE && (GetLastError() == ERROR_BAD_PATHNAME ||
GetLastError() == ERROR_PATH_NOT_FOUND),
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
ret = GetSystemDirectoryA(tmpdir, MAX_PATH);
ok(ret < MAX_PATH, "System directory should fit into MAX_PATH\n");
@@ -201,53 +201,53 @@ static void test_CreateDirectoryA(void)
ret = CreateDirectoryA(".", NULL);
ok(ret == FALSE && GetLastError() == ERROR_ALREADY_EXISTS,
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
ret = CreateDirectoryA("..", NULL);
ok(ret == FALSE && GetLastError() == ERROR_ALREADY_EXISTS,
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
GetTempPathA(MAX_PATH, tmpdir);
tmpdir[3] = 0; /* truncate the path */
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == FALSE && (GetLastError() == ERROR_ALREADY_EXISTS ||
GetLastError() == ERROR_ACCESS_DENIED),
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
GetTempPathA(MAX_PATH, tmpdir);
lstrcatA(tmpdir, "Please Remove Me");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE, "CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
ok(ret == TRUE, "CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == FALSE && GetLastError() == ERROR_ALREADY_EXISTS,
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
lstrcatA(tmpdir, "?");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == FALSE && (GetLastError() == ERROR_INVALID_NAME ||
GetLastError() == ERROR_PATH_NOT_FOUND),
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
RemoveDirectoryA(tmpdir);
tmpdir[lstrlenA(tmpdir) - 1] = '*';
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == FALSE && (GetLastError() == ERROR_INVALID_NAME ||
GetLastError() == ERROR_PATH_NOT_FOUND),
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
RemoveDirectoryA(tmpdir);
GetTempPathA(MAX_PATH, tmpdir);
lstrcatA(tmpdir, "Please Remove Me/Please Remove Me");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
RemoveDirectoryA(tmpdir);
/* Test behavior with a trailing dot.
@@ -257,21 +257,21 @@ static void test_CreateDirectoryA(void)
lstrcatA(tmpdir, "Please Remove Me.");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE,
"CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
lstrcatA(tmpdir, "/Please Remove Me");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE,
"CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
GetTempPathA(MAX_PATH, tmpdir);
lstrcatA(tmpdir, "Please Remove Me");
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
/* Test behavior with two trailing dots.
* The directory should be created without the trailing dots.
@@ -280,25 +280,25 @@ static void test_CreateDirectoryA(void)
lstrcatA(tmpdir, "Please Remove Me..");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE,
"CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
lstrcatA(tmpdir, "/Please Remove Me");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE || /* On Win98 */
(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND), /* On NT! */
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
if (ret == TRUE)
{
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
}
GetTempPathA(MAX_PATH, tmpdir);
lstrcatA(tmpdir, "Please Remove Me");
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
/* Test behavior with a trailing space.
* The directory should be created without the trailing space.
@@ -307,25 +307,25 @@ static void test_CreateDirectoryA(void)
lstrcatA(tmpdir, "Please Remove Me ");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE,
"CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
lstrcatA(tmpdir, "/Please Remove Me");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE || /* On Win98 */
(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND), /* On NT! */
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
if (ret == TRUE)
{
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
}
GetTempPathA(MAX_PATH, tmpdir);
lstrcatA(tmpdir, "Please Remove Me");
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
/* Test behavior with a trailing space.
* The directory should be created without the trailing spaces.
@@ -334,25 +334,25 @@ static void test_CreateDirectoryA(void)
lstrcatA(tmpdir, "Please Remove Me ");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE,
"CreateDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"CreateDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
lstrcatA(tmpdir, "/Please Remove Me");
ret = CreateDirectoryA(tmpdir, NULL);
ok(ret == TRUE || /* On Win98 */
(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND), /* On NT! */
"CreateDirectoryA(%s): ret=%d err=%d\n", tmpdir, ret, GetLastError());
"CreateDirectoryA(%s): ret=%d err=%ld\n", tmpdir, ret, GetLastError());
if (ret == TRUE)
{
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
}
GetTempPathA(MAX_PATH, tmpdir);
lstrcatA(tmpdir, "Please Remove Me");
ret = RemoveDirectoryA(tmpdir);
ok(ret == TRUE,
"RemoveDirectoryA(%s) failed err=%d\n", tmpdir, GetLastError());
"RemoveDirectoryA(%s) failed err=%ld\n", tmpdir, GetLastError());
SetCurrentDirectoryW(curdir);
}
@@ -375,32 +375,32 @@ static void test_CreateDirectoryW(void)
return;
}
ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
"should not create NULL path ret %u err %u\n", ret, GetLastError());
"should not create NULL path ret %u err %lu\n", ret, GetLastError());
ret = CreateDirectoryW(empty_strW, NULL);
ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
"should not create empty path ret %u err %u\n", ret, GetLastError());
"should not create empty path ret %u err %lu\n", ret, GetLastError());
ret = GetSystemDirectoryW(tmpdir, MAX_PATH);
ok(ret < MAX_PATH, "System directory should fit into MAX_PATH\n");
GetCurrentDirectoryW(MAX_PATH, curdir);
ret = SetCurrentDirectoryW(tmpdir);
ok(ret == TRUE, "could not chdir to the System directory ret %u err %u\n", ret, GetLastError());
ok(ret == TRUE, "could not chdir to the System directory ret %u err %lu\n", ret, GetLastError());
ret = CreateDirectoryW(dotW, NULL);
ok(ret == FALSE && GetLastError() == ERROR_ALREADY_EXISTS,
"should not create existing path ret %u err %u\n", ret, GetLastError());
"should not create existing path ret %u err %lu\n", ret, GetLastError());
ret = CreateDirectoryW(dotdotW, NULL);
ok(ret == FALSE && GetLastError() == ERROR_ALREADY_EXISTS,
"should not create existing path ret %u err %u\n", ret, GetLastError());
"should not create existing path ret %u err %lu\n", ret, GetLastError());
GetTempPathW(MAX_PATH, tmpdir);
tmpdir[3] = 0; /* truncate the path */
ret = CreateDirectoryW(tmpdir, NULL);
ok(ret == FALSE && (GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == ERROR_ALREADY_EXISTS),
"should deny access to the drive root ret %u err %u\n", ret, GetLastError());
"should deny access to the drive root ret %u err %lu\n", ret, GetLastError());
GetTempPathW(MAX_PATH, tmpdir);
lstrcatW(tmpdir, tmp_dir_name);
@@ -409,7 +409,7 @@ static void test_CreateDirectoryW(void)
ret = CreateDirectoryW(tmpdir, NULL);
ok(ret == FALSE && GetLastError() == ERROR_ALREADY_EXISTS,
"should not create existing path ret %u err %u\n", ret, GetLastError());
"should not create existing path ret %u err %lu\n", ret, GetLastError());
ret = RemoveDirectoryW(tmpdir);
ok(ret == TRUE, "RemoveDirectoryW should always succeed\n");
@@ -417,7 +417,7 @@ static void test_CreateDirectoryW(void)
lstrcatW(tmpdir, questionW);
ret = CreateDirectoryW(tmpdir, NULL);
ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
"CreateDirectoryW with ? wildcard name should fail with error 183, ret=%s error=%d\n",
"CreateDirectoryW with ? wildcard name should fail with error 183, ret=%s error=%ld\n",
ret ? " True" : "False", GetLastError());
ret = RemoveDirectoryW(tmpdir);
ok(ret == FALSE, "RemoveDirectoryW should have failed\n");
@@ -425,7 +425,7 @@ static void test_CreateDirectoryW(void)
tmpdir[lstrlenW(tmpdir) - 1] = '*';
ret = CreateDirectoryW(tmpdir, NULL);
ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
"CreateDirectoryW with * wildcard name should fail with error 183, ret=%s error=%d\n",
"CreateDirectoryW with * wildcard name should fail with error 183, ret=%s error=%ld\n",
ret ? " True" : "False", GetLastError());
ret = RemoveDirectoryW(tmpdir);
ok(ret == FALSE, "RemoveDirectoryW should have failed\n");
@@ -436,7 +436,7 @@ static void test_CreateDirectoryW(void)
lstrcatW(tmpdir, tmp_dir_name);
ret = CreateDirectoryW(tmpdir, NULL);
ok(ret == FALSE && GetLastError() == ERROR_PATH_NOT_FOUND,
"CreateDirectoryW with multiple nonexistent directories in path should fail ret %u err %u\n",
"CreateDirectoryW with multiple nonexistent directories in path should fail ret %u err %lu\n",
ret, GetLastError());
ret = RemoveDirectoryW(tmpdir);
ok(ret == FALSE, "RemoveDirectoryW should have failed\n");
@@ -461,7 +461,7 @@ static void test_RemoveDirectoryA(void)
SetLastError(0xdeadbeef);
ok(!RemoveDirectoryA(tmpdir), "RemoveDirectoryA succeeded\n");
ok(GetLastError() == ERROR_SHARING_VIOLATION,
"Expected ERROR_SHARING_VIOLATION, got %u\n", GetLastError());
"Expected ERROR_SHARING_VIOLATION, got %lu\n", GetLastError());
TEST_GRANTED_ACCESS(NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.Handle,
FILE_TRAVERSE | SYNCHRONIZE);
@@ -474,14 +474,14 @@ static void test_RemoveDirectoryA(void)
ret = RemoveDirectoryA(tmpdir);
ok(ret == FALSE && (GetLastError() == ERROR_INVALID_NAME ||
GetLastError() == ERROR_PATH_NOT_FOUND),
"RemoveDirectoryA with ? wildcard name should fail, ret=%s error=%d\n",
"RemoveDirectoryA with ? wildcard name should fail, ret=%s error=%ld\n",
ret ? " True" : "False", GetLastError());
tmpdir[lstrlenA(tmpdir) - 1] = '*';
ret = RemoveDirectoryA(tmpdir);
ok(ret == FALSE && (GetLastError() == ERROR_INVALID_NAME ||
GetLastError() == ERROR_PATH_NOT_FOUND),
"RemoveDirectoryA with * wildcard name should fail, ret=%s error=%d\n",
"RemoveDirectoryA with * wildcard name should fail, ret=%s error=%ld\n",
ret ? " True" : "False", GetLastError());
}
@@ -510,7 +510,7 @@ static void test_RemoveDirectoryW(void)
SetLastError(0xdeadbeef);
ok(!RemoveDirectoryW(tmpdir), "RemoveDirectoryW succeeded\n");
ok(GetLastError() == ERROR_SHARING_VIOLATION,
"Expected ERROR_SHARING_VIOLATION, got %u\n", GetLastError());
"Expected ERROR_SHARING_VIOLATION, got %lu\n", GetLastError());
TEST_GRANTED_ACCESS(NtCurrentTeb()->Peb->ProcessParameters->CurrentDirectory.Handle,
FILE_TRAVERSE | SYNCHRONIZE);
@@ -522,13 +522,13 @@ static void test_RemoveDirectoryW(void)
lstrcatW(tmpdir, questionW);
ret = RemoveDirectoryW(tmpdir);
ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
"RemoveDirectoryW with wildcard should fail with error 183, ret=%s error=%d\n",
"RemoveDirectoryW with wildcard should fail with error 183, ret=%s error=%ld\n",
ret ? " True" : "False", GetLastError());
tmpdir[lstrlenW(tmpdir) - 1] = '*';
ret = RemoveDirectoryW(tmpdir);
ok(ret == FALSE && GetLastError() == ERROR_INVALID_NAME,
"RemoveDirectoryW with * wildcard name should fail with error 183, ret=%s error=%d\n",
"RemoveDirectoryW with * wildcard name should fail with error 183, ret=%s error=%ld\n",
ret ? " True" : "False", GetLastError());
}
@@ -536,15 +536,58 @@ static void test_SetCurrentDirectoryA(void)
{
SetLastError(0);
ok( !SetCurrentDirectoryA( "\\some_dummy_dir" ), "SetCurrentDirectoryA succeeded\n" );
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %d\n", GetLastError() );
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "wrong error %ld\n", GetLastError() );
ok( !SetCurrentDirectoryA( "\\some_dummy\\subdir" ), "SetCurrentDirectoryA succeeded\n" );
ok( GetLastError() == ERROR_PATH_NOT_FOUND, "wrong error %d\n", GetLastError() );
ok( GetLastError() == ERROR_PATH_NOT_FOUND, "wrong error %ld\n", GetLastError() );
}
static void test_CreateDirectory_root(void)
{
static const WCHAR drive_c_root[] = { 'C',':','\\',0 };
static const WCHAR drive_c[] = { 'C',':',0 };
char curdir[MAX_PATH];
BOOL ret;
GetCurrentDirectoryA(sizeof(curdir), curdir);
ret = SetCurrentDirectoryA("C:\\");
ok(ret, "SetCurrentDirectory error %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = CreateDirectoryA("C:\\", NULL);
ok(!ret, "CreateDirectory should fail\n");
if (GetLastError() == ERROR_ACCESS_DENIED)
{
win_skip("not an administrator\n");
SetCurrentDirectoryA(curdir);
return;
}
ok(GetLastError() == ERROR_ALREADY_EXISTS, "got %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = CreateDirectoryA("C:", NULL);
ok(!ret, "CreateDirectory should fail\n");
ok(GetLastError() == ERROR_ALREADY_EXISTS, "got %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = CreateDirectoryW(drive_c_root, NULL);
ok(!ret, "CreateDirectory should fail\n");
ok(GetLastError() == ERROR_ALREADY_EXISTS, "got %lu\n", GetLastError());
SetLastError(0xdeadbeef);
ret = CreateDirectoryW(drive_c, NULL);
ok(!ret, "CreateDirectory should fail\n");
ok(GetLastError() == ERROR_ALREADY_EXISTS, "got %lu\n", GetLastError());
SetCurrentDirectoryA(curdir);
}
START_TEST(directory)
{
init();
test_CreateDirectory_root();
test_GetWindowsDirectoryA();
test_GetWindowsDirectoryW();
+45 -18
View File
@@ -35,7 +35,7 @@ static void test_GetDriveTypeA(void)
UINT type;
logical_drives = GetLogicalDrives();
ok(logical_drives != 0, "GetLogicalDrives error %d\n", GetLastError());
ok(logical_drives != 0, "GetLogicalDrives error %ld\n", GetLastError());
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
{
@@ -88,7 +88,7 @@ static void test_GetDriveTypeW(void)
UINT type;
logical_drives = GetLogicalDrives();
ok(logical_drives != 0, "GetLogicalDrives error %d\n", GetLastError());
ok(logical_drives != 0, "GetLogicalDrives error %ld\n", GetLastError());
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
{
@@ -138,25 +138,41 @@ static void test_GetDiskFreeSpaceA(void)
{
BOOL ret;
DWORD sectors_per_cluster, bytes_per_sector, free_clusters, total_clusters;
char volume_guid_path[50];
char drive[] = "?:\\";
DWORD logical_drives;
ret = GetDiskFreeSpaceA(NULL, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceA error %d\n", GetLastError());
ok(ret, "GetDiskFreeSpaceA error %ld\n", GetLastError());
ret = GetDiskFreeSpaceA("", &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_INVALID_NAME),
"GetDiskFreeSpaceA(\"\"): ret=%d GetLastError=%d\n",
"GetDiskFreeSpaceA(\"\"): ret=%d GetLastError=%ld\n",
ret, GetLastError());
ret = GetDiskFreeSpaceA("\\", &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceA error %d\n", GetLastError());
ok(ret, "GetDiskFreeSpaceA error %ld\n", GetLastError());
ret = GetDiskFreeSpaceA("/", &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceA error %d\n", GetLastError());
ok(ret, "GetDiskFreeSpaceA error %ld\n", GetLastError());
ret = GetDiskFreeSpaceA("C:\\", &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceA error %ld\n", GetLastError());
#ifdef __REACTOS__
if (GetNTVersion() >= _WIN32_WINNT_VISTA) {
#endif
ret = GetVolumeNameForVolumeMountPointA("C:\\", volume_guid_path, ARRAY_SIZE(volume_guid_path));
ok(ret, "GetVolumeNameForVolumeMountPointA error %ld\n", GetLastError());
ret = GetDiskFreeSpaceA(volume_guid_path, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceA error %ld\n", GetLastError());
#ifdef __REACTOS__
}
#endif
logical_drives = GetLogicalDrives();
ok(logical_drives != 0, "GetLogicalDrives error %d\n", GetLastError());
ok(logical_drives != 0, "GetLogicalDrives error %ld\n", GetLastError());
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
{
@@ -169,7 +185,7 @@ static void test_GetDiskFreeSpaceA(void)
ret = GetDiskFreeSpaceA(drive, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
if (!(logical_drives & 1))
ok(!ret && (GetLastError() == ERROR_PATH_NOT_FOUND || GetLastError() == ERROR_INVALID_DRIVE),
"GetDiskFreeSpaceA(%s): ret=%d GetLastError=%d\n",
"GetDiskFreeSpaceA(%s): ret=%d GetLastError=%ld\n",
drive, ret, GetLastError());
else
{
@@ -177,12 +193,12 @@ static void test_GetDiskFreeSpaceA(void)
if (!ret)
/* GetDiskFreeSpaceA() should succeed, but it can fail with too many
different GetLastError() results to be usable for an ok() */
trace("GetDiskFreeSpaceA(%s) failed with %d\n", drive, GetLastError());
trace("GetDiskFreeSpaceA(%s) failed with %ld\n", drive, GetLastError());
if( GetVersion() & 0x80000000)
/* win3.0 through winME */
ok( total_clusters <= 65535,
"total clusters is %d > 65535\n", total_clusters);
"total clusters is %ld > 65535\n", total_clusters);
else if (pGetDiskFreeSpaceExA) {
/* NT, 2k, XP : GetDiskFreeSpace should be accurate */
ULARGE_INTEGER totEx, tot, d;
@@ -194,7 +210,7 @@ static void test_GetDiskFreeSpaceA(void)
if (!ret)
/* GetDiskFreeSpaceExA() should succeed, but it can fail with too many
different GetLastError() results to be usable for an ok() */
trace("GetDiskFreeSpaceExA(%s) failed with %d\n", drive, GetLastError());
trace("GetDiskFreeSpaceExA(%s) failed with %ld\n", drive, GetLastError());
ok( bytes_per_sector == 0 || /* empty cd rom drive */
totEx.QuadPart <= tot.QuadPart,
@@ -210,11 +226,13 @@ static void test_GetDiskFreeSpaceW(void)
{
BOOL ret;
DWORD sectors_per_cluster, bytes_per_sector, free_clusters, total_clusters;
WCHAR volume_guid_path[50];
WCHAR drive[] = {'?',':','\\',0};
DWORD logical_drives;
static const WCHAR empty_pathW[] = { 0 };
static const WCHAR root_pathW[] = { '\\', 0 };
static const WCHAR unix_style_root_pathW[] = { '/', 0 };
static const WCHAR c_drive_pathW[] = { 'C', ':', '\\', 0 };
ret = GetDiskFreeSpaceW(NULL, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
if (ret == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
@@ -222,21 +240,30 @@ static void test_GetDiskFreeSpaceW(void)
win_skip("GetDiskFreeSpaceW is not available\n");
return;
}
ok(ret, "GetDiskFreeSpaceW error %d\n", GetLastError());
ok(ret, "GetDiskFreeSpaceW error %ld\n", GetLastError());
ret = GetDiskFreeSpaceW(empty_pathW, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
"GetDiskFreeSpaceW(\"\"): ret=%d GetLastError=%d\n",
"GetDiskFreeSpaceW(\"\"): ret=%d GetLastError=%ld\n",
ret, GetLastError());
ret = GetDiskFreeSpaceW(root_pathW, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceW(\"\") error %d\n", GetLastError());
ok(ret, "GetDiskFreeSpaceW(\"\") error %ld\n", GetLastError());
ret = GetDiskFreeSpaceW(unix_style_root_pathW, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceW error %d\n", GetLastError());
ok(ret, "GetDiskFreeSpaceW error %ld\n", GetLastError());
ret = GetDiskFreeSpaceW(c_drive_pathW, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceW error %ld\n", GetLastError());
ret = GetVolumeNameForVolumeMountPointW(c_drive_pathW, volume_guid_path, ARRAY_SIZE(volume_guid_path));
ok(ret, "GetVolumeNameForVolumeMountPointW error %ld\n", GetLastError());
ret = GetDiskFreeSpaceW(volume_guid_path, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
ok(ret, "GetDiskFreeSpaceW error %ld\n", GetLastError());
logical_drives = GetLogicalDrives();
ok(logical_drives != 0, "GetLogicalDrives error %d\n", GetLastError());
ok(logical_drives != 0, "GetLogicalDrives error %ld\n", GetLastError());
for (drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++)
{
@@ -247,12 +274,12 @@ static void test_GetDiskFreeSpaceW(void)
ret = GetDiskFreeSpaceW(drive, &sectors_per_cluster, &bytes_per_sector, &free_clusters, &total_clusters);
if (!(logical_drives & 1))
ok(!ret && GetLastError() == ERROR_PATH_NOT_FOUND,
"GetDiskFreeSpaceW(%c): ret=%d GetLastError=%d\n",
"GetDiskFreeSpaceW(%c): ret=%d GetLastError=%ld\n",
drive[0], ret, GetLastError());
else if (!ret)
/* GetDiskFreeSpaceW() should succeed, but it can fail with too many
different GetLastError() results to be usable for an ok() */
trace("GetDiskFreeSpaceW(%c) failed with %d\n", drive[0], GetLastError());
trace("GetDiskFreeSpaceW(%c) failed with %ld\n", drive[0], GetLastError());
}
logical_drives >>= 1;
}
@@ -0,0 +1,42 @@
/*
* Copyright 2019 Fabian Maurer
*
* 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
*/
#if 0
#pragma makedep testdll
#endif
#include <windows.h>
static HINSTANCE instance;
BOOL WINAPI DllMain(HINSTANCE instance_new, DWORD reason, LPVOID reserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
instance = instance_new;
break;
}
return TRUE;
}
void WINAPI get_path(char *buffer, int buffer_size)
{
GetModuleFileNameA(instance, buffer, buffer_size);
}
@@ -0,0 +1 @@
@ stdcall get_path(ptr long)
+510 -81
View File
@@ -34,18 +34,17 @@ static CHAR string[MAX_PATH];
static BOOL (WINAPI *pGetComputerNameExA)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD);
static BOOL (WINAPI *pGetComputerNameExW)(COMPUTER_NAME_FORMAT,LPWSTR,LPDWORD);
static BOOL (WINAPI *pOpenProcessToken)(HANDLE,DWORD,PHANDLE);
static BOOL (WINAPI *pGetUserProfileDirectoryA)(HANDLE,LPSTR,LPDWORD);
static BOOL (WINAPI *pSetEnvironmentStringsW)(WCHAR *);
static void init_functionpointers(void)
{
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
HMODULE hadvapi32 = GetModuleHandleA("advapi32.dll");
HMODULE huserenv = LoadLibraryA("userenv.dll");
pGetComputerNameExA = (void *)GetProcAddress(hkernel32, "GetComputerNameExA");
pGetComputerNameExW = (void *)GetProcAddress(hkernel32, "GetComputerNameExW");
pOpenProcessToken = (void *)GetProcAddress(hadvapi32, "OpenProcessToken");
pSetEnvironmentStringsW = (void *)GetProcAddress(hkernel32, "SetEnvironmentStringsW");
pGetUserProfileDirectoryA = (void *)GetProcAddress(huserenv,
"GetUserProfileDirectoryA");
}
@@ -63,21 +62,21 @@ static void test_Predefined(void)
* Check value of %USERPROFILE%, should be same as GetUserProfileDirectory()
* If this fails, your test environment is probably not set up
*/
if (pOpenProcessToken == NULL || pGetUserProfileDirectoryA == NULL)
if (pGetUserProfileDirectoryA == NULL)
{
skip("Skipping USERPROFILE check\n");
return;
}
NoErr = pOpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
ok(NoErr, "Failed to open token, error %u\n", GetLastError());
NoErr = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &Token);
ok(NoErr, "Failed to open token, error %lu\n", GetLastError());
DataSize = sizeof(Data);
NoErr = pGetUserProfileDirectoryA(Token, Data, &DataSize);
ok(NoErr, "Failed to get user profile dir, error %u\n", GetLastError());
ok(NoErr, "Failed to get user profile dir, error %lu\n", GetLastError());
if (NoErr)
{
EnvSize = GetEnvironmentVariableA("USERPROFILE", Env, sizeof(Env));
ok(EnvSize != 0 && EnvSize <= sizeof(Env),
"Failed to retrieve environment variable USERPROFILE, error %u\n",
"Failed to retrieve environment variable USERPROFILE, error %lu\n",
GetLastError());
ok(strcmp(Data, Env) == 0,
"USERPROFILE env var %s doesn't match GetUserProfileDirectory %s\n",
@@ -86,7 +85,7 @@ static void test_Predefined(void)
else
skip("Skipping USERPROFILE check, can't get user profile dir\n");
NoErr = CloseHandle(Token);
ok(NoErr, "Failed to close token, error %u\n", GetLastError());
ok(NoErr, "Failed to close token, error %lu\n", GetLastError());
}
static void test_GetSetEnvironmentVariableA(void)
@@ -100,82 +99,99 @@ static void test_GetSetEnvironmentVariableA(void)
ret = SetEnvironmentVariableA(name, value);
ok(ret == TRUE,
"unexpected error in SetEnvironmentVariableA, GetLastError=%d\n",
"unexpected error in SetEnvironmentVariableA, GetLastError=%ld\n",
GetLastError());
/* Try to retrieve the environment variable we just set */
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, NULL, 0);
ok(ret_size == strlen(value) + 1,
"should return length with terminating 0 ret_size=%d\n", ret_size);
"should return length with terminating 0 ret_size=%ld\n", ret_size);
ok(GetLastError() == 0xdeadbeef,
"should not fail with zero size but GetLastError=%ld\n", GetLastError());
lstrcpyA(buf, "foo");
ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value));
ok(lstrcmpA(buf, "foo") == 0, "should not touch the buffer\n");
ok(ret_size == strlen(value) + 1,
"should return length with terminating 0 ret_size=%d\n", ret_size);
"should return length with terminating 0 ret_size=%ld\n", ret_size);
lstrcpyA(buf, "foo");
ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
ok(lstrcmpA(buf, value) == 0, "should touch the buffer\n");
ok(ret_size == strlen(value),
"should return length without terminating 0 ret_size=%d\n", ret_size);
"should return length without terminating 0 ret_size=%ld\n", ret_size);
lstrcpyA(buf, "foo");
ret_size = GetEnvironmentVariableA(name_cased, buf, lstrlenA(value) + 1);
ok(lstrcmpA(buf, value) == 0, "should touch the buffer\n");
ok(ret_size == strlen(value),
"should return length without terminating 0 ret_size=%d\n", ret_size);
"should return length without terminating 0 ret_size=%ld\n", ret_size);
/* Remove that environment variable */
ret = SetEnvironmentVariableA(name_cased, NULL);
ok(ret == TRUE, "should erase existing variable\n");
lstrcpyA(buf, "foo");
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
ok(lstrcmpA(buf, "foo") == 0, "should not touch the buffer\n");
ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
"should not find variable but ret_size=%d GetLastError=%d\n",
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
/* Check behavior of SetEnvironmentVariableA(name, "") */
ret = SetEnvironmentVariableA(name, value);
ok(ret == TRUE,
"unexpected error in SetEnvironmentVariableA, GetLastError=%d\n",
"unexpected error in SetEnvironmentVariableA, GetLastError=%ld\n",
GetLastError());
lstrcpyA(buf, "foo");
ret_size = GetEnvironmentVariableA(name_cased, buf, lstrlenA(value) + 1);
ok(lstrcmpA(buf, value) == 0, "should touch the buffer\n");
ok(ret_size == strlen(value),
"should return length without terminating 0 ret_size=%d\n", ret_size);
"should return length without terminating 0 ret_size=%ld\n", ret_size);
ret = SetEnvironmentVariableA(name_cased, "");
ok(ret == TRUE,
"should not fail with empty value but GetLastError=%d\n", GetLastError());
"should not fail with empty value but GetLastError=%ld\n", GetLastError());
lstrcpyA(buf, "foo");
SetLastError(0);
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
ok(ret_size == 0 &&
((GetLastError() == 0 && lstrcmpA(buf, "") == 0) ||
((GetLastError() == 0xdeadbeef && lstrcmpA(buf, "") == 0) ||
(GetLastError() == ERROR_ENVVAR_NOT_FOUND)),
"%s should be set to \"\" (NT) or removed (Win9x) but ret_size=%d GetLastError=%d and buf=%s\n",
"%s should be set to \"\" (NT) or removed (Win9x) but ret_size=%ld GetLastError=%ld and buf=%s\n",
name, ret_size, GetLastError(), buf);
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, NULL, 0);
ok(ret_size == 1 ||
broken(ret_size == 0), /* XP */
"should return 1 for empty string but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
ok(GetLastError() == 0xdeadbeef ||
broken(GetLastError() == ERROR_MORE_DATA), /* XP */
"should not fail with zero size but GetLastError=%ld\n", GetLastError());
/* Test the limits */
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(NULL, NULL, 0);
ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
"should not find variable but ret_size=%d GetLastError=%d\n",
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(NULL, buf, lstrlenA(value) + 1);
ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
"should not find variable but ret_size=%d GetLastError=%d\n",
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA("", buf, lstrlenA(value) + 1);
ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
"should not find variable but ret_size=%d GetLastError=%d\n",
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
}
@@ -198,14 +214,17 @@ static void test_GetSetEnvironmentVariableW(void)
return;
}
ok(ret == TRUE,
"unexpected error in SetEnvironmentVariableW, GetLastError=%d\n",
"unexpected error in SetEnvironmentVariableW, GetLastError=%ld\n",
GetLastError());
/* Try to retrieve the environment variable we just set */
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(name, NULL, 0);
ok(ret_size == lstrlenW(value) + 1,
"should return length with terminating 0 ret_size=%d\n",
"should return length with terminating 0 ret_size=%ld\n",
ret_size);
ok(GetLastError() == 0xdeadbeef,
"should not fail with zero size but GetLastError=%ld\n", GetLastError());
lstrcpyW(buf, fooW);
ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value));
@@ -214,85 +233,322 @@ static void test_GetSetEnvironmentVariableW(void)
"Expected untouched or empty buffer, got \"%s\"\n", buf);
ok(ret_size == lstrlenW(value) + 1,
"should return length with terminating 0 ret_size=%d\n", ret_size);
"should return length with terminating 0 ret_size=%ld\n", ret_size);
lstrcpyW(buf, fooW);
ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
ok(lstrcmpW(buf, value) == 0, "should touch the buffer\n");
ok(ret_size == lstrlenW(value),
"should return length without terminating 0 ret_size=%d\n", ret_size);
"should return length without terminating 0 ret_size=%ld\n", ret_size);
lstrcpyW(buf, fooW);
ret_size = GetEnvironmentVariableW(name_cased, buf, lstrlenW(value) + 1);
ok(lstrcmpW(buf, value) == 0, "should touch the buffer\n");
ok(ret_size == lstrlenW(value),
"should return length without terminating 0 ret_size=%d\n", ret_size);
"should return length without terminating 0 ret_size=%ld\n", ret_size);
/* Remove that environment variable */
ret = SetEnvironmentVariableW(name_cased, NULL);
ok(ret == TRUE, "should erase existing variable\n");
lstrcpyW(buf, fooW);
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
ok(lstrcmpW(buf, fooW) == 0, "should not touch the buffer\n");
ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
"should not find variable but ret_size=%d GetLastError=%d\n",
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
/* Check behavior of SetEnvironmentVariableW(name, "") */
ret = SetEnvironmentVariableW(name, value);
ok(ret == TRUE,
"unexpected error in SetEnvironmentVariableW, GetLastError=%d\n",
"unexpected error in SetEnvironmentVariableW, GetLastError=%ld\n",
GetLastError());
lstrcpyW(buf, fooW);
ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
ok(lstrcmpW(buf, value) == 0, "should touch the buffer\n");
ok(ret_size == lstrlenW(value),
"should return length without terminating 0 ret_size=%d\n", ret_size);
"should return length without terminating 0 ret_size=%ld\n", ret_size);
ret = SetEnvironmentVariableW(name_cased, empty_strW);
ok(ret == TRUE, "should not fail with empty value but GetLastError=%d\n", GetLastError());
ok(ret == TRUE, "should not fail with empty value but GetLastError=%ld\n", GetLastError());
lstrcpyW(buf, fooW);
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(name, buf, lstrlenW(value) + 1);
ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
"should not find variable but ret_size=%d GetLastError=%d\n",
ok(ret_size == 0 &&
((GetLastError() == 0xdeadbeef && lstrcmpW(buf, empty_strW) == 0) ||
(GetLastError() == ERROR_ENVVAR_NOT_FOUND)),
"should be set to \"\" (NT) or removed (Win9x) but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
ok(lstrcmpW(buf, empty_strW) == 0, "should copy an empty string\n");
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(name, NULL, 0);
ok(ret_size == 1 ||
broken(ret_size == 0), /* XP */
"should return 1 for empty string but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
ok(GetLastError() == 0xdeadbeef ||
broken(GetLastError() == ERROR_MORE_DATA), /* XP */
"should not fail with zero size but GetLastError=%ld\n", GetLastError());
/* Test the limits */
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(NULL, NULL, 0);
ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
"should not find variable but ret_size=%d GetLastError=%d\n",
ok(ret_size == 0 && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
if (0) /* Both tests crash on Vista */
{
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(NULL, buf, lstrlenW(value) + 1);
ok(ret_size == 0 && GetLastError() == ERROR_ENVVAR_NOT_FOUND,
"should not find variable but ret_size=%d GetLastError=%d\n",
"should not find variable but ret_size=%ld GetLastError=%ld\n",
ret_size, GetLastError());
SetLastError(0xdeadbeef);
ret = SetEnvironmentVariableW(NULL, NULL);
ok(ret == FALSE && (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ENVVAR_NOT_FOUND),
"should fail with NULL, NULL but ret=%d and GetLastError=%d\n",
"should fail with NULL, NULL but ret=%d and GetLastError=%ld\n",
ret, GetLastError());
}
}
static void test_GetSetEnvironmentVariableAW(void)
{
static const WCHAR nameW[] = {0x540D, 0x524D, 0};
static const char name[] = "\x96\xBC\x91\x4F";
static const WCHAR valueW[] = {0x5024, 0};
static const char value[] = "\x92\x6C";
WCHAR bufW[256];
char buf[256];
DWORD ret_size;
BOOL ret;
if (GetACP() != 932)
{
skip("GetACP() == %d, need 932 for A/W tests\n", GetACP());
return;
}
/* Write W, read A */
ret = SetEnvironmentVariableW(nameW, valueW);
ok(ret == TRUE, "SetEnvironmentVariableW failed, last error %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, NULL, 0);
todo_wine ok(ret_size == lstrlenA(value) + 1, "expected ret_size %d, got %ld\n", lstrlenA(value) + 1, ret_size);
ok(GetLastError() == 0xdeadbeef, "expected last error 0xdeadbeef, got %ld\n", GetLastError());
lstrcpyA(buf, "foo");
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
todo_wine ok(lstrcmpA(buf, value) == 0, "expected %s, got %s\n", debugstr_a(value), debugstr_a(buf));
todo_wine ok(ret_size == lstrlenA(value), "expected ret_size %d, got %ld\n", lstrlenA(value), ret_size);
ok(GetLastError() == 0xdeadbeef, "expected last error 0xdeadbeef, got %ld\n", GetLastError());
/* Write A, read A/W */
ret = SetEnvironmentVariableA(name, value);
ok(ret == TRUE, "SetEnvironmentVariableW failed, last error %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, NULL, 0);
todo_wine ok(ret_size == lstrlenA(value) + 1, "expected ret_size %d, got %ld\n", lstrlenA(value) + 1, ret_size);
ok(GetLastError() == 0xdeadbeef, "expected last error 0xdeadbeef, got %ld\n", GetLastError());
lstrcpyA(buf, "foo");
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableA(name, buf, lstrlenA(value) + 1);
todo_wine ok(lstrcmpA(buf, value) == 0, "expected %s, got %s\n", debugstr_a(value), debugstr_a(buf));
todo_wine ok(ret_size == lstrlenA(value), "expected ret_size %d, got %ld\n", lstrlenA(value), ret_size);
ok(GetLastError() == 0xdeadbeef, "expected last error 0xdeadbeef, got %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(nameW, NULL, 0);
ok(ret_size == lstrlenW(valueW) + 1, "expected ret_size %d, got %ld\n", lstrlenW(valueW) + 1, ret_size);
ok(GetLastError() == 0xdeadbeef, "expected last error 0xdeadbeef, got %ld\n", GetLastError());
lstrcpyW(bufW, L"foo");
SetLastError(0xdeadbeef);
ret_size = GetEnvironmentVariableW(nameW, bufW, lstrlenW(valueW) + 1);
ok(ret_size == lstrlenW(valueW), "expected ret_size %d, got %ld\n", lstrlenW(valueW), ret_size);
ok(GetLastError() == 0xdeadbeef, "expected last error 0xdeadbeef, got %ld\n", GetLastError());
ok(lstrcmpW(bufW, valueW) == 0, "expected %s, got %s\n", debugstr_w(valueW), debugstr_w(bufW));
}
static void test_ExpandEnvironmentStringsW(void)
{
int i;
WCHAR buf[256];
DWORD ret;
BOOL success;
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 },
#ifndef __REACTOS__
/* 8 */ { L"%TVAR% long long", L"", 1, 15 },
/* 9 */ { L"%TVAR% long long", L"", 2, 15 },
/* 10 */ { L"%TVAR% long long", L"", 4, 15 },
#endif
/* 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 },
#ifndef __REACTOS__
/* 16 */ { L"%TVAR%%TVAR% long", L"", 4, 14 },
#endif
/* 17 */ { L"%TVAR%%TVAR% long", L"WINE", 5, 14 },
/* 18 */ { L"%TVAR%%TVAR% long", L"WINE", 6, 14 },
#ifndef __REACTOS__
/* 19 */ { L"%TVAR%%TVAR% long", L"WINE", 8, 14 },
#endif
/* 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 },
#ifndef __REACTOS__
/* 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 },
#endif
/* 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 },
};
success = SetEnvironmentVariableW(L"TVAR", L"WINE");
ok(success, "SetEnvironmentVariableW failed with %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret = ExpandEnvironmentStringsW(L"Long long value", NULL, 0);
ok(ret == 16, "got %lu\n", ret);
ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
const struct test_info *test = &tests[i];
SetLastError(0xdeadbeef);
wcscpy(buf, L"abcdefghijklmnopqrstuv");
ret = ExpandEnvironmentStringsW(test->input, buf, test->count_in);
ok(ret == test->expected_count_out, "Test %d: got %lu\n", i, ret);
ok(GetLastError() == 0xdeadbeef, "Test %d: got last error %ld\n", i, GetLastError());
ok(!wcscmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_w(buf));
}
success = SetEnvironmentVariableW(L"TVAR", NULL);
ok(success, "SetEnvironmentVariableW failed with %ld\n", GetLastError());
}
static void test_ExpandEnvironmentStringsA(void)
{
const char* value="Long long value";
const char* not_an_env_var="%NotAnEnvVar%";
char buf[256], buf1[256], buf2[0x8000];
DWORD ret_size, ret_size1;
int i;
DWORD ret;
BOOL success;
static const struct test_info
{
const char *input;
const char *expected_str;
int count_in;
int expected_count_out;
} tests[] =
{
/* 0 */ { "Long long value", "", 0, 17 },
/* 1 */ { "Long long value", "", 1, 17 },
/* 2 */ { "Long long value", "", 2, 17 },
/* 3 */ { "Long long value", "", 3, 17 },
/* 4 */ { "Long long value", "", 15, 17 },
/* 5 */ { "Long long value", "", 16, 17 },
/* 6 */ { "Long long value", "Long long value", 17, 16 },
/* 7 */ { "%TVAR% long long", "", 0, 16 },
/* 8 */ { "%TVAR% long long", "", 1, 16 },
/* 9 */ { "%TVAR% long long", "", 2, 16 },
/* 10 */ { "%TVAR% long long", "", 4, 16 },
/* 11 */ { "%TVAR% long long", "", 5, 16 },
/* 12 */ { "%TVAR% long long", "", 6, 16 },
/* 13 */ { "%TVAR% long long", "", 7, 16 },
/* 14 */ { "%TVAR% long long", "", 15, 16 },
/* 15 */ { "%TVAR% long long", "WINE long long", 16, 15 },
/* 16 */ { "%TVAR%%TVAR% long", "", 4, 15 },
/* 17 */ { "%TVAR%%TVAR% long", "", 5, 15 },
/* 18 */ { "%TVAR%%TVAR% long", "", 6, 15 },
/* 19 */ { "%TVAR%%TVAR% long", "", 8, 15 },
/* 20 */ { "%TVAR%%TVAR% long", "", 9, 15 },
/* 21 */ { "%TVAR%%TVAR% long", "", 10, 15 },
/* 22 */ { "%TVAR%%TVAR% long", "", 14, 15 },
/* 23 */ { "%TVAR%%TVAR% long", "WINEWINE long", 15, 14 },
/* 24 */ { "%TVAR% %TVAR% long", "", 5, 16 },
/* 25 */ { "%TVAR% %TVAR% long", "", 6, 16 },
/* 26 */ { "%TVAR% %TVAR% long", "", 8, 16 },
/* 27 */ { "%TVAR% %TVAR% long", "", 9, 16 },
/* 28 */ { "%TVAR% %TVAR% long", "", 10, 16 },
/* 29 */ { "%TVAR% %TVAR% long", "", 11, 16 },
/* 30 */ { "%TVAR% %TVAR% long", "", 12, 16 },
/* 31 */ { "%TVAR% %TVAR% long", "", 14, 16 },
/* 32 */ { "%TVAR% %TVAR% long", "", 15, 16 },
/* 33 */ { "%TVAR% %TVAR% long", "WINE WINE long", 16, 15 },
/* 34 */ { "%TVAR2% long long", "", 1, 19 },
/* 35 */ { "%TVAR2% long long", "", 2, 19 },
/* 36 */ { "%TVAR2% long long", "", 4, 19 },
/* 37 */ { "%TVAR2% long long", "", 7, 19 },
/* 38 */ { "%TVAR2% long long", "", 8, 19 },
/* 39 */ { "%TVAR2% long long", "", 9, 19 },
/* 40 */ { "%TVAR2% long long", "", 10, 19 },
/* 41 */ { "%TVAR2% long long", "", 18, 19 },
/* 42 */ { "%TVAR2% long long", "%TVAR2% long long", 19, 18 },
/* 43 */ { "%TVAR long long", "", 1, 17 },
/* 44 */ { "%TVAR long long", "", 2, 17 },
/* 45 */ { "%TVAR long long", "", 3, 17 },
/* 46 */ { "%TVAR long long", "", 15, 17 },
/* 47 */ { "%TVAR long long", "", 16, 17 },
/* 48 */ { "%TVAR long long", "%TVAR long long", 17, 16 },
};
SetEnvironmentVariableA("EnvVar", value);
ret_size = ExpandEnvironmentStringsA(NULL, buf1, sizeof(buf1));
ok(ret_size == 1 || ret_size == 0 /* Win9x */ || ret_size == 2 /* NT4 */,
"ExpandEnvironmentStrings returned %d\n", ret_size);
"ExpandEnvironmentStrings returned %ld\n", ret_size);
/* Try to get the required buffer size 'the natural way' */
strcpy(buf, "%EnvVar%");
@@ -301,7 +557,7 @@ static void test_ExpandEnvironmentStringsA(void)
ret_size == (strlen(value)+1)*2 || /* NT4 */
ret_size == strlen(value)+2 || /* win2k, XP, win2k3 */
ret_size == 0 /* Win95 */,
"ExpandEnvironmentStrings returned %d instead of %d, %d or %d\n",
"ExpandEnvironmentStrings returned %ld instead of %d, %d or %d\n",
ret_size, lstrlenA(value)+1, lstrlenA(value)+2, 0);
/* Again, side-stepping the Win95 bug */
@@ -309,7 +565,7 @@ static void test_ExpandEnvironmentStringsA(void)
/* v5.1.2600.2945 (XP SP2) returns len + 2 here! */
ok(ret_size == strlen(value)+1 || ret_size == strlen(value)+2 ||
ret_size == (strlen(value)+1)*2 /* NT4 */,
"ExpandEnvironmentStrings returned %d instead of %d\n",
"ExpandEnvironmentStrings returned %ld instead of %d\n",
ret_size, lstrlenA(value)+1);
/* Try with a buffer that's too small */
@@ -317,7 +573,7 @@ static void test_ExpandEnvironmentStringsA(void)
/* v5.1.2600.2945 (XP SP2) returns len + 2 here! */
ok(ret_size == strlen(value)+1 || ret_size == strlen(value)+2 ||
ret_size == (strlen(value)+1)*2 /* NT4 */,
"ExpandEnvironmentStrings returned %d instead of %d\n",
"ExpandEnvironmentStrings returned %ld instead of %d\n",
ret_size, lstrlenA(value)+1);
/* Try with a buffer of just the right size */
@@ -325,7 +581,7 @@ static void test_ExpandEnvironmentStringsA(void)
ret_size = ExpandEnvironmentStringsA(buf, buf1, ret_size);
ok(ret_size == strlen(value)+1 || ret_size == strlen(value)+2 ||
ret_size == (strlen(value)+1)*2 /* NT4 */,
"ExpandEnvironmentStrings returned %d instead of %d\n",
"ExpandEnvironmentStrings returned %ld instead of %d\n",
ret_size, lstrlenA(value)+1);
ok(!strcmp(buf1, value), "ExpandEnvironmentStrings returned [%s]\n", buf1);
@@ -334,20 +590,21 @@ static void test_ExpandEnvironmentStringsA(void)
ret_size = ExpandEnvironmentStringsA(buf, buf1, sizeof(buf1));
ok(ret_size == strlen(not_an_env_var)+1 ||
ret_size == (strlen(not_an_env_var)+1)*2 /* NT4 */,
"ExpandEnvironmentStrings returned %d instead of %d\n", ret_size, lstrlenA(not_an_env_var)+1);
"ExpandEnvironmentStrings returned %ld instead of %d\n", ret_size, lstrlenA(not_an_env_var)+1);
ok(!strcmp(buf1, not_an_env_var), "ExpandEnvironmentStrings returned [%s]\n", buf1);
/* test a large destination size */
strcpy(buf, "12345");
ret_size = ExpandEnvironmentStringsA(buf, buf2, sizeof(buf2));
ok(!strcmp(buf, buf2), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %d\n", buf, buf2, ret_size);
ok(!strcmp(buf, buf2), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %ld\n", buf, buf2, ret_size);
SetLastError(0xdeadbeef);
ret_size1 = GetWindowsDirectoryA(buf1,256);
ok ((ret_size1 >0) && (ret_size1<256), "GetWindowsDirectory Failed\n");
ret_size = ExpandEnvironmentStringsA("%SystemRoot%",buf,sizeof(buf));
if (ERROR_ENVVAR_NOT_FOUND != GetLastError())
{
ok(!strcmp(buf, buf1), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %d\n", buf, buf1, ret_size);
ok(!strcmp(buf, buf1), "ExpandEnvironmentStrings failed %s vs %s. ret_size = %ld\n", buf, buf1, ret_size);
}
/* Try with a variable that references another */
@@ -357,11 +614,60 @@ static void test_ExpandEnvironmentStringsA(void)
ret_size = ExpandEnvironmentStringsA(buf, buf1, sizeof(buf1));
ok(ret_size == strlen(buf2)+1 ||
ret_size == (strlen(buf2)+1)*2 /* NT4 */,
"ExpandEnvironmentStrings returned %d instead of %d\n", ret_size, lstrlenA(buf2)+1);
"ExpandEnvironmentStrings returned %ld instead of %d\n", ret_size, lstrlenA(buf2)+1);
ok(!strcmp(buf1, buf2), "ExpandEnvironmentStrings returned [%s]\n", buf1);
SetEnvironmentVariableA("IndirectVar", NULL);
SetEnvironmentVariableA("EnvVar", NULL);
success = SetEnvironmentVariableA("TVAR", "WINE");
ok(success, "SetEnvironmentVariableA failed with %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret = ExpandEnvironmentStringsW(L"Long long value", NULL, 0);
ok(ret == 16, "got %lu\n", ret);
ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
const struct test_info *test = &tests[i];
SetLastError(0xdeadbeef);
strcpy(buf, "abcdefghijklmnopqrstuv");
ret = ExpandEnvironmentStringsA(test->input, buf, test->count_in);
ok(ret == test->expected_count_out, "Test %d: got %lu\n", i, ret);
ok(GetLastError() == 0xdeadbeef, "Test %d: got last error %ld\n", i, GetLastError());
ok(!strcmp(buf, test->expected_str), "Test %d: got %s\n", i, debugstr_a(buf));
}
success = SetEnvironmentVariableA("TVAR", NULL);
ok(success, "SetEnvironmentVariableA failed with %ld\n", GetLastError());
if (GetACP() == 932) /* shift-jis */
{
const char *japanese_test = "\x88\xEA\x93\xF1\x8E\x4F\x8E\x6C\x8C\xDC\x98\x5A\x8E\xB5\x94\xAA\x8B\xE3"; /* Japanese Kanji for "one" to "nine", in shift-jis */
int japanese_len = strlen(japanese_test);
SetLastError(0xdeadbeef);
ret_size = ExpandEnvironmentStringsA(japanese_test, NULL, 0);
ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size);
SetLastError(0xdeadbeef);
ret_size = ExpandEnvironmentStringsA(japanese_test, buf, ret_size);
ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size);
ok(!strcmp(buf, japanese_test), "Got %s\n", debugstr_a(buf));
SetLastError(0xdeadbeef);
ret_size = ExpandEnvironmentStringsA(japanese_test, buf, japanese_len / 2); /* Buffer too small */
ok(GetLastError() == 0xdeadbeef, "got last error %ld\n", GetLastError());
ok(ret_size >= japanese_len, "Needed at least %d, got %lu\n", japanese_len, ret_size);
}
else
{
skip("Skipping japanese language tests\n");
}
}
static void test_GetComputerName(void)
@@ -374,29 +680,30 @@ static void test_GetComputerName(void)
int name_len;
size = 0;
SetLastError(0xdeadbeef);
ret = GetComputerNameA((LPSTR)0xdeadbeef, &size);
error = GetLastError();
ok(!ret && error == ERROR_BUFFER_OVERFLOW, "GetComputerNameA should have failed with ERROR_BUFFER_OVERFLOW instead of %d\n", error);
ok(!ret && error == ERROR_BUFFER_OVERFLOW, "GetComputerNameA should have failed with ERROR_BUFFER_OVERFLOW instead of %ld\n", error);
/* Only Vista returns the computer name length as documented in the MSDN */
if (size != 0)
{
size++; /* nul terminating character */
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(name != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = GetComputerNameA(name, &size);
ok(ret, "GetComputerNameA failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameA failed with error %ld\n", GetLastError());
HeapFree(GetProcessHeap(), 0, name);
}
size = MAX_COMPUTERNAME_LENGTH + 1;
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(name != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = GetComputerNameA(name, &size);
ok(ret, "GetComputerNameA failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameA failed with error %ld\n", GetLastError());
trace("computer name is \"%s\"\n", name);
name_len = strlen(name);
ok(size == name_len, "size should be same as length, name_len=%d, size=%d\n", name_len, size);
ok(size == name_len, "size should be same as length, name_len=%d, size=%ld\n", name_len, size);
HeapFree(GetProcessHeap(), 0, name);
size = 0;
@@ -407,12 +714,12 @@ static void test_GetComputerName(void)
win_skip("GetComputerNameW is not implemented\n");
else
{
ok(!ret && error == ERROR_BUFFER_OVERFLOW, "GetComputerNameW should have failed with ERROR_BUFFER_OVERFLOW instead of %d\n", error);
ok(!ret && error == ERROR_BUFFER_OVERFLOW, "GetComputerNameW should have failed with ERROR_BUFFER_OVERFLOW instead of %ld\n", error);
size++; /* nul terminating character */
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(nameW != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = GetComputerNameW(nameW, &size);
ok(ret, "GetComputerNameW failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameW failed with error %ld\n", GetLastError());
HeapFree(GetProcessHeap(), 0, nameW);
}
}
@@ -433,10 +740,11 @@ static void test_GetComputerNameExA(void)
}
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExA(ComputerNameDnsDomain, (LPSTR)0xdeadbeef, &size);
error = GetLastError();
ok(ret == 0, "Expected 0, got %d\n", ret);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", error);
/* size is not set in win2k */
if (size == 0)
@@ -445,57 +753,67 @@ static void test_GetComputerNameExA(void)
size = MAX_COMP_NAME;
}
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(name != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExA(ComputerNameDnsDomain, name, &size);
ok(ret, "GetComputerNameExA(ComputerNameDnsDomain) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExA(ComputerNameDnsDomain) failed with error %ld\n", GetLastError());
trace("domain name is \"%s\"\n", name);
HeapFree(GetProcessHeap(), 0, name);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, (LPSTR)0xdeadbeef, &size);
error = GetLastError();
ok(ret == 0, "Expected 0, got %d\n", ret);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", error);
/* size is not set in win2k */
if (size == 0)
size = MAX_COMP_NAME;
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(name != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExA(ComputerNameDnsFullyQualified, name, &size);
ok(ret, "GetComputerNameExA(ComputerNameDnsFullyQualified) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExA(ComputerNameDnsFullyQualified) failed with error %ld\n", GetLastError());
trace("fully qualified hostname is \"%s\"\n", name);
HeapFree(GetProcessHeap(), 0, name);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExA(ComputerNameDnsHostname, (LPSTR)0xdeadbeef, &size);
error = GetLastError();
ok(ret == 0, "Expected 0, got %d\n", ret);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", error);
/* size is not set in win2k */
if (size == 0)
size = MAX_COMP_NAME;
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(name != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExA(ComputerNameDnsHostname, name, &size);
ok(ret, "GetComputerNameExA(ComputerNameDnsHostname) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExA(ComputerNameDnsHostname) failed with error %ld\n", GetLastError());
trace("hostname is \"%s\"\n", name);
HeapFree(GetProcessHeap(), 0, name);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExA(ComputerNameNetBIOS, (LPSTR)0xdeadbeef, &size);
error = GetLastError();
ok(ret == 0, "Expected 0, got %d\n", ret);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", error);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", error);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExA(ComputerNameNetBIOS, NULL, &size);
error = GetLastError();
ok(ret == 0, "Expected 0, got %d\n", ret);
ok(error == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %ld\n", error);
/* size is not set in win2k */
if (size == 0)
size = MAX_COMP_NAME;
name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(name[0]));
ok(name != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(name != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExA(ComputerNameNetBIOS, name, &size);
ok(ret, "GetComputerNameExA(ComputerNameNetBIOS) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExA(ComputerNameNetBIOS) failed with error %ld\n", GetLastError());
trace("NetBIOS name is \"%s\"\n", name);
HeapFree(GetProcessHeap(), 0, name);
}
@@ -514,44 +832,151 @@ static void test_GetComputerNameExW(void)
}
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExW(ComputerNameDnsDomain, (LPWSTR)0xdeadbeef, &size);
error = GetLastError();
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %ld\n", error);
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(nameW != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExW(ComputerNameDnsDomain, nameW, &size);
ok(ret, "GetComputerNameExW(ComputerNameDnsDomain) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExW(ComputerNameDnsDomain) failed with error %ld\n", GetLastError());
HeapFree(GetProcessHeap(), 0, nameW);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExW(ComputerNameDnsFullyQualified, (LPWSTR)0xdeadbeef, &size);
error = GetLastError();
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %ld\n", error);
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(nameW != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExW(ComputerNameDnsFullyQualified, nameW, &size);
ok(ret, "GetComputerNameExW(ComputerNameDnsFullyQualified) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExW(ComputerNameDnsFullyQualified) failed with error %ld\n", GetLastError());
HeapFree(GetProcessHeap(), 0, nameW);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExW(ComputerNameDnsHostname, (LPWSTR)0xdeadbeef, &size);
error = GetLastError();
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %ld\n", error);
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(nameW != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExW(ComputerNameDnsHostname, nameW, &size);
ok(ret, "GetComputerNameExW(ComputerNameDnsHostname) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExW(ComputerNameDnsHostname) failed with error %ld\n", GetLastError());
HeapFree(GetProcessHeap(), 0, nameW);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExW(ComputerNameNetBIOS, (LPWSTR)0xdeadbeef, &size);
error = GetLastError();
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %d\n", error);
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %ld\n", error);
nameW = HeapAlloc(GetProcessHeap(), 0, size * sizeof(nameW[0]));
ok(nameW != NULL, "HeapAlloc failed with error %d\n", GetLastError());
ok(nameW != NULL, "HeapAlloc failed with error %ld\n", GetLastError());
ret = pGetComputerNameExW(ComputerNameNetBIOS, nameW, &size);
ok(ret, "GetComputerNameExW(ComputerNameNetBIOS) failed with error %d\n", GetLastError());
ok(ret, "GetComputerNameExW(ComputerNameNetBIOS) failed with error %ld\n", GetLastError());
HeapFree(GetProcessHeap(), 0, nameW);
size = 0;
SetLastError(0xdeadbeef);
ret = pGetComputerNameExW(ComputerNameNetBIOS, NULL, &size);
error = GetLastError();
ok(!ret && error == ERROR_MORE_DATA, "GetComputerNameExW should have failed with ERROR_MORE_DATA instead of %ld\n", error);
}
static void test_GetEnvironmentStringsW(void)
{
PWCHAR env1;
PWCHAR env2;
env1 = GetEnvironmentStringsW();
env2 = GetEnvironmentStringsW();
ok(env1 != env2 ||
broken(env1 == env2), /* NT <= 5.1 */
"should return different copies\n");
FreeEnvironmentStringsW(env1);
FreeEnvironmentStringsW(env2);
}
#define copy_string(dst, src) memcpy(dst, src, sizeof(src))
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_SetEnvironmentStrings(void)
{
static const WCHAR testenv[] = L"testenv1=unus\0testenv3=tres\0";
WCHAR env[200];
WCHAR *old_env;
BOOL ret;
if (!pSetEnvironmentStringsW)
{
win_skip("SetEnvironmentStringsW() is not available\n");
return;
}
ret = SetEnvironmentVariableA("testenv1", "heis");
ok(ret, "got error %lu\n", GetLastError());
ret = SetEnvironmentVariableA("testenv2", "dyo");
ok(ret, "got error %lu\n", GetLastError());
old_env = GetEnvironmentStringsW();
memcpy(env, testenv, sizeof(testenv));
ret = pSetEnvironmentStringsW(env);
ok(ret, "got error %lu\n", GetLastError());
ok(!memcmp(env, testenv, sizeof(testenv)), "input parameter should not be changed\n");
check_env_var("testenv1", "unus");
check_env_var("testenv2", NULL);
check_env_var("testenv3", "tres");
check_env_var("PATH", NULL);
ret = pSetEnvironmentStringsW(old_env);
ok(ret, "got error %lu\n", GetLastError());
check_env_var("testenv1", "heis");
check_env_var("testenv2", "dyo");
check_env_var("testenv3", NULL);
SetEnvironmentVariableA("testenv1", NULL);
SetEnvironmentVariableA("testenv2", NULL);
copy_string(env, L"testenv\0");
SetLastError(0xdeadbeef);
ret = pSetEnvironmentStringsW(env);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
copy_string(env, L"=unus\0");
SetLastError(0xdeadbeef);
ret = pSetEnvironmentStringsW(env);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %lu\n", GetLastError());
copy_string(env, L"one=two=three four=five\0");
ret = pSetEnvironmentStringsW(env);
ok(ret, "got error %lu\n", GetLastError());
check_env_var("one", "two=three four=five");
ret = pSetEnvironmentStringsW(old_env);
ok(ret, "got error %lu\n", GetLastError());
ret = FreeEnvironmentStringsW(old_env);
ok(ret, "got error %lu\n", GetLastError());
}
START_TEST(environ)
@@ -561,8 +986,12 @@ START_TEST(environ)
test_Predefined();
test_GetSetEnvironmentVariableA();
test_GetSetEnvironmentVariableW();
test_GetSetEnvironmentVariableAW();
test_ExpandEnvironmentStringsW();
test_ExpandEnvironmentStringsA();
test_GetComputerName();
test_GetComputerNameExA();
test_GetComputerNameExW();
test_GetEnvironmentStringsW();
test_SetEnvironmentStrings();
}
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
+186 -98
View File
@@ -25,7 +25,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 +47,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)
@@ -1140,15 +1140,6 @@ static void test_pack_LPTHREAD_START_ROUTINE(void)
TEST_TYPE_ALIGN (LPTHREAD_START_ROUTINE, 8)
}
static void test_pack_LPTIME_ZONE_INFORMATION(void)
{
/* LPTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (LPTIME_ZONE_INFORMATION, 8)
TEST_TYPE_ALIGN (LPTIME_ZONE_INFORMATION, 8)
TEST_TARGET_SIZE (LPTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(LPTIME_ZONE_INFORMATION, 4)
}
static void test_pack_LPWIN32_FILE_ATTRIBUTE_DATA(void)
{
/* LPWIN32_FILE_ATTRIBUTE_DATA */
@@ -1523,15 +1514,6 @@ static void test_pack_PTIMERAPCROUTINE(void)
TEST_TYPE_ALIGN (PTIMERAPCROUTINE, 8)
}
static void test_pack_PTIME_ZONE_INFORMATION(void)
{
/* PTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (PTIME_ZONE_INFORMATION, 8)
TEST_TYPE_ALIGN (PTIME_ZONE_INFORMATION, 8)
TEST_TARGET_SIZE (PTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(PTIME_ZONE_INFORMATION, 4)
}
static void test_pack_PWIN32_FIND_DATAA(void)
{
/* PWIN32_FIND_DATAA */
@@ -1762,34 +1744,6 @@ static void test_pack_SYSTEM_POWER_STATUS(void)
TEST_FIELD_OFFSET(SYSTEM_POWER_STATUS, BatteryFullLifeTime, 8)
}
static void test_pack_TIME_ZONE_INFORMATION(void)
{
/* TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (TIME_ZONE_INFORMATION, 172)
TEST_TYPE_ALIGN (TIME_ZONE_INFORMATION, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, Bias, 0)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardName, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardDate, 68)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardBias, 84)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightName, 88)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightDate, 152)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightBias, 168)
}
static void test_pack_UNLOAD_DLL_DEBUG_INFO(void)
{
/* UNLOAD_DLL_DEBUG_INFO */
@@ -1928,6 +1882,95 @@ static void test_pack_WIN32_STREAM_ID(void)
TEST_FIELD_OFFSET(WIN32_STREAM_ID, cStreamName, 20)
}
static void test_pack_DYNAMIC_TIME_ZONE_INFORMATION(void)
{
/* DYNAMIC_TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, 432)
TEST_TYPE_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, 4)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, Bias, 0)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, StandardName, 64)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, StandardName, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, StandardName, 4)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, StandardDate, 16)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, StandardDate, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, StandardDate, 68)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, StandardBias, 84)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DaylightName, 64)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DaylightName, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DaylightName, 88)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DaylightDate, 16)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DaylightDate, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DaylightDate, 152)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DaylightBias, 168)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, TimeZoneKeyName, 256)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, TimeZoneKeyName, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, TimeZoneKeyName, 172)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DynamicDaylightTimeDisabled, 1)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DynamicDaylightTimeDisabled, 1)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DynamicDaylightTimeDisabled, 428)
}
static void test_pack_LPTIME_ZONE_INFORMATION(void)
{
/* LPTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (LPTIME_ZONE_INFORMATION, 8)
TEST_TYPE_ALIGN (LPTIME_ZONE_INFORMATION, 8)
TEST_TARGET_SIZE (LPTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(LPTIME_ZONE_INFORMATION, 4)
}
static void test_pack_PDYNAMIC_TIME_ZONE_INFORMATION(void)
{
/* PDYNAMIC_TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (PDYNAMIC_TIME_ZONE_INFORMATION, 8)
TEST_TYPE_ALIGN (PDYNAMIC_TIME_ZONE_INFORMATION, 8)
TEST_TARGET_SIZE (PDYNAMIC_TIME_ZONE_INFORMATION, 432)
TEST_TARGET_ALIGN(PDYNAMIC_TIME_ZONE_INFORMATION, 4)
}
static void test_pack_PTIME_ZONE_INFORMATION(void)
{
/* PTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (PTIME_ZONE_INFORMATION, 8)
TEST_TYPE_ALIGN (PTIME_ZONE_INFORMATION, 8)
TEST_TARGET_SIZE (PTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(PTIME_ZONE_INFORMATION, 4)
}
static void test_pack_TIME_ZONE_INFORMATION(void)
{
/* TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (TIME_ZONE_INFORMATION, 172)
TEST_TYPE_ALIGN (TIME_ZONE_INFORMATION, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, Bias, 0)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardName, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardDate, 68)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardBias, 84)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightName, 88)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightDate, 152)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightBias, 168)
}
#else /* _WIN64 */
static void test_pack_LPOSVERSIONINFOA(void)
@@ -2997,15 +3040,6 @@ static void test_pack_LPTHREAD_START_ROUTINE(void)
TEST_TYPE_ALIGN (LPTHREAD_START_ROUTINE, 4)
}
static void test_pack_LPTIME_ZONE_INFORMATION(void)
{
/* LPTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (LPTIME_ZONE_INFORMATION, 4)
TEST_TYPE_ALIGN (LPTIME_ZONE_INFORMATION, 4)
TEST_TARGET_SIZE (LPTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(LPTIME_ZONE_INFORMATION, 4)
}
static void test_pack_LPWIN32_FILE_ATTRIBUTE_DATA(void)
{
/* LPWIN32_FILE_ATTRIBUTE_DATA */
@@ -3380,15 +3414,6 @@ static void test_pack_PTIMERAPCROUTINE(void)
TEST_TYPE_ALIGN (PTIMERAPCROUTINE, 4)
}
static void test_pack_PTIME_ZONE_INFORMATION(void)
{
/* PTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (PTIME_ZONE_INFORMATION, 4)
TEST_TYPE_ALIGN (PTIME_ZONE_INFORMATION, 4)
TEST_TARGET_SIZE (PTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(PTIME_ZONE_INFORMATION, 4)
}
static void test_pack_PWIN32_FIND_DATAA(void)
{
/* PWIN32_FIND_DATAA */
@@ -3619,34 +3644,6 @@ static void test_pack_SYSTEM_POWER_STATUS(void)
TEST_FIELD_OFFSET(SYSTEM_POWER_STATUS, BatteryFullLifeTime, 8)
}
static void test_pack_TIME_ZONE_INFORMATION(void)
{
/* TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (TIME_ZONE_INFORMATION, 172)
TEST_TYPE_ALIGN (TIME_ZONE_INFORMATION, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, Bias, 0)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardName, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardDate, 68)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardBias, 84)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightName, 88)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightDate, 152)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightBias, 168)
}
static void test_pack_UNLOAD_DLL_DEBUG_INFO(void)
{
/* UNLOAD_DLL_DEBUG_INFO */
@@ -3785,6 +3782,95 @@ static void test_pack_WIN32_STREAM_ID(void)
TEST_FIELD_OFFSET(WIN32_STREAM_ID, cStreamName, 20)
}
static void test_pack_DYNAMIC_TIME_ZONE_INFORMATION(void)
{
/* DYNAMIC_TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, 432)
TEST_TYPE_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, 4)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, Bias, 0)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, StandardName, 64)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, StandardName, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, StandardName, 4)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, StandardDate, 16)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, StandardDate, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, StandardDate, 68)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, StandardBias, 84)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DaylightName, 64)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DaylightName, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DaylightName, 88)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DaylightDate, 16)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DaylightDate, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DaylightDate, 152)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DaylightBias, 168)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, TimeZoneKeyName, 256)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, TimeZoneKeyName, 2)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, TimeZoneKeyName, 172)
TEST_FIELD_SIZE (DYNAMIC_TIME_ZONE_INFORMATION, DynamicDaylightTimeDisabled, 1)
TEST_FIELD_ALIGN (DYNAMIC_TIME_ZONE_INFORMATION, DynamicDaylightTimeDisabled, 1)
TEST_FIELD_OFFSET(DYNAMIC_TIME_ZONE_INFORMATION, DynamicDaylightTimeDisabled, 428)
}
static void test_pack_LPTIME_ZONE_INFORMATION(void)
{
/* LPTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (LPTIME_ZONE_INFORMATION, 4)
TEST_TYPE_ALIGN (LPTIME_ZONE_INFORMATION, 4)
TEST_TARGET_SIZE (LPTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(LPTIME_ZONE_INFORMATION, 4)
}
static void test_pack_PDYNAMIC_TIME_ZONE_INFORMATION(void)
{
/* PDYNAMIC_TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (PDYNAMIC_TIME_ZONE_INFORMATION, 4)
TEST_TYPE_ALIGN (PDYNAMIC_TIME_ZONE_INFORMATION, 4)
TEST_TARGET_SIZE (PDYNAMIC_TIME_ZONE_INFORMATION, 432)
TEST_TARGET_ALIGN(PDYNAMIC_TIME_ZONE_INFORMATION, 4)
}
static void test_pack_PTIME_ZONE_INFORMATION(void)
{
/* PTIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (PTIME_ZONE_INFORMATION, 4)
TEST_TYPE_ALIGN (PTIME_ZONE_INFORMATION, 4)
TEST_TARGET_SIZE (PTIME_ZONE_INFORMATION, 172)
TEST_TARGET_ALIGN(PTIME_ZONE_INFORMATION, 4)
}
static void test_pack_TIME_ZONE_INFORMATION(void)
{
/* TIME_ZONE_INFORMATION */
TEST_TYPE_SIZE (TIME_ZONE_INFORMATION, 172)
TEST_TYPE_ALIGN (TIME_ZONE_INFORMATION, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, Bias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, Bias, 0)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardName, 4)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardDate, 68)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, StandardBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, StandardBias, 84)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightName, 64)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightName, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightName, 88)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightDate, 16)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightDate, 2)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightDate, 152)
TEST_FIELD_SIZE (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_ALIGN (TIME_ZONE_INFORMATION, DaylightBias, 4)
TEST_FIELD_OFFSET(TIME_ZONE_INFORMATION, DaylightBias, 168)
}
#endif /* _WIN64 */
static void test_pack(void)
@@ -3806,6 +3892,7 @@ static void test_pack(void)
test_pack_CRITICAL_SECTION_DEBUG();
test_pack_DCB();
test_pack_DEBUG_EVENT();
test_pack_DYNAMIC_TIME_ZONE_INFORMATION();
test_pack_ENUMRESLANGPROCA();
test_pack_ENUMRESLANGPROCW();
test_pack_ENUMRESNAMEPROCA();
@@ -3881,6 +3968,7 @@ static void test_pack(void)
test_pack_PCACTCTX_SECTION_KEYED_DATA_ASSEMBLY_METADATA();
test_pack_PCRITICAL_SECTION();
test_pack_PCRITICAL_SECTION_DEBUG();
test_pack_PDYNAMIC_TIME_ZONE_INFORMATION();
test_pack_PFIBER_START_ROUTINE();
test_pack_PHKEY();
test_pack_POFSTRUCT();
@@ -0,0 +1,10 @@
.code
PUBLIC get_fpu_cw_raw
get_fpu_cw_raw PROC
fnstcw word ptr [rcx]
stmxcsr dword ptr [rdx]
ret
get_fpu_cw_raw ENDP
END
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
+156 -38
View File
@@ -22,18 +22,27 @@
#include <stdlib.h>
#include <stdio.h>
#include <ntstatus.h>
#define WIN32_NO_STATUS
#include <windef.h>
#include <winbase.h>
#include <winternl.h>
#include "wine/test.h"
#ifdef __REACTOS__
#include "winehacks.h"
#endif
static const char szmspath[] = "\\\\.\\mailslot\\wine_mailslot_test";
static int mailslot_test(void)
{
UNICODE_STRING nt_path = RTL_CONSTANT_STRING( L"\\??\\MAILSLOT\\wine_mailslot_test" );
HANDLE hSlot, hSlot2, hWriter, hWriter2;
unsigned char buffer[16];
DWORD count, dwMax, dwNext, dwMsgCount, dwTimeout;
FILE_MAILSLOT_QUERY_INFORMATION info;
OBJECT_ATTRIBUTES attr;
IO_STATUS_BLOCK io;
BOOL ret;
/* sanity check on GetMailslotInfo */
@@ -81,38 +90,51 @@ static int mailslot_test(void)
SetLastError(0xdeadbeef);
ret = ReadFile(INVALID_HANDLE_VALUE, buffer, 0, &count, NULL);
ok(!ret, "ReadFile should fail\n");
ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %u\n", GetLastError());
ok(count == 0, "expected 0, got %u\n", count);
ok(GetLastError() == ERROR_INVALID_HANDLE, "wrong error %lu\n", GetLastError());
ok(count == 0, "expected 0, got %lu\n", count);
count = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = ReadFile(hSlot, buffer, 0, &count, NULL);
ok(!ret, "ReadFile should fail\n");
todo_wine
ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError());
ok(count == 0, "expected 0, got %u\n", count);
ok(GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError());
ok(count == 0, "expected 0, got %lu\n", count);
count = 0;
memset(buffer, 0, sizeof buffer);
ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL);
ok( !ret, "slot read\n");
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
else ok( count == 0, "wrong count %u\n", count );
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() );
else ok( count == 0, "wrong count %lu\n", count );
ok( !WriteFile( hSlot, buffer, sizeof buffer, &count, NULL),
"slot write\n");
ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
ok( ret == STATUS_IO_TIMEOUT, "got %#x\n", ret );
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
ret = NtWriteFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
ok( ret == STATUS_ACCESS_DENIED, "got %#x\n", ret );
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
/* now try and open the client, but with the wrong sharing mode */
hWriter = CreateFileA(szmspath, GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter != INVALID_HANDLE_VALUE /* vista */ || GetLastError() == ERROR_SHARING_VIOLATION,
"error should be ERROR_SHARING_VIOLATION got %p / %u\n", hWriter, GetLastError());
"error should be ERROR_SHARING_VIOLATION got %p / %lu\n", hWriter, GetLastError());
if (hWriter != INVALID_HANDLE_VALUE) CloseHandle( hWriter );
/* now open the client with the correct sharing mode */
hWriter = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot err %u\n", GetLastError());
ok( hWriter != INVALID_HANDLE_VALUE, "existing mailslot err %lu\n", GetLastError());
/*
* opening a client should make no difference to
@@ -120,11 +142,11 @@ todo_wine
*/
ret = ReadFile( hSlot, buffer, sizeof buffer/2, &count, NULL);
ok( !ret, "slot read\n");
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
else ok( count == 0, "wrong count %u\n", count );
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() );
else ok( count == 0, "wrong count %lu\n", count );
ok( !WriteFile( hSlot, buffer, sizeof buffer/2, &count, NULL),
"slot write\n");
ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
/*
* we can't read from this client,
@@ -133,13 +155,20 @@ todo_wine
ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
"can read client\n");
ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ACCESS_DENIED,
"wrong error %u\n", GetLastError() );
"wrong error %lu\n", GetLastError() );
ok( WriteFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
"can't write client\n");
ok( !ReadFile( hWriter, buffer, sizeof buffer/2, &count, NULL),
"can read client\n");
ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ACCESS_DENIED,
"wrong error %u\n", GetLastError() );
"wrong error %lu\n", GetLastError() );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
ret = NtReadFile( hWriter, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
todo_wine ok( ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret );
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
/*
* seeing as there's something in the slot,
@@ -152,8 +181,8 @@ todo_wine
/* but not again */
ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL);
ok( !ret, "slot read\n");
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
else ok( count == 0, "wrong count %u\n", count );
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() );
else ok( count == 0, "wrong count %lu\n", count );
/* now try open another writer... should fail */
hWriter2 = CreateFileA(szmspath, GENERIC_READ|GENERIC_WRITE,
@@ -214,8 +243,8 @@ todo_wine
/* check there's still no data */
ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL);
ok( !ret, "slot read\n");
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
else ok( count == 0, "wrong count %u\n", count );
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() );
else ok( count == 0, "wrong count %lu\n", count );
/* write two messages */
buffer[0] = 'a';
@@ -237,9 +266,7 @@ todo_wine
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
"getmailslotinfo failed\n");
ok( dwNext == 1, "dwNext incorrect\n");
todo_wine {
ok( dwMsgCount == 2, "dwMsgCount incorrect\n");
}
/* write a 3rd message with zero size */
ok( WriteFile( hWriter2, buffer, 0, &count, NULL), "3rd write failed\n");
@@ -249,8 +276,7 @@ todo_wine
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
"getmailslotinfo failed\n");
ok( dwNext == 1, "dwNext incorrect\n");
todo_wine
ok( dwMsgCount == 3, "dwMsgCount incorrect %u\n", dwMsgCount);
ok( dwMsgCount == 3, "dwMsgCount incorrect %lu\n", dwMsgCount);
buffer[0]=buffer[1]=0;
@@ -268,9 +294,7 @@ todo_wine
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
"getmailslotinfo failed\n");
ok( dwNext == 2, "dwNext incorrect\n");
todo_wine {
ok( dwMsgCount == 2, "dwMsgCount incorrect %u\n", dwMsgCount);
}
ok( dwMsgCount == 2, "dwMsgCount incorrect %lu\n", dwMsgCount);
/* read the second message */
ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
@@ -282,16 +306,12 @@ todo_wine
dwNext = dwMsgCount = 0;
ok( GetMailslotInfo( hSlot, NULL, &dwNext, &dwMsgCount, NULL ),
"getmailslotinfo failed\n");
ok( dwNext == 0, "dwNext incorrect %u\n", dwNext);
todo_wine {
ok( dwMsgCount == 1, "dwMsgCount incorrect %u\n", dwMsgCount);
}
ok( dwNext == 0, "dwNext incorrect %lu\n", dwNext);
ok( dwMsgCount == 1, "dwMsgCount incorrect %lu\n", dwMsgCount);
/* read the 3rd (zero length) message */
todo_wine {
ok( ReadFile( hSlot, buffer, sizeof buffer, &count, NULL),
"3rd slot read failed\n");
}
ok( count == 0, "failed to get 3rd message\n");
/*
@@ -307,8 +327,50 @@ todo_wine
/* check that reads fail */
ret = ReadFile( hSlot, buffer, sizeof buffer, &count, NULL);
ok( !ret, "3rd slot read succeeded\n");
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
else ok( count == 0, "wrong count %u\n", count );
if (!ret) ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() );
else ok( count == 0, "wrong count %lu\n", count );
/* Try to perform a partial read. */
count = 0;
ret = WriteFile( hWriter, buffer, 2, &count, NULL );
ok( ret, "got %d\n", ret );
ok( count == 2, "got count %lu\n", count );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, 1, NULL, NULL );
ok( ret == STATUS_BUFFER_TOO_SMALL, "got %#x\n", ret );
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
memset( &info, 0xcc, sizeof(info) );
ret = NtQueryInformationFile( hSlot, &io, &info, sizeof(info), FileMailslotQueryInformation );
ok( ret == STATUS_SUCCESS, "got %#x\n", ret );
ok( io.Status == STATUS_SUCCESS, "got status %#lx\n", io.Status );
ok( io.Information == sizeof(info), "got size %Iu\n", io.Information );
ok( !info.MaximumMessageSize, "got maximum size %lu\n", info.MaximumMessageSize );
ok( !info.MailslotQuota, "got quota %lu\n", info.MailslotQuota );
ok( info.NextMessageSize == 2, "got next size %lu\n", info.NextMessageSize );
ok( info.MessagesAvailable == 1, "got message count %lu\n", info.MessagesAvailable );
ok( !info.ReadTimeout.QuadPart, "got timeout %I64u\n", info.ReadTimeout.QuadPart );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
memset( &info, 0xcc, sizeof(info) );
ret = NtQueryInformationFile( hWriter, &io, &info, sizeof(info), FileMailslotQueryInformation );
todo_wine ok( ret == STATUS_SUCCESS || ret == STATUS_INVALID_PARAMETER /* Win < 8 */, "got %#x\n", ret );
if (ret == STATUS_SUCCESS)
{
ok( io.Status == STATUS_SUCCESS, "got status %#lx\n", io.Status );
ok( io.Information == sizeof(info), "got size %Iu\n", io.Information );
ok( !info.MaximumMessageSize, "got maximum size %lu\n", info.MaximumMessageSize );
ok( !info.MailslotQuota, "got quota %lu\n", info.MailslotQuota );
ok( info.NextMessageSize == 2, "got next size %lu\n", info.NextMessageSize );
ok( info.MessagesAvailable == 1, "got message count %lu\n", info.MessagesAvailable );
ok( !info.ReadTimeout.QuadPart, "got timeout %I64u\n", info.ReadTimeout.QuadPart );
}
/* finally close the mailslot and its client */
ok( CloseHandle( hWriter2 ), "closing 2nd client\n");
@@ -322,12 +384,68 @@ todo_wine
memset(buffer, 0, sizeof buffer);
dwTimeout = GetTickCount();
ok( !ReadFile( hSlot, buffer, sizeof buffer, &count, NULL), "slot read\n");
ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_SEM_TIMEOUT, "wrong error %lu\n", GetLastError() );
dwTimeout = GetTickCount() - dwTimeout;
ros_skip_flaky
ok( dwTimeout >= 990, "timeout too short %u\n", dwTimeout );
ok( dwTimeout >= 900, "timeout too short %lu\n", dwTimeout );
ok( CloseHandle( hSlot ), "closing the mailslot\n");
InitializeObjectAttributes( &attr, &nt_path, 0, NULL, NULL );
ret = NtCreateMailslotFile( &hSlot, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &attr, &io, 0, 0, 0, NULL );
ok( !ret, "got %#x\n", ret );
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
ret = NtWriteFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
todo_wine ok( ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret );
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
#ifdef __REACTOS__
if (is_reactos()) {
ok(FALSE, "FIXME: This often bugchecks on ReactOS. This does not bugcheck on checked Windows builds.\n");
} else {
#endif
io.Status = 0xdeadbeef;
io.Information = 0xdeadbeef;
ret = NtReadFile( hSlot, NULL, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
ok( ret == STATUS_PENDING, "got %#x\n", ret );
ok( io.Status == 0xdeadbeef, "got status %#lx\n", io.Status );
ok( io.Information == 0xdeadbeef, "got size %Iu\n", io.Information );
#ifdef __REACTOS__
}
#endif
ret = WaitForSingleObject( hSlot, 0 );
ok( ret == WAIT_TIMEOUT, "got %d\n", ret );
hWriter = CreateFileA( szmspath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
#ifdef __REACTOS__
ok( hWriter != INVALID_HANDLE_VALUE || broken(GetLastError() == ERROR_SHARING_VIOLATION) /* WS03 */, "got err %lu\n", GetLastError() );
#else
ok( hWriter != INVALID_HANDLE_VALUE, "got err %lu\n", GetLastError() );
#endif
ret = WriteFile( hWriter, "data", 4, &count, NULL );
#ifdef __REACTOS__
ok( ret == TRUE || broken(GetLastError() == ERROR_INVALID_HANDLE) /* WS03 */, "got error %lu\n", GetLastError() );
#else
ok( ret == TRUE, "got error %lu\n", GetLastError() );
#endif
ret = WaitForSingleObject( hSlot, 1000 );
#ifdef __REACTOS__
ok( !ret || broken(ret == WAIT_TIMEOUT) /* WS03 */, "got %d\n", ret );
ok( !io.Status || broken(io.Status == 0xdeadbeef) /* WS03 */, "got status %#lx\n", io.Status );
if (GetNTVersion() >= _WIN32_WINNT_VISTA)
#else
ok( !ret, "got %d\n", ret );
ok( !io.Status, "got status %#lx\n", io.Status );
#endif
ok( io.Information == 4, "got size %Iu\n", io.Information );
CloseHandle( hWriter );
CloseHandle( hSlot );
return 0;
}
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
@@ -0,0 +1,83 @@
/*
* Unit tests for power management functions
*
* Copyright (c) 2019 Alex Henrie
*
* 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 "wine/test.h"
void test_GetSystemPowerStatus(void)
{
SYSTEM_POWER_STATUS ps;
BOOL ret;
BYTE capacity_flags, expected_capacity_flags;
if (0) /* crashes */
GetSystemPowerStatus(NULL);
memset(&ps, 0x23, sizeof(ps));
ret = GetSystemPowerStatus(&ps);
ok(ret == TRUE, "expected TRUE\n");
if (ps.BatteryFlag == BATTERY_FLAG_UNKNOWN)
{
skip("GetSystemPowerStatus not implemented or not working\n");
return;
}
else if (ps.BatteryFlag != BATTERY_FLAG_NO_BATTERY)
{
trace("battery detected\n");
expected_capacity_flags = 0;
if (ps.BatteryLifePercent > 66)
expected_capacity_flags |= BATTERY_FLAG_HIGH;
if (ps.BatteryLifePercent < 33)
expected_capacity_flags |= BATTERY_FLAG_LOW;
if (ps.BatteryLifePercent < 5)
expected_capacity_flags |= BATTERY_FLAG_CRITICAL;
capacity_flags = (ps.BatteryFlag & ~BATTERY_FLAG_CHARGING);
ok(capacity_flags == expected_capacity_flags,
"expected %u%%-charged battery to have capacity flags 0x%02x, got 0x%02x\n",
ps.BatteryLifePercent, expected_capacity_flags, capacity_flags);
ok(ps.BatteryLifeTime <= ps.BatteryFullLifeTime,
"expected BatteryLifeTime %lu to be less than or equal to BatteryFullLifeTime %lu\n",
ps.BatteryLifeTime, ps.BatteryFullLifeTime);
if (ps.BatteryFlag & BATTERY_FLAG_CHARGING)
{
ok(ps.BatteryLifeTime == BATTERY_LIFE_UNKNOWN,
"expected BatteryLifeTime to be -1 when charging, got %lu\n", ps.BatteryLifeTime);
ok(ps.BatteryFullLifeTime == BATTERY_LIFE_UNKNOWN,
"expected BatteryFullLifeTime to be -1 when charging, got %lu\n", ps.BatteryFullLifeTime);
}
}
else
{
trace("no battery detected\n");
ok(ps.ACLineStatus == AC_LINE_ONLINE,
"expected ACLineStatus to be 1, got %u\n", ps.ACLineStatus);
ok(ps.BatteryLifePercent == BATTERY_PERCENTAGE_UNKNOWN,
"expected BatteryLifePercent to be -1, got %u\n", ps.BatteryLifePercent);
ok(ps.BatteryLifeTime == BATTERY_LIFE_UNKNOWN,
"expected BatteryLifeTime to be -1, got %lu\n", ps.BatteryLifeTime);
ok(ps.BatteryFullLifeTime == BATTERY_LIFE_UNKNOWN,
"expected BatteryFullLifeTime to be -1, got %lu\n", ps.BatteryFullLifeTime);
}
}
START_TEST(power)
{
test_GetSystemPowerStatus();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+398 -19
View File
@@ -24,6 +24,7 @@
#include "wine/test.h"
static const char filename[] = "test_.exe";
static const WCHAR filenameW[] = {'t','e','s','t','_','.','e','x','e',0};
static DWORD GLE;
enum constants {
@@ -200,6 +201,7 @@ static int build_exe( const sec_build* sec_descr )
opt->SectionAlignment = page_size;
opt->FileAlignment = page_size;
opt->NumberOfRvaAndSizes = IMAGE_FILE_RESOURCE_DIRECTORY + 1;
opt->DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY].VirtualAddress = rva_rsrc_start;
opt->DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY].Size = page_size;
@@ -330,10 +332,10 @@ static void update_resources_version( void )
MAKEINTRESOURCEA(0x4567),
0xabcd,
foo, sizeof foo );
ok( r == TRUE, "UpdateResource failed: %d\n", GetLastError());
ok( r == TRUE, "UpdateResource failed: %ld\n", GetLastError());
r = EndUpdateResourceA( res, FALSE );
ok( r, "EndUpdateResource failed: %d\n", GetLastError());
ok( r, "EndUpdateResource failed: %ld\n", GetLastError());
}
static void update_resources_bigdata( void )
@@ -350,12 +352,44 @@ static void update_resources_bigdata( void )
MAKEINTRESOURCEA(0x5647),
0xcdba,
foo, sizeof foo );
ok( r == TRUE, "UpdateResource failed: %d\n", GetLastError());
ok( r == TRUE, "UpdateResource failed: %ld\n", GetLastError());
r = EndUpdateResourceA( res, FALSE );
ok( r, "EndUpdateResource failed\n");
}
static void update_resources_name( void )
{
char foo[] = "resource data", res_name[] = "name", res_type[] = "type";
HANDLE res = NULL;
HMODULE module;
HRSRC rsrc;
BOOL ret;
res = BeginUpdateResourceA( filename, TRUE );
ok( res != NULL, "BeginUpdateResource failed: %lu\n", GetLastError() );
if ( !res ) return;
ret = UpdateResourceA( res, res_type, res_name, MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), foo, sizeof(foo) );
ok( ret == TRUE, "UpdateResource failed: %lu\n", GetLastError() );
ret = EndUpdateResourceA( res, FALSE );
ok( ret, "EndUpdateResource failed: %lu\n", GetLastError() );
if ( !ret ) return;
module = LoadLibraryExA( filename, NULL, LOAD_LIBRARY_AS_DATAFILE );
ok( module != NULL, "LoadLibraryEx failed: %lu\n", GetLastError() );
if ( !module ) return;
rsrc = FindResourceA( module, res_name, res_type );
ok( rsrc != NULL ||
broken( GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND ) /* win2008 */,
"FindResource failed: %lu\n", GetLastError() );
ret = FreeLibrary(module);
ok( ret, "FreeLibrary failed: %lu\n", GetLastError() );
}
static void check_exe( const sec_verify *verify )
{
int i;
@@ -368,7 +402,7 @@ static void check_exe( const sec_verify *verify )
DWORD length, sec_count = 0;
file = CreateFileA(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
ok (file != INVALID_HANDLE_VALUE, "failed to create file (%d)\n", GetLastError());
ok (file != INVALID_HANDLE_VALUE, "failed to create file (%ld)\n", GetLastError());
length = GetFileSize( file, NULL );
ok( length >= verify->length, "file size wrong\n");
@@ -389,11 +423,11 @@ static void check_exe( const sec_verify *verify )
for(i = 0; i < max_sections; i++)
if (verify->sect_out[i])
{
ok( !memcmp(&verify->sect_out[i]->Name, &sec[sec_count].Name, 8), "section %d name wrong\n", sec_count);
ok( verify->sect_out[i]->VirtualAddress == sec[sec_count].VirtualAddress, "section %d vaddr wrong\n", sec_count);
ok( verify->sect_out[i]->SizeOfRawData <= sec[sec_count].SizeOfRawData, "section %d SizeOfRawData wrong (%d vs %d)\n", sec_count, verify->sect_out[i]->SizeOfRawData ,sec[sec_count].SizeOfRawData);
ok( verify->sect_out[i]->PointerToRawData == sec[sec_count].PointerToRawData, "section %d PointerToRawData wrong\n", sec_count);
ok( verify->sect_out[i]->Characteristics == sec[sec_count].Characteristics , "section %d characteristics wrong\n", sec_count);
ok( !memcmp(&verify->sect_out[i]->Name, &sec[sec_count].Name, 8), "section %ld name wrong\n", sec_count);
ok( verify->sect_out[i]->VirtualAddress == sec[sec_count].VirtualAddress, "section %ld vaddr wrong\n", sec_count);
ok( verify->sect_out[i]->SizeOfRawData <= sec[sec_count].SizeOfRawData, "section %ld SizeOfRawData wrong (%ld vs %ld)\n", sec_count, verify->sect_out[i]->SizeOfRawData ,sec[sec_count].SizeOfRawData);
ok( verify->sect_out[i]->PointerToRawData == sec[sec_count].PointerToRawData, "section %ld PointerToRawData wrong\n", sec_count);
ok( verify->sect_out[i]->Characteristics == sec[sec_count].Characteristics , "section %ld characteristics wrong\n", sec_count);
sec_count++;
}
@@ -404,18 +438,17 @@ static void check_exe( const sec_verify *verify )
dir = (void*) ((BYTE*) dos + sec[verify->rsrc_section].VirtualAddress);
ok( dir->Characteristics == 0, "Characteristics wrong\n");
ok( dir->TimeDateStamp == 0 || abs( dir->TimeDateStamp - GetTickCount() ) < 1000 /* nt4 */,
"TimeDateStamp wrong %u\n", dir->TimeDateStamp);
ok( dir->TimeDateStamp == 0, "TimeDateStamp wrong %lu\n", dir->TimeDateStamp);
ok( dir->MajorVersion == 4, "MajorVersion wrong\n");
ok( dir->MinorVersion == 0, "MinorVersion wrong\n");
ok( dir->NumberOfNamedEntries == verify->NumberOfNamedEntries, "NumberOfNamedEntries should be %d instead of %d\n",
ok( dir->NumberOfNamedEntries == verify->NumberOfNamedEntries, "NumberOfNamedEntries should be %ld instead of %d\n",
verify->NumberOfNamedEntries, dir->NumberOfNamedEntries);
ok( dir->NumberOfIdEntries == verify->NumberOfIdEntries, "NumberOfIdEntries should be %d instead of %d\n",
ok( dir->NumberOfIdEntries == verify->NumberOfIdEntries, "NumberOfIdEntries should be %ld instead of %d\n",
verify->NumberOfIdEntries, dir->NumberOfIdEntries);
ok(opt->DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY].VirtualAddress == sec[verify->rsrc_section].VirtualAddress,
"VirtualAddress in optional header should be %d instead of %d\n",
"VirtualAddress in optional header should be %ld instead of %ld\n",
sec[verify->rsrc_section].VirtualAddress, opt->DataDirectory[IMAGE_FILE_RESOURCE_DIRECTORY].VirtualAddress);
}
@@ -443,24 +476,367 @@ static void test_find_resource(void)
SetLastError( 0xdeadbeef );
rsrc = FindResourceW( GetModuleHandleW(NULL), MAKEINTRESOURCEW(1), (LPCWSTR)RT_DIALOG );
ok( !rsrc, "resource found\n" );
ok( GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_RESOURCE_TYPE_NOT_FOUND, "wrong error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
rsrc = FindResourceW( GetModuleHandleW(NULL), MAKEINTRESOURCEW(2), (LPCWSTR)RT_MENU );
ok( !rsrc, "resource found\n" );
ok( GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_RESOURCE_NAME_NOT_FOUND, "wrong error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
rsrc = FindResourceExW( GetModuleHandleW(NULL), (LPCWSTR)RT_MENU, MAKEINTRESOURCEW(1),
MAKELANGID( LANG_ENGLISH, SUBLANG_DEFAULT ) );
ok( !rsrc, "resource found\n" );
ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND, "wrong error %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
rsrc = FindResourceExW( GetModuleHandleW(NULL), (LPCWSTR)RT_MENU, MAKEINTRESOURCEW(1),
MAKELANGID( LANG_FRENCH, SUBLANG_DEFAULT ) );
ok( !rsrc, "resource found\n" );
ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_RESOURCE_LANG_NOT_FOUND, "wrong error %lu\n", GetLastError() );
}
typedef struct
{
void *unknown[6];
HGLOBAL pFileName;
} QUEUEDUPDATES;
static void test_internal_structure(void)
{
HANDLE res;
QUEUEDUPDATES *res_data;
WCHAR *res_filenameW;
res = BeginUpdateResourceW( filenameW, FALSE );
ok( res != NULL, "BeginUpdateResourceW failed\n" );
res_data = GlobalLock(res);
ok( res_data != NULL, "GlobalLock failed\n" );
res_filenameW = GlobalLock( res_data->pFileName );
ok( res_filenameW != NULL, "GlobalLock for res_filenameW failed\n" );
ok( !lstrcmpW( res_filenameW, filenameW ), "Filename fields do not match\n" );
ok( GlobalUnlock( res_filenameW ), "GlobalUnlock res_filenamed failed\n" );
ok( GlobalUnlock( res_data ), "GlobalUnlock res_data failed\n" );
ok( EndUpdateResourceW( res, TRUE ), "EndUpdateResourceW failed\n");
}
static const struct
{
IMAGE_DOS_HEADER dos;
IMAGE_NT_HEADERS nt;
IMAGE_SECTION_HEADER section;
} dll_image =
{
{ IMAGE_DOS_SIGNATURE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0 }, 0, 0, { 0 },
sizeof(IMAGE_DOS_HEADER) },
{
IMAGE_NT_SIGNATURE, /* Signature */
{
#if defined __i386__
IMAGE_FILE_MACHINE_I386, /* Machine */
#elif defined __x86_64__
IMAGE_FILE_MACHINE_AMD64, /* Machine */
#elif defined __arm__
IMAGE_FILE_MACHINE_ARMNT, /* Machine */
#elif defined __aarch64__
IMAGE_FILE_MACHINE_ARM64, /* Machine */
#else
# error You must specify the machine type
#endif
1, /* NumberOfSections */
0, /* TimeDateStamp */
0, /* PointerToSymbolTable */
0, /* NumberOfSymbols */
sizeof(IMAGE_OPTIONAL_HEADER), /* SizeOfOptionalHeader */
IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_DLL /* Characteristics */
},
{ IMAGE_NT_OPTIONAL_HDR_MAGIC, /* Magic */
1, /* MajorLinkerVersion */
0, /* MinorLinkerVersion */
0, /* SizeOfCode */
0, /* SizeOfInitializedData */
0, /* SizeOfUninitializedData */
0, /* AddressOfEntryPoint */
0x1000, /* BaseOfCode */
#ifndef _WIN64
0, /* BaseOfData */
#endif
0x10000000, /* ImageBase */
0x1000, /* SectionAlignment */
0x1000, /* FileAlignment */
4, /* MajorOperatingSystemVersion */
0, /* MinorOperatingSystemVersion */
1, /* MajorImageVersion */
0, /* MinorImageVersion */
4, /* MajorSubsystemVersion */
0, /* MinorSubsystemVersion */
0, /* Win32VersionValue */
0x3000, /* SizeOfImage */
sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS),
0, /* CheckSum */
IMAGE_SUBSYSTEM_WINDOWS_CUI, /* Subsystem */
IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE | IMAGE_DLLCHARACTERISTICS_NX_COMPAT, /* DllCharacteristics */
0, /* SizeOfStackReserve */
0, /* SizeOfStackCommit */
0, /* SizeOfHeapReserve */
0, /* SizeOfHeapCommit */
0, /* LoaderFlags */
IMAGE_FILE_RESOURCE_DIRECTORY + 1, /* NumberOfRvaAndSizes */
{ { 0 }, { 0 }, { 0x1000, 0x1000 } } /* DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES] */
}
},
{ ".rsrc\0\0", { 0 }, 0x1000, 0x1000, 0, 0, 0, 0, 0,
IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ }
};
static void create_test_dll( const WCHAR *name )
{
DWORD dummy;
HANDLE handle = CreateFileW( name, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, 0 );
ok( handle != INVALID_HANDLE_VALUE, "failed to create file err %lu\n", GetLastError() );
WriteFile( handle, &dll_image, sizeof(dll_image), &dummy, NULL );
SetFilePointer( handle, dll_image.nt.OptionalHeader.SizeOfImage, NULL, FILE_BEGIN );
SetEndOfFile( handle );
CloseHandle( handle );
}
static struct mui_res
{
DWORD signature;
DWORD size;
DWORD version;
DWORD path_type;
DWORD file_type;
DWORD system_attributes;
DWORD fallback_location;
BYTE service_checksum[16];
BYTE checksum[16];
DWORD unk1[2];
DWORD mui_path_off;
DWORD mui_path_size;
DWORD unk2[2];
DWORD ln_type_name_off;
DWORD ln_type_name_size;
DWORD ln_type_id_off;
DWORD ln_type_id_size;
DWORD mui_type_name_off;
DWORD mui_type_name_size;
DWORD mui_type_id_off;
DWORD mui_type_id_size;
DWORD lang_off;
DWORD lang_size;
DWORD fallback_lang_off;
DWORD fallback_lang_size;
WCHAR ln_type_names[8];
DWORD ln_type_ids[1];
WCHAR mui_type_names[8];
DWORD mui_type_ids[1];
WCHAR lang[8];
WCHAR fallback_lang[8];
} ln_mui_res = {
0xfecdfecd, sizeof(ln_mui_res), 0x10000, 0,
MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN >> 1,
0, 0, {'s','c'}, {'c'}, {0}, 0, 0, {0},
offsetof(struct mui_res, ln_type_names), sizeof(L"MUI\0"),
offsetof(struct mui_res, ln_type_ids), sizeof(ln_mui_res.ln_type_ids),
offsetof(struct mui_res, mui_type_names), sizeof(L"MUI\0"),
offsetof(struct mui_res, mui_type_ids), sizeof(ln_mui_res.mui_type_ids), 0, 0,
offsetof(struct mui_res, fallback_lang), sizeof(L"en-US"),
{'M','U','I',0,0}, {RT_CURSOR}, {'M','U','I',0,0}, {RT_STRING}, {0}, {'e','n','-','U','S',0},
}, en_mui_res = {
0xfecdfecd, sizeof(ln_mui_res), 0x10000, 0,
MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI >> 1,
0, 0, {'s','c'}, {'c'}, {0}, 0, 0, {0},
offsetof(struct mui_res, ln_type_names), sizeof(L"MUI\0"),
offsetof(struct mui_res, ln_type_ids), sizeof(ln_mui_res.ln_type_ids),
0, 0, 0, 0, offsetof(struct mui_res, lang), sizeof(L"en-US"), 0, 0,
{'M','U','I',0,0}, {RT_STRING}, {0}, {0}, {'e','n','-','U','S',0}
};
static void test_mui(void)
{
#if defined(__REACTOS__) && DLL_EXPORT_VERSION < 0x600
skip("Cannot build test_mui() unless DLL_EXPORT_VERSION >= 0x600.\n");
#else
static const WCHAR ln_dll[] = L"test_mui.dll";
static const WCHAR en_dll[] = L"en-US\\test_mui.dll.mui";
static const BYTE zeros[16] = { 0 };
BYTE buf[1024];
FILEMUIINFO *info = (FILEMUIINFO *)buf;
const WCHAR *str;
DWORD size, *id;
HANDLE res;
BOOL r;
size = 0;
r = GetFileMUIInfo( 0, ln_dll, NULL, &size);
ok( !r, "GetFileMUIInfo succeeded\n" );
ok( GetLastError() == ERROR_FILE_NOT_FOUND, "GetLastError() = %ld\n", GetLastError() );
create_test_dll( ln_dll );
CreateDirectoryW( L"en-US", NULL );
create_test_dll( en_dll );
size = 0;
r = GetFileMUIInfo( 0, ln_dll, NULL, &size );
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
ok( size == sizeof(*info), "unexpected size: %ld\n", size );
memset( buf, 0xfe, sizeof(buf) );
size = sizeof(buf);
info->dwSize = sizeof(buf);
info->dwVersion = 0;
r = GetFileMUIInfo( 0, ln_dll, info, &size );
ok( !r, "GetFileMUIInfo succeeded\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "GetLastError() = %ld\n", GetLastError() );
ok( !size, "size = %ld\n", size );
size = sizeof(buf);
info->dwVersion = MUI_FILEINFO_VERSION;
r = GetFileMUIInfo( 0, ln_dll, info, &size );
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
ok( info->dwSize == sizeof(buf), "dwSize = %ld\n", info->dwSize );
ok( info->dwVersion == MUI_FILEINFO_VERSION, "dwVersion = %ld\n", info->dwVersion );
ok( info->dwFileType == MUI_FILETYPE_NOT_LANGUAGE_NEUTRAL, "dwFileType = %ld\n", info->dwFileType );
ok( !memcmp(info->pChecksum, zeros, sizeof(info->pChecksum)), "pChecksum = %s\n",
wine_dbgstr_an((char *)info->pChecksum, sizeof(info->pChecksum)) );
ok( !memcmp(info->pServiceChecksum, zeros, sizeof(info->pServiceChecksum)), "pServiceChecksum = %s\n",
wine_dbgstr_an((char *)info->pServiceChecksum, sizeof(info->pServiceChecksum)) );
ok( !info->dwLanguageNameOffset, "dwLanguageNameOffset = %ld\n", info->dwLanguageNameOffset );
ok( !info->dwTypeIDMainSize, "dwTypeIDMainSize = %ld\n", info->dwTypeIDMainSize );
ok( !info->dwTypeIDMainOffset, "dwTypeIDMainOffset = %ld\n", info->dwTypeIDMainOffset );
ok( !info->dwTypeNameMainOffset, "dwTypeNameMainOffset = %ld\n", info->dwTypeNameMainOffset );
ok( !info->dwTypeIDMUISize, "dwTypeIDMUISize = %ld\n", info->dwTypeIDMUISize );
ok( !info->dwTypeIDMUIOffset, "dwTypeIDMUIOffset = %ld\n", info->dwTypeIDMUIOffset );
ok( !info->dwTypeNameMUIOffset, "dwTypeNameMUIOffset = %ld\n", info->dwTypeNameMUIOffset );
ok( !memcmp(info->abBuffer, zeros, sizeof(info->abBuffer)), "abBuffer = %s\n",
wine_dbgstr_an((char *)info->abBuffer, sizeof(info->abBuffer)) );
res = BeginUpdateResourceW( ln_dll, TRUE );
ok( res != NULL, "BeginUpdateResourceW failed: %ld\n", GetLastError() );
r = UpdateResourceW( res, L"MUI", MAKEINTRESOURCEW(1), 0, &ln_mui_res, 4 );
ok( r, "UpdateResource failed: %ld\n", GetLastError() );
r = EndUpdateResourceW( res, FALSE );
ok( r, "EndUpdateResourceW failed: %ld\n", GetLastError() );
size = 0;
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
| MUI_QUERY_RESOURCE_TYPES, ln_dll, NULL, &size );
ok( !r, "GetFileMUIInfo succeeded\n" );
#if defined(__REACTOS__) && defined(_WIN64)
ok( GetLastError() == ERROR_BAD_EXE_FORMAT || GetLastError() == ERROR_INSUFFICIENT_BUFFER /* Vista x64 */, "GetLastError() = %ld\n", GetLastError() );
#else
ok( GetLastError() == ERROR_BAD_EXE_FORMAT, "GetLastError() = %ld\n", GetLastError() );
#endif
res = BeginUpdateResourceW( ln_dll, TRUE );
ok( res != NULL, "BeginUpdateResourceW failed: %ld\n", GetLastError() );
r = UpdateResourceW( res, L"MUI", MAKEINTRESOURCEW(1), 0, &ln_mui_res, sizeof(ln_mui_res) );
ok( r, "UpdateResource failed: %ld\n", GetLastError() );
r = EndUpdateResourceW( res, FALSE );
ok( r, "EndUpdateResourceW failed: %ld\n", GetLastError() );
size = 0;
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
| MUI_QUERY_RESOURCE_TYPES, ln_dll, NULL, &size );
ok( !r, "GetFileMUIInfo succeeded\n" );
ok( GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() = %ld\n", GetLastError() );
ok( size, "size was not set\n" );
memset( buf, 0xfe, sizeof(buf) );
size = sizeof(buf);
info->dwSize = sizeof(buf);
info->dwVersion = MUI_FILEINFO_VERSION;
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
| MUI_QUERY_RESOURCE_TYPES, ln_dll, info, &size );
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
ok( info->dwSize == sizeof(buf), "dwSize = %ld\n", info->dwSize );
ok( info->dwVersion == MUI_FILEINFO_VERSION, "dwVersion = %ld\n", info->dwVersion );
ok( info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MAIN, "dwFileType = %ld\n", info->dwFileType );
ok( info->pChecksum[0] == 'c', "pChecksum = %s\n",
wine_dbgstr_an((char *)info->pChecksum, sizeof(info->pChecksum)) );
ok( info->pServiceChecksum[0] == 's', "pServiceChecksum = %s\n",
wine_dbgstr_an((char *)info->pServiceChecksum, sizeof(info->pServiceChecksum)) );
ok( info->dwLanguageNameOffset == 72, "dwLanguageNameOffset = %ld\n", info->dwLanguageNameOffset );
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
if (is_reactos()) {
ok(FALSE, "FIXME: These tests crash on ReactOS!\n");
} else {
#endif
str = (WCHAR *)(buf + info->dwLanguageNameOffset);
ok( !wcscmp(str, L"en-US"), "language name = %s\n", wine_dbgstr_w(str) );
ok( info->dwTypeIDMainSize == 1, "dwTypeIDMainSize = %ld\n", info->dwTypeIDMainSize );
ok( info->dwTypeIDMainOffset == 84, "dwTypeIDMainOffset = %ld\n", info->dwTypeIDMainOffset );
id = (DWORD *)(buf + info->dwTypeIDMainOffset);
ok( id[0] == RT_CURSOR, "type ID main[0] = %ld\n", id[0] );
ok( info->dwTypeNameMainOffset == 88, "dwTypeNameMainOffset = %ld\n", info->dwTypeNameMainOffset );
str = (WCHAR *)(buf + info->dwTypeNameMainOffset);
ok( !wcscmp(str, L"MUI"), "type name main[0] = %s\n", wine_dbgstr_w(str) );
str += wcslen(str) + 1;
ok( !str[0], "string list is not NULL terminated: %s\n", wine_dbgstr_w(str) );
ok( info->dwTypeIDMUISize == 1, "dwTypeIDMUISize = %ld\n", info->dwTypeIDMUISize );
ok( info->dwTypeIDMUIOffset == 98, "dwTypeIDMUIOffset = %ld\n", info->dwTypeIDMUIOffset );
id = (DWORD *)(buf + info->dwTypeIDMUIOffset);
ok( id[0] == RT_STRING, "type ID MUI[0] = %ld\n", id[0] );
ok( info->dwTypeNameMUIOffset == 102, "dwTypeNameMUIOffset = %ld\n", info->dwTypeNameMUIOffset );
str = (WCHAR *)(buf + info->dwTypeNameMUIOffset);
ok( !wcscmp(str, L"MUI"), "type name MUI[0] = %s\n", wine_dbgstr_w(str) );
str += wcslen(str) + 1;
ok( !str[0], "string list is not NULL terminated: %s\n", wine_dbgstr_w(str) );
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
}
#endif
res = BeginUpdateResourceW( en_dll, TRUE );
ok( res != NULL, "BeginUpdateResourceW failed: %ld\n", GetLastError() );
r = UpdateResourceW( res, L"MUI", MAKEINTRESOURCEW(1), 0, &en_mui_res, sizeof(en_mui_res) );
ok( r, "UpdateResource failed: %ld\n", GetLastError() );
r = EndUpdateResourceW( res, FALSE );
ok( r, "EndUpdateResourceW failed: %ld\n", GetLastError() );
memset( buf, 0xfe, sizeof(buf) );
size = sizeof(buf);
info->dwSize = sizeof(buf);
info->dwVersion = MUI_FILEINFO_VERSION;
r = GetFileMUIInfo( MUI_QUERY_TYPE | MUI_QUERY_CHECKSUM | MUI_QUERY_LANGUAGE_NAME
| MUI_QUERY_RESOURCE_TYPES, en_dll, info, &size );
ok( r, "GetFileMUIInfo failed: %ld\n", GetLastError() );
ok( info->dwSize == sizeof(buf), "dwSize = %ld\n", info->dwSize );
ok( info->dwVersion == MUI_FILEINFO_VERSION, "dwVersion = %ld\n", info->dwVersion );
ok( info->dwFileType == MUI_FILETYPE_LANGUAGE_NEUTRAL_MUI, "dwFileType = %ld\n", info->dwFileType );
ok( info->pChecksum[0] == 'c', "pChecksum = %s\n",
wine_dbgstr_an((char *)info->pChecksum, sizeof(info->pChecksum)) );
ok( info->pServiceChecksum[0] == 's', "pServiceChecksum = %s\n",
wine_dbgstr_an((char *)info->pServiceChecksum, sizeof(info->pServiceChecksum)) );
ok( info->dwLanguageNameOffset == 72, "dwLanguageNameOffset = %ld\n", info->dwLanguageNameOffset );
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
if (is_reactos()) {
ok(FALSE, "FIXME: These tests crash on ReactOS!\n");
} else {
#endif
str = (WCHAR *)(buf + info->dwLanguageNameOffset);
ok( !wcscmp(str, L"en-US"), "language name = %s\n", wine_dbgstr_w(str) );
ok( !info->dwTypeIDMainSize, "dwTypeIDMainSize = %ld\n", info->dwTypeIDMainSize );
ok( !info->dwTypeIDMainOffset, "dwTypeIDMainOffset = %ld\n", info->dwTypeIDMainOffset );
ok( !info->dwTypeNameMainOffset, "dwTypeNameMainOffset = %ld\n", info->dwTypeNameMainOffset );
ok( info->dwTypeIDMUISize == 1, "dwTypeIDMUISize = %ld\n", info->dwTypeIDMUISize );
ok( info->dwTypeIDMUIOffset == 84, "dwTypeIDMUIOffset = %ld\n", info->dwTypeIDMUIOffset );
id = (DWORD *)(buf + info->dwTypeIDMUIOffset);
ok( id[0] == RT_STRING, "type ID MUI[0] = %ld\n", id[0] );
ok( info->dwTypeNameMUIOffset == 88, "dwTypeNameMUIOffset = %ld\n", info->dwTypeNameMUIOffset );
str = (WCHAR *)(buf + info->dwTypeNameMUIOffset);
ok( !wcscmp(str, L"MUI"), "type name MUI[0] = %s\n", wine_dbgstr_w(str) );
str += wcslen(str) + 1;
ok( !str[0], "string list is not NULL terminated: %s\n", wine_dbgstr_w(str) );
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
}
#endif
DeleteFileW( ln_dll );
DeleteFileW( en_dll );
RemoveDirectoryW( L"en-US" );
#endif
}
START_TEST(resource)
@@ -478,10 +854,11 @@ START_TEST(resource)
update_empty_exe();
for(i=0; i < sizeof( sec_variants ) / sizeof( sec_variants[0] ); i++)
for(i=0; i < ARRAY_SIZE(sec_variants); i++)
{
const struct _sec_variants *sec = &sec_variants[i];
build_exe( &sec->build );
test_internal_structure();
update_resources_none();
check_exe( &sec->chk_none );
update_resources_delete();
@@ -490,7 +867,9 @@ START_TEST(resource)
check_exe( &sec->chk_version );
update_resources_bigdata();
check_exe( &sec->chk_bigdata );
update_resources_name();
DeleteFileA( filename );
}
test_find_resource();
test_mui();
}
@@ -24,3 +24,9 @@
{
MENUITEM "foo", 1
}
/* @makedep: wine_test.manifest */
124 24 wine_test.manifest
#ifdef __REACTOS__
DUMMY.DLL TESTDLL "dummy.dll"
#endif
File diff suppressed because it is too large Load Diff
@@ -24,6 +24,7 @@ extern void func_mailslot(void);
extern void func_module(void);
extern void func_path(void);
extern void func_pipe(void);
extern void func_power(void);
extern void func_process(void);
extern void func_profile(void);
extern void func_resource(void);
@@ -48,7 +49,7 @@ const struct test winetest_testlist[] =
{ "comm", func_comm },
{ "console", func_console },
/* ReactOS */
//{ "debugger", func_debugger },
{ "debugger", func_debugger },
{ "directory", func_directory },
{ "drive", func_drive },
{ "environ", func_environ },
@@ -56,7 +57,7 @@ const struct test winetest_testlist[] =
{ "file", func_file },
{ "format_msg", func_format_msg },
/* ReactOS */
//{ "generated", func_generated },
{ "generated", func_generated },
{ "heap", func_heap },
{ "loader", func_loader },
{ "locale", func_locale },
@@ -64,6 +65,7 @@ const struct test winetest_testlist[] =
{ "module", func_module },
{ "path", func_path },
{ "pipe", func_pipe },
{ "power", func_power },
{ "process", func_process },
{ "profile", func_profile },
{ "resource", func_resource },
File diff suppressed because it is too large Load Diff
+341 -92
View File
@@ -32,6 +32,7 @@ static int (WINAPI *pGetCalendarInfoW)(LCID,CALID,CALTYPE,LPWSTR,int,LPDWORD);
static DWORD (WINAPI *pGetDynamicTimeZoneInformation)(DYNAMIC_TIME_ZONE_INFORMATION*);
static void (WINAPI *pGetSystemTimePreciseAsFileTime)(LPFILETIME);
static BOOL (WINAPI *pGetTimeZoneInformationForYear)(USHORT, PDYNAMIC_TIME_ZONE_INFORMATION, LPTIME_ZONE_INFORMATION);
static ULONG (WINAPI *pNtGetTickCount)(void);
#define SECSPERMIN 60
#define SECSPERDAY 86400
@@ -121,14 +122,14 @@ static void test_conversions(void)
SETUP_ZEROTIME(st)
ok (SystemTimeToFileTime(&st, &ft), "Conversion failed ZERO_TIME\n");
ok( (!((ft.dwHighDateTime != 0) || (ft.dwLowDateTime != 0))),
"Wrong time for ATIME: %08x %08x (correct %08x %08x)\n",
"Wrong time for ATIME: %08lx %08lx (correct %08x %08x)\n",
ft.dwLowDateTime, ft.dwHighDateTime, 0, 0);
SETUP_ATIME(st)
ok (SystemTimeToFileTime(&st,&ft), "Conversion Failed ATIME\n");
ok( (!((ft.dwHighDateTime != ATIME_HI) || (ft.dwLowDateTime!=ATIME_LOW))),
"Wrong time for ATIME: %08x %08x (correct %08x %08x)\n",
"Wrong time for ATIME: %08lx %08lx (correct %08x %08x)\n",
ft.dwLowDateTime, ft.dwHighDateTime, ATIME_LOW, ATIME_HI);
@@ -137,7 +138,7 @@ static void test_conversions(void)
ok( (!((ft.dwHighDateTime != MAYDAY_2002_HI) ||
(ft.dwLowDateTime!=MAYDAY_2002_LO))),
"Wrong time for 2002 %08x %08x (correct %08x %08x)\n", ft.dwLowDateTime,
"Wrong time for 2002 %08lx %08lx (correct %08x %08x)\n", ft.dwLowDateTime,
ft.dwHighDateTime, MAYDAY_2002_LO, MAYDAY_2002_HI);
@@ -146,7 +147,7 @@ static void test_conversions(void)
ok( (!((ft.dwHighDateTime!=NEWYEAR_1980_HI) ||
(ft.dwLowDateTime!=NEWYEAR_1980_LO))) ,
"Wrong time for 1980 %08x %08x (correct %08x %08x)\n", ft.dwLowDateTime,
"Wrong time for 1980 %08lx %08lx (correct %08x %08x)\n", ft.dwLowDateTime,
ft.dwHighDateTime, NEWYEAR_1980_LO,NEWYEAR_1980_HI );
ok(DosDateTimeToFileTime(DOS_DATE(1980,1,1),DOS_TIME(0,0,0),&ft),
@@ -154,7 +155,7 @@ static void test_conversions(void)
ok( (!((ft.dwHighDateTime!=NEWYEAR_1980_HI) ||
(ft.dwLowDateTime!=NEWYEAR_1980_LO))),
"Wrong time DosDateTimeToFileTime %08x %08x (correct %08x %08x)\n",
"Wrong time DosDateTimeToFileTime %08lx %08lx (correct %08x %08x)\n",
ft.dwHighDateTime, ft.dwLowDateTime, NEWYEAR_1980_HI, NEWYEAR_1980_LO);
}
@@ -172,7 +173,7 @@ static void test_invalid_arg(void)
"DosDateTimeToFileTime() failed\n");
ok( (ft.dwHighDateTime==NEWYEAR_1980_HI) && (ft.dwLowDateTime==NEWYEAR_1980_LO),
"filetime for 1/1/80 00:00:00 was %08x %08x\n", ft.dwHighDateTime, ft.dwLowDateTime);
"filetime for 1/1/80 00:00:00 was %08lx %08lx\n", ft.dwHighDateTime, ft.dwLowDateTime);
/* now check SystemTimeToFileTime */
memset(&ft,0,sizeof ft);
@@ -205,7 +206,7 @@ static LONGLONG system_time_to_minutes(const SYSTEMTIME *st)
SetLastError(0xdeadbeef);
ret = SystemTimeToFileTime(st, &ft);
ok(ret, "SystemTimeToFileTime error %u\n", GetLastError());
ok(ret, "SystemTimeToFileTime error %lu\n", GetLastError());
minutes = ((LONGLONG)ft.dwHighDateTime << 32) + ft.dwLowDateTime;
minutes /= (LONGLONG)600000000; /* convert to minutes */
@@ -225,7 +226,7 @@ static LONG get_tz_bias(const TIME_ZONE_INFORMATION *tzinfo, DWORD tz_id)
return tzinfo->StandardBias;
default:
trace("unknown time zone id %d\n", tz_id);
trace("unknown time zone id %ld\n", tz_id);
/* fall through */
case TIME_ZONE_ID_UNKNOWN:
return 0;
@@ -248,19 +249,19 @@ static void test_GetTimeZoneInformation(void)
SetLastError(0xdeadbeef);
res = SystemTimeToFileTime(&st, &s_ft);
ok(res, "SystemTimeToFileTime error %u\n", GetLastError());
ok(res, "SystemTimeToFileTime error %lu\n", GetLastError());
SetLastError(0xdeadbeef);
res = FileTimeToLocalFileTime(&s_ft, &l_ft);
ok(res, "FileTimeToLocalFileTime error %u\n", GetLastError());
ok(res, "FileTimeToLocalFileTime error %lu\n", GetLastError());
SetLastError(0xdeadbeef);
res = FileTimeToSystemTime(&l_ft, &local);
ok(res, "FileTimeToSystemTime error %u\n", GetLastError());
ok(res, "FileTimeToSystemTime error %lu\n", GetLastError());
l_time = system_time_to_minutes(&local);
tz_id = GetTimeZoneInformation(&tzinfo);
ok(tz_id != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
trace("tz_id %u (%s)\n", tz_id,
trace("tz_id %lu (%s)\n", tz_id,
tz_id == TIME_ZONE_ID_DAYLIGHT ? "TIME_ZONE_ID_DAYLIGHT" :
(tz_id == TIME_ZONE_ID_STANDARD ? "TIME_ZONE_ID_STANDARD" :
(tz_id == TIME_ZONE_ID_UNKNOWN ? "TIME_ZONE_ID_UNKNOWN" :
@@ -268,14 +269,14 @@ static void test_GetTimeZoneInformation(void)
WideCharToMultiByte(CP_ACP, 0, tzinfo.StandardName, -1, std_name, sizeof(std_name), NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, tzinfo.DaylightName, -1, dlt_name, sizeof(dlt_name), NULL, NULL);
trace("bias %d, %s - %s\n", tzinfo.Bias, std_name, dlt_name);
trace("standard (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n",
trace("bias %ld, %s - %s\n", tzinfo.Bias, std_name, dlt_name);
trace("standard (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %ld\n",
tzinfo.StandardDate.wDay, tzinfo.StandardDate.wMonth,
tzinfo.StandardDate.wYear, tzinfo.StandardDate.wDayOfWeek,
tzinfo.StandardDate.wHour, tzinfo.StandardDate.wMinute,
tzinfo.StandardDate.wSecond, tzinfo.StandardDate.wMilliseconds,
tzinfo.StandardBias);
trace("daylight (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %d\n",
trace("daylight (d/m/y): %u/%02u/%04u day of week %u %u:%02u:%02u.%03u bias %ld\n",
tzinfo.DaylightDate.wDay, tzinfo.DaylightDate.wMonth,
tzinfo.DaylightDate.wYear, tzinfo.DaylightDate.wDayOfWeek,
tzinfo.DaylightDate.wHour, tzinfo.DaylightDate.wMinute,
@@ -284,7 +285,7 @@ static void test_GetTimeZoneInformation(void)
diff = (LONG)(s_time - l_time);
ok(diff == tzinfo.Bias + get_tz_bias(&tzinfo, tz_id),
"system/local diff %d != tz bias %d\n",
"system/local diff %ld != tz bias %ld\n",
diff, tzinfo.Bias + get_tz_bias(&tzinfo, tz_id));
ok(SetEnvironmentVariableA("TZ","GMT0") != 0,
@@ -316,16 +317,16 @@ static void test_GetTimeZoneInformation(void)
return;
}
ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError());
ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError());
s_time = system_time_to_minutes(&current);
tzinfo.StandardBias -= 123;
tzinfo.DaylightBias += 456;
res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local);
ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError());
ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError());
l_time = system_time_to_minutes(&local);
ok(l_time - s_time == diff - get_tz_bias(&tzinfo, tz_id), "got %d, expected %d\n",
ok(l_time - s_time == diff - get_tz_bias(&tzinfo, tz_id), "got %ld, expected %ld\n",
(LONG)(l_time - s_time), diff - get_tz_bias(&tzinfo, tz_id));
/* pretend that there is no transition dates */
@@ -337,9 +338,9 @@ static void test_GetTimeZoneInformation(void)
tzinfo.StandardDate.wYear = 0;
res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local);
ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError());
ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError());
l_time = system_time_to_minutes(&local);
ok(l_time - s_time == diff, "got %d, expected %d\n",
ok(l_time - s_time == diff, "got %ld, expected %ld\n",
(LONG)(l_time - s_time), diff);
/* test 23:01, 31st of December date */
@@ -360,7 +361,7 @@ static void test_GetTimeZoneInformation(void)
utc.wHour = 23;
utc.wMinute = 1;
res = pSystemTimeToTzSpecificLocalTime(&tzinfo, &utc, &local);
ok(res, "SystemTimeToTzSpecificLocalTime error %u\n", GetLastError());
ok(res, "SystemTimeToTzSpecificLocalTime error %lu\n", GetLastError());
ok(local.wYear==2012 && local.wMonth==12 && local.wDay==31 && local.wHour==23 && local.wMinute==1,
"got (%d-%d-%d %02d:%02d), expected (2012-12-31 23:01)\n",
local.wYear, local.wMonth, local.wDay, local.wHour, local.wMinute);
@@ -377,7 +378,7 @@ static void test_FileTimeToSystemTime(void)
ft.dwLowDateTime = 0;
ret = FileTimeToSystemTime(&ft, &st);
ok( ret,
"FileTimeToSystemTime() failed with Error %d\n",GetLastError());
"FileTimeToSystemTime() failed with Error %ld\n",GetLastError());
ok(((st.wYear == 1601) && (st.wMonth == 1) && (st.wDay == 1) &&
(st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 0) &&
(st.wMilliseconds == 0)),
@@ -387,13 +388,21 @@ static void test_FileTimeToSystemTime(void)
ft.dwLowDateTime = (UINT)time;
ret = FileTimeToSystemTime(&ft, &st);
ok( ret,
"FileTimeToSystemTime() failed with Error %d\n",GetLastError());
"FileTimeToSystemTime() failed with Error %ld\n",GetLastError());
ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) &&
(st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) &&
(st.wMilliseconds == 0)),
"Got Year %4d Month %2d Day %2d Hour %2d Min %2d Sec %2d mSec %3d\n",
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond,
st.wMilliseconds);
ft.dwHighDateTime = -1;
ft.dwLowDateTime = -1;
SetLastError(0xdeadbeef);
ret = FileTimeToSystemTime(&ft, &st);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
}
static void test_FileTimeToLocalFileTime(void)
@@ -414,7 +423,7 @@ static void test_FileTimeToLocalFileTime(void)
ft.dwLowDateTime = (UINT)time;
ret = FileTimeToLocalFileTime(&ft, &lft);
ok( ret,
"FileTimeToLocalFileTime() failed with Error %d\n",GetLastError());
"FileTimeToLocalFileTime() failed with Error %ld\n",GetLastError());
FileTimeToSystemTime(&lft, &st);
ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) &&
(st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) &&
@@ -428,7 +437,7 @@ static void test_FileTimeToLocalFileTime(void)
ok(res != TIME_ZONE_ID_INVALID, "GetTimeZoneInformation failed\n");
ret = FileTimeToLocalFileTime(&ft, &lft);
ok( ret,
"FileTimeToLocalFileTime() failed with Error %d\n",GetLastError());
"FileTimeToLocalFileTime() failed with Error %ld\n",GetLastError());
FileTimeToSystemTime(&lft, &st);
ok(((st.wYear == 1970) && (st.wMonth == 1) && (st.wDay == 1) &&
(st.wHour == 0) && (st.wMinute == 0) && (st.wSecond == 1) &&
@@ -646,25 +655,25 @@ static void test_FileTimeToDosDateTime(void)
ret = FileTimeToDosDateTime(&ft, NULL, NULL);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
"expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret = FileTimeToDosDateTime(&ft, &fatdate, NULL);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
"expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret = FileTimeToDosDateTime(&ft, NULL, &fattime);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
"expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
SetLastError(0xdeadbeef);
ret = FileTimeToDosDateTime(&ft, &fatdate, &fattime);
ok(!ret, "expected failure\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
"expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
}
static void test_GetCalendarInfo(void)
@@ -672,7 +681,7 @@ static void test_GetCalendarInfo(void)
char bufferA[20];
WCHAR bufferW[20];
DWORD val1, val2;
int ret, ret2;
int i, j, ret, ret2;
if (!pGetCalendarInfoA || !pGetCalendarInfoW)
{
@@ -682,59 +691,85 @@ static void test_GetCalendarInfo(void)
ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
NULL, 0, &val1 );
ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() );
ok( ret == sizeof(val1), "wrong size %u\n", ret );
ok( val1 >= 2000 && val1 < 2100, "wrong value %u\n", val1 );
ok( val1 >= 2000 && val1 < 2100, "wrong value %lu\n", val1 );
ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
NULL, 0, &val2 );
ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
ok( ret, "GetCalendarInfoW failed err %lu\n", GetLastError() );
ok( ret == sizeof(val2)/sizeof(WCHAR), "wrong size %u\n", ret );
ok( val1 == val2, "A/W mismatch %u/%u\n", val1, val2 );
ok( val1 == val2, "A/W mismatch %lu/%lu\n", val1, val2 );
ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferA, sizeof(bufferA), NULL );
ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() );
ok( ret == 5, "wrong size %u\n", ret );
ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 );
ok( atoi( bufferA ) == val1, "wrong value %s/%lu\n", bufferA, val1 );
ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, sizeof(bufferW), NULL );
ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, ARRAY_SIZE(bufferW), NULL );
ok( ret, "GetCalendarInfoW failed err %lu\n", GetLastError() );
ok( ret == 5, "wrong size %u\n", ret );
memset( bufferA, 0x55, sizeof(bufferA) );
WideCharToMultiByte( CP_ACP, 0, bufferW, -1, bufferA, sizeof(bufferA), NULL, NULL );
ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 );
ok( atoi( bufferA ) == val1, "wrong value %s/%lu\n", bufferA, val1 );
ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
NULL, 0, NULL );
ok( !ret, "GetCalendarInfoA succeeded\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
ret = pGetCalendarInfoA( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL );
ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() );
ok( ret == 5, "wrong size %u\n", ret );
ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
NULL, 0, NULL );
ok( !ret, "GetCalendarInfoW succeeded\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, NULL, 0, NULL );
ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
ok( ret, "GetCalendarInfoW failed err %lu\n", GetLastError() );
ok( ret == 5, "wrong size %u\n", ret );
ret = pGetCalendarInfoA( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1,
bufferA, sizeof(bufferA), NULL);
ok( ret, "GetCalendarInfoA failed err %u\n", GetLastError() );
ok( ret, "GetCalendarInfoA failed err %lu\n", GetLastError() );
ret2 = pGetCalendarInfoA( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1,
bufferA, 0, NULL);
ok( ret2, "GetCalendarInfoA failed err %u\n", GetLastError() );
ok( ret2, "GetCalendarInfoA failed err %lu\n", GetLastError() );
ok( ret == ret2, "got %d, expected %d\n", ret2, ret );
ret2 = pGetCalendarInfoW( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1,
bufferW, sizeof(bufferW), NULL);
ok( ret2, "GetCalendarInfoW failed err %u\n", GetLastError() );
bufferW, ARRAY_SIZE(bufferW), NULL);
ok( ret2, "GetCalendarInfoW failed err %lu\n", GetLastError() );
ret2 = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
ok( ret == ret2, "got %d, expected %d\n", ret, ret2 );
#ifdef __REACTOS__
if (GetNTVersion() >= _WIN32_WINNT_VISTA) {
#endif
for (i = CAL_GREGORIAN; i <= CAL_UMALQURA; i++)
{
WCHAR name[80];
ret = pGetCalendarInfoW( 0x0409, i, CAL_SCALNAME, name, ARRAY_SIZE(name), NULL);
for (j = CAL_ICALINTVALUE; j <= CAL_SRELATIVELONGDATE; j++)
{
ret2 = pGetCalendarInfoW( 0x0409, i, j, bufferW, ARRAY_SIZE(bufferW), NULL);
if (ret || j == CAL_ITWODIGITYEARMAX)
#ifdef __REACTOS__
ok( ret2 || broken(j == CAL_SRELATIVELONGDATE) /* Win7 */ || broken(j == CAL_SMONTHDAY || j == CAL_SABBREVERASTRING), /* Vista */
#else
ok( ret2 || broken(j == CAL_SRELATIVELONGDATE), /* win7 doesn't have this */
#endif
"calendar %u %s value %02x failed\n", i, wine_dbgstr_w(name), j );
else
ok( !ret2, "calendar %u %s value %02x succeeded %s\n",
i, wine_dbgstr_w(name), j, wine_dbgstr_w(bufferW) );
}
}
#ifdef __REACTOS__
}
#endif
}
static void test_GetDynamicTimeZoneInformation(void)
@@ -743,7 +778,12 @@ static void test_GetDynamicTimeZoneInformation(void)
TIME_ZONE_INFORMATION tzinfo;
DWORD ret, ret2;
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
/* FIXME: GetDynamicTimeZoneInformation is a STUB on ReactOS */
if (is_reactos() || !pGetDynamicTimeZoneInformation)
#else
if (!pGetDynamicTimeZoneInformation)
#endif
{
win_skip("GetDynamicTimeZoneInformation() is not supported.\n");
return;
@@ -751,13 +791,13 @@ static void test_GetDynamicTimeZoneInformation(void)
ret = pGetDynamicTimeZoneInformation(&dyninfo);
ret2 = GetTimeZoneInformation(&tzinfo);
ok(ret == ret2, "got %d, %d\n", ret, ret2);
ok(ret == ret2, "got %ld, %ld\n", ret, ret2);
ok(dyninfo.Bias == tzinfo.Bias, "got %d, %d\n", dyninfo.Bias, tzinfo.Bias);
ok(dyninfo.Bias == tzinfo.Bias, "got %ld, %ld\n", dyninfo.Bias, tzinfo.Bias);
ok(!lstrcmpW(dyninfo.StandardName, tzinfo.StandardName), "got std name %s, %s\n",
wine_dbgstr_w(dyninfo.StandardName), wine_dbgstr_w(tzinfo.StandardName));
ok(!memcmp(&dyninfo.StandardDate, &tzinfo.StandardDate, sizeof(dyninfo.StandardDate)), "got different StandardDate\n");
ok(dyninfo.StandardBias == tzinfo.StandardBias, "got %d, %d\n", dyninfo.StandardBias, tzinfo.StandardBias);
ok(dyninfo.StandardBias == tzinfo.StandardBias, "got %ld, %ld\n", dyninfo.StandardBias, tzinfo.StandardBias);
ok(!lstrcmpW(dyninfo.DaylightName, tzinfo.DaylightName), "got daylight name %s, %s\n",
wine_dbgstr_w(dyninfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName));
ok(!memcmp(&dyninfo.DaylightDate, &tzinfo.DaylightDate, sizeof(dyninfo.DaylightDate)), "got different DaylightDate\n");
@@ -773,6 +813,20 @@ static ULONGLONG get_longlong_time(FILETIME *time)
return uli.QuadPart;
}
static void test_GetSystemTimeAsFileTime(void)
{
LARGE_INTEGER t1, t2, t3;
FILETIME ft;
NtQuerySystemTime( &t1 );
GetSystemTimeAsFileTime( &ft );
NtQuerySystemTime( &t3 );
t2.QuadPart = get_longlong_time( &ft );
ok(t1.QuadPart <= t2.QuadPart, "out of order %s %s\n", wine_dbgstr_longlong(t1.QuadPart), wine_dbgstr_longlong(t2.QuadPart));
ok(t2.QuadPart <= t3.QuadPart, "out of order %s %s\n", wine_dbgstr_longlong(t2.QuadPart), wine_dbgstr_longlong(t3.QuadPart));
}
static void test_GetSystemTimePreciseAsFileTime(void)
{
FILETIME ft;
@@ -841,7 +895,7 @@ static void test_GetSystemTimes(void)
ok( !NtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), &ReturnLength),
"NtQuerySystemInformation failed\n" );
ok( sizeof(sbi) == ReturnLength, "Inconsistent length %d\n", ReturnLength );
ok( sizeof(sbi) == ReturnLength, "Inconsistent length %ld\n", ReturnLength );
/* Check if we have some return values */
trace( "Number of Processors : %d\n", sbi.NumberOfProcessors );
@@ -879,6 +933,9 @@ static WORD day_of_month(const SYSTEMTIME* systemtime, WORD year)
if (systemtime->wYear != 0)
return systemtime->wDay;
if (systemtime->wMonth == 0)
return 0;
first_of_month.wYear = year;
first_of_month.wMonth = systemtime->wMonth;
first_of_month.wDay = 1;
@@ -911,15 +968,42 @@ static WORD day_of_month(const SYSTEMTIME* systemtime, WORD year)
static void test_GetTimeZoneInformationForYear(void)
{
BOOL ret;
BOOL ret, broken_test = FALSE;
SYSTEMTIME systemtime;
TIME_ZONE_INFORMATION local_tzinfo, tzinfo, tzinfo2;
DYNAMIC_TIME_ZONE_INFORMATION dyn_tzinfo;
static const WCHAR std_tzname[] = {'G','r','e','e','n','l','a','n','d',' ','S','t','a','n','d','a','r','d',' ','T','i','m','e',0};
static const WCHAR dlt_tzname[] = {'G','r','e','e','n','l','a','n','d',' ','D','a','y','l','i','g','h','t',' ','T','i','m','e',0};
WORD std_day, dlt_day;
unsigned i;
static const struct
{
const WCHAR *tzname;
USHORT year;
LONG bias, std_bias, dlt_bias;
WORD std_month, std_day, dlt_month, dlt_day;
}
test_data[] =
{
{ L"Greenland Standard Time", 2015, 180, 0, -60, 10, 24, 3, 28 },
{ L"Greenland Standard Time", 2016, 180, 0, -60, 10, 29, 3, 26 },
{ L"Greenland Standard Time", 2017, 180, 0, -60, 10, 28, 3, 25 },
{ L"Easter Island Standard Time", 2014, 360, 0, -60, 4, 26, 9, 6 },
{ L"Easter Island Standard Time", 2015, 300, 0, -60, 0, 0, 0, 0 },
{ L"Easter Island Standard Time", 2016, 360, 0, -60, 5, 14, 8, 13 },
{ L"Egypt Standard Time", 2013, -120, 0, -60, 0, 0, 0, 0 },
{ L"Egypt Standard Time", 2014, -120, 0, -60, 9, 25, 5, 15 },
{ L"Egypt Standard Time", 2015, -120, 0, -60, 0, 0, 0, 0 },
{ L"Egypt Standard Time", 2016, -120, 0, -60, 0, 0, 0, 0 },
{ L"Altai Standard Time", 2016, -420, 0, 60, 3, 27, 1, 1 },
{ L"Altai Standard Time", 2017, -420, 0, -60, 0, 0, 0, 0 },
{ L"Altai Standard Time", 2018, -420, 0, -60, 0, 0, 0, 0 },
};
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
/* FIXME: GetTimeZoneInformationForYear and GetDynamicTimeZoneInformation are STUBS on ReactOS */
if (is_reactos() || !pGetTimeZoneInformationForYear || !pGetDynamicTimeZoneInformation)
#else
if (!pGetTimeZoneInformationForYear || !pGetDynamicTimeZoneInformation)
#endif
{
win_skip("GetTimeZoneInformationForYear not available\n");
return;
@@ -930,69 +1014,227 @@ static void test_GetTimeZoneInformationForYear(void)
GetTimeZoneInformation(&local_tzinfo);
ret = pGetTimeZoneInformationForYear(systemtime.wYear, NULL, &tzinfo);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError());
ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %d, got %d\n", local_tzinfo.Bias, tzinfo.Bias);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu\n", GetLastError());
ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %ld, got %ld\n", local_tzinfo.Bias, tzinfo.Bias);
ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName),
"Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName));
ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n");
ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %d, got %d\n", local_tzinfo.StandardBias, tzinfo.StandardBias);
ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %ld, got %ld\n", local_tzinfo.StandardBias, tzinfo.StandardBias);
ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName),
"Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName));
ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n");
ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %d, got %d\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias);
ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %ld, got %ld\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias);
pGetDynamicTimeZoneInformation(&dyn_tzinfo);
ret = pGetTimeZoneInformationForYear(systemtime.wYear, &dyn_tzinfo, &tzinfo);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError());
ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %d, got %d\n", local_tzinfo.Bias, tzinfo.Bias);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu\n", GetLastError());
ok(tzinfo.Bias == local_tzinfo.Bias, "Expected Bias %ld, got %ld\n", local_tzinfo.Bias, tzinfo.Bias);
ok(!lstrcmpW(tzinfo.StandardName, local_tzinfo.StandardName),
"Expected StandardName %s, got %s\n", wine_dbgstr_w(local_tzinfo.StandardName), wine_dbgstr_w(tzinfo.StandardName));
ok(!memcmp(&tzinfo.StandardDate, &local_tzinfo.StandardDate, sizeof(SYSTEMTIME)), "StandardDate does not match\n");
ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %d, got %d\n", local_tzinfo.StandardBias, tzinfo.StandardBias);
ok(tzinfo.StandardBias == local_tzinfo.StandardBias, "Expected StandardBias %ld, got %ld\n", local_tzinfo.StandardBias, tzinfo.StandardBias);
ok(!lstrcmpW(tzinfo.DaylightName, local_tzinfo.DaylightName),
"Expected DaylightName %s, got %s\n", wine_dbgstr_w(local_tzinfo.DaylightName), wine_dbgstr_w(tzinfo.DaylightName));
ok(!memcmp(&tzinfo.DaylightDate, &local_tzinfo.DaylightDate, sizeof(SYSTEMTIME)), "DaylightDate does not match\n");
ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %d, got %d\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias);
ok(tzinfo.DaylightBias == local_tzinfo.DaylightBias, "Expected DaylightBias %ld, got %ld\n", local_tzinfo.DaylightBias, tzinfo.DaylightBias);
memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo));
lstrcpyW(dyn_tzinfo.TimeZoneKeyName, std_tzname);
dyn_tzinfo.DynamicDaylightTimeDisabled = FALSE;
ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError());
ok(tzinfo.Bias == 180, "Expected Bias 180, got %d\n", tzinfo.Bias);
ok(tzinfo.StandardDate.wMonth == 10, "Expected standard month 10, got %d\n", tzinfo.StandardDate.wMonth);
std_day = day_of_month(&tzinfo.StandardDate, 2015);
ok(std_day == 24, "Expected standard day 24, got %d\n", std_day);
ok(tzinfo.StandardBias == 0, "Expected StandardBias 0, got %d\n", tzinfo.StandardBias);
ok(tzinfo.DaylightDate.wMonth == 3, "Expected daylight month 3, got %d\n", tzinfo.DaylightDate.wMonth);
dlt_day = day_of_month(&tzinfo.DaylightDate, 2015);
ok(dlt_day == 28, "Expected daylight day 28, got %d\n", dlt_day);
ok(tzinfo.DaylightBias == -60, "Expected DaylightBias -60, got %d\n", tzinfo.DaylightBias);
ret = pGetTimeZoneInformationForYear(2016, &dyn_tzinfo, &tzinfo2);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %u\n", GetLastError());
ok(!lstrcmpW(tzinfo.StandardName, tzinfo2.StandardName),
"Got differing StandardName values %s and %s\n",
wine_dbgstr_w(tzinfo.StandardName), wine_dbgstr_w(tzinfo2.StandardName));
ok(!lstrcmpW(tzinfo.DaylightName, tzinfo2.DaylightName),
"Got differing DaylightName values %s and %s\n",
wine_dbgstr_w(tzinfo.DaylightName), wine_dbgstr_w(tzinfo2.DaylightName));
memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo));
lstrcpyW(dyn_tzinfo.TimeZoneKeyName, dlt_tzname);
lstrcpyW(dyn_tzinfo.TimeZoneKeyName, L"Greenland Daylight Time");
SetLastError(0xdeadbeef);
ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo);
if (ret)
broken_test = TRUE;
ok((ret == FALSE && GetLastError() == ERROR_FILE_NOT_FOUND) ||
broken(ret == TRUE) /* vista,7 */,
"GetTimeZoneInformationForYear err %u\n", GetLastError());
broken(broken_test) /* vista,7 */,
"GetTimeZoneInformationForYear err %lu\n", GetLastError());
memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo));
lstrcpyW(dyn_tzinfo.TimeZoneKeyName, L"Altai Standard Time");
SetLastError(0xdeadbeef);
ret = pGetTimeZoneInformationForYear(2015, &dyn_tzinfo, &tzinfo);
if (!ret && GetLastError() == ERROR_FILE_NOT_FOUND)
broken_test = TRUE;
ok(ret == TRUE || broken(broken_test) /* before 10 1809 */,
"GetTimeZoneInformationForYear err %lu\n", GetLastError());
if (broken(broken_test))
{
win_skip("Old Windows version\n");
return;
}
for (i = 0; i < ARRAY_SIZE(test_data); i++)
{
memset(&dyn_tzinfo, 0xaa, sizeof(dyn_tzinfo));
memset(&tzinfo, 0xbb, sizeof(tzinfo));
lstrcpyW(dyn_tzinfo.TimeZoneKeyName, test_data[i].tzname);
dyn_tzinfo.DynamicDaylightTimeDisabled = FALSE;
ret = pGetTimeZoneInformationForYear(test_data[i].year, &dyn_tzinfo, &tzinfo);
ok(ret == TRUE, "GetTimeZoneInformationForYear failed, err %lu, for %s\n", GetLastError(), wine_dbgstr_w(test_data[i].tzname));
if (!ret)
continue;
ok(tzinfo.Bias == test_data[i].bias, "Expected bias %ld, got %ld, for %s\n",
test_data[i].bias, tzinfo.Bias, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.StandardDate.wMonth == test_data[i].std_month, "Expected standard month %d, got %d, for %s\n",
test_data[i].std_month, tzinfo.StandardDate.wMonth, wine_dbgstr_w(test_data[i].tzname));
std_day = day_of_month(&tzinfo.StandardDate, test_data[i].year);
ok(std_day == test_data[i].std_day, "Expected standard day %d, got %d, for %s\n",
test_data[i].std_day, std_day, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.StandardBias == test_data[i].std_bias, "Expected standard bias %ld, got %ld, for %s\n",
test_data[i].std_bias, tzinfo.StandardBias, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.DaylightDate.wMonth == test_data[i].dlt_month, "Expected daylight month %d, got %d, for %s\n",
test_data[i].dlt_month, tzinfo.DaylightDate.wMonth, wine_dbgstr_w(test_data[i].tzname));
dlt_day = day_of_month(&tzinfo.DaylightDate, test_data[i].year);
ok(dlt_day == test_data[i].dlt_day, "Expected daylight day %d, got %d, for %s\n",
test_data[i].dlt_day, dlt_day, wine_dbgstr_w(test_data[i].tzname));
ok(tzinfo.DaylightBias == test_data[i].dlt_bias, "Expected daylight bias %ld, got %ld, for %s\n",
test_data[i].dlt_bias, tzinfo.DaylightBias, wine_dbgstr_w(test_data[i].tzname));
if (i > 0 && test_data[i-1].tzname == test_data[i].tzname)
{
ok(!lstrcmpW(tzinfo.StandardName, tzinfo2.StandardName),
"Got differing StandardName values %s and %s\n",
wine_dbgstr_w(tzinfo.StandardName), wine_dbgstr_w(tzinfo2.StandardName));
ok(!lstrcmpW(tzinfo.DaylightName, tzinfo2.DaylightName),
"Got differing DaylightName values %s and %s\n",
wine_dbgstr_w(tzinfo.DaylightName), wine_dbgstr_w(tzinfo2.DaylightName));
}
memcpy(&tzinfo2, &tzinfo, sizeof(tzinfo2));
}
}
static void test_GetTickCount(void)
{
DWORD t1, t2, t3;
int i = 0;
if (!pNtGetTickCount)
{
win_skip("NtGetTickCount not implemented\n");
return;
}
do
{
t1 = pNtGetTickCount();
t2 = GetTickCount();
t3 = pNtGetTickCount();
} while(t3 < t1 && i++ < 1); /* allow for wrap, but only once */
ok(t1 <= t2, "out of order %ld %ld\n", t1, t2);
ok(t2 <= t3, "out of order %ld %ld\n", t2, t3);
}
BOOL (WINAPI *pQueryUnbiasedInterruptTime)(ULONGLONG *time);
BOOL (WINAPI *pRtlQueryUnbiasedInterruptTime)(ULONGLONG *time);
static void test_QueryUnbiasedInterruptTime(void)
{
ULONGLONG time;
BOOL ret;
if (pQueryUnbiasedInterruptTime)
{
SetLastError( 0xdeadbeef );
ret = pQueryUnbiasedInterruptTime( &time );
ok( ret, "QueryUnbiasedInterruptTime failed err %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
ret = pQueryUnbiasedInterruptTime( NULL );
ok( !ret, "QueryUnbiasedInterruptTime succeeded\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
}
else win_skip( "QueryUnbiasedInterruptTime not supported\n" );
if (pRtlQueryUnbiasedInterruptTime)
{
SetLastError( 0xdeadbeef );
ret = pRtlQueryUnbiasedInterruptTime( &time );
ok( ret, "RtlQueryUnbiasedInterruptTime failed err %lu\n", GetLastError() );
SetLastError( 0xdeadbeef );
ret = pRtlQueryUnbiasedInterruptTime( NULL );
ok( !ret, "RtlQueryUnbiasedInterruptTime succeeded\n" );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
}
else win_skip( "RtlQueryUnbiasedInterruptTime not supported\n" );
}
static void test_processor_idle_cycle_time(void)
{
#ifdef __REACTOS__
skip("Cannot build test_processor_idle_cycle_time() until kernelbase is synced.\n");
#else
unsigned int cpu_count = NtCurrentTeb()->Peb->NumberOfProcessors;
ULONG64 buffer[64];
ULONG size;
DWORD err;
BOOL bret;
SetLastError( 0xdeadbeef );
size = 0;
bret = QueryIdleProcessorCycleTime( &size, NULL );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size );
size = 4;
memset( buffer, 0xcc, sizeof(buffer) );
SetLastError( 0xdeadbeef );
bret = QueryIdleProcessorCycleTime( &size, NULL );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == 4, "got %lu.\n", size );
ok( buffer[0] == 0xcccccccccccccccc, "got %#I64x.\n", buffer[0] );
size = sizeof(buffer);
SetLastError( 0xdeadbeef );
bret = QueryIdleProcessorCycleTime( &size, NULL );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == sizeof(buffer), "got %lu.\n", size );
size = sizeof(buffer);
SetLastError( 0xdeadbeef );
bret = QueryIdleProcessorCycleTime( &size, buffer );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size );
SetLastError( 0xdeadbeef );
size = 0;
bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size );
size = 4;
SetLastError( 0xdeadbeef );
bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == 4, "got %lu.\n", size );
size = sizeof(buffer);
SetLastError( 0xdeadbeef );
bret = QueryIdleProcessorCycleTimeEx( 0, &size, NULL );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == sizeof(buffer), "got %lu.\n", size );
size = sizeof(buffer);
SetLastError( 0xdeadbeef );
bret = QueryIdleProcessorCycleTimeEx( 0, &size, buffer );
err = GetLastError();
ok( bret == TRUE && err == 0xdeadbeef, "got %d, %ld.\n", bret, err );
ok( size == cpu_count * sizeof(ULONG64), "got %lu.\n", size );
#endif
}
START_TEST(time)
{
HMODULE hKernel = GetModuleHandleA("kernel32");
HMODULE hntdll = GetModuleHandleA("ntdll");
pTzSpecificLocalTimeToSystemTime = (void *)GetProcAddress(hKernel, "TzSpecificLocalTimeToSystemTime");
pSystemTimeToTzSpecificLocalTime = (void *)GetProcAddress( hKernel, "SystemTimeToTzSpecificLocalTime");
pGetSystemTimes = (void *)GetProcAddress( hKernel, "GetSystemTimes");
@@ -1001,6 +1243,9 @@ START_TEST(time)
pGetDynamicTimeZoneInformation = (void *)GetProcAddress(hKernel, "GetDynamicTimeZoneInformation");
pGetSystemTimePreciseAsFileTime = (void *)GetProcAddress(hKernel, "GetSystemTimePreciseAsFileTime");
pGetTimeZoneInformationForYear = (void *)GetProcAddress(hKernel, "GetTimeZoneInformationForYear");
pQueryUnbiasedInterruptTime = (void *)GetProcAddress(hKernel, "QueryUnbiasedInterruptTime");
pNtGetTickCount = (void *)GetProcAddress(hntdll, "NtGetTickCount");
pRtlQueryUnbiasedInterruptTime = (void *)GetProcAddress(hntdll, "RtlQueryUnbiasedInterruptTime");
test_conversions();
test_invalid_arg();
@@ -1012,6 +1257,10 @@ START_TEST(time)
test_FileTimeToDosDateTime();
test_GetCalendarInfo();
test_GetDynamicTimeZoneInformation();
test_GetSystemTimeAsFileTime();
test_GetSystemTimePreciseAsFileTime();
test_GetTimeZoneInformationForYear();
test_GetTickCount();
test_QueryUnbiasedInterruptTime();
test_processor_idle_cycle_time();
}
+192 -21
View File
@@ -20,53 +20,224 @@
#include "wine/test.h"
#include "winbase.h"
#include "winternl.h"
#include "winuser.h"
static void test_timer(void)
{
HANDLE (WINAPI *pCreateWaitableTimerA)( SECURITY_ATTRIBUTES*, BOOL, LPSTR );
BOOL (WINAPI *pSetWaitableTimer)(HANDLE, LARGE_INTEGER*, LONG, PTIMERAPCROUTINE, LPVOID, BOOL);
HMODULE hker = GetModuleHandleA("kernel32.dll");
HANDLE handle;
BOOL r;
LARGE_INTEGER due;
pCreateWaitableTimerA = (void*)GetProcAddress( hker, "CreateWaitableTimerA");
if( !pCreateWaitableTimerA )
{
win_skip("CreateWaitableTimerA is not available\n");
return;
}
pSetWaitableTimer = (void*)GetProcAddress( hker, "SetWaitableTimer");
if( !pSetWaitableTimer )
{
win_skip("SetWaitableTimer is not available\n");
return;
}
/* try once with a positive number */
handle = pCreateWaitableTimerA( NULL, 0, NULL );
handle = CreateWaitableTimerA( NULL, 0, NULL );
ok( handle != NULL, "failed to create waitable timer with no name\n" );
due.QuadPart = 10000;
r = pSetWaitableTimer( handle, &due, 0x1f4, NULL, NULL, FALSE );
r = SetWaitableTimer( handle, &due, 0x1f4, NULL, NULL, FALSE );
ok( r, "failed to set timer\n");
CloseHandle( handle );
/* try once with a negative number */
handle = pCreateWaitableTimerA( NULL, 0, NULL );
handle = CreateWaitableTimerA( NULL, 0, NULL );
ok( handle != NULL, "failed to create waitable timer with no name\n" );
due.QuadPart = -10000;
r = pSetWaitableTimer( handle, &due, 0x1f4, NULL, NULL, FALSE );
r = SetWaitableTimer( handle, &due, 0x1f4, NULL, NULL, FALSE );
ok( r, "failed to set timer\n");
CloseHandle( handle );
}
#define TICKSPERSEC 10000000
static BOOL adjust_system_time(int sec)
{
ULARGE_INTEGER uli;
SYSTEMTIME st;
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
uli.u.LowPart = ft.dwLowDateTime;
uli.u.HighPart = ft.dwHighDateTime;
uli.QuadPart += (LONGLONG)sec * TICKSPERSEC;
ft.dwLowDateTime = uli.u.LowPart;
ft.dwHighDateTime = uli.u.HighPart;
if (!FileTimeToSystemTime(&ft, &st))
return FALSE;
return SetSystemTime(&st);
}
static DWORD WINAPI thread_WaitForSingleObject(void *arg)
{
HANDLE event;
DWORD t, r;
event = CreateEventW(NULL, FALSE, FALSE, NULL);
ok(event != NULL, "CreateEvent failed\n");
t = GetTickCount();
r = WaitForSingleObject(event, 3000);
ok(r == WAIT_TIMEOUT, "WiatForSingleObject returned %lx\n", r);
CloseHandle(event);
t = GetTickCount() - t;
ok(t > 2000, "t = %ld\n", t);
return 0;
}
static DWORD WINAPI thread_Sleep(void *arg)
{
DWORD t = GetTickCount();
Sleep(3000);
t = GetTickCount() - t;
ok(t > 2000, "t = %ld\n", t);
return 0;
}
static DWORD WINAPI thread_SleepEx(void *arg)
{
DWORD t = GetTickCount();
SleepEx(3000, TRUE);
t = GetTickCount() - t;
ok(t > 2000, "t = %ld\n", t);
return 0;
}
static DWORD WINAPI thread_WaitableTimer_rel(void *arg)
{
LARGE_INTEGER li;
HANDLE timer;
DWORD t, r;
li.QuadPart = -3 * TICKSPERSEC;
timer = CreateWaitableTimerA(NULL, TRUE, NULL);
ok(timer != NULL, "CreateWaitableTimer failed\n");
t = GetTickCount();
r = SetWaitableTimer(timer, &li, 0, NULL, NULL, FALSE);
ok(r, "SetWaitableTimer failed\n");
r = WaitForSingleObject(timer, INFINITE);
ok(r == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", r);
CloseHandle(timer);
t = GetTickCount() - t;
ok(t > 2000, "t = %ld\n", t);
return 0;
}
static DWORD WINAPI thread_WaitableTimer_abs(void *arg)
{
LARGE_INTEGER li;
HANDLE timer;
FILETIME ft;
DWORD t, r;
GetSystemTimeAsFileTime(&ft);
li.u.LowPart = ft.dwLowDateTime;
li.u.HighPart = ft.dwHighDateTime;
li.QuadPart += 3 * TICKSPERSEC;
timer = CreateWaitableTimerA(NULL, TRUE, NULL);
ok(timer != NULL, "CreateWaitableTimer failed\n");
t = GetTickCount();
r = SetWaitableTimer(timer, &li, 0, NULL, NULL, FALSE);
ok(r, "SetWaitableTimer failed\n");
r = WaitForSingleObject(timer, INFINITE);
ok(r == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", r);
CloseHandle(timer);
t = GetTickCount() - t;
ok(t < 2000, "t = %ld\n", t);
return 0;
}
static DWORD WINAPI thread_WaitableTimer_period(void *arg)
{
LARGE_INTEGER li;
HANDLE timer;
DWORD t, r;
li.QuadPart = -1;
timer = CreateWaitableTimerA(NULL, FALSE, NULL);
ok(timer != NULL, "CreateWaitableTimer failed\n");
t = GetTickCount();
r = SetWaitableTimer(timer, &li, 3000, NULL, NULL, FALSE);
ok(r, "SetWaitableTimer failed\n");
r = WaitForSingleObject(timer, INFINITE);
ok(r == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", r);
r = WaitForSingleObject(timer, INFINITE);
ok(r == WAIT_OBJECT_0, "WaitForSingleObject returned %ld\n", r);
CloseHandle(timer);
t = GetTickCount() - t;
ok(t > 2000, "t = %ld\n", t);
return 0;
}
static DWORD WINAPI thread_SetTimer(void *arg)
{
DWORD t = GetTickCount();
UINT_PTR timer;
MSG msg;
timer = SetTimer(NULL, 0, 3000, NULL);
ok(timer, "SetTimer failed (%ld)\n", GetLastError());
while (GetMessageW(&msg, NULL, 0, 0))
{
DispatchMessageW(&msg);
if (msg.message == WM_TIMER) break;
}
t = GetTickCount() - t;
ok(t > 2000, "t = %ld\n", t);
KillTimer(NULL, timer);
return 0;
}
static void test_timeouts(void)
{
HANDLE threads[7];
DWORD i;
if (!adjust_system_time(1))
{
skip("can't adjust system clock (%ld)\n", GetLastError());
return;
}
threads[0] = CreateThread(NULL, 0, thread_WaitForSingleObject, NULL, 0, NULL);
threads[1] = CreateThread(NULL, 0, thread_Sleep, NULL, 0, NULL);
threads[2] = CreateThread(NULL, 0, thread_SleepEx, NULL, 0, NULL);
threads[3] = CreateThread(NULL, 0, thread_WaitableTimer_rel, NULL, 0, NULL);
threads[4] = CreateThread(NULL, 0, thread_WaitableTimer_abs, NULL, 0, NULL);
threads[5] = CreateThread(NULL, 0, thread_WaitableTimer_period, NULL, 0, NULL);
threads[6] = CreateThread(NULL, 0, thread_SetTimer, NULL, 0, NULL);
for(i=0; i<ARRAY_SIZE(threads); i++)
ok(threads[i] != NULL, "CreateThread failed\n");
Sleep(500);
adjust_system_time(10);
for (i=0; i<ARRAY_SIZE(threads); i++)
{
WaitForSingleObject(threads[i], INFINITE);
CloseHandle(threads[i]);
}
adjust_system_time(-11);
}
START_TEST(timer)
{
test_timer();
test_timeouts();
}
+187 -19
View File
@@ -22,11 +22,14 @@
#include <stdlib.h>
#include <stdio.h>
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
#include "tlhelp32.h"
#include "wine/test.h"
#include "winuser.h"
#include "winternl.h"
static char selfname[MAX_PATH];
@@ -38,9 +41,12 @@ static BOOL (WINAPI *pProcess32First)(HANDLE, LPPROCESSENTRY32);
static BOOL (WINAPI *pProcess32Next)(HANDLE, LPPROCESSENTRY32);
static BOOL (WINAPI *pThread32First)(HANDLE, LPTHREADENTRY32);
static BOOL (WINAPI *pThread32Next)(HANDLE, LPTHREADENTRY32);
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
/* 1 minute should be more than enough */
#define WAIT_TIME (60 * 1000)
/* Specify the number of simultaneous threads to test */
#define NUM_THREADS 4
static DWORD WINAPI sub_thread(void* pmt)
{
@@ -118,11 +124,15 @@ static void test_process(DWORD curr_pid, DWORD sub_pcs_pid)
{
if (pe.th32ProcessID == curr_pid) found++;
if (pe.th32ProcessID == sub_pcs_pid) { childpos = num; found++; }
trace("PID=%x %s\n", pe.th32ProcessID, pe.szExeFile);
trace("PID=%lx %s\n", pe.th32ProcessID, pe.szExeFile);
num++;
} while (pProcess32Next( hSnapshot, &pe ));
}
#if defined(__REACTOS__) && defined(_WIN64)
ok(found == 2 || broken(found == 0) /* x86_64 */, "couldn't find self and/or sub-process in process list\n");
#else
ok(found == 2, "couldn't find self and/or sub-process in process list\n");
#endif
/* check that first really resets the enumeration */
found = 0;
@@ -132,11 +142,15 @@ static void test_process(DWORD curr_pid, DWORD sub_pcs_pid)
{
if (pe.th32ProcessID == curr_pid) found++;
if (pe.th32ProcessID == sub_pcs_pid) found++;
trace("PID=%x %s\n", pe.th32ProcessID, pe.szExeFile);
trace("PID=%lx %s\n", pe.th32ProcessID, pe.szExeFile);
num--;
} while (pProcess32Next( hSnapshot, &pe ));
}
#if defined(__REACTOS__) && defined(_WIN64)
ok(found == 2 || broken(found == 0) /* x86_64 */, "couldn't find self and/or sub-process in process list\n");
#else
ok(found == 2, "couldn't find self and/or sub-process in process list\n");
#endif
ok(!num, "mismatch in counting\n");
/* one broken program does Process32First() and does not expect anything
@@ -150,15 +164,169 @@ static void test_process(DWORD curr_pid, DWORD sub_pcs_pid)
ok(!pProcess32First( hSnapshot, &pe ), "shouldn't return a process\n");
}
static DWORD WINAPI get_id_thread(void* curr_pid)
{
HANDLE hSnapshot;
THREADENTRY32 te;
HANDLE ev, threads[NUM_THREADS];
DWORD thread_ids[NUM_THREADS];
DWORD thread_traversed[NUM_THREADS];
DWORD tid, first_tid = 0;
BOOL found = FALSE;
int i, matched_idx = -1;
ULONG buf_size = 0;
NTSTATUS status;
BYTE* pcs_buffer = NULL;
DWORD pcs_offset = 0;
SYSTEM_PROCESS_INFORMATION* spi = NULL;
ev = CreateEventW(NULL, TRUE, FALSE, NULL);
ok(ev != NULL, "Cannot create event\n");
for (i = 0; i < NUM_THREADS; i++)
{
threads[i] = CreateThread(NULL, 0, sub_thread, ev, 0, &tid);
ok(threads[i] != NULL, "Cannot create thread\n");
thread_ids[i] = tid;
}
hSnapshot = pCreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
ok(hSnapshot != NULL, "Cannot create snapshot\n");
/* Check that this current process is enumerated */
te.dwSize = sizeof(te);
ok(pThread32First(hSnapshot, &te), "Thread cannot traverse\n");
do
{
if (found)
{
if (te.th32OwnerProcessID != PtrToUlong(curr_pid)) break;
if (matched_idx >= 0)
{
thread_traversed[matched_idx++] = te.th32ThreadID;
if (matched_idx >= NUM_THREADS) break;
}
else if (thread_ids[0] == te.th32ThreadID)
{
matched_idx = 0;
thread_traversed[matched_idx++] = te.th32ThreadID;
}
}
else if (te.th32OwnerProcessID == PtrToUlong(curr_pid))
{
found = TRUE;
first_tid = te.th32ThreadID;
}
}
while (pThread32Next(hSnapshot, &te));
ok(found, "Couldn't find self and/or sub-process in process list\n");
/* Check if the thread order is strictly consistent */
found = FALSE;
for (i = 0; i < NUM_THREADS; i++)
{
if (thread_traversed[i] != thread_ids[i])
{
found = TRUE;
break;
}
/* Reset data */
thread_traversed[i] = 0;
}
ok(found == FALSE, "The thread order is not strictly consistent\n");
/* Determine the order by NtQuerySystemInformation function */
while ((status = NtQuerySystemInformation(SystemProcessInformation,
pcs_buffer, buf_size, &buf_size)) == STATUS_INFO_LENGTH_MISMATCH)
{
free(pcs_buffer);
pcs_buffer = malloc(buf_size);
}
ok(status == STATUS_SUCCESS, "got %#lx\n", status);
found = FALSE;
matched_idx = -1;
do
{
spi = (SYSTEM_PROCESS_INFORMATION*)&pcs_buffer[pcs_offset];
if (spi->UniqueProcessId == curr_pid)
{
found = TRUE;
break;
}
pcs_offset += spi->NextEntryOffset;
} while (spi->NextEntryOffset != 0);
ok(found && spi, "No process found\n");
for (i = 0; i < spi->dwThreadCount; i++)
{
tid = HandleToULong(spi->ti[i].ClientId.UniqueThread);
if (matched_idx > 0)
{
thread_traversed[matched_idx++] = tid;
if (matched_idx >= NUM_THREADS) break;
}
else if (tid == thread_ids[0])
{
matched_idx = 0;
thread_traversed[matched_idx++] = tid;
}
}
free(pcs_buffer);
ok(matched_idx > 0, "No thread id match found\n");
found = FALSE;
for (i = 0; i < NUM_THREADS; i++)
{
if (thread_traversed[i] != thread_ids[i])
{
found = TRUE;
break;
}
}
ok(found == FALSE, "wrong order in NtQuerySystemInformation function\n");
SetEvent(ev);
WaitForMultipleObjects( NUM_THREADS, threads, TRUE, WAIT_TIME );
for (i = 0; i < NUM_THREADS; i++)
CloseHandle(threads[i]);
CloseHandle(ev);
CloseHandle(hSnapshot);
return first_tid;
}
static void test_main_thread(DWORD curr_pid, DWORD main_tid)
{
HANDLE thread;
DWORD tid = 0;
int error;
/* Check that the main thread id is first one in this thread. */
tid = get_id_thread(ULongToPtr(curr_pid));
ok(tid == main_tid, "The first thread id returned is not the main thread id\n");
/* Check that the main thread id is first one in other thread. */
thread = CreateThread(NULL, 0, get_id_thread, ULongToPtr(curr_pid), 0, NULL);
error = WaitForSingleObject(thread, WAIT_TIME);
ok(error == WAIT_OBJECT_0, "Thread did not complete within timelimit\n");
ok(GetExitCodeThread(thread, &tid), "Could not retrieve exit code\n");
ok(tid == main_tid, "The first thread id returned is not the main thread id\n");
}
static void test_thread(DWORD curr_pid, DWORD sub_pcs_pid)
{
HANDLE hSnapshot;
THREADENTRY32 te;
MODULEENTRY32 me;
int num = 0;
unsigned curr_found = 0;
unsigned sub_found = 0;
hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
ok(hSnapshot != NULL, "Cannot create snapshot\n");
@@ -171,8 +339,7 @@ static void test_thread(DWORD curr_pid, DWORD sub_pcs_pid)
if (te.th32OwnerProcessID == curr_pid) curr_found++;
if (te.th32OwnerProcessID == sub_pcs_pid) sub_found++;
if (winetest_debug > 1)
trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
num++;
trace("PID=%lx TID=%lx %ld\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
} while (pThread32Next( hSnapshot, &te ));
}
ok(curr_found, "couldn't find self in thread list\n");
@@ -188,8 +355,7 @@ static void test_thread(DWORD curr_pid, DWORD sub_pcs_pid)
if (te.th32OwnerProcessID == curr_pid) curr_found++;
if (te.th32OwnerProcessID == sub_pcs_pid) sub_found++;
if (winetest_debug > 1)
trace("PID=%x TID=%x %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
num--;
trace("PID=%lx TID=%lx %ld\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
} while (pThread32Next( hSnapshot, &te ));
}
ok(curr_found, "couldn't find self in thread list\n");
@@ -217,8 +383,6 @@ static const char* sub_expected_modules[] =
"ntdll.dll"
};
#define NUM_OF(x) (sizeof(x) / sizeof(x[0]))
static void test_module(DWORD pid, const char* expected[], unsigned num_expected)
{
HANDLE hSnapshot;
@@ -229,7 +393,7 @@ static void test_module(DWORD pid, const char* expected[], unsigned num_expected
unsigned i;
int num = 0;
ok(NUM_OF(found) >= num_expected, "Internal: bump found[] size\n");
ok(ARRAY_SIZE(found) >= num_expected, "Internal: bump found[] size\n");
hSnapshot = pCreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
ok(hSnapshot != NULL, "Cannot create snapshot\n");
@@ -240,7 +404,7 @@ static void test_module(DWORD pid, const char* expected[], unsigned num_expected
{
do
{
trace("PID=%x base=%p size=%x %s %s\n",
trace("PID=%lx base=%p size=%lx %s %s\n",
me.th32ProcessID, me.modBaseAddr, me.modBaseSize, me.szExePath, me.szModule);
ok(me.th32ProcessID == pid, "wrong returned process id\n");
for (i = 0; i < num_expected; i++)
@@ -259,7 +423,7 @@ static void test_module(DWORD pid, const char* expected[], unsigned num_expected
{
do
{
trace("PID=%x base=%p size=%x %s %s\n",
trace("PID=%lx base=%p size=%lx %s %s\n",
me.th32ProcessID, me.modBaseAddr, me.modBaseSize, me.szExePath, me.szModule);
for (i = 0; i < num_expected; i++)
if (!lstrcmpiA(expected[i], me.szModule)) found[i]++;
@@ -286,13 +450,14 @@ START_TEST(toolhelp)
DWORD pid = GetCurrentProcessId();
int r;
char *p, module[MAX_PATH];
char buffer[MAX_PATH];
char buffer[MAX_PATH + 21];
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION info;
STARTUPINFOA startup;
HANDLE ev1, ev2;
DWORD w;
HANDLE hkernel32 = GetModuleHandleA("kernel32");
HANDLE hntdll = GetModuleHandleA("ntdll.dll");
pCreateToolhelp32Snapshot = (VOID *) GetProcAddress(hkernel32, "CreateToolhelp32Snapshot");
pModule32First = (VOID *) GetProcAddress(hkernel32, "Module32First");
@@ -301,11 +466,13 @@ START_TEST(toolhelp)
pProcess32Next = (VOID *) GetProcAddress(hkernel32, "Process32Next");
pThread32First = (VOID *) GetProcAddress(hkernel32, "Thread32First");
pThread32Next = (VOID *) GetProcAddress(hkernel32, "Thread32Next");
pNtQuerySystemInformation = (VOID *) GetProcAddress(hntdll, "NtQuerySystemInformation");
if (!pCreateToolhelp32Snapshot ||
!pModule32First || !pModule32Next ||
!pProcess32First || !pProcess32Next ||
!pThread32First || !pThread32Next)
!pThread32First || !pThread32Next ||
!pNtQuerySystemInformation)
{
win_skip("Needed functions are not available, most likely running on Windows NT\n");
return;
@@ -327,7 +494,7 @@ START_TEST(toolhelp)
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
sprintf(buffer, "%s tests/toolhelp.c %lu %lu", selfname, (DWORD_PTR)ev1, (DWORD_PTR)ev2);
sprintf(buffer, "%s toolhelp %Iu %Iu", selfname, (DWORD_PTR)ev1, (DWORD_PTR)ev2);
ok(CreateProcessA(NULL, buffer, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &info), "CreateProcess\n");
/* wait for child to be initialized */
w = WaitForSingleObject(ev1, WAIT_TIME);
@@ -341,9 +508,10 @@ START_TEST(toolhelp)
test_process(pid, info.dwProcessId);
test_thread(pid, info.dwProcessId);
test_module(pid, curr_expected_modules, NUM_OF(curr_expected_modules));
test_module(info.dwProcessId, sub_expected_modules, NUM_OF(sub_expected_modules));
test_main_thread(pid, GetCurrentThreadId());
test_module(pid, curr_expected_modules, ARRAY_SIZE(curr_expected_modules));
test_module(info.dwProcessId, sub_expected_modules, ARRAY_SIZE(sub_expected_modules));
SetEvent(ev2);
winetest_wait_child_process( info.hProcess );
wait_child_process( info.hProcess );
}
+465 -19
View File
@@ -18,16 +18,28 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "ntstatus.h"
#define WIN32_NO_STATUS
#include "wine/test.h"
#include "winbase.h"
#include "winternl.h"
#include "appmodel.h"
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
static UINT (WINAPI * pEnumSystemFirmwareTables)(DWORD, void *, DWORD);
static UINT (WINAPI * pGetSystemFirmwareTable)(DWORD, DWORD, void *, DWORD);
static LONG (WINAPI * pPackageIdFromFullName)(const WCHAR *, UINT32, UINT32 *, BYTE *);
static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
#define GET_PROC(func) \
p##func = (void *)GetProcAddress(hmod, #func);
/* Firmware table providers */
#define ACPI 0x41435049
#define FIRM 0x4649524D
#define RSMB 0x52534D42
static void init_function_pointers(void)
{
HMODULE hmod;
@@ -35,9 +47,13 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("kernel32.dll");
GET_PROC(GetProductInfo);
GET_PROC(EnumSystemFirmwareTables);
GET_PROC(GetSystemFirmwareTable);
GET_PROC(PackageIdFromFullName);
hmod = GetModuleHandleA("ntdll.dll");
GET_PROC(NtQuerySystemInformation);
GET_PROC(RtlGetVersion);
}
@@ -65,7 +81,12 @@ static void test_GetProductInfo(void)
DWORD *entry = table;
#if defined(__REACTOS__) && DLL_EXPORT_VERSION >= 0x600
/* FIXME: GetProductInfo is a STUB on ReactOS */
if (is_reactos() || !pGetProductInfo)
#else
if (!pGetProductInfo)
#endif
{
/* Not present before Vista */
win_skip("GetProductInfo() not available\n");
@@ -81,10 +102,10 @@ static void test_GetProductInfo(void)
if (entry[0] >= 6)
ok(res && (product > PRODUCT_UNDEFINED) && (product <= PRODUCT_ENTERPRISE_S_N_EVALUATION),
"got %d and 0x%x (expected TRUE and a valid PRODUCT_* value)\n", res, product);
"got %ld and 0x%lx (expected TRUE and a valid PRODUCT_* value)\n", res, product);
else
ok(!res && !product && (GetLastError() == 0xdeadbeef),
"got %d and 0x%x with 0x%x (expected FALSE and PRODUCT_UNDEFINED with LastError untouched)\n",
"got %ld and 0x%lx with 0x%lx (expected FALSE and PRODUCT_UNDEFINED with LastError untouched)\n",
res, product, GetLastError());
entry+= 4;
@@ -94,7 +115,7 @@ static void test_GetProductInfo(void)
SetLastError(0xdeadbeef);
res = pGetProductInfo(6, 1, 0, 0, NULL);
ok( (!res) && (GetLastError() == 0xdeadbeef),
"got %d with 0x%x (expected FALSE with LastError untouched\n", res, GetLastError());
"got %ld with 0x%lx (expected FALSE with LastError untouched\n", res, GetLastError());
}
static void test_GetVersionEx(void)
@@ -115,7 +136,7 @@ static void test_GetVersionEx(void)
ok(!ret, "Expected GetVersionExA to fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
GetLastError() == 0xdeadbeef /* Win9x */,
"Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
"Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %ld\n",
GetLastError());
SetLastError(0xdeadbeef);
@@ -124,7 +145,7 @@ static void test_GetVersionEx(void)
ok(!ret, "Expected GetVersionExA to fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
GetLastError() == 0xdeadbeef /* Win9x */,
"Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
"Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %ld\n",
GetLastError());
SetLastError(0xdeadbeef);
@@ -133,7 +154,7 @@ static void test_GetVersionEx(void)
ok(!ret, "Expected GetVersionExA to fail\n");
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER ||
GetLastError() == 0xdeadbeef /* Win9x */,
"Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %d\n",
"Expected ERROR_INSUFFICIENT_BUFFER or 0xdeadbeef (Win9x), got %ld\n",
GetLastError());
SetLastError(0xdeadbeef);
@@ -141,7 +162,7 @@ static void test_GetVersionEx(void)
ret = GetVersionExA(&infoA);
ok(ret, "Expected GetVersionExA to succeed\n");
ok(GetLastError() == 0xdeadbeef,
"Expected 0xdeadbeef, got %d\n", GetLastError());
"Expected 0xdeadbeef, got %ld\n", GetLastError());
SetLastError(0xdeadbeef);
infoExA.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
@@ -181,8 +202,6 @@ static void test_VerifyVersionInfo(void)
DWORD condition3;
DWORD typemask4;
DWORD condition4;
BOOL todo;
} verify_version_tests[] =
{
{
@@ -598,12 +617,12 @@ static void test_VerifyVersionInfo(void)
if (rtlinfo.dwMajorVersion != 6 || rtlinfo.dwMinorVersion != 2)
{
win_skip("GetVersionEx and VerifyVersionInfo are faking values\n");
skip("GetVersionEx and VerifyVersionInfo are faking values\n");
return;
}
}
for (i = 0; i < sizeof(verify_version_tests)/sizeof(verify_version_tests[0]); i++)
for (i = 0; i < ARRAY_SIZE(verify_version_tests); i++)
{
struct verify_version_test *test = &verify_version_tests[i];
DWORD srcinfo = test->srcinfo;
@@ -653,12 +672,9 @@ static void test_VerifyVersionInfo(void)
SetLastError(0xdeadbeef);
ret = VerifyVersionInfoA(&info, test->verifymask, mask);
todo_wine_if(test->todo)
{
ok(test->err ? !ret : ret, "%u: unexpected return value %d.\n", i, ret);
if (!ret)
ok(GetLastError() == test->err, "%u: unexpected error code %d, expected %d.\n", i, GetLastError(), test->err);
}
ok(GetLastError() == test->err, "%u: unexpected error code %ld, expected %ld.\n", i, GetLastError(), test->err);
}
/* test handling of version numbers */
@@ -669,21 +685,21 @@ static void test_VerifyVersionInfo(void)
ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
info.dwMinorVersion = 0;
info.wServicePackMajor = 10;
ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
info.wServicePackMajor = 0;
info.wServicePackMinor = 10;
ret = VerifyVersionInfoA(&info, VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
VerSetConditionMask(VerSetConditionMask(0, VER_MINORVERSION, VER_GREATER_EQUAL),
VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
/* test bad dwOSVersionInfoSize */
info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXA);
@@ -691,14 +707,444 @@ static void test_VerifyVersionInfo(void)
info.dwOSVersionInfoSize = 0;
ret = VerifyVersionInfoA(&info, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL));
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
ok(ret, "VerifyVersionInfoA failed with error %ld\n", GetLastError());
}
static void test_SystemFirmwareTable(void)
{
static const ULONG min_sfti_len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
ULONG expected_len;
UINT len;
NTSTATUS status;
SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
UCHAR *smbios_table;
if (!pGetSystemFirmwareTable || !pEnumSystemFirmwareTables)
{
win_skip("SystemFirmwareTable functions not available\n");
return;
}
sfti = HeapAlloc(GetProcessHeap(), 0, sizeof(*sfti));
ok(!!sfti, "Failed to allocate memory\n");
sfti->ProviderSignature = RSMB;
sfti->Action = SystemFirmwareTable_Get;
sfti->TableID = 0;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
if (expected_len == 0) /* xp, 2003 */
{
win_skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
}
#ifdef __REACTOS__
ok( status == STATUS_BUFFER_TOO_SMALL || broken(status == STATUS_INVALID_DEVICE_REQUEST) /* Vista x64 ROS testbot */, "NtQuerySystemInformation failed %lx\n", status );
#else
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
#endif
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
#ifdef __REACTOS__
ok( !status || broken(status == STATUS_INVALID_DEVICE_REQUEST) /* Vista x64 ROS testbot */, "NtQuerySystemInformation failed %lx\n", status );
#else
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
#endif
expected_len -= min_sfti_len;
ok( sfti->TableBufferLength == expected_len, "wrong len %lu/%lx\n",
sfti->TableBufferLength, expected_len );
len = pGetSystemFirmwareTable(RSMB, 0, NULL, 0);
ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
smbios_table = HeapAlloc(GetProcessHeap(), 0, expected_len);
len = pGetSystemFirmwareTable(RSMB, 0, smbios_table, expected_len);
ok(len == expected_len, "Expected length %lu, got %u\n", expected_len, len);
ok(len == 0 || !memcmp(smbios_table, sfti->TableBuffer, 6),
"Expected prologue %02x %02x %02x %02x %02x %02x, got %02x %02x %02x %02x %02x %02x\n",
sfti->TableBuffer[0], sfti->TableBuffer[1], sfti->TableBuffer[2],
sfti->TableBuffer[3], sfti->TableBuffer[4], sfti->TableBuffer[5],
smbios_table[0], smbios_table[1], smbios_table[2],
smbios_table[3], smbios_table[4], smbios_table[5]);
HeapFree(GetProcessHeap(), 0, smbios_table);
sfti->Action = SystemFirmwareTable_Enumerate;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, min_sfti_len, &expected_len);
ok( status == STATUS_BUFFER_TOO_SMALL, "NtQuerySystemInformation failed %lx\n", status );
sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
ok( !status, "NtQuerySystemInformation failed %lx\n", status );
ok( expected_len == min_sfti_len + sizeof(UINT), "wrong len %lu\n", expected_len );
ok( sfti->TableBufferLength == sizeof(UINT), "wrong len %lu\n", sfti->TableBufferLength );
ok( *(UINT *)sfti->TableBuffer == 0, "wrong table id %x\n", *(UINT *)sfti->TableBuffer );
len = pEnumSystemFirmwareTables( RSMB, NULL, 0 );
ok( len == sizeof(UINT), "wrong len %u\n", len );
smbios_table = malloc( len );
len = pEnumSystemFirmwareTables( RSMB, smbios_table, len );
ok( len == sizeof(UINT), "wrong len %u\n", len );
ok( *(UINT *)smbios_table == 0, "wrong table id %x\n", *(UINT *)smbios_table );
free( smbios_table );
HeapFree(GetProcessHeap(), 0, sfti);
}
static const struct
{
UINT32 code;
const WCHAR *name;
BOOL broken;
}
arch_data[] =
{
{PROCESSOR_ARCHITECTURE_INTEL, L"X86"},
{PROCESSOR_ARCHITECTURE_ARM, L"Arm"},
{PROCESSOR_ARCHITECTURE_AMD64, L"X64"},
{PROCESSOR_ARCHITECTURE_NEUTRAL, L"Neutral"},
{PROCESSOR_ARCHITECTURE_ARM64, L"Arm64", TRUE /* Before Win10. */},
{PROCESSOR_ARCHITECTURE_UNKNOWN, L"Unknown", TRUE /* Before Win10 1709. */},
};
static const WCHAR *arch_string_from_code(UINT32 arch)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(arch_data); ++i)
if (arch_data[i].code == arch)
return arch_data[i].name;
return NULL;
}
static unsigned int get_package_str_size(const WCHAR *str)
{
return str ? (lstrlenW(str) + 1) * sizeof(*str) : 0;
}
static unsigned int get_package_id_size(const PACKAGE_ID *id)
{
return sizeof(*id) + get_package_str_size(id->name)
+ get_package_str_size(id->resourceId) + 14 * sizeof(WCHAR);
}
static void packagefullname_from_packageid(WCHAR *buffer, size_t count, const PACKAGE_ID *id)
{
swprintf(buffer, count, L"%s_%u.%u.%u.%u_%s_%s_%s", id->name, id->version.Major,
id->version.Minor, id->version.Build, id->version.Revision,
arch_string_from_code(id->processorArchitecture), id->resourceId,
id->publisherId);
}
static void test_PackageIdFromFullName(void)
{
static const PACKAGE_ID test_package_id =
{
0, PROCESSOR_ARCHITECTURE_INTEL,
{{.Major = 1, .Minor = 2, .Build = 3, .Revision = 4}},
(WCHAR *)L"TestPackage", NULL,
(WCHAR *)L"TestResourceId", (WCHAR *)L"0abcdefghjkme"
};
UINT32 size, expected_size;
PACKAGE_ID test_id;
WCHAR fullname[512];
BYTE id_buffer[512];
unsigned int i;
PACKAGE_ID *id;
LONG ret;
if (!pPackageIdFromFullName)
{
win_skip("PackageIdFromFullName not available.\n");
return;
}
#ifdef __REACTOS__
if (GetNTVersion() < _WIN32_WINNT_WIN10) {
skip("test_PackageIdFromFullName() broken on Win8.1 and older\n");
return;
}
#endif
packagefullname_from_packageid(fullname, ARRAY_SIZE(fullname), &test_package_id);
id = (PACKAGE_ID *)id_buffer;
memset(id_buffer, 0xcc, sizeof(id_buffer));
expected_size = get_package_id_size(&test_package_id);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(fullname, 0, &size, id_buffer);
ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
ok(size == expected_size, "Got unexpected length %u, expected %u.\n", size, expected_size);
ok(!lstrcmpW(id->name, test_package_id.name), "Got unexpected name %s.\n", debugstr_w(id->name));
ok(!lstrcmpW(id->resourceId, test_package_id.resourceId), "Got unexpected resourceId %s.\n",
debugstr_w(id->resourceId));
ok(!lstrcmpW(id->publisherId, test_package_id.publisherId), "Got unexpected publisherId %s.\n",
debugstr_w(id->publisherId));
ok(!id->publisher, "Got unexpected publisher %s.\n", debugstr_w(id->publisher));
ok(id->processorArchitecture == PROCESSOR_ARCHITECTURE_INTEL, "Got unexpected processorArchitecture %u.\n",
id->processorArchitecture);
ok(id->version.Version == 0x0001000200030004, "Got unexpected Version %s.\n",
wine_dbgstr_longlong(id->version.Version));
ok((BYTE *)id->name == id_buffer + sizeof(*id), "Got unexpected name %p, buffer %p.\n", id->name, id_buffer);
ok((BYTE *)id->resourceId == (BYTE *)id->name + (lstrlenW(id->name) + 1) * 2,
"Got unexpected resourceId %p, buffer %p.\n", id->resourceId, id_buffer);
ok((BYTE *)id->publisherId == (BYTE *)id->resourceId + (lstrlenW(id->resourceId) + 1) * 2,
"Got unexpected publisherId %p, buffer %p.\n", id->resourceId, id_buffer);
ret = pPackageIdFromFullName(fullname, 0, NULL, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(NULL, 0, &size, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
ok(size == sizeof(id_buffer), "Got unexpected size %u.\n", size);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(fullname, 0, &size, NULL);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
ok(size == sizeof(id_buffer), "Got unexpected size %u.\n", size);
size = expected_size - 1;
ret = pPackageIdFromFullName(fullname, 0, &size, NULL);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %ld.\n", ret);
ok(size == expected_size - 1, "Got unexpected size %u.\n", size);
size = expected_size - 1;
ret = pPackageIdFromFullName(fullname, 0, &size, id_buffer);
ok(ret == ERROR_INSUFFICIENT_BUFFER, "Got unexpected ret %ld.\n", ret);
ok(size == expected_size, "Got unexpected size %u.\n", size);
size = 0;
ret = pPackageIdFromFullName(fullname, 0, &size, NULL);
ok(ret == ERROR_INSUFFICIENT_BUFFER, "Got unexpected ret %ld.\n", ret);
ok(size == expected_size, "Got unexpected size %u.\n", size);
for (i = 0; i < ARRAY_SIZE(arch_data); ++i)
{
test_id = test_package_id;
test_id.processorArchitecture = arch_data[i].code;
packagefullname_from_packageid(fullname, ARRAY_SIZE(fullname), &test_id);
size = expected_size;
ret = pPackageIdFromFullName(fullname, 0, &size, id_buffer);
ok(ret == ERROR_SUCCESS || broken(arch_data[i].broken && ret == ERROR_INVALID_PARAMETER),
"Got unexpected ret %lu.\n", ret);
if (ret != ERROR_SUCCESS)
continue;
ok(size == expected_size, "Got unexpected length %u, expected %u.\n", size, expected_size);
ok(id->processorArchitecture == arch_data[i].code, "Got unexpected processorArchitecture %u, arch %S.\n",
id->processorArchitecture, arch_data[i].name);
}
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_0abcdefghjkme", 0, &size, id_buffer);
ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_abcdefghjkme", 0, &size, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_0abcdefghjkmee", 0, &size, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3_X86_TestResourceId_0abcdefghjkme", 0, &size, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_TestResourceId_0abcdefghjkme_", 0, &size, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86__0abcdefghjkme", 0, &size, id_buffer);
ok(ret == ERROR_SUCCESS, "Got unexpected ret %lu.\n", ret);
ok(!lstrcmpW(id->resourceId, L""), "Got unexpected resourceId %s.\n", debugstr_w(id->resourceId));
size = sizeof(id_buffer);
ret = pPackageIdFromFullName(L"TestPackage_1.2.3.4_X86_0abcdefghjkme", 0, &size, id_buffer);
ok(ret == ERROR_INVALID_PARAMETER, "Got unexpected ret %lu.\n", ret);
}
#define TEST_VERSION_WIN7 1
#define TEST_VERSION_WIN8 2
#define TEST_VERSION_WIN8_1 4
#define TEST_VERSION_WIN10 8
static const struct
{
unsigned int pe_version_major, pe_version_minor;
unsigned int manifest_versions;
unsigned int expected_major, expected_minor;
}
test_pe_os_version_tests[] =
{
{ 4, 0, 0, 6, 2},
{ 4, 0, TEST_VERSION_WIN10, 10, 0},
{ 6, 3, TEST_VERSION_WIN8, 6, 2},
{10, 0, 0, 10, 0},
{ 6, 3, 0, 6, 3},
{ 6, 4, 0, 6, 3},
{ 9, 0, 0, 6, 3},
{11, 0, 0, 10, 0},
{10, 0,
TEST_VERSION_WIN7 | TEST_VERSION_WIN8 | TEST_VERSION_WIN8_1,
6, 3},
};
static void test_pe_os_version_child(unsigned int test)
{
OSVERSIONINFOEXA info;
BOOL ret;
info.dwOSVersionInfoSize = sizeof(info);
ret = GetVersionExA((OSVERSIONINFOA *)&info);
ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
ok(info.dwMajorVersion == test_pe_os_version_tests[test].expected_major,
"Test %u, expected major version %u, got %lu.\n", test, test_pe_os_version_tests[test].expected_major,
info.dwMajorVersion);
ok(info.dwMinorVersion == test_pe_os_version_tests[test].expected_minor,
"Test %u, expected minor version %u, got %lu.\n", test, test_pe_os_version_tests[test].expected_minor,
info.dwMinorVersion);
}
static void test_pe_os_version(void)
{
static const char manifest_header[] =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
"<assembly manifestVersion=\"1.0\" xmlns=\"urn:schemas-microsoft-com:asm.v1\""
" xmlns:asmv3=\"urn:schemas-microsoft-com:asm.v3\">\n"
"\t<compatibility xmlns=\"urn:schemas-microsoft-com:compatibility.v1\">\n"
"\t\t<application>\n";
static const char manifest_footer[] =
"\t\t</application>\n"
"\t</compatibility>\n"
"</assembly>\n";
static const char *version_guids[] =
{
"{35138b9a-5d96-4fbd-8e2d-a2440225f93a}",
"{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}",
"{1f676c76-80e1-4239-95bb-83d0f6d0da78}",
"{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}",
};
LONG hdr_offset, offset_major, offset_minor;
char str[MAX_PATH], tmp_exe_name[9];
RTL_OSVERSIONINFOEXW rtlinfo;
STARTUPINFOA si = { 0 };
PROCESS_INFORMATION pi;
DWORD result, code;
unsigned int i, j;
HANDLE file;
char **argv;
DWORD size;
BOOL ret;
winetest_get_mainargs( &argv );
if (!pRtlGetVersion)
{
win_skip("RtlGetVersion is not supported, skipping tests.\n");
return;
}
rtlinfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
ok(!pRtlGetVersion(&rtlinfo), "RtlGetVersion failed.\n");
if (rtlinfo.dwMajorVersion < 10)
{
skip("Too old Windows version %lu.%lu, skipping tests.\n", rtlinfo.dwMajorVersion, rtlinfo.dwMinorVersion);
return;
}
file = CreateFileA(argv[0], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %lu.\n", GetLastError());
SetFilePointer(file, 0x3c, NULL, FILE_BEGIN);
ReadFile(file, &hdr_offset, sizeof(hdr_offset), &size, NULL);
CloseHandle(file);
offset_major = hdr_offset + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)
+ FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, MajorOperatingSystemVersion);
offset_minor = hdr_offset + FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader)
+ FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, MinorOperatingSystemVersion);
si.cb = sizeof(si);
for (i = 0; i < ARRAY_SIZE(test_pe_os_version_tests); ++i)
{
sprintf(tmp_exe_name, "tmp%u.exe", i);
ret = CopyFileA(argv[0], tmp_exe_name, FALSE);
ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
file = CreateFileA(tmp_exe_name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %lu.\n", GetLastError());
SetFilePointer(file, offset_major, NULL, FILE_BEGIN);
WriteFile(file, &test_pe_os_version_tests[i].pe_version_major,
sizeof(test_pe_os_version_tests[i].pe_version_major), &size, NULL);
SetFilePointer(file, offset_minor, NULL, FILE_BEGIN);
WriteFile(file, &test_pe_os_version_tests[i].pe_version_minor,
sizeof(test_pe_os_version_tests[i].pe_version_minor), &size, NULL);
CloseHandle(file);
sprintf(str, "%s.manifest", tmp_exe_name);
file = CreateFileA(str, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %lu.\n", GetLastError());
WriteFile(file, manifest_header, strlen(manifest_header), &size, NULL);
for (j = 0; j < ARRAY_SIZE(version_guids); ++j)
{
if (test_pe_os_version_tests[i].manifest_versions & (1 << j))
{
sprintf(str, "\t\t\t<supportedOS Id=\"%s\"/>\n", version_guids[j]);
WriteFile(file, str, strlen(str), &size, NULL);
}
}
WriteFile(file, manifest_footer, strlen(manifest_footer), &size, NULL);
CloseHandle(file);
sprintf(str, "%s version pe_os_version %u", tmp_exe_name, i);
ret = CreateProcessA(NULL, str, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
CloseHandle(pi.hThread);
result = WaitForSingleObject(pi.hProcess, 10000);
ok(result == WAIT_OBJECT_0, "Got unexpected result %#lx.\n", result);
ret = GetExitCodeProcess(pi.hProcess, &code);
ok(ret, "Got unexpected ret %#x, GetLastError() %lu.\n", ret, GetLastError());
ok(!code, "Test %u failed.\n", i);
CloseHandle(pi.hProcess);
DeleteFileA(tmp_exe_name);
sprintf(str, "%s.manifest", tmp_exe_name);
DeleteFileA(str);
}
}
START_TEST(version)
{
char **argv;
int argc;
argc = winetest_get_mainargs( &argv );
init_function_pointers();
if (argc >= 4)
{
if (!strcmp(argv[2], "pe_os_version"))
{
unsigned int test;
test = atoi(argv[3]);
test_pe_os_version_child(test);
}
return;
}
test_GetProductInfo();
test_GetVersionEx();
test_VerifyVersionInfo();
test_pe_os_version();
test_SystemFirmwareTable();
test_PackageIdFromFullName();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="Wine.Test"/>
</assembly>
@@ -0,0 +1,32 @@
/* These definitions below are from Wine's headers, but for one reason or another
* cannot be currently imported. The ultimate goal should be to phase this header
* out entirely by importing these Wine headers unchanged into sdk/include/wine.
*
* Note: the header filenames correspond to Wine headers, they are often incompatible
* with our headers or Microsoft's corresponding header.
*/
/* NTDEF.H */
#define RTL_CONSTANT_STRING(s) { sizeof(s) - sizeof(s[0]), sizeof(s), (void*)s }
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
/* WINBASE.H */
typedef void *HPCON;
typedef enum _MACHINE_ATTRIBUTES
{
UserEnabled = 0x00000001,
KernelEnabled = 0x00000002,
Wow64Container = 0x00000004,
} MACHINE_ATTRIBUTES;
typedef struct _PROCESS_MACHINE_INFORMATION {
USHORT ProcessMachine;
USHORT Res0;
MACHINE_ATTRIBUTES MachineAttributes;
} PROCESS_MACHINE_INFORMATION;
/* WINCON.H */
WINBASEAPI BOOL WINAPI CloseConsoleHandle(HANDLE);
WINBASEAPI HANDLE WINAPI DuplicateConsoleHandle(HANDLE,DWORD,BOOL,DWORD);
WINBASEAPI HANDLE WINAPI GetConsoleInputWaitHandle(void);