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

📄 wsnmp_cf.c

📁 windows的snmp api源码
💻 C
📖 第 1 页 / 共 3 页
字号:

if (TaskData.hTask == 0)
   {
   lError = SNMPAPI_NOT_INITIALIZED;
   goto ERROR_OUT;
   }
if (status != SNMPAPI_OFF) status = SNMPAPI_ON;
if (status == SNMPAPI_ON)
   {
   if (!snmpValidTableEntry(&SessDescr, nSes))
      {
      lError = SNMPAPI_SESSION_INVALID;
      goto ERROR_OUT;
      }
   else // Got a valid session...save for possible error return
      lSession = hSession;
   }
if (hSrc)
   {
   nSrc = HandleToUlong(hSrc) - 1;
   if (!snmpValidTableEntry(&EntsDescr, nSrc))
      {
      lError = SNMPAPI_ENTITY_INVALID;
      goto ERROR_OUT;
      }
   pEntSrc = snmpGetTableEntry(&EntsDescr, nSrc);
   }
if (hDst)
   {
   nDst = HandleToUlong(hDst) - 1;
   if (!snmpValidTableEntry(&EntsDescr, nDst))
      {
      lError = SNMPAPI_ENTITY_INVALID;
      goto ERROR_OUT;
      }
   pEntDst = snmpGetTableEntry(&EntsDescr, nDst);
   }
if (hCtx)
   {
   nCtx = HandleToUlong(hCtx) - 1;
   if (!snmpValidTableEntry(&CntxDescr, nCtx))
      {
      lError = SNMPAPI_CONTEXT_INVALID;
      goto ERROR_OUT;
      }
   pCtxt = snmpGetTableEntry(&CntxDescr, nCtx);
   }
if (notification)
   {
   if ((!notification->len) || notification->len > MAXOBJIDSIZE)
      {
      lError = SNMPAPI_SIZE_INVALID;
      goto ERROR_OUT;
      }
   if (!notification->ptr)
      {
      lError = SNMPAPI_OID_INVALID;
      goto ERROR_OUT;
      }
   }
EnterCriticalSection (&cs_TRAP);
for (nNotice = 0, nFound = 0; nNotice < TrapDescr.Allocated,
                              nFound < TrapDescr.Used; nNotice++)
   { // First, count now many we've tested
   pTrap = snmpGetTableEntry(&TrapDescr, nNotice);
   if (pTrap->Session) nFound++;
   // then search for a parameter matches
   if ((pTrap->Session == hSession) &&
       (pTrap->ourEntity == hSrc) &&
       (pTrap->agentEntity == hDst) &&
       (pTrap->Context == hCtx))
      { // Ok, we found one
      if (!notification)
         // if the notification parameter is null, then we
         // want to either turn on or turn off all notifications
         // from this match...so clear any entries already in
         // the table and we'll add this wildcard entry if the
         // operation is SNMPAPI_ON at the end.
         {
         FreeRegister (nNotice);
         continue;
         }
      else // notification specified
         {
         if (!pTrap->notification.len)
            {
            // Redundant request (already wildcarded)
            // Skip it and return!
            goto ERROR_PRECHECK;
            }
         else // pTrap->notification
            {
            // compare OIDs
            SnmpOidCompare (notification, &(pTrap->notification),
                            0, &nCmp);
            if (nCmp)      // no match
               continue;   // ...try the next one
            else // !nCcmp
               { // got a match...
               // if SNMPAPI_ON, redundant request...skip it and return
               // if SNMPAPI_OFF, free the entry first
               if (status != SNMPAPI_ON)
                  FreeRegister (nNotice); // SNMPAPI_OFF
               goto ERROR_PRECHECK;
               } // end_else_!nCmp
            } // end_else_TrapTable[nNotice].notificatin
         } // end_else_notification_specified
      } // end_if_we_found_one
   } // end_for
if (status == SNMPAPI_OFF)
   { // Found nothing to turn off...that's ok.
   goto ERROR_PRECHECK;
   }
//
#ifndef SOLARIS
// Special check for NT...is SNMPTRAP service running?
if (TaskData.trapThread == NULL &&
    TaskData.sEnv.dwPlatformId == VER_PLATFORM_WIN32_NT)
   {
   DWORD   dwReturn  = SNMPAPI_TL_NOT_INITIALIZED;
   DWORD   pMode     = PIPE_WAIT | PIPE_READMODE_MESSAGE;
   LPCTSTR svcName   = "SNMPTRAP";
   LPCTSTR svcDesc   = "SNMP Trap Service";
   LPCTSTR svcPath   = "%SystemRoot%\\system32\\snmptrap.exe";
   SC_HANDLE scmHandle = NULL;
   SC_HANDLE svcHandle = NULL;
   SERVICE_STATUS svcStatus;
   BOOL fStatus;
   // Minimal SCM connection, for case when SNMPTRAP is running
   scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_CONNECT);
   if (scmHandle == NULL)
      goto DONE_SC;
   svcHandle = OpenService (scmHandle, svcName, SERVICE_QUERY_STATUS);
   if (svcHandle == NULL)
      {
      if (GetLastError() != ERROR_SERVICE_DOES_NOT_EXIST)
         goto DONE_SC;
      else
         { // Must attempt to create service
         PACL pAcl;
         SECURITY_DESCRIPTOR S_Desc;
         // Need new scmHandle with admin priv
         CloseServiceHandle (scmHandle);
         scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_CREATE_SERVICE);
         if (scmHandle == NULL)
            goto DONE_SC; // Could not open SCM with admin priv
         svcHandle = CreateService (scmHandle, svcName, svcDesc,
                                    WRITE_DAC|SERVICE_QUERY_STATUS,
                                    SERVICE_WIN32_OWN_PROCESS,
                                    SERVICE_DEMAND_START,
                                    SERVICE_ERROR_NORMAL,
                                    svcPath,
                                    NULL, NULL,
                                    "TCPIP\0EventLog\0\0",
                                    NULL, NULL);
         if (svcHandle == NULL)
            goto DONE_SC; // Could not create service
         InitializeSecurityDescriptor (&S_Desc, SECURITY_DESCRIPTOR_REVISION);
         if ((pAcl = AllocGenericACL()) == NULL ||
             !SetSecurityDescriptorDacl (&S_Desc, TRUE, pAcl, FALSE))
         {
             FreeGenericACL(pAcl);
             goto DONE_SC;
         }
         SetServiceObjectSecurity (svcHandle, DACL_SECURITY_INFORMATION, &S_Desc);
         FreeGenericACL(pAcl);
         }
      }
   fStatus = QueryServiceStatus (svcHandle, &svcStatus);
   while (fStatus)
      {
      switch (svcStatus.dwCurrentState)
         {
         case SERVICE_RUNNING:
         dwReturn = SNMPAPI_SUCCESS;
         goto DONE_SC;

         case SERVICE_STOPPED:
         // Start SNMPTRAP service if necessary
         CloseServiceHandle (svcHandle);
         svcHandle = OpenService (scmHandle, svcName, SERVICE_START|SERVICE_QUERY_STATUS);
         if (svcHandle == NULL)
            goto DONE_SC; // Could not start service
         svcStatus.dwCurrentState = SERVICE_START_PENDING;
         fStatus = StartService (svcHandle, 0, NULL);
         break;

         case SERVICE_STOP_PENDING:
         case SERVICE_START_PENDING:
         Sleep (MAX_PENDING_WAIT);
         fStatus = QueryServiceStatus (svcHandle, &svcStatus);
         break;

         case SERVICE_PAUSED:
         case SERVICE_PAUSE_PENDING:
         case SERVICE_CONTINUE_PENDING:
         default:
         fStatus = FALSE;  // Nothing to do about these
         break;
         }
      }
DONE_SC:
   if (scmHandle)
      CloseServiceHandle (scmHandle);
   if (svcHandle)
      CloseServiceHandle (svcHandle);
   if (dwReturn != SNMPAPI_SUCCESS)
      {
ERROR_PRECHECK1:
      lError = dwReturn;
      goto ERROR_PRECHECK;
      }
   // Setup for pipe-oriented operations
   dwReturn = SNMPAPI_TL_RESOURCE_ERROR;
   // block on instance of server pipe becoming available
   if (!WaitNamedPipe (SNMPTRAPPIPE, TRAPSERVERTIMEOUT))
      goto ERROR_PRECHECK1;
   TaskData.trapPipe =
      CreateFile (SNMPTRAPPIPE, GENERIC_READ|GENERIC_WRITE,
                  FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
   if (TaskData.trapPipe == INVALID_HANDLE_VALUE)
      goto ERROR_PRECHECK1;
   if (!SetNamedPipeHandleState (TaskData.trapPipe, &pMode, NULL, NULL))
      {
      CloseHandle (TaskData.trapPipe);
      TaskData.trapPipe = INVALID_HANDLE_VALUE;
      goto ERROR_PRECHECK1;
      }
   } // end_NT check for SNMPTRAP service
#endif // !SOLARIS
//If we got this far, add it
lError = snmpAllocTableEntry(&TrapDescr, &nNotice);
if (lError != SNMPAPI_SUCCESS)
    goto ERROR_PRECHECK;
pTrap = snmpGetTableEntry(&TrapDescr, nNotice);

// add it
pTrap->Session = hSession;
// Deliberate assignments in next three if statements
if (pTrap->ourEntity = hSrc)
   //EntityTable[nSrc-1].refCount++; -- was this a bug??? nSrc is already 0 based
    pEntSrc->refCount++;
if (pTrap->agentEntity = hDst)
   //EntityTable[nDst-1].refCount++; -- was this a bug??? nDst is already 0 based
    pEntDst->refCount++;
if (pTrap->Context = hCtx)
   //ContextTable[nCtx-1].refCount++; -- was this a bug?? nCtx is already 0 based
   pCtxt->refCount++;
if (notification)
   { // Reproduce the OID
   pTrap->notification.ptr = NULL;
   // Deliberate assignment in next statement
   if (pTrap->notification.len = notification->len)
      {
      if (pTrap->notification.len > MAXTRAPIDS)
         pTrap->notification.len = MAXTRAPIDS;
      if (notification->ptr)
         {
         // Deliberate assignment in next statement
         pTrap->notification.ptr = &(pTrap->notificationValue[0]);
         CopyMemory (pTrap->notification.ptr, notification->ptr,
                     pTrap->notification.len * sizeof(smiUINT32));
         }
      }
   }
if (TaskData.trapThread == NULL)
   {
// Leave # lines at margin (for Solaris cc compiler)
#ifdef SOLARIS
   thr_create (NULL, 0, thrTrap, NULL, THR_FLAGS, &TaskData.trapThread);
#else // Win32
   DWORD thrId;
   TaskData.trapThread = (HANDLE)_beginthreadex (NULL, 0, thrTrap, NULL, 0, &thrId);
#endif
   }
ERROR_PRECHECK:
LeaveCriticalSection (&cs_TRAP);
if (lError == SNMPAPI_SUCCESS)
   return (SNMPAPI_SUCCESS);
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpRegister

void FreeMsg (DWORD nMsg)
{
LPSNMPMSG pMsg;
EnterCriticalSection (&cs_MSG);
// Decrement reference counts
pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
SnmpFreeEntity (pMsg->agentEntity);
SnmpFreeEntity (pMsg->ourEntity);
SnmpFreeContext (pMsg->Context);
if (pMsg->Addr)
   GlobalFree (pMsg->Addr);
snmpFreeTableEntry(&MsgDescr, nMsg);
LeaveCriticalSection (&cs_MSG);
return;
} // end_FreeMsg

