Alexandre Julliard : ntdll: Implement NtSetInformationProcess(ProcessThreadStackAllocation).
Alexandre Julliard
julliard at winehq.org
Wed Jul 22 16:34:29 CDT 2020
Module: wine
Branch: master
Commit: 1372d8fc2cac3466d759500063a50d86f03dc94a
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1372d8fc2cac3466d759500063a50d86f03dc94a
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Jul 22 14:15:55 2020 +0200
ntdll: Implement NtSetInformationProcess(ProcessThreadStackAllocation).
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/tests/info.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/unix/process.c | 22 ++++++++++++++++
include/winternl.h | 16 ++++++++++++
3 files changed, 102 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index e5137ef5a4..6fdd2b6e59 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -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();
diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c
index 9854f13aba..bde46264d0 100644
--- a/dlls/ntdll/unix/process.c
+++ b/dlls/ntdll/unix/process.c
@@ -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;
diff --git a/include/winternl.h b/include/winternl.h
index b3fbb90fef..81eb417bb5 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -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) */
More information about the wine-cvs
mailing list