5461 lines
174 KiB
C
5461 lines
174 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1990 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
winscnf.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module contains functions that deal with the configuration
|
|||
|
information for the WINS
|
|||
|
|
|||
|
Portability:
|
|||
|
|
|||
|
This module is portable
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Pradeep Bahl (PradeepB) Dec-1992
|
|||
|
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
Modification date Person Description of modification
|
|||
|
----------------- ------- ----------------------------
|
|||
|
--*/
|
|||
|
|
|||
|
/*
|
|||
|
* Includes
|
|||
|
*/
|
|||
|
|
|||
|
#include "wins.h"
|
|||
|
#include <winsock2.h>
|
|||
|
#include <string.h>
|
|||
|
#include <stddef.h>
|
|||
|
#include <stdlib.h>
|
|||
|
#include <search.h>
|
|||
|
#include "comm.h"
|
|||
|
#include "winreg.h"
|
|||
|
#include "winsevt.h"
|
|||
|
#include "winsmsc.h"
|
|||
|
#include "winscnf.h"
|
|||
|
#include "nms.h"
|
|||
|
#include "nmsnmh.h"
|
|||
|
#include "rpl.h"
|
|||
|
#include "rplpush.h"
|
|||
|
#include "winsintf.h"
|
|||
|
#include "nmfilter.h"
|
|||
|
#include <resapi.h>
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* Local Macro Declarations
|
|||
|
*/
|
|||
|
|
|||
|
//
|
|||
|
// Size of max string that a user can input in a REG_SZ field
|
|||
|
//
|
|||
|
#define MAX_SZ_SIZE 80
|
|||
|
|
|||
|
#define REG_M(fn, evt, exc) \
|
|||
|
{ \
|
|||
|
if((fn) != ERROR_SUCCESS) \
|
|||
|
{ \
|
|||
|
WINSEVT_LOG_M( \
|
|||
|
WINS_FATAL_ERR, \
|
|||
|
(evt) \
|
|||
|
); \
|
|||
|
WINS_RAISE_EXC_M((exc)); \
|
|||
|
} \
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// pointer to default path for log file. If you change this to a NON NULL
|
|||
|
// value, make sure you don't try to free the memory in SetSystemParam
|
|||
|
// in nmsdb.c
|
|||
|
//
|
|||
|
#define DEFAULT_LOG_PATH NULL
|
|||
|
|
|||
|
#define _WINS_CFG_KEY \
|
|||
|
TEXT("System\\CurrentControlSet\\Services\\Wins")
|
|||
|
#define _WINS_CFG_PARAMETERS_KEY TEXT("Parameters")
|
|||
|
#define _WINS_CFG_PARTNERS_KEY TEXT("Partners")
|
|||
|
#define _WINS_CFG_CC_KEY TEXT("Parameters\\ConsistencyCheck")
|
|||
|
#define _WINS_CFG_PULL_KEY TEXT("Partners\\Pull")
|
|||
|
#define _WINS_CFG_PUSH_KEY TEXT("Partners\\Push")
|
|||
|
#define _WINS_CFG_DATAFILES_KEY TEXT("Parameters\\Datafiles")
|
|||
|
#define _WINS_CFG_SPEC_GRP_MASKS_KEY TEXT("Parameters\\InternetGrpMasks")
|
|||
|
|
|||
|
#define _WINS_LOG_KEY \
|
|||
|
TEXT("System\\CurrentControlSet\\Services\\EventLog\\Application\\WinsInt")
|
|||
|
#define _WINS_MSGFILE_SKEY TEXT("EventMessageFile")
|
|||
|
|
|||
|
|
|||
|
#define _WINS_LOG_FILE_NAME TEXT("%SystemRoot%\\System32\\winsevnt.dll")
|
|||
|
|
|||
|
|
|||
|
#define _RPL_CLASS TEXT("RplClass")//class for Rpl Pull and Push
|
|||
|
//keys
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// The start version number should never be allowed to go above this number
|
|||
|
// This will avoid a wrap around.
|
|||
|
//
|
|||
|
|
|||
|
#define MAX_START_VERS_NO 0x0FFFFFFF
|
|||
|
|
|||
|
//
|
|||
|
// Names of event variables used for notification purposes
|
|||
|
//
|
|||
|
#ifdef WINSDBG
|
|||
|
#define WINS_KEY_CHG_EVT_NM TEXT("WinsKChgEvt")
|
|||
|
#define PARAMETERS_KEY_CHG_EVT_NM TEXT("WinsParamatersKChgEvt")
|
|||
|
#define PARTNERS_KEY_CHG_EVT_NM TEXT("WinsPartenersKChgEvt")
|
|||
|
#define CNF_CHG_EVT_NM TEXT("WinsConfigChangeEvt")
|
|||
|
#else
|
|||
|
#define WINS_KEY_CHG_EVT_NM NULL
|
|||
|
#define PARAMETERS_KEY_CHG_EVT_NM NULL
|
|||
|
#define PARTNERS_KEY_CHG_EVT_NM NULL
|
|||
|
#define CNF_CHG_EVT_NM NULL
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Values for the fStaticInit field of the configuration data structure
|
|||
|
//
|
|||
|
#define DO_STATIC_INIT TRUE
|
|||
|
#define DONT_DO_STATIC_INIT FALSE
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// defines for the InitTimeRpl and InitTimePush fields of WinsCnf
|
|||
|
//
|
|||
|
#define DO_INIT_TIME_RPL 1
|
|||
|
#define NO_INIT_TIME_RPL 0
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// NO_LIMIT_CHK_FLAG - for easing the task of testers
|
|||
|
//
|
|||
|
// If this flag is set in LogDetailedEvts DWORD, WINS skips all
|
|||
|
// checks for the min. values of the time intervals and Update Count.
|
|||
|
// This kind of operation of WINS is unsupported and is being provided
|
|||
|
// only to help out testers
|
|||
|
//
|
|||
|
#define NO_LIMIT_CHK_FLAG 0x80000000 //MSB is set.
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// If ErrEvt passed is 0, we don't log any message. NOTE: a WINS event
|
|||
|
// can never have 0 as its value (checkout winsevnt.mc)
|
|||
|
//
|
|||
|
#define QUERY_VALUE_M(Key, Str, ValTyp, Var, ErrEvt, DefVal) \
|
|||
|
{ \
|
|||
|
DWORD Sz = sizeof((Var)); \
|
|||
|
if (RegQueryValueEx( \
|
|||
|
(Key), \
|
|||
|
(Str), \
|
|||
|
NULL, \
|
|||
|
&(ValTyp), \
|
|||
|
(LPBYTE)&(Var), \
|
|||
|
&Sz \
|
|||
|
) != ERROR_SUCCESS \
|
|||
|
) \
|
|||
|
{ \
|
|||
|
if ((ErrEvt) != 0) \
|
|||
|
{ \
|
|||
|
WINSEVT_LOG_INFO_M( \
|
|||
|
WINS_SUCCESS, \
|
|||
|
(ErrEvt) \
|
|||
|
); \
|
|||
|
} \
|
|||
|
Var = DefVal; \
|
|||
|
} \
|
|||
|
}
|
|||
|
/*
|
|||
|
* Local Typedef Declarations
|
|||
|
*/
|
|||
|
|
|||
|
/*
|
|||
|
* Global Variable Definitions
|
|||
|
*/
|
|||
|
|
|||
|
CRITICAL_SECTION WinsCnfCnfCrtSec; //used for reinitialization
|
|||
|
//of certain fields of the
|
|||
|
//WinsCnf structure
|
|||
|
|
|||
|
|
|||
|
BOOL fWinsCnfRplEnabled = TRUE; //replication is enabled
|
|||
|
BOOL fWinsCnfScvEnabled = TRUE; //scavenging is enabled
|
|||
|
|
|||
|
FUTURES("use #ifdef PERF around the following three perf. mon. vars")
|
|||
|
BOOL fWinsCnfPerfMonEnabled = FALSE; //perf. mon is disabled
|
|||
|
BOOL fWinsCnfHighResPerfCntr = FALSE; //indicates whether the
|
|||
|
//hardware supports a high
|
|||
|
//performance counter
|
|||
|
LARGE_INTEGER LiWinsCnfPerfCntrFreq; //indicates the frequency of
|
|||
|
//the counter
|
|||
|
|
|||
|
BOOL fWinsCnfReadNextTimeVersNo = FALSE;
|
|||
|
DWORD WinsCnfCnfMagicNo = WINSCNF_INITIAL_CNF_MAGIC_NO;
|
|||
|
BOOL fWinsCnfInitStatePaused;
|
|||
|
|
|||
|
//TCHAR WinsCnfDb[WINS_MAX_FILENAME_SZ]; //db file to hold tables
|
|||
|
BOOL WinsCnfRegUpdThdExists = FALSE;
|
|||
|
//#define MAX_PATH_SIZE 200
|
|||
|
PTCHAR pWinsCnfNbtPath;
|
|||
|
|
|||
|
|
|||
|
BOOL sfNoLimitChk = FALSE; //to override the limit checks
|
|||
|
//
|
|||
|
// NetBt handle
|
|||
|
//
|
|||
|
HANDLE WinsCnfNbtHandle = NULL;
|
|||
|
|
|||
|
//
|
|||
|
//
|
|||
|
// Init the configuration structure with default values
|
|||
|
//
|
|||
|
WINSCNF_CNF_T WinsCnf = {
|
|||
|
WINSCNF_INITIAL_CNF_MAGIC_NO, //id
|
|||
|
NOTE("Change 1 to 0 before production")
|
|||
|
0, //Log detailed evts
|
|||
|
1, //default number of processors
|
|||
|
200, //default no. of db buffers
|
|||
|
{ 0, NULL}, //Spec.grp mask
|
|||
|
WINSCNF_E_INITING, //state
|
|||
|
WINSCNF_DEF_REFRESH_INTERVAL,
|
|||
|
WINSCNF_MIN_TOMBSTONE_INTERVAL,
|
|||
|
WINSCNF_MIN_TOMBSTONE_TIMEOUT,
|
|||
|
WINSCNF_MIN_VERIFY_INTERVAL,
|
|||
|
WINSCNF_SCV_CHUNK,
|
|||
|
WINSCNF_DEF_CHL_MAX_RETRIES,
|
|||
|
WINSCNF_DEF_INIT_CHL_RETRY_INTVL,
|
|||
|
WINSCNF_DB_NAME_ASCII, //db file name
|
|||
|
0, //no of STATIC files
|
|||
|
NULL, //ptr to file names
|
|||
|
DONT_DO_STATIC_INIT,
|
|||
|
(HANDLE)0, //notify event handle (WINS)
|
|||
|
(HANDLE)0, //not. evt hdl (PARAMETSRS)
|
|||
|
(HANDLE)0, //not. evt hdl (PARTNERS)
|
|||
|
(HANDLE)0, //Config change handle
|
|||
|
(HANDLE)0, //log event handle
|
|||
|
(DWORD)WINSINTF_E_NORMAL,
|
|||
|
WINSTHD_DEF_NO_NBT_THDS,
|
|||
|
WINSCNF_SCV_PRIORITY_LVL,
|
|||
|
WINSCNF_MIN_VALID_RPL_INTVL,//max Rpl
|
|||
|
//Time Intvl
|
|||
|
TRUE, //rpl. only with cnf partners
|
|||
|
TRUE, //add 1B to responses to 1C name queries
|
|||
|
#if MCAST > 0
|
|||
|
FALSE, //no rpl. with self found pnrs
|
|||
|
WINSCNF_DEF_MCAST_TTL,
|
|||
|
WINSCNF_DEF_MCAST_INTVL,
|
|||
|
#endif
|
|||
|
TRUE, //logging is on
|
|||
|
NULL, //current directory
|
|||
|
NULL, //no backup directory
|
|||
|
FALSE, //Do backup on term flg
|
|||
|
FALSE, //PStatic flag
|
|||
|
0, //type of persona list (0 = non-grata)
|
|||
|
0, //number of addresses in persona list
|
|||
|
NULL, //persona list
|
|||
|
WINSCNF_RPL_DEFAULT_TYPE, //def. rpl
|
|||
|
TRUE, //No rpl on error
|
|||
|
TRUE, //no persistent connections
|
|||
|
//
|
|||
|
// CC initialization
|
|||
|
//
|
|||
|
MAXULONG, //CC Time Int
|
|||
|
FALSE, //SpTime Set
|
|||
|
MAXULONG, //Sp Time
|
|||
|
WINSCNF_CC_DEF_RECS_AAT,
|
|||
|
WINSCNF_CC_DEF_USE_RPL_PNRS,
|
|||
|
|
|||
|
FALSE, //no spoofing
|
|||
|
FALSE, // no randomization of 1C list.
|
|||
|
//
|
|||
|
//PullInfo initialization
|
|||
|
//
|
|||
|
WINSCNF_MAX_COMM_RETRIES, //comm.
|
|||
|
//failure
|
|||
|
//retries
|
|||
|
0, //no of Push Pnrs
|
|||
|
NULL,//ptr to Pull Pnrs records
|
|||
|
DO_INIT_TIME_RPL, //do init time
|
|||
|
//pulling
|
|||
|
WINSCNF_RPL_DEFAULT_TYPE,
|
|||
|
TRUE, // persistent connections
|
|||
|
//
|
|||
|
// PushInfo initialization
|
|||
|
//
|
|||
|
TRUE, // trigger on address change
|
|||
|
//of owned entry
|
|||
|
0, //no of Pull Pnrs
|
|||
|
0, //no of Push recs with valid
|
|||
|
//update count
|
|||
|
NULL,//ptr to Push Pnrs records
|
|||
|
DO_INIT_TIME_RPL, //init time
|
|||
|
//pushing disabled
|
|||
|
DO_PROP_NET_UPD_NTF, //prop net upd
|
|||
|
//ntfs.
|
|||
|
WINSCNF_RPL_DEFAULT_TYPE,
|
|||
|
TRUE // persistent connections
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* Local Variable Definitions
|
|||
|
*/
|
|||
|
STATIC BOOL sfVersNoUpdThdExists = FALSE;
|
|||
|
STATIC BOOL sfVersNoChanged = FALSE;
|
|||
|
|
|||
|
STATIC HKEY sConfigRoot; //HKEY for the WINS root
|
|||
|
STATIC HKEY sParametersKey; //HKEY for the PARAMETERS subkey
|
|||
|
STATIC HKEY sCCKey; //HKEY for the CC subkey
|
|||
|
STATIC HKEY sPartnersKey; //HKEY for PARTNERS subkey
|
|||
|
STATIC HKEY sLogRoot; //HKEY for the log root
|
|||
|
|
|||
|
FUTURES("Might want to change these to auto variables later")
|
|||
|
STATIC TCHAR sWinsCfgKey[] = _WINS_CFG_KEY;
|
|||
|
STATIC TCHAR sWinsLogKey[] = _WINS_LOG_KEY;
|
|||
|
STATIC TCHAR sWinsMsgFileSKey[] = _WINS_MSGFILE_SKEY;
|
|||
|
|
|||
|
//
|
|||
|
// flags that indicate to WinsCnfOpenSubKeys() whether the corresponding keys
|
|||
|
// exist.
|
|||
|
//
|
|||
|
STATIC BOOL sfParametersKeyExists = FALSE;
|
|||
|
STATIC BOOL sfPartnersKeyExists = FALSE;
|
|||
|
|
|||
|
STATIC BOOL sfParametersKeyOpen = FALSE;
|
|||
|
STATIC BOOL sfPartnersKeyOpen = FALSE;
|
|||
|
|
|||
|
TCHAR sLogFilePath[WINS_MAX_FILENAME_SZ]; //path to log file
|
|||
|
|
|||
|
/*
|
|||
|
* Local Function Prototype Declarations
|
|||
|
*/
|
|||
|
|
|||
|
/* prototypes for functions local to this module go here */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
LnkWSameMetricValRecs(
|
|||
|
PWINSCNF_CNF_T pWinsCnf,
|
|||
|
PRPL_CONFIG_REC_T pCnfRec
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
int
|
|||
|
__cdecl
|
|||
|
CompUpdCnt(
|
|||
|
CONST LPVOID pElem1,
|
|||
|
CONST LPVOID pElem2
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
GetPnrInfo(
|
|||
|
RPL_RR_TYPE_E RRType_e,
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
GetKeyInfo(
|
|||
|
IN HKEY Key,
|
|||
|
IN WINSCNF_KEY_E KeyTyp_e,
|
|||
|
OUT LPDWORD pNoOfSubKeys,
|
|||
|
OUT LPDWORD pNoOfVals
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
BOOL
|
|||
|
SanityChkParam(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
ChkWinsSubKeys(
|
|||
|
VOID
|
|||
|
);
|
|||
|
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
GetSpTimeData(
|
|||
|
HKEY SubKey,
|
|||
|
LPSYSTEMTIME pCurrTime,
|
|||
|
LPBOOL pfSpTime,
|
|||
|
LPDWORD pSpTimeIntvl
|
|||
|
);
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
ReadSpecGrpMasks(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
GetOwnerList(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
);
|
|||
|
|
|||
|
VOID
|
|||
|
ReadCCInfo(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
);
|
|||
|
|
|||
|
#if MCAST > 0
|
|||
|
STATIC
|
|||
|
DWORD
|
|||
|
SetVal(
|
|||
|
HKEY RootKey,
|
|||
|
LPWSTR pName,
|
|||
|
DWORD ValType,
|
|||
|
LPWSTR pVal,
|
|||
|
DWORD ValSize
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef WINSDBG
|
|||
|
STATIC
|
|||
|
VOID
|
|||
|
PrintRecs(
|
|||
|
RPL_RR_TYPE_E RRType_e,
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
/*function defs*/
|
|||
|
|
|||
|
STATUS
|
|||
|
WinsCnfInitConfig(
|
|||
|
VOID
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function opens the registry and reads in all the configuration
|
|||
|
information from it.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
WinsCnf
|
|||
|
|
|||
|
Called by:
|
|||
|
Init() in nms.c
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes --
|
|||
|
Error status codes --
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD NewKeyInd;
|
|||
|
LONG RetVal;
|
|||
|
|
|||
|
/*
|
|||
|
First and foremost, open (or create if non-existent) the log file
|
|||
|
*/
|
|||
|
#if 0
|
|||
|
InitLog();
|
|||
|
#endif
|
|||
|
|
|||
|
RetVal = RegCreateKeyEx(
|
|||
|
HKEY_LOCAL_MACHINE, //predefined key value
|
|||
|
sWinsCfgKey, //subkey for WINS
|
|||
|
0, //must be zero (reserved)
|
|||
|
TEXT("Class"), //class -- may change in future
|
|||
|
REG_OPTION_NON_VOLATILE, //non-volatile information
|
|||
|
KEY_ALL_ACCESS, //we desire all access to the keyo
|
|||
|
NULL, //let key have default sec. attributes
|
|||
|
&sConfigRoot, //handle to key
|
|||
|
&NewKeyInd //is it a new key (out arg)
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_N_RET_M(
|
|||
|
WINS_FATAL_ERR,
|
|||
|
WINS_EVT_CANT_OPEN_WINS_KEY,
|
|||
|
WINS_FATAL_ERR
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the critical section that guards the fields used
|
|||
|
// by Scavenger thread
|
|||
|
//
|
|||
|
InitializeCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
InitializeCriticalSection(&g_cs1BFilter);
|
|||
|
|
|||
|
/*
|
|||
|
First create the events that will be passed to the
|
|||
|
RegNotifyChangeKeyValue function
|
|||
|
*/
|
|||
|
try {
|
|||
|
WinsMscCreateEvt(
|
|||
|
WINS_KEY_CHG_EVT_NM,
|
|||
|
FALSE, //auto reset event
|
|||
|
&WinsCnf.WinsKChgEvtHdl
|
|||
|
);
|
|||
|
WinsMscCreateEvt(
|
|||
|
PARAMETERS_KEY_CHG_EVT_NM,
|
|||
|
FALSE, //auto reset event
|
|||
|
&WinsCnf.ParametersKChgEvtHdl
|
|||
|
);
|
|||
|
WinsMscCreateEvt(
|
|||
|
PARTNERS_KEY_CHG_EVT_NM,
|
|||
|
FALSE, //auto reset event
|
|||
|
&WinsCnf.PartnersKChgEvtHdl
|
|||
|
);
|
|||
|
|
|||
|
}
|
|||
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("WinsCnfInitConfig");
|
|||
|
WINSEVT_LOG_M(WINS_FATAL_ERR, WINS_EVT_CANT_CREATE_REG_EVT);
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Create the event that this main thread will set when configuration changes
|
|||
|
// The main thread sets this event to notify the scavenger thread (for now)
|
|||
|
// about the changes
|
|||
|
//
|
|||
|
WinsMscCreateEvt(
|
|||
|
CNF_CHG_EVT_NM,
|
|||
|
FALSE, //auto reset event
|
|||
|
&WinsCnf.CnfChgEvtHdl
|
|||
|
);
|
|||
|
//
|
|||
|
// Opens the Partners and Parameters keys
|
|||
|
//
|
|||
|
WinsCnfOpenSubKeys();
|
|||
|
|
|||
|
//
|
|||
|
// Read in the registry information
|
|||
|
//
|
|||
|
WinsCnfReadRegInfo(&WinsCnf);
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Ask to be notified when the Configuration key or any of the subkeys
|
|||
|
change
|
|||
|
*/
|
|||
|
WinsCnfAskToBeNotified(WINSCNF_E_WINS_KEY);
|
|||
|
return(WINS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfReadPartnerInfo(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function gets all the information pertaining to the Partners of this
|
|||
|
WINS. Under the configuration key above, there are two Keys PULL and PUSH.
|
|||
|
Under each key, there can be one or more keys (IP addresses). The values
|
|||
|
for each IP address key are:
|
|||
|
Time Interval (for both Pull and Push IP address keys)
|
|||
|
Update Count (for Push IP address keys)
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
pWinsCnf - Address of Wins Configuration structure
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
Init function of the Replicator.
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
|
|||
|
Note: This function should never be called when inside the
|
|||
|
NmsNmhNamRegCrtSec, otherwise a deadlock can occur with the Pull
|
|||
|
thread (check out Reconfig in rplpull.c)
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DWORD ValTyp;
|
|||
|
//
|
|||
|
// Initialize the MaxRplTimeInterval field to 0. After we have read
|
|||
|
// both the PULL and PUSH key information from the registry, the above
|
|||
|
// field will contain the max. replication time interval specified for
|
|||
|
// pulling and pushing replicas
|
|||
|
//
|
|||
|
pWinsCnf->MaxRplTimeInterval = 0;
|
|||
|
|
|||
|
pWinsCnf->PullInfo.NoOfPushPnrs = 0;
|
|||
|
pWinsCnf->PullInfo.pPullCnfRecs = NULL;
|
|||
|
pWinsCnf->PullInfo.RplType = WINSCNF_RPL_DEFAULT_TYPE;
|
|||
|
|
|||
|
pWinsCnf->PushInfo.NoOfPullPnrs = 0;
|
|||
|
pWinsCnf->PushInfo.pPushCnfRecs = NULL;
|
|||
|
pWinsCnf->PushInfo.fAddChgTrigger = FALSE;
|
|||
|
pWinsCnf->PushInfo.RplType = WINSCNF_RPL_DEFAULT_TYPE;
|
|||
|
//
|
|||
|
// Since we are again reading the info about the Partners key, increment
|
|||
|
// the magic no. No other thread increments this no. The thread that
|
|||
|
// looks at this no is the Pull thread.
|
|||
|
//
|
|||
|
EnterCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
pWinsCnf->MagicNo = ++WinsCnfCnfMagicNo;
|
|||
|
LeaveCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
|
|||
|
try {
|
|||
|
GetOwnerList(pWinsCnf); // get list of persona (grata / non-grata)
|
|||
|
//
|
|||
|
// Read in the RplType DWORD. Even if no partners are defined, we do this
|
|||
|
// in case this WINS is open to all partners (i.e. fOnlyWCnfPnrs is FALSE)
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sPartnersKey,
|
|||
|
WINSCNF_RPL_TYPE_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->RplType,
|
|||
|
0, // no logging
|
|||
|
WINSCNF_RPL_DEFAULT_TYPE
|
|||
|
);
|
|||
|
|
|||
|
GetPnrInfo(RPL_E_PULL, pWinsCnf);
|
|||
|
GetPnrInfo(RPL_E_PUSH, pWinsCnf);
|
|||
|
}
|
|||
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DWORD ExcCode = GetExceptionCode();
|
|||
|
//
|
|||
|
// If there is some problem with the registry, we don't want
|
|||
|
// to bugcheck WINS. It can proceed with default values.
|
|||
|
// Since we have already logged the errors, the administrator
|
|||
|
// can take corrective action if necessary
|
|||
|
//
|
|||
|
if (
|
|||
|
(ExcCode != WINS_EXC_CANT_OPEN_KEY)
|
|||
|
&&
|
|||
|
(ExcCode != WINS_EXC_CANT_QUERY_KEY)
|
|||
|
&&
|
|||
|
(ExcCode != WINS_EXC_CANT_CLOSE_KEY)
|
|||
|
)
|
|||
|
{
|
|||
|
WINS_RERAISE_EXC_M();
|
|||
|
}
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
STATUS
|
|||
|
WinsCnfInitLog(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function open (or creates) a log file for registering events
|
|||
|
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes -- WINS_SUCCESS
|
|||
|
Error status codes -- WINS_FAILURE
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
WinsCnfInitConfig
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
LONG RetVal = ERROR_SUCCESS;
|
|||
|
STATUS RetStat = WINS_SUCCESS;
|
|||
|
|
|||
|
#ifdef WINS_INTERACTIVE
|
|||
|
DWORD NewKeyInd;
|
|||
|
TCHAR Buff[160];
|
|||
|
DWORD dwData;
|
|||
|
|
|||
|
RetVal = RegCreateKeyEx(
|
|||
|
HKEY_LOCAL_MACHINE, //predefined key value
|
|||
|
sWinsLogKey, //subkey for WINS
|
|||
|
0, //must be zero (reserved)
|
|||
|
TEXT("Class"), //class -- may change in future
|
|||
|
REG_OPTION_NON_VOLATILE, //non-volatile information
|
|||
|
KEY_ALL_ACCESS, //we desire all access to the keyo
|
|||
|
NULL, //let key have default sec. attributes
|
|||
|
&sLogRoot, //handle to key
|
|||
|
&NewKeyInd //is it a new key (out arg) -- not
|
|||
|
//looked at
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
Set the event id message file name
|
|||
|
*/
|
|||
|
lstrcpy(Buff, _WINS_LOG_FILE_NAME);
|
|||
|
|
|||
|
/*
|
|||
|
Add the Event-ID message-file name to the subkey
|
|||
|
*/
|
|||
|
RetVal = RegSetValueEx(
|
|||
|
sLogRoot, //key handle
|
|||
|
sWinsMsgFileSKey, //value name
|
|||
|
0, //must be zero
|
|||
|
REG_EXPAND_SZ, //value type
|
|||
|
(LPBYTE)Buff,
|
|||
|
(lstrlen(Buff) + 1) * sizeof(TCHAR) //length of value data
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
Set the supported data types flags
|
|||
|
*/
|
|||
|
dwData = EVENTLOG_ERROR_TYPE |
|
|||
|
EVENTLOG_WARNING_TYPE |
|
|||
|
EVENTLOG_INFORMATION_TYPE;
|
|||
|
|
|||
|
|
|||
|
RetVal = RegSetValueEx (
|
|||
|
sLogRoot, //subkey handle
|
|||
|
TEXT("TypesSupported"), //value name
|
|||
|
0, //must be zero
|
|||
|
REG_DWORD, //value type
|
|||
|
(LPBYTE)&dwData, //Address of value data
|
|||
|
sizeof(DWORD) //length of value data
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Done with the key. Close it
|
|||
|
*/
|
|||
|
RetVal = RegCloseKey(sLogRoot);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
#endif
|
|||
|
WinsCnf.LogHdl = RegisterEventSource(
|
|||
|
(LPCTSTR)NULL, //use local machine
|
|||
|
TEXT("Wins")
|
|||
|
);
|
|||
|
if (WinsCnf.LogHdl == NULL)
|
|||
|
{
|
|||
|
DBGPRINT1(ERR, "InitLog: RegisterEventSource error = (%x)\n", GetLastError());
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
|
|||
|
WINSEVT_LOG_INFO_D_M(WINS_SUCCESS, WINS_EVT_LOG_INITED);
|
|||
|
return(RetStat);
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
LnkWSameMetricValRecs(
|
|||
|
PWINSCNF_CNF_T pWinsCnf,
|
|||
|
PRPL_CONFIG_REC_T pCnfRec
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to link a configuration record with all
|
|||
|
other configuration records with the same metric value. The metric
|
|||
|
to use depends upon the type of the record. If it is a PULL record,
|
|||
|
the metric is "Time Interval". If the record is a PUSH record,
|
|||
|
the metric is "Update Count"
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
pWinsCnf - Address of configuration block
|
|||
|
pCnfRec - Configuration Record to link.
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
WinsCnfReadPartnerInfo
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
The record to be linked is the last record in the buffer of
|
|||
|
records of the same type.
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PRPL_CONFIG_REC_T pTmp;
|
|||
|
DWORD OffMetricToComp;
|
|||
|
LONG MetricVal;
|
|||
|
|
|||
|
//
|
|||
|
// Set the variables used later based on the record type
|
|||
|
//
|
|||
|
if (pCnfRec->RRTyp_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
pTmp = pWinsCnf->PullInfo.pPullCnfRecs;
|
|||
|
MetricVal = pCnfRec->TimeInterval;
|
|||
|
OffMetricToComp = offsetof(RPL_CONFIG_REC_T, TimeInterval);
|
|||
|
}
|
|||
|
else //it is a PUSH record
|
|||
|
{
|
|||
|
pTmp = pWinsCnf->PushInfo.pPushCnfRecs;
|
|||
|
MetricVal = pCnfRec->UpdateCount;
|
|||
|
OffMetricToComp = offsetof(RPL_CONFIG_REC_T, UpdateCount);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Link in this record at the end of the linked list of
|
|||
|
// records with the same metric value in the buffer pointed by
|
|||
|
// the starting value of pTmp (set above).
|
|||
|
//
|
|||
|
for (
|
|||
|
;
|
|||
|
pTmp != pCnfRec; //until we reach this record
|
|||
|
pTmp = (PRPL_CONFIG_REC_T)((LPBYTE)pTmp + RPL_CONFIG_REC_SIZE)
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// If Metric Value is same, go to end of linked list and
|
|||
|
// link in the record
|
|||
|
//
|
|||
|
if (*((LONG *)((LPBYTE)pTmp + OffMetricToComp)) == MetricVal)
|
|||
|
{
|
|||
|
//
|
|||
|
// Note: if the metric is UpdateCount (Push records)
|
|||
|
// then, the following if will fail.
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// If both records have a specific time for replication,
|
|||
|
// that time must agree too
|
|||
|
//
|
|||
|
if (pTmp->fSpTime && pCnfRec->fSpTime)
|
|||
|
{
|
|||
|
//
|
|||
|
// If specific time is not the same, go to the
|
|||
|
// next record in the array
|
|||
|
//
|
|||
|
if (pTmp->SpTimeIntvl != pCnfRec->SpTimeIntvl)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for(
|
|||
|
;
|
|||
|
pTmp->pNext != NULL;
|
|||
|
pTmp = pTmp->pNext
|
|||
|
)
|
|||
|
; //NULL body
|
|||
|
|
|||
|
pTmp->pNext = pCnfRec;
|
|||
|
|
|||
|
//
|
|||
|
// Set flag to indicate that this record has
|
|||
|
// been linked. Used in SubmitTimerReqs in rplpull.c
|
|||
|
//
|
|||
|
pCnfRec->fLinked = TRUE;
|
|||
|
break; //record is linked. break out of the loop
|
|||
|
}
|
|||
|
|
|||
|
} //end of for { .. } for looping over all records in the buffer
|
|||
|
|
|||
|
//
|
|||
|
// Make pNext to NULL since this is the last record in the buffer
|
|||
|
// buffer of Config Records (also in the chain if records with
|
|||
|
// the same metric)
|
|||
|
//
|
|||
|
pCnfRec->pNext = NULL;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfSetLastUpdCnt(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This function is called at initialization/reinitialization time if
|
|||
|
InitTimePush registry variable is set to 1) to set the LastVersNo
|
|||
|
field of all Push Configuration records to the value of the
|
|||
|
NmsNmhMyMAxVersNo counter. This is done to avoid Push Notifications
|
|||
|
to be sent at Init time.
|
|||
|
|
|||
|
Arguments:
|
|||
|
pWinsCnf - Wins Configuration Info
|
|||
|
|
|||
|
Externals Used:
|
|||
|
NmsNmhMyMaxVersNo
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
NmsDbInit, Reinit (in nms.c)
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
This function is called only after the local Database
|
|||
|
Name-Address mapping table has been read and NmsNmhMyMaxVersNo
|
|||
|
counter initialized (see GetMaxVersNos in nmsdb.c). Also,
|
|||
|
this function is called only if the counter value is > 0
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PRPL_CONFIG_REC_T pCnfRec = pWinsCnf->PushInfo.pPushCnfRecs;
|
|||
|
|
|||
|
for (
|
|||
|
; //null expr 1
|
|||
|
pCnfRec->WinsAdd.Add.IPAdd != INADDR_NONE;
|
|||
|
pCnfRec = (PRPL_CONFIG_REC_T)(
|
|||
|
(LPBYTE) pCnfRec + RPL_CONFIG_REC_SIZE
|
|||
|
)
|
|||
|
)
|
|||
|
{
|
|||
|
//
|
|||
|
// If the Update count field is invalid, go to the next record
|
|||
|
//
|
|||
|
if (pCnfRec->UpdateCount == RPL_INVALID_METRIC)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
pCnfRec->LastVersNo = NmsNmhMyMaxVersNo;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
GetPnrInfo(
|
|||
|
RPL_RR_TYPE_E RRType_e,
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to read PULL/PUSH records
|
|||
|
|
|||
|
Arguments:
|
|||
|
RRType_e - Type of Information to read (PULL or PUSH records)
|
|||
|
pWinsCnf - Configuration structure
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
WinsCnfReadPartnerInfo
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
LONG RetVal;
|
|||
|
HKEY CnfKey;
|
|||
|
TCHAR KeyName[20]; // will hold name of subkey of
|
|||
|
// PULL/PUSH records. These keys are IP
|
|||
|
// addresses for which 20 is a
|
|||
|
// big enough size
|
|||
|
|
|||
|
CHAR AscKeyName[20];
|
|||
|
DWORD KeyNameSz;
|
|||
|
FILETIME LastWrite;
|
|||
|
DWORD BuffSize;
|
|||
|
HKEY SubKey;
|
|||
|
DWORD ValTyp;
|
|||
|
DWORD Sz;
|
|||
|
PRPL_CONFIG_REC_T paCnfRecs;
|
|||
|
DWORD NoOfPnrs = 0; //# of valid PULL or PUSH pnrs
|
|||
|
DWORD NoOfPnrsSv; //# of valid PULL or PUSH pnrs saved
|
|||
|
DWORD NoOfVals;
|
|||
|
DWORD InitTime;
|
|||
|
DWORD IndexOfPnr = 0; //total # of pnrs
|
|||
|
DWORD RplType;
|
|||
|
SYSTEMTIME CurrTime;
|
|||
|
|
|||
|
//
|
|||
|
// Get the current time. It may be needed if we have partners with SpTime
|
|||
|
// specified.
|
|||
|
//
|
|||
|
if (RRType_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
GetLocalTime(&CurrTime);
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Open the key (PULL/PUSH)
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
_WINS_CFG_PULL_KEY :
|
|||
|
_WINS_CFG_PUSH_KEY, //subkey for WINS
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_READ, //we desire read access to the keyo
|
|||
|
&CnfKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
|
|||
|
CHECK("Is there any need to log this")
|
|||
|
WINSEVT_LOG_INFO_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
WINS_EVT_CANT_OPEN_PULL_KEY :
|
|||
|
WINS_EVT_CANT_OPEN_PUSH_KEY
|
|||
|
);
|
|||
|
}
|
|||
|
else //key was successfully opened
|
|||
|
{
|
|||
|
|
|||
|
/*
|
|||
|
* Query the key. The subkeys are IP addresses of PULL
|
|||
|
* partners.
|
|||
|
*/
|
|||
|
GetKeyInfo(
|
|||
|
CnfKey,
|
|||
|
(RRType_e == RPL_E_PULL ? WINSCNF_E_PULL_KEY :
|
|||
|
WINSCNF_E_PUSH_KEY),
|
|||
|
&NoOfPnrs,
|
|||
|
&NoOfVals //ignored
|
|||
|
);
|
|||
|
|
|||
|
if (NoOfPnrs == 0)
|
|||
|
{
|
|||
|
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
WINS_EVT_NO_SUBKEYS_UNDER_PULL :
|
|||
|
WINS_EVT_NO_SUBKEYS_UNDER_PUSH
|
|||
|
);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Since we have one or more Partners to replicate with,
|
|||
|
// read in the value of the InitTimeReplication attribute
|
|||
|
// of all such Partners
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
CnfKey,
|
|||
|
WINSCNF_INIT_TIME_RPL_NM,
|
|||
|
ValTyp,
|
|||
|
InitTime,
|
|||
|
0, //WINS_EVT_CANT_GET_INITRPL_VAL,
|
|||
|
DO_INIT_TIME_RPL
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Since we have one or more Partners to replicate with,
|
|||
|
// read in the value of the RplType attribute
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
CnfKey,
|
|||
|
WINSCNF_RPL_TYPE_NM,
|
|||
|
ValTyp,
|
|||
|
RplType,
|
|||
|
0,
|
|||
|
pWinsCnf->RplType
|
|||
|
);
|
|||
|
#if PRSCONN
|
|||
|
QUERY_VALUE_M(
|
|||
|
CnfKey,
|
|||
|
WINSCNF_PRS_CONN_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->fPrsConn,
|
|||
|
0,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
#endif
|
|||
|
//
|
|||
|
// Allocate buffer big enough to hold data for
|
|||
|
// the number of subkeys found under the PULL key
|
|||
|
//
|
|||
|
BuffSize = RPL_CONFIG_REC_SIZE * (NoOfPnrs + 1);
|
|||
|
WinsMscAlloc( BuffSize, &paCnfRecs);
|
|||
|
|
|||
|
if (RRType_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
pWinsCnf->PullInfo.pPullCnfRecs = paCnfRecs;
|
|||
|
QUERY_VALUE_M(
|
|||
|
CnfKey,
|
|||
|
WINSCNF_RETRY_COUNT_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->PullInfo.MaxNoOfRetries,
|
|||
|
0, //WINS_EVT_CANT_GET_RETRY_COUNT,
|
|||
|
WINSCNF_MAX_COMM_RETRIES
|
|||
|
);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Get the value of the field that indicates
|
|||
|
// whether we should send a trigger when the
|
|||
|
// address of an owned entry changes.
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->PushInfo.fAddChgTrigger);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
CnfKey,
|
|||
|
WINSCNF_ADDCHG_TRIGGER_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->PushInfo.fAddChgTrigger,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
pWinsCnf->PushInfo.fAddChgTrigger = FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pWinsCnf->PushInfo.fAddChgTrigger =
|
|||
|
(pWinsCnf->PushInfo.fAddChgTrigger >= 1);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
QUERY_VALUE_M(
|
|||
|
CnfKey,
|
|||
|
WINSCNF_PROP_NET_UPD_NTF,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->PushInfo.PropNetUpdNtf,
|
|||
|
0, //no event
|
|||
|
DO_PROP_NET_UPD_NTF
|
|||
|
);
|
|||
|
|
|||
|
pWinsCnf->PushInfo.pPushCnfRecs = paCnfRecs;
|
|||
|
pWinsCnf->PushInfo.NoPushRecsWValUpdCnt = 0;
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* For each key, get the values (Time Interval/UpdateCount,
|
|||
|
* etc)
|
|||
|
*/
|
|||
|
NoOfPnrsSv = NoOfPnrs; //save the number that we got from the
|
|||
|
//GetkeyInfo function
|
|||
|
for(
|
|||
|
IndexOfPnr = 0, NoOfPnrs = 0;
|
|||
|
NoOfPnrs < NoOfPnrsSv; //no of valid pnrs < the total #
|
|||
|
IndexOfPnr++
|
|||
|
)
|
|||
|
{
|
|||
|
KeyNameSz = sizeof(KeyName)/sizeof(TCHAR); //init before every call
|
|||
|
RetVal = RegEnumKeyEx(
|
|||
|
CnfKey,
|
|||
|
IndexOfPnr, //Index Of Pnr
|
|||
|
KeyName,
|
|||
|
&KeyNameSz,
|
|||
|
NULL, //reserved
|
|||
|
NULL, //don't need class name
|
|||
|
NULL, //ptr to var. to hold class name
|
|||
|
&LastWrite //not looked at by us
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
//
|
|||
|
// No more ip address keys to get
|
|||
|
//
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Store pointer to the Wins Config structure in
|
|||
|
// the configuration record
|
|||
|
//
|
|||
|
paCnfRecs->pWinsCnf = pWinsCnf;
|
|||
|
|
|||
|
//
|
|||
|
// pWinsCnf->MagicNo contains the value of
|
|||
|
// WinsCnfCnfMagicNo
|
|||
|
//
|
|||
|
paCnfRecs->MagicNo = pWinsCnf->MagicNo;
|
|||
|
paCnfRecs->RRTyp_e = RRType_e;
|
|||
|
|
|||
|
#ifdef UNICODE
|
|||
|
if (wcstombs(AscKeyName, KeyName, KeyNameSz) == -1)
|
|||
|
{
|
|||
|
DBGPRINT0(ERR,
|
|||
|
"Conversion not possible in the current locale\n");
|
|||
|
}
|
|||
|
AscKeyName[KeyNameSz] = EOS;
|
|||
|
|
|||
|
NONPORT("Call a comm function to do this")
|
|||
|
paCnfRecs->WinsAdd.Add.IPAdd = inet_addr(AscKeyName);
|
|||
|
#else
|
|||
|
paCnfRecs->WinsAdd.Add.IPAdd = inet_addr(KeyName);
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// inet_addr returns bytes in network byte order
|
|||
|
// (Left to Right). Let us convert this into host
|
|||
|
// order. This will avoid confusion later on. All
|
|||
|
// formatting functions expect address to be in host
|
|||
|
// order.
|
|||
|
//
|
|||
|
paCnfRecs->WinsAdd.AddLen = COMM_IP_ADD_SIZE;
|
|||
|
paCnfRecs->WinsAdd.AddTyp_e = COMM_ADD_E_TCPUDPIP;
|
|||
|
paCnfRecs->WinsAdd.Add.IPAdd = ntohl(
|
|||
|
paCnfRecs->WinsAdd.Add.IPAdd
|
|||
|
);
|
|||
|
if (COMM_ADDRESS_SAME_M(&NmsLocalAdd, &paCnfRecs->WinsAdd))
|
|||
|
{
|
|||
|
//
|
|||
|
// Invalid partner. Ignore. NoOfPnrs will
|
|||
|
// not be incremented. Also, the buffer
|
|||
|
// pointer stays the same
|
|||
|
//
|
|||
|
continue;
|
|||
|
}
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
CnfKey,
|
|||
|
KeyName,
|
|||
|
0, //reserved; must be 0
|
|||
|
KEY_READ,
|
|||
|
&SubKey
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_M(
|
|||
|
WINS_FATAL_ERR,
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
WINS_EVT_CANT_OPEN_PULL_SUBKEY :
|
|||
|
WINS_EVT_CANT_OPEN_PUSH_SUBKEY
|
|||
|
);
|
|||
|
FUTURES("It is possible that the user deleted the key. Recover from this")
|
|||
|
if (RRType_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
pWinsCnf->PullInfo.NoOfPushPnrs = 0;
|
|||
|
WinsMscDealloc(pWinsCnf->PullInfo.pPullCnfRecs);
|
|||
|
pWinsCnf->PullInfo.pPullCnfRecs = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pWinsCnf->PushInfo.NoOfPullPnrs = 0;
|
|||
|
WinsMscDealloc(pWinsCnf->PushInfo.pPushCnfRecs);
|
|||
|
pWinsCnf->PushInfo.pPushCnfRecs = NULL;
|
|||
|
}
|
|||
|
WINS_RAISE_EXC_M(WINS_EXC_CANT_OPEN_KEY);
|
|||
|
}
|
|||
|
|
|||
|
FUTURES("Maybe, we will support a time interval attribute for Push records")
|
|||
|
FUTURES("when that is done, LnkRecsWSameMetric would need to be updated")
|
|||
|
|
|||
|
if (RRType_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Read in specific time for replication if one
|
|||
|
// has been specified
|
|||
|
//
|
|||
|
GetSpTimeData(SubKey, &CurrTime, &paCnfRecs->fSpTime, &paCnfRecs->SpTimeIntvl);
|
|||
|
|
|||
|
Sz = sizeof(paCnfRecs->TimeInterval);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
SubKey,
|
|||
|
WINSCNF_RPL_INTERVAL_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&paCnfRecs->TimeInterval,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_PULL_TIMEINT
|
|||
|
);
|
|||
|
paCnfRecs->TimeInterval = RPL_INVALID_METRIC;
|
|||
|
}
|
|||
|
else // a value was read in
|
|||
|
{
|
|||
|
//
|
|||
|
// If the time interval is less than or
|
|||
|
// equal to the minimum allowed, use the
|
|||
|
// default minimum
|
|||
|
//
|
|||
|
if (paCnfRecs->TimeInterval
|
|||
|
< WINSCNF_MIN_VALID_RPL_INTVL)
|
|||
|
{
|
|||
|
paCnfRecs->TimeInterval =
|
|||
|
WINSCNF_MIN_VALID_RPL_INTVL;
|
|||
|
}
|
|||
|
if (
|
|||
|
(DWORD)paCnfRecs->TimeInterval >
|
|||
|
pWinsCnf->MaxRplTimeInterval
|
|||
|
)
|
|||
|
{
|
|||
|
pWinsCnf->MaxRplTimeInterval =
|
|||
|
paCnfRecs->TimeInterval;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the precedence level. This can currently
|
|||
|
// be either HIGH (> 0) or LOW (0).
|
|||
|
//
|
|||
|
Sz = sizeof(paCnfRecs->MemberPrec);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
SubKey,
|
|||
|
WINSCNF_MEMBER_PREC_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&paCnfRecs->MemberPrec,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
paCnfRecs->MemberPrec = WINSCNF_LOW_PREC;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
paCnfRecs->MemberPrec =
|
|||
|
(paCnfRecs->MemberPrec > 0) ?
|
|||
|
WINSCNF_HIGH_PREC : WINSCNF_LOW_PREC;
|
|||
|
}
|
|||
|
|
|||
|
#if PRSCONN
|
|||
|
QUERY_VALUE_M(
|
|||
|
SubKey,
|
|||
|
WINSCNF_PRS_CONN_NM,
|
|||
|
ValTyp,
|
|||
|
paCnfRecs->fPrsConn,
|
|||
|
0,
|
|||
|
pWinsCnf->fPrsConn
|
|||
|
);
|
|||
|
#endif
|
|||
|
}
|
|||
|
else // it is a PUSH record
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Currently, we don't support periodic
|
|||
|
// or specific time replication for Push
|
|||
|
// records
|
|||
|
//
|
|||
|
paCnfRecs->fSpTime = FALSE;
|
|||
|
|
|||
|
#if PRSCONN
|
|||
|
QUERY_VALUE_M(
|
|||
|
SubKey,
|
|||
|
WINSCNF_PRS_CONN_NM,
|
|||
|
ValTyp,
|
|||
|
paCnfRecs->fPrsConn,
|
|||
|
0,
|
|||
|
pWinsCnf->fPrsConn
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
Sz = sizeof(paCnfRecs->UpdateCount);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
SubKey,
|
|||
|
WINSCNF_UPDATE_COUNT_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&paCnfRecs->UpdateCount,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
paCnfRecs->UpdateCount =
|
|||
|
RPL_INVALID_METRIC;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
paCnfRecs->LastVersNo.QuadPart = 0;
|
|||
|
#if PRSCONN
|
|||
|
if (!paCnfRecs->fPrsConn && !sfNoLimitChk)
|
|||
|
#else
|
|||
|
if (!sfNoLimitChk)
|
|||
|
#endif
|
|||
|
{
|
|||
|
if (paCnfRecs->UpdateCount <
|
|||
|
WINSCNF_MIN_VALID_UPDATE_CNT)
|
|||
|
{
|
|||
|
paCnfRecs->UpdateCount =
|
|||
|
WINSCNF_MIN_VALID_UPDATE_CNT;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (paCnfRecs->UpdateCount == 0)
|
|||
|
{
|
|||
|
paCnfRecs->UpdateCount = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
pWinsCnf->PushInfo.NoPushRecsWValUpdCnt++;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if MCAST > 0
|
|||
|
Sz = sizeof(paCnfRecs->fSelfFnd);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
SubKey,
|
|||
|
WINSCNF_SELF_FND_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&paCnfRecs->fSelfFnd,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
paCnfRecs->fSelfFnd = FALSE;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
Sz = sizeof(paCnfRecs->fOnlyDynRecs);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
SubKey,
|
|||
|
WINSCNF_ONLY_DYN_RECS_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&paCnfRecs->fOnlyDynRecs,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
paCnfRecs->fOnlyDynRecs = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
QUERY_VALUE_M(
|
|||
|
SubKey,
|
|||
|
WINSCNF_RPL_TYPE_NM,
|
|||
|
ValTyp,
|
|||
|
paCnfRecs->RplType,
|
|||
|
0,
|
|||
|
pWinsCnf->RplType
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
if (paCnfRecs->RplType != 0)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_M(paCnfRecs->WinsAdd.Add.IPAdd, WINS_EVT_PARTIAL_RPL_TYPE);
|
|||
|
}
|
|||
|
|
|||
|
#if PRSCONN
|
|||
|
if (paCnfRecs->fPrsConn != 0)
|
|||
|
{
|
|||
|
paCnfRecs->fPrsConn = TRUE;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
REG_M(
|
|||
|
RegCloseKey(SubKey),
|
|||
|
WINS_EVT_CANT_CLOSE_KEY,
|
|||
|
WINS_EXC_CANT_CLOSE_KEY
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the retry count to 0 and the fLinked flag
|
|||
|
// to FALSE
|
|||
|
//
|
|||
|
//used when pulling
|
|||
|
//
|
|||
|
paCnfRecs->RetryCount = 0;
|
|||
|
|
|||
|
paCnfRecs->fLinked = FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// Initialize the following to 0 so that once we stop
|
|||
|
// communicating with a WINS we can start again when
|
|||
|
// the following count reaches
|
|||
|
// WINSCNF_RETRY_AFTER_THIS_MANY_RPL
|
|||
|
//
|
|||
|
paCnfRecs->RetryAfterThisManyRpl = 0;
|
|||
|
|
|||
|
|
|||
|
#if PRSCONN
|
|||
|
ECOMM_INIT_DLG_HDL_M(&paCnfRecs->PrsDlgHdl);
|
|||
|
paCnfRecs->LastCommTime = 0;
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Initialize LastCommFailTime to 0. Used by
|
|||
|
// SndPushNtf in rplpull.c
|
|||
|
//
|
|||
|
|
|||
|
paCnfRecs->LastCommFailTime = 0;
|
|||
|
paCnfRecs->PushNtfTries = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Link the record with other PULL records with the same
|
|||
|
// Time Interval
|
|||
|
//
|
|||
|
LnkWSameMetricValRecs(pWinsCnf, paCnfRecs);
|
|||
|
//
|
|||
|
// Mark the record as permanent (i.e. it will stay
|
|||
|
// around until a reconfiguration or until the process
|
|||
|
// terminates
|
|||
|
//
|
|||
|
paCnfRecs->fTemp = FALSE;
|
|||
|
|
|||
|
NoOfPnrs++;
|
|||
|
paCnfRecs = (PRPL_CONFIG_REC_T)(
|
|||
|
(LPBYTE)paCnfRecs +
|
|||
|
RPL_CONFIG_REC_SIZE);
|
|||
|
} // end of for {..} for looping over subkeys of PULL
|
|||
|
|
|||
|
//
|
|||
|
// GetReplicasNew expects the list to be terminated with a
|
|||
|
// record with INADDR_NONE as the address
|
|||
|
//
|
|||
|
paCnfRecs->WinsAdd.Add.IPAdd = INADDR_NONE;
|
|||
|
if (RRType_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
pWinsCnf->PullInfo.NoOfPushPnrs = NoOfPnrs;
|
|||
|
pWinsCnf->PullInfo.InitTimeRpl = InitTime;
|
|||
|
pWinsCnf->PullInfo.RplType = RplType;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
pWinsCnf->PushInfo.NoOfPullPnrs = NoOfPnrs;
|
|||
|
pWinsCnf->PushInfo.InitTimePush = InitTime;
|
|||
|
pWinsCnf->PushInfo.RplType = RplType;
|
|||
|
|
|||
|
//
|
|||
|
// Now that we are done with the Push record list,
|
|||
|
//let us sort it on the update count field
|
|||
|
//
|
|||
|
//
|
|||
|
// Sort the array in increasing order of Update Counts
|
|||
|
//
|
|||
|
|
|||
|
FUTURES("May use qsort to optimize the update notification process")
|
|||
|
CHECK("Not sure yet whether sorting would optimize it")
|
|||
|
#if 0
|
|||
|
CHECK("this is resulting in compilation warnings. haven't figured out")
|
|||
|
CHECK("yet why.")
|
|||
|
qsort(
|
|||
|
pWinsCnf->pPushCnfRecs, //start of array
|
|||
|
(size_t)pWinsCnf->NoOfPullPnrs,//no of elements
|
|||
|
RPL_CONFIG_REC_SIZE, //size of each
|
|||
|
//element
|
|||
|
CompUpdCnt //compare func
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
} //end of else (It is PULL key)
|
|||
|
} // end of else (NoOfPnrs == 0)
|
|||
|
|
|||
|
/*
|
|||
|
* Close the key
|
|||
|
*/
|
|||
|
REG_M(
|
|||
|
RegCloseKey(CnfKey),
|
|||
|
WINS_EVT_CANT_CLOSE_KEY,
|
|||
|
WINS_EXC_CANT_CLOSE_KEY
|
|||
|
);
|
|||
|
} //end of else (key could not be opened)
|
|||
|
#if 0
|
|||
|
#ifdef WINSDBG
|
|||
|
PrintRecs(RRType_e, pWinsCnf);
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
|
|||
|
return;
|
|||
|
} // GetPnrInfo
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
GetOwnerList(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function reads the list of owners whose records should be or should not be pulled
|
|||
|
from a partner WINS.
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes --
|
|||
|
Error status codes --
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
LONG RetVal;
|
|||
|
DWORD dwValType; // type of the reg value
|
|||
|
LPSTR pValName; // pointer to the reg
|
|||
|
LPBYTE pValData; // pointer to the reg value's data
|
|||
|
DWORD dwValDataLen; // length of the reg value's data
|
|||
|
|
|||
|
DBGENTER("GetOwnerList\n");
|
|||
|
|
|||
|
// query for the type of persona (grata (1) / non-grata (0))
|
|||
|
pWinsCnf->fPersonaGrata = 0;
|
|||
|
dwValDataLen = sizeof(DWORD);
|
|||
|
RetVal = RegQueryValueExA(
|
|||
|
sPartnersKey, // reg key [HKLM\System\CCS\Services\Wins\Partners]
|
|||
|
WINSCNF_PERSONA_MODE_NM, // name of the value: "PersonaType"
|
|||
|
NULL, // reserved; must be NULL
|
|||
|
&dwValType, // type of the value: should get REG_DWORD
|
|||
|
(LPVOID)&(pWinsCnf->fPersonaGrata), // value data
|
|||
|
&dwValDataLen); // size of the value's data
|
|||
|
// if this call didn't succeed, we go on with the default which is 0, 'non-grata'
|
|||
|
|
|||
|
// get the actual entry we're going to pick the list of addresses from
|
|||
|
pValName = pWinsCnf->fPersonaGrata ?
|
|||
|
WINSCNF_PERSONA_GRATA_NM :
|
|||
|
WINSCNF_PERSONA_NON_GRATA_NM;
|
|||
|
|
|||
|
// get the size of the data from the registry
|
|||
|
// since Sz is 0, if there are any personas
|
|||
|
// grata/non-grata then we should get ERROR_MORE_DATA
|
|||
|
// if we get a different error than just remove the current list
|
|||
|
dwValDataLen = 0;
|
|||
|
RetVal = RegQueryValueExA(
|
|||
|
sPartnersKey, // reg key [HKLM\System\CCS\Services\Wins\Partners]
|
|||
|
pValName, // name of the value: "PersonaList"
|
|||
|
NULL, // reserved; must be NULL
|
|||
|
&dwValType, // type of the value: should get REG_MULTI_SZ
|
|||
|
(LPVOID)&pValData, // dummy address
|
|||
|
&dwValDataLen); // initially 0 since we try to determine the actual size
|
|||
|
// this call should return ERROR_MORE_DATA for a REG_MULTI_SZ value
|
|||
|
|
|||
|
// clear-up the old buffer
|
|||
|
if (pWinsCnf->pPersonaList != NULL)
|
|||
|
{
|
|||
|
WinsMscDealloc(pWinsCnf->pPersonaList);
|
|||
|
}
|
|||
|
pWinsCnf->NoOfPersona = 0;
|
|||
|
pWinsCnf->pPersonaList = NULL;
|
|||
|
|
|||
|
// check if there is a valid value, with the expected type; return if not
|
|||
|
if (RetVal != ERROR_MORE_DATA || dwValType != REG_MULTI_SZ)
|
|||
|
{
|
|||
|
DBGLEAVE("GetOwnerList\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// allocate the needed buffer
|
|||
|
WinsMscAlloc(dwValDataLen, &pValData);
|
|||
|
|
|||
|
// now query for the data value with a buffer large enough
|
|||
|
RetVal = RegQueryValueExA(
|
|||
|
sPartnersKey,
|
|||
|
pValName,
|
|||
|
NULL, // reserved; must be NULL
|
|||
|
&dwValType,
|
|||
|
(LPVOID)pValData, // now this is the real address
|
|||
|
&dwValDataLen);
|
|||
|
|
|||
|
// ERROR_SUCCESS is expected here
|
|||
|
if (RetVal == ERROR_SUCCESS)
|
|||
|
{
|
|||
|
LPBYTE pString = pValData;
|
|||
|
|
|||
|
// count in nAddr the number of addresses in the string
|
|||
|
for( pWinsCnf->NoOfPersona=0; *pString; pWinsCnf->NoOfPersona++)
|
|||
|
pString+= strlen(pString)+1;
|
|||
|
|
|||
|
// see if there are any addresses there
|
|||
|
if (pWinsCnf->NoOfPersona > 0)
|
|||
|
{
|
|||
|
COMM_IP_ADD_T IpAdd;
|
|||
|
|
|||
|
// allocate an array of nAddr COMM_ADD_T structures
|
|||
|
WinsMscAlloc(
|
|||
|
(pWinsCnf->NoOfPersona) * sizeof(COMM_ADD_T),
|
|||
|
&(pWinsCnf->pPersonaList));
|
|||
|
|
|||
|
// loop through the string of addresses and convert
|
|||
|
// them to COMM_IP_ADD_T structures
|
|||
|
for (pString = pValData, pWinsCnf->NoOfPersona = 0;
|
|||
|
*pString;
|
|||
|
pString += strlen(pString) + 1)
|
|||
|
{
|
|||
|
if ((IpAdd = inet_addr(pString)) != -1)
|
|||
|
{
|
|||
|
// initialize a COMM_ADD_T structure only if the string token is
|
|||
|
// indeed an IP address
|
|||
|
(pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].AddTyp_e = COMM_ADD_E_TCPUDPIP;
|
|||
|
(pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].AddLen = COMM_IP_ADD_SIZE;
|
|||
|
(pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].Add.IPAdd = ntohl(IpAdd);
|
|||
|
|
|||
|
DBGPRINT2(
|
|||
|
DET,
|
|||
|
"GetOwnerList: Address[%d] = %x\n",
|
|||
|
pWinsCnf->NoOfPersona,
|
|||
|
(pWinsCnf->pPersonaList)[pWinsCnf->NoOfPersona].Add.IPAdd);
|
|||
|
|
|||
|
pWinsCnf->NoOfPersona++;
|
|||
|
} //end 'if valid ip address'
|
|||
|
} //end 'for each token in the string'
|
|||
|
|
|||
|
// if there are at least two addresses in the list,
|
|||
|
// sort them in ascending order
|
|||
|
if (pWinsCnf->NoOfPersona > 1)
|
|||
|
{
|
|||
|
qsort(pWinsCnf->pPersonaList,
|
|||
|
(size_t)pWinsCnf->NoOfPersona,
|
|||
|
sizeof(COMM_ADD_T),
|
|||
|
ECommCompareAdd);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DBGPRINT0(DET, "GetOwnerList: No valid address found\n");
|
|||
|
} //end 'if there are more than two addresses picked up'
|
|||
|
|
|||
|
} //end 'if there are any tokens at all'
|
|||
|
} //end 'if string could be read successfully from the registry'
|
|||
|
|
|||
|
// the string buffer is no longer needed here
|
|||
|
WinsMscDealloc(pValData);
|
|||
|
|
|||
|
#ifdef WINSDBG
|
|||
|
{
|
|||
|
DWORD tstNAddrs;
|
|||
|
PCOMM_ADD_T tstPAddrs;
|
|||
|
DWORD i;
|
|||
|
|
|||
|
DBGPRINT1(
|
|||
|
DET,
|
|||
|
"GetOwnerList: Persona %sGrata List:\n",
|
|||
|
pWinsCnf->fPersonaGrata ? "" : "Non-");
|
|||
|
|
|||
|
tstNAddrs = pWinsCnf->NoOfPersona;
|
|||
|
tstPAddrs = pWinsCnf->pPersonaList;
|
|||
|
for (i = 0; i < tstNAddrs; i++)
|
|||
|
{
|
|||
|
DBGPRINT2(
|
|||
|
DET,
|
|||
|
"GetOwnerList:PersonaList[%d] = %08x\n",
|
|||
|
i,
|
|||
|
tstPAddrs[i].Add.IPAdd);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
DBGLEAVE("GetOwnerList\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
LONG
|
|||
|
ReadClusterIp(
|
|||
|
HKEY KeyHandle,
|
|||
|
DWORD *IpAddress
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD Sz;
|
|||
|
LONG RetVal;
|
|||
|
DWORD ValTyp;
|
|||
|
TCHAR DirPath[WINS_MAX_FILENAME_SZ];
|
|||
|
|
|||
|
*IpAddress = 0;
|
|||
|
// Read the wins cluster name
|
|||
|
Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
KeyHandle,
|
|||
|
WINSCNF_CLUSTER_RESOURCE_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)DirPath,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if ((RetVal == ERROR_SUCCESS) && (DirPath[0] != (TCHAR)EOS))
|
|||
|
{
|
|||
|
HCLUSTER hCluster;
|
|||
|
HRESOURCE hResource;
|
|||
|
CHAR IpAddressStr[sizeof ("xxx.xxx.xxx.xxx")];
|
|||
|
WCHAR IpAddressWStr[sizeof ("xxx.xxx.xxx.xxx")];
|
|||
|
DWORD i;
|
|||
|
HMODULE Dll1, Dll2;
|
|||
|
#define FUNC_TBL_ENTRY( _Dll, _Name ) { _Dll, &(#_Name)[1], NULL }
|
|||
|
#define CALL_FUNC( _Func) (PVOID)( *FuncTbl[_Func].FuncHdl )
|
|||
|
enum {
|
|||
|
_OpenCluster,
|
|||
|
_OpenClusterResource,
|
|||
|
_CloseCluster,
|
|||
|
_CloseClusterResource,
|
|||
|
_ResUtilGetResourceDependentIPAddressProps
|
|||
|
};
|
|||
|
struct {
|
|||
|
HMODULE *Dll;
|
|||
|
LPCSTR FuncName;
|
|||
|
FARPROC FuncHdl;
|
|||
|
} FuncTbl[] = {
|
|||
|
FUNC_TBL_ENTRY( &Dll1,_OpenCluster),
|
|||
|
FUNC_TBL_ENTRY( &Dll1,_OpenClusterResource),
|
|||
|
FUNC_TBL_ENTRY( &Dll1,_CloseCluster),
|
|||
|
FUNC_TBL_ENTRY( &Dll1,_CloseClusterResource),
|
|||
|
FUNC_TBL_ENTRY( &Dll2,_ResUtilGetResourceDependentIPAddressProps)
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
DBGPRINT1(DET, "WinsCnfReadWinsInfo: ClusterResourceName is (%ws)\n", DirPath);
|
|||
|
hCluster = NULL;
|
|||
|
hResource = NULL;
|
|||
|
Dll1 = Dll2 = NULL;
|
|||
|
do {
|
|||
|
Dll1 = LoadLibrary(TEXT("clusapi.dll"));
|
|||
|
if (!Dll1) {
|
|||
|
RetVal = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
Dll2 = LoadLibrary(TEXT("resutils.dll"));
|
|||
|
if (!Dll2) {
|
|||
|
|
|||
|
RetVal = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
for (i=0; i<(sizeof(FuncTbl)/sizeof(FuncTbl[0])); i++) {
|
|||
|
FuncTbl[i].FuncHdl = GetProcAddress(*FuncTbl[i].Dll, FuncTbl[i].FuncName);
|
|||
|
if (!FuncTbl[i].FuncHdl) {
|
|||
|
RetVal = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
if (i<(sizeof(FuncTbl)/sizeof(FuncTbl[0]))) {
|
|||
|
break;
|
|||
|
}
|
|||
|
hCluster = CALL_FUNC(_OpenCluster)( NULL );
|
|||
|
if (!hCluster) {
|
|||
|
RetVal = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
hResource = CALL_FUNC(_OpenClusterResource)(hCluster, DirPath);
|
|||
|
if (!hResource) {
|
|||
|
RetVal = GetLastError();
|
|||
|
break;
|
|||
|
}
|
|||
|
Sz = sizeof (IpAddressWStr);
|
|||
|
RetVal = PtrToLong(CALL_FUNC(_ResUtilGetResourceDependentIPAddressProps)(
|
|||
|
hResource,
|
|||
|
IpAddressWStr,
|
|||
|
&Sz,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL,
|
|||
|
NULL
|
|||
|
));
|
|||
|
if (ERROR_SUCCESS != RetVal) {
|
|||
|
break;
|
|||
|
}
|
|||
|
WinsMscConvertUnicodeStringToAscii((LPBYTE)IpAddressWStr, IpAddressStr, sizeof(IpAddressStr));
|
|||
|
*IpAddress = ntohl(inet_addr(IpAddressStr));
|
|||
|
DBGPRINT1(DET, "ReadClusterIp: Cluster IpAddress is (%lx)\n", *IpAddress);
|
|||
|
} while ( FALSE );
|
|||
|
if( hResource ) CALL_FUNC(_CloseClusterResource)(hResource);
|
|||
|
if( hCluster ) CALL_FUNC(_CloseCluster) (hCluster);
|
|||
|
if ( Dll1 ) FreeLibrary(Dll1);
|
|||
|
if ( Dll2 ) FreeLibrary(Dll2);
|
|||
|
}
|
|||
|
|
|||
|
return RetVal;
|
|||
|
}
|
|||
|
|
|||
|
extern DOM_CACHE_T sDomCache;
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfReadWinsInfo(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function reads information (excluding subkeys) about
|
|||
|
the local WINS
|
|||
|
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
sConfigRoot,
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
WinsCnfInitConfig
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
DWORD Sz;
|
|||
|
LONG RetVal;
|
|||
|
DWORD ValTyp;
|
|||
|
VERS_NO_T MaxVersNo;
|
|||
|
WINSEVT_STRS_T EvtStr;
|
|||
|
TCHAR DirPath[WINS_MAX_FILENAME_SZ];
|
|||
|
TCHAR Path2[WINS_MAX_FILENAME_SZ];
|
|||
|
LPTSTR pHoldFileName;
|
|||
|
DWORD fUse351Db;
|
|||
|
DWORD fUse4Db;
|
|||
|
EvtStr.NoOfStrs = 1;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
#if defined(DBGSVC) && !defined(WINS_INTERACTIVE)
|
|||
|
//
|
|||
|
// Read the value of WinsDbg. Though this value is
|
|||
|
// being used concurrently by multiple threads (at reinit time), we
|
|||
|
// don't enter any critical section here. This value
|
|||
|
// is used only for debugging
|
|||
|
//
|
|||
|
WinsCnfReadWinsDbgFlagValue();
|
|||
|
#endif
|
|||
|
|
|||
|
Sz = sizeof(pWinsCnf->LogDetailedEvts);
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_LOG_DETAILED_EVTS_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->LogDetailedEvts,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
// Read in the 1B filter. If the "Filter1BRequests" is there and it is a REG_MULTI_SZ
|
|||
|
// then the filter is created for each of the names specified there. When R_WinsGetBrowserNames
|
|||
|
// is called, the database is filtered only for the name present in the filter.
|
|||
|
RetVal = RegQueryValueExW(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_FILTER1BREQUESTS_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
NULL,
|
|||
|
&Sz);
|
|||
|
|
|||
|
if (RetVal == ERROR_SUCCESS && ValTyp == REG_MULTI_SZ)
|
|||
|
{
|
|||
|
LPWSTR str1BFilters = NULL;
|
|||
|
LPWSTR p1BFilter;
|
|||
|
|
|||
|
WinsMscAlloc(Sz, &str1BFilters);
|
|||
|
|
|||
|
if (RegQueryValueExW(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_FILTER1BREQUESTS_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)str1BFilters,
|
|||
|
&Sz) == ERROR_SUCCESS)
|
|||
|
{
|
|||
|
EnterCriticalSection(&g_cs1BFilter);
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
g_p1BFilter = InitNmFilter(g_p1BFilter);
|
|||
|
|
|||
|
p1BFilter = str1BFilters;
|
|||
|
do
|
|||
|
{
|
|||
|
DWORD nLenFilter = wcslen(p1BFilter);
|
|||
|
CHAR strOemName[17];
|
|||
|
OEM_STRING oemString;
|
|||
|
UNICODE_STRING unicodeString;
|
|||
|
|
|||
|
if (nLenFilter == 0)
|
|||
|
break;
|
|||
|
|
|||
|
memset(strOemName, ' ', 16);
|
|||
|
strOemName[16]=0;
|
|||
|
if (nLenFilter > 15)
|
|||
|
p1BFilter[16]=L'\0';
|
|||
|
|
|||
|
RtlInitUnicodeString(&unicodeString, p1BFilter);
|
|||
|
RtlInitString(&oemString, strOemName);
|
|||
|
RtlUpcaseUnicodeStringToOemString(&oemString, &unicodeString, FALSE);
|
|||
|
|
|||
|
strOemName[strlen(strOemName)] = ' ';
|
|||
|
strOemName[15] = strOemName[0];
|
|||
|
strOemName[0] = 0x1B;
|
|||
|
InsertNmInFilter(g_p1BFilter, strOemName, 16);
|
|||
|
p1BFilter += nLenFilter+1;
|
|||
|
}
|
|||
|
while(TRUE);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
LeaveCriticalSection(&g_cs1BFilter);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
WinsMscDealloc(str1BFilters);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// if the reg key is not there, reset the filter - all names will be returned.
|
|||
|
EnterCriticalSection(&g_cs1BFilter);
|
|||
|
try
|
|||
|
{
|
|||
|
g_p1BFilter = DestroyNmFilter(g_p1BFilter);
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
g_p1BFilter = NULL;
|
|||
|
LeaveCriticalSection(&g_cs1BFilter);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
sDomCache.bRefresh = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// Read in the fAdd1Bto1CQueries parameter. Default is TRUE
|
|||
|
// meaning: when processing name queries for 1C names, prepend the
|
|||
|
// response with the 1B name (browser name).
|
|||
|
//
|
|||
|
pWinsCnf->fAdd1Bto1CQueries = TRUE;
|
|||
|
Sz = sizeof(pWinsCnf->fAdd1Bto1CQueries);
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_ADD1BTO1CQUERIES_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->fAdd1Bto1CQueries,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
//
|
|||
|
// Read in the cap value on the number of worker threads.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_MAX_NO_WRK_THDS_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->MaxNoOfWrkThds,
|
|||
|
0,
|
|||
|
0 //WINSTHD_DEF_NO_NBT_THDS
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Check if the user needs to override our checks.
|
|||
|
//
|
|||
|
sfNoLimitChk = pWinsCnf->MaxNoOfWrkThds & NO_LIMIT_CHK_FLAG;
|
|||
|
if (sfNoLimitChk)
|
|||
|
{
|
|||
|
WINSEVT_LOG_M(pWinsCnf->LogDetailedEvts, WINS_EVT_INTERNAL_FEATURE);
|
|||
|
pWinsCnf->MaxNoOfWrkThds &= ~NO_LIMIT_CHK_FLAG;
|
|||
|
}
|
|||
|
|
|||
|
if (pWinsCnf->MaxNoOfWrkThds > WINSTHD_MAX_NO_NBT_THDS)
|
|||
|
{
|
|||
|
pWinsCnf->MaxNoOfWrkThds = WINSTHD_MAX_NO_NBT_THDS;
|
|||
|
}
|
|||
|
if (pWinsCnf->MaxNoOfWrkThds < WINSTHD_MIN_NO_NBT_THDS)
|
|||
|
{
|
|||
|
pWinsCnf->MaxNoOfWrkThds = WINSTHD_MIN_NO_NBT_THDS;
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
if (WinsCnf.State_e == WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
ReadSpecGrpMasks(pWinsCnf);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
#if DYNLOADJET
|
|||
|
//
|
|||
|
// Read in the cap value on the number of worker threads.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_USE_351DB_NM,
|
|||
|
ValTyp,
|
|||
|
fUse351Db,
|
|||
|
0,
|
|||
|
0 //Use 500 db
|
|||
|
);
|
|||
|
//
|
|||
|
// If set to a non-zero value, we need to load jet.dll
|
|||
|
//
|
|||
|
if (fUse351Db)
|
|||
|
{
|
|||
|
DynLoadJetVersion = DYN_LOAD_JET_200;
|
|||
|
} else {
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_USE_4DB_NM,
|
|||
|
ValTyp,
|
|||
|
fUse4Db,
|
|||
|
0,
|
|||
|
0 //Use 500 db
|
|||
|
);
|
|||
|
//
|
|||
|
// If set to a non-zero value, we need to load jet.dll
|
|||
|
//
|
|||
|
if (fUse4Db)
|
|||
|
{
|
|||
|
DynLoadJetVersion = DYN_LOAD_JET_500;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
//
|
|||
|
// Read in the refresh Interval
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->RefreshInterval);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_REFRESH_INTVL_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->RefreshInterval,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_REFRESH_INTERVAL_VAL
|
|||
|
);
|
|||
|
pWinsCnf->RefreshInterval = WINSCNF_DEF_REFRESH_INTERVAL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (!sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->RefreshInterval <
|
|||
|
WINSCNF_MIN_REFRESH_INTERVAL)
|
|||
|
{
|
|||
|
pWinsCnf->RefreshInterval = WINSCNF_MIN_REFRESH_INTERVAL;
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_REFRESH_INTVL_NM,
|
|||
|
pWinsCnf->RefreshInterval);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->RefreshInterval < 60)
|
|||
|
{
|
|||
|
pWinsCnf->RefreshInterval = 60;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the Initial Challenge Retry Interval
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->RetryInterval);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_INIT_CHL_RETRY_INTVL_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->RetryInterval,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_INIT_CHL_RETRY_INTVL_VAL
|
|||
|
);
|
|||
|
pWinsCnf->RetryInterval = WINSCNF_DEF_INIT_CHL_RETRY_INTVL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (!sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->RetryInterval <
|
|||
|
WINSCNF_MIN_INIT_CHL_RETRY_INTVL)
|
|||
|
{
|
|||
|
pWinsCnf->RetryInterval = WINSCNF_MIN_INIT_CHL_RETRY_INTVL;
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_INIT_CHL_RETRY_INTVL_NM,
|
|||
|
pWinsCnf->RetryInterval);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->RetryInterval < WINSCNF_MIN_INIT_CHL_RETRY_INTVL)
|
|||
|
{
|
|||
|
pWinsCnf->RetryInterval = WINSCNF_MIN_INIT_CHL_RETRY_INTVL;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the Initial Challenge Max. No. of Retries
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->MaxNoOfRetries);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_CHL_MAX_RETRIES_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->MaxNoOfRetries,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_CHL_MAX_RETRIES_VAL
|
|||
|
);
|
|||
|
pWinsCnf->MaxNoOfRetries = WINSCNF_DEF_CHL_MAX_RETRIES;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (!sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->MaxNoOfRetries <
|
|||
|
WINSCNF_MIN_CHL_MAX_RETRIES)
|
|||
|
{
|
|||
|
pWinsCnf->MaxNoOfRetries = WINSCNF_MIN_CHL_MAX_RETRIES;
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_CHL_MAX_RETRIES_NM,
|
|||
|
pWinsCnf->MaxNoOfRetries);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->MaxNoOfRetries < WINSCNF_MIN_CHL_MAX_RETRIES)
|
|||
|
{
|
|||
|
pWinsCnf->MaxNoOfRetries = WINSCNF_MIN_CHL_MAX_RETRIES;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the tombstone Interval
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->TombstoneInterval);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_TOMBSTONE_INTVL_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->TombstoneInterval,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_TOMBSTONE_INTERVAL_VAL
|
|||
|
);
|
|||
|
|
|||
|
pWinsCnf->TombstoneInterval =
|
|||
|
WINSCNF_MAKE_TOMB_INTVL_0_M(pWinsCnf->RefreshInterval);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
if ( !sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->TombstoneInterval <
|
|||
|
WINSCNF_MAKE_TOMB_INTVL_0_M(pWinsCnf->RefreshInterval) )
|
|||
|
{
|
|||
|
pWinsCnf->TombstoneInterval =
|
|||
|
WINSCNF_MAKE_TOMB_INTVL_0_M(pWinsCnf->RefreshInterval);
|
|||
|
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_TOMBSTONE_INTVL_NM,
|
|||
|
pWinsCnf->TombstoneInterval);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->TombstoneInterval < 60)
|
|||
|
{
|
|||
|
pWinsCnf->TombstoneInterval = 60;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the tombstone timeout
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->TombstoneTimeout);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_TOMBSTONE_TMOUT_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->TombstoneTimeout,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_TOMBSTONE_TIMEOUT_VAL
|
|||
|
);
|
|||
|
pWinsCnf->TombstoneTimeout = pWinsCnf->RefreshInterval;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (!sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->TombstoneTimeout < pWinsCnf->RefreshInterval)
|
|||
|
{
|
|||
|
pWinsCnf->TombstoneTimeout = pWinsCnf->RefreshInterval;
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_TOMBSTONE_TMOUT_NM,
|
|||
|
pWinsCnf->TombstoneTimeout);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->TombstoneTimeout < 60)
|
|||
|
{
|
|||
|
pWinsCnf->TombstoneTimeout = 60;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the Verify Interval
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->VerifyInterval);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_VERIFY_INTVL_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->VerifyInterval,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_VERIFY_INTERVAL_VAL
|
|||
|
);
|
|||
|
|
|||
|
pWinsCnf->VerifyInterval =
|
|||
|
WINSCNF_MAKE_VERIFY_INTVL_M(pWinsCnf->TombstoneInterval);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
if ( !sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->VerifyInterval <
|
|||
|
WINSCNF_MAKE_VERIFY_INTVL_M(pWinsCnf->TombstoneInterval))
|
|||
|
{
|
|||
|
pWinsCnf->VerifyInterval =
|
|||
|
WINSCNF_MAKE_VERIFY_INTVL_M(pWinsCnf->TombstoneInterval);
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_VERIFY_INTVL_NM,
|
|||
|
pWinsCnf->VerifyInterval);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->VerifyInterval < 60)
|
|||
|
{
|
|||
|
pWinsCnf->VerifyInterval = 60;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
ReadCCInfo(pWinsCnf);
|
|||
|
|
|||
|
//
|
|||
|
// Check if the admin. wants us to do pull/push replications with
|
|||
|
// pnrs found by self.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_BURST_HANDLING_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->fDoSpoofing,
|
|||
|
0,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
if (pWinsCnf->fDoSpoofing)
|
|||
|
{
|
|||
|
pWinsCnf->fDoSpoofing = TRUE; //for robustness
|
|||
|
}
|
|||
|
|
|||
|
#if MCAST > 0
|
|||
|
//
|
|||
|
// Check if the admin. wants us to do pull/push replications with
|
|||
|
// pnrs found by self.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_USE_SELF_FND_PNRS_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->fUseSelfFndPnrs,
|
|||
|
0,
|
|||
|
FALSE
|
|||
|
);
|
|||
|
|
|||
|
if (pWinsCnf->fUseSelfFndPnrs)
|
|||
|
{
|
|||
|
if (WinsCnf.State_e == WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
Sz = sizeof(pWinsCnf->McastTtl);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_MCAST_TTL_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->McastTtl,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
pWinsCnf->McastTtl = WINSCNF_DEF_MCAST_TTL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (
|
|||
|
(pWinsCnf->McastTtl < WINSCNF_MIN_MCAST_TTL)
|
|||
|
||
|
|||
|
(pWinsCnf->McastTtl > WINSCNF_MAX_MCAST_TTL)
|
|||
|
)
|
|||
|
{
|
|||
|
pWinsCnf->McastTtl = WINSCNF_DEF_MCAST_TTL;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Sz = sizeof(pWinsCnf->McastIntvl);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_MCAST_INTVL_NM,
|
|||
|
NULL,
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->McastIntvl,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
pWinsCnf->McastIntvl = WINSCNF_DEF_MCAST_INTVL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if ( pWinsCnf->McastIntvl < WINSCNF_MIN_MCAST_INTVL )
|
|||
|
{
|
|||
|
pWinsCnf->McastIntvl = WINSCNF_MIN_MCAST_INTVL;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
//
|
|||
|
// Check if replication is to be done only with configured partners.
|
|||
|
// If set to TRUE, it means that an administrator will not be allowed
|
|||
|
// to trigger replication to/from a WINS that this WINS does not know
|
|||
|
// about. Default value is FALSE
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_RPL_ONLY_W_CNF_PNRS_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->fRplOnlyWCnfPnrs,
|
|||
|
0,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
//
|
|||
|
// Robust programming (in case the registry has a value other than 1
|
|||
|
// and later on we compare the value with TRUE)
|
|||
|
//
|
|||
|
if (pWinsCnf->fRplOnlyWCnfPnrs != FALSE)
|
|||
|
{
|
|||
|
pWinsCnf->fRplOnlyWCnfPnrs = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if (WinsCnf.State_e == WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
|
|||
|
(VOID)WinsMscAlloc(WINS_MAX_FILENAME_SZ, &(pWinsCnf->pWinsDb));
|
|||
|
//
|
|||
|
// Read in the name of the database file
|
|||
|
//
|
|||
|
FUTURES("when jet supports UNICODE in its api, change this")
|
|||
|
Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_DB_FILE_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)DirPath,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if ((RetVal != ERROR_SUCCESS) || (DirPath[0] == (TCHAR)EOS))
|
|||
|
{
|
|||
|
WinsMscDealloc(pWinsCnf->pWinsDb);
|
|||
|
pWinsCnf->pWinsDb = WINSCNF_DB_NAME_ASCII;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if(!WinsMscGetName(ValTyp, DirPath, Path2, WINS_MAX_FILENAME_SZ, &pHoldFileName))
|
|||
|
{
|
|||
|
WinsMscDealloc(pWinsCnf->pWinsDb);
|
|||
|
pWinsCnf->pWinsDb = WINSCNF_DB_NAME_ASCII;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
WinsMscConvertUnicodeStringToAscii((LPBYTE)pHoldFileName, pWinsCnf->pWinsDb, WINS_MAX_FILENAME_SZ);
|
|||
|
DBGPRINT1(DET, "WinsCnfReadWinsInfo: Db file path is (%s)\n", pWinsCnf->pWinsDb);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
RetVal = ReadClusterIp(
|
|||
|
sParametersKey,
|
|||
|
&WinsClusterIpAddress
|
|||
|
);
|
|||
|
if (ERROR_SUCCESS == RetVal) {
|
|||
|
NmsLocalAdd.Add.IPAdd = WinsClusterIpAddress;
|
|||
|
} else {
|
|||
|
DBGPRINT1(DET, "ReadClusterIp: Returned (%ld)\n", RetVal);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read in the PriorityClassHigh value. Default is normal
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_PRIORITY_CLASS_HIGH_NM,
|
|||
|
ValTyp,
|
|||
|
pWinsCnf->WinsPriorityClass,
|
|||
|
0,
|
|||
|
WINSINTF_E_NORMAL
|
|||
|
);
|
|||
|
|
|||
|
if (pWinsCnf->WinsPriorityClass != WINSINTF_E_NORMAL)
|
|||
|
{
|
|||
|
if (WinsCnf.WinsPriorityClass != WINSINTF_E_HIGH)
|
|||
|
{
|
|||
|
WinsSetPriorityClass(WINSINTF_E_HIGH);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (WinsCnf.WinsPriorityClass != WINSINTF_E_NORMAL)
|
|||
|
{
|
|||
|
WinsSetPriorityClass(WINSINTF_E_NORMAL);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (WinsCnf.State_e == WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
//
|
|||
|
// Read in the InitTimeState value. Default is FALSE
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_INIT_TIME_PAUSE_NM,
|
|||
|
ValTyp,
|
|||
|
fWinsCnfInitStatePaused,
|
|||
|
0,
|
|||
|
FALSE
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// Read in the name of the recovery file
|
|||
|
//
|
|||
|
(VOID)WinsMscAlloc(WINS_MAX_FILENAME_SZ, &(pWinsCnf->pLogFilePath));
|
|||
|
Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_LOG_FILE_PATH_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)DirPath,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if ((RetVal != ERROR_SUCCESS) || (DirPath[0] == (TCHAR)EOS))
|
|||
|
{
|
|||
|
DBGPRINT1(ERR, "WinsCnfReadInfo: RetVal=(%x)\n", RetVal);
|
|||
|
WinsMscDealloc(pWinsCnf->pLogFilePath);
|
|||
|
pWinsCnf->pLogFilePath = DEFAULT_LOG_PATH;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if(!WinsMscGetName(ValTyp, DirPath, Path2, WINS_MAX_FILENAME_SZ, &pHoldFileName))
|
|||
|
{
|
|||
|
DBGPRINT0(ERR, "WinsCnfReadInfo:WinsMscGetName returned FALSE\n");
|
|||
|
WinsMscDealloc(pWinsCnf->pLogFilePath);
|
|||
|
pWinsCnf->pLogFilePath = DEFAULT_LOG_PATH;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DBGPRINT1(DET, "WinsCnfReadInfo:pHoldFileName=%s\n", pHoldFileName);
|
|||
|
WinsMscConvertUnicodeStringToAscii((LPBYTE)pHoldFileName, pWinsCnf->pLogFilePath, WINS_MAX_FILENAME_SZ);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check if user wants logging to be turned on.
|
|||
|
// In case of Q servers, the user would not wish the logging to be
|
|||
|
// turned on
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->fLoggingOn);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_LOG_FLAG_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->fLoggingOn,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
//
|
|||
|
// default is to turn on logging
|
|||
|
//
|
|||
|
pWinsCnf->fLoggingOn = TRUE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// If user has specified logging, get the path to the log
|
|||
|
// file if specified by user
|
|||
|
//
|
|||
|
if (pWinsCnf->fLoggingOn)
|
|||
|
{
|
|||
|
pWinsCnf->fLoggingOn = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
//
|
|||
|
// Check to see if STATIC initialization of the WINS database needs
|
|||
|
// to be done
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->fStaticInit);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_STATIC_INIT_FLAG_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->fStaticInit,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
pWinsCnf->fStaticInit = FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Safe programming (just in case a maintainer of this code
|
|||
|
// assumes a BOOL field to have just TRUE and FALSE values
|
|||
|
//
|
|||
|
pWinsCnf->fStaticInit = pWinsCnf->fStaticInit > 0 ? TRUE : FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If Static Initialization needs to be done, read in the name of
|
|||
|
// the file that contains the data.
|
|||
|
//
|
|||
|
if(pWinsCnf->fStaticInit)
|
|||
|
{
|
|||
|
WinsCnfGetNamesOfDataFiles(pWinsCnf);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Assign MaxVersNo with the default value
|
|||
|
//
|
|||
|
WINS_ASSIGN_INT_TO_VERS_NO_M(MaxVersNo, 0);
|
|||
|
|
|||
|
//
|
|||
|
// If the WINS server is just coming up (i.e. it is not a reinit),
|
|||
|
// then read in the starting value of the version number counter
|
|||
|
// if present in the registry
|
|||
|
//
|
|||
|
Sz = sizeof(DWORD);
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_INIT_VERSNO_VAL_LW_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&MaxVersNo.LowPart,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_INIT_VERSNO_VAL_HW_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&MaxVersNo.HighPart,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// if we read in a value for the version counter
|
|||
|
//
|
|||
|
if (LiGtrZero(MaxVersNo) && (MaxVersNo.HighPart == 0) &&
|
|||
|
(MaxVersNo.LowPart < MAX_START_VERS_NO))
|
|||
|
{
|
|||
|
//
|
|||
|
// Use WinsCnf, not pWinsCnf since at initialization time, we always
|
|||
|
// read into WinsCnf. At reinit, the State_e field in the WinsCnf
|
|||
|
// structure allocated may have garbage (actually will be 0 since we
|
|||
|
// initialize allocated memory to zero -- I might change in the
|
|||
|
// future to improve performance)
|
|||
|
//
|
|||
|
if (WinsCnf.State_e == WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
//
|
|||
|
// Min. Vers. to start scavenging from.
|
|||
|
//
|
|||
|
// NOTE: if we find local records or the special record then
|
|||
|
// NmsScvMinScvVersNo will get changed (check out GetMaxVersNos
|
|||
|
// in nmsdb.c
|
|||
|
//
|
|||
|
NmsNmhMyMaxVersNo = MaxVersNo;
|
|||
|
NmsScvMinScvVersNo = NmsNmhMyMaxVersNo;
|
|||
|
NmsVersNoToStartFromNextTime.QuadPart =
|
|||
|
LiAdd(NmsNmhMyMaxVersNo, NmsRangeSize);
|
|||
|
|
|||
|
NmsHighWaterMarkVersNo.QuadPart =
|
|||
|
LiAdd(NmsNmhMyMaxVersNo, NmsHalfRangeSize);
|
|||
|
}
|
|||
|
else // this must be a reconfiguration
|
|||
|
{
|
|||
|
EnterCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
|
|||
|
//
|
|||
|
// change the value of the version counter if
|
|||
|
// the new value is more than it.
|
|||
|
//
|
|||
|
if (LiGtr(MaxVersNo, NmsNmhMyMaxVersNo))
|
|||
|
{
|
|||
|
NmsNmhMyMaxVersNo = MaxVersNo;
|
|||
|
WINSEVT_LOG_INFO_M(MaxVersNo.LowPart,
|
|||
|
WINS_EVT_VERS_COUNTER_CHANGED);
|
|||
|
}
|
|||
|
NmsVersNoToStartFromNextTime.QuadPart =
|
|||
|
LiAdd(NmsNmhMyMaxVersNo, NmsRangeSize);
|
|||
|
NmsHighWaterMarkVersNo.QuadPart =
|
|||
|
LiAdd(NmsNmhMyMaxVersNo, NmsHalfRangeSize);
|
|||
|
LeaveCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (WinsCnf.State_e == WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
//
|
|||
|
// Check if a port has been assigned by the user.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_WINS_PORT_NO_NM,
|
|||
|
ValTyp,
|
|||
|
CommWinsTcpPortNo,
|
|||
|
0,
|
|||
|
COMM_DEFAULT_IP_PORT
|
|||
|
);
|
|||
|
DBGPRINT1(DET, "WinsCnfReadWinsInfo: Port No is (%d)\n", CommWinsTcpPortNo);
|
|||
|
|
|||
|
//
|
|||
|
// Check if WINS should continue replication in case of an
|
|||
|
// error in replication.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_NO_RPL_ON_ERR_NM,
|
|||
|
ValTyp,
|
|||
|
WinsCnf.fNoRplOnErr,
|
|||
|
0,
|
|||
|
TRUE
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Assign MaxVersNo with the default value
|
|||
|
//
|
|||
|
WINS_ASSIGN_INT_TO_VERS_NO_M(MaxVersNo, 0);
|
|||
|
|
|||
|
//
|
|||
|
// Read in the value specified in the registry for the version
|
|||
|
// number that we should use when starting.
|
|||
|
//
|
|||
|
Sz = sizeof(DWORD);
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sConfigRoot,
|
|||
|
WINSCNF_INT_VERSNO_NEXTTIME_LW_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&MaxVersNo.LowPart,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sConfigRoot,
|
|||
|
WINSCNF_INT_VERSNO_NEXTTIME_HW_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&MaxVersNo.HighPart,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// if we read in a value for the version counter and it is greater
|
|||
|
// than the high-water mark currently there
|
|||
|
//
|
|||
|
if (LiGtr(MaxVersNo, NmsHighWaterMarkVersNo))
|
|||
|
{
|
|||
|
fWinsCnfReadNextTimeVersNo = TRUE;
|
|||
|
|
|||
|
//
|
|||
|
// Use WinsCnf, not pWinsCnf since at initialization time,
|
|||
|
// we always read into WinsCnf. At reinit, the State_e field
|
|||
|
// in the WinsCnf structure allocated may have garbage
|
|||
|
// (actually will be 0 since we initialize allocated memory
|
|||
|
// to zero -- I might change in the future to improve
|
|||
|
// performance)
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Min. Vers. to start scavenging from.
|
|||
|
//
|
|||
|
// NOTE: if we find local records or the special record then
|
|||
|
// NmsScvMinScvVersNo will get changed (check out GetMaxVersNos
|
|||
|
// in nmsdb.c
|
|||
|
//
|
|||
|
if (LiLtr(NmsNmhMyMaxVersNo, MaxVersNo))
|
|||
|
{
|
|||
|
NmsNmhMyMaxVersNo = MaxVersNo;
|
|||
|
NmsScvMinScvVersNo = NmsNmhMyMaxVersNo;
|
|||
|
}
|
|||
|
NmsVersNoToStartFromNextTime.QuadPart =
|
|||
|
LiAdd(NmsNmhMyMaxVersNo, NmsRangeSize);
|
|||
|
NmsHighWaterMarkVersNo.QuadPart =
|
|||
|
LiAdd(NmsNmhMyMaxVersNo, NmsHalfRangeSize);
|
|||
|
}
|
|||
|
} //end of if state is INITING
|
|||
|
|
|||
|
//
|
|||
|
// Check to see if a backup directory has been specified for the WINS
|
|||
|
// database
|
|||
|
//
|
|||
|
//
|
|||
|
// Read in the name of the recovery file
|
|||
|
//
|
|||
|
Sz = WINS_MAX_FILENAME_SZ * sizeof(TCHAR);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_BACKUP_DIR_PATH_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)DirPath,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if ((RetVal != ERROR_SUCCESS) || (DirPath[0] == (TCHAR)EOS))
|
|||
|
{
|
|||
|
pWinsCnf->pBackupDirPath = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if(!WinsMscGetName(ValTyp, DirPath, Path2, WINS_MAX_FILENAME_SZ, &pHoldFileName))
|
|||
|
{
|
|||
|
pWinsCnf->pBackupDirPath = NULL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
WinsMscAlloc(Sz + sizeof(WINS_BACKUP_DIR_ASCII), &pWinsCnf->pBackupDirPath);
|
|||
|
FUTURES("When Jet starts taking UNICODE input, get rid of this")
|
|||
|
WinsMscConvertUnicodeStringToAscii((LPBYTE)pHoldFileName, pWinsCnf->pBackupDirPath, WINS_MAX_FILENAME_SZ);
|
|||
|
strcat(pWinsCnf->pBackupDirPath, WINS_BACKUP_DIR_ASCII);
|
|||
|
|
|||
|
//
|
|||
|
// No need to look at the return code.
|
|||
|
//
|
|||
|
CreateDirectoryA(pWinsCnf->pBackupDirPath, NULL);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check to see if the admin. has told WINS to do a backup on
|
|||
|
// termination
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->fDoBackupOnTerm);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_DO_BACKUP_ON_TERM_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->fDoBackupOnTerm,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
pWinsCnf->fDoBackupOnTerm = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Check to see if static records have to be treated as p-static
|
|||
|
//
|
|||
|
Sz = sizeof(pWinsCnf->fPStatic);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_MIGRATION_ON_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->fPStatic,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
pWinsCnf->fPStatic = FALSE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Read max wins registration que len.
|
|||
|
//
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_BURST_QUE_SIZE_NM,
|
|||
|
ValTyp,
|
|||
|
QueOtherNbtWrkQueMaxLen,
|
|||
|
0,
|
|||
|
WINS_QUEUE_HWM
|
|||
|
);
|
|||
|
|
|||
|
if (QueOtherNbtWrkQueMaxLen < WINS_QUEUE_HWM_MIN) {
|
|||
|
QueOtherNbtWrkQueMaxLen = WINS_QUEUE_HWM_MIN;
|
|||
|
} else if (QueOtherNbtWrkQueMaxLen > WINS_QUEUE_HWM_MAX) {
|
|||
|
QueOtherNbtWrkQueMaxLen = WINS_QUEUE_HWM_MAX;
|
|||
|
}
|
|||
|
|
|||
|
// Read whether or not we randomize 1c list retrieval.
|
|||
|
QUERY_VALUE_M(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_RANDOMIZE_1C_LIST_NM,
|
|||
|
ValTyp,
|
|||
|
WinsCnf.fRandomize1CList,
|
|||
|
0,
|
|||
|
FALSE
|
|||
|
);
|
|||
|
|
|||
|
} // end of try ..
|
|||
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("WinsCnfReadWinsInfo");
|
|||
|
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_SFT_ERR);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
ReadCCInfo(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
Function to read in CC info
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes --
|
|||
|
Error status codes --
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
SYSTEMTIME CurrTime;
|
|||
|
DWORD Sz;
|
|||
|
LONG RetVal;
|
|||
|
DWORD ValTyp;
|
|||
|
VERS_NO_T MaxVersNo;
|
|||
|
WINSEVT_STRS_T EvtStr;
|
|||
|
|
|||
|
DBGENTER("ReadCCInfo\n");
|
|||
|
|
|||
|
//
|
|||
|
// Open the Consistency Chk Key
|
|||
|
//
|
|||
|
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
_WINS_CFG_CC_KEY,
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_READ | KEY_WRITE, //we desire read/write access
|
|||
|
// to the key
|
|||
|
&sCCKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_OPEN_CC_KEY
|
|||
|
);
|
|||
|
pWinsCnf->CC.TimeInt = MAXULONG;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
Sz = sizeof(pWinsCnf->CC.TimeInt);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sCCKey,
|
|||
|
WINSCNF_CC_INTVL_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->CC.TimeInt,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_CC_INTERVAL_VAL
|
|||
|
);
|
|||
|
|
|||
|
pWinsCnf->CC.TimeInt = WINSCNF_CC_DEF_INTERVAL;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
if ( !sfNoLimitChk)
|
|||
|
{
|
|||
|
if (pWinsCnf->CC.TimeInt < WINSCNF_CC_MIN_INTERVAL)
|
|||
|
{
|
|||
|
pWinsCnf->CC.TimeInt = WINSCNF_CC_MIN_INTERVAL;
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_CC_INTVL_NM,
|
|||
|
pWinsCnf->CC.TimeInt);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->CC.TimeInt < 60)
|
|||
|
{
|
|||
|
pWinsCnf->CC.TimeInt = 60;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
Sz = sizeof(pWinsCnf->CC.MaxRecsAAT);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sCCKey,
|
|||
|
WINSCNF_CC_MAX_RECS_AAT_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->CC.MaxRecsAAT,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_CC_MAX_RECS_AAT_VAL
|
|||
|
);
|
|||
|
|
|||
|
pWinsCnf->CC.MaxRecsAAT = WINSCNF_CC_DEF_RECS_AAT;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->CC.MaxRecsAAT < WINSCNF_CC_MIN_RECS_AAT)
|
|||
|
{
|
|||
|
if ( !sfNoLimitChk)
|
|||
|
{
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_MAX_RECS_AAT,
|
|||
|
NULL, __LINE__, "udd",
|
|||
|
WINSCNF_CC_MAX_RECS_AAT_NM,
|
|||
|
WINSCNF_CC_MIN_RECS_AAT,
|
|||
|
pWinsCnf->CC.MaxRecsAAT);
|
|||
|
pWinsCnf->CC.MaxRecsAAT = WINSCNF_CC_MIN_RECS_AAT;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pWinsCnf->CC.MaxRecsAAT < 2)
|
|||
|
{
|
|||
|
pWinsCnf->CC.MaxRecsAAT = 2;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Sz = sizeof(pWinsCnf->CC.fUseRplPnrs);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
sCCKey,
|
|||
|
WINSCNF_CC_USE_RPL_PNRS_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&pWinsCnf->CC.fUseRplPnrs,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_INFO_D_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_GET_CC_USE_RPL_PNRS_VAL
|
|||
|
);
|
|||
|
|
|||
|
pWinsCnf->CC.fUseRplPnrs = WINSCNF_CC_DEF_USE_RPL_PNRS;
|
|||
|
}
|
|||
|
|
|||
|
GetLocalTime(&CurrTime);
|
|||
|
GetSpTimeData(sCCKey, &CurrTime, &pWinsCnf->CC.fSpTime, &pWinsCnf->CC.SpTimeInt);
|
|||
|
REG_M(
|
|||
|
RegCloseKey(sCCKey),
|
|||
|
WINS_EVT_CANT_CLOSE_KEY,
|
|||
|
WINS_EXC_CANT_CLOSE_KEY
|
|||
|
);
|
|||
|
DBGLEAVE("ReadCCInfo\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
#if USENETBT > 0
|
|||
|
//------------------------------------------------------------------------
|
|||
|
STATUS
|
|||
|
WinsCnfReadNbtDeviceName(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This procedure reads the registry to get the name of NBT to bind to.
|
|||
|
That name is stored in the Linkage section under the Netbt key.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
0 if successful, -1 otherwise.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
PTCHAR SubKeyLinkage=NETBT_LINKAGE_KEY;
|
|||
|
HKEY Key;
|
|||
|
PTCHAR pLinkage=TEXT("Export");
|
|||
|
LONG Type;
|
|||
|
LONG Status;
|
|||
|
LONG Status2;
|
|||
|
ULONG Size;
|
|||
|
|
|||
|
//
|
|||
|
// Open the NETBT key
|
|||
|
//
|
|||
|
Status = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|||
|
SubKeyLinkage,
|
|||
|
0,
|
|||
|
KEY_READ,
|
|||
|
&Key);
|
|||
|
|
|||
|
if (Status == ERROR_SUCCESS)
|
|||
|
{
|
|||
|
//
|
|||
|
// now read the linkage values
|
|||
|
//
|
|||
|
Status = RegQueryValueEx(Key,
|
|||
|
pLinkage,
|
|||
|
NULL,
|
|||
|
&Type,
|
|||
|
NULL,
|
|||
|
&Size);
|
|||
|
if (Status != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
DBGPRINT0(ERR, "Error closing the Registry key\n");
|
|||
|
WINSEVT_LOG_M(Status, WINS_EVT_QUERY_NETBT_KEY_ERR);
|
|||
|
(VOID)RegCloseKey(Key);
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Let us allocate a buffer that is big enough to hold all the
|
|||
|
// data
|
|||
|
//
|
|||
|
WinsMscAlloc(Size, (LPVOID *)&pWinsCnfNbtPath);
|
|||
|
|
|||
|
//
|
|||
|
// now read the linkage values
|
|||
|
//
|
|||
|
Status = RegQueryValueEx(Key,
|
|||
|
pLinkage,
|
|||
|
NULL,
|
|||
|
&Type,
|
|||
|
(LPBYTE)pWinsCnfNbtPath,
|
|||
|
&Size);
|
|||
|
Status2 = RegCloseKey(Key);
|
|||
|
if ((Status != ERROR_SUCCESS) || (Status2 != ERROR_SUCCESS))
|
|||
|
{
|
|||
|
DBGPRINT0(ERR, "Error closing the Registry key\n");
|
|||
|
WINSEVT_LOG_M(Status, WINS_EVT_QUERY_NETBT_KEY_ERR);
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
WINSEVT_LOG_D_M(Status, WINS_EVT_OPEN_NETBT_KEY_ERR);
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
|
|||
|
return(WINS_SUCCESS);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfReadRegInfo(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to read the registry in order to populate the
|
|||
|
WinsCnf structure
|
|||
|
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
WinsCnfInitConfig
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
try {
|
|||
|
if (sfParametersKeyExists)
|
|||
|
{
|
|||
|
/*
|
|||
|
Read in the registry information pertaining to WINS
|
|||
|
*/
|
|||
|
WinsCnfReadWinsInfo(pWinsCnf);
|
|||
|
}
|
|||
|
|
|||
|
if (sfPartnersKeyExists)
|
|||
|
{
|
|||
|
//
|
|||
|
// Read the PUSH/PULL records and other global information used for
|
|||
|
// replication
|
|||
|
//
|
|||
|
WinsCnfReadPartnerInfo(pWinsCnf);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Do a sanity check on the params. We are not interested in the
|
|||
|
// return code
|
|||
|
//
|
|||
|
(VOID)SanityChkParam(pWinsCnf);
|
|||
|
}
|
|||
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("WinsCnfReadRegInfo");
|
|||
|
|
|||
|
//
|
|||
|
// If we encountered an exception at boot time, we do not want to
|
|||
|
// reraise the exception, since we want to come up and continue on
|
|||
|
// For the non-initing case, the exception that we raise will be caught
|
|||
|
// in Reinit(). For the boot time case, it is ok to come up with the
|
|||
|
// defaults (an event message is being logged) - in WinsCnf.
|
|||
|
// In the non-init case, the defaults are not in the memory used to
|
|||
|
// read in the parameters (WinsCnf is initialized with stuff in
|
|||
|
// this memory block later).
|
|||
|
//
|
|||
|
if (WinsCnf.State_e != WINSCNF_E_INITING)
|
|||
|
{
|
|||
|
WINS_RERAISE_EXC_M();
|
|||
|
}
|
|||
|
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RECONFIG_ERR);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfCopyWinsCnf(
|
|||
|
WINS_CLIENT_E Client_e,
|
|||
|
PWINSCNF_CNF_T pSrc
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to copy relevant information from a WINS
|
|||
|
Cnf structure to the master (external) Wins Cnf structure
|
|||
|
|
|||
|
Arguments:
|
|||
|
pSrc - WinsCnf stucture to copy from
|
|||
|
|
|||
|
Externals Used:
|
|||
|
WinsCnf
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
RplPullInit
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
This function may be enhanced in the future
|
|||
|
|
|||
|
Note: this function is called only by the main thread
|
|||
|
--*/
|
|||
|
{
|
|||
|
|
|||
|
BOOL fScvParamChg = FALSE;
|
|||
|
|
|||
|
if (Client_e == WINS_E_WINSCNF)
|
|||
|
{
|
|||
|
|
|||
|
FUTURES("Queue a message to the Scavenger thread passing it pSrc")
|
|||
|
FUTURES("That will avoid this synchronization overhead")
|
|||
|
|
|||
|
//
|
|||
|
// We need to synchronize with the scavenger thread and
|
|||
|
// RPC threads that might be looking at fRplOnlyWCnfPnrs
|
|||
|
//
|
|||
|
EnterCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
|
|||
|
//
|
|||
|
// Also need to synchronize with the nbt threads doing
|
|||
|
// name registrations/refreshes
|
|||
|
//
|
|||
|
EnterCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
|
|||
|
//
|
|||
|
// Sanity check the parameters
|
|||
|
//
|
|||
|
fScvParamChg = SanityChkParam(pSrc);
|
|||
|
|
|||
|
if (fScvParamChg)
|
|||
|
{
|
|||
|
//
|
|||
|
// Initialize the scavenging stuff.
|
|||
|
//
|
|||
|
WinsCnf.RefreshInterval = pSrc->RefreshInterval;
|
|||
|
WinsCnf.TombstoneInterval = pSrc->TombstoneInterval;
|
|||
|
WinsCnf.TombstoneTimeout = pSrc->TombstoneTimeout;
|
|||
|
WinsCnf.CC = pSrc->CC;
|
|||
|
WinsCnf.ScvThdPriorityLvl = pSrc->ScvThdPriorityLvl;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Store the verify interval since SanityChkParam does
|
|||
|
// not set fScvParamChg if VerifyINterval has changed.
|
|||
|
//
|
|||
|
WinsCnf.VerifyInterval = pSrc->VerifyInterval;
|
|||
|
|
|||
|
WinsCnf.fRplOnlyWCnfPnrs = pSrc->fRplOnlyWCnfPnrs;
|
|||
|
WinsCnf.LogDetailedEvts = pSrc->LogDetailedEvts;
|
|||
|
WinsCnf.fAdd1Bto1CQueries = pSrc->fAdd1Bto1CQueries;
|
|||
|
WinsCnf.fPStatic = pSrc->fPStatic;
|
|||
|
|
|||
|
LeaveCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
|
|||
|
WinsCnf.fDoSpoofing = pSrc->fDoSpoofing;
|
|||
|
WinsCnf.MaxNoOfWrkThds = pSrc->MaxNoOfWrkThds;
|
|||
|
|
|||
|
WinsCnf.fDoBackupOnTerm = pSrc->fDoBackupOnTerm;
|
|||
|
#if MCAST > 0
|
|||
|
WinsCnf.fUseSelfFndPnrs = pSrc->fUseSelfFndPnrs;
|
|||
|
WinsCnf.McastIntvl = pSrc->McastIntvl;
|
|||
|
#endif
|
|||
|
|
|||
|
#if PRSCONN
|
|||
|
WinsCnf.fPrsConn = pSrc->fPrsConn;
|
|||
|
#endif
|
|||
|
if (WinsCnf.fDoBackupOnTerm && pSrc->pBackupDirPath != NULL)
|
|||
|
{
|
|||
|
if (WinsCnf.pBackupDirPath != NULL)
|
|||
|
{
|
|||
|
WinsMscDealloc(WinsCnf.pBackupDirPath);
|
|||
|
}
|
|||
|
WinsCnf.pBackupDirPath = pSrc->pBackupDirPath;
|
|||
|
}
|
|||
|
|
|||
|
LeaveCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
// return;
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (Client_e == WINS_E_RPLPULL)
|
|||
|
{
|
|||
|
|
|||
|
EnterCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
//
|
|||
|
// Copy the Scavenging parameters into the cnf structure
|
|||
|
// just allocated so that we can compare them for
|
|||
|
// compatibility with the new max. replication time interval
|
|||
|
// (since the Partners key was signaled, the replication
|
|||
|
// stuff might have changed)
|
|||
|
//
|
|||
|
pSrc->RefreshInterval = WinsCnf.RefreshInterval;
|
|||
|
pSrc->TombstoneInterval = WinsCnf.TombstoneInterval;
|
|||
|
pSrc->TombstoneTimeout = WinsCnf.TombstoneTimeout;
|
|||
|
pSrc->VerifyInterval = WinsCnf.VerifyInterval;
|
|||
|
|
|||
|
//
|
|||
|
// Wasteful here and in SanityChkParam
|
|||
|
//
|
|||
|
PERF("Pass an argument to SanityChk so that we don't have to do this")
|
|||
|
PERF("See similar remark in SanityChk")
|
|||
|
pSrc->CC = WinsCnf.CC;
|
|||
|
|
|||
|
//
|
|||
|
// Sanity check the parameters.
|
|||
|
//
|
|||
|
// Sanity checking of the parameters is done here in
|
|||
|
// the main thread instead of in the PULL thread because
|
|||
|
// we don't want a situation where two different threads
|
|||
|
// (the main thread for changes to the PARAMETERS key)
|
|||
|
// and the PULL thread (for changes in the PARTNERS key)
|
|||
|
// updating the WinsCnf structure
|
|||
|
//
|
|||
|
// Also, as an aside, we don't copy the PullInfo information
|
|||
|
// into WinsCnf here to avoid unnecessary complication and
|
|||
|
// synchronization that would ensue by the fact that we
|
|||
|
// would then have two threads (main thread) and the PULL
|
|||
|
// thread accessing that field (check Reconfig() in
|
|||
|
// rplpull.c).
|
|||
|
//
|
|||
|
FUTURES("When we start supporting time interval as an attribute of PUSHing")
|
|||
|
FUTURES("move this check inside the NmsNmhNamRegCrtSec below")
|
|||
|
fScvParamChg = SanityChkParam(pSrc);
|
|||
|
|
|||
|
//
|
|||
|
// If one or more scavenging parameters have changed,
|
|||
|
// update WinsCnf and signal the Scavenger thread.
|
|||
|
//
|
|||
|
if (fScvParamChg)
|
|||
|
{
|
|||
|
WinsCnf.RefreshInterval = pSrc->RefreshInterval;
|
|||
|
WinsCnf.TombstoneInterval = pSrc->TombstoneInterval;
|
|||
|
WinsCnf.TombstoneTimeout = pSrc->TombstoneTimeout;
|
|||
|
|
|||
|
//
|
|||
|
// If SanityChkParam changed Tombstone interval, then
|
|||
|
// verify interval has also changed.
|
|||
|
//
|
|||
|
WinsCnf.VerifyInterval = pSrc->VerifyInterval;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
WinsCnf.MaxRplTimeInterval = pSrc->MaxRplTimeInterval;
|
|||
|
WinsCnf.RplType = pSrc->RplType;
|
|||
|
LeaveCriticalSection(&WinsCnfCnfCrtSec);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If the scavenging params have changed we need to signal
|
|||
|
// the scavenger thread
|
|||
|
//
|
|||
|
if (fScvParamChg)
|
|||
|
{
|
|||
|
WinsMscSignalHdl(WinsCnf.CnfChgEvtHdl);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
LPVOID
|
|||
|
WinsCnfGetNextRplCnfRec(
|
|||
|
PRPL_CONFIG_REC_T pCnfRec,
|
|||
|
RPL_REC_TRAVERSAL_E RecTrv_e
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to get to the next configuration record
|
|||
|
|
|||
|
Arguments:
|
|||
|
pCnfRec - The current configuration record in a buffer of configuration
|
|||
|
records
|
|||
|
RecTrv_e - indicates how the next one should be retrieved. If set to
|
|||
|
TRUE, it means that the next record to be retrieved is one
|
|||
|
that follows the current record in the buffer. If set to
|
|||
|
FALSE, the next record is retrieved using the pNext field
|
|||
|
of the current configuration record
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
address of the next configuration record
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
EstablishComm in rplpull.c, WinsPushTrigger() in wins.c
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
//
|
|||
|
// If no traversal is desired, return NULL as the next record
|
|||
|
//
|
|||
|
if (RecTrv_e == RPL_E_NO_TRAVERSAL)
|
|||
|
{
|
|||
|
return(NULL);
|
|||
|
}
|
|||
|
//
|
|||
|
// Go to the next configuration record in a way specified
|
|||
|
// by the value of the RecTrv_e flag.
|
|||
|
//
|
|||
|
if(RecTrv_e == RPL_E_IN_SEQ)
|
|||
|
{
|
|||
|
pCnfRec = (PRPL_CONFIG_REC_T)(
|
|||
|
(LPBYTE)pCnfRec + RPL_CONFIG_REC_SIZE);
|
|||
|
}
|
|||
|
else // RPL_E_VIA_LINK
|
|||
|
{
|
|||
|
return(pCnfRec->pNext);
|
|||
|
}
|
|||
|
return(pCnfRec);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfAskToBeNotified(
|
|||
|
WINSCNF_KEY_E KeyToMonitor_e
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to request that WINS be notified when
|
|||
|
the information pertaining to WINS and its subkeys in the registry
|
|||
|
changes
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
KeyToMonitor_e
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
Reinit() in nms.c
|
|||
|
WinsCnfOpenSubKeys()
|
|||
|
WinsCnfInitConfig()
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD NotifyFilter = 0;
|
|||
|
LONG RetVal;
|
|||
|
DWORD Error;
|
|||
|
|
|||
|
#define CHK_RET_VAL_M { \
|
|||
|
if (RetVal != ERROR_SUCCESS) \
|
|||
|
{ \
|
|||
|
DBGPRINT1(ERR, "WinsAskToBeNotified: Error = (%d)\n", RetVal); \
|
|||
|
WINSEVT_LOG_M( \
|
|||
|
WINS_FATAL_ERR, \
|
|||
|
WINS_EVT_REG_NTFY_FN_ERR \
|
|||
|
); \
|
|||
|
} \
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* Set the notify filter. Ask to be notified for all changes.
|
|||
|
*/
|
|||
|
NotifyFilter = REG_NOTIFY_CHANGE_NAME |
|
|||
|
REG_NOTIFY_CHANGE_ATTRIBUTES |
|
|||
|
REG_NOTIFY_CHANGE_LAST_SET |
|
|||
|
REG_NOTIFY_CHANGE_SECURITY ;
|
|||
|
|
|||
|
|
|||
|
switch(KeyToMonitor_e)
|
|||
|
{
|
|||
|
case(WINSCNF_E_WINS_KEY):
|
|||
|
|
|||
|
// DBGPRINT0(SPEC, "WinsCnfAskToBeNotified: WINS Key\n");
|
|||
|
RetVal = RegNotifyChangeKeyValue(
|
|||
|
sConfigRoot,
|
|||
|
TRUE, //report changes in key and all subkeys
|
|||
|
REG_NOTIFY_CHANGE_NAME,
|
|||
|
WinsCnf.WinsKChgEvtHdl,
|
|||
|
TRUE //Async signaling is what we want
|
|||
|
);
|
|||
|
CHK_RET_VAL_M;
|
|||
|
break;
|
|||
|
case(WINSCNF_E_PARAMETERS_KEY):
|
|||
|
|
|||
|
// DBGPRINT0(SPEC, "WinsCnfAskToBeNotified: PARAMETERS Key\n");
|
|||
|
RetVal = RegNotifyChangeKeyValue(
|
|||
|
sParametersKey,
|
|||
|
TRUE, //report changes in key and all subkeys
|
|||
|
NotifyFilter,
|
|||
|
WinsCnf.ParametersKChgEvtHdl,
|
|||
|
TRUE //Async signaling is what we want
|
|||
|
);
|
|||
|
CHK_RET_VAL_M;
|
|||
|
break;
|
|||
|
|
|||
|
case(WINSCNF_E_PARTNERS_KEY):
|
|||
|
|
|||
|
// DBGPRINT0(SPEC, "WinsCnfAskToBeNotified: PARTNERS Key\n");
|
|||
|
RetVal = RegNotifyChangeKeyValue(
|
|||
|
sPartnersKey,
|
|||
|
TRUE, //report changes in key and all subkeys
|
|||
|
NotifyFilter,
|
|||
|
WinsCnf.PartnersKChgEvtHdl,
|
|||
|
TRUE //Async signaling is what we want
|
|||
|
);
|
|||
|
|
|||
|
CHK_RET_VAL_M;
|
|||
|
break;
|
|||
|
|
|||
|
FUTURES("Remove the following case")
|
|||
|
//
|
|||
|
// The following case would never get exercised.
|
|||
|
//
|
|||
|
case(WINSCNF_E_ALL_KEYS):
|
|||
|
|
|||
|
RetVal = RegNotifyChangeKeyValue(
|
|||
|
sConfigRoot,
|
|||
|
TRUE, //report changes in key and all subkeys
|
|||
|
REG_NOTIFY_CHANGE_NAME,
|
|||
|
WinsCnf.WinsKChgEvtHdl,
|
|||
|
TRUE //Async signaling is what we want
|
|||
|
);
|
|||
|
CHK_RET_VAL_M;
|
|||
|
if (sfParametersKeyExists)
|
|||
|
{
|
|||
|
RetVal = RegNotifyChangeKeyValue(
|
|||
|
sParametersKey,
|
|||
|
TRUE, //report changes in key and
|
|||
|
//all subkeys
|
|||
|
NotifyFilter,
|
|||
|
WinsCnf.ParametersKChgEvtHdl,
|
|||
|
TRUE //Async signaling is what we
|
|||
|
// want
|
|||
|
);
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
Error = GetLastError();
|
|||
|
if (Error == ERROR_BADKEY)
|
|||
|
{
|
|||
|
//
|
|||
|
// Key must not be there
|
|||
|
//
|
|||
|
sfParametersKeyExists = FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DBGPRINT1(ERR,
|
|||
|
"WinsCnfAskToBeNotified: RegNotifyChangeKeyValue error = (%d)\n",
|
|||
|
Error);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if (sfPartnersKeyExists)
|
|||
|
{
|
|||
|
RetVal = RegNotifyChangeKeyValue(
|
|||
|
sPartnersKey,
|
|||
|
TRUE, //report changes in key and
|
|||
|
//all subkeys
|
|||
|
NotifyFilter,
|
|||
|
WinsCnf.PartnersKChgEvtHdl,
|
|||
|
TRUE //Async signaling is what we
|
|||
|
//want
|
|||
|
);
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
Error = GetLastError();
|
|||
|
if (Error == ERROR_BADKEY)
|
|||
|
{
|
|||
|
//
|
|||
|
// Key must not be there
|
|||
|
//
|
|||
|
sfPartnersKeyExists = FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DBGPRINT1(ERR,
|
|||
|
"WinsCnfAskToBeNotified: RegNotifyChangeKeyValue error = (%d)\n",
|
|||
|
Error);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
break;
|
|||
|
default:
|
|||
|
|
|||
|
DBGPRINT1(ERR, "WinsCnfAskToBeNotified: Wrong Hdl (%d)\n",
|
|||
|
KeyToMonitor_e);
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_SFT_ERR);
|
|||
|
WINS_RAISE_EXC_M(WINS_EXC_FAILURE);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfDeallocCnfMem(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to deallocate the Wins Cnf structure and
|
|||
|
memory associated with it
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
Reconfig in rplpull.c
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
try {
|
|||
|
//
|
|||
|
// Deallocate the buffer holding one or more names of files used
|
|||
|
// for STATIC initialization of WINS
|
|||
|
//
|
|||
|
if (pWinsCnf->pStaticDataFile != NULL)
|
|||
|
{
|
|||
|
WinsMscDealloc(pWinsCnf->pStaticDataFile);
|
|||
|
}
|
|||
|
WinsMscDealloc(pWinsCnf);
|
|||
|
}
|
|||
|
except(EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("WinsCnfDeallocCnfMem");
|
|||
|
DBGPRINT0(EXC, "WinsCnfDeallocCnfMem: Got an exception\n");
|
|||
|
WINSEVT_LOG_M(GetExceptionCode(), WINS_EVT_RECONFIG_ERR);
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
VOID
|
|||
|
GetKeyInfo(
|
|||
|
IN HKEY Key,
|
|||
|
IN WINSCNF_KEY_E KeyType_e,
|
|||
|
OUT LPDWORD pNoOfSubKeys,
|
|||
|
OUT LPDWORD pNoOfVals
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to get the number of subkeys under a key
|
|||
|
|
|||
|
Arguments:
|
|||
|
Key - Key whose subkey count has to be determined
|
|||
|
KeyType_e
|
|||
|
pNoOfSubKeys
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
None
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
GetPnrInfo()
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
TCHAR ClsStr[40];
|
|||
|
DWORD ClsStrSz = sizeof(ClsStr);
|
|||
|
DWORD LongestKeyLen;
|
|||
|
DWORD LongestKeyClassLen;
|
|||
|
DWORD LongestValueNameLen;
|
|||
|
DWORD LongestValueDataLen;
|
|||
|
DWORD SecDesc;
|
|||
|
LONG RetVal;
|
|||
|
|
|||
|
FILETIME LastWrite;
|
|||
|
/*
|
|||
|
Query the key. The subkeys are IP addresses of PULL
|
|||
|
partners.
|
|||
|
*/
|
|||
|
RetVal = RegQueryInfoKey(
|
|||
|
Key,
|
|||
|
ClsStr,
|
|||
|
&ClsStrSz,
|
|||
|
NULL, //must be NULL, reserved
|
|||
|
pNoOfSubKeys,
|
|||
|
&LongestKeyLen,
|
|||
|
&LongestKeyClassLen,
|
|||
|
pNoOfVals,
|
|||
|
&LongestValueNameLen,
|
|||
|
&LongestValueDataLen,
|
|||
|
&SecDesc,
|
|||
|
&LastWrite
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_M(
|
|||
|
WINS_FATAL_ERR,
|
|||
|
KeyType_e == WINSCNF_E_DATAFILES_KEY ?
|
|||
|
WINS_EVT_CANT_QUERY_DATAFILES_KEY :
|
|||
|
((KeyType_e == WINSCNF_E_PULL_KEY) ?
|
|||
|
WINS_EVT_CANT_QUERY_PULL_KEY :
|
|||
|
((KeyType_e == WINSCNF_E_PUSH_KEY) ?
|
|||
|
WINS_EVT_CANT_QUERY_PUSH_KEY :
|
|||
|
WINS_EVT_CANT_QUERY_SPEC_GRP_MASKS_KEY))
|
|||
|
);
|
|||
|
WINS_RAISE_EXC_M(WINS_EXC_CANT_QUERY_KEY);
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
VOID
|
|||
|
WinsCnfOpenSubKeys(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function opens the subkeys of the WINS key. The subkeys are
|
|||
|
the PARTNERS key and the PARAMETERS key.
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
sfParamatersKeyExists
|
|||
|
sfPartnersKeyExists
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
WinsCnfInitConfig()
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
LONG RetVal;
|
|||
|
|
|||
|
//
|
|||
|
// Check if the Parameters and Partners Keys are present
|
|||
|
//
|
|||
|
ChkWinsSubKeys();
|
|||
|
|
|||
|
//
|
|||
|
// Try to open the Parameters key if it exists
|
|||
|
//
|
|||
|
if ((sfParametersKeyExists) && (!sfParametersKeyOpen))
|
|||
|
{
|
|||
|
/*
|
|||
|
* Open the Parameters key
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
_WINS_CFG_PARAMETERS_KEY,
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_READ | KEY_WRITE, //we desire read/write access
|
|||
|
// to the key
|
|||
|
&sParametersKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
CHECK("Is there any need to log this")
|
|||
|
WINSEVT_LOG_INFO_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_OPEN_PARAMETERS_KEY
|
|||
|
);
|
|||
|
sfParametersKeyExists = FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sfParametersKeyOpen = TRUE;
|
|||
|
WinsCnfAskToBeNotified(WINSCNF_E_PARAMETERS_KEY);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Try to open the Partners key if it exists
|
|||
|
//
|
|||
|
if ((sfPartnersKeyExists) && (!sfPartnersKeyOpen))
|
|||
|
{
|
|||
|
/*
|
|||
|
* Open the Partners key
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
_WINS_CFG_PARTNERS_KEY,
|
|||
|
0, //must be zero(reserved)
|
|||
|
KEY_READ, //we desire read
|
|||
|
//access to the key
|
|||
|
&sPartnersKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
|
|||
|
CHECK("Is there any need to log this")
|
|||
|
WINSEVT_LOG_INFO_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_OPEN_KEY
|
|||
|
);
|
|||
|
sfPartnersKeyExists = FALSE;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sfPartnersKeyOpen = TRUE;
|
|||
|
WinsCnfAskToBeNotified(WINSCNF_E_PARTNERS_KEY);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
|
|||
|
} //WinsCnfOpenSubKeys()
|
|||
|
|
|||
|
BOOL
|
|||
|
SanityChkParam(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to ensure that the time intervals for
|
|||
|
scavenging specified in WinsCnf are compatible with the ones
|
|||
|
used for replication
|
|||
|
|
|||
|
Arguments:
|
|||
|
pWinsCnf - ptr to the WINS configuration
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
WinsCnfCopyWinsCnf (during reinitialization of the WINS), by
|
|||
|
WinsCnfReadRegInfo() during initialization of the WINS
|
|||
|
Side Effects:
|
|||
|
|
|||
|
The scavenging intervals could be affected
|
|||
|
|
|||
|
Comments:
|
|||
|
This function must be called from inside the critical section
|
|||
|
guarded by WinsCnfCnfCrtSec except at process initialization.
|
|||
|
--*/
|
|||
|
{
|
|||
|
DWORD MinTombInterval;
|
|||
|
BOOL fScvParamChg = FALSE;
|
|||
|
WINSEVT_STRS_T EvtStr;
|
|||
|
EvtStr.NoOfStrs = 1;
|
|||
|
|
|||
|
DBGENTER("SanityChkParam\n");
|
|||
|
|
|||
|
//
|
|||
|
// Get the minimum tombstone time interval
|
|||
|
//
|
|||
|
MinTombInterval = WINSCNF_MAKE_TOMB_INTVL_M(pWinsCnf->RefreshInterval,
|
|||
|
pWinsCnf->MaxRplTimeInterval);
|
|||
|
|
|||
|
//
|
|||
|
// Make the actual equal to the min. if it is less
|
|||
|
//
|
|||
|
if (!sfNoLimitChk && (pWinsCnf->TombstoneInterval < MinTombInterval))
|
|||
|
{
|
|||
|
DBGPRINT2(FLOW, "SanityChkParam: Adjusting Tombstone Interval from (%d) to (%d)\n", pWinsCnf->TombstoneInterval, MinTombInterval);
|
|||
|
|
|||
|
FUTURES("This is actually a warning. Use a different macro or enhance it")
|
|||
|
FUTURES("Currently, it will log this message as an informational")
|
|||
|
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL_R,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_TOMBSTONE_INTVL_NM,
|
|||
|
MinTombInterval );
|
|||
|
|
|||
|
pWinsCnf->TombstoneInterval = MinTombInterval;
|
|||
|
|
|||
|
//
|
|||
|
// Verify Interval is dependent on the tombstone interval
|
|||
|
//
|
|||
|
pWinsCnf->VerifyInterval = WINSCNF_MAKE_VERIFY_INTVL_M(MinTombInterval);
|
|||
|
fScvParamChg = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// reusing the var. The time interval is for tombstone timeout
|
|||
|
//
|
|||
|
MinTombInterval =
|
|||
|
WINSCNF_MAKE_TOMBTMOUT_INTVL_M(pWinsCnf->MaxRplTimeInterval);
|
|||
|
if (!sfNoLimitChk && (pWinsCnf->TombstoneTimeout < MinTombInterval))
|
|||
|
{
|
|||
|
DBGPRINT2(FLOW, "SanityChkParam: Adjusting Tombstone Timeout from (%d) to (%d)\n", pWinsCnf->TombstoneInterval, MinTombInterval);
|
|||
|
|
|||
|
pWinsCnf->TombstoneTimeout = MinTombInterval;
|
|||
|
WinsEvtLogDetEvt(TRUE, WINS_EVT_ADJ_TIME_INTVL_R,
|
|||
|
NULL, __LINE__, "ud",
|
|||
|
WINSCNF_TOMBSTONE_TMOUT_NM,
|
|||
|
MinTombInterval );
|
|||
|
if (!fScvParamChg)
|
|||
|
{
|
|||
|
fScvParamChg = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
if (!fScvParamChg)
|
|||
|
{
|
|||
|
PERF("Pass an argument to SanityChk so that we don't have to do this")
|
|||
|
PERF("for CC for the case where we just read the partner info. See")
|
|||
|
PERF("WinsCnfCopyWinsCnf for the case where client_e is WINS_E_RPLPULL")
|
|||
|
if (
|
|||
|
(WinsCnf.RefreshInterval != pWinsCnf->RefreshInterval)
|
|||
|
||
|
|||
|
(WinsCnf.TombstoneInterval != pWinsCnf->TombstoneInterval)
|
|||
|
||
|
|||
|
(WinsCnf.TombstoneTimeout != pWinsCnf->TombstoneTimeout)
|
|||
|
||
|
|||
|
(WinsCnf.CC.TimeInt != pWinsCnf->CC.TimeInt)
|
|||
|
||
|
|||
|
(WinsCnf.CC.SpTimeInt != pWinsCnf->CC.SpTimeInt)
|
|||
|
||
|
|||
|
(WinsCnf.CC.fUseRplPnrs != pWinsCnf->CC.fUseRplPnrs)
|
|||
|
||
|
|||
|
(WinsCnf.CC.MaxRecsAAT != pWinsCnf->CC.MaxRecsAAT)
|
|||
|
)
|
|||
|
{
|
|||
|
fScvParamChg = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
DBGLEAVE("SanityChkParam\n");
|
|||
|
return(fScvParamChg);
|
|||
|
}
|
|||
|
STATUS
|
|||
|
WinsCnfGetNamesOfDataFiles(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function gets the names of all the datafiles that need to
|
|||
|
be used for initializing WINS.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes -- WINS_SUCCESS
|
|||
|
Error status codes -- WINS_FAILURE
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
LONG RetVal;
|
|||
|
HKEY DFKey;
|
|||
|
DWORD BuffSize;
|
|||
|
STATUS RetStat = WINS_SUCCESS;
|
|||
|
PWINSCNF_DATAFILE_INFO_T pSaveDef;
|
|||
|
DWORD NoOfSubKeys;
|
|||
|
|
|||
|
DBGENTER("WinsCnfGetNamesOfDataFiles\n");
|
|||
|
|
|||
|
//
|
|||
|
// Store timestamp of initialization in the statistics structure
|
|||
|
//
|
|||
|
WinsIntfSetTime(NULL, WINSINTF_E_INIT_DB);
|
|||
|
|
|||
|
//
|
|||
|
// Set up the default name
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// First allocate the buffer that will hold the default file name
|
|||
|
//
|
|||
|
WinsMscAlloc(WINSCNF_FILE_INFO_SZ, &pWinsCnf->pStaticDataFile);
|
|||
|
|
|||
|
lstrcpy(pWinsCnf->pStaticDataFile->FileNm, WINSCNF_STATIC_DATA_NAME);
|
|||
|
|
|||
|
//
|
|||
|
// The default name contains a %<string>% in it. Therefore, specify
|
|||
|
// the type as EXPAND_SZ
|
|||
|
//
|
|||
|
pWinsCnf->pStaticDataFile->StrType = REG_EXPAND_SZ;
|
|||
|
pWinsCnf->NoOfDataFiles = 1;
|
|||
|
|
|||
|
pSaveDef = pWinsCnf->pStaticDataFile; //save the address
|
|||
|
|
|||
|
/*
|
|||
|
* Open the DATAFILES key
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
_WINS_CFG_DATAFILES_KEY,
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_READ, //we desire read access to the keyo
|
|||
|
&DFKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
|
|||
|
CHECK("Is there any need to log this")
|
|||
|
WINSEVT_LOG_INFO_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
WINS_EVT_CANT_OPEN_DATAFILES_KEY
|
|||
|
);
|
|||
|
DBGLEAVE("WinsCnfGetNamesOfDataFiles\n");
|
|||
|
return(FALSE);
|
|||
|
}
|
|||
|
else
|
|||
|
try {
|
|||
|
{
|
|||
|
//
|
|||
|
// Get the count of data files listed under the DATAFILES
|
|||
|
// key
|
|||
|
//
|
|||
|
GetKeyInfo(
|
|||
|
DFKey,
|
|||
|
WINSCNF_E_DATAFILES_KEY,
|
|||
|
&NoOfSubKeys, //ignored
|
|||
|
&pWinsCnf->NoOfDataFiles
|
|||
|
);
|
|||
|
}
|
|||
|
if (pWinsCnf->NoOfDataFiles > 0)
|
|||
|
{
|
|||
|
|
|||
|
DWORD Index;
|
|||
|
PWINSCNF_DATAFILE_INFO_T pTmp;
|
|||
|
TCHAR ValNmBuff[MAX_PATH];
|
|||
|
DWORD ValNmBuffSz = MAX_PATH;
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Allocate buffer big enough to hold data for
|
|||
|
// the number of subkeys found under the PULL key
|
|||
|
//
|
|||
|
BuffSize = WINSCNF_FILE_INFO_SZ * pWinsCnf->NoOfDataFiles;
|
|||
|
WinsMscAlloc( BuffSize, &pWinsCnf->pStaticDataFile);
|
|||
|
|
|||
|
/*
|
|||
|
* Enumerate the values
|
|||
|
*/
|
|||
|
for(
|
|||
|
Index = 0, pTmp = pWinsCnf->pStaticDataFile;
|
|||
|
Index < pWinsCnf->NoOfDataFiles;
|
|||
|
// no third expression
|
|||
|
)
|
|||
|
{
|
|||
|
ValNmBuffSz = sizeof(ValNmBuff)/sizeof(TCHAR); //init before
|
|||
|
//every call
|
|||
|
BuffSize = sizeof(pWinsCnf->pStaticDataFile->FileNm);
|
|||
|
RetVal = RegEnumValue(
|
|||
|
DFKey,
|
|||
|
Index, //key
|
|||
|
ValNmBuff,
|
|||
|
&ValNmBuffSz,
|
|||
|
(LPDWORD)NULL, //reserved
|
|||
|
&pTmp->StrType,
|
|||
|
(LPBYTE)(pTmp->FileNm),//ptr to var. to
|
|||
|
//hold name of
|
|||
|
//datafile
|
|||
|
&BuffSize //not looked at by us
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
//
|
|||
|
// if StrType is not REG_SZ or REG_EXPAND_SZ, go to
|
|||
|
// the next Value
|
|||
|
//
|
|||
|
if (
|
|||
|
(pTmp->StrType != REG_EXPAND_SZ)
|
|||
|
&&
|
|||
|
(pTmp->StrType != REG_SZ)
|
|||
|
)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
Index++;
|
|||
|
pTmp = (PWINSCNF_DATAFILE_INFO_T)((LPBYTE)pTmp +
|
|||
|
WINSCNF_FILE_INFO_SZ);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If not even one valid name was retrieved, get rid of the
|
|||
|
// buffer
|
|||
|
//
|
|||
|
if (Index == 0)
|
|||
|
{
|
|||
|
//
|
|||
|
// Get rid of the buffer
|
|||
|
//
|
|||
|
WinsMscDealloc((LPBYTE)pWinsCnf->pStaticDataFile);
|
|||
|
|
|||
|
//
|
|||
|
// We will use the default
|
|||
|
//
|
|||
|
pWinsCnf->pStaticDataFile = pSaveDef;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
//
|
|||
|
// Get rid of the default name buffer
|
|||
|
//
|
|||
|
WinsMscDealloc((LPBYTE)pSaveDef);
|
|||
|
}
|
|||
|
|
|||
|
pWinsCnf->NoOfDataFiles = Index;
|
|||
|
}
|
|||
|
} // end of try ..
|
|||
|
except (EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("WinsCnfGetNamesOfDataFiles");
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_SFT_ERR);
|
|||
|
RetStat = WINS_FAILURE;
|
|||
|
}
|
|||
|
REG_M(
|
|||
|
RegCloseKey(DFKey),
|
|||
|
WINS_EVT_CANT_CLOSE_KEY,
|
|||
|
WINS_EXC_CANT_CLOSE_KEY
|
|||
|
);
|
|||
|
DBGLEAVE("WinsCnfGetNamesOfDataFiles\n");
|
|||
|
return(RetStat);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
WinsCnfCloseKeys(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function closes the the open keys. The keys closed are
|
|||
|
the WINS key, the PARTNERS key, and the PARAMETERS key.
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
sfParametersKeyExists
|
|||
|
sfPartnersKeyExists
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
Reinit()
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
We don't look at the return code of RegCloseKey. This is because
|
|||
|
we might call this function even with the key not being open (not
|
|||
|
the case currently).
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// Close the PARAMETERS key if it is open
|
|||
|
//
|
|||
|
if (sfParametersKeyOpen)
|
|||
|
{
|
|||
|
(VOID)RegCloseKey(sParametersKey);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Close the PARTNERS key if it is open
|
|||
|
//
|
|||
|
if (sfPartnersKeyOpen)
|
|||
|
{
|
|||
|
(VOID)RegCloseKey(sPartnersKey);
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
//
|
|||
|
// NOTE NOTE NOTE: Build 436. If we attempt to close a key that has been
|
|||
|
// deleted from the registry NT comes down
|
|||
|
//
|
|||
|
|
|||
|
//
|
|||
|
// Close the WINS key
|
|||
|
//
|
|||
|
(VOID)RegCloseKey(sConfigRoot);
|
|||
|
#endif
|
|||
|
|
|||
|
return;
|
|||
|
} //WinsCnfCloseKeys()
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
ChkWinsSubKeys(
|
|||
|
VOID
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to check whether we have the PARTNERS
|
|||
|
and PARAMETERS sub-keys under the root subkey of WINS.
|
|||
|
|
|||
|
Arguments:
|
|||
|
None
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
None
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
Reinit() in nms.c
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD NoOfSubKeys = 0;
|
|||
|
DWORD KeyNameSz;
|
|||
|
TCHAR KeyName[20];
|
|||
|
FILETIME LastWrite;
|
|||
|
LONG RetVal;
|
|||
|
BOOL fParametersKey = FALSE;
|
|||
|
BOOL fPartnersKey = FALSE;
|
|||
|
|
|||
|
/*
|
|||
|
* Get each subkey's name
|
|||
|
*/
|
|||
|
RetVal = ERROR_SUCCESS;
|
|||
|
for(
|
|||
|
;
|
|||
|
RetVal == ERROR_SUCCESS;
|
|||
|
NoOfSubKeys++
|
|||
|
)
|
|||
|
{
|
|||
|
KeyNameSz = sizeof(KeyName)/sizeof(TCHAR); //init before every call
|
|||
|
RetVal = RegEnumKeyEx(
|
|||
|
sConfigRoot,
|
|||
|
NoOfSubKeys, //key
|
|||
|
KeyName,
|
|||
|
&KeyNameSz,
|
|||
|
NULL, //reserved
|
|||
|
NULL, //don't need class name
|
|||
|
NULL, //ptr to var. to hold class name
|
|||
|
&LastWrite //not looked at by us
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
if (lstrcmp(KeyName, _WINS_CFG_PARAMETERS_KEY) == 0)
|
|||
|
{
|
|||
|
fParametersKey = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
if (lstrcmp(KeyName, _WINS_CFG_PARTNERS_KEY) == 0)
|
|||
|
{
|
|||
|
fPartnersKey = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// if the Parameters key does not exist but it existed before,
|
|||
|
// close the key to get rid of the handle we have
|
|||
|
//
|
|||
|
if (!fParametersKey)
|
|||
|
{
|
|||
|
if (sfParametersKeyExists)
|
|||
|
{
|
|||
|
sfParametersKeyExists = FALSE;
|
|||
|
sfParametersKeyOpen = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sfParametersKeyExists = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// if the Partners key does not exist but it existed before,
|
|||
|
// close the key to get rid of the handle we have
|
|||
|
//
|
|||
|
if (!fPartnersKey)
|
|||
|
{
|
|||
|
if (sfPartnersKeyExists)
|
|||
|
{
|
|||
|
sfPartnersKeyExists = FALSE;
|
|||
|
sfPartnersKeyOpen = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
sfPartnersKeyExists = TRUE;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
} //ChkWinsSubKeys()
|
|||
|
|
|||
|
VOID
|
|||
|
GetSpTimeData(
|
|||
|
HKEY SubKey,
|
|||
|
LPSYSTEMTIME pCurrTime,
|
|||
|
LPBOOL pfSpTime,
|
|||
|
LPDWORD pSpTimeIntvl
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to get the specific time and period information
|
|||
|
for a PULL/PUSH record.
|
|||
|
|
|||
|
Arguments:
|
|||
|
SubKey - Key of a WINS under the Pull/Push key
|
|||
|
pCnfRFec - ptr to the Conf. record of the WINS
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes -- WINS_SUCCESS
|
|||
|
Error status codes -- WINS_NO_SP_TIME
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
GetPnrInfo
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD ValTyp;
|
|||
|
BYTE tSpTime[MAX_SZ_SIZE];
|
|||
|
BYTE SpTime[MAX_SZ_SIZE];
|
|||
|
LPBYTE pSpTime = SpTime;
|
|||
|
DWORD Sz = sizeof(tSpTime);
|
|||
|
LONG RetVal;
|
|||
|
DWORD Hr = 0;
|
|||
|
DWORD Mt = 0;
|
|||
|
DWORD Sec = 0;
|
|||
|
LONG TimeInt;
|
|||
|
|
|||
|
|
|||
|
// DBGENTER("GetSpTimeData\n");
|
|||
|
*pfSpTime = FALSE;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
Sz = sizeof(tSpTime);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
SubKey,
|
|||
|
WINSCNF_SP_TIME_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
tSpTime,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// If the user has not specifed a specific time, then we use
|
|||
|
// the current time as the specific time. For current time,
|
|||
|
// the interval is 0
|
|||
|
//
|
|||
|
if (RetVal == ERROR_SUCCESS)
|
|||
|
{
|
|||
|
|
|||
|
#ifdef UNICODE
|
|||
|
(VOID)WinsMscConvertUnicodeStringToAscii(tSpTime, SpTime, MAX_SZ_SIZE);
|
|||
|
#else
|
|||
|
pSpTime = tSpTime;
|
|||
|
#endif
|
|||
|
|
|||
|
RetVal = (LONG)sscanf(pSpTime, "%d:%d:%d", &Hr, &Mt, &Sec);
|
|||
|
if ((RetVal == EOF) || (RetVal == 0))
|
|||
|
{
|
|||
|
DBGPRINT1(ERR, "GetSpTime: Wrong time format (%s)\n",
|
|||
|
pSpTime);
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_WRONG_TIME_FORMAT);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
*pSpTimeIntvl = 0;
|
|||
|
if ((Hr <= 23) && (Mt <= 59) && (Sec <= 59))
|
|||
|
{
|
|||
|
TimeInt = ((Hr * 3600) + (Mt * 60) + Sec) -
|
|||
|
((pCurrTime->wHour * 3600) +
|
|||
|
(pCurrTime->wMinute * 60) +
|
|||
|
pCurrTime->wSecond);
|
|||
|
if (TimeInt < 0)
|
|||
|
{
|
|||
|
*pSpTimeIntvl = (24 * 3600) + TimeInt;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
*pSpTimeIntvl = TimeInt;
|
|||
|
}
|
|||
|
*pfSpTime = TRUE;
|
|||
|
DBGPRINT1(DET, "GetSpTimeData: Sp. Time Interval is %d\n",
|
|||
|
*pSpTimeIntvl);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
DBGPRINT0(DET, "GetSpTimeData: WRONG TIME FORMAT\n");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
except (EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("GetSpTime");
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_CONFIG_ERR);
|
|||
|
}
|
|||
|
// DBGLEAVE("GetSpTimeData\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
#if MCAST > 0
|
|||
|
STATUS
|
|||
|
WinsCnfAddPnr(
|
|||
|
RPL_RR_TYPE_E RRType_e,
|
|||
|
LPBYTE pPnrAdd
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes --
|
|||
|
Error status codes --
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
LONG RetVal;
|
|||
|
HKEY CnfKey;
|
|||
|
HKEY PnrKey;
|
|||
|
DWORD NewKeyInd;
|
|||
|
|
|||
|
DBGENTER("WinsCnfAddPnr\n");
|
|||
|
/*
|
|||
|
* Open the key (PULL/PUSH)
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
_WINS_CFG_PULL_KEY :
|
|||
|
_WINS_CFG_PUSH_KEY, //subkey for WINS
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_CREATE_SUB_KEY, //we want "subkey create" priv
|
|||
|
&CnfKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
|
|||
|
CHECK("Is there any need to log this")
|
|||
|
WINSEVT_LOG_INFO_M(
|
|||
|
RetVal,
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
WINS_EVT_CANT_OPEN_PULL_KEY :
|
|||
|
WINS_EVT_CANT_OPEN_PUSH_KEY
|
|||
|
);
|
|||
|
return (WINS_FAILURE);
|
|||
|
}
|
|||
|
//
|
|||
|
// Add the pnr
|
|||
|
//
|
|||
|
RetVal = RegCreateKeyExA(
|
|||
|
CnfKey, //predefined key value
|
|||
|
pPnrAdd, //subkey for WINS
|
|||
|
0, //must be zero (reserved)
|
|||
|
"Class", //class -- may change in future
|
|||
|
REG_OPTION_NON_VOLATILE, //non-volatile information
|
|||
|
KEY_ALL_ACCESS, //we desire all access to the keyo
|
|||
|
NULL, //let key have default sec. attributes
|
|||
|
&PnrKey, //handle to key
|
|||
|
&NewKeyInd //is it a new key (out arg)
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_M(
|
|||
|
RetVal,
|
|||
|
RRType_e == RPL_E_PULL ? WINS_EVT_CANT_OPEN_PULL_SUBKEY
|
|||
|
: WINS_EVT_CANT_OPEN_PUSH_SUBKEY
|
|||
|
);
|
|||
|
DBGPRINT3(ERR, "WinsCnfAddPnr: Could not create key with address = (%s) under the %s Key. RetVal = (%d)\n", pPnrAdd,
|
|||
|
RRType_e == RPL_E_PULL ? "PULL" : "PUSH",
|
|||
|
RetVal);
|
|||
|
return(WINS_FAILURE);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (NewKeyInd != REG_CREATED_NEW_KEY)
|
|||
|
{
|
|||
|
DBGPRINT2(ERR, "WinsCnfAddPnr: key with address = (%s) under the %s Key already present\n", pPnrAdd, RRType_e == RPL_E_PULL ? "PULL" : "PUSH");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
|
|||
|
//
|
|||
|
// If Pull pnr, add the time interval
|
|||
|
//
|
|||
|
if (RRType_e == RPL_E_PULL)
|
|||
|
{
|
|||
|
//
|
|||
|
// Add the time interval
|
|||
|
//
|
|||
|
SetVal(PnrKey, WINSCNF_RPL_INTERVAL_NM, REG_DWORD,
|
|||
|
(LPWSTR)WINSCNF_TIME_INT_W_SELF_FND_PNRS, sizeof(DWORD));
|
|||
|
|
|||
|
}
|
|||
|
SetVal(PnrKey, WINSCNF_SELF_FND_NM, REG_DWORD,
|
|||
|
(LPWSTR)TRUE, sizeof(DWORD));
|
|||
|
|
|||
|
}
|
|||
|
RegCloseKey(PnrKey);
|
|||
|
RegCloseKey(CnfKey);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DBGLEAVE("WinsCnfAddPnr\n");
|
|||
|
return(WINS_SUCCESS);
|
|||
|
}
|
|||
|
STATUS
|
|||
|
WinsCnfDelPnr(
|
|||
|
RPL_RR_TYPE_E RRType_e,
|
|||
|
LPBYTE pPnrAdd
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes --
|
|||
|
Error status codes --
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
LONG RetVal;
|
|||
|
HKEY TypeOfPnrKey;
|
|||
|
HKEY PnrKey;
|
|||
|
//WCHAR Key[160];
|
|||
|
WCHAR String[160];
|
|||
|
BOOL fSelfFnd;
|
|||
|
DWORD Sz;
|
|||
|
DWORD ValType;
|
|||
|
|
|||
|
DBGENTER("WinsCnfDelPnr\n");
|
|||
|
|
|||
|
WinsMscConvertAsciiStringToUnicode(pPnrAdd, (LPBYTE)String, sizeof(String)/sizeof(WCHAR));
|
|||
|
|
|||
|
/*
|
|||
|
* Open the key (PULL/PUSH)
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sConfigRoot, //predefined key value
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
_WINS_CFG_PULL_KEY :
|
|||
|
_WINS_CFG_PUSH_KEY,
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_ALL_ACCESS,
|
|||
|
&TypeOfPnrKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
|
|||
|
CHECK("Is there any need to log this")
|
|||
|
WINSEVT_LOG_INFO_M(
|
|||
|
WINS_SUCCESS,
|
|||
|
RRType_e == RPL_E_PULL ?
|
|||
|
WINS_EVT_CANT_OPEN_PULL_KEY :
|
|||
|
WINS_EVT_CANT_OPEN_PUSH_KEY
|
|||
|
);
|
|||
|
//--ft: Prefix bug 444974 - this key has to exist. If absurdly is missing, we won't find
|
|||
|
// the partner anyhow.
|
|||
|
return (WINS_SUCCESS);
|
|||
|
}
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
TypeOfPnrKey, //predefined key value
|
|||
|
String,
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_ALL_ACCESS, //we want "subkey create" priv
|
|||
|
&PnrKey //handle to key
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
DBGPRINT3(ERR, "WinsCnfDelPnr: %s Pnr with address = (%s) is Non-existent. RetVal = (%d)",
|
|||
|
RRType_e == RPL_E_PULL ? "PULL" : "PUSH", pPnrAdd,
|
|||
|
RetVal);
|
|||
|
return(WINS_SUCCESS);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Sz = sizeof(fSelfFnd);
|
|||
|
RetVal = RegQueryValueEx(
|
|||
|
PnrKey,
|
|||
|
WINSCNF_SELF_FND_NM,
|
|||
|
NULL,
|
|||
|
&ValType,
|
|||
|
(LPBYTE)&fSelfFnd,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
//
|
|||
|
// If SelfFnd is there and it's value is 1, delete it
|
|||
|
//
|
|||
|
if ((RetVal == ERROR_SUCCESS) && (fSelfFnd == 1))
|
|||
|
{
|
|||
|
RetVal = RegDeleteKey(TypeOfPnrKey, String);
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
DBGPRINT3(ERR, "WinsCnfDelPnr: Could not delete %s Pnr with address = (%s). RetVal = (%d)",
|
|||
|
RRType_e == RPL_E_PULL ? "PULL" : "PUSH", pPnrAdd,
|
|||
|
RetVal);
|
|||
|
RegCloseKey(PnrKey);
|
|||
|
return(WINS_FAILURE);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
RegCloseKey(TypeOfPnrKey);
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
DBGLEAVE("WinsCnfDelPnr\n");
|
|||
|
return(WINS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
DWORD
|
|||
|
SetVal(
|
|||
|
HKEY RootKey,
|
|||
|
LPWSTR pName,
|
|||
|
DWORD ValType,
|
|||
|
LPWSTR pVal,
|
|||
|
DWORD ValSize
|
|||
|
)
|
|||
|
{
|
|||
|
UINT Status = WINS_SUCCESS;
|
|||
|
LONG RetVal;
|
|||
|
DWORD Val;
|
|||
|
if (ValType == REG_DWORD)
|
|||
|
{
|
|||
|
Val = PtrToUlong (pVal);
|
|||
|
}
|
|||
|
RetVal = RegSetValueEx(
|
|||
|
RootKey,
|
|||
|
pName,
|
|||
|
0, //reserved -- must be 0
|
|||
|
ValType,
|
|||
|
ValType == REG_DWORD ? (LPBYTE)&Val : (LPBYTE)pVal,
|
|||
|
ValType == REG_DWORD ? ValSize : lstrlen(pVal)
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
printf("SetVal: Could not set value of %s\n", pName);
|
|||
|
Status = WINS_FAILURE;
|
|||
|
}
|
|||
|
|
|||
|
return(Status);
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
DWORD
|
|||
|
WinsCnfWriteReg(
|
|||
|
LPVOID pTmp
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function write the value of the version counter to be used
|
|||
|
at the next invocation.
|
|||
|
|
|||
|
Arguments:
|
|||
|
pTmp - Will be NULL if WinsCnfNextTimeVersNo was found in the registry
|
|||
|
when WINS came up.
|
|||
|
|
|||
|
Externals Used:
|
|||
|
NmsHighWaterMarkVersNo
|
|||
|
NmsVersNoToStartFromNextTime
|
|||
|
NmsNmhNamRegCrtSec
|
|||
|
NmsRangeSize
|
|||
|
NmsHalfRangeSize
|
|||
|
sfVersNoChanged
|
|||
|
sfVersNoUpdThdExists
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
VOID
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
NMSNMH_INC_VERS_COUNTER_M
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
LONG RetVal;
|
|||
|
LONG RetVal2;
|
|||
|
VERS_NO_T VersNo;
|
|||
|
DBGENTER("WinsCnfWriteReg\n");
|
|||
|
EnterCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
|
|||
|
//
|
|||
|
// if pTmp is not NULL, it means that either WINS did not find
|
|||
|
// Next time's version number in the registry or that the max. version
|
|||
|
// number in the db is greater than the high water mark we set at
|
|||
|
// initialization. In the former case, we already have the correct
|
|||
|
// value in NmsNmhToStartFromNextTime, so the if body is not executed.
|
|||
|
//
|
|||
|
if (!pTmp || LiLtr(NmsHighWaterMarkVersNo, NmsNmhMyMaxVersNo))
|
|||
|
{
|
|||
|
NmsHighWaterMarkVersNo.QuadPart = LiAdd(NmsVersNoToStartFromNextTime,
|
|||
|
NmsHalfRangeSize);
|
|||
|
NmsVersNoToStartFromNextTime.QuadPart = LiAdd(NmsVersNoToStartFromNextTime,
|
|||
|
NmsRangeSize);
|
|||
|
}
|
|||
|
VersNo = NmsVersNoToStartFromNextTime;
|
|||
|
LeaveCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
|
|||
|
RetVal = RegSetValueEx(
|
|||
|
sConfigRoot,
|
|||
|
WINSCNF_INT_VERSNO_NEXTTIME_LW_NM,
|
|||
|
0, //reserved -- must be 0
|
|||
|
REG_DWORD,
|
|||
|
(LPBYTE)&VersNo.LowPart,
|
|||
|
sizeof(DWORD)
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
RetVal2 = RegSetValueEx(
|
|||
|
sConfigRoot,
|
|||
|
WINSCNF_INT_VERSNO_NEXTTIME_HW_NM,
|
|||
|
0, //reserved -- must be 0
|
|||
|
REG_DWORD,
|
|||
|
(LPBYTE)&VersNo.HighPart,
|
|||
|
sizeof(DWORD)
|
|||
|
);
|
|||
|
if ((RetVal != ERROR_SUCCESS) || (RetVal2 != ERROR_SUCCESS))
|
|||
|
{
|
|||
|
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);
|
|||
|
}
|
|||
|
|
|||
|
EnterCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
WinsCnfRegUpdThdExists = FALSE;
|
|||
|
LeaveCriticalSection(&NmsNmhNamRegCrtSec);
|
|||
|
DBGLEAVE("WinsCnfWriteReg\n");
|
|||
|
return(WINS_SUCCESS);
|
|||
|
}
|
|||
|
|
|||
|
#if defined (DBGSVC) && !defined (WINS_INTERACTIVE)
|
|||
|
VOID
|
|||
|
WinsCnfReadWinsDbgFlagValue(
|
|||
|
VOID
|
|||
|
)
|
|||
|
{
|
|||
|
DWORD Sz;
|
|||
|
DWORD ValTyp;
|
|||
|
|
|||
|
WinsDbg = 0; //set it to zero now. It was set to a value by Init() in
|
|||
|
//nms.c
|
|||
|
Sz = sizeof(WinsDbg);
|
|||
|
(VOID)RegQueryValueEx(
|
|||
|
sParametersKey,
|
|||
|
WINSCNF_DBGFLAGS_NM,
|
|||
|
NULL, //reserved; must be NULL
|
|||
|
&ValTyp,
|
|||
|
(LPBYTE)&WinsDbg,
|
|||
|
&Sz
|
|||
|
);
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
VOID
|
|||
|
ReadSpecGrpMasks(
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called to read in the special group masks specified
|
|||
|
under the SpecialGrpMasks key
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Success status codes --
|
|||
|
Error status codes --
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
None
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD NoOfSubKeys;
|
|||
|
HKEY SGMKey;
|
|||
|
BOOL fKeyOpen = FALSE;
|
|||
|
LONG RetVal;
|
|||
|
DBGENTER("ReadSpecGrpMasks\n");
|
|||
|
try {
|
|||
|
/*
|
|||
|
* Open the SPEC_GRP_MASKS key
|
|||
|
*/
|
|||
|
RetVal = RegOpenKeyEx(
|
|||
|
sParametersKey, //predefined key value
|
|||
|
_WINS_CFG_SPEC_GRP_MASKS_KEY,
|
|||
|
0, //must be zero (reserved)
|
|||
|
KEY_READ, //we desire read access to the keyo
|
|||
|
&SGMKey //handle to key
|
|||
|
);
|
|||
|
if (RetVal == ERROR_SUCCESS)
|
|||
|
{
|
|||
|
fKeyOpen = TRUE;
|
|||
|
//
|
|||
|
// Get the count of data files listed under the DATAFILES
|
|||
|
// key
|
|||
|
//
|
|||
|
GetKeyInfo(
|
|||
|
SGMKey,
|
|||
|
WINSCNF_E_SPEC_GRP_MASKS_KEY,
|
|||
|
&NoOfSubKeys, //ignored
|
|||
|
&pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks
|
|||
|
);
|
|||
|
if (pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks > 0)
|
|||
|
{
|
|||
|
|
|||
|
DWORD Index;
|
|||
|
LPBYTE pTmp;
|
|||
|
TCHAR ValNmBuff[5];
|
|||
|
DWORD ValNmBuffSz;
|
|||
|
DWORD StrType;
|
|||
|
LPBYTE pByte;
|
|||
|
DWORD BuffSize;
|
|||
|
CHAR Tmp[WINS_MAX_FILENAME_SZ];
|
|||
|
#ifdef UNICODE
|
|||
|
WCHAR Str[WINSCNF_SPEC_GRP_MASK_SZ];
|
|||
|
#endif
|
|||
|
|
|||
|
//
|
|||
|
// Allocate buffer big enough to hold data for
|
|||
|
// the number of subkeys found under the PULL key
|
|||
|
//
|
|||
|
BuffSize = (WINSCNF_SPEC_GRP_MASK_SZ + 1) *
|
|||
|
pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks;
|
|||
|
WinsMscAlloc( BuffSize, &pWinsCnf->SpecGrpMasks.pSpecGrpMasks);
|
|||
|
|
|||
|
/*
|
|||
|
* Enumerate the values
|
|||
|
*/
|
|||
|
for(
|
|||
|
Index = 0, pTmp = pWinsCnf->SpecGrpMasks.pSpecGrpMasks;
|
|||
|
Index < pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks;
|
|||
|
// no third expression
|
|||
|
)
|
|||
|
{
|
|||
|
ValNmBuffSz = sizeof(ValNmBuff)/sizeof(TCHAR); //init before
|
|||
|
//every call
|
|||
|
BuffSize = WINSCNF_SPEC_GRP_MASK_SZ;
|
|||
|
RetVal = RegEnumValue(
|
|||
|
SGMKey,
|
|||
|
Index, //key
|
|||
|
ValNmBuff,
|
|||
|
&ValNmBuffSz,
|
|||
|
(LPDWORD)NULL, //reserved
|
|||
|
&StrType,
|
|||
|
#ifdef UNICODE
|
|||
|
(LPBYTE)Str,
|
|||
|
#else
|
|||
|
pTmp,
|
|||
|
#endif
|
|||
|
&BuffSize
|
|||
|
);
|
|||
|
|
|||
|
if (RetVal != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// if StrType is not REG_SZ go to the next Value
|
|||
|
//
|
|||
|
if (StrType != REG_SZ)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
if (BuffSize != WINSCNF_SPEC_GRP_MASK_SZ)
|
|||
|
{
|
|||
|
DBGPRINT1(ERR, "ReadSpecGrpMasks: Wrong spec. grp mask (%s)\n", pTmp);
|
|||
|
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_WRONG_SPEC_GRP_MASK_M);
|
|||
|
continue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
#ifdef UNICODE
|
|||
|
WinsMscConvertUnicodeStringToAscii(
|
|||
|
(LPBYTE)Str,
|
|||
|
(LPBYTE)Tmp,
|
|||
|
WINSCNF_SPEC_GRP_MASK_SZ
|
|||
|
);
|
|||
|
#endif
|
|||
|
pByte = (LPBYTE)Tmp;
|
|||
|
for (Index = 0; Index < WINSCNF_SPEC_GRP_MASK_SZ;
|
|||
|
Index++, pByte++)
|
|||
|
{
|
|||
|
*pByte = (BYTE)CharUpperA((LPSTR)*pByte);
|
|||
|
if (
|
|||
|
((*pByte >= '0') && (*pByte <= '9'))
|
|||
|
||
|
|||
|
((*pByte >= 'A') && (*pByte <= 'F'))
|
|||
|
)
|
|||
|
{
|
|||
|
continue;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
if (Index > WINSCNF_SPEC_GRP_MASK_SZ)
|
|||
|
{
|
|||
|
DBGPRINT1(ERR, "ReadSpecGrpMasks: Wrong spec. grp mask (%s)\n", pTmp);
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_WRONG_SPEC_GRP_MASK_M);
|
|||
|
continue;
|
|||
|
}
|
|||
|
*(pTmp + WINSCNF_SPEC_GRP_MASK_SZ) = EOS;
|
|||
|
}
|
|||
|
|
|||
|
Index++;
|
|||
|
pTmp += WINSCNF_SPEC_GRP_MASK_SZ + 1;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// If not even one valid name was retrieved, get rid of the
|
|||
|
// buffer
|
|||
|
//
|
|||
|
if (Index == 0)
|
|||
|
{
|
|||
|
//
|
|||
|
// Get rid of the buffer
|
|||
|
//
|
|||
|
WinsMscDealloc((LPBYTE)pWinsCnf->SpecGrpMasks.pSpecGrpMasks);
|
|||
|
}
|
|||
|
|
|||
|
pWinsCnf->SpecGrpMasks.NoOfSpecGrpMasks = Index;
|
|||
|
}
|
|||
|
} // end of if
|
|||
|
} // end of try ..
|
|||
|
except (EXCEPTION_EXECUTE_HANDLER) {
|
|||
|
DBGPRINTEXC("ReadSpecGrpMasks");
|
|||
|
WINSEVT_LOG_D_M(GetExceptionCode(), WINS_EVT_CANT_INIT);
|
|||
|
}
|
|||
|
|
|||
|
if (fKeyOpen && RegCloseKey(SGMKey) != ERROR_SUCCESS)
|
|||
|
{
|
|||
|
WINSEVT_LOG_M(WINS_FAILURE, WINS_EVT_CANT_CLOSE_KEY);
|
|||
|
DBGPRINT0(ERR, "ReadSpecGrpMasks: Can not read the spec. grp. mask. key\n");
|
|||
|
}
|
|||
|
DBGLEAVE("ReadSpecGrpMasks\n");
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
#if 0
|
|||
|
int
|
|||
|
__cdecl
|
|||
|
CompUpdCnt(
|
|||
|
CONST LPVOID pElem1,
|
|||
|
CONST LPVOID pElem2
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
This function is called by qsort crtl function to compare two
|
|||
|
elements of the array that has to be sorted
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
pElem1 - ptr to first element
|
|||
|
pElem1 - ptr to second element
|
|||
|
|
|||
|
Externals Used:
|
|||
|
None
|
|||
|
|
|||
|
Return Value:
|
|||
|
-1 if first element is < second element
|
|||
|
= 0 if first element is == second element
|
|||
|
1 if first element is > second element
|
|||
|
|
|||
|
Error Handling:
|
|||
|
|
|||
|
Called by:
|
|||
|
qsort (which is called by WinsCnfReadPartnerInfo
|
|||
|
|
|||
|
Side Effects:
|
|||
|
|
|||
|
Comments:
|
|||
|
Not used currently
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
CONST PRPL_CONFIG_REC_T pCnfRec1 = pElem1;
|
|||
|
CONST PRPL_CONFIG_REC_T pCnfRec2 = pElem2;
|
|||
|
|
|||
|
if (pCnfRec1->UpdateCount < pCnfRec2->UpdateCount)
|
|||
|
{
|
|||
|
return(-1);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
if (pCnfRec1->UpdateCount == pCnfRec2->UpdateCount)
|
|||
|
{
|
|||
|
return(0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// The first record has a higher UpdateCount than the second one
|
|||
|
//
|
|||
|
return(1);
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef WINSDBG
|
|||
|
VOID
|
|||
|
PrintRecs(
|
|||
|
RPL_RR_TYPE_E RRType_e,
|
|||
|
PWINSCNF_CNF_T pWinsCnf
|
|||
|
)
|
|||
|
{
|
|||
|
return;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|