/*++ BUILD Version: 0001 // Increment this if a change has global effects Copyright (c) Microsoft Corporation. All rights reserved. Module Name: wow64t.h Abstract: 32-bit structure definitions for 64-bit NT. Author: Barry Bond (barrybo) 20-Jun-1998 Revision History: --*/ #ifndef _WOW64T_ #define _WOW64T_ #if _MSC_VER > 1000 #pragma once #endif // // Page size on x86 NT // #define PAGE_SIZE_X86NT 0x1000 #define PAGE_SHIFT_X86NT 12L // // Convert the number of native pages to sub x86-pages // #define Wow64GetNumberOfX86Pages(NativePages) \ (NativePages * (PAGE_SIZE >> PAGE_SHIFT_X86NT)) // // Macro to round to the nearest page size // #define WOW64_ROUND_TO_PAGES(Size) \ (((ULONG_PTR)(Size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) // // Get number of native pages // #define WOW64_BYTES_TO_PAGES(Size) (((ULONG)(Size) >> PAGE_SHIFT) + \ (((ULONG)(Size) & (PAGE_SIZE - 1)) != 0)) // // The name of the 32-bit system directory, which is a child of %SystemRoot% // #define WOW64_SYSTEM_DIRECTORY "syswow64" #define WOW64_SYSTEM_DIRECTORY_U L"syswow64" // Length in bytes of the new system directory, not counting a // null terminator // #define WOW64_SYSTEM_DIRECTORY_SIZE (sizeof(WOW64_SYSTEM_DIRECTORY)-sizeof(CHAR)) #define WOW64_SYSTEM_DIRECTORY_U_SIZE (sizeof(WOW64_SYSTEM_DIRECTORY_U)-sizeof(WCHAR)) // // Wow64 Registry Configuration // #define WOW64_REGISTRY_CONFIG_ROOT L"\\REGISTRY\\MACHINE\\SOFTWARE\\Microsoft\\WOW64" #define WOW64_REGISTRY_CONFIG_EXECUTE_OPTIONS L"ExecuteOptions" #define WOW64_X86_TAG " (x86)" #define WOW64_X86_TAG_U L" (x86)" // // File system redirection values // #define WOW64_FILE_SYSTEM_ENABLE_REDIRECT (UlongToPtr(0x00)) // enable file-system redirection for the currently executing thread #define WOW64_FILE_SYSTEM_DISABLE_REDIRECT (UlongToPtr(0x01)) // disable file-system redirection for the currently executing thread #define WOW64_FILE_SYSTEM_DISABLE_REDIRECT_LEGACY ((PVOID)L"[<__wow64_disable_redirect_all__]>") #define TYPE32(x) ULONG #define TYPE64(x) ULONGLONG #if !_WIN64 __inline void * ULonglongToPtr( const ULONGLONG ull ) { #pragma warning (push) #pragma warning (disable : 4305) return((void *) ull ); #pragma warning (pop) } #endif // // Wow64Info structure is shared between 32-bit and 64-bit modules inside a Wow64 process. // NOTE : This structure shouldn't contain any pointer-dependent data, as // it is viewed from 32-bit and 64-bit code. // typedef struct _WOW64INFO { ULONG NativeSystemPageSize; // Page size of the native system the emulator is running on. ULONG CpuFlags; } WOW64INFO, *PWOW64INFO; typedef struct _PEB_LDR_DATA32 { ULONG Length; BOOLEAN Initialized; TYPE32(HANDLE) SsHandle; LIST_ENTRY32 InLoadOrderModuleList; LIST_ENTRY32 InMemoryOrderModuleList; LIST_ENTRY32 InInitializationOrderModuleList; TYPE32(PVOID) EntryInProgress; } PEB_LDR_DATA32, *PPEB_LDR_DATA32; typedef struct _GDI_TEB_BATCH32 { ULONG Offset; TYPE32(ULONG_PTR) HDC; ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; } GDI_TEB_BATCH32,*PGDI_TEB_BATCH32; typedef struct _GDI_TEB_BATCH64 { ULONG Offset; TYPE64(ULONG_PTR) HDC; ULONG Buffer[GDI_BATCH_BUFFER_SIZE]; } GDI_TEB_BATCH64,*PGDI_TEB_BATCH64; typedef struct _Wx86ThreadState32 { TYPE32(PULONG) CallBx86Eip; TYPE32(PVOID) DeallocationCpu; BOOLEAN UseKnownWx86Dll; char OleStubInvoked; } WX86THREAD32, *PWX86THREAD32; typedef struct _Wx86ThreadState64 { TYPE64(PULONG) CallBx86Eip; TYPE64(PVOID) DeallocationCpu; BOOLEAN UseKnownWx86Dll; char OleStubInvoked; } WX86THREAD64, *PWX86THREAD64; typedef struct _CLIENT_ID32 { TYPE32(HANDLE) UniqueProcess; TYPE32(HANDLE) UniqueThread; } CLIENT_ID32; typedef CLIENT_ID32 *PCLIENT_ID32; #if !defined(CLIENT_ID64_DEFINED) typedef struct _CLIENT_ID64 { TYPE64(HANDLE) UniqueProcess; TYPE64(HANDLE) UniqueThread; } CLIENT_ID64; typedef CLIENT_ID64 *PCLIENT_ID64; #define CLIENT_ID64_DEFINED #endif typedef ULONG GDI_HANDLE_BUFFER32[GDI_HANDLE_BUFFER_SIZE32]; typedef ULONG GDI_HANDLE_BUFFER64[GDI_HANDLE_BUFFER_SIZE64]; #define PEBTEB_BITS 32 #include "pebteb.h" #undef PEBTEB_BITS #define PEBTEB_BITS 64 #include "pebteb.h" #undef PEBTEB_BITS typedef struct _RTL_DRIVE_LETTER_CURDIR32 { USHORT Flags; USHORT Length; ULONG TimeStamp; STRING32 DosPath; } RTL_DRIVE_LETTER_CURDIR32, *PRTL_DRIVE_LETTER_CURDIR32; typedef struct _CURDIR32 { UNICODE_STRING32 DosPath; TYPE32(HANDLE) Handle; } CURDIR32, *PCURDIR32; typedef struct _RTL_USER_PROCESS_PARAMETERS32 { ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; TYPE32(HANDLE) ConsoleHandle; ULONG ConsoleFlags; TYPE32(HANDLE) StandardInput; TYPE32(HANDLE) StandardOutput; TYPE32(HANDLE) StandardError; CURDIR32 CurrentDirectory; // ProcessParameters UNICODE_STRING32 DllPath; // ProcessParameters UNICODE_STRING32 ImagePathName; // ProcessParameters UNICODE_STRING32 CommandLine; // ProcessParameters TYPE32(PVOID) Environment; // NtAllocateVirtualMemory ULONG StartingX; ULONG StartingY; ULONG CountX; ULONG CountY; ULONG CountCharsX; ULONG CountCharsY; ULONG FillAttribute; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING32 WindowTitle; // ProcessParameters UNICODE_STRING32 DesktopInfo; // ProcessParameters UNICODE_STRING32 ShellInfo; // ProcessParameters UNICODE_STRING32 RuntimeData; // ProcessParameters RTL_DRIVE_LETTER_CURDIR32 CurrentDirectores[ RTL_MAX_DRIVE_LETTERS ]; } RTL_USER_PROCESS_PARAMETERS32, *PRTL_USER_PROCESS_PARAMETERS32; #if !defined(BUILD_WOW6432) // // Get the 32-bit TEB without doing a memory reference. // #define WOW64_GET_TEB32_SAFE(teb64) \ ((PTEB32) ((ULONGLONG)teb64 + WOW64_ROUND_TO_PAGES (sizeof (TEB)))) #define WOW64_GET_TEB32(teb64) \ WOW64_GET_TEB32_SAFE(teb64) // // Update the first qword in the 64-bit TEB. The 32-bit rdteb instruction // reads the TEB32 pointer value directly from this field. // #define WOW64_SET_TEB32(teb64, teb32) \ (teb64)->NtTib.ExceptionList = (struct _EXCEPTION_REGISTRATION_RECORD *)(teb32); #define WOW64_TEB32_POINTER_ADDRESS(teb64) \ (PVOID)&((teb64)->NtTib.ExceptionList) #endif // // Thunk macros #define UStr32ToUStr(dst, src) { (dst)->Length = (src)->Length; \ (dst)->MaximumLength = (src)->MaximumLength; \ (dst)->Buffer = (PWSTR) ((src)->Buffer); } #define UStrToUStr32(dst, src) { (dst)->Length = (src)->Length; \ (dst)->MaximumLength = (src)->MaximumLength; \ (dst)->Buffer = (ULONG) ((src)->Buffer); } #define NtCurrentTeb32() ((PTEB32) WOW64_GET_TEB32_SAFE (NtCurrentTeb ())) #define NtCurrentPeb32() ((PPEB32) UlongToPtr ((NtCurrentTeb32()->ProcessEnvironmentBlock)) ) // This is currently defined in windows\core\w32inc\w32wow64.h: #define NtCurrentTeb64() ((PTEB64)((PTEB32)NtCurrentTeb())->GdiBatchCount) // This is currently defined in base\wow64\inc\wow64.h: #define WOW64_TLS_FILESYSREDIR 8 // Used to enable/disable the filesystem #define WOW64_TLS_WOW64INFO 10 // Used to access native system information for wow64 processes. #define WOW64_TLS_INITIAL_TEB32 11 // A pointer to the 32-bit initial TEB #define WOW64_TLS_MAX_NUMBER 12 // Maximum number of TLS slot entries to allocate. // These should only be called from Win32 code known to be running on Win64. #if !_WIN64 #define Wow64EnableFilesystemRedirector() \ NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR] = 0; #define Wow64DisableFilesystemRedirector(filename) \ NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR] = (ULONGLONG)PtrToUlong(filename); __inline PVOID Wow64SetFilesystemRedirectorEx ( PVOID NewValue ) /*++ Routine Description: This routine allows a thread running inside Wow64 to disable file-system redirection for all calls happening in the context of this thread. NOTE: This routine should only called from a wow64 process, and is only available when running on .NET server platforms and beyond. If you component will run on downlevel platforms (XP 2600 for example), you shouldn't use WOW64_FILE_SYSTEM_DISABLE_REDIRECT (see below). Example (Enumerating files under c:\windows\system32): { HANDLE File; WIN32_FIND_DATA FindData; #ifndef _WIN64 BOOL bWow64Process = FALSE; PVOID Wow64RedirectionOld; #endif // // Disable Wow64 file system redirection // #ifndef _WIN64 IsWow64Process (GetCurrentProcess (), &bWow64Process); if (bWow64Process == TRUE) { Wow64RedirectionOld = Wow64SetFilesystemRedirectorEx (WOW64_FILE_SYSTEM_DISABLE_REDIRECT); } #endif File = FindFirstFileA ("c:\\windows\\system32\\*.*", &FindData); do { . . } while (FindNextFileA (File, &FindData) != 0); FindClose (File); // // Enable Wow64 file-system redirection // #ifndef _WIN64 if (bWow64Process == TRUE) { Wow64SetFilesystemRedirectorEx (Wow64RedirectionOld); } #endif } Arguments: NewValue - New Wow64 file-system redirection value. This can either be: a- pointer to a unicode string with a fully-qualified path name (e.g. L"c:\\windows\\notepad.exe"). b- any of the following predefined values : * WOW64_FILE_SYSTEM_ENABLE_REDIRECT : Enables file-system redirection (default) * WOW64_FILE_SYSTEM_DISABLE_REDIRECT : Disables file-system redirection on all file I/O operations happening within the context of the current thread. * WOW64_FILE_SYSTEM_DISABLE_REDIRECT_LEGACY: Use this only if you want to run on download level platforms (for example XP 2600), as it will have no effect and prevents your program from malfunctioning. Return: Old Wow64 file-system redirection value --*/ { NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR] = (ULONGLONG)PtrToUlong(NewValue); return UlongToPtr ((ULONG)NtCurrentTeb64()->TlsSlots[WOW64_TLS_FILESYSREDIR]); } // // Wow64Info is accessed only from compiled code for x86 on win64. // NOTE: Only Wow64 processes are allowed to call these macros. // #define Wow64GetSharedInfo() ((PWOW64INFO)NtCurrentTeb64()->TlsSlots[WOW64_TLS_WOW64INFO]) #define Wow64GetSystemNativePageSize() \ ((PWOW64INFO)ULonglongToPtr((NtCurrentTeb64()->TlsSlots[WOW64_TLS_WOW64INFO])))->NativeSystemPageSize #else #define Wow64GetSharedInfo() ((PWOW64INFO)NtCurrentTeb()->TlsSlots[WOW64_TLS_WOW64INFO]) #define Wow64GetInitialTeb32() ((PINITIAL_TEB)NtCurrentTeb()->TlsSlots[WOW64_TLS_INITIAL_TEB32]) #endif typedef ULONGLONG SIZE_T64, *PSIZE_T64; #if defined(BUILD_WOW6432) typedef VOID * __ptr64 NATIVE_PVOID; typedef ULONG64 NATIVE_ULONG_PTR; typedef SIZE_T64 NATIVE_SIZE_T; typedef PSIZE_T64 PNATIVE_SIZE_T; typedef struct _PEB64 NATIVE_PEB; typedef struct _PROCESS_BASIC_INFORMATION64 NATIVE_PROCESS_BASIC_INFORMATION; typedef struct _MEMORY_BASIC_INFORMATION64 NATIVE_MEMORY_BASIC_INFORMATION; #else typedef ULONG_PTR NATIVE_ULONG_PTR; typedef SIZE_T NATIVE_SIZE_T; typedef PSIZE_T PNATIVE_SIZE_T; typedef PVOID NATIVE_PVOID; typedef struct _PEB NATIVE_PEB; typedef struct _PROCESS_BASIC_INFORMATION NATIVE_PROCESS_BASIC_INFORMATION; typedef struct _MEMORY_BASIC_INFORMATION NATIVE_MEMORY_BASIC_INFORMATION; #endif #endif // _WOW64T_