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

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