|
|
/*++
Copyright (c) 1992-1997 Microsoft Corporation
Module Name:
startup.c
Abstract:
Contains routines for starting SNMP master agent.
Environment:
User Mode - Win32
Revision History:
10-Feb-1997 DonRyan Rewrote to implement SNMPv2 support.
--*/
///////////////////////////////////////////////////////////////////////////////
// //
// Include files //
// //
///////////////////////////////////////////////////////////////////////////////
#include "globals.h"
#include "startup.h"
#include "network.h"
#include "registry.h"
#include "snmpthrd.h"
#include "regthrd.h"
#include "trapthrd.h"
#include "args.h"
#include "mem.h"
#include "snmpmgmt.h"
///////////////////////////////////////////////////////////////////////////////
// //
// Global variables //
// //
///////////////////////////////////////////////////////////////////////////////
HANDLE g_hAgentThread = NULL; HANDLE g_hRegistryThread = NULL; // Used to track registry changes
CRITICAL_SECTION g_RegCriticalSectionA; CRITICAL_SECTION g_RegCriticalSectionB; CRITICAL_SECTION g_RegCriticalSectionC; // protect the generation of trap from
// registry changes
///////////////////////////////////////////////////////////////////////////////
// //
// Private procedures //
// //
///////////////////////////////////////////////////////////////////////////////
BOOL LoadWinsock( )
/*++
Routine Description:
Startup winsock.
Arguments:
None.
Return Values:
Returns true if successful.
--*/
{ WSADATA WsaData; WORD wVersionRequested = MAKEWORD(2,0); INT nStatus; // attempt to startup winsock
nStatus = WSAStartup(wVersionRequested, &WsaData);
// validate return code
if (nStatus == SOCKET_ERROR) { SNMPDBG(( SNMP_LOG_ERROR, "SNMP: SVC: error %d starting winsock.\n", WSAGetLastError() ));
// failure
return FALSE; }
// success
return TRUE; }
BOOL UnloadWinsock( )
/*++
Routine Description:
Shutdown winsock.
Arguments:
None.
Return Values:
Returns true if successful.
--*/
{ INT nStatus;
// cleanup
nStatus = WSACleanup();
// validate return code
if (nStatus == SOCKET_ERROR) { SNMPDBG(( SNMP_LOG_ERROR, "SNMP: SVC: error %d stopping winsock.\n", WSAGetLastError() ));
// failure
return FALSE; }
// success
return TRUE; }
///////////////////////////////////////////////////////////////////////////////
// //
// Public procedures //
// //
///////////////////////////////////////////////////////////////////////////////
BOOL StartupAgent( )
/*++
Routine Description:
Performs essential initialization of master agent.
Arguments:
None.
Return Values:
Returns true if successful.
--*/
{ BOOL fOk = TRUE; DWORD dwThreadId = 0; DWORD regThreadId = 0; INT nCSOk = 0; // counts the number of CS that were successfully initialized
// initialize management variables
mgmtInit();
// initialize list heads
InitializeListHead(&g_Subagents); InitializeListHead(&g_SupportedRegions); InitializeListHead(&g_ValidCommunities); InitializeListHead(&g_TrapDestinations); InitializeListHead(&g_PermittedManagers); InitializeListHead(&g_IncomingTransports); InitializeListHead(&g_OutgoingTransports);
__try { InitializeCriticalSection(&g_RegCriticalSectionA); nCSOk++; InitializeCriticalSection(&g_RegCriticalSectionB); nCSOk++; InitializeCriticalSection(&g_RegCriticalSectionC); nCSOk++; } __except(EXCEPTION_EXECUTE_HANDLER) { if (nCSOk == 1) DeleteCriticalSection(&g_RegCriticalSectionA); if (nCSOk == 2) { DeleteCriticalSection(&g_RegCriticalSectionA); DeleteCriticalSection(&g_RegCriticalSectionB); } // nCSOk can't be 3 as far as we are here
fOk = FALSE; } SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Initialize critical sections...%s\n", fOk? "Ok" : "Failed"));
fOk = fOk && (g_hRegistryEvent = CreateEvent(NULL, FALSE, TRUE, NULL)) != NULL;
g_dwUpTimeReference = SnmpSvcInitUptime(); // retreive system uptime reference
SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Getting system uptime...%d\n", g_dwUpTimeReference));
// allocate essentials
fOk = fOk && AgentHeapCreate(); SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Creating agent heap...%s\n", fOk? "Ok" : "Failed"));
fOk = fOk && LoadWinsock(); SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Loading Winsock stack...%s\n", fOk? "Ok" : "Failed"));
fOk = fOk && LoadIncomingTransports(); SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Loading Incoming transports...%s\n", fOk? "Ok" : "Failed"));
fOk = fOk && LoadOutgoingTransports(); SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Loading Outgoing transports...%s\n", fOk? "Ok" : "Failed"));
fOk = fOk && // attempt to start main thread
(g_hAgentThread = CreateThread( NULL, // lpThreadAttributes
0, // dwStackSize
ProcessSnmpMessages, NULL, // lpParameter
CREATE_SUSPENDED, // dwCreationFlags
&dwThreadId )) != NULL; SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Starting ProcessSnmpMessages thread...%s\n", fOk? "Ok" : "Failed"));
fOk = fOk && // attempt to start registry listener thread
(g_hRegistryThread = CreateThread( NULL, 0, ProcessRegistryMessage, NULL, CREATE_SUSPENDED, ®ThreadId)) != NULL; SNMPDBG(( SNMP_LOG_TRACE, "SNMP: SVC: Starting ProcessRegistryMessages thread...%s\n", fOk? "Ok" : "Failed"));
return fOk; }
BOOL ShutdownAgent( )
/*++
Routine Description:
Performs final cleanup of master agent.
Arguments:
None.
Return Values:
Returns true if successful.
--*/
{ BOOL fOk; DWORD dwStatus;
// make sure shutdown signalled
fOk = SetEvent(g_hTerminationEvent);
if (!fOk) { SNMPDBG(( SNMP_LOG_ERROR, "SNMP: SVC: error %d signalling termination.\n", GetLastError() )); }
// check if thread created
if ((g_hAgentThread != NULL) && (g_hRegistryThread != NULL)) { HANDLE hEvntArray[2];
hEvntArray[0] = g_hAgentThread; hEvntArray[1] = g_hRegistryThread;
dwStatus = WaitForMultipleObjects(2, hEvntArray, TRUE, SHUTDOWN_WAIT_HINT);
// validate return status
if ((dwStatus != WAIT_OBJECT_0) && (dwStatus != WAIT_OBJECT_0 + 1) && (dwStatus != WAIT_TIMEOUT)) { SNMPDBG(( SNMP_LOG_ERROR, "SNMP: SVC: error %d waiting for thread(s) termination.\n", GetLastError() )); } } else if (g_hAgentThread != NULL) {
// wait for pdu processing thread to terminate
dwStatus = WaitForSingleObject(g_hAgentThread, SHUTDOWN_WAIT_HINT);
// validate return status
if ((dwStatus != WAIT_OBJECT_0) && (dwStatus != WAIT_TIMEOUT)) { SNMPDBG(( SNMP_LOG_ERROR, "SNMP: SVC: error %d waiting for main thread termination.\n", GetLastError() )); } } else if (g_hRegistryThread != NULL) {
// wait for registry processing thread to terminate
dwStatus = WaitForSingleObject(g_hRegistryThread, SHUTDOWN_WAIT_HINT);
// validate return status
if ((dwStatus != WAIT_OBJECT_0) && (dwStatus != WAIT_TIMEOUT)) { SNMPDBG(( SNMP_LOG_ERROR, "SNMP: SVC: error %d waiting for registry thread termination.\n", GetLastError() )); } }
// unload incoming transports
UnloadIncomingTransports();
// unload outgoing transports
UnloadOutgoingTransports();
// unload registry info
UnloadRegistryParameters();
// unload the winsock stack
UnloadWinsock();
// cleanup the internal management buffers
mgmtCleanup();
// nuke private heap
AgentHeapDestroy();
// clean up critical section resources
DeleteCriticalSection(&g_RegCriticalSectionA); DeleteCriticalSection(&g_RegCriticalSectionB); DeleteCriticalSection(&g_RegCriticalSectionC);
ReportSnmpEvent( SNMP_EVENT_SERVICE_STOPPED, 0, NULL, 0);
return TRUE; }
|