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__));
|
|||
|
}
|
|||
|
|