Source code of Windows XP (NT5)
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.

5990 lines
184 KiB

  1. //
  2. // TODO: Make it multithreaded
  3. //
  4. /*++ BUILD Version: 0001 // Increment this if a change has global effects
  5. Copyright (c) 1991 Microsoft Corporation
  6. Module Name:
  7. winsmib.c
  8. Abstract:
  9. Sample SNMP Extension Agent for Windows NT.
  10. These files (testdll.c, winsmib.c, and winsmib.h) provide an example of
  11. how to structure an Extension Agent DLL which works in conjunction with
  12. the SNMP Extendible Agent for Windows NT.
  13. Extensive comments have been included to describe its structure and
  14. operation. See also "Microsoft Windows/NT SNMP Programmer's Reference".
  15. Created:
  16. 7-Oct-1991
  17. Revision History:
  18. --*/
  19. #ifdef UNICODE
  20. #undef UNICODE
  21. #endif
  22. // This Extension Agent implements the Internet toaster MIB. It's
  23. // definition follows here:
  24. //
  25. //
  26. // Necessary includes.
  27. #include "wins.h"
  28. #include <malloc.h>
  29. #include <snmp.h>
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <string.h>
  33. #include <time.h>
  34. #include <search.h>
  35. #include <winsock2.h>
  36. #include "nmsdb.h"
  37. //#include "winsif.h"
  38. #include "winsintf.h"
  39. #include "winscnf.h"
  40. #include "nmsmsgf.h"
  41. // Contains definitions for the table structure describing the MIB. This
  42. // is used in conjunction with winsmib.c where the MIB requests are resolved.
  43. #include "winsmib.h"
  44. // If an addition or deletion to the MIB is necessary, there are several
  45. // places in the code that must be checked and possibly changed.
  46. //
  47. // The last field in each MIB entry is used to point to the NEXT
  48. // leaf variable. If an addition or deletetion is made, these pointers
  49. // may need to be updated to reflect the modification.
  50. #define _WINS_CNF_KEY TEXT("System\\CurrentControlSet\\Services\\Wins")
  51. #define _WINS_PARAMETERS_KEY TEXT("Parameters")
  52. #define _WINS_PARTNERS_KEY TEXT("Partners")
  53. #define _WINS_DATAFILES_KEY TEXT("Datafiles")
  54. #define _WINS_PULL_KEY TEXT("Pull")
  55. #define _WINS_PUSH_KEY TEXT("Push")
  56. #define NO_FLDS_IN_PULLADD_KEY 8 //Flds are ip add, time interval, sp time
  57. #define NO_FLDS_IN_PUSHADD_KEY 2 //Flds are ip add, update count
  58. #define NO_FLDS_IN_DR 5 //Flds in a data record
  59. #define LOCAL_ADD "127.0.0.1"
  60. #define WINSMIB_FILE_INFO_SIZE 255
  61. #define WINSMIB_DR_CACHE_TIME (120) //2 minutes
  62. BOOL fWinsMibWinsKeyOpen = FALSE;
  63. HKEY WinsMibWinsKey;
  64. STATIC HKEY sParametersKey;
  65. STATIC HKEY sPartnersKey;
  66. STATIC HKEY sPullKey;
  67. STATIC HKEY sPushKey;
  68. STATIC HKEY sDatafilesKey;
  69. STATIC BOOL sfParametersKeyOpen = FALSE;
  70. STATIC BOOL sfPartnersKeyOpen = FALSE;
  71. STATIC BOOL sfDatafilesKeyOpen = FALSE;
  72. STATIC BOOL sfPullKeyOpen = FALSE;
  73. STATIC BOOL sfPushKeyOpen = FALSE;
  74. STATIC time_t sDRCacheInitTime = 0;
  75. //
  76. // The prefix to all of the WINS MIB variables is 1.3.6.1.4.1.311.1.2
  77. //
  78. // The last digit -- 2 is for the WINS MIB
  79. //
  80. UINT OID_Prefix[] = { 1, 3, 6, 1, 4, 1, 311, 1 , 2};
  81. AsnObjectIdentifier MIB_OidPrefix = { OID_SIZEOF(OID_Prefix), OID_Prefix };
  82. BOOL fWinsMibWinsStatusCnfCalled;
  83. BOOL fWinsMibWinsStatusStatCalled;
  84. WINSINTF_BIND_DATA_T sBindData;
  85. WINSINTF_RECS_T sRecs = {0};
  86. //
  87. // Definition of the Wins MIB (not used)
  88. //
  89. //UINT MIB_Wins[] = { 2 };
  90. //
  91. // OID definitions for MIB
  92. //
  93. //
  94. // Definition of group and leaf variables under the wins group
  95. // All leaf variables have a zero appended to their OID to indicate
  96. // that it is the only instance of this variable and it exists.
  97. //
  98. UINT MIB_Parameters[] = { 1 };
  99. UINT MIB_WinsStartTime[] = { 1, 1, 0 };
  100. UINT MIB_LastPScvTime[] = { 1, 2, 0 };
  101. UINT MIB_LastATScvTime[] = { 1, 3, 0 };
  102. UINT MIB_LastTombScvTime[] = { 1, 4, 0 };
  103. UINT MIB_LastVerifyScvTime[] = { 1, 5, 0 };
  104. UINT MIB_LastPRplTime[] = { 1, 6, 0 };
  105. UINT MIB_LastATRplTime[] = { 1, 7, 0 };
  106. UINT MIB_LastNTRplTime[] = { 1, 8, 0 };
  107. UINT MIB_LastACTRplTime[] = { 1, 9, 0 };
  108. UINT MIB_LastInitDbTime[] = { 1, 10, 0 };
  109. UINT MIB_LastCounterResetTime[] = { 1, 11, 0 };
  110. UINT MIB_WinsTotalNoOfReg[] = { 1, 12, 0 };
  111. UINT MIB_WinsTotalNoOfQueries[] = { 1, 13, 0 };
  112. UINT MIB_WinsTotalNoOfRel[] = { 1, 14, 0 };
  113. UINT MIB_WinsTotalNoOfSuccRel[] = { 1, 15, 0 };
  114. UINT MIB_WinsTotalNoOfFailRel[] = { 1, 16, 0 };
  115. UINT MIB_WinsTotalNoOfSuccQueries[] = { 1, 17, 0 };
  116. UINT MIB_WinsTotalNoOfFailQueries[] = { 1, 18, 0 };
  117. UINT MIB_RefreshInterval[] = { 1, 19, 0 };
  118. UINT MIB_TombstoneInterval[] = { 1, 20, 0 };
  119. UINT MIB_TombstoneTimeout[] = { 1, 21, 0 };
  120. UINT MIB_VerifyInterval[] = { 1, 22, 0 };
  121. UINT MIB_VersCounterStartVal_LowWord[] = { 1, 23, 0 };
  122. UINT MIB_VersCounterStartVal_HighWord[] = { 1, 24, 0 };
  123. UINT MIB_RplOnlyWCnfPnrs[] = { 1, 25, 0 };
  124. UINT MIB_StaticDataInit[] = { 1, 26, 0 };
  125. UINT MIB_LogFlag[] = { 1, 27, 0 };
  126. UINT MIB_LogFileName[] = { 1, 28, 0 };
  127. UINT MIB_BackupDirPath[] = { 1, 29, 0 };
  128. UINT MIB_DoBackupOnTerm[] = { 1, 30, 0 };
  129. UINT MIB_MigrateOn[] = { 1, 31, 0 };
  130. //
  131. // Pull mib vars
  132. //
  133. UINT MIB_Pull[] = { 2 };
  134. UINT MIB_PullInitTime[] = { 2, 1, 0 };
  135. UINT MIB_CommRetryCount[] = { 2, 2, 0 };
  136. UINT MIB_PullPnrTable[] = { 2, 3};
  137. UINT MIB_PullPnrTableEntry[] = { 2, 3, 1};
  138. //
  139. // Push mib vars
  140. //
  141. UINT MIB_Push[] = { 3 };
  142. UINT MIB_PushInitTime[] = { 3, 1, 0 };
  143. UINT MIB_RplOnAddChg[] = { 3, 2, 0 };
  144. UINT MIB_PushPnrTable[] = { 3, 3};
  145. UINT MIB_PushPnrTableEntry[] = { 3, 3, 1};
  146. //
  147. // Datafile mib vars
  148. //
  149. UINT MIB_Datafiles[] = { 4 };
  150. UINT MIB_DatafilesTable[] = { 4 , 1};
  151. UINT MIB_DatafilesTableEntry[] = { 4 , 1, 1};
  152. //
  153. // Cmd mib Vars
  154. UINT MIB_Cmd[] = { 5 };
  155. UINT MIB_PullTrigger[] = { 5, 1, 0};
  156. UINT MIB_PushTrigger[] = { 5, 2, 0};
  157. UINT MIB_DeleteWins[] = { 5, 3, 0};
  158. UINT MIB_DoScavenging[] = { 5, 4, 0};
  159. UINT MIB_DoStaticInit[] = { 5, 5, 0};
  160. UINT MIB_NoOfWrkThds[] = { 5, 6, 0};
  161. UINT MIB_PriorityClass[] = { 5, 7, 0};
  162. UINT MIB_ResetCounters[] = { 5, 8, 0};
  163. UINT MIB_DeleteDbRecs[] = { 5, 9, 0};
  164. UINT MIB_GetDbRecs[] = { 5, 10, 0};
  165. UINT MIB_DbRecsTable[] = { 5, 11};
  166. UINT MIB_DbRecsTableEntry[] = { 5, 11, 1};
  167. UINT MIB_MaxVersNo_LowWord[] = { 5, 12, 0 };
  168. UINT MIB_MaxVersNo_HighWord[] = { 5, 13, 0 };
  169. //
  170. // //
  171. // Storage definitions for MIB //
  172. // //
  173. // Parameters group
  174. char MIB_WinsStartTimeStore[80];
  175. char MIB_LastPScvTimeStore[80];
  176. char MIB_LastATScvTimeStore[80];
  177. char MIB_LastTombScvTimeStore[80];
  178. char MIB_LastVerifyScvTimeStore[80];
  179. char MIB_LastPRplTimeStore[80];
  180. char MIB_LastATRplTimeStore[80];
  181. char MIB_LastNTRplTimeStore[80];
  182. char MIB_LastACTRplTimeStore[80];
  183. char MIB_LastInitDbTimeStore[80];
  184. char MIB_LastCounterResetTimeStore[80];
  185. AsnCounter MIB_WinsTotalNoOfRegStore = 0;
  186. AsnCounter MIB_WinsTotalNoOfQueriesStore = 0;
  187. AsnCounter MIB_WinsTotalNoOfRelStore = 0;
  188. AsnCounter MIB_WinsTotalNoOfSuccRelStore = 0;
  189. AsnCounter MIB_WinsTotalNoOfFailRelStore = 0;
  190. AsnCounter MIB_WinsTotalNoOfSuccQueriesStore = 0;
  191. AsnCounter MIB_WinsTotalNoOfFailQueriesStore = 0;
  192. AsnInteger MIB_RefreshIntervalStore = 0;
  193. AsnInteger MIB_TombstoneIntervalStore = 0;
  194. AsnInteger MIB_TombstoneTimeoutStore = 0;
  195. AsnInteger MIB_VerifyIntervalStore = 0;
  196. AsnCounter MIB_VersCounterStartVal_HighWordStore = 0;
  197. AsnCounter MIB_VersCounterStartVal_LowWordStore = 0;
  198. AsnInteger MIB_RplOnlyWCnfPnrsStore = 0;
  199. AsnInteger MIB_StaticDataInitStore = 0;
  200. AsnInteger MIB_LogFlagStore = 1;
  201. char MIB_LogFileNameStore[256];
  202. char MIB_BackupDirPathStore[256];
  203. AsnInteger MIB_DoBackupOnTermStore = 0;
  204. AsnInteger MIB_MigrateOnStore = 0;
  205. //Pull
  206. AsnInteger MIB_PullInitTimeStore = 1 ;
  207. AsnInteger MIB_CommRetryCountStore = 0 ;
  208. //PullPnr
  209. char MIB_SpTimeStore[256];
  210. AsnInteger MIB_TimeIntervalStore = 0 ;
  211. AsnInteger MIB_MemberPrecStore = 0 ;
  212. //Push
  213. AsnInteger MIB_RplOnAddChgStore = 0;
  214. //PushPnr
  215. AsnInteger MIB_PushInitTimeStore = 0 ;
  216. AsnInteger MIB_UpdateCountStore = 0 ;
  217. //
  218. // Cmd
  219. //
  220. char MIB_PullTriggerStore[10]; // double the size to store the old value in case of failure
  221. char MIB_PushTriggerStore[10]; // double the size to store the old value in case of failure
  222. char MIB_DeleteWinsStore[10];
  223. AsnInteger MIB_DoScavengingStore;
  224. char MIB_DoStaticInitStore[WINSMIB_FILE_INFO_SIZE] = {EOS};
  225. AsnInteger MIB_NoOfWrkThdsStore;
  226. AsnInteger MIB_PriorityClassStore;
  227. AsnInteger MIB_ResetCountersStore;
  228. char MIB_DeleteDbRecsStore[10];
  229. char MIB_GetDbRecsStore[5] = {0};
  230. AsnInteger MIB_MaxVersNo_LowWordStore;
  231. AsnInteger MIB_MaxVersNo_HighWordStore;
  232. CRITICAL_SECTION WinsMibCrtSec;
  233. //
  234. // Value Id.
  235. //
  236. // NOTE NOTE NOTE: The sequence must be the same as in VarInfo[]
  237. //
  238. typedef enum _VAL_ID_E {
  239. //values for the Parameters Key
  240. REF_INTVL_E = 0,
  241. TOMB_INTVL_E,
  242. TOMB_TMOUT_E,
  243. VER_INTVL_E,
  244. VERS_COUNT_LW_E,
  245. VERS_COUNT_HW_E,
  246. RPL_ONLY_W_CNF_PNRS_E,
  247. STATIC_DATA_INIT_E,
  248. LOG_FLAG_E,
  249. LOG_FILE_NAME_E,
  250. BACKUP_DIR_PATH_E,
  251. DO_BACKUP_ON_TERM_E,
  252. MIGRATE_ON_E,
  253. //values for the Pull Key
  254. COMM_RETRY_E,
  255. PULL_INIT_TIME_E,
  256. //values for pnrs under the pull key
  257. SP_TIME_E,
  258. TIME_INTVL_E,
  259. MEMBER_PREC_E,
  260. //values for the Push Key
  261. PUSH_INIT_TIME_E,
  262. //values for pnrs under the push key
  263. RPL_ON_ADD_CHG_E,
  264. UPD_CNT_E
  265. } VAL_ID_E, *PVAL_ID_E;
  266. //
  267. // Holds information about partners (pull/push) used for accessing the
  268. // Pull and Push partner tables
  269. //
  270. typedef struct _ADD_KEY_T {
  271. BYTE asIpAddress[20];
  272. DWORD IpAdd;
  273. BYTE asSpTime[20];
  274. BOOL fSpTimeSet;
  275. union {
  276. DWORD TimeInterval;
  277. DWORD UpdateCount;
  278. };
  279. BOOL fTimeIntOrUpdCntSet;
  280. DWORD MemberPrec;
  281. DWORD NoOfRpls;
  282. DWORD NoOfCommFails;
  283. WINSINTF_VERS_NO_T VersNo;
  284. } ADD_KEY_T, *PADD_KEY_T;
  285. typedef struct _DATAFILE_INFO_T {
  286. TCHAR FileNm[WINSMIB_FILE_INFO_SIZE];
  287. DWORD StrType;
  288. TCHAR ValNm[10];
  289. } DATAFILE_INFO_T, *PDATAFILE_INFO_T;
  290. #define DATAFILE_INFO_SZ sizeof(DATAFILE_INFO_T)
  291. //
  292. // holds info about variable used when accessing registry.
  293. //
  294. typedef struct _VAR_INFO_T {
  295. LPDWORD pId; //Oid under WINS
  296. LPBYTE pName;
  297. LPVOID pStorage;
  298. VAL_ID_E Val_Id_e;
  299. DWORD ValType;
  300. DWORD SizeOfData;
  301. HKEY *pRootKey;
  302. } VARINFO_T, *PVARINFO_T;
  303. //
  304. // This array comprises of stuff that needs to be read from/written to
  305. // the registry.
  306. //
  307. VARINFO_T VarInfo[] = {
  308. {
  309. &MIB_RefreshInterval[1],
  310. { WINSCNF_REFRESH_INTVL_NM },
  311. &MIB_RefreshIntervalStore,
  312. REF_INTVL_E,
  313. REG_DWORD,
  314. sizeof(DWORD),
  315. &sParametersKey
  316. },
  317. {
  318. &MIB_TombstoneInterval[1],
  319. WINSCNF_TOMBSTONE_INTVL_NM,
  320. &MIB_TombstoneIntervalStore,
  321. TOMB_INTVL_E,
  322. REG_DWORD,
  323. sizeof(DWORD),
  324. &sParametersKey
  325. },
  326. {
  327. &MIB_TombstoneTimeout[1],
  328. WINSCNF_TOMBSTONE_TMOUT_NM,
  329. &MIB_TombstoneTimeoutStore,
  330. TOMB_TMOUT_E,
  331. REG_DWORD,
  332. sizeof(DWORD),
  333. &sParametersKey
  334. },
  335. {
  336. &MIB_VerifyInterval[1],
  337. WINSCNF_VERIFY_INTVL_NM,
  338. &MIB_VerifyIntervalStore,
  339. VER_INTVL_E,
  340. REG_DWORD,
  341. sizeof(DWORD),
  342. &sParametersKey
  343. },
  344. {
  345. &MIB_VersCounterStartVal_LowWord[1],
  346. WINSCNF_INIT_VERSNO_VAL_LW_NM,
  347. &MIB_VersCounterStartVal_LowWordStore,
  348. VERS_COUNT_LW_E,
  349. REG_DWORD,
  350. sizeof(DWORD),
  351. &sParametersKey
  352. },
  353. {
  354. &MIB_VersCounterStartVal_HighWord[1],
  355. WINSCNF_INIT_VERSNO_VAL_HW_NM,
  356. &MIB_VersCounterStartVal_HighWordStore,
  357. VERS_COUNT_HW_E,
  358. REG_DWORD,
  359. sizeof(DWORD),
  360. &sParametersKey
  361. },
  362. {
  363. &MIB_RplOnlyWCnfPnrs[1],
  364. WINSCNF_RPL_ONLY_W_CNF_PNRS_NM,
  365. &MIB_RplOnlyWCnfPnrsStore,
  366. RPL_ONLY_W_CNF_PNRS_E,
  367. REG_DWORD,
  368. sizeof(DWORD),
  369. &sParametersKey
  370. },
  371. {
  372. &MIB_StaticDataInit[1],
  373. WINSCNF_STATIC_INIT_FLAG_NM,
  374. &MIB_StaticDataInitStore,
  375. STATIC_DATA_INIT_E,
  376. REG_DWORD,
  377. sizeof(DWORD),
  378. &sParametersKey
  379. },
  380. {
  381. &MIB_LogFlag[1],
  382. WINSCNF_LOG_FLAG_NM,
  383. &MIB_LogFlagStore,
  384. LOG_FLAG_E,
  385. REG_DWORD,
  386. sizeof(DWORD),
  387. &sParametersKey
  388. },
  389. {
  390. &MIB_LogFileName[1],
  391. WINSCNF_LOG_FILE_PATH_NM,
  392. &MIB_LogFileNameStore,
  393. LOG_FILE_NAME_E,
  394. REG_EXPAND_SZ,
  395. sizeof(MIB_LogFileNameStore),
  396. &sParametersKey
  397. },
  398. {
  399. &MIB_BackupDirPath[1],
  400. WINSCNF_BACKUP_DIR_PATH_NM,
  401. &MIB_BackupDirPathStore,
  402. BACKUP_DIR_PATH_E,
  403. REG_EXPAND_SZ,
  404. sizeof(MIB_BackupDirPathStore),
  405. &sParametersKey
  406. },
  407. {
  408. &MIB_DoBackupOnTerm[1],
  409. WINSCNF_DO_BACKUP_ON_TERM_NM,
  410. &MIB_DoBackupOnTermStore,
  411. DO_BACKUP_ON_TERM_E,
  412. REG_DWORD,
  413. sizeof(DWORD),
  414. &sParametersKey
  415. },
  416. {
  417. &MIB_MigrateOn[1],
  418. WINSCNF_MIGRATION_ON_NM,
  419. &MIB_MigrateOnStore,
  420. MIGRATE_ON_E,
  421. REG_DWORD,
  422. sizeof(DWORD),
  423. &sParametersKey
  424. },
  425. {
  426. &MIB_CommRetryCount[1],
  427. WINSCNF_RETRY_COUNT_NM,
  428. &MIB_CommRetryCountStore,
  429. COMM_RETRY_E,
  430. REG_DWORD,
  431. sizeof(DWORD),
  432. &sPullKey
  433. },
  434. {
  435. &MIB_PullInitTime[1],
  436. WINSCNF_INIT_TIME_RPL_NM,
  437. &MIB_PullInitTimeStore,
  438. PULL_INIT_TIME_E,
  439. REG_DWORD,
  440. sizeof(DWORD),
  441. &sPullKey
  442. },
  443. {
  444. NULL, //&MIB_SpTime[1]
  445. WINSCNF_SP_TIME_NM,
  446. &MIB_SpTimeStore,
  447. SP_TIME_E,
  448. REG_SZ,
  449. sizeof(MIB_SpTimeStore),
  450. &sPullKey
  451. },
  452. {
  453. NULL, //&MIB_TimeInterval[1]
  454. WINSCNF_RPL_INTERVAL_NM,
  455. &MIB_TimeIntervalStore,
  456. TIME_INTVL_E,
  457. REG_DWORD,
  458. sizeof(DWORD),
  459. &sPullKey
  460. },
  461. {
  462. NULL,
  463. WINSCNF_MEMBER_PREC_NM,
  464. &MIB_MemberPrecStore,
  465. MEMBER_PREC_E,
  466. REG_DWORD,
  467. sizeof(DWORD),
  468. &sPullKey
  469. },
  470. {
  471. &MIB_PushInitTime[1],
  472. WINSCNF_INIT_TIME_RPL_NM,
  473. &MIB_PushInitTimeStore,
  474. PUSH_INIT_TIME_E,
  475. REG_DWORD,
  476. sizeof(DWORD),
  477. &sPushKey
  478. },
  479. {
  480. &MIB_RplOnAddChg[1],
  481. WINSCNF_ADDCHG_TRIGGER_NM,
  482. &MIB_RplOnAddChgStore,
  483. RPL_ON_ADD_CHG_E,
  484. REG_DWORD,
  485. sizeof(DWORD),
  486. &sPushKey
  487. },
  488. {
  489. NULL, //&MIB_UpdateCount[1]
  490. WINSCNF_UPDATE_COUNT_NM,
  491. &MIB_UpdateCountStore,
  492. UPD_CNT_E,
  493. REG_DWORD,
  494. sizeof(DWORD),
  495. &sPushKey
  496. }
  497. };
  498. //
  499. // Type of key
  500. //
  501. typedef enum _KEY_TYPE_E {
  502. PARAMETERS_E_KEY,
  503. PARTNERS_E_KEY,
  504. DATAFILES_E_KEY,
  505. PULL_E_KEY,
  506. PUSH_E_KEY,
  507. IPADD_E_KEY
  508. } KEY_TYPE_E, *PKEY_TYPE_E;
  509. //
  510. // Determines if the MIB variable falls in the range requiring access to the
  511. // the registry
  512. //
  513. #define PARAMETERS_VAL_M(pMib) ( \
  514. ((pMib)->Oid.ids[0] == 1) \
  515. && \
  516. ((pMib)->Oid.ids[1] >= 19) \
  517. && \
  518. ((pMib)->Oid.ids[1] <= 31) \
  519. )
  520. //
  521. // All MIB variables in the common group have 1 as their first id
  522. //
  523. #define COMMON_VAL_M(pMib) ((pMib)->Oid.ids[0] == 1)
  524. //
  525. // All MIB variables in the common group have 2 as their first id
  526. //
  527. #define PULL_VAL_M(pMib) ((pMib)->Oid.ids[0] == 2)
  528. //
  529. // All MIB variables in the common group have 3 as their first id
  530. //
  531. #define PUSH_VAL_M(pMib) ((pMib)->Oid.ids[0] == 3)
  532. //
  533. // Finds the enumerator corresponding to the registry parameter
  534. //
  535. #define PARAMETERS_ID_M(pMib, Val_Id_e) { \
  536. if(pMib->Storage==&MIB_RefreshIntervalStore) { Val_Id_e = REF_INTVL_E; }else{\
  537. if(pMib->Storage==&MIB_TombstoneIntervalStore){ Val_Id_e=TOMB_INTVL_E;}else{\
  538. if(pMib->Storage==&MIB_TombstoneTimeoutStore) { Val_Id_e=TOMB_TMOUT_E; }else{\
  539. if(pMib->Storage==&MIB_VerifyIntervalStore) { Val_Id_e = VER_INTVL_E; } else{\
  540. if (pMib->Storage==&MIB_VersCounterStartVal_LowWordStore) { Val_Id_e = VERS_COUNT_LW_E; } else{ \
  541. if (pMib->Storage == &MIB_VersCounterStartVal_HighWordStore) { Val_Id_e = VERS_COUNT_HW_E; } else{ \
  542. if (pMib->Storage == &MIB_RplOnlyWCnfPnrsStore) { Val_Id_e = RPL_ONLY_W_CNF_PNRS_E; } else {\
  543. if (pMib->Storage == &MIB_StaticDataInitStore) { Val_Id_e = STATIC_DATA_INIT_E; } else {\
  544. if (pMib->Storage == &MIB_LogFlagStore) { Val_Id_e = LOG_FLAG_E; } else {\
  545. if (pMib->Storage == &MIB_LogFileNameStore) { Val_Id_e = LOG_FILE_NAME_E; } else {\
  546. if (pMib->Storage == &MIB_BackupDirPathStore) { Val_Id_e = BACKUP_DIR_PATH_E; } else {\
  547. if (pMib->Storage == &MIB_DoBackupOnTermStore) { Val_Id_e = DO_BACKUP_ON_TERM_E; } else {\
  548. if (pMib->Storage == &MIB_MigrateOnStore) { Val_Id_e = MIGRATE_ON_E; } else {\
  549. }}}}}}}}}}}}}}
  550. //
  551. // Finds the enumerator corresponding to the pull group's parameter
  552. //
  553. #define PULL_ID_M(pMib, Val_Id_e) { \
  554. if (pMib->Storage == &MIB_CommRetryCountStore) { Val_Id_e = COMM_RETRY_E; }else{\
  555. if (pMib->Storage == &MIB_PullInitTimeStore) { Val_Id_e = PULL_INIT_TIME_E;} else{\
  556. }}}
  557. //
  558. // Finds the enumerator corresponding to the push group's parameter
  559. //
  560. #define PUSH_ID_M(pMib, Val_Id_e) { \
  561. if (pMib->Storage == &MIB_RplOnAddChgStore) { Val_Id_e = RPL_ON_ADD_CHG_E;} else{\
  562. if (pMib->Storage == &MIB_PushInitTimeStore) { Val_Id_e = PUSH_INIT_TIME_E;}else{ \
  563. }}}
  564. STATIC
  565. UINT
  566. HandleCmd(
  567. IN UINT Action,
  568. IN PMIB_ENTRY pMibPtr,
  569. IN RFC1157VarBind *VarBind
  570. );
  571. STATIC
  572. UINT
  573. ExecuteCmd(
  574. IN PMIB_ENTRY pMibPtr
  575. );
  576. STATIC
  577. UINT
  578. MIB_RWReg(
  579. IN UINT Action,
  580. IN PMIB_ENTRY pMibPtr,
  581. IN RFC1157VarBind *VarBind
  582. );
  583. STATIC
  584. UINT
  585. PullPnrs(
  586. IN UINT Action,
  587. IN PMIB_ENTRY pMibPtr,
  588. IN RFC1157VarBind *VarBind
  589. );
  590. STATIC
  591. UINT
  592. PushPnrs(
  593. IN UINT Action,
  594. IN PMIB_ENTRY pMibPtr,
  595. IN RFC1157VarBind *VarBind
  596. );
  597. STATIC
  598. UINT
  599. MIB_Table(
  600. IN DWORD Index,
  601. IN UINT Action,
  602. IN PMIB_ENTRY pMibPtr,
  603. IN RFC1157VarBind *VarBind,
  604. IN KEY_TYPE_E KeyType_e
  605. );
  606. STATIC
  607. UINT
  608. MIB_PullTable(
  609. IN UINT Action,
  610. IN PMIB_ENTRY pMibPtr,
  611. IN RFC1157VarBind *VarBind
  612. );
  613. STATIC
  614. UINT
  615. MIB_PushTable(
  616. IN UINT Action,
  617. IN PMIB_ENTRY pMibPtr,
  618. IN RFC1157VarBind *VarBind
  619. );
  620. STATIC
  621. UINT
  622. MIB_DFTable(
  623. IN UINT Action,
  624. IN PMIB_ENTRY pMibPtr,
  625. IN RFC1157VarBind *VarBind
  626. );
  627. STATIC
  628. UINT
  629. MIB_DRTable(
  630. IN UINT Action,
  631. IN PMIB_ENTRY pMibPtr,
  632. IN RFC1157VarBind *VarBind
  633. );
  634. STATIC
  635. UINT
  636. WriteDFValue(
  637. IN RFC1157VarBind *pVarBind,
  638. PDATAFILE_INFO_T pDFKey,
  639. DWORD Index
  640. );
  641. STATIC
  642. UINT
  643. MIB_leaf_func(
  644. IN UINT Action,
  645. IN MIB_ENTRY *MibPtr,
  646. IN RFC1157VarBind *VarBind
  647. );
  648. STATIC
  649. UINT
  650. MIB_Stat(
  651. IN UINT Action,
  652. IN MIB_ENTRY *MibPtr,
  653. IN RFC1157VarBind *VarBind
  654. );
  655. //
  656. // MIB definiton
  657. //
  658. MIB_ENTRY Mib[] = {
  659. //parameters
  660. { { OID_SIZEOF(MIB_Parameters), MIB_Parameters },
  661. NULL, ASN_RFC1155_OPAQUE,
  662. MIB_NOACCESS, NULL, &Mib[1] },
  663. { { OID_SIZEOF(MIB_WinsStartTime), MIB_WinsStartTime },
  664. &MIB_WinsStartTimeStore, ASN_RFC1213_DISPSTRING,
  665. MIB_ACCESS_READ, MIB_Stat, &Mib[2] },
  666. { { OID_SIZEOF(MIB_LastPScvTime), MIB_LastPScvTime },
  667. &MIB_LastPScvTimeStore, ASN_RFC1213_DISPSTRING,
  668. MIB_ACCESS_READ, MIB_Stat, &Mib[3] },
  669. { { OID_SIZEOF(MIB_LastATScvTime), MIB_LastATScvTime },
  670. &MIB_LastATScvTimeStore, ASN_RFC1213_DISPSTRING,
  671. MIB_ACCESS_READ, MIB_Stat, &Mib[4] },
  672. { { OID_SIZEOF(MIB_LastTombScvTime), MIB_LastTombScvTime },
  673. &MIB_LastTombScvTimeStore, ASN_RFC1213_DISPSTRING,
  674. MIB_ACCESS_READ, MIB_Stat, &Mib[5] },
  675. { { OID_SIZEOF(MIB_LastVerifyScvTime), MIB_LastVerifyScvTime },
  676. &MIB_LastVerifyScvTimeStore, ASN_RFC1213_DISPSTRING,
  677. MIB_ACCESS_READ, MIB_Stat, &Mib[6] },
  678. { { OID_SIZEOF(MIB_LastPRplTime), MIB_LastPRplTime },
  679. &MIB_LastPRplTimeStore, ASN_RFC1213_DISPSTRING,
  680. MIB_ACCESS_READ, MIB_Stat, &Mib[7] },
  681. { { OID_SIZEOF(MIB_LastATRplTime), MIB_LastATRplTime },
  682. &MIB_LastATRplTimeStore, ASN_RFC1213_DISPSTRING,
  683. MIB_ACCESS_READ, MIB_Stat, &Mib[8] },
  684. { { OID_SIZEOF(MIB_LastNTRplTime), MIB_LastNTRplTime },
  685. &MIB_LastNTRplTimeStore, ASN_RFC1213_DISPSTRING,
  686. MIB_ACCESS_READ, MIB_Stat, &Mib[9] },
  687. { { OID_SIZEOF(MIB_LastACTRplTime), MIB_LastACTRplTime },
  688. &MIB_LastACTRplTimeStore, ASN_RFC1213_DISPSTRING,
  689. MIB_ACCESS_READ, MIB_Stat, &Mib[10] },
  690. { { OID_SIZEOF(MIB_LastInitDbTime), MIB_LastInitDbTime },
  691. &MIB_LastInitDbTimeStore, ASN_RFC1213_DISPSTRING,
  692. MIB_ACCESS_READ, MIB_Stat, &Mib[11] },
  693. { { OID_SIZEOF(MIB_LastCounterResetTime), MIB_LastCounterResetTime },
  694. &MIB_LastCounterResetTimeStore, ASN_RFC1213_DISPSTRING,
  695. MIB_ACCESS_READ, MIB_Stat, &Mib[12] },
  696. { { OID_SIZEOF(MIB_WinsTotalNoOfReg), MIB_WinsTotalNoOfReg },
  697. &MIB_WinsTotalNoOfRegStore, ASN_RFC1155_COUNTER,
  698. MIB_ACCESS_READ, MIB_Stat, &Mib[13] },
  699. { { OID_SIZEOF(MIB_WinsTotalNoOfQueries), MIB_WinsTotalNoOfQueries },
  700. &MIB_WinsTotalNoOfQueriesStore, ASN_RFC1155_COUNTER,
  701. MIB_ACCESS_READ, MIB_Stat, &Mib[14] },
  702. { { OID_SIZEOF(MIB_WinsTotalNoOfRel), MIB_WinsTotalNoOfRel },
  703. &MIB_WinsTotalNoOfRelStore, ASN_RFC1155_COUNTER,
  704. MIB_ACCESS_READ, MIB_Stat, &Mib[15] },
  705. { { OID_SIZEOF(MIB_WinsTotalNoOfSuccRel), MIB_WinsTotalNoOfSuccRel },
  706. &MIB_WinsTotalNoOfSuccRelStore, ASN_RFC1155_COUNTER,
  707. MIB_ACCESS_READ, MIB_Stat, &Mib[16] },
  708. { { OID_SIZEOF(MIB_WinsTotalNoOfFailRel), MIB_WinsTotalNoOfFailRel },
  709. &MIB_WinsTotalNoOfFailRelStore, ASN_RFC1155_COUNTER,
  710. MIB_ACCESS_READ, MIB_Stat, &Mib[17] },
  711. { { OID_SIZEOF(MIB_WinsTotalNoOfSuccQueries),
  712. MIB_WinsTotalNoOfSuccQueries },
  713. &MIB_WinsTotalNoOfSuccQueriesStore, ASN_RFC1155_COUNTER,
  714. MIB_ACCESS_READ, MIB_Stat, &Mib[18] },
  715. { { OID_SIZEOF(MIB_WinsTotalNoOfFailQueries),
  716. MIB_WinsTotalNoOfFailQueries },
  717. &MIB_WinsTotalNoOfFailQueriesStore, ASN_RFC1155_COUNTER,
  718. MIB_ACCESS_READ, MIB_Stat, &Mib[19] },
  719. { { OID_SIZEOF(MIB_RefreshInterval), MIB_RefreshInterval },
  720. &MIB_RefreshIntervalStore, ASN_INTEGER,
  721. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[20] },
  722. { { OID_SIZEOF(MIB_TombstoneInterval), MIB_TombstoneInterval },
  723. &MIB_TombstoneIntervalStore, ASN_INTEGER,
  724. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[21] },
  725. { { OID_SIZEOF(MIB_TombstoneTimeout), MIB_TombstoneTimeout },
  726. &MIB_TombstoneTimeoutStore, ASN_INTEGER,
  727. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[22] },
  728. { { OID_SIZEOF(MIB_VerifyInterval), MIB_VerifyInterval },
  729. &MIB_VerifyIntervalStore, ASN_INTEGER,
  730. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[23] },
  731. { { OID_SIZEOF(MIB_VersCounterStartVal_LowWord),
  732. MIB_VersCounterStartVal_LowWord },
  733. &MIB_VersCounterStartVal_LowWordStore, ASN_RFC1155_COUNTER,
  734. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[24] },
  735. { { OID_SIZEOF(MIB_VersCounterStartVal_HighWord),
  736. MIB_VersCounterStartVal_HighWord },
  737. &MIB_VersCounterStartVal_HighWordStore, ASN_RFC1155_COUNTER,
  738. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[25] },
  739. { { OID_SIZEOF(MIB_RplOnlyWCnfPnrs), MIB_RplOnlyWCnfPnrs },
  740. &MIB_RplOnlyWCnfPnrsStore, ASN_INTEGER,
  741. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[26] },
  742. { { OID_SIZEOF(MIB_StaticDataInit), MIB_StaticDataInit },
  743. &MIB_StaticDataInitStore, ASN_INTEGER,
  744. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[27] },
  745. { { OID_SIZEOF(MIB_LogFlag), MIB_LogFlag },
  746. &MIB_LogFlagStore, ASN_INTEGER,
  747. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[28] },
  748. { { OID_SIZEOF(MIB_LogFileName), MIB_LogFileName },
  749. &MIB_LogFileNameStore, ASN_RFC1213_DISPSTRING,
  750. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[29] },
  751. { { OID_SIZEOF(MIB_BackupDirPath), MIB_BackupDirPath },
  752. &MIB_BackupDirPathStore, ASN_RFC1213_DISPSTRING,
  753. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[30] },
  754. { { OID_SIZEOF(MIB_DoBackupOnTerm), MIB_DoBackupOnTerm },
  755. &MIB_DoBackupOnTermStore, ASN_INTEGER,
  756. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[31] },
  757. { { OID_SIZEOF(MIB_MigrateOn), MIB_MigrateOn },
  758. &MIB_MigrateOnStore, ASN_INTEGER,
  759. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[32] },
  760. //
  761. // Pull
  762. //
  763. { { OID_SIZEOF(MIB_Pull), MIB_Pull },
  764. NULL, ASN_RFC1155_OPAQUE,
  765. MIB_NOACCESS, NULL, &Mib[33] },
  766. { { OID_SIZEOF(MIB_PullInitTime), MIB_PullInitTime },
  767. &MIB_PullInitTimeStore, ASN_INTEGER,
  768. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[34] },
  769. { { OID_SIZEOF(MIB_CommRetryCount), MIB_CommRetryCount },
  770. &MIB_CommRetryCountStore, ASN_INTEGER,
  771. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[35] },
  772. { { OID_SIZEOF(MIB_PullPnrTable), MIB_PullPnrTable },
  773. NULL, ASN_RFC1155_OPAQUE,
  774. MIB_ACCESS_READWRITE, NULL, &Mib[36] },
  775. { { OID_SIZEOF(MIB_PullPnrTableEntry), MIB_PullPnrTableEntry },
  776. NULL, ASN_SEQUENCE,
  777. MIB_ACCESS_READWRITE, MIB_PullTable, &Mib[37] },
  778. //
  779. // Push
  780. //
  781. { { OID_SIZEOF(MIB_Push), MIB_Push },
  782. NULL, ASN_RFC1155_OPAQUE,
  783. MIB_NOACCESS, NULL, &Mib[38] },
  784. { { OID_SIZEOF(MIB_PushInitTime), MIB_PushInitTime },
  785. &MIB_PushInitTimeStore, ASN_INTEGER,
  786. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[39] },
  787. { { OID_SIZEOF(MIB_RplOnAddChg),
  788. MIB_RplOnAddChg },
  789. &MIB_RplOnAddChgStore, ASN_INTEGER,
  790. MIB_ACCESS_READWRITE, MIB_RWReg, &Mib[40] },
  791. { { OID_SIZEOF(MIB_PushPnrTable), MIB_PushPnrTable },
  792. NULL, ASN_RFC1155_OPAQUE,
  793. MIB_ACCESS_READWRITE, NULL, &Mib[41] },
  794. { { OID_SIZEOF(MIB_PushPnrTableEntry), MIB_PushPnrTableEntry },
  795. NULL, ASN_SEQUENCE,
  796. MIB_ACCESS_READWRITE, MIB_PushTable, &Mib[42] },
  797. //
  798. // Datafiles
  799. //
  800. { { OID_SIZEOF(MIB_Datafiles), MIB_Datafiles },
  801. NULL, ASN_RFC1155_OPAQUE,
  802. MIB_NOACCESS, NULL, &Mib[43] },
  803. { { OID_SIZEOF(MIB_DatafilesTable), MIB_DatafilesTable },
  804. NULL, ASN_RFC1155_OPAQUE,
  805. MIB_ACCESS_READWRITE, NULL, &Mib[44] },
  806. { { OID_SIZEOF(MIB_DatafilesTableEntry), MIB_DatafilesTableEntry },
  807. NULL, ASN_SEQUENCE,
  808. MIB_ACCESS_READWRITE, MIB_DFTable, &Mib[45] },
  809. //
  810. // Cmds
  811. //
  812. { { OID_SIZEOF(MIB_Cmd), MIB_Cmd },
  813. NULL, ASN_RFC1155_OPAQUE,
  814. MIB_NOACCESS, NULL, &Mib[46] },
  815. { { OID_SIZEOF(MIB_PullTrigger), MIB_PullTrigger },
  816. &MIB_PullTriggerStore, ASN_RFC1155_IPADDRESS,
  817. MIB_ACCESS_READWRITE, HandleCmd, &Mib[47] },
  818. { { OID_SIZEOF(MIB_PushTrigger), MIB_PushTrigger },
  819. &MIB_PushTriggerStore, ASN_RFC1155_IPADDRESS,
  820. MIB_ACCESS_READWRITE, HandleCmd, &Mib[48] },
  821. // NOTE: The following command was changed from READWRITE
  822. // to READ only due to security reason.
  823. // Anyone with access to SNMP agent, could delete
  824. // the wins database with this sigle command.
  825. { { OID_SIZEOF(MIB_DeleteWins), MIB_DeleteWins },
  826. &MIB_DeleteWinsStore, ASN_RFC1155_IPADDRESS,
  827. MIB_ACCESS_READ, HandleCmd, &Mib[49] },
  828. { { OID_SIZEOF(MIB_DoScavenging), MIB_DoScavenging },
  829. &MIB_DoScavengingStore, ASN_INTEGER,
  830. MIB_ACCESS_READWRITE, HandleCmd, &Mib[50] },
  831. { { OID_SIZEOF(MIB_DoStaticInit), MIB_DoStaticInit },
  832. &MIB_DoStaticInitStore, ASN_OCTETSTRING,
  833. MIB_ACCESS_READWRITE, HandleCmd, &Mib[51] },
  834. { { OID_SIZEOF(MIB_NoOfWrkThds), MIB_NoOfWrkThds },
  835. &MIB_NoOfWrkThdsStore, ASN_INTEGER,
  836. MIB_ACCESS_READ, HandleCmd, &Mib[52] },
  837. { { OID_SIZEOF(MIB_PriorityClass), MIB_PriorityClass},
  838. &MIB_PriorityClassStore, ASN_INTEGER,
  839. MIB_ACCESS_READ, HandleCmd, &Mib[53] },
  840. { { OID_SIZEOF(MIB_ResetCounters), MIB_ResetCounters},
  841. &MIB_ResetCountersStore, ASN_INTEGER,
  842. MIB_ACCESS_READWRITE, HandleCmd, &Mib[54] },
  843. { { OID_SIZEOF(MIB_DeleteDbRecs), MIB_DeleteDbRecs},
  844. &MIB_DeleteDbRecsStore, ASN_RFC1155_IPADDRESS,
  845. MIB_ACCESS_READWRITE, HandleCmd, &Mib[55] },
  846. { { OID_SIZEOF(MIB_GetDbRecs), MIB_GetDbRecs},
  847. &MIB_GetDbRecsStore, ASN_RFC1155_IPADDRESS,
  848. MIB_ACCESS_READWRITE, HandleCmd, &Mib[56] },
  849. { { OID_SIZEOF(MIB_DbRecsTable), MIB_DbRecsTable },
  850. NULL, ASN_RFC1155_OPAQUE,
  851. MIB_ACCESS_READWRITE, NULL, &Mib[57] },
  852. { { OID_SIZEOF(MIB_DbRecsTableEntry), MIB_DbRecsTableEntry },
  853. NULL, ASN_SEQUENCE,
  854. MIB_ACCESS_READWRITE, MIB_DRTable, &Mib[58] },
  855. { { OID_SIZEOF(MIB_MaxVersNo_LowWord), MIB_MaxVersNo_LowWord },
  856. &MIB_MaxVersNo_LowWordStore, ASN_INTEGER,
  857. MIB_ACCESS_READ, HandleCmd, &Mib[59] },
  858. { { OID_SIZEOF(MIB_MaxVersNo_HighWord), MIB_MaxVersNo_HighWord },
  859. &MIB_MaxVersNo_HighWordStore, ASN_INTEGER,
  860. MIB_ACCESS_READ, HandleCmd, NULL }
  861. };
  862. //
  863. // defines pertaining to tables
  864. //
  865. #define PNR_OIDLEN (MIB_PREFIX_LEN + OID_SIZEOF(MIB_PullPnrTableEntry))
  866. #define PULLPNR_OIDLEN PNR_OIDLEN
  867. #define PUSHPNR_OIDLEN PNR_OIDLEN
  868. #define DR_OIDLEN (MIB_PREFIX_LEN + OID_SIZEOF(MIB_DbRecsTableEntry))
  869. #define DF_OIDLEN (MIB_PREFIX_LEN + OID_SIZEOF(MIB_DatafilesTableEntry))
  870. #define PULL_TABLE_INDEX 0
  871. #define PUSH_TABLE_INDEX 1
  872. #define DF_TABLE_INDEX 2
  873. #define DR_TABLE_INDEX 3
  874. #define NUM_TABLES sizeof(Tables)/sizeof(TAB_INFO_T)
  875. UINT MIB_num_variables = sizeof Mib / sizeof( MIB_ENTRY );
  876. //
  877. // table structure containing the functions to invoke for different actions
  878. // on the table
  879. //
  880. typedef struct _TAB_INFO_T {
  881. UINT (*ti_get)(
  882. RFC1157VarBind *VarBind,
  883. DWORD NoOfKeys,
  884. LPVOID pKey
  885. );
  886. UINT (*ti_getf)(
  887. RFC1157VarBind *VarBind,
  888. PMIB_ENTRY pMibEntry,
  889. KEY_TYPE_E KeyType_e
  890. );
  891. UINT (*ti_getn)(
  892. RFC1157VarBind *VarBind,
  893. PMIB_ENTRY pMibEntry,
  894. KEY_TYPE_E KeyType_e
  895. );
  896. UINT (*ti_set)(
  897. RFC1157VarBind *VarBind
  898. );
  899. PMIB_ENTRY pMibPtr;
  900. } TAB_INFO_T, *PTAB_INFO_T;
  901. STATIC
  902. UINT
  903. WriteReg(
  904. PMIB_ENTRY pMib
  905. );
  906. STATIC
  907. UINT
  908. ReadReg(
  909. PMIB_ENTRY pMib
  910. );
  911. STATIC
  912. UINT
  913. SetVal(
  914. PVARINFO_T pVarInfo
  915. );
  916. STATIC
  917. UINT
  918. GetVal(
  919. PVARINFO_T pVarInfo
  920. );
  921. STATIC
  922. UINT
  923. OpenKey(
  924. KEY_TYPE_E Key_e,
  925. LPBYTE pKeyStr,
  926. HKEY *ptrNewKey,
  927. HKEY *pRootKey,
  928. BOOL fCreateAllowed
  929. );
  930. STATIC
  931. UINT
  932. OpenReqKey(
  933. PMIB_ENTRY pMib,
  934. PVAL_ID_E pVal_Id_e,
  935. BOOL fCreateAllowed
  936. );
  937. STATIC
  938. UINT
  939. CloseReqKey(
  940. VOID
  941. );
  942. STATIC
  943. UINT
  944. GetKeyInfo(
  945. IN HKEY Key,
  946. OUT LPDWORD pNoOfSubKeys,
  947. OUT LPDWORD pNoOfVals
  948. );
  949. STATIC
  950. UINT
  951. PnrGetNext(
  952. IN RFC1157VarBind *VarBind,
  953. IN PMIB_ENTRY pMibPtr,
  954. IN KEY_TYPE_E KeyType_e
  955. );
  956. STATIC
  957. UINT
  958. PullGet(
  959. IN RFC1157VarBind *VarBind,
  960. IN DWORD NumKeys,
  961. IN LPVOID pAddKey
  962. );
  963. STATIC
  964. UINT
  965. PushGet(
  966. IN RFC1157VarBind *VarBind,
  967. IN DWORD NumKeys,
  968. IN LPVOID pAddKey
  969. );
  970. STATIC
  971. UINT
  972. PnrGetFirst(
  973. IN RFC1157VarBind *VarBind,
  974. IN PMIB_ENTRY pMibPtr,
  975. IN KEY_TYPE_E KeyType_e
  976. );
  977. STATIC
  978. UINT
  979. PullSet(
  980. IN RFC1157VarBind *VarBind
  981. );
  982. STATIC
  983. UINT
  984. PushSet(
  985. IN RFC1157VarBind *VarBind
  986. );
  987. STATIC
  988. UINT
  989. PnrMatch(
  990. IN RFC1157VarBind *VarBind,
  991. DWORD NoOfKeys,
  992. IN PADD_KEY_T pAddKey,
  993. IN LPDWORD pIndex,
  994. IN LPDWORD pField,
  995. IN KEY_TYPE_E KeyType_e,
  996. IN UINT PduAction,
  997. IN LPBOOL pfFirst
  998. );
  999. extern
  1000. UINT
  1001. PnrFindNext(
  1002. INT AddKeyNo,
  1003. DWORD NumAddKeys,
  1004. PADD_KEY_T pAddKey
  1005. );
  1006. STATIC
  1007. UINT
  1008. EnumAddKeys(
  1009. KEY_TYPE_E KeyType_e,
  1010. PADD_KEY_T *ppAddKey,
  1011. LPDWORD pNumAddKeys
  1012. );
  1013. STATIC
  1014. UINT
  1015. EnumDataFileKeys(
  1016. PDATAFILE_INFO_T *ppDFValues,
  1017. LPDWORD pNumDFValues
  1018. );
  1019. STATIC
  1020. UINT
  1021. DFSet(
  1022. IN RFC1157VarBind *VarBind
  1023. );
  1024. STATIC
  1025. UINT
  1026. DFGet(
  1027. IN RFC1157VarBind *VarBind,
  1028. IN DWORD NumValues,
  1029. IN LPVOID pKey
  1030. );
  1031. STATIC
  1032. UINT
  1033. DFGetFirst(
  1034. IN RFC1157VarBind *VarBind,
  1035. IN PMIB_ENTRY pMibPtr,
  1036. IN KEY_TYPE_E KeyType_e
  1037. );
  1038. STATIC
  1039. UINT
  1040. DFGetNext(
  1041. IN RFC1157VarBind *VarBind,
  1042. IN PMIB_ENTRY pMibPtr,
  1043. IN KEY_TYPE_E KeyType_e
  1044. );
  1045. STATIC
  1046. DWORD
  1047. PopulateDRCache(
  1048. VOID
  1049. );
  1050. STATIC
  1051. UINT
  1052. DRGetNext(
  1053. IN RFC1157VarBind *VarBind,
  1054. IN PMIB_ENTRY pMibPtr,
  1055. IN KEY_TYPE_E KeyType_e
  1056. );
  1057. STATIC
  1058. UINT
  1059. DRMatch(
  1060. IN RFC1157VarBind *VarBind,
  1061. IN PWINSINTF_RECORD_ACTION_T *ppRow,
  1062. IN LPDWORD pIndex,
  1063. IN LPDWORD pField,
  1064. IN UINT PduAction,
  1065. OUT LPBOOL pfFirst
  1066. );
  1067. STATIC
  1068. int
  1069. __cdecl
  1070. CompareIndexes(
  1071. const VOID *pKey1,
  1072. const VOID *pKey2
  1073. );
  1074. STATIC
  1075. int
  1076. __cdecl
  1077. CompareNames(
  1078. const VOID *pKey1,
  1079. const VOID *pKey2
  1080. );
  1081. // NOTE:
  1082. //
  1083. // Info passed for 2nd and 3rd param is different from other table's GET
  1084. // functions
  1085. //
  1086. STATIC
  1087. UINT
  1088. DRGet(
  1089. IN RFC1157VarBind *VarBind,
  1090. IN DWORD FieldParam,
  1091. IN LPVOID pRowParam
  1092. );
  1093. STATIC
  1094. UINT
  1095. DRGetFirst(
  1096. IN RFC1157VarBind *VarBind,
  1097. IN PMIB_ENTRY pMibPtr,
  1098. IN KEY_TYPE_E KeyType_e
  1099. );
  1100. STATIC
  1101. UINT
  1102. DRSet(
  1103. IN RFC1157VarBind *VarBind
  1104. );
  1105. STATIC
  1106. UINT
  1107. WriteKeyNValues(
  1108. KEY_TYPE_E KeyType_e,
  1109. PADD_KEY_T pAddKey,
  1110. DWORD FieldNo
  1111. );
  1112. STATIC
  1113. VOID
  1114. GetSpTimeData(
  1115. HKEY SubKey,
  1116. PADD_KEY_T pAddKey
  1117. );
  1118. STATIC
  1119. int
  1120. __cdecl
  1121. CompareAdd(
  1122. const VOID *pKey1,
  1123. const VOID *pKey2
  1124. );
  1125. STATIC
  1126. UINT
  1127. GetNextVar(
  1128. IN RFC1157VarBind *pVarBind,
  1129. IN PMIB_ENTRY pMibPtr
  1130. );
  1131. TAB_INFO_T Tables[] = {
  1132. {
  1133. PullGet,
  1134. PnrGetFirst,
  1135. PnrGetNext,
  1136. PullSet,
  1137. &Mib[36]
  1138. },
  1139. {
  1140. PushGet,
  1141. PnrGetFirst,
  1142. PnrGetNext,
  1143. PushSet,
  1144. &Mib[41]
  1145. },
  1146. {
  1147. DFGet,
  1148. DFGetFirst,
  1149. DFGetNext,
  1150. DFSet,
  1151. &Mib[44]
  1152. },
  1153. {
  1154. DRGet,
  1155. DRGetFirst,
  1156. DRGetNext,
  1157. DRSet,
  1158. &Mib[57]
  1159. }
  1160. };
  1161. UINT
  1162. ResolveVarBind(
  1163. IN OUT RFC1157VarBind *VarBind, // Variable Binding to resolve
  1164. IN UINT PduAction // Action specified in PDU
  1165. )
  1166. //
  1167. // ResolveVarBind
  1168. // Resolves a single variable binding. Modifies the variable on a GET
  1169. // or a GET-NEXT.
  1170. //
  1171. // Notes:
  1172. //
  1173. // Return Codes:
  1174. // Standard PDU error codes.
  1175. //
  1176. // Error Codes:
  1177. // None.
  1178. //
  1179. {
  1180. MIB_ENTRY *MibPtr;
  1181. AsnObjectIdentifier TempOid;
  1182. int CompResult;
  1183. UINT I;
  1184. UINT nResult;
  1185. DWORD TableIndex;
  1186. BOOL fTableMatch = FALSE;
  1187. // SNMPDBG ((SNMP_LOG_TRACE,
  1188. // "WINSMIB: Entering ResolveVarBind.\n"));
  1189. // initialize MibPtr to NULL. When this becomes not null, it means we found a match (table or scalar)
  1190. MibPtr = NULL;
  1191. //
  1192. // Check the Tables array
  1193. //
  1194. // See if the prefix of the variable matches the prefix of
  1195. // any of the tables
  1196. //
  1197. for (TableIndex = 0; TableIndex < NUM_TABLES; TableIndex++)
  1198. {
  1199. //
  1200. // Construct OID with complete prefix for comparison purposes
  1201. //
  1202. SNMP_oidcpy( &TempOid, &MIB_OidPrefix );
  1203. if (TempOid.ids == NULL)
  1204. {
  1205. nResult = SNMP_ERRORSTATUS_GENERR;
  1206. goto Exit;
  1207. }
  1208. SNMP_oidappend( &TempOid, &Tables[TableIndex].pMibPtr->Oid );
  1209. //
  1210. // is there a match with the prefix oid of a table entry
  1211. //
  1212. if (
  1213. SnmpUtilOidNCmp(
  1214. &VarBind->name,
  1215. &TempOid,
  1216. MIB_PREFIX_LEN +
  1217. Tables[TableIndex].pMibPtr->Oid.idLength
  1218. ) == 0
  1219. )
  1220. {
  1221. //
  1222. // the prefix string of the var. matched the oid
  1223. // of a table.
  1224. //
  1225. MibPtr = Tables[TableIndex].pMibPtr;
  1226. fTableMatch = TRUE;
  1227. break;
  1228. }
  1229. // Free OID memory before checking with another table entry
  1230. SNMP_oidfree( &TempOid );
  1231. }
  1232. //
  1233. // There was an exact match with a table entry's prefix.
  1234. //
  1235. if ( fTableMatch)
  1236. {
  1237. if (
  1238. (SnmpUtilOidCmp(
  1239. &VarBind->name,
  1240. &TempOid
  1241. ) == 0)
  1242. )
  1243. {
  1244. //
  1245. // The oid specified is a prefix of a table entry. if the operation
  1246. // is not GETNEXT, return NOSUCHNAME
  1247. //
  1248. if (PduAction != MIB_GETNEXT)
  1249. {
  1250. SNMP_oidfree( &TempOid );
  1251. nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  1252. goto Exit;
  1253. }
  1254. else
  1255. {
  1256. UINT TableEntryIds[1];
  1257. AsnObjectIdentifier TableEntryOid = {
  1258. OID_SIZEOF(TableEntryIds), TableEntryIds };
  1259. //
  1260. // Replace var bind name with new name
  1261. //
  1262. //
  1263. // A sequence item oid always starts with a field no.
  1264. // The first item has a field no of 1.
  1265. //
  1266. TableEntryIds[0] = 1;
  1267. SNMP_oidappend( &VarBind->name, &TableEntryOid);
  1268. //
  1269. // Get the first entry in the table
  1270. //
  1271. PduAction = MIB_GETFIRST;
  1272. }
  1273. }
  1274. SNMP_oidfree( &TempOid );
  1275. //
  1276. // if there was no exact match with a prefix entry, then we
  1277. // don't touch the PduAction value specified.
  1278. //
  1279. }
  1280. else
  1281. {
  1282. //
  1283. // There was no match with any table entry. Let us see if there is
  1284. // a match with a group entry, a table, or a leaf variable
  1285. //
  1286. //
  1287. // Search for var bind name in the MIB
  1288. //
  1289. I = 0;
  1290. while ( MibPtr == NULL && I < MIB_num_variables )
  1291. {
  1292. //
  1293. // Construct OID with complete prefix for comparison purposes
  1294. //
  1295. SNMP_oidcpy( &TempOid, &MIB_OidPrefix );
  1296. SNMP_oidappend( &TempOid, &Mib[I].Oid );
  1297. //
  1298. //Check for OID in MIB - On a GET-NEXT the OID does not have to exactly
  1299. // match a variable in the MIB, it must only fall under the MIB root.
  1300. //
  1301. CompResult = SNMP_oidcmp( &VarBind->name, &TempOid );
  1302. //
  1303. // If CompResult is negative, the only valid operation is GET_NEXT
  1304. //
  1305. if ( CompResult < 0)
  1306. {
  1307. //
  1308. // This could be the oid of a leaf (without a 0)
  1309. // or it could be an invalid oid (in between two valid oids)
  1310. // The next oid might be that of a group or a table or table
  1311. // entry. In that case, we do not change the PduAction
  1312. //
  1313. if (PduAction == MIB_GETNEXT)
  1314. {
  1315. MibPtr = &Mib[I];
  1316. SNMP_oidfree( &VarBind->name );
  1317. SNMP_oidcpy( &VarBind->name, &MIB_OidPrefix );
  1318. SNMP_oidappend( &VarBind->name, &MibPtr->Oid );
  1319. if (MibPtr->Type != ASN_RFC1155_OPAQUE)
  1320. {
  1321. PduAction = (MibPtr->Type == ASN_SEQUENCE)? MIB_GETFIRST : MIB_GET;
  1322. }
  1323. }
  1324. else
  1325. {
  1326. nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  1327. SNMP_oidfree( &TempOid );
  1328. goto Exit;
  1329. }
  1330. SNMP_oidfree( &TempOid );
  1331. break;
  1332. }
  1333. else
  1334. {
  1335. //
  1336. // An exact match was found ( a group, table, or leaf).
  1337. //
  1338. if ( CompResult == 0)
  1339. {
  1340. MibPtr = &Mib[I];
  1341. }
  1342. }
  1343. //
  1344. // Free OID memory before checking another variable
  1345. //
  1346. SNMP_oidfree( &TempOid );
  1347. I++;
  1348. } // while
  1349. } // end of else
  1350. //
  1351. // if there was a match
  1352. //
  1353. if (MibPtr != NULL)
  1354. {
  1355. // SNMPDBG ((SNMP_LOG_TRACE,
  1356. // "WINSMIB: Found MibPtr.\n"));
  1357. //
  1358. // the function will be NULL only if the match was with a group
  1359. // or a sequence (table). If the match was with a table entry
  1360. // (entire VarBind string match or partial string match), we
  1361. // function would be a table function
  1362. //
  1363. if (MibPtr->MibFunc == NULL)
  1364. {
  1365. if(PduAction != MIB_GETNEXT)
  1366. {
  1367. nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  1368. goto Exit;
  1369. }
  1370. else
  1371. {
  1372. //
  1373. // Get the next variable which allows access
  1374. //
  1375. nResult = GetNextVar(VarBind, MibPtr);
  1376. goto Exit;
  1377. }
  1378. }
  1379. }
  1380. else
  1381. {
  1382. nResult = SNMP_ERRORSTATUS_NOSUCHNAME;
  1383. goto Exit;
  1384. }
  1385. // SNMPDBG ((SNMP_LOG_TRACE,
  1386. // "WINSMIB: Diving in OID handler.\n"));
  1387. //
  1388. // Call function to process request. Each MIB entry has a function pointer
  1389. // that knows how to process its MIB variable.
  1390. //
  1391. nResult = (*MibPtr->MibFunc)( PduAction, MibPtr, VarBind );
  1392. Exit:
  1393. return nResult;
  1394. } // ResolveVarBind
  1395. //
  1396. // MIB_leaf_func
  1397. // Performs generic actions on LEAF variables in the MIB.
  1398. //
  1399. // Notes:
  1400. //
  1401. // Return Codes:
  1402. // Standard PDU error codes.
  1403. //
  1404. // Error Codes:
  1405. // None.
  1406. //
  1407. UINT MIB_leaf_func(
  1408. IN UINT Action,
  1409. IN MIB_ENTRY *MibPtr,
  1410. IN RFC1157VarBind *VarBind
  1411. )
  1412. {
  1413. UINT ErrStat;
  1414. switch ( Action )
  1415. {
  1416. case MIB_GETNEXT:
  1417. //
  1418. // If there is no GET-NEXT pointer, this is the end of this MIB
  1419. //
  1420. if ( MibPtr->MibNext == NULL )
  1421. {
  1422. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  1423. goto Exit;
  1424. }
  1425. ErrStat = GetNextVar(VarBind, MibPtr);
  1426. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  1427. {
  1428. goto Exit;
  1429. }
  1430. break;
  1431. case MIB_GETFIRST: // fall through
  1432. case MIB_GET:
  1433. // Make sure that this variable's ACCESS is GET'able
  1434. if ( MibPtr->Access != MIB_ACCESS_READ &&
  1435. MibPtr->Access != MIB_ACCESS_READWRITE )
  1436. {
  1437. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  1438. goto Exit;
  1439. }
  1440. // Setup varbind's return value
  1441. VarBind->value.asnType = MibPtr->Type;
  1442. switch ( VarBind->value.asnType )
  1443. {
  1444. case ASN_RFC1155_COUNTER:
  1445. VarBind->value.asnValue.number = *(AsnCounter *)(MibPtr->Storage);
  1446. break;
  1447. case ASN_RFC1155_GAUGE:
  1448. case ASN_INTEGER:
  1449. VarBind->value.asnValue.number = *(AsnInteger *)(MibPtr->Storage);
  1450. break;
  1451. case ASN_RFC1155_IPADDRESS:
  1452. // continue as for ASN_OCTETSTRING
  1453. case ASN_OCTETSTRING:
  1454. if (VarBind->value.asnType == ASN_RFC1155_IPADDRESS)
  1455. {
  1456. VarBind->value.asnValue.string.length = 4;
  1457. }
  1458. else
  1459. {
  1460. VarBind->value.asnValue.string.length =
  1461. strlen( (LPSTR)MibPtr->Storage );
  1462. }
  1463. if ( NULL ==
  1464. (VarBind->value.asnValue.string.stream =
  1465. SNMP_malloc(VarBind->value.asnValue.string.length *
  1466. sizeof(char))) )
  1467. {
  1468. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1469. goto Exit;
  1470. }
  1471. memcpy( VarBind->value.asnValue.string.stream,
  1472. (LPSTR)MibPtr->Storage,
  1473. VarBind->value.asnValue.string.length );
  1474. VarBind->value.asnValue.string.dynamic = TRUE;
  1475. break;
  1476. default:
  1477. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1478. goto Exit;
  1479. }
  1480. break;
  1481. case MIB_SET:
  1482. // Make sure that this variable's ACCESS is SET'able
  1483. if ( MibPtr->Access != MIB_ACCESS_READWRITE &&
  1484. MibPtr->Access != MIB_ACCESS_WRITE )
  1485. {
  1486. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  1487. goto Exit;
  1488. }
  1489. // Check for proper type before setting
  1490. if ( MibPtr->Type != VarBind->value.asnType )
  1491. {
  1492. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  1493. goto Exit;
  1494. }
  1495. // Save value in MIB
  1496. switch ( VarBind->value.asnType )
  1497. {
  1498. case ASN_RFC1155_COUNTER:
  1499. *(AsnCounter *)(MibPtr->Storage) = VarBind->value.asnValue.number;
  1500. break;
  1501. case ASN_RFC1155_GAUGE:
  1502. case ASN_INTEGER:
  1503. *(AsnInteger *)(MibPtr->Storage) = VarBind->value.asnValue.number;
  1504. break;
  1505. case ASN_RFC1155_IPADDRESS:
  1506. if (MibPtr->Storage == &MIB_PullTriggerStore ||
  1507. MibPtr->Storage == &MIB_PushTriggerStore ||
  1508. MibPtr->Storage == &MIB_DeleteDbRecsStore ||
  1509. MibPtr->Storage == &MIB_DeleteWinsStore)
  1510. {
  1511. int backupSize = (MibPtr->Storage == &MIB_PullTriggerStore) ?
  1512. sizeof(MIB_PullTriggerStore)/2 :
  1513. sizeof(MIB_PushTriggerStore)/2 ;
  1514. // those variables are ASN_RFC1155_IPADDRESS
  1515. // their old values have to be stored as the WinsTrigger() might fail
  1516. // in which case the old values will be restored
  1517. // each of these variables has 10 octets, the payload being of 5 octets.
  1518. // the last 5 = for backup
  1519. memcpy( (LPSTR)MibPtr->Storage + backupSize, (LPSTR)MibPtr->Storage, backupSize);
  1520. }
  1521. case ASN_OCTETSTRING:
  1522. // The storage must be adequate to contain the new string
  1523. // including a NULL terminator.
  1524. memcpy( (LPSTR)MibPtr->Storage,
  1525. VarBind->value.asnValue.string.stream,
  1526. VarBind->value.asnValue.string.length );
  1527. ((LPSTR)MibPtr->Storage)[VarBind->value.asnValue.string.length] =
  1528. '\0';
  1529. #if 0
  1530. if ( VarBind->value.asnValue.string.dynamic)
  1531. {
  1532. SNMP_free( VarBind->value.asnValue.string.stream);
  1533. }
  1534. #endif
  1535. break;
  1536. default:
  1537. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1538. goto Exit;
  1539. }
  1540. break;
  1541. default:
  1542. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1543. goto Exit;
  1544. } // switch
  1545. // Signal no error occurred
  1546. ErrStat = SNMP_ERRORSTATUS_NOERROR;
  1547. Exit:
  1548. return ErrStat;
  1549. } // MIB_leaf_func
  1550. #define TMST(x) sResults.WinsStat.TimeStamps.x.wHour,\
  1551. sResults.WinsStat.TimeStamps.x.wMinute,\
  1552. sResults.WinsStat.TimeStamps.x.wSecond,\
  1553. sResults.WinsStat.TimeStamps.x.wMonth,\
  1554. sResults.WinsStat.TimeStamps.x.wDay,\
  1555. sResults.WinsStat.TimeStamps.x.wYear
  1556. #define PRINTTIME(Var, x) sprintf(Var, "%02u:%02u:%02u on %02u:%02u:%04u.\n", TMST(x))
  1557. static WINSINTF_RESULTS_T sResults;
  1558. //
  1559. // MIB_Stat
  1560. // Performs specific actions on the different MIB variable
  1561. //
  1562. // Notes:
  1563. //
  1564. // Return Codes:
  1565. // Standard PDU error codes.
  1566. //
  1567. // Error Codes:
  1568. // None.
  1569. //
  1570. UINT MIB_Stat(
  1571. IN UINT Action,
  1572. IN MIB_ENTRY *MibPtr,
  1573. IN RFC1157VarBind *VarBind
  1574. )
  1575. {
  1576. //WINSINTF_RESULTS_T Results;
  1577. DWORD Status;
  1578. UINT ErrStat;
  1579. handle_t BindHdl;
  1580. switch ( Action )
  1581. {
  1582. case MIB_SET:
  1583. ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  1584. break;
  1585. case MIB_GETNEXT:
  1586. ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  1587. break;
  1588. case MIB_GETFIRST:
  1589. #if 0
  1590. //
  1591. // If it is an OPAQUE type (i.e. aggregate)
  1592. //
  1593. if (MibPtr->Type == ASN_RFC1155_OPAQUE)
  1594. {
  1595. ErrStat = MIB_leaf_func( MIB_GETNEXT, MibPtr, VarBind );
  1596. break;
  1597. }
  1598. #endif
  1599. //
  1600. // fall through
  1601. //
  1602. case MIB_GET:
  1603. if (!fWinsMibWinsStatusStatCalled)
  1604. {
  1605. //
  1606. // Call the WinsStatus function to get the statistics
  1607. //
  1608. BindHdl = WinsBind(&sBindData);
  1609. sResults.WinsStat.NoOfPnrs = 0;
  1610. sResults.WinsStat.pRplPnrs = NULL;
  1611. if ((Status = WinsStatus(BindHdl, WINSINTF_E_STAT, &sResults)) !=
  1612. WINSINTF_SUCCESS)
  1613. {
  1614. SNMPDBG((
  1615. SNMP_LOG_ERROR,
  1616. "WINSMIB: Error from WinsStatus = (%d).\n",
  1617. Status
  1618. ));
  1619. WinsFreeMem(sResults.WinsStat.pRplPnrs);
  1620. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1621. goto Exit;
  1622. }
  1623. else
  1624. {
  1625. fWinsMibWinsStatusStatCalled = TRUE;
  1626. }
  1627. WinsFreeMem(sResults.WinsStat.pRplPnrs);
  1628. WinsUnbind(&sBindData, BindHdl);
  1629. }
  1630. if (MibPtr->Storage == &MIB_WinsStartTimeStore)
  1631. {
  1632. PRINTTIME(MIB_WinsStartTimeStore, WinsStartTime);
  1633. goto LEAF1;
  1634. }
  1635. if (MibPtr->Storage == &MIB_LastPScvTimeStore)
  1636. {
  1637. PRINTTIME(MIB_LastPScvTimeStore, LastPScvTime);
  1638. goto LEAF1;
  1639. }
  1640. if (MibPtr->Storage == &MIB_LastATScvTimeStore)
  1641. {
  1642. PRINTTIME(MIB_LastATScvTimeStore, LastATScvTime);
  1643. goto LEAF1;
  1644. }
  1645. if (MibPtr->Storage == &MIB_LastTombScvTimeStore)
  1646. {
  1647. PRINTTIME(MIB_LastTombScvTimeStore, LastTombScvTime);
  1648. goto LEAF1;
  1649. }
  1650. if (MibPtr->Storage == &MIB_LastVerifyScvTimeStore)
  1651. {
  1652. PRINTTIME(MIB_LastVerifyScvTimeStore, LastVerifyScvTime);
  1653. goto LEAF1;
  1654. }
  1655. if (MibPtr->Storage == &MIB_LastPRplTimeStore)
  1656. {
  1657. PRINTTIME(MIB_LastPRplTimeStore, LastPRplTime);
  1658. goto LEAF1;
  1659. }
  1660. if (MibPtr->Storage == &MIB_LastATRplTimeStore)
  1661. {
  1662. PRINTTIME(MIB_LastATRplTimeStore, LastATRplTime);
  1663. goto LEAF1;
  1664. }
  1665. if (MibPtr->Storage == &MIB_LastNTRplTimeStore)
  1666. {
  1667. PRINTTIME(MIB_LastNTRplTimeStore, LastNTRplTime);
  1668. goto LEAF1;
  1669. }
  1670. if (MibPtr->Storage == &MIB_LastACTRplTimeStore)
  1671. {
  1672. PRINTTIME(MIB_LastACTRplTimeStore, LastACTRplTime);
  1673. goto LEAF1;
  1674. }
  1675. if (MibPtr->Storage == &MIB_LastInitDbTimeStore)
  1676. {
  1677. PRINTTIME(MIB_LastInitDbTimeStore, LastInitDbTime);
  1678. goto LEAF1;
  1679. }
  1680. if (MibPtr->Storage == &MIB_LastCounterResetTimeStore)
  1681. {
  1682. PRINTTIME(MIB_LastCounterResetTimeStore, CounterResetTime);
  1683. goto LEAF1;
  1684. }
  1685. if (MibPtr->Storage == &MIB_WinsTotalNoOfRegStore)
  1686. {
  1687. MIB_WinsTotalNoOfRegStore =
  1688. sResults.WinsStat.Counters.NoOfUniqueReg +
  1689. sResults.WinsStat.Counters.NoOfGroupReg;
  1690. goto LEAF1;
  1691. }
  1692. if (MibPtr->Storage == &MIB_WinsTotalNoOfQueriesStore)
  1693. {
  1694. MIB_WinsTotalNoOfQueriesStore =
  1695. sResults.WinsStat.Counters.NoOfQueries;
  1696. goto LEAF1;
  1697. }
  1698. if (MibPtr->Storage == &MIB_WinsTotalNoOfRelStore)
  1699. {
  1700. MIB_WinsTotalNoOfRelStore = sResults.WinsStat.Counters.NoOfRel;
  1701. goto LEAF1;
  1702. }
  1703. if (MibPtr->Storage == &MIB_WinsTotalNoOfSuccRelStore)
  1704. {
  1705. MIB_WinsTotalNoOfSuccRelStore =
  1706. sResults.WinsStat.Counters.NoOfSuccRel;
  1707. goto LEAF1;
  1708. }
  1709. if (MibPtr->Storage == &MIB_WinsTotalNoOfFailRelStore)
  1710. {
  1711. MIB_WinsTotalNoOfFailRelStore =
  1712. sResults.WinsStat.Counters.NoOfFailRel;
  1713. goto LEAF1;
  1714. }
  1715. if (MibPtr->Storage == &MIB_WinsTotalNoOfSuccQueriesStore)
  1716. {
  1717. MIB_WinsTotalNoOfSuccQueriesStore =
  1718. sResults.WinsStat.Counters.NoOfSuccQueries;
  1719. goto LEAF1;
  1720. }
  1721. if (MibPtr->Storage == &MIB_WinsTotalNoOfFailQueriesStore)
  1722. {
  1723. MIB_WinsTotalNoOfFailQueriesStore =
  1724. sResults.WinsStat.Counters.NoOfFailQueries;
  1725. // goto LEAF1;
  1726. }
  1727. LEAF1:
  1728. // Call the more generic function to perform the action
  1729. ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  1730. break;
  1731. default:
  1732. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1733. goto Exit;
  1734. } // switch
  1735. Exit:
  1736. return ErrStat;
  1737. } // MIB_Stat
  1738. //
  1739. // MIB_RWReg
  1740. // Performs specific actions on the different MIB variable
  1741. //
  1742. // Notes:
  1743. //
  1744. // Return Codes:
  1745. // Standard PDU error codes.
  1746. //
  1747. // Error Codes:
  1748. // None.
  1749. //
  1750. UINT MIB_RWReg(
  1751. IN UINT Action,
  1752. IN MIB_ENTRY *MibPtr,
  1753. IN RFC1157VarBind *VarBind
  1754. )
  1755. {
  1756. WINSINTF_RESULTS_T Results;
  1757. DWORD Status;
  1758. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  1759. handle_t BindHdl;
  1760. // SNMPDBG ((SNMP_LOG_TRACE,
  1761. // "WINSMIB: Entering MIB_RWReg.\n"));
  1762. switch ( Action )
  1763. {
  1764. case MIB_SET:
  1765. if (MIB_leaf_func( Action, MibPtr, VarBind )
  1766. == SNMP_ERRORSTATUS_NOERROR)
  1767. {
  1768. ErrStat = WriteReg(MibPtr);
  1769. }
  1770. break;
  1771. case MIB_GETFIRST:
  1772. #if 0
  1773. //
  1774. // If it is an OPAQUE type (i.e. aggregate)
  1775. //
  1776. if (MibPtr->Type == ASN_RFC1155_OPAQUE)
  1777. {
  1778. ErrStat = MIB_leaf_func( MIB_GETNEXT, MibPtr, VarBind );
  1779. break;
  1780. }
  1781. #endif
  1782. //
  1783. // fall through
  1784. //
  1785. case MIB_GET:
  1786. //
  1787. // Call the WinsStatus function to get the statistics
  1788. //
  1789. if (
  1790. (MibPtr->Storage == &MIB_RefreshIntervalStore)
  1791. ||
  1792. (MibPtr->Storage == &MIB_TombstoneIntervalStore)
  1793. ||
  1794. (MibPtr->Storage == &MIB_TombstoneTimeoutStore)
  1795. ||
  1796. (MibPtr->Storage == &MIB_VerifyIntervalStore)
  1797. )
  1798. {
  1799. BindHdl = WinsBind(&sBindData);
  1800. Results.WinsStat.NoOfPnrs = 0;
  1801. Results.WinsStat.pRplPnrs = NULL;
  1802. if ((Status = WinsStatus(BindHdl, WINSINTF_E_CONFIG, &Results))
  1803. == WINSINTF_SUCCESS)
  1804. {
  1805. MIB_RefreshIntervalStore = Results.RefreshInterval;
  1806. MIB_TombstoneIntervalStore = Results.TombstoneInterval;
  1807. MIB_TombstoneTimeoutStore = Results.TombstoneTimeout;
  1808. MIB_VerifyIntervalStore = Results.VerifyInterval;
  1809. }
  1810. else
  1811. {
  1812. SNMPDBG((
  1813. SNMP_LOG_ERROR,
  1814. "WINSMIB: Error from WinsStatus = (%d).\n",
  1815. Status
  1816. ));
  1817. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1818. }
  1819. WinsUnbind(&sBindData, BindHdl);
  1820. }
  1821. else
  1822. {
  1823. //
  1824. // If a value could not be read
  1825. // then the storage for the mib variable would have been
  1826. // initialized to 0.
  1827. //
  1828. ErrStat = ReadReg(MibPtr);
  1829. }
  1830. //
  1831. // fall through
  1832. //
  1833. case MIB_GETNEXT:
  1834. //
  1835. // Call the more generic function to perform the action
  1836. //
  1837. ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  1838. break;
  1839. default:
  1840. ErrStat = SNMP_ERRORSTATUS_GENERR;
  1841. goto Exit;
  1842. } // switch
  1843. Exit:
  1844. return ErrStat;
  1845. } // MIB_RWReg
  1846. UINT
  1847. OpenReqKey(
  1848. MIB_ENTRY *pMib,
  1849. VAL_ID_E *pVal_Id_e,
  1850. BOOL fCreateAllowed
  1851. )
  1852. /*++
  1853. Routine Description:
  1854. The function opens the required keys for the parameter indicated
  1855. by the structure pointed to by pMib
  1856. Arguments:
  1857. Externals Used:
  1858. None
  1859. Return Value:
  1860. Success status codes --
  1861. Error status codes --
  1862. Error Handling:
  1863. Called by:
  1864. Side Effects:
  1865. Comments:
  1866. None
  1867. --*/
  1868. {
  1869. UINT Status = SNMP_ERRORSTATUS_GENERR;
  1870. // SNMPDBG ((SNMP_LOG_TRACE,
  1871. // "WINSMIB: Entering OpenReqKey.\n"));
  1872. //
  1873. // if it is a parameter value, open the parameters key
  1874. //
  1875. if (PARAMETERS_VAL_M(pMib))
  1876. {
  1877. Status = OpenKey(PARAMETERS_E_KEY, NULL, NULL, NULL, fCreateAllowed);
  1878. if (Status == SNMP_ERRORSTATUS_NOERROR)
  1879. {
  1880. // sfParametersKeyOpen = TRUE;
  1881. PARAMETERS_ID_M(pMib, *pVal_Id_e);
  1882. }
  1883. }
  1884. else
  1885. {
  1886. //
  1887. // if it is a Pull key value, open the partner and
  1888. // pull keys
  1889. //
  1890. if (PULL_VAL_M(pMib))
  1891. {
  1892. Status = OpenKey(PARTNERS_E_KEY, NULL, NULL, NULL, fCreateAllowed);
  1893. if (Status == SNMP_ERRORSTATUS_NOERROR)
  1894. {
  1895. //sfPartnersKeyOpen = TRUE;
  1896. Status = OpenKey(PULL_E_KEY, NULL, NULL, NULL, fCreateAllowed);
  1897. if (Status == SNMP_ERRORSTATUS_NOERROR)
  1898. {
  1899. PULL_ID_M(pMib, *pVal_Id_e);
  1900. }
  1901. }
  1902. }
  1903. else
  1904. {
  1905. //
  1906. // if it is a Push key value, open the partner and
  1907. // pull keys
  1908. //
  1909. if (PUSH_VAL_M(pMib))
  1910. {
  1911. Status = OpenKey(PARTNERS_E_KEY, NULL, NULL, NULL, fCreateAllowed);
  1912. if (Status == SNMP_ERRORSTATUS_NOERROR)
  1913. {
  1914. sfPartnersKeyOpen = TRUE;
  1915. Status = OpenKey(PUSH_E_KEY, NULL, NULL, NULL, fCreateAllowed);
  1916. if (Status == SNMP_ERRORSTATUS_NOERROR)
  1917. {
  1918. PUSH_ID_M(pMib, *pVal_Id_e);
  1919. }
  1920. }
  1921. }
  1922. }
  1923. }
  1924. return(Status);
  1925. }
  1926. UINT
  1927. CloseReqKey(
  1928. VOID
  1929. )
  1930. /*++
  1931. Routine Description:
  1932. Arguments:
  1933. Externals Used:
  1934. None
  1935. Return Value:
  1936. Success status codes --
  1937. Error status codes --
  1938. Error Handling:
  1939. Called by:
  1940. Side Effects:
  1941. Comments:
  1942. None
  1943. --*/
  1944. {
  1945. UINT Status = SNMP_ERRORSTATUS_NOERROR;
  1946. if (sfParametersKeyOpen)
  1947. {
  1948. if (sfDatafilesKeyOpen)
  1949. {
  1950. SNMPDBG((
  1951. SNMP_LOG_VERBOSE,
  1952. "WINSMIB: Closing sDatafilesKey 0x%08lx (fKeyOpen=TRUE).\n",
  1953. sDatafilesKey
  1954. ));
  1955. RegCloseKey(sDatafilesKey);
  1956. sfDatafilesKeyOpen = FALSE;
  1957. }
  1958. SNMPDBG((
  1959. SNMP_LOG_VERBOSE,
  1960. "WINSMIB: Closing sParametersKey 0x%08lx (fKeyOpen=TRUE).\n",
  1961. sParametersKey
  1962. ));
  1963. RegCloseKey(sParametersKey);
  1964. sfParametersKeyOpen = FALSE;
  1965. }
  1966. else
  1967. {
  1968. if (sfPartnersKeyOpen)
  1969. {
  1970. if (sfPullKeyOpen)
  1971. {
  1972. SNMPDBG((
  1973. SNMP_LOG_VERBOSE,
  1974. "WINSMIB: Closing sPullKey 0x%08lx (fKeyOpen=TRUE).\n",
  1975. sPullKey
  1976. ));
  1977. RegCloseKey(sPullKey);
  1978. sfPullKeyOpen = FALSE;
  1979. }
  1980. else
  1981. {
  1982. if (sfPushKeyOpen)
  1983. {
  1984. SNMPDBG((
  1985. SNMP_LOG_VERBOSE,
  1986. "WINSMIB: Closing sPushKey 0x%08lx (fKeyOpen=TRUE).\n",
  1987. sPushKey
  1988. ));
  1989. RegCloseKey(sPushKey);
  1990. sfPushKeyOpen = FALSE;
  1991. }
  1992. }
  1993. SNMPDBG((
  1994. SNMP_LOG_VERBOSE,
  1995. "WINSMIB: Closing sPartnersKey 0x%08lx (fKeyOpen=TRUE).\n",
  1996. sPartnersKey
  1997. ));
  1998. RegCloseKey(sPartnersKey);
  1999. sfPartnersKeyOpen = FALSE;
  2000. }
  2001. }
  2002. return(Status);
  2003. }
  2004. UINT
  2005. ReadReg(
  2006. MIB_ENTRY *pMib
  2007. )
  2008. {
  2009. UINT Status = SNMP_ERRORSTATUS_NOERROR;
  2010. VAL_ID_E Val_Id_e;
  2011. // SNMPDBG ((SNMP_LOG_TRACE,
  2012. // "WINSMIB: Entering ReadReg.\n"));
  2013. Status = OpenReqKey(pMib, &Val_Id_e, FALSE);
  2014. if (Status == SNMP_ERRORSTATUS_NOERROR)
  2015. {
  2016. Status = GetVal(&VarInfo[Val_Id_e]);
  2017. }
  2018. CloseReqKey();
  2019. return(Status);
  2020. }
  2021. UINT
  2022. WriteReg(
  2023. MIB_ENTRY *pMib
  2024. )
  2025. {
  2026. UINT Status = SNMP_ERRORSTATUS_NOERROR;
  2027. VAL_ID_E Val_Id_e;
  2028. Status = OpenReqKey(pMib, &Val_Id_e, TRUE);
  2029. if (SNMP_ERRORSTATUS_NOERROR == Status) {
  2030. Status = SetVal(&VarInfo[Val_Id_e]);
  2031. SNMPDBG((
  2032. SNMP_LOG_VERBOSE,
  2033. "WINSMIB: Closing sParametersKey 0x%08lx (fKeyOpen=%s).\n",
  2034. sParametersKey, sfParametersKeyOpen ? "TRUE" : "FALSE"
  2035. ));
  2036. }
  2037. CloseReqKey();
  2038. //RegCloseKey(sParametersKey);
  2039. return(Status);
  2040. }
  2041. UINT
  2042. OpenKey(
  2043. KEY_TYPE_E Key_e,
  2044. LPBYTE ptrKeyStr,
  2045. HKEY *ptrNewKey,
  2046. HKEY *pRootKey,
  2047. BOOL fCreateAllowed
  2048. )
  2049. {
  2050. LONG RetVal;
  2051. DWORD NewKeyInd;
  2052. HKEY RootKey;
  2053. LPBYTE pKeyStr;
  2054. HKEY *pNewKey;
  2055. LPBOOL pfNewKeyOpen;
  2056. if (!fWinsMibWinsKeyOpen)
  2057. {
  2058. SNMPDBG((
  2059. SNMP_LOG_VERBOSE,
  2060. "WINSMIB: Creating/opening Wins key.\n",
  2061. WinsMibWinsKey
  2062. ));
  2063. RetVal = RegCreateKeyEx(
  2064. HKEY_LOCAL_MACHINE, //predefined key value
  2065. _WINS_CNF_KEY, //subkey for WINS
  2066. 0, //must be zero (reserved)
  2067. TEXT("Class"), //class -- may change in future
  2068. REG_OPTION_NON_VOLATILE, //non-volatile information
  2069. KEY_ALL_ACCESS, //we desire all access to the keyo
  2070. NULL, //let key have default sec. attributes
  2071. &WinsMibWinsKey, //handle to key
  2072. &NewKeyInd //is it a new key (out arg)
  2073. );
  2074. if (RetVal != ERROR_SUCCESS)
  2075. {
  2076. SNMPDBG((
  2077. SNMP_LOG_ERROR,
  2078. "WINSMIB: Error creating/opening Wins key 0x%08lx.\n",
  2079. GetLastError()
  2080. ));
  2081. return(SNMP_ERRORSTATUS_GENERR);
  2082. }
  2083. fWinsMibWinsKeyOpen = TRUE;
  2084. }
  2085. SNMPDBG((
  2086. SNMP_LOG_VERBOSE,
  2087. "WINSMIB: WinsMibWinsKey=0x%08lx, opening %s.\n",
  2088. WinsMibWinsKey,
  2089. (Key_e == PARAMETERS_E_KEY)
  2090. ? "PARAMETERS_E_KEY"
  2091. : (Key_e == PARTNERS_E_KEY)
  2092. ? "PARTNERS_E_KEY"
  2093. : (Key_e == PULL_E_KEY)
  2094. ? "PULL_E_KEY"
  2095. : (Key_e == PUSH_E_KEY)
  2096. ? "PUSH_E_KEY"
  2097. : (Key_e == DATAFILES_E_KEY)
  2098. ? "DATAFILES_E_KEY"
  2099. : "IPADD_E_KEY"
  2100. ));
  2101. switch(Key_e)
  2102. {
  2103. case(PARAMETERS_E_KEY):
  2104. RootKey = WinsMibWinsKey;
  2105. pKeyStr = _WINS_PARAMETERS_KEY;
  2106. pNewKey = &sParametersKey;
  2107. pfNewKeyOpen = &sfParametersKeyOpen;
  2108. break;
  2109. case(PARTNERS_E_KEY):
  2110. RootKey = WinsMibWinsKey;
  2111. pKeyStr = _WINS_PARTNERS_KEY;
  2112. pNewKey = &sPartnersKey;
  2113. pfNewKeyOpen = &sfPartnersKeyOpen;
  2114. break;
  2115. case(PULL_E_KEY):
  2116. RootKey = sPartnersKey;
  2117. pKeyStr = _WINS_PULL_KEY;
  2118. pNewKey = &sPullKey;
  2119. pfNewKeyOpen = &sfPullKeyOpen;
  2120. break;
  2121. case(PUSH_E_KEY):
  2122. RootKey = sPartnersKey;
  2123. pKeyStr = _WINS_PUSH_KEY;
  2124. pNewKey = &sPushKey;
  2125. pfNewKeyOpen = &sfPushKeyOpen;
  2126. break;
  2127. case(DATAFILES_E_KEY):
  2128. RootKey = sParametersKey;
  2129. pKeyStr = _WINS_DATAFILES_KEY;
  2130. pNewKey = &sDatafilesKey;
  2131. pfNewKeyOpen = &sfDatafilesKeyOpen;
  2132. break;
  2133. case(IPADD_E_KEY):
  2134. RootKey = *pRootKey;
  2135. pKeyStr = ptrKeyStr;
  2136. pNewKey = ptrNewKey;
  2137. break;
  2138. default:
  2139. SNMPDBG((
  2140. SNMP_LOG_ERROR,
  2141. "WINSMIB: Error in key type.\n"
  2142. ));
  2143. return(SNMP_ERRORSTATUS_GENERR);
  2144. }
  2145. if (fCreateAllowed)
  2146. {
  2147. RetVal = RegCreateKeyEx(
  2148. RootKey, //predefined key value
  2149. pKeyStr, //subkey for WINS
  2150. 0, //must be zero (reserved)
  2151. TEXT("Class"), //class -- may change in future
  2152. REG_OPTION_NON_VOLATILE, //non-volatile information
  2153. KEY_ALL_ACCESS, //we desire all access to the keyo
  2154. NULL, //let key have default sec. attributes
  2155. pNewKey, //handle to key
  2156. &NewKeyInd //is it a new key (out arg)
  2157. );
  2158. }
  2159. else
  2160. {
  2161. RetVal = RegOpenKeyEx(
  2162. RootKey, //predefined key value
  2163. pKeyStr, //subkey for WINS
  2164. 0, //must be zero (reserved)
  2165. KEY_READ, //we desire read access to the keyo
  2166. pNewKey //handle to key
  2167. );
  2168. }
  2169. if (RetVal != ERROR_SUCCESS)
  2170. {
  2171. SNMPDBG((
  2172. SNMP_LOG_ERROR,
  2173. "WINSMIB: Error creating/opening Wins/Parameters key 0x%08lx.\n",
  2174. GetLastError()
  2175. ));
  2176. return(SNMP_ERRORSTATUS_GENERR);
  2177. }
  2178. SNMPDBG((
  2179. SNMP_LOG_VERBOSE,
  2180. "WINSMIB: Opened %s=0x%08lx (fKeyOpen=TRUE).\n",
  2181. (Key_e == PARAMETERS_E_KEY)
  2182. ? "sParametersKey"
  2183. : (Key_e == PARTNERS_E_KEY)
  2184. ? "sPartnersKey"
  2185. : (Key_e == PULL_E_KEY)
  2186. ? "sPullKey"
  2187. : (Key_e == PUSH_E_KEY)
  2188. ? "sPushKey"
  2189. : (Key_e == DATAFILES_E_KEY)
  2190. ? "sDatafilesKey"
  2191. : "ipAddKey", *pNewKey
  2192. ));
  2193. if (Key_e != IPADD_E_KEY)
  2194. {
  2195. if (ptrNewKey != NULL)
  2196. {
  2197. *ptrNewKey = *pNewKey;
  2198. }
  2199. *pfNewKeyOpen = TRUE;
  2200. }
  2201. return(SNMP_ERRORSTATUS_NOERROR);
  2202. }
  2203. UINT
  2204. SetVal(
  2205. PVARINFO_T pVarInfo
  2206. )
  2207. {
  2208. UINT Status = SNMP_ERRORSTATUS_NOERROR;
  2209. LONG RetVal;
  2210. RetVal = RegSetValueEx(
  2211. *(pVarInfo->pRootKey),
  2212. pVarInfo->pName,
  2213. 0, //reserved -- must be 0
  2214. pVarInfo->ValType,
  2215. pVarInfo->pStorage,
  2216. pVarInfo->ValType == REG_DWORD ?
  2217. pVarInfo->SizeOfData :
  2218. strlen(pVarInfo->pStorage)
  2219. );
  2220. if (RetVal != ERROR_SUCCESS)
  2221. {
  2222. SNMPDBG((
  2223. SNMP_LOG_ERROR,
  2224. "WINSMIB: Could not set value of %s.\n",
  2225. pVarInfo->pName
  2226. ));
  2227. Status = SNMP_ERRORSTATUS_GENERR;
  2228. }
  2229. return(Status);
  2230. }
  2231. UINT
  2232. GetVal(
  2233. PVARINFO_T pVarInfo
  2234. )
  2235. {
  2236. LONG RetVal;
  2237. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2238. DWORD ValType;
  2239. DWORD Sz;
  2240. // SNMPDBG ((SNMP_LOG_TRACE,
  2241. // "WINSMIB: GetVal(%s).\n",
  2242. // pVarInfo->pName));
  2243. Sz = pVarInfo->SizeOfData;
  2244. RetVal = RegQueryValueEx(
  2245. *(pVarInfo->pRootKey),
  2246. pVarInfo->pName,
  2247. NULL,
  2248. &ValType,
  2249. pVarInfo->pStorage,
  2250. &Sz
  2251. );
  2252. // SNMPDBG ((SNMP_LOG_TRACE,
  2253. // "WINSMIB: GetVal()->%d\n",
  2254. // RetVal));
  2255. if (RetVal != ERROR_SUCCESS)
  2256. {
  2257. (VOID)RtlFillMemory(pVarInfo->pStorage, pVarInfo->SizeOfData, 0);
  2258. ErrStat = SNMP_ERRORSTATUS_GENERR;
  2259. }
  2260. return(ErrStat);
  2261. }
  2262. #if 0
  2263. //
  2264. // PullPnrs
  2265. // Performs specific actions on the PullPnrs table
  2266. //
  2267. // Notes:
  2268. //
  2269. // Return Codes:
  2270. // Standard PDU error codes.
  2271. //
  2272. // Error Codes:
  2273. // None.
  2274. //
  2275. UINT
  2276. PullPnrs(
  2277. IN UINT Action,
  2278. IN MIB_ENTRY *MibPtr,
  2279. IN RFC1157VarBind *VarBind,
  2280. IN PTABLE_ENTRY *TablePtr
  2281. )
  2282. {
  2283. WINSINTF_RESULTS_T Results;
  2284. DWORD Status = WINSINTF_SUCCESS;
  2285. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2286. handle_t BindHdl;
  2287. BindHdl = WinsBind(&sBindData);
  2288. switch ( Action )
  2289. {
  2290. case MIB_SET:
  2291. break;
  2292. case MIB_GETNEXT:
  2293. case MIB_GET:
  2294. ErrStat = TableMatch(MibPtr, VarBind, TablePtr);
  2295. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2296. {
  2297. return(ErrStat);
  2298. }
  2299. //
  2300. // Call the WinsStatus function to get the statistics
  2301. //
  2302. if (
  2303. (MibPtr->Storage == &MIB_RefreshIntervalStore)
  2304. ||
  2305. (MibPtr->Storage == &MIB_TombstoneIntervalStore)
  2306. ||
  2307. (MibPtr->Storage == &MIB_TombstoneTimeoutStore)
  2308. ||
  2309. (MibPtr->Storage == &MIB_VerifyIntervalStore)
  2310. )
  2311. {
  2312. Status = WinsStatus(WINSINTF_E_CONFIG, &Results);
  2313. if (Status == WINSINTF_SUCCESS)
  2314. {
  2315. MIB_RefreshIntervalStore = Results.RefreshInterval;
  2316. MIB_TombstoneIntervalStore = Results.TombstoneInterval;
  2317. MIB_TombstoneTimeoutStore = Results.TombstoneTimeout;
  2318. MIB_VerifyIntervalStore = Results.VerifyInterval;
  2319. }
  2320. else
  2321. {
  2322. SNMPDBG((
  2323. SNMP_LOG_ERROR,
  2324. "WINSMIB: Error from WinsStatus = (%d).\n",
  2325. Status
  2326. ));
  2327. ErrStat = SNMP_ERRORSTATUS_GENERR;
  2328. }
  2329. }
  2330. else
  2331. {
  2332. if ((ErrStat = ReadReg(MibPtr)) != SNMP_ERRORSTATUS_NOERROR)
  2333. {
  2334. break;
  2335. }
  2336. }
  2337. // Call the more generic function to perform the action
  2338. ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  2339. break;
  2340. default:
  2341. ErrStat = SNMP_ERRORSTATUS_GENERR;
  2342. goto Exit;
  2343. } // switch
  2344. Exit:
  2345. WinsUnbind(&sBindData, BindHdl);
  2346. return ErrStat;
  2347. } //PullPnrs
  2348. #endif
  2349. UINT
  2350. PnrGetNext(
  2351. IN RFC1157VarBind *VarBind,
  2352. IN MIB_ENTRY *MibPtr,
  2353. IN KEY_TYPE_E KeyType_e
  2354. )
  2355. {
  2356. DWORD OidIndex;
  2357. DWORD NumAddKeys;
  2358. INT Index;
  2359. PADD_KEY_T pAddKey = NULL;
  2360. DWORD FieldNo;
  2361. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2362. BOOL fFirst;
  2363. //
  2364. // Read in all ip address keys. For each key, the values of its fields
  2365. // is stored in the ADD_KEY_T structure. The number of Address
  2366. // keys are stored in NumAddKeys and in the TABLE_INFO structure
  2367. //
  2368. ErrStat = EnumAddKeys(KeyType_e, &pAddKey, &NumAddKeys);
  2369. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2370. {
  2371. return ErrStat;
  2372. }
  2373. //
  2374. // Check if the name passed matches any in the table (i.e. table of
  2375. // of ADD_KEY_T structures. If there is a match, the address
  2376. // of the ip address key and the matching field's no. are returned
  2377. //
  2378. ErrStat = PnrMatch(VarBind, NumAddKeys, pAddKey, &Index,
  2379. &FieldNo, KeyType_e, MIB_GETNEXT, &fFirst);
  2380. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2381. {
  2382. goto Exit;
  2383. // return(ErrStat);
  2384. }
  2385. //
  2386. // We were passed an oid that is less than all oids in the table. Set
  2387. // the Index to -1 so that we retrieve the first record in the table
  2388. //
  2389. if (fFirst)
  2390. {
  2391. Index = -1;
  2392. }
  2393. //
  2394. // Since the operation is GETNEXT, get the next IP address (i.e. one
  2395. // that is lexicographically bigger. If there is none, we must increment
  2396. // the field value and move back to the lexically first item in the table
  2397. // If the new field value is more than the largest supported, we call
  2398. // the MibFunc of the next MIB entry.
  2399. //
  2400. if ((Index = PnrFindNext(Index, NumAddKeys, pAddKey)) < 0)
  2401. {
  2402. //
  2403. // if we were trying to retrieve the second or subsequent record
  2404. // we must increment the field number nd get the first record in
  2405. // the table. If we were retrieving the first record, then
  2406. // we should get the next var.
  2407. //
  2408. if (!fFirst)
  2409. {
  2410. Index = PnrFindNext(-1, NumAddKeys, pAddKey);
  2411. }
  2412. else
  2413. {
  2414. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pAddKey);
  2415. return(GetNextVar(VarBind, MibPtr));
  2416. }
  2417. //
  2418. // If either there is no entry in the table or if we have
  2419. // exhausted all fields of the entry, call the function
  2420. // of the next mib entry.
  2421. //
  2422. if (
  2423. (++FieldNo > (DWORD)((KeyType_e == PULL_E_KEY)
  2424. ? NO_FLDS_IN_PULLADD_KEY
  2425. : NO_FLDS_IN_PUSHADD_KEY)) || (Index < 0)
  2426. )
  2427. {
  2428. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pAddKey);
  2429. return(GetNextVar(VarBind, MibPtr));
  2430. }
  2431. }
  2432. //
  2433. // The fixed part of the objid is corect. Update the rest.
  2434. //
  2435. //
  2436. // If there is not enough space, deallocate what is currently
  2437. // there and allocate.
  2438. //
  2439. if (VarBind->name.idLength <= (PNR_OIDLEN + 4))
  2440. {
  2441. UINT TableEntryIds[5]; //field and Ip address have a length of 5
  2442. AsnObjectIdentifier TableEntryOid = {OID_SIZEOF(TableEntryIds),
  2443. TableEntryIds };
  2444. SNMP_oidfree( &VarBind->name);
  2445. SNMP_oidcpy(&VarBind->name, &MIB_OidPrefix);
  2446. SNMP_oidappend(&VarBind->name, &MibPtr->Oid);
  2447. TableEntryIds[0] = (UINT)FieldNo;
  2448. OidIndex = 1;
  2449. TableEntryIds[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd >> 24);
  2450. TableEntryIds[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd >> 16 & 0xFF);
  2451. TableEntryIds[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd >> 8 & 0xFF);
  2452. TableEntryIds[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd & 0xFF);
  2453. TableEntryOid.idLength = OidIndex;
  2454. SNMP_oidappend(&VarBind->name, &TableEntryOid);
  2455. }
  2456. else
  2457. {
  2458. OidIndex = PNR_OIDLEN;
  2459. VarBind->name.ids[OidIndex++] = (UINT)FieldNo;
  2460. VarBind->name.ids[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd >> 24);
  2461. VarBind->name.ids[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd >> 16 & 0xFF);
  2462. VarBind->name.ids[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd >> 8 & 0xFF);
  2463. VarBind->name.ids[OidIndex++] = (UINT)((pAddKey + Index)->IpAdd & 0xFF);
  2464. VarBind->name.idLength = OidIndex;
  2465. }
  2466. //
  2467. // Get the value
  2468. //
  2469. if (KeyType_e == PULL_E_KEY)
  2470. {
  2471. ErrStat = PullGet(VarBind, NumAddKeys, pAddKey);
  2472. }
  2473. else
  2474. {
  2475. ErrStat = PushGet(VarBind, NumAddKeys, pAddKey);
  2476. }
  2477. //
  2478. // Let us free the memory that was allocated earlier. No need to
  2479. // check whether pAddKey is NULL. It just can not be otherwise we
  2480. // would have returned from this function earlier.
  2481. //
  2482. Exit:
  2483. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pAddKey);
  2484. return(ErrStat);
  2485. }
  2486. UINT
  2487. PullGet(
  2488. IN RFC1157VarBind *VarBind,
  2489. IN DWORD NumKeys,
  2490. IN LPVOID pKey
  2491. )
  2492. {
  2493. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2494. DWORD Field;
  2495. DWORD Index;
  2496. DWORD NumAddKeys = NumKeys;
  2497. IN PADD_KEY_T pAddKey = pKey;
  2498. if (pAddKey == NULL)
  2499. {
  2500. //
  2501. // Call EnumAddresses only if we have not been invoked by PnrGetNext
  2502. //
  2503. EnumAddKeys(PULL_E_KEY, &pAddKey, &NumAddKeys);
  2504. }
  2505. ErrStat = PnrMatch(VarBind, NumAddKeys, pAddKey, &Index, &Field,
  2506. PULL_E_KEY, MIB_GET, NULL);
  2507. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2508. {
  2509. goto Exit;
  2510. //return(ErrStat);
  2511. }
  2512. switch(Field)
  2513. {
  2514. case 1: //IP address itself
  2515. VarBind->value.asnType = ASN_RFC1155_IPADDRESS;
  2516. VarBind->value.asnValue.string.length = sizeof(ULONG);
  2517. if ( NULL == (VarBind->value.asnValue.string.stream =
  2518. SNMP_malloc(VarBind->value.asnValue.string.length
  2519. )) )
  2520. {
  2521. ErrStat = SNMP_ERRORSTATUS_GENERR;
  2522. goto Exit;
  2523. }
  2524. VarBind->value.asnValue.string.stream[0] =
  2525. (BYTE)((pAddKey + Index)->IpAdd >> 24);
  2526. VarBind->value.asnValue.string.stream[1] =
  2527. (BYTE)(((pAddKey + Index)->IpAdd >> 16) & 0xFF);
  2528. VarBind->value.asnValue.string.stream[2] =
  2529. (BYTE)(((pAddKey + Index)->IpAdd >> 8) & 0xFF);
  2530. VarBind->value.asnValue.string.stream[3] =
  2531. (BYTE)((pAddKey + Index)->IpAdd & 0xFF );
  2532. VarBind->value.asnValue.address.dynamic = TRUE;
  2533. #if 0
  2534. memcpy( VarBind->value.asnValue.string.stream,
  2535. (LPSTR)(&((pAddKey + Index)->IpAdd)),
  2536. VarBind->value.asnValue.string.length );
  2537. *((ULONG *)VarBind->value.asnValue.address.stream)
  2538. = (ULONG)(pAddKey + Index)->IpAdd;
  2539. #endif
  2540. #if 0
  2541. VarBind->value.asnValue.string.length =
  2542. strlen( (LPSTR)((pAddKey + Index)->asIpAddress));
  2543. if ( NULL ==
  2544. (VarBind->value.asnValue.string.stream =
  2545. SNMP_malloc(VarBind->value.asnValue.string.length *
  2546. sizeof(char))) )
  2547. {
  2548. ErrStat = SNMP_ERRORSTATUS_GENERR;
  2549. goto Exit;
  2550. }
  2551. memcpy( VarBind->value.asnValue.string.stream,
  2552. (LPSTR)((pAddKey + Index)->asIpAddress),
  2553. VarBind->value.asnValue.string.length );
  2554. #endif
  2555. break;
  2556. case 2: // SpTime
  2557. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  2558. if (((pAddKey + Index)->asSpTime[0]) != EOS)
  2559. {
  2560. VarBind->value.asnValue.string.length =
  2561. strlen( (LPSTR)((pAddKey + Index)->asSpTime));
  2562. if ( NULL ==
  2563. (VarBind->value.asnValue.string.stream =
  2564. SNMP_malloc(VarBind->value.asnValue.string.length *
  2565. sizeof(char))) )
  2566. {
  2567. ErrStat = SNMP_ERRORSTATUS_GENERR;
  2568. goto Exit;
  2569. }
  2570. memcpy( VarBind->value.asnValue.string.stream,
  2571. (LPSTR)((pAddKey + Index)->asSpTime),
  2572. VarBind->value.asnValue.string.length );
  2573. }
  2574. else
  2575. {
  2576. VarBind->value.asnValue.string.length = 0;
  2577. VarBind->value.asnValue.string.stream = NULL;
  2578. }
  2579. VarBind->value.asnValue.address.dynamic = TRUE;
  2580. break;
  2581. case 3: // TimeInterval
  2582. VarBind->value.asnType = ASN_INTEGER;
  2583. VarBind->value.asnValue.number =
  2584. (AsnInteger)((pAddKey + Index)->
  2585. TimeInterval);
  2586. break;
  2587. case 4: //Member Precedence
  2588. VarBind->value.asnType = ASN_INTEGER;
  2589. VarBind->value.asnValue.number =
  2590. (AsnInteger)((pAddKey + Index)->
  2591. MemberPrec);
  2592. break;
  2593. case 5: //No of successful replications
  2594. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  2595. VarBind->value.asnValue.number =
  2596. (AsnCounter)((pAddKey + Index)->
  2597. NoOfRpls);
  2598. break;
  2599. case 6: //No of replication failures due to comm failures
  2600. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  2601. VarBind->value.asnValue.number =
  2602. (AsnCounter)((pAddKey + Index)->
  2603. NoOfCommFails);
  2604. break;
  2605. case 7: //Low part of the highest vers. no of owned records
  2606. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  2607. VarBind->value.asnValue.number =
  2608. (AsnCounter)((pAddKey + Index)->
  2609. VersNo.LowPart);
  2610. break;
  2611. case 8: //High part of the highest vers. no of owned records
  2612. VarBind->value.asnType = ASN_RFC1155_COUNTER;
  2613. VarBind->value.asnValue.number =
  2614. (AsnCounter)((pAddKey + Index)->
  2615. VersNo.HighPart);
  2616. break;
  2617. default:
  2618. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  2619. break;
  2620. }
  2621. Exit:
  2622. //
  2623. // if we allocated memory here, free it
  2624. //
  2625. if ((pKey == NULL) && (pAddKey != NULL))
  2626. {
  2627. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pAddKey);
  2628. }
  2629. return(ErrStat);
  2630. }
  2631. UINT
  2632. PnrMatch(
  2633. IN RFC1157VarBind *VarBind,
  2634. DWORD NoOfKeys,
  2635. IN PADD_KEY_T pAddKey,
  2636. IN LPDWORD pIndex,
  2637. IN LPDWORD pField,
  2638. IN KEY_TYPE_E KeyType_e,
  2639. IN UINT PduAction,
  2640. IN LPBOOL pfFirst
  2641. )
  2642. {
  2643. DWORD OidIndex;
  2644. DWORD Index;
  2645. DWORD AddIndex;
  2646. DWORD Add = 0;
  2647. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2648. DWORD AddLen;
  2649. ASSERT(PduAction != MIB_SET);
  2650. if (pfFirst != NULL)
  2651. {
  2652. *pfFirst = FALSE;
  2653. }
  2654. //
  2655. // If there are no keys, return error
  2656. //
  2657. if (NoOfKeys == 0)
  2658. {
  2659. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  2660. }
  2661. //
  2662. // fixed part of the PullPnr table entries
  2663. //
  2664. OidIndex = PNR_OIDLEN;
  2665. //
  2666. // if the field specified is more than the max. in the table entry
  2667. // barf
  2668. //
  2669. if (
  2670. (NoOfKeys == 0)
  2671. ||
  2672. ((*pField = VarBind->name.ids[OidIndex++]) >
  2673. (DWORD)
  2674. ((KeyType_e == PULL_E_KEY) ? NO_FLDS_IN_PULLADD_KEY
  2675. : NO_FLDS_IN_PUSHADD_KEY))
  2676. )
  2677. {
  2678. if (PduAction == MIB_GETNEXT)
  2679. {
  2680. if (NoOfKeys == 0)
  2681. {
  2682. *pfFirst = TRUE;
  2683. }
  2684. else
  2685. {
  2686. *pIndex = NoOfKeys - 1;
  2687. }
  2688. }
  2689. else
  2690. {
  2691. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  2692. }
  2693. goto Exit;
  2694. }
  2695. //
  2696. // get the length of key specified
  2697. //
  2698. AddLen = VarBind->name.idLength - (PNR_OIDLEN + 1);
  2699. AddIndex = OidIndex;
  2700. for (Index = 0; Index < AddLen; Index++)
  2701. {
  2702. Add = Add | (((BYTE)(VarBind->name.ids[AddIndex++])) << (24 - (Index * 8)));
  2703. }
  2704. //
  2705. // Check if the address specified matches with one of the keys
  2706. //
  2707. for (Index = 0; Index < NoOfKeys; Index++, pAddKey++)
  2708. {
  2709. if (Add == pAddKey->IpAdd)
  2710. {
  2711. *pIndex = Index;
  2712. return(SNMP_ERRORSTATUS_NOERROR);
  2713. }
  2714. else
  2715. {
  2716. //
  2717. // if passed in value is greater, continue on to
  2718. // the next item. The list is in ascending order
  2719. //
  2720. if (Add > pAddKey->IpAdd)
  2721. {
  2722. continue;
  2723. }
  2724. else
  2725. {
  2726. //
  2727. // the list element is > passed in value,
  2728. // break out of the loop
  2729. //
  2730. break;
  2731. }
  2732. }
  2733. }
  2734. //
  2735. // if no match, but field is GetNext, return the (highest index - 1)
  2736. // reached above. This is because, PnrFindNext will be called by
  2737. // the caller
  2738. //
  2739. if (PduAction == MIB_GETNEXT)
  2740. {
  2741. if (Index == 0)
  2742. {
  2743. *pfFirst = TRUE;
  2744. }
  2745. else
  2746. {
  2747. *pIndex = Index - 1;
  2748. }
  2749. ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2750. goto Exit;
  2751. }
  2752. else
  2753. {
  2754. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  2755. }
  2756. Exit:
  2757. return(ErrStat);
  2758. }
  2759. UINT
  2760. PnrFindNext(
  2761. INT AddKeyNo,
  2762. DWORD NumAddKeys,
  2763. PADD_KEY_T pAddKey
  2764. )
  2765. {
  2766. DWORD i;
  2767. LONG nextif;
  2768. //
  2769. // if AddKeyNo is 0 or more, search for the key next to
  2770. // the key passed.
  2771. //
  2772. for (nextif = -1, i = 0 ; i < NumAddKeys; i++)
  2773. {
  2774. if (AddKeyNo >= 0)
  2775. {
  2776. if ( (pAddKey + i)->IpAdd <=
  2777. (pAddKey + AddKeyNo)->IpAdd)
  2778. {
  2779. //
  2780. // This item is lexicographically less or equal,
  2781. // continue
  2782. //
  2783. continue;
  2784. }
  2785. else
  2786. {
  2787. nextif = i;
  2788. break;
  2789. }
  2790. }
  2791. else
  2792. {
  2793. //
  2794. // We want the first key
  2795. //
  2796. nextif = 0;
  2797. break;
  2798. }
  2799. #if 0
  2800. //
  2801. // if we want the first entry, then continue until
  2802. // we get an entry that is lexicographically same or
  2803. // greater
  2804. //
  2805. if (
  2806. (nextif < 0)
  2807. ||
  2808. (pAddKey + (i - 1))->IpAdd < (pAddKey + nextif)->IpAdd
  2809. )
  2810. {
  2811. nextif = i;
  2812. }
  2813. #endif
  2814. }
  2815. return(nextif);
  2816. }
  2817. UINT
  2818. PnrGetFirst(
  2819. IN RFC1157VarBind *VarBind,
  2820. IN MIB_ENTRY *MibPtr,
  2821. IN KEY_TYPE_E KeyType_e
  2822. )
  2823. {
  2824. PADD_KEY_T pAddKey = NULL;
  2825. DWORD NumAddKeys;
  2826. INT Iface;
  2827. UINT TableEntryIds[5];
  2828. AsnObjectIdentifier TableEntryOid = { OID_SIZEOF(TableEntryIds),
  2829. TableEntryIds };
  2830. UINT ErrStat;
  2831. //
  2832. // Get all the address key information
  2833. //
  2834. EnumAddKeys(KeyType_e, &pAddKey, &NumAddKeys);
  2835. //
  2836. // If there is no entry in the table, go to the next MIB variable
  2837. //
  2838. if (NumAddKeys == 0)
  2839. {
  2840. return(GetNextVar(VarBind, MibPtr));
  2841. }
  2842. //
  2843. // Get the first entry in the table
  2844. //
  2845. Iface = PnrFindNext(-1, NumAddKeys, pAddKey);
  2846. //
  2847. // Write the object Id into the binding list and call get
  2848. // func
  2849. //
  2850. SNMP_oidfree( &VarBind->name );
  2851. SNMP_oidcpy( &VarBind->name, &MIB_OidPrefix );
  2852. SNMP_oidappend( &VarBind->name, &MibPtr->Oid );
  2853. //
  2854. // The fixed part of the objid is correct. Update the rest.
  2855. //
  2856. TableEntryIds[0] = 1;
  2857. TableEntryIds[1] = (UINT)((pAddKey + Iface)->IpAdd >> 24);
  2858. TableEntryIds[2] = (UINT)(((pAddKey + Iface)->IpAdd >> 16)
  2859. & 0xFF);
  2860. TableEntryIds[3] = (UINT)(((pAddKey + Iface)->IpAdd >> 8)
  2861. & 0xFF);
  2862. TableEntryIds[4] = (UINT)((pAddKey + Iface)->IpAdd & 0xFF);
  2863. SNMP_oidappend( &VarBind->name, &TableEntryOid );
  2864. ErrStat = (KeyType_e == PULL_E_KEY)
  2865. ? PullGet(VarBind, NumAddKeys, pAddKey)
  2866. : PushGet(VarBind, NumAddKeys, pAddKey);
  2867. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pAddKey);
  2868. return(ErrStat);
  2869. }
  2870. UINT
  2871. PullSet(
  2872. IN RFC1157VarBind *VarBind
  2873. )
  2874. {
  2875. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2876. DWORD Field;
  2877. ADD_KEY_T AddKey;
  2878. #if 0
  2879. LPBYTE pTmpB;
  2880. #endif
  2881. struct in_addr InAddr;
  2882. //
  2883. // Extract the field that needs to be set
  2884. //
  2885. Field = VarBind->name.ids[PULLPNR_OIDLEN];
  2886. AddKey.IpAdd = (VarBind->name.ids[PNR_OIDLEN + 1] << 24);
  2887. AddKey.IpAdd |= (VarBind->name.ids[PNR_OIDLEN + 2] << 16);
  2888. AddKey.IpAdd |= (VarBind->name.ids[PNR_OIDLEN + 3] << 8);
  2889. AddKey.IpAdd |= VarBind->name.ids[PNR_OIDLEN + 4];
  2890. InAddr.s_addr = htonl(AddKey.IpAdd);
  2891. //
  2892. // The storage must be adequate to contain the new
  2893. // string including a NULL terminator.
  2894. //
  2895. strcpy( (LPSTR)AddKey.asIpAddress, inet_ntoa(InAddr) );
  2896. switch(Field)
  2897. {
  2898. case 1:
  2899. if (VarBind->value.asnType != ASN_RFC1155_IPADDRESS)
  2900. {
  2901. return(SNMP_ERRORSTATUS_BADVALUE);
  2902. }
  2903. #if 0
  2904. pTmpB =
  2905. VarBind->value.asnValue.string.stream;
  2906. NMSMSGF_RETRIEVE_IPADD_M(pTmpB, AddKey.IpAdd);
  2907. InAddr.s_addr = htonl(AddKey.IpAdd);
  2908. //
  2909. // The storage must be adequate to contain the new
  2910. // string including a NULL terminator.
  2911. //
  2912. strcpy(
  2913. (LPSTR)AddKey.asIpAddress,
  2914. inet_ntoa(InAddr)
  2915. );
  2916. #endif
  2917. #if 0
  2918. memcpy( (LPSTR)AddKey.asIpAddress,
  2919. VarBind->value.asnValue.string.stream,
  2920. VarBind->value.asnValue.string.length );
  2921. ((LPSTR)AddKey.asIpAddress)
  2922. [VarBind->value.asnValue.string.length] = '\0';
  2923. #endif
  2924. break;
  2925. case 2: // SpTime
  2926. if (VarBind->value.asnType != ASN_RFC1213_DISPSTRING)
  2927. {
  2928. return(SNMP_ERRORSTATUS_BADVALUE);
  2929. }
  2930. // The storage must be adequate to contain the new
  2931. // string including a NULL terminator.
  2932. memcpy( (LPSTR)AddKey.asSpTime,
  2933. VarBind->value.asnValue.string.stream,
  2934. VarBind->value.asnValue.string.length );
  2935. ((LPSTR)AddKey.asSpTime)
  2936. [VarBind->value.asnValue.string.length] = '\0';
  2937. break;
  2938. case 3: // TimeInterval
  2939. if (VarBind->value.asnType != ASN_INTEGER)
  2940. {
  2941. return(SNMP_ERRORSTATUS_BADVALUE);
  2942. }
  2943. (AsnInteger)(AddKey.TimeInterval) =
  2944. VarBind->value.asnValue.number;
  2945. break;
  2946. case 4: // MemberPrec
  2947. if (VarBind->value.asnType != ASN_INTEGER)
  2948. {
  2949. return(SNMP_ERRORSTATUS_BADVALUE);
  2950. }
  2951. (AsnInteger)(AddKey.MemberPrec) =
  2952. VarBind->value.asnValue.number;
  2953. break;
  2954. case 5: //fall through
  2955. case 6: //fall through
  2956. case 7: //fall through
  2957. case 8: //fall through
  2958. ErrStat = SNMP_ERRORSTATUS_READONLY;
  2959. break;
  2960. default:
  2961. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  2962. break;
  2963. }
  2964. if (ErrStat == SNMP_ERRORSTATUS_NOERROR)
  2965. {
  2966. ErrStat = WriteKeyNValues(PULL_E_KEY, &AddKey, Field);
  2967. }
  2968. return(ErrStat);
  2969. } //PullSet
  2970. UINT
  2971. WriteKeyNValues(
  2972. KEY_TYPE_E KeyType_e,
  2973. PADD_KEY_T pAddKey,
  2974. DWORD FieldNo
  2975. )
  2976. {
  2977. HKEY AddKeyHdl;
  2978. HKEY RootKeyHdl;
  2979. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  2980. //
  2981. // Open the Parameters key and the key under that
  2982. //
  2983. ErrStat = OpenKey(PARTNERS_E_KEY, NULL, NULL, NULL, TRUE);
  2984. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2985. {
  2986. return(ErrStat);
  2987. }
  2988. ErrStat = OpenKey(KeyType_e, NULL, &RootKeyHdl, NULL, TRUE);
  2989. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2990. {
  2991. return(ErrStat);
  2992. }
  2993. ErrStat = OpenKey(IPADD_E_KEY, pAddKey->asIpAddress, &AddKeyHdl, &RootKeyHdl, TRUE);
  2994. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  2995. {
  2996. return(ErrStat);
  2997. }
  2998. switch(FieldNo)
  2999. {
  3000. case(1):
  3001. //
  3002. // for this field, we don't need to do anything.
  3003. // The field (actually the key) has already been
  3004. // created.
  3005. //
  3006. break;
  3007. case(2):
  3008. if (KeyType_e == PUSH_E_KEY)
  3009. {
  3010. MIB_UpdateCountStore =
  3011. pAddKey->UpdateCount;
  3012. VarInfo[UPD_CNT_E].pRootKey = &AddKeyHdl;
  3013. SetVal(&VarInfo[UPD_CNT_E]);
  3014. }
  3015. else
  3016. {
  3017. strcpy(MIB_SpTimeStore, pAddKey->asSpTime);
  3018. VarInfo[SP_TIME_E].SizeOfData = strlen(pAddKey->asSpTime);
  3019. VarInfo[SP_TIME_E].pRootKey = &AddKeyHdl;
  3020. SetVal(&VarInfo[SP_TIME_E]);
  3021. }
  3022. break;
  3023. case(3):
  3024. MIB_TimeIntervalStore = pAddKey->TimeInterval;
  3025. VarInfo[TIME_INTVL_E].pRootKey = &AddKeyHdl;
  3026. SetVal(&VarInfo[TIME_INTVL_E]);
  3027. break;
  3028. case(4):
  3029. MIB_MemberPrecStore = pAddKey->MemberPrec;
  3030. VarInfo[MEMBER_PREC_E].pRootKey = &AddKeyHdl;
  3031. SetVal(&VarInfo[MEMBER_PREC_E]);
  3032. break;
  3033. default:
  3034. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  3035. break;
  3036. }
  3037. //
  3038. // Let us close the keys that we opened/created
  3039. //
  3040. SNMPDBG((
  3041. SNMP_LOG_VERBOSE,
  3042. "WINSMIB: Closing AddKeyHdl 0x%08lx.\n",
  3043. AddKeyHdl
  3044. ));
  3045. SNMPDBG((
  3046. SNMP_LOG_VERBOSE,
  3047. "WINSMIB: Closing RootKeyHdl 0x%08lx.\n",
  3048. RootKeyHdl
  3049. ));
  3050. SNMPDBG((
  3051. SNMP_LOG_VERBOSE,
  3052. "WINSMIB: Closing sParametersKey 0x%08lx (fKeyOpen=%s).\n",
  3053. sParametersKey, sfParametersKeyOpen ? "TRUE" : "FALSE"
  3054. ));
  3055. RegCloseKey(AddKeyHdl);
  3056. CloseReqKey();
  3057. /*
  3058. RegCloseKey(RootKeyHdl);
  3059. RegCloseKey(sParametersKey);
  3060. */
  3061. return(SNMP_ERRORSTATUS_NOERROR);
  3062. }
  3063. UINT
  3064. MIB_PullTable(
  3065. IN UINT Action,
  3066. IN MIB_ENTRY *MibPtr,
  3067. IN RFC1157VarBind *VarBind
  3068. )
  3069. {
  3070. //
  3071. // if the length indicates a 0 or partial key, then only the get next
  3072. // operation is allowed. The field and the full key
  3073. // have a length of 5
  3074. //
  3075. if (VarBind->name.idLength <= (PULLPNR_OIDLEN + 4))
  3076. {
  3077. if ((Action == MIB_GET) || (Action == MIB_SET))
  3078. {
  3079. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  3080. }
  3081. }
  3082. return(
  3083. MIB_Table(PULL_TABLE_INDEX, Action, MibPtr, VarBind, PULL_E_KEY)
  3084. );
  3085. }
  3086. UINT
  3087. MIB_PushTable(
  3088. IN UINT Action,
  3089. IN MIB_ENTRY *MibPtr,
  3090. IN RFC1157VarBind *VarBind
  3091. )
  3092. {
  3093. //
  3094. // if the length indicates a 0 or partial key, then only the get next
  3095. // operation is allowed. The field and the full key
  3096. // have a length of 5.
  3097. //
  3098. if (VarBind->name.idLength <= (PUSHPNR_OIDLEN + 4))
  3099. {
  3100. if ((Action == MIB_GET) || (Action == MIB_SET))
  3101. {
  3102. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  3103. }
  3104. }
  3105. return(
  3106. MIB_Table(PUSH_TABLE_INDEX, Action, MibPtr, VarBind, PUSH_E_KEY)
  3107. );
  3108. }
  3109. UINT
  3110. MIB_DFTable(
  3111. IN UINT Action,
  3112. IN MIB_ENTRY *MibPtr,
  3113. IN RFC1157VarBind *VarBind
  3114. )
  3115. {
  3116. //
  3117. // if the length indicates a 0 or partial key, then only the get next
  3118. // operation is allowed. Actually, the length can never
  3119. // be < DF_OIDLEN + 1
  3120. //
  3121. if (VarBind->name.idLength <= (DF_OIDLEN + 1))
  3122. {
  3123. if ((Action == MIB_GET) || (Action == MIB_SET))
  3124. {
  3125. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  3126. }
  3127. Action = MIB_GETFIRST;
  3128. }
  3129. return(
  3130. MIB_Table(DF_TABLE_INDEX, Action, MibPtr, VarBind, PUSH_E_KEY)
  3131. );
  3132. }
  3133. UINT
  3134. MIB_DRTable(
  3135. IN UINT Action,
  3136. IN MIB_ENTRY *MibPtr,
  3137. IN RFC1157VarBind *VarBind
  3138. )
  3139. {
  3140. time_t CurrentTime;
  3141. DWORD RetStat = WINSINTF_SUCCESS;
  3142. if (Action == MIB_SET)
  3143. {
  3144. return(SNMP_ERRORSTATUS_READONLY);
  3145. }
  3146. //
  3147. // if the length indicates a 0 or partial key, then only the get next
  3148. // operation is allowed. Actually, the length can never
  3149. // be < DR_OIDLEN + 1
  3150. //
  3151. if (VarBind->name.idLength <= (DR_OIDLEN + 1))
  3152. {
  3153. if ((Action == MIB_GET) || (Action == MIB_SET))
  3154. {
  3155. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  3156. }
  3157. }
  3158. (void)time(&CurrentTime);
  3159. if ((CurrentTime - sDRCacheInitTime) > WINSMIB_DR_CACHE_TIME)
  3160. {
  3161. if ((RetStat = PopulateDRCache()) == WINSINTF_SUCCESS)
  3162. {
  3163. sDRCacheInitTime = CurrentTime;
  3164. }
  3165. if ((RetStat != WINSINTF_SUCCESS) || (sRecs.NoOfRecs == 0))
  3166. {
  3167. if (Action == MIB_GETNEXT)
  3168. {
  3169. return(GetNextVar(VarBind, MibPtr));
  3170. }
  3171. else
  3172. {
  3173. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  3174. }
  3175. }
  3176. }
  3177. return(
  3178. MIB_Table(DR_TABLE_INDEX, Action, MibPtr, VarBind, PUSH_E_KEY)
  3179. );
  3180. }
  3181. UINT
  3182. MIB_Table(
  3183. IN DWORD Index,
  3184. IN UINT Action,
  3185. IN MIB_ENTRY *MibPtr,
  3186. IN RFC1157VarBind *VarBind,
  3187. IN KEY_TYPE_E KeyType_e
  3188. )
  3189. {
  3190. UINT ErrStat;
  3191. switch(Action)
  3192. {
  3193. case(MIB_GET):
  3194. ErrStat = (*Tables[Index].ti_get)(VarBind, 0, NULL);
  3195. break;
  3196. case(MIB_GETFIRST):
  3197. ErrStat = (*Tables[Index].ti_getf)(VarBind, MibPtr, KeyType_e);
  3198. break;
  3199. case(MIB_GETNEXT):
  3200. ErrStat = (*Tables[Index].ti_getn)(VarBind, MibPtr, KeyType_e);
  3201. break;
  3202. case(MIB_SET):
  3203. ErrStat = (*Tables[Index].ti_set)(VarBind);
  3204. break;
  3205. default:
  3206. ErrStat = SNMP_ERRORSTATUS_GENERR;
  3207. break;
  3208. }
  3209. return(ErrStat);
  3210. } //MIB_Table
  3211. UINT
  3212. PushSet(
  3213. IN RFC1157VarBind *VarBind
  3214. )
  3215. {
  3216. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  3217. DWORD Field;
  3218. ADD_KEY_T AddKey;
  3219. LPBYTE pTmpB;
  3220. struct in_addr InAddr;
  3221. Field = VarBind->name.ids[PUSHPNR_OIDLEN];
  3222. AddKey.IpAdd = VarBind->name.ids[PNR_OIDLEN + 1] << 24;
  3223. AddKey.IpAdd |= (VarBind->name.ids[PNR_OIDLEN + 2] << 16);
  3224. AddKey.IpAdd |= (VarBind->name.ids[PNR_OIDLEN + 3] << 8);
  3225. AddKey.IpAdd |= VarBind->name.ids[PNR_OIDLEN + 4];
  3226. InAddr.s_addr = htonl(AddKey.IpAdd);
  3227. //
  3228. // The storage must be adequate to contain the new
  3229. // string including a NULL terminator.
  3230. //
  3231. pTmpB = inet_ntoa(InAddr);
  3232. if (NULL == pTmpB) {
  3233. return SNMP_ERRORSTATUS_GENERR;
  3234. }
  3235. strcpy( (LPSTR)AddKey.asIpAddress, pTmpB);
  3236. switch(Field)
  3237. {
  3238. case 1:
  3239. if (VarBind->value.asnType != ASN_RFC1155_IPADDRESS)
  3240. {
  3241. return(SNMP_ERRORSTATUS_BADVALUE);
  3242. }
  3243. break;
  3244. case 2: // UpdateCount
  3245. if (VarBind->value.asnType != ASN_INTEGER)
  3246. {
  3247. return(SNMP_ERRORSTATUS_BADVALUE);
  3248. }
  3249. (AsnInteger)(AddKey.UpdateCount) =
  3250. VarBind->value.asnValue.number;
  3251. break;
  3252. default:
  3253. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  3254. break;
  3255. }
  3256. if (ErrStat == SNMP_ERRORSTATUS_NOERROR)
  3257. {
  3258. ErrStat = WriteKeyNValues(PUSH_E_KEY, &AddKey, Field);
  3259. }
  3260. return(ErrStat);
  3261. } //PushSet
  3262. UINT
  3263. PushGet(
  3264. IN RFC1157VarBind *VarBind,
  3265. IN DWORD NumKeys,
  3266. IN LPVOID pKey
  3267. )
  3268. {
  3269. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  3270. DWORD Field;
  3271. DWORD Index;
  3272. DWORD NumAddKeys = NumKeys;
  3273. IN PADD_KEY_T pAddKey = pKey;
  3274. if (pAddKey == NULL)
  3275. {
  3276. //
  3277. // Call EnumAddresses only if we have not been invoked by PnrGetNext
  3278. //
  3279. EnumAddKeys(PUSH_E_KEY, &pAddKey, &NumAddKeys);
  3280. }
  3281. ErrStat = PnrMatch(VarBind, NumAddKeys, pAddKey, &Index, &Field,
  3282. PUSH_E_KEY, MIB_GET, NULL);
  3283. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  3284. {
  3285. return(ErrStat);
  3286. }
  3287. switch(Field)
  3288. {
  3289. case 1: //IP address itself
  3290. VarBind->value.asnType = ASN_RFC1155_IPADDRESS;
  3291. VarBind->value.asnValue.string.length = sizeof(ULONG);
  3292. if ( NULL ==
  3293. (VarBind->value.asnValue.string.stream =
  3294. SNMP_malloc(VarBind->value.asnValue.string.length
  3295. )) )
  3296. {
  3297. ErrStat = SNMP_ERRORSTATUS_GENERR;
  3298. goto Exit;
  3299. }
  3300. //
  3301. // SNMP expects the MSB to be in the first byte, MSB-1
  3302. // to be in the second, ....
  3303. //
  3304. VarBind->value.asnValue.string.stream[0] =
  3305. (BYTE)((pAddKey + Index)->IpAdd >> 24);
  3306. VarBind->value.asnValue.string.stream[1] =
  3307. (BYTE)(((pAddKey + Index)->IpAdd >> 16) & 0xFF);
  3308. VarBind->value.asnValue.string.stream[2] =
  3309. (BYTE)(((pAddKey + Index)->IpAdd >> 8) & 0xFF);
  3310. VarBind->value.asnValue.string.stream[3] =
  3311. (BYTE)((pAddKey + Index)->IpAdd & 0xFF );
  3312. VarBind->value.asnValue.address.dynamic = TRUE;
  3313. break;
  3314. case 2: // UpdateCount
  3315. VarBind->value.asnType = ASN_INTEGER;
  3316. VarBind->value.asnValue.number =
  3317. (AsnInteger)((pAddKey + Index)->
  3318. UpdateCount);
  3319. break;
  3320. default:
  3321. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  3322. break;
  3323. }
  3324. Exit:
  3325. if ((pKey == NULL) && (pAddKey != NULL))
  3326. {
  3327. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pAddKey);
  3328. }
  3329. return(ErrStat);
  3330. } // PushGet
  3331. UINT
  3332. EnumAddKeys(
  3333. KEY_TYPE_E KeyType_e,
  3334. PADD_KEY_T *ppAddKey,
  3335. LPDWORD pNumAddKeys
  3336. )
  3337. {
  3338. LONG RetVal;
  3339. TCHAR KeyName[20]; // will hold name of subkey of
  3340. // PULL/PUSH records. These keys are IP
  3341. // addresses for which 20 is a
  3342. // big enough size
  3343. #ifdef UNICODE
  3344. CHAR AscKeyName[20];
  3345. #endif
  3346. DWORD KeyNameSz;
  3347. FILETIME LastWrite;
  3348. DWORD BuffSize;
  3349. HKEY SubKey;
  3350. DWORD ValTyp;
  3351. DWORD Sz;
  3352. DWORD NoOfPnrs = 0; //# of PULL or PUSH pnrs
  3353. DWORD NoOfVals;
  3354. HKEY KeyHdl;
  3355. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  3356. PADD_KEY_T pAddKey;
  3357. PADD_KEY_T pAddKeySave;
  3358. DWORD IndexOfPnr;
  3359. HANDLE PrHeapHdl;
  3360. *pNumAddKeys = 0; //init to 0
  3361. PrHeapHdl = GetProcessHeap();
  3362. /*
  3363. * Open the key (PARTNERS)
  3364. */
  3365. ErrStat = OpenKey(PARTNERS_E_KEY, NULL, NULL, NULL, FALSE);
  3366. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  3367. {
  3368. return(ErrStat);
  3369. }
  3370. //
  3371. // Open the Pull/Push key
  3372. //
  3373. ErrStat = OpenKey(KeyType_e, NULL, &KeyHdl, NULL, FALSE);
  3374. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  3375. {
  3376. CloseReqKey();
  3377. return(ErrStat);
  3378. }
  3379. else //key was successfully opened
  3380. {
  3381. /*
  3382. * Query the key. The subkeys are IP addresses of PULL
  3383. * partners.
  3384. */
  3385. GetKeyInfo(
  3386. KeyHdl,
  3387. &NoOfPnrs,
  3388. &NoOfVals //ignored
  3389. );
  3390. if (NoOfPnrs == 0)
  3391. {
  3392. *ppAddKey = NULL;
  3393. }
  3394. else
  3395. {
  3396. //
  3397. // Allocate buffer big enough to hold data for
  3398. // the number of subkeys found under the PULL key
  3399. //
  3400. BuffSize = sizeof(ADD_KEY_T) * NoOfPnrs;
  3401. *ppAddKey = HeapAlloc(
  3402. PrHeapHdl,
  3403. HEAP_NO_SERIALIZE |
  3404. HEAP_GENERATE_EXCEPTIONS |
  3405. HEAP_ZERO_MEMORY,
  3406. BuffSize
  3407. );
  3408. if (NULL == *ppAddKey) {
  3409. return SNMP_ERRORSTATUS_RESOURCEUNAVAILABLE;
  3410. }
  3411. pAddKey = *ppAddKey;
  3412. pAddKeySave = pAddKey;
  3413. /*
  3414. * For each key, get the values
  3415. */
  3416. for(
  3417. IndexOfPnr = 0;
  3418. IndexOfPnr < NoOfPnrs;
  3419. IndexOfPnr++
  3420. )
  3421. {
  3422. KeyNameSz = sizeof(KeyName); //init before every call
  3423. RetVal = RegEnumKeyEx(
  3424. KeyHdl, //handle of Push/Pull key
  3425. IndexOfPnr, //key
  3426. KeyName,
  3427. &KeyNameSz,
  3428. NULL, //reserved
  3429. NULL, //don't need class name
  3430. NULL, //ptr to var. to hold class name
  3431. &LastWrite //not looked at by us
  3432. );
  3433. if (RetVal != ERROR_SUCCESS)
  3434. {
  3435. break;
  3436. }
  3437. #ifdef UNICODE
  3438. if (wcstombs(AscKeyName, KeyName, KeyNameSz) == -1)
  3439. {
  3440. DBGPRINT0(ERR,
  3441. "Conversion not possible in the current locale\n");
  3442. }
  3443. AscKeyName[KeyNameSz] = EOS;
  3444. NONPORT("Call a comm function to do this")
  3445. pAddKey->IpAdd = inet_addr(AscKeyName);
  3446. strcpy(pAddKey->asIpAddress, AscKeyName);
  3447. #else
  3448. pAddKey->IpAdd = inet_addr(KeyName);
  3449. strcpy(pAddKey->asIpAddress, KeyName);
  3450. #endif
  3451. //
  3452. // inet_addr returns bytes in network byte order
  3453. // (Left to
  3454. // Right). Let us convert this into host order. This
  3455. // will avoid confusion later on. All formatting
  3456. // functions
  3457. // expect address to be in host order.
  3458. //
  3459. pAddKey->IpAdd = ntohl( pAddKey->IpAdd );
  3460. RetVal = RegOpenKeyEx(
  3461. KeyHdl,
  3462. KeyName,
  3463. 0, //reserved; must be 0
  3464. KEY_READ,
  3465. &SubKey
  3466. );
  3467. if (RetVal != ERROR_SUCCESS)
  3468. {
  3469. CloseReqKey();
  3470. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE,
  3471. *ppAddKey);
  3472. *ppAddKey = NULL;
  3473. return(SNMP_ERRORSTATUS_GENERR);
  3474. }
  3475. if (KeyType_e == PULL_E_KEY)
  3476. {
  3477. //
  3478. // Read in specific time for replication if one
  3479. // has been specified
  3480. //
  3481. GetSpTimeData(SubKey, pAddKey);
  3482. Sz = sizeof(pAddKey->TimeInterval);
  3483. RetVal = RegQueryValueEx(
  3484. SubKey,
  3485. WINSCNF_RPL_INTERVAL_NM,
  3486. NULL, //reserved; must be NULL
  3487. &ValTyp,
  3488. (LPBYTE)&(pAddKey->TimeInterval),
  3489. &Sz
  3490. );
  3491. if (RetVal != ERROR_SUCCESS)
  3492. {
  3493. pAddKey->TimeInterval = 0;
  3494. pAddKey->fTimeIntOrUpdCntSet = FALSE;
  3495. }
  3496. else // a value was read in
  3497. {
  3498. pAddKey->fTimeIntOrUpdCntSet = TRUE;
  3499. }
  3500. Sz = sizeof(pAddKey->MemberPrec);
  3501. RetVal = RegQueryValueEx(
  3502. SubKey,
  3503. WINSCNF_MEMBER_PREC_NM,
  3504. NULL, //reserved; must be NULL
  3505. &ValTyp,
  3506. (LPBYTE)&(pAddKey->MemberPrec),
  3507. &Sz
  3508. );
  3509. if (RetVal != ERROR_SUCCESS)
  3510. {
  3511. pAddKey->MemberPrec = 0;
  3512. }
  3513. }
  3514. else // it is a PUSH record
  3515. {
  3516. //
  3517. // Currently, we don't support periodic
  3518. // or specific time replication for Push
  3519. // records
  3520. //
  3521. Sz = sizeof(pAddKey->UpdateCount);
  3522. RetVal = RegQueryValueEx(
  3523. SubKey,
  3524. WINSCNF_UPDATE_COUNT_NM,
  3525. NULL,
  3526. &ValTyp,
  3527. (LPBYTE)&(pAddKey->UpdateCount),
  3528. &Sz
  3529. );
  3530. if (RetVal != ERROR_SUCCESS)
  3531. {
  3532. pAddKey->UpdateCount = 0;
  3533. pAddKey->fTimeIntOrUpdCntSet = FALSE;
  3534. }
  3535. else
  3536. {
  3537. pAddKey->fTimeIntOrUpdCntSet = TRUE;
  3538. }
  3539. }
  3540. pAddKey->NoOfRpls = 0;
  3541. pAddKey->NoOfCommFails = 0;
  3542. WINS_ASSIGN_INT_TO_VERS_NO_M(pAddKey->VersNo, 0);
  3543. RegCloseKey(SubKey);
  3544. pAddKey++;
  3545. } // end of for {..} for looping over subkeys of PULL
  3546. NoOfPnrs = IndexOfPnr;
  3547. /*
  3548. * Close the key
  3549. */
  3550. // RegCloseKey(KeyHdl);
  3551. } //end of else (key could not be opened)
  3552. if ((NoOfPnrs > 0) && (KeyType_e == PULL_E_KEY))
  3553. {
  3554. DWORD Status;
  3555. DWORD i, j;
  3556. WINSINTF_RESULTS_NEW_T ResultsN;
  3557. WINSINTF_RESULTS_T Results;
  3558. handle_t BindHdl;
  3559. PWINSINTF_RPL_COUNTERS_T pTmp;
  3560. PWINSINTF_ADD_VERS_MAP_T pTmp2;
  3561. BOOL fOld = FALSE;
  3562. // pAddKey = *ppAddKey;
  3563. BindHdl = WinsBind(&sBindData);
  3564. ResultsN.WinsStat.NoOfPnrs = 0;
  3565. ResultsN.WinsStat.pRplPnrs = NULL;
  3566. ResultsN.pAddVersMaps = NULL;
  3567. if ((Status = WinsStatusNew(BindHdl, WINSINTF_E_STAT, &ResultsN)) ==
  3568. RPC_S_PROCNUM_OUT_OF_RANGE)
  3569. {
  3570. Results.WinsStat.NoOfPnrs = 0;
  3571. Results.WinsStat.pRplPnrs = NULL;
  3572. Status = WinsStatus(BindHdl, WINSINTF_E_STAT, &Results);
  3573. fOld = TRUE;
  3574. }
  3575. PERF("Can be speeded up by restructuring the data structure and code on the")
  3576. PERF("Wins side")
  3577. if (Status == WINSINTF_SUCCESS)
  3578. {
  3579. DWORD NoOfRplPnrs;
  3580. DWORD NoOfOwners;
  3581. //
  3582. // Get the stats for comm. with pnrs. For this we
  3583. // compare each member that we found in the registry
  3584. // with all members returned in the WinsStat structure
  3585. // until there is a match. If there is no match, we
  3586. // make the values of the stats 0.
  3587. //
  3588. NoOfRplPnrs = fOld ? Results.WinsStat.NoOfPnrs :
  3589. ResultsN.WinsStat.NoOfPnrs;
  3590. if (NoOfRplPnrs > 0)
  3591. {
  3592. pTmp = fOld ? Results.WinsStat.pRplPnrs :
  3593. ResultsN.WinsStat.pRplPnrs;
  3594. for (j=0; j < NoOfRplPnrs; j++, pTmp++)
  3595. {
  3596. pAddKey = pAddKeySave; //init to the first element
  3597. for (i = 0; i < NoOfPnrs; i++, pAddKey++)
  3598. {
  3599. if (pAddKey->IpAdd == pTmp->Add.IPAdd)
  3600. {
  3601. pAddKey->NoOfRpls = pTmp->NoOfRpls;
  3602. pAddKey->NoOfCommFails =
  3603. pTmp->NoOfCommFails;
  3604. break;
  3605. }
  3606. }
  3607. }
  3608. // WinsFreeMem(fOld ? Results.WinsStat.pRplPnrs : ResultsN.WinsStat.pRplPnrs); // deallocation at the end of the if branch - bug #187206
  3609. }
  3610. //
  3611. // Add the highest vers. no. for each pnr
  3612. //
  3613. pTmp2 = fOld ? &Results.AddVersMaps[1] :
  3614. (ResultsN.pAddVersMaps + 1);
  3615. NoOfOwners = fOld ? Results.NoOfOwners : ResultsN.NoOfOwners;
  3616. NOTE("This is an assumption that we should not rely on in the future")
  3617. //
  3618. // We start from 1 since 0 is always the local WINS.
  3619. //
  3620. for (i = 1; i < NoOfOwners; i++, pTmp2++)
  3621. {
  3622. pAddKey = pAddKeySave;
  3623. for (j = 0; j < NoOfPnrs; j++, pAddKey++)
  3624. {
  3625. if (pAddKey->IpAdd == pTmp2->Add.IPAdd)
  3626. {
  3627. pAddKey->VersNo = pTmp2->VersNo;
  3628. break;
  3629. }
  3630. }
  3631. }
  3632. if (!fOld)
  3633. {
  3634. WinsFreeMem( ResultsN.pAddVersMaps);
  3635. }
  3636. WinsFreeMem( fOld? Results.WinsStat.pRplPnrs : ResultsN.WinsStat.pRplPnrs );
  3637. }
  3638. WinsUnbind(&sBindData, BindHdl);
  3639. }
  3640. if (NoOfPnrs > 1)
  3641. {
  3642. qsort((LPVOID)*ppAddKey,(size_t)NoOfPnrs,sizeof(ADD_KEY_T),CompareAdd );
  3643. }
  3644. }
  3645. CloseReqKey();
  3646. *pNumAddKeys = NoOfPnrs;
  3647. if ((*pNumAddKeys == 0) && (*ppAddKey != NULL))
  3648. {
  3649. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, *ppAddKey);
  3650. *ppAddKey = NULL;
  3651. }
  3652. return (ErrStat);
  3653. } // EnumAddKeys
  3654. UINT
  3655. GetKeyInfo(
  3656. IN HKEY Key,
  3657. OUT LPDWORD pNoOfSubKeys,
  3658. OUT LPDWORD pNoOfVals
  3659. )
  3660. /*++
  3661. Routine Description:
  3662. This function is called to get the number of subkeys under a key
  3663. Arguments:
  3664. Key - Key whose subkey count has to be determined
  3665. KeyType_e
  3666. pNoOfSubKeys
  3667. Externals Used:
  3668. None
  3669. Return Value:
  3670. None
  3671. Error Handling:
  3672. Called by:
  3673. GetPnrInfo()
  3674. Side Effects:
  3675. Comments:
  3676. None
  3677. --*/
  3678. {
  3679. TCHAR ClsStr[40];
  3680. DWORD ClsStrSz = sizeof(ClsStr);
  3681. DWORD LongestKeyLen;
  3682. DWORD LongestKeyClassLen;
  3683. DWORD LongestValueNameLen;
  3684. DWORD LongestValueDataLen;
  3685. DWORD SecDesc;
  3686. LONG RetVal;
  3687. FILETIME LastWrite;
  3688. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  3689. /*
  3690. Query the key.
  3691. */
  3692. RetVal = RegQueryInfoKey(
  3693. Key,
  3694. ClsStr,
  3695. &ClsStrSz,
  3696. NULL, //must be NULL, reserved
  3697. pNoOfSubKeys,
  3698. &LongestKeyLen,
  3699. &LongestKeyClassLen,
  3700. pNoOfVals,
  3701. &LongestValueNameLen,
  3702. &LongestValueDataLen,
  3703. &SecDesc,
  3704. &LastWrite
  3705. );
  3706. if (RetVal != ERROR_SUCCESS)
  3707. {
  3708. ErrStat = SNMP_ERRORSTATUS_GENERR;
  3709. }
  3710. return (ErrStat);
  3711. }
  3712. VOID
  3713. GetSpTimeData(
  3714. HKEY SubKey,
  3715. PADD_KEY_T pAddKey
  3716. )
  3717. /*++
  3718. Routine Description:
  3719. This function is called to get the specific time and period information
  3720. for a PULL/PUSH record.
  3721. Arguments:
  3722. SubKey - Key of a WINS under the Pull/Push key
  3723. Externals Used:
  3724. None
  3725. Return Value:
  3726. Success status codes -- WINS_SUCCESS
  3727. Error status codes -- WINS_NO_SP_TIME
  3728. Error Handling:
  3729. Called by:
  3730. GetPnrInfo
  3731. Side Effects:
  3732. Comments:
  3733. None
  3734. --*/
  3735. {
  3736. DWORD ValTyp;
  3737. DWORD Sz;
  3738. LONG RetVal;
  3739. pAddKey->fSpTimeSet = FALSE;
  3740. FUTURES("Do internationalization of strings here")
  3741. Sz = sizeof(pAddKey->asSpTime);
  3742. RetVal = RegQueryValueEx(
  3743. SubKey,
  3744. WINSCNF_SP_TIME_NM,
  3745. NULL, //reserved; must be NULL
  3746. &ValTyp,
  3747. pAddKey->asSpTime,
  3748. &Sz
  3749. );
  3750. //PERF(If memory is initialized to 0, we don't need to do the following
  3751. //
  3752. // If the user has not specifed a specific time, then we use
  3753. // the current time as the specific time. For current time,
  3754. // the interval is 0
  3755. //
  3756. if (RetVal == ERROR_SUCCESS)
  3757. {
  3758. pAddKey->fSpTimeSet = TRUE;
  3759. }
  3760. else
  3761. {
  3762. pAddKey->asSpTime[0] = EOS;
  3763. }
  3764. return;
  3765. }
  3766. int
  3767. __cdecl
  3768. CompareAdd(
  3769. const VOID *pKey1,
  3770. const VOID *pKey2
  3771. )
  3772. {
  3773. const PADD_KEY_T pAddKey1 = (PADD_KEY_T)pKey1;
  3774. const PADD_KEY_T pAddKey2 = (PADD_KEY_T)pKey2;
  3775. return(pAddKey1->IpAdd - pAddKey2->IpAdd);
  3776. }
  3777. UINT
  3778. GetNextVar(
  3779. IN RFC1157VarBind *pVarBind,
  3780. IN MIB_ENTRY *pMibPtr
  3781. )
  3782. {
  3783. UINT ErrStat;
  3784. while (pMibPtr != NULL)
  3785. {
  3786. if (pMibPtr->MibNext != NULL)
  3787. {
  3788. //
  3789. // Setup var bind name of NEXT MIB variable
  3790. //
  3791. SNMP_oidfree( &pVarBind->name );
  3792. SNMP_oidcpy( &pVarBind->name, &MIB_OidPrefix );
  3793. SNMP_oidappend( &pVarBind->name, &pMibPtr->MibNext->Oid );
  3794. //
  3795. // If the func. ptr is NULL and the type of the mib variable
  3796. // is anything but OPAQUE, call function to process the
  3797. // MIB variable
  3798. //
  3799. if (
  3800. (pMibPtr->MibNext->MibFunc != NULL)
  3801. &&
  3802. (pMibPtr->MibNext->Type != ASN_RFC1155_OPAQUE)
  3803. )
  3804. {
  3805. ErrStat = (*pMibPtr->MibNext->MibFunc)( MIB_GETFIRST,
  3806. pMibPtr->MibNext, pVarBind );
  3807. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  3808. {
  3809. goto Exit;
  3810. }
  3811. break;
  3812. }
  3813. else
  3814. {
  3815. pMibPtr = pMibPtr->MibNext;
  3816. }
  3817. }
  3818. else
  3819. {
  3820. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  3821. break;
  3822. }
  3823. }
  3824. if (pMibPtr == NULL)
  3825. {
  3826. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  3827. }
  3828. Exit:
  3829. return(ErrStat);
  3830. }
  3831. UINT
  3832. EnumDFValues(
  3833. PDATAFILE_INFO_T *ppDFValues,
  3834. LPDWORD pNumDFValues
  3835. )
  3836. /*++
  3837. Routine Description:
  3838. This function gets the names of all the datafiles that need to
  3839. be used for initializing WINS.
  3840. Arguments:
  3841. Externals Used:
  3842. None
  3843. Return Value:
  3844. Success status codes -- WINS_SUCCESS
  3845. Error status codes -- WINS_FAILURE
  3846. Error Handling:
  3847. Called by:
  3848. Side Effects:
  3849. Comments:
  3850. None
  3851. --*/
  3852. {
  3853. LONG RetVal;
  3854. DWORD BuffSize;
  3855. STATUS RetStat = WINS_SUCCESS;
  3856. DWORD NoOfSubKeys;
  3857. DWORD NoOfDFValues;
  3858. UINT ErrStat;
  3859. DWORD n;
  3860. *pNumDFValues = 0;
  3861. *ppDFValues = NULL;
  3862. n = 0;
  3863. ErrStat = OpenKey(PARAMETERS_E_KEY, NULL, NULL, NULL, FALSE);
  3864. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  3865. {
  3866. return(ErrStat);
  3867. }
  3868. ErrStat = OpenKey(DATAFILES_E_KEY, NULL, &sDatafilesKey, NULL, FALSE);
  3869. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  3870. {
  3871. CloseReqKey();
  3872. return(ErrStat);
  3873. }
  3874. try {
  3875. //
  3876. // Get the count of data files listed under the DATAFILES
  3877. // key
  3878. //
  3879. GetKeyInfo(
  3880. sDatafilesKey,
  3881. &NoOfSubKeys, //ignored
  3882. &NoOfDFValues
  3883. );
  3884. if (NoOfDFValues > 0)
  3885. {
  3886. DWORD Index;
  3887. PDATAFILE_INFO_T pTmp;
  3888. #if 0
  3889. TCHAR ValNmBuff[MAX_PATH];
  3890. #endif
  3891. DWORD ValNmBuffSz;
  3892. //
  3893. // Allocate buffer big enough to hold data for
  3894. // the number of values found under the Datafiles key
  3895. //
  3896. BuffSize = DATAFILE_INFO_SZ * NoOfDFValues;
  3897. pTmp = HeapAlloc(
  3898. GetProcessHeap(),
  3899. HEAP_NO_SERIALIZE |
  3900. HEAP_GENERATE_EXCEPTIONS |
  3901. HEAP_ZERO_MEMORY,
  3902. BuffSize
  3903. );
  3904. if (pTmp != NULL)
  3905. {
  3906. *ppDFValues = pTmp;
  3907. }
  3908. else
  3909. {
  3910. Index = 0;
  3911. ErrStat = SNMP_ERRORSTATUS_GENERR;
  3912. goto Exit;
  3913. }
  3914. /*
  3915. * Get the values
  3916. */
  3917. for(
  3918. Index = 0, n = 0;
  3919. Index < NoOfDFValues;
  3920. Index++
  3921. )
  3922. {
  3923. ValNmBuffSz = sizeof(pTmp->ValNm); //init before
  3924. // every call
  3925. BuffSize = WINSMIB_FILE_INFO_SIZE;
  3926. RetVal = RegEnumValue(
  3927. sDatafilesKey,
  3928. Index, //value index
  3929. pTmp->ValNm,
  3930. &ValNmBuffSz,
  3931. (LPDWORD)NULL, //reserved
  3932. &pTmp->StrType,
  3933. (LPBYTE)(pTmp->FileNm),//ptr to var. to
  3934. //hold name of
  3935. //datafile
  3936. &BuffSize //not looked at by us
  3937. );
  3938. if (RetVal != ERROR_SUCCESS)
  3939. {
  3940. continue;
  3941. }
  3942. pTmp->FileNm[BuffSize] = EOS;
  3943. //
  3944. // if StrType is not REG_SZ or REG_EXPAND_SZ, go to
  3945. // the next Value
  3946. //
  3947. if (
  3948. (pTmp->StrType != REG_EXPAND_SZ)
  3949. &&
  3950. (pTmp->StrType != REG_SZ)
  3951. )
  3952. {
  3953. continue;
  3954. }
  3955. n++;
  3956. pTmp = (PDATAFILE_INFO_T)((LPTCH)pTmp +
  3957. DATAFILE_INFO_SZ);
  3958. }
  3959. Exit:
  3960. if (n > 1)
  3961. {
  3962. qsort(
  3963. (LPVOID)*ppDFValues,
  3964. (size_t)n,
  3965. sizeof(DATAFILE_INFO_T),
  3966. CompareIndexes
  3967. );
  3968. }
  3969. *pNumDFValues = n;
  3970. }
  3971. } // end of try ..
  3972. except (EXCEPTION_EXECUTE_HANDLER) {
  3973. SNMPDBG((
  3974. SNMP_LOG_ERROR,
  3975. "WINSMIB: WinsCnfGetNamesOfDataFiles. Exception = (%d).\n",
  3976. GetExceptionCode()
  3977. ));
  3978. ErrStat = SNMP_ERRORSTATUS_GENERR;
  3979. }
  3980. CloseReqKey();
  3981. if ((*pNumDFValues == 0) && (*ppDFValues != NULL))
  3982. {
  3983. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, *ppDFValues);
  3984. }
  3985. return(ErrStat);
  3986. }
  3987. UINT
  3988. DFGet(
  3989. IN RFC1157VarBind *VarBind,
  3990. IN DWORD NumValues,
  3991. IN LPVOID pValues
  3992. )
  3993. {
  3994. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  3995. DWORD Index;
  3996. DWORD i;
  3997. DWORD NumDFValues = NumValues;
  3998. PDATAFILE_INFO_T pDFValues;
  3999. PVOID pDFValuesSv;
  4000. INT iValNm;
  4001. //
  4002. // Get the index of the file to get. If the Index is more than
  4003. // the # of files, we return an error.
  4004. //
  4005. Index = VarBind->name.ids[VarBind->name.idLength - 1];
  4006. if (Index == 0)
  4007. {
  4008. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  4009. }
  4010. EnumDFValues(&pDFValues, &NumDFValues);
  4011. pDFValuesSv = pDFValues;
  4012. for (i=0; i < NumDFValues; i++, pDFValues++)
  4013. {
  4014. //
  4015. // atoi returns a 0 if it can not do a conversion, so if
  4016. // somebody other than an snmp agent messes with the
  4017. // registry names and introduces alphabets, atoi will return
  4018. // 0 and we will not see a match
  4019. //
  4020. iValNm = atoi(pDFValues->ValNm);
  4021. if (iValNm == (INT)Index)
  4022. {
  4023. break;
  4024. }
  4025. }
  4026. if (i == NumDFValues)
  4027. {
  4028. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  4029. goto Exit;
  4030. }
  4031. //
  4032. // Initialize VarBind fields with the type, length, and value
  4033. //
  4034. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  4035. VarBind->value.asnValue.string.length =
  4036. strlen((LPSTR)(pDFValues->FileNm));
  4037. if ( NULL == (VarBind->value.asnValue.string.stream =
  4038. SNMP_malloc(VarBind->value.asnValue.string.length *
  4039. sizeof(CHAR))) )
  4040. {
  4041. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4042. goto Exit;
  4043. }
  4044. memcpy( VarBind->value.asnValue.string.stream,
  4045. (LPSTR)(pDFValues->FileNm),
  4046. VarBind->value.asnValue.string.length );
  4047. VarBind->value.asnValue.string.dynamic = TRUE;
  4048. Exit:
  4049. //
  4050. // If we allocated memory for storing datafiles info, deallocate it
  4051. // now
  4052. //
  4053. if (pDFValuesSv != NULL)
  4054. {
  4055. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pDFValuesSv);
  4056. }
  4057. return(ErrStat);
  4058. }
  4059. UINT
  4060. DFGetNext(
  4061. IN RFC1157VarBind *VarBind,
  4062. IN MIB_ENTRY *MibPtr,
  4063. IN KEY_TYPE_E KeyType_e
  4064. )
  4065. {
  4066. DWORD NumDFValues;
  4067. INT Index;
  4068. PDATAFILE_INFO_T pDFValues;
  4069. PVOID pDFValuesSv;
  4070. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4071. DWORD i;
  4072. INT iValNm;
  4073. BOOL fMatch = FALSE;
  4074. UNREFERENCED_PARAMETER(KeyType_e);
  4075. //
  4076. // Read in all ip address keys. For each key, the values of its fields
  4077. // is stored in the PDATAFILE_INFO structure. The number of
  4078. // files found is stored in NumDFValues
  4079. //
  4080. EnumDFValues(&pDFValues, &NumDFValues);
  4081. pDFValuesSv = pDFValues;
  4082. //
  4083. // Check if the name passed matches any in the table (i.e. table of
  4084. // of ADD_KEY_T structures. If there is a match, the address
  4085. // of the ip address key and the matching field's no. are returned
  4086. //
  4087. Index = VarBind->name.ids[DF_OIDLEN + 1];
  4088. // Index = VarBind->name.ids[VarBind->name.idLength - 1];
  4089. for (i=0; i < NumDFValues; i++, pDFValues++)
  4090. {
  4091. iValNm = atoi(pDFValues->ValNm);
  4092. if (iValNm == Index)
  4093. {
  4094. fMatch = TRUE;
  4095. break;
  4096. }
  4097. if (iValNm > Index)
  4098. {
  4099. break;
  4100. }
  4101. }
  4102. //
  4103. // if the index specified is higher than all existing indices or if
  4104. // match was with the last entry in the list, get to next var.
  4105. //
  4106. if ((i == 0) || (i >= (NumDFValues - 1)))
  4107. {
  4108. if (pDFValuesSv != NULL)
  4109. {
  4110. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pDFValuesSv);
  4111. }
  4112. return(GetNextVar(VarBind, MibPtr));
  4113. }
  4114. //
  4115. // Since the operation is GET_NEXT, get the next Value number
  4116. // If there is no next file, we call the MibFunc of the next MIB entry.
  4117. // Put the index of the next datafile
  4118. //
  4119. if (fMatch)
  4120. {
  4121. ++pDFValues;
  4122. }
  4123. VarBind->name.ids[VarBind->name.idLength - 1] = atoi(pDFValues->ValNm);
  4124. //
  4125. // Get the value
  4126. //
  4127. //
  4128. // Initialize VarBind fields with the type, length, and value
  4129. //
  4130. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  4131. VarBind->value.asnValue.string.length =
  4132. strlen((LPSTR)(pDFValues->FileNm));
  4133. if ( NULL == (VarBind->value.asnValue.string.stream =
  4134. SNMP_malloc(VarBind->value.asnValue.string.length *
  4135. sizeof(CHAR))) )
  4136. {
  4137. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4138. goto Exit;
  4139. }
  4140. memcpy( VarBind->value.asnValue.string.stream,
  4141. (LPSTR)(pDFValues->FileNm),
  4142. VarBind->value.asnValue.string.length );
  4143. Exit:
  4144. if (pDFValuesSv != NULL)
  4145. {
  4146. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pDFValuesSv);
  4147. }
  4148. return(ErrStat);
  4149. }
  4150. UINT
  4151. DFGetFirst(
  4152. IN RFC1157VarBind *VarBind,
  4153. IN MIB_ENTRY *MibPtr,
  4154. IN KEY_TYPE_E KeyType_e
  4155. )
  4156. {
  4157. PDATAFILE_INFO_T pDFValues;
  4158. DWORD NumDFValues;
  4159. UINT TableEntryId[2];
  4160. AsnObjectIdentifier TableEntryOid = { OID_SIZEOF(TableEntryId),
  4161. TableEntryId };
  4162. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4163. UNREFERENCED_PARAMETER(KeyType_e);
  4164. //
  4165. // Get all the address key information
  4166. //
  4167. PERF("Get the first entry only. Since we won't have very many entries, this")
  4168. PERF("is ok. When a cache is implemented, this will serve to populate the")
  4169. PERF("cache")
  4170. EnumDFValues(&pDFValues, &NumDFValues);
  4171. //
  4172. // If there is no entry in the table, go to the next MIB variable
  4173. //
  4174. if (NumDFValues == 0)
  4175. {
  4176. return(GetNextVar(VarBind, MibPtr));
  4177. }
  4178. //
  4179. // Write the object Id into the binding list and call get
  4180. // func
  4181. //
  4182. SNMP_oidfree( &VarBind->name );
  4183. SNMP_oidcpy( &VarBind->name, &MIB_OidPrefix );
  4184. SNMP_oidappend( &VarBind->name, &MibPtr->Oid );
  4185. //
  4186. // The fixed part of the objid is correct. Update the rest.
  4187. //
  4188. TableEntryId[0] = 2; //put 2 to access the datafile name
  4189. #if 0
  4190. TableEntryId[1] = 1; //put 1 (for the datafile index). This is
  4191. //used for indexing the row of the table
  4192. #endif
  4193. TableEntryId[1] = atoi(pDFValues->ValNm);
  4194. SNMP_oidappend( &VarBind->name, &TableEntryOid );
  4195. //
  4196. // Initialize VarBind fields with the type, length, and value
  4197. //
  4198. VarBind->value.asnType = ASN_RFC1213_DISPSTRING;
  4199. VarBind->value.asnValue.string.length =
  4200. strlen((LPSTR)(pDFValues->FileNm));
  4201. if ( NULL == (VarBind->value.asnValue.string.stream =
  4202. SNMP_malloc(VarBind->value.asnValue.string.length *
  4203. sizeof(CHAR))) )
  4204. {
  4205. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4206. goto Exit;
  4207. }
  4208. (void)memcpy( VarBind->value.asnValue.string.stream,
  4209. (LPSTR)(pDFValues->FileNm),
  4210. VarBind->value.asnValue.string.length );
  4211. #if 0
  4212. //
  4213. // get the file name
  4214. //
  4215. ErrStat = DFGet(VarBind, NumDFValues, pDFValues);
  4216. #endif
  4217. Exit:
  4218. HeapFree(GetProcessHeap(), HEAP_NO_SERIALIZE, pDFValues);
  4219. return(ErrStat);
  4220. }
  4221. UINT
  4222. DFSet(
  4223. IN RFC1157VarBind *pVarBind
  4224. )
  4225. {
  4226. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4227. DWORD Index;
  4228. DATAFILE_INFO_T DFValue;
  4229. #if 0
  4230. PDATAFILE_INFO_T pDFValues;
  4231. #endif
  4232. Index = pVarBind->name.ids[pVarBind->name.idLength - 1];
  4233. if (Index == 0)
  4234. {
  4235. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  4236. }
  4237. if ( pVarBind->value.asnType != ASN_RFC1213_DISPSTRING)
  4238. {
  4239. return(SNMP_ERRORSTATUS_BADVALUE);
  4240. }
  4241. #if 0
  4242. // The storage must be adequate to contain the new
  4243. // string including a NULL terminator.
  4244. memcpy( (LPSTR)DFValue.FileNm,
  4245. pVarBind->value.asnValue.string.stream,
  4246. pVarBind->value.asnValue.string.length );
  4247. ((LPSTR)DFValue.FileNm)[pVarBind->value.asnValue.string.length] = '\0';
  4248. #endif
  4249. ErrStat = WriteDFValue(pVarBind, &DFValue, Index);
  4250. return(ErrStat);
  4251. } //DFSet
  4252. UINT
  4253. WriteDFValue(
  4254. IN RFC1157VarBind *pVarBind,
  4255. PDATAFILE_INFO_T pDFValue,
  4256. DWORD Index
  4257. )
  4258. {
  4259. //
  4260. // remove pDFValue as an argument. Use local
  4261. //
  4262. TCHAR ValNmBuff[MAX_PATH];
  4263. DWORD ValNmBuffSz = MAX_PATH;
  4264. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4265. LONG RetVal;
  4266. if (pVarBind->value.asnType != ASN_RFC1213_DISPSTRING)
  4267. {
  4268. return(SNMP_ERRORSTATUS_BADVALUE);
  4269. }
  4270. if (
  4271. pVarBind->value.asnValue.string.stream[0] == '%')
  4272. {
  4273. pDFValue->StrType = REG_EXPAND_SZ;
  4274. }
  4275. else
  4276. {
  4277. pDFValue->StrType = REG_SZ;
  4278. }
  4279. //
  4280. // Open the Parameters key and the Datafiles key under that
  4281. //
  4282. ErrStat = OpenKey(PARAMETERS_E_KEY, NULL, NULL, NULL, TRUE);
  4283. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  4284. {
  4285. return(ErrStat);
  4286. }
  4287. ErrStat = OpenKey(DATAFILES_E_KEY, NULL, NULL, NULL, TRUE);
  4288. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  4289. {
  4290. return(ErrStat);
  4291. }
  4292. //
  4293. // If the index is within the range that we have in the registry,
  4294. // let us get the name of the value that stores the datafile name
  4295. //
  4296. // We get the name because we don't know what it is. If we have
  4297. // to overwrite the name, we need to know what it is first.
  4298. //
  4299. sprintf(ValNmBuff, "%d", Index);
  4300. //
  4301. // Set the name
  4302. //
  4303. RetVal = RegSetValueEx(
  4304. sDatafilesKey,
  4305. ValNmBuff,
  4306. 0, //reserved -- must be 0
  4307. pDFValue->StrType,
  4308. pVarBind->value.asnValue.string.stream,
  4309. pVarBind->value.asnValue.string.length
  4310. );
  4311. if (RetVal != ERROR_SUCCESS)
  4312. {
  4313. SNMPDBG((
  4314. SNMP_LOG_ERROR,
  4315. "WINSMIB: Could not set value of %s.\n",
  4316. pVarBind->value.asnValue.string.stream
  4317. ));
  4318. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4319. }
  4320. //
  4321. // Let us close the keys that we opened/created
  4322. //
  4323. SNMPDBG((
  4324. SNMP_LOG_VERBOSE,
  4325. "WINSMIB: Closing sParametersKey 0x%08lx (fKeyOpen=%s).\n",
  4326. sParametersKey, sfParametersKeyOpen ? "TRUE" : "FALSE"
  4327. ));
  4328. SNMPDBG((
  4329. SNMP_LOG_VERBOSE,
  4330. "WINSMIB: Closing sDatafilesKey 0x%08lx (fKeyOpen=%s).\n",
  4331. sDatafilesKey, sfDatafilesKeyOpen ? "TRUE" : "FALSE"
  4332. ));
  4333. CloseReqKey();
  4334. /*
  4335. RegCloseKey(sParametersKey);
  4336. RegCloseKey(sDatafilesKey);
  4337. */
  4338. return(ErrStat);
  4339. }
  4340. //
  4341. // HandleCmd
  4342. // Performs specific actions on the different Cmd MIB variable
  4343. //
  4344. // Notes:
  4345. //
  4346. // Return Codes:
  4347. // Standard PDU error codes.
  4348. //
  4349. // Error Codes:
  4350. // None.
  4351. //
  4352. UINT HandleCmd(
  4353. IN UINT Action,
  4354. IN MIB_ENTRY *MibPtr,
  4355. IN RFC1157VarBind *VarBind
  4356. )
  4357. {
  4358. WINSINTF_RESULTS_T Results;
  4359. handle_t BindHdl;
  4360. DWORD Status;
  4361. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4362. switch ( Action )
  4363. {
  4364. case MIB_SET:
  4365. if ((ErrStat = MIB_leaf_func( Action, MibPtr, VarBind ))
  4366. == SNMP_ERRORSTATUS_NOERROR)
  4367. {
  4368. ErrStat = ExecuteCmd(MibPtr);
  4369. }
  4370. break;
  4371. case MIB_GETFIRST:
  4372. //
  4373. // fall through
  4374. //
  4375. case MIB_GET:
  4376. if (
  4377. (MibPtr->Storage == &MIB_NoOfWrkThdsStore)
  4378. ||
  4379. (MibPtr->Storage == &MIB_PriorityClassStore)
  4380. ||
  4381. (MibPtr->Storage == &MIB_MaxVersNo_LowWordStore)
  4382. ||
  4383. (MibPtr->Storage == &MIB_MaxVersNo_HighWordStore)
  4384. )
  4385. {
  4386. if (!fWinsMibWinsStatusCnfCalled)
  4387. {
  4388. Results.WinsStat.NoOfPnrs = 0;
  4389. Results.WinsStat.pRplPnrs = NULL;
  4390. BindHdl = WinsBind(&sBindData);
  4391. Status = WinsStatus(BindHdl, WINSINTF_E_CONFIG, &Results);
  4392. if (Status != WINSINTF_SUCCESS)
  4393. {
  4394. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4395. WinsUnbind(&sBindData, BindHdl);
  4396. goto Exit;
  4397. }
  4398. MIB_NoOfWrkThdsStore = Results.NoOfWorkerThds;
  4399. if (Results.WinsPriorityClass == NORMAL_PRIORITY_CLASS)
  4400. {
  4401. MIB_PriorityClassStore = 0;
  4402. }
  4403. else
  4404. {
  4405. MIB_PriorityClassStore = 1;
  4406. }
  4407. MIB_MaxVersNo_LowWordStore = Results.AddVersMaps[0].VersNo.LowPart;
  4408. MIB_MaxVersNo_HighWordStore = Results.AddVersMaps[0].VersNo.HighPart;
  4409. fWinsMibWinsStatusCnfCalled = TRUE;
  4410. WinsUnbind(&sBindData, BindHdl);
  4411. }
  4412. }
  4413. //
  4414. // fall through
  4415. //
  4416. case MIB_GETNEXT:
  4417. //
  4418. // Call the more generic function to perform the action
  4419. //
  4420. ErrStat = MIB_leaf_func( Action, MibPtr, VarBind );
  4421. break;
  4422. default:
  4423. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4424. goto Exit;
  4425. } // switch
  4426. Exit:
  4427. return ErrStat;
  4428. } // HandleCmd
  4429. UINT
  4430. ExecuteCmd(
  4431. IN MIB_ENTRY *pMibPtr
  4432. )
  4433. {
  4434. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4435. WINSINTF_ADD_T WinsAdd;
  4436. LPBYTE pStorage;
  4437. handle_t BindHdl;
  4438. DWORD Status;
  4439. WinsAdd.Len = 4;
  4440. WinsAdd.Type = 0;
  4441. BindHdl = WinsBind(&sBindData);
  4442. //
  4443. // For Performance, arrange the following in the order of
  4444. // expected frequency.
  4445. //
  4446. if ( pMibPtr->Storage == &MIB_PullTriggerStore )
  4447. {
  4448. pStorage = MIB_PullTriggerStore;
  4449. WinsAdd.IPAdd = ntohl(*(DWORD*)pStorage);
  4450. //NMSMSGF_RETRIEVE_IPADD_M(pStorage, WinsAdd.IPAdd);
  4451. Status = WinsTrigger(BindHdl, &WinsAdd, WINSINTF_E_PULL);
  4452. if (Status != WINSINTF_SUCCESS)
  4453. {
  4454. int backupSize = sizeof(MIB_PullTriggerStore) / 2;
  4455. // setting back the original value
  4456. memcpy( (LPSTR)pMibPtr->Storage, (LPSTR)pMibPtr->Storage + backupSize, backupSize);
  4457. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4458. }
  4459. goto Exit;
  4460. }
  4461. if ( pMibPtr->Storage == &MIB_PushTriggerStore )
  4462. {
  4463. pStorage = MIB_PushTriggerStore;
  4464. WinsAdd.IPAdd = ntohl(*(DWORD*)pStorage);
  4465. //NMSMSGF_RETRIEVE_IPADD_M(pStorage, WinsAdd.IPAdd);
  4466. Status = WinsTrigger(BindHdl, &WinsAdd, WINSINTF_E_PUSH);
  4467. if (Status != WINSINTF_SUCCESS)
  4468. {
  4469. int backupSize = sizeof(MIB_PushTriggerStore) / 2;
  4470. // setting back the original value
  4471. memcpy( (LPSTR)pMibPtr->Storage, (LPSTR)pMibPtr->Storage + backupSize, backupSize);
  4472. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4473. }
  4474. goto Exit;
  4475. }
  4476. if ( pMibPtr->Storage == &MIB_DoScavengingStore )
  4477. {
  4478. if (MIB_DoScavengingStore == 1)
  4479. {
  4480. Status = WinsDoScavenging(BindHdl);
  4481. if (Status != WINSINTF_SUCCESS)
  4482. {
  4483. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4484. }
  4485. }
  4486. else
  4487. {
  4488. if (MIB_DoScavengingStore != 0)
  4489. {
  4490. MIB_DoScavengingStore = 0;
  4491. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  4492. }
  4493. }
  4494. goto Exit;
  4495. }
  4496. if ( pMibPtr->Storage == &MIB_DoStaticInitStore )
  4497. {
  4498. LPBYTE pDataFile = MIB_DoStaticInitStore;
  4499. WCHAR UcDataFile[WINSMIB_FILE_INFO_SIZE];
  4500. if (MIB_DoStaticInitStore[0] == EOS)
  4501. {
  4502. UcDataFile[0] = (WCHAR)NULL;
  4503. }
  4504. else
  4505. {
  4506. MultiByteToWideChar( CP_ACP, 0,
  4507. pDataFile, -1, UcDataFile,
  4508. WINSMIB_FILE_INFO_SIZE
  4509. );
  4510. }
  4511. Status = WinsDoStaticInit(BindHdl, UcDataFile, FALSE);
  4512. if (Status != WINSINTF_SUCCESS)
  4513. {
  4514. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4515. }
  4516. goto Exit;
  4517. }
  4518. if ( pMibPtr->Storage == &MIB_NoOfWrkThdsStore )
  4519. {
  4520. if (
  4521. (MIB_NoOfWrkThdsStore < 1)
  4522. ||
  4523. (MIB_NoOfWrkThdsStore > 4)
  4524. )
  4525. {
  4526. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  4527. goto Exit;
  4528. }
  4529. Status = WinsWorkerThdUpd(BindHdl, (DWORD)MIB_NoOfWrkThdsStore);
  4530. if (Status != WINSINTF_SUCCESS)
  4531. {
  4532. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4533. }
  4534. goto Exit;
  4535. }
  4536. if ( pMibPtr->Storage == &MIB_PriorityClassStore )
  4537. {
  4538. if (
  4539. (MIB_PriorityClassStore < 0)
  4540. ||
  4541. (MIB_PriorityClassStore > 1)
  4542. )
  4543. {
  4544. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  4545. goto Exit;
  4546. }
  4547. Status = WinsSetPriorityClass(
  4548. BindHdl,
  4549. (DWORD)MIB_PriorityClassStore);
  4550. if (Status != WINSINTF_SUCCESS)
  4551. {
  4552. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4553. }
  4554. goto Exit;
  4555. }
  4556. if ( pMibPtr->Storage == &MIB_ResetCountersStore )
  4557. {
  4558. Status = WinsResetCounters(BindHdl);
  4559. if (Status != WINSINTF_SUCCESS)
  4560. {
  4561. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4562. }
  4563. goto Exit;
  4564. }
  4565. if ( pMibPtr->Storage == &MIB_DeleteDbRecsStore )
  4566. {
  4567. WINSINTF_VERS_NO_T MaxVersNo, MinVersNo;
  4568. WINS_ASSIGN_INT_TO_VERS_NO_M(MaxVersNo, 0);
  4569. WINS_ASSIGN_INT_TO_VERS_NO_M(MinVersNo, 0);
  4570. pStorage = MIB_DeleteDbRecsStore;
  4571. WinsAdd.IPAdd = ntohl(*(DWORD*)pStorage);
  4572. //NMSMSGF_RETRIEVE_IPADD_M(pStorage, WinsAdd.IPAdd);
  4573. Status = WinsDelDbRecs(BindHdl, &WinsAdd, MinVersNo, MaxVersNo);
  4574. if (Status != WINSINTF_SUCCESS)
  4575. {
  4576. int backupSize = sizeof(MIB_DeleteDbRecsStore) / 2;
  4577. // setting back the original value
  4578. memcpy( (LPSTR)pMibPtr->Storage, (LPSTR)pMibPtr->Storage + backupSize, backupSize);
  4579. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4580. }
  4581. goto Exit;
  4582. }
  4583. if ( pMibPtr->Storage == &MIB_GetDbRecsStore )
  4584. {
  4585. if (PopulateDRCache() == WINSINTF_SUCCESS)
  4586. {
  4587. (VOID)time(&sDRCacheInitTime);
  4588. }
  4589. else
  4590. {
  4591. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4592. }
  4593. goto Exit;
  4594. }
  4595. if ( pMibPtr->Storage == &MIB_DeleteWinsStore )
  4596. {
  4597. pStorage = MIB_DeleteWinsStore;
  4598. WinsAdd.IPAdd = ntohl(*(DWORD*)pStorage);
  4599. //NMSMSGF_RETRIEVE_IPADD_M(pStorage, WinsAdd.IPAdd);
  4600. Status = WinsDeleteWins(BindHdl, &WinsAdd);
  4601. if (Status != WINSINTF_SUCCESS)
  4602. {
  4603. int backupSize = sizeof(MIB_DeleteWinsStore) / 2;
  4604. // setting back the original value
  4605. memcpy( (LPSTR)pMibPtr->Storage, (LPSTR)pMibPtr->Storage + backupSize, backupSize);
  4606. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4607. }
  4608. goto Exit;
  4609. }
  4610. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  4611. Exit:
  4612. WinsUnbind(&sBindData, BindHdl);
  4613. return ErrStat;
  4614. }
  4615. VOID
  4616. WinsMibInit(
  4617. VOID
  4618. )
  4619. {
  4620. #if 0
  4621. DWORD i;
  4622. MIB_ENTRY *pMib;
  4623. #endif
  4624. //
  4625. // We use named pipe to communicate with WINS when it is on
  4626. // the same machine since it is faster than TCP/IP. We don't
  4627. // use LRPC since WINS does not listen on that (to minimize
  4628. // on thread usage)
  4629. //
  4630. sBindData.fTcpIp = TRUE;
  4631. sBindData.pServerAdd = LOCAL_ADD;
  4632. sBindData.pPipeName = NULL;
  4633. // InitializeCriticalSection(&WinsMibCrtSec);
  4634. #if 0
  4635. pMib = Mib;
  4636. for (i=1; i < (MIB_num_variables + 1); i++, pMib++)
  4637. {
  4638. if (pMib->
  4639. pMib->MibNext = &Mib[i];
  4640. }
  4641. for (i=0; i < NUM_TABLES; i++)
  4642. {
  4643. }
  4644. #endif
  4645. return;
  4646. }
  4647. UINT
  4648. DRGet(
  4649. IN RFC1157VarBind *VarBind,
  4650. IN DWORD FieldParam,
  4651. IN LPVOID pRowParam
  4652. )
  4653. {
  4654. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4655. DWORD Field;
  4656. PWINSINTF_RECORD_ACTION_T pRow = NULL;
  4657. DWORD i, n;
  4658. LPBYTE pTmp;
  4659. //
  4660. // if the row was passed (for instance from DRGetNext), skip
  4661. // the search part
  4662. //
  4663. if (pRowParam == NULL)
  4664. {
  4665. ErrStat = DRMatch(VarBind, &pRow, &i /*not used*/ , &Field,
  4666. MIB_GET, NULL);
  4667. if (
  4668. (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  4669. ||
  4670. (pRow == NULL)
  4671. ||
  4672. (pRow->State_e == WINSINTF_E_DELETED)
  4673. )
  4674. {
  4675. // bug #235928 - if the first condition in the above if is true, then the
  4676. // derefferencing pRow causes a first chance exception!
  4677. // if (pRow->State_e == WINSINTF_E_DELETED)
  4678. if (ErrStat == SNMP_ERRORSTATUS_NOERROR)
  4679. {
  4680. ErrStat = SNMP_ERRORSTATUS_NOSUCHNAME;
  4681. }
  4682. return(ErrStat);
  4683. }
  4684. }
  4685. else
  4686. {
  4687. pRow = pRowParam;
  4688. Field = FieldParam;
  4689. }
  4690. switch(Field)
  4691. {
  4692. case 1: //name
  4693. VarBind->value.asnType = ASN_OCTETSTRING;
  4694. VarBind->value.asnValue.string.length = pRow->NameLen;
  4695. if ( NULL ==
  4696. (VarBind->value.asnValue.string.stream =
  4697. SNMP_malloc(VarBind->value.asnValue.string.length
  4698. )) )
  4699. {
  4700. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4701. goto Exit;
  4702. }
  4703. memcpy( VarBind->value.asnValue.string.stream,
  4704. (LPSTR)(pRow->pName),
  4705. VarBind->value.asnValue.string.length );
  4706. VarBind->value.asnValue.string.dynamic = TRUE;
  4707. break;
  4708. case 2: // address(es)
  4709. VarBind->value.asnType = ASN_OCTETSTRING;
  4710. if (
  4711. (pRow->TypOfRec_e == WINSINTF_E_UNIQUE)
  4712. ||
  4713. (pRow->TypOfRec_e == WINSINTF_E_NORM_GROUP)
  4714. )
  4715. {
  4716. VarBind->value.asnValue.string.length = 4;
  4717. }
  4718. else
  4719. {
  4720. VarBind->value.asnValue.string.length =
  4721. 4 * pRow->NoOfAdds;
  4722. }
  4723. if ( NULL ==
  4724. (VarBind->value.asnValue.string.stream =
  4725. SNMP_malloc(VarBind->value.asnValue.string.length *
  4726. sizeof(char))) )
  4727. {
  4728. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4729. goto Exit;
  4730. }
  4731. pTmp = VarBind->value.asnValue.string.stream;
  4732. if (
  4733. (pRow->TypOfRec_e == WINSINTF_E_UNIQUE)
  4734. ||
  4735. (pRow->TypOfRec_e == WINSINTF_E_NORM_GROUP)
  4736. )
  4737. {
  4738. NMSMSGF_INSERT_IPADD_M(pTmp,pRow->Add.IPAdd);
  4739. }
  4740. else
  4741. {
  4742. for (i = 0, n = 0; i < pRow->NoOfAdds/2; i++)
  4743. {
  4744. NMSMSGF_INSERT_IPADD_M(pTmp,
  4745. (pRow->pAdd + n)->IPAdd);
  4746. n++;
  4747. NMSMSGF_INSERT_IPADD_M(pTmp,
  4748. (pRow->pAdd + n)->IPAdd);
  4749. n++;
  4750. }
  4751. }
  4752. VarBind->value.asnValue.string.dynamic = TRUE;
  4753. break;
  4754. case 3: // Record Type
  4755. VarBind->value.asnType = ASN_INTEGER;
  4756. VarBind->value.asnValue.number =
  4757. (AsnInteger)(pRow->TypOfRec_e);
  4758. break;
  4759. case 4: //Persistence Type
  4760. VarBind->value.asnType = ASN_INTEGER;
  4761. VarBind->value.asnValue.number =
  4762. (AsnInteger)pRow->fStatic;
  4763. break;
  4764. case 5: //State
  4765. VarBind->value.asnType = ASN_INTEGER;
  4766. VarBind->value.asnValue.number =
  4767. (AsnInteger)pRow->State_e;
  4768. break;
  4769. default:
  4770. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  4771. break;
  4772. }
  4773. Exit:
  4774. return(ErrStat);
  4775. }
  4776. UINT
  4777. DRGetNext(
  4778. IN RFC1157VarBind *VarBind,
  4779. IN MIB_ENTRY *MibPtr,
  4780. IN KEY_TYPE_E KeyType_e
  4781. )
  4782. {
  4783. DWORD OidIndex;
  4784. DWORD FieldNo;
  4785. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4786. DWORD Index;
  4787. DWORD i;
  4788. LPBYTE pNameChar;
  4789. UINT TableEntryIds[NMSDB_MAX_NAM_LEN];
  4790. BOOL fFirst;
  4791. AsnObjectIdentifier TableEntryOid = { OID_SIZEOF(TableEntryIds),
  4792. TableEntryIds };
  4793. PWINSINTF_RECORD_ACTION_T pRow;
  4794. //
  4795. // If there is no entry in the table, go to the next MIB variable
  4796. //
  4797. if (sRecs.NoOfRecs == 0)
  4798. {
  4799. return(GetNextVar(VarBind, MibPtr));
  4800. }
  4801. //
  4802. // Check if the name passed matches any in the table (i.e. table of
  4803. // of WINSINTF_RECORD_ACTION_T structures. If there is a match, the
  4804. // address of the structure and the matching field's no. are returned
  4805. //
  4806. ErrStat = DRMatch(VarBind, &pRow, &Index, &FieldNo, MIB_GETNEXT, &fFirst);
  4807. if (ErrStat != SNMP_ERRORSTATUS_NOERROR)
  4808. {
  4809. return(ErrStat);
  4810. }
  4811. //
  4812. // Since the operation is GETNEXT, get the next name (i.e. one
  4813. // that is lexicographically bigger. If there is none, we must increment
  4814. // the field value and move back to the lexically first item in the table
  4815. // If the new field value is more than the largest supported, we call
  4816. // the MibFunc of the next MIB entry.
  4817. //
  4818. // sRecs.NoOfRecs > 0 since otherwise we won't be here.
  4819. //
  4820. //
  4821. // If we are at the last record and this is not that case where no name
  4822. // was passed to us, then increment the field and if it is still within
  4823. // bounds, get the first record in the cache
  4824. //
  4825. //
  4826. if ((Index == (sRecs.NoOfRecs - 1)) && !fFirst)
  4827. {
  4828. if (++FieldNo > NO_FLDS_IN_DR)
  4829. {
  4830. return(GetNextVar(VarBind, MibPtr));
  4831. }
  4832. else
  4833. {
  4834. Index = 0;
  4835. pRow = (PWINSINTF_RECORD_ACTION_T)sRecs.pRow;
  4836. }
  4837. }
  4838. else
  4839. {
  4840. //
  4841. // no name was passed, so we need to get the field of the first
  4842. // record in the table
  4843. //
  4844. if (fFirst)
  4845. {
  4846. pRow = (PWINSINTF_RECORD_ACTION_T)sRecs.pRow;
  4847. }
  4848. else
  4849. {
  4850. //
  4851. // Get the field of the next record in the cache
  4852. //
  4853. Index++;
  4854. pRow++;
  4855. }
  4856. while(pRow->State_e == WINSINTF_E_DELETED)
  4857. {
  4858. if (Index == (sRecs.NoOfRecs - 1))
  4859. {
  4860. if (++FieldNo > NO_FLDS_IN_DR)
  4861. {
  4862. return(GetNextVar(VarBind, MibPtr));
  4863. }
  4864. else
  4865. {
  4866. Index = 0;
  4867. pRow = (PWINSINTF_RECORD_ACTION_T)sRecs.pRow;
  4868. }
  4869. }
  4870. else
  4871. {
  4872. pRow++;
  4873. Index++;
  4874. }
  4875. }
  4876. }
  4877. //
  4878. // Write the object Id into the binding list and call get
  4879. // func
  4880. //
  4881. SNMP_oidfree( &VarBind->name );
  4882. SNMP_oidcpy( &VarBind->name, &MIB_OidPrefix );
  4883. SNMP_oidappend( &VarBind->name, &MibPtr->Oid );
  4884. TableEntryIds[0] = FieldNo;
  4885. OidIndex = 1;
  4886. pNameChar = pRow->pName;
  4887. //
  4888. // The fixed part of the objid is correct. Update the rest.
  4889. //
  4890. for (i = 0; i < pRow->NameLen; i++)
  4891. {
  4892. TableEntryIds[OidIndex++] = (UINT)*pNameChar++;
  4893. }
  4894. TableEntryOid.idLength = OidIndex;
  4895. SNMP_oidappend( &VarBind->name, &TableEntryOid );
  4896. //
  4897. // Get the value
  4898. //
  4899. ErrStat = DRGet(VarBind, FieldNo, pRow);
  4900. return(ErrStat);
  4901. }
  4902. //
  4903. // The rpc function WinsRecordAction has changed in that now it takes
  4904. // the address of a pointer. On return the buffer allocated by RPC has
  4905. // to be freed. Modify this function to account for that. Currently,
  4906. // we never call this function so this work is being deferred - 4/28/94.
  4907. //
  4908. UINT
  4909. DRSet(
  4910. IN RFC1157VarBind *VarBind
  4911. )
  4912. {
  4913. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  4914. DWORD Field;
  4915. LPBYTE pName;
  4916. DWORD NameLen;
  4917. PWINSINTF_RECORD_ACTION_T pRow;
  4918. PWINSINTF_RECORD_ACTION_T pSvRow;
  4919. DWORD Index;
  4920. DWORD FieldNo;
  4921. handle_t BindHdl;
  4922. DWORD i;
  4923. BOOL fFound = FALSE;
  4924. //
  4925. // Extract the field that needs to be set
  4926. //
  4927. Field = VarBind->name.ids[DR_OIDLEN];
  4928. switch(Field)
  4929. {
  4930. //
  4931. // Only the state field is settable
  4932. //
  4933. case 5:
  4934. if ( VarBind->value.asnType != ASN_INTEGER)
  4935. {
  4936. return(SNMP_ERRORSTATUS_BADVALUE);
  4937. }
  4938. if (
  4939. (VarBind->value.asnValue.number != WINSINTF_E_RELEASED)
  4940. &&
  4941. (VarBind->value.asnValue.number != WINSINTF_E_DELETED)
  4942. )
  4943. {
  4944. return(SNMP_ERRORSTATUS_BADVALUE);
  4945. }
  4946. if (sRecs.NoOfRecs == 0)
  4947. return (SNMP_ERRORSTATUS_NOSUCHNAME);
  4948. NameLen = VarBind->name.idLength - (DR_OIDLEN + 1);
  4949. if ( NULL == (pName = SNMP_malloc(NameLen * sizeof(char))) )
  4950. {
  4951. return(SNMP_ERRORSTATUS_GENERR);
  4952. }
  4953. ErrStat = DRMatch(VarBind, &pRow, &Index, &FieldNo, MIB_SET, NULL);
  4954. if (ErrStat == SNMP_ERRORSTATUS_NOERROR)
  4955. {
  4956. fFound = TRUE;
  4957. }
  4958. else
  4959. {
  4960. LPBYTE pNameChar = pRow->pName;
  4961. DWORD n = DR_OIDLEN + 1;
  4962. for (i=0; i<NameLen;i++)
  4963. {
  4964. *pNameChar = (BYTE)
  4965. VarBind->name.ids[n++];
  4966. }
  4967. pRow->NameLen = NameLen;
  4968. }
  4969. pRow->fStatic = 1;
  4970. if ( VarBind->value.asnValue.number ==
  4971. WINSINTF_E_RELEASED)
  4972. {
  4973. pRow->Cmd_e = WINSINTF_E_RELEASE;
  4974. }
  4975. else
  4976. {
  4977. pRow->Cmd_e = WINSINTF_E_DELETE;
  4978. }
  4979. BindHdl = WinsBind(&sBindData);
  4980. pSvRow = pRow;
  4981. if ( WinsRecordAction(BindHdl, &pSvRow) != WINSINTF_SUCCESS)
  4982. {
  4983. ErrStat = SNMP_ERRORSTATUS_GENERR;
  4984. goto Exit;
  4985. }
  4986. WinsFreeMem(pSvRow->pName);
  4987. WinsFreeMem(pSvRow->pAdd);
  4988. WinsFreeMem(pSvRow);
  4989. pRow->State_e = VarBind->value.asnValue.number;
  4990. break;
  4991. case(1):
  4992. case(2):
  4993. case(3):
  4994. case(4):
  4995. ErrStat = SNMP_ERRORSTATUS_READONLY;
  4996. break;
  4997. default:
  4998. ErrStat = SNMP_ERRORSTATUS_BADVALUE;
  4999. break;
  5000. }
  5001. Exit:
  5002. WinsUnbind(&sBindData, BindHdl);
  5003. return(ErrStat);
  5004. } //DRSet
  5005. UINT
  5006. DRGetFirst(
  5007. IN RFC1157VarBind *VarBind,
  5008. IN MIB_ENTRY *MibPtr,
  5009. IN KEY_TYPE_E KeyType_e
  5010. )
  5011. {
  5012. DWORD OidIndex;
  5013. UINT TableEntryIds[NMSDB_MAX_NAM_LEN];
  5014. AsnObjectIdentifier TableEntryOid = { OID_SIZEOF(TableEntryIds),
  5015. TableEntryIds };
  5016. UINT ErrStat;
  5017. PTUCHAR pNameChar;
  5018. PWINSINTF_RECORD_ACTION_T pRow = (PWINSINTF_RECORD_ACTION_T)sRecs.pRow;
  5019. DWORD i;
  5020. if (sRecs.NoOfRecs == 0)
  5021. {
  5022. return(GetNextVar(VarBind, MibPtr));
  5023. }
  5024. //
  5025. // Write the object Id into the binding list and call get
  5026. // func
  5027. //
  5028. SNMP_oidfree( &VarBind->name );
  5029. SNMP_oidcpy( &VarBind->name, &MIB_OidPrefix );
  5030. SNMP_oidappend( &VarBind->name, &MibPtr->Oid );
  5031. //
  5032. // The fixed part of the objid is corect. Update the rest.
  5033. //
  5034. //OidIndex = VarBind->name.idLength;
  5035. TableEntryIds[0] = 1;
  5036. OidIndex = 1;
  5037. pNameChar = pRow->pName;
  5038. for (i = 0; i < pRow->NameLen; i++)
  5039. {
  5040. TableEntryIds[OidIndex++] = (UINT)*pNameChar++;
  5041. }
  5042. TableEntryOid.idLength = OidIndex;
  5043. SNMP_oidappend( &VarBind->name, &TableEntryOid );
  5044. ErrStat = DRGet(VarBind, 0, NULL);
  5045. return(ErrStat);
  5046. }
  5047. UINT
  5048. DRMatch(
  5049. IN RFC1157VarBind *VarBind,
  5050. IN PWINSINTF_RECORD_ACTION_T *ppRow,
  5051. IN LPDWORD pIndex,
  5052. IN LPDWORD pField,
  5053. IN UINT PduAction,
  5054. OUT LPBOOL pfFirst
  5055. )
  5056. {
  5057. DWORD NameLen;
  5058. BYTE Name[NMSDB_MAX_NAM_LEN];
  5059. LPBYTE pNameChar = Name;
  5060. DWORD NameIndex = DR_OIDLEN + 1;
  5061. UINT *pTmp = &VarBind->name.ids[NameIndex];
  5062. DWORD i;
  5063. PWINSINTF_RECORD_ACTION_T pRow = (PWINSINTF_RECORD_ACTION_T)sRecs.pRow;
  5064. UINT ErrStat = SNMP_ERRORSTATUS_NOERROR;
  5065. INT CmpVal;
  5066. if (pfFirst != NULL)
  5067. {
  5068. *pfFirst = FALSE;
  5069. }
  5070. NameLen = VarBind->name.idLength - (DR_OIDLEN + 1);
  5071. *pField = VarBind->name.ids[DR_OIDLEN];
  5072. //
  5073. // if a name has been specified, get it into Name array
  5074. //
  5075. if (NameLen > 0)
  5076. {
  5077. for(i=0; i<NameLen; i++)
  5078. {
  5079. *pNameChar++ = (BYTE)*pTmp++;
  5080. }
  5081. //
  5082. // Compare the name with names in the cache (in ascending order)
  5083. //
  5084. for (i=0; i < sRecs.NoOfRecs; i++, pRow++)
  5085. {
  5086. //
  5087. // replace with RtlCompareMemory
  5088. //
  5089. CmpVal = memcmp(Name, pRow->pName, NameLen);
  5090. if (CmpVal == 0)
  5091. {
  5092. *pIndex = i;
  5093. *ppRow = pRow;
  5094. return(SNMP_ERRORSTATUS_NOERROR);
  5095. }
  5096. else
  5097. {
  5098. //
  5099. // Passed in name is lexicographically > than
  5100. // name being looked at, continue on
  5101. //
  5102. if (CmpVal > 0)
  5103. {
  5104. continue;
  5105. }
  5106. else
  5107. {
  5108. //
  5109. // Passed in name is lexicographically < than
  5110. // name being looked at, continue on
  5111. //
  5112. break;
  5113. }
  5114. }
  5115. }
  5116. //
  5117. // if the action is not GETNEXT, we return an error, since we
  5118. // did not find a matching name
  5119. //
  5120. if (PduAction != MIB_GETNEXT)
  5121. {
  5122. return(SNMP_ERRORSTATUS_NOSUCHNAME);
  5123. }
  5124. else
  5125. {
  5126. //
  5127. // Either the name is lexicographically > than all names
  5128. // or we reached a name in the list that is lexicographically
  5129. // < it. In the first case, i needs to be decremented by
  5130. // 1. *ppRow needs to be initialized to either the last
  5131. // row in the table or to the element before the one we
  5132. // found to be lexicographically greater.
  5133. //
  5134. *pIndex = i - 1;
  5135. *ppRow = --pRow;
  5136. return(SNMP_ERRORSTATUS_NOERROR);
  5137. }
  5138. }
  5139. else // NameLen == 0
  5140. {
  5141. //
  5142. // The action has got to be GETNEXT (see MIB_DRTable)
  5143. // which means that pfFirst is not NULL
  5144. //
  5145. //--ft: prefix bug #444993
  5146. *pIndex = 0;
  5147. if (pfFirst != NULL)
  5148. *pfFirst = TRUE;
  5149. }
  5150. return(ErrStat);
  5151. }
  5152. int
  5153. __cdecl
  5154. CompareNames(
  5155. const VOID *pKey1,
  5156. const VOID *pKey2
  5157. )
  5158. {
  5159. const PWINSINTF_RECORD_ACTION_T pRow1 = (PWINSINTF_RECORD_ACTION_T)pKey1;
  5160. const PWINSINTF_RECORD_ACTION_T pRow2 = (PWINSINTF_RECORD_ACTION_T)pKey2;
  5161. ULONG CmpVal;
  5162. DWORD LenToCmp = min(pRow1->NameLen, pRow2->NameLen);
  5163. PERF("replace with RtlCompareMemory")
  5164. CmpVal = memcmp(pRow1->pName, pRow2->pName, LenToCmp);
  5165. if (CmpVal == LenToCmp)
  5166. {
  5167. return(pRow1->NameLen - pRow2->NameLen);
  5168. }
  5169. else
  5170. {
  5171. return(CmpVal);
  5172. }
  5173. }
  5174. int
  5175. __cdecl
  5176. CompareIndexes(
  5177. const VOID *pKey1,
  5178. const VOID *pKey2
  5179. )
  5180. {
  5181. const PDATAFILE_INFO_T pRow1 = (PDATAFILE_INFO_T)pKey1;
  5182. const PDATAFILE_INFO_T pRow2 = (PDATAFILE_INFO_T)pKey2;
  5183. PERF("replace with RtlCompareMemory")
  5184. return(strcmp(pRow1->ValNm, pRow2->ValNm));
  5185. }
  5186. DWORD
  5187. PopulateDRCache(
  5188. VOID
  5189. )
  5190. {
  5191. DWORD RetStat = WINSINTF_SUCCESS;
  5192. WINSINTF_VERS_NO_T MaxVersNo, MinVersNo;
  5193. handle_t BindHdl;
  5194. WINSINTF_ADD_T WinsAdd;
  5195. DWORD SvNoOfRecs;
  5196. LPVOID pSvRplPnrs;
  5197. LPBYTE pStorage;
  5198. WINS_ASSIGN_INT_TO_VERS_NO_M(MaxVersNo, 0);
  5199. WINS_ASSIGN_INT_TO_VERS_NO_M(MinVersNo, 0);
  5200. WinsAdd.Len = 4;
  5201. WinsAdd.Type = 0;
  5202. pSvRplPnrs = sRecs.pRow;
  5203. SvNoOfRecs = sRecs.NoOfRecs;
  5204. sRecs.pRow = NULL;
  5205. sRecs.NoOfRecs = 0;
  5206. pStorage = MIB_GetDbRecsStore;
  5207. WinsAdd.IPAdd = ntohl(*(DWORD*)pStorage);
  5208. //NMSMSGF_RETRIEVE_IPADD_M(pStorage, WinsAdd.IPAdd);
  5209. BindHdl = WinsBind(&sBindData);
  5210. RetStat = WinsGetDbRecs(BindHdl, &WinsAdd, MinVersNo, MaxVersNo, &sRecs);
  5211. WinsUnbind(&sBindData, BindHdl);
  5212. if (RetStat == WINSINTF_SUCCESS)
  5213. {
  5214. if (sRecs.NoOfRecs > 1)
  5215. {
  5216. qsort(
  5217. (LPVOID)sRecs.pRow,
  5218. (size_t)sRecs.NoOfRecs,
  5219. sizeof(WINSINTF_RECORD_ACTION_T),
  5220. CompareNames
  5221. );
  5222. }
  5223. if (pSvRplPnrs != NULL)
  5224. {
  5225. WinsFreeMem(pSvRplPnrs);
  5226. }
  5227. }
  5228. else
  5229. {
  5230. sRecs.NoOfRecs = SvNoOfRecs;
  5231. sRecs.pRow = pSvRplPnrs;
  5232. }
  5233. return(RetStat);
  5234. }