ntdll: Implement NtSetInformationProcess(ProcessThreadStackAllocation).

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-07-22 14:15:55 +02:00
parent d41b1c28c3
commit 1372d8fc2c
3 changed files with 102 additions and 0 deletions

View file

@ -2081,6 +2081,69 @@ static void test_mapprotection(void)
pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &oldflags, sizeof(oldflags) );
}
static void test_threadstack(void)
{
PROCESS_STACK_ALLOCATION_INFORMATION info = { 0x100000, 0, (void *)0xdeadbeef };
PROCESS_STACK_ALLOCATION_INFORMATION_EX info_ex = { 0 };
MEMORY_BASIC_INFORMATION meminfo;
SIZE_T retlen;
NTSTATUS status;
info.ReserveSize = 0x100000;
info.StackBase = (void *)0xdeadbeef;
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation, &info, sizeof(info) );
ok( !status, "NtSetInformationProcess failed %08x\n", status );
ok( info.StackBase != (void *)0xdeadbeef, "stackbase not set\n" );
status = pNtQueryVirtualMemory( GetCurrentProcess(), info.StackBase, MemoryBasicInformation,
&meminfo, sizeof(meminfo), &retlen );
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( retlen == sizeof(meminfo), "Expected STATUS_SUCCESS, got %08x\n", status);
ok( meminfo.AllocationBase == info.StackBase, "wrong base %p/%p\n",
meminfo.AllocationBase, info.StackBase );
ok( meminfo.RegionSize == info.ReserveSize, "wrong size %lx/%lx\n",
meminfo.RegionSize, info.ReserveSize );
ok( meminfo.State == MEM_RESERVE, "wrong state %x\n", meminfo.State );
ok( meminfo.Protect == 0, "wrong protect %x\n", meminfo.Protect );
ok( meminfo.Type == MEM_PRIVATE, "wrong type %x\n", meminfo.Type );
info_ex.AllocInfo = info;
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation,
&info_ex, sizeof(info_ex) );
if (status != STATUS_INVALID_PARAMETER)
{
ok( !status, "NtSetInformationProcess failed %08x\n", status );
ok( info_ex.AllocInfo.StackBase != info.StackBase, "stackbase not set\n" );
status = pNtQueryVirtualMemory( GetCurrentProcess(), info_ex.AllocInfo.StackBase,
MemoryBasicInformation, &meminfo, sizeof(meminfo), &retlen );
ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
ok( retlen == sizeof(meminfo), "Expected STATUS_SUCCESS, got %08x\n", status);
ok( meminfo.AllocationBase == info_ex.AllocInfo.StackBase, "wrong base %p/%p\n",
meminfo.AllocationBase, info_ex.AllocInfo.StackBase );
ok( meminfo.RegionSize == info_ex.AllocInfo.ReserveSize, "wrong size %lx/%lx\n",
meminfo.RegionSize, info_ex.AllocInfo.ReserveSize );
ok( meminfo.State == MEM_RESERVE, "wrong state %x\n", meminfo.State );
ok( meminfo.Protect == 0, "wrong protect %x\n", meminfo.Protect );
ok( meminfo.Type == MEM_PRIVATE, "wrong type %x\n", meminfo.Type );
VirtualFree( info_ex.AllocInfo.StackBase, 0, MEM_FREE );
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation,
&info, sizeof(info) - 1 );
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtSetInformationProcess failed %08x\n", status );
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation,
&info, sizeof(info) + 1 );
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtSetInformationProcess failed %08x\n", status );
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation,
&info_ex, sizeof(info_ex) - 1 );
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtSetInformationProcess failed %08x\n", status );
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessThreadStackAllocation,
&info_ex, sizeof(info_ex) + 1 );
ok( status == STATUS_INFO_LENGTH_MISMATCH, "NtSetInformationProcess failed %08x\n", status );
}
else win_skip( "ProcessThreadStackAllocation ex not supported\n" );
VirtualFree( info.StackBase, 0, MEM_FREE );
}
static void test_queryvirtualmemory(void)
{
NTSTATUS status;
@ -2621,6 +2684,7 @@ START_TEST(info)
test_query_process_debug_flags(argc, argv);
test_query_process_image_info();
test_mapprotection();
test_threadstack();
/* NtQueryInformationThread */
test_thread_info();

View file

@ -1580,6 +1580,28 @@ NTSTATUS WINAPI NtSetInformationProcess( HANDLE handle, PROCESSINFOCLASS class,
}
break;
case ProcessThreadStackAllocation:
{
void *addr = NULL;
SIZE_T reserve;
PROCESS_STACK_ALLOCATION_INFORMATION *stack = info;
if (size == sizeof(PROCESS_STACK_ALLOCATION_INFORMATION_EX))
stack = &((PROCESS_STACK_ALLOCATION_INFORMATION_EX *)info)->AllocInfo;
else if (size != sizeof(*stack)) return STATUS_INFO_LENGTH_MISMATCH;
reserve = stack->ReserveSize;
ret = NtAllocateVirtualMemory( GetCurrentProcess(), &addr, stack->ZeroBits, &reserve,
MEM_RESERVE, PAGE_READWRITE );
if (!ret)
{
#ifdef VALGRIND_STACK_REGISTER
VALGRIND_STACK_REGISTER( addr, (char *)addr + reserve );
#endif
stack->StackBase = addr;
}
break;
}
default:
FIXME( "(%p,0x%08x,%p,0x%08x) stub\n", handle, class, info, size );
ret = STATUS_NOT_IMPLEMENTED;

View file

@ -1313,6 +1313,22 @@ typedef struct _PROCESS_PRIORITY_CLASS {
UCHAR PriorityClass;
} PROCESS_PRIORITY_CLASS, *PPROCESS_PRIORITY_CLASS;
typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION
{
SIZE_T ReserveSize;
SIZE_T ZeroBits;
PVOID StackBase;
} PROCESS_STACK_ALLOCATION_INFORMATION, *PPROCESS_STACK_ALLOCATION_INFORMATION;
typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION_EX
{
ULONG PreferredNode;
ULONG Reserved0;
ULONG Reserved1;
ULONG Reserved2;
PROCESS_STACK_ALLOCATION_INFORMATION AllocInfo;
} PROCESS_STACK_ALLOCATION_INFORMATION_EX, *PPROCESS_STACK_ALLOCATION_INFORMATION_EX;
typedef struct _RTL_HEAP_DEFINITION {
ULONG Length; /* = sizeof(RTL_HEAP_DEFINITION) */