[NTDLL_WINETEST]

* Sync with Wine 1.7.17.
CORE-8080

svn path=/trunk/; revision=62842
This commit is contained in:
Amine Khaldi
2014-04-20 13:44:55 +00:00
parent 05557a4614
commit cd9c73cf39
19 changed files with 1394 additions and 312 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
remove_definitions(-DWINVER=0x502 -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x502)
add_definitions(-D__ROS_LONG64__)
add_definitions(-D__WINESRC__)
list(APPEND SOURCE
atom.c
+3 -3
View File
@@ -25,7 +25,7 @@
#include <stdarg.h>
#include "ntstatus.h"
/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro
* definition errors when we get to winnt.h
*/
#define WIN32_NO_STATUS
@@ -432,7 +432,7 @@ static void test_Global(void)
{
NTSTATUS res;
RTL_ATOM atom;
ULONG ptr[(sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR) + sizeof(ULONG)) / sizeof(ULONG)];
char ptr[sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR)];
ATOM_BASIC_INFORMATION* abi = (ATOM_BASIC_INFORMATION*)ptr;
ULONG ptr_size = sizeof(ATOM_BASIC_INFORMATION) + 255 * sizeof(WCHAR);
@@ -445,7 +445,7 @@ static void test_Global(void)
memset( ptr, 0xcc, sizeof(ptr) );
res = pNtQueryInformationAtom( atom, AtomBasicInformation, (void*)ptr, ptr_size, NULL );
ok(!res, "atom lookup failed with status = 0x%x\n", res);
ok(!res, "atom lookup\n");
ok(!lstrcmpW(abi->Name, testAtom1), "ok strings\n");
ok(abi->NameLength == lstrlenW(testAtom1) * sizeof(WCHAR), "wrong string length\n");
ok(abi->Name[lstrlenW(testAtom1)] == 0, "wrong string termination %x\n", abi->Name[lstrlenW(testAtom1)]);
+3 -3
View File
@@ -69,7 +69,7 @@ static void test_ntncdf(void)
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
hEvent = CreateEvent( NULL, 0, 0, NULL );
hEvent = CreateEventA( NULL, 0, 0, NULL );
r = pNtNotifyChangeDirectoryFile(hdir,NULL,NULL,NULL,&iosb,NULL,0,0,0);
ok(r==STATUS_INVALID_PARAMETER, "should return invalid parameter\n");
@@ -197,7 +197,7 @@ static void test_ntncdf_async(void)
OPEN_EXISTING, fflags, NULL);
ok( hdir != INVALID_HANDLE_VALUE, "failed to open directory\n");
hEvent = CreateEvent( NULL, 0, 0, NULL );
hEvent = CreateEventA( NULL, 0, 0, NULL );
filter = FILE_NOTIFY_CHANGE_FILE_NAME;
filter |= FILE_NOTIFY_CHANGE_DIR_NAME;
@@ -312,7 +312,7 @@ static void test_ntncdf_async(void)
START_TEST(change)
{
HMODULE hntdll = GetModuleHandle("ntdll");
HMODULE hntdll = GetModuleHandleA("ntdll");
if (!hntdll)
{
win_skip("not running on NT, skipping test\n");
+2 -2
View File
@@ -120,11 +120,11 @@ static void tear_down_attribute_test(const char *testdirA)
continue;
sprintf(buf, "%s\\%s", testdirA, testfiles[i].name);
if (testfiles[i].attr & FILE_ATTRIBUTE_DIRECTORY) {
ret = RemoveDirectory(buf);
ret = RemoveDirectoryA(buf);
ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
"Failed to rmdir %s, error %d\n", buf, GetLastError());
} else {
ret = DeleteFile(buf);
ret = DeleteFileA(buf);
ok(ret || (GetLastError() == ERROR_PATH_NOT_FOUND),
"Failed to rm %s, error %d\n", buf, GetLastError());
}
+3 -3
View File
@@ -50,7 +50,7 @@
static ULONG (WINAPI *pRtlNtStatusToDosError)(NTSTATUS Status);
static int strict;
static int prepare_test(void)
static BOOL prepare_test(void)
{
HMODULE ntdll;
int argc;
@@ -61,12 +61,12 @@ static int prepare_test(void)
if (!pRtlNtStatusToDosError)
{
win_skip("RtlNtStatusToDosError is not available\n");
return 0;
return FALSE;
}
argc = winetest_get_mainargs(&argv);
strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
return 1;
return TRUE;
}
static void cmp_call(NTSTATUS win_nt, ULONG win32, const char* message)
+143 -7
View File
@@ -51,6 +51,13 @@ static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS,
static NTSTATUS (WINAPI *pNtSetInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG);
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#if defined(__x86_64__)
static BOOLEAN (CDECL *pRtlAddFunctionTable)(RUNTIME_FUNCTION*, DWORD, DWORD64);
static BOOLEAN (CDECL *pRtlDeleteFunctionTable)(RUNTIME_FUNCTION*);
static BOOLEAN (CDECL *pRtlInstallFunctionTableCallback)(DWORD64, DWORD64, DWORD, PGET_RUNTIME_FUNCTION_CALLBACK, PVOID, PCWSTR);
static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG64, ULONG64*, UNWIND_HISTORY_TABLE*);
#endif
#ifdef __i386__
#ifndef __WINE_WINTRNL_H
@@ -314,7 +321,7 @@ static DWORD rtlraiseexception_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTR
return ExceptionContinueSearch;
/* Eip in context is decreased by 1
* Increase it again, else execution will continue in the middle of a instruction */
* Increase it again, else execution will continue in the middle of an instruction */
if(rec->ExceptionCode == EXCEPTION_BREAKPOINT && (context->Eip == (DWORD)code_mem + 0xa))
context->Eip += 1;
return ExceptionContinueExecution;
@@ -731,7 +738,7 @@ static void test_debugger(void)
{
char cmdline[MAX_PATH];
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
STARTUPINFOA si = { 0 };
DEBUG_EVENT de;
DWORD continuestatus;
PVOID code_mem_address = NULL;
@@ -748,7 +755,7 @@ static void test_debugger(void)
}
sprintf(cmdline, "%s %s %s %p", my_argv[0], my_argv[1], "debuggee", &test_stage);
ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
ok(ret, "could not create child process error: %u\n", GetLastError());
if (!ret)
return;
@@ -796,7 +803,7 @@ static void test_debugger(void)
if (counter > 100)
{
ok(FALSE, "got way too many exceptions, probably caught in a infinite loop, terminating child\n");
ok(FALSE, "got way too many exceptions, probably caught in an infinite loop, terminating child\n");
pNtTerminateProcess(pi.hProcess, 1);
}
else if (counter >= 2) /* skip startup breakpoint */
@@ -1057,7 +1064,7 @@ static DWORD dpe_exception_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION
static void test_dpe_exceptions(void)
{
static char single_ret[] = {0xC3};
static const BYTE single_ret[] = {0xC3};
struct dpe_exception_info info;
NTSTATUS stat;
BOOL has_hw_support;
@@ -1065,7 +1072,7 @@ static void test_dpe_exceptions(void)
DWORD val;
ULONG len;
/* Query DEP with len to small */
/* Query DEP with len too small */
stat = pNtQueryInformationProcess(GetCurrentProcess(), ProcessExecuteFlags, &val, sizeof val - 1, &len);
if(stat == STATUS_INVALID_INFO_CLASS)
{
@@ -1447,6 +1454,122 @@ static void test_virtual_unwind(void)
call_virtual_unwind( i, &tests[i] );
}
static RUNTIME_FUNCTION* CALLBACK dynamic_unwind_callback( DWORD64 pc, PVOID context )
{
static const int code_offset = 1024;
static RUNTIME_FUNCTION runtime_func;
(*(DWORD *)context)++;
runtime_func.BeginAddress = code_offset + 16;
runtime_func.EndAddress = code_offset + 32;
runtime_func.UnwindData = 0;
return &runtime_func;
}
static void test_dynamic_unwind(void)
{
static const int code_offset = 1024;
char buf[sizeof(RUNTIME_FUNCTION) + 4];
RUNTIME_FUNCTION *runtime_func, *func;
ULONG_PTR table, base;
DWORD count;
/* Test RtlAddFunctionTable with aligned RUNTIME_FUNCTION pointer */
runtime_func = (RUNTIME_FUNCTION *)buf;
runtime_func->BeginAddress = code_offset;
runtime_func->EndAddress = code_offset + 16;
runtime_func->UnwindData = 0;
ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
"RtlAddFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
/* Lookup function outside of any function table */
base = 0xdeadbeef;
func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 16, &base, NULL );
ok( func == NULL,
"RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n", func );
ok( base == 0xdeadbeef,
"RtlLookupFunctionEntry modified base address, expected: 0xdeadbeef, got: %lx\n", base );
/* Test with pointer inside of our function */
base = 0xdeadbeef;
func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 8, &base, NULL );
ok( func == runtime_func,
"RtlLookupFunctionEntry didn't return expected function, expected: %p, got: %p\n", runtime_func, func );
ok( base == (ULONG_PTR)code_mem,
"RtlLookupFunctionEntry returned invalid base, expected: %lx, got: %lx\n", (ULONG_PTR)code_mem, base );
/* Test RtlDeleteFunctionTable */
ok( pRtlDeleteFunctionTable( runtime_func ),
"RtlDeleteFunctionTable failed for runtime_func = %p (aligned)\n", runtime_func );
ok( !pRtlDeleteFunctionTable( runtime_func ),
"RtlDeleteFunctionTable returned success for nonexistent table runtime_func = %p\n", runtime_func );
/* Unaligned RUNTIME_FUNCTION pointer */
runtime_func = (RUNTIME_FUNCTION *)((ULONG_PTR)buf | 0x3);
runtime_func->BeginAddress = code_offset;
runtime_func->EndAddress = code_offset + 16;
runtime_func->UnwindData = 0;
ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
"RtlAddFunctionTable failed for runtime_func = %p (unaligned)\n", runtime_func );
ok( pRtlDeleteFunctionTable( runtime_func ),
"RtlDeleteFunctionTable failed for runtime_func = %p (unaligned)\n", runtime_func );
/* Attempt to insert the same entry twice */
runtime_func = (RUNTIME_FUNCTION *)buf;
runtime_func->BeginAddress = code_offset;
runtime_func->EndAddress = code_offset + 16;
runtime_func->UnwindData = 0;
ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
"RtlAddFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
ok( pRtlAddFunctionTable( runtime_func, 1, (ULONG_PTR)code_mem ),
"RtlAddFunctionTable failed for runtime_func = %p (second attempt)\n", runtime_func );
ok( pRtlDeleteFunctionTable( runtime_func ),
"RtlDeleteFunctionTable failed for runtime_func = %p (first attempt)\n", runtime_func );
ok( pRtlDeleteFunctionTable( runtime_func ),
"RtlDeleteFunctionTable failed for runtime_func = %p (second attempt)\n", runtime_func );
ok( !pRtlDeleteFunctionTable( runtime_func ),
"RtlDeleteFunctionTable returned success for nonexistent table runtime_func = %p\n", runtime_func );
/* Test RtlInstallFunctionTableCallback with both low bits unset */
table = (ULONG_PTR)code_mem;
ok( !pRtlInstallFunctionTableCallback( table, (ULONG_PTR)code_mem, code_offset + 32, &dynamic_unwind_callback, (PVOID*)&count, NULL ),
"RtlInstallFunctionTableCallback returned success for table = %lx\n", table );
/* Test RtlInstallFunctionTableCallback with both low bits set */
table = (ULONG_PTR)code_mem | 0x3;
ok( pRtlInstallFunctionTableCallback( table, (ULONG_PTR)code_mem, code_offset + 32, &dynamic_unwind_callback, (PVOID*)&count, NULL ),
"RtlInstallFunctionTableCallback failed for table = %lx\n", table );
/* Lookup function outside of any function table */
count = 0;
base = 0xdeadbeef;
func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 32, &base, NULL );
ok( func == NULL,
"RtlLookupFunctionEntry returned unexpected function, expected: NULL, got: %p\n", func );
ok( base == 0xdeadbeef,
"RtlLookupFunctionEntry modified base address, expected: 0xdeadbeef, got: %lx\n", base );
ok( !count,
"RtlLookupFunctionEntry issued %d unexpected calls to dynamic_unwind_callback\n", count );
/* Test with pointer inside of our function */
count = 0;
base = 0xdeadbeef;
func = pRtlLookupFunctionEntry( (ULONG_PTR)code_mem + code_offset + 24, &base, NULL );
ok( func != NULL && func->BeginAddress == code_offset + 16 && func->EndAddress == code_offset + 32,
"RtlLookupFunctionEntry didn't return expected function, got: %p\n", func );
ok( base == (ULONG_PTR)code_mem,
"RtlLookupFunctionEntry returned invalid base, expected: %lx, got: %lx\n", (ULONG_PTR)code_mem, base );
ok( count == 1,
"RtlLookupFunctionEntry issued %d calls to dynamic_unwind_callback, expected: 1\n", count );
/* Clean up again */
ok( pRtlDeleteFunctionTable( (PRUNTIME_FUNCTION)table ),
"RtlDeleteFunctionTable failed for table = %p\n", (PVOID)table );
ok( !pRtlDeleteFunctionTable( (PRUNTIME_FUNCTION)table ),
"RtlDeleteFunctionTable returned success for nonexistent table = %p\n", (PVOID)table );
}
#endif /* __x86_64__ */
START_TEST(exception)
@@ -1473,7 +1596,7 @@ START_TEST(exception)
"NtQueryInformationProcess" );
pNtSetInformationProcess = (void*)GetProcAddress( hntdll,
"NtSetInformationProcess" );
pIsWow64Process = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
#ifdef __i386__
if (!pNtCurrentTeb)
@@ -1534,9 +1657,22 @@ START_TEST(exception)
test_dpe_exceptions();
#elif defined(__x86_64__)
pRtlAddFunctionTable = (void *)GetProcAddress( hntdll,
"RtlAddFunctionTable" );
pRtlDeleteFunctionTable = (void *)GetProcAddress( hntdll,
"RtlDeleteFunctionTable" );
pRtlInstallFunctionTableCallback = (void *)GetProcAddress( hntdll,
"RtlInstallFunctionTableCallback" );
pRtlLookupFunctionEntry = (void *)GetProcAddress( hntdll,
"RtlLookupFunctionEntry" );
test_virtual_unwind();
if (pRtlAddFunctionTable && pRtlDeleteFunctionTable && pRtlInstallFunctionTableCallback && pRtlLookupFunctionEntry)
test_dynamic_unwind();
else
skip( "Dynamic unwind functions not found\n" );
#endif
VirtualFree(code_mem, 0, MEM_FREE);
File diff suppressed because it is too large Load Diff
-45
View File
@@ -1903,13 +1903,6 @@ static void test_pack_PCSTR(void)
TEST_TARGET_ALIGN(PCSTR, 1)
}
static void test_pack_PCTSTR(void)
{
/* PCTSTR */
TEST_TYPE_SIZE (PCTSTR, 8)
TEST_TYPE_ALIGN (PCTSTR, 8)
}
static void test_pack_PCWCH(void)
{
/* PCWCH */
@@ -2574,13 +2567,6 @@ static void test_pack_PTOKEN_USER(void)
TEST_TARGET_ALIGN(PTOKEN_USER, 8)
}
static void test_pack_PTSTR(void)
{
/* PTSTR */
TEST_TYPE_SIZE (PTSTR, 8)
TEST_TYPE_ALIGN (PTSTR, 8)
}
static void test_pack_PULARGE_INTEGER(void)
{
/* PULARGE_INTEGER */
@@ -2935,13 +2921,6 @@ static void test_pack_SYSTEM_AUDIT_ACE(void)
TEST_FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart, 8)
}
static void test_pack_TCHAR(void)
{
/* TCHAR */
TEST_TYPE_SIZE (TCHAR, 1)
TEST_TYPE_ALIGN (TCHAR, 1)
}
static void test_pack_TOKEN_DEFAULT_DACL(void)
{
/* TOKEN_DEFAULT_DACL */
@@ -5271,13 +5250,6 @@ static void test_pack_PCSTR(void)
TEST_TARGET_ALIGN(PCSTR, 1)
}
static void test_pack_PCTSTR(void)
{
/* PCTSTR */
TEST_TYPE_SIZE (PCTSTR, 4)
TEST_TYPE_ALIGN (PCTSTR, 4)
}
static void test_pack_PCWCH(void)
{
/* PCWCH */
@@ -5940,13 +5912,6 @@ static void test_pack_PTOKEN_USER(void)
TEST_TARGET_ALIGN(PTOKEN_USER, 4)
}
static void test_pack_PTSTR(void)
{
/* PTSTR */
TEST_TYPE_SIZE (PTSTR, 4)
TEST_TYPE_ALIGN (PTSTR, 4)
}
static void test_pack_PULARGE_INTEGER(void)
{
/* PULARGE_INTEGER */
@@ -6301,13 +6266,6 @@ static void test_pack_SYSTEM_AUDIT_ACE(void)
TEST_FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart, 8)
}
static void test_pack_TCHAR(void)
{
/* TCHAR */
TEST_TYPE_SIZE (TCHAR, 1)
TEST_TYPE_ALIGN (TCHAR, 1)
}
static void test_pack_TOKEN_DEFAULT_DACL(void)
{
/* TOKEN_DEFAULT_DACL */
@@ -6935,7 +6893,6 @@ static void test_pack(void)
test_pack_PCCH();
test_pack_PCH();
test_pack_PCSTR();
test_pack_PCTSTR();
test_pack_PCWCH();
test_pack_PCWSTR();
test_pack_PEXCEPTION_POINTERS();
@@ -7022,7 +6979,6 @@ static void test_pack(void)
test_pack_PTOKEN_GROUPS();
test_pack_PTOKEN_PRIVILEGES();
test_pack_PTOKEN_USER();
test_pack_PTSTR();
test_pack_PULARGE_INTEGER();
test_pack_PVECTORED_EXCEPTION_HANDLER();
test_pack_PVOID();
@@ -7052,7 +7008,6 @@ static void test_pack(void)
test_pack_SSIZE_T();
test_pack_SYSTEM_ALARM_ACE();
test_pack_SYSTEM_AUDIT_ACE();
test_pack_TCHAR();
test_pack_TOKEN_DEFAULT_DACL();
test_pack_TOKEN_GROUPS();
test_pack_TOKEN_OWNER();
+24 -19
View File
@@ -55,7 +55,7 @@ static DWORD one_before_last_pid = 0;
static BOOL InitFunctionPtrs(void)
{
/* All needed functions are NT based, so using GetModuleHandle is a good check */
HMODULE hntdll = GetModuleHandle("ntdll");
HMODULE hntdll = GetModuleHandleA("ntdll");
if (!hntdll)
{
win_skip("Not running on NT\n");
@@ -78,7 +78,7 @@ static BOOL InitFunctionPtrs(void)
/* not present before XP */
pNtGetCurrentProcessorNumber = (void *) GetProcAddress(hntdll, "NtGetCurrentProcessorNumber");
pIsWow64Process = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
return TRUE;
}
@@ -110,7 +110,7 @@ static void test_query_basic(void)
ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_PARAMETER /* vista */,
"Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_PARAMETER, got %08x\n", status);
/* Use a existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
/* Use an existing class, correct length, a pointer to a buffer but no ReturnLength pointer */
trace("Check no ReturnLength pointer\n");
status = pNtQuerySystemInformation(SystemBasicInformation, &sbi, sizeof(sbi), NULL);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
@@ -259,7 +259,7 @@ static void test_query_process(void)
DWORD last_pid;
ULONG ReturnLength;
int i = 0, k = 0;
int is_nt = 0;
BOOL is_nt = FALSE;
SYSTEM_BASIC_INFORMATION sbi;
/* Copy of our winternl.h structure turned into a private one */
@@ -946,14 +946,14 @@ static void test_query_process_debug_port(int argc, char **argv)
DWORD_PTR debug_port = 0xdeadbeef;
char cmdline[MAX_PATH];
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
STARTUPINFOA si = { 0 };
NTSTATUS status;
BOOL ret;
sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
si.cb = sizeof(si);
ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
if (!ret) return;
@@ -1099,7 +1099,7 @@ static void test_query_process_image_file_name(void)
static void test_query_process_debug_object_handle(int argc, char **argv)
{
char cmdline[MAX_PATH];
STARTUPINFO si = {0};
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi;
BOOL ret;
HANDLE debug_object;
@@ -1108,7 +1108,7 @@ static void test_query_process_debug_object_handle(int argc, char **argv)
sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
si.cb = sizeof(si);
ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL,
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS, NULL,
NULL, &si, &pi);
ok(ret, "CreateProcess failed with last error %u\n", GetLastError());
if (!ret) return;
@@ -1198,14 +1198,14 @@ static void test_query_process_debug_flags(int argc, char **argv)
DWORD debug_flags = 0xdeadbeef;
char cmdline[MAX_PATH];
PROCESS_INFORMATION pi;
STARTUPINFO si = { 0 };
STARTUPINFOA si = { 0 };
NTSTATUS status;
BOOL ret;
sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
si.cb = sizeof(si);
ret = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi);
ret = CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi);
ok(ret, "CreateProcess failed, last error %#x.\n", GetLastError());
if (!ret) return;
@@ -1359,12 +1359,17 @@ static void test_mapprotection(void)
addr = NULL;
status = pNtMapViewOfSection ( h, GetCurrentProcess(), &addr, 0, 0, &offset, &count, ViewShare, 0, PAGE_READWRITE);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
#if defined(__x86_64__) || defined(__i386__)
memset (addr, 0xc3, 1); /* lret ... in both i386 and x86_64 */
*(unsigned char*)addr = 0xc3; /* lret ... in both i386 and x86_64 */
#elif defined(__arm__)
*(unsigned long*)addr = 0xe12fff1e; /* bx lr */
#else
ok(0, "Add a return opcode for your architecture or expect a crash in this test\n");
#endif
trace("trying to execute code in the readwrite only mapped anon file...\n");
f = addr;f();
trace("...done.\n");
#endif
status = pNtQueryVirtualMemory( GetCurrentProcess(), addr, MemoryBasicInformation, &info, sizeof(info), &retlen );
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
@@ -1390,7 +1395,7 @@ static void test_queryvirtualmemory(void)
char stackbuf[42];
HMODULE module;
module = GetModuleHandle( "ntdll.dll" );
module = GetModuleHandleA( "ntdll.dll" );
trace("Check flags of the PE header of NTDLL.DLL at %p\n", module);
status = pNtQueryVirtualMemory(NtCurrentProcess(), module, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
@@ -1402,7 +1407,7 @@ static void test_queryvirtualmemory(void)
ok (mbi.Type == MEM_IMAGE, "mbi.Type is 0x%x, expected 0x%x\n", mbi.Type, MEM_IMAGE);
trace("Check flags of a function entry in NTDLL.DLL at %p\n", pNtQueryVirtualMemory);
module = GetModuleHandle( "ntdll.dll" );
module = GetModuleHandleA( "ntdll.dll" );
status = pNtQueryVirtualMemory(NtCurrentProcess(), pNtQueryVirtualMemory, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1430,7 +1435,7 @@ static void test_queryvirtualmemory(void)
ok (mbi.Protect == PAGE_READWRITE, "mbi.Protect is 0x%x, expected 0x%x\n", mbi.Protect, PAGE_READWRITE);
trace("Check flags of read-only data at %p\n", teststring);
module = GetModuleHandle( NULL );
module = GetModuleHandleA( NULL );
status = pNtQueryVirtualMemory(NtCurrentProcess(), teststring, MemoryBasicInformation, &mbi, sizeof(MEMORY_BASIC_INFORMATION), &readcount);
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( readcount == sizeof(MEMORY_BASIC_INFORMATION), "Expected to read %d bytes, got %ld\n",(int)sizeof(MEMORY_BASIC_INFORMATION),readcount);
@@ -1475,7 +1480,7 @@ static void test_affinity(void)
GetSystemInfo(&si);
status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL );
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
proc_affinity = (DWORD_PTR)pbi.Reserved2[0];
proc_affinity = pbi.AffinityMask;
ok( proc_affinity == (1 << si.dwNumberOfProcessors) - 1, "Unexpected process affinity\n" );
proc_affinity = 1 << si.dwNumberOfProcessors;
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessAffinityMask, &proc_affinity, sizeof(proc_affinity) );
@@ -1534,7 +1539,7 @@ static void test_affinity(void)
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL );
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
proc_affinity = (DWORD_PTR)pbi.Reserved2[0];
proc_affinity = pbi.AffinityMask;
ok( proc_affinity == 2, "Unexpected process affinity\n" );
/* Setting the process affinity changes the thread affinity to match */
status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL );
@@ -1578,7 +1583,7 @@ static void test_NtGetCurrentProcessorNumber(void)
trace("dwNumberOfProcessors: %d, current processor: %d\n", si.dwNumberOfProcessors, current_cpu);
status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
old_process_mask = (DWORD_PTR)pbi.Reserved2[0];
old_process_mask = pbi.AffinityMask;
ok(status == STATUS_SUCCESS, "got 0x%x (expected STATUS_SUCCESS)\n", status);
status = pNtQueryInformationThread(GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
@@ -1721,7 +1726,7 @@ START_TEST(info)
trace("Starting test_process_debug_flags()\n");
test_query_process_debug_flags(argc, argv);
/* belongs into it's own file */
/* belongs to its own file */
trace("Starting test_readvirtualmemory()\n");
test_readvirtualmemory();
+1 -1
View File
@@ -26,7 +26,7 @@
#include "stdlib.h"
static HANDLE (WINAPI *pCreateWaitableTimerA)(SECURITY_ATTRIBUTES*, BOOL, LPCSTR);
static NTSTATUS (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
static BOOLEAN (WINAPI *pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
static VOID (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN, BOOLEAN);
+33 -12
View File
@@ -30,7 +30,7 @@ static BOOLEAN (WINAPI *pRtlIsNameLegalDOS8Dot3)(const UNICODE_STRING*,POEM_STRI
static DWORD (WINAPI *pRtlGetFullPathName_U)(const WCHAR*,ULONG,WCHAR*,WCHAR**);
static void test_RtlDetermineDosPathNameType(void)
static void test_RtlDetermineDosPathNameType_U(void)
{
struct test
{
@@ -75,6 +75,12 @@ static void test_RtlDetermineDosPathNameType(void)
WCHAR buffer[MAX_PATH];
UINT ret;
if (!pRtlDetermineDosPathNameType_U)
{
win_skip("RtlDetermineDosPathNameType_U is not available\n");
return;
}
for (test = tests; test->path; test++)
{
pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 );
@@ -84,7 +90,7 @@ static void test_RtlDetermineDosPathNameType(void)
}
static void test_RtlIsDosDeviceName(void)
static void test_RtlIsDosDeviceName_U(void)
{
struct test
{
@@ -96,8 +102,8 @@ static void test_RtlIsDosDeviceName(void)
static const struct test tests[] =
{
{ "\\\\.\\CON", 8, 6 },
{ "\\\\.\\con", 8, 6 },
{ "\\\\.\\CON", 8, 6, TRUE }, /* fails on win8 */
{ "\\\\.\\con", 8, 6, TRUE }, /* fails on win8 */
{ "\\\\.\\CON2", 0, 0 },
{ "", 0, 0 },
{ "\\\\foo\\nul", 0, 0 },
@@ -144,6 +150,12 @@ static void test_RtlIsDosDeviceName(void)
WCHAR buffer[2000];
ULONG ret;
if (!pRtlIsDosDeviceName_U)
{
win_skip("RtlIsDosDeviceName_U is not available\n");
return;
}
for (test = tests; test->path; test++)
{
pRtlMultiByteToUnicodeN( buffer, sizeof(buffer), NULL, test->path, strlen(test->path)+1 );
@@ -197,6 +209,12 @@ static void test_RtlIsNameLegalDOS8Dot3(void)
char buff2[12];
BOOLEAN ret, spaces;
if (!pRtlIsNameLegalDOS8Dot3)
{
win_skip("RtlIsNameLegalDOS8Dot3 is not available\n");
return;
}
ustr.MaximumLength = sizeof(buffer);
ustr.Buffer = buffer;
for (test = tests; test->path; test++)
@@ -274,6 +292,12 @@ static void test_RtlGetFullPathName_U(void)
DWORD reslen;
UINT len;
if (!pRtlGetFullPathName_U)
{
win_skip("RtlGetFullPathName_U is not available\n");
return;
}
file_part = (WCHAR *)0xdeadbeef;
lstrcpyW(rbufferW, deadbeefW);
ret = pRtlGetFullPathName_U(NULL, MAX_PATH, rbufferW, &file_part);
@@ -336,12 +360,9 @@ START_TEST(path)
pRtlOemStringToUnicodeString = (void *)GetProcAddress(mod,"RtlOemStringToUnicodeString");
pRtlIsNameLegalDOS8Dot3 = (void *)GetProcAddress(mod,"RtlIsNameLegalDOS8Dot3");
pRtlGetFullPathName_U = (void *)GetProcAddress(mod,"RtlGetFullPathName_U");
if (pRtlDetermineDosPathNameType_U)
test_RtlDetermineDosPathNameType();
if (pRtlIsDosDeviceName_U)
test_RtlIsDosDeviceName();
if (pRtlIsNameLegalDOS8Dot3)
test_RtlIsNameLegalDOS8Dot3();
if (pRtlGetFullPathName_U && pRtlMultiByteToUnicodeN)
test_RtlGetFullPathName_U();
test_RtlDetermineDosPathNameType_U();
test_RtlIsDosDeviceName_U();
test_RtlIsNameLegalDOS8Dot3();
test_RtlGetFullPathName_U();
}
+2 -2
View File
@@ -77,7 +77,7 @@ static DWORD (WINAPI *pQueueUserAPC)(PAPCFUNC pfnAPC, HANDLE hThread, ULONG_PTR
static BOOL init_func_ptrs(void)
{
HMODULE module = GetModuleHandle("ntdll.dll");
HMODULE module = GetModuleHandleA("ntdll.dll");
#define loadfunc(name) if (!(p##name = (void *)GetProcAddress(module, #name))) { \
trace("GetProcAddress(%s) failed\n", #name); \
@@ -91,7 +91,7 @@ static BOOL init_func_ptrs(void)
loadfunc(RtlInitUnicodeString)
/* not fatal */
module = GetModuleHandle("kernel32.dll");
module = GetModuleHandleA("kernel32.dll");
pOpenThread = (void *)GetProcAddress(module, "OpenThread");
pQueueUserAPC = (void *)GetProcAddress(module, "QueueUserAPC");
return TRUE;
+21 -21
View File
@@ -160,7 +160,7 @@ static BOOL init_function_ptrs(void)
return FALSE;
}
pIsWow64Process = (void *)GetProcAddress(GetModuleHandle("kernel32.dll"), "IsWow64Process");
pIsWow64Process = (void *)GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process");
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
return TRUE;
}
@@ -197,30 +197,30 @@ static void ProcessLpcRequest(HANDLE PortHandle, union lpc_message *LpcMessage)
{
ok(LpcMessage->msg64.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REQUEST2),
ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST2),
"Expected %s, got %s\n", REQUEST2, LpcMessage->msg64.Data);
lstrcpy((LPSTR)LpcMessage->msg64.Data, REPLY);
strcpy((LPSTR)LpcMessage->msg64.Data, REPLY);
status = pNtReplyPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg64.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg64.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REPLY),
ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REPLY),
"Expected %s, got %s\n", REPLY, LpcMessage->msg64.Data);
}
else
{
ok(LpcMessage->msg.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REQUEST2),
ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST2),
"Expected %s, got %s\n", REQUEST2, LpcMessage->msg.Data);
lstrcpy((LPSTR)LpcMessage->msg.Data, REPLY);
strcpy((LPSTR)LpcMessage->msg.Data, REPLY);
status = pNtReplyPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg.MessageType == LPC_REQUEST,
"Expected LPC_REQUEST, got %d\n", LpcMessage->msg.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REPLY),
ok(!strcmp((LPSTR)LpcMessage->msg.Data, REPLY),
"Expected %s, got %s\n", REPLY, LpcMessage->msg.Data);
}
}
@@ -251,26 +251,26 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
out = HeapAlloc(GetProcessHeap(), 0, size);
LpcMessage->msg64.DataSize = lstrlen(REQUEST1) + 1;
LpcMessage->msg64.DataSize = strlen(REQUEST1) + 1;
LpcMessage->msg64.MessageSize = FIELD_OFFSET(LPC_MESSAGE64, Data[LpcMessage->msg64.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg64.Data, REQUEST1);
strcpy((LPSTR)LpcMessage->msg64.Data, REQUEST1);
status = pNtRequestPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg64.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg64.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data);
/* Fill in the message */
memset(LpcMessage, 0, size);
LpcMessage->msg64.DataSize = lstrlen(REQUEST2) + 1;
LpcMessage->msg64.DataSize = strlen(REQUEST2) + 1;
LpcMessage->msg64.MessageSize = FIELD_OFFSET(LPC_MESSAGE64, Data[LpcMessage->msg64.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg64.Data, REQUEST2);
strcpy((LPSTR)LpcMessage->msg64.Data, REQUEST2);
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(!lstrcmp((LPSTR)out->msg64.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg64.Data);
ok(!strcmp((LPSTR)out->msg64.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg64.Data);
ok(out->msg64.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg64.MessageType);
}
else
@@ -279,26 +279,26 @@ static DWORD WINAPI test_ports_client(LPVOID arg)
LpcMessage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
out = HeapAlloc(GetProcessHeap(), 0, size);
LpcMessage->msg.DataSize = lstrlen(REQUEST1) + 1;
LpcMessage->msg.DataSize = strlen(REQUEST1) + 1;
LpcMessage->msg.MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->msg.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg.Data, REQUEST1);
strcpy((LPSTR)LpcMessage->msg.Data, REQUEST1);
status = pNtRequestPort(PortHandle, &LpcMessage->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(LpcMessage->msg.MessageType == 0, "Expected 0, got %d\n", LpcMessage->msg.MessageType);
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data);
/* Fill in the message */
memset(LpcMessage, 0, size);
LpcMessage->msg.DataSize = lstrlen(REQUEST2) + 1;
LpcMessage->msg.DataSize = strlen(REQUEST2) + 1;
LpcMessage->msg.MessageSize = FIELD_OFFSET(LPC_MESSAGE, Data[LpcMessage->msg.DataSize]);
lstrcpy((LPSTR)LpcMessage->msg.Data, REQUEST2);
strcpy((LPSTR)LpcMessage->msg.Data, REQUEST2);
/* Send the message and wait for the reply */
status = pNtRequestWaitReplyPort(PortHandle, &LpcMessage->msg, &out->msg);
ok(status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %x\n", status);
ok(!lstrcmp((LPSTR)out->msg.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg.Data);
ok(!strcmp((LPSTR)out->msg.Data, REPLY), "Expected %s, got %s\n", REPLY, out->msg.Data);
ok(out->msg.MessageType == LPC_REPLY, "Expected LPC_REPLY, got %d\n", out->msg.MessageType);
}
@@ -345,10 +345,10 @@ static void test_ports_server( HANDLE PortHandle )
case LPC_DATAGRAM:
if (is_wow64)
ok(!lstrcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
ok(!strcmp((LPSTR)LpcMessage->msg64.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg64.Data);
else
ok(!lstrcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
ok(!strcmp((LPSTR)LpcMessage->msg.Data, REQUEST1),
"Expected %s, got %s\n", REQUEST1, LpcMessage->msg.Data);
break;
+2 -2
View File
@@ -115,7 +115,7 @@ typedef enum _KEY_VALUE_INFORMATION_CLASS {
#endif
static NTSTATUS (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
static BOOLEAN (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
static void (WINAPI * pRtlInitUnicodeString)(PUNICODE_STRING,PCWSTR);
static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
@@ -134,7 +134,7 @@ static NTSTATUS (WINAPI * pNtSetValueKey)(HANDLE, const PUNICODE_STRING, ULONG,
ULONG, const void*, ULONG );
static NTSTATUS (WINAPI * pNtQueryInformationProcess)(HANDLE,PROCESSINFOCLASS,PVOID,ULONG,PULONG);
static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(PUNICODE_STRING);
static NTSTATUS (WINAPI * pRtlCreateUnicodeString)( PUNICODE_STRING, LPCWSTR);
static BOOLEAN (WINAPI * pRtlCreateUnicodeString)(PUNICODE_STRING, LPCWSTR);
static LPVOID (WINAPI * pRtlReAllocateHeap)(IN PVOID, IN ULONG, IN PVOID, IN ULONG);
static NTSTATUS (WINAPI * pRtlAppendUnicodeToString)(PUNICODE_STRING, PCWSTR);
static NTSTATUS (WINAPI * pRtlUnicodeStringToAnsiString)(PSTRING, PUNICODE_STRING, BOOL);
+58
View File
@@ -89,6 +89,7 @@ static IMAGE_BASE_RELOCATION *(WINAPI *pLdrProcessRelocationBlock)(void*,UINT,US
static CHAR * (WINAPI *pRtlIpv4AddressToStringA)(const IN_ADDR *, LPSTR);
static NTSTATUS (WINAPI *pRtlIpv4AddressToStringExA)(const IN_ADDR *, USHORT, LPSTR, PULONG);
static NTSTATUS (WINAPI *pRtlIpv4StringToAddressA)(PCSTR, BOOLEAN, PCSTR *, IN_ADDR *);
static NTSTATUS (WINAPI *pLdrAddRefDll)(ULONG, HMODULE);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -133,6 +134,7 @@ static void InitFunctionPtrs(void)
pRtlIpv4AddressToStringA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringA");
pRtlIpv4AddressToStringExA = (void *)GetProcAddress(hntdll, "RtlIpv4AddressToStringExA");
pRtlIpv4StringToAddressA = (void *)GetProcAddress(hntdll, "RtlIpv4StringToAddressA");
pLdrAddRefDll = (void *)GetProcAddress(hntdll, "LdrAddRefDll");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -1486,6 +1488,61 @@ static void test_RtlIpv4StringToAddress(void)
}
}
static void test_LdrAddRefDll(void)
{
HMODULE mod, mod2;
NTSTATUS status;
BOOL ret;
if (!pLdrAddRefDll)
{
win_skip( "LdrAddRefDll not supported\n" );
return;
}
mod = LoadLibraryA("comctl32.dll");
ok(mod != NULL, "got %p\n", mod);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
mod2 = GetModuleHandleA("comctl32.dll");
ok(mod2 == NULL, "got %p\n", mod2);
/* load, addref and release 2 times */
mod = LoadLibraryA("comctl32.dll");
ok(mod != NULL, "got %p\n", mod);
status = pLdrAddRefDll(0, mod);
ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
mod2 = GetModuleHandleA("comctl32.dll");
ok(mod2 != NULL, "got %p\n", mod2);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
mod2 = GetModuleHandleA("comctl32.dll");
ok(mod2 == NULL, "got %p\n", mod2);
/* pin refcount */
mod = LoadLibraryA("comctl32.dll");
ok(mod != NULL, "got %p\n", mod);
status = pLdrAddRefDll(LDR_ADDREF_DLL_PIN, mod);
ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
ret = FreeLibrary(mod);
ok(ret, "got %d\n", ret);
mod2 = GetModuleHandleA("comctl32.dll");
ok(mod2 != NULL, "got %p\n", mod2);
}
START_TEST(rtl)
{
InitFunctionPtrs();
@@ -1510,4 +1567,5 @@ START_TEST(rtl)
test_RtlIpv4AddressToString();
test_RtlIpv4AddressToStringEx();
test_RtlIpv4StringToAddress();
test_LdrAddRefDll();
}
+527
View File
@@ -68,6 +68,8 @@ static NTSTATUS (WINAPI *pRtlGUIDFromString)(const UNICODE_STRING*,GUID*);
static NTSTATUS (WINAPI *pRtlStringFromGUID)(const GUID*, UNICODE_STRING*);
static BOOLEAN (WINAPI *pRtlIsTextUnicode)(LPVOID, INT, INT *);
static NTSTATUS (WINAPI *pRtlHashUnicodeString)(PCUNICODE_STRING,BOOLEAN,ULONG,ULONG*);
static NTSTATUS (WINAPI *pRtlUnicodeToUTF8N)(CHAR *, ULONG, ULONG *, const WCHAR *, ULONG);
static NTSTATUS (WINAPI *pRtlUTF8ToUnicodeN)(WCHAR *, ULONG, ULONG *, const CHAR *, ULONG);
/*static VOID (WINAPI *pRtlFreeOemString)(PSTRING);*/
/*static VOID (WINAPI *pRtlCopyUnicodeString)(UNICODE_STRING *, const UNICODE_STRING *);*/
@@ -137,6 +139,8 @@ static void InitFunctionPtrs(void)
pRtlStringFromGUID = (void *)GetProcAddress(hntdll, "RtlStringFromGUID");
pRtlIsTextUnicode = (void *)GetProcAddress(hntdll, "RtlIsTextUnicode");
pRtlHashUnicodeString = (void*)GetProcAddress(hntdll, "RtlHashUnicodeString");
pRtlUnicodeToUTF8N = (void*)GetProcAddress(hntdll, "RtlUnicodeToUTF8N");
pRtlUTF8ToUnicodeN = (void*)GetProcAddress(hntdll, "RtlUTF8ToUnicodeN");
}
}
@@ -1971,6 +1975,527 @@ static void test_RtlHashUnicodeString(void)
}
}
struct unicode_to_utf8_test {
WCHAR unicode[128];
const char *expected;
NTSTATUS status;
};
static const struct unicode_to_utf8_test unicode_to_utf8[] = {
{ { 0 }, "", STATUS_SUCCESS },
{ { '-',0 }, "-", STATUS_SUCCESS },
{ { 'h','e','l','l','o',0 }, "hello", STATUS_SUCCESS },
{ { '-',0x7f,'-',0x80,'-',0xff,'-',0x100,'-',0 }, "-\x7F-\xC2\x80-\xC3\xBF-\xC4\x80-", STATUS_SUCCESS },
{ { '-',0x7ff,'-',0x800,'-',0 }, "-\xDF\xBF-\xE0\xA0\x80-", STATUS_SUCCESS },
{ { '-',0xd7ff,'-',0xe000,'-',0 }, "-\xED\x9F\xBF-\xEE\x80\x80-", STATUS_SUCCESS },
/* 0x10000 */
{ { '-',0xffff,'-',0xd800,0xdc00,'-',0 }, "-\xEF\xBF\xBF-\xF0\x90\x80\x80-", STATUS_SUCCESS },
/* 0x103ff */ /* 0x10400 */
{ { '-',0xd800,0xdfff,'-',0xd801,0xdc00,'-',0 }, "-\xF0\x90\x8F\xBF-\xF0\x90\x90\x80-", STATUS_SUCCESS },
/* 0x10ffff */
{ { '-',0xdbff,0xdfff,'-',0 }, "-\xF4\x8F\xBF\xBF-", STATUS_SUCCESS },
/* standalone lead surrogates become 0xFFFD */
{ { '-',0xd800,'-',0xdbff,'-',0 }, "-\xEF\xBF\xBD-\xEF\xBF\xBD-", STATUS_SOME_NOT_MAPPED },
/* standalone trail surrogates become 0xFFFD */
{ { '-',0xdc00,'-',0xdfff,'-',0 }, "-\xEF\xBF\xBD-\xEF\xBF\xBD-", STATUS_SOME_NOT_MAPPED },
/* reverse surrogate pair */
{ { '-',0xdfff,0xdbff,'-',0 }, "-\xEF\xBF\xBD\xEF\xBF\xBD-", STATUS_SOME_NOT_MAPPED },
/* byte order marks */
{ { '-',0xfeff,'-',0xfffe,'-',0 }, "-\xEF\xBB\xBF-\xEF\xBF\xBE-", STATUS_SUCCESS },
{ { 0xfeff,'-',0 }, "\xEF\xBB\xBF-", STATUS_SUCCESS },
{ { 0xfffe,'-',0 }, "\xEF\xBF\xBE-", STATUS_SUCCESS },
/* invalid code point */
{ { 0xffff,'-',0 }, "\xEF\xBF\xBF-", STATUS_SUCCESS },
/* canonically equivalent representations -- no normalization should happen */
{ { '-',0x1e09,'-',0 }, "-\xE1\xB8\x89-", STATUS_SUCCESS },
{ { '-',0x0107,0x0327,'-',0 }, "-\xC4\x87\xCC\xA7-", STATUS_SUCCESS },
{ { '-',0x00e7,0x0301,'-',0 }, "-\xC3\xA7\xCC\x81-", STATUS_SUCCESS },
{ { '-',0x0063,0x0327,0x0301,'-',0 }, "-\x63\xCC\xA7\xCC\x81-", STATUS_SUCCESS },
{ { '-',0x0063,0x0301,0x0327,'-',0 }, "-\x63\xCC\x81\xCC\xA7-", STATUS_SUCCESS },
};
static void utf8_expect_(const unsigned char *out_string, ULONG buflen, ULONG out_bytes,
const WCHAR *in_string, ULONG in_bytes,
NTSTATUS expect_status, int line)
{
NTSTATUS status;
ULONG bytes_out;
char buffer[128];
unsigned char *buf = (unsigned char *)buffer;
unsigned int i;
if (buflen == (ULONG)-1)
buflen = sizeof(buffer);
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUnicodeToUTF8N(
out_string ? buffer : NULL, buflen, &bytes_out,
in_string, in_bytes);
ok_(__FILE__, line)(status == expect_status, "status = 0x%x\n", status);
ok_(__FILE__, line)(bytes_out == out_bytes, "bytes_out = %u\n", bytes_out);
if (out_string)
{
for (i = 0; i < bytes_out; i++)
ok_(__FILE__, line)(buf[i] == out_string[i],
"buffer[%d] = 0x%x, expected 0x%x\n",
i, buf[i], out_string[i]);
for (; i < sizeof(buffer); i++)
ok_(__FILE__, line)(buf[i] == 0x55,
"buffer[%d] = 0x%x, expected 0x55\n",
i, buf[i]);
}
}
#define utf8_expect(out_string, buflen, out_bytes, in_string, in_bytes, expect_status) \
utf8_expect_(out_string, buflen, out_bytes, in_string, in_bytes, expect_status, __LINE__)
static void test_RtlUnicodeToUTF8N(void)
{
NTSTATUS status;
ULONG bytes_out;
ULONG bytes_out_array[2];
void * const invalid_pointer = (void *)0x8;
char buffer[128];
const WCHAR empty_string[] = { 0 };
const WCHAR test_string[] = { 'A',0,'a','b','c','d','e','f','g',0 };
const WCHAR special_string[] = { 'X',0x80,0xd800,0 };
const unsigned char special_expected[] = { 'X',0xc2,0x80,0xef,0xbf,0xbd,0 };
unsigned int input_len;
const unsigned int test_count = sizeof(unicode_to_utf8) / sizeof(unicode_to_utf8[0]);
unsigned int i;
if (!pRtlUnicodeToUTF8N)
{
skip("RtlUnicodeToUTF8N unavailable\n");
return;
}
/* show that bytes_out is really ULONG */
memset(bytes_out_array, 0x55, sizeof(bytes_out_array));
status = pRtlUnicodeToUTF8N(NULL, 0, bytes_out_array, empty_string, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out_array[0] == 0x00000000, "Got 0x%x\n", bytes_out_array[0]);
ok(bytes_out_array[1] == 0x55555555, "Got 0x%x\n", bytes_out_array[1]);
/* parameter checks */
status = pRtlUnicodeToUTF8N(NULL, 0, NULL, NULL, 0);
ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%x\n", status);
status = pRtlUnicodeToUTF8N(NULL, 0, NULL, empty_string, 0);
ok(status == STATUS_INVALID_PARAMETER, "status = 0x%x\n", status);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, NULL, 0);
ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%x\n", status);
ok(bytes_out == 0x55555555, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, invalid_pointer, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, empty_string, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, test_string, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(NULL, 0, &bytes_out, empty_string, 1);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(invalid_pointer, 0, &bytes_out, empty_string, 1);
ok(status == STATUS_INVALID_PARAMETER_5, "status = 0x%x\n", status);
ok(bytes_out == 0x55555555, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUnicodeToUTF8N(invalid_pointer, 8, &bytes_out, empty_string, 1);
ok(status == STATUS_INVALID_PARAMETER_5, "status = 0x%x\n", status);
ok(bytes_out == 0x55555555, "bytes_out = 0x%x\n", bytes_out);
/* length output with special chars */
#define length_expect(in_chars, out_bytes, expect_status) \
utf8_expect_(NULL, 0, out_bytes, \
special_string, in_chars * sizeof(WCHAR), \
expect_status, __LINE__)
length_expect(0, 0, STATUS_SUCCESS);
length_expect(1, 1, STATUS_SUCCESS);
length_expect(2, 3, STATUS_SUCCESS);
length_expect(3, 6, STATUS_SOME_NOT_MAPPED);
length_expect(4, 7, STATUS_SOME_NOT_MAPPED);
#undef length_expect
/* output truncation */
#define truncate_expect(buflen, out_bytes, expect_status) \
utf8_expect_(special_expected, buflen, out_bytes, \
special_string, sizeof(special_string), \
expect_status, __LINE__)
truncate_expect(0, 0, STATUS_BUFFER_TOO_SMALL);
truncate_expect(1, 1, STATUS_BUFFER_TOO_SMALL);
truncate_expect(2, 1, STATUS_BUFFER_TOO_SMALL);
truncate_expect(3, 3, STATUS_BUFFER_TOO_SMALL);
truncate_expect(4, 3, STATUS_BUFFER_TOO_SMALL);
truncate_expect(5, 3, STATUS_BUFFER_TOO_SMALL);
truncate_expect(6, 6, STATUS_BUFFER_TOO_SMALL);
truncate_expect(7, 7, STATUS_SOME_NOT_MAPPED);
#undef truncate_expect
/* conversion behavior with varying input length */
for (input_len = 0; input_len <= sizeof(test_string); input_len++) {
/* no output buffer, just length */
utf8_expect(NULL, 0, input_len / sizeof(WCHAR),
test_string, input_len, STATUS_SUCCESS);
/* write output */
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUnicodeToUTF8N(
buffer, sizeof(buffer), &bytes_out,
test_string, input_len);
if (input_len % sizeof(WCHAR) == 0) {
ok(status == STATUS_SUCCESS,
"(len %u): status = 0x%x\n", input_len, status);
ok(bytes_out == input_len / sizeof(WCHAR),
"(len %u): bytes_out = 0x%x\n", input_len, bytes_out);
for (i = 0; i < bytes_out; i++) {
ok(buffer[i] == test_string[i],
"(len %u): buffer[%d] = 0x%x, expected 0x%x\n",
input_len, i, buffer[i], test_string[i]);
}
for (; i < sizeof(buffer); i++) {
ok(buffer[i] == 0x55,
"(len %u): buffer[%d] = 0x%x\n", input_len, i, buffer[i]);
}
} else {
ok(status == STATUS_INVALID_PARAMETER_5,
"(len %u): status = 0x%x\n", input_len, status);
ok(bytes_out == 0x55555555,
"(len %u): bytes_out = 0x%x\n", input_len, bytes_out);
for (i = 0; i < sizeof(buffer); i++) {
ok(buffer[i] == 0x55,
"(len %u): buffer[%d] = 0x%x\n", input_len, i, buffer[i]);
}
}
}
/* test cases for special characters */
for (i = 0; i < test_count; i++) {
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUnicodeToUTF8N(
buffer, sizeof(buffer), &bytes_out,
unicode_to_utf8[i].unicode, lstrlenW(unicode_to_utf8[i].unicode) * sizeof(WCHAR));
ok(status == unicode_to_utf8[i].status,
"(test %d): status is 0x%x, expected 0x%x\n",
i, status, unicode_to_utf8[i].status);
ok(bytes_out == strlen(unicode_to_utf8[i].expected),
"(test %d): bytes_out is %u, expected %u\n",
i, bytes_out, lstrlenA(unicode_to_utf8[i].expected));
ok(!memcmp(buffer, unicode_to_utf8[i].expected, bytes_out),
"(test %d): got \"%.*s\", expected \"%s\"\n",
i, bytes_out, buffer, unicode_to_utf8[i].expected);
ok(buffer[bytes_out] == 0x55,
"(test %d): behind string: 0x%x\n", i, buffer[bytes_out]);
/* same test but include the null terminator */
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUnicodeToUTF8N(
buffer, sizeof(buffer), &bytes_out,
unicode_to_utf8[i].unicode, (lstrlenW(unicode_to_utf8[i].unicode) + 1) * sizeof(WCHAR));
ok(status == unicode_to_utf8[i].status,
"(test %d): status is 0x%x, expected 0x%x\n",
i, status, unicode_to_utf8[i].status);
ok(bytes_out == strlen(unicode_to_utf8[i].expected) + 1,
"(test %d): bytes_out is %u, expected %u\n",
i, bytes_out, lstrlenA(unicode_to_utf8[i].expected) + 1);
ok(!memcmp(buffer, unicode_to_utf8[i].expected, bytes_out),
"(test %d): got \"%.*s\", expected \"%s\"\n",
i, bytes_out, buffer, unicode_to_utf8[i].expected);
ok(buffer[bytes_out] == 0x55,
"(test %d): behind string: 0x%x\n", i, buffer[bytes_out]);
}
}
struct utf8_to_unicode_test {
const char *utf8;
WCHAR expected[128];
NTSTATUS status;
};
static const struct utf8_to_unicode_test utf8_to_unicode[] = {
{ "", { 0 }, STATUS_SUCCESS },
{ "-", { '-',0 }, STATUS_SUCCESS },
{ "hello", { 'h','e','l','l','o',0 }, STATUS_SUCCESS },
/* first and last of each range */
{ "-\x7F-\xC2\x80-\xC3\xBF-\xC4\x80-", { '-',0x7f,'-',0x80,'-',0xff,'-',0x100,'-',0 }, STATUS_SUCCESS },
{ "-\xDF\xBF-\xE0\xA0\x80-", { '-',0x7ff,'-',0x800,'-',0 }, STATUS_SUCCESS },
{ "-\xED\x9F\xBF-\xEE\x80\x80-", { '-',0xd7ff,'-',0xe000,'-',0 }, STATUS_SUCCESS },
/* 0x10000 */
{ "-\xEF\xBF\xBF-\xF0\x90\x80\x80-", { '-',0xffff,'-',0xd800,0xdc00,'-',0 }, STATUS_SUCCESS },
/* 0x103ff */ /* 0x10400 */
{ "-\xF0\x90\x8F\xBF-\xF0\x90\x90\x80-", { '-',0xd800,0xdfff,'-',0xd801,0xdc00,'-',0 }, STATUS_SUCCESS },
/* 0x10ffff */
{ "-\xF4\x8F\xBF\xBF-", { '-',0xdbff,0xdfff,'-',0 }, STATUS_SUCCESS },
/* standalone surrogate code points */
/* 0xd800 */ /* 0xdbff */
{ "-\xED\xA0\x80-\xED\xAF\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* 0xdc00 */ /* 0xdfff */
{ "-\xED\xB0\x80-\xED\xBF\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* UTF-8 encoded surrogate pair */
/* 0xdbff *//* 0xdfff */
{ "-\xED\xAF\xBF\xED\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* reverse surrogate pair */
/* 0xdfff *//* 0xdbff */
{ "-\xED\xBF\xBF\xED\xAF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* code points outside the UTF-16 range */
/* 0x110000 */
{ "-\xF4\x90\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* 0x1fffff */
{ "-\xF7\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* 0x200000 */
{ "-\xFA\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* 0x3ffffff */
{ "-\xFB\xBF\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* 0x4000000 */
{ "-\xFC\x84\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* 0x7fffffff */
{ "-\xFD\xBF\xBF\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* overlong encodings of each length for -, NUL, and the highest possible value */
{ "-\xC0\xAD-\xC0\x80-\xC1\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xE0\x80\xAD-\xE0\x80\x80-\xE0\x9F\xBF-", { '-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xF0\x80\x80\xAD-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xF0\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xF0\x8F\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xF8\x80\x80\x80\xAD-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xF8\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xF8\x87\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xFC\x80\x80\x80\x80\xAD-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xFC\x80\x80\x80\x80\x80-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "-\xFC\x83\xBF\xBF\xBF\xBF-", { '-',0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* invalid bytes */
{ "\xFE", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFF", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFE\xBF\xBF\xBF\xBF\xBF\xBF\xBF\xBF", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFF\xBF\xBF\xBF\xBF\xBF\xBF\xBF\xBF", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFF\x80\x80\x80\x80\x80\x80\x80\x80", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFF\x40\x80\x80\x80\x80\x80\x80\x80", { 0xfffd,0x40,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
/* lone continuation bytes */
{ "\x80", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\x80\x80", { 0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xBF", { 0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
{ "\xBF\xBF", { 0xfffd,0xfffd,0 }, STATUS_SOME_NOT_MAPPED },
/* incomplete sequences */
{ "\xC2-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "\xE0\xA0-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "\xF0\x90\x80-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "\xF4\x8F\xBF-", { 0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFA\x80\x80\x80-", { 0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
{ "\xFC\x84\x80\x80\x80-", { 0xfffd,0xfffd,0xfffd,0xfffd,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* multibyte sequence followed by lone continuation byte */
{ "\xE0\xA0\x80\x80-", { 0x800,0xfffd,'-',0 }, STATUS_SOME_NOT_MAPPED },
/* byte order marks */
{ "-\xEF\xBB\xBF-\xEF\xBF\xBE-", { '-',0xfeff,'-',0xfffe,'-',0 }, STATUS_SUCCESS },
{ "\xEF\xBB\xBF-", { 0xfeff,'-',0 }, STATUS_SUCCESS },
{ "\xEF\xBF\xBE-", { 0xfffe,'-',0 }, STATUS_SUCCESS },
/* invalid code point */
/* 0xffff */
{ "\xEF\xBF\xBF-", { 0xffff,'-',0 }, STATUS_SUCCESS },
/* canonically equivalent representations -- no normalization should happen */
{ "-\xE1\xB8\x89-", { '-',0x1e09,'-',0 }, STATUS_SUCCESS },
{ "-\xC4\x87\xCC\xA7-", { '-',0x0107,0x0327,'-',0 }, STATUS_SUCCESS },
{ "-\xC3\xA7\xCC\x81-", { '-',0x00e7,0x0301,'-',0 }, STATUS_SUCCESS },
{ "-\x63\xCC\xA7\xCC\x81-", { '-',0x0063,0x0327,0x0301,'-',0 }, STATUS_SUCCESS },
{ "-\x63\xCC\x81\xCC\xA7-", { '-',0x0063,0x0301,0x0327,'-',0 }, STATUS_SUCCESS },
};
static void unicode_expect_(const WCHAR *out_string, ULONG buflen, ULONG out_chars,
const char *in_string, ULONG in_chars,
NTSTATUS expect_status, int line)
{
NTSTATUS status;
ULONG bytes_out;
WCHAR buffer[128];
unsigned int i;
if (buflen == (ULONG)-1)
buflen = sizeof(buffer);
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUTF8ToUnicodeN(
out_string ? buffer : NULL, buflen, &bytes_out,
in_string, in_chars);
ok_(__FILE__, line)(status == expect_status, "status = 0x%x\n", status);
ok_(__FILE__, line)(bytes_out == out_chars * sizeof(WCHAR),
"bytes_out = %u, expected %u\n", bytes_out, out_chars * (ULONG)sizeof(WCHAR));
if (out_string)
{
for (i = 0; i < bytes_out / sizeof(WCHAR); i++)
ok_(__FILE__, line)(buffer[i] == out_string[i],
"buffer[%d] = 0x%x, expected 0x%x\n",
i, buffer[i], out_string[i]);
for (; i < sizeof(buffer) / sizeof(WCHAR); i++)
ok_(__FILE__, line)(buffer[i] == 0x5555,
"buffer[%d] = 0x%x, expected 0x5555\n",
i, buffer[i]);
}
}
#define unicode_expect(out_string, buflen, out_chars, in_string, in_chars, expect_status) \
unicode_expect_(out_string, buflen, out_chars, in_string, in_chars, expect_status, __LINE__)
static void test_RtlUTF8ToUnicodeN(void)
{
NTSTATUS status;
ULONG bytes_out;
ULONG bytes_out_array[2];
void * const invalid_pointer = (void *)0x8;
WCHAR buffer[128];
const char empty_string[] = "";
const char test_string[] = "A\0abcdefg";
const WCHAR test_stringW[] = {'A',0,'a','b','c','d','e','f','g',0 };
const char special_string[] = { 'X',0xc2,0x80,0xF0,0x90,0x80,0x80,0 };
const WCHAR special_expected[] = { 'X',0x80,0xd800,0xdc00,0 };
unsigned int input_len;
const unsigned int test_count = sizeof(utf8_to_unicode) / sizeof(utf8_to_unicode[0]);
unsigned int i;
if (!pRtlUTF8ToUnicodeN)
{
skip("RtlUTF8ToUnicodeN unavailable\n");
return;
}
/* show that bytes_out is really ULONG */
memset(bytes_out_array, 0x55, sizeof(bytes_out_array));
status = pRtlUTF8ToUnicodeN(NULL, 0, bytes_out_array, empty_string, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out_array[0] == 0x00000000, "Got 0x%x\n", bytes_out_array[0]);
ok(bytes_out_array[1] == 0x55555555, "Got 0x%x\n", bytes_out_array[1]);
/* parameter checks */
status = pRtlUTF8ToUnicodeN(NULL, 0, NULL, NULL, 0);
ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%x\n", status);
status = pRtlUTF8ToUnicodeN(NULL, 0, NULL, empty_string, 0);
ok(status == STATUS_INVALID_PARAMETER, "status = 0x%x\n", status);
bytes_out = 0x55555555;
status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, NULL, 0);
ok(status == STATUS_INVALID_PARAMETER_4, "status = 0x%x\n", status);
ok(bytes_out == 0x55555555, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, invalid_pointer, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, empty_string, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, test_string, 0);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == 0, "bytes_out = 0x%x\n", bytes_out);
bytes_out = 0x55555555;
status = pRtlUTF8ToUnicodeN(NULL, 0, &bytes_out, empty_string, 1);
ok(status == STATUS_SUCCESS, "status = 0x%x\n", status);
ok(bytes_out == sizeof(WCHAR), "bytes_out = 0x%x\n", bytes_out);
/* length output with special chars */
#define length_expect(in_chars, out_chars, expect_status) \
unicode_expect_(NULL, 0, out_chars, special_string, in_chars, \
expect_status, __LINE__)
length_expect(0, 0, STATUS_SUCCESS);
length_expect(1, 1, STATUS_SUCCESS);
length_expect(2, 2, STATUS_SOME_NOT_MAPPED);
length_expect(3, 2, STATUS_SUCCESS);
length_expect(4, 3, STATUS_SOME_NOT_MAPPED);
length_expect(5, 3, STATUS_SOME_NOT_MAPPED);
length_expect(6, 3, STATUS_SOME_NOT_MAPPED);
length_expect(7, 4, STATUS_SUCCESS);
length_expect(8, 5, STATUS_SUCCESS);
#undef length_expect
/* output truncation */
#define truncate_expect(buflen, out_chars, expect_status) \
unicode_expect_(special_expected, buflen, out_chars, \
special_string, sizeof(special_string), \
expect_status, __LINE__)
truncate_expect( 0, 0, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 1, 0, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 2, 1, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 3, 1, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 4, 2, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 5, 2, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 6, 3, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 7, 3, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 8, 4, STATUS_BUFFER_TOO_SMALL);
truncate_expect( 9, 4, STATUS_BUFFER_TOO_SMALL);
truncate_expect(10, 5, STATUS_SUCCESS);
#undef truncate_expect
/* conversion behavior with varying input length */
for (input_len = 0; input_len <= sizeof(test_string); input_len++) {
/* no output buffer, just length */
unicode_expect(NULL, 0, input_len,
test_string, input_len, STATUS_SUCCESS);
/* write output */
unicode_expect(test_stringW, -1, input_len,
test_string, input_len, STATUS_SUCCESS);
}
/* test cases for special characters */
for (i = 0; i < test_count; i++) {
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUTF8ToUnicodeN(
buffer, sizeof(buffer), &bytes_out,
utf8_to_unicode[i].utf8, strlen(utf8_to_unicode[i].utf8));
ok(status == utf8_to_unicode[i].status,
"(test %d): status is 0x%x, expected 0x%x\n",
i, status, utf8_to_unicode[i].status);
ok(bytes_out == lstrlenW(utf8_to_unicode[i].expected) * sizeof(WCHAR),
"(test %d): bytes_out is %u, expected %u\n",
i, bytes_out, lstrlenW(utf8_to_unicode[i].expected) * (ULONG)sizeof(WCHAR));
ok(!memcmp(buffer, utf8_to_unicode[i].expected, bytes_out),
"(test %d): got %s, expected %s\n",
i, wine_dbgstr_wn(buffer, bytes_out / sizeof(WCHAR)), wine_dbgstr_w(utf8_to_unicode[i].expected));
ok(buffer[bytes_out] == 0x5555,
"(test %d): behind string: 0x%x\n", i, buffer[bytes_out]);
/* same test but include the null terminator */
bytes_out = 0x55555555;
memset(buffer, 0x55, sizeof(buffer));
status = pRtlUTF8ToUnicodeN(
buffer, sizeof(buffer), &bytes_out,
utf8_to_unicode[i].utf8, strlen(utf8_to_unicode[i].utf8) + 1);
ok(status == utf8_to_unicode[i].status,
"(test %d): status is 0x%x, expected 0x%x\n",
i, status, utf8_to_unicode[i].status);
ok(bytes_out == (lstrlenW(utf8_to_unicode[i].expected) + 1) * sizeof(WCHAR),
"(test %d): bytes_out is %u, expected %u\n",
i, bytes_out, (lstrlenW(utf8_to_unicode[i].expected) + 1) * (ULONG)sizeof(WCHAR));
ok(!memcmp(buffer, utf8_to_unicode[i].expected, bytes_out),
"(test %d): got %s, expected %s\n",
i, wine_dbgstr_wn(buffer, bytes_out / sizeof(WCHAR)), wine_dbgstr_w(utf8_to_unicode[i].expected));
ok(buffer[bytes_out] == 0x5555,
"(test %d): behind string: 0x%x\n", i, buffer[bytes_out]);
}
}
START_TEST(rtlstr)
{
InitFunctionPtrs();
@@ -2004,4 +2529,6 @@ START_TEST(rtlstr)
test_RtlDowncaseUnicodeString();
}
test_RtlHashUnicodeString();
test_RtlUnicodeToUTF8N();
test_RtlUTF8ToUnicodeN();
}
+36
View File
@@ -59,6 +59,7 @@ static LPWSTR (WINAPIV *p_wcsrchr)(LPCWSTR, WCHAR);
static void (__cdecl *p_qsort)(void *,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static void* (__cdecl *p_bsearch)(void *,void*,size_t,size_t, int(__cdecl *compar)(const void *, const void *) );
static int (__cdecl *p__snprintf)(char *, size_t, const char *, ...);
static void InitFunctionPtrs(void)
@@ -96,6 +97,8 @@ static void InitFunctionPtrs(void)
p_wcsrchr= (void *)GetProcAddress(hntdll, "wcsrchr");
p_qsort= (void *)GetProcAddress(hntdll, "qsort");
p_bsearch= (void *)GetProcAddress(hntdll, "bsearch");
p__snprintf = (void *)GetProcAddress(hntdll, "_snprintf");
} /* if */
}
@@ -1270,6 +1273,37 @@ static void test_bsearch(void)
}
}
static void test__snprintf(void)
{
const char *origstring = "XXXXXXXXXXXX";
const char *teststring = "hello world";
char buffer[32];
int res;
res = p__snprintf(NULL, 0, teststring);
ok(res == lstrlenA(teststring) || broken(res == -1) /* <= w2k */,
"_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
if (res != -1)
{
res = p__snprintf(NULL, 1, teststring);
ok(res == lstrlenA(teststring) /* WinXP */ || res < 0 /* Vista and greater */,
"_snprintf returned %d, expected %d or < 0.\n", res, lstrlenA(teststring));
}
res = p__snprintf(buffer, strlen(teststring) - 1, teststring);
ok(res < 0, "_snprintf returned %d, expected < 0.\n", res);
strcpy(buffer, origstring);
res = p__snprintf(buffer, strlen(teststring), teststring);
ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
ok(!strcmp(buffer, "hello worldX"), "_snprintf returned buffer '%s', expected 'hello worldX'.\n", buffer);
strcpy(buffer, origstring);
res = p__snprintf(buffer, strlen(teststring) + 1, teststring);
ok(res == lstrlenA(teststring), "_snprintf returned %d, expected %d.\n", res, lstrlenA(teststring));
ok(!strcmp(buffer, teststring), "_snprintf returned buffer '%s', expected '%s'.\n", buffer, teststring);
}
START_TEST(string)
{
InitFunctionPtrs();
@@ -1304,4 +1338,6 @@ START_TEST(string)
test_qsort();
if (p_bsearch)
test_bsearch();
if (p__snprintf)
test__snprintf();
}
+1 -4
View File
@@ -1,10 +1,7 @@
/* Automatically generated file; DO NOT EDIT!! */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define STANDALONE
#include "wine/test.h"
#include <wine/test.h>
extern void func_atom(void);
extern void func_change(void);
+2 -2
View File
@@ -33,9 +33,9 @@ static const int MonthLengths[2][12] =
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
static inline int IsLeapYear(int Year)
static inline BOOL IsLeapYear(int Year)
{
return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0) ? 1 : 0;
return Year % 4 == 0 && (Year % 100 != 0 || Year % 400 == 0);
}
/* start time of the tests */