255 lines
7.1 KiB
C++
255 lines
7.1 KiB
C++
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2000, Microsoft Corporation
|
|
//
|
|
// File: DfsRegistryRootFolder.cxx
|
|
//
|
|
// Contents: the Root DFS Folder class for Registry Store
|
|
//
|
|
// Classes: DfsRegistryRootFolder
|
|
//
|
|
// History: Dec. 8 2000, Author: udayh
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
#include "DfsRegistryRootFolder.hxx"
|
|
#include "DfsReplica.hxx"
|
|
|
|
#include "lmdfs.h"
|
|
#include "DfsClusterSupport.hxx"
|
|
//
|
|
// logging specific includes
|
|
//
|
|
#include "DfsRegistryRootFolder.tmh"
|
|
|
|
//+----------------------------------------------------------------------------
|
|
//
|
|
// Class: DfsRegistryRootFolder
|
|
//
|
|
// Synopsis: This class implements The Dfs Registry root folder.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: DfsRegistryRootFolder - constructor
|
|
//
|
|
// Arguments: NameContext - the dfs name context
|
|
// pLogicalShare - the logical share
|
|
// pParentStore - the parent store for this root.
|
|
// pStatus - the return status
|
|
//
|
|
// Returns: NONE
|
|
//
|
|
// Description: This routine initializes a RegistryRootFolder instance
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
DfsRegistryRootFolder::DfsRegistryRootFolder(
|
|
LPWSTR NameContext,
|
|
LPWSTR pRootRegKeyNameString,
|
|
PUNICODE_STRING pLogicalShare,
|
|
PUNICODE_STRING pPhysicalShare,
|
|
DfsRegistryStore *pParentStore,
|
|
DFSSTATUS *pStatus ) : DfsRootFolder ( NameContext,
|
|
pRootRegKeyNameString,
|
|
pLogicalShare,
|
|
pPhysicalShare,
|
|
DFS_OBJECT_TYPE_REGISTRY_ROOT_FOLDER,
|
|
pStatus )
|
|
{
|
|
DFSSTATUS Status = *pStatus;
|
|
|
|
_pStore = pParentStore;
|
|
if (_pStore != NULL)
|
|
{
|
|
_pStore->AcquireReference();
|
|
}
|
|
|
|
//
|
|
// If the namecontext that we are passed is an emptry string,
|
|
// then we are dealing with the referral server running on the root
|
|
// itself. We are required to ignore the name context for such
|
|
// roots during lookups, so that aliasing works. (Aliasing is where
|
|
// someone may access the root with an aliased machine name or ip
|
|
// address)
|
|
//
|
|
if (IsEmptyString(NameContext) == TRUE)
|
|
{
|
|
SetIgnoreNameContext();
|
|
_LocalCreate = TRUE;
|
|
}
|
|
|
|
//
|
|
// dfsdev: If this is cluster resource, we should set the visible name
|
|
// to virtual server name of this resource.
|
|
//
|
|
// The constructor for DfsRootFolder will be called before we
|
|
// get here, and pstatus will be initialized
|
|
//
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
if (DfsIsMachineCluster())
|
|
{
|
|
GetRootClusterInformation( pLogicalShare,
|
|
&_DfsVisibleContext);
|
|
}
|
|
if (IsEmptyString(_DfsVisibleContext.Buffer))
|
|
{
|
|
Status = DfsGetMachineName( &_DfsVisibleContext );
|
|
}
|
|
}
|
|
|
|
*pStatus = Status;
|
|
}
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: Synchronize
|
|
//
|
|
// Arguments: None
|
|
//
|
|
// Returns: Status: Success or Error status code
|
|
//
|
|
// Description: This routine synchronizes the children folders
|
|
// of this root.
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
DFSSTATUS
|
|
DfsRegistryRootFolder::Synchronize( )
|
|
{
|
|
|
|
DFSSTATUS Status;
|
|
HKEY RootKey;
|
|
ULONG ChildNum = 0;
|
|
FILETIME LastModifiedTime;
|
|
|
|
DFS_TRACE_HIGH(REFERRAL_SERVER, "Synchronize for %p\n", this);
|
|
|
|
|
|
Status = AcquireRootLock();
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
if (CheckRootFolderSkipSynchronize() == TRUE)
|
|
{
|
|
ReleaseRootLock();
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
|
|
//
|
|
// now acquire the root share directory. If this
|
|
// fails, we continue our operation: we can continue
|
|
// with synchonize and not create directories.
|
|
// dfsdev:we need to post a eventlog or something when
|
|
// we run into this.
|
|
//
|
|
DFSSTATUS RootStatus = AcquireRootShareDirectory();
|
|
|
|
DFS_TRACE_ERROR_LOW(RootStatus, REFERRAL_SERVER, "Recognize Dfs: Root folder for %p, validate status %x\n",
|
|
this, RootStatus );
|
|
|
|
|
|
//
|
|
// if we are in a standby mode, we dont synchronize, till we obtain
|
|
// ownership again.
|
|
//
|
|
|
|
Status = GetMetadataKey( &RootKey );
|
|
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
|
|
do
|
|
{
|
|
//
|
|
// For each child, get the child name.
|
|
//
|
|
|
|
DWORD ChildNameLen = DFS_REGISTRY_CHILD_NAME_SIZE_MAX;
|
|
WCHAR ChildName[DFS_REGISTRY_CHILD_NAME_SIZE_MAX];
|
|
|
|
Status = RegEnumKeyEx( RootKey,
|
|
ChildNum,
|
|
ChildName,
|
|
&ChildNameLen,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&LastModifiedTime );
|
|
|
|
ChildNum++;
|
|
|
|
//
|
|
// Call update on the child. This either adds a new folder
|
|
// or if it exists, ensure the child folder is upto date.
|
|
//
|
|
if ( Status == ERROR_SUCCESS )
|
|
{
|
|
DFS_METADATA_HANDLE DfsHandle;
|
|
|
|
DfsHandle = CreateMetadataHandle(RootKey);
|
|
|
|
Status = UpdateLinkInformation( DfsHandle,
|
|
ChildName );
|
|
|
|
DestroyMetadataHandle(DfsHandle );
|
|
}
|
|
//
|
|
// If the child is holding information we dont understand, just
|
|
// skip that child.
|
|
//
|
|
if ( Status == ERROR_INVALID_DATA )
|
|
{
|
|
DFSLOG("DfsREgistryRootFolder: synchronize: skipping child %wS\n", ChildName );
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
} while ( Status == ERROR_SUCCESS );
|
|
|
|
if ( Status == ERROR_NO_MORE_ITEMS )
|
|
{
|
|
Status = ERROR_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// We are done with synchronize.
|
|
// update the Root folder, so that this root folder may be made
|
|
// either available or unavailable, as the case may be.
|
|
//
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
SetRootFolderSynchronized();
|
|
}
|
|
else
|
|
{
|
|
ClearRootFolderSynchronized();
|
|
}
|
|
|
|
//
|
|
// Now release the Root metadata key.
|
|
//
|
|
ReleaseMetadataKey( RootKey );
|
|
}
|
|
|
|
DFS_TRACE_HIGH(REFERRAL_SERVER, "Synchronize for %p, Status %x\n", this, Status);
|
|
|
|
ReleaseRootLock();
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|