1719 lines
40 KiB
C++
1719 lines
40 KiB
C++
//+----------------------------------------------------------------------------
|
||
//
|
||
// Copyright (C) 1995, Microsoft Corporation
|
||
//
|
||
// File: dfsminit.cxx
|
||
//
|
||
// Contents: Initialization code for Dfs Manager service.
|
||
//
|
||
// Classes:
|
||
//
|
||
// Functions: DfsManager --
|
||
// DfsInitGlobals --
|
||
// InitializeDfsManager --
|
||
// InitializeVolumeObject --
|
||
// DfsHandleKnowledgeInconsistency --
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
//#include <ntos.h>
|
||
//#include <ntrtl.h>
|
||
//#include <nturtl.h>
|
||
//#include <dfsfsctl.h>
|
||
//#include <windows.h>
|
||
|
||
#include <headers.hxx>
|
||
#pragma hdrstop
|
||
|
||
#include <dfsfsctl.h> // For EA_NAME_OPENIFJP
|
||
|
||
#include <dfsmsrv.h> // For public function
|
||
#include <clusapi.h>
|
||
#include <resapi.h>
|
||
#include <winldap.h>
|
||
#include "cdfsvol.hxx" // prototypes
|
||
#include "localvol.hxx"
|
||
#include "security.hxx"
|
||
#include "dsgetdc.h"
|
||
#include "setup.hxx"
|
||
#include "dfsmwml.h"
|
||
|
||
extern "C"
|
||
DWORD
|
||
DfsGetFtServersFromDs(
|
||
PLDAP pLDAP,
|
||
LPWSTR wszDomainName,
|
||
LPWSTR wszDfsName,
|
||
LPWSTR **List);
|
||
|
||
DWORD
|
||
DfspGetPdc(void);
|
||
|
||
//
|
||
// Debug variables
|
||
//
|
||
|
||
//WMILIB_REG_STRUCT DfsRtlWmiReg;
|
||
///GUID DfsmRtlTraceGuid = { // 08fbc600-67ac-4ae4-9f22-c51a4f82f6c9
|
||
// 0x08fbc600, 0x67ac, 0x4ae4,
|
||
// {
|
||
// 0x9f, 0x22, 0xc5, 0x1a, 0x4f, 0x82, 0xf6, 0xc9
|
||
// }
|
||
//};
|
||
|
||
//WML_DATA wml;
|
||
|
||
|
||
DECLARE_INFOLEVEL(IDfsVol)
|
||
|
||
//
|
||
// Global variables.
|
||
//
|
||
|
||
CRITICAL_SECTION globalCritSec;
|
||
ULONG ulDfsManagerType;
|
||
WCHAR wszComputerName[MAX_PATH];
|
||
LPWSTR pwszComputerName = NULL;
|
||
WCHAR wszDomainName[MAX_PATH];
|
||
LPWSTR pwszDomainName = NULL;
|
||
WCHAR wszDfsRootName[MAX_PATH];
|
||
LPWSTR pwszDfsRootName = NULL;
|
||
WCHAR wszDSMachineName[MAX_PATH];
|
||
LPWSTR pwszDSMachineName = NULL;
|
||
|
||
//
|
||
// Contains the name of the FtDfs, if we are an FtDfs root
|
||
//
|
||
WCHAR wszFtDfsName[MAX_PATH];
|
||
LPWSTR pwszFtDfsName = NULL;
|
||
|
||
//
|
||
// If an FtDfs, this is the ldap connection we're using
|
||
//
|
||
PLDAP pLdapConnection = NULL;
|
||
|
||
ULONG GTimeout = 0;
|
||
|
||
extern "C" {
|
||
ULONG DfsSvcVerbose = 0;
|
||
ULONG DfsSvcLdap = 0;
|
||
ULONG DfsEventLog = 0;
|
||
ULONG DfsDnsConfig = 0;
|
||
}
|
||
|
||
BOOLEAN NetDfsInitDone = FALSE;
|
||
|
||
HANDLE hSyncThread = NULL;
|
||
HANDLE hSyncEvent = NULL;
|
||
HANDLE hFrsSyncEvent = NULL;
|
||
DWORD dwFrsSyncIntervalInMs = 1000 * 60; // 1 minute by default
|
||
DWORD dwSyncIntervalInMs = 1000 * 60 * 60; // 1 hour by default
|
||
DWORD dwSyncThreadId;
|
||
|
||
ULONG DcLockIntervalInMs = 1000 * 60 * 60 * 2; // 2 hours by default
|
||
|
||
CStorageDirectory *pDfsmStorageDirectory = NULL;
|
||
CSites *pDfsmSites = NULL;
|
||
|
||
#if (DBG == 1) || (_CT_TEST_HOOK == 1)
|
||
RECOVERY_BREAK_POINT gRecoveryBkptInfo;
|
||
#endif
|
||
|
||
//
|
||
// The name of the Dfs configuration container
|
||
//
|
||
WCHAR DfsConfigContainer[] = L"CN=Dfs-Configuration,CN=System";
|
||
LPWSTR gConfigurationDN = NULL;
|
||
|
||
//
|
||
// Useful EA Buffer for opening Junction Points
|
||
//
|
||
|
||
CHAR EaBuffer[ sizeof(FILE_FULL_EA_INFORMATION) + sizeof(EA_NAME_OPENIFJP) ];
|
||
PFILE_FULL_EA_INFORMATION pOpenIfJPEa = (PFILE_FULL_EA_INFORMATION) EaBuffer;
|
||
ULONG cbOpenIfJPEa = sizeof(EaBuffer);
|
||
|
||
|
||
DWORD
|
||
InitializeVolumeObject(
|
||
PWSTR pwszVolName,
|
||
BOOLEAN bInitVol,
|
||
BOOLEAN SyncRemoteServerName=FALSE);
|
||
|
||
DWORD
|
||
InitializeDfsManager(void);
|
||
|
||
DWORD
|
||
InitializeNetDfsInterface(void);
|
||
|
||
DWORD
|
||
DfsManagerStartDSSync();
|
||
|
||
DWORD
|
||
DfsManagerDSSyncThread(
|
||
PVOID Context);
|
||
|
||
DWORD
|
||
GetSyncInterval();
|
||
|
||
ULONG
|
||
GetDcLockInterval();
|
||
|
||
DWORD
|
||
GetEntryTimeout();
|
||
|
||
VOID
|
||
GetDebugSwitches();
|
||
|
||
VOID
|
||
GetEventLogSwitches();
|
||
|
||
VOID
|
||
GetConfigSwitches();
|
||
|
||
DWORD
|
||
DfspGetFtDfsName();
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsManager
|
||
//
|
||
// Synopsis: Entry procedure for the main Dfs Manager service thread.
|
||
// Initializes the Dfs Manager structures, creates the RPC
|
||
// threads that will wait around listening for admin operation
|
||
// calls, and lastly, creates a thread to monitor Knowledge
|
||
// Sync calls from the driver.
|
||
//
|
||
// Arguments: [wszRootName] -- Name of dfs root for which this Dfs Manager
|
||
// is being instantiated.
|
||
// [dwType] -- Type of Dfs Manager being instantiated -
|
||
// DFS_MANAGER_SERVER or DFS_MANAGER_FTDFS
|
||
//
|
||
// Returns: [ERROR_SUCCESS] -- If Dfs Manager started correctly.
|
||
//
|
||
// [ERROR_OUTOFMEMORY] -- If globals could not be allocated.
|
||
//
|
||
// Error from reading the Dfs Volume Objects.
|
||
//
|
||
// Win32 error from registering the RPC interface.
|
||
//
|
||
// Win32 error from creating the knowledge sync thread.
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
DfsManager(
|
||
LPWSTR wszRootName,
|
||
DWORD dwType)
|
||
{
|
||
HANDLE hthreadSync;
|
||
DWORD idThread;
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
HKEY hkey;
|
||
DFS_NAME_CONVENTION NameType;
|
||
|
||
//
|
||
// Initialize the global data structures of Dfs Manager...
|
||
//
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsManager(%ws,0x%x)\n", wszRootName, dwType));
|
||
|
||
if (dwType == DFS_MANAGER_FTDFS) {
|
||
dwErr = DfsInitGlobals(wszRootName, dwType);
|
||
} else {
|
||
NameType = DFS_NAMETYPE_EITHER;
|
||
dwErr = GetDomAndComputerName(NULL, wszComputerName, &NameType);
|
||
dwErr = DfsInitGlobals(wszComputerName, dwType);
|
||
}
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "DfsInitGlobals failed %08lx\n", dwErr));
|
||
return(dwErr);
|
||
}
|
||
|
||
//
|
||
// Initialize the NetDfs RPC interface...
|
||
//
|
||
|
||
dwErr = InitializeNetDfsInterface();
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "InitializeNetDfsInterface failed %08lx\n", dwErr));
|
||
return dwErr;
|
||
}
|
||
|
||
//
|
||
// Read in all the Dfs volume objects and initialize them
|
||
//
|
||
|
||
ENTER_DFSM_OPERATION;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
RegCloseKey( hkey );
|
||
DfsmStopDfs();
|
||
DfsmResetPkt();
|
||
DfsmInitLocalPartitions();
|
||
DfsmMarkStalePktEntries();
|
||
InitializeVolumeObject( DOMAIN_ROOT_VOL, TRUE, (ulDfsManagerType == DFS_MANAGER_FTDFS)?TRUE:FALSE );
|
||
DfsmFlushStalePktEntries();
|
||
}
|
||
DfsmStartDfs();
|
||
DfsmPktFlushCache();
|
||
|
||
EXIT_DFSM_OPERATION;
|
||
|
||
if (dwErr != ERROR_SUCCESS)
|
||
{
|
||
IDfsVolInlineDebOut((DEB_ERROR, "InitializeDfsManager failed %08lx\n", dwErr));
|
||
return dwErr;
|
||
}
|
||
|
||
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
|
||
//
|
||
// Start the thread that does the DS sync
|
||
//
|
||
|
||
dwErr = DfsManagerStartDSSync();
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "DfsManagerStartDSSync failed %08lx\n", dwErr));
|
||
return(dwErr);
|
||
}
|
||
|
||
}
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsManager exit\n"));
|
||
|
||
return ERROR_SUCCESS;
|
||
|
||
} // DfsManager
|
||
|
||
DWORD
|
||
ClusCallBackFunction(
|
||
HRESOURCE hSelf,
|
||
HRESOURCE hResource,
|
||
LPVOID lpNull)
|
||
{
|
||
DWORD Value = 0;
|
||
DWORD dwStatus = ERROR_INVALID_HANDLE;
|
||
HKEY hKey = NULL;
|
||
HKEY hParamKey = NULL;
|
||
WCHAR wszClusterName[MAX_PATH];
|
||
ULONG cSize = MAX_PATH;
|
||
|
||
hKey = GetClusterResourceKey(hResource, KEY_READ);
|
||
|
||
if (hKey != NULL) {
|
||
dwStatus = ClusterRegOpenKey( hKey, L"Parameters", KEY_READ, &hParamKey );
|
||
DFSM_TRACE_ERROR_HIGH(dwStatus, ALL_ERROR, ClusCallBackFunction_Error_ClusterRegOpenKey,
|
||
LOGSTATUS(dwStatus));
|
||
}
|
||
|
||
if (dwStatus != ERROR_SUCCESS)
|
||
goto ExitWithStatus;
|
||
|
||
ResUtilGetDwordValue(hParamKey, L"IsDfsRoot", &Value, 0);
|
||
if (Value == 1
|
||
&&
|
||
GetClusterResourceNetworkName(hResource, wszClusterName, &cSize) == TRUE
|
||
) {
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("ClusCallBackFunction: ClusterName = [%ws]\n", wszClusterName);
|
||
#endif
|
||
wcscpy(wszDfsRootName, wszClusterName);
|
||
wcscpy(wszComputerName, wszClusterName);
|
||
} else {
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("ClusCallBackFunction: Not a root on a cluster.\n");
|
||
#endif
|
||
}
|
||
|
||
ExitWithStatus:
|
||
if (hKey != NULL)
|
||
ClusterRegCloseKey(hKey);
|
||
if (hParamKey != NULL)
|
||
ClusterRegCloseKey(hParamKey);
|
||
return dwStatus;
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsInitGlobals
|
||
//
|
||
// Synopsis: Initialize the Dfs Manager globals.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// Returns:
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
extern "C" DWORD
|
||
DfsInitGlobals(
|
||
LPWSTR pwszRootName,
|
||
DWORD dwType)
|
||
{
|
||
static BOOLEAN fInitDone = FALSE;
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
ULONG ulSize = MAX_PATH*sizeof(WCHAR);
|
||
DFS_NAME_CONVENTION NameType;
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsInitGlobals(%ws, %x)\n", pwszRootName, dwType));
|
||
|
||
//
|
||
// Only do init once.
|
||
//
|
||
|
||
if ( !fInitDone ) {
|
||
|
||
DebugInitialize();
|
||
|
||
#if DBG
|
||
GetDebugSwitches();
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfsInitGlobals(%ws,%d)\n", pwszRootName, dwType);
|
||
#endif
|
||
GetEventLogSwitches();
|
||
GetConfigSwitches();
|
||
|
||
pwszDSMachineName = NULL;
|
||
|
||
GTimeout = GetEntryTimeout();
|
||
|
||
DcLockIntervalInMs = GetDcLockInterval();
|
||
|
||
ulDfsManagerType = dwType;
|
||
|
||
pOpenIfJPEa->NextEntryOffset = 0;
|
||
pOpenIfJPEa->Flags = 0;
|
||
pOpenIfJPEa->EaNameLength = strlen(EA_NAME_OPENIFJP);
|
||
pOpenIfJPEa->EaValueLength = 0;
|
||
strcpy(pOpenIfJPEa->EaName, EA_NAME_OPENIFJP);
|
||
|
||
//
|
||
// Must enforce exclusivity before the service starts.
|
||
//
|
||
|
||
InitializeCriticalSection(&globalCritSec);
|
||
|
||
#if (DBG == 1) || (_CT_TEST_HOOK == 1)
|
||
gRecoveryBkptInfo.BreakPt = 0xFFFFFFFF;
|
||
gRecoveryBkptInfo.pwszApiBreak = NULL;
|
||
#endif
|
||
|
||
wcscpy(wszDfsRootName, pwszRootName);
|
||
pwszDfsRootName = wszDfsRootName;
|
||
|
||
//
|
||
// Get computer and domain names
|
||
//
|
||
|
||
NameType = (ulDfsManagerType == DFS_MANAGER_FTDFS) ? DFS_NAMETYPE_DNS : DFS_NAMETYPE_EITHER;
|
||
dwErr = GetDomAndComputerName(wszDomainName, wszComputerName, &NameType);
|
||
|
||
if (dwErr == NERR_Success) {
|
||
pwszDomainName = wszDomainName;
|
||
pwszComputerName = wszComputerName;
|
||
} else {
|
||
pwszDomainName = NULL;
|
||
pwszComputerName = NULL;
|
||
}
|
||
|
||
//
|
||
// Figure out the root of the namespace.
|
||
// The root name is the cluster name on clusters, if
|
||
// this is a machine-based Dfs.
|
||
//
|
||
|
||
if (dwErr == NERR_Success && ulDfsManagerType == DFS_MANAGER_SERVER) {
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfsInitGlobals: calling ResUtilEnumResources()\n");
|
||
#endif
|
||
|
||
ResUtilEnumResources(NULL,
|
||
L"File Share",
|
||
ClusCallBackFunction,
|
||
NULL);
|
||
|
||
}
|
||
|
||
//
|
||
// Initialize the ACLs and other global security datastructures needed
|
||
// for Access Validation
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
if (DfsInitializeSecurity())
|
||
dwErr = ERROR_SUCCESS;
|
||
else
|
||
dwErr = ERROR_UNEXP_NET_ERR;
|
||
}
|
||
|
||
//
|
||
// Initialize the LDAP storage
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS && ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
|
||
dwErr = InitializeLdapStorage(
|
||
wszDfsRootName);
|
||
|
||
}
|
||
|
||
//
|
||
// Initialize the CSites class/storage
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
|
||
pDfsmSites = new CSites(LDAP_VOLUMES_DIR SITE_ROOT, &dwErr);
|
||
|
||
} else {
|
||
|
||
pDfsmSites = new CSites(VOLUMES_DIR SITE_ROOT, &dwErr);
|
||
|
||
}
|
||
|
||
if (pDfsmSites != NULL) {
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
|
||
delete pDfsmSites;
|
||
|
||
pDfsmSites = NULL;
|
||
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// Initialize the Dfs Manager Storage Directory
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS ) {
|
||
|
||
pDfsmStorageDirectory = new CStorageDirectory( &dwErr );
|
||
|
||
if (pDfsmStorageDirectory != NULL) {
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
fInitDone = TRUE;
|
||
|
||
} else {
|
||
|
||
delete pDfsmStorageDirectory;
|
||
|
||
pDfsmStorageDirectory = NULL;
|
||
|
||
delete pDfsmSites;
|
||
|
||
pDfsmSites = NULL;
|
||
|
||
fInitDone = FALSE;
|
||
}
|
||
|
||
} else {
|
||
|
||
delete pDfsmSites;
|
||
|
||
pDfsmSites = NULL;
|
||
|
||
fInitDone = FALSE;
|
||
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsInitGlobals() exit\n"));
|
||
|
||
return dwErr;
|
||
|
||
} // DfsInitGlobals
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsReinitGlobals
|
||
//
|
||
// Synopsis: ReInitialize the Dfs Manager globals.
|
||
//
|
||
// Arguments:
|
||
//
|
||
// Returns:
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
DfsReInitGlobals(
|
||
LPWSTR pwszRootName,
|
||
DWORD dwType)
|
||
{
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
ULONG ulSize = MAX_PATH*sizeof(WCHAR);
|
||
DFS_NAME_CONVENTION NameType;
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsReInitGlobals(%ws, %x)\n", pwszRootName, dwType));
|
||
|
||
#if DBG
|
||
GetDebugSwitches();
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfsReInitGlobals(%ws, %d)\n", pwszRootName, dwType);
|
||
#endif
|
||
GetEventLogSwitches();
|
||
GetConfigSwitches();
|
||
|
||
//
|
||
// Get rid of Dfs Manager storage & site info
|
||
//
|
||
|
||
if (pDfsmStorageDirectory != NULL) {
|
||
|
||
delete pDfsmStorageDirectory;
|
||
pDfsmStorageDirectory = NULL;
|
||
|
||
}
|
||
|
||
if (pDfsmSites != NULL) {
|
||
|
||
delete pDfsmSites;
|
||
pDfsmSites = NULL;
|
||
|
||
}
|
||
|
||
//
|
||
// Get rid of Ldap storage
|
||
//
|
||
|
||
UnInitializeLdapStorage();
|
||
|
||
ulDfsManagerType = dwType;
|
||
|
||
wcscpy(wszDfsRootName, pwszRootName);
|
||
pwszDfsRootName = wszDfsRootName;
|
||
|
||
//
|
||
// Get computer and domain names
|
||
//
|
||
|
||
NameType = (ulDfsManagerType == DFS_MANAGER_FTDFS) ? DFS_NAMETYPE_DNS : DFS_NAMETYPE_EITHER;
|
||
dwErr = GetDomAndComputerName(wszDomainName, wszComputerName, &NameType);
|
||
|
||
if (dwErr == NERR_Success) {
|
||
pwszDomainName = wszDomainName;
|
||
pwszComputerName = wszComputerName;
|
||
} else {
|
||
pwszDomainName = NULL;
|
||
pwszComputerName = NULL;
|
||
}
|
||
|
||
//
|
||
// Figure out the root of the namespace.
|
||
// The root name is the cluster name on clusters, if
|
||
// this is a machine-based Dfs.
|
||
//
|
||
|
||
if (dwErr == NERR_Success && ulDfsManagerType == DFS_MANAGER_SERVER) {
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfsReInitGlobals: calling ResUtilEnumResources()\n");
|
||
#endif
|
||
|
||
ResUtilEnumResources(NULL,
|
||
L"File Share",
|
||
ClusCallBackFunction,
|
||
NULL);
|
||
|
||
}
|
||
|
||
//
|
||
// Initialize the LDAP storage
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS && ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
|
||
dwErr = InitializeLdapStorage(
|
||
wszDfsRootName);
|
||
|
||
}
|
||
|
||
//
|
||
// Initialize the CSites class/storage
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
|
||
pDfsmSites = new CSites(LDAP_VOLUMES_DIR SITE_ROOT, &dwErr);
|
||
|
||
} else {
|
||
|
||
pDfsmSites = new CSites(VOLUMES_DIR SITE_ROOT, &dwErr);
|
||
|
||
}
|
||
|
||
if (pDfsmSites != NULL) {
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
|
||
delete pDfsmSites;
|
||
pDfsmSites = NULL;
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// Initialize the Dfs Manager Storage Directory
|
||
//
|
||
|
||
if (dwErr == ERROR_SUCCESS ) {
|
||
|
||
pDfsmStorageDirectory = new CStorageDirectory( &dwErr );
|
||
|
||
if (pDfsmStorageDirectory != NULL) {
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
|
||
delete pDfsmStorageDirectory;
|
||
pDfsmStorageDirectory = NULL;
|
||
delete pDfsmSites;
|
||
pDfsmSites = NULL;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
delete pDfsmSites;
|
||
pDfsmSites = NULL;
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
if (dwType == DFS_MANAGER_FTDFS && hSyncThread == NULL) {
|
||
|
||
//
|
||
// Start the thread that does the DS sync
|
||
//
|
||
|
||
dwErr = DfsManagerStartDSSync();
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "DfsManagerStartDSSync failed %08lx\n", dwErr));
|
||
return(dwErr);
|
||
}
|
||
|
||
}
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsReInitGlobals() exit\n"));
|
||
|
||
return dwErr;
|
||
|
||
} // DfsReInitGlobals
|
||
|
||
//+------------------------------------------------------------------------
|
||
//
|
||
// Function: InitializeDfsManager
|
||
//
|
||
// Synopsis: This method initializes the PKT with the volume objects
|
||
//
|
||
// Arguments: None
|
||
//
|
||
// Returns:
|
||
//
|
||
// Notes:
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
DWORD
|
||
InitializeDfsManager(void)
|
||
{
|
||
|
||
DWORD dwErr;
|
||
HKEY hkey;
|
||
|
||
GetEventLogSwitches();
|
||
GetConfigSwitches();
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
RegCloseKey( hkey );
|
||
|
||
dwErr = InitializeVolumeObject( DOMAIN_ROOT_VOL, TRUE );
|
||
|
||
} else {
|
||
|
||
dwErr = ERROR_SUCCESS;
|
||
|
||
}
|
||
|
||
return(dwErr);
|
||
}
|
||
|
||
//+-----------------------------------------------------------------------
|
||
//
|
||
// Function: InitializeVolumeObject
|
||
//
|
||
// Synopsis: This function initializes a volume object and hence all
|
||
// objects underneath that one.
|
||
//
|
||
// Arguments: [pwszVolName] -- Volume Object's Name.
|
||
// [bInitVol] -- If TRUE call UpdatePktEntry on this object also.
|
||
//
|
||
//------------------------------------------------------------------------
|
||
DWORD
|
||
InitializeVolumeObject(
|
||
PWSTR pwszVolName,
|
||
BOOLEAN bInitVol,
|
||
BOOLEAN SyncRemoteServerName)
|
||
{
|
||
|
||
ULONG count = 0;
|
||
DWORD dwErr;
|
||
CDfsVolume *tempCDfs;
|
||
WCHAR wszVolObjName[MAX_PATH];
|
||
HANDLE PktHandle = NULL;
|
||
NTSTATUS status;
|
||
|
||
IDfsVolInlineDebOut(
|
||
(DEB_TRACE,
|
||
"InitializeVolumeObject(%ws,%d)\n",
|
||
pwszVolName, bInitVol));
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("InitializeVolumeObject(%ws,%s)\n",
|
||
pwszVolName,
|
||
bInitVol == TRUE ? "TRUE" : "FALSE");
|
||
#endif
|
||
|
||
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
wcscpy(wszVolObjName, LDAP_VOLUMES_DIR);
|
||
} else {
|
||
wcscpy(wszVolObjName, VOLUMES_DIR);
|
||
}
|
||
wcscat(wszVolObjName, pwszVolName);
|
||
|
||
IDfsVolInlineDebOut(
|
||
(DEB_TRACE,
|
||
"wszVolObjName=%ws\n",
|
||
wszVolObjName));
|
||
|
||
tempCDfs = new CDfsVolume();
|
||
|
||
if (tempCDfs == NULL) {
|
||
|
||
dwErr = ERROR_OUTOFMEMORY;
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "InitializeVolumeObject Exit\n"));
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("InitializeVolumeObject exit %d\n", dwErr);
|
||
#endif
|
||
|
||
return dwErr;
|
||
|
||
}
|
||
|
||
dwErr = tempCDfs->LoadNoRegister(wszVolObjName, 0);
|
||
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
//
|
||
// We'll be sync'ing the site table, so be sure it's ready
|
||
//
|
||
pDfsmSites->AddRef();
|
||
pDfsmSites->MarkEntriesForMerge();
|
||
|
||
//
|
||
// We have to update the PKT entry first since InitializePkt
|
||
// will not bother about that part.
|
||
//
|
||
|
||
if (bInitVol) {
|
||
status = PktOpen(&PktHandle, 0, 0, NULL);
|
||
if (!NT_SUCCESS(status))
|
||
PktHandle = NULL;
|
||
dwErr = tempCDfs->UpdatePktEntry(PktHandle);
|
||
}
|
||
|
||
if (dwErr != ERROR_SUCCESS) {
|
||
|
||
//
|
||
// We log an EVENT here since this needs admin intervention
|
||
// but we go on however.
|
||
//
|
||
|
||
IDfsVolInlineDebOut((DEB_ERROR, "Could not UpdatePkt on %ws %08lx\n",
|
||
pwszVolName, dwErr));
|
||
|
||
} else
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("InitializevolumeObject:Calling InitializePkt\n");
|
||
#endif
|
||
if (PktHandle == NULL) {
|
||
status = PktOpen(&PktHandle, 0, 0, NULL);
|
||
if (!NT_SUCCESS(status))
|
||
PktHandle = NULL;
|
||
}
|
||
dwErr = tempCDfs->InitializePkt(PktHandle);
|
||
if (PktHandle != NULL)
|
||
PktClose(PktHandle);
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("InitializevolumeObject:InitializePkt returned %d\n", dwErr);
|
||
#endif
|
||
|
||
//
|
||
// The site table should now be in sync
|
||
//
|
||
pDfsmSites->SyncPktSiteTable();
|
||
pDfsmSites->Release();
|
||
|
||
} else {
|
||
|
||
IDfsVolInlineDebOut((DEB_ERROR, "Unable to get to %ws %08lx\n",
|
||
pwszVolName, dwErr));
|
||
}
|
||
|
||
tempCDfs->Release();
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "InitializeVolumeObject Exit\n"));
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("InitializeVolumeObject exit %d\n", dwErr);
|
||
#endif
|
||
return( dwErr );
|
||
}
|
||
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: InitializeNetDfsInterface
|
||
//
|
||
// Synopsis: Initializes the NetDfs RPC interface, so this Dfs Manager can
|
||
// start servicing the NetDfsXXX APIs.
|
||
//
|
||
// Arguments: None
|
||
//
|
||
// Returns: DWORD_FROM_WIN32 of the RPC status from registering the
|
||
// RPC interface.
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
InitializeNetDfsInterface()
|
||
{
|
||
RPC_STATUS status;
|
||
LPWSTR wszProtocolSeq = L"ncacn_np";
|
||
LPWSTR wszEndPoint = L"\\pipe\\netdfs";
|
||
|
||
if (NetDfsInitDone == TRUE)
|
||
return ERROR_SUCCESS;
|
||
|
||
status = RpcServerUseProtseqEpW(
|
||
(USHORT *)wszProtocolSeq, // Named Pipe protocol
|
||
20, // Max # of calls
|
||
(USHORT *)wszEndPoint, // Name of named pipe
|
||
NULL); // Security Descriptor
|
||
|
||
DFSM_TRACE_ERROR_HIGH(status, ALL_ERROR, InitializeNetDfsInterface_Error_RpcServerUseProtseqEpW,
|
||
LOGSTATUS(status));
|
||
|
||
if (status) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "RpcServerUseProtseqEpW failed %08lx\n", status));
|
||
return(status);
|
||
}
|
||
|
||
//
|
||
// Register the DfsAdministration interface with the RPC runtime library
|
||
//
|
||
status = RpcServerRegisterIf(netdfs_ServerIfHandle, 0, 0);
|
||
DFSM_TRACE_ERROR_HIGH(status, ALL_ERROR, InitializeNetDfsInterface_Error_RpcServerRegisterIf,
|
||
LOGSTATUS(status));
|
||
|
||
if (status) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "RpcServerRegisterIf failed %08lx\n", status));
|
||
return(status);
|
||
}
|
||
|
||
//
|
||
// Wait for client calls...
|
||
//
|
||
|
||
status = RpcServerListen(
|
||
1, // Minimum # of calls
|
||
RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Max calls
|
||
1); // Don't wait...
|
||
|
||
DFSM_TRACE_ERROR_HIGH(status, ALL_ERROR, InitializeNetDfsInterface_Error_RpcServerListen,
|
||
LOGSTATUS(status));
|
||
if (status) {
|
||
IDfsVolInlineDebOut((DEB_ERROR, "RpcServerListen failed %08lx\n", status));
|
||
}
|
||
|
||
if (status == ERROR_SUCCESS) {
|
||
NetDfsInitDone = TRUE;
|
||
}
|
||
|
||
return( status );
|
||
|
||
}
|
||
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsManagerHandleKnowledgeInconsistency
|
||
//
|
||
// Synopsis: Routine to handle knowledge inconsistencies being reported by
|
||
// Dfs clients.
|
||
//
|
||
// Arguments: [Buffer] -- Pointer to marshalled Volume Verify Arg
|
||
// [cbMessage] -- size in bytes of pBuffer
|
||
//
|
||
// Returns: [STATUS_SUCCESS] -- Knowledge inconsistency fixed.
|
||
//
|
||
// [STATUS_UNSUCCESSFUL] -- Unable to fix Knowledge inconsistency.
|
||
// Problem has been logged to event log.
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
extern "C" NTSTATUS
|
||
DfsManagerHandleKnowledgeInconsistency(
|
||
PBYTE Buffer,
|
||
ULONG cbMessage)
|
||
{
|
||
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
NTSTATUS Status;
|
||
|
||
MARSHAL_BUFFER MarshalBuffer;
|
||
DFS_VOLUME_VERIFY_ARG arg;
|
||
|
||
PWSTR pwszVolName;
|
||
CDfsVolume *pcdfsvol;
|
||
|
||
pcdfsvol = new CDfsVolume();
|
||
|
||
if (pcdfsvol != NULL) {
|
||
|
||
MarshalBufferInitialize(&MarshalBuffer, cbMessage, Buffer);
|
||
|
||
Status = DfsRtlGet(&MarshalBuffer, &MiVolumeVerifyArg, &arg);
|
||
|
||
if (NT_SUCCESS(Status)) {
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "GotParameters: %ws\n", arg.ServiceName.Buffer));
|
||
|
||
dwErr = GetVolObjForPath(arg.Id.Prefix.Buffer, TRUE, &pwszVolName);
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "GotVolObjName: %ws\n", pwszVolName));
|
||
|
||
dwErr = pcdfsvol->LoadNoRegister(pwszVolName, 0);
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
//
|
||
// Remember that the ID actually has the serviceName.
|
||
//
|
||
|
||
dwErr = pcdfsvol->FixServiceKnowledge(arg.ServiceName.Buffer);
|
||
|
||
} else {
|
||
|
||
IDfsVolInlineDebOut((
|
||
DEB_TRACE, "Could not bind to Vol object\n"));
|
||
|
||
}
|
||
|
||
delete [] pwszVolName;
|
||
|
||
} else {
|
||
|
||
IDfsVolInlineDebOut((
|
||
DEB_TRACE, "Could not get volume objectName\n"));
|
||
|
||
}
|
||
|
||
if (arg.Id.Prefix.Buffer != NULL) {
|
||
|
||
MarshalBufferFree(arg.Id.Prefix.Buffer);
|
||
|
||
}
|
||
|
||
if (arg.ServiceName.Buffer != NULL) {
|
||
|
||
MarshalBufferFree(arg.ServiceName.Buffer);
|
||
|
||
}
|
||
|
||
if (dwErr != ERROR_SUCCESS)
|
||
Status = STATUS_UNSUCCESSFUL;
|
||
|
||
} else {
|
||
|
||
IDfsVolInlineDebOut((
|
||
DEB_TRACE,
|
||
"Error (NTSTATUS) unmarshalling Knowledge Sync Params %08lx\n",
|
||
Status));
|
||
|
||
}
|
||
|
||
pcdfsvol->Release();
|
||
|
||
} else {
|
||
|
||
Status = STATUS_UNSUCCESSFUL;
|
||
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsManagerStartDSSync
|
||
//
|
||
// Synopsis: Starts a thread that will periodically sync up with the PKT
|
||
// in the DS. Used on FT-Dfs root servers.
|
||
//
|
||
// Arguments: None
|
||
//
|
||
// Returns: Win32 error from result of allocating necessary resources to
|
||
// do DS sync
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
DfsManagerStartDSSync()
|
||
{
|
||
|
||
DWORD dwErr = ERROR_SUCCESS;
|
||
NTSTATUS Status;
|
||
OBJECT_ATTRIBUTES obja;
|
||
|
||
ASSERT( ulDfsManagerType == DFS_MANAGER_FTDFS );
|
||
|
||
InitializeObjectAttributes(&obja, NULL, OBJ_OPENIF, NULL, NULL);
|
||
Status = NtCreateEvent(
|
||
&hSyncEvent,
|
||
SYNCHRONIZE | EVENT_QUERY_STATE | EVENT_MODIFY_STATE,
|
||
&obja,
|
||
SynchronizationEvent,
|
||
FALSE);
|
||
|
||
if (Status == STATUS_SUCCESS) {
|
||
Status = NtCreateEvent(
|
||
&hFrsSyncEvent,
|
||
SYNCHRONIZE | EVENT_QUERY_STATE | EVENT_MODIFY_STATE,
|
||
&obja,
|
||
SynchronizationEvent,
|
||
FALSE);
|
||
}
|
||
|
||
DFSM_TRACE_ERROR_HIGH(Status, ALL_ERROR, DfsManagerStartDSSync_Error_NtCreateEvent,
|
||
LOGSTATUS(Status));
|
||
|
||
if (Status == STATUS_SUCCESS) {
|
||
|
||
hSyncThread = CreateThread(
|
||
NULL,
|
||
0,
|
||
DfsManagerDSSyncThread,
|
||
NULL,
|
||
0,
|
||
&dwSyncThreadId);
|
||
|
||
if (hSyncThread == NULL)
|
||
dwErr = GetLastError();
|
||
|
||
} else {
|
||
|
||
dwErr = GetLastError();
|
||
hSyncEvent = NULL;
|
||
|
||
}
|
||
|
||
return( dwErr );
|
||
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfsManagerDSSyncThread
|
||
//
|
||
// Synopsis: Periodically syncs the local metadata with the DS
|
||
//
|
||
// Arguments: [Context] -- Ignored
|
||
//
|
||
// Returns: Nothing
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
|
||
#if _MSC_FULL_VER >= 13008827
|
||
#pragma warning(push)
|
||
#pragma warning(disable:4715) // Not all control paths return (due to infinite loop)
|
||
#endif
|
||
DWORD
|
||
DfsManagerDSSyncThread(
|
||
PVOID Context)
|
||
{
|
||
DWORD dwErr;
|
||
HKEY hkey;
|
||
|
||
while (1) {
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfsManagerDSSyncThread()\n");
|
||
#endif
|
||
|
||
dwSyncIntervalInMs = GetSyncInterval();
|
||
|
||
dwErr = WaitForSingleObject(hSyncEvent, dwSyncIntervalInMs);
|
||
|
||
if (dwErr != WAIT_TIMEOUT) {
|
||
WaitForSingleObject(hFrsSyncEvent, dwFrsSyncIntervalInMs);
|
||
}
|
||
|
||
IDfsVolInlineDebOut((DEB_TRACE, "DfsManagerDSSyncThread()\n"));
|
||
|
||
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
|
||
|
||
ENTER_DFSM_OPERATION;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
RegCloseKey( hkey );
|
||
LdapIncrementBlob(TRUE);
|
||
dwErr = LdapDecrementBlob();
|
||
}
|
||
|
||
EXIT_DFSM_OPERATION;
|
||
}
|
||
|
||
}
|
||
|
||
return( 0 );
|
||
|
||
}
|
||
#if _MSC_FULL_VER >= 13008827
|
||
#pragma warning(pop)
|
||
#endif
|
||
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfspGetPdc
|
||
//
|
||
// Synopsis: Sets the global pwszDSMachineName to the PDC
|
||
//
|
||
// Arguments: None
|
||
//
|
||
// Returns: ERROR_SUCCESS or failure
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
DWORD
|
||
DfspGetPdc(void)
|
||
{
|
||
DWORD dwErr;
|
||
PDOMAIN_CONTROLLER_INFO pDCInfo;
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfspGetPdc()\n");
|
||
#endif
|
||
|
||
dwErr = DsGetDcName(
|
||
NULL, // Computer to remote to
|
||
NULL, // Domain - use local domain
|
||
NULL, // Domain Guid
|
||
NULL, // Site Guid
|
||
DS_PDC_REQUIRED | DS_FORCE_REDISCOVERY,
|
||
&pDCInfo);
|
||
|
||
DFSM_TRACE_ERROR_HIGH(dwErr, ALL_ERROR, DfspGetPdc_Error_DsGetDcName,
|
||
LOGULONG(dwErr)
|
||
);
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
if (pwszDSMachineName == NULL)
|
||
pwszDSMachineName = wszDSMachineName;
|
||
wcscpy(pwszDSMachineName, &pDCInfo->DomainControllerName[2]);
|
||
NetApiBufferFree( pDCInfo );
|
||
|
||
}
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("DfspGetPdc() returning %d\n", dwErr);
|
||
#endif
|
||
|
||
return( dwErr );
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetSyncInterval
|
||
//
|
||
// Synopsis: Returns the interval at which to sync with the DS
|
||
//
|
||
// Arguments: None
|
||
//
|
||
// Returns: Returns the interval at which to sync with the DS
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
GetSyncInterval()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD dwIntervalInSeconds = 60 * 60;
|
||
DWORD cbData;
|
||
HKEY hkey;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbData = sizeof(dwIntervalInSeconds);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
SYNC_INTERVAL_NAME,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &dwIntervalInSeconds,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
|
||
|
||
dwIntervalInSeconds = 60 * 60;
|
||
|
||
}
|
||
|
||
RegCloseKey(hkey);
|
||
|
||
}
|
||
|
||
return( dwIntervalInSeconds * 1000 );
|
||
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetDcLockInterval
|
||
//
|
||
// Synopsis: Returns the interval to lock onto a DC
|
||
//
|
||
// Arguments: None
|
||
//
|
||
// Returns: Returns the interval to lock onto a DC
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
ULONG
|
||
GetDcLockInterval()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD dwIntervalInSeconds = 60 * 60 * 2;
|
||
DWORD cbData;
|
||
HKEY hkey;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbData = sizeof(dwIntervalInSeconds);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
DCLOCK_INTERVAL_NAME,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &dwIntervalInSeconds,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
|
||
|
||
dwIntervalInSeconds = 60 * 60 * 2;
|
||
|
||
}
|
||
|
||
RegCloseKey(hkey);
|
||
|
||
}
|
||
|
||
return( dwIntervalInSeconds * 1000 );
|
||
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetEntryTimeout
|
||
//
|
||
// Synopsis: Returns the timeout (in seconds) for jp's
|
||
//
|
||
// Arguments: None
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
GetEntryTimeout()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD dwTimeoutInSeconds = DEFAULT_PKT_ENTRY_TIMEOUT;
|
||
DWORD cbData;
|
||
HKEY hkey;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbData = sizeof(dwTimeoutInSeconds);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_TIMETOLIVE,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &dwTimeoutInSeconds,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
|
||
|
||
dwTimeoutInSeconds = DEFAULT_PKT_ENTRY_TIMEOUT;
|
||
|
||
}
|
||
|
||
RegCloseKey(hkey);
|
||
|
||
}
|
||
|
||
return( dwTimeoutInSeconds );
|
||
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: DfspGetFtDfsName
|
||
//
|
||
// Synopsis: Gets the FtDfs name from the registry
|
||
//
|
||
// Arguments: None
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
DWORD
|
||
DfspGetFtDfsName()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD cbName;
|
||
HKEY hkey;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, VOLUMES_DIR, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbName = sizeof(wszFtDfsName);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
FTDFS_VALUE_NAME,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) wszFtDfsName,
|
||
&cbName);
|
||
|
||
if (dwErr == ERROR_SUCCESS && dwType != REG_SZ) {
|
||
|
||
dwErr = ERROR_FILE_NOT_FOUND;
|
||
|
||
}
|
||
|
||
RegCloseKey( hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
pwszFtDfsName = wszFtDfsName;
|
||
|
||
} else {
|
||
|
||
pwszFtDfsName = NULL;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
return dwErr;
|
||
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetConfigSwitches
|
||
//
|
||
// Synopsis: Get configuration switches from the registry
|
||
//
|
||
// Arguments: None
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
VOID
|
||
GetConfigSwitches()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD cbData;
|
||
HKEY hkey;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbData = sizeof(DfsDnsConfig);
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_DFSDNSCONFIG,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &DfsDnsConfig,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD))
|
||
DfsDnsConfig = 0;
|
||
|
||
cbData = sizeof(DfsSvcLdap);
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_LDAP,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &DfsSvcLdap,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD))
|
||
DfsSvcLdap = 0;
|
||
|
||
|
||
RegCloseKey(hkey);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetEventLogSwitches
|
||
//
|
||
// Synopsis: Gets the event log switch values
|
||
//
|
||
// Arguments: None
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
VOID
|
||
GetEventLogSwitches()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD cbData;
|
||
HKEY hkey = NULL;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_EVENTLOG, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbData = sizeof(DfsEventLog);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_EVENTLOG_GLOBAL,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &DfsEventLog,
|
||
&cbData);
|
||
|
||
if (dwErr == ERROR_SUCCESS && dwType == REG_DWORD)
|
||
goto Cleanup;
|
||
|
||
DfsEventLog = 0;
|
||
|
||
cbData = sizeof(DfsEventLog);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_EVENTLOG_DFS,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &DfsEventLog,
|
||
&cbData);
|
||
|
||
if (dwErr == ERROR_SUCCESS && dwType == REG_DWORD)
|
||
goto Cleanup;
|
||
|
||
//
|
||
// Could not find either the global nor the dfs event log setting
|
||
//
|
||
|
||
DfsEventLog = 0;
|
||
|
||
}
|
||
|
||
#if DBG
|
||
if (DfsSvcVerbose)
|
||
DbgPrint("Dfssvc:DfsEventLog = 0x%x\n", DfsEventLog);
|
||
#endif
|
||
|
||
Cleanup:
|
||
|
||
if (hkey != NULL)
|
||
RegCloseKey(hkey);
|
||
|
||
}
|
||
|
||
#if DBG
|
||
//+----------------------------------------------------------------------------
|
||
//
|
||
// Function: GetDebugSwitches
|
||
//
|
||
// Synopsis: Gets the debug switch values
|
||
//
|
||
// Arguments: None
|
||
//
|
||
//-----------------------------------------------------------------------------
|
||
|
||
VOID
|
||
GetDebugSwitches()
|
||
{
|
||
DWORD dwErr;
|
||
DWORD dwType;
|
||
DWORD cbData;
|
||
HKEY hkey;
|
||
|
||
dwErr = RegOpenKey( HKEY_LOCAL_MACHINE, REG_KEY_DFSSVC, &hkey );
|
||
|
||
if (dwErr == ERROR_SUCCESS) {
|
||
|
||
cbData = sizeof(DfsSvcVerbose);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_VERBOSE,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &DfsSvcVerbose,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
|
||
|
||
DfsSvcVerbose = 0;
|
||
|
||
}
|
||
|
||
cbData = sizeof(IDfsVolInfoLevel);
|
||
|
||
dwErr = RegQueryValueEx(
|
||
hkey,
|
||
REG_VALUE_IDFSVOL,
|
||
NULL,
|
||
&dwType,
|
||
(PBYTE) &IDfsVolInfoLevel,
|
||
&cbData);
|
||
|
||
if (!(dwErr == ERROR_SUCCESS && dwType == REG_DWORD)) {
|
||
|
||
IDfsVolInfoLevel = DEF_INFOLEVEL;
|
||
|
||
}
|
||
|
||
RegCloseKey(hkey);
|
||
|
||
}
|
||
|
||
}
|
||
#endif
|
||
|
||
|
||
|
||
//+------------------------------------------------------------------------
|
||
//
|
||
// Function: LogMessage()
|
||
//
|
||
// Synopsis: This method takes an error code and a list of strings and
|
||
// displays the right message for now. Later on this will have
|
||
// to raise an event and do the appropriate stuff actually.
|
||
//
|
||
// Arguments: [ErrNum] -- Error Number (SCODE). This identifies message to
|
||
// pick up.
|
||
// [pwcstrs] -- The strings that are to be displayed.
|
||
// [count] -- Number of strings in above array.
|
||
// [Severity] -- The severity of the error so that we can turn
|
||
// off debuggin selectively.
|
||
//
|
||
// Returns: Nothing.
|
||
//
|
||
// Notes:
|
||
//
|
||
// History: 10-Feb-1993 SudK Created.
|
||
//
|
||
//-------------------------------------------------------------------------
|
||
VOID
|
||
LogMessageFull(
|
||
DWORD Severity,
|
||
PWCHAR pwcstrs[],
|
||
DWORD count,
|
||
DWORD ErrNum)
|
||
{
|
||
IDfsVolInlineDebOut(( Severity, " [%ws] \n", DfsErrString[ErrNum] ));
|
||
|
||
for (ULONG _i=0; _i<count; _i++) {
|
||
IDfsVolInlineDebOut(( Severity, "Str%d : [%ws] \n", _i, pwcstrs[_i] ));
|
||
}
|
||
IDfsVolInlineDebOut((Severity, "***%s @ %d *****\n", __FILE__, __LINE__));
|
||
}
|
||
|