Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

224 lines
6.1 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992.
  5. //
  6. // File: dllentry.c
  7. //
  8. // Contents: Dll Entry point code. Calls the appropriate run-time
  9. // init/term code and then defers to LibMain for further
  10. // processing.
  11. //
  12. // Classes: <none>
  13. //
  14. // Functions: DllEntryPoint - Called by loader
  15. //
  16. // History: 10-May-92 BryanT Created
  17. // 22-Jul-92 BryanT Switch to calling _cexit/_mtdeletelocks
  18. // on cleanup.
  19. // 06-Oct-92 BryanT Call RegisterWithCommnot on entry
  20. // and DeRegisterWithCommnot on exit.
  21. // This should fix the heap dump code.
  22. // 12-23-93 TerryRu Replace LockExit, and UnLockExit
  23. // with critial sections for Daytona.
  24. // 12-28-93 TerryRu Place Regiter/DeRegister WinCommnot apis
  25. // Inside WIN32 endifs for Daytona builds.
  26. //
  27. //--------------------------------------------------------------------
  28. #include <windows.h>
  29. //#include <win4p.h>
  30. #include <process.h>
  31. #include <string.h>
  32. #include <stdlib.h>
  33. #include <malloc.h>
  34. BOOL WINAPI _CRT_INIT (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
  35. BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
  36. BOOL __cdecl LibMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
  37. void __cdecl _mtdeletelocks(void);
  38. DWORD WINAPI
  39. GetModuleFileNameCtC(
  40. HMODULE hModule,
  41. LPWSTR pwszFilename,
  42. DWORD nSize);
  43. #ifdef USE_CRTDLL
  44. #define _RT_ONEXIT 24
  45. /*
  46. * routine in DLL to do initialization (in this case, C++ constructors)
  47. */
  48. typedef void (__cdecl *PF)(void);
  49. /*
  50. * pointers to initialization sections
  51. */
  52. PF *__onexitbegin;
  53. PF *__onexitend;
  54. /*
  55. * Define increment (in entries) for growing the _onexit/atexit table
  56. */
  57. #define ONEXITTBLINCR 4
  58. static void __cdecl _onexitinit ( void );
  59. extern void __cdecl _initterm(PF *, PF *);
  60. extern void __cdecl _amsg_exit(int);
  61. extern void __cdecl _lockexit(void);
  62. extern void __cdecl _unlockexit(void);
  63. #endif
  64. // BUGBUG: defined in $(COMMON)\src\except\memory.cxx
  65. void RegisterWithCommnot(void);
  66. void DeRegisterWithCommnot(void);
  67. CRITICAL_SECTION __gCriticalSection;
  68. BOOL __stdcall DllEntryPoint (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  69. {
  70. BOOL fRc = FALSE;
  71. switch (dwReason)
  72. {
  73. case DLL_PROCESS_ATTACH:
  74. #ifdef USE_CRTDLL
  75. //
  76. // Assumption: The run-time is sufficiantly up and running to
  77. // support malloc that _onexitinit will perform.
  78. //
  79. _onexitinit();
  80. InitializeCriticalSection(&__gCriticalSection );
  81. #endif
  82. _CRT_INIT(hDll, dwReason, lpReserved);
  83. #if WIN32==300
  84. RegisterWithCommnot();
  85. #endif
  86. case DLL_THREAD_ATTACH:
  87. case DLL_THREAD_DETACH:
  88. fRc = LibMain (hDll, dwReason, lpReserved);
  89. break;
  90. case DLL_PROCESS_DETACH:
  91. fRc = LibMain (hDll, dwReason, lpReserved);
  92. //
  93. // BUGBUG: What a hack. In order to make sure we don't kill
  94. // commnot's objects while still in use (_cexit will do
  95. // the atexit list processing where the compiler stores
  96. // pointers to all the static destructors), test the
  97. // module name. If not commnot, call _cexit().
  98. // DeRegisterWithCommnot will call it for commnot...
  99. //
  100. #ifdef USE_CRTDLL
  101. {
  102. wchar_t pwszModName[512];
  103. GetModuleFileName(hDll, pwszModName, 512);
  104. if (!wcswcs(wcsupr(pwszModName), L"COMMNOT"))
  105. if (__onexitbegin)
  106. _initterm(__onexitbegin, __onexitend);
  107. }
  108. DeleteCriticalSection( & __gCriticalSection );
  109. #else
  110. {
  111. wchar_t pwszModName[512];
  112. GetModuleFileName(hDll, pwszModName, 512);
  113. if (!wcswcs(wcsupr(pwszModName), L"COMMNOT"))
  114. _cexit();
  115. }
  116. _mtdeletelocks();
  117. #endif
  118. #if WIN32==300
  119. DeRegisterWithCommnot();
  120. #endif
  121. break;
  122. }
  123. return(fRc);
  124. }
  125. #ifdef USE_CRTDLL
  126. _onexit_t __cdecl _onexit ( _onexit_t func )
  127. {
  128. PF *p;
  129. EnterCriticalSection( &__gCriticalSection ); /* lock the exit code */
  130. /*
  131. * First, make sure the table has room for a new entry
  132. */
  133. if ( _msize(__onexitbegin) <= (unsigned)((char *)__onexitend -
  134. (char *)__onexitbegin) ) {
  135. /*
  136. * not enough room, try to grow the table
  137. */
  138. if ( (p = (PF *) realloc(__onexitbegin, _msize(__onexitbegin) +
  139. ONEXITTBLINCR * sizeof(PF))) == NULL ) {
  140. /*
  141. * didn't work. don't do anything rash, just fail
  142. */
  143. LeaveCriticalSection(&__gCriticalSection );
  144. return NULL;
  145. }
  146. /*
  147. * update __onexitend and __onexitbegin
  148. */
  149. __onexitend = p + (__onexitend - __onexitbegin);
  150. __onexitbegin = p;
  151. }
  152. /*
  153. * Put the new entry into the table and update the end-of-table
  154. * pointer.
  155. */
  156. *(__onexitend++) = (PF)func;
  157. LeaveCriticalSection( &__gCriticalSection );
  158. return func;
  159. }
  160. int __cdecl atexit ( PF func )
  161. {
  162. return (_onexit((_onexit_t)func) == NULL) ? -1 : 0;
  163. }
  164. static void __cdecl _onexitinit ( void )
  165. {
  166. if ( (__onexitbegin = (PF *)malloc(32 * sizeof(PF))) == NULL )
  167. /*
  168. * cannot allocate minimal required size. generate
  169. * fatal runtime error.
  170. */
  171. _amsg_exit(_RT_ONEXIT);
  172. *(__onexitbegin) = (PF) NULL;
  173. __onexitend = __onexitbegin;
  174. }
  175. #endif // USE_CRTDLL