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.

118 lines
4.1 KiB

  1. /***
  2. *atonexit.c - _onexit/atexit for using the MSVCRT* model of C run-time
  3. *
  4. * Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * atexit and _onexit are handled differently for EXE's and DLL's linked
  8. * with MSVCRT.LIB to call MSVCRT*.DLL. Specifically, the _onexit/atexit
  9. * list for DLL's must be maintained on a per-module basis and must be
  10. * processed at DLL process detach . For EXE's the atexit/_onexit list
  11. * should be maintained by MSVCRT*.DLL and processed at process exit.
  12. *
  13. *Revision History:
  14. * 05-24-93 SKS Initial version
  15. * 10-19-93 CFW MIPS support for _imp__xxx.
  16. * 10-26-93 GJF Replaced PF with _PVFV (defined in internal.h).
  17. * 04-12-94 GJF Build with _DLL defined, not CRTDLL.
  18. * 05-19-94 GJF For Win32s serialize calls to __dllonexit by multiple
  19. * client processes.
  20. * 05-26-94 GJF Replaced compile-time conditioning on DLL_FOR_WIN32S
  21. * with a runtime test for Win32s.
  22. * 06-06-94 GJF In Win32s, onexitflag wasn't getting decremented.
  23. * 12-13-94 GJF Made Win32s support conditional on _M_IX86.
  24. * 02-22-95 JWM Spliced in PMAC code.
  25. * 11-15-95 BWT Win32s isn't interesting for the NT build
  26. * 06-27-96 GJF Purged Win32s support (removed __win32sflag). Replaced
  27. * defined(_WIN32) with !defined(_MAC).
  28. * 08-01-96 RDK For PMAC, make _onexit parallel x86 functionality.
  29. * 05-17-99 PML Remove all Macintosh support.
  30. * 03-27-01 PML Remove unneeded proto for _initterm.
  31. *
  32. *******************************************************************************/
  33. /*
  34. * SPECIAL BUILD MACRO! Note that atonexit.c is linked in with the client's
  35. * code. It does not go into crtdll.dll! Therefore, it must be built under
  36. * the _DLL switch (like user code) and CRTDLL must be undefined.
  37. */
  38. #undef CRTDLL
  39. #ifndef _DLL
  40. #define _DLL
  41. #endif
  42. #include <cruntime.h>
  43. #include <oscalls.h>
  44. #include <internal.h>
  45. #include <stdlib.h>
  46. /*
  47. * Pointers to beginning and end of the table of function pointers manipulated
  48. * by _onexit()/atexit(). If this module is an EXE, _onexitbegin will be -1.
  49. * Otherwise _onexitbegin will point to a block of malloc-ed memory used to
  50. * maintain the DLL module's private onexit list of terminator routines.
  51. */
  52. _PVFV *__onexitbegin;
  53. _PVFV *__onexitend;
  54. /***
  55. *_onexit, atexit - calls to _onexit & atexit in MSVCRT*.DLL
  56. *
  57. *Purpose:
  58. * A DLL linked with MSVCRT.LIB must not call the standard _onexit or
  59. * atexit exported from MSVCRT*.DLL, but an EXE linked with MSVCRT.LIB
  60. * will call the standard versions of those two routines. The standard
  61. * names are not exported from MSVCRT*.DLL, but the _imp__* names are,
  62. * so this module can just invoke the standard versions if linked into
  63. * an EXE module (indicated by __onexitbegin == -1). If this module is
  64. * linked into a DLL (indicated by __onexitbegin != -1), it will call a
  65. * helper routine in MSVCRT*.DLL called __dllonexit to manager the DLL's
  66. * private onexit list.
  67. *
  68. *Entry:
  69. * Same as the regular versions of _onexit, atexit.
  70. *
  71. *Exit:
  72. * Same as the regular versions of _onexit, atexit.
  73. *
  74. *Exceptions:
  75. *
  76. *******************************************************************************/
  77. extern _onexit_t __dllonexit(_onexit_t, _PVFV**, _PVFV**);
  78. #ifdef _M_IX86
  79. extern _onexit_t (__cdecl *_imp___onexit)(_onexit_t func);
  80. #else
  81. extern _onexit_t (__cdecl *__imp__onexit)(_onexit_t func);
  82. #endif
  83. _onexit_t __cdecl _onexit (
  84. _onexit_t func
  85. )
  86. {
  87. #ifdef _M_IX86
  88. return( (__onexitbegin == (_PVFV *) -1)
  89. /* EXE */ ? (*_imp___onexit)(func)
  90. /* DLL */ : __dllonexit(func, &__onexitbegin, &__onexitend));
  91. #else /* _M_IX86 */
  92. return( (__onexitbegin == (_PVFV *) -1)
  93. /* EXE */ ? (*__imp__onexit)(func)
  94. /* DLL */ : __dllonexit(func, &__onexitbegin, &__onexitend) );
  95. #endif /* _M_IX86 */
  96. }
  97. int __cdecl atexit (
  98. _PVFV func
  99. )
  100. {
  101. return (_onexit((_onexit_t)func) == NULL) ? -1 : 0;
  102. }