resetstk.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:3k
源码类别:

模拟服务器

开发平台:

C/C++

  1. /***
  2. *resetstk.c - Recover from Stack overflow.
  3. *
  4. *       Copyright (c) 1989-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. *       Defines the _resetstkoflw() function.
  8. *
  9. *******************************************************************************/
  10. #if defined(_MSC_VER) & _MSC_VER < 1300
  11. #include <stdlib.h>
  12. #include <malloc.h>
  13. #include <windows.h>
  14. #define MIN_STACK_REQ_WIN9X 0x11000
  15. #define MIN_STACK_REQ_WINNT 0x2000
  16. #ifdef _WIN64
  17. typedef unsigned __int64 REGEX_DWORD_PTR;
  18. #else
  19. typedef unsigned __int32 REGEX_DWORD_PTR;
  20. #endif
  21. struct osplatform_getter
  22. {
  23.     int m_osplatform;
  24.     osplatform_getter() : m_osplatform( 0 )
  25.     {
  26.         OSVERSIONINFOA osvi;
  27.         osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  28.         if( GetVersionExA( & osvi ) )
  29.             m_osplatform = osvi.dwPlatformId;
  30.     }
  31. };
  32. inline int get_osplatform()
  33. {
  34.     static osplatform_getter const s_osplatform_getter;
  35.     return s_osplatform_getter.m_osplatform;
  36. };
  37. /***
  38. * void _resetstkoflw(void) - Recovers from Stack Overflow
  39. *
  40. * Purpose:
  41. *       Sets the guard page to its position before the stack overflow.
  42. *
  43. * Exit:
  44. *       Returns nonzero on success, zero on failure
  45. *
  46. *******************************************************************************/
  47. extern "C" int __cdecl _resetstkoflw(void)
  48. {
  49.     LPBYTE pStack, pGuard, pStackBase, pMinGuard;
  50.     MEMORY_BASIC_INFORMATION mbi;
  51.     SYSTEM_INFO si;
  52.     DWORD PageSize;
  53.     DWORD flNewProtect;
  54.     DWORD flOldProtect;
  55.     // Use _alloca() to get the current stack pointer
  56.     pStack = static_cast<LPBYTE>( _alloca(1) );
  57.     // Find the base of the stack.
  58.     if (VirtualQuery(pStack, &mbi, sizeof mbi) == 0)
  59.         return 0;
  60.     pStackBase = static_cast<LPBYTE>( mbi.AllocationBase );
  61.     // Find the page just below where the stack pointer currently points.
  62.     // This is the new guard page.
  63.     GetSystemInfo(&si);
  64.     PageSize = si.dwPageSize;
  65.     pGuard = (LPBYTE) (((REGEX_DWORD_PTR)pStack & ~(REGEX_DWORD_PTR)(PageSize - 1))
  66.                        - PageSize);
  67.     // If the potential guard page is too close to the start of the stack
  68.     // region, abandon the reset effort for lack of space.  Win9x has a
  69.     // larger reserved stack requirement.
  70.     pMinGuard = pStackBase + ((get_osplatform() == VER_PLATFORM_WIN32_WINDOWS)
  71.                               ? MIN_STACK_REQ_WIN9X
  72.                               : MIN_STACK_REQ_WINNT);
  73.     if (pGuard < pMinGuard)
  74.         return 0;
  75.     // On a non-Win9x system, release the stack region below the new guard
  76.     // page.  This can't be done for Win9x because of OS limitations.
  77.     if (get_osplatform() != VER_PLATFORM_WIN32_WINDOWS) {
  78.         if (pGuard > pStackBase)
  79.             VirtualFree(pStackBase, pGuard - pStackBase, MEM_DECOMMIT);
  80.         VirtualAlloc(pGuard, PageSize, MEM_COMMIT, PAGE_READWRITE);
  81.     }
  82.     // Enable the new guard page.
  83.     flNewProtect = get_osplatform() == VER_PLATFORM_WIN32_WINDOWS
  84.                    ? PAGE_NOACCESS
  85.                    : PAGE_READWRITE | PAGE_GUARD;
  86.     return VirtualProtect(pGuard, PageSize, flNewProtect, &flOldProtect);
  87. }
  88. #endif