cpprun.cpp
上传用户:ykzxjx
上传日期:2022-04-03
资源大小:1175k
文件大小:6k
开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 1999 - 2000 Mark Roddy
  4. //
  5. // Hollis Technology Solutions
  6. // 94 Dow Road
  7. // Hollis, NH 03049
  8. // info@hollistech.com
  9. // www.hollistech.com
  10. //
  11. // This library is free software; you can redistribute it and/or
  12. // modify it under the terms of the GNU Lesser General Public
  13. // License as published by the Free Software Foundation; either
  14. // version 2 of the License, or (at your option) any later version.
  15. //
  16. // This library is distributed in the hope that it will be useful,
  17. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19. // Lesser General Public License for more details.
  20. //
  21. // You should have received a copy of the GNU Lesser General Public
  22. // License along with this library; if not, write to the Free Software
  23. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24. //
  25. // www.fsf.org
  26. //
  27. //
  28. //
  29. // Synopsis: 
  30. // 
  31. //
  32. // Version Information:
  33. //
  34. // $Header: /cpprun/sys/cpplib/cpprun.cpp 4     1/01/00 11:00p Markr $ 
  35. //
  36. ///////////////////////////////////////////////////////////////////////////////
  37. #define HTS_UNIQUE_FILE_ID 0x1204002
  38. #include "htscpp_internal.h"
  39. //
  40. // we appropriate DriverEntry so the driver must use another name for this routine.
  41. //
  42. #ifdef __cplusplus
  43. extern "C" {
  44. #endif
  45.     NTSTATUS
  46.     Cp_DriverEntry(PDRIVER_OBJECT DriverObject,
  47.                    PUNICODE_STRING RegistryPath); 
  48.     NTSTATUS
  49.     DriverEntry(PDRIVER_OBJECT DriverObject,
  50.                    PUNICODE_STRING RegistryPath);
  51. #ifdef __cplusplus
  52. }
  53. #endif  /* __cplusplus */
  54. static
  55. void __cdecl onexitinit (
  56.         void
  57.         );
  58. static 
  59. PVFV __cdecl onexit (
  60.         PVFV func
  61.         );
  62. static
  63. void __cdecl callPVFVArray (
  64.         PVFV * pfbegin,
  65.         PVFV * pfend
  66.         );
  67. static
  68. void __cdecl doexit (
  69.         int code,
  70.         int quick,
  71.         int retcaller
  72.         );
  73. static VOID
  74.     _CppDriverUnload(PDRIVER_OBJECT DriverObject);
  75. static PDRIVER_UNLOAD clientUnload = NULL;
  76. NTSTATUS
  77. DriverEntry(PDRIVER_OBJECT DriverObject,
  78.                PUNICODE_STRING RegistryPath)
  79. {
  80.     onexitinit();
  81.     
  82.     callPVFVArray(__crtXca, __crtXcz);
  83.     //
  84.     // call the clients driver entry routine.
  85.     //
  86.     NTSTATUS Status = Cp_DriverEntry(DriverObject, RegistryPath);
  87.     if (NT_SUCCESS(Status)) {
  88.         //
  89.         // we have to steal the unload vector if it exists
  90.         //
  91.         if (DriverObject->DriverUnload) {
  92.             clientUnload = DriverObject->DriverUnload;
  93.             DriverObject->DriverUnload = _CppDriverUnload;
  94.         }
  95.     } else {
  96.         //
  97.         // call the d'tors for global and static objects?
  98.         //
  99.         doexit (0, 0, 1);
  100.     }
  101.     return Status;
  102. }
  103. static
  104. VOID
  105.     _CppDriverUnload(PDRIVER_OBJECT DriverObject)
  106. {
  107.     
  108.     //
  109.     // call the clients unload routine
  110.     //
  111.     if (clientUnload) {
  112.         clientUnload(DriverObject);
  113.     }
  114.     //
  115.     // do what is appropriate for destorying global objects
  116.     //
  117.     doexit (0, 0, 1);
  118.     return;
  119. }
  120. //
  121. // this must be externally visible!
  122. //
  123. int __cdecl atexit (
  124.         PVFV func
  125.         )
  126. {
  127.         return (onexit(func) == NULL) ? -1 : 0;
  128. }
  129. //
  130. // this was "initterm" but we ain't initting any 'terms' I can think
  131. // of. What we are doing is calling an array of functions.
  132. //
  133. void __cdecl callPVFVArray (
  134.         PVFV * pfbegin,
  135.         PVFV * pfend
  136.         )
  137. {
  138.     
  139.     while ( pfbegin < pfend )
  140.     {
  141.         /*
  142.          * if current table entry is non-NULL, call thru it.
  143.          */
  144.         if ( *pfbegin != NULL )
  145.             (**pfbegin)();
  146.         ++pfbegin;
  147.     }
  148. }
  149. //
  150. // the CRT code had some ugly stuff that created a variable length array of
  151. // function pointers. This was scrapped in favor of a linked list.
  152. //
  153. typedef struct {
  154.     LIST_ENTRY  link; // double linked list of exit functions
  155.     PVFV         exitFunc;
  156. } EXIT_FUNC_LIST, *PEXIT_FUNC_LIST;
  157. LIST_ENTRY exitList;
  158. void __cdecl onexitinit (
  159.         void
  160.         )
  161. {
  162.     //
  163.     // this is a bit easier
  164.     //
  165.     InitializeListHead(&exitList);
  166. }
  167. PVFV __cdecl onexit (
  168.         PVFV func
  169.         )
  170. {
  171.     PEXIT_FUNC_LIST pFuncListEntry = 
  172.         (PEXIT_FUNC_LIST)malloc(sizeof(EXIT_FUNC_LIST), 'EPcO');
  173.     if (!pFuncListEntry) {
  174.         return NULL;
  175.     }
  176.     pFuncListEntry->exitFunc = func;
  177.     //
  178.     // gee, creating a lifo list is rather trivial
  179.     //
  180.     InsertHeadList(&exitList, &pFuncListEntry->link);
  181.         
  182.     return func;
  183. }
  184. void drainExit()
  185. {
  186.     PEXIT_FUNC_LIST pFuncListEntry;
  187.     while(!IsListEmpty(&exitList)) {
  188.         //
  189.         // this cast relies on link being the first field of
  190.         // EXIT_FUNC_LIST.
  191.         //        
  192.         pFuncListEntry = (PEXIT_FUNC_LIST) RemoveHeadList(&exitList);
  193.         AssertAlways((PVOID) pFuncListEntry == (PVOID)&pFuncListEntry->link);
  194.         //
  195.         // wrap this in a try/except handler?
  196.         //
  197.         if (pFuncListEntry->exitFunc) {
  198.             pFuncListEntry->exitFunc();
  199.         }
  200.         free(pFuncListEntry);
  201.     }
  202. }
  203. void __cdecl doexit (
  204.         int code,
  205.         int quick,
  206.         int retcaller
  207.         )
  208. {
  209.     if (!quick) {
  210.       
  211.         drainExit();
  212.         
  213.     }
  214.     
  215.     return;
  216. }
  217. ///////////////////////////////////////////////////////////////////////////////
  218. // 
  219. // Change History Log
  220. //
  221. // $Log: /cpprun/sys/cpplib/cpprun.cpp $
  222. // 
  223. // 4     1/01/00 11:00p Markr
  224. // 
  225. // 3     12/31/99 4:29p Markr
  226. // 
  227. // 2     12/17/99 8:30a Markr
  228. //
  229. ///////////////////////////////////////////////////////////////////////////////