mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-29 12:23:30 +00:00
[NTDLL_WINETEST]
* Sync with Wine 1.7.17. CORE-8080 svn path=/trunk/; revision=62842
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)]);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
+532
-185
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user