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.

5460 lines
174 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. winscnf.c
  5. Abstract:
  6. This module contains functions that deal with the configuration
  7. information for the WINS
  8. Portability:
  9. This module is portable
  10. Author:
  11. Pradeep Bahl (PradeepB) Dec-1992
  12. Revision History:
  13. Modification date Person Description of modification
  14. ----------------- ------- ----------------------------
  15. --*/
  16. /*
  17. * Includes
  18. */
  19. #include "wins.h"
  20. #include <winsock2.h>
  21. #include <string.h>
  22. #include <stddef.h>
  23. #include <stdlib.h>
  24. #include <search.h>
  25. #include "comm.h"
  26. #include "winreg.h"
  27. #include "winsevt.h"
  28. #include "winsmsc.h"
  29. #include "winscnf.h"
  30. #include "nms.h"
  31. #include "nmsnmh.h"
  32. #include "rpl.h"
  33. #include "rplpush.h"
  34. #include "winsintf.h"
  35. #include "nmfilter.h"
  36. #include <resapi.h>
  37. /*
  38. * Local Macro Declarations
  39. */
  40. //
  41. // Size of max string that a user can input in a REG_SZ field
  42. //
  43. #define MAX_SZ_SIZE 80
  44. #define REG_M(fn, evt, exc) \
  45. { \
  46. if((fn) != ERROR_SUCCESS) \
  47. { \
  48. WINSEVT_LOG_M( \
  49. WINS_FATAL_ERR, \
  50. (evt) \
  51. ); \
  52. WINS_RAISE_EXC_M((exc)); \
  53. } \
  54. }
  55. //
  56. // pointer to default path for log file. If you change this to a NON NULL
  57. // value, make sure you don't try to free the memory in SetSystemParam
  58. // in nmsdb.c
  59. //
  60. #define DEFAULT_LOG_PATH NULL
  61. #define _WINS_CFG_KEY \
  62. TEXT("System\\CurrentControlSet\\Services\\Wins")
  63. #define _WINS_CFG_PARAMETERS_KEY TEXT("Parameters")
  64. #define _WINS_CFG_PARTNERS_KEY TEXT("Partners")
  65. #define _WINS_CFG_CC_KEY TEXT("Parameters\\ConsistencyCheck")
  66. #define _WINS_CFG_PULL_KEY TEXT("Partners\\Pull")
  67. #define _WINS_CFG_PUSH_KEY TEXT("Partners\\Push")
  68. #define _WINS_CFG_DATAFILES_KEY TEXT("Parameters\\Datafiles")
  69. #define _WINS_CFG_SPEC_GRP_MASKS_KEY TEXT("Parameters\\InternetGrpMasks")
  70. #define _WINS_LOG_KEY \
  71. TEXT("System\\CurrentControlSet\\Services\\EventLog\\Application\\WinsInt")
  72. #define _WINS_MSGFILE_SKEY TEXT("EventMessageFile")
  73. #define _WINS_LOG_FILE_NAME TEXT("%SystemRoot%\\System32\\winsevnt.dll")
  74. #define _RPL_CLASS TEXT("RplClass")//class for Rpl Pull and Push
  75. //keys
  76. //
  77. // The start version number should never be allowed to go above this number
  78. // This will avoid a wrap around.
  79. //
  80. #define MAX_START_VERS_NO 0x0FFFFFFF
  81. //
  82. // Names of event variables used for notification purposes
  83. //
  84. #ifdef WINSDBG
  85. #define WINS_KEY_CHG_EVT_NM TEXT("WinsKChgEvt")
  86. #define PARAMETERS_KEY_CHG_EVT_NM TEXT("WinsParamatersKChgEvt")
  87. #define PARTNERS_KEY_CHG_EVT_NM TEXT("WinsPartenersKChgEvt")
  88. #define CNF_CHG_EVT_NM TEXT("WinsConfigChangeEvt")
  89. #else
  90. #define WINS_KEY_CHG_EVT_NM NULL
  91. #define PARAMETERS_KEY_CHG_EVT_NM NULL
  92. #define PARTNERS_KEY_CHG_EVT_NM NULL
  93. #define CNF_CHG_EVT_NM NULL
  94. #endif
  95. //
  96. // Values for the fStaticInit field of the configuration data structure
  97. //
  98. #define DO_STATIC_INIT TRUE
  99. #define DONT_DO_STATIC_INIT FALSE
  100. //
  101. // defines for the InitTimeRpl and InitTimePush fields of WinsCnf
  102. //
  103. #define DO_INIT_TIME_RPL 1
  104. #define NO_INIT_TIME_RPL 0
  105. //
  106. // NO_LIMIT_CHK_FLAG - for easing the task of testers
  107. //
  108. // If this flag is set in LogDetailedEvts DWORD, WINS skips all
  109. // checks for the min. values of the time intervals and Update Count.
  110. // This kind of operation of WINS is unsupported and is being provided
  111. // only to help out testers
  112. //
  113. #define NO_LIMIT_CHK_FLAG 0x80000000 //MSB is set.
  114. //
  115. // If ErrEvt passed is 0, we don't log any message. NOTE: a WINS event
  116. // can never have 0 as its value (checkout winsevnt.mc)
  117. //
  118. #define QUERY_VALUE_M(Key, Str, ValTyp, Var, ErrEvt, DefVal) \
  119. { \
  120. DWORD Sz = sizeof((Var)); \
  121. if (RegQueryValueEx( \
  122. (Key), \
  123. (Str), \
  124. NULL, \
  125. &(ValTyp), \
  126. (LPBYTE)&(Var), \
  127. &Sz \
  128. ) != ERROR_SUCCESS \
  129. ) \
  130. { \
  131. if ((ErrEvt) != 0) \
  132. { \
  133. WINSEVT_LOG_INFO_M( \
  134. WINS_SUCCESS, \
  135. (ErrEvt) \
  136. ); \
  137. } \
  138. Var = DefVal; \
  139. } \
  140. }
  141. /*
  142. * Local Typedef Declarations
  143. */
  144. /*
  145. * Global Variable Definitions
  146. */
  147. CRITICAL_SECTION WinsCnfCnfCrtSec; //used for reinitialization
  148. //of certain fields of the
  149. //WinsCnf structure
  150. BOOL fWinsCnfRplEnabled = TRUE; //replication is enabled
  151. BOOL fWinsCnfScvEnabled = TRUE; //scavenging is enabled
  152. FUTURES("use #ifdef PERF around the following three perf. mon. vars")
  153. BOOL fWinsCnfPerfMonEnabled = FALSE; //perf. mon is disabled
  154. BOOL fWinsCnfHighResPerfCntr = FALSE; //indicates whether the
  155. //hardware supports a high
  156. //performance counter
  157. LARGE_INTEGER LiWinsCnfPerfCntrFreq; //indicates the frequency of
  158. //the counter
  159. BOOL fWinsCnfReadNextTimeVersNo = FALSE;
  160. DWORD WinsCnfCnfMagicNo = WINSCNF_INITIAL_CNF_MAGIC_NO;
  161. BOOL fWinsCnfInitStatePaused;
  162. //TCHAR WinsCnfDb[WINS_MAX_FILENAME_SZ]; //db file to hold tables
  163. BOOL WinsCnfRegUpdThdExists = FALSE;
  164. //#define MAX_PATH_SIZE 200
  165. PTCHAR pWinsCnfNbtPath;
  166. BOOL sfNoLimitChk = FALSE; //to override the limit checks
  167. //
  168. // NetBt handle
  169. //
  170. HANDLE WinsCnfNbtHandle = NULL;
  171. //
  172. //
  173. // Init the configuration structure with default values
  174. //
  175. WINSCNF_CNF_T WinsCnf = {
  176. WINSCNF_INITIAL_CNF_MAGIC_NO, //id
  177. NOTE("Change 1 to 0 before production")
  178. 0, //Log detailed evts
  179. 1, //default number of processors
  180. 200, //default no. of db buffers
  181. { 0, NULL}, //Spec.grp mask
  182. WINSCNF_E_INITING, //state
  183. WINSCNF_DEF_REFRESH_INTERVAL,
  184. WINSCNF_MIN_TOMBSTONE_INTERVAL,
  185. WINSCNF_MIN_TOMBSTONE_TIMEOUT,
  186. WINSCNF_MIN_VERIFY_INTERVAL,
  187. WINSCNF_SCV_CHUNK,
  188. WINSCNF_DEF_CHL_MAX_RETRIES,
  189. WINSCNF_DEF_INIT_CHL_RETRY_INTVL,
  190. WINSCNF_DB_NAME_ASCII, //db file name
  191. 0, //no of STATIC files
  192. NULL, //ptr to file names
  193. DONT_DO_STATIC_INIT,
  194. (HANDLE)0, //notify event handle (WINS)
  195. (HANDLE)0, //not. evt hdl (PARAMETSRS)
  196. (HANDLE)0, //not. evt hdl (PARTNERS)
  197. (HANDLE)0, //Config change handle
  198. (HANDLE)0, //log event handle
  199. (DWORD)WINSINTF_E_NORMAL,
  200. WINSTHD_DEF_NO_NBT_THDS,
  201. WINSCNF_SCV_PRIORITY_LVL,
  202. WINSCNF_MIN_VALID_RPL_INTVL,//max Rpl
  203. //Time Intvl
  204. TRUE, //rpl. only with cnf partners
  205. TRUE, //add 1B to responses to 1C name queries
  206. #if MCAST > 0
  207. FALSE, //no rpl. with self found pnrs
  208. WINSCNF_DEF_MCAST_TTL,
  209. WINSCNF_DEF_MCAST_INTVL,
  210. #endif
  211. TRUE, //logging is on
  212. NULL, //current directory
  213. NULL, //no backup directory
  214. FALSE, //Do backup on term flg
  215. FALSE, //PStatic flag
  216. 0, //type of persona list (0 = non-grata)
  217. 0, //number of addresses in persona list
  218. NULL, //persona list
  219. WINSCNF_RPL_DEFAULT_TYPE, //def. rpl
  220. TRUE, //No rpl on error
  221. TRUE, //no persistent connections
  222. //
  223. // CC initialization
  224. //
  225. MAXULONG, //CC Time Int
  226. FALSE, //SpTime Set
  227. MAXULONG, //Sp Time
  228. WINSCNF_CC_DEF_RECS_AAT,
  229. WINSCNF_CC_DEF_USE_RPL_PNRS,
  230. FALSE, //no spoofing
  231. FALSE, // no randomization of 1C list.
  232. //
  233. //PullInfo initialization
  234. //
  235. WINSCNF_MAX_COMM_RETRIES, //comm.
  236. //failure
  237. //retries
  238. 0, //no of Push Pnrs
  239. NULL,//ptr to Pull Pnrs records
  240. DO_INIT_TIME_RPL, //do init time
  241. //pulling
  242. WINSCNF_RPL_DEFAULT_TYPE,
  243. TRUE, // persistent connections
  244. //
  245. // PushInfo initialization
  246. //
  247. TRUE, // trigger on address change
  248. //of owned entry
  249. 0, //no of Pull Pnrs
  250. 0, //no of Push recs with valid
  251. //update count
  252. NULL,//ptr to Push Pnrs records
  253. DO_INIT_TIME_RPL, //init time
  254. //pushing disabled
  255. DO_PROP_NET_UPD_NTF, //prop net upd
  256. //ntfs.
  257. WINSCNF_RPL_DEFAULT_TYPE,
  258. TRUE // persistent connections
  259. };
  260. /*
  261. * Local Variable Definitions
  262. */
  263. STATIC BOOL sfVersNoUpdThdExists = FALSE;
  264. STATIC BOOL sfVersNoChanged = FALSE;
  265. STATIC HKEY sConfigRoot; //HKEY for the WINS root
  266. STATIC HKEY sParametersKey; //HKEY for the PARAMETERS subkey
  267. STATIC HKEY sCCKey; //HKEY for the CC subkey
  268. STATIC HKEY sPartnersKey; //HKEY for PARTNERS subkey
  269. STATIC HKEY sLogRoot; //HKEY for the log root
  270. FUTURES("Might want to change these to auto variables later")
  271. STATIC TCHAR sWinsCfgKey[] = _WINS_CFG_KEY;
  272. STATIC TCHAR sWinsLogKey[] = _WINS_LOG_KEY;
  273. STATIC TCHAR sWinsMsgFileSKey[] = _WINS_MSGFILE_SKEY;
  274. //
  275. // flags that indicate to WinsCnfOpenSubKeys() whether the corresponding keys
  276. // exist.
  277. //
  278. STATIC BOOL sfParametersKeyExists = FALSE;
  279. STATIC BOOL sfPartnersKeyExists = FALSE;
  280. STATIC BOOL sfParametersKeyOpen = FALSE;
  281. STATIC BOOL sfPartnersKeyOpen = FALSE;
  282. TCHAR sLogFilePath[WINS_MAX_FILENAME_SZ]; //path to log file
  283. /*
  284. * Local Function Prototype Declarations
  285. */
  286. /* prototypes for functions local to this module go here */
  287. STATIC
  288. VOID
  289. LnkWSameMetricValRecs(
  290. PWINSCNF_CNF_T pWinsCnf,
  291. PRPL_CONFIG_REC_T pCnfRec
  292. );
  293. STATIC
  294. int
  295. __cdecl
  296. CompUpdCnt(
  297. CONST LPVOID pElem1,
  298. CONST LPVOID pElem2
  299. );
  300. STATIC
  301. VOID
  302. GetPnrInfo(
  303. RPL_RR_TYPE_E RRType_e,
  304. PWINSCNF_CNF_T pWinsCnf
  305. );
  306. STATIC
  307. VOID
  308. GetKeyInfo(
  309. IN HKEY Key,
  310. IN WINSCNF_KEY_E KeyTyp_e,
  311. OUT LPDWORD pNoOfSubKeys,
  312. OUT LPDWORD pNoOfVals
  313. );
  314. STATIC
  315. BOOL
  316. SanityChkParam(
  317. PWINSCNF_CNF_T pWinsCnf
  318. );
  319. STATIC
  320. VOID
  321. ChkWinsSubKeys(
  322. VOID
  323. );
  324. STATIC
  325. VOID
  326. GetSpTimeData(
  327. HKEY SubKey,
  328. LPSYSTEMTIME pCurrTime,
  329. LPBOOL pfSpTime,
  330. LPDWORD pSpTimeIntvl
  331. );
  332. STATIC
  333. VOID
  334. ReadSpecGrpMasks(
  335. PWINSCNF_CNF_T pWinsCnf
  336. );
  337. VOID
  338. GetOwnerList(
  339. PWINSCNF_CNF_T pWinsCnf
  340. );
  341. VOID
  342. ReadCCInfo(
  343. PWINSCNF_CNF_T pWinsCnf
  344. );
  345. #if MCAST > 0
  346. STATIC
  347. DWORD
  348. SetVal(
  349. HKEY RootKey,
  350. LPWSTR pName,
  351. DWORD ValType,
  352. LPWSTR pVal,
  353. DWORD ValSize
  354. );
  355. #endif
  356. #ifdef WINSDBG
  357. STATIC
  358. VOID
  359. PrintRecs(
  360. RPL_RR_TYPE_E RRType_e,
  361. PWINSCNF_CNF_T pWinsCnf
  362. );
  363. #endif
  364. /*function defs*/
  365. STATUS
  366. WinsCnfInitConfig(
  367. VOID
  368. )
  369. /*++
  370. Routine Description:
  371. This function opens the registry and reads in all the configuration
  372. information from it.
  373. Arguments:
  374. None
  375. Externals Used:
  376. WinsCnf
  377. Called by:
  378. Init() in nms.c
  379. Comments:
  380. None
  381. Return Value:
  382. Success status codes --
  383. Error status codes --
  384. --*/
  385. {
  386. DWORD NewKeyInd;
  387. LONG RetVal;
  388. /*
  389. First and foremost, open (or create if non-existent) the log file
  390. */
  391. #if 0
  392. InitLog();
  393. #endif
  394. RetVal = RegCreateKeyEx(
  395. HKEY_LOCAL_MACHINE, //predefined key value
  396. sWinsCfgKey, //subkey for WINS
  397. 0, //must be zero (reserved)
  398. TEXT("Class"), //class -- may change in future
  399. REG_OPTION_NON_VOLATILE, //non-volatile information
  400. KEY_ALL_ACCESS, //we desire all access to the keyo
  401. NULL, //let key have default sec. attributes
  402. &sConfigRoot, //handle to key
  403. &NewKeyInd //is it a new key (out arg)
  404. );
  405. if (RetVal != ERROR_SUCCESS)
  406. {
  407. WINSEVT_LOG_N_RET_M(
  408. WINS_FATAL_ERR,
  409. WINS_EVT_CANT_OPEN_WINS_KEY,
  410. WINS_FATAL_ERR
  411. );
  412. }
  413. //
  414. // Initialize the critical section that guards the fields used
  415. // by Scavenger thread
  416. //
  417. InitializeCriticalSection(&WinsCnfCnfCrtSec);
  418. InitializeCriticalSection(&g_cs1BFilter);
  419. /*
  420. First create the events that will be passed to the
  421. RegNotifyChangeKeyValue function
  422. */
  423. try {
  424. WinsMscCreateEvt(
  425. WINS_KEY_CHG_EVT_NM,
  426. FALSE, //auto reset event
  427. &WinsCnf.WinsKChgEvtHdl
  428. );
  429. WinsMscCreateEvt(
  430. PARAMETERS_KEY_CHG_EVT_NM,
  431. FALSE, //auto reset event
  432. &WinsCnf.ParametersKChgEvtHdl
  433. );
  434. WinsMscCreateEvt(
  435. PARTNERS_KEY_CHG_EVT_NM,
  436. FALSE, //auto reset event
  437. &WinsCnf.PartnersKChgEvtHdl
  438. );
  439. }
  440. except(EXCEPTION_EXECUTE_HANDLER) {
  441. DBGPRINTEXC("WinsCnfInitConfig");
  442. WINSEVT_LOG_M(WINS_FATAL_ERR, WINS_EVT_CANT_CREATE_REG_EVT);
  443. return(WINS_FAILURE);
  444. }
  445. //
  446. // Create the event that this main thread will set when configuration changes
  447. // The main thread sets this event to notify the scavenger thread (for now)
  448. // about the changes
  449. //
  450. WinsMscCreateEvt(
  451. CNF_CHG_EVT_NM,
  452. FALSE, //auto reset event
  453. &WinsCnf.CnfChgEvtHdl
  454. );
  455. //
  456. // Opens the Partners and Parameters keys
  457. //
  458. WinsCnfOpenSubKeys();
  459. //
  460. // Read in the registry information
  461. //
  462. WinsCnfReadRegInfo(&WinsCnf);
  463. /*
  464. Ask to be notified when the Configuration key or any of the subkeys
  465. change
  466. */
  467. WinsCnfAskToBeNotified(WINSCNF_E_WINS_KEY);
  468. return(WINS_SUCCESS);
  469. }
  470. VOID
  471. WinsCnfReadPartnerInfo(
  472. PWINSCNF_CNF_T pWinsCnf
  473. )
  474. /*++
  475. Routine Description:
  476. This function gets all the information pertaining to the Partners of this
  477. WINS. Under the configuration key above, there are two Keys PULL and PUSH.
  478. Under each key, there can be one or more keys (IP addresses). The values
  479. for each IP address key are:
  480. Time Interval (for both Pull and Push IP address keys)
  481. Update Count (for Push IP address keys)
  482. Arguments:
  483. pWinsCnf - Address of Wins Configuration structure
  484. Externals Used:
  485. None
  486. Return Value:
  487. None
  488. Error Handling:
  489. Called by:
  490. Init function of the Replicator.
  491. Side Effects:
  492. Comments:
  493. Note: This function should never be called when inside the
  494. NmsNmhNamRegCrtSec, otherwise a deadlock can occur with the Pull
  495. thread (check out Reconfig in rplpull.c)
  496. --*/
  497. {
  498. DWORD ValTyp;
  499. //
  500. // Initialize the MaxRplTimeInterval field to 0. After we have read
  501. // both the PULL and PUSH key information from the registry, the above
  502. // field will contain the max. replication time interval specified for
  503. // pulling and pushing replicas
  504. //
  505. pWinsCnf->MaxRplTimeInterval = 0;
  506. pWinsCnf->PullInfo.NoOfPushPnrs = 0;
  507. pWinsCnf->PullInfo.pPullCnfRecs = NULL;
  508. pWinsCnf->PullInfo.RplType = WINSCNF_RPL_DEFAULT_TYPE;
  509. pWinsCnf->PushInfo.NoOfPullPnrs = 0;
  510. pWinsCnf->PushInfo.pPushCnfRecs = NULL;
  511. pWinsCnf->PushInfo.fAddChgTrigger = FALSE;
  512. pWinsCnf->PushInfo.RplType = WINSCNF_RPL_DEFAULT_TYPE;
  513. //
  514. // Since we are again reading the info about the Partners key, increment
  515. // the magic no. No other thread increments this no. The thread that
  516. // looks at this no is the Pull thread.
  517. //
  518. EnterCriticalSection(&WinsCnfCnfCrtSec);
  519. pWinsCnf->MagicNo = ++WinsCnfCnfMagicNo;
  520. LeaveCriticalSection(&WinsCnfCnfCrtSec);
  521. try {
  522. GetOwnerList(pWinsCnf); // get list of persona (grata / non-grata)
  523. //
  524. // Read in the RplType DWORD. Even if no partners are defined, we do this
  525. // in case this WINS is open to all partners (i.e. fOnlyWCnfPnrs is FALSE)
  526. //
  527. QUERY_VALUE_M(
  528. sPartnersKey,
  529. WINSCNF_RPL_TYPE_NM,
  530. ValTyp,
  531. pWinsCnf->RplType,
  532. 0, // no logging
  533. WINSCNF_RPL_DEFAULT_TYPE
  534. );
  535. GetPnrInfo(RPL_E_PULL, pWinsCnf);
  536. GetPnrInfo(RPL_E_PUSH, pWinsCnf);
  537. }
  538. except(EXCEPTION_EXECUTE_HANDLER) {
  539. DWORD ExcCode = GetExceptionCode();
  540. //
  541. // If there is some problem with the registry, we don't want
  542. // to bugcheck WINS. It can proceed with default values.
  543. // Since we have already logged the errors, the administrator
  544. // can take corrective action if necessary
  545. //
  546. if (
  547. (ExcCode != WINS_EXC_CANT_OPEN_KEY)
  548. &&
  549. (ExcCode != WINS_EXC_CANT_QUERY_KEY)
  550. &&
  551. (ExcCode != WINS_EXC_CANT_CLOSE_KEY)
  552. )
  553. {
  554. WINS_RERAISE_EXC_M();
  555. }
  556. }
  557. return;
  558. }
  559. STATUS
  560. WinsCnfInitLog(
  561. VOID
  562. )
  563. /*++
  564. Routine Description:
  565. This function open (or creates) a log file for registering events
  566. Arguments:
  567. None
  568. Externals Used:
  569. None
  570. Return Value:
  571. Success status codes -- WINS_SUCCESS
  572. Error status codes -- WINS_FAILURE
  573. Error Handling:
  574. Called by:
  575. WinsCnfInitConfig
  576. Side Effects:
  577. Comments:
  578. None
  579. --*/
  580. {
  581. LONG RetVal = ERROR_SUCCESS;
  582. STATUS RetStat = WINS_SUCCESS;
  583. #ifdef WINS_INTERACTIVE
  584. DWORD NewKeyInd;
  585. TCHAR Buff[160];
  586. DWORD dwData;
  587. RetVal = RegCreateKeyEx(
  588. HKEY_LOCAL_MACHINE, //predefined key value
  589. sWinsLogKey, //subkey for WINS
  590. 0, //must be zero (reserved)
  591. TEXT("Class"), //class -- may change in future
  592. REG_OPTION_NON_VOLATILE, //non-volatile information
  593. KEY_ALL_ACCESS, //we desire all access to the keyo
  594. NULL, //let key have default sec. attributes
  595. &sLogRoot, //handle to key
  596. &NewKeyInd //is it a new key (out arg) -- not
  597. //looked at
  598. );
  599. if (RetVal != ERROR_SUCCESS)
  600. {
  601. return(WINS_FAILURE);
  602. }
  603. /*
  604. Set the event id message file name
  605. */
  606. lstrcpy(Buff, _WINS_LOG_FILE_NAME);
  607. /*
  608. Add the Event-ID message-file name to the subkey
  609. */
  610. RetVal = RegSetValueEx(
  611. sLogRoot, //key handle
  612. sWinsMsgFileSKey, //value name
  613. 0, //must be zero
  614. REG_EXPAND_SZ, //value type
  615. (LPBYTE)Buff,
  616. (lstrlen(Buff) + 1) * sizeof(TCHAR) //length of value data
  617. );
  618. if (RetVal != ERROR_SUCCESS)
  619. {
  620. return(WINS_FAILURE);
  621. }
  622. /*
  623. Set the supported data types flags
  624. */
  625. dwData = EVENTLOG_ERROR_TYPE |
  626. EVENTLOG_WARNING_TYPE |
  627. EVENTLOG_INFORMATION_TYPE;
  628. RetVal = RegSetValueEx (
  629. sLogRoot, //subkey handle
  630. TEXT("TypesSupported"), //value name
  631. 0, //must be zero
  632. REG_DWORD, //value type
  633. (LPBYTE)&dwData, //Address of value data
  634. sizeof(DWORD) //length of value data
  635. );
  636. if (RetVal != ERROR_SUCCESS)
  637. {
  638. return(WINS_FAILURE);
  639. }
  640. /*
  641. * Done with the key. Close it
  642. */
  643. RetVal = RegCloseKey(sLogRoot);
  644. if (RetVal != ERROR_SUCCESS)
  645. {
  646. return(WINS_FAILURE);
  647. }
  648. #endif
  649. WinsCnf.LogHdl = RegisterEventSource(
  650. (LPCTSTR)NULL, //use local machine
  651. TEXT("Wins")
  652. );
  653. if (WinsCnf.LogHdl == NULL)
  654. {
  655. DBGPRINT1(ERR, "InitLog: RegisterEventSource error = (%x)\n", GetLastError());
  656. return(WINS_FAILURE);
  657. }
  658. WINSEVT_LOG_INFO_D_M(WINS_SUCCESS, WINS_EVT_LOG_INITED);
  659. return(RetStat);
  660. }
  661. VOID
  662. LnkWSameMetricValRecs(
  663. PWINSCNF_CNF_T pWinsCnf,
  664. PRPL_CONFIG_REC_T pCnfRec
  665. )
  666. /*++
  667. Routine Description:
  668. This function is called to link a configuration record with all
  669. other configuration records with the same metric value. The metric
  670. to use depends upon the type of the record. If it is a PULL record,
  671. the metric is "Time Interval". If the record is a PUSH record,
  672. the metric is "Update Count"
  673. Arguments:
  674. pWinsCnf - Address of configuration block
  675. pCnfRec - Configuration Record to link.
  676. Externals Used:
  677. None
  678. Return Value:
  679. None
  680. Error Handling:
  681. Called by:
  682. WinsCnfReadPartnerInfo
  683. Side Effects:
  684. Comments:
  685. The record to be linked is the last record in the buffer of
  686. records of the same type.
  687. --*/
  688. {
  689. PRPL_CONFIG_REC_T pTmp;
  690. DWORD OffMetricToComp;
  691. LONG MetricVal;
  692. //
  693. // Set the variables used later based on the record type
  694. //
  695. if (pCnfRec->RRTyp_e == RPL_E_PULL)
  696. {
  697. pTmp = pWinsCnf->PullInfo.pPullCnfRecs;
  698. MetricVal = pCnfRec->TimeInterval;
  699. OffMetricToComp = offsetof(RPL_CONFIG_REC_T, TimeInterval);
  700. }
  701. else //it is a PUSH record
  702. {
  703. pTmp = pWinsCnf->PushInfo.pPushCnfRecs;
  704. MetricVal = pCnfRec->UpdateCount;
  705. OffMetricToComp = offsetof(RPL_CONFIG_REC_T, UpdateCount);
  706. }
  707. //
  708. // Link in this record at the end of the linked list of
  709. // records with the same metric value in the buffer pointed by
  710. // the starting value of pTmp (set above).
  711. //
  712. for (
  713. ;
  714. pTmp != pCnfRec; //until we reach this record
  715. pTmp = (PRPL_CONFIG_REC_T)((LPBYTE)pTmp + RPL_CONFIG_REC_SIZE)
  716. )
  717. {
  718. //
  719. // If Metric Value is same, go to end of linked list and
  720. // link in the record
  721. //
  722. if (*((LONG *)((LPBYTE)pTmp + OffMetricToComp)) == MetricVal)
  723. {
  724. //
  725. // Note: if the metric is UpdateCount (Push records)
  726. // then, the following if will fail.
  727. //
  728. //
  729. // If both records have a specific time for replication,
  730. // that time must agree too
  731. //
  732. if (pTmp->fSpTime && pCnfRec->fSpTime)
  733. {
  734. //
  735. // If specific time is not the same, go to the
  736. // next record in the array
  737. //
  738. if (pTmp->SpTimeIntvl != pCnfRec->SpTimeIntvl)
  739. {
  740. continue;
  741. }
  742. }
  743. for(
  744. ;
  745. pTmp->pNext != NULL;
  746. pTmp = pTmp->pNext
  747. )
  748. ; //NULL body
  749. pTmp->pNext = pCnfRec;
  750. //
  751. // Set flag to indicate that this record has
  752. // been linked. Used in SubmitTimerReqs in rplpull.c
  753. //
  754. pCnfRec->fLinked = TRUE;
  755. break; //record is linked. break out of the loop
  756. }
  757. } //end of for { .. } for looping over all records in the buffer
  758. //
  759. // Make pNext to NULL since this is the last record in the buffer
  760. // buffer of Config Records (also in the chain if records with
  761. // the same metric)
  762. //
  763. pCnfRec->pNext = NULL;
  764. return;
  765. }
  766. VOID
  767. WinsCnfSetLastUpdCnt(
  768. PWINSCNF_CNF_T pWinsCnf
  769. )
  770. /*++
  771. Routine Description:
  772. This function is called at initialization/reinitialization time if
  773. InitTimePush registry variable is set to 1) to set the LastVersNo
  774. field of all Push Configuration records to the value of the
  775. NmsNmhMyMAxVersNo counter. This is done to avoid Push Notifications
  776. to be sent at Init time.
  777. Arguments:
  778. pWinsCnf - Wins Configuration Info
  779. Externals Used:
  780. NmsNmhMyMaxVersNo
  781. Return Value:
  782. None
  783. Error Handling:
  784. Called by:
  785. NmsDbInit, Reinit (in nms.c)
  786. Side Effects:
  787. Comments:
  788. This function is called only after the local Database
  789. Name-Address mapping table has been read and NmsNmhMyMaxVersNo
  790. counter initialized (see GetMaxVersNos in nmsdb.c). Also,
  791. this function is called only if the counter value is > 0
  792. --*/
  793. {
  794. PRPL_CONFIG_REC_T pCnfRec = pWinsCnf->PushInfo.pPushCnfRecs;
  795. for (
  796. ; //null expr 1
  797. pCnfRec->WinsAdd.Add.IPAdd != INADDR_NONE;
  798. pCnfRec = (PRPL_CONFIG_REC_T)(
  799. (LPBYTE) pCnfRec + RPL_CONFIG_REC_SIZE
  800. )
  801. )
  802. {
  803. //
  804. // If the Update count field is invalid, go to the next record
  805. //
  806. if (pCnfRec->UpdateCount == RPL_INVALID_METRIC)
  807. {
  808. continue;
  809. }
  810. pCnfRec->LastVersNo = NmsNmhMyMaxVersNo;
  811. }
  812. return;
  813. }
  814. VOID
  815. GetPnrInfo(
  816. RPL_RR_TYPE_E RRType_e,
  817. PWINSCNF_CNF_T pWinsCnf
  818. )
  819. /*++
  820. Routine Description:
  821. This function is called to read PULL/PUSH records
  822. Arguments:
  823. RRType_e - Type of Information to read (PULL or PUSH records)
  824. pWinsCnf - Configuration structure
  825. Externals Used:
  826. None
  827. Return Value:
  828. None
  829. Error Handling:
  830. Called by:
  831. WinsCnfReadPartnerInfo
  832. Side Effects:
  833. Comments:
  834. None
  835. --*/
  836. {
  837. LONG RetVal;
  838. HKEY CnfKey;
  839. TCHAR KeyName[20]; // will hold name of subkey of
  840. // PULL/PUSH records. These keys are IP
  841. // addresses for which 20 is a
  842. // big enough size
  843. CHAR AscKeyName[20];
  844. DWORD KeyNameSz;
  845. FILETIME LastWrite;
  846. DWORD BuffSize;
  847. HKEY SubKey;
  848. DWORD ValTyp;
  849. DWORD Sz;
  850. PRPL_CONFIG_REC_T paCnfRecs;
  851. DWORD NoOfPnrs = 0; //# of valid PULL or PUSH pnrs
  852. DWORD NoOfPnrsSv; //# of valid PULL or PUSH pnrs saved
  853. DWORD NoOfVals;
  854. DWORD InitTime;
  855. DWORD IndexOfPnr = 0; //total # of pnrs
  856. DWORD RplType;
  857. SYSTEMTIME CurrTime;
  858. //
  859. // Get the current time. It may be needed if we have partners with SpTime
  860. // specified.
  861. //
  862. if (RRType_e == RPL_E_PULL)
  863. {
  864. GetLocalTime(&CurrTime);
  865. }
  866. /*
  867. * Open the key (PULL/PUSH)
  868. */
  869. RetVal = RegOpenKeyEx(
  870. sConfigRoot, //predefined key value
  871. RRType_e == RPL_E_PULL ?
  872. _WINS_CFG_PULL_KEY :
  873. _WINS_CFG_PUSH_KEY, //subkey for WINS
  874. 0, //must be zero (reserved)
  875. KEY_READ, //we desire read access to the keyo
  876. &CnfKey //handle to key
  877. );
  878. if (RetVal != ERROR_SUCCESS)
  879. {
  880. CHECK("Is there any need to log this")
  881. WINSEVT_LOG_INFO_M(
  882. WINS_SUCCESS,
  883. RRType_e == RPL_E_PULL ?
  884. WINS_EVT_CANT_OPEN_PULL_KEY :
  885. WINS_EVT_CANT_OPEN_PUSH_KEY
  886. );
  887. }
  888. else //key was successfully opened
  889. {
  890. /*
  891. * Query the key. The subkeys are IP addresses of PULL
  892. * partners.
  893. */
  894. GetKeyInfo(
  895. CnfKey,
  896. (RRType_e == RPL_E_PULL ? WINSCNF_E_PULL_KEY :
  897. WINSCNF_E_PUSH_KEY),
  898. &NoOfPnrs,
  899. &NoOfVals //ignored
  900. );
  901. if (NoOfPnrs == 0)
  902. {
  903. WINSEVT_LOG_INFO_D_M(
  904. WINS_SUCCESS,
  905. RRType_e == RPL_E_PULL ?
  906. WINS_EVT_NO_SUBKEYS_UNDER_PULL :
  907. WINS_EVT_NO_SUBKEYS_UNDER_PUSH
  908. );
  909. }
  910. else
  911. {
  912. //
  913. // Since we have one or more Partners to replicate with,
  914. // read in the value of the InitTimeReplication attribute
  915. // of all such Partners
  916. //
  917. QUERY_VALUE_M(
  918. CnfKey,
  919. WINSCNF_INIT_TIME_RPL_NM,
  920. ValTyp,
  921. InitTime,
  922. 0, //WINS_EVT_CANT_GET_INITRPL_VAL,
  923. DO_INIT_TIME_RPL
  924. );
  925. //
  926. // Since we have one or more Partners to replicate with,
  927. // read in the value of the RplType attribute
  928. //
  929. QUERY_VALUE_M(
  930. CnfKey,
  931. WINSCNF_RPL_TYPE_NM,
  932. ValTyp,
  933. RplType,
  934. 0,
  935. pWinsCnf->RplType
  936. );
  937. #if PRSCONN
  938. QUERY_VALUE_M(
  939. CnfKey,
  940. WINSCNF_PRS_CONN_NM,
  941. ValTyp,
  942. pWinsCnf->fPrsConn,
  943. 0,
  944. TRUE
  945. );
  946. #endif
  947. //
  948. // Allocate buffer big enough to hold data for
  949. // the number of subkeys found under the PULL key
  950. //
  951. BuffSize = RPL_CONFIG_REC_SIZE * (NoOfPnrs + 1);
  952. WinsMscAlloc( BuffSize, &paCnfRecs);
  953. if (RRType_e == RPL_E_PULL)
  954. {
  955. pWinsCnf->PullInfo.pPullCnfRecs = paCnfRecs;
  956. QUERY_VALUE_M(
  957. CnfKey,
  958. WINSCNF_RETRY_COUNT_NM,
  959. ValTyp,
  960. pWinsCnf->PullInfo.MaxNoOfRetries,
  961. 0, //WINS_EVT_CANT_GET_RETRY_COUNT,
  962. WINSCNF_MAX_COMM_RETRIES
  963. );
  964. }
  965. else
  966. {
  967. //
  968. // Get the value of the field that indicates
  969. // whether we should send a trigger when the
  970. // address of an owned entry changes.
  971. //
  972. Sz = sizeof(pWinsCnf->PushInfo.fAddChgTrigger);
  973. RetVal = RegQueryValueEx(
  974. CnfKey,
  975. WINSCNF_ADDCHG_TRIGGER_NM,
  976. NULL, //reserved; must be NULL
  977. &ValTyp,
  978. (LPBYTE)&pWinsCnf->PushInfo.fAddChgTrigger,
  979. &Sz
  980. );
  981. if (RetVal != ERROR_SUCCESS)
  982. {
  983. pWinsCnf->PushInfo.fAddChgTrigger = FALSE;
  984. }
  985. else
  986. {
  987. pWinsCnf->PushInfo.fAddChgTrigger =
  988. (pWinsCnf->PushInfo.fAddChgTrigger >= 1);
  989. }
  990. QUERY_VALUE_M(
  991. CnfKey,
  992. WINSCNF_PROP_NET_UPD_NTF,
  993. ValTyp,
  994. pWinsCnf->PushInfo.PropNetUpdNtf,
  995. 0, //no event
  996. DO_PROP_NET_UPD_NTF
  997. );
  998. pWinsCnf->PushInfo.pPushCnfRecs = paCnfRecs;
  999. pWinsCnf->PushInfo.NoPushRecsWValUpdCnt = 0;
  1000. }
  1001. /*
  1002. * For each key, get the values (Time Interval/UpdateCount,
  1003. * etc)
  1004. */
  1005. NoOfPnrsSv = NoOfPnrs; //save the number that we got from the
  1006. //GetkeyInfo function
  1007. for(
  1008. IndexOfPnr = 0, NoOfPnrs = 0;
  1009. NoOfPnrs < NoOfPnrsSv; //no of valid pnrs < the total #
  1010. IndexOfPnr++
  1011. )
  1012. {
  1013. KeyNameSz = sizeof(KeyName)/sizeof(TCHAR); //init before every call
  1014. RetVal = RegEnumKeyEx(
  1015. CnfKey,
  1016. IndexOfPnr, //Index Of Pnr
  1017. KeyName,
  1018. &KeyNameSz,
  1019. NULL, //reserved
  1020. NULL, //don't need class name
  1021. NULL, //ptr to var. to hold class name
  1022. &LastWrite //not looked at by us
  1023. );
  1024. if (RetVal != ERROR_SUCCESS)
  1025. {
  1026. //
  1027. // No more ip address keys to get
  1028. //
  1029. break;
  1030. }
  1031. //
  1032. // Store pointer to the Wins Config structure in
  1033. // the configuration record
  1034. //
  1035. paCnfRecs->pWinsCnf = pWinsCnf;
  1036. //
  1037. // pWinsCnf->MagicNo contains the value of
  1038. // WinsCnfCnfMagicNo
  1039. //
  1040. paCnfRecs->MagicNo = pWinsCnf->MagicNo;
  1041. paCnfRecs->RRTyp_e = RRType_e;
  1042. #ifdef UNICODE
  1043. if (wcstombs(AscKeyName, KeyName, KeyNameSz) == -1)
  1044. {
  1045. DBGPRINT0(ERR,
  1046. "Conversion not possible in the current locale\n");
  1047. }
  1048. AscKeyName[KeyNameSz] = EOS;
  1049. NONPORT("Call a comm function to do this")
  1050. paCnfRecs->WinsAdd.Add.IPAdd = inet_addr(AscKeyName);
  1051. #else
  1052. paCnfRecs->WinsAdd.Add.IPAdd = inet_addr(KeyName);
  1053. #endif
  1054. //
  1055. // inet_addr returns bytes in network byte order
  1056. // (Left to Right). Let us convert this into host
  1057. // order. This will avoid confusion later on. All
  1058. // formatting functions expect address to be in host
  1059. // order.
  1060. //
  1061. paCnfRecs->WinsAdd.AddLen = COMM_IP_ADD_SIZE;
  1062. paCnfRecs->WinsAdd.AddTyp_e = COMM_ADD_E_TCPUDPIP;
  1063. paCnfRecs->WinsAdd.Add.IPAdd = ntohl(
  1064. paCnfRecs->WinsAdd.Add.IPAdd
  1065. );
  1066. if (COMM_ADDRESS_SAME_M(&NmsLocalAdd, &paCnfRecs->WinsAdd))
  1067. {
  1068. //
  1069. // Invalid partner. Ignore. NoOfPnrs will
  1070. // not be incremented. Also, the buffer
  1071. // pointer stays the same
  1072. //
  1073. continue;
  1074. }
  1075. RetVal = RegOpenKeyEx(
  1076. CnfKey,
  1077. KeyName,
  1078. 0, //reserved; must be 0
  1079. KEY_READ,
  1080. &SubKey
  1081. );
  1082. if (RetVal != ERROR_SUCCESS)
  1083. {
  1084. WINSEVT_LOG_M(
  1085. WINS_FATAL_ERR,
  1086. RRType_e == RPL_E_PULL ?
  1087. WINS_EVT_CANT_OPEN_PULL_SUBKEY :
  1088. WINS_EVT_CANT_OPEN_PUSH_SUBKEY
  1089. );
  1090. FUTURES("It is possible that the user deleted the key. Recover from this")
  1091. if (RRType_e == RPL_E_PULL)
  1092. {
  1093. pWinsCnf->PullInfo.NoOfPushPnrs = 0;
  1094. WinsMscDealloc(pWinsCnf->PullInfo.pPullCnfRecs);
  1095. pWinsCnf->PullInfo.pPullCnfRecs = NULL;
  1096. }
  1097. else
  1098. {
  1099. pWinsCnf->PushInfo.NoOfPullPnrs = 0;
  1100. WinsMscDealloc(pWinsCnf->PushInfo.pPushCnfRecs);
  1101. pWinsCnf->PushInfo.pPushCnfRecs = NULL;
  1102. }
  1103. WINS_RAISE_EXC_M(WINS_EXC_CANT_OPEN_KEY);
  1104. }
  1105. FUTURES("Maybe, we will support a time interval attribute for Push records")
  1106. FUTURES("when that is done, LnkRecsWSameMetric would need to be updated")
  1107. if (RRType_e == RPL_E_PULL)
  1108. {
  1109. //
  1110. // Read in specific time for replication if one
  1111. // has been specified
  1112. //
  1113. GetSpTimeData(SubKey, &CurrTime, &paCnfRecs->fSpTime, &paCnfRecs->SpTimeIntvl);
  1114. Sz = sizeof(paCnfRecs->TimeInterval);
  1115. RetVal = RegQueryValueEx(
  1116. SubKey,
  1117. WINSCNF_RPL_INTERVAL_NM,
  1118. NULL, //reserved; must be NULL
  1119. &ValTyp,
  1120. (LPBYTE)&paCnfRecs->TimeInterval,
  1121. &Sz
  1122. );
  1123. if (RetVal != ERROR_SUCCESS)
  1124. {
  1125. WINSEVT_LOG_INFO_D_M(
  1126. WINS_SUCCESS,
  1127. WINS_EVT_CANT_GET_PULL_TIMEINT
  1128. );
  1129. paCnfRecs->TimeInterval = RPL_INVALID_METRIC;
  1130. }
  1131. else // a value was read in
  1132. {
  1133. //
  1134. // If the time interval is less than or
  1135. // equal to the minimum allowed, use the
  1136. // default minimum
  1137. //
  1138. if (paCnfRecs->TimeInterval
  1139. < WINSCNF_MIN_VALID_RPL_INTVL)
  1140. {
  1141. paCnfRecs->TimeInterval =
  1142. WINSCNF_MIN_VALID_RPL_INTVL;
  1143. }
  1144. if (
  1145. (DWORD)paCnfRecs->TimeInterval >
  1146. pWinsCnf->MaxRplTimeInterval
  1147. )
  1148. {
  1149. pWinsCnf->MaxRplTimeInterval =
  1150. paCnfRecs->TimeInterval;
  1151. }
  1152. }
  1153. //
  1154. // Read in the precedence level. This can currently
  1155. // be either HIGH (> 0) or LOW (0).
  1156. //
  1157. Sz = sizeof(paCnfRecs->MemberPrec);
  1158. RetVal = RegQueryValueEx(
  1159. SubKey,
  1160. WINSCNF_MEMBER_PREC_NM,
  1161. NULL, //reserved; must be NULL
  1162. &ValTyp,
  1163. (LPBYTE)&paCnfRecs->MemberPrec,
  1164. &Sz
  1165. );
  1166. if (RetVal != ERROR_SUCCESS)
  1167. {
  1168. paCnfRecs->MemberPrec = WINSCNF_LOW_PREC;
  1169. }
  1170. else
  1171. {
  1172. paCnfRecs->MemberPrec =
  1173. (paCnfRecs->MemberPrec > 0) ?
  1174. WINSCNF_HIGH_PREC : WINSCNF_LOW_PREC;
  1175. }
  1176. #if PRSCONN
  1177. QUERY_VALUE_M(
  1178. SubKey,
  1179. WINSCNF_PRS_CONN_NM,
  1180. ValTyp,
  1181. paCnfRecs->fPrsConn,
  1182. 0,
  1183. pWinsCnf->fPrsConn
  1184. );
  1185. #endif
  1186. }
  1187. else // it is a PUSH record
  1188. {
  1189. //
  1190. // Currently, we don't support periodic
  1191. // or specific time replication for Push
  1192. // records
  1193. //
  1194. paCnfRecs->fSpTime = FALSE;
  1195. #if PRSCONN
  1196. QUERY_VALUE_M(
  1197. SubKey,
  1198. WINSCNF_PRS_CONN_NM,
  1199. ValTyp,
  1200. paCnfRecs->fPrsConn,
  1201. 0,
  1202. pWinsCnf->fPrsConn
  1203. );
  1204. #endif
  1205. Sz = sizeof(paCnfRecs->UpdateCount);
  1206. RetVal = RegQueryValueEx(
  1207. SubKey,
  1208. WINSCNF_UPDATE_COUNT_NM,
  1209. NULL,
  1210. &ValTyp,
  1211. (LPBYTE)&paCnfRecs->UpdateCount,
  1212. &Sz
  1213. );
  1214. if (RetVal != ERROR_SUCCESS)
  1215. {
  1216. paCnfRecs->UpdateCount =
  1217. RPL_INVALID_METRIC;
  1218. }
  1219. else
  1220. {
  1221. paCnfRecs->LastVersNo.QuadPart = 0;
  1222. #if PRSCONN
  1223. if (!paCnfRecs->fPrsConn && !sfNoLimitChk)
  1224. #else
  1225. if (!sfNoLimitChk)
  1226. #endif
  1227. {
  1228. if (paCnfRecs->UpdateCount <
  1229. WINSCNF_MIN_VALID_UPDATE_CNT)
  1230. {
  1231. paCnfRecs->UpdateCount =
  1232. WINSCNF_MIN_VALID_UPDATE_CNT;
  1233. }
  1234. }
  1235. else
  1236. {
  1237. if (paCnfRecs->UpdateCount == 0)
  1238. {
  1239. paCnfRecs->UpdateCount = 1;
  1240. }
  1241. }
  1242. pWinsCnf->PushInfo.NoPushRecsWValUpdCnt++;
  1243. }
  1244. }
  1245. #if MCAST > 0
  1246. Sz = sizeof(paCnfRecs->fSelfFnd);
  1247. RetVal = RegQueryValueEx(
  1248. SubKey,
  1249. WINSCNF_SELF_FND_NM,
  1250. NULL,
  1251. &ValTyp,
  1252. (LPBYTE)&paCnfRecs->fSelfFnd,
  1253. &Sz
  1254. );
  1255. if (RetVal != ERROR_SUCCESS)
  1256. {
  1257. paCnfRecs->fSelfFnd = FALSE;
  1258. }
  1259. #endif
  1260. Sz = sizeof(paCnfRecs->fOnlyDynRecs);
  1261. RetVal = RegQueryValueEx(
  1262. SubKey,
  1263. WINSCNF_ONLY_DYN_RECS_NM,
  1264. NULL,
  1265. &ValTyp,
  1266. (LPBYTE)&paCnfRecs->fOnlyDynRecs,
  1267. &Sz
  1268. );
  1269. if (RetVal != ERROR_SUCCESS)
  1270. {
  1271. paCnfRecs->fOnlyDynRecs = FALSE;
  1272. }
  1273. QUERY_VALUE_M(
  1274. SubKey,
  1275. WINSCNF_RPL_TYPE_NM,
  1276. ValTyp,
  1277. paCnfRecs->RplType,
  1278. 0,
  1279. pWinsCnf->RplType
  1280. );
  1281. if (paCnfRecs->RplType != 0)
  1282. {
  1283. WINSEVT_LOG_INFO_M(paCnfRecs->WinsAdd.Add.IPAdd, WINS_EVT_PARTIAL_RPL_TYPE);
  1284. }
  1285. #if PRSCONN
  1286. if (paCnfRecs->fPrsConn != 0)
  1287. {
  1288. paCnfRecs->fPrsConn = TRUE;
  1289. }
  1290. #endif
  1291. REG_M(
  1292. RegCloseKey(SubKey),
  1293. WINS_EVT_CANT_CLOSE_KEY,
  1294. WINS_EXC_CANT_CLOSE_KEY
  1295. );
  1296. //
  1297. // Initialize the retry count to 0 and the fLinked flag
  1298. // to FALSE
  1299. //
  1300. //used when pulling
  1301. //
  1302. paCnfRecs->RetryCount = 0;
  1303. paCnfRecs->fLinked = FALSE;
  1304. //
  1305. // Initialize the following to 0 so that once we stop
  1306. // communicating with a WINS we can start again when
  1307. // the following count reaches
  1308. // WINSCNF_RETRY_AFTER_THIS_MANY_RPL
  1309. //
  1310. paCnfRecs->RetryAfterThisManyRpl = 0;
  1311. #if PRSCONN
  1312. ECOMM_INIT_DLG_HDL_M(&paCnfRecs->PrsDlgHdl);
  1313. paCnfRecs->LastCommTime = 0;
  1314. #endif
  1315. //
  1316. // Initialize LastCommFailTime to 0. Used by
  1317. // SndPushNtf in rplpull.c
  1318. //
  1319. paCnfRecs->LastCommFailTime = 0;
  1320. paCnfRecs->PushNtfTries = 0;
  1321. //
  1322. // Link the record with other PULL records with the same
  1323. // Time Interval
  1324. //
  1325. LnkWSameMetricValRecs(pWinsCnf, paCnfRecs);
  1326. //
  1327. // Mark the record as permanent (i.e. it will stay
  1328. // around until a reconfiguration or until the process
  1329. // terminates
  1330. //
  1331. paCnfRecs->fTemp = FALSE;
  1332. NoOfPnrs++;
  1333. paCnfRecs = (PRPL_CONFIG_REC_T)(
  1334. (LPBYTE)paCnfRecs +
  1335. RPL_CONFIG_REC_SIZE);
  1336. } // end of for {..} for looping over subkeys of PULL
  1337. //
  1338. // GetReplicasNew expects the list to be terminated with a
  1339. // record with INADDR_NONE as the address
  1340. //
  1341. paCnfRecs->WinsAdd.Add.IPAdd = INADDR_NONE;
  1342. if (RRType_e == RPL_E_PULL)
  1343. {
  1344. pWinsCnf->PullInfo.NoOfPushPnrs = NoOfPnrs;
  1345. pWinsCnf->PullInfo.InitTimeRpl = InitTime;
  1346. pWinsCnf->PullInfo.RplType = RplType;
  1347. }
  1348. else
  1349. {
  1350. pWinsCnf->PushInfo.NoOfPullPnrs = NoOfPnrs;
  1351. pWinsCnf->PushInfo.InitTimePush = InitTime;
  1352. pWinsCnf->PushInfo.RplType = RplType;
  1353. //
  1354. // Now that we are done with the Push record list,
  1355. //let us sort it on the update count field
  1356. //
  1357. //
  1358. // Sort the array in increasing order of Update Counts
  1359. //
  1360. FUTURES("May use qsort to optimize the update notification process")
  1361. CHECK("Not sure yet whether sorting would optimize it")
  1362. #if 0
  1363. CHECK("this is resulting in compilation warnings. haven't figured out")
  1364. CHECK("yet why.")
  1365. qsort(
  1366. pWinsCnf->pPushCnfRecs, //start of array
  1367. (size_t)pWinsCnf->NoOfPullPnrs,//no of elements
  1368. RPL_CONFIG_REC_SIZE, //size of each
  1369. //element
  1370. CompUpdCnt //compare func
  1371. );
  1372. #endif
  1373. } //end of else (It is PULL key)
  1374. } // end of else (NoOfPnrs == 0)
  1375. /*
  1376. * Close the key
  1377. */
  1378. REG_M(
  1379. RegCloseKey(CnfKey),
  1380. WINS_EVT_CANT_CLOSE_KEY,
  1381. WINS_EXC_CANT_CLOSE_KEY
  1382. );
  1383. } //end of else (key could not be opened)
  1384. #if 0
  1385. #ifdef WINSDBG
  1386. PrintRecs(RRType_e, pWinsCnf);
  1387. #endif
  1388. #endif
  1389. return;
  1390. } // GetPnrInfo
  1391. VOID
  1392. GetOwnerList(
  1393. PWINSCNF_CNF_T pWinsCnf
  1394. )
  1395. /*++
  1396. Routine Description:
  1397. This function reads the list of owners whose records should be or should not be pulled
  1398. from a partner WINS.
  1399. Arguments:
  1400. Externals Used:
  1401. None
  1402. Return Value:
  1403. Success status codes --
  1404. Error status codes --
  1405. Error Handling:
  1406. Called by:
  1407. Side Effects:
  1408. Comments:
  1409. None
  1410. --*/
  1411. {
  1412. LONG RetVal;
  1413. DWORD dwValType; // type of the reg value
  1414. LPSTR pValName; // pointer to the reg
  1415. LPBYTE pValData; // pointer to the reg value's data
  1416. DWORD dwValDataLen; // length of the reg value's data
  1417. DBGENTER("GetOwnerList\n");
  1418. // query for the type of persona (grata (1) / non-grata (0))
  1419. pWinsCnf->fPersonaGrata = 0;
  1420. dwValDataLen = sizeof(DWORD);
  1421. RetVal = RegQueryValueExA(
  1422. sPartnersKey, // reg key [HKLM\System\CCS\Services\Wins\Partners]
  1423. WINSCNF_PERSONA_MODE_NM, // name of the value: "PersonaType"
  1424. NULL, // reserved; must be NULL
  1425. &dwValType, // type of the value: should get REG_DWORD
  1426. (LPVOID)&(pWinsCnf->fPersonaGrata), // value data
  1427. &dwValDataLen); // size of the value's data
  1428. // if this call didn't succeed, we go on with the default which is 0, 'non-grata'
  1429. // get the actual entry we're going to pick the list of addresses from
  1430. pValName = pWinsCnf->fPersonaGrata ?
  1431. WINSCNF_PERSONA_GRATA_NM :
  1432. WINSCNF_PERSONA_NON_GRATA_NM;
  1433. // get the size of the data from the registry
  1434. // since Sz is 0, if there are any personas
  1435. // grata/non-grata then we should get ERROR_MORE_DATA
  1436. // if we get a different error than just remove the current list
  1437. dwValDataLen = 0;
  1438. RetVal = RegQueryValueExA(
  1439. sPartnersKey, // reg key [HKLM\System\CCS\Services\Wins\Partners]
  1440. pValName, // name of the value: "PersonaList"
  1441. NULL, // reserved; must be NULL
  1442. &dwValType, // type of the value: should get REG_MULTI_SZ
  1443. (LPVOID)&pValData, // dummy address
  1444. &dwValDataLen); // initially 0 since we try to determine the actual size
  1445. // this call should return ERROR_MORE_DATA for a REG_MULTI_SZ value
  1446. // clear-up the old buffer
  1447. if (pWinsCnf->pPersonaList != NULL)
  1448. {
  1449. WinsMscDealloc(pWinsCnf->pPersonaList);
  1450. }
  1451. pWinsCnf->NoOfPersona = 0;
  1452. pWinsCnf->pPersonaList = NULL;
  1453. // check if there is a valid value, with the expected type; return if not
  1454. if (RetVal != ERROR_MORE_DATA || dwValType != REG_MULTI_SZ)
  1455. {
  1456. DBGLEAVE("GetOwnerList\n");
  1457. return;
  1458. }
  1459. // allocate the needed buffer
  1460. WinsMscAlloc(dwValDataLen, &pValData);
  1461. // now query for the data value with a buffer large enough
  1462. RetVal = RegQueryValueExA(
  1463. sPartnersKey,
  1464. pValName,
  1465. NULL, // reserved; must be NULL
  1466. &dwValType,
  1467. (LPVOID)pValData, // now this is the real address
  1468. &dwValDataLen);
  1469. // ERROR_SUCCESS is expected here
  1470. if (RetVal == ERROR_SUCCESS)
  1471. {
  1472. LPBYTE pString = pValData;
  1473. // count in nAddr the number of addresses in the string
  1474. for( pWinsCnf->NoOfPersona=0; *pString; pWinsCnf->NoOfPersona++)
  1475. pString+= strlen(pString)+1;
  1476. // see if there are any addresses there
  1477. if (pWinsCnf->NoOfPersona > 0)
  1478. {
  1479. COMM_IP_ADD_T IpAdd;
  1480. // allocate an array of nAddr COMM_ADD_T structures
  1481. WinsMscAlloc(
  1482. (pWinsCnf->NoOfPersona) * sizeof(COMM_ADD_T),
  1483. &(pWinsCnf->pPersonaList));
  1484. // loop through the string of addresses and convert
  1485. // them to COMM_IP_ADD_T structures
  1486. for (pString = pValData, pWinsCnf->NoOfPersona = 0;
  1487. *pString;
  1488. pString += strlen(pString) + 1)
  1489. {
  1490. if ((IpAdd = inet_addr(pString)) != -1)
  1491. {
  1492. // initialize a COMM_ADD_T structure only if the string token is
  1493. // indeed an IP address
  1494. (pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].AddTyp_e = COMM_ADD_E_TCPUDPIP;
  1495. (pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].AddLen = COMM_IP_ADD_SIZE;
  1496. (pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].Add.IPAdd = ntohl(IpAdd);
  1497. DBGPRINT2(
  1498. DET,
  1499. "GetOwnerList: Address[%d] = %x\n",
  1500. pWinsCnf->NoOfPersona,
  1501. (pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].Add.IPAdd);
  1502. pWinsCnf->NoOfPersona++;
  1503. } //end 'if valid ip address'
  1504. } //end 'for each token in the string'
  1505. // if there are at least two addresses in the list,
  1506. // sort them in ascending order
  1507. if (pWinsCnf->NoOfPersona > 1)
  1508. {
  1509. qsort(pWinsCnf->pPersonaList,
  1510. (size_t)pWinsCnf->NoOfPersona,
  1511. sizeof(COMM_ADD_T),
  1512. ECommCompareAdd);
  1513. }
  1514. else
  1515. {
  1516. DBGPRINT0(DET, "GetOwnerList: No valid address found\n");
  1517. } //end 'if there are more than two addresses picked up'
  1518. } //end 'if there are any tokens at all'
  1519. } //end 'if string could be read successfully from the registry'
  1520. // the string buffer is no longer needed here
  1521. WinsMscDealloc(pValData);
  1522. #ifdef WINSDBG
  1523. {
  1524. DWORD tstNAddrs;
  1525. PCOMM_ADD_T tstPAddrs;
  1526. DWORD i;
  1527. DBGPRINT1(
  1528. DET,
  1529. "GetOwnerList: Persona %sGrata List:\n",
  1530. pWinsCnf->fPersonaGrata ? "" : "Non-");
  1531. tstNAddrs = pWinsCnf->NoOfPersona;
  1532. tstPAddrs = pWinsCnf->pPersonaList;
  1533. for (i = 0; i < tstNAddrs; i++)
  1534. {
  1535. DBGPRINT2(
  1536. DET,
  1537. "GetOwnerList:PersonaList[%d] = %08x\n",
  1538. i,
  1539. tstPAddrs[i].Add.IPAdd);
  1540. }
  1541. }
  1542. #endif
  1543. DBGLEAVE("GetOwnerList\n");
  1544. return;
  1545. }
  1546. LONG
  1547. ReadClusterIp(
  1548. HKEY KeyHandle,
  1549. DWORD *IpAddress
  1550. )
  1551. {
  1552. DWORD Sz;
  1553. LONG RetVal;
  1554. DWORD ValTyp;
  1555. TCHAR DirPath[WINS_MAX_FILENAME_SZ];
  1556. *IpAddress = 0;
  1557. // Read the wins cluster name
  1558. Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
  1559. RetVal = RegQueryValueEx(
  1560. KeyHandle,
  1561. WINSCNF_CLUSTER_RESOURCE_NM,
  1562. NULL, //reserved; must be NULL
  1563. &ValTyp,
  1564. (LPBYTE)DirPath,
  1565. &Sz
  1566. );
  1567. if ((RetVal == ERROR_SUCCESS) && (DirPath[0] != (TCHAR)EOS))
  1568. {
  1569. HCLUSTER hCluster;
  1570. HRESOURCE hResource;
  1571. CHAR IpAddressStr[sizeof ("xxx.xxx.xxx.xxx")];
  1572. WCHAR IpAddressWStr[sizeof ("xxx.xxx.xxx.xxx")];
  1573. DWORD i;
  1574. HMODULE Dll1, Dll2;
  1575. #define FUNC_TBL_ENTRY( _Dll, _Name ) { _Dll, &(#_Name)[1], NULL }
  1576. #define CALL_FUNC( _Func) (PVOID)( *FuncTbl[_Func].FuncHdl )
  1577. enum {
  1578. _OpenCluster,
  1579. _OpenClusterResource,
  1580. _CloseCluster,
  1581. _CloseClusterResource,
  1582. _ResUtilGetResourceDependentIPAddressProps
  1583. };
  1584. struct {
  1585. HMODULE *Dll;
  1586. LPCSTR FuncName;
  1587. FARPROC FuncHdl;
  1588. } FuncTbl[] = {
  1589. FUNC_TBL_ENTRY( &Dll1,_OpenCluster),
  1590. FUNC_TBL_ENTRY( &Dll1,_OpenClusterResource),
  1591. FUNC_TBL_ENTRY( &Dll1,_CloseCluster),
  1592. FUNC_TBL_ENTRY( &Dll1,_CloseClusterResource),
  1593. FUNC_TBL_ENTRY( &Dll2,_ResUtilGetResourceDependentIPAddressProps)
  1594. };
  1595. DBGPRINT1(DET, "WinsCnfReadWinsInfo: ClusterResourceName is (%ws)\n", DirPath);
  1596. hCluster = NULL;
  1597. hResource = NULL;
  1598. Dll1 = Dll2 = NULL;
  1599. do {
  1600. Dll1 = LoadLibrary(TEXT("clusapi.dll"));
  1601. if (!Dll1) {
  1602. RetVal = GetLastError();
  1603. break;
  1604. }
  1605. Dll2 = LoadLibrary(TEXT("resutils.dll"));
  1606. if (!Dll2) {
  1607. RetVal = GetLastError();
  1608. break;
  1609. }
  1610. for (i=0; i<(sizeof(FuncTbl)/sizeof(FuncTbl[0])); i++) {
  1611. FuncTbl[i].FuncHdl = GetProcAddress(*FuncTbl[i].Dll, FuncTbl[i].FuncName);
  1612. if (!FuncTbl[i].FuncHdl) {
  1613. RetVal = GetLastError();
  1614. break;
  1615. }
  1616. }
  1617. if (i<(sizeof(FuncTbl)/sizeof(FuncTbl[0]))) {
  1618. break;
  1619. }
  1620. hCluster = CALL_FUNC(_OpenCluster)( NULL );
  1621. if (!hCluster) {
  1622. RetVal = GetLastError();
  1623. break;
  1624. }
  1625. hResource = CALL_FUNC(_OpenClusterResource)(hCluster, DirPath);
  1626. if (!hResource) {
  1627. RetVal = GetLastError();
  1628. break;
  1629. }
  1630. Sz = sizeof (IpAddressWStr);
  1631. RetVal = PtrToLong(CALL_FUNC(_ResUtilGetResourceDependentIPAddressProps)(
  1632. hResource,
  1633. IpAddressWStr,
  1634. &Sz,
  1635. NULL,
  1636. NULL,
  1637. NULL,
  1638. NULL
  1639. ));
  1640. if (ERROR_SUCCESS != RetVal) {
  1641. break;
  1642. }
  1643. WinsMscConvertUnicodeStringToAscii((LPBYTE)IpAddressWStr, IpAddressStr, sizeof(IpAddressStr));
  1644. *IpAddress = ntohl(inet_addr(IpAddressStr));
  1645. DBGPRINT1(DET, "ReadClusterIp: Cluster IpAddress is (%lx)\n", *IpAddress);
  1646. } while ( FALSE );
  1647. if( hResource ) CALL_FUNC(_CloseClusterResource)(hResource);
  1648. if( hCluster ) CALL_FUNC(_CloseCluster) (hCluster);
  1649. if ( Dll1 ) FreeLibrary(Dll1);
  1650. if ( Dll2 ) FreeLibrary(Dll2);
  1651. }
  1652. return RetVal;
  1653. }
  1654. extern DOM_CACHE_T sDomCache;
  1655. VOID
  1656. WinsCnfReadWinsInfo(
  1657. PWINSCNF_CNF_T pWinsCnf
  1658. )
  1659. /*++
  1660. Routine Description:
  1661. This function reads information (excluding subkeys) about
  1662. the local WINS
  1663. Arguments:
  1664. None
  1665. Externals Used:
  1666. sConfigRoot,
  1667. Return Value:
  1668. None
  1669. Error Handling:
  1670. Called by:
  1671. WinsCnfInitConfig
  1672. Side Effects:
  1673. Comments:
  1674. None
  1675. --*/
  1676. {
  1677. DWORD Sz;
  1678. LONG RetVal;
  1679. DWORD ValTyp;
  1680. VERS_NO_T MaxVersNo;
  1681. WINSEVT_STRS_T EvtStr;
  1682. TCHAR DirPath[WINS_MAX_FILENAME_SZ];
  1683. TCHAR Path2[WINS_MAX_FILENAME_SZ];
  1684. LPTSTR pHoldFileName;
  1685. DWORD fUse351Db;
  1686. DWORD fUse4Db;
  1687. EvtStr.NoOfStrs = 1;
  1688. try {
  1689. #if defined(DBGSVC) && !defined(WINS_INTERACTIVE)
  1690. //
  1691. // Read the value of WinsDbg. Though this value is
  1692. // being used concurrently by multiple threads (at reinit time), we
  1693. // don't enter any critical section here. This value
  1694. // is used only for debugging
  1695. //
  1696. WinsCnfReadWinsDbgFlagValue();
  1697. #endif
  1698. Sz = sizeof(pWinsCnf->LogDetailedEvts);
  1699. (VOID)RegQueryValueEx(
  1700. sParametersKey,
  1701. WINSCNF_LOG_DETAILED_EVTS_NM,
  1702. NULL, //reserved; must be NULL
  1703. &ValTyp,
  1704. (LPBYTE)&pWinsCnf->LogDetailedEvts,
  1705. &Sz
  1706. );
  1707. // Read in the 1B filter. If the "Filter1BRequests" is there and it is a REG_MULTI_SZ
  1708. // then the filter is created for each of the names specified there. When R_WinsGetBrowserNames
  1709. // is called, the database is filtered only for the name present in the filter.
  1710. RetVal = RegQueryValueExW(
  1711. sParametersKey,
  1712. WINSCNF_FILTER1BREQUESTS_NM,
  1713. NULL,
  1714. &ValTyp,
  1715. NULL,
  1716. &Sz);
  1717. if (RetVal == ERROR_SUCCESS && ValTyp == REG_MULTI_SZ)
  1718. {
  1719. LPWSTR str1BFilters = NULL;
  1720. LPWSTR p1BFilter;
  1721. WinsMscAlloc(Sz, &str1BFilters);
  1722. if (RegQueryValueExW(
  1723. sParametersKey,
  1724. WINSCNF_FILTER1BREQUESTS_NM,
  1725. NULL,
  1726. &ValTyp,
  1727. (LPBYTE)str1BFilters,
  1728. &Sz) == ERROR_SUCCESS)
  1729. {
  1730. EnterCriticalSection(&g_cs1BFilter);
  1731. try
  1732. {
  1733. g_p1BFilter = InitNmFilter(g_p1BFilter);
  1734. p1BFilter = str1BFilters;
  1735. do
  1736. {
  1737. DWORD nLenFilter = wcslen(p1BFilter);
  1738. CHAR strOemName[17];
  1739. OEM_STRING oemString;
  1740. UNICODE_STRING unicodeString;
  1741. if (nLenFilter == 0)
  1742. break;
  1743. memset(strOemName, ' ', 16);
  1744. strOemName[16]=0;
  1745. if (nLenFilter > 15)
  1746. p1BFilter[16]=L'\0';
  1747. RtlInitUnicodeString(&unicodeString, p1BFilter);
  1748. RtlInitString(&oemString, strOemName);
  1749. RtlUpcaseUnicodeStringToOemString(&oemString, &unicodeString, FALSE);
  1750. strOemName[strlen(strOemName)] = ' ';
  1751. strOemName[15] = strOemName[0];
  1752. strOemName[0] = 0x1B;
  1753. InsertNmInFilter(g_p1BFilter, strOemName, 16);
  1754. p1BFilter += nLenFilter+1;
  1755. }
  1756. while(TRUE);
  1757. }
  1758. finally
  1759. {
  1760. LeaveCriticalSection(&g_cs1BFilter);
  1761. }
  1762. }
  1763. WinsMscDealloc(str1BFilters);
  1764. }
  1765. else
  1766. {
  1767. // if the reg key is not there, reset the filter - all names will be returned.
  1768. EnterCriticalSection(&g_cs1BFilter);
  1769. try
  1770. {
  1771. g_p1BFilter = DestroyNmFilter(g_p1BFilter);
  1772. }
  1773. finally
  1774. {
  1775. g_p1BFilter = NULL;
  1776. LeaveCriticalSection(&g_cs1BFilter);
  1777. }
  1778. }
  1779. sDomCache.bRefresh = TRUE;
  1780. //
  1781. // Read in the fAdd1Bto1CQueries parameter. Default is TRUE
  1782. // meaning: when processing name queries for 1C names, prepend the
  1783. // response with the 1B name (browser name).
  1784. //
  1785. pWinsCnf->fAdd1Bto1CQueries = TRUE;
  1786. Sz = sizeof(pWinsCnf->fAdd1Bto1CQueries);
  1787. (VOID)RegQueryValueEx(
  1788. sParametersKey,
  1789. WINSCNF_ADD1BTO1CQUERIES_NM,
  1790. NULL,
  1791. &ValTyp,
  1792. (LPBYTE)&pWinsCnf->fAdd1Bto1CQueries,
  1793. &Sz
  1794. );
  1795. //
  1796. // Read in the cap value on the number of worker threads.
  1797. //
  1798. QUERY_VALUE_M(
  1799. sParametersKey,
  1800. WINSCNF_MAX_NO_WRK_THDS_NM,
  1801. ValTyp,
  1802. pWinsCnf->MaxNoOfWrkThds,
  1803. 0,
  1804. 0 //WINSTHD_DEF_NO_NBT_THDS
  1805. );
  1806. //
  1807. // Check if the user needs to override our checks.
  1808. //
  1809. sfNoLimitChk = pWinsCnf->MaxNoOfWrkThds & NO_LIMIT_CHK_FLAG;
  1810. if (sfNoLimitChk)
  1811. {
  1812. WINSEVT_LOG_M(pWinsCnf->LogDetailedEvts, WINS_EVT_INTERNAL_FEATURE);
  1813. pWinsCnf->MaxNoOfWrkThds &= ~NO_LIMIT_CHK_FLAG;
  1814. }
  1815. if (pWinsCnf->MaxNoOfWrkThds > WINSTHD_MAX_NO_NBT_THDS)
  1816. {
  1817. pWinsCnf->MaxNoOfWrkThds = WINSTHD_MAX_NO_NBT_THDS;
  1818. }
  1819. if (pWinsCnf->MaxNoOfWrkThds < WINSTHD_MIN_NO_NBT_THDS)
  1820. {
  1821. pWinsCnf->MaxNoOfWrkThds = WINSTHD_MIN_NO_NBT_THDS;
  1822. }
  1823. #if 0
  1824. if (WinsCnf.State_e == WINSCNF_E_INITING)
  1825. {
  1826. ReadSpecGrpMasks(pWinsCnf);
  1827. }
  1828. #endif
  1829. #if DYNLOADJET
  1830. //
  1831. // Read in the cap value on the number of worker threads.
  1832. //
  1833. QUERY_VALUE_M(
  1834. sParametersKey,
  1835. WINSCNF_USE_351DB_NM,
  1836. ValTyp,
  1837. fUse351Db,
  1838. 0,
  1839. 0 //Use 500 db
  1840. );
  1841. //
  1842. // If set to a non-zero value, we need to load jet.dll
  1843. //
  1844. if (fUse351Db)
  1845. {
  1846. DynLoadJetVersion = DYN_LOAD_JET_200;
  1847. } else {
  1848. QUERY_VALUE_M(
  1849. sParametersKey,
  1850. WINSCNF_USE_4DB_NM,
  1851. ValTyp,
  1852. fUse4Db,
  1853. 0,
  1854. 0 //Use 500 db
  1855. );
  1856. //
  1857. // If set to a non-zero value, we need to load jet.dll
  1858. //
  1859. if (fUse4Db)
  1860. {
  1861. DynLoadJetVersion = DYN_LOAD_JET_500;
  1862. }
  1863. }
  1864. #endif
  1865. //
  1866. // Read in the refresh Interval
  1867. //
  1868. Sz = sizeof(pWinsCnf->RefreshInterval);
  1869. RetVal = RegQueryValueEx(
  1870. sParametersKey,
  1871. WINSCNF_REFRESH_INTVL_NM,
  1872. NULL, //reserved; must be NULL
  1873. &ValTyp,
  1874. (LPBYTE)&pWinsCnf->RefreshInterval,
  1875. &Sz
  1876. );
  1877. if (RetVal != ERROR_SUCCESS)
  1878. {
  1879. WINSEVT_LOG_INFO_D_M(
  1880. WINS_SUCCESS,
  1881. WINS_EVT_CANT_GET_REFRESH_INTERVAL_VAL
  1882. );
  1883. pWinsCnf->RefreshInterval = WINSCNF_DEF_REFRESH_INTERVAL;
  1884. }
  1885. else
  1886. {
  1887. if (!sfNoLimitChk)
  1888. {
  1889. if (pWinsCnf->RefreshInterval <
  1890. WINSCNF_MIN_REFRESH_INTERVAL)
  1891. {
  1892. pWinsCnf->RefreshInterval = WINSCNF_MIN_REFRESH_INTERVAL;
  1893. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  1894. NULL, __LINE__, "ud",
  1895. WINSCNF_REFRESH_INTVL_NM,
  1896. pWinsCnf->RefreshInterval);
  1897. }
  1898. }
  1899. else
  1900. {
  1901. if (pWinsCnf->RefreshInterval < 60)
  1902. {
  1903. pWinsCnf->RefreshInterval = 60;
  1904. }
  1905. }
  1906. }
  1907. //
  1908. // Read in the Initial Challenge Retry Interval
  1909. //
  1910. Sz = sizeof(pWinsCnf->RetryInterval);
  1911. RetVal = RegQueryValueEx(
  1912. sParametersKey,
  1913. WINSCNF_INIT_CHL_RETRY_INTVL_NM,
  1914. NULL, //reserved; must be NULL
  1915. &ValTyp,
  1916. (LPBYTE)&pWinsCnf->RetryInterval,
  1917. &Sz
  1918. );
  1919. if (RetVal != ERROR_SUCCESS)
  1920. {
  1921. WINSEVT_LOG_INFO_D_M(
  1922. WINS_SUCCESS,
  1923. WINS_EVT_CANT_GET_INIT_CHL_RETRY_INTVL_VAL
  1924. );
  1925. pWinsCnf->RetryInterval = WINSCNF_DEF_INIT_CHL_RETRY_INTVL;
  1926. }
  1927. else
  1928. {
  1929. if (!sfNoLimitChk)
  1930. {
  1931. if (pWinsCnf->RetryInterval <
  1932. WINSCNF_MIN_INIT_CHL_RETRY_INTVL)
  1933. {
  1934. pWinsCnf->RetryInterval = WINSCNF_MIN_INIT_CHL_RETRY_INTVL;
  1935. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  1936. NULL, __LINE__, "ud",
  1937. WINSCNF_INIT_CHL_RETRY_INTVL_NM,
  1938. pWinsCnf->RetryInterval);
  1939. }
  1940. }
  1941. else
  1942. {
  1943. if (pWinsCnf->RetryInterval < WINSCNF_MIN_INIT_CHL_RETRY_INTVL)
  1944. {
  1945. pWinsCnf->RetryInterval = WINSCNF_MIN_INIT_CHL_RETRY_INTVL;
  1946. }
  1947. }
  1948. }
  1949. //
  1950. // Read in the Initial Challenge Max. No. of Retries
  1951. //
  1952. Sz = sizeof(pWinsCnf->MaxNoOfRetries);
  1953. RetVal = RegQueryValueEx(
  1954. sParametersKey,
  1955. WINSCNF_CHL_MAX_RETRIES_NM,
  1956. NULL, //reserved; must be NULL
  1957. &ValTyp,
  1958. (LPBYTE)&pWinsCnf->MaxNoOfRetries,
  1959. &Sz
  1960. );
  1961. if (RetVal != ERROR_SUCCESS)
  1962. {
  1963. WINSEVT_LOG_INFO_D_M(
  1964. WINS_SUCCESS,
  1965. WINS_EVT_CANT_GET_CHL_MAX_RETRIES_VAL
  1966. );
  1967. pWinsCnf->MaxNoOfRetries = WINSCNF_DEF_CHL_MAX_RETRIES;
  1968. }
  1969. else
  1970. {
  1971. if (!sfNoLimitChk)
  1972. {
  1973. if (pWinsCnf->MaxNoOfRetries <
  1974. WINSCNF_MIN_CHL_MAX_RETRIES)
  1975. {
  1976. pWinsCnf->MaxNoOfRetries = WINSCNF_MIN_CHL_MAX_RETRIES;
  1977. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  1978. NULL, __LINE__, "ud",
  1979. WINSCNF_CHL_MAX_RETRIES_NM,
  1980. pWinsCnf->MaxNoOfRetries);
  1981. }
  1982. }
  1983. else
  1984. {
  1985. if (pWinsCnf->MaxNoOfRetries < WINSCNF_MIN_CHL_MAX_RETRIES)
  1986. {
  1987. pWinsCnf->MaxNoOfRetries = WINSCNF_MIN_CHL_MAX_RETRIES;
  1988. }
  1989. }
  1990. }
  1991. //
  1992. // Read in the tombstone Interval
  1993. //
  1994. Sz = sizeof(pWinsCnf->TombstoneInterval);
  1995. RetVal = RegQueryValueEx(
  1996. sParametersKey,
  1997. WINSCNF_TOMBSTONE_INTVL_NM,
  1998. NULL, //reserved; must be NULL
  1999. &ValTyp,
  2000. (LPBYTE)&pWinsCnf->TombstoneInterval,
  2001. &Sz
  2002. );
  2003. if (RetVal != ERROR_SUCCESS)
  2004. {
  2005. WINSEVT_LOG_INFO_D_M(
  2006. WINS_SUCCESS,
  2007. WINS_EVT_CANT_GET_TOMBSTONE_INTERVAL_VAL
  2008. );
  2009. pWinsCnf->TombstoneInterval =
  2010. WINSCNF_MAKE_TOMB_INTVL_0_M(pWinsCnf->RefreshInterval);
  2011. }
  2012. else
  2013. {
  2014. if ( !sfNoLimitChk)
  2015. {
  2016. if (pWinsCnf->TombstoneInterval <
  2017. WINSCNF_MAKE_TOMB_INTVL_0_M(pWinsCnf->RefreshInterval) )
  2018. {
  2019. pWinsCnf->TombstoneInterval =
  2020. WINSCNF_MAKE_TOMB_INTVL_0_M(pWinsCnf->RefreshInterval);
  2021. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  2022. NULL, __LINE__, "ud",
  2023. WINSCNF_TOMBSTONE_INTVL_NM,
  2024. pWinsCnf->TombstoneInterval);
  2025. }
  2026. }
  2027. else
  2028. {
  2029. if (pWinsCnf->TombstoneInterval < 60)
  2030. {
  2031. pWinsCnf->TombstoneInterval = 60;
  2032. }
  2033. }
  2034. }
  2035. //
  2036. // Read in the tombstone timeout
  2037. //
  2038. Sz = sizeof(pWinsCnf->TombstoneTimeout);
  2039. RetVal = RegQueryValueEx(
  2040. sParametersKey,
  2041. WINSCNF_TOMBSTONE_TMOUT_NM,
  2042. NULL, //reserved; must be NULL
  2043. &ValTyp,
  2044. (LPBYTE)&pWinsCnf->TombstoneTimeout,
  2045. &Sz
  2046. );
  2047. if (RetVal != ERROR_SUCCESS)
  2048. {
  2049. WINSEVT_LOG_INFO_D_M(
  2050. WINS_SUCCESS,
  2051. WINS_EVT_CANT_GET_TOMBSTONE_TIMEOUT_VAL
  2052. );
  2053. pWinsCnf->TombstoneTimeout = pWinsCnf->RefreshInterval;
  2054. }
  2055. else
  2056. {
  2057. if (!sfNoLimitChk)
  2058. {
  2059. if (pWinsCnf->TombstoneTimeout < pWinsCnf->RefreshInterval)
  2060. {
  2061. pWinsCnf->TombstoneTimeout = pWinsCnf->RefreshInterval;
  2062. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  2063. NULL, __LINE__, "ud",
  2064. WINSCNF_TOMBSTONE_TMOUT_NM,
  2065. pWinsCnf->TombstoneTimeout);
  2066. }
  2067. }
  2068. else
  2069. {
  2070. if (pWinsCnf->TombstoneTimeout < 60)
  2071. {
  2072. pWinsCnf->TombstoneTimeout = 60;
  2073. }
  2074. }
  2075. }
  2076. //
  2077. // Read in the Verify Interval
  2078. //
  2079. Sz = sizeof(pWinsCnf->VerifyInterval);
  2080. RetVal = RegQueryValueEx(
  2081. sParametersKey,
  2082. WINSCNF_VERIFY_INTVL_NM,
  2083. NULL, //reserved; must be NULL
  2084. &ValTyp,
  2085. (LPBYTE)&pWinsCnf->VerifyInterval,
  2086. &Sz
  2087. );
  2088. if (RetVal != ERROR_SUCCESS)
  2089. {
  2090. WINSEVT_LOG_INFO_D_M(
  2091. WINS_SUCCESS,
  2092. WINS_EVT_CANT_GET_VERIFY_INTERVAL_VAL
  2093. );
  2094. pWinsCnf->VerifyInterval =
  2095. WINSCNF_MAKE_VERIFY_INTVL_M(pWinsCnf->TombstoneInterval);
  2096. }
  2097. else
  2098. {
  2099. if ( !sfNoLimitChk)
  2100. {
  2101. if (pWinsCnf->VerifyInterval <
  2102. WINSCNF_MAKE_VERIFY_INTVL_M(pWinsCnf->TombstoneInterval))
  2103. {
  2104. pWinsCnf->VerifyInterval =
  2105. WINSCNF_MAKE_VERIFY_INTVL_M(pWinsCnf->TombstoneInterval);
  2106. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  2107. NULL, __LINE__, "ud",
  2108. WINSCNF_VERIFY_INTVL_NM,
  2109. pWinsCnf->VerifyInterval);
  2110. }
  2111. }
  2112. else
  2113. {
  2114. if (pWinsCnf->VerifyInterval < 60)
  2115. {
  2116. pWinsCnf->VerifyInterval = 60;
  2117. }
  2118. }
  2119. }
  2120. ReadCCInfo(pWinsCnf);
  2121. //
  2122. // Check if the admin. wants us to do pull/push replications with
  2123. // pnrs found by self.
  2124. //
  2125. QUERY_VALUE_M(
  2126. sParametersKey,
  2127. WINSCNF_BURST_HANDLING_NM,
  2128. ValTyp,
  2129. pWinsCnf->fDoSpoofing,
  2130. 0,
  2131. TRUE
  2132. );
  2133. if (pWinsCnf->fDoSpoofing)
  2134. {
  2135. pWinsCnf->fDoSpoofing = TRUE; //for robustness
  2136. }
  2137. #if MCAST > 0
  2138. //
  2139. // Check if the admin. wants us to do pull/push replications with
  2140. // pnrs found by self.
  2141. //
  2142. QUERY_VALUE_M(
  2143. sParametersKey,
  2144. WINSCNF_USE_SELF_FND_PNRS_NM,
  2145. ValTyp,
  2146. pWinsCnf->fUseSelfFndPnrs,
  2147. 0,
  2148. FALSE
  2149. );
  2150. if (pWinsCnf->fUseSelfFndPnrs)
  2151. {
  2152. if (WinsCnf.State_e == WINSCNF_E_INITING)
  2153. {
  2154. Sz = sizeof(pWinsCnf->McastTtl);
  2155. RetVal = RegQueryValueEx(
  2156. sParametersKey,
  2157. WINSCNF_MCAST_TTL_NM,
  2158. NULL,
  2159. &ValTyp,
  2160. (LPBYTE)&pWinsCnf->McastTtl,
  2161. &Sz
  2162. );
  2163. if (RetVal != ERROR_SUCCESS)
  2164. {
  2165. pWinsCnf->McastTtl = WINSCNF_DEF_MCAST_TTL;
  2166. }
  2167. else
  2168. {
  2169. if (
  2170. (pWinsCnf->McastTtl < WINSCNF_MIN_MCAST_TTL)
  2171. ||
  2172. (pWinsCnf->McastTtl > WINSCNF_MAX_MCAST_TTL)
  2173. )
  2174. {
  2175. pWinsCnf->McastTtl = WINSCNF_DEF_MCAST_TTL;
  2176. }
  2177. }
  2178. }
  2179. Sz = sizeof(pWinsCnf->McastIntvl);
  2180. RetVal = RegQueryValueEx(
  2181. sParametersKey,
  2182. WINSCNF_MCAST_INTVL_NM,
  2183. NULL,
  2184. &ValTyp,
  2185. (LPBYTE)&pWinsCnf->McastIntvl,
  2186. &Sz
  2187. );
  2188. if (RetVal != ERROR_SUCCESS)
  2189. {
  2190. pWinsCnf->McastIntvl = WINSCNF_DEF_MCAST_INTVL;
  2191. }
  2192. else
  2193. {
  2194. if ( pWinsCnf->McastIntvl < WINSCNF_MIN_MCAST_INTVL )
  2195. {
  2196. pWinsCnf->McastIntvl = WINSCNF_MIN_MCAST_INTVL;
  2197. }
  2198. }
  2199. }
  2200. #endif
  2201. //
  2202. // Check if replication is to be done only with configured partners.
  2203. // If set to TRUE, it means that an administrator will not be allowed
  2204. // to trigger replication to/from a WINS that this WINS does not know
  2205. // about. Default value is FALSE
  2206. //
  2207. QUERY_VALUE_M(
  2208. sParametersKey,
  2209. WINSCNF_RPL_ONLY_W_CNF_PNRS_NM,
  2210. ValTyp,
  2211. pWinsCnf->fRplOnlyWCnfPnrs,
  2212. 0,
  2213. TRUE
  2214. );
  2215. //
  2216. // Robust programming (in case the registry has a value other than 1
  2217. // and later on we compare the value with TRUE)
  2218. //
  2219. if (pWinsCnf->fRplOnlyWCnfPnrs != FALSE)
  2220. {
  2221. pWinsCnf->fRplOnlyWCnfPnrs = TRUE;
  2222. }
  2223. if (WinsCnf.State_e == WINSCNF_E_INITING)
  2224. {
  2225. (VOID)WinsMscAlloc(WINS_MAX_FILENAME_SZ, &(pWinsCnf->pWinsDb));
  2226. //
  2227. // Read in the name of the database file
  2228. //
  2229. FUTURES("when jet supports UNICODE in its api, change this")
  2230. Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
  2231. RetVal = RegQueryValueEx(
  2232. sParametersKey,
  2233. WINSCNF_DB_FILE_NM,
  2234. NULL, //reserved; must be NULL
  2235. &ValTyp,
  2236. (LPBYTE)DirPath,
  2237. &Sz
  2238. );
  2239. if ((RetVal != ERROR_SUCCESS) || (DirPath[0] == (TCHAR)EOS))
  2240. {
  2241. WinsMscDealloc(pWinsCnf->pWinsDb);
  2242. pWinsCnf->pWinsDb = WINSCNF_DB_NAME_ASCII;
  2243. }
  2244. else
  2245. {
  2246. if(!WinsMscGetName(ValTyp, DirPath, Path2, WINS_MAX_FILENAME_SZ, &pHoldFileName))
  2247. {
  2248. WinsMscDealloc(pWinsCnf->pWinsDb);
  2249. pWinsCnf->pWinsDb = WINSCNF_DB_NAME_ASCII;
  2250. }
  2251. else
  2252. {
  2253. WinsMscConvertUnicodeStringToAscii((LPBYTE)pHoldFileName, pWinsCnf->pWinsDb, WINS_MAX_FILENAME_SZ);
  2254. DBGPRINT1(DET, "WinsCnfReadWinsInfo: Db file path is (%s)\n", pWinsCnf->pWinsDb);
  2255. }
  2256. }
  2257. RetVal = ReadClusterIp(
  2258. sParametersKey,
  2259. &WinsClusterIpAddress
  2260. );
  2261. if (ERROR_SUCCESS == RetVal) {
  2262. NmsLocalAdd.Add.IPAdd = WinsClusterIpAddress;
  2263. } else {
  2264. DBGPRINT1(DET, "ReadClusterIp: Returned (%ld)\n", RetVal);
  2265. }
  2266. }
  2267. //
  2268. // Read in the PriorityClassHigh value. Default is normal
  2269. //
  2270. QUERY_VALUE_M(
  2271. sParametersKey,
  2272. WINSCNF_PRIORITY_CLASS_HIGH_NM,
  2273. ValTyp,
  2274. pWinsCnf->WinsPriorityClass,
  2275. 0,
  2276. WINSINTF_E_NORMAL
  2277. );
  2278. if (pWinsCnf->WinsPriorityClass != WINSINTF_E_NORMAL)
  2279. {
  2280. if (WinsCnf.WinsPriorityClass != WINSINTF_E_HIGH)
  2281. {
  2282. WinsSetPriorityClass(WINSINTF_E_HIGH);
  2283. }
  2284. }
  2285. else
  2286. {
  2287. if (WinsCnf.WinsPriorityClass != WINSINTF_E_NORMAL)
  2288. {
  2289. WinsSetPriorityClass(WINSINTF_E_NORMAL);
  2290. }
  2291. }
  2292. if (WinsCnf.State_e == WINSCNF_E_INITING)
  2293. {
  2294. //
  2295. // Read in the InitTimeState value. Default is FALSE
  2296. //
  2297. QUERY_VALUE_M(
  2298. sParametersKey,
  2299. WINSCNF_INIT_TIME_PAUSE_NM,
  2300. ValTyp,
  2301. fWinsCnfInitStatePaused,
  2302. 0,
  2303. FALSE
  2304. );
  2305. //
  2306. // Read in the name of the recovery file
  2307. //
  2308. (VOID)WinsMscAlloc(WINS_MAX_FILENAME_SZ, &(pWinsCnf->pLogFilePath));
  2309. Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
  2310. RetVal = RegQueryValueEx(
  2311. sParametersKey,
  2312. WINSCNF_LOG_FILE_PATH_NM,
  2313. NULL, //reserved; must be NULL
  2314. &ValTyp,
  2315. (LPBYTE)DirPath,
  2316. &Sz
  2317. );
  2318. if ((RetVal != ERROR_SUCCESS) || (DirPath[0] == (TCHAR)EOS))
  2319. {
  2320. DBGPRINT1(ERR, "WinsCnfReadInfo: RetVal=(%x)\n", RetVal);
  2321. WinsMscDealloc(pWinsCnf->pLogFilePath);
  2322. pWinsCnf->pLogFilePath = DEFAULT_LOG_PATH;
  2323. }
  2324. else
  2325. {
  2326. if(!WinsMscGetName(ValTyp, DirPath, Path2, WINS_MAX_FILENAME_SZ, &pHoldFileName))
  2327. {
  2328. DBGPRINT0(ERR, "WinsCnfReadInfo:WinsMscGetName returned FALSE\n");
  2329. WinsMscDealloc(pWinsCnf->pLogFilePath);
  2330. pWinsCnf->pLogFilePath = DEFAULT_LOG_PATH;
  2331. }
  2332. else
  2333. {
  2334. DBGPRINT1(DET, "WinsCnfReadInfo:pHoldFileName=%s\n", pHoldFileName);
  2335. WinsMscConvertUnicodeStringToAscii((LPBYTE)pHoldFileName, pWinsCnf->pLogFilePath, WINS_MAX_FILENAME_SZ);
  2336. }
  2337. }
  2338. //
  2339. // Check if user wants logging to be turned on.
  2340. // In case of Q servers, the user would not wish the logging to be
  2341. // turned on
  2342. //
  2343. Sz = sizeof(pWinsCnf->fLoggingOn);
  2344. RetVal = RegQueryValueEx(
  2345. sParametersKey,
  2346. WINSCNF_LOG_FLAG_NM,
  2347. NULL, //reserved; must be NULL
  2348. &ValTyp,
  2349. (LPBYTE)&pWinsCnf->fLoggingOn,
  2350. &Sz
  2351. );
  2352. if (RetVal != ERROR_SUCCESS)
  2353. {
  2354. //
  2355. // default is to turn on logging
  2356. //
  2357. pWinsCnf->fLoggingOn = TRUE;
  2358. }
  2359. else
  2360. {
  2361. //
  2362. // If user has specified logging, get the path to the log
  2363. // file if specified by user
  2364. //
  2365. if (pWinsCnf->fLoggingOn)
  2366. {
  2367. pWinsCnf->fLoggingOn = TRUE;
  2368. }
  2369. }
  2370. }
  2371. //
  2372. // Check to see if STATIC initialization of the WINS database needs
  2373. // to be done
  2374. //
  2375. Sz = sizeof(pWinsCnf->fStaticInit);
  2376. RetVal = RegQueryValueEx(
  2377. sParametersKey,
  2378. WINSCNF_STATIC_INIT_FLAG_NM,
  2379. NULL, //reserved; must be NULL
  2380. &ValTyp,
  2381. (LPBYTE)&pWinsCnf->fStaticInit,
  2382. &Sz
  2383. );
  2384. if (RetVal != ERROR_SUCCESS)
  2385. {
  2386. pWinsCnf->fStaticInit = FALSE;
  2387. }
  2388. else
  2389. {
  2390. //
  2391. // Safe programming (just in case a maintainer of this code
  2392. // assumes a BOOL field to have just TRUE and FALSE values
  2393. //
  2394. pWinsCnf->fStaticInit = pWinsCnf->fStaticInit > 0 ? TRUE : FALSE;
  2395. }
  2396. //
  2397. // If Static Initialization needs to be done, read in the name of
  2398. // the file that contains the data.
  2399. //
  2400. if(pWinsCnf->fStaticInit)
  2401. {
  2402. WinsCnfGetNamesOfDataFiles(pWinsCnf);
  2403. }
  2404. //
  2405. // Assign MaxVersNo with the default value
  2406. //
  2407. WINS_ASSIGN_INT_TO_VERS_NO_M(MaxVersNo, 0);
  2408. //
  2409. // If the WINS server is just coming up (i.e. it is not a reinit),
  2410. // then read in the starting value of the version number counter
  2411. // if present in the registry
  2412. //
  2413. Sz = sizeof(DWORD);
  2414. (VOID)RegQueryValueEx(
  2415. sParametersKey,
  2416. WINSCNF_INIT_VERSNO_VAL_LW_NM,
  2417. NULL, //reserved; must be NULL
  2418. &ValTyp,
  2419. (LPBYTE)&MaxVersNo.LowPart,
  2420. &Sz
  2421. );
  2422. (VOID)RegQueryValueEx(
  2423. sParametersKey,
  2424. WINSCNF_INIT_VERSNO_VAL_HW_NM,
  2425. NULL, //reserved; must be NULL
  2426. &ValTyp,
  2427. (LPBYTE)&MaxVersNo.HighPart,
  2428. &Sz
  2429. );
  2430. //
  2431. // if we read in a value for the version counter
  2432. //
  2433. if (LiGtrZero(MaxVersNo) && (MaxVersNo.HighPart == 0) &&
  2434. (MaxVersNo.LowPart < MAX_START_VERS_NO))
  2435. {
  2436. //
  2437. // Use WinsCnf, not pWinsCnf since at initialization time, we always
  2438. // read into WinsCnf. At reinit, the State_e field in the WinsCnf
  2439. // structure allocated may have garbage (actually will be 0 since we
  2440. // initialize allocated memory to zero -- I might change in the
  2441. // future to improve performance)
  2442. //
  2443. if (WinsCnf.State_e == WINSCNF_E_INITING)
  2444. {
  2445. //
  2446. // Min. Vers. to start scavenging from.
  2447. //
  2448. // NOTE: if we find local records or the special record then
  2449. // NmsScvMinScvVersNo will get changed (check out GetMaxVersNos
  2450. // in nmsdb.c
  2451. //
  2452. NmsNmhMyMaxVersNo = MaxVersNo;
  2453. NmsScvMinScvVersNo = NmsNmhMyMaxVersNo;
  2454. NmsVersNoToStartFromNextTime.QuadPart =
  2455. LiAdd(NmsNmhMyMaxVersNo, NmsRangeSize);
  2456. NmsHighWaterMarkVersNo.QuadPart =
  2457. LiAdd(NmsNmhMyMaxVersNo, NmsHalfRangeSize);
  2458. }
  2459. else // this must be a reconfiguration
  2460. {
  2461. EnterCriticalSection(&NmsNmhNamRegCrtSec);
  2462. //
  2463. // change the value of the version counter if
  2464. // the new value is more than it.
  2465. //
  2466. if (LiGtr(MaxVersNo, NmsNmhMyMaxVersNo))
  2467. {
  2468. NmsNmhMyMaxVersNo = MaxVersNo;
  2469. WINSEVT_LOG_INFO_M(MaxVersNo.LowPart,
  2470. WINS_EVT_VERS_COUNTER_CHANGED);
  2471. }
  2472. NmsVersNoToStartFromNextTime.QuadPart =
  2473. LiAdd(NmsNmhMyMaxVersNo, NmsRangeSize);
  2474. NmsHighWaterMarkVersNo.QuadPart =
  2475. LiAdd(NmsNmhMyMaxVersNo, NmsHalfRangeSize);
  2476. LeaveCriticalSection(&NmsNmhNamRegCrtSec);
  2477. }
  2478. }
  2479. if (WinsCnf.State_e == WINSCNF_E_INITING)
  2480. {
  2481. //
  2482. // Check if a port has been assigned by the user.
  2483. //
  2484. QUERY_VALUE_M(
  2485. sParametersKey,
  2486. WINSCNF_WINS_PORT_NO_NM,
  2487. ValTyp,
  2488. CommWinsTcpPortNo,
  2489. 0,
  2490. COMM_DEFAULT_IP_PORT
  2491. );
  2492. DBGPRINT1(DET, "WinsCnfReadWinsInfo: Port No is (%d)\n", CommWinsTcpPortNo);
  2493. //
  2494. // Check if WINS should continue replication in case of an
  2495. // error in replication.
  2496. //
  2497. QUERY_VALUE_M(
  2498. sParametersKey,
  2499. WINSCNF_NO_RPL_ON_ERR_NM,
  2500. ValTyp,
  2501. WinsCnf.fNoRplOnErr,
  2502. 0,
  2503. TRUE
  2504. );
  2505. //
  2506. // Assign MaxVersNo with the default value
  2507. //
  2508. WINS_ASSIGN_INT_TO_VERS_NO_M(MaxVersNo, 0);
  2509. //
  2510. // Read in the value specified in the registry for the version
  2511. // number that we should use when starting.
  2512. //
  2513. Sz = sizeof(DWORD);
  2514. (VOID)RegQueryValueEx(
  2515. sConfigRoot,
  2516. WINSCNF_INT_VERSNO_NEXTTIME_LW_NM,
  2517. NULL, //reserved; must be NULL
  2518. &ValTyp,
  2519. (LPBYTE)&MaxVersNo.LowPart,
  2520. &Sz
  2521. );
  2522. (VOID)RegQueryValueEx(
  2523. sConfigRoot,
  2524. WINSCNF_INT_VERSNO_NEXTTIME_HW_NM,
  2525. NULL, //reserved; must be NULL
  2526. &ValTyp,
  2527. (LPBYTE)&MaxVersNo.HighPart,
  2528. &Sz
  2529. );
  2530. //
  2531. // if we read in a value for the version counter and it is greater
  2532. // than the high-water mark currently there
  2533. //
  2534. if (LiGtr(MaxVersNo, NmsHighWaterMarkVersNo))
  2535. {
  2536. fWinsCnfReadNextTimeVersNo = TRUE;
  2537. //
  2538. // Use WinsCnf, not pWinsCnf since at initialization time,
  2539. // we always read into WinsCnf. At reinit, the State_e field
  2540. // in the WinsCnf structure allocated may have garbage
  2541. // (actually will be 0 since we initialize allocated memory
  2542. // to zero -- I might change in the future to improve
  2543. // performance)
  2544. //
  2545. //
  2546. // Min. Vers. to start scavenging from.
  2547. //
  2548. // NOTE: if we find local records or the special record then
  2549. // NmsScvMinScvVersNo will get changed (check out GetMaxVersNos
  2550. // in nmsdb.c
  2551. //
  2552. if (LiLtr(NmsNmhMyMaxVersNo, MaxVersNo))
  2553. {
  2554. NmsNmhMyMaxVersNo = MaxVersNo;
  2555. NmsScvMinScvVersNo = NmsNmhMyMaxVersNo;
  2556. }
  2557. NmsVersNoToStartFromNextTime.QuadPart =
  2558. LiAdd(NmsNmhMyMaxVersNo, NmsRangeSize);
  2559. NmsHighWaterMarkVersNo.QuadPart =
  2560. LiAdd(NmsNmhMyMaxVersNo, NmsHalfRangeSize);
  2561. }
  2562. } //end of if state is INITING
  2563. //
  2564. // Check to see if a backup directory has been specified for the WINS
  2565. // database
  2566. //
  2567. //
  2568. // Read in the name of the recovery file
  2569. //
  2570. Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
  2571. RetVal = RegQueryValueEx(
  2572. sParametersKey,
  2573. WINSCNF_BACKUP_DIR_PATH_NM,
  2574. NULL, //reserved; must be NULL
  2575. &ValTyp,
  2576. (LPBYTE)DirPath,
  2577. &Sz
  2578. );
  2579. if ((RetVal != ERROR_SUCCESS) || (DirPath[0] == (TCHAR)EOS))
  2580. {
  2581. pWinsCnf->pBackupDirPath = NULL;
  2582. }
  2583. else
  2584. {
  2585. if(!WinsMscGetName(ValTyp, DirPath, Path2, WINS_MAX_FILENAME_SZ, &pHoldFileName))
  2586. {
  2587. pWinsCnf->pBackupDirPath = NULL;
  2588. }
  2589. else
  2590. {
  2591. WinsMscAlloc(Sz + sizeof(WINS_BACKUP_DIR_ASCII), &pWinsCnf->pBackupDirPath);
  2592. FUTURES("When Jet starts taking UNICODE input, get rid of this")
  2593. WinsMscConvertUnicodeStringToAscii((LPBYTE)pHoldFileName, pWinsCnf->pBackupDirPath, WINS_MAX_FILENAME_SZ);
  2594. strcat(pWinsCnf->pBackupDirPath, WINS_BACKUP_DIR_ASCII);
  2595. //
  2596. // No need to look at the return code.
  2597. //
  2598. CreateDirectoryA(pWinsCnf->pBackupDirPath, NULL);
  2599. }
  2600. }
  2601. //
  2602. // Check to see if the admin. has told WINS to do a backup on
  2603. // termination
  2604. //
  2605. Sz = sizeof(pWinsCnf->fDoBackupOnTerm);
  2606. RetVal = RegQueryValueEx(
  2607. sParametersKey,
  2608. WINSCNF_DO_BACKUP_ON_TERM_NM,
  2609. NULL, //reserved; must be NULL
  2610. &ValTyp,
  2611. (LPBYTE)&pWinsCnf->fDoBackupOnTerm,
  2612. &Sz
  2613. );
  2614. if (RetVal != ERROR_SUCCESS)
  2615. {
  2616. pWinsCnf->fDoBackupOnTerm = FALSE;
  2617. }
  2618. //
  2619. // Check to see if static records have to be treated as p-static
  2620. //
  2621. Sz = sizeof(pWinsCnf->fPStatic);
  2622. RetVal = RegQueryValueEx(
  2623. sParametersKey,
  2624. WINSCNF_MIGRATION_ON_NM,
  2625. NULL, //reserved; must be NULL
  2626. &ValTyp,
  2627. (LPBYTE)&pWinsCnf->fPStatic,
  2628. &Sz
  2629. );
  2630. if (RetVal != ERROR_SUCCESS)
  2631. {
  2632. pWinsCnf->fPStatic = FALSE;
  2633. }
  2634. //
  2635. // Read max wins registration que len.
  2636. //
  2637. QUERY_VALUE_M(
  2638. sParametersKey,
  2639. WINSCNF_BURST_QUE_SIZE_NM,
  2640. ValTyp,
  2641. QueOtherNbtWrkQueMaxLen,
  2642. 0,
  2643. WINS_QUEUE_HWM
  2644. );
  2645. if (QueOtherNbtWrkQueMaxLen < WINS_QUEUE_HWM_MIN) {
  2646. QueOtherNbtWrkQueMaxLen = WINS_QUEUE_HWM_MIN;
  2647. } else if (QueOtherNbtWrkQueMaxLen > WINS_QUEUE_HWM_MAX) {
  2648. QueOtherNbtWrkQueMaxLen = WINS_QUEUE_HWM_MAX;
  2649. }
  2650. // Read whether or not we randomize 1c list retrieval.
  2651. QUERY_VALUE_M(
  2652. sParametersKey,
  2653. WINSCNF_RANDOMIZE_1C_LIST_NM,
  2654. ValTyp,
  2655. WinsCnf.fRandomize1CList,
  2656. 0,
  2657. FALSE
  2658. );
  2659. } // end of try ..
  2660. except(EXCEPTION_EXECUTE_HANDLER) {
  2661. DBGPRINTEXC("WinsCnfReadWinsInfo");
  2662. WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_SFT_ERR);
  2663. }
  2664. return;
  2665. }
  2666. VOID
  2667. ReadCCInfo(
  2668. PWINSCNF_CNF_T pWinsCnf
  2669. )
  2670. /*++
  2671. Routine Description:
  2672. Function to read in CC info
  2673. Arguments:
  2674. Externals Used:
  2675. None
  2676. Return Value:
  2677. Success status codes --
  2678. Error status codes --
  2679. Error Handling:
  2680. Called by:
  2681. Side Effects:
  2682. Comments:
  2683. None
  2684. --*/
  2685. {
  2686. SYSTEMTIME CurrTime;
  2687. DWORD Sz;
  2688. LONG RetVal;
  2689. DWORD ValTyp;
  2690. VERS_NO_T MaxVersNo;
  2691. WINSEVT_STRS_T EvtStr;
  2692. DBGENTER("ReadCCInfo\n");
  2693. //
  2694. // Open the Consistency Chk Key
  2695. //
  2696. RetVal = RegOpenKeyEx(
  2697. sConfigRoot, //predefined key value
  2698. _WINS_CFG_CC_KEY,
  2699. 0, //must be zero (reserved)
  2700. KEY_READ | KEY_WRITE, //we desire read/write access
  2701. // to the key
  2702. &sCCKey //handle to key
  2703. );
  2704. if (RetVal != ERROR_SUCCESS)
  2705. {
  2706. WINSEVT_LOG_INFO_D_M(
  2707. WINS_SUCCESS,
  2708. WINS_EVT_CANT_OPEN_CC_KEY
  2709. );
  2710. pWinsCnf->CC.TimeInt = MAXULONG;
  2711. return;
  2712. }
  2713. Sz = sizeof(pWinsCnf->CC.TimeInt);
  2714. RetVal = RegQueryValueEx(
  2715. sCCKey,
  2716. WINSCNF_CC_INTVL_NM,
  2717. NULL, //reserved; must be NULL
  2718. &ValTyp,
  2719. (LPBYTE)&pWinsCnf->CC.TimeInt,
  2720. &Sz
  2721. );
  2722. if (RetVal != ERROR_SUCCESS)
  2723. {
  2724. WINSEVT_LOG_INFO_D_M(
  2725. WINS_SUCCESS,
  2726. WINS_EVT_CANT_GET_CC_INTERVAL_VAL
  2727. );
  2728. pWinsCnf->CC.TimeInt = WINSCNF_CC_DEF_INTERVAL;
  2729. }
  2730. else
  2731. {
  2732. if ( !sfNoLimitChk)
  2733. {
  2734. if (pWinsCnf->CC.TimeInt < WINSCNF_CC_MIN_INTERVAL)
  2735. {
  2736. pWinsCnf->CC.TimeInt = WINSCNF_CC_MIN_INTERVAL;
  2737. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
  2738. NULL, __LINE__, "ud",
  2739. WINSCNF_CC_INTVL_NM,
  2740. pWinsCnf->CC.TimeInt);
  2741. }
  2742. }
  2743. else
  2744. {
  2745. if (pWinsCnf->CC.TimeInt < 60)
  2746. {
  2747. pWinsCnf->CC.TimeInt = 60;
  2748. }
  2749. }
  2750. }
  2751. Sz = sizeof(pWinsCnf->CC.MaxRecsAAT);
  2752. RetVal = RegQueryValueEx(
  2753. sCCKey,
  2754. WINSCNF_CC_MAX_RECS_AAT_NM,
  2755. NULL, //reserved; must be NULL
  2756. &ValTyp,
  2757. (LPBYTE)&pWinsCnf->CC.MaxRecsAAT,
  2758. &Sz
  2759. );
  2760. if (RetVal != ERROR_SUCCESS)
  2761. {
  2762. WINSEVT_LOG_INFO_D_M(
  2763. WINS_SUCCESS,
  2764. WINS_EVT_CANT_GET_CC_MAX_RECS_AAT_VAL
  2765. );
  2766. pWinsCnf->CC.MaxRecsAAT = WINSCNF_CC_DEF_RECS_AAT;
  2767. }
  2768. else
  2769. {
  2770. if (pWinsCnf->CC.MaxRecsAAT < WINSCNF_CC_MIN_RECS_AAT)
  2771. {
  2772. if ( !sfNoLimitChk)
  2773. {
  2774. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_MAX_RECS_AAT,
  2775. NULL, __LINE__, "udd",
  2776. WINSCNF_CC_MAX_RECS_AAT_NM,
  2777. WINSCNF_CC_MIN_RECS_AAT,
  2778. pWinsCnf->CC.MaxRecsAAT);
  2779. pWinsCnf->CC.MaxRecsAAT = WINSCNF_CC_MIN_RECS_AAT;
  2780. }
  2781. else
  2782. {
  2783. if (pWinsCnf->CC.MaxRecsAAT < 2)
  2784. {
  2785. pWinsCnf->CC.MaxRecsAAT = 2;
  2786. }
  2787. }
  2788. }
  2789. }
  2790. Sz = sizeof(pWinsCnf->CC.fUseRplPnrs);
  2791. RetVal = RegQueryValueEx(
  2792. sCCKey,
  2793. WINSCNF_CC_USE_RPL_PNRS_NM,
  2794. NULL, //reserved; must be NULL
  2795. &ValTyp,
  2796. (LPBYTE)&pWinsCnf->CC.fUseRplPnrs,
  2797. &Sz
  2798. );
  2799. if (RetVal != ERROR_SUCCESS)
  2800. {
  2801. WINSEVT_LOG_INFO_D_M(
  2802. WINS_SUCCESS,
  2803. WINS_EVT_CANT_GET_CC_USE_RPL_PNRS_VAL
  2804. );
  2805. pWinsCnf->CC.fUseRplPnrs = WINSCNF_CC_DEF_USE_RPL_PNRS;
  2806. }
  2807. GetLocalTime(&CurrTime);
  2808. GetSpTimeData(sCCKey, &CurrTime, &pWinsCnf->CC.fSpTime, &pWinsCnf->CC.SpTimeInt);
  2809. REG_M(
  2810. RegCloseKey(sCCKey),
  2811. WINS_EVT_CANT_CLOSE_KEY,
  2812. WINS_EXC_CANT_CLOSE_KEY
  2813. );
  2814. DBGLEAVE("ReadCCInfo\n");
  2815. return;
  2816. }
  2817. #if USENETBT > 0
  2818. //------------------------------------------------------------------------
  2819. STATUS
  2820. WinsCnfReadNbtDeviceName(
  2821. VOID
  2822. )
  2823. /*++
  2824. Routine Description:
  2825. This procedure reads the registry to get the name of NBT to bind to.
  2826. That name is stored in the Linkage section under the Netbt key.
  2827. Arguments:
  2828. Return Value:
  2829. 0 if successful, -1 otherwise.
  2830. --*/
  2831. {
  2832. PTCHAR SubKeyLinkage=NETBT_LINKAGE_KEY;
  2833. HKEY Key;
  2834. PTCHAR pLinkage=TEXT("Export");
  2835. LONG Type;
  2836. LONG Status;
  2837. LONG Status2;
  2838. ULONG Size;
  2839. //
  2840. // Open the NETBT key
  2841. //
  2842. Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2843. SubKeyLinkage,
  2844. 0,
  2845. KEY_READ,
  2846. &Key);
  2847. if (Status == ERROR_SUCCESS)
  2848. {
  2849. //
  2850. // now read the linkage values
  2851. //
  2852. Status = RegQueryValueEx(Key,
  2853. pLinkage,
  2854. NULL,
  2855. &Type,
  2856. NULL,
  2857. &Size);
  2858. if (Status != ERROR_SUCCESS)
  2859. {
  2860. DBGPRINT0(ERR, "Error closing the Registry key\n");
  2861. WINSEVT_LOG_M(Status, WINS_EVT_QUERY_NETBT_KEY_ERR);
  2862. (VOID)RegCloseKey(Key);
  2863. return(WINS_FAILURE);
  2864. }
  2865. else
  2866. {
  2867. //
  2868. // Let us allocate a buffer that is big enough to hold all the
  2869. // data
  2870. //
  2871. WinsMscAlloc(Size, (LPVOID *)&pWinsCnfNbtPath);
  2872. //
  2873. // now read the linkage values
  2874. //
  2875. Status = RegQueryValueEx(Key,
  2876. pLinkage,
  2877. NULL,
  2878. &Type,
  2879. (LPBYTE)pWinsCnfNbtPath,
  2880. &Size);
  2881. Status2 = RegCloseKey(Key);
  2882. if ((Status != ERROR_SUCCESS) || (Status2 != ERROR_SUCCESS))
  2883. {
  2884. DBGPRINT0(ERR, "Error closing the Registry key\n");
  2885. WINSEVT_LOG_M(Status, WINS_EVT_QUERY_NETBT_KEY_ERR);
  2886. return(WINS_FAILURE);
  2887. }
  2888. }
  2889. }
  2890. else
  2891. {
  2892. WINSEVT_LOG_D_M(Status, WINS_EVT_OPEN_NETBT_KEY_ERR);
  2893. return(WINS_FAILURE);
  2894. }
  2895. return(WINS_SUCCESS);
  2896. }
  2897. #endif
  2898. VOID
  2899. WinsCnfReadRegInfo(
  2900. PWINSCNF_CNF_T pWinsCnf
  2901. )
  2902. /*++
  2903. Routine Description:
  2904. This function is called to read the registry in order to populate the
  2905. WinsCnf structure
  2906. Arguments:
  2907. None
  2908. Externals Used:
  2909. None
  2910. Return Value:
  2911. None
  2912. Error Handling:
  2913. Called by:
  2914. WinsCnfInitConfig
  2915. Side Effects:
  2916. Comments:
  2917. None
  2918. --*/
  2919. {
  2920. try {
  2921. if (sfParametersKeyExists)
  2922. {
  2923. /*
  2924. Read in the registry information pertaining to WINS
  2925. */
  2926. WinsCnfReadWinsInfo(pWinsCnf);
  2927. }
  2928. if (sfPartnersKeyExists)
  2929. {
  2930. //
  2931. // Read the PUSH/PULL records and other global information used for
  2932. // replication
  2933. //
  2934. WinsCnfReadPartnerInfo(pWinsCnf);
  2935. }
  2936. //
  2937. // Do a sanity check on the params. We are not interested in the
  2938. // return code
  2939. //
  2940. (VOID)SanityChkParam(pWinsCnf);
  2941. }
  2942. except(EXCEPTION_EXECUTE_HANDLER) {
  2943. DBGPRINTEXC("WinsCnfReadRegInfo");
  2944. //
  2945. // If we encountered an exception at boot time, we do not want to
  2946. // reraise the exception, since we want to come up and continue on
  2947. // For the non-initing case, the exception that we raise will be caught
  2948. // in Reinit(). For the boot time case, it is ok to come up with the
  2949. // defaults (an event message is being logged) - in WinsCnf.
  2950. // In the non-init case, the defaults are not in the memory used to
  2951. // read in the parameters (WinsCnf is initialized with stuff in
  2952. // this memory block later).
  2953. //
  2954. if (WinsCnf.State_e != WINSCNF_E_INITING)
  2955. {
  2956. WINS_RERAISE_EXC_M();
  2957. }
  2958. WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RECONFIG_ERR);
  2959. }
  2960. return;
  2961. }
  2962. VOID
  2963. WinsCnfCopyWinsCnf(
  2964. WINS_CLIENT_E Client_e,
  2965. PWINSCNF_CNF_T pSrc
  2966. )
  2967. /*++
  2968. Routine Description:
  2969. This function is called to copy relevant information from a WINS
  2970. Cnf structure to the master (external) Wins Cnf structure
  2971. Arguments:
  2972. pSrc - WinsCnf stucture to copy from
  2973. Externals Used:
  2974. WinsCnf
  2975. Return Value:
  2976. None
  2977. Error Handling:
  2978. Called by:
  2979. RplPullInit
  2980. Side Effects:
  2981. Comments:
  2982. This function may be enhanced in the future
  2983. Note: this function is called only by the main thread
  2984. --*/
  2985. {
  2986. BOOL fScvParamChg = FALSE;
  2987. if (Client_e == WINS_E_WINSCNF)
  2988. {
  2989. FUTURES("Queue a message to the Scavenger thread passing it pSrc")
  2990. FUTURES("That will avoid this synchronization overhead")
  2991. //
  2992. // We need to synchronize with the scavenger thread and
  2993. // RPC threads that might be looking at fRplOnlyWCnfPnrs
  2994. //
  2995. EnterCriticalSection(&WinsCnfCnfCrtSec);
  2996. //
  2997. // Also need to synchronize with the nbt threads doing
  2998. // name registrations/refreshes
  2999. //
  3000. EnterCriticalSection(&NmsNmhNamRegCrtSec);
  3001. //
  3002. // Sanity check the parameters
  3003. //
  3004. fScvParamChg = SanityChkParam(pSrc);
  3005. if (fScvParamChg)
  3006. {
  3007. //
  3008. // Initialize the scavenging stuff.
  3009. //
  3010. WinsCnf.RefreshInterval = pSrc->RefreshInterval;
  3011. WinsCnf.TombstoneInterval = pSrc->TombstoneInterval;
  3012. WinsCnf.TombstoneTimeout = pSrc->TombstoneTimeout;
  3013. WinsCnf.CC = pSrc->CC;
  3014. WinsCnf.ScvThdPriorityLvl = pSrc->ScvThdPriorityLvl;
  3015. }
  3016. //
  3017. // Store the verify interval since SanityChkParam does
  3018. // not set fScvParamChg if VerifyINterval has changed.
  3019. //
  3020. WinsCnf.VerifyInterval = pSrc->VerifyInterval;
  3021. WinsCnf.fRplOnlyWCnfPnrs = pSrc->fRplOnlyWCnfPnrs;
  3022. WinsCnf.LogDetailedEvts = pSrc->LogDetailedEvts;
  3023. WinsCnf.fAdd1Bto1CQueries = pSrc->fAdd1Bto1CQueries;
  3024. WinsCnf.fPStatic = pSrc->fPStatic;
  3025. LeaveCriticalSection(&NmsNmhNamRegCrtSec);
  3026. WinsCnf.fDoSpoofing = pSrc->fDoSpoofing;
  3027. WinsCnf.MaxNoOfWrkThds = pSrc->MaxNoOfWrkThds;
  3028. WinsCnf.fDoBackupOnTerm = pSrc->fDoBackupOnTerm;
  3029. #if MCAST > 0
  3030. WinsCnf.fUseSelfFndPnrs = pSrc->fUseSelfFndPnrs;
  3031. WinsCnf.McastIntvl = pSrc->McastIntvl;
  3032. #endif
  3033. #if PRSCONN
  3034. WinsCnf.fPrsConn = pSrc->fPrsConn;
  3035. #endif
  3036. if (WinsCnf.fDoBackupOnTerm && pSrc->pBackupDirPath != NULL)
  3037. {
  3038. if (WinsCnf.pBackupDirPath != NULL)
  3039. {
  3040. WinsMscDealloc(WinsCnf.pBackupDirPath);
  3041. }
  3042. WinsCnf.pBackupDirPath = pSrc->pBackupDirPath;
  3043. }
  3044. LeaveCriticalSection(&WinsCnfCnfCrtSec);
  3045. // return;
  3046. }
  3047. else
  3048. {
  3049. if (Client_e == WINS_E_RPLPULL)
  3050. {
  3051. EnterCriticalSection(&WinsCnfCnfCrtSec);
  3052. //
  3053. // Copy the Scavenging parameters into the cnf structure
  3054. // just allocated so that we can compare them for
  3055. // compatibility with the new max. replication time interval
  3056. // (since the Partners key was signaled, the replication
  3057. // stuff might have changed)
  3058. //
  3059. pSrc->RefreshInterval = WinsCnf.RefreshInterval;
  3060. pSrc->TombstoneInterval = WinsCnf.TombstoneInterval;
  3061. pSrc->TombstoneTimeout = WinsCnf.TombstoneTimeout;
  3062. pSrc->VerifyInterval = WinsCnf.VerifyInterval;
  3063. //
  3064. // Wasteful here and in SanityChkParam
  3065. //
  3066. PERF("Pass an argument to SanityChk so that we don't have to do this")
  3067. PERF("See similar remark in SanityChk")
  3068. pSrc->CC = WinsCnf.CC;
  3069. //
  3070. // Sanity check the parameters.
  3071. //
  3072. // Sanity checking of the parameters is done here in
  3073. // the main thread instead of in the PULL thread because
  3074. // we don't want a situation where two different threads
  3075. // (the main thread for changes to the PARAMETERS key)
  3076. // and the PULL thread (for changes in the PARTNERS key)
  3077. // updating the WinsCnf structure
  3078. //
  3079. // Also, as an aside, we don't copy the PullInfo information
  3080. // into WinsCnf here to avoid unnecessary complication and
  3081. // synchronization that would ensue by the fact that we
  3082. // would then have two threads (main thread) and the PULL
  3083. // thread accessing that field (check Reconfig() in
  3084. // rplpull.c).
  3085. //
  3086. FUTURES("When we start supporting time interval as an attribute of PUSHing")
  3087. FUTURES("move this check inside the NmsNmhNamRegCrtSec below")
  3088. fScvParamChg = SanityChkParam(pSrc);
  3089. //
  3090. // If one or more scavenging parameters have changed,
  3091. // update WinsCnf and signal the Scavenger thread.
  3092. //
  3093. if (fScvParamChg)
  3094. {
  3095. WinsCnf.RefreshInterval = pSrc->RefreshInterval;
  3096. WinsCnf.TombstoneInterval = pSrc->TombstoneInterval;
  3097. WinsCnf.TombstoneTimeout = pSrc->TombstoneTimeout;
  3098. //
  3099. // If SanityChkParam changed Tombstone interval, then
  3100. // verify interval has also changed.
  3101. //
  3102. WinsCnf.VerifyInterval = pSrc->VerifyInterval;
  3103. }
  3104. WinsCnf.MaxRplTimeInterval = pSrc->MaxRplTimeInterval;
  3105. WinsCnf.RplType = pSrc->RplType;
  3106. LeaveCriticalSection(&WinsCnfCnfCrtSec);
  3107. }
  3108. }
  3109. //
  3110. // If the scavenging params have changed we need to signal
  3111. // the scavenger thread
  3112. //
  3113. if (fScvParamChg)
  3114. {
  3115. WinsMscSignalHdl(WinsCnf.CnfChgEvtHdl);
  3116. }
  3117. return;
  3118. }
  3119. LPVOID
  3120. WinsCnfGetNextRplCnfRec(
  3121. PRPL_CONFIG_REC_T pCnfRec,
  3122. RPL_REC_TRAVERSAL_E RecTrv_e
  3123. )
  3124. /*++
  3125. Routine Description:
  3126. This function is called to get to the next configuration record
  3127. Arguments:
  3128. pCnfRec - The current configuration record in a buffer of configuration
  3129. records
  3130. RecTrv_e - indicates how the next one should be retrieved. If set to
  3131. TRUE, it means that the next record to be retrieved is one
  3132. that follows the current record in the buffer. If set to
  3133. FALSE, the next record is retrieved using the pNext field
  3134. of the current configuration record
  3135. Externals Used:
  3136. None
  3137. Return Value:
  3138. address of the next configuration record
  3139. Error Handling:
  3140. Called by:
  3141. EstablishComm in rplpull.c, WinsPushTrigger() in wins.c
  3142. Side Effects:
  3143. Comments:
  3144. None
  3145. --*/
  3146. {
  3147. //
  3148. // If no traversal is desired, return NULL as the next record
  3149. //
  3150. if (RecTrv_e == RPL_E_NO_TRAVERSAL)
  3151. {
  3152. return(NULL);
  3153. }
  3154. //
  3155. // Go to the next configuration record in a way specified
  3156. // by the value of the RecTrv_e flag.
  3157. //
  3158. if(RecTrv_e == RPL_E_IN_SEQ)
  3159. {
  3160. pCnfRec = (PRPL_CONFIG_REC_T)(
  3161. (LPBYTE)pCnfRec + RPL_CONFIG_REC_SIZE);
  3162. }
  3163. else // RPL_E_VIA_LINK
  3164. {
  3165. return(pCnfRec->pNext);
  3166. }
  3167. return(pCnfRec);
  3168. }
  3169. VOID
  3170. WinsCnfAskToBeNotified(
  3171. WINSCNF_KEY_E KeyToMonitor_e
  3172. )
  3173. /*++
  3174. Routine Description:
  3175. This function is called to request that WINS be notified when
  3176. the information pertaining to WINS and its subkeys in the registry
  3177. changes
  3178. Arguments:
  3179. KeyToMonitor_e
  3180. Externals Used:
  3181. None
  3182. Return Value:
  3183. None
  3184. Error Handling:
  3185. Called by:
  3186. Reinit() in nms.c
  3187. WinsCnfOpenSubKeys()
  3188. WinsCnfInitConfig()
  3189. Side Effects:
  3190. Comments:
  3191. None
  3192. --*/
  3193. {
  3194. DWORD NotifyFilter = 0;
  3195. LONG RetVal;
  3196. DWORD Error;
  3197. #define CHK_RET_VAL_M { \
  3198. if (RetVal != ERROR_SUCCESS) \
  3199. { \
  3200. DBGPRINT1(ERR, "WinsAskToBeNotified: Error = (%d)\n", RetVal); \
  3201. WINSEVT_LOG_M( \
  3202. WINS_FATAL_ERR, \
  3203. WINS_EVT_REG_NTFY_FN_ERR \
  3204. ); \
  3205. } \
  3206. }
  3207. /*
  3208. * Set the notify filter. Ask to be notified for all changes.
  3209. */
  3210. NotifyFilter = REG_NOTIFY_CHANGE_NAME |
  3211. REG_NOTIFY_CHANGE_ATTRIBUTES |
  3212. REG_NOTIFY_CHANGE_LAST_SET |
  3213. REG_NOTIFY_CHANGE_SECURITY ;
  3214. switch(KeyToMonitor_e)
  3215. {
  3216. case(WINSCNF_E_WINS_KEY):
  3217. // DBGPRINT0(SPEC, "WinsCnfAskToBeNotified: WINS Key\n");
  3218. RetVal = RegNotifyChangeKeyValue(
  3219. sConfigRoot,
  3220. TRUE, //report changes in key and all subkeys
  3221. REG_NOTIFY_CHANGE_NAME,
  3222. WinsCnf.WinsKChgEvtHdl,
  3223. TRUE //Async signaling is what we want
  3224. );
  3225. CHK_RET_VAL_M;
  3226. break;
  3227. case(WINSCNF_E_PARAMETERS_KEY):
  3228. // DBGPRINT0(SPEC, "WinsCnfAskToBeNotified: PARAMETERS Key\n");
  3229. RetVal = RegNotifyChangeKeyValue(
  3230. sParametersKey,
  3231. TRUE, //report changes in key and all subkeys
  3232. NotifyFilter,
  3233. WinsCnf.ParametersKChgEvtHdl,
  3234. TRUE //Async signaling is what we want
  3235. );
  3236. CHK_RET_VAL_M;
  3237. break;
  3238. case(WINSCNF_E_PARTNERS_KEY):
  3239. // DBGPRINT0(SPEC, "WinsCnfAskToBeNotified: PARTNERS Key\n");
  3240. RetVal = RegNotifyChangeKeyValue(
  3241. sPartnersKey,
  3242. TRUE, //report changes in key and all subkeys
  3243. NotifyFilter,
  3244. WinsCnf.PartnersKChgEvtHdl,
  3245. TRUE //Async signaling is what we want
  3246. );
  3247. CHK_RET_VAL_M;
  3248. break;
  3249. FUTURES("Remove the following case")
  3250. //
  3251. // The following case would never get exercised.
  3252. //
  3253. case(WINSCNF_E_ALL_KEYS):
  3254. RetVal = RegNotifyChangeKeyValue(
  3255. sConfigRoot,
  3256. TRUE, //report changes in key and all subkeys
  3257. REG_NOTIFY_CHANGE_NAME,
  3258. WinsCnf.WinsKChgEvtHdl,
  3259. TRUE //Async signaling is what we want
  3260. );
  3261. CHK_RET_VAL_M;
  3262. if (sfParametersKeyExists)
  3263. {
  3264. RetVal = RegNotifyChangeKeyValue(
  3265. sParametersKey,
  3266. TRUE, //report changes in key and
  3267. //all subkeys
  3268. NotifyFilter,
  3269. WinsCnf.ParametersKChgEvtHdl,
  3270. TRUE //Async signaling is what we
  3271. // want
  3272. );
  3273. if (RetVal != ERROR_SUCCESS)
  3274. {
  3275. Error = GetLastError();
  3276. if (Error == ERROR_BADKEY)
  3277. {
  3278. //
  3279. // Key must not be there
  3280. //
  3281. sfParametersKeyExists = FALSE;
  3282. }
  3283. else
  3284. {
  3285. DBGPRINT1(ERR,
  3286. "WinsCnfAskToBeNotified: RegNotifyChangeKeyValue error = (%d)\n",
  3287. Error);
  3288. }
  3289. }
  3290. }
  3291. if (sfPartnersKeyExists)
  3292. {
  3293. RetVal = RegNotifyChangeKeyValue(
  3294. sPartnersKey,
  3295. TRUE, //report changes in key and
  3296. //all subkeys
  3297. NotifyFilter,
  3298. WinsCnf.PartnersKChgEvtHdl,
  3299. TRUE //Async signaling is what we
  3300. //want
  3301. );
  3302. if (RetVal != ERROR_SUCCESS)
  3303. {
  3304. Error = GetLastError();
  3305. if (Error == ERROR_BADKEY)
  3306. {
  3307. //
  3308. // Key must not be there
  3309. //
  3310. sfPartnersKeyExists = FALSE;
  3311. }
  3312. else
  3313. {
  3314. DBGPRINT1(ERR,
  3315. "WinsCnfAskToBeNotified: RegNotifyChangeKeyValue error = (%d)\n",
  3316. Error);
  3317. }
  3318. }
  3319. }
  3320. break;
  3321. default:
  3322. DBGPRINT1(ERR, "WinsCnfAskToBeNotified: Wrong Hdl (%d)\n",
  3323. KeyToMonitor_e);
  3324. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_SFT_ERR);
  3325. WINS_RAISE_EXC_M(WINS_EXC_FAILURE);
  3326. break;
  3327. }
  3328. return;
  3329. }
  3330. VOID
  3331. WinsCnfDeallocCnfMem(
  3332. PWINSCNF_CNF_T pWinsCnf
  3333. )
  3334. /*++
  3335. Routine Description:
  3336. This function is called to deallocate the Wins Cnf structure and
  3337. memory associated with it
  3338. Arguments:
  3339. Externals Used:
  3340. None
  3341. Return Value:
  3342. None
  3343. Error Handling:
  3344. Called by:
  3345. Reconfig in rplpull.c
  3346. Side Effects:
  3347. Comments:
  3348. None
  3349. --*/
  3350. {
  3351. try {
  3352. //
  3353. // Deallocate the buffer holding one or more names of files used
  3354. // for STATIC initialization of WINS
  3355. //
  3356. if (pWinsCnf->pStaticDataFile != NULL)
  3357. {
  3358. WinsMscDealloc(pWinsCnf->pStaticDataFile);
  3359. }
  3360. WinsMscDealloc(pWinsCnf);
  3361. }
  3362. except(EXCEPTION_EXECUTE_HANDLER) {
  3363. DBGPRINTEXC("WinsCnfDeallocCnfMem");
  3364. DBGPRINT0(EXC, "WinsCnfDeallocCnfMem: Got an exception\n");
  3365. WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RECONFIG_ERR);
  3366. }
  3367. return;
  3368. }
  3369. VOID
  3370. GetKeyInfo(
  3371. IN HKEY Key,
  3372. IN WINSCNF_KEY_E KeyType_e,
  3373. OUT LPDWORD pNoOfSubKeys,
  3374. OUT LPDWORD pNoOfVals
  3375. )
  3376. /*++
  3377. Routine Description:
  3378. This function is called to get the number of subkeys under a key
  3379. Arguments:
  3380. Key - Key whose subkey count has to be determined
  3381. KeyType_e
  3382. pNoOfSubKeys
  3383. Externals Used:
  3384. None
  3385. Return Value:
  3386. None
  3387. Error Handling:
  3388. Called by:
  3389. GetPnrInfo()
  3390. Side Effects:
  3391. Comments:
  3392. None
  3393. --*/
  3394. {
  3395. TCHAR ClsStr[40];
  3396. DWORD ClsStrSz = sizeof(ClsStr);
  3397. DWORD LongestKeyLen;
  3398. DWORD LongestKeyClassLen;
  3399. DWORD LongestValueNameLen;
  3400. DWORD LongestValueDataLen;
  3401. DWORD SecDesc;
  3402. LONG RetVal;
  3403. FILETIME LastWrite;
  3404. /*
  3405. Query the key. The subkeys are IP addresses of PULL
  3406. partners.
  3407. */
  3408. RetVal = RegQueryInfoKey(
  3409. Key,
  3410. ClsStr,
  3411. &ClsStrSz,
  3412. NULL, //must be NULL, reserved
  3413. pNoOfSubKeys,
  3414. &LongestKeyLen,
  3415. &LongestKeyClassLen,
  3416. pNoOfVals,
  3417. &LongestValueNameLen,
  3418. &LongestValueDataLen,
  3419. &SecDesc,
  3420. &LastWrite
  3421. );
  3422. if (RetVal != ERROR_SUCCESS)
  3423. {
  3424. WINSEVT_LOG_M(
  3425. WINS_FATAL_ERR,
  3426. KeyType_e == WINSCNF_E_DATAFILES_KEY ?
  3427. WINS_EVT_CANT_QUERY_DATAFILES_KEY :
  3428. ((KeyType_e == WINSCNF_E_PULL_KEY) ?
  3429. WINS_EVT_CANT_QUERY_PULL_KEY :
  3430. ((KeyType_e == WINSCNF_E_PUSH_KEY) ?
  3431. WINS_EVT_CANT_QUERY_PUSH_KEY :
  3432. WINS_EVT_CANT_QUERY_SPEC_GRP_MASKS_KEY))
  3433. );
  3434. WINS_RAISE_EXC_M(WINS_EXC_CANT_QUERY_KEY);
  3435. }
  3436. return;
  3437. }
  3438. VOID
  3439. WinsCnfOpenSubKeys(
  3440. VOID
  3441. )
  3442. /*++
  3443. Routine Description:
  3444. This function opens the subkeys of the WINS key. The subkeys are
  3445. the PARTNERS key and the PARAMETERS key.
  3446. Arguments:
  3447. None
  3448. Externals Used:
  3449. sfParamatersKeyExists
  3450. sfPartnersKeyExists
  3451. Return Value:
  3452. None
  3453. Error Handling:
  3454. Called by:
  3455. WinsCnfInitConfig()
  3456. Side Effects:
  3457. Comments:
  3458. None
  3459. --*/
  3460. {
  3461. LONG RetVal;
  3462. //
  3463. // Check if the Parameters and Partners Keys are present
  3464. //
  3465. ChkWinsSubKeys();
  3466. //
  3467. // Try to open the Parameters key if it exists
  3468. //
  3469. if ((sfParametersKeyExists) && (!sfParametersKeyOpen))
  3470. {
  3471. /*
  3472. * Open the Parameters key
  3473. */
  3474. RetVal = RegOpenKeyEx(
  3475. sConfigRoot, //predefined key value
  3476. _WINS_CFG_PARAMETERS_KEY,
  3477. 0, //must be zero (reserved)
  3478. KEY_READ | KEY_WRITE, //we desire read/write access
  3479. // to the key
  3480. &sParametersKey //handle to key
  3481. );
  3482. if (RetVal != ERROR_SUCCESS)
  3483. {
  3484. CHECK("Is there any need to log this")
  3485. WINSEVT_LOG_INFO_M(
  3486. WINS_SUCCESS,
  3487. WINS_EVT_CANT_OPEN_PARAMETERS_KEY
  3488. );
  3489. sfParametersKeyExists = FALSE;
  3490. }
  3491. else
  3492. {
  3493. sfParametersKeyOpen = TRUE;
  3494. WinsCnfAskToBeNotified(WINSCNF_E_PARAMETERS_KEY);
  3495. }
  3496. }
  3497. //
  3498. // Try to open the Partners key if it exists
  3499. //
  3500. if ((sfPartnersKeyExists) && (!sfPartnersKeyOpen))
  3501. {
  3502. /*
  3503. * Open the Partners key
  3504. */
  3505. RetVal = RegOpenKeyEx(
  3506. sConfigRoot, //predefined key value
  3507. _WINS_CFG_PARTNERS_KEY,
  3508. 0, //must be zero(reserved)
  3509. KEY_READ, //we desire read
  3510. //access to the key
  3511. &sPartnersKey //handle to key
  3512. );
  3513. if (RetVal != ERROR_SUCCESS)
  3514. {
  3515. CHECK("Is there any need to log this")
  3516. WINSEVT_LOG_INFO_M(
  3517. WINS_SUCCESS,
  3518. WINS_EVT_CANT_OPEN_KEY
  3519. );
  3520. sfPartnersKeyExists = FALSE;
  3521. }
  3522. else
  3523. {
  3524. sfPartnersKeyOpen = TRUE;
  3525. WinsCnfAskToBeNotified(WINSCNF_E_PARTNERS_KEY);
  3526. }
  3527. }
  3528. return;
  3529. } //WinsCnfOpenSubKeys()
  3530. BOOL
  3531. SanityChkParam(
  3532. PWINSCNF_CNF_T pWinsCnf
  3533. )
  3534. /*++
  3535. Routine Description:
  3536. This function is called to ensure that the time intervals for
  3537. scavenging specified in WinsCnf are compatible with the ones
  3538. used for replication
  3539. Arguments:
  3540. pWinsCnf - ptr to the WINS configuration
  3541. Externals Used:
  3542. None
  3543. Return Value:
  3544. None
  3545. Error Handling:
  3546. Called by:
  3547. WinsCnfCopyWinsCnf (during reinitialization of the WINS), by
  3548. WinsCnfReadRegInfo() during initialization of the WINS
  3549. Side Effects:
  3550. The scavenging intervals could be affected
  3551. Comments:
  3552. This function must be called from inside the critical section
  3553. guarded by WinsCnfCnfCrtSec except at process initialization.
  3554. --*/
  3555. {
  3556. DWORD MinTombInterval;
  3557. BOOL fScvParamChg = FALSE;
  3558. WINSEVT_STRS_T EvtStr;
  3559. EvtStr.NoOfStrs = 1;
  3560. DBGENTER("SanityChkParam\n");
  3561. //
  3562. // Get the minimum tombstone time interval
  3563. //
  3564. MinTombInterval = WINSCNF_MAKE_TOMB_INTVL_M(pWinsCnf->RefreshInterval,
  3565. pWinsCnf->MaxRplTimeInterval);
  3566. //
  3567. // Make the actual equal to the min. if it is less
  3568. //
  3569. if (!sfNoLimitChk && (pWinsCnf->TombstoneInterval < MinTombInterval))
  3570. {
  3571. DBGPRINT2(FLOW, "SanityChkParam: Adjusting Tombstone Interval from (%d) to (%d)\n", pWinsCnf->TombstoneInterval, MinTombInterval);
  3572. FUTURES("This is actually a warning. Use a different macro or enhance it")
  3573. FUTURES("Currently, it will log this message as an informational")
  3574. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL_R,
  3575. NULL, __LINE__, "ud",
  3576. WINSCNF_TOMBSTONE_INTVL_NM,
  3577. MinTombInterval );
  3578. pWinsCnf->TombstoneInterval = MinTombInterval;
  3579. //
  3580. // Verify Interval is dependent on the tombstone interval
  3581. //
  3582. pWinsCnf->VerifyInterval = WINSCNF_MAKE_VERIFY_INTVL_M(MinTombInterval);
  3583. fScvParamChg = TRUE;
  3584. }
  3585. //
  3586. // reusing the var. The time interval is for tombstone timeout
  3587. //
  3588. MinTombInterval =
  3589. WINSCNF_MAKE_TOMBTMOUT_INTVL_M(pWinsCnf->MaxRplTimeInterval);
  3590. if (!sfNoLimitChk && (pWinsCnf->TombstoneTimeout < MinTombInterval))
  3591. {
  3592. DBGPRINT2(FLOW, "SanityChkParam: Adjusting Tombstone Timeout from (%d) to (%d)\n", pWinsCnf->TombstoneInterval, MinTombInterval);
  3593. pWinsCnf->TombstoneTimeout = MinTombInterval;
  3594. WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL_R,
  3595. NULL, __LINE__, "ud",
  3596. WINSCNF_TOMBSTONE_TMOUT_NM,
  3597. MinTombInterval );
  3598. if (!fScvParamChg)
  3599. {
  3600. fScvParamChg = TRUE;
  3601. }
  3602. }
  3603. if (!fScvParamChg)
  3604. {
  3605. PERF("Pass an argument to SanityChk so that we don't have to do this")
  3606. PERF("for CC for the case where we just read the partner info. See")
  3607. PERF("WinsCnfCopyWinsCnf for the case where client_e is WINS_E_RPLPULL")
  3608. if (
  3609. (WinsCnf.RefreshInterval != pWinsCnf->RefreshInterval)
  3610. ||
  3611. (WinsCnf.TombstoneInterval != pWinsCnf->TombstoneInterval)
  3612. ||
  3613. (WinsCnf.TombstoneTimeout != pWinsCnf->TombstoneTimeout)
  3614. ||
  3615. (WinsCnf.CC.TimeInt != pWinsCnf->CC.TimeInt)
  3616. ||
  3617. (WinsCnf.CC.SpTimeInt != pWinsCnf->CC.SpTimeInt)
  3618. ||
  3619. (WinsCnf.CC.fUseRplPnrs != pWinsCnf->CC.fUseRplPnrs)
  3620. ||
  3621. (WinsCnf.CC.MaxRecsAAT != pWinsCnf->CC.MaxRecsAAT)
  3622. )
  3623. {
  3624. fScvParamChg = TRUE;
  3625. }
  3626. }
  3627. DBGLEAVE("SanityChkParam\n");
  3628. return(fScvParamChg);
  3629. }
  3630. STATUS
  3631. WinsCnfGetNamesOfDataFiles(
  3632. PWINSCNF_CNF_T pWinsCnf
  3633. )
  3634. /*++
  3635. Routine Description:
  3636. This function gets the names of all the datafiles that need to
  3637. be used for initializing WINS.
  3638. Arguments:
  3639. Externals Used:
  3640. None
  3641. Return Value:
  3642. Success status codes -- WINS_SUCCESS
  3643. Error status codes -- WINS_FAILURE
  3644. Error Handling:
  3645. Called by:
  3646. Side Effects:
  3647. Comments:
  3648. None
  3649. --*/
  3650. {
  3651. LONG RetVal;
  3652. HKEY DFKey;
  3653. DWORD BuffSize;
  3654. STATUS RetStat = WINS_SUCCESS;
  3655. PWINSCNF_DATAFILE_INFO_T pSaveDef;
  3656. DWORD NoOfSubKeys;
  3657. DBGENTER("WinsCnfGetNamesOfDataFiles\n");
  3658. //
  3659. // Store timestamp of initialization in the statistics structure
  3660. //
  3661. WinsIntfSetTime(NULL, WINSINTF_E_INIT_DB);
  3662. //
  3663. // Set up the default name
  3664. //
  3665. //
  3666. // First allocate the buffer that will hold the default file name
  3667. //
  3668. WinsMscAlloc(WINSCNF_FILE_INFO_SZ, &pWinsCnf->pStaticDataFile);
  3669. lstrcpy(pWinsCnf->pStaticDataFile->FileNm, WINSCNF_STATIC_DATA_NAME);
  3670. //
  3671. // The default name contains a %<string>% in it. Therefore, specify
  3672. // the type as EXPAND_SZ
  3673. //
  3674. pWinsCnf->pStaticDataFile->StrType = REG_EXPAND_SZ;
  3675. pWinsCnf->NoOfDataFiles = 1;
  3676. pSaveDef = pWinsCnf->pStaticDataFile; //save the address
  3677. /*
  3678. * Open the DATAFILES key
  3679. */
  3680. RetVal = RegOpenKeyEx(
  3681. sConfigRoot, //predefined key value
  3682. _WINS_CFG_DATAFILES_KEY,
  3683. 0, //must be zero (reserved)
  3684. KEY_READ, //we desire read access to the keyo
  3685. &DFKey //handle to key
  3686. );
  3687. if (RetVal != ERROR_SUCCESS)
  3688. {
  3689. CHECK("Is there any need to log this")
  3690. WINSEVT_LOG_INFO_M(
  3691. WINS_SUCCESS,
  3692. WINS_EVT_CANT_OPEN_DATAFILES_KEY
  3693. );
  3694. DBGLEAVE("WinsCnfGetNamesOfDataFiles\n");
  3695. return(FALSE);
  3696. }
  3697. else
  3698. try {
  3699. {
  3700. //
  3701. // Get the count of data files listed under the DATAFILES
  3702. // key
  3703. //
  3704. GetKeyInfo(
  3705. DFKey,
  3706. WINSCNF_E_DATAFILES_KEY,
  3707. &NoOfSubKeys, //ignored
  3708. &pWinsCnf->NoOfDataFiles
  3709. );
  3710. }
  3711. if (pWinsCnf->NoOfDataFiles > 0)
  3712. {
  3713. DWORD Index;
  3714. PWINSCNF_DATAFILE_INFO_T pTmp;
  3715. TCHAR ValNmBuff[MAX_PATH];
  3716. DWORD ValNmBuffSz = MAX_PATH;
  3717. //
  3718. // Allocate buffer big enough to hold data for
  3719. // the number of subkeys found under the PULL key
  3720. //
  3721. BuffSize = WINSCNF_FILE_INFO_SZ * pWinsCnf->NoOfDataFiles;
  3722. WinsMscAlloc( BuffSize, &pWinsCnf->pStaticDataFile);
  3723. /*
  3724. * Enumerate the values
  3725. */
  3726. for(
  3727. Index = 0, pTmp = pWinsCnf->pStaticDataFile;
  3728. Index < pWinsCnf->NoOfDataFiles;
  3729. // no third expression
  3730. )
  3731. {
  3732. ValNmBuffSz = sizeof(ValNmBuff)/sizeof(TCHAR); //init before
  3733. //every call
  3734. BuffSize = sizeof(pWinsCnf->pStaticDataFile->FileNm);
  3735. RetVal = RegEnumValue(
  3736. DFKey,
  3737. Index, //key
  3738. ValNmBuff,
  3739. &ValNmBuffSz,
  3740. (LPDWORD)NULL, //reserved
  3741. &pTmp->StrType,
  3742. (LPBYTE)(pTmp->FileNm),//ptr to var. to
  3743. //hold name of
  3744. //datafile
  3745. &BuffSize //not looked at by us
  3746. );
  3747. if (RetVal != ERROR_SUCCESS)
  3748. {
  3749. continue;
  3750. }
  3751. //
  3752. // if StrType is not REG_SZ or REG_EXPAND_SZ, go to
  3753. // the next Value
  3754. //
  3755. if (
  3756. (pTmp->StrType != REG_EXPAND_SZ)
  3757. &&
  3758. (pTmp->StrType != REG_SZ)
  3759. )
  3760. {
  3761. continue;
  3762. }
  3763. Index++;
  3764. pTmp = (PWINSCNF_DATAFILE_INFO_T)((LPBYTE)pTmp +
  3765. WINSCNF_FILE_INFO_SZ);
  3766. }
  3767. //
  3768. // If not even one valid name was retrieved, get rid of the
  3769. // buffer
  3770. //
  3771. if (Index == 0)
  3772. {
  3773. //
  3774. // Get rid of the buffer
  3775. //
  3776. WinsMscDealloc((LPBYTE)pWinsCnf->pStaticDataFile);
  3777. //
  3778. // We will use the default
  3779. //
  3780. pWinsCnf->pStaticDataFile = pSaveDef;
  3781. }
  3782. else
  3783. {
  3784. //
  3785. // Get rid of the default name buffer
  3786. //
  3787. WinsMscDealloc((LPBYTE)pSaveDef);
  3788. }
  3789. pWinsCnf->NoOfDataFiles = Index;
  3790. }
  3791. } // end of try ..
  3792. except (EXCEPTION_EXECUTE_HANDLER) {
  3793. DBGPRINTEXC("WinsCnfGetNamesOfDataFiles");
  3794. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_SFT_ERR);
  3795. RetStat = WINS_FAILURE;
  3796. }
  3797. REG_M(
  3798. RegCloseKey(DFKey),
  3799. WINS_EVT_CANT_CLOSE_KEY,
  3800. WINS_EXC_CANT_CLOSE_KEY
  3801. );
  3802. DBGLEAVE("WinsCnfGetNamesOfDataFiles\n");
  3803. return(RetStat);
  3804. }
  3805. VOID
  3806. WinsCnfCloseKeys(
  3807. VOID
  3808. )
  3809. /*++
  3810. Routine Description:
  3811. This function closes the the open keys. The keys closed are
  3812. the WINS key, the PARTNERS key, and the PARAMETERS key.
  3813. Arguments:
  3814. None
  3815. Externals Used:
  3816. sfParametersKeyExists
  3817. sfPartnersKeyExists
  3818. Return Value:
  3819. None
  3820. Error Handling:
  3821. Called by:
  3822. Reinit()
  3823. Side Effects:
  3824. Comments:
  3825. We don't look at the return code of RegCloseKey. This is because
  3826. we might call this function even with the key not being open (not
  3827. the case currently).
  3828. --*/
  3829. {
  3830. //
  3831. // Close the PARAMETERS key if it is open
  3832. //
  3833. if (sfParametersKeyOpen)
  3834. {
  3835. (VOID)RegCloseKey(sParametersKey);
  3836. }
  3837. //
  3838. // Close the PARTNERS key if it is open
  3839. //
  3840. if (sfPartnersKeyOpen)
  3841. {
  3842. (VOID)RegCloseKey(sPartnersKey);
  3843. }
  3844. #if 0
  3845. //
  3846. // NOTE NOTE NOTE: Build 436. If we attempt to close a key that has been
  3847. // deleted from the registry NT comes down
  3848. //
  3849. //
  3850. // Close the WINS key
  3851. //
  3852. (VOID)RegCloseKey(sConfigRoot);
  3853. #endif
  3854. return;
  3855. } //WinsCnfCloseKeys()
  3856. VOID
  3857. ChkWinsSubKeys(
  3858. VOID
  3859. )
  3860. /*++
  3861. Routine Description:
  3862. This function is called to check whether we have the PARTNERS
  3863. and PARAMETERS sub-keys under the root subkey of WINS.
  3864. Arguments:
  3865. None
  3866. Externals Used:
  3867. None
  3868. Return Value:
  3869. None
  3870. Error Handling:
  3871. Called by:
  3872. Reinit() in nms.c
  3873. Side Effects:
  3874. Comments:
  3875. None
  3876. --*/
  3877. {
  3878. DWORD NoOfSubKeys = 0;
  3879. DWORD KeyNameSz;
  3880. TCHAR KeyName[20];
  3881. FILETIME LastWrite;
  3882. LONG RetVal;
  3883. BOOL fParametersKey = FALSE;
  3884. BOOL fPartnersKey = FALSE;
  3885. /*
  3886. * Get each subkey's name
  3887. */
  3888. RetVal = ERROR_SUCCESS;
  3889. for(
  3890. ;
  3891. RetVal == ERROR_SUCCESS;
  3892. NoOfSubKeys++
  3893. )
  3894. {
  3895. KeyNameSz = sizeof(KeyName)/sizeof(TCHAR); //init before every call
  3896. RetVal = RegEnumKeyEx(
  3897. sConfigRoot,
  3898. NoOfSubKeys, //key
  3899. KeyName,
  3900. &KeyNameSz,
  3901. NULL, //reserved
  3902. NULL, //don't need class name
  3903. NULL, //ptr to var. to hold class name
  3904. &LastWrite //not looked at by us
  3905. );
  3906. if (RetVal != ERROR_SUCCESS)
  3907. {
  3908. continue;
  3909. }
  3910. if (lstrcmp(KeyName, _WINS_CFG_PARAMETERS_KEY) == 0)
  3911. {
  3912. fParametersKey = TRUE;
  3913. }
  3914. if (lstrcmp(KeyName, _WINS_CFG_PARTNERS_KEY) == 0)
  3915. {
  3916. fPartnersKey = TRUE;
  3917. }
  3918. }
  3919. //
  3920. // if the Parameters key does not exist but it existed before,
  3921. // close the key to get rid of the handle we have
  3922. //
  3923. if (!fParametersKey)
  3924. {
  3925. if (sfParametersKeyExists)
  3926. {
  3927. sfParametersKeyExists = FALSE;
  3928. sfParametersKeyOpen = FALSE;
  3929. }
  3930. }
  3931. else
  3932. {
  3933. sfParametersKeyExists = TRUE;
  3934. }
  3935. //
  3936. // if the Partners key does not exist but it existed before,
  3937. // close the key to get rid of the handle we have
  3938. //
  3939. if (!fPartnersKey)
  3940. {
  3941. if (sfPartnersKeyExists)
  3942. {
  3943. sfPartnersKeyExists = FALSE;
  3944. sfPartnersKeyOpen = FALSE;
  3945. }
  3946. }
  3947. else
  3948. {
  3949. sfPartnersKeyExists = TRUE;
  3950. }
  3951. return;
  3952. } //ChkWinsSubKeys()
  3953. VOID
  3954. GetSpTimeData(
  3955. HKEY SubKey,
  3956. LPSYSTEMTIME pCurrTime,
  3957. LPBOOL pfSpTime,
  3958. LPDWORD pSpTimeIntvl
  3959. /*++
  3960. Routine Description:
  3961. This function is called to get the specific time and period information
  3962. for a PULL/PUSH record.
  3963. Arguments:
  3964. SubKey - Key of a WINS under the Pull/Push key
  3965. pCnfRFec - ptr to the Conf. record of the WINS
  3966. Externals Used:
  3967. None
  3968. Return Value:
  3969. Success status codes -- WINS_SUCCESS
  3970. Error status codes -- WINS_NO_SP_TIME
  3971. Error Handling:
  3972. Called by:
  3973. GetPnrInfo
  3974. Side Effects:
  3975. Comments:
  3976. None
  3977. --*/
  3978. )
  3979. {
  3980. DWORD ValTyp;
  3981. BYTE tSpTime[MAX_SZ_SIZE];
  3982. BYTE SpTime[MAX_SZ_SIZE];
  3983. LPBYTE pSpTime = SpTime;
  3984. DWORD Sz = sizeof(tSpTime);
  3985. LONG RetVal;
  3986. DWORD Hr = 0;
  3987. DWORD Mt = 0;
  3988. DWORD Sec = 0;
  3989. LONG TimeInt;
  3990. // DBGENTER("GetSpTimeData\n");
  3991. *pfSpTime = FALSE;
  3992. try {
  3993. Sz = sizeof(tSpTime);
  3994. RetVal = RegQueryValueEx(
  3995. SubKey,
  3996. WINSCNF_SP_TIME_NM,
  3997. NULL, //reserved; must be NULL
  3998. &ValTyp,
  3999. tSpTime,
  4000. &Sz
  4001. );
  4002. //
  4003. // If the user has not specifed a specific time, then we use
  4004. // the current time as the specific time. For current time,
  4005. // the interval is 0
  4006. //
  4007. if (RetVal == ERROR_SUCCESS)
  4008. {
  4009. #ifdef UNICODE
  4010. (VOID)WinsMscConvertUnicodeStringToAscii(tSpTime, SpTime, MAX_SZ_SIZE);
  4011. #else
  4012. pSpTime = tSpTime;
  4013. #endif
  4014. RetVal = (LONG)sscanf(pSpTime, "%d:%d:%d", &Hr, &Mt, &Sec);
  4015. if ((RetVal == EOF) || (RetVal == 0))
  4016. {
  4017. DBGPRINT1(ERR, "GetSpTime: Wrong time format (%s)\n",
  4018. pSpTime);
  4019. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_WRONG_TIME_FORMAT);
  4020. }
  4021. else
  4022. {
  4023. *pSpTimeIntvl = 0;
  4024. if ((Hr <= 23) && (Mt <= 59) && (Sec <= 59))
  4025. {
  4026. TimeInt = ((Hr * 3600) + (Mt * 60) + Sec) -
  4027. ((pCurrTime->wHour * 3600) +
  4028. (pCurrTime->wMinute * 60) +
  4029. pCurrTime->wSecond);
  4030. if (TimeInt < 0)
  4031. {
  4032. *pSpTimeIntvl = (24 * 3600) + TimeInt;
  4033. }
  4034. else
  4035. {
  4036. *pSpTimeIntvl = TimeInt;
  4037. }
  4038. *pfSpTime = TRUE;
  4039. DBGPRINT1(DET, "GetSpTimeData: Sp. Time Interval is %d\n",
  4040. *pSpTimeIntvl);
  4041. }
  4042. else
  4043. {
  4044. DBGPRINT0(DET, "GetSpTimeData: WRONG TIME FORMAT\n");
  4045. }
  4046. }
  4047. }
  4048. }
  4049. except (EXCEPTION_EXECUTE_HANDLER) {
  4050. DBGPRINTEXC("GetSpTime");
  4051. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_CONFIG_ERR);
  4052. }
  4053. // DBGLEAVE("GetSpTimeData\n");
  4054. return;
  4055. }
  4056. #if MCAST > 0
  4057. STATUS
  4058. WinsCnfAddPnr(
  4059. RPL_RR_TYPE_E RRType_e,
  4060. LPBYTE pPnrAdd
  4061. )
  4062. /*++
  4063. Routine Description:
  4064. Arguments:
  4065. Externals Used:
  4066. None
  4067. Return Value:
  4068. Success status codes --
  4069. Error status codes --
  4070. Error Handling:
  4071. Called by:
  4072. Side Effects:
  4073. Comments:
  4074. None
  4075. --*/
  4076. {
  4077. LONG RetVal;
  4078. HKEY CnfKey;
  4079. HKEY PnrKey;
  4080. DWORD NewKeyInd;
  4081. DBGENTER("WinsCnfAddPnr\n");
  4082. /*
  4083. * Open the key (PULL/PUSH)
  4084. */
  4085. RetVal = RegOpenKeyEx(
  4086. sConfigRoot, //predefined key value
  4087. RRType_e == RPL_E_PULL ?
  4088. _WINS_CFG_PULL_KEY :
  4089. _WINS_CFG_PUSH_KEY, //subkey for WINS
  4090. 0, //must be zero (reserved)
  4091. KEY_CREATE_SUB_KEY, //we want "subkey create" priv
  4092. &CnfKey //handle to key
  4093. );
  4094. if (RetVal != ERROR_SUCCESS)
  4095. {
  4096. CHECK("Is there any need to log this")
  4097. WINSEVT_LOG_INFO_M(
  4098. RetVal,
  4099. RRType_e == RPL_E_PULL ?
  4100. WINS_EVT_CANT_OPEN_PULL_KEY :
  4101. WINS_EVT_CANT_OPEN_PUSH_KEY
  4102. );
  4103. return (WINS_FAILURE);
  4104. }
  4105. //
  4106. // Add the pnr
  4107. //
  4108. RetVal = RegCreateKeyExA(
  4109. CnfKey, //predefined key value
  4110. pPnrAdd, //subkey for WINS
  4111. 0, //must be zero (reserved)
  4112. "Class", //class -- may change in future
  4113. REG_OPTION_NON_VOLATILE, //non-volatile information
  4114. KEY_ALL_ACCESS, //we desire all access to the keyo
  4115. NULL, //let key have default sec. attributes
  4116. &PnrKey, //handle to key
  4117. &NewKeyInd //is it a new key (out arg)
  4118. );
  4119. if (RetVal != ERROR_SUCCESS)
  4120. {
  4121. WINSEVT_LOG_M(
  4122. RetVal,
  4123. RRType_e == RPL_E_PULL ? WINS_EVT_CANT_OPEN_PULL_SUBKEY
  4124. : WINS_EVT_CANT_OPEN_PUSH_SUBKEY
  4125. );
  4126. DBGPRINT3(ERR, "WinsCnfAddPnr: Could not create key with address = (%s) under the %s Key. RetVal = (%d)\n", pPnrAdd,
  4127. RRType_e == RPL_E_PULL ? "PULL" : "PUSH",
  4128. RetVal);
  4129. return(WINS_FAILURE);
  4130. }
  4131. else
  4132. {
  4133. if (NewKeyInd != REG_CREATED_NEW_KEY)
  4134. {
  4135. DBGPRINT2(ERR, "WinsCnfAddPnr: key with address = (%s) under the %s Key already present\n", pPnrAdd, RRType_e == RPL_E_PULL ? "PULL" : "PUSH");
  4136. }
  4137. else
  4138. {
  4139. //
  4140. // If Pull pnr, add the time interval
  4141. //
  4142. if (RRType_e == RPL_E_PULL)
  4143. {
  4144. //
  4145. // Add the time interval
  4146. //
  4147. SetVal(PnrKey, WINSCNF_RPL_INTERVAL_NM, REG_DWORD,
  4148. (LPWSTR)WINSCNF_TIME_INT_W_SELF_FND_PNRS, sizeof(DWORD));
  4149. }
  4150. SetVal(PnrKey, WINSCNF_SELF_FND_NM, REG_DWORD,
  4151. (LPWSTR)TRUE, sizeof(DWORD));
  4152. }
  4153. RegCloseKey(PnrKey);
  4154. RegCloseKey(CnfKey);
  4155. }
  4156. DBGLEAVE("WinsCnfAddPnr\n");
  4157. return(WINS_SUCCESS);
  4158. }
  4159. STATUS
  4160. WinsCnfDelPnr(
  4161. RPL_RR_TYPE_E RRType_e,
  4162. LPBYTE pPnrAdd
  4163. )
  4164. /*++
  4165. Routine Description:
  4166. Arguments:
  4167. Externals Used:
  4168. None
  4169. Return Value:
  4170. Success status codes --
  4171. Error status codes --
  4172. Error Handling:
  4173. Called by:
  4174. Side Effects:
  4175. Comments:
  4176. None
  4177. --*/
  4178. {
  4179. LONG RetVal;
  4180. HKEY TypeOfPnrKey;
  4181. HKEY PnrKey;
  4182. //WCHAR Key[160];
  4183. WCHAR String[160];
  4184. BOOL fSelfFnd;
  4185. DWORD Sz;
  4186. DWORD ValType;
  4187. DBGENTER("WinsCnfDelPnr\n");
  4188. WinsMscConvertAsciiStringToUnicode(pPnrAdd, (LPBYTE)String, sizeof(String)/sizeof(WCHAR));
  4189. /*
  4190. * Open the key (PULL/PUSH)
  4191. */
  4192. RetVal = RegOpenKeyEx(
  4193. sConfigRoot, //predefined key value
  4194. RRType_e == RPL_E_PULL ?
  4195. _WINS_CFG_PULL_KEY :
  4196. _WINS_CFG_PUSH_KEY,
  4197. 0, //must be zero (reserved)
  4198. KEY_ALL_ACCESS,
  4199. &TypeOfPnrKey //handle to key
  4200. );
  4201. if (RetVal != ERROR_SUCCESS)
  4202. {
  4203. CHECK("Is there any need to log this")
  4204. WINSEVT_LOG_INFO_M(
  4205. WINS_SUCCESS,
  4206. RRType_e == RPL_E_PULL ?
  4207. WINS_EVT_CANT_OPEN_PULL_KEY :
  4208. WINS_EVT_CANT_OPEN_PUSH_KEY
  4209. );
  4210. //--ft: Prefix bug 444974 - this key has to exist. If absurdly is missing, we won't find
  4211. // the partner anyhow.
  4212. return (WINS_SUCCESS);
  4213. }
  4214. RetVal = RegOpenKeyEx(
  4215. TypeOfPnrKey, //predefined key value
  4216. String,
  4217. 0, //must be zero (reserved)
  4218. KEY_ALL_ACCESS, //we want "subkey create" priv
  4219. &PnrKey //handle to key
  4220. );
  4221. if (RetVal != ERROR_SUCCESS)
  4222. {
  4223. DBGPRINT3(ERR, "WinsCnfDelPnr: %s Pnr with address = (%s) is Non-existent. RetVal = (%d)",
  4224. RRType_e == RPL_E_PULL ? "PULL" : "PUSH", pPnrAdd,
  4225. RetVal);
  4226. return(WINS_SUCCESS);
  4227. }
  4228. else
  4229. {
  4230. Sz = sizeof(fSelfFnd);
  4231. RetVal = RegQueryValueEx(
  4232. PnrKey,
  4233. WINSCNF_SELF_FND_NM,
  4234. NULL,
  4235. &ValType,
  4236. (LPBYTE)&fSelfFnd,
  4237. &Sz
  4238. );
  4239. //
  4240. // If SelfFnd is there and it's value is 1, delete it
  4241. //
  4242. if ((RetVal == ERROR_SUCCESS) && (fSelfFnd == 1))
  4243. {
  4244. RetVal = RegDeleteKey(TypeOfPnrKey, String);
  4245. if (RetVal != ERROR_SUCCESS)
  4246. {
  4247. DBGPRINT3(ERR, "WinsCnfDelPnr: Could not delete %s Pnr with address = (%s). RetVal = (%d)",
  4248. RRType_e == RPL_E_PULL ? "PULL" : "PUSH", pPnrAdd,
  4249. RetVal);
  4250. RegCloseKey(PnrKey);
  4251. return(WINS_FAILURE);
  4252. }
  4253. }
  4254. RegCloseKey(TypeOfPnrKey);
  4255. }
  4256. DBGLEAVE("WinsCnfDelPnr\n");
  4257. return(WINS_SUCCESS);
  4258. }
  4259. DWORD
  4260. SetVal(
  4261. HKEY RootKey,
  4262. LPWSTR pName,
  4263. DWORD ValType,
  4264. LPWSTR pVal,
  4265. DWORD ValSize
  4266. )
  4267. {
  4268. UINT Status = WINS_SUCCESS;
  4269. LONG RetVal;
  4270. DWORD Val;
  4271. if (ValType == REG_DWORD)
  4272. {
  4273. Val = PtrToUlong (pVal);
  4274. }
  4275. RetVal = RegSetValueEx(
  4276. RootKey,
  4277. pName,
  4278. 0, //reserved -- must be 0
  4279. ValType,
  4280. ValType == REG_DWORD ? (LPBYTE)&Val : (LPBYTE)pVal,
  4281. ValType == REG_DWORD ? ValSize : lstrlen(pVal)
  4282. );
  4283. if (RetVal != ERROR_SUCCESS)
  4284. {
  4285. printf("SetVal: Could not set value of %s\n", pName);
  4286. Status = WINS_FAILURE;
  4287. }
  4288. return(Status);
  4289. }
  4290. #endif
  4291. DWORD
  4292. WinsCnfWriteReg(
  4293. LPVOID pTmp
  4294. )
  4295. /*++
  4296. Routine Description:
  4297. This function write the value of the version counter to be used
  4298. at the next invocation.
  4299. Arguments:
  4300. pTmp - Will be NULL if WinsCnfNextTimeVersNo was found in the registry
  4301. when WINS came up.
  4302. Externals Used:
  4303. NmsHighWaterMarkVersNo
  4304. NmsVersNoToStartFromNextTime
  4305. NmsNmhNamRegCrtSec
  4306. NmsRangeSize
  4307. NmsHalfRangeSize
  4308. sfVersNoChanged
  4309. sfVersNoUpdThdExists
  4310. Return Value:
  4311. VOID
  4312. Error Handling:
  4313. Called by:
  4314. NMSNMH_INC_VERS_COUNTER_M
  4315. Side Effects:
  4316. Comments:
  4317. None
  4318. --*/
  4319. {
  4320. LONG RetVal;
  4321. LONG RetVal2;
  4322. VERS_NO_T VersNo;
  4323. DBGENTER("WinsCnfWriteReg\n");
  4324. EnterCriticalSection(&NmsNmhNamRegCrtSec);
  4325. //
  4326. // if pTmp is not NULL, it means that either WINS did not find
  4327. // Next time's version number in the registry or that the max. version
  4328. // number in the db is greater than the high water mark we set at
  4329. // initialization. In the former case, we already have the correct
  4330. // value in NmsNmhToStartFromNextTime, so the if body is not executed.
  4331. //
  4332. if (!pTmp || LiLtr(NmsHighWaterMarkVersNo, NmsNmhMyMaxVersNo))
  4333. {
  4334. NmsHighWaterMarkVersNo.QuadPart = LiAdd(NmsVersNoToStartFromNextTime,
  4335. NmsHalfRangeSize);
  4336. NmsVersNoToStartFromNextTime.QuadPart = LiAdd(NmsVersNoToStartFromNextTime,
  4337. NmsRangeSize);
  4338. }
  4339. VersNo = NmsVersNoToStartFromNextTime;
  4340. LeaveCriticalSection(&NmsNmhNamRegCrtSec);
  4341. RetVal = RegSetValueEx(
  4342. sConfigRoot,
  4343. WINSCNF_INT_VERSNO_NEXTTIME_LW_NM,
  4344. 0, //reserved -- must be 0
  4345. REG_DWORD,
  4346. (LPBYTE)&VersNo.LowPart,
  4347. sizeof(DWORD)
  4348. );
  4349. RetVal2 = RegSetValueEx(
  4350. sConfigRoot,
  4351. WINSCNF_INT_VERSNO_NEXTTIME_HW_NM,
  4352. 0, //reserved -- must be 0
  4353. REG_DWORD,
  4354. (LPBYTE)&VersNo.HighPart,
  4355. sizeof(DWORD)
  4356. );
  4357. if ((RetVal != ERROR_SUCCESS) || (RetVal2 != ERROR_SUCCESS))
  4358. {
  4359. DBGPRINT2(ERR, "WinsCnfWriteReg - Could not set Next time's start version counter value in the registry. The new value is (%d %d)\n", VersNo.HighPart, VersNo.LowPart);
  4360. }
  4361. EnterCriticalSection(&NmsNmhNamRegCrtSec);
  4362. WinsCnfRegUpdThdExists = FALSE;
  4363. LeaveCriticalSection(&NmsNmhNamRegCrtSec);
  4364. DBGLEAVE("WinsCnfWriteReg\n");
  4365. return(WINS_SUCCESS);
  4366. }
  4367. #if defined (DBGSVC) && !defined (WINS_INTERACTIVE)
  4368. VOID
  4369. WinsCnfReadWinsDbgFlagValue(
  4370. VOID
  4371. )
  4372. {
  4373. DWORD Sz;
  4374. DWORD ValTyp;
  4375. WinsDbg = 0; //set it to zero now. It was set to a value by Init() in
  4376. //nms.c
  4377. Sz = sizeof(WinsDbg);
  4378. (VOID)RegQueryValueEx(
  4379. sParametersKey,
  4380. WINSCNF_DBGFLAGS_NM,
  4381. NULL, //reserved; must be NULL
  4382. &ValTyp,
  4383. (LPBYTE)&WinsDbg,
  4384. &Sz
  4385. );
  4386. return;
  4387. }
  4388. #endif
  4389. VOID
  4390. ReadSpecGrpMasks(
  4391. PWINSCNF_CNF_T pWinsCnf
  4392. )
  4393. /*++
  4394. Routine Description:
  4395. This function is called to read in the special group masks specified
  4396. under the SpecialGrpMasks key
  4397. Arguments:
  4398. Externals Used:
  4399. None
  4400. Return Value:
  4401. Success status codes --
  4402. Error status codes --
  4403. Error Handling:
  4404. Called by:
  4405. Side Effects:
  4406. Comments:
  4407. None
  4408. --*/
  4409. {
  4410. DWORD NoOfSubKeys;
  4411. HKEY SGMKey;
  4412. BOOL fKeyOpen = FALSE;
  4413. LONG RetVal;
  4414. DBGENTER("ReadSpecGrpMasks\n");
  4415. try {
  4416. /*
  4417. * Open the SPEC_GRP_MASKS key
  4418. */
  4419. RetVal = RegOpenKeyEx(
  4420. sParametersKey, //predefined key value
  4421. _WINS_CFG_SPEC_GRP_MASKS_KEY,
  4422. 0, //must be zero (reserved)
  4423. KEY_READ, //we desire read access to the keyo
  4424. &SGMKey //handle to key
  4425. );
  4426. if (RetVal == ERROR_SUCCESS)
  4427. {
  4428. fKeyOpen = TRUE;
  4429. //
  4430. // Get the count of data files listed under the DATAFILES
  4431. // key
  4432. //
  4433. GetKeyInfo(
  4434. SGMKey,
  4435. WINSCNF_E_SPEC_GRP_MASKS_KEY,
  4436. &NoOfSubKeys, //ignored
  4437. &pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks
  4438. );
  4439. if (pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks > 0)
  4440. {
  4441. DWORD Index;
  4442. LPBYTE pTmp;
  4443. TCHAR ValNmBuff[5];
  4444. DWORD ValNmBuffSz;
  4445. DWORD StrType;
  4446. LPBYTE pByte;
  4447. DWORD BuffSize;
  4448. CHAR Tmp[WINS_MAX_FILENAME_SZ];
  4449. #ifdef UNICODE
  4450. WCHAR Str[WINSCNF_SPEC_GRP_MASK_SZ];
  4451. #endif
  4452. //
  4453. // Allocate buffer big enough to hold data for
  4454. // the number of subkeys found under the PULL key
  4455. //
  4456. BuffSize = (WINSCNF_SPEC_GRP_MASK_SZ + 1) *
  4457. pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks;
  4458. WinsMscAlloc( BuffSize, &pWinsCnf->SpecGrpMasks.pSpecGrpMasks);
  4459. /*
  4460. * Enumerate the values
  4461. */
  4462. for(
  4463. Index = 0, pTmp = pWinsCnf->SpecGrpMasks.pSpecGrpMasks;
  4464. Index < pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks;
  4465. // no third expression
  4466. )
  4467. {
  4468. ValNmBuffSz = sizeof(ValNmBuff)/sizeof(TCHAR); //init before
  4469. //every call
  4470. BuffSize = WINSCNF_SPEC_GRP_MASK_SZ;
  4471. RetVal = RegEnumValue(
  4472. SGMKey,
  4473. Index, //key
  4474. ValNmBuff,
  4475. &ValNmBuffSz,
  4476. (LPDWORD)NULL, //reserved
  4477. &StrType,
  4478. #ifdef UNICODE
  4479. (LPBYTE)Str,
  4480. #else
  4481. pTmp,
  4482. #endif
  4483. &BuffSize
  4484. );
  4485. if (RetVal != ERROR_SUCCESS)
  4486. {
  4487. continue;
  4488. }
  4489. //
  4490. // if StrType is not REG_SZ go to the next Value
  4491. //
  4492. if (StrType != REG_SZ)
  4493. {
  4494. continue;
  4495. }
  4496. if (BuffSize != WINSCNF_SPEC_GRP_MASK_SZ)
  4497. {
  4498. DBGPRINT1(ERR, "ReadSpecGrpMasks: Wrong spec. grp mask (%s)\n", pTmp);
  4499. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_WRONG_SPEC_GRP_MASK_M);
  4500. continue;
  4501. }
  4502. else
  4503. {
  4504. #ifdef UNICODE
  4505. WinsMscConvertUnicodeStringToAscii(
  4506. (LPBYTE)Str,
  4507. (LPBYTE)Tmp,
  4508. WINSCNF_SPEC_GRP_MASK_SZ
  4509. );
  4510. #endif
  4511. pByte = (LPBYTE)Tmp;
  4512. for (Index = 0; Index < WINSCNF_SPEC_GRP_MASK_SZ;
  4513. Index++, pByte++)
  4514. {
  4515. *pByte = (BYTE)CharUpperA((LPSTR)*pByte);
  4516. if (
  4517. ((*pByte >= '0') && (*pByte <= '9'))
  4518. ||
  4519. ((*pByte >= 'A') && (*pByte <= 'F'))
  4520. )
  4521. {
  4522. continue;
  4523. }
  4524. else
  4525. {
  4526. break;
  4527. }
  4528. }
  4529. if (Index > WINSCNF_SPEC_GRP_MASK_SZ)
  4530. {
  4531. DBGPRINT1(ERR, "ReadSpecGrpMasks: Wrong spec. grp mask (%s)\n", pTmp);
  4532. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_WRONG_SPEC_GRP_MASK_M);
  4533. continue;
  4534. }
  4535. *(pTmp + WINSCNF_SPEC_GRP_MASK_SZ) = EOS;
  4536. }
  4537. Index++;
  4538. pTmp += WINSCNF_SPEC_GRP_MASK_SZ + 1;
  4539. }
  4540. //
  4541. // If not even one valid name was retrieved, get rid of the
  4542. // buffer
  4543. //
  4544. if (Index == 0)
  4545. {
  4546. //
  4547. // Get rid of the buffer
  4548. //
  4549. WinsMscDealloc((LPBYTE)pWinsCnf->SpecGrpMasks.pSpecGrpMasks);
  4550. }
  4551. pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks = Index;
  4552. }
  4553. } // end of if
  4554. } // end of try ..
  4555. except (EXCEPTION_EXECUTE_HANDLER) {
  4556. DBGPRINTEXC("ReadSpecGrpMasks");
  4557. WINSEVT_LOG_D_M(GetExceptionCode(), WINS_EVT_CANT_INIT);
  4558. }
  4559. if (fKeyOpen && RegCloseKey(SGMKey) != ERROR_SUCCESS)
  4560. {
  4561. WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_CANT_CLOSE_KEY);
  4562. DBGPRINT0(ERR, "ReadSpecGrpMasks: Can not read the spec. grp. mask. key\n");
  4563. }
  4564. DBGLEAVE("ReadSpecGrpMasks\n");
  4565. return;
  4566. }
  4567. #if 0
  4568. int
  4569. __cdecl
  4570. CompUpdCnt(
  4571. CONST LPVOID pElem1,
  4572. CONST LPVOID pElem2
  4573. )
  4574. /*++
  4575. Routine Description:
  4576. This function is called by qsort crtl function to compare two
  4577. elements of the array that has to be sorted
  4578. Arguments:
  4579. pElem1 - ptr to first element
  4580. pElem1 - ptr to second element
  4581. Externals Used:
  4582. None
  4583. Return Value:
  4584. -1 if first element is < second element
  4585. = 0 if first element is == second element
  4586. 1 if first element is > second element
  4587. Error Handling:
  4588. Called by:
  4589. qsort (which is called by WinsCnfReadPartnerInfo
  4590. Side Effects:
  4591. Comments:
  4592. Not used currently
  4593. --*/
  4594. {
  4595. CONST PRPL_CONFIG_REC_T pCnfRec1 = pElem1;
  4596. CONST PRPL_CONFIG_REC_T pCnfRec2 = pElem2;
  4597. if (pCnfRec1->UpdateCount < pCnfRec2->UpdateCount)
  4598. {
  4599. return(-1);
  4600. }
  4601. else
  4602. {
  4603. if (pCnfRec1->UpdateCount == pCnfRec2->UpdateCount)
  4604. {
  4605. return(0);
  4606. }
  4607. }
  4608. //
  4609. // The first record has a higher UpdateCount than the second one
  4610. //
  4611. return(1);
  4612. }
  4613. #endif
  4614. #ifdef WINSDBG
  4615. VOID
  4616. PrintRecs(
  4617. RPL_RR_TYPE_E RRType_e,
  4618. PWINSCNF_CNF_T pWinsCnf
  4619. )
  4620. {
  4621. return;
  4622. }
  4623. #endif