📄 wsnmp_cf.c
字号:
// wsnmp_cf.c
//
// WinSNMP Communications Functions and helpers
// Copyright 1995-1998 ACE*COMM Corp
// Rleased to Microsoft under Contract
//
// Bob Natale (bnatale@acecomm.com)
//
// 19980625 - Modified SnmpStartup() to allow for NULL
// output args and to check for IsBadWritePtr()
// when non-NULL
//
#include "winsnmp.inc"
#define SNMP_MAJOR_VERSION 2
#define SNMP_MINOR_VERSION 0
#define SNMP_SUPPORT_LEVEL SNMPAPI_V2_SUPPORT
#ifdef SOLARIS
BOOL DllMain (HINSTANCE, DWORD, LPVOID);
#endif // SOLARIS
LPPDUS MapV2TrapV1 (HSNMP_PDU hPdu);
THR_TYPE WINAPI thrManager (LPVOID);
THR_TYPE WINAPI thrTrap (LPVOID);
THR_TYPE WINAPI thrTimer (LPVOID);
THR_TYPE WINAPI thrAgent (LPVOID);
THR_TYPE WINAPI thrNotify (LPVOID);
void FreeRegister (DWORD nTrap)
{
LPTRAPNOTICE pTrap;
EnterCriticalSection (&cs_TRAP);
pTrap = snmpGetTableEntry(&TrapDescr, nTrap);
if (pTrap->ourEntity)
SnmpFreeEntity (pTrap->ourEntity);
if (pTrap->agentEntity)
SnmpFreeEntity (pTrap->agentEntity);
if (pTrap->Context)
SnmpFreeContext (pTrap->Context);
snmpFreeTableEntry(&TrapDescr, nTrap);
LeaveCriticalSection (&cs_TRAP);
return;
} // end_FreeRegister
// Exported Functions
// SnmpStartup
SNMPAPI_STATUS SNMPAPI_CALL
SnmpStartup (OUT smiLPUINT32 nMajorVersion,
OUT smiLPUINT32 nMinorVersion,
OUT smiLPUINT32 nLevel,
OUT smiLPUINT32 nTranslateMode,
OUT smiLPUINT32 nRetransmitMode)
{
WSADATA wsaData;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION hTask = (HSNMP_SESSION)GetCurrentProcessId();
//
#ifdef SOLARIS
if (TaskData.hTask != hTask)
DllMain (NULL, DLL_PROCESS_ATTACH, NULL);
#endif
//
if (nMajorVersion)
{
if (IsBadWritePtr (nMajorVersion, sizeof(smiUINT32)))
goto ARG_ERROR;
*nMajorVersion = SNMP_MAJOR_VERSION;
}
if (nMinorVersion)
{
if (IsBadWritePtr (nMinorVersion, sizeof(smiUINT32)))
goto ARG_ERROR;
*nMinorVersion = SNMP_MINOR_VERSION;
}
if (nLevel)
{
if (IsBadWritePtr (nLevel, sizeof(smiUINT32)))
goto ARG_ERROR;
*nLevel = SNMP_SUPPORT_LEVEL;
}
if (nTranslateMode)
{
if (IsBadWritePtr (nTranslateMode, sizeof(smiUINT32)))
goto ARG_ERROR;
*nTranslateMode = SNMPAPI_UNTRANSLATED_V1;
}
if (nRetransmitMode)
{
if (IsBadWritePtr (nRetransmitMode, sizeof(smiUINT32)))
goto ARG_ERROR;
*nRetransmitMode = SNMPAPI_ON;
}
goto ARGS_OK;
ARG_ERROR:
lError = SNMPAPI_ALLOC_ERROR;
goto ERROR_OUT;
ARGS_OK:
EnterCriticalSection (&cs_TASK);
TaskData.nRetransmitMode = SNMPAPI_ON;
TaskData.nTranslateMode = SNMPAPI_UNTRANSLATED_V1;
// SnmpStartup is idempotent...
if (TaskData.hTask == hTask)
goto DONE; // ...already called
// New task starting up...get OS info
TaskData.sEnv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx (&TaskData.sEnv);
// Start WinSock connection...should return 0
if (WSAStartup ((WORD)0x0101, &wsaData))
{
lError = SNMPAPI_TL_NOT_INITIALIZED;
goto ERROR_PRECHECK;
}
// Set trapPipe (used in NT case only)
TaskData.trapPipe = INVALID_HANDLE_VALUE;
// Set trapSock (used in Win95 case only)
TaskData.trapSock = INVALID_SOCKET;
// Set "manager" sockets (used at SnmpSendMsg() time)
TaskData.ipSock = TaskData.ipxSock = INVALID_SOCKET;
// Start timer thread
#ifdef SOLARIS
thr_create (NULL, 0, thrTimer, NULL, THR_FLAGS, &TaskData.timerThread);
#else
{
DWORD thrId;
TaskData.timerThread = (HANDLE)_beginthreadex (NULL, 0, thrTimer, NULL, 0, &thrId);
}
#endif // SOLARIS
//
DONE:
TaskData.hTask = hTask;
TaskData.nLastError = SNMPAPI_SUCCESS;
ERROR_PRECHECK:
LeaveCriticalSection (&cs_TASK);
if (lError == SNMPAPI_SUCCESS)
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (0, lError));
} // end_SnmpStartup
// SnmpCleanup
SNMPAPI_STATUS SNMPAPI_CALL SnmpCleanup (void)
{
DWORD nSession;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
// Variables for threads not associated with a specific session
DWORD nHandles = 0;
HANDLE hTemp[4] = {NULL, NULL, NULL, NULL};
CONST HANDLE *hObjects = &hTemp[0];
//--------------------------------------------------------------
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
EnterCriticalSection (&cs_SESSION);
// Do all Forgotten Closes
if (SessDescr.Used)
{
for (nSession = 0; nSession < SessDescr.Allocated; nSession++)
if (((LPSESSION)snmpGetTableEntry(&SessDescr, nSession))->nTask)
SnmpClose ((HSNMP_SESSION)(nSession + 1));
}
LeaveCriticalSection (&cs_SESSION);
EnterCriticalSection (&cs_TASK);
// Terminate thrTimer
if (TaskData.timerThread)
{
hTemp[nHandles++] = TaskData.timerThread;
// NULL signals the timer thread to terminate itself
TaskData.timerThread = NULL;
}
// Close "Mgr" sockets and threads
if (TaskData.ipSock != INVALID_SOCKET)
{// UDP channel
// check thrManager code to understand the lines below:
SOCKET ipSock = TaskData.ipSock;
TaskData.ipSock = INVALID_SOCKET;
closesocket (ipSock);
if (TaskData.ipThread)
hTemp[nHandles++] = TaskData.ipThread;
}
if (TaskData.ipxSock != INVALID_SOCKET)
{// IPX channel
// check thrManager code to understand the lines below:
SOCKET ipxSock = TaskData.ipxSock;
TaskData.ipxSock = INVALID_SOCKET;
closesocket (ipxSock);
if (TaskData.ipxThread)
hTemp[nHandles++] = TaskData.ipxThread;
}
// Terminate thrTrap
if (TaskData.trapThread)
{
if (TaskData.sEnv.dwPlatformId == VER_PLATFORM_WIN32_NT)
{ // NT-specific stuff
TerminateThread (TaskData.trapThread, 0);
if (TaskData.trapPipe != INVALID_HANDLE_VALUE)
CloseHandle (TaskData.trapPipe);
}
if (TaskData.sEnv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
{ // Win95-specific stuff
if (IsWindow (TaskData.trapWnd))
PostMessage (TaskData.trapWnd, WSNMP_TRAPS_OFF, (DWORD_PTR)TaskData.hTask, 0L);
if (TaskData.trapSock != INVALID_SOCKET)
closesocket (TaskData.trapSock);
}
hTemp[nHandles++] = TaskData.trapThread;
}
WaitForMultipleObjects (nHandles, hObjects, TRUE, 5000);
while (nHandles > 0)
{
nHandles--;
CloseHandle (hTemp[nHandles]);
}
// Do the main thing
ZeroMemory (&TaskData, sizeof(TASK));
LeaveCriticalSection (&cs_TASK);
// Close down WinSock connection
WSACleanup ();
//
#ifdef SOLARIS
DllMain (NULL, DLL_PROCESS_DETACH, NULL);
#endif // SOLARIS
//
return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (0, lError));
} // end_SnmpCleanup
// Open a session (v1 and v2)
HSNMP_SESSION SNMPAPI_CALL SnmpOpen (IN HWND hWnd, IN UINT wMsg)
{
return (SnmpCreateSession (hWnd, wMsg, NULL, NULL));
} // end_SnmpOpen
// Open a session, w/callback option (v2)
HSNMP_SESSION SNMPAPI_CALL
SnmpCreateSession (IN HWND hWnd, IN UINT wMsg,
IN SNMPAPI_CALLBACK fCallBack,
IN LPVOID lpClientData)
{
DWORD nSession;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
LPSESSION pSession;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
// Check for window/message notification mode argument validity
if (fCallBack == NULL)
if (!IsWindow(hWnd))
{
lError = SNMPAPI_HWND_INVALID;
goto ERROR_OUT;
}
//
EnterCriticalSection (&cs_SESSION);
lError = snmpAllocTableEntry(&SessDescr, &nSession);
if (lError != SNMPAPI_SUCCESS)
goto ERROR_PRECHECK;
pSession = snmpGetTableEntry(&SessDescr, nSession);
pSession->nTask = TaskData.hTask;
pSession->hWnd = hWnd;
pSession->wMsg = wMsg;
pSession->fCallBack = fCallBack;
pSession->lpClientData = lpClientData;
if (fCallBack)
{
DWORD thrId;
pSession->thrEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
pSession->thrCount = 0;
pSession->thrHandle = (HANDLE)_beginthreadex
(NULL, 0, thrNotify, (LPVOID)nSession, 0, &thrId);
}
pSession->nLastError = SNMPAPI_SUCCESS;
ERROR_PRECHECK:
LeaveCriticalSection (&cs_SESSION);
if (lError == SNMPAPI_SUCCESS)
return ((HSNMP_SESSION)(nSession+1));
ERROR_OUT:
return ((HSNMP_SESSION)SaveError (0, lError));
} // end_SnmpOpen
// SnmpClose
SNMPAPI_STATUS SNMPAPI_CALL
SnmpClose (IN HSNMP_SESSION hSession)
{
HANDLE thrTemp;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
DWORD nSes = HandleToUlong(hSession) - 1;
DWORD i;
LPSESSION pSession;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&SessDescr, nSes))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
}
pSession = snmpGetTableEntry(&SessDescr, nSes);
// Strategy:
// 1st: Stop notifications to session
// 2nd: Stop accepting new messages
// Traps
// Agents
// 3rd: Clear out pending messages
// 4th: Free up all other resources
//
// PART_1: Stop notifications to the closing Session
// Block window/message notification (in all cases!)
pSession->hWnd = NULL;
// Block callback notification (if required)
if (pSession->fCallBack != NULL)
{
// Save thrHandle for WaitForSingleObject call
EnterCriticalSection (&cs_SESSION);
thrTemp = pSession->thrHandle;
// If this is a callback session, must stop thrNotify instance
pSession->thrHandle = NULL;
// 0xFFFFFFFF signals thrNotify instance to terminate itself
pSession->thrCount = 0xFFFFFFFF;
// SetEvent signals thrNotify instance to run
SetEvent (pSession->thrEvent);
LeaveCriticalSection (&cs_SESSION);
// Wait for termination signal from thread handle
WaitForSingleObject (thrTemp, 30000);
// Close thrNotify instance handle
CloseHandle (thrTemp);
// Close thrNotify event handle
CloseHandle (pSession->thrEvent);
}
// PART_2: Stop accepting new messages for the closing Session
// Free Notifications registered by the closing Session
EnterCriticalSection (&cs_TRAP);
for (i = 0; i < TrapDescr.Allocated && TrapDescr.Used != 0; i++)
{
LPTRAPNOTICE pTrap = snmpGetTableEntry(&TrapDescr, i);
if (pTrap->Session == hSession)
FreeRegister (i);
} // end_for (Traps)
LeaveCriticalSection (&cs_TRAP);
// Free Agents registered by the closing Session
EnterCriticalSection (&cs_AGENT);
for (i = 0; i < AgentDescr.Allocated && AgentDescr.Used != 0; i++)
{
LPAGENT pAgent = snmpGetTableEntry(&AgentDescr, i);
if (pAgent->Session == hSession)
SnmpListen (pAgent->Entity, SNMPAPI_OFF);
}
LeaveCriticalSection (&cs_AGENT);
// PART_3: Free all pending messages for the closing Session
EnterCriticalSection (&cs_MSG);
for (i = 0; i < MsgDescr.Allocated && MsgDescr.Used != 0; i++)
{
LPSNMPMSG pMsg = snmpGetTableEntry(&MsgDescr, i);
if (pMsg->Session == hSession)
FreeMsg (i);
}
LeaveCriticalSection (&cs_MSG);
// PART_4: Free all other resources
// Free Entities allocated by the closing Session
EnterCriticalSection (&cs_ENTITY);
for (i = 0; i < EntsDescr.Allocated && EntsDescr.Used != 0; i++)
{
LPENTITY pEntity = snmpGetTableEntry(&EntsDescr, i);
if (pEntity->Session == hSession)
SnmpFreeEntity ((HSNMP_ENTITY)(i+1));
}
LeaveCriticalSection (&cs_ENTITY);
// Free Contexts allocated by the closing Session
EnterCriticalSection (&cs_CONTEXT);
for (i = 0; i < CntxDescr.Allocated && CntxDescr.Used != 0; i++)
{
LPCTXT pCtxt = snmpGetTableEntry(&CntxDescr, i);
if (pCtxt->Session == hSession)
SnmpFreeContext ((HSNMP_CONTEXT)(i+1));
}
LeaveCriticalSection (&cs_CONTEXT);
// Free VBLs allocated by the closing Session
EnterCriticalSection (&cs_VBL);
for (i = 0; i < VBLsDescr.Allocated && VBLsDescr.Used != 0; i++)
{
LPVBLS pVbl = snmpGetTableEntry(&VBLsDescr, i);
if (pVbl->Session == hSession)
SnmpFreeVbl ((HSNMP_VBL)(i+1));
}
LeaveCriticalSection (&cs_VBL);
// Free PDUs allocated by the closing Session
EnterCriticalSection (&cs_PDU);
for (i = 0; i < PDUsDescr.Allocated && PDUsDescr.Used != 0; i++)
{
LPPDUS pPDU = snmpGetTableEntry(&PDUsDescr, i);
if (pPDU->Session == hSession)
SnmpFreePdu ((HSNMP_PDU)(i+1));
}
LeaveCriticalSection (&cs_PDU);
// Free the Session table entry used by the closing Session
EnterCriticalSection (&cs_SESSION);
snmpFreeTableEntry(&SessDescr, nSes);
LeaveCriticalSection (&cs_SESSION);
return (SNMPAPI_SUCCESS);
ERROR_OUT:
// As of 19980808 there are no error cases with a valid session
return (SaveError (0, lError));
} // end_SnmpClose
// SnmpSendMsg
SNMPAPI_STATUS SNMPAPI_CALL
SnmpSendMsg (IN HSNMP_SESSION hSession,
IN HSNMP_ENTITY hSrc,
IN HSNMP_ENTITY hDst,
IN HSNMP_CONTEXT hCtx,
IN HSNMP_PDU hPdu)
{
LPPDUS sendPdu;
BOOL fMsg;
DWORD nMsg;
DWORD pduType;
smiINT32 dllReqId;
smiOCTETS tmpContext;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
//
DWORD thrId;
SOCKET *pSock;
int tFamily;
SOCKADDR tAddr;
HANDLE *pThread;
//
DWORD nSrc;
DWORD nDst;
DWORD nCtx;
DWORD nPdu;
//
BOOL fBroadcast;
//
LPPDUS pPdu;
LPENTITY pEntSrc, pEntDst;
LPCTXT pCtxt;
LPSNMPMSG pMsg;
if (TaskData.hTask == 0)
{
lError = SNMPAPI_NOT_INITIALIZED;
goto ERROR_OUT;
}
if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
{
lError = SNMPAPI_SESSION_INVALID;
goto ERROR_OUT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -