Index: dll/win32/kernel32/client/thread.c =================================================================== --- dll/win32/kernel32/client/thread.c (révision 71402) +++ dll/win32/kernel32/client/thread.c (copie de travail) @@ -188,9 +188,10 @@ /* Create the Stack */ Status = BaseCreateStack(hProcess, - dwStackSize, - dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION ? - dwStackSize : 0, + (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ? + 0 : dwStackSize, + (dwCreationFlags & STACK_SIZE_PARAM_IS_A_RESERVATION) ? + dwStackSize : 0, &InitialTeb); if (!NT_SUCCESS(Status)) { @@ -972,7 +973,7 @@ } /* - * @implemented + * @unimplemented */ BOOL WINAPI @@ -979,9 +980,43 @@ SetThreadStackGuarantee(IN OUT PULONG StackSizeInBytes) { static int once; + + PTEB Teb; + ULONG GuaranteedStackBytes; + ULONG AllocationSize; + + if (!StackSizeInBytes) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + AllocationSize = *StackSizeInBytes; + + Teb = NtCurrentTeb(); + + /* Retrieve the current stack size */ + GuaranteedStackBytes = Teb->GuaranteedStackBytes; + + /* Return the size of the previous stack */ + *StackSizeInBytes = GuaranteedStackBytes; + + /* + * If the new stack size is either zero or is less than the current size, + * the previous stack size is returned and we return success. + */ + if ((AllocationSize == 0) || (AllocationSize < GuaranteedStackBytes)) + { + return TRUE; + } + + // FIXME: Unimplemented! + if (once++ == 0) DPRINT1("SetThreadStackGuarantee(%p): stub\n", StackSizeInBytes); - return TRUE; + + // return TRUE; + return FALSE; } /* Index: dll/win32/kernel32/client/utils.c =================================================================== --- dll/win32/kernel32/client/utils.c (révision 71401) +++ dll/win32/kernel32/client/utils.c (copie de travail) @@ -346,21 +346,26 @@ } /* - * Creates a stack for a thread or fiber + * Creates a stack for a thread or fiber. + * NOTE: Adapted from sdk/lib/rtl/thread.c:RtlpCreateUserStack */ NTSTATUS WINAPI -BaseCreateStack(HANDLE hProcess, - SIZE_T StackCommit, - SIZE_T StackReserve, - PINITIAL_TEB InitialTeb) +BaseCreateStack(IN HANDLE hProcess, + IN SIZE_T StackCommit, + IN SIZE_T StackReserve, + OUT PINITIAL_TEB InitialTeb) { NTSTATUS Status; PIMAGE_NT_HEADERS Headers; ULONG_PTR Stack; BOOLEAN UseGuard; - ULONG PageSize, Dummy, AllocationGranularity; - SIZE_T StackReserveHeader, StackCommitHeader, GuardPageSize, GuaranteedStackCommit; + ULONG PageSize, AllocationGranularity, Dummy; +#if 0 + SIZE_T GuaranteedStackCommit, GuardPageSize; +#else + SIZE_T MinimumStackCommit, GuardPageSize; +#endif DPRINT("BaseCreateStack (hProcess: %p, Max: %lx, Current: %lx)\n", hProcess, StackReserve, StackCommit); @@ -372,28 +377,36 @@ Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); if (!Headers) return STATUS_INVALID_IMAGE_FORMAT; - StackCommitHeader = Headers->OptionalHeader.SizeOfStackCommit; - StackReserveHeader = Headers->OptionalHeader.SizeOfStackReserve; + if (StackReserve == 0) + StackReserve = Headers->OptionalHeader.SizeOfStackReserve; - if (!StackReserve) StackReserve = StackReserveHeader; - - if (!StackCommit) + if (StackCommit == 0) { - StackCommit = StackCommitHeader; + StackCommit = Headers->OptionalHeader.SizeOfStackCommit; } else if (StackCommit >= StackReserve) { + /* Grow the reserve beyond the commit, up to 1MB alignment */ StackReserve = ROUND_UP(StackCommit, 1024 * 1024); } + /* Align everything to Page Size */ StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity); +#if 0 GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes; if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit)) { StackCommit = GuaranteedStackCommit; } +#else + MinimumStackCommit = NtCurrentTeb()->ProcessEnvironmentBlock->MinimumStackCommit; + if ((MinimumStackCommit) && (StackCommit < MinimumStackCommit)) + { + StackCommit = MinimumStackCommit; + } +#endif if (StackCommit >= StackReserve) { @@ -423,11 +436,11 @@ InitialTeb->PreviousStackBase = NULL; InitialTeb->PreviousStackLimit = NULL; - /* Update the Stack Position */ + /* Update the stack position */ Stack += StackReserve - StackCommit; - /* Check if we will need a guard page */ - if (StackReserve > StackCommit) + /* Check if we can add a guard page */ + if (StackReserve >= StackCommit + PageSize) { Stack -= PageSize; StackCommit += PageSize; @@ -456,11 +469,10 @@ /* Now set the current Stack Limit */ InitialTeb->StackLimit = (PVOID)Stack; - /* Create a guard page */ + /* Create a guard page if needed */ if (UseGuard) { - /* Set the guard page */ - GuardPageSize = PAGE_SIZE; + GuardPageSize = PageSize; Status = NtProtectVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, @@ -481,6 +493,9 @@ return STATUS_SUCCESS; } +/* + * NOTE: Adapted from sdk/lib/rtl/thread.c:RtlpFreeUserStack + */ VOID WINAPI BaseFreeThreadStack(IN HANDLE hProcess, @@ -501,10 +516,10 @@ VOID WINAPI BaseInitializeContext(IN PCONTEXT Context, - IN PVOID Parameter, - IN PVOID StartAddress, - IN PVOID StackAddress, - IN ULONG ContextType) + IN PVOID Parameter, + IN PVOID StartAddress, + IN PVOID StackAddress, + IN ULONG ContextType) { #ifdef _M_IX86 ULONG ContextFlags; Index: ntoskrnl/mm/ARM3/procsup.c =================================================================== --- ntoskrnl/mm/ARM3/procsup.c (révision 71401) +++ ntoskrnl/mm/ARM3/procsup.c (copie de travail) @@ -757,7 +757,12 @@ // Allocate the TEB // Status = MiCreatePebOrTeb(Process, sizeof(TEB), (PULONG_PTR)&Teb); - ASSERT(NT_SUCCESS(Status)); + if (!NT_SUCCESS(Status)) + { + /* Cleanup and exit */ + KeDetachProcess(); + return Status; + } // // Use SEH in case we can't load the TEB Index: sdk/lib/rtl/thread.c =================================================================== --- sdk/lib/rtl/thread.c (révision 71401) +++ sdk/lib/rtl/thread.c (copie de travail) @@ -20,7 +20,7 @@ NTSTATUS NTAPI -RtlpCreateUserStack(IN HANDLE hProcess, +RtlpCreateUserStack(IN HANDLE ProcessHandle, IN SIZE_T StackReserve OPTIONAL, IN SIZE_T StackCommit OPTIONAL, IN ULONG StackZeroBits OPTIONAL, @@ -29,10 +29,10 @@ NTSTATUS Status; SYSTEM_BASIC_INFORMATION SystemBasicInfo; PIMAGE_NT_HEADERS Headers; - ULONG_PTR Stack = 0; - BOOLEAN UseGuard = FALSE; + ULONG_PTR Stack; + BOOLEAN UseGuard; ULONG Dummy; - SIZE_T GuardPageSize; + SIZE_T MinimumStackCommit, GuardPageSize; /* Get some memory information */ Status = ZwQuerySystemInformation(SystemBasicInformation, @@ -42,7 +42,7 @@ if (!NT_SUCCESS(Status)) return Status; /* Use the Image Settings if we are dealing with the current Process */ - if (hProcess == NtCurrentProcess()) + if (ProcessHandle == NtCurrentProcess()) { /* Get the Image Headers */ Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); @@ -49,10 +49,16 @@ if (!Headers) return STATUS_INVALID_IMAGE_FORMAT; /* If we didn't get the parameters, find them ourselves */ - if (!StackReserve) StackReserve = Headers->OptionalHeader. - SizeOfStackReserve; - if (!StackCommit) StackCommit = Headers->OptionalHeader. - SizeOfStackCommit; + if (StackReserve == 0) + StackReserve = Headers->OptionalHeader.SizeOfStackReserve; + if (StackCommit == 0) + StackCommit = Headers->OptionalHeader.SizeOfStackCommit; + + MinimumStackCommit = NtCurrentPeb()->MinimumStackCommit; + if ((MinimumStackCommit) && (StackCommit < MinimumStackCommit)) + { + StackCommit = MinimumStackCommit; + } } else { @@ -61,7 +67,7 @@ if (!StackCommit) StackCommit = SystemBasicInfo.PageSize; } - /* Check if the commit is higher than the reserve*/ + /* Check if the commit is higher than the reserve */ if (StackCommit >= StackReserve) { /* Grow the reserve beyond the commit, up to 1MB alignment */ @@ -69,11 +75,12 @@ } /* Align everything to Page Size */ + StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize); StackReserve = ROUND_UP(StackReserve, SystemBasicInfo.AllocationGranularity); - StackCommit = ROUND_UP(StackCommit, SystemBasicInfo.PageSize); /* Reserve memory for the stack */ - Status = ZwAllocateVirtualMemory(hProcess, + Stack = 0; + Status = ZwAllocateVirtualMemory(ProcessHandle, (PVOID*)&Stack, StackZeroBits, &StackReserve, @@ -82,41 +89,48 @@ if (!NT_SUCCESS(Status)) return Status; /* Now set up some basic Initial TEB Parameters */ + InitialTeb->AllocatedStackBase = (PVOID)Stack; + InitialTeb->StackBase = (PVOID)(Stack + StackReserve); InitialTeb->PreviousStackBase = NULL; InitialTeb->PreviousStackLimit = NULL; - InitialTeb->AllocatedStackBase = (PVOID)Stack; - InitialTeb->StackBase = (PVOID)(Stack + StackReserve); - /* Update the Stack Position */ + /* Update the stack position */ Stack += StackReserve - StackCommit; - /* Check if we will need a guard page */ - if (StackReserve > StackCommit) + /* Check if we can add a guard page */ + if (StackReserve >= StackCommit + SystemBasicInfo.PageSize) { - /* Remove a page to set as guard page */ Stack -= SystemBasicInfo.PageSize; StackCommit += SystemBasicInfo.PageSize; UseGuard = TRUE; } + else + { + UseGuard = FALSE; + } /* Allocate memory for the stack */ - Status = ZwAllocateVirtualMemory(hProcess, + Status = ZwAllocateVirtualMemory(ProcessHandle, (PVOID*)&Stack, 0, &StackCommit, MEM_COMMIT, PAGE_READWRITE); - if (!NT_SUCCESS(Status)) return Status; + if (!NT_SUCCESS(Status)) + { + GuardPageSize = 0; + ZwFreeVirtualMemory(ProcessHandle, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE); + return Status; + } /* Now set the current Stack Limit */ InitialTeb->StackLimit = (PVOID)Stack; - /* Create a guard page */ + /* Create a guard page if needed */ if (UseGuard) { - /* Attempt maximum space possible */ GuardPageSize = SystemBasicInfo.PageSize; - Status = ZwProtectVirtualMemory(hProcess, + Status = ZwProtectVirtualMemory(ProcessHandle, (PVOID*)&Stack, &GuardPageSize, PAGE_GUARD | PAGE_READWRITE, @@ -132,23 +146,21 @@ return STATUS_SUCCESS; } -NTSTATUS +VOID NTAPI -RtlpFreeUserStack(IN HANDLE Process, +RtlpFreeUserStack(IN HANDLE ProcessHandle, IN PINITIAL_TEB InitialTeb) { SIZE_T Dummy = 0; - NTSTATUS Status; /* Free the Stack */ - Status = ZwFreeVirtualMemory(Process, - &InitialTeb->AllocatedStackBase, - &Dummy, - MEM_RELEASE); + ZwFreeVirtualMemory(ProcessHandle, + &InitialTeb->AllocatedStackBase, + &Dummy, + MEM_RELEASE); /* Clear the initial TEB */ - RtlZeroMemory(InitialTeb, sizeof(INITIAL_TEB)); - return Status; + RtlZeroMemory(InitialTeb, sizeof(*InitialTeb)); } /* FUNCTIONS ***************************************************************/