windows-nt/Source/XPSP1/NT/ds/security/base/lsa/server/spmgr.cxx
2020-09-26 16:20:57 +08:00

283 lines
6.2 KiB
C++

//+-----------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (c) Microsoft Corporation 1991 - 1992
//
// File: spmgr.c
//
// Contents: Main file of the SPMgr component
//
// Functions: SetKsecEvent -- Sets the event exported by DD
// ServerMain -- Main startup
//
//
// History: 27 May 92, RichardW Commented
//
//------------------------------------------------------------------------
#include <lsapch.hxx>
extern "C"
{
#include "spinit.h"
}
///////////////////////////////////////////////////////////////////////////
//
//
// Global "Variables"
//
//
// Most of these variables are set during initialization, and are used
// in a read-only fashion afterwards.
//
//
///////////////////////////////////////////////////////////////////////////
PWSTR pszPackageList; // Not really needed
LUID SystemLogonId = SYSTEM_LUID; // Logon Session for the system (should be 999:0)
DWORD dwSession; // TLS: Thread Session ptr
DWORD dwLastError; // TLS: Thread last error
DWORD dwExceptionInfo; // TLS: Thread exception info
DWORD dwCallInfo; // TLS: Thread LPC message ptr
DWORD dwThreadPackage; // TLS: Thread Package ID
DWORD dwThreadHeap; // TLS: Thread Heap
BOOLEAN SetupPhase;
HANDLE hShutdownEvent; // Shutdown synch event
HANDLE hStateChangeEvent; // State change event
SECURITY_STRING MachineName;
PWSTR * ppszPackages; // Contains a null terminated array of dll names
PWSTR * ppszOldPkgs; // Contains a null terminated array of old pkgs
LsaState lsState; // State of the process, for relay to the dll
LSA_TUNING_PARAMETERS LsaTuningParameters ;
BOOL ShutdownBegun ;
//
// Name of event which says that the LSA RPC server is ready
//
#define LSA_RPC_SERVER_ACTIVE L"\\BaseNamedObjects\\LSA_RPC_SERVER_ACTIVE"
#if TRACK_MEM
extern FILE * pMemoryFile;
extern DWORD dwTotalHeap;
extern DWORD dwHeapHW;
#endif
HANDLE hPrelimShutdownEvent;
DWORD
ShutdownWorker(
PVOID Ignored
)
{
NTSTATUS Status ;
PLSAP_SECURITY_PACKAGE pAuxPackage;
ULONG_PTR iPackage ;
DWORD Tick ;
DWORD TickMax ;
//
// Stop any new calls from getting through
//
ShutdownBegun = TRUE ;
LsapShutdownInprocDll();
if ( LsaTuningParameters.Options & TUNE_SRV_HIGH_PRIORITY )
{
TickMax = 100 ;
}
else
{
TickMax = 10 ;
}
pAuxPackage = SpmpIteratePackagesByRequest( NULL, SP_ORDINAL_SHUTDOWN );
while (pAuxPackage)
{
iPackage = pAuxPackage->dwPackageID;
pAuxPackage->fPackage |= SP_SHUTDOWN_PENDING | SP_SHUTDOWN ;
DebugLog((DEB_TRACE, "Shutting down package %ws\n",
pAuxPackage->Name.Buffer ));
//
// Spin wait for the calls in progress to complete
//
Tick = 0 ;
while ( (pAuxPackage->CallsInProgress > 0) &&
( Tick < TickMax ) )
{
Sleep( 100 );
Tick++ ;
}
if ( Tick == TickMax )
{
DebugLog(( DEB_ERROR, "Package %ws did not respond in %d seconds for shutdown\n",
pAuxPackage->Name.Buffer,
Tick / 10 ));
pAuxPackage = SpmpIteratePackagesByRequest( pAuxPackage,
SP_ORDINAL_SHUTDOWN );
continue;
}
SetCurrentPackageId( iPackage );
__try
{
Status = pAuxPackage->FunctionTable.Shutdown();
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status = (NTSTATUS) GetExceptionCode();
}
pAuxPackage->fPackage &= ~SP_SHUTDOWN_PENDING ;
pAuxPackage = SpmpIteratePackagesByRequest( pAuxPackage,
SP_ORDINAL_SHUTDOWN );
}
SetCurrentPackageId( SPMGR_ID );
SetEvent( hShutdownEvent );
return 0;
}
//+-------------------------------------------------------------------------
//
// Function: ServerStop
//
// Synopsis: Stop the SPM. Clean shutdown
//
//--------------------------------------------------------------------------
HRESULT
ServerStop(void)
{
// First, see if we are already in the middle of a shutdown. The
// hShutdownEvent handle will be non-null.
if (hShutdownEvent)
{
return(0);
}
DebugLog((DEB_TRACE, "LSA shutdown:\n"));
hShutdownEvent = SpmCreateEvent(NULL, TRUE, FALSE, L"\\SpmShutdownEvent");
if (hPrelimShutdownEvent)
{
SetEvent(hPrelimShutdownEvent);
}
QueueUserWorkItem( ShutdownWorker, NULL, FALSE );
return(S_OK);
}
#if DBG
void
SpmpThreadStartupEx(void)
{
PSpmExceptDbg pExcept;
pExcept = (PSpmExceptDbg) LsapAllocateLsaHeap(sizeof(SpmExceptDbg));
MarkPermanent(pExcept);
TlsSetValue(dwExceptionInfo, pExcept);
}
void
SpmpThreadExitEx(void)
{
PSpmExceptDbg pExcept;
pExcept = (PSpmExceptDbg) TlsGetValue(dwExceptionInfo);
if (pExcept)
{
UnmarkPermanent(pExcept);
LsapFreeLsaHeap(pExcept);
}
}
#endif // DBG
//+-------------------------------------------------------------------------
//
// Function: SpControlHandler
//
// Synopsis: Console Control Function handler
//
// Effects: Handles system shutdown
//
// Arguments:
//
// Requires:
//
// Returns:
//
// Notes:
//
//--------------------------------------------------------------------------
BOOL
SpConsoleHandler(DWORD dwCtrlType)
{
SpmpThreadStartup();
DebugLog((DEB_TRACE, "Entered SpConsoleHandler(%d)\n", dwCtrlType));
switch (dwCtrlType)
{
case CTRL_C_EVENT:
case CTRL_BREAK_EVENT:
SpmpThreadExit();
return(FALSE);
break;
case CTRL_CLOSE_EVENT:
case CTRL_SHUTDOWN_EVENT:
DebugLog((DEB_TRACE, "Shutdown event received\n"));
LsapState.SystemShutdownPending = TRUE;
(void) ServerStop();
(void) WaitForSingleObject(hShutdownEvent, 10000L);
DebugLog((DEB_TRACE, "Shutdown complete\n"));
// Fall through to:
default:
SpmpThreadExit();
return(FALSE);
}
}