SNMPAPI_STATUS SNMPAPI_CALL
   SnmpListen (IN HSNMP_ENTITY hEntity,
               IN smiUINT32 status)
{
smiUINT32 nAgent = 0;
DWORD thrId;
DWORD nEntity = HandleToUlong(hEntity) - 1;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
LPENTITY pEntity;
LPAGENT pAgent;

if (TaskData.hTask == 0)
   {
   lError = SNMPAPI_NOT_INITIALIZED;
   goto ERROR_OUT;
   }
if (!snmpValidTableEntry(&EntsDescr, nEntity))
   {
   lError = SNMPAPI_ENTITY_INVALID;
   goto ERROR_OUT;
   }
pEntity = snmpGetTableEntry(&EntsDescr, nEntity);
lSession = pEntity->Session;
if (status != SNMPAPI_ON && status != SNMPAPI_OFF)
   {
   lError = SNMPAPI_MODE_INVALID;
   goto ERROR_OUT;
   }
EnterCriticalSection (&cs_ENTITY);
EnterCriticalSection (&cs_AGENT);
if (status)
   { // status == SNMPAPI_ON
   int nProto = IPPROTO_UDP;
   int nSize = sizeof(SOCKADDR_IN);
   int nFamily = pEntity->addr.inet.sin_family;
   if (pEntity->Agent)
      { // Entity already running as agent
      lError = SNMPAPI_NOOP;
      goto ERROR_PRECHECK;
      }
   // Allocate a slot in AGENT table
   lError = snmpAllocTableEntry(&AgentDescr, &nAgent);
   if (lError != SNMPAPI_SUCCESS)
       goto ERROR_PRECHECK;
   pAgent = snmpGetTableEntry(&AgentDescr, nAgent);

// Agent table entry allocated...setup for agent thread
   if (nFamily == AF_IPX)
      {
      nProto = NSPROTO_IPX;
      nSize = sizeof(SOCKADDR_IPX);
      }
   pAgent->Socket = socket (nFamily, SOCK_DGRAM, nProto);
   if (pAgent->Socket == INVALID_SOCKET)
      {
      snmpFreeTableEntry(&AgentDescr, nAgent);
      lError = SNMPAPI_TL_RESOURCE_ERROR;
      goto ERROR_PRECHECK;
      }
   if (bind (pAgent->Socket,
            (LPSOCKADDR)&pEntity->addr, nSize)
      == SOCKET_ERROR)
      {
      snmpFreeTableEntry(&AgentDescr, nAgent);
      closesocket (pAgent->Socket);
      lError = SNMPAPI_TL_OTHER;
      goto ERROR_PRECHECK;
      }
   // Make Entity and Agent point to each other
   pEntity->Agent = nAgent + 1;
   pAgent->Entity = hEntity;
   pAgent->Session = lSession;
   // Create agent thread...needs error checking
#ifdef SOLARIS // Leave at left margin for Solaris compiler
   thr_create (NULL, 0, thrAgent, (LPVOID)nAgent, THR_FLAGS, &(pAgent->Thread));
#else  // Win32
   pAgent->Thread = (HANDLE)_beginthreadex (NULL, 0, thrAgent, (LPVOID)nAgent, 0, &thrId);
#endif // SOLARIS
   } // end_if status == SNMPAPI_ON
else
   { // status == SNMPAPI_OFF
   if (!pEntity->Agent)
      { // Entity not running as agent
      lError = SNMPAPI_NOOP;
      goto ERROR_PRECHECK;
      }
   // Entity is running as agent
   nAgent = pEntity->Agent - 1;
   pAgent = snmpGetTableEntry(&AgentDescr, nAgent);
   closesocket (pAgent->Socket);
   WaitForSingleObject (pAgent->Thread, INFINITE);
   CloseHandle (pAgent->Thread);
   snmpFreeTableEntry(&AgentDescr, nAgent);
   // Must terminate entity's agent status
   pEntity->Agent = 0;
   // Must terminate entity if nothing else was using it
   if (pEntity->refCount == 0)
      SnmpFreeEntity (hEntity);
   } // end_else status == SNMPAPI_OFF
ERROR_PRECHECK:
LeaveCriticalSection (&cs_AGENT);
LeaveCriticalSection (&cs_ENTITY);
ERROR_OUT:
if (lError == SNMPAPI_SUCCESS)
   return (SNMPAPI_SUCCESS);
else
   return (SaveError (lSession, lError));
} // end_SnmpListen()

SNMPAPI_STATUS SNMPAPI_CALL
   SnmpCancelMsg (HSNMP_SESSION hSession, smiINT32 nReqID)
{
DWORD nMsg = 0;
DWORD nFound = 0;
SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
HSNMP_SESSION lSession = 0;
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;
   }
lSession = hSession;
EnterCriticalSection (&cs_MSG);

while (nFound < MsgDescr.Used && nMsg < MsgDescr.Allocated)
   {
   pMsg = snmpGetTableEntry(&MsgDescr, nMsg);
   // Deliberate assignement in next conditional
   if (pMsg->Session)
      {
      nFound++;
      if (pMsg->Session == hSession)
         {
         if (pMsg->Status == NP_SENT &&
             pMsg->appReqId == (smiUINT32)nReqID)
            {
            FreeMsg (nMsg);
            goto ERROR_PRECHECK;
            }
         }
      }
   nMsg++;
   }
// Falied to find a MSG that matched the request
lError = SNMPAPI_PDU_INVALID;
ERROR_PRECHECK:
LeaveCriticalSection (&cs_MSG);
if (lError == SNMPAPI_SUCCESS)
   return (SNMPAPI_SUCCESS);
// else...failure case
ERROR_OUT:
return (SaveError (lSession, lError));
} // end_SnmpCancelMsg

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -