diff options
Diffstat (limited to 'private/eventlog/server/terminat.c')
-rw-r--r-- | private/eventlog/server/terminat.c | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/private/eventlog/server/terminat.c b/private/eventlog/server/terminat.c new file mode 100644 index 000000000..7a2f0d519 --- /dev/null +++ b/private/eventlog/server/terminat.c @@ -0,0 +1,267 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + TERMINAT.C + +Abstract: + + This file contains all the cleanup routines for the Eventlog service. + These routines are called when the service is terminating. + +Author: + + Rajen Shah (rajens) 09-Aug-1991 + + +Revision History: + + +--*/ + +// +// INCLUDES +// + +#include <eventp.h> +#include <ntrpcp.h> + + + + +VOID +StopLPCThread () + +/*++ + +Routine Description: + + This routine stops the LPC thread and cleans up LPC-related resources. + +Arguments: + + NONE + +Return Value: + + NONE + +--*/ + +{ + ElfDbgPrint(( "[ELF] Stop the LPC thread\n" )); + + // + // Close communication port handle + // + + NtClose ( ElfCommunicationPortHandle ); + + // + // Close connection port handle + // + + NtClose ( ElfConnectionPortHandle ); + + // + // Terminate the LPC thread. + // + + if (!TerminateThread(LPCThreadHandle,NO_ERROR)) { + ElfDbgPrint(("[ELF] LPC Thread termination failed %d\n",GetLastError())); + } + CloseHandle ( LPCThreadHandle ); + + return; +} + + + + +VOID +FreeModuleAndLogFileStructs ( ) + +/*++ + +Routine Description: + + This routine walks the module and log file list and frees all the + data structures. + +Arguments: + + NONE + +Return Value: + + NONE + +Note: + + The file header and ditry bits must have been dealt with before + this routine is called. Also, the file must have been unmapped and + the handle closed. + +--*/ +{ + + NTSTATUS Status; + PLOGMODULE pModule; + PLOGFILE pLogFile; + + ElfDbgPrint (("[ELF] Freeing module and log file structs\n")); + + // + // First free all the modules + // + + while (!IsListEmpty (&LogModuleHead) ) { + + pModule = (PLOGMODULE) + CONTAINING_RECORD(LogModuleHead.Flink, LOGMODULE, ModuleList); + + UnlinkLogModule(pModule); // Remove from linked list + + ElfpFreeBuffer (pModule); // Free module memory + + } + + // + // Now free all the logfiles + // + + while (!IsListEmpty (&LogFilesHead) ) { + + pLogFile = (PLOGFILE) + CONTAINING_RECORD(LogFilesHead.Flink, LOGFILE, FileList); + + Status = ElfpCloseLogFile ( pLogFile, ELF_LOG_CLOSE_NORMAL); + + UnlinkLogFile(pLogFile); // Unlink the structure + RtlDeleteResource ( &pLogFile->Resource ); + ElfpFreeBuffer (pLogFile->LogFileName); + ElfpFreeBuffer (pLogFile); + } +} + + +VOID +ElfpCleanUp ( + ULONG EventFlags + ) + +/*++ + +Routine Description: + + This routine cleans up before the service terminates. It cleans up + based on the parameter passed in (which indicates what has been allocated + and/or started. + +Arguments: + + Bit-mask indicating what needs to be cleaned up. + +Return Value: + + NONE + +Note: + It is expected that the RegistryMonitor has already + been notified of Shutdown prior to calling this routine. + +--*/ +{ + DWORD status = NO_ERROR; + + + ElfDbgPrint (("[ELF] ElfpCleanUp.\n")); + + // + // Notify the Service Controller for the first time that we are + // about to stop the service. + // + // *** STATUS UPDATE *** + ElfStatusUpdate(STOPPING); + + + // + // Stop the RPC Server + // + if (EventFlags & ELF_STARTED_RPC_SERVER) { + ElfDbgPrint (("[ELF] Stopping the RPC Server.\n")); + + status = ElfGlobalData->StopRpcServer(eventlog_ServerIfHandle); + if (status != NO_ERROR) { + ElfDbgPrint (("[ELF] Stopping RpcServer Failed %d\n",status)); + } + } + + // + // Stop the LPC thread + // + if (EventFlags & ELF_STARTED_LPC_THREAD) + StopLPCThread(); + + // + // Tell service controller that we are making progress + // + // *** STATUS UPDATE *** + ElfStatusUpdate(STOPPING); + + // + // Flush all the log files to disk. + // + ElfDbgPrint (("[ELF] Flushing Files.\n")); + ElfpFlushFiles(); + + // + // Tell service controller that we are making progress + // + ElfStatusUpdate(STOPPING); + + // + // Clean up any resources that were allocated + // + FreeModuleAndLogFileStructs(); + + // + // Free up memory + // + + if (LocalComputerName) { + ElfpFreeBuffer(LocalComputerName); + } + + // + // If we queued up any events, flush them + // + + ElfDbgPrint (("[ELF] Flushing QueuedEvents.\n")); + FlushQueuedEvents(); + + // + // Tell service controller of that we are making progress + // + ElfStatusUpdate(STOPPING); + + if (EventFlags & ELF_INIT_GLOBAL_RESOURCE) + RtlDeleteResource ( &GlobalElfResource ); + + if (EventFlags & ELF_INIT_LOGHANDLE_CRIT_SEC) + RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&LogHandleCritSec); + + if (EventFlags & ELF_INIT_LOGFILE_CRIT_SEC) + RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&LogFileCritSec); + + if (EventFlags & ELF_INIT_QUEUED_EVENT_CRIT_SEC) + RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&QueuedEventCritSec); + + // *** STATUS UPDATE *** + ElfDbgPrint(("[ELF] Leaving the Eventlog service\n")); + ElfStatusUpdate(STOPPED); + ElCleanupStatus(); + return; +} |