Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

732 lines
19 KiB

  1. // wsnmp_vb.c
  2. //
  3. // WinSNMP VarBind Functions and helpers
  4. // Copyright 1995-1997 ACE*COMM Corp
  5. // Rleased to Microsoft under Contract
  6. // Beta 1 version, 970228
  7. // Bob Natale ([email protected])
  8. //
  9. // 980705 - Changed test on return from SnmpMakeVB()
  10. // in SnmpCreateVbl() to "!= SNMPAPI_SUCCESS".
  11. //
  12. #include "winsnmp.inc"
  13. BOOL IsBadReadSMIValue(smiLPCVALUE value)
  14. {
  15. if (IsBadReadPtr((LPVOID)value, sizeof(smiLPCVALUE)))
  16. return TRUE;
  17. switch(value->syntax)
  18. {
  19. case SNMP_SYNTAX_OCTETS:
  20. case SNMP_SYNTAX_BITS:
  21. case SNMP_SYNTAX_OPAQUE:
  22. case SNMP_SYNTAX_IPADDR:
  23. case SNMP_SYNTAX_NSAPADDR:
  24. return IsBadReadPtr((LPVOID)(value->value.string.ptr),
  25. value->value.string.len);
  26. case SNMP_SYNTAX_OID:
  27. return IsBadReadPtr((LPVOID)(value->value.oid.ptr),
  28. value->value.oid.len);
  29. }
  30. return FALSE;
  31. }
  32. SNMPAPI_STATUS SnmpMakeVB (smiLPCOID name,
  33. smiLPCVALUE value,
  34. LPVARBIND FAR *pvb)
  35. {
  36. LPVARBIND vb;
  37. if (!(vb =(LPVARBIND)GlobalAlloc (GPTR, sizeof(VARBIND))))
  38. return (SNMPAPI_ALLOC_ERROR);
  39. vb->next_var = NULL;
  40. vb->name.ptr = NULL;
  41. if (vb->name.len = name->len) // Deliberate assignment in conditional
  42. {
  43. if (name->ptr)
  44. {
  45. smiUINT32 len = vb->name.len * sizeof(smiUINT32);
  46. if (vb->name.ptr = (smiLPUINT32)GlobalAlloc (GPTR, len))
  47. CopyMemory (vb->name.ptr, name->ptr, len);
  48. }
  49. }
  50. if (!vb->name.ptr)
  51. {
  52. FreeVarBind (vb);
  53. return (SNMPAPI_OID_INVALID);
  54. }
  55. //
  56. if (value)
  57. {
  58. switch (value->syntax)
  59. {
  60. case SNMP_SYNTAX_OCTETS:
  61. // case SNMP_SYNTAX_BITS: -- removed per Bob Natale mail from 10/09/98
  62. case SNMP_SYNTAX_OPAQUE:
  63. case SNMP_SYNTAX_IPADDR:
  64. case SNMP_SYNTAX_NSAPADDR:
  65. vb->value.value.string.ptr = NULL;
  66. if (vb->value.value.string.len = value->value.string.len)
  67. { // Deliberate assignment, above and below
  68. if (!(vb->value.value.string.ptr =
  69. (smiLPBYTE)GlobalAlloc (GPTR, value->value.string.len)))
  70. {
  71. FreeVarBind (vb);
  72. return (SNMPAPI_ALLOC_ERROR);
  73. }
  74. CopyMemory (vb->value.value.string.ptr, value->value.string.ptr,
  75. value->value.string.len);
  76. }
  77. break;
  78. case SNMP_SYNTAX_OID:
  79. vb->value.value.oid.ptr = NULL;
  80. if (vb->value.value.oid.len = value->value.oid.len)
  81. { // Deliberate assignment, above and below
  82. smiUINT32 len = value->value.oid.len * sizeof(smiUINT32);
  83. if (!(vb->value.value.oid.ptr = (smiLPUINT32)GlobalAlloc (GPTR, len)))
  84. {
  85. FreeVarBind (vb);
  86. return (SNMPAPI_ALLOC_ERROR);
  87. }
  88. CopyMemory (vb->value.value.oid.ptr, value->value.oid.ptr, len);
  89. }
  90. break;
  91. case SNMP_SYNTAX_NULL:
  92. case SNMP_SYNTAX_NOSUCHOBJECT:
  93. case SNMP_SYNTAX_NOSUCHINSTANCE:
  94. case SNMP_SYNTAX_ENDOFMIBVIEW:
  95. break;
  96. case SNMP_SYNTAX_INT:
  97. //case SNMP_SYNTAX_INT32: -- it have the same value as above
  98. vb->value.value.sNumber = value->value.sNumber;
  99. break;
  100. case SNMP_SYNTAX_CNTR32:
  101. case SNMP_SYNTAX_GAUGE32:
  102. case SNMP_SYNTAX_TIMETICKS:
  103. case SNMP_SYNTAX_UINT32:
  104. vb->value.value.uNumber = value->value.uNumber;
  105. break;
  106. case SNMP_SYNTAX_CNTR64:
  107. vb->value.value.hNumber = value->value.hNumber;
  108. break;
  109. default:
  110. // Clean up the allocated VarBind structure
  111. FreeVarBind (vb);
  112. return (SNMPAPI_SYNTAX_INVALID);
  113. } // end_switch
  114. vb->value.syntax = value->syntax;
  115. } // end_if
  116. else
  117. vb->value.syntax = SNMP_SYNTAX_NULL;
  118. //
  119. *pvb = vb;
  120. return (SNMPAPI_SUCCESS);
  121. } //end_SnmpMakeVB
  122. LPVARBIND SnmpCopyVbl (LPVARBIND VarBindFrom)
  123. {
  124. SNMPAPI_STATUS status;
  125. LPVARBIND VarBindTo;
  126. LPVARBIND VarBindToPrev;
  127. LPVARBIND VarBindNewFrom = NULL; // base VB address
  128. DWORD count = 0;
  129. while (VarBindFrom)
  130. {
  131. status = SnmpMakeVB (&VarBindFrom->name, &VarBindFrom->value, &VarBindTo);
  132. if (status != SNMPAPI_SUCCESS)
  133. {
  134. FreeVarBindList(VarBindNewFrom); // Checks for NULL
  135. VarBindNewFrom = NULL;
  136. SaveError (0, status);
  137. break;
  138. }
  139. if (!count)
  140. VarBindNewFrom = VarBindTo;
  141. else
  142. VarBindToPrev->next_var = VarBindTo;
  143. VarBindToPrev = VarBindTo;
  144. VarBindFrom = VarBindFrom->next_var;
  145. count++;
  146. }
  147. return (VarBindNewFrom);
  148. } // end_SnmpCopyVBL
  149. HSNMP_VBL SNMPAPI_CALL
  150. SnmpCreateVbl (IN HSNMP_SESSION hSession,
  151. IN smiLPCOID name,
  152. IN smiLPCVALUE value)
  153. {
  154. DWORD nVbl;
  155. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  156. HSNMP_SESSION lSession = 0;
  157. LPVARBIND VarBindPtr = NULL; // must initialize to NULL
  158. LPVBLS pVbl;
  159. if (TaskData.hTask == 0)
  160. {
  161. lError = SNMPAPI_NOT_INITIALIZED;
  162. goto ERROR_OUT;
  163. }
  164. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  165. {
  166. lError = SNMPAPI_SESSION_INVALID;
  167. goto ERROR_OUT;
  168. }
  169. lSession = hSession; // save it for possible error return
  170. if (name != NULL)
  171. {
  172. if (IsBadReadPtr((LPVOID)name, sizeof(smiOID)))
  173. {
  174. lError = SNMPAPI_ALLOC_ERROR;
  175. goto ERROR_OUT;
  176. }
  177. if (name->len != 0 &&
  178. name->ptr != NULL &&
  179. IsBadReadPtr((LPVOID)name->ptr, name->len))
  180. {
  181. lError = SNMPAPI_ALLOC_ERROR;
  182. goto ERROR_OUT;
  183. }
  184. }
  185. if (value != NULL &&
  186. IsBadReadSMIValue(value))
  187. {
  188. lError = SNMPAPI_ALLOC_ERROR;
  189. goto ERROR_OUT;
  190. }
  191. // We have a valid session at this point...
  192. if (name != NULL && name->ptr != NULL)
  193. {
  194. lError = SnmpMakeVB (name, value, &VarBindPtr);
  195. if (lError != SNMPAPI_SUCCESS)
  196. goto ERROR_OUT;
  197. else
  198. VarBindPtr->next_var = NULL;
  199. }
  200. EnterCriticalSection (&cs_VBL);
  201. lError = snmpAllocTableEntry(&VBLsDescr, &nVbl);
  202. if (lError != SNMPAPI_SUCCESS)
  203. goto ERROR_PRECHECK;
  204. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  205. pVbl->Session = hSession;
  206. pVbl->vbList = VarBindPtr;
  207. ERROR_PRECHECK:
  208. LeaveCriticalSection (&cs_VBL);
  209. if (lError == SNMPAPI_SUCCESS)
  210. return ((HSNMP_VBL) ULongToPtr(nVbl+1));
  211. ERROR_OUT:
  212. FreeVarBind (VarBindPtr); // Hnadles NULL case
  213. return ((HSNMP_VBL) ULongToPtr(SaveError(lSession, lError)));
  214. } // end_SnmpCreateVbl
  215. // SnmpSetVb
  216. SNMPAPI_STATUS SNMPAPI_CALL
  217. SnmpSetVb(IN HSNMP_VBL hVbl,
  218. IN smiUINT32 index,
  219. IN smiLPCOID name,
  220. IN smiLPCVALUE value)
  221. {
  222. DWORD nVbl = HandleToUlong(hVbl) - 1;
  223. LPVARBIND VarBindList = NULL;
  224. LPVARBIND VarBindPtr = NULL;
  225. LPVARBIND VarBindPrev = NULL;
  226. SNMPAPI_STATUS lError = 0;
  227. HSNMP_SESSION lSession = 0;
  228. smiUINT32 i;
  229. LPVBLS pVbl;
  230. if (TaskData.hTask == 0)
  231. {
  232. lError = SNMPAPI_NOT_INITIALIZED;
  233. goto ERROR_OUT;
  234. }
  235. if (!snmpValidTableEntry(&VBLsDescr, nVbl))
  236. {
  237. lError = SNMPAPI_VBL_INVALID;
  238. goto ERROR_OUT;
  239. }
  240. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  241. // We have a valid session at this point...
  242. lSession = pVbl->Session; // save it for possible error return
  243. i = SnmpCountVbl (hVbl);
  244. // make sure the index has a valid value
  245. if ( index > i) // index is unsigned long => no need to test for (index < 0)
  246. {
  247. lError = SNMPAPI_INDEX_INVALID;
  248. goto ERROR_OUT;
  249. }
  250. // check for valid data in 'name' parameter
  251. if (IsBadReadPtr((LPVOID)name, sizeof(smiOID)))
  252. {
  253. // if index points to an existent varbind and the
  254. // name parameter was not provided, take it from the
  255. // original varbind.
  256. if (index != 0 && name == NULL)
  257. {
  258. smiUINT32 iVar;
  259. // look for the original varbind
  260. for (iVar = 1, VarBindPtr = pVbl->vbList;
  261. iVar < index;
  262. iVar++, VarBindPtr = VarBindPtr->next_var);
  263. // make name to point to that varbind name
  264. name = &(VarBindPtr->name);
  265. }
  266. else
  267. {
  268. // either adding a value with NULL OID or specifying an
  269. // invalid value for 'name' is an SNMPAPI_ALLOC_ERROR
  270. lError = SNMPAPI_ALLOC_ERROR;
  271. goto ERROR_OUT;
  272. }
  273. }
  274. // If the index is 0 then a new varbind is to be added to the list.
  275. // If it is non-zero it references a varbind in the list.
  276. // Except we are currently allow index = count+1 to signal add to
  277. // accommodate FTP Software's faulty implementation as used by HP OpenView
  278. if (!index) // Allow 0 for FTP/HP OpenView mistake
  279. index = i+1; // But make it look like the right thing!
  280. if (name->len != 0 &&
  281. name->ptr != NULL &&
  282. IsBadReadPtr((LPVOID)name->ptr, name->len))
  283. {
  284. lError = SNMPAPI_OID_INVALID;
  285. goto ERROR_OUT;
  286. }
  287. if (value != NULL &&
  288. IsBadReadSMIValue(value))
  289. {
  290. lError = SNMPAPI_ALLOC_ERROR;
  291. goto ERROR_OUT;
  292. }
  293. lError = SnmpMakeVB (name, value, &VarBindPtr);
  294. if (lError != SNMPAPI_SUCCESS)
  295. goto ERROR_OUT;
  296. VarBindPrev = VarBindList = pVbl->vbList;
  297. if (index == i+1)
  298. { // Adding a VarBind
  299. if (VarBindList)
  300. {
  301. while (VarBindList->next_var != NULL)
  302. VarBindList = VarBindList->next_var;
  303. VarBindList->next_var = VarBindPtr;
  304. }
  305. else
  306. {
  307. VarBindList = VarBindPtr;
  308. pVbl->vbList = VarBindPtr;
  309. }
  310. }
  311. else
  312. { // Updating a VarBind
  313. for (i = 1; i < index; i++)
  314. { // Position and prepare
  315. VarBindPrev = VarBindList;
  316. VarBindList = VarBindList->next_var;
  317. } // end_for
  318. // Replace
  319. VarBindPtr->next_var = VarBindList->next_var;
  320. VarBindPrev->next_var = VarBindPtr;
  321. if (index == 1)
  322. pVbl->vbList = VarBindPtr;
  323. FreeVarBind (VarBindList);
  324. } // end_else
  325. return (index);
  326. ERROR_OUT:
  327. return (SaveError (lSession, lError));
  328. } // end_SnmpSetVb
  329. HSNMP_VBL SNMPAPI_CALL
  330. SnmpDuplicateVbl (IN HSNMP_SESSION hSession, IN HSNMP_VBL hVbl)
  331. {
  332. DWORD lVbl;
  333. DWORD nVbl;
  334. SNMPAPI_STATUS lError = SNMPAPI_SUCCESS;
  335. HSNMP_SESSION lSession = 0;
  336. LPVBLS pVblOld, pVblNew;
  337. if (TaskData.hTask == 0)
  338. {
  339. lError = SNMPAPI_NOT_INITIALIZED;
  340. goto ERROR_OUT;
  341. }
  342. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  343. {
  344. lError = SNMPAPI_SESSION_INVALID;
  345. goto ERROR_OUT;
  346. }
  347. // We have a valid session at this point...
  348. lSession = hSession; // save it for possible error return
  349. lVbl = HandleToUlong(hVbl) - 1;
  350. if (!snmpValidTableEntry(&VBLsDescr, lVbl))
  351. {
  352. lError = SNMPAPI_VBL_INVALID;
  353. goto ERROR_OUT;
  354. }
  355. pVblOld = snmpGetTableEntry(&VBLsDescr, lVbl);
  356. EnterCriticalSection (&cs_VBL);
  357. lError = snmpAllocTableEntry(&VBLsDescr, &nVbl);
  358. if (lError != SNMPAPI_SUCCESS)
  359. goto ERROR_PRECHECK;
  360. pVblNew = snmpGetTableEntry(&VBLsDescr, nVbl);
  361. if (pVblOld->vbList)
  362. { // Deliberate assignment follows
  363. if (!(pVblNew->vbList = SnmpCopyVbl (pVblOld->vbList)))
  364. { // Inherit error code from SnmpCopy Vbl
  365. snmpFreeTableEntry(&VBLsDescr, nVbl);
  366. lError = SNMPAPI_ALLOC_ERROR;
  367. goto ERROR_PRECHECK;
  368. }
  369. }
  370. pVblNew->Session = hSession;
  371. ERROR_PRECHECK:
  372. LeaveCriticalSection (&cs_VBL);
  373. if (lError == SNMPAPI_SUCCESS)
  374. return ((HSNMP_VBL) ULongToPtr(nVbl+1));
  375. ERROR_OUT:
  376. return ((HSNMP_VBL) ULongToPtr(SaveError(lSession, lError)));
  377. } // end_SnmpDuplicateVbl
  378. // SnmpFreeVbl
  379. SNMPAPI_STATUS SNMPAPI_CALL
  380. SnmpFreeVbl (IN HSNMP_VBL hVbl)
  381. {
  382. DWORD nVbl = HandleToUlong(hVbl) - 1;
  383. SNMPAPI_STATUS lError = 0;
  384. DWORD i;
  385. LPVBLS pVbl;
  386. if (TaskData.hTask == 0)
  387. {
  388. lError = SNMPAPI_NOT_INITIALIZED;
  389. goto ERROR_OUT;
  390. }
  391. if (!snmpValidTableEntry(&VBLsDescr, nVbl))
  392. {
  393. lError = SNMPAPI_VBL_INVALID;
  394. goto ERROR_OUT;
  395. }
  396. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  397. EnterCriticalSection (&cs_PDU);
  398. if (PDUsDescr.Used)
  399. {
  400. for (i = 0; i < PDUsDescr.Allocated; i++)
  401. {
  402. LPPDUS pPdu = snmpGetTableEntry(&PDUsDescr, i);
  403. if (pPdu->VBL == hVbl)
  404. pPdu->VBL = 0;
  405. }
  406. }
  407. LeaveCriticalSection (&cs_PDU);
  408. EnterCriticalSection (&cs_VBL);
  409. // Free all substructures
  410. FreeVarBindList (pVbl->vbList);
  411. // Clean VBL List
  412. snmpFreeTableEntry(&VBLsDescr, nVbl);
  413. LeaveCriticalSection (&cs_VBL);
  414. return (SNMPAPI_SUCCESS);
  415. //
  416. ERROR_OUT:
  417. return (SaveError (0, lError));
  418. } // end_SnmpFreeVbl
  419. // SnmpCountVbl
  420. SNMPAPI_STATUS SNMPAPI_CALL
  421. SnmpCountVbl (IN HSNMP_VBL hVbl)
  422. {
  423. DWORD nVbl;
  424. smiUINT32 count;
  425. SNMPAPI_STATUS lError;
  426. LPVARBIND VarBindPtr;
  427. HSNMP_SESSION lSession = 0;
  428. LPVBLS pVbl;
  429. if (TaskData.hTask == 0)
  430. {
  431. lError = SNMPAPI_NOT_INITIALIZED;
  432. goto ERROR_OUT;
  433. }
  434. nVbl = HandleToUlong(hVbl) - 1;
  435. if (!snmpValidTableEntry(&VBLsDescr, nVbl))
  436. {
  437. lError = SNMPAPI_VBL_INVALID;
  438. goto ERROR_OUT;
  439. }
  440. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  441. count = 0;
  442. VarBindPtr = pVbl->vbList;
  443. lSession = pVbl->Session;
  444. while (VarBindPtr)
  445. {
  446. VarBindPtr = VarBindPtr->next_var;
  447. count++;
  448. }
  449. if (!count) // No varbinds
  450. {
  451. lError = SNMPAPI_NOOP;
  452. goto ERROR_OUT;
  453. }
  454. return (count);
  455. //
  456. ERROR_OUT:
  457. return (SaveError (lSession, lError));
  458. } // end_SnmpCountVbl
  459. // SnmpDeleteVb
  460. SNMPAPI_STATUS SNMPAPI_CALL
  461. SnmpDeleteVb (IN HSNMP_VBL hVbl, IN smiUINT32 index)
  462. {
  463. DWORD nVbl = HandleToUlong(hVbl) - 1;
  464. HSNMP_SESSION hSession;
  465. smiUINT32 status;
  466. smiUINT32 lError = 0;
  467. HSNMP_SESSION lSession = 0;
  468. UINT i= 0;
  469. LPVARBIND VarBindList;
  470. LPVARBIND VarBindPtr;
  471. LPVARBIND VarBindPrev;
  472. LPVBLS pVbl;
  473. if (TaskData.hTask == 0)
  474. {
  475. lError = SNMPAPI_NOT_INITIALIZED;
  476. goto ERROR_OUT;
  477. }
  478. if (!snmpValidTableEntry(&VBLsDescr, nVbl))
  479. {
  480. lError = SNMPAPI_VBL_INVALID;
  481. goto ERROR_OUT;
  482. }
  483. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  484. hSession = pVbl->Session;
  485. if (!snmpValidTableEntry(&SessDescr, HandleToUlong(hSession)-1))
  486. {
  487. lError = SNMPAPI_SESSION_INVALID;
  488. goto ERROR_OUT;
  489. }
  490. lSession = hSession; // Load for SaveError() return
  491. status = SnmpCountVbl (hVbl);
  492. if ((!index) || (index > status))
  493. {
  494. lError = SNMPAPI_INDEX_INVALID;
  495. goto ERROR_OUT;
  496. }
  497. EnterCriticalSection (&cs_VBL);
  498. // Following cannot be NULL due to passing above test
  499. VarBindPtr = VarBindList = pVbl->vbList;
  500. // Deleting a VarBind
  501. for (i = 1; i <= index; i++)
  502. { // Position
  503. VarBindPrev = VarBindPtr;
  504. VarBindPtr = VarBindList;
  505. VarBindList = VarBindList->next_var;
  506. } // end_for
  507. if (index == 1)
  508. { // Replace
  509. pVbl->vbList = VarBindList;
  510. }
  511. else
  512. { // Skip
  513. VarBindPrev->next_var = VarBindList;
  514. } // end_else
  515. FreeVarBind (VarBindPtr);
  516. LeaveCriticalSection (&cs_VBL);
  517. return (SNMPAPI_SUCCESS);
  518. //
  519. ERROR_OUT:
  520. return (SaveError (lSession, lError));
  521. } // end_SnmpDeleteVb
  522. // SnmpGetVb
  523. SNMPAPI_STATUS SNMPAPI_CALL
  524. SnmpGetVb (IN HSNMP_VBL hVbl,
  525. IN smiUINT32 index,
  526. OUT smiLPOID name,
  527. OUT smiLPVALUE value)
  528. {
  529. DWORD nVbl = HandleToUlong(hVbl) - 1;
  530. LPVARBIND VarBindPtr;
  531. SNMPAPI_STATUS lError = 0;
  532. HSNMP_SESSION lSession = 0;
  533. smiUINT32 nLength;
  534. LPVBLS pVbl;
  535. if (TaskData.hTask == 0)
  536. {
  537. lError = SNMPAPI_NOT_INITIALIZED;
  538. goto ERROR_OUT;
  539. }
  540. if (!snmpValidTableEntry(&VBLsDescr, nVbl))
  541. {
  542. lError = SNMPAPI_VBL_INVALID;
  543. goto ERROR_OUT;
  544. }
  545. pVbl = snmpGetTableEntry(&VBLsDescr, nVbl);
  546. lSession = pVbl->Session;
  547. if (!name && !value)
  548. {
  549. lError = SNMPAPI_NOOP;
  550. goto ERROR_OUT;
  551. }
  552. // Test for output descriptor address validity
  553. if ((name && IsBadWritePtr (name, sizeof(smiOID))) ||
  554. (value && IsBadWritePtr (value, sizeof(smiVALUE))))
  555. {
  556. lError = SNMPAPI_ALLOC_ERROR;
  557. goto ERROR_OUT;
  558. }
  559. nLength = SnmpCountVbl (hVbl);
  560. if ((!index) || (index > nLength))
  561. {
  562. lError = SNMPAPI_INDEX_INVALID;
  563. goto ERROR_OUT;
  564. }
  565. if (!(VarBindPtr = pVbl->vbList))
  566. {
  567. lError = SNMPAPI_VBL_INVALID;
  568. goto ERROR_OUT;
  569. }
  570. // SnmpFillOidValue
  571. for (nLength = 1; nLength < index; nLength++)
  572. VarBindPtr = VarBindPtr->next_var;
  573. if (name != NULL)
  574. {
  575. ZeroMemory (name, sizeof(smiOID));
  576. // Copy the name OID
  577. if ((VarBindPtr->name.len == 0) || (VarBindPtr->name.len > MAXOBJIDSIZE))
  578. {
  579. lError = SNMPAPI_OID_INVALID;
  580. goto ERROR_OUT;
  581. }
  582. nLength = VarBindPtr->name.len * sizeof(smiUINT32);
  583. // App must free following alloc via SnmpFreeDescriptor()
  584. if (!(name->ptr = (smiLPUINT32)GlobalAlloc (GPTR, nLength)))
  585. {
  586. lError = SNMPAPI_ALLOC_ERROR;
  587. goto ERROR_OUT;
  588. }
  589. CopyMemory (name->ptr, VarBindPtr->name.ptr, nLength);
  590. name->len = VarBindPtr->name.len;
  591. }
  592. if (value != NULL)
  593. {
  594. // Initialize output structure
  595. ZeroMemory (value, sizeof(smiVALUE));
  596. // Copy the VALUE structure
  597. switch (VarBindPtr->value.syntax)
  598. {
  599. case SNMP_SYNTAX_OCTETS:
  600. case SNMP_SYNTAX_IPADDR:
  601. case SNMP_SYNTAX_OPAQUE:
  602. case SNMP_SYNTAX_NSAPADDR:
  603. // Do copy only if nLength is non-zero
  604. if (nLength = VarBindPtr->value.value.string.len) // Deliberate assignment
  605. { // App must free following alloc via SnmpFreeDescriptor()
  606. if (!(value->value.string.ptr = (smiLPBYTE)GlobalAlloc (GPTR, nLength)))
  607. {
  608. lError = SNMPAPI_ALLOC_ERROR;
  609. goto ERROR_PRECHECK;
  610. }
  611. CopyMemory (value->value.string.ptr, VarBindPtr->value.value.string.ptr, nLength);
  612. value->value.string.len = nLength;
  613. }
  614. break;
  615. case SNMP_SYNTAX_OID:
  616. nLength = VarBindPtr->value.value.oid.len;
  617. if (nLength > MAXOBJIDSIZE)
  618. {
  619. lError = SNMPAPI_OID_INVALID;
  620. goto ERROR_PRECHECK;
  621. }
  622. if (nLength)
  623. { // Do copy only if nLength is non-zero
  624. nLength *= sizeof(smiUINT32);
  625. // App must free following alloc via SnmpFreeDescriptor()
  626. if (!(value->value.oid.ptr = (smiLPUINT32)GlobalAlloc (GPTR, nLength)))
  627. {
  628. lError = SNMPAPI_ALLOC_ERROR;
  629. goto ERROR_PRECHECK;
  630. }
  631. CopyMemory (value->value.oid.ptr,
  632. VarBindPtr->value.value.oid.ptr, nLength);
  633. value->value.oid.len = VarBindPtr->value.value.oid.len;
  634. }
  635. break;
  636. case SNMP_SYNTAX_NULL:
  637. case SNMP_SYNTAX_NOSUCHOBJECT:
  638. case SNMP_SYNTAX_NOSUCHINSTANCE:
  639. case SNMP_SYNTAX_ENDOFMIBVIEW:
  640. // Use initialized (NULL) smiVALUE
  641. break;
  642. case SNMP_SYNTAX_INT:
  643. value->value.sNumber = VarBindPtr->value.value.sNumber;
  644. break;
  645. case SNMP_SYNTAX_CNTR32:
  646. case SNMP_SYNTAX_GAUGE32:
  647. case SNMP_SYNTAX_TIMETICKS:
  648. case SNMP_SYNTAX_UINT32:
  649. value->value.uNumber = VarBindPtr->value.value.uNumber;
  650. break;
  651. case SNMP_SYNTAX_CNTR64:
  652. value->value.hNumber = VarBindPtr->value.value.hNumber;
  653. break;
  654. default:
  655. lError = SNMPAPI_SYNTAX_INVALID;
  656. goto ERROR_PRECHECK;
  657. } // end_switch
  658. value->syntax = VarBindPtr->value.syntax;
  659. }
  660. return (SNMPAPI_SUCCESS);
  661. // Post-name allocation failure modes
  662. ERROR_PRECHECK:
  663. if (name && name->ptr)
  664. {
  665. GlobalFree (name->ptr);
  666. ZeroMemory (name, sizeof(smiOID));
  667. }
  668. if (value && value->value.string.ptr)
  669. {
  670. GlobalFree (value->value.string.ptr);
  671. ZeroMemory (value, sizeof(smiVALUE));
  672. }
  673. ERROR_OUT:
  674. return (SaveError (lSession, lError));
  675. } // end_SnmpGetVb