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.

326 lines
6.3 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. TERMINAT.C
  5. Abstract:
  6. This file contains all the cleanup routines for the Eventlog service.
  7. These routines are called when the service is terminating.
  8. Author:
  9. Rajen Shah (rajens) 09-Aug-1991
  10. Revision History:
  11. --*/
  12. //
  13. // INCLUDES
  14. //
  15. #include <eventp.h>
  16. #include <ntrpcp.h>
  17. VOID
  18. StopLPCThread(
  19. VOID
  20. )
  21. /*++
  22. Routine Description:
  23. This routine stops the LPC thread and cleans up LPC-related resources.
  24. Arguments:
  25. NONE
  26. Return Value:
  27. NONE
  28. --*/
  29. {
  30. ELF_LOG0(TRACE,
  31. "StopLpcThread: Clean up LPC thread and global data\n");
  32. //
  33. // Close communication port handle
  34. //
  35. NtClose(ElfCommunicationPortHandle);
  36. //
  37. // Close connection port handle
  38. //
  39. NtClose(ElfConnectionPortHandle);
  40. //
  41. // Terminate the LPC thread.
  42. //
  43. if (!TerminateThread(LPCThreadHandle, NO_ERROR))
  44. {
  45. ELF_LOG1(ERROR,
  46. "StopLpcThread: TerminateThread failed %d\n",
  47. GetLastError());
  48. }
  49. CloseHandle(LPCThreadHandle);
  50. return;
  51. }
  52. VOID
  53. FreeModuleAndLogFileStructs(
  54. VOID
  55. )
  56. /*++
  57. Routine Description:
  58. This routine walks the module and log file list and frees all the
  59. data structures.
  60. Arguments:
  61. NONE
  62. Return Value:
  63. NONE
  64. Note:
  65. The file header and ditry bits must have been dealt with before
  66. this routine is called. Also, the file must have been unmapped and
  67. the handle closed.
  68. --*/
  69. {
  70. NTSTATUS Status;
  71. PLOGMODULE pModule;
  72. PLOGFILE pLogFile;
  73. ELF_LOG0(TRACE,
  74. "FreeModuleAndLogFileStructs: Emptying log module list\n");
  75. //
  76. // First free all the modules
  77. //
  78. while (!IsListEmpty(&LogModuleHead))
  79. {
  80. pModule = (PLOGMODULE) CONTAINING_RECORD(LogModuleHead.Flink, LOGMODULE, ModuleList);
  81. UnlinkLogModule(pModule); // Remove from linked list
  82. ElfpFreeBuffer (pModule); // Free module memory
  83. }
  84. //
  85. // Now free all the logfiles
  86. //
  87. ELF_LOG0(TRACE,
  88. "FreeModuleAndLogFileStructs: Emptying log file list\n");
  89. while (!IsListEmpty(&LogFilesHead))
  90. {
  91. pLogFile = (PLOGFILE) CONTAINING_RECORD(LogFilesHead.Flink, LOGFILE, FileList);
  92. Status = ElfpCloseLogFile(pLogFile, ELF_LOG_CLOSE_NORMAL);
  93. if (!NT_SUCCESS(Status))
  94. {
  95. ELF_LOG2(FILES,
  96. "FreeModuleAndLogFileStructs: ElfpCloseLogFile on %ws failed %#x\n",
  97. pLogFile->LogModuleName->Buffer,
  98. Status);
  99. }
  100. UnlinkLogFile(pLogFile);
  101. RtlDeleteResource(&pLogFile->Resource);
  102. ElfpFreeBuffer(pLogFile->LogFileName);
  103. ElfpFreeBuffer(pLogFile->LogModuleName);
  104. ElfpFreeBuffer(pLogFile);
  105. }
  106. }
  107. VOID
  108. ElfpCleanUp (
  109. ULONG EventFlags
  110. )
  111. /*++
  112. Routine Description:
  113. This routine cleans up before the service terminates. It cleans up
  114. based on the parameter passed in (which indicates what has been allocated
  115. and/or started.
  116. Arguments:
  117. Bit-mask indicating what needs to be cleaned up.
  118. Return Value:
  119. NONE
  120. Note:
  121. It is expected that the RegistryMonitor has already
  122. been notified of Shutdown prior to calling this routine.
  123. --*/
  124. {
  125. DWORD status = NO_ERROR;
  126. //
  127. // Notify the Service Controller for the first time that we are
  128. // about to stop the service.
  129. //
  130. ElfStatusUpdate(STOPPING);
  131. ELF_LOG0(TRACE, "ElfpCleanUp: Cleaning up so service can exit\n");
  132. //
  133. // Give the ElfpSendMessage thread a 1 second chance to exit before
  134. // we free the QueuedMessageCritSec critical section
  135. //
  136. if( MBThreadHandle != NULL )
  137. {
  138. ELF_LOG0(TRACE, "ElfpCleanUp: Waiting for ElfpSendMessage thread to exit\n");
  139. status = WaitForSingleObject(MBThreadHandle, 1000);
  140. if (status != WAIT_OBJECT_0)
  141. {
  142. ELF_LOG1(ERROR,
  143. "ElfpCleanUp: NtWaitForSingleObject status = %d\n",
  144. status);
  145. }
  146. }
  147. //
  148. // Stop the RPC Server
  149. //
  150. if (EventFlags & ELF_STARTED_RPC_SERVER)
  151. {
  152. ELF_LOG0(TRACE,
  153. "ElfpCleanUp: Stopping the RPC server\n");
  154. status = ElfGlobalData->StopRpcServer(eventlog_ServerIfHandle);
  155. if (status != NO_ERROR)
  156. {
  157. ELF_LOG1(ERROR,
  158. "ElfpCleanUp: StopRpcServer failed %d\n",
  159. status);
  160. }
  161. }
  162. //
  163. // Stop the LPC thread
  164. //
  165. if (EventFlags & ELF_STARTED_LPC_THREAD)
  166. {
  167. StopLPCThread();
  168. }
  169. //
  170. // Tell service controller that we are making progress
  171. //
  172. ElfStatusUpdate(STOPPING);
  173. //
  174. // Flush all the log files to disk.
  175. //
  176. ELF_LOG0(TRACE,
  177. "ElfpCleanUp: Flushing log files\n");
  178. ElfpFlushFiles();
  179. //
  180. // Tell service controller that we are making progress
  181. //
  182. ElfStatusUpdate(STOPPING);
  183. //
  184. // Clean up any resources that were allocated
  185. //
  186. FreeModuleAndLogFileStructs();
  187. //
  188. // If we queued up any events, flush them
  189. //
  190. ELF_LOG0(TRACE,
  191. "ElfpCleanUp: Flushing queued events\n");
  192. FlushQueuedEvents();
  193. //
  194. // Tell service controller of that we are making progress
  195. //
  196. ElfStatusUpdate(STOPPING);
  197. if (EventFlags & ELF_INIT_GLOBAL_RESOURCE)
  198. {
  199. RtlDeleteResource(&GlobalElfResource);
  200. }
  201. if (EventFlags & ELF_INIT_CLUS_CRIT_SEC)
  202. {
  203. RtlDeleteCriticalSection(&gClPropCritSec);
  204. }
  205. if (EventFlags & ELF_INIT_LOGHANDLE_CRIT_SEC)
  206. {
  207. RtlDeleteCriticalSection(&LogHandleCritSec);
  208. }
  209. if (EventFlags & ELF_INIT_QUEUED_MESSAGE_CRIT_SEC)
  210. {
  211. RtlDeleteCriticalSection(&QueuedMessageCritSec);
  212. }
  213. if (EventFlags & ELF_INIT_QUEUED_EVENT_CRIT_SEC)
  214. {
  215. RtlDeleteCriticalSection(&QueuedEventCritSec);
  216. }
  217. if (EventFlags & ELF_INIT_LOGMODULE_CRIT_SEC)
  218. {
  219. RtlDeleteCriticalSection(&LogModuleCritSec);
  220. }
  221. if (EventFlags & ELF_INIT_LOGFILE_CRIT_SEC)
  222. {
  223. RtlDeleteCriticalSection(&LogFileCritSec);
  224. }
  225. LocalFree(GlobalMessageBoxTitle);
  226. GlobalMessageBoxTitle = NULL;
  227. //
  228. // *** STATUS UPDATE ***
  229. //
  230. ELF_LOG0(TRACE,
  231. "ElfpCleanUp: The Eventlog service has left the building\n");
  232. ElfStatusUpdate(STOPPED);
  233. ElCleanupStatus();
  234. return;
  235. }