233 lines
6.7 KiB
C
233 lines
6.7 KiB
C
/*++
|
||
|
||
Copyright (c) 1990 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ELFRPC.C
|
||
|
||
Abstract:
|
||
|
||
This file contains the routines that handle the RPC calls to the
|
||
Eventlog service via the Elf APIs.
|
||
|
||
Author:
|
||
|
||
Rajen Shah (rajens) 16-Jul-1991
|
||
|
||
Revision History:
|
||
|
||
15-Feb-1995 MarkBl
|
||
Unlink the ElfHandle *prior* to unlinking the module. Otherwise,
|
||
if another thread happens to coincidentally be in the routine
|
||
FindModuleStrucFromAtom, it's not going to get a hit for the
|
||
module atom.
|
||
|
||
18-May-1994 Danl
|
||
IELF_HANDLE_rundown: If the eventlog has been shutdown, then
|
||
we want to skip the code in this routine because most of the
|
||
resources will have been free'd.
|
||
|
||
31-Jan-1994 Danl
|
||
IELF_HANDLE_rundown: Notifiee structure was being free'd and then
|
||
referenced when it's handle was removed from the list. Now this
|
||
is fixed so it advances to the next Notifiee in the list BEFORE the
|
||
buffer is free'd.
|
||
|
||
--*/
|
||
|
||
//
|
||
// INCLUDES
|
||
//
|
||
|
||
#include <eventp.h>
|
||
|
||
extern DWORD ElState;
|
||
|
||
|
||
VOID
|
||
IELF_HANDLE_rundown(
|
||
IELF_HANDLE ElfHandle
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine is called by the server RPC runtime to run down a
|
||
Context Handle and to free any allocated data. It also does all
|
||
the work for ElfrCloseEL.
|
||
|
||
It has to undo whatever was done in ElfrOpenEventLog in terms of
|
||
allocating memory.
|
||
|
||
Arguments:
|
||
|
||
None.
|
||
|
||
Return Value:
|
||
|
||
--*/
|
||
|
||
{
|
||
PLOGMODULE pModule;
|
||
NTSTATUS Status;
|
||
PNOTIFIEE Notifiee;
|
||
PNOTIFIEE NotifieeToDelete;
|
||
|
||
//
|
||
// Generate an Audit if neccessary
|
||
//
|
||
ElfpCloseAudit(L"EventLog", ElfHandle);
|
||
|
||
//
|
||
// If the eventlog service is stopped or in the process of
|
||
// stopping, then we just want to ignore this rundown and return.
|
||
//
|
||
// Note, we don't bother calling GetElState() because that uses
|
||
// a critical section which may not exist anymore as the
|
||
// eventlog service has been shutdown.
|
||
//
|
||
// The eventlog isn't designed to be shutdown (except when the
|
||
// system is shutdown), so it isn't real good at cleaning up
|
||
// its resources.
|
||
//
|
||
if (ElState == STOPPING || ElState == STOPPED)
|
||
{
|
||
ELF_LOG1(HANDLE,
|
||
"IELF_HANDLE_rundown: Skipping rundown since ElState is %ws\n",
|
||
(ElState == STOPPING ? L"STOPPING" :
|
||
L"STOPPED"));
|
||
|
||
return;
|
||
}
|
||
|
||
ELF_LOG1(HANDLE,
|
||
"IELF_HANDLE_rundown: Run down context handle %#x\n",
|
||
ElfHandle);
|
||
|
||
if (ElfHandle->Signature != ELF_CONTEXTHANDLE_SIGN)
|
||
{
|
||
ELF_LOG0(ERROR,
|
||
"IELF_HANDLE_rundown: Invalid context handle in rundown routine\n");
|
||
|
||
return;
|
||
}
|
||
|
||
pModule = FindModuleStrucFromAtom(ElfHandle->Atom);
|
||
|
||
//
|
||
// This shouldn't ever happen. It means that a handle got created
|
||
// and its module went away without the handle getting closed.
|
||
//
|
||
if (!pModule)
|
||
{
|
||
ELF_LOG1(ERROR,
|
||
"IELF_HANDLE_rundown: Could not find module for atom %d on close\n",
|
||
ElfHandle->Atom);
|
||
|
||
return;
|
||
}
|
||
|
||
UnlinkContextHandle(ElfHandle); // Unlink it from the linked list
|
||
|
||
//
|
||
// If this handle was for a backup module, then we need to
|
||
// close the file and clean up the data structures. The standard logs
|
||
// (Application, Security, and System) are never freed.
|
||
//
|
||
if (ElfHandle->Flags & ELF_LOG_HANDLE_BACKUP_LOG)
|
||
{
|
||
ELF_LOG0(HANDLE,
|
||
"IELF_HANDLE_rundown: Handle was for a backup log\n");
|
||
|
||
Status = ElfpCloseLogFile(pModule->LogFile, ELF_LOG_CLOSE_BACKUP);
|
||
|
||
UnlinkLogModule(pModule);
|
||
DeleteAtom(pModule->ModuleAtom);
|
||
ElfpFreeBuffer(pModule->ModuleName);
|
||
|
||
//
|
||
// ElfpCloseLogFile decrements the RefCount.
|
||
//
|
||
if (pModule->LogFile->RefCount == 0)
|
||
{
|
||
ELF_LOG1(HANDLE,
|
||
"IELF_HANDLE_rundown: RefCount for LogFile %ws is 0 -- unlinking\n",
|
||
pModule->LogFile->LogFileName->Buffer);
|
||
|
||
UnlinkLogFile(pModule->LogFile);
|
||
RtlDeleteResource ( &pModule->LogFile->Resource );
|
||
RtlDeleteSecurityObject(&pModule->LogFile->Sd);
|
||
|
||
ElfpFreeBuffer(pModule->LogFile->LogFileName);
|
||
ElfpFreeBuffer(pModule->LogFile->LogModuleName);
|
||
ElfpFreeBuffer(pModule->LogFile);
|
||
}
|
||
|
||
ElfpFreeBuffer(pModule);
|
||
}
|
||
else
|
||
{
|
||
ELF_LOG0(HANDLE,
|
||
"IELF_HANDLE_rundown: Handle was not for a backup log\n");
|
||
|
||
//
|
||
// See if this handle had an ElfChangeNotify outstanding and if so,
|
||
// remove it from the list. ElfChangeNotify can't be called with a
|
||
// handle to a backup file.
|
||
//
|
||
|
||
//
|
||
// Get exclusive access to the log file. This will ensure no one
|
||
// else is accessing the file.
|
||
//
|
||
RtlAcquireResourceExclusive(&pModule->LogFile->Resource,
|
||
TRUE); // Wait until available
|
||
|
||
//
|
||
// Walk the linked list and remove any entries for this handle
|
||
//
|
||
Notifiee = CONTAINING_RECORD(pModule->LogFile->Notifiees.Flink,
|
||
struct _NOTIFIEE,
|
||
Next);
|
||
|
||
while (Notifiee->Next.Flink != pModule->LogFile->Notifiees.Flink)
|
||
{
|
||
//
|
||
// If it's for this handle, remove it from the list
|
||
//
|
||
if (Notifiee->Handle == ElfHandle)
|
||
{
|
||
ELF_LOG0(HANDLE,
|
||
"IELF_HANDLE_rundown: Deleting a ChangeNotify request for handle\n");
|
||
|
||
RemoveEntryList(&Notifiee->Next);
|
||
NtClose(Notifiee->Event);
|
||
NotifieeToDelete = Notifiee;
|
||
|
||
Notifiee = CONTAINING_RECORD(Notifiee->Next.Flink,
|
||
struct _NOTIFIEE,
|
||
Next);
|
||
|
||
ElfpFreeBuffer(NotifieeToDelete);
|
||
}
|
||
else
|
||
{
|
||
Notifiee = CONTAINING_RECORD(Notifiee->Next.Flink,
|
||
struct _NOTIFIEE,
|
||
Next);
|
||
}
|
||
}
|
||
|
||
//
|
||
// Free the resource
|
||
//
|
||
RtlReleaseResource ( &pModule->LogFile->Resource );
|
||
}
|
||
|
||
ElfpFreeBuffer(ElfHandle); // Free the context-handle structure
|
||
|
||
return;
|
||
}
|