|
|
//+----------------------------------------------------------------------------
//
// 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__
|