You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
420 lines
12 KiB
420 lines
12 KiB
/*++ 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_
|