ReactOS 0.4.17-dev-37-g0bfb40d
wow64.c File Reference
#include <stdarg.h>
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "winioctl.h"
#include "winuser.h"
#include "ddk/wdm.h"
#include "wine/test.h"
Include dependency graph for wow64.c:

Go to the source code of this file.

Classes

struct  arm64ec_shared_info
 
struct  expected_notification
 

Macros

#define WIN32_NO_STATUS
 
#define GET_PROC(func)   p##func = (void *)GetProcAddress( ntdll, #func )
 
#define expect_cross_work_entry(list, entry, id, addr, size, arg0, arg1, arg2, arg3)    expect_cross_work_entry_(list,entry,id,addr,size,arg0,arg1,arg2,arg3,__LINE__)
 
#define CHECK_STR(name)
 
#define CHECK_STR(name)
 
#define GET_ENTRY(info, size, ret)    NtQueryInformationThread( GetCurrentThread(), ThreadDescriptorTableEntry, info, size, ret )
 
#define expect_notifications(results, count, expect, syscall)    expect_notifications_(results, count, expect, syscall, __LINE__)
 
#define CHECK_MODULE(mod)   do { if (!wcsicmp( name, L"" #mod ".dll" )) { mod ## _module = base; return; } } while(0)
 
#define CHECK_FUNC(val, func)
 

Functions

static NTSTATUS (WINAPI *pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS
 
static void ULONG *static void void ULONG *static void ULONG *static void (WINAPI *pRtlOpenCrossProcessEmulatorWorkConnection)(HANDLE
 
static void ULONG *static void void ULONG *static void ULONG *static HANDLE void **static void *WINAPIpRtlFindExportedRoutineByName (HMODULE, const char *)
 
static USHORT (WINAPI *pRtlWow64GetCurrentMachine)(void)
 
static BOOL is_machine_32bit (USHORT machine)
 
static void init (void)
 
static BOOL create_process_machine (char *cmdline, DWORD flags, USHORT machine, PROCESS_INFORMATION *pi)
 
static void test_process_architecture (HANDLE process, USHORT expect_machine, USHORT expect_native)
 
static void test_process_machine (HANDLE process, HANDLE thread, USHORT expect_machine, USHORT expect_image)
 
static void test_query_architectures (void)
 
static void push_onto_free_list (CROSS_PROCESS_WORK_HDR *list, CROSS_PROCESS_WORK_ENTRY *entry)
 
static void push_onto_work_list (CROSS_PROCESS_WORK_HDR *list, CROSS_PROCESS_WORK_ENTRY *entry)
 
static CROSS_PROCESS_WORK_ENTRYpop_from_free_list (CROSS_PROCESS_WORK_HDR *list)
 
static CROSS_PROCESS_WORK_ENTRYpop_from_work_list (CROSS_PROCESS_WORK_HDR *list)
 
static void request_cross_process_flush (CROSS_PROCESS_WORK_HDR *list)
 
static CROSS_PROCESS_WORK_ENTRYexpect_cross_work_entry_ (CROSS_PROCESS_WORK_LIST *list, CROSS_PROCESS_WORK_ENTRY *entry, UINT id, void *addr, SIZE_T size, UINT arg0, UINT arg1, UINT arg2, UINT arg3, int line)
 
static void test_cross_process_notifications (HANDLE process, ULONG_PTR section, ULONG_PTR ptr)
 
static void test_wow64_shared_info (HANDLE process)
 
static void test_amd64_shared_info (HANDLE process)
 
static void test_peb_teb (void)
 
static void test_selectors (void)
 
static void test_image_mappings (void)
 
static void CALLBACK dummy_apc (ULONG_PTR arg)
 
static void reset_results (ULONG64 *results)
 
static void expect_notifications_ (ULONG64 *results, UINT count, const struct expected_notification *expect, BOOL syscall, int line)
 
static void add_work_item (CROSS_PROCESS_WORK_LIST *list, UINT id, ULONG64 addr, ULONG64 size, UINT arg0, UINT arg1, UINT arg2, UINT arg3)
 
static void process_work_items (void)
 
static voidhook_notification_function (HMODULE module, const char *win32_name, const char *win64_name)
 
static void test_notifications (HMODULE module, CROSS_PROCESS_WORK_LIST *list)
 
static NTSTATUS call_func64 (ULONG64 func64, int nb_args, ULONG64 *args)
 
static void enum_modules64 (void(*func)(ULONG64, const WCHAR *))
 
static ULONG64 get_proc_address64 (ULONG64 module, const char *name)
 
static void check_module (ULONG64 base, const WCHAR *name)
 
static void test_modules (void)
 
static void test_nt_wow64 (void)
 
static void test_init_block (void)
 
static void test_memory_notifications (void)
 
static DWORD WINAPI iosb_delayed_write_thread (void *arg)
 
static void test_iosb (void)
 
static NTSTATUS invoke_syscall (const char *name, ULONG args32[])
 
static void test_syscalls (void)
 
static void test_cpu_area (void)
 
static void test_exception_dispatcher (void)
 
static void test_arm64ec (void)
 
 START_TEST (wow64)
 

Variables

static void ULONG
 
static WORD WORD *static BOOLEAN WOW64INFO *static WOW64_CONTEXT *static BOOLEAN *static HANDLE
 
static ULONG64 ULONG64
 
static PROCESSINFOCLASS
 
static void ULONG *static void ULONG64 *static const void ULONG64 *static BOOL is_win64 = sizeof(void *) > sizeof(int)
 
static BOOL is_wow64
 
static BOOL old_wow64
 
static voidcode_mem
 
static USHORT current_machine
 
static USHORT native_machine
 
static DWORD hook_code []
 
static const DWORD log_params_code []
 
static BYTE old_code [sizeof(hook_code)]
 
static const BYTE call_func64_code []
 
static ULONG64 main_module
 
static ULONG64 ntdll_module
 
static ULONG64 wow64_module
 
static ULONG64 wow64base_module
 
static ULONG64 wow64con_module
 
static ULONG64 wow64cpu_module
 
static ULONG64 xtajit_module
 
static ULONG64 wow64win_module
 

Macro Definition Documentation

◆ CHECK_FUNC

#define CHECK_FUNC (   val,
  func 
)
Value:
"got %p for %s %p\n", (void *)(ULONG_PTR)(val), func, GetProcAddress( ntdll, func ))
#define ok(value,...)
Definition: atltest.h:57
#define GetProcAddress(x, y)
Definition: compat.h:753
GLenum func
Definition: glext.h:6028
GLuint GLfloat * val
Definition: glext.h:7180
static HMODULE ntdll
Definition: debugger.c:59
uint32_t ULONG_PTR
Definition: typedefs.h:65

◆ CHECK_MODULE

#define CHECK_MODULE (   mod)    do { if (!wcsicmp( name, L"" #mod ".dll" )) { mod ## _module = base; return; } } while(0)

◆ CHECK_STR [1/2]

#define CHECK_STR (   name)
Value:
ok( (char *)params.name.Buffer >= (char *)peb.ProcessParameters && \
(char *)params.name.Buffer < (char *)peb.ProcessParameters + params.Size, \
"wrong " #name " ptr %p / %p-%p\n", params.name.Buffer, peb.ProcessParameters, \
(char *)peb.ProcessParameters + params.Size )
GLenum const GLfloat * params
Definition: glext.h:5645
Definition: name.c:39
WCHAR * name
Definition: name.c:42

◆ CHECK_STR [2/2]

#define CHECK_STR (   name)
Value:
ok( ULongToPtr(params32.name.Buffer) >= ULongToPtr(peb32.ProcessParameters) && \
ULongToPtr(params32.name.Buffer) < ULongToPtr(peb32.ProcessParameters + params32.Size), \
"wrong " #name " ptr %lx / %lx-%lx\n", params32.name.Buffer, peb32.ProcessParameters, \
peb32.ProcessParameters + params.Size ); \
ok( params32.name.Length == params.name.Length, "wrong " #name "len %u / %u\n", \
params32.name.Length, params.name.Length )
#define ULongToPtr(ul)
Definition: basetsd.h:86

◆ expect_cross_work_entry

#define expect_cross_work_entry (   list,
  entry,
  id,
  addr,
  size,
  arg0,
  arg1,
  arg2,
  arg3 
)     expect_cross_work_entry_(list,entry,id,addr,size,arg0,arg1,arg2,arg3,__LINE__)

Definition at line 509 of file wow64.c.

◆ expect_notifications

#define expect_notifications (   results,
  count,
  expect,
  syscall 
)     expect_notifications_(results, count, expect, syscall, __LINE__)

Definition at line 1517 of file wow64.c.

◆ GET_ENTRY

◆ GET_PROC

#define GET_PROC (   func)    p##func = (void *)GetProcAddress( ntdll, #func )

◆ WIN32_NO_STATUS

#define WIN32_NO_STATUS

Definition at line 25 of file wow64.c.

Function Documentation

◆ add_work_item()

static void add_work_item ( CROSS_PROCESS_WORK_LIST list,
UINT  id,
ULONG64  addr,
ULONG64  size,
UINT  arg0,
UINT  arg1,
UINT  arg2,
UINT  arg3 
)
static

Definition at line 1541 of file wow64.c.

1543{
1545
1546 entry->id = id;
1547 entry->addr = addr;
1548 entry->size = size;
1549 entry->args[0] = arg0;
1550 entry->args[1] = arg1;
1551 entry->args[2] = arg2;
1552 entry->args[3] = arg3;
1553 push_onto_work_list( &list->work_list, entry );
1554}
Definition: list.h:37
GLsizeiptr size
Definition: glext.h:5919
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg3
Definition: glext.h:9515
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLenum const GLvoid * addr
Definition: glext.h:9621
GLuint id
Definition: glext.h:5910
uint32_t entry
Definition: isohybrid.c:63
Definition: winternl.h:391
static CROSS_PROCESS_WORK_ENTRY * pop_from_free_list(CROSS_PROCESS_WORK_HDR *list)
Definition: wow64.c:461
static void push_onto_work_list(CROSS_PROCESS_WORK_HDR *list, CROSS_PROCESS_WORK_ENTRY *entry)
Definition: wow64.c:450

Referenced by test_notifications().

◆ call_func64()

static NTSTATUS call_func64 ( ULONG64  func64,
int  nb_args,
ULONG64 args 
)
static

Definition at line 2288 of file wow64.c.

2289{
2290 NTSTATUS (WINAPI *func)( ULONG64 func64, int nb_args, ULONG64 *args ) = code_mem;
2291
2293 return func( func64, nb_args, args );
2294}
#define NTSTATUS
Definition: precomp.h:19
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned __int64 ULONG64
Definition: imports.h:198
#define args
Definition: format.c:66
Definition: match.c:390
#define WINAPI
Definition: msvc.h:6
static void * code_mem
Definition: wow64.c:76
static const BYTE call_func64_code[]
Definition: wow64.c:2250

Referenced by invoke_syscall(), test_cpu_area(), and test_iosb().

◆ check_module()

static void check_module ( ULONG64  base,
const WCHAR name 
)
static

Definition at line 2395 of file wow64.c.

2396{
2397 if (base == (ULONG_PTR)GetModuleHandleW(0))
2398 {
2400
2402 if ((p = wcsrchr( module, '\\' ))) p++;
2403 else p = module;
2404 ok( !wcsicmp( name, p ), "wrong name %s / %s\n", debugstr_w(name), debugstr_w(module));
2405 main_module = base;
2406 return;
2407 }
2408#define CHECK_MODULE(mod) do { if (!wcsicmp( name, L"" #mod ".dll" )) { mod ## _module = base; return; } } while(0)
2411 CHECK_MODULE(wow64base);
2412 CHECK_MODULE(wow64con);
2413 CHECK_MODULE(wow64win);
2415 CHECK_MODULE(xtajit);
2416 else
2417 CHECK_MODULE(wow64cpu);
2418#undef CHECK_MODULE
2419 todo_wine_if( !wcscmp( name, L"win32u.dll" ))
2420 ok( 0, "unknown module %s %s found\n", wine_dbgstr_longlong(base), wine_dbgstr_w(name));
2421}
#define wcsrchr
Definition: compat.h:16
static __inline const char * wine_dbgstr_longlong(ULONGLONG ll)
Definition: compat.h:49
#define MAX_PATH
Definition: compat.h:34
#define IMAGE_FILE_MACHINE_ARM64
Definition: compat.h:129
#define wcsicmp
Definition: compat.h:15
DWORD WINAPI GetModuleFileNameW(HINSTANCE hModule, LPWSTR lpFilename, DWORD nSize)
Definition: loader.c:600
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1972
#define L(x)
Definition: resources.c:13
GLfloat GLfloat p
Definition: glext.h:8902
#define debugstr_w
Definition: kernel32.h:32
#define wine_dbgstr_w
Definition: kernel32.h:34
#define todo_wine_if(is_todo)
Definition: minitest.h:81
short WCHAR
Definition: pedump.c:58
static BOOL wow64
Definition: psapi_main.c:44
static USHORT native_machine
Definition: wow64.c:92
#define CHECK_MODULE(mod)
static ULONG64 main_module
Definition: wow64.c:2296

Referenced by test_modules().

◆ create_process_machine()

static BOOL create_process_machine ( char cmdline,
DWORD  flags,
USHORT  machine,
PROCESS_INFORMATION pi 
)
static

Definition at line 198 of file wow64.c.

199{
201 STARTUPINFOEXA si = {{ sizeof(si) }};
202 SIZE_T size = 1024;
203 BOOL ret;
204
205 si.lpAttributeList = list = malloc( size );
208 &machine, sizeof(machine), NULL, NULL );
210 EXTENDED_STARTUPINFO_PRESENT | flags, NULL, NULL, &si.StartupInfo, pi );
212 free( list );
213 return ret;
214}
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(const char *app_name, char *cmd_line, SECURITY_ATTRIBUTES *process_attr, SECURITY_ATTRIBUTES *thread_attr, BOOL inherit, DWORD flags, void *env, const char *cur_dir, STARTUPINFOA *startup_info, PROCESS_INFORMATION *info)
Definition: process.c:686
void WINAPI DECLSPEC_HOTPATCH DeleteProcThreadAttributeList(struct _PROC_THREAD_ATTRIBUTE_LIST *list)
Definition: process.c:1860
BOOL WINAPI DECLSPEC_HOTPATCH UpdateProcThreadAttribute(struct _PROC_THREAD_ATTRIBUTE_LIST *list, DWORD flags, DWORD_PTR attr, void *value, SIZE_T size, void *prev_ret, SIZE_T *size_ret)
Definition: process.c:1820
BOOL WINAPI DECLSPEC_HOTPATCH InitializeProcThreadAttributeList(struct _PROC_THREAD_ATTRIBUTE_LIST *list, DWORD count, DWORD flags, SIZE_T *size)
Definition: process.c:1753
return ret
Definition: mutex.c:146
unsigned int BOOL
Definition: ntddk_ex.h:94
GLbitfield flags
Definition: glext.h:7161
static PROCESS_INFORMATION pi
Definition: debugger.c:2303
static SYSTEM_INFO si
Definition: virtual.c:39
static const char machine[]
Definition: profile.c:104
#define list
Definition: rosglue.h:35
TCHAR * cmdline
Definition: stretchblt.cpp:32
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define PROC_THREAD_ATTRIBUTE_MACHINE_TYPE
Definition: winbase.h:1157
#define EXTENDED_STARTUPINFO_PRESENT
Definition: winbase.h:204

Referenced by test_arm64ec(), test_peb_teb(), and test_query_architectures().

◆ dummy_apc()

static void CALLBACK dummy_apc ( ULONG_PTR  arg)
static

Definition at line 1501 of file wow64.c.

1502{
1503}

Referenced by process_work_items().

◆ enum_modules64()

static void enum_modules64 ( void(*)(ULONG64, const WCHAR *)  func)
static

Definition at line 2299 of file wow64.c.

2300{
2301 typedef struct
2302 {
2303 LIST_ENTRY64 InLoadOrderLinks;
2304 LIST_ENTRY64 InMemoryOrderLinks;
2305 LIST_ENTRY64 InInitializationOrderLinks;
2306 ULONG64 DllBase;
2307 ULONG64 EntryPoint;
2308 ULONG SizeOfImage;
2310 UNICODE_STRING64 BaseDllName;
2311 /* etc. */
2312 } LDR_DATA_TABLE_ENTRY64;
2313
2314 TEB64 *teb64 = (TEB64 *)NtCurrentTeb()->GdiBatchCount;
2315 PEB64 peb64;
2316 ULONG64 ptr;
2317 PEB_LDR_DATA64 ldr;
2318 LDR_DATA_TABLE_ENTRY64 entry;
2321
2323 ok( process != 0, "failed to open current process %lu\n", GetLastError() );
2324 status = pNtWow64ReadVirtualMemory64( process, teb64->Peb, &peb64, sizeof(peb64), NULL );
2325 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2327 ok( peb64.LdrData, "LdrData not initialized\n" );
2328 if (!peb64.LdrData) goto done;
2329 status = pNtWow64ReadVirtualMemory64( process, peb64.LdrData, &ldr, sizeof(ldr), NULL );
2330 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2332 for (;;)
2333 {
2334 WCHAR buffer[256];
2335 status = pNtWow64ReadVirtualMemory64( process, ptr, &entry, sizeof(entry), NULL );
2336 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2337 status = pNtWow64ReadVirtualMemory64( process, entry.BaseDllName.Buffer, buffer, sizeof(buffer), NULL );
2338 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2339 if (status) break;
2340 func( entry.DllBase, buffer );
2341 ptr = entry.InLoadOrderLinks.Flink;
2342 if (ptr == peb64.LdrData + offsetof( PEB_LDR_DATA64, InLoadOrderModuleList )) break;
2343 }
2344done:
2345 NtClose( process );
2346}
LONG NTSTATUS
Definition: precomp.h:26
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1225
GLuint buffer
Definition: glext.h:5915
#define NtCurrentTeb
_In_ PCWSTR FullDllName
Definition: ldrtypes.h:264
static PVOID ptr
Definition: dispmode.c:27
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1327
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define offsetof(TYPE, MEMBER)
ULONG64 Flink
Definition: winternl.h:757
ULONG64 LdrData
Definition: winternl.h:1047
LIST_ENTRY64 InLoadOrderModuleList
Definition: winternl.h:914
ULONG64 Peb
Definition: winternl.h:1254
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1156
static BOOL old_wow64
Definition: wow64.c:75

Referenced by test_modules().

◆ expect_cross_work_entry_()

static CROSS_PROCESS_WORK_ENTRY * expect_cross_work_entry_ ( CROSS_PROCESS_WORK_LIST list,
CROSS_PROCESS_WORK_ENTRY entry,
UINT  id,
void addr,
SIZE_T  size,
UINT  arg0,
UINT  arg1,
UINT  arg2,
UINT  arg3,
int  line 
)
static

Definition at line 511 of file wow64.c.

516{
518
519 ok_(__FILE__,line)( entry != NULL, "no more entries in list\n" );
520 if (!entry) return NULL;
521 ok_(__FILE__,line)( entry->id == id, "wrong type %u / %u\n", entry->id, id );
522 ok_(__FILE__,line)( entry->addr == (ULONG_PTR)addr, "wrong address %s / %p\n",
524 ok_(__FILE__,line)( entry->size == size, "wrong size %s / %Ix\n",
526 ok_(__FILE__,line)( entry->args[0] == arg0, "wrong args[0] %x / %x\n", entry->args[0], arg0 );
527 ok_(__FILE__,line)( entry->args[1] == arg1, "wrong args[1] %x / %x\n", entry->args[1], arg1 );
528 ok_(__FILE__,line)( entry->args[2] == arg2, "wrong args[2] %x / %x\n", entry->args[2], arg2 );
529 ok_(__FILE__,line)( entry->args[3] == arg3, "wrong args[3] %x / %x\n", entry->args[3], arg3 );
530 next = entry->next ? CROSS_PROCESS_LIST_ENTRY( &list->work_list, entry->next ) : NULL;
531 memset( entry, 0xcc, sizeof(*entry) );
532 push_onto_free_list( &list->free_list, entry );
533 return next;
534}
#define ok_(x1, x2)
Definition: atltest.h:61
#define ULONG_PTR
Definition: config.h:101
static unsigned __int64 next
Definition: rand_nt.c:6
#define memset(x, y, z)
Definition: compat.h:39
Definition: parser.c:49
#define CROSS_PROCESS_LIST_ENTRY(list, pos)
Definition: winternl.h:431
static void push_onto_free_list(CROSS_PROCESS_WORK_HDR *list, CROSS_PROCESS_WORK_ENTRY *entry)
Definition: wow64.c:440

◆ expect_notifications_()

static void expect_notifications_ ( ULONG64 results,
UINT  count,
const struct expected_notification expect,
BOOL  syscall,
int  line 
)
static

Definition at line 1519 of file wow64.c.

1521{
1522 ULONG64 *regs = results + 2;
1523 UINT i, j, len = (results[0] - (ULONG_PTR)regs) / 8 / sizeof(*regs);
1524
1525#ifdef _WIN64
1526 if (syscall)
1527 {
1528 CHPE_V2_CPU_AREA_INFO *cpu_area = NtCurrentTeb()->ChpeV2CpuAreaInfo;
1529 if (cpu_area && cpu_area->InSyscallCallback) count = 0;
1530 }
1531#endif
1532
1533 ok_(__FILE__,line)( count == len, "wrong notification count %u / %u\n", len, count );
1534 for (i = 0; i < min( count, len ); i++, expect++, regs += 8)
1535 for (j = 0; j < expect->nb_args; j++)
1536 ok_(__FILE__,line)( regs[j] == expect->args[j], "%u: wrong args[%u] %I64x / %I64x\n",
1537 i, j, regs[j], expect->args[j] );
1539}
static struct _test_info results[8]
Definition: SetCursorPos.c:31
#define expect(EXPECTED, GOT)
Definition: SystemMenu.c:483
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
BOOLEAN InSyscallCallback
Definition: winternl.h:437
static void reset_results(ULONG64 *results)
Definition: wow64.c:1511

◆ get_proc_address64()

static ULONG64 get_proc_address64 ( ULONG64  module,
const char name 
)
static

Definition at line 2348 of file wow64.c.

2349{
2352 IMAGE_EXPORT_DIRECTORY exports;
2353 ULONG i, *names, *funcs;
2354 USHORT *ordinals;
2357 ULONG64 ret = 0;
2358 char buffer[64];
2359
2360 if (!module) return 0;
2362 ok( process != 0, "failed to open current process %lu\n", GetLastError() );
2363 status = pNtWow64ReadVirtualMemory64( process, module, &dos, sizeof(dos), NULL );
2364 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2365 status = pNtWow64ReadVirtualMemory64( process, module + dos.e_lfanew, &nt, sizeof(nt), NULL );
2366 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2368 &exports, sizeof(exports), NULL );
2369 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2370 names = calloc( exports.NumberOfNames, sizeof(*names) );
2371 ordinals = calloc( exports.NumberOfNames, sizeof(*ordinals) );
2372 funcs = calloc( exports.NumberOfFunctions, sizeof(*funcs) );
2373 status = pNtWow64ReadVirtualMemory64( process, module + exports.AddressOfNames,
2374 names, exports.NumberOfNames * sizeof(*names), NULL );
2375 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2376 status = pNtWow64ReadVirtualMemory64( process, module + exports.AddressOfNameOrdinals,
2377 ordinals, exports.NumberOfNames * sizeof(*ordinals), NULL );
2378 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2379 status = pNtWow64ReadVirtualMemory64( process, module + exports.AddressOfFunctions,
2380 funcs, exports.NumberOfFunctions * sizeof(*funcs), NULL );
2381 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2382 for (i = 0; i < exports.NumberOfNames && !ret; i++)
2383 {
2384 status = pNtWow64ReadVirtualMemory64( process, module + names[i], buffer, sizeof(buffer), NULL );
2385 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2386 if (!strcmp( buffer, name )) ret = module + funcs[ordinals[i]];
2387 }
2388 free( funcs );
2389 free( ordinals );
2390 free( names );
2391 NtClose( process );
2392 return ret;
2393}
PIMAGE_NT_HEADERS nt
Definition: delayimp.cpp:445
#define IMAGE_DIRECTORY_ENTRY_EXPORT
Definition: compat.h:151
_ACRTIMP int __cdecl strcmp(const char *, const char *)
Definition: string.c:3319
GLuint GLuint * names
Definition: glext.h:11545
IMAGE_DOS_HEADER dos
Definition: module.c:67
unsigned short USHORT
Definition: pedump.c:61
#define calloc
Definition: rosglue.h:14
static struct __wine_debug_functions funcs
Definition: debug.c:48
DWORD AddressOfNameOrdinals
Definition: compat.h:167
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178

Referenced by invoke_syscall(), test_cpu_area(), test_exception_dispatcher(), test_init_block(), test_iosb(), and test_syscalls().

◆ hook_notification_function()

static void * hook_notification_function ( HMODULE  module,
const char win32_name,
const char win64_name 
)
static

Definition at line 1571 of file wow64.c.

1572{
1573 BYTE *ptr;
1574 BOOL ret;
1575
1577 {
1578 static const BYTE fast_forward[] = { 0x48, 0x8b, 0xc4, 0x48, 0x89, 0x58, 0x20, 0x55, 0x5d, 0xe9 };
1579
1580 if (!(ptr = pRtlFindExportedRoutineByName( module, win64_name )))
1581 {
1582 skip( "%s not exported\n", win64_name );
1583 return NULL;
1584 }
1585 if (memcmp( ptr, fast_forward, sizeof(fast_forward) ))
1586 {
1587 skip( "unrecognized x64 thunk for %s\n", win64_name );
1588 return NULL;
1589 }
1590 ptr += sizeof(fast_forward);
1591 ptr += sizeof(LONG) + *(LONG *)ptr;
1592 }
1593 else if (!(ptr = pRtlFindExportedRoutineByName( module, win32_name )))
1594 {
1595 skip( "%s not exported\n", win32_name );
1596 return NULL;
1597 }
1598
1599 memcpy( old_code, ptr, sizeof(old_code) );
1601 ok( ret, "hooking failed %p %lu\n", ptr, GetLastError() );
1602 return ptr;
1603}
#define skip(...)
Definition: atltest.h:64
#define GetCurrentProcess()
Definition: compat.h:759
BOOL NTAPI WriteProcessMemory(IN HANDLE hProcess, IN LPVOID lpBaseAddress, IN LPCVOID lpBuffer, IN SIZE_T nSize, OUT SIZE_T *lpNumberOfBytesWritten)
Definition: proc.c:1906
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2802
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
long LONG
Definition: pedump.c:60
static BYTE old_code[sizeof(hook_code)]
Definition: wow64.c:1569
static DWORD hook_code[]
Definition: wow64.c:1481
static USHORT current_machine
Definition: wow64.c:91
static void ULONG *static void void ULONG *static void ULONG *static HANDLE void **static void *WINAPI * pRtlFindExportedRoutineByName(HMODULE, const char *)
unsigned char BYTE
Definition: xxhash.c:193

Referenced by test_notifications().

◆ init()

static void init ( void  )
static

Definition at line 112 of file wow64.c.

113{
114 HMODULE ntdll = GetModuleHandleA( "ntdll.dll" );
115
117
118 if (is_wow64)
119 {
120 TEB64 *teb64 = ULongToPtr( NtCurrentTeb()->GdiBatchCount );
121
122 if (teb64)
123 {
124 PEB64 *peb64 = ULongToPtr(teb64->Peb);
125 old_wow64 = !peb64->LdrData;
126 }
127 }
128
129#define GET_PROC(func) p##func = (void *)GetProcAddress( ntdll, #func )
134 GET_PROC( RtlOpenCrossProcessEmulatorWorkConnection );
139 GET_PROC( RtlWow64GetThreadContext );
141#ifdef _WIN64
143 GET_PROC( RtlWow64GetCpuAreaInfo );
144 GET_PROC( RtlWow64GetThreadSelectorEntry );
145 GET_PROC( RtlWow64PopAllCrossProcessWorkFromWorkList );
146 GET_PROC( RtlWow64PopCrossProcessWorkFromFreeList );
147 GET_PROC( RtlWow64PushCrossProcessWorkOntoFreeList );
148 GET_PROC( RtlWow64PushCrossProcessWorkOntoWorkList );
149 GET_PROC( RtlWow64RequestCrossProcessHeavyFlush );
150 GET_PROC( ProcessPendingCrossProcessEmulatorWork );
151#else
158#endif
159#undef GET_PROC
160
161 if (pNtQuerySystemInformationEx)
162 {
165 NTSTATUS status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process,
166 sizeof(process), machines, sizeof(machines), NULL );
167 if (!status)
168 for (int i = 0; machines[i].Machine; i++)
169 trace( "machine %04x kernel %u user %u native %u process %u wow64 %u\n",
170 machines[i].Machine, machines[i].KernelMode, machines[i].UserMode,
171 machines[i].Native, machines[i].Process, machines[i].WoW64Container );
172 }
173
174 if (pRtlGetNativeSystemInformation)
175 {
177 ULONG len;
178
179 pRtlGetNativeSystemInformation( SystemCpuInformation, &info, sizeof(info), &len );
180 switch (info.ProcessorArchitecture)
181 {
184 break;
187 break;
188 }
189 }
190
191 trace( "current %04x native %04x\n", current_machine, native_machine );
192
195}
#define trace
Definition: atltest.h:70
VOID NTAPI KiUserExceptionDispatcher(PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context)
Definition: dispatch.c:26
#define IsWow64Process
Definition: compat.h:760
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
unsigned int Native
Definition: fpcontrol.c:84
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
@ SystemSupportedProcessorArchitectures
Definition: extypes.h:414
#define KernelMode
Definition: asm.h:38
#define UserMode
Definition: asm.h:39
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MEM_COMMIT
Definition: nt_native.h:1316
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
PVOID NTAPI RtlFindExportedRoutineByName(_In_ PVOID ImageBase, _In_ PCSTR ExportName)
Finds the address of a given named exported routine in a loaded image. Note that this function does n...
Definition: sysldr.c:401
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
NTSYSAPI NTSTATUS WINAPI RtlWow64GetProcessMachines(HANDLE, USHORT *, USHORT *)
NTSYSAPI NTSTATUS WINAPI NtQuerySystemInformationEx(SYSTEM_INFORMATION_CLASS, void *, ULONG, void *, ULONG, ULONG *)
NTSYSAPI NTSTATUS WINAPI NtWow64AllocateVirtualMemory64(HANDLE, ULONG64 *, ULONG64, ULONG64 *, ULONG, ULONG)
NTSYSAPI NTSTATUS WINAPI NtWow64WriteVirtualMemory64(HANDLE, ULONG64, const void *, ULONG64, ULONG64 *)
NTSYSAPI NTSTATUS WINAPI NtMapViewOfSectionEx(HANDLE, HANDLE, PVOID *, const LARGE_INTEGER *, SIZE_T *, ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG)
NTSYSAPI USHORT WINAPI RtlWow64GetCurrentMachine(void)
NTSYSAPI NTSTATUS WINAPI RtlGetNativeSystemInformation(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *)
NTSYSAPI NTSTATUS WINAPI RtlWow64GetSharedInfoProcess(HANDLE, BOOLEAN *, WOW64INFO *)
NTSYSAPI NTSTATUS WINAPI NtWow64ReadVirtualMemory64(HANDLE, ULONG64, void *, ULONG64, ULONG64 *)
@ SystemCpuInformation
Definition: winternl.h:2014
NTSYSAPI NTSTATUS WINAPI NtWow64GetNativeSystemInformation(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *)
NTSYSAPI NTSTATUS WINAPI NtWow64IsProcessorFeaturePresent(UINT)
NTSYSAPI NTSTATUS WINAPI RtlWow64IsWowGuestMachineSupported(USHORT, BOOLEAN *)
NTSYSAPI NTSTATUS WINAPI NtWow64QueryInformationProcess64(HANDLE, PROCESSINFOCLASS, void *, ULONG, ULONG *)
#define PROCESSOR_ARCHITECTURE_ARM64
Definition: winnt_old.h:503
static BOOL is_wow64
Definition: wow64.c:74
#define GET_PROC(func)

Referenced by START_TEST().

◆ invoke_syscall()

static NTSTATUS invoke_syscall ( const char name,
ULONG  args32[] 
)
static

Definition at line 3013 of file wow64.c.

3014{
3015 ULONG64 args64[] = { -1, PtrToUlong( args32 ) };
3016 ULONG64 func = get_proc_address64( wow64_module, "Wow64SystemServiceEx" );
3017 BYTE *syscall = (BYTE *)GetProcAddress( GetModuleHandleA("ntdll.dll"), name );
3018
3019 ok( syscall != NULL, "syscall %s not found\n", name );
3020 if (syscall[0] == 0xb8)
3021 args64[0] = *(DWORD *)(syscall + 1);
3022 else
3023 win_skip( "syscall thunk %s not recognized\n", name );
3024
3025 return call_func64( func, ARRAY_SIZE(args64), args64 );
3026}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define PtrToUlong(u)
Definition: config.h:107
unsigned long DWORD
Definition: ntddk_ex.h:95
#define win_skip
Definition: minitest.h:67
static NTSTATUS call_func64(ULONG64 func64, int nb_args, ULONG64 *args)
Definition: wow64.c:2288
static ULONG64 get_proc_address64(ULONG64 module, const char *name)
Definition: wow64.c:2348
static ULONG64 wow64_module
Definition: wow64.c:2296

Referenced by test_syscalls().

◆ iosb_delayed_write_thread()

static DWORD WINAPI iosb_delayed_write_thread ( void arg)
static

Definition at line 2834 of file wow64.c.

2835{
2836 HANDLE client = arg;
2837 DWORD size;
2838 BOOL ret;
2839
2840 Sleep(100);
2841
2842 ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
2843 ok( ret == TRUE, "got error %lu\n", GetLastError() );
2844
2845 return 0;
2846}
#define TRUE
Definition: types.h:120
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static FILE * client
Definition: client.c:37
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:726
void * arg
Definition: msvc.h:10

Referenced by test_iosb().

◆ is_machine_32bit()

static BOOL is_machine_32bit ( USHORT  machine)
static

Definition at line 106 of file wow64.c.

107{
109}
#define IMAGE_FILE_MACHINE_ARMNT
Definition: compat.h:127
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174

Referenced by test_process_architecture(), and test_query_architectures().

◆ NTSTATUS()

static NTSTATUS ( WINAPI pNtQuerySystemInformation)
static

◆ pop_from_free_list()

static CROSS_PROCESS_WORK_ENTRY * pop_from_free_list ( CROSS_PROCESS_WORK_HDR list)
static

Definition at line 461 of file wow64.c.

462{
463#ifdef _WIN64
464 return pRtlWow64PopCrossProcessWorkFromFreeList( list );
465#else
467
468 if (!list->first) return NULL;
469 ret = (CROSS_PROCESS_WORK_ENTRY *)((char *)list + list->first);
470 list->first = ret->next;
471 ret->next = 0;
472 return ret;
473#endif
474}

Referenced by add_work_item().

◆ pop_from_work_list()

static CROSS_PROCESS_WORK_ENTRY * pop_from_work_list ( CROSS_PROCESS_WORK_HDR list)
static

Definition at line 476 of file wow64.c.

477{
478#ifdef _WIN64
480
481 return pRtlWow64PopAllCrossProcessWorkFromWorkList( list, &flush );
482#else
483 UINT pos = list->first, prev_pos = 0;
484
485 list->first = 0;
486 if (!pos) return NULL;
487
488 for (;;) /* reverse the list */
489 {
491 UINT next = entry->next;
492 entry->next = prev_pos;
493 if (!next) return entry;
494 prev_pos = pos;
495 pos = next;
496 }
497#endif
498}
unsigned char BOOLEAN
Definition: actypes.h:127
int flush
Definition: zlib.h:309

Referenced by test_cross_process_notifications().

◆ process_work_items()

static void process_work_items ( void  )
static

Definition at line 1556 of file wow64.c.

1557{
1558#ifdef _WIN64
1559 if (pProcessPendingCrossProcessEmulatorWork)
1560 {
1561 pProcessPendingCrossProcessEmulatorWork();
1562 return;
1563 }
1564#endif
1566 SleepEx( 1, TRUE );
1567}
DWORD WINAPI QueueUserAPC(IN PAPCFUNC pfnAPC, IN HANDLE hThread, IN ULONG_PTR dwData)
Definition: thread.c:959
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:738
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1146
static void CALLBACK dummy_apc(ULONG_PTR arg)
Definition: wow64.c:1501

Referenced by test_notifications().

◆ pRtlFindExportedRoutineByName()

static void ULONG *static void void ULONG *static void ULONG *static HANDLE void **static void *WINAPI * pRtlFindExportedRoutineByName ( HMODULE  ,
const char  
)
static

◆ push_onto_free_list()

static void push_onto_free_list ( CROSS_PROCESS_WORK_HDR list,
CROSS_PROCESS_WORK_ENTRY entry 
)
static

Definition at line 440 of file wow64.c.

441{
442#ifdef _WIN64
443 pRtlWow64PushCrossProcessWorkOntoFreeList( list, entry );
444#else
445 entry->next = list->first;
446 list->first = (char *)entry - (char *)list;
447#endif
448}

Referenced by expect_cross_work_entry_().

◆ push_onto_work_list()

static void push_onto_work_list ( CROSS_PROCESS_WORK_HDR list,
CROSS_PROCESS_WORK_ENTRY entry 
)
static

Definition at line 450 of file wow64.c.

451{
452#ifdef _WIN64
453 void *ret;
454 pRtlWow64PushCrossProcessWorkOntoWorkList( list, entry, &ret );
455#else
456 entry->next = list->first;
457 list->first = (char *)entry - (char *)list;
458#endif
459}

Referenced by add_work_item().

◆ request_cross_process_flush()

static void request_cross_process_flush ( CROSS_PROCESS_WORK_HDR list)
static

Definition at line 500 of file wow64.c.

501{
502#ifdef _WIN64
503 pRtlWow64RequestCrossProcessHeavyFlush( list );
504#else
506#endif
507}
#define CROSS_PROCESS_LIST_FLUSH
Definition: winternl.h:430

Referenced by test_notifications().

◆ reset_results()

static void reset_results ( ULONG64 results)
static

Definition at line 1511 of file wow64.c.

1512{
1513 memset( results + 1, 0xcc, 0x1000 - sizeof(*results) );
1514 results[0] = (ULONG_PTR)(results + 2);
1515}

Referenced by expect_notifications_(), and test_notifications().

◆ START_TEST()

START_TEST ( wow64  )

Definition at line 3205 of file wow64.c.

3206{
3207 init();
3208#if !defined (__REACTOS__) || (DLL_EXPORT_VERSION >= 0x600)
3210#endif
3211 test_peb_teb();
3214#ifdef _WIN64
3215 test_xtajit64();
3216 test_cross_process_work_list();
3217#else
3218 test_nt_wow64();
3219 test_modules();
3221 test_iosb();
3222 test_syscalls();
3223#endif
3225 test_cpu_area();
3227 test_arm64ec();
3228}
static void test_init_block(void)
Definition: wow64.c:2670
static void init(void)
Definition: wow64.c:112
static void test_modules(void)
Definition: wow64.c:2423
static void test_syscalls(void)
Definition: wow64.c:3028
static void test_arm64ec(void)
Definition: wow64.c:3181
static void test_memory_notifications(void)
Definition: wow64.c:2800
static void test_iosb(void)
Definition: wow64.c:2849
static void test_exception_dispatcher(void)
Definition: wow64.c:3145
static void test_query_architectures(void)
Definition: wow64.c:317
static void test_peb_teb(void)
Definition: wow64.c:910
static void test_nt_wow64(void)
Definition: wow64.c:2441
static void test_cpu_area(void)
Definition: wow64.c:3115
static void test_image_mappings(void)
Definition: wow64.c:1334
static void test_selectors(void)
Definition: wow64.c:1186

◆ test_amd64_shared_info()

static void test_amd64_shared_info ( HANDLE  process)
static

Definition at line 871 of file wow64.c.

872{
873 ULONG i, peb_data[0x200], buffer[16];
876 SIZE_T res;
877 BOOLEAN wow64 = 0xcc;
878 struct arm64ec_shared_info *info = NULL;
879
880 NtQueryInformationProcess( process, ProcessBasicInformation, &proc_info, sizeof(proc_info), NULL );
881
882 memset( buffer, 0xcc, sizeof(buffer) );
883 status = pRtlWow64GetSharedInfoProcess( process, &wow64, (WOW64INFO *)buffer );
884 ok( !status, "RtlWow64GetSharedInfoProcess failed %lx\n", status );
885 ok( !wow64, "wrong wow64 %u\n", wow64 );
886 ok( buffer[0] == 0xcccccccc, "buffer initialized %lx\n", buffer[0] );
887
888 if (ReadProcessMemory( process, (void *)proc_info.PebBaseAddress, peb_data, sizeof(peb_data), &res ))
889 {
890 ULONG limit = (sizeof(peb_data) - sizeof(*info)) / sizeof(ULONG);
891 for (i = 0; i < limit; i++)
892 {
893 info = (struct arm64ec_shared_info *)(peb_data + i);
894 if (info->NativeMachineType == IMAGE_FILE_MACHINE_ARM64 &&
895 info->EmulatedMachineType == IMAGE_FILE_MACHINE_AMD64)
896 {
897 trace( "shared info found at %lx\n", i * 4 );
898 break;
899 }
900 }
901 ok( i < limit, "shared info not found in PEB\n" );
902 }
903 if (info && info->SectionHandle && info->CrossProcessWorkList)
904 test_cross_process_notifications( process, info->SectionHandle, info->CrossProcessWorkList );
905 else
906 trace( "no shared info section handle\n" );
907}
@ ProcessBasicInformation
Definition: cicbase.cpp:63
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
GLuint res
Definition: glext.h:9613
GLint limit
Definition: glext.h:10326
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
static void test_cross_process_notifications(HANDLE process, ULONG_PTR section, ULONG_PTR ptr)
Definition: wow64.c:536

Referenced by test_peb_teb().

◆ test_arm64ec()

static void test_arm64ec ( void  )
static

Definition at line 3181 of file wow64.c.

3182{
3183#ifdef __aarch64__
3185 char cmdline[MAX_PATH];
3186 char **argv;
3187
3188 trace( "restarting test as arm64ec\n" );
3189
3191 sprintf( cmdline, "%s %s", argv[0], argv[1] );
3193 {
3195 ok( ret == 0, "wait failed %lx\n", ret );
3197 ok( exit_code == 0xbeef, "wrong exit code %lx\n", exit_code );
3200 }
3201 else skip( "could not start arm64ec process: %lu\n", GetLastError() );
3202#endif
3203}
#define CloseHandle
Definition: compat.h:739
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1166
#define sprintf
Definition: sprintf.c:45
static UINT exit_code
Definition: process.c:80
#define argv
Definition: mplay32.c:18
int winetest_get_mainargs(char ***pargv)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
static BOOL create_process_machine(char *cmdline, DWORD flags, USHORT machine, PROCESS_INFORMATION *pi)
Definition: wow64.c:198

Referenced by START_TEST().

◆ test_cpu_area()

static void test_cpu_area ( void  )
static

Definition at line 3115 of file wow64.c.

3116{
3117 TEB64 *teb64 = (TEB64 *)NtCurrentTeb()->GdiBatchCount;
3118 ULONG64 ptr;
3120
3121 if (!is_wow64) return;
3122 if (!code_mem) return;
3123 if (!ntdll_module) return;
3124
3125 if ((ptr = get_proc_address64( ntdll_module, "RtlWow64GetCurrentCpuArea" )))
3126 {
3127 USHORT machine = 0xdead;
3130
3132 ok( !status, "RtlWow64GetCpuAreaInfo failed %lx\n", status );
3133 ok( machine == IMAGE_FILE_MACHINE_I386, "wrong machine %x\n", machine );
3134 ok( context == teb64->TlsSlots[WOW64_TLS_CPURESERVED] + 4, "wrong context %s / %s\n",
3136 ok( !context_ex, "got context_ex %s\n", wine_dbgstr_longlong(context_ex) );
3137 args[0] = args[1] = args[2] = 0;
3139 ok( !status, "RtlWow64GetCpuAreaInfo failed %lx\n", status );
3140 }
3141 else win_skip( "RtlWow64GetCpuAreaInfo not supported\n" );
3142
3143}
static ULONG CONTEXT_EX ** context_ex
Definition: exception.c:71
ULONG64 TlsSlots[64]
Definition: winternl.h:1299
Definition: http.c:7252
#define WOW64_TLS_CPURESERVED
Definition: winternl.h:1362
static ULONG64 ntdll_module
Definition: wow64.c:2296

Referenced by START_TEST().

◆ test_cross_process_notifications()

static void test_cross_process_notifications ( HANDLE  process,
ULONG_PTR  section,
ULONG_PTR  ptr 
)
static

Definition at line 536 of file wow64.c.

537{
540 UINT pos;
541 void *addr = NULL, *addr2;
542 SIZE_T size = 0;
543 DWORD old_prot;
547 BOOL ret;
548 BYTE data[] = { 0xcc, 0xcc, 0xcc };
549
552 ok( ret, "DuplicateHandle failed %lu\n", GetLastError() );
555 ok( !status, "NtMapViewOfSection failed %lx\n", status );
556 ok( size == 0x4000, "unexpected size %Ix\n", size );
557 list = addr;
558 addr2 = malloc( size );
559 ret = ReadProcessMemory( process, (void *)ptr, addr2, size, &size );
560 ok( ret, "ReadProcessMemory failed %lu\n", GetLastError() );
561 ok( !memcmp( addr2, addr, size ), "wrong data\n" );
562 free( addr2 );
564
565 if (pRtlOpenCrossProcessEmulatorWorkConnection)
566 {
567 pRtlOpenCrossProcessEmulatorWorkConnection( process, &mapping, &addr2 );
568 ok( mapping != 0, "got 0 handle\n" );
569 ok( addr2 != NULL, "got NULL data\n" );
570 ok( !memcmp( addr2, addr, size ), "wrong data\n" );
571 UnmapViewOfFile( addr2 );
572 addr2 = NULL;
573 size = 0;
576 ok( !status, "NtMapViewOfSection failed %lx\n", status );
577 ok( !memcmp( addr2, addr, size ), "wrong data\n" );
578 ok( CloseHandle( mapping ), "invalid handle\n" );
579 UnmapViewOfFile( addr2 );
580
581 mapping = (HANDLE)0xdead;
582 addr2 = (void *)0xdeadbeef;
583 pRtlOpenCrossProcessEmulatorWorkConnection( GetCurrentProcess(), &mapping, &addr2 );
584 ok( !mapping, "got handle %p\n", mapping );
585 ok( !addr2, "got data %p\n", addr2 );
586 }
587 else skip( "RtlOpenCrossProcessEmulatorWorkConnection not supported\n" );
588
590
591 /* set argument values in free list to detect changes */
592 for (pos = list->free_list.first; pos; pos = entry->next )
593 {
594 entry = CROSS_PROCESS_LIST_ENTRY( &list->free_list, pos );
595 memset( entry->args, 0xcc, sizeof(entry->args) );
596 }
597
599 entry = pop_from_work_list( &list->work_list );
601 {
603 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE, 0, 0xcccccccc );
605 MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE, 0, 0xcccccccc );
606 }
607 ok( !entry, "not at end of list\n" );
608
609 VirtualProtectEx( process, (char *)addr + 0x333, 17, PAGE_READONLY, &old_prot );
610 entry = pop_from_work_list( &list->work_list );
612 {
614 (char *)addr + 0x333, 17,
615 PAGE_READONLY, 0, 0xcccccccc, 0xcccccccc );
617 PAGE_READONLY, 0, 0xcccccccc, 0xcccccccc );
618 }
619 ok( !entry, "not at end of list\n" );
620
622 entry = pop_from_work_list( &list->work_list );
624 {
626 MEM_RELEASE, 0, 0xcccccccc, 0xcccccccc );
628 MEM_RELEASE, 0, 0xcccccccc, 0xcccccccc );
629 }
630 ok( !entry, "not at end of list\n" );
631
632 addr = (void *)0x123;
633 size = 0x321;
636 "NtAllocateVirtualMemory failed %lx\n", status );
637 entry = pop_from_work_list( &list->work_list );
639 {
641 MEM_COMMIT, PAGE_EXECUTE_READ, 0, 0xcccccccc );
643 MEM_COMMIT, PAGE_EXECUTE_READ, status, 0xcccccccc );
644 }
645 ok( !entry, "not at end of list\n" );
646
647 addr = NULL;
648 size = 0x321;
650 ok( status == STATUS_INVALID_PARAMETER, "NtAllocateVirtualMemory failed %lx\n", status );
651 entry = pop_from_work_list( &list->work_list );
653 {
655 0, PAGE_EXECUTE_READ, 0, 0xcccccccc );
657 0, PAGE_EXECUTE_READ, status, 0xcccccccc );
658 }
659 ok( !entry, "not at end of list\n" );
660
661 addr = NULL;
662 size = 0x4321;
664 ok( !status, "NtAllocateVirtualMemory failed %lx\n", status );
665 entry = pop_from_work_list( &list->work_list );
667 {
669 MEM_RESERVE, PAGE_EXECUTE_READWRITE, 0, 0xcccccccc );
671 MEM_RESERVE, PAGE_EXECUTE_READWRITE, 0, 0xcccccccc );
672 }
673 ok( !entry, "not at end of list\n" );
674
675 size = 0x4321;
677 ok( !status, "NtAllocateVirtualMemory failed %lx\n", status );
678 entry = pop_from_work_list( &list->work_list );
680 {
682 MEM_COMMIT, PAGE_READWRITE, 0, 0xcccccccc );
684 MEM_COMMIT, PAGE_READWRITE, 0, 0xcccccccc );
685 }
686 ok( !entry, "not at end of list\n" );
687
688 addr2 = (char *)addr + 0x111;
689 size = 23;
691 ok( !status, "NtProtectVirtualMemory failed %lx\n", status );
692 entry = pop_from_work_list( &list->work_list );
694 {
696 PAGE_EXECUTE_READWRITE, 0, 0xcccccccc, 0xcccccccc );
698 PAGE_EXECUTE_READWRITE, 0, 0xcccccccc, 0xcccccccc );
699 }
700 ok( !entry, "not at end of list\n" );
701
702 addr2 = (char *)addr + 0x222;
703 size = 34;
706 "NtProtectVirtualMemory failed %lx\n", status );
707 entry = pop_from_work_list( &list->work_list );
709 {
711 (char *)addr + 0x222, 34,
712 PAGE_EXECUTE_WRITECOPY, 0, 0xcccccccc, 0xcccccccc );
714 (char *)addr + 0x222, 34,
715 PAGE_EXECUTE_WRITECOPY, status, 0xcccccccc, 0xcccccccc );
716 }
717 ok( !entry, "not at end of list\n" );
718
719 status = NtWriteVirtualMemory( process, (char *)addr + 0x1111, data, sizeof(data), &size );
720 ok( !status, "NtWriteVirtualMemory failed %lx\n", status );
721 entry = pop_from_work_list( &list->work_list );
722 ok( !entry, "not at end of list\n" );
723
724 addr2 = (char *)addr + 0x1234;
725 size = 45;
727 ok( !status, "NtFreeVirtualMemory failed %lx\n", status );
728 entry = pop_from_work_list( &list->work_list );
730 {
732 MEM_DECOMMIT, 0, 0xcccccccc, 0xcccccccc );
734 MEM_DECOMMIT, 0, 0xcccccccc, 0xcccccccc );
735 }
736 ok( !entry, "not at end of list\n" );
737
738 size = 0;
740 ok( !status, "NtFreeVirtualMemory failed %lx\n", status );
741 entry = pop_from_work_list( &list->work_list );
743 {
745 MEM_RELEASE, 0, 0xcccccccc, 0xcccccccc );
747 MEM_RELEASE, 0, 0xcccccccc, 0xcccccccc );
748 }
749 ok( !entry, "not at end of list\n" );
750
751 addr = (void *)0x123;
752 size = 0;
755 "NtFreeVirtualMemory failed %lx\n", status );
756 entry = pop_from_work_list( &list->work_list );
758 {
760 MEM_RELEASE, 0, 0xcccccccc, 0xcccccccc );
762 MEM_RELEASE, status, 0xcccccccc, 0xcccccccc );
763 }
764 ok( !entry, "not at end of list\n" );
765
766 file = CreateFileA( "c:\\windows\\syswow64\\version.dll", GENERIC_READ | GENERIC_EXECUTE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
767 ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
769 ok( mapping != 0, "CreateFileMapping failed\n" );
770 addr = NULL;
771 size = 0;
772 offset.QuadPart = 0;
774 ok( NT_SUCCESS(status), "NtMapViewOfSection failed %lx\n", status );
775 entry = pop_from_work_list( &list->work_list );
776 ok( !entry, "list not empty\n" );
777
779 entry = pop_from_work_list( &list->work_list );
781 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc );
782 ok( !entry, "not at end of list\n" );
783
785 entry = pop_from_work_list( &list->work_list );
787 {
789 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc );
790 }
791 ok( !entry, "not at end of list\n" );
792
793 WriteProcessMemory( process, (char *)addr + 0x1ffe, data, sizeof(data), &size );
794 entry = pop_from_work_list( &list->work_list );
796 (char *)addr + 0x1000, 0x2000, 0x60000000 | PAGE_EXECUTE_WRITECOPY,
797 (current_machine != IMAGE_FILE_MACHINE_ARM64) ? 0 : 0xcccccccc,
798 0xcccccccc, 0xcccccccc );
800 (char *)addr + 0x1000, 0x2000,
801 0x60000000 | PAGE_EXECUTE_WRITECOPY, 0, 0xcccccccc, 0xcccccccc );
803 (char *)addr + 0x1ffe, sizeof(data),
804 0xcccccccc, 0xcccccccc, 0xcccccccc, 0xcccccccc );
806 (char *)addr + 0x1000, 0x2000, 0x60000000 | PAGE_EXECUTE_READ,
807 (current_machine != IMAGE_FILE_MACHINE_ARM64) ? 0 : 0xcccccccc,
808 0xcccccccc, 0xcccccccc );
810 (char *)addr + 0x1000, 0x2000,
811 0x60000000 | PAGE_EXECUTE_READ, 0, 0xcccccccc, 0xcccccccc );
812 ok( !entry, "not at end of list\n" );
813
815 ok( !status, "NtUnmapViewOfSection failed %lx\n", status );
816 entry = pop_from_work_list( &list->work_list );
817 ok( !entry, "list not empty\n" );
818
820 CloseHandle( file );
822}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3485
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3259
NTSTATUS WINAPI NtSuspendProcess(HANDLE handle)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define PAGE_READONLY
Definition: compat.h:138
#define UnmapViewOfFile
Definition: compat.h:746
#define OPEN_EXISTING
Definition: compat.h:775
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define GENERIC_READ
Definition: compat.h:135
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI DuplicateHandle(IN HANDLE hSourceProcessHandle, IN HANDLE hSourceHandle, IN HANDLE hTargetProcessHandle, OUT LPHANDLE lpTargetHandle, IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwOptions)
Definition: handle.c:149
BOOL WINAPI FlushInstructionCache(IN HANDLE hProcess, IN LPCVOID lpBaseAddress, IN SIZE_T nSize)
Definition: proc.c:1307
HANDLE NTAPI CreateFileMappingA(IN HANDLE hFile, IN LPSECURITY_ATTRIBUTES lpFileMappingAttributes, IN DWORD flProtect, IN DWORD dwMaximumSizeHigh, IN DWORD dwMaximumSizeLow, IN LPCSTR lpName)
Definition: filemap.c:23
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLintptr offset
Definition: glext.h:5920
GLenum GLenum GLenum GLenum mapping
Definition: glext.h:9031
#define SEC_IMAGE
Definition: mmtypes.h:97
#define MEM_DECOMMIT
Definition: nt_native.h:1318
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define PAGE_EXECUTE_READ
Definition: nt_native.h:1310
@ ViewShare
Definition: nt_native.h:1281
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1312
#define MEM_RELEASE
Definition: nt_native.h:1319
#define GENERIC_EXECUTE
Definition: nt_native.h:91
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5192
NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL)
Definition: virtual.c:2895
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:3076
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4457
NTSTATUS NTAPI NtFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress, _In_ SIZE_T FlushSize)
Definition: virtual.c:3009
#define STATUS_MEMORY_NOT_ALLOCATED
Definition: ntstatus.h:490
#define STATUS_INVALID_PARAMETER_4
Definition: ntstatus.h:572
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:354
#define STATUS_INVALID_PAGE_PROTECTION
Definition: ntstatus.h:399
Definition: fci.c:127
Definition: parser.c:56
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LPVOID NTAPI VirtualAllocEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:23
BOOL NTAPI VirtualProtectEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:153
BOOL NTAPI VirtualFreeEx(IN HANDLE hProcess, IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:83
@ CrossProcessPreVirtualProtect
Definition: winternl.h:423
@ CrossProcessPreVirtualFree
Definition: winternl.h:421
@ CrossProcessPostVirtualFree
Definition: winternl.h:422
@ CrossProcessPreVirtualAlloc
Definition: winternl.h:419
@ CrossProcessFlushCache
Definition: winternl.h:425
@ CrossProcessPostVirtualAlloc
Definition: winternl.h:420
@ CrossProcessPostVirtualProtect
Definition: winternl.h:424
static WORD WORD *static BOOLEAN WOW64INFO *static WOW64_CONTEXT *static BOOLEAN *static HANDLE
Definition: wow64.c:53
#define expect_cross_work_entry(list, entry, id, addr, size, arg0, arg1, arg2, arg3)
Definition: wow64.c:509
static CROSS_PROCESS_WORK_ENTRY * pop_from_work_list(CROSS_PROCESS_WORK_HDR *list)
Definition: wow64.c:476
#define DUPLICATE_SAME_ACCESS

Referenced by test_amd64_shared_info(), and test_wow64_shared_info().

◆ test_exception_dispatcher()

static void test_exception_dispatcher ( void  )
static

Definition at line 3145 of file wow64.c.

3146{
3147 ULONG64 ptr, hook_ptr, hook, expect, res;
3149 BYTE code[8];
3150
3151 if (!is_wow64) return;
3152 if (!code_mem) return;
3153 if (!ntdll_module) return;
3154
3155 ptr = get_proc_address64( ntdll_module, "KiUserExceptionDispatcher" );
3156 ok( ptr, "KiUserExceptionDispatcher not found\n" );
3157
3158 if (pNtWow64ReadVirtualMemory64)
3159 {
3161
3162 ok( process != 0, "failed to open current process %lu\n", GetLastError() );
3163 status = pNtWow64ReadVirtualMemory64( process, ptr, &code, sizeof(code), &res );
3164 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
3165
3166 /* cld; mov xxx(%rip),%rax */
3167 ok( code[0] == 0xfc && code[1] == 0x48 && code[2] == 0x8b && code[3] == 0x05,
3168 "wrong opcodes %02x %02x %02x %02x\n", code[0], code[1], code[2], code[3] );
3169 hook_ptr = ptr + 8 + *(int *)(code + 4);
3170 status = pNtWow64ReadVirtualMemory64( process, hook_ptr, &hook, sizeof(hook), &res );
3171 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
3172
3173 expect = get_proc_address64( wow64_module, "Wow64PrepareForException" );
3174 ok( hook == expect, "hook %I64x set to %I64x / %I64x\n", hook_ptr, hook, expect );
3175 NtClose( process );
3176 }
3177}
@ hook
Definition: SystemMenu.c:35
Definition: inflate.c:139

Referenced by START_TEST().

◆ test_image_mappings()

static void test_image_mappings ( void  )
static

Definition at line 1334 of file wow64.c.

1335{
1339 SIZE_T size;
1341 void *ptr;
1342
1343 if (!pNtMapViewOfSectionEx)
1344 {
1345 win_skip( "NtMapViewOfSectionEx() not supported\n" );
1346 return;
1347 }
1348
1349 offset.QuadPart = 0;
1350 file = CreateFileA( "c:\\windows\\system32\\version.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1351 ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
1353 ok( mapping != 0, "CreateFileMapping failed\n" );
1354 CloseHandle( file );
1355
1356 ptr = NULL;
1357 size = 0;
1359 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1361 {
1362 win_skip( "MemExtendedParameterImageMachine not supported\n" );
1363 NtClose( mapping );
1364 return;
1365 }
1367 {
1369 "NtMapViewOfSection returned %08lx\n", status );
1371 }
1373 {
1374 todo_wine
1375 ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status );
1377 }
1378 else ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1379
1380 ptr = NULL;
1381 size = 0;
1383 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1385 {
1387 "NtMapViewOfSection returned %08lx\n", status );
1389 }
1390 else ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1391
1392 ptr = NULL;
1393 size = 0;
1395 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1397 {
1398 switch (current_machine)
1399 {
1402 "NtMapViewOfSection returned %08lx\n", status );
1404 break;
1406 ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status );
1408 break;
1409 default:
1410 ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1411 break;
1412 }
1413 }
1414 else ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1415
1416 ptr = NULL;
1417 size = 0;
1419 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1420 ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1421
1422 ptr = NULL;
1423 size = 0;
1424 ext.ULong = 0;
1425 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1427 "NtMapViewOfSection returned %08lx\n", status );
1429
1430 NtClose( mapping );
1431
1432 if (is_wow64)
1433 {
1434 file = CreateFileA( "c:\\windows\\sysnative\\version.dll", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0 );
1435 ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
1436
1438 ok( mapping != 0, "CreateFileMapping failed\n" );
1439 CloseHandle( file );
1440
1441 ptr = NULL;
1442 size = 0;
1443 ext.ULong = native_machine;
1444 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1446 "NtMapViewOfSection returned %08lx\n", status );
1448
1449 ptr = NULL;
1450 size = 0;
1452 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1453 ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1454 NtClose( mapping );
1455 }
1457 {
1458 file = CreateFileA( "c:\\windows\\syswow64\\version.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
1459 ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
1460
1462 ok( mapping != 0, "CreateFileMapping failed\n" );
1463 CloseHandle( file );
1464
1465 ptr = NULL;
1466 size = 0;
1467 ext.ULong = native_machine;
1468 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1469 ok( status == STATUS_NOT_SUPPORTED, "NtMapViewOfSection returned %08lx\n", status );
1470
1471 ptr = NULL;
1472 size = 0;
1474 status = pNtMapViewOfSectionEx( mapping, process, &ptr, &offset, &size, 0, PAGE_READONLY, &ext, 1 );
1475 ok( status == STATUS_IMAGE_MACHINE_TYPE_MISMATCH, "NtMapViewOfSection returned %08lx\n", status );
1477 NtClose( mapping );
1478 }
1479}
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
static const WCHAR *const ext[]
Definition: module.c:53
#define todo_wine
Definition: minitest.h:80
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH
Definition: ntstatus.h:203
#define STATUS_IMAGE_NOT_AT_BASE
Definition: ntstatus.h:192
#define IMAGE_FILE_MACHINE_R3000
Definition: pedump.c:175
#define STATUS_SUCCESS
Definition: shellext.h:65
MEM_EXTENDED_PARAMETER
Definition: winnt_old.h:1265
@ MemExtendedParameterImageMachine
Definition: winnt_old.h:1238

