Commit 78cbc269 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Fill the Wow64 PEB and process parameters.

parent 72ace07c
......@@ -3695,12 +3695,10 @@ static void init_wow64(void)
if (!NtCurrentTeb64()) return;
peb64 = UlongToPtr( NtCurrentTeb64()->Peb );
peb64->ImageBaseAddress = PtrToUlong( peb->ImageBaseAddress );
peb64->OSMajorVersion = peb->OSMajorVersion;
peb64->OSMinorVersion = peb->OSMinorVersion;
peb64->OSBuildNumber = peb->OSBuildNumber;
peb64->OSPlatformId = peb->OSPlatformId;
peb64->SessionId = peb->SessionId;
map_wow64cpu();
}
......
......@@ -367,7 +367,7 @@ static void test_process_params(void)
ok( align(pos, sizeof(void *)) == size ||
broken( align(pos, 4) == size ), "wrong size %lx/%lx\n", pos, size );
ok( params->EnvironmentSize == size - ((char *)params->Environment - (char *)params),
"wrong len %x/%lx\n", params->EnvironmentSize,
"wrong len %lx/%lx\n", params->EnvironmentSize,
size - ((char *)params->Environment - (char *)params) );
}
else ok( broken(TRUE), "environment not inside block\n" ); /* <= win2k3 */
......@@ -421,7 +421,7 @@ static void test_process_params(void)
ok( align(pos, sizeof(void *)) == size ||
broken( align(pos, 4) == size ), "wrong size %lx/%lx\n", pos, size );
ok( params->EnvironmentSize == size - ((char *)params->Environment - (char *)params),
"wrong len %x/%lx\n", params->EnvironmentSize,
"wrong len %lx/%lx\n", params->EnvironmentSize,
size - ((char *)params->Environment - (char *)params) );
}
else ok( broken(TRUE), "environment not inside block\n" ); /* <= win2k3 */
......@@ -475,7 +475,7 @@ static void test_process_params(void)
size = HeapSize( GetProcessHeap(), 0, initial_env );
ok( size != ~(SIZE_T)0, "env is not a heap block %p / %p\n", cur_params, initial_env );
ok( cur_params->EnvironmentSize == size,
"wrong len %x/%lx\n", cur_params->EnvironmentSize, size );
"wrong len %lx/%lx\n", cur_params->EnvironmentSize, size );
}
}
......@@ -526,17 +526,17 @@ static void test_RtlSetCurrentEnvironment(void)
old_env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == get_env_length(old_env) * sizeof(WCHAR),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, old_env ),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
RtlSetCurrentEnvironment(env, &prev);
ok(prev == old_env, "got wrong previous env %p\n", prev);
ok(NtCurrentTeb()->Peb->ProcessParameters->Environment == env, "got wrong current env\n");
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == get_env_length(env) * sizeof(WCHAR),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
check_env_var("testenv1", "unus");
check_env_var("testenv2", NULL);
......@@ -546,14 +546,14 @@ static void test_RtlSetCurrentEnvironment(void)
env = HeapReAlloc( GetProcessHeap(), 0, env, HeapSize( GetProcessHeap(), 0, env) + 120 );
RtlSetCurrentEnvironment(env, &prev);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
RtlSetCurrentEnvironment(old_env, NULL);
ok(NtCurrentTeb()->Peb->ProcessParameters->Environment == old_env, "got wrong current env\n");
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == get_env_length(old_env) * sizeof(WCHAR),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
ok(NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == HeapSize( GetProcessHeap(), 0, old_env ),
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize);
check_env_var("testenv1", "heis");
check_env_var("testenv2", "dyo");
......@@ -562,7 +562,7 @@ static void test_RtlSetCurrentEnvironment(void)
env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
size = get_env_length(env) * sizeof(WCHAR);
ok( NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == size,
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize );
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize );
ok( size == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %lu / %lu\n", size, HeapSize( GetProcessHeap(), 0, env ));
......@@ -571,7 +571,7 @@ static void test_RtlSetCurrentEnvironment(void)
env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
ok( NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize == size,
"got wrong size %u\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize );
"got wrong size %lu\n", NtCurrentTeb()->Peb->ProcessParameters->EnvironmentSize );
ok( size == HeapSize( GetProcessHeap(), 0, env ),
"got wrong size %lu / %lu\n", size, HeapSize( GetProcessHeap(), 0, env ));
ok( size > get_env_length(env) * sizeof(WCHAR), "got wrong size %lu\n", size );
......
......@@ -3140,6 +3140,8 @@ static void test_wow64(void)
PEB peb;
TEB32 teb32;
PEB32 peb32;
RTL_USER_PROCESS_PARAMETERS params;
RTL_USER_PROCESS_PARAMETERS32 params32;
Wow64DisableWow64FsRedirection( &redir );
......@@ -3190,6 +3192,42 @@ static void test_wow64(void)
ok( !peb32.BeingDebugged, "BeingDebugged is %u\n", peb32.BeingDebugged );
}
if (!ReadProcessMemory( pi.hProcess, peb.ProcessParameters, &params, sizeof(params), &res )) res = 0;
ok( res == sizeof(params), "wrong len %lx\n", res );
#define CHECK_STR(name) \
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 )
CHECK_STR( ImagePathName );
CHECK_STR( CommandLine );
CHECK_STR( WindowTitle );
CHECK_STR( Desktop );
CHECK_STR( ShellInfo );
#undef CHECK_STR
if (!is_wow64)
{
ok( peb32.ProcessParameters && ULongToPtr(peb32.ProcessParameters) != peb.ProcessParameters,
"wrong ptr32 %p / %p\n", ULongToPtr(peb32.ProcessParameters), peb.ProcessParameters );
if (!ReadProcessMemory( pi.hProcess, ULongToPtr(peb32.ProcessParameters), &params32, sizeof(params32), &res )) res = 0;
ok( res == sizeof(params32), "wrong len %lx\n", res );
#define CHECK_STR(name) \
ok( ULongToPtr(params32.name.Buffer) >= ULongToPtr(peb32.ProcessParameters) && \
ULongToPtr(params32.name.Buffer) < ULongToPtr(peb32.ProcessParameters + params32.Size), \
"wrong " #name " ptr %x / %x-%x\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 )
CHECK_STR( ImagePathName );
CHECK_STR( CommandLine );
CHECK_STR( WindowTitle );
CHECK_STR( Desktop );
CHECK_STR( ShellInfo );
#undef CHECK_STR
ok( params32.EnvironmentSize == params.EnvironmentSize, "wrong size %u / %lu\n",
params32.EnvironmentSize, params.EnvironmentSize );
}
ok( DebugActiveProcess( pi.dwProcessId ), "debugging failed\n" );
if (!ReadProcessMemory( pi.hProcess, proc_info.PebBaseAddress, &peb, sizeof(peb), &res )) res = 0;
ok( res == sizeof(peb), "wrong len %lx\n", res );
......
......@@ -1913,13 +1913,131 @@ static inline DWORD append_string( void **ptr, const RTL_USER_PROCESS_PARAMETERS
return str->Length;
}
#ifdef _WIN64
static inline void dup_unicode_string( const UNICODE_STRING *src, WCHAR **dst, UNICODE_STRING32 *str )
#else
static inline void dup_unicode_string( const UNICODE_STRING *src, WCHAR **dst, UNICODE_STRING64 *str )
#endif
{
if (!src->Buffer) return;
str->Buffer = PtrToUlong( *dst );
str->Length = src->Length;
str->MaximumLength = src->MaximumLength;
memcpy( *dst, src->Buffer, src->MaximumLength );
*dst += src->MaximumLength / sizeof(WCHAR);
}
/*************************************************************************
* build_wow64_parameters
*/
static void *build_wow64_parameters( const RTL_USER_PROCESS_PARAMETERS *params )
{
#ifdef _WIN64
RTL_USER_PROCESS_PARAMETERS32 *wow64_params = NULL;
#else
RTL_USER_PROCESS_PARAMETERS64 *wow64_params = NULL;
#endif
NTSTATUS status;
WCHAR *dst;
SIZE_T size = (sizeof(*wow64_params)
+ params->CurrentDirectory.DosPath.MaximumLength
+ params->DllPath.MaximumLength
+ params->ImagePathName.MaximumLength
+ params->CommandLine.MaximumLength
+ params->WindowTitle.MaximumLength
+ params->Desktop.MaximumLength
+ params->ShellInfo.MaximumLength
+ params->RuntimeInfo.MaximumLength
+ params->EnvironmentSize);
status = NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&wow64_params, 0, &size,
MEM_COMMIT, PAGE_READWRITE );
assert( !status );
wow64_params->AllocationSize = size;
wow64_params->Size = size;
wow64_params->Flags = params->Flags;
wow64_params->DebugFlags = params->DebugFlags;
wow64_params->ConsoleHandle = HandleToULong( params->ConsoleHandle );
wow64_params->ConsoleFlags = params->ConsoleFlags;
wow64_params->hStdInput = HandleToULong( params->hStdInput );
wow64_params->hStdOutput = HandleToULong( params->hStdOutput );
wow64_params->hStdError = HandleToULong( params->hStdError );
wow64_params->dwX = params->dwX;
wow64_params->dwY = params->dwY;
wow64_params->dwXSize = params->dwXSize;
wow64_params->dwYSize = params->dwYSize;
wow64_params->dwXCountChars = params->dwXCountChars;
wow64_params->dwYCountChars = params->dwYCountChars;
wow64_params->dwFillAttribute = params->dwFillAttribute;
wow64_params->dwFlags = params->dwFlags;
wow64_params->wShowWindow = params->wShowWindow;
dst = (WCHAR *)(wow64_params + 1);
dup_unicode_string( &params->CurrentDirectory.DosPath, &dst, &wow64_params->CurrentDirectory.DosPath );
dup_unicode_string( &params->DllPath, &dst, &wow64_params->DllPath );
dup_unicode_string( &params->ImagePathName, &dst, &wow64_params->ImagePathName );
dup_unicode_string( &params->CommandLine, &dst, &wow64_params->CommandLine );
dup_unicode_string( &params->WindowTitle, &dst, &wow64_params->WindowTitle );
dup_unicode_string( &params->Desktop, &dst, &wow64_params->Desktop );
dup_unicode_string( &params->ShellInfo, &dst, &wow64_params->ShellInfo );
dup_unicode_string( &params->RuntimeInfo, &dst, &wow64_params->RuntimeInfo );
wow64_params->Environment = PtrToUlong( dst );
wow64_params->EnvironmentSize = params->EnvironmentSize;
memcpy( dst, params->Environment, params->EnvironmentSize );
return wow64_params;
}
/*************************************************************************
* init_peb
*/
static void init_peb( RTL_USER_PROCESS_PARAMETERS *params, void *module )
{
PEB *peb = NtCurrentTeb()->Peb;
peb->ImageBaseAddress = module;
peb->ProcessParameters = params;
peb->OSMajorVersion = 6;
peb->OSMinorVersion = 1;
peb->OSBuildNumber = 0x1db1;
peb->OSPlatformId = VER_PLATFORM_WIN32_NT;
peb->ImageSubSystem = main_image_info.SubSystemType;
peb->ImageSubSystemMajorVersion = main_image_info.MajorSubsystemVersion;
peb->ImageSubSystemMinorVersion = main_image_info.MinorSubsystemVersion;
peb->SessionId = 1;
if (NtCurrentTeb()->WowTebOffset)
{
void *wow64_params = build_wow64_parameters( params );
#ifdef _WIN64
PEB32 *wow64_peb = (PEB32 *)((char *)peb + page_size);
#else
PEB64 *wow64_peb = (PEB64 *)((char *)peb - page_size);
#endif
wow64_peb->ImageBaseAddress = PtrToUlong( peb->ImageBaseAddress );
wow64_peb->ProcessParameters = PtrToUlong( wow64_params );
wow64_peb->NumberOfProcessors = peb->NumberOfProcessors;
wow64_peb->OSMajorVersion = peb->OSMajorVersion;
wow64_peb->OSMinorVersion = peb->OSMinorVersion;
wow64_peb->OSBuildNumber = peb->OSBuildNumber;
wow64_peb->OSPlatformId = peb->OSPlatformId;
wow64_peb->ImageSubSystem = peb->ImageSubSystem;
wow64_peb->ImageSubSystemMajorVersion = peb->ImageSubSystemMajorVersion;
wow64_peb->ImageSubSystemMinorVersion = peb->ImageSubSystemMinorVersion;
wow64_peb->SessionId = peb->SessionId;
}
}
/*************************************************************************
* build_initial_params
*
* Build process parameters from scratch, for processes without a parent.
*/
static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
static RTL_USER_PROCESS_PARAMETERS *build_initial_params( void **module )
{
static const WCHAR valueW[] = {'1',0};
static const WCHAR pathW[] = {'P','A','T','H'};
......@@ -1928,7 +2046,6 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
WCHAR *dst, *image, *cmdline, *path, *bootstrap;
WCHAR *env = get_initial_environment( &env_pos, &env_size );
WCHAR *curdir = get_initial_directory();
void *module = NULL;
NTSTATUS status;
/* store the initial PATH value */
......@@ -1950,7 +2067,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
add_registry_environment( &env, &env_pos, &env_size );
env[env_pos++] = 0;
status = load_main_exe( NULL, main_argv[1], curdir, &image, &module );
status = load_main_exe( NULL, main_argv[1], curdir, &image, module );
if (!status)
{
if (main_image_info.ImageCharacteristics & IMAGE_FILE_DLL) status = STATUS_INVALID_IMAGE_FORMAT;
......@@ -1963,13 +2080,12 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
{
static const char *args[] = { "start.exe", "/exec" };
free( image );
if (module) NtUnmapViewOfSection( GetCurrentProcess(), module );
load_start_exe( &image, &module );
if (*module) NtUnmapViewOfSection( GetCurrentProcess(), *module );
load_start_exe( &image, module );
prepend_argv( args, 2 );
}
else rebuild_argv();
NtCurrentTeb()->Peb->ImageBaseAddress = module;
main_wargv = build_wargv( get_dos_path( image ));
cmdline = build_command_line( main_wargv );
......@@ -2021,7 +2137,7 @@ static RTL_USER_PROCESS_PARAMETERS *build_initial_params(void)
void init_startup_info(void)
{
WCHAR *src, *dst, *env, *image;
void *module;
void *module = NULL;
NTSTATUS status;
SIZE_T size, info_size, env_size, env_pos;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
......@@ -2029,7 +2145,8 @@ void init_startup_info(void)
if (!startup_info_size)
{
NtCurrentTeb()->Peb->ProcessParameters = build_initial_params();
params = build_initial_params( &module );
init_peb( params, module );
return;
}
......@@ -2116,7 +2233,6 @@ void init_startup_info(void)
memcpy( dst, env, env_pos * sizeof(WCHAR) );
free( env );
free( info );
NtCurrentTeb()->Peb->ProcessParameters = params;
status = load_main_exe( params->ImagePathName.Buffer, NULL,
params->CommandLine.Buffer, &image, &module );
......@@ -2125,10 +2241,10 @@ void init_startup_info(void)
MESSAGE( "wine: failed to start %s\n", debugstr_us(&params->ImagePathName) );
NtTerminateProcess( GetCurrentProcess(), status );
}
NtCurrentTeb()->Peb->ImageBaseAddress = module;
rebuild_argv();
main_wargv = build_wargv( get_dos_path( image ));
free( image );
init_peb( params, module );
}
......
......@@ -2812,25 +2812,6 @@ NTSTATUS virtual_create_builtin_view( void *module, const UNICODE_STRING *nt_nam
}
/* set some initial values in the new PEB */
static PEB *init_peb( void *ptr )
{
PEB64 *peb64 = ptr;
PEB32 *peb32 = (PEB32 *)((char *)ptr + page_size);
peb32->OSMajorVersion = peb64->OSMajorVersion = 6;
peb32->OSMinorVersion = peb64->OSMinorVersion = 1;
peb32->OSBuildNumber = peb64->OSBuildNumber = 0x1db1;
peb32->OSPlatformId = peb64->OSPlatformId = VER_PLATFORM_WIN32_NT;
peb32->SessionId = peb64->SessionId = 1;
#ifdef _WIN64
return (PEB *)peb64;
#else
return (PEB *)peb32;
#endif
}
/* set some initial values in a new TEB */
static TEB *init_teb( void *ptr, PEB *peb, BOOL is_wow )
{
......@@ -2917,7 +2898,7 @@ TEB *virtual_alloc_first_teb(void)
ptr = (char *)teb_block + 30 * block_size;
data_size = 2 * block_size;
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&ptr, 0, &data_size, MEM_COMMIT, PAGE_READWRITE );
peb = init_peb( (char *)teb_block + 31 * block_size );
peb = (PEB *)((char *)teb_block + 31 * block_size + (is_win64 ? 0 : page_size));
teb = init_teb( ptr, peb, FALSE );
*(ULONG_PTR *)&peb->CloudFileFlags = get_image_address();
return teb;
......
......@@ -199,8 +199,8 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeInfo;
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
ULONG EnvironmentSize;
ULONG EnvironmentVersion;
ULONG_PTR EnvironmentSize;
ULONG_PTR EnvironmentVersion;
PVOID PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads;
......@@ -584,6 +584,108 @@ typedef struct _ACTIVATION_CONTEXT_STACK64
ULONG64 StackId;
} ACTIVATION_CONTEXT_STACK64;
typedef struct _CURDIR32
{
UNICODE_STRING32 DosPath;
ULONG Handle;
} CURDIR32;
typedef struct _CURDIR64
{
UNICODE_STRING64 DosPath;
ULONG64 Handle;
} CURDIR64;
typedef struct RTL_DRIVE_LETTER_CURDIR32
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING32 DosPath;
} RTL_DRIVE_LETTER_CURDIR32;
typedef struct RTL_DRIVE_LETTER_CURDIR64
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING64 DosPath;
} RTL_DRIVE_LETTER_CURDIR64;
typedef struct _RTL_USER_PROCESS_PARAMETERS32
{
ULONG AllocationSize;
ULONG Size;
ULONG Flags;
ULONG DebugFlags;
ULONG ConsoleHandle;
ULONG ConsoleFlags;
ULONG hStdInput;
ULONG hStdOutput;
ULONG hStdError;
CURDIR32 CurrentDirectory;
UNICODE_STRING32 DllPath;
UNICODE_STRING32 ImagePathName;
UNICODE_STRING32 CommandLine;
ULONG Environment;
ULONG dwX;
ULONG dwY;
ULONG dwXSize;
ULONG dwYSize;
ULONG dwXCountChars;
ULONG dwYCountChars;
ULONG dwFillAttribute;
ULONG dwFlags;
ULONG wShowWindow;
UNICODE_STRING32 WindowTitle;
UNICODE_STRING32 Desktop;
UNICODE_STRING32 ShellInfo;
UNICODE_STRING32 RuntimeInfo;
RTL_DRIVE_LETTER_CURDIR32 DLCurrentDirectory[0x20];
ULONG EnvironmentSize;
ULONG EnvironmentVersion;
ULONG PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads;
} RTL_USER_PROCESS_PARAMETERS32;
typedef struct _RTL_USER_PROCESS_PARAMETERS64
{
ULONG AllocationSize;
ULONG Size;
ULONG Flags;
ULONG DebugFlags;
ULONG64 ConsoleHandle;
ULONG ConsoleFlags;
ULONG64 hStdInput;
ULONG64 hStdOutput;
ULONG64 hStdError;
CURDIR64 CurrentDirectory;
UNICODE_STRING64 DllPath;
UNICODE_STRING64 ImagePathName;
UNICODE_STRING64 CommandLine;
ULONG64 Environment;
ULONG dwX;
ULONG dwY;
ULONG dwXSize;
ULONG dwYSize;
ULONG dwXCountChars;
ULONG dwYCountChars;
ULONG dwFillAttribute;
ULONG dwFlags;
ULONG wShowWindow;
UNICODE_STRING64 WindowTitle;
UNICODE_STRING64 Desktop;
UNICODE_STRING64 ShellInfo;
UNICODE_STRING64 RuntimeInfo;
RTL_DRIVE_LETTER_CURDIR64 DLCurrentDirectory[0x20];
ULONG64 EnvironmentSize;
ULONG64 EnvironmentVersion;
ULONG64 PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads;
} RTL_USER_PROCESS_PARAMETERS64;
typedef struct _PEB_LDR_DATA32
{
ULONG Length;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment