⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wsnmp_cf.c

📁 windows的snmp api源码
💻 C
📖 第 1 页 / 共 3 页
字号:
// 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 + -