Referenced by START_TEST().

◆ test_init_block()

static void test_init_block ( void  )
static

Definition at line 2670 of file wow64.c.

2671{
2672 HMODULE ntdll = GetModuleHandleA( "ntdll.dll" );
2673 ULONG i, size = 0, *init_block;
2674 ULONG64 ptr64, *block64;
2675 void *ptr;
2676
2677 if (!is_wow64) return;
2678 if ((ptr = GetProcAddress( ntdll, "LdrSystemDllInitBlock" )))
2679 {
2680 init_block = ptr;
2681 trace( "got init block %08lx\n", init_block[0] );
2682#define CHECK_FUNC(val,func) \
2683 ok( (val) == (ULONG_PTR)GetProcAddress( ntdll, func ), \
2684 "got %p for %s %p\n", (void *)(ULONG_PTR)(val), func, GetProcAddress( ntdll, func ))
2685 switch (init_block[0])
2686 {
2687 case 0x44: /* vistau64 */
2688 CHECK_FUNC( init_block[1], "LdrInitializeThunk" );
2689 CHECK_FUNC( init_block[2], "KiUserExceptionDispatcher" );
2690 CHECK_FUNC( init_block[3], "KiUserApcDispatcher" );
2691 CHECK_FUNC( init_block[4], "KiUserCallbackDispatcher" );
2692 CHECK_FUNC( init_block[5], "LdrHotPatchRoutine" );
2693 CHECK_FUNC( init_block[6], "ExpInterlockedPopEntrySListFault" );
2694 CHECK_FUNC( init_block[7], "ExpInterlockedPopEntrySListResume" );
2695 CHECK_FUNC( init_block[8], "ExpInterlockedPopEntrySListEnd" );
2696 CHECK_FUNC( init_block[9], "RtlUserThreadStart" );
2697 CHECK_FUNC( init_block[10], "RtlpQueryProcessDebugInformationRemote" );
2698 CHECK_FUNC( init_block[11], "EtwpNotificationThread" );
2699 ok( init_block[12] == (ULONG_PTR)ntdll, "got %p for ntdll %p\n",
2700 (void *)(ULONG_PTR)init_block[12], ntdll );
2701 size = 13 * sizeof(*init_block);
2702 break;
2703 case 0x50: /* win7 */
2704 CHECK_FUNC( init_block[4], "LdrInitializeThunk" );
2705 CHECK_FUNC( init_block[5], "KiUserExceptionDispatcher" );
2706 CHECK_FUNC( init_block[6], "KiUserApcDispatcher" );
2707 CHECK_FUNC( init_block[7], "KiUserCallbackDispatcher" );
2708 CHECK_FUNC( init_block[8], "LdrHotPatchRoutine" );
2709 CHECK_FUNC( init_block[9], "ExpInterlockedPopEntrySListFault" );
2710 CHECK_FUNC( init_block[10], "ExpInterlockedPopEntrySListResume" );
2711 CHECK_FUNC( init_block[11], "ExpInterlockedPopEntrySListEnd" );
2712 CHECK_FUNC( init_block[12], "RtlUserThreadStart" );
2713 CHECK_FUNC( init_block[13], "RtlpQueryProcessDebugInformationRemote" );
2714 CHECK_FUNC( init_block[14], "EtwpNotificationThread" );
2715 ok( init_block[15] == (ULONG_PTR)ntdll, "got %p for ntdll %p\n",
2716 (void *)(ULONG_PTR)init_block[15], ntdll );
2717 /* CHECK_FUNC( init_block[16], "LdrSystemDllInitBlock" ); not always present */
2718 size = 17 * sizeof(*init_block);
2719 break;
2720 case 0x70: /* win8 */
2721 CHECK_FUNC( init_block[4], "LdrInitializeThunk" );
2722 CHECK_FUNC( init_block[5], "KiUserExceptionDispatcher" );
2723 CHECK_FUNC( init_block[6], "KiUserApcDispatcher" );
2724 CHECK_FUNC( init_block[7], "KiUserCallbackDispatcher" );
2725 CHECK_FUNC( init_block[8], "ExpInterlockedPopEntrySListFault" );
2726 CHECK_FUNC( init_block[9], "ExpInterlockedPopEntrySListResume" );
2727 CHECK_FUNC( init_block[10], "ExpInterlockedPopEntrySListEnd" );
2728 CHECK_FUNC( init_block[11], "RtlUserThreadStart" );
2729 CHECK_FUNC( init_block[12], "RtlpQueryProcessDebugInformationRemote" );
2730 ok( init_block[13] == (ULONG_PTR)ntdll, "got %p for ntdll %p\n",
2731 (void *)(ULONG_PTR)init_block[13], ntdll );
2732 CHECK_FUNC( init_block[14], "LdrSystemDllInitBlock" );
2733 size = 15 * sizeof(*init_block);
2734 break;
2735 case 0x80: /* win10 1507 */
2736 CHECK_FUNC( init_block[4], "LdrInitializeThunk" );
2737 CHECK_FUNC( init_block[5], "KiUserExceptionDispatcher" );
2738 CHECK_FUNC( init_block[6], "KiUserApcDispatcher" );
2739 CHECK_FUNC( init_block[7], "KiUserCallbackDispatcher" );
2740 if (GetProcAddress( ntdll, "ExpInterlockedPopEntrySListFault" ))
2741 {
2742 CHECK_FUNC( init_block[8], "ExpInterlockedPopEntrySListFault" );
2743 CHECK_FUNC( init_block[9], "ExpInterlockedPopEntrySListResume" );
2744 CHECK_FUNC( init_block[10], "ExpInterlockedPopEntrySListEnd" );
2745 CHECK_FUNC( init_block[11], "RtlUserThreadStart" );
2746 CHECK_FUNC( init_block[12], "RtlpQueryProcessDebugInformationRemote" );
2747 ok( init_block[13] == (ULONG_PTR)ntdll, "got %p for ntdll %p\n",
2748 (void *)(ULONG_PTR)init_block[13], ntdll );
2749 CHECK_FUNC( init_block[14], "LdrSystemDllInitBlock" );
2750 size = 15 * sizeof(*init_block);
2751 }
2752 else /* win10 1607 */
2753 {
2754 CHECK_FUNC( init_block[8], "RtlUserThreadStart" );
2755 CHECK_FUNC( init_block[9], "RtlpQueryProcessDebugInformationRemote" );
2756 ok( init_block[10] == (ULONG_PTR)ntdll, "got %p for ntdll %p\n",
2757 (void *)(ULONG_PTR)init_block[10], ntdll );
2758 CHECK_FUNC( init_block[11], "LdrSystemDllInitBlock" );
2759 size = 12 * sizeof(*init_block);
2760 }
2761 break;
2762 case 0xe0: /* win10 1809 */
2763 case 0xf0: /* win10 2004 */
2764 case 0x128: /* win11 24h2 */
2765 block64 = ptr;
2766 CHECK_FUNC( block64[3], "LdrInitializeThunk" );
2767 CHECK_FUNC( block64[4], "KiUserExceptionDispatcher" );
2768 CHECK_FUNC( block64[5], "KiUserApcDispatcher" );
2769 CHECK_FUNC( block64[6], "KiUserCallbackDispatcher" );
2770 CHECK_FUNC( block64[7], "RtlUserThreadStart" );
2771 CHECK_FUNC( block64[8], "RtlpQueryProcessDebugInformationRemote" );
2773 ok( block64[9] == (ULONG_PTR)ntdll, "got %p for ntdll %p\n",
2774 (void *)(ULONG_PTR)block64[9], ntdll );
2775 CHECK_FUNC( block64[10], "LdrSystemDllInitBlock" );
2776 CHECK_FUNC( block64[11], "RtlpFreezeTimeBias" );
2777 size = 12 * sizeof(*block64);
2778 break;
2779 default:
2780 ok( 0, "unknown init block %08lx\n", init_block[0] );
2781 for (i = 0; i < init_block[0] / sizeof(ULONG); i++) trace("%04lx: %08lx\n", i, init_block[i]);
2782 break;
2783 }
2784#undef CHECK_FUNC
2785
2786 if (size && (ptr64 = get_proc_address64( ntdll_module, "LdrSystemDllInitBlock" )))
2787 {
2788 DWORD buffer[64];
2790 NTSTATUS status = pNtWow64ReadVirtualMemory64( process, ptr64, buffer, size, NULL );
2791 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2792 ok( !memcmp( buffer, init_block, size ), "wrong 64-bit init block\n" );
2793 NtClose( process );
2794 }
2795 }
2796 else todo_wine win_skip( "LdrSystemDllInitBlock not supported\n" );
2797}
void init_block(deflate_state *s)
Definition: trees.c:407
static void ULONG
Definition: wow64.c:43
#define CHECK_FUNC(val, func)

Referenced by START_TEST().

◆ test_iosb()

static void test_iosb ( void  )
static

Definition at line 2849 of file wow64.c.

2850{
2851 static const char pipe_name[] = "\\\\.\\pipe\\wow64iosbnamedpipe";
2854 ULONG64 read_func, flush_func;
2855 IO_STATUS_BLOCK iosb32;
2856 char buffer[6];
2857 DWORD size;
2858 BOOL ret;
2859 struct
2860 {
2861 union
2862 {
2864 ULONG64 Pointer;
2865 };
2867 } iosb64;
2868 ULONG64 args[] = { 0, 0, 0, 0, (ULONG_PTR)&iosb64, (ULONG_PTR)buffer, sizeof(buffer), 0, 0 };
2869 ULONG64 flush_args[] = { 0, (ULONG_PTR)&iosb64 };
2870
2871 if (!is_wow64) return;
2872 if (!code_mem) return;
2873 if (!ntdll_module) return;
2874 read_func = get_proc_address64( ntdll_module, "NtReadFile" );
2875 flush_func = get_proc_address64( ntdll_module, "NtFlushBuffersFile" );
2876
2877 /* async calls set iosb32 but not iosb64 */
2878
2881 4, 1024, 1024, 1000, NULL );
2882 ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
2883
2886 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
2887
2888 memset( buffer, 0xcc, sizeof(buffer) );
2889 memset( &iosb32, 0x55, sizeof(iosb32) );
2890 iosb64.Pointer = PtrToUlong( &iosb32 );
2891 iosb64.Information = 0xdeadbeef;
2892
2893 args[0] = (LONG_PTR)server;
2894 status = call_func64( read_func, ARRAY_SIZE(args), args );
2895 ok( status == STATUS_PENDING, "NtReadFile returned %lx\n", status );
2896 ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
2897 ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer );
2898 ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
2899
2900 ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
2901 ok( ret == TRUE, "got error %lu\n", GetLastError() );
2902
2903 ok( iosb32.Status == 0, "Wrong iostatus %lx\n", iosb32.Status );
2904 ok( iosb32.Information == sizeof("data"), "Wrong information %Ix\n", iosb32.Information );
2905 ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer );
2906 ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
2907 ok( !memcmp( buffer, "data", iosb32.Information ),
2908 "got wrong data %s\n", debugstr_an(buffer, iosb32.Information) );
2909
2910 memset( buffer, 0xcc, sizeof(buffer) );
2911 memset( &iosb32, 0x55, sizeof(iosb32) );
2912 iosb64.Pointer = PtrToUlong( &iosb32 );
2913 iosb64.Information = 0xdeadbeef;
2914
2915 ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
2916 ok( ret == TRUE, "got error %lu\n", GetLastError() );
2917
2918 status = call_func64( read_func, ARRAY_SIZE(args), args );
2919 ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status );
2920 ok( iosb32.Status == STATUS_SUCCESS, "status changed to %lx\n", iosb32.Status );
2921 ok( iosb32.Information == sizeof("data"), "info changed to %Ix\n", iosb32.Information );
2922 ok( iosb64.Pointer == PtrToUlong(&iosb32), "pointer changed to %I64x\n", iosb64.Pointer );
2923 ok( iosb64.Information == 0xdeadbeef, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
2924 ok( !memcmp( buffer, "data", iosb32.Information ),
2925 "got wrong data %s\n", debugstr_an(buffer, iosb32.Information) );
2926
2927 /* syscalls which are always synchronous set iosb64 but not iosb32 */
2928
2929 memset( &iosb32, 0x55, sizeof(iosb32) );
2930 iosb64.Pointer = PtrToUlong( &iosb32 );
2931 iosb64.Information = 0xdeadbeef;
2932
2933 flush_args[0] = (LONG_PTR)server;
2934 status = call_func64( flush_func, ARRAY_SIZE(flush_args), flush_args );
2935 ok( status == STATUS_SUCCESS, "NtFlushBuffersFile returned %lx\n", status );
2936 ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
2937 ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information );
2938 ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
2939 ok( iosb64.Information == 0, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
2940
2943
2944 /* synchronous calls set iosb64 but not iosb32 */
2945
2948 4, 1024, 1024, 1000, NULL );
2949 ok( server != INVALID_HANDLE_VALUE, "CreateNamedPipe failed: %lu\n", GetLastError() );
2950
2953 ok( client != INVALID_HANDLE_VALUE, "CreateFile failed: %lu\n", GetLastError() );
2954
2955 ret = WriteFile( client, "data", sizeof("data"), &size, NULL );
2956 ok( ret == TRUE, "got error %lu\n", GetLastError() );
2957
2958 memset( buffer, 0xcc, sizeof(buffer) );
2959 memset( &iosb32, 0x55, sizeof(iosb32) );
2960 iosb64.Pointer = PtrToUlong( &iosb32 );
2961 iosb64.Information = 0xdeadbeef;
2962
2963 args[0] = (LONG_PTR)server;
2964 status = call_func64( read_func, ARRAY_SIZE(args), args );
2965 ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status );
2966 ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
2967 ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information );
2968 ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
2969 ok( iosb64.Information == sizeof("data"), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
2970 ok( !memcmp( buffer, "data", iosb64.Information ),
2971 "got wrong data %s\n", debugstr_an(buffer, iosb64.Information) );
2972
2974
2975 memset( buffer, 0xcc, sizeof(buffer) );
2976 memset( &iosb32, 0x55, sizeof(iosb32) );
2977 iosb64.Pointer = PtrToUlong( &iosb32 );
2978 iosb64.Information = 0xdeadbeef;
2979
2980 args[0] = (LONG_PTR)server;
2981 status = call_func64( read_func, ARRAY_SIZE(args), args );
2982 ok( status == STATUS_SUCCESS, "NtReadFile returned %lx\n", status );
2983 todo_wine
2984 {
2985 ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
2986 ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information );
2987 ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
2988 ok( iosb64.Information == sizeof("data"), "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
2989 ok( !memcmp( buffer, "data", iosb64.Information ),
2990 "got wrong data %s\n", debugstr_an(buffer, iosb64.Information) );
2991 }
2992
2993 ret = WaitForSingleObject( thread, 1000 );
2994 ok(!ret, "got %d\n", ret );
2996
2997 memset( &iosb32, 0x55, sizeof(iosb32) );
2998 iosb64.Pointer = PtrToUlong( &iosb32 );
2999 iosb64.Information = 0xdeadbeef;
3000
3001 flush_args[0] = (LONG_PTR)server;
3002 status = call_func64( flush_func, ARRAY_SIZE(flush_args), flush_args );
3003 ok( status == STATUS_SUCCESS, "NtFlushBuffersFile returned %lx\n", status );
3004 ok( iosb32.Status == 0x55555555, "status changed to %lx\n", iosb32.Status );
3005 ok( iosb32.Information == 0x55555555, "info changed to %Ix\n", iosb32.Information );
3006 ok( iosb64.Pointer == STATUS_SUCCESS, "pointer changed to %I64x\n", iosb64.Pointer );
3007 ok( iosb64.Information == 0, "info changed to %Ix\n", (ULONG_PTR)iosb64.Information );
3008
3011}
static HANDLE thread
Definition: service.c:33
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
Status
Definition: gdiplustypes.h:25
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define FILE_FLAG_NO_BUFFERING
Definition: disk.h:45
HANDLE WINAPI CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: npipe.c:220
#define GENERIC_WRITE
Definition: nt_native.h:90
#define STATUS_PENDING
Definition: telnetd.h:14
#define LONG_PTR
Definition: treelist.c:79
static rfbScreenInfoPtr server
Definition: vnc.c:74
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define PIPE_ACCESS_DUPLEX
Definition: winbase.h:166
#define PIPE_WAIT
Definition: winbase.h:173
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:172
#define PIPE_TYPE_MESSAGE
Definition: winbase.h:170
static DWORD WINAPI iosb_delayed_write_thread(void *arg)
Definition: wow64.c:2834

Referenced by START_TEST().

◆ test_memory_notifications()

static void test_memory_notifications ( void  )
static

Definition at line 2800 of file wow64.c.

2801{
2803 WOW64INFO *info;
2804 DWORD i;
2805
2806 if (!xtajit_module)
2807 {
2808 skip( "xtajit.dll not loaded\n" );
2809 return;
2810 }
2812 {
2813 skip( "xtajit.dll loaded above 4G\n" );
2814 return;
2815 }
2816
2817 for (i = 0x400; i < 0x800; i += sizeof(ULONG))
2818 {
2819 info = (WOW64INFO *)((char *)NtCurrentTeb()->Peb + i);
2820 if (info->NativeMachineType == native_machine &&
2821 info->EmulatedMachineType == IMAGE_FILE_MACHINE_I386)
2822 {
2823 if (info->CrossProcessWorkList >> 32)
2824 skip( "cross-process work list above 4G (%I64x)\n", info->CrossProcessWorkList );
2825 else
2826 test_notifications( module, ULongToPtr( info->CrossProcessWorkList ));
2827 return;
2828 }
2829 }
2830 skip( "WOW64INFO not found\n" );
2831}
static void test_notifications(void)
Definition: txtsrv.c:1226
HANDLE HMODULE
Definition: typedefs.h:77
static ULONG64 xtajit_module
Definition: wow64.c:2297

Referenced by START_TEST().

◆ test_modules()

static void test_modules ( void  )
static

Definition at line 2423 of file wow64.c.

2424{
2425 if (!is_wow64) return;
2426 if (!pNtWow64ReadVirtualMemory64) return;
2429 {
2430 ok( main_module, "main module not found\n" );
2431 ok( ntdll_module, "64-bit ntdll not found\n" );
2432 ok( wow64_module, "wow64.dll not found\n" );
2434 ok( xtajit_module, "xtajit.dll not found\n" );
2435 else
2436 ok( wow64cpu_module, "wow64cpu.dll not found\n" );
2437 ok( wow64win_module, "wow64win.dll not found\n" );
2438 }
2439}
static ULONG64 wow64cpu_module
Definition: wow64.c:2297
static void check_module(ULONG64 base, const WCHAR *name)
Definition: wow64.c:2395
static void enum_modules64(void(*func)(ULONG64, const WCHAR *))
Definition: wow64.c:2299
static ULONG64 wow64win_module
Definition: wow64.c:2297

Referenced by START_TEST().

◆ test_notifications()

static void test_notifications ( HMODULE  module,
CROSS_PROCESS_WORK_LIST list 
)
static

Definition at line 1605 of file wow64.c.

