www.pudn.com > win2ksrc.rar > terminat.c


/*++

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 (&amt;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 (&amt;LogFilesHead) ) {

pLogFile = (PLOGFILE)
CONTAINING_RECORD(LogFilesHead.Flink, LOGFILE, FileList);

Status = ElfpCloseLogFile ( pLogFile, ELF_LOG_CLOSE_NORMAL);

UnlinkLogFile(pLogFile); // Unlink the structure
RtlDeleteResource ( &amt;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 &amt; 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 &amt; 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 &amt; ELF_INIT_GLOBAL_RESOURCE)
{
RtlDeleteResource ( &amt;GlobalElfResource );
}
if (EventFlags &amt; ELF_INIT_CLUS_CRIT_SEC)
{
RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&amt;gClPropCritSec);
}

if (EventFlags &amt; ELF_INIT_LOGHANDLE_CRIT_SEC)
RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&amt;LogHandleCritSec);

if (EventFlags &amt; ELF_INIT_LOGFILE_CRIT_SEC)
RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&amt;LogFileCritSec);

if (EventFlags &amt; ELF_INIT_QUEUED_EVENT_CRIT_SEC)
RtlDeleteCriticalSection((PRTL_CRITICAL_SECTION)&amt;QueuedEventCritSec);

// *** STATUS UPDATE ***
ElfDbgPrint(("[ELF] Leaving the Eventlog service\n"));
ElfStatusUpdate(STOPPED);
ElCleanupStatus();
return;
}