| OLD | NEW |
| (Empty) |
| 1 //========================================== | |
| 2 // LIBCTINY - Matt Pietrek 2001 | |
| 3 // MSDN Magazine, January 2001 | |
| 4 // ========================================== | |
| 5 | |
| 6 #include "libctiny.h" | |
| 7 #include <windows.h> | |
| 8 #include <malloc.h> | |
| 9 #include "initterm.h" | |
| 10 | |
| 11 #pragma data_seg(".CRT$XCA") | |
| 12 _PVFV __xc_a[] = { NULL }; | |
| 13 #pragma data_seg(".CRT$XCZ") | |
| 14 _PVFV __xc_z[] = { NULL }; | |
| 15 | |
| 16 /* | |
| 17 #pragma data_seg(".CRT$XIA") | |
| 18 _PVFV __xi_a[] = { NULL }; | |
| 19 #pragma data_seg(".CRT$XIZ") | |
| 20 _PVFV __xi_z[] = { NULL }; | |
| 21 | |
| 22 #pragma data_seg(".CRT$XTA") | |
| 23 _PVFV __xt_a[] = { NULL }; | |
| 24 #pragma data_seg(".CRT$XTZ") | |
| 25 _PVFV __xt_z[] = { NULL }; | |
| 26 | |
| 27 #pragma data_seg(".CRT$XPA") | |
| 28 _PVFV __xp_a[] = { NULL }; | |
| 29 #pragma data_seg(".CRT$XPZ") | |
| 30 _PVFV __xp_z[] = { NULL }; | |
| 31 */ | |
| 32 | |
| 33 #pragma data_seg() /* reset */ | |
| 34 | |
| 35 #pragma comment(linker, "/merge:.CRT=.data") | |
| 36 | |
| 37 typedef void (__cdecl *_PVFV)(); | |
| 38 | |
| 39 void __cdecl _initterm( | |
| 40 _PVFV * pfbegin, | |
| 41 _PVFV * pfend | |
| 42 ) { | |
| 43 // walk the table of function pointers from the bottom up, until | |
| 44 // the end is encountered. Do not skip the first entry. The initial | |
| 45 // value of pfbegin points to the first valid entry. Do not try to | |
| 46 // execute what pfend points to. Only entries before pfend are valid. | |
| 47 while (pfbegin < pfend) | |
| 48 { | |
| 49 // if current table entry is non-NULL, call thru it. | |
| 50 if (*pfbegin != NULL) | |
| 51 (**pfbegin)(); | |
| 52 ++pfbegin; | |
| 53 } | |
| 54 } | |
| 55 | |
| 56 static _PVFV * pf_atexitlist = 0; | |
| 57 static unsigned max_atexitlist_entries = 0; | |
| 58 static unsigned cur_atexitlist_entries = 0; | |
| 59 | |
| 60 void __cdecl _atexit_init() { | |
| 61 max_atexitlist_entries = 32; | |
| 62 pf_atexitlist = (_PVFV *)calloc( max_atexitlist_entries, | |
| 63 sizeof(_PVFV*) ); | |
| 64 } | |
| 65 | |
| 66 int __cdecl atexit(_PVFV func ) { | |
| 67 if (cur_atexitlist_entries < max_atexitlist_entries) | |
| 68 { | |
| 69 pf_atexitlist[cur_atexitlist_entries++] = func; | |
| 70 return 0; | |
| 71 } | |
| 72 | |
| 73 return -1; | |
| 74 } | |
| 75 | |
| 76 void __cdecl _DoExit() { | |
| 77 if (cur_atexitlist_entries) | |
| 78 { | |
| 79 _initterm( pf_atexitlist, | |
| 80 // Use ptr math to find the end of the array | |
| 81 pf_atexitlist + cur_atexitlist_entries ); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 // ----------------------------------------------------- | |
| 86 | |
| 87 /* | |
| 88 static HANDLE g_hProcessHeap = NULL; | |
| 89 | |
| 90 extern "C" _PVFV* __onexitbegin = NULL; | |
| 91 extern "C" _PVFV* __onexitend = NULL; | |
| 92 | |
| 93 extern "C" _PVFV __xi_a[], __xi_z[]; // C initializers | |
| 94 extern "C" _PVFV __xc_a[], __xc_z[]; // C++ initializers | |
| 95 extern "C" _PVFV __xp_a[], __xp_z[]; // C pre-terminators | |
| 96 extern "C" _PVFV __xt_a[], __xt_z[]; // C terminators | |
| 97 | |
| 98 // Critical section to protect initialization/exit code | |
| 99 static CRITICAL_SECTION g_csInit; | |
| 100 | |
| 101 extern "C" void DoInitialization() { | |
| 102 _PVFV* pf; | |
| 103 | |
| 104 // memset(&osi, 0, sizeof(OSVERSIONINFO)); | |
| 105 // osi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); | |
| 106 // GetVersionEx(&osi); | |
| 107 // _osplatform = osi.dwPlatformId; | |
| 108 | |
| 109 InitializeCriticalSection( &g_csInit ); | |
| 110 | |
| 111 EnterCriticalSection( &g_csInit ); | |
| 112 | |
| 113 __try | |
| 114 { | |
| 115 g_hProcessHeap = GetProcessHeap(); | |
| 116 | |
| 117 // Call initialization routines (contructors for globals, etc.) | |
| 118 for (pf = __xi_a; pf < __xi_z; pf++) | |
| 119 { | |
| 120 if (*pf != NULL) | |
| 121 { | |
| 122 (**pf)(); | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 for (pf = __xc_a; pf < __xc_z; pf++) | |
| 127 { | |
| 128 if (*pf != NULL) | |
| 129 { | |
| 130 (**pf)(); | |
| 131 } | |
| 132 } | |
| 133 } | |
| 134 __finally | |
| 135 { | |
| 136 LeaveCriticalSection(&g_csInit); | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 extern "C" void DoCleanup() { | |
| 141 _PVFV* pf; | |
| 142 | |
| 143 EnterCriticalSection(&g_csInit); // Protect access to the atexit table | |
| 144 | |
| 145 __try | |
| 146 { | |
| 147 // Call routines registered with atexit() from most recently registered | |
| 148 // to least recently registered | |
| 149 if (__onexitbegin != NULL) | |
| 150 { | |
| 151 for (pf = __onexitend-1; pf >= __onexitbegin; pf--) | |
| 152 { | |
| 153 if (*pf != NULL) | |
| 154 (**pf)(); | |
| 155 } | |
| 156 } | |
| 157 | |
| 158 free(__onexitbegin); | |
| 159 __onexitbegin = NULL; | |
| 160 __onexitend = NULL; | |
| 161 | |
| 162 for (pf = __xp_a; pf < __xp_z; pf++) | |
| 163 { | |
| 164 if (*pf != NULL) | |
| 165 { | |
| 166 (**pf)(); | |
| 167 } | |
| 168 } | |
| 169 | |
| 170 for (pf = __xt_a; pf < __xt_z; pf++) | |
| 171 { | |
| 172 if (*pf != NULL) | |
| 173 { | |
| 174 (**pf)(); | |
| 175 } | |
| 176 } | |
| 177 } | |
| 178 __finally | |
| 179 { | |
| 180 LeaveCriticalSection(&g_csInit); | |
| 181 DeleteCriticalSection(&g_csInit); | |
| 182 } | |
| 183 } | |
| 184 | |
| 185 int __cdecl atexit(_PVFV pf) { | |
| 186 size_t nCurrentSize; | |
| 187 int nRet = 0; | |
| 188 | |
| 189 EnterCriticalSection(&g_csInit); | |
| 190 | |
| 191 __try | |
| 192 { | |
| 193 if (__onexitbegin == NULL) | |
| 194 { | |
| 195 __onexitbegin = (_PVFV*)malloc(16*sizeof(_PVFV)); | |
| 196 if (__onexitbegin == NULL) | |
| 197 { | |
| 198 LeaveCriticalSection(&g_csInit); | |
| 199 return(-1); | |
| 200 } | |
| 201 __onexitend = __onexitbegin; | |
| 202 } | |
| 203 | |
| 204 nCurrentSize = _msize(__onexitbegin); | |
| 205 if ((nCurrentSize+sizeof(_PVFV)) < ULONG(((const byte*)__onexitend- | |
| 206 (const byte*)__onexitbegin))) | |
| 207 { | |
| 208 _PVFV* pNew; | |
| 209 | |
| 210 pNew = (_PVFV*)realloc(__onexitbegin, 2*nCurrentSize); | |
| 211 if (pNew == NULL) | |
| 212 { | |
| 213 LeaveCriticalSection(&g_csInit); | |
| 214 return(-1); | |
| 215 } | |
| 216 } | |
| 217 | |
| 218 *__onexitend = pf; | |
| 219 __onexitend++; | |
| 220 } | |
| 221 __except (1) | |
| 222 { | |
| 223 nRet = -1; | |
| 224 } | |
| 225 | |
| 226 LeaveCriticalSection(&g_csInit); | |
| 227 | |
| 228 return(nRet); | |
| 229 } | |
| 230 */ | |
| OLD | NEW |