Author: ion Date: Thu Nov 3 06:46:22 2011 New Revision: 54285
URL: http://svn.reactos.org/svn/reactos?rev=54285&view=rev Log: [KERNEL32]: Fix multiple issues in BaseCreateStack: - StackLimit was set incorrectly. - Code was not using BaseStaticServerdata, but querying NT instead. - Fix memory leak in failure case. - StackCommit and StackReserved values were not aligned correctly. - Windows Server 2003+ feature of "Guaranteed Stack Commit Size" was not respected. - Some math was screwy. - Failure to get NT headers was not handled.
Modified: trunk/reactos/dll/win32/kernel32/client/fiber.c trunk/reactos/dll/win32/kernel32/client/proc.c trunk/reactos/dll/win32/kernel32/client/thread.c trunk/reactos/dll/win32/kernel32/client/utils.c trunk/reactos/dll/win32/kernel32/include/kernel32.h
Modified: trunk/reactos/dll/win32/kernel32/client/fiber.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/f... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/fiber.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/fiber.c [iso-8859-1] Thu Nov 3 06:46:22 2011 @@ -201,7 +201,7 @@ }
/* Create the stack for the fiber */ - Status = BasepCreateStack(NtCurrentProcess(), + Status = BaseCreateStack(NtCurrentProcess(), dwStackCommitSize, dwStackReserveSize, &InitialTeb);
Modified: trunk/reactos/dll/win32/kernel32/client/proc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/p... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/proc.c [iso-8859-1] Thu Nov 3 06:46:22 2011 @@ -187,7 +187,7 @@ DPRINT("BasepCreateFirstThread. hProcess: %lx\n", ProcessHandle);
/* Create the Thread's Stack */ - BasepCreateStack(ProcessHandle, + BaseCreateStack(ProcessHandle, SectionImageInfo->MaximumStackSize, SectionImageInfo->CommittedStackSize, &InitialTeb);
Modified: trunk/reactos/dll/win32/kernel32/client/thread.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/t... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/thread.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/thread.c [iso-8859-1] Thu Nov 3 06:46:22 2011 @@ -137,7 +137,7 @@ ClientId.UniqueProcess = hProcess;
/* Create the Stack */ - Status = BasepCreateStack(hProcess, + Status = BaseCreateStack(hProcess, dwStackSize, dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION ? dwStackSize : 0,
Modified: trunk/reactos/dll/win32/kernel32/client/utils.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/u... ============================================================================== --- trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/client/utils.c [iso-8859-1] Thu Nov 3 06:46:22 2011 @@ -247,60 +247,64 @@ */ NTSTATUS WINAPI -BasepCreateStack(HANDLE hProcess, +BaseCreateStack(HANDLE hProcess, SIZE_T StackReserve, SIZE_T StackCommit, PINITIAL_TEB InitialTeb) { NTSTATUS Status; - SYSTEM_BASIC_INFORMATION SystemBasicInfo; PIMAGE_NT_HEADERS Headers; - ULONG_PTR Stack = 0; - BOOLEAN UseGuard = FALSE; - - DPRINT("BasepCreateStack (hProcess: %lx, Max: %lx, Current: %lx)\n", + ULONG_PTR Stack; + BOOLEAN UseGuard; + ULONG PageSize, Dummy, AllocationGranularity; + SIZE_T StackReserveHeader, StackCommitHeader, GuardPageSize, GuaranteedStackCommit; + DPRINT("BaseCreateStack (hProcess: %lx, Max: %lx, Current: %lx)\n", hProcess, StackReserve, StackCommit);
- /* Get some memory information */ - Status = NtQuerySystemInformation(SystemBasicInformation, - &SystemBasicInfo, - sizeof(SYSTEM_BASIC_INFORMATION), - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failure to query system info\n"); - return Status; - } - - /* Use the Image Settings if we are dealing with the current Process */ - if (hProcess == NtCurrentProcess()) - { - /* Get the Image Headers */ - Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); - - /* If we didn't get the parameters, find them ourselves */ - StackReserve = (StackReserve) ? - StackReserve : Headers->OptionalHeader.SizeOfStackReserve; - StackCommit = (StackCommit) ? - StackCommit : Headers->OptionalHeader.SizeOfStackCommit; - } - else - { - /* Use the System Settings if needed */ - StackReserve = (StackReserve) ? StackReserve : - SystemBasicInfo.AllocationGranularity; - StackCommit = (StackCommit) ? StackCommit : SystemBasicInfo.PageSize; - } - - /* Align everything to Page Size */ - StackReserve = ROUND_UP(StackReserve, SystemBasicInfo.AllocationGranularity); - StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize); - #if 1 // FIXME: Remove once Guard Page support is here + /* Read page size */ + PageSize = BaseStaticServerData->SysInfo.PageSize; + AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity; + + /* Get the Image Headers */ + Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); + if (!Headers) return STATUS_INVALID_IMAGE_FORMAT; + + StackCommitHeader = Headers->OptionalHeader.SizeOfStackCommit; + StackReserveHeader = Headers->OptionalHeader.SizeOfStackReserve; + + if (!StackReserve) StackReserve = StackReserveHeader; + + if (!StackCommit) + { + StackCommit = StackCommitHeader; + } + else if (StackCommit >= StackReserve) + { + StackReserve = ROUND_UP(StackCommit, 1024 * 1024); + } + + StackCommit = ROUND_UP(StackCommit, PageSize); + StackReserve = ROUND_UP(StackReserve, AllocationGranularity); + + GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes; + if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit)) + { + StackCommit = GuaranteedStackCommit; + } + + if (StackCommit >= StackReserve) + { + StackReserve = ROUND_UP(StackCommit, 1024 * 1024); + } + + StackCommit = ROUND_UP(StackCommit, PageSize); + StackReserve = ROUND_UP(StackReserve, AllocationGranularity); + + /* ROS Hack until we support guard page stack expansion */ StackCommit = StackReserve; - #endif - DPRINT("StackReserve: %lx, StackCommit: %lx\n", StackReserve, StackCommit);
/* Reserve memory for the stack */ + Stack = 0; Status = ZwAllocateVirtualMemory(hProcess, (PVOID*)&Stack, 0, @@ -309,7 +313,7 @@ PAGE_READWRITE); if (!NT_SUCCESS(Status)) { - DPRINT1("Failure to reserve stack\n"); + DPRINT1("Failure to reserve stack: %lx\n", Status); return Status; }
@@ -325,11 +329,15 @@ /* Check if we will need a guard page */ if (StackReserve > StackCommit) { - Stack -= SystemBasicInfo.PageSize; - StackCommit += SystemBasicInfo.PageSize; + Stack -= PageSize; + StackCommit += PageSize; UseGuard = TRUE; } - + else + { + UseGuard = FALSE; + } + /* Allocate memory for the stack */ Status = ZwAllocateVirtualMemory(hProcess, (PVOID*)&Stack, @@ -340,6 +348,8 @@ if (!NT_SUCCESS(Status)) { DPRINT1("Failure to allocate stack\n"); + GuardPageSize = 0; + ZwFreeVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE); return Status; }
@@ -349,10 +359,8 @@ /* Create a guard page */ if (UseGuard) { - SIZE_T GuardPageSize = SystemBasicInfo.PageSize; - ULONG Dummy; - - /* Attempt maximum space possible */ + /* Set the guard page */ + GuardPageSize = PAGE_SIZE; Status = ZwProtectVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, @@ -360,12 +368,13 @@ &Dummy); if (!NT_SUCCESS(Status)) { - DPRINT1("Failure to create guard page\n"); + DPRINT1("Failure to set guard page\n"); return Status; }
/* Update the Stack Limit keeping in mind the Guard Page */ - InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit - GuardPageSize); + InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit + + GuardPageSize); }
/* We are done! */
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include/... ============================================================================== --- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original) +++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Thu Nov 3 06:46:22 2011 @@ -173,7 +173,7 @@
NTSTATUS WINAPI -BasepCreateStack(HANDLE hProcess, +BaseCreateStack(HANDLE hProcess, SIZE_T StackReserve, SIZE_T StackCommit, PINITIAL_TEB InitialTeb);