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.

207 lines
5.7 KiB

  1. /***
  2. *dllcrt0.c - C runtime initialization routine for a DLL with linked-in C R-T
  3. *
  4. * Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * This the startup routine for a DLL which is linked with its own
  8. * C run-time code. It is similar to the routine _mainCRTStartup()
  9. * in the file CRT0.C, except that there is no main() in a DLL.
  10. *
  11. *Revision History:
  12. * 05-04-92 SKS Based on CRT0.C (start-up code for EXE's)
  13. * 08-26-92 SKS Add _osver, _winver, _winmajor, _winminor
  14. * 09-16-92 SKS This module used to be enabled only in LIBCMT.LIB,
  15. * but it is now enabled for LIBC.LIB as well!
  16. * 09-29-92 SKS _CRT_INIT needs to be WINAPI, not cdecl
  17. * 10-16-92 SKS Call _heap_init before _mtinit (fix copied from CRT0.C)
  18. * 10-24-92 SKS Call to _mtdeletelocks() must be under #ifdef MTHREAD!
  19. * 04-16-93 SKS Call _mtterm instead of _mtdeletelocks on
  20. * PROCESS_DETACH to do all multi-thread cleanup
  21. * It will call _mtdeletelocks and free up the TLS index.
  22. * 04-27-93 GJF Removed support for _RT_STACK, _RT_INTDIV,
  23. * _RT_INVALDISP and _RT_NONCONT.
  24. * 05-11-93 SKS Add _DllMainCRTStartup to co-exist with _CRT_INIT
  25. * _mtinit now returns 0 or 1, no longer calls _amsg_exit
  26. * Delete obsolete variable _atopsp
  27. * 06-03-93 GJF Added __proc_attached flag.
  28. * 06-08-93 SKS Clean up failure handling in _CRT_INIT
  29. * 12-13-93 SKS Free up per-thread CRT data on DLL_THREAD_DETACH
  30. * using a call to _freeptd() in _CRT_INIT()
  31. *
  32. *******************************************************************************/
  33. #include <windows.h>
  34. #include <cruntime.h>
  35. #include <internal.h>
  36. #include <process.h>
  37. /*
  38. * flag set iff _CRTDLL_INIT was called with DLL_PROCESS_ATTACH
  39. */
  40. static int __proc_attached = 0;
  41. #pragma data_seg()
  42. /*
  43. * User routine DllMain is called on all notifications
  44. */
  45. extern BOOL WINAPI DllMain(
  46. HANDLE hDllHandle,
  47. DWORD dwReason,
  48. LPVOID lpreserved
  49. ) ;
  50. /***
  51. *BOOL WINAPI _CRT_INIT(hDllHandle, dwReason, lpreserved) - C Run-Time
  52. * initialization for a DLL linked with a C run-time library.
  53. *
  54. *Purpose:
  55. * This routine does the C run-time initialization.
  56. * For the multi-threaded run-time library, it also cleans up the
  57. * multi-threading locks on DLL termination.
  58. *
  59. *Entry:
  60. *
  61. *Exit:
  62. *
  63. *NOTES:
  64. * This routine should either be the entry-point for the DLL
  65. * or else be called by the entry-point routine for the DLL.
  66. *
  67. *******************************************************************************/
  68. BOOL WINAPI _CRT_INIT(
  69. HANDLE hDllHandle,
  70. DWORD dwReason,
  71. LPVOID lpreserved
  72. )
  73. {
  74. /*
  75. * Start-up code only gets executed when the process is initialized
  76. */
  77. if ( dwReason != DLL_PROCESS_ATTACH ) {
  78. if ( dwReason == DLL_PROCESS_DETACH ) {
  79. /*
  80. * make sure there has been prior process attach
  81. * notification!
  82. */
  83. if ( __proc_attached > 0 ) {
  84. __proc_attached--;
  85. if ( _C_Termination_Done == FALSE )
  86. /* do exit() time clean-up */
  87. _cexit();
  88. /*
  89. * Any basic clean-up code that goes here must be duplicated
  90. * below in _DllMainCRTStartup for the case where the user's
  91. * DllMain() routine fails on a Process Attach notification.
  92. * This does not include calling user C++ destructors, etc.
  93. */
  94. /* delete MT locks, free TLS index, etc. */
  95. _mtterm();
  96. }
  97. else
  98. /* no prior process attach, just return */
  99. return FALSE;
  100. }
  101. return TRUE;
  102. }
  103. /*
  104. * increment flag to indicate process attach notification has been
  105. * received
  106. */
  107. __proc_attached++;
  108. if(!_mtinit()) /* initialize multi-thread */
  109. return FALSE; /* fail to load DLL */
  110. _cinit(); /* do C data initialize */
  111. return TRUE; /* initialization succeeded */
  112. }
  113. /***
  114. *BOOL WINAPI _DllMainCRTStartup(hDllHandle, dwReason, lpreserved) -
  115. * C Run-Time initialization for a DLL linked with a C run-time library.
  116. *
  117. *Purpose:
  118. * This routine does the C run-time initialization or termination
  119. * and then calls the user code notification handler "DllMain".
  120. * For the multi-threaded run-time library, it also cleans up the
  121. * multi-threading locks on DLL termination.
  122. *
  123. *Entry:
  124. *
  125. *Exit:
  126. *
  127. *NOTES:
  128. * This routine should be the entry point for the DLL if
  129. * the user is not supplying one and calling _CRT_INIT.
  130. *
  131. *******************************************************************************/
  132. BOOL WINAPI _DllMainCRTStartup(
  133. HANDLE hDllHandle,
  134. DWORD dwReason,
  135. LPVOID lpreserved
  136. )
  137. {
  138. BOOL retcode = TRUE;
  139. /*
  140. * If this is a process attach notification, increment the process
  141. * attached flag. If this is a process detach notification, check
  142. * that there has been a prior process attach notification.
  143. */
  144. if ( dwReason == DLL_PROCESS_ATTACH ) {
  145. __proc_attached++;
  146. } else if ( dwReason == DLL_PROCESS_DETACH ) {
  147. if ( __proc_attached > 0 )
  148. __proc_attached--;
  149. else
  150. /*
  151. * no prior process attach notification. just return
  152. * without doing anything.
  153. */
  154. return FALSE;
  155. }
  156. if ( dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH )
  157. retcode = _CRT_INIT(hDllHandle, dwReason, lpreserved);
  158. if ( retcode )
  159. retcode = DllMain(hDllHandle, dwReason, lpreserved);
  160. /*
  161. * If _CRT_INIT successfully handles a Process Attach notification
  162. * but the user's DllMain routine returns failure, we need to do
  163. * clean-up of the C run-time similar to what _CRT_INIT does on a
  164. * Process Detach Notification.
  165. */
  166. if ( retcode == FALSE && dwReason == DLL_PROCESS_ATTACH )
  167. {
  168. /* Failure to attach DLL - must clean up C run-time */
  169. _mtterm();
  170. }
  171. if ( dwReason == DLL_PROCESS_DETACH || dwReason == DLL_THREAD_DETACH )
  172. {
  173. if ( _CRT_INIT(hDllHandle, dwReason, lpreserved) == FALSE )
  174. retcode = FALSE ;
  175. }
  176. return retcode ;
  177. }