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

358 lines
9.5 KiB

//+----------------------------------------------------------------------------
//
// Copyright (C) 2000, Microsoft Corporation
//
// File: DfsRegistryRootFolder.hxx
//
// Contents: the Root DFS Folder class for Registry Store
//
// Classes: DfsRegistryRootFolder
//
// History: Dec. 8 2000, Author: udayh
//
//-----------------------------------------------------------------------------
#ifndef __DFS_REGISTRY_ROOT_FOLDER__
#define __DFS_REGISTRY_ROOT_FOLDER__
#include "DfsRootFolder.hxx"
#include "DfsRegistryStore.hxx"
//+----------------------------------------------------------------------------
//
// Class: DfsRegistryRootFolder
//
// Synopsis: This class implements The Dfs Registry root folder.
//
//-----------------------------------------------------------------------------
class DfsRegistryRootFolder: public DfsRootFolder
{
private:
DfsRegistryStore *_pStore; // Pointer to registered store
// that owns this root.
protected:
DfsStore *
GetMetadataStore()
{
return _pStore;
}
//
// Function GetMetadataKey: Gets the registry metadata key for
// this root folder.
//
DFSSTATUS
GetMetadataHandle( PDFS_METADATA_HANDLE pRootHandle )
{
HKEY RootKey;
DFSSTATUS Status;
Status = GetMetadataKey( &RootKey );
if (Status == ERROR_SUCCESS)
{
*pRootHandle = CreateMetadataHandle(RootKey);
}
return Status;
}
VOID
ReleaseMetadataHandle( DFS_METADATA_HANDLE RootHandle )
{
HKEY RootKey;
RootKey = (HKEY)ExtractFromMetadataHandle(RootHandle);
ReleaseMetadataKey(RootKey);
DestroyMetadataHandle(RootHandle);
return;
}
private:
DFSSTATUS
GetMetadataKey( PHKEY pOpenedKey )
{
return _pStore->GetRootKey( GetNameContextString(),
GetRootRegKeyNameString(),
NULL,
pOpenedKey );
}
//
// Function ReleaseMetadataKey: Clsoes the registry metadata key for
// this root folder.
//
VOID
ReleaseMetadataKey( HKEY OpenedKey )
{
RegCloseKey( OpenedKey );
}
public:
//
// Function DfsRegistryRootFolder: Constructor.
// Initializes the RegistryRootFolder class instance.
//
DfsRegistryRootFolder(
LPWSTR NameContext,
LPWSTR RootRegistryName,
PUNICODE_STRING pLogicalName,
PUNICODE_STRING pPhysicalShare,
DfsRegistryStore *pParentStore,
DFSSTATUS *pStatus );
~DfsRegistryRootFolder()
{
DfsFreeUnicodeString(&_DfsVisibleContext);
if (_pStore != NULL)
{
_pStore->ReleaseReference();
_pStore = NULL;
}
}
//
// Function Synchronize: This function overrides the synchronize
// defined in the base class.
// The synchronize function updates the root folder's children
// with the uptodate information available in the store's metadata.
//
DFSSTATUS
Synchronize(BOOLEAN fForceSynch = FALSE, BOOLEAN CalledByApi = FALSE);
DFSSTATUS
GetMetadataLogicalToLinkName( PUNICODE_STRING pIn,
PUNICODE_STRING pOut )
{
UNICODE_STRING FirstComp;
return DfsGetFirstComponent( pIn,
&FirstComp,
pOut );
}
VOID
ReleaseMetadataLogicalToLinkName( PUNICODE_STRING pIn )
{
UNREFERENCED_PARAMETER(pIn);
return NOTHING;
}
//
// The default behavior for ADBLOB roots is Force == FALSE. The reason
// for that is because ADBLOBs have a GUID that it can do a first level
// check on.
// There is no such thing for the registry roots. We ignore the force flag
// altogether.
//
DFSSTATUS
ReSynchronize(BOOLEAN fForceSync)
{
DFSSTATUS Status = ERROR_SUCCESS;
Status = Synchronize(fForceSync);
return Status;
}
//
// CheckPreSyncrhonize:
// The registry store has an issue. If someone updates the registry
// without going through the standard API, the service does not
// know about deletions and only picks up new entries or modifications.
// This can cause severe leaks if someone does put in a replication
// for registries, causing all roots on the server to slow down.
//
// For longhorn, we should move the name_table usage to sash and use
// the sash enumeration to enumerate and mark entries as stale etc.
// This needs other fixes as well: in the meanwhile, we have a
// fixed mechanism of checking before synchronize if each
// folder we have actually exists in the registry.
//
//
//
VOID
CheckPreSynchronize( HKEY RootKey)
{
struct _DFS_LINK_LIST {
DfsFolder *pFolder;
struct _DFS_LINK_LIST *pNext;
};
struct _DFS_LINK_LIST *pNewEntry = NULL, *pOldEntry = NULL;
struct _DFS_LINK_LIST *pListEntry = NULL, *pUseEntry = NULL;
PVOID pHandle = NULL;
DfsFolder *pFolder;
NTSTATUS NtStatus;
DFSSTATUS Status;
ULONG NumChild;
Status = RegQueryInfoKey( RootKey, // Key
NULL, // Class string
NULL, // Size of class string
NULL, // Reserved
&NumChild, // # of subkeys
NULL, // max size of subkey name
NULL, // max size of class name
NULL, // # of values
NULL, // max size of value name
NULL, // max size of value data,
NULL, // security descriptor
NULL ); // Last write time
if ( (Status != ERROR_SUCCESS) ||
(NumChild == GetChildCount()) )
{
return NOTHING;
}
NtStatus = DfsNameTableAcquireReadLock( _pMetadataNameTable );
while (NtStatus == STATUS_SUCCESS)
{
NtStatus = DfsEnumerateNameTableLocked( _pMetadataNameTable,
&pHandle,
(PVOID *)&pFolder );
if (NtStatus == STATUS_SUCCESS)
{
HKEY NewKey;
Status = RegOpenKeyEx( RootKey,
pFolder->GetFolderMetadataNameString(),
0,
KEY_READ,
&NewKey );
if (Status == ERROR_SUCCESS)
{
RegCloseKey( NewKey );
}
if (Status == ERROR_FILE_NOT_FOUND)
{
pNewEntry = new struct _DFS_LINK_LIST;
if (pNewEntry != NULL)
{
if (pOldEntry)
{
pOldEntry->pNext = pNewEntry;
}
else
{
pListEntry = pNewEntry;
}
pNewEntry->pFolder = pFolder;
pNewEntry->pFolder->AcquireReference();
pNewEntry->pNext = NULL;
pOldEntry = pNewEntry;
}
}
}
}
DfsNameTableReleaseLock( _pMetadataNameTable );
while (pListEntry != NULL)
{
pUseEntry = pListEntry;
pListEntry = pUseEntry->pNext;
RemoveLinkFolder( pUseEntry->pFolder, TRUE);
pUseEntry->pFolder->ReleaseReference();
delete pUseEntry;
}
return NOTHING;
}
DFSSTATUS
RootApiRequestPrologue( BOOLEAN WriteRequest,
LPWSTR Name = NULL )
{
DFSSTATUS Status;
UNREFERENCED_PARAMETER(Name);
Status = CommonRootApiPrologue( WriteRequest );
return Status;
}
VOID
RootApiRequestEpilogue(
BOOLEAN WriteRequest,
DFSSTATUS CompletionStatus )
{
UNREFERENCED_PARAMETER(CompletionStatus);
UNREFERENCED_PARAMETER(WriteRequest);
return NOTHING;
}
DFSSTATUS
RootRequestPrologue( LPWSTR Name )
{
UNREFERENCED_PARAMETER(Name);
return ERROR_NOT_SUPPORTED;
}
VOID
RootRequestEpilogue ()
{
}
DFSSTATUS
Flush()
{
return ERROR_SUCCESS;
}
DFSSTATUS
RenameLinks( IN LPWSTR OldDomainName,
IN LPWSTR NewDomainName)
{
UNREFERENCED_PARAMETER(OldDomainName);
UNREFERENCED_PARAMETER(NewDomainName);
return ERROR_NOT_SUPPORTED;
}
DFSSTATUS
CheckResynchronizeAccess( DFSSTATUS AccessCheckStatus)
{
return AccessCheckStatus;
}
};
#endif // __DFS_REGISTRY_ROOT_FOLDER__