📄 snmpelpt.cpp
字号:
/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
SNMPELPT.CPP
Abstract:
This routine is the event log processing thread for the SNMP Event Log Agent DLL.
The function of this routine is to wait for an event to occur, as indicated by an
event log record, check the registry to determine if the event is being tracked,
then to return a buffer to the processing agent DLL indicating that an SNMP trap
should be sent to the extension agent. An event is posted complete when a buffer is
built and ready for trap processing.
In order to maintain data integrity between this thread and the processing agent
thread, a MUTEX object is used to synchronize access to the trap buffer queue. If
an error occurs, an event log message and trace records are written to indicate the
problem and the event is ignored.
When the extension agent is terminated, the processing agent DLL receives control
in the process detach routine. An event is posted complete to indicate to this thread
that processing should be terminated and all event logs should be closed.
Author:
Randy G. Braze Created 16 October 1994
Revision History:
7 Feb 96 Restructured building of varbinds to be outside of trap generation.
Calculated trap buffer length correctly.
Created varbind queue and removed event log buffer queue.
28 Feb 96 Added code to support a performance threshold reached indicator.
Removed inclusion of base OID information from varbind OIDs.
Added conversion from OEM to current code page for varbind data.
Removed pointer references to varbindlist and enterpriseoid.
Fixed memory leak for not freeing storage arrays upon successful build of trap.
10 Mar 96 Removed OemToChar coding and registry checking.
Modifications to read log file names from EventLog registry entries and not
from specific entries in the SNMP Extension Agent's registry entries.
Included SnmpMgrStrToOid as an internal function, as opposed to using the function
provided by MGMTAPI.DLL. SNMPTRAP.EXE will be called if MGMTAPI is called, which
will disable other agents from being able to receive any traps. All references
to MGMTAPI.DLL and MGMTAPI.H will be removed.
Added a ThresholdEnabled flag to the registry to indicate if the threshold values
were to be monitored or ignored.
15 Mar 96 Modified to move the sources for the eventlog in the registry down below a new
key called Sources.
07 May 96 Removed SnmpUtilOidFree and use two SNMP_free. One for the OID's ids array and
one for the OID itself.
22 May 96 Edited FreeVarBind to make sure we only freed memory we allocated.
26 Jun 96 Added code to make sure message dlls were not loaded and unloaded (leaks) just have
a list of handles to the loaded dlls and free them at the end. Also plugged some other
memory leaks. Added a function to make sure the CountTable is kept tidy.
--*/
extern "C" {
#include <windows.h> // basic windows applications information
#include <winperf.h>
#include <stdlib.h>
#include <malloc.h> // needed for memory allocations
#include <string.h> // string stuff
#include <snmp.h> // snmp stuff
// #include <mgmtapi.h> // snmp mgr definitions
#include <TCHAR.H>
#include <time.h>
#include "snmpelea.h" // global dll definitions
#include "snmpelpt.h" // module specific definitions
#include "snmpelmg.h" // message definitions
}
#include "snmpelep.h" // c++ definitions and variables
extern BOOL StrToOid(PCHAR str, AsnObjectIdentifier *oid);
void
TidyCountTimeTable(
IN LPTSTR lpszLog, // pointer to log file name
IN LPTSTR lpszSource, // pointer to source of event
IN DWORD nEventID // event ID
)
/*++
Routine Description:
TidyCountTimeTable is called to remove items from the lpCountTable which no longer
have a count greater than 1.
Arguments:
lpszLog - Pointer to the log file for this event.
lpszSource - Pointer to source for this event.
nEventID - Event ID.
Return Value:
None.
--*/
{
PCOUNTTABLE lpTable; // temporary fields
PCOUNTTABLE lpPrev;
WriteTrace(0x0a,"TidyCountTimeTable: Entering TidyCountTimeTable routine\n");
if (lpCountTable == NULL)
{
WriteTrace(0x0a,"TidyCountTimeTable: Empty table, exiting TidyCountTimeTable\n");
return;
}
// if we get here, then a table exists and must be scanned for a current entry
lpTable = lpCountTable; // start with first table pointer
lpPrev = NULL; // set previous to NULL
while (TRUE)
{
WriteTrace(0x0a,"TidyCountTimeTable: Checking entry %08X\n", lpTable);
if ((strcmp(lpTable->log,lpszLog) != 0) ||
(strcmp(lpTable->source,lpszSource) != 0) ||
(lpTable->event != nEventID)
)
{
if (lpTable->lpNext == NULL)
{
WriteTrace(0x0a,"TidyCountTimeTable: Entry not found\n");
break;
}
lpPrev = lpTable;
lpTable = lpTable->lpNext; // point to next entry
continue; // continue the loop
}
if (lpPrev == NULL)
{
WriteTrace(0x0a,"TidyCountTimeTable: Freeing first entry in lpCountTable at %08X\n", lpTable);
lpCountTable = lpCountTable->lpNext;
SNMP_free(lpTable);
}
else
{
WriteTrace(0x0a,"TidyCountTimeTable: Freeing entry in lpCountTable at %08X\n", lpTable);
lpPrev->lpNext = lpTable->lpNext;
SNMP_free(lpTable);
}
break;
}
WriteTrace(0x0a,"TidyCountTimeTable: Exiting TidyCountTimeTable\n");
return;
}
BOOL
CheckCountTime(
IN LPTSTR lpszLog, // pointer to log file name
IN LPTSTR lpszSource, // pointer to source of event
IN DWORD nEventID, // event ID
IN DWORD dwTime, // time of event
IN PREGSTRUCT regStruct // pointer to registry structure
)
/*++
Routine Description:
CheckCountTime is called to determine if a specific event with count and/or time
values specified in the registry have met the indicated criteria. If an entry does
not exist in the current table of entries, a new entry is added for later tracking.
Arguments:
lpszLog - Pointer to the log file for this event.
lpszSource - Pointer to source for this event.
nEventID - Event ID.
regStruct - Pointer to a structure where data read from the registry is provided.
Return Value:
TRUE - If a trap should be sent. Count and/or time value criteria satisified.
FALSE - If no trap should be sent.
--*/
{
PCOUNTTABLE lpTable; // temporary field
DWORD dwTimeDiff = 0; // temporary field
WriteTrace(0x0a,"CheckCountTime: Entering CheckCountTime routine\n");
if (lpCountTable == NULL)
{
WriteTrace(0x0a,"CheckCountTime: Count/Time table is currently empty. Adding entry.\n");
lpCountTable = (PCOUNTTABLE) SNMP_malloc(sizeof(COUNTTABLE));
if (lpCountTable == NULL)
{
WriteTrace(0x14,"CheckCountTime: Unable to acquire storage for Count/Time table entry.\n");
WriteLog(SNMPELEA_COUNT_TABLE_ALLOC_ERROR);
return(FALSE);
}
lpCountTable->lpNext = NULL; // set forward pointer to null
strcpy(lpCountTable->log,lpszLog); // copy log file name to table
strcpy(lpCountTable->source,lpszSource); // copy source name to table
lpCountTable->event = nEventID; // copy event id to table
lpCountTable->curcount = 0; // set table count to 0
lpCountTable->time = dwTime; // set table time to event time
WriteTrace(0x0a,"CheckCountTime: New table entry is %08X\n", lpCountTable);
}
// if we get here, then a table exists and must be scanned for a current entry
lpTable = lpCountTable; // start with first table pointer
while (TRUE)
{
WriteTrace(0x0a,"CheckCountTime: Checking entry %08X\n", lpTable);
if ((strcmp(lpTable->log,lpszLog) != 0) ||
(strcmp(lpTable->source,lpszSource) != 0) ||
(lpTable->event != nEventID)
)
{
if (lpTable->lpNext == NULL)
{
break;
}
lpTable = lpTable->lpNext; // point to next entry
continue; // continue the loop
}
dwTimeDiff = dwTime - lpTable->time; // compute elapsed time in seconds
WriteTrace(0x0a,"CheckCountTime: Entry information located in table at %08X\n", lpTable);
WriteTrace(0x00,"CheckCountTime: Entry count value is %lu\n",lpTable->curcount);
WriteTrace(0x00,"CheckCountTime: Entry last time value is %08X\n",lpTable->time);
WriteTrace(0x00,"CheckCountTime: Entry current time value is %08X\n",dwTime);
WriteTrace(0x00,"CheckCountTime: Time difference is %lu\n",dwTimeDiff);
WriteTrace(0x00,"CheckCountTime: Registry count is %lu, time is %lu\n",
regStruct->nCount, regStruct->nTime);
if (regStruct->nTime)
{
WriteTrace(0x0a,"CheckCountTime: Time value is being checked\n");
if (dwTimeDiff > regStruct->nTime)
{
WriteTrace(0x0a,"CheckCountTime: Specified time parameters exceeded for entry. Resetting table information.\n");
lpTable->time = dwTime; // reset time field
lpTable->curcount = 1; // reset count field
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with FALSE\n");
return(FALSE);
}
}
if (++lpTable->curcount >= regStruct->nCount)
{
WriteTrace(0x0a,"CheckCountTime: Count field has been satisfied for entry\n");
lpTable->curcount = 0; // reset count field for event
lpTable->time = dwTime; // reset time field
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with TRUE\n");
return(TRUE);
}
else
{
WriteTrace(0x0a,"CheckCountTime: Count field not satisfied for entry\n");
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with FALSE\n");
return(FALSE);
}
}
// if we get here, then a table entry does not exist for the current entry
lpTable->lpNext = (PCOUNTTABLE) SNMP_malloc(sizeof(COUNTTABLE)); // allocate storage for new entry
lpTable = lpTable->lpNext; // set table pointer
if (lpCountTable == NULL)
{
WriteTrace(0x14,"CheckCountTime: Unable to acquire storage for Count/Time table entry.\n");
WriteLog(SNMPELEA_COUNT_TABLE_ALLOC_ERROR);
return(FALSE);
}
lpTable->lpNext = NULL; // set forward pointer to NULL
strcpy(lpTable->log,lpszLog); // copy log file name to table
strcpy(lpTable->source,lpszSource); // copy source name to table
lpTable->event = nEventID; // copy event id to table
lpTable->curcount = 0; // set table count to 0
lpTable->time = dwTime; // set table time to event time
WriteTrace(0x0a,"CheckCountTime: New table entry added at %08X\n", lpTable);
if (regStruct->nTime)
{
WriteTrace(0x0a,"CheckCountTime: Time value is being checked\n");
if (dwTimeDiff > regStruct->nTime)
{
WriteTrace(0x0a,"CheckCountTime: Specified time parameters exceeded for entry. Resetting table information.\n");
lpTable->time = dwTime; // reset time field
lpTable->curcount = 1; // reset count field
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with FALSE\n");
return(FALSE);
}
}
if (++lpTable->curcount >= regStruct->nCount)
{
WriteTrace(0x0a,"CheckCountTime: Count field has been satisfied for entry\n");
lpTable->curcount = 0; // reset count field for event
lpTable->time = dwTime; // reset time field
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with TRUE\n");
return(TRUE);
}
else
{
WriteTrace(0x0a,"CheckCountTime: Count field not satisfied for entry\n");
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with FALSE\n");
return(FALSE);
}
// default exit point (should never occur)
WriteTrace(0x0a,"CheckCountTime: Exiting CheckCountTime with FALSE\n");
return(FALSE);
}
BOOL
GetRegistryValue(
IN LPTSTR sourceName, // source name for event
IN LPTSTR eventID, // event ID for event
IN LPTSTR logFile, // log file of event
IN DWORD timeGenerated, // time this event was generated
IN OUT PREGSTRUCT regStruct // pointer to registry structure to return
)
/*++
Routine Description:
GetRegistryValue is called to read a specific key value from the system registry.
Arguments:
sourceName - Specifies the source name from the event log.
eventID - This the event ID from the event log record.
regStruct - Pointer to a structure where data will be returned from the registry.
Return Value:
TRUE - If a registry entry is located and all parameters could be read.
FALSE - If no registry entry exists or some other error occurs.
--*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -