ReactOS 0.4.16-dev-732-g2d1144a
resetstk.cpp
Go to the documentation of this file.
1/***
2*resetstk.c - Recover from Stack overflow.
3*
4* Copyright (c) Microsoft Corporation. All rights reserved.
5*
6*Purpose:
7* Defines the _resetstkoflw() function.
8*
9*******************************************************************************/
10
11#include <corecrt_internal.h>
12#include <malloc.h>
13
14#define MIN_STACK_REQ_WINNT 2
15
16
17
18/***
19* void _resetstkoflw(void) - Recovers from Stack Overflow
20*
21* Purpose:
22* Sets the guard page to its position before the stack overflow.
23*
24* Exit:
25* Returns nonzero on success, zero on failure
26*
27*******************************************************************************/
28
29extern "C" int __cdecl _resetstkoflw()
30{
31 LPBYTE pStack, pStackBase, pMaxGuard, pMinGuard;
33 SYSTEM_INFO si;
34 DWORD PageSize;
36 DWORD flOldProtect;
37 ULONG StackSizeInBytes;
38
39 // Use _alloca() to get the current stack pointer
40#pragma warning(push)
41#pragma warning(disable:6255)
42 // prefast(6255): This alloca is safe and we do not want a __try here
43 pStack = (LPBYTE)_alloca(1);
44#pragma warning(pop)
45
46 // Find the base of the stack.
47
48 if (VirtualQuery(pStack, &mbi, sizeof mbi) == 0) {
49 return 0;
50 }
51
52 pStackBase = (LPBYTE)mbi.AllocationBase;
53
54 GetSystemInfo(&si);
55 PageSize = si.dwPageSize;
56 RegionSize = 0;
57 StackSizeInBytes = 0; // Indicate just querying
58 if (__acrt_SetThreadStackGuarantee(&StackSizeInBytes) && StackSizeInBytes > 0) {
59 RegionSize = StackSizeInBytes;
60 }
61
62#pragma warning(push)
63#pragma warning(disable:6255)
64 // Silence prefast about overflow/underflow
65 RegionSize = (RegionSize + PageSize - 1) & ~(PageSize - 1);
66#pragma warning(pop)
67
68 //
69 // If there is a stack guarantee (RegionSize nonzero), then increase
70 // our guard page size by 1 so that even a subsequent fault that occurs
71 // midway (instead of at the beginning) through the first guard page
72 // will have the extra page to preserve the guarantee.
73 //
74
75 if (RegionSize != 0) {
76 RegionSize += PageSize;
77 }
78
79 if (RegionSize < MIN_STACK_REQ_WINNT * PageSize) {
81 }
82
83 //
84 // Find the page(s) just below where the stack pointer currently points.
85 // This is the highest potential guard page.
86 //
87
88 pMaxGuard = (LPBYTE) (((DWORD_PTR)pStack & ~(DWORD_PTR)(PageSize - 1))
89 - RegionSize);
90
91 //
92 // If the potential guard page is too close to the start of the stack
93 // region, abandon the reset effort for lack of space. Win9x has a
94 // larger reserved stack requirement.
95 //
96
97 pMinGuard = pStackBase + PageSize;
98
99 if (pMaxGuard < pMinGuard) {
100 return 0;
101 }
102
103 // Set the new guard page just below the current stack page.
104
105 if (VirtualAlloc(pMaxGuard, RegionSize, MEM_COMMIT, PAGE_READWRITE) == nullptr ||
106 VirtualProtect(pMaxGuard, RegionSize, PAGE_READWRITE | PAGE_GUARD, &flOldProtect) == 0) {
107 return 0;
108 }
109
110 return 1;
111}
#define __cdecl
Definition: accygwin.h:79
BOOL WINAPI __acrt_SetThreadStackGuarantee(_Inout_ PULONG stack_size_in_bytes)
VOID WINAPI GetSystemInfo(IN LPSYSTEM_INFO lpSystemInfo)
Definition: sysinfo.c:143
unsigned long DWORD
Definition: ntddk_ex.h:95
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define MEM_COMMIT
Definition: nt_native.h:1313
#define PAGE_GUARD
Definition: nt_native.h:1310
#define MIN_STACK_REQ_WINNT
Definition: resetstk.cpp:14
int __cdecl _resetstkoflw()
Definition: resetstk.cpp:29
CardRegion * pStack[NUM_STACKS]
Definition: spigame.cpp:21
DWORD dwPageSize
Definition: winbase.h:1198
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualProtect(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flNewProtect, OUT PDWORD lpflOldProtect)
Definition: virtmem.c:135
SIZE_T NTAPI VirtualQuery(IN LPCVOID lpAddress, OUT PMEMORY_BASIC_INFORMATION lpBuffer, IN SIZE_T dwLength)
Definition: virtmem.c:211