1606{
1607 void *code, *ptr, *addr = NULL;
1608 DWORD old_prot;
1609 SIZE_T size;
1613
1616 VirtualProtect( code, 0x1000, PAGE_EXECUTE_READ, &old_prot );
1617 *(void **)&hook_code[2] = code;
1618
1619 results = (ULONG64 *)((char *)code + 0x1000);
1621
1622 file = CreateFileA( "c:\\windows\\system32\\version.dll", GENERIC_READ | GENERIC_EXECUTE,
1624 ok( file != INVALID_HANDLE_VALUE, "Failed to open version.dll\n" );
1626 ok( mapping != 0, "CreateFileMapping failed\n" );
1627
1628 if ((ptr = hook_notification_function( module, "BTCpuNotifyMemoryAlloc", "NotifyMemoryAlloc" )))
1629 {
1630 struct expected_notification expect_cross[2] =
1631 {
1632 { 6, { 0x1234567890, 0x6543210000, MEM_COMMIT, PAGE_EXECUTE_READ, 0, 0 } },
1633 { 6, { 0x1234567890, 0x6543210000, MEM_COMMIT, PAGE_EXECUTE_READ, 1, 0xdeadbeef } }
1634 };
1635 struct expected_notification expect_alloc[2] =
1636 {
1637 { 6, { 0, 0x123456, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE, 0, 0 } },
1638 { 6, { 0, 0x124000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE, 1, 0 } }
1639 };
1640
1641 add_work_item( list, CrossProcessPreVirtualAlloc, expect_cross[0].args[0], expect_cross[0].args[1],
1642 expect_cross[0].args[2], expect_cross[0].args[3], 0, 0 );
1643 add_work_item( list, CrossProcessPostVirtualAlloc, expect_cross[1].args[0], expect_cross[1].args[1],
1644 expect_cross[1].args[2], expect_cross[1].args[3], 0xdeadbeef, 0 );
1646 expect_notifications( results, 2, expect_cross, FALSE );
1647 ok( !list->work_list.first, "list not empty\n" );
1648
1649 size = expect_alloc[0].args[1];
1651 ok( !status, "NtAllocateVirtualMemory failed %lx\n", status );
1652 expect_alloc[1].args[0] = (ULONG_PTR)addr;
1653 expect_notifications( results, 2, expect_alloc, TRUE );
1655 }
1656
1657 if ((ptr = hook_notification_function( module, "BTCpuNotifyMemoryProtect", "NotifyMemoryProtect" )))
1658 {
1659 struct expected_notification expect_cross[2] =
1660 {
1661 { 5, { 0x1234567890, 0x6543210000, PAGE_READWRITE, 0, 0 } },
1662 { 5, { 0x1234567890, 0x6543210000, PAGE_READWRITE, 1, 0xdeadbeef } }
1663 };
1664 struct expected_notification expect_protect[2] =
1665 {
1666 { 5, { 0, 0x123456, PAGE_EXECUTE_READ, 0, 0 } },
1667 { 5, { 0, 0x124000, PAGE_EXECUTE_READ, 1, 0 } }
1668 };
1669
1672 expect_cross[0].args[1], expect_cross[0].args[2], 0, 0, 0 );
1674 expect_cross[1].args[1], expect_cross[1].args[2], 0xdeadbeef, 0, 0 );
1676 expect_notifications( results, 2, expect_cross, FALSE );
1677 ok( !list->work_list.first, "list not empty\n" );
1678
1679 expect_protect[1].args[0] = (ULONG_PTR)addr;
1680 addr = (char *)addr + 0x123;
1681 expect_protect[0].args[0] = (ULONG_PTR)addr;
1682 size = expect_protect[0].args[1];
1684 ok( !status, "NtProtectVirtualMemory failed %lx\n", status );
1685 expect_notifications( results, 2, expect_protect, TRUE );
1686
1689 }
1690
1691 if ((ptr = hook_notification_function( module, "BTCpuNotifyMemoryFree", "NotifyMemoryFree" )))
1692 {
1693 struct expected_notification expect_cross[2] =
1694 {
1695 { 5, { 0x1234567890, 0x6543210000, MEM_RELEASE, 0, 0 } },
1696 { 5, { 0x1234567890, 0x6543210000, MEM_RELEASE, 1, 0xdeadbeef } }
1697 };
1698 struct expected_notification expect_free[2] =
1699 {
1700 { 5, { 0, 0x123456, MEM_RELEASE, 0, 0 } },
1701 { 5, { 0, 0x124000, MEM_RELEASE, 1, 0 } }
1702 };
1703
1704 add_work_item( list, CrossProcessPreVirtualFree, expect_cross[0].args[0],
1705 expect_cross[0].args[1], expect_cross[0].args[2], 0, 0, 0 );
1706 add_work_item( list, CrossProcessPostVirtualFree, expect_cross[1].args[0],
1707 expect_cross[1].args[1], expect_cross[1].args[2], 0xdeadbeef, 0, 0 );
1709 expect_notifications( results, 2, expect_cross, FALSE );
1710 ok( !list->work_list.first, "list not empty\n" );
1711
1712 expect_free[0].args[0] = (ULONG_PTR)addr;
1713 expect_free[1].args[0] = (ULONG_PTR)addr;
1714 size = expect_free[0].args[1];
1716 ok( !status, "NtFreeVirtualMemory failed %lx\n", status );
1717 expect_notifications( results, 2, expect_free, TRUE );
1718
1720 }
1721
1722 if ((ptr = hook_notification_function( module, "BTCpuNotifyMemoryDirty", "BTCpu64NotifyMemoryDirty" )))
1723 {
1724 struct expected_notification expect = { 2, { 0x1234567890, 0x6543210000 } };
1725
1726 add_work_item( list, CrossProcessMemoryWrite, expect.args[0], expect.args[1], 0, 0, 0, 0 );
1729 ok( !list->work_list.first, "list not empty\n" );
1730
1732 }
1733
1734 if ((ptr = hook_notification_function( module, "BTCpuFlushInstructionCache2", "BTCpu64FlushInstructionCache" )))
1735 {
1736 struct expected_notification expect_cross = { 2, { 0x1234567890, 0x6543210000 } };
1737 struct expected_notification expect_flush = { 2, { 0, 0x1234 } };
1738
1741 expect_cross.args[1], 0, 0, 0, 0 );
1743 expect_notifications( results, 1, &expect_cross, FALSE );
1744 ok( !list->work_list.first, "list not empty\n" );
1745
1746 expect_flush.args[0] = (ULONG_PTR)ptr;
1747 NtFlushInstructionCache( GetCurrentProcess(), ptr, expect_flush.args[1] );
1748 expect_notifications( results, 1, &expect_flush, TRUE );
1749
1751 }
1752
1753 if ((ptr = hook_notification_function( module, "BTCpuFlushInstructionCacheHeavy", "FlushInstructionCacheHeavy" )))
1754 {
1755 struct expected_notification expect = { 2, { 0x1234567890, 0x6543210000 } };
1756 struct expected_notification expect2 = { 2 };
1757
1759 add_work_item( list, CrossProcessFlushCacheHeavy, expect.args[0], expect.args[1], 0, 0, 0, 0 );
1762 ok( !list->work_list.first, "list not empty\n" );
1763
1764 request_cross_process_flush( &list->work_list );
1767 ok( !list->work_list.first, "list not empty\n" );
1768
1770 }
1771
1772 if ((ptr = hook_notification_function( module, "BTCpuNotifyMapViewOfSection", "NotifyMapViewOfSection" )))
1773 {
1774 struct expected_notification expect = { 6 };
1776
1777 addr = NULL;
1778 size = 0;
1779 offset.QuadPart = 0;
1782 ok( NT_SUCCESS(status), "NtMapViewOfSection failed %lx\n", status );
1785
1786 /* only NtMapViewOfSection calls coming from the loader trigger a notification */
1787 NtCurrentTeb()->Tib.ArbitraryUserPointer = (WCHAR *)L"c:\\windows\\system32\\version.dll";
1788 addr = NULL;
1789 size = 0;
1793 ok( NT_SUCCESS(status), "NtMapViewOfSection failed %lx\n", status );
1794 expect.args[0] = results[2]; /* FIXME: first parameter unknown */
1795 expect.args[1] = (ULONG_PTR)addr;
1796 expect.args[3] = size;
1797 expect.args[5] = PAGE_READONLY;
1800
1801 results[1] = 0xdeadbeef;
1804#ifdef _WIN64
1805 if (NtCurrentTeb()->ChpeV2CpuAreaInfo->InSyscallCallback)
1806 {
1807 ok( status == STATUS_SUCCESS, "NtMapViewOfSection failed %lx\n", status );
1810 }
1811 else
1812#endif
1813 {
1814 ok( status == 0xdeadbeef, "NtMapViewOfSection failed %lx\n", status );
1815 expect.args[0] = results[2]; /* FIXME: first parameter unknown */
1816 expect.args[1] = (ULONG_PTR)addr;
1817 expect.args[3] = size;
1818 expect.args[5] = PAGE_READONLY;
1820 }
1821 NtCurrentTeb()->Tib.ArbitraryUserPointer = NULL;
1823 }
1824
1825 if ((ptr = hook_notification_function( module, "BTCpuNotifyUnmapViewOfSection", "NotifyUnmapViewOfSection" )))
1826 {
1827 struct expected_notification expect[2] = { { 3 }, { 3 } };
1829
1830 addr = NULL;
1831 size = 0;
1832 offset.QuadPart = 0;
1835 ok( NT_SUCCESS(status), "NtMapViewOfSection failed %lx\n", status );
1836 NtUnmapViewOfSection( GetCurrentProcess(), (char *)addr + 0x123 );
1837 expect[0].args[0] = expect[1].args[0] = (ULONG_PTR)addr + 0x123;
1838 expect[1].args[1] = 1;
1840
1841 NtUnmapViewOfSection( GetCurrentProcess(), (char *)0x1234 );
1842 expect[0].args[0] = expect[1].args[0] = 0x1234;
1843 expect[1].args[1] = 1;
1844 expect[1].args[2] = (ULONG)STATUS_NOT_MAPPED_VIEW;
1846
1848 }
1849
1850 if ((ptr = hook_notification_function( module, "BTCpuNotifyReadFile", "BTCpu64NotifyReadFile" )))
1851 {
1852 char buffer[0x123];
1854 struct expected_notification expect[2] =
1855 {
1856 { 5, { (ULONG_PTR)file, (ULONG_PTR)buffer, sizeof(buffer), 0, 0 } },
1857 { 5, { (ULONG_PTR)file, (ULONG_PTR)buffer, sizeof(buffer), 1, 0 } }
1858 };
1859
1861 status = NtReadFile( file, 0, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
1862 ok( !status, "NtReadFile failed %lx\n", status );
1864
1865 status = NtReadFile( (HANDLE)0xdead, 0, NULL, NULL, &io, buffer, sizeof(buffer), NULL, NULL );
1866 ok( status == STATUS_INVALID_HANDLE, "NtReadFile failed %lx\n", status );
1867 expect[0].args[0] = expect[1].args[0] = 0xdead;
1868 expect[1].args[4] = (ULONG)STATUS_INVALID_HANDLE;
1870
1872 }
1873
1874 if ((ptr = hook_notification_function( module, "BTCpuThreadTerm", "ThreadTerm" )))
1875 {
1876 struct expected_notification expect = { 2, { 0xdead, 0xbeef } };
1877
1879 status = NtTerminateThread( (HANDLE)0xdead, 0xbeef );
1880 ok( status == STATUS_INVALID_HANDLE, "NtTerminateThread failed %lx\n", status );
1882
1884 }
1885
1886 if ((ptr = hook_notification_function( module, "BTCpuProcessTerm", "ProcessTerm" )))
1887 {
1888 struct expected_notification expect[2] =
1889 {
1890 { 3, { 0, 0, 0 } },
1891 { 3, { 0, 1, 0 } }
1892 };
1893
1895 status = NtTerminateProcess( (HANDLE)0xdead, 0xbeef );
1896 ok( status == STATUS_INVALID_HANDLE, "NtTerminateProcess failed %lx\n", status );
1898
1899 status = NtTerminateProcess( 0, 0xbeef );
1900 ok( !status, "NtTerminateProcess failed %lx\n", status );
1902
1904 }
1905
1906 NtClose( mapping );
1907 NtClose( file );
1909}
#define STATUS_INVALID_HANDLE
Definition: d3dkmdt.h:40
#define expect2(expected1, expected2, got1, got2)
Definition: listview.c:50
static HANDLE PIO_APC_ROUTINE PVOID PIO_STATUS_BLOCK io
Definition: file.c:72
NTSTATUS NtTerminateThread(IN HANDLE ThreadHandle OPTIONAL, IN NTSTATUS ExitStatus)
Definition: kill.c:1287
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define STATUS_NOT_MAPPED_VIEW
Definition: ntstatus.h:355
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
ULONG64 args[6]
Definition: wow64.c:1508
BOOL NTAPI VirtualProtect(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:135
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
@ CrossProcessFlushCacheHeavy
Definition: winternl.h:426
@ CrossProcessMemoryWrite
Definition: winternl.h:427
static void request_cross_process_flush(CROSS_PROCESS_WORK_HDR *list)
Definition: wow64.c:500
static void add_work_item(CROSS_PROCESS_WORK_LIST *list, UINT id, ULONG64 addr, ULONG64 size, UINT arg0, UINT arg1, UINT arg2, UINT arg3)
Definition: wow64.c:1541
static void * hook_notification_function(HMODULE module, const char *win32_name, const char *win64_name)
Definition: wow64.c:1571
static const DWORD log_params_code[]
Definition: wow64.c:1488
#define expect_notifications(results, count, expect, syscall)
Definition: wow64.c:1517
static void process_work_items(void)
Definition: wow64.c:1556

◆ test_nt_wow64()

static void test_nt_wow64 ( void  )
static

Definition at line 2441 of file wow64.c.

2442{
2443 const char str[] = "hello wow64";
2444 char buffer[100];
2446 ULONG64 res;
2448
2449 ok( process != 0, "failed to open current process %lu\n", GetLastError() );
2450 if (pNtWow64ReadVirtualMemory64)
2451 {
2452 status = pNtWow64ReadVirtualMemory64( process, (ULONG_PTR)str, buffer, sizeof(str), &res );
2453 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2454 ok( res == sizeof(str), "wrong size %s\n", wine_dbgstr_longlong(res) );
2455 ok( !strcmp( buffer, str ), "wrong data %s\n", debugstr_a(buffer) );
2456 status = pNtWow64WriteVirtualMemory64( process, (ULONG_PTR)buffer, " bye ", 5, &res );
2457 ok( !status, "NtWow64WriteVirtualMemory64 failed %lx\n", status );
2458 ok( res == 5, "wrong size %s\n", wine_dbgstr_longlong(res) );
2459 ok( !strcmp( buffer, " bye wow64" ), "wrong data %s\n", debugstr_a(buffer) );
2460 /* current process pseudo-handle is broken on some Windows versions */
2461 status = pNtWow64ReadVirtualMemory64( GetCurrentProcess(), (ULONG_PTR)str, buffer, sizeof(str), &res );
2463 "NtWow64ReadVirtualMemory64 failed %lx\n", status );
2464 status = pNtWow64WriteVirtualMemory64( GetCurrentProcess(), (ULONG_PTR)buffer, " bye ", 5, &res );
2466 "NtWow64WriteVirtualMemory64 failed %lx\n", status );
2467 }
2468 else win_skip( "NtWow64ReadVirtualMemory64 not supported\n" );
2469
2470 if (pNtWow64AllocateVirtualMemory64)
2471 {
2472 ULONG64 ptr = 0;
2473 ULONG64 size = 0x2345;
2474
2475 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
2477 ok( !status, "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2478 ok( ptr, "ptr not set\n" );
2479 ok( size == 0x3000, "size not set %s\n", wine_dbgstr_longlong(size) );
2480 ptr += 0x1000;
2481 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
2483 ok( status == STATUS_CONFLICTING_ADDRESSES, "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2484 ptr = 0;
2485 size = 0;
2486 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
2489 "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2490 size = 0x1000;
2491 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 22, &size,
2494 "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2495 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 33, &size,
2498 "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2499 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0x3fffffff, &size,
2502 ok( !status, "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2503 ok( ptr < 0x40000000, "got wrong ptr %s\n", wine_dbgstr_longlong(ptr) );
2504 if (!status && pNtWow64WriteVirtualMemory64)
2505 {
2506 status = pNtWow64WriteVirtualMemory64( process, ptr, str, sizeof(str), &res );
2507 ok( !status, "NtWow64WriteVirtualMemory64 failed %lx\n", status );
2508 ok( res == sizeof(str), "wrong size %s\n", wine_dbgstr_longlong(res) );
2509 ok( !strcmp( (char *)(ULONG_PTR)ptr, str ), "wrong data %s\n",
2510 debugstr_a((char *)(ULONG_PTR)ptr) );
2511 ptr = 0;
2512 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
2514 ok( !status, "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2515 status = pNtWow64WriteVirtualMemory64( process, ptr, str, sizeof(str), &res );
2516 todo_wine
2518 "NtWow64WriteVirtualMemory64 failed %lx\n", status );
2519 todo_wine
2520 ok( !res || broken(res) /* win10 1709 */, "wrong size %s\n", wine_dbgstr_longlong(res) );
2521 }
2522 ptr = 0x9876543210ull;
2523 status = pNtWow64AllocateVirtualMemory64( process, &ptr, 0, &size,
2527 "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2528 if (!status) ok( ptr == 0x9876540000ull || broken(ptr == 0x76540000), /* win 8.1 */
2529 "wrong ptr %s\n", wine_dbgstr_longlong(ptr) );
2530 ptr = 0;
2531 status = pNtWow64AllocateVirtualMemory64( GetCurrentProcess(), &ptr, 0, &size,
2534 "NtWow64AllocateVirtualMemory64 failed %lx\n", status );
2535 }
2536 else win_skip( "NtWow64AllocateVirtualMemory64 not supported\n" );
2537
2538 if (pNtWow64GetNativeSystemInformation)
2539 {
2540 ULONG i, len;
2541 SYSTEM_BASIC_INFORMATION sbi, sbi2, sbi3;
2542
2543 memset( &sbi, 0xcc, sizeof(sbi) );
2544 status = pNtQuerySystemInformation( SystemBasicInformation, &sbi, sizeof(sbi), &len );
2545 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2546 ok( len == sizeof(sbi), "wrong length %ld\n", len );
2547
2548 memset( &sbi2, 0xcc, sizeof(sbi2) );
2549 status = pRtlGetNativeSystemInformation( SystemBasicInformation, &sbi2, sizeof(sbi2), &len );
2550 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2551 ok( len == sizeof(sbi2), "wrong length %ld\n", len );
2552
2553 ok( sbi.HighestUserAddress == (void *)0x7ffeffff, "wrong limit %p\n", sbi.HighestUserAddress);
2555 ok( sbi2.HighestUserAddress == (is_wow64 ? (void *)0xfffeffff : (void *)0x7ffeffff),
2556 "wrong limit %p\n", sbi.HighestUserAddress);
2557
2558 memset( &sbi3, 0xcc, sizeof(sbi3) );
2559 status = pNtWow64GetNativeSystemInformation( SystemBasicInformation, &sbi3, sizeof(sbi3), &len );
2560 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2561 ok( len == sizeof(sbi3), "wrong length %ld\n", len );
2562 ok( !memcmp( &sbi2, &sbi3, offsetof(SYSTEM_BASIC_INFORMATION,NumberOfProcessors)+1 ),
2563 "info is different\n" );
2564
2565 memset( &sbi3, 0xcc, sizeof(sbi3) );
2566 status = pNtWow64GetNativeSystemInformation( SystemEmulationBasicInformation, &sbi3, sizeof(sbi3), &len );
2567 ok( status == STATUS_SUCCESS, "failed %lx\n", status );
2568 ok( len == sizeof(sbi3), "wrong length %ld\n", len );
2569 ok( !memcmp( &sbi, &sbi3, offsetof(SYSTEM_BASIC_INFORMATION,NumberOfProcessors)+1 ),
2570 "info is different\n" );
2571
2572 for (i = 0; i < 256; i++)
2573 {
2574 NTSTATUS expect = pNtQuerySystemInformation( i, NULL, 0, &len );
2575 status = pNtWow64GetNativeSystemInformation( i, NULL, 0, &len );
2576 switch (i)
2577 {
2580 broken(status == STATUS_NOT_IMPLEMENTED) /* vista */, "%lu: %lx / %lx\n", i, status, expect );
2581 break;
2586 ok( status == expect, "%lu: %lx / %lx\n", i, status, expect );
2587 break;
2588 default:
2589 if (is_wow64) /* only a few info classes are supported on Wow64 */
2591 broken(status == STATUS_NOT_IMPLEMENTED), /* vista */
2592 "%lu: %lx\n", i, status );
2593 else
2594 ok( status == expect, "%lu: %lx / %lx\n", i, status, expect );
2595 break;
2596 }
2597 }
2598 }
2599 else win_skip( "NtWow64GetNativeSystemInformation not supported\n" );
2600
2601 if (pNtWow64IsProcessorFeaturePresent)
2602 {
2603 ULONG i;
2604
2605 for (i = 0; i < 64; i++)
2606 ok( pNtWow64IsProcessorFeaturePresent( i ) == IsProcessorFeaturePresent( i ),
2607 "mismatch %lu wow64 returned %lx\n", i, pNtWow64IsProcessorFeaturePresent( i ));
2608
2610 {
2612
2613 ok( user_shared_data->ProcessorFeatures[PF_ARM_V8_INSTRUCTIONS_AVAILABLE], "no ARM_V8\n" );
2614 ok( user_shared_data->ProcessorFeatures[PF_MMX_INSTRUCTIONS_AVAILABLE], "no MMX\n" );
2615 ok( !pNtWow64IsProcessorFeaturePresent( PF_ARM_V8_INSTRUCTIONS_AVAILABLE ), "ARM_V8 present\n" );
2616 ok( pNtWow64IsProcessorFeaturePresent( PF_MMX_INSTRUCTIONS_AVAILABLE ), "MMX not present\n" );
2617 }
2618 }
2619 else win_skip( "NtWow64IsProcessorFeaturePresent not supported\n" );
2620
2621 if (pNtWow64QueryInformationProcess64)
2622 {
2625 ULONG expected_peb;
2626 ULONG class;
2627
2628 for (class = 0; class <= MaxProcessInfoClass; class++)
2629 {
2630 winetest_push_context( "Process information class %lu", class );
2631
2632 switch (class)
2633 {
2636 ok( !status, "NtQueryInformationProcess returned 0x%08lx\n", status );
2637
2638 status = pNtWow64QueryInformationProcess64( GetCurrentProcess(), ProcessBasicInformation, &pbi64, sizeof(pbi64), NULL );
2639 ok( !status, "NtWow64QueryInformationProcess64 returned 0x%08lx\n", status );
2640
2641 expected_peb = (ULONG)pbi32.PebBaseAddress;
2642 if (is_wow64) expected_peb -= 0x1000;
2643
2644 ok( pbi64.ExitStatus == pbi32.ExitStatus,
2645 "expected %lu got %lu\n", pbi32.ExitStatus, pbi64.ExitStatus );
2646 ok( pbi64.PebBaseAddress == expected_peb ||
2647 /* The 64-bit PEB is usually, but not always, 4096 bytes below the 32-bit PEB */
2648 broken( is_wow64 && llabs( (INT64)pbi64.PebBaseAddress - (INT64)expected_peb ) < 0x10000 ),
2649 "expected 0x%lx got 0x%I64x\n", expected_peb, pbi64.PebBaseAddress );
2650 ok( pbi64.AffinityMask == pbi32.AffinityMask,
2651 "expected 0x%Ix got 0x%I64x\n", pbi32.AffinityMask, pbi64.AffinityMask );
2652 ok( pbi64.UniqueProcessId == pbi32.UniqueProcessId,
2653 "expected %Ix got %I64x\n", pbi32.UniqueProcessId, pbi64.UniqueProcessId );
2655 "expected %Ix got %I64x\n", pbi32.UniqueProcessId, pbi64.UniqueProcessId );
2656 break;
2657 default:
2658 status = pNtWow64QueryInformationProcess64( GetCurrentProcess(), class, NULL, 0, NULL );
2659 ok( status == STATUS_NOT_IMPLEMENTED, "NtWow64QueryInformationProcess64 returned 0x%08lx\n", status );
2660 }
2661
2663 }
2664 }
2665 else win_skip( "NtWow64QueryInformationProcess64 not supported\n" );
2666
2667 NtClose( process );
2668}
COMPILER_DEPENDENT_INT64 INT64
Definition: actypes.h:132
#define broken(x)
Definition: atltest.h:178
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
BOOL WINAPI IsProcessorFeaturePresent(IN DWORD ProcessorFeature)
Definition: sysinfo.c:169
static const struct _KUSER_SHARED_DATA * user_shared_data
Definition: sync.c:43
_ACRTIMP __int64 __cdecl llabs(__int64)
@ SystemBasicInformation
Definition: ntddk_ex.h:11
#define STATUS_ACCESS_VIOLATION
#define debugstr_a
Definition: kernel32.h:31
if(dx< 0)
Definition: linetemp.h:194
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl void winetest_pop_context(void)
void __cdecl void __cdecl void __cdecl void __cdecl void __cdecl winetest_push_context(const char *fmt,...) __WINE_PRINTF_ATTR(1
Definition: test.h:537
static SYSTEM_BASIC_INFORMATION sbi
Definition: virtual.c:53
@ SystemEmulationBasicInformation
Definition: extypes.h:279
@ SystemEmulationProcessorInformation
Definition: extypes.h:280
@ SystemNativeBasicInformation
Definition: extypes.h:336
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
#define STATUS_INVALID_PARAMETER_3
Definition: ntstatus.h:571
#define STATUS_PARTIAL_COPY
Definition: ntstatus.h:273
const WCHAR * str
ULONG_PTR InheritedFromUniqueProcessId
Definition: pstypes.h:362
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
@ MaxProcessInfoClass
Definition: winternl.h:1994
#define PF_MMX_INSTRUCTIONS_AVAILABLE
Definition: ketypes.h:179
#define PF_ARM_V8_INSTRUCTIONS_AVAILABLE
Definition: ketypes.h:205

Referenced by START_TEST().

◆ test_peb_teb()

static void test_peb_teb ( void  )
static

Definition at line 910 of file wow64.c.

911{
915 STARTUPINFOA si = {0};
917 void *redir;
918 SIZE_T res;
919 BOOL ret;
920 TEB teb;
921 PEB peb;
922 TEB32 teb32;
923 PEB32 peb32;
926 ULONG_PTR peb_ptr;
927 ULONG buffer[16];
928 WOW64INFO *wow64info = (WOW64INFO *)buffer;
930
932
933 if (CreateProcessA( "C:\\windows\\syswow64\\msinfo32.exe", NULL, NULL, NULL,
935 {
936 memset( &info, 0xcc, sizeof(info) );
938 ok( !status, "ThreadBasicInformation failed %lx\n", status );
939 if (!ReadProcessMemory( pi.hProcess, info.TebBaseAddress, &teb, sizeof(teb), &res )) res = 0;
940 ok( res == sizeof(teb), "wrong len %Ix\n", res );
941 ok( teb.Tib.Self == info.TebBaseAddress, "wrong teb %p / %p\n", teb.Tib.Self, info.TebBaseAddress );
942 if (is_wow64)
943 {
944 ok( !!teb.GdiBatchCount, "GdiBatchCount not set\n" );
945 ok( (char *)info.TebBaseAddress + teb.WowTebOffset == ULongToPtr(teb.GdiBatchCount) ||
946 broken(!NtCurrentTeb()->WowTebOffset), /* pre-win10 */
947 "wrong teb offset %ld\n", teb.WowTebOffset );
948 }
949 else
950 {
951 ok( !teb.GdiBatchCount, "GdiBatchCount set\n" );
952 ok( teb.WowTebOffset == 0x2000 ||
953 broken( !teb.WowTebOffset || teb.WowTebOffset == 1 ), /* pre-win10 */
954 "wrong teb offset %ld\n", teb.WowTebOffset );
955 ok( (char *)teb.Tib.ExceptionList == (char *)info.TebBaseAddress + 0x2000,
956 "wrong Tib.ExceptionList %p / %p\n",
957 (char *)teb.Tib.ExceptionList, (char *)info.TebBaseAddress + 0x2000 );
958 if (!ReadProcessMemory( pi.hProcess, teb.Tib.ExceptionList, &teb32, sizeof(teb32), &res )) res = 0;
959 ok( res == sizeof(teb32), "wrong len %Ix\n", res );
960 ok( (char *)ULongToPtr(teb32.Peb) == (char *)teb.Peb + 0x1000 ||
961 broken( ULongToPtr(teb32.Peb) != teb.Peb ), /* vista */
962 "wrong peb %p / %p\n", ULongToPtr(teb32.Peb), teb.Peb );
963 }
964
966 &proc_info, sizeof(proc_info), NULL );
967 ok( !status, "ProcessBasicInformation failed %lx\n", status );
968 ok( proc_info.PebBaseAddress == teb.Peb, "wrong peb %p / %p\n", proc_info.PebBaseAddress, teb.Peb );
969
971 &peb_ptr, sizeof(peb_ptr), NULL );
972 ok( !status, "ProcessWow64Information failed %lx\n", status );
973 ok( (void *)peb_ptr == (is_wow64 ? teb.Peb : ULongToPtr(teb32.Peb)),
974 "wrong peb %p\n", (void *)peb_ptr );
975
976 if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0;
977 ok( res == sizeof(peb), "wrong len %Ix\n", res );
978 ok( !peb.BeingDebugged, "BeingDebugged is %u\n", peb.BeingDebugged );
979 if (!is_wow64)
980 {
981 if (!ReadProcessMemory( pi.hProcess, ULongToPtr(teb32.Peb), &peb32, sizeof(peb32), &res )) res = 0;
982 ok( res == sizeof(peb32), "wrong len %Ix\n", res );
983 ok( !peb32.BeingDebugged, "BeingDebugged is %u\n", peb32.BeingDebugged );
984 }
985
986 if (!ReadProcessMemory( pi.hProcess, peb.ProcessParameters, &params, sizeof(params), &res )) res = 0;
987 ok( res == sizeof(params), "wrong len %Ix\n", res );
988#define CHECK_STR(name) \
989 ok( (char *)params.name.Buffer >= (char *)peb.ProcessParameters && \
990 (char *)params.name.Buffer < (char *)peb.ProcessParameters + params.Size, \
991 "wrong " #name " ptr %p / %p-%p\n", params.name.Buffer, peb.ProcessParameters, \
992 (char *)peb.ProcessParameters + params.Size )
993 CHECK_STR( ImagePathName );
994 CHECK_STR( CommandLine );
995 CHECK_STR( WindowTitle );
997 CHECK_STR( ShellInfo );
998#undef CHECK_STR
999 if (!is_wow64)
1000 {
1002 "wrong ptr32 %p / %p\n", ULongToPtr(peb32.ProcessParameters), peb.ProcessParameters );
1003 if (!ReadProcessMemory( pi.hProcess, ULongToPtr(peb32.ProcessParameters), &params32, sizeof(params32), &res )) res = 0;
1004 ok( res == sizeof(params32), "wrong len %Ix\n", res );
1005#define CHECK_STR(name) \
1006 ok( ULongToPtr(params32.name.Buffer) >= ULongToPtr(peb32.ProcessParameters) && \
1007 ULongToPtr(params32.name.Buffer) < ULongToPtr(peb32.ProcessParameters + params32.Size), \
1008 "wrong " #name " ptr %lx / %lx-%lx\n", params32.name.Buffer, peb32.ProcessParameters, \
1009 peb32.ProcessParameters + params.Size ); \
1010 ok( params32.name.Length == params.name.Length, "wrong " #name "len %u / %u\n", \
1011 params32.name.Length, params.name.Length )
1012 CHECK_STR( ImagePathName );
1013 CHECK_STR( CommandLine );
1014 CHECK_STR( WindowTitle );
1015 CHECK_STR( Desktop );
1016 CHECK_STR( ShellInfo );
1017#undef CHECK_STR
1018 ok( params32.EnvironmentSize == params.EnvironmentSize, "wrong size %lu / %Iu\n",
1019 params32.EnvironmentSize, params.EnvironmentSize );
1020 }
1021
1023 WaitForInputIdle( pi.hProcess, 1000 );
1024
1025 if (pRtlWow64GetSharedInfoProcess) test_wow64_shared_info( pi.hProcess );
1026 else win_skip( "RtlWow64GetSharedInfoProcess not supported\n" );
1027
1029 ok( ret, "debugging failed\n" );
1030 if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0;
1031 ok( res == sizeof(peb), "wrong len %Ix\n", res );
1032 ok( peb.BeingDebugged == !!ret, "BeingDebugged is %u\n", peb.BeingDebugged );
1033 if (!is_wow64)
1034 {
1035 if (!ReadProcessMemory( pi.hProcess, ULongToPtr(teb32.Peb), &peb32, sizeof(peb32), &res )) res = 0;
1036 ok( res == sizeof(peb32), "wrong len %Ix\n", res );
1037 ok( peb32.BeingDebugged == !!ret, "BeingDebugged is %u\n", peb32.BeingDebugged );
1038 }
1039
1043 }
1044
1045#if !defined (__REACTOS__) || (DLL_EXPORT_VERSION >= 0x600)
1047 create_process_machine( (char *)"C:\\windows\\system32\\regsvr32.exe /?", CREATE_SUSPENDED,
1049 {
1050 memset( &info, 0xcc, sizeof(info) );
1052 ok( !status, "ThreadBasicInformation failed %lx\n", status );
1053 if (!ReadProcessMemory( pi.hProcess, info.TebBaseAddress, &teb, sizeof(teb), &res )) res = 0;
1054 ok( res == sizeof(teb), "wrong len %Ix\n", res );
1055 ok( teb.Tib.Self == info.TebBaseAddress, "wrong teb %p / %p\n", teb.Tib.Self, info.TebBaseAddress );
1056 ok( !teb.GdiBatchCount, "GdiBatchCount set\n" );
1057 ok( !teb.WowTebOffset, "wrong teb offset %ld\n", teb.WowTebOffset );
1058 ok( !teb.Tib.ExceptionList, "wrong Tib.ExceptionList %p\n", (char *)teb.Tib.ExceptionList );
1059
1061 &proc_info, sizeof(proc_info), NULL );
1062 ok( !status, "ProcessBasicInformation failed %lx\n", status );
1063 ok( proc_info.PebBaseAddress == teb.Peb, "wrong peb %p / %p\n", proc_info.PebBaseAddress, teb.Peb );
1064
1066 &peb_ptr, sizeof(peb_ptr), NULL );
1067 ok( !status, "ProcessWow64Information failed %lx\n", status );
1068 ok( !peb_ptr, "wrong peb %p\n", (void *)peb_ptr );
1069
1070 if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0;
1071 ok( res == sizeof(peb), "wrong len %Ix\n", res );
1072 ok( !peb.BeingDebugged, "BeingDebugged is %u\n", peb.BeingDebugged );
1073
1075 WaitForInputIdle( pi.hProcess, 1000 );
1076
1078
1082 }
1083#endif
1084
1085 if (CreateProcessA( "C:\\windows\\system32\\msinfo32.exe", NULL, NULL, NULL,
1087 {
1088 memset( &info, 0xcc, sizeof(info) );
1090 ok( !status, "ThreadBasicInformation failed %lx\n", status );
1091 if (!is_wow64)
1092 {
1093 if (!ReadProcessMemory( pi.hProcess, info.TebBaseAddress, &teb, sizeof(teb), &res )) res = 0;
1094 ok( res == sizeof(teb), "wrong len %Ix\n", res );
1095 ok( teb.Tib.Self == info.TebBaseAddress, "wrong teb %p / %p\n",
1096 teb.Tib.Self, info.TebBaseAddress );
1097 ok( !teb.GdiBatchCount, "GdiBatchCount set\n" );
1098 ok( !teb.WowTebOffset || broken( teb.WowTebOffset == 1 ), /* vista */
1099 "wrong teb offset %ld\n", teb.WowTebOffset );
1100 }
1101 else ok( !info.TebBaseAddress, "got teb %p\n", info.TebBaseAddress );
1102
1104 &proc_info, sizeof(proc_info), NULL );
1105 ok( !status, "ProcessBasicInformation failed %lx\n", status );
1106 if (is_wow64)
1107 ok( !proc_info.PebBaseAddress ||
1108 broken( (char *)proc_info.PebBaseAddress >= (char *)0x7f000000 ), /* vista */
1109 "wrong peb %p\n", proc_info.PebBaseAddress );
1110 else
1111 ok( proc_info.PebBaseAddress == teb.Peb, "wrong peb %p / %p\n",
1112 proc_info.PebBaseAddress, teb.Peb );
1113
1115 WaitForInputIdle( pi.hProcess, 1000 );
1116
1117 if (pRtlWow64GetSharedInfoProcess)
1118 {
1119 wow64 = 0xcc;
1120 memset( buffer, 0xcc, sizeof(buffer) );
1121 status = pRtlWow64GetSharedInfoProcess( pi.hProcess, &wow64, wow64info );
1122 ok( !status, "RtlWow64GetSharedInfoProcess failed %lx\n", status );
1123 ok( !wow64, "wrong wow64 %u\n", wow64 );
1124 ok( buffer[0] == 0xcccccccc, "buffer set %lx\n", buffer[0] );
1125 }
1126
1130 }
1131
1133
1134#ifndef _WIN64
1135 if (is_wow64)
1136 {
1137 PEB64 *peb64;
1138 TEB64 *teb64 = (TEB64 *)NtCurrentTeb()->GdiBatchCount;
1139
1140 ok( !!teb64, "GdiBatchCount not set\n" );
1141 ok( (char *)NtCurrentTeb() + NtCurrentTeb()->WowTebOffset == (char *)teb64 ||
1142 broken(!NtCurrentTeb()->WowTebOffset), /* pre-win10 */
1143 "wrong WowTebOffset %lx (%p/%p)\n", NtCurrentTeb()->WowTebOffset, teb64, NtCurrentTeb() );
1144 ok( (char *)teb64 + 0x2000 == (char *)NtCurrentTeb(), "unexpected diff %p / %p\n",
1145 teb64, NtCurrentTeb() );
1146 ok( (char *)teb64 + teb64->WowTebOffset == (char *)NtCurrentTeb() ||
1147 broken( !teb64->WowTebOffset || teb64->WowTebOffset == 1 ), /* pre-win10 */
1148 "wrong WowTebOffset %lx (%p/%p)\n", teb64->WowTebOffset, teb64, NtCurrentTeb() );
1149 ok( !teb64->GdiBatchCount, "GdiBatchCount set %lx\n", teb64->GdiBatchCount );
1150 ok( teb64->Tib.ExceptionList == PtrToUlong( NtCurrentTeb() ), "wrong Tib.ExceptionList %s / %p\n",
1152 ok( teb64->Tib.Self == PtrToUlong( teb64 ), "wrong Tib.Self %s / %p\n",
1153 wine_dbgstr_longlong(teb64->Tib.Self), teb64 );
1155 "wrong StaticUnicodeString %s / %p\n",
1157 ok( teb64->ClientId.UniqueProcess == GetCurrentProcessId(), "wrong pid %s / %lx\n",
1159 ok( teb64->ClientId.UniqueThread == GetCurrentThreadId(), "wrong tid %s / %lx\n",
1161 peb64 = ULongToPtr( teb64->Peb );
1163 "wrong ImageBaseAddress %s / %p\n",
1165 ok( peb64->OSBuildNumber == NtCurrentTeb()->Peb->OSBuildNumber, "wrong OSBuildNumber %lx / %lx\n",
1167 ok( peb64->OSPlatformId == NtCurrentTeb()->Peb->OSPlatformId, "wrong OSPlatformId %lx / %lx\n",
1170 "wrong AnsiCodePageData %I64x / %p\n",
1173 "wrong OemCodePageData %I64x / %p\n",
1176 "wrong UnicodeCaseTableData %I64x / %p\n",
1178 return;
1179 }
1180#endif
1181 ok( !NtCurrentTeb()->GdiBatchCount, "GdiBatchCount set to %lx\n", NtCurrentTeb()->GdiBatchCount );
1182 ok( !NtCurrentTeb()->WowTebOffset || broken( NtCurrentTeb()->WowTebOffset == 1 ), /* vista */
1183 "WowTebOffset set to %lx\n", NtCurrentTeb()->WowTebOffset );
1184}
@ ProcessWow64Information
Definition: cicbase.cpp:65
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
@ ThreadBasicInformation
Definition: compat.h:935
BOOL WINAPI DebugActiveProcess(IN DWORD dwProcessId)
Definition: debugger.c:445
PPEB Peb
Definition: dllmain.c:27
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1376
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:567
BOOL WINAPI Wow64RevertWow64FsRedirection(IN PVOID OldValue)
Definition: utils.c:809
BOOL WINAPI Wow64DisableWow64FsRedirection(IN PVOID *OldValue)
Definition: utils.c:786
NTSTATUS NTAPI NtQueryInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _Out_writes_bytes_to_opt_(ThreadInformationLength, *ReturnLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:2985
ULONG64 UniqueThread
Definition: pstypes.h:774
ULONG64 UniqueProcess
Definition: pstypes.h:773
ULONG64 ExceptionList
Definition: winternl.h:726
ULONG64 Self
Definition: winternl.h:732
struct _NT_TIB * Self
Definition: compat.h:720
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
ULONG ProcessParameters
Definition: winternl.h:938
BOOLEAN BeingDebugged
Definition: winternl.h:926
ULONG OSPlatformId
Definition: winternl.h:1093
ULONG64 OemCodePageData
Definition: winternl.h:1074
ULONG64 AnsiCodePageData
Definition: winternl.h:1073
ULONG OSBuildNumber
Definition: winternl.h:1092
ULONG64 UnicodeCaseTableData
Definition: winternl.h:1075
ULONG64 ImageBaseAddress
Definition: winternl.h:1046
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
ULONG OSBuildNumber
Definition: ntddk_ex.h:302
PVOID OemCodePageData
Definition: ntddk_ex.h:265
ULONG OSPlatformId
Definition: ntddk_ex.h:303
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
ULONG Peb
Definition: winternl.h:1153
LONG WowTebOffset
Definition: winternl.h:1344
UNICODE_STRING64 StaticUnicodeString
Definition: winternl.h:1296
WCHAR StaticUnicodeBuffer[261]
Definition: winternl.h:1297
ULONG GdiBatchCount
Definition: winternl.h:1311
NT_TIB64 Tib
Definition: winternl.h:1249
CLIENT_ID64 ClientId
Definition: winternl.h:1251
Definition: compat.h:836
LONG WowTebOffset
Definition: winternl.h:701
PVOID Peb
Definition: compat.h:842
ULONG GdiBatchCount
Definition: compat.h:887
NT_TIB Tib
Definition: compat.h:837
ULONG64 Buffer
Definition: winternl.h:773
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
#define CREATE_SUSPENDED
Definition: winbase.h:182
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)
#define CHECK_STR(name)
static void test_wow64_shared_info(HANDLE process)
Definition: wow64.c:824
static void test_amd64_shared_info(HANDLE process)
Definition: wow64.c:871
static void ULONG *static void ULONG64 *static const void ULONG64 *static BOOL is_win64
Definition: wow64.c:73

Referenced by START_TEST().

◆ test_process_architecture()

static void test_process_architecture ( HANDLE  process,
USHORT  expect_machine,
USHORT  expect_native 
)
static

Definition at line 216 of file wow64.c.

217{
220 ULONG i, len;
221
222 len = 0xdead;
223 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
224 machines, sizeof(machines), &len );
225 ok( !status, "failed %lx\n", status );
226 ok( !(len & 3), "wrong len %lx\n", len );
227 len /= sizeof(machines[0]);
228 for (i = 0; i < len - 1; i++)
229 {
230 if (machines[i].Process)
231 ok( machines[i].Machine == expect_machine, "wrong process machine %x\n", machines[i].Machine);
232 else
233 ok( machines[i].Machine != expect_machine, "wrong machine %x\n", machines[i].Machine);
234
235 if (machines[i].Native)
236 ok( machines[i].Machine == expect_native, "wrong native machine %x\n", machines[i].Machine);
237 else
238 ok( machines[i].Machine != expect_native, "wrong machine %x\n", machines[i].Machine);
239
240 if (machines[i].WoW64Container)
241 ok( is_machine_32bit( machines[i].Machine ) && !is_machine_32bit( native_machine ),
242 "wrong wow64 %x\n", machines[i].Machine);
243 }
244 ok( !*(DWORD *)&machines[i], "missing terminating null\n" );
245
246 len = i * sizeof(machines[0]);
247 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
248 machines, len, &len );
249 ok( status == STATUS_BUFFER_TOO_SMALL, "failed %lx\n", status );
250 ok( len == (i + 1) * sizeof(machines[0]), "wrong len %lu\n", len );
251
252 if (pRtlWow64GetProcessMachines)
253 {
254 USHORT current = 0xdead, native = 0xbeef;
255 status = pRtlWow64GetProcessMachines( process, &current, &native );
256 ok( !status, "failed %lx\n", status );
257 if (expect_machine == expect_native)
258 ok( current == 0, "wrong current machine %x / %x\n", current, expect_machine );
259 else
260 ok( current == expect_machine, "wrong current machine %x / %x\n", current, expect_machine );
261 ok( native == expect_native, "wrong native machine %x / %x\n", native, expect_native );
262 }
263}
struct task_struct * current
Definition: linux.c:32
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
static BOOL is_machine_32bit(USHORT machine)
Definition: wow64.c:106

Referenced by test_query_architectures().

◆ test_process_machine()

static void test_process_machine ( HANDLE  process,
HANDLE  thread,
USHORT  expect_machine,
USHORT  expect_image 
)
static

Definition at line 265 of file wow64.c.

267{
272 PEB peb;
273 ULONG len;
274 SIZE_T size;
276 void *entry_point = NULL;
277 void *win32_entry = NULL;
278
280 ok( !status, "ProcessBasicInformation failed %lx\n", status );
281 if (ReadProcessMemory( process, basic.PebBaseAddress, &peb, sizeof(peb), &size ) &&
282 ReadProcessMemory( process, peb.ImageBaseAddress, &dos, sizeof(dos), &size ) &&
283 ReadProcessMemory( process, (char *)peb.ImageBaseAddress + dos.e_lfanew, &nt, sizeof(nt), &size ))
284 {
285 ok( nt.FileHeader.Machine == expect_machine, "wrong nt machine %x / %x\n",
286 nt.FileHeader.Machine, expect_machine );
287 entry_point = (char *)peb.ImageBaseAddress + nt.OptionalHeader.AddressOfEntryPoint;
288 }
289
291 ok( !status, "ProcessImageInformation failed %lx\n", status );
292 ok( image.Machine == expect_image, "wrong image info %x / %x\n", image.Machine, expect_image );
293
295 &win32_entry, sizeof(win32_entry), &len );
296 ok( !status, "ThreadQuerySetWin32StartAddress failed %lx\n", status );
297
298 if (!entry_point) return;
299
300 if (image.Machine == expect_machine)
301 {
302 ok( image.TransferAddress == entry_point, "wrong entry %p / %p\n",
303 image.TransferAddress, entry_point );
304 ok( win32_entry == entry_point, "wrong win32 entry %p / %p\n",
305 win32_entry, entry_point );
306 }
307 else
308 {
309 /* image.TransferAddress is the ARM64 entry, entry_point is the x86-64 one,
310 win32_entry is the redirected x86-64 -> ARM64EC one */
311 ok( image.TransferAddress != entry_point, "wrong entry %p\n", image.TransferAddress );
312 ok( image.TransferAddress != win32_entry, "wrong entry %p\n", image.TransferAddress );
313 ok( win32_entry != entry_point, "wrong win32 entry %p\n", win32_entry );
314 }
315}
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
GLeglImageOES image
Definition: gl.h:2204
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
@ ProcessImageInformation
Definition: winternl.h:1919

Referenced by test_query_architectures().

◆ test_query_architectures()

static void test_query_architectures ( void  )
static

Definition at line 317 of file wow64.c.

318{
319 static char cmd_sysnative[] = "C:\\windows\\sysnative\\cmd.exe /c exit";
320 static char cmd_system32[] = "C:\\windows\\system32\\cmd.exe /c exit";
321 static char cmd_syswow64[] = "C:\\windows\\syswow64\\cmd.exe /c exit";
324 STARTUPINFOA si = { sizeof(si) };
327 ULONG i, len;
328#ifdef __arm64ec__
330#else
332#endif
333
334 if (!pNtQuerySystemInformationEx) return;
335
337 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
338 machines, sizeof(machines), &len );
340 {
341 win_skip( "SystemSupportedProcessorArchitectures not supported\n" );
342 return;
343 }
344 ok( !status, "failed %lx\n", status );
345
346 process = (HANDLE)0xdeadbeef;
347 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, sizeof(process),
348 machines, sizeof(machines), &len );
349 ok( status == STATUS_INVALID_HANDLE, "failed %lx\n", status );
350 process = (HANDLE)0xdeadbeef;
351 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, 3,
352 machines, sizeof(machines), &len );
354 "failed %lx\n", status );
356 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, &process, 3,
357 machines, sizeof(machines), &len );
359 "failed %lx\n", status );
360 status = pNtQuerySystemInformationEx( SystemSupportedProcessorArchitectures, NULL, 0,
361 machines, sizeof(machines), &len );
362 ok( status == STATUS_INVALID_PARAMETER, "failed %lx\n", status );
363
364 winetest_push_context( "current" );
370
371 winetest_push_context( "zero" );
374
375 if (CreateProcessA( NULL, is_win64 ? cmd_system32 : cmd_sysnative, NULL, NULL,
377 {
378 winetest_push_context( "system32" );
386 }
387 if (CreateProcessA( NULL, is_win64 ? cmd_syswow64 : cmd_system32, NULL, NULL,
389 {
390 winetest_push_context( "syswow64" );
397 }
399 {
401
402 if (create_process_machine( cmd_system32, CREATE_SUSPENDED, machine, &pi ))
403 {
411 }
412 }
413
414 if (pRtlWow64GetCurrentMachine)
415 {
416 USHORT machine = pRtlWow64GetCurrentMachine();
417 ok( machine == current_machine, "wrong machine %x / %x\n", machine, current_machine );
418 }
419 if (pRtlWow64IsWowGuestMachineSupported)
420 {
421 static const WORD machines[] = { IMAGE_FILE_MACHINE_I386, IMAGE_FILE_MACHINE_ARMNT,
423
424 for (i = 0; i < ARRAY_SIZE(machines); i++)
425 {
426 BOOLEAN ret = 0xcc;
427 status = pRtlWow64IsWowGuestMachineSupported( machines[i], &ret );
428 ok( !status, "failed %lx\n", status );
429 if (is_machine_32bit( machines[i] ) && !is_machine_32bit( native_machine ))
430 ok( ret || machines[i] == IMAGE_FILE_MACHINE_ARMNT ||
431 broken(current_machine == IMAGE_FILE_MACHINE_I386), /* win10-1607 wow64 */
432 "%04x: got %u\n", machines[i], ret );
433 else
434 ok( !ret, "%04x: got %u\n", machines[i], ret );
435 }
436 }
437}
unsigned short WORD
Definition: ntddk_ex.h:93
static BOOL is_arm64ec
Definition: exception.c:53
static void test_process_architecture(HANDLE process, USHORT expect_machine, USHORT expect_native)
Definition: wow64.c:216
static void test_process_machine(HANDLE process, HANDLE thread, USHORT expect_machine, USHORT expect_image)
Definition: wow64.c:265

Referenced by START_TEST().

◆ test_selectors()

static void test_selectors ( void  )
static

Definition at line 1186 of file wow64.c.

1187{
1188#ifndef __arm__
1191 ULONG base, limit, sel, retlen;
1193
1194#ifdef _WIN64
1195 if (!pRtlWow64GetThreadSelectorEntry)
1196 {
1197 win_skip( "RtlWow64GetThreadSelectorEntry not supported\n" );
1198 return;
1199 }
1200 if (!pRtlWow64GetThreadContext || pRtlWow64GetThreadContext( GetCurrentThread(), &context ))
1201 {
1202 /* hardcoded values */
1203#ifdef __arm64ec__
1204 context.SegCs = 0x23;
1205 context.SegSs = 0x2b;
1206 context.SegFs = 0x53;
1207#elif defined __x86_64__
1208#ifdef _MSC_VER
1209 context.SegFs = __readsegfs();
1210 context.SegSs = __readsegss();
1211#else
1212 __asm__( "movw %%fs,%0" : "=m" (context.SegFs) );
1213 __asm__( "movw %%ss,%0" : "=m" (context.SegSs) );
1214#endif
1215#else
1216 context.SegCs = 0x1b;
1217 context.SegSs = 0x23;
1218 context.SegFs = 0x3b;
1219#endif
1220 }
1221#define GET_ENTRY(info,size,ret) \
1222 pRtlWow64GetThreadSelectorEntry( GetCurrentThread(), info, size, ret )
1223
1224#else
1226#define GET_ENTRY(info,size,ret) \
1227 NtQueryInformationThread( GetCurrentThread(), ThreadDescriptorTableEntry, info, size, ret )
1228#endif
1229
1230 trace( "cs %04lx ss %04lx fs %04lx\n", context.SegCs, context.SegSs, context.SegFs );
1231 retlen = 0xdeadbeef;
1232 info.Selector = 0;
1233 status = GET_ENTRY( &info, sizeof(info) - 1, &retlen );
1234 ok( status == STATUS_INFO_LENGTH_MISMATCH, "wrong status %lx\n", status );
1235 ok( retlen == 0xdeadbeef, "len set %lu\n", retlen );
1236
1237 retlen = 0xdeadbeef;
1238 status = GET_ENTRY( &info, sizeof(info) + 1, &retlen );
1239 ok( status == STATUS_INFO_LENGTH_MISMATCH, "wrong status %lx\n", status );
1240 ok( retlen == 0xdeadbeef, "len set %lu\n", retlen );
1241
1242 retlen = 0xdeadbeef;
1243 status = GET_ENTRY( NULL, 0, &retlen );
1244 ok( status == STATUS_INFO_LENGTH_MISMATCH, "wrong status %lx\n", status );
1245 ok( retlen == 0xdeadbeef, "len set %lu\n", retlen );
1246
1247 status = GET_ENTRY( &info, sizeof(info), NULL );
1248 ok( !status, "wrong status %lx\n", status );
1249
1250 for (info.Selector = 0; info.Selector < 0x100; info.Selector++)
1251 {
1252 retlen = 0xdeadbeef;
1253 status = GET_ENTRY( &info, sizeof(info), &retlen );
1254 base = (info.Entry.BaseLow |
1255 (info.Entry.HighWord.Bytes.BaseMid << 16) |
1256 (info.Entry.HighWord.Bytes.BaseHi << 24));
1257 limit = (info.Entry.LimitLow | info.Entry.HighWord.Bits.LimitHi << 16);
1258 sel = info.Selector | 3;
1259
1260 if (sel == 0x03) /* null selector */
1261 {
1262 ok( !status, "wrong status %lx\n", status );
1263 ok( retlen == sizeof(info.Entry), "len set %lu\n", retlen );
1264 ok( !base, "wrong base %lx\n", base );
1265 ok( !limit, "wrong limit %lx\n", limit );
1266 ok( !info.Entry.HighWord.Bytes.Flags1, "wrong flags1 %x\n", info.Entry.HighWord.Bytes.Flags1 );
1267 ok( !info.Entry.HighWord.Bytes.Flags2, "wrong flags2 %x\n", info.Entry.HighWord.Bytes.Flags2 );
1268 }
1269 else if (sel == context.SegCs) /* 32-bit code selector */
1270 {
1271 ok( !status, "wrong status %lx\n", status );
1272 ok( retlen == sizeof(info.Entry), "len set %lu\n", retlen );
1273 ok( !base, "wrong base %lx\n", base );
1274 ok( limit == 0xfffff, "wrong limit %lx\n", limit );
1275 ok( info.Entry.HighWord.Bits.Type == 0x1b, "wrong type %x\n", info.Entry.HighWord.Bits.Type );
1276 ok( info.Entry.HighWord.Bits.Dpl == 3, "wrong dpl %x\n", info.Entry.HighWord.Bits.Dpl );
1277 ok( info.Entry.HighWord.Bits.Pres, "wrong pres\n" );
1278 ok( !info.Entry.HighWord.Bits.Sys, "wrong sys\n" );
1279 ok( info.Entry.HighWord.Bits.Default_Big, "wrong big\n" );
1280 ok( info.Entry.HighWord.Bits.Granularity, "wrong granularity\n" );
1281 }
1282 else if (sel == context.SegSs) /* 32-bit data selector */
1283 {
1284 ok( !status, "wrong status %lx\n", status );
1285 ok( retlen == sizeof(info.Entry), "len set %lu\n", retlen );
1286 ok( !base, "wrong base %lx\n", base );
1287 ok( limit == 0xfffff, "wrong limit %lx\n", limit );
1288 ok( info.Entry.HighWord.Bits.Type == 0x13, "wrong type %x\n", info.Entry.HighWord.Bits.Type );
1289 ok( info.Entry.HighWord.Bits.Dpl == 3, "wrong dpl %x\n", info.Entry.HighWord.Bits.Dpl );
1290 ok( info.Entry.HighWord.Bits.Pres, "wrong pres\n" );
1291 ok( !info.Entry.HighWord.Bits.Sys, "wrong sys\n" );
1292 ok( info.Entry.HighWord.Bits.Default_Big, "wrong big\n" );
1293 ok( info.Entry.HighWord.Bits.Granularity, "wrong granularity\n" );
1294 }
1295 else if (sel == context.SegFs) /* TEB selector */
1296 {
1297 ok( !status, "wrong status %lx\n", status );
1298 ok( retlen == sizeof(info.Entry), "len set %lu\n", retlen );
1299#ifdef _WIN64
1300 if (NtCurrentTeb()->WowTebOffset == 0x2000)
1301 ok( base == (ULONG_PTR)NtCurrentTeb() + 0x2000, "wrong base %lx / %p\n",
1302 base, NtCurrentTeb() );
1303#else
1304 ok( base == (ULONG_PTR)NtCurrentTeb(), "wrong base %lx / %p\n", base, NtCurrentTeb() );
1305#endif
1306 ok( limit == 0xfff || broken(limit == 0x4000), /* <= win8 */
1307 "wrong limit %lx\n", limit );
1308 ok( info.Entry.HighWord.Bits.Type == 0x13, "wrong type %x\n", info.Entry.HighWord.Bits.Type );
1309 ok( info.Entry.HighWord.Bits.Dpl == 3, "wrong dpl %x\n", info.Entry.HighWord.Bits.Dpl );
1310 ok( info.Entry.HighWord.Bits.Pres, "wrong pres\n" );
1311 ok( !info.Entry.HighWord.Bits.Sys, "wrong sys\n" );
1312 ok( info.Entry.HighWord.Bits.Default_Big, "wrong big\n" );
1313 ok( !info.Entry.HighWord.Bits.Granularity, "wrong granularity\n" );
1314 }
1315 else if (!status)
1316 {
1317 ok( retlen == sizeof(info.Entry), "len set %lu\n", retlen );
1318 trace( "succeeded for %lx base %lx limit %lx type %x\n",
1319 sel, base, limit, info.Entry.HighWord.Bits.Type );
1320 }
1321 else
1322 {
1324 ((sel & 4) && (status == STATUS_NO_LDT)) ||
1325 broken( status == STATUS_ACCESS_VIOLATION), /* <= win8 */
1326 "%lx: wrong status %lx\n", info.Selector, status );
1327 ok( retlen == 0xdeadbeef, "len set %lu\n", retlen );
1328 }
1329 }
1330#undef GET_ENTRY
1331#endif /* __arm__ */
1332}
BOOL WINAPI GetThreadContext(IN HANDLE hThread, OUT LPCONTEXT lpContext)
Definition: thread.c:501
#define STATUS_NO_LDT
Definition: ntstatus.h:609
__asm__(".p2align 4, 0x90\n" ".seh_proc __seh2_global_filter_func\n" "__seh2_global_filter_func:\n" "\tsub %rbp, %rax\n" "\tpush %rbp\n" "\t.seh_pushreg %rbp\n" "\tpush %rbx\n" "\t.seh_pushreg %rbx\n" "\tpush %rdi\n" "\t.seh_pushreg %rdi\n" "\tpush %rsi\n" "\t.seh_pushreg %rsi\n" "\tpush %r12\n" "\t.seh_pushreg %r12\n" "\tpush %r13\n" "\t.seh_pushreg %r13\n" "\tpush %r14\n" "\t.seh_pushreg %r14\n" "\tpush %r15\n" "\t.seh_pushreg %r15\n" "\tsub $40, %rsp\n" "\t.seh_stackalloc 40\n" "\t.seh_endprologue\n" "\tsub %rax, %rdx\n" "\tmov %rdx, %rbp\n" "\tjmp *%r8\n" "__seh2_global_filter_func_exit:\n" "\t.p2align 4\n" "\tadd $40, %rsp\n" "\tpop %r15\n" "\tpop %r14\n" "\tpop %r13\n" "\tpop %r12\n" "\tpop %rsi\n" "\tpop %rdi\n" "\tpop %rbx\n" "\tpop %rbp\n" "\tret\n" "\t.seh_endproc")
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define CONTEXT_I386_SEGMENTS
Definition: winnt.h:11
#define CONTEXT_I386_CONTROL
Definition: winnt.h:9
#define GET_ENTRY(info, size, ret)

Referenced by START_TEST().

◆ test_syscalls()

static void test_syscalls ( void  )
static

Definition at line 3028 of file wow64.c.

3029{
3030 ULONG64 func;
3031 ULONG args32[8];
3032 HANDLE event, event2;
3036
3037 if (!is_wow64) return;
3038 if (!code_mem) return;
3039 if (!ntdll_module) return;
3040
3041 func = get_proc_address64( wow64_module, "Wow64SystemServiceEx" );
3042 ok( func, "Wow64SystemServiceEx not found\n" );
3043
3044 event = CreateEventA( NULL, FALSE, FALSE, NULL );
3045
3047 ok( !status, "NtSetEvent failed %lx\n", status );
3048 args32[0] = HandleToLong( event );
3049 status = invoke_syscall( "NtClose", args32 );
3050 ok( !status, "syscall failed %lx\n", status );
3052 ok( status == STATUS_INVALID_HANDLE, "NtSetEvent failed %lx\n", status );
3053 status = invoke_syscall( "NtClose", args32 );
3054 ok( status == STATUS_INVALID_HANDLE, "syscall failed %lx\n", status );
3055 args32[0] = 0xdeadbeef;
3056 status = invoke_syscall( "NtClose", args32 );
3057 ok( status == STATUS_INVALID_HANDLE, "syscall failed %lx\n", status );
3058
3059 RtlInitUnicodeString( &name, L"\\BaseNamedObjects\\wow64-test");
3061 event = (HANDLE)0xdeadbeef;
3062 args32[0] = PtrToUlong(&event );
3063 args32[1] = EVENT_ALL_ACCESS;
3064 args32[2] = PtrToUlong( &attr );
3065 args32[3] = NotificationEvent;
3066 args32[4] = 0;
3067 status = invoke_syscall( "NtCreateEvent", args32 );
3068 ok( !status, "syscall failed %lx\n", status );
3070 ok( !status, "NtSetEvent failed %lx\n", status );
3071
3072 event2 = (HANDLE)0xdeadbeef;
3073 args32[0] = PtrToUlong( &event2 );
3074 status = invoke_syscall( "NtOpenEvent", args32 );
3075 ok( !status, "syscall failed %lx\n", status );
3076 status = NtSetEvent( event2, NULL );
3077 ok( !status, "NtSetEvent failed %lx\n", status );
3078 args32[0] = HandleToLong( event2 );
3079 status = invoke_syscall( "NtClose", args32 );
3080 ok( !status, "syscall failed %lx\n", status );
3081
3082 event2 = (HANDLE)0xdeadbeef;
3083 args32[0] = PtrToUlong( &event2 );
3084 status = invoke_syscall( "NtCreateEvent", args32 );
3085 ok( status == STATUS_OBJECT_NAME_EXISTS, "syscall failed %lx\n", status );
3086 status = NtSetEvent( event2, NULL );
3087 ok( !status, "NtSetEvent failed %lx\n", status );
3088 args32[0] = HandleToLong( event2 );
3089 status = invoke_syscall( "NtClose", args32 );
3090 ok( !status, "syscall failed %lx\n", status );
3091
3092 status = NtClose( event );
3093 ok( !status, "NtClose failed %lx\n", status );
3094
3095 if (pNtWow64ReadVirtualMemory64)
3096 {
3097 TEB64 *teb64 = (TEB64 *)NtCurrentTeb()->GdiBatchCount;
3098 PEB64 peb64, peb64_2;
3099 ULONG64 res, res2;
3101 ULONG args32[] = { HandleToLong( process ), (ULONG)teb64->Peb, teb64->Peb >> 32,
3102 PtrToUlong(&peb64_2), sizeof(peb64_2), 0, PtrToUlong(&res2) };
3103
3104 ok( process != 0, "failed to open current process %lu\n", GetLastError() );
3105 status = pNtWow64ReadVirtualMemory64( process, teb64->Peb, &peb64, sizeof(peb64), &res );
3106 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
3107 status = invoke_syscall( "NtWow64ReadVirtualMemory64", args32 );
3108 ok( !status, "NtWow64ReadVirtualMemory64 failed %lx\n", status );
3109 ok( res2 == res, "wrong len %s / %s\n", wine_dbgstr_longlong(res), wine_dbgstr_longlong(res2) );
3110 ok( !memcmp( &peb64, &peb64_2, res ), "data is different\n" );
3111 NtClose( process );
3112 }
3113}
#define HandleToLong(h)
Definition: basetsd.h:74
struct _cl_event * event
Definition: glext.h:7739
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:115
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
@ NotificationEvent
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:463
#define STATUS_OBJECT_NAME_EXISTS
Definition: ntstatus.h:189
#define OBJ_OPENIF
Definition: winternl.h:229
Definition: cookie.c:202
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:573
static NTSTATUS invoke_syscall(const char *name, ULONG args32[])
Definition: wow64.c:3013

Referenced by START_TEST().

◆ test_wow64_shared_info()

static void test_wow64_shared_info ( HANDLE  process)
static

Definition at line 824 of file wow64.c.

825{
826 ULONG i, peb_data[0x200], buffer[16];
828 ULONG_PTR peb_ptr;
830 SIZE_T res;
831 BOOLEAN wow64 = 0xcc;
832
833 NtQueryInformationProcess( process, ProcessWow64Information, &peb_ptr, sizeof(peb_ptr), NULL );
834 memset( buffer, 0xcc, sizeof(buffer) );
835 status = pRtlWow64GetSharedInfoProcess( process, &wow64, info );
836 ok( !status, "RtlWow64GetSharedInfoProcess failed %lx\n", status );
837 ok( wow64 == TRUE, "wrong wow64 %u\n", wow64 );
838 todo_wine_if (!info->NativeSystemPageSize) /* not set in old wow64 */
839 {
840 ok( info->NativeSystemPageSize == 0x1000, "wrong page size %lx\n",
841 info->NativeSystemPageSize );
843 "wrong flags %lx\n", info->CpuFlags );
844 ok( info->NativeMachineType == native_machine, "wrong machine %x / %x\n",
845 info->NativeMachineType, native_machine );
846 ok( info->EmulatedMachineType == IMAGE_FILE_MACHINE_I386, "wrong machine %x\n",
847 info->EmulatedMachineType );
848 }
849 ok( buffer[sizeof(*info) / sizeof(ULONG)] == 0xcccccccc, "buffer set %lx\n",
850 buffer[sizeof(*info) / sizeof(ULONG)] );
851 if (ReadProcessMemory( process, (void *)peb_ptr, peb_data, sizeof(peb_data), &res ))
852 {
853 ULONG limit = (sizeof(peb_data) - sizeof(info)) / sizeof(ULONG);
854 for (i = 0; i < limit; i++)
855 {
856 if (!memcmp( peb_data + i, info, sizeof(*info) ))
857 {
858 trace( "wow64info found at %lx\n", i * 4 );
859 break;
860 }
861 }
862 ok( i < limit, "wow64info not found in PEB\n" );
863 }
864 if (info->SectionHandle && info->CrossProcessWorkList)
865 test_cross_process_notifications( process, info->SectionHandle, info->CrossProcessWorkList );
866 else
867 trace( "no WOW64INFO section handle\n" );
868}
#define WOW64_CPUFLAGS_SOFTWARE
Definition: winternl.h:4424
#define WOW64_CPUFLAGS_MSFT64
Definition: winternl.h:4423

Referenced by test_peb_teb().

◆ USHORT()

static USHORT ( WINAPI pRtlWow64GetCurrentMachine)
static

◆ void()

static void ULONG *static void void ULONG *static void ULONG *static void ( WINAPI pRtlOpenCrossProcessEmulatorWorkConnection)
static

Variable Documentation

◆ call_func64_code

const BYTE call_func64_code[]
static

Definition at line 2250 of file wow64.c.

Referenced by call_func64().

◆ code_mem

void* code_mem
static

◆ current_machine

◆ HANDLE

WORD WORD *static BOOLEAN WOW64INFO *static WOW64_CONTEXT *static BOOLEAN *static HANDLE

◆ hook_code

DWORD hook_code[]
static
Initial value:
=
{
0x58000048,
0xd61f0100,
0, 0
}

Definition at line 1481 of file wow64.c.

Referenced by hook_notification_function(), and test_notifications().

◆ is_win64

void ULONG *static void ULONG64 *static const void ULONG64* static BOOL is_win64 = sizeof(void *) > sizeof(int)
static

Definition at line 73 of file wow64.c.

Referenced by test_peb_teb(), and test_query_architectures().

◆ is_wow64

◆ log_params_code

const DWORD log_params_code[]
static
Initial value:
=
{
0x10008009,
0xf940012a,
0xa8810540,
0xa8810d42,
0xa8811544,
0xa8811d46,
0xf900012a,
0xf9400520,
0xd65f03c0,
}

Definition at line 1488 of file wow64.c.

Referenced by test_notifications().

◆ main_module

ULONG64 main_module
static

Definition at line 2296 of file wow64.c.

Referenced by check_module(), test_instances(), and test_modules().

◆ native_machine

◆ ntdll_module

ULONG64 ntdll_module
static

◆ old_code

BYTE old_code[sizeof(hook_code)]
static

Definition at line 1569 of file wow64.c.

Referenced by ft_lzwstate_io(), hook_notification_function(), and test_notifications().

◆ old_wow64

BOOL old_wow64
static

Definition at line 75 of file wow64.c.

Referenced by enum_modules64(), init(), test_init_block(), test_modules(), and test_nt_wow64().

◆ PROCESSINFOCLASS

Definition at line 68 of file wow64.c.

◆ ULONG

◆ ULONG64

void ULONG *static void ULONG64 *static const void ULONG64

Definition at line 65 of file wow64.c.

◆ wow64_module

ULONG64 wow64_module
static

Definition at line 2296 of file wow64.c.

Referenced by invoke_syscall(), test_exception_dispatcher(), test_modules(), and test_syscalls().

◆ wow64base_module

ULONG64 wow64base_module
static

Definition at line 2296 of file wow64.c.

◆ wow64con_module

ULONG64 wow64con_module
static

Definition at line 2296 of file wow64.c.

◆ wow64cpu_module

ULONG64 wow64cpu_module
static

Definition at line 2297 of file wow64.c.

Referenced by test_modules().

◆ wow64win_module

ULONG64 wow64win_module
static

Definition at line 2297 of file wow64.c.

Referenced by test_modules().

◆ xtajit_module

ULONG64 xtajit_module
static

Definition at line 2297 of file wow64.c.

Referenced by test_memory_notifications(), and test_modules().