|
|
//+----------------------------------------------------------------------------
//
// Copyright (C) 2000, Microsoft Corporation
//
// File: DfsStore.hxx
//
// Contents: the base DFS Store class, this contains the common
// store functionality.
//
// Classes: DfsStore.
//
// History: Dec. 8 2000, Author: udayh
//
//-----------------------------------------------------------------------------
#ifndef __DFS_STORE__
#define __DFS_STORE__
#include "DfsGeneric.hxx"
#include "DfsRootFolder.hxx"
#include "lmdfs.h"
#include "rpc.h"
#include "rpcdce.h"
#include <DfsServerLibrary.hxx>
//
// The first part of this file contains the marshalling/unmarshalling
// routines that are used by the old stores (registry and AD)
// These routines help us read a binary blob and unravel their contents.
//
// the latter part defines the common store class for all our stores.
//
#define BYTE_0_MASK 0xFF
#define BYTE_0(Value) (UCHAR)( (Value) & BYTE_0_MASK)
#define BYTE_1(Value) (UCHAR)( ((Value) >> 8) & BYTE_0_MASK)
#define BYTE_2(Value) (UCHAR)( ((Value) >> 16) & BYTE_0_MASK)
#define BYTE_3(Value) (UCHAR)( ((Value) >> 24) & BYTE_0_MASK)
#define MTYPE_BASE_TYPE (0x0000ffffL)
#define MTYPE_COMPOUND (0x00000001L)
#define MTYPE_GUID (0x00000002L)
#define MTYPE_ULONG (0x00000003L)
#define MTYPE_USHORT (0x00000004L)
#define MTYPE_PWSTR (0x00000005L)
#define MTYPE_UCHAR (0x00000006L)
#define _MCode_Base(t,s,m,i)\
{t,offsetof(s,m),0L,0L,i}
#define _MCode_struct(s,m,i)\
_MCode_Base(MTYPE_COMPOUND,s,m,i)
#define _MCode_pwstr(s,m)\
_MCode_Base(MTYPE_PWSTR,s,m,NULL)
#define _MCode_ul(s,m)\
_MCode_Base(MTYPE_ULONG,s,m,NULL)
#define _MCode_guid(s,m)\
_MCode_Base(MTYPE_GUID,s,m,NULL)
#define _mkMarshalInfo(s, i)\
{(ULONG)sizeof(s),(ULONG)(sizeof(i)/sizeof(MARSHAL_TYPE_INFO)),i}
typedef struct _MARSHAL_TYPE_INFO {
ULONG _type; // the type of item to be marshalled
ULONG _off; // offset of item (in the struct)
ULONG _cntsize; // size of counter for counted array
ULONG _cntoff; // else, offset count item (in the struct)
struct _MARSHAL_INFO * _subinfo;// if compound type, need info
} MARSHAL_TYPE_INFO, *PMARSHAL_TYPE_INFO;
typedef struct _MARSHAL_INFO {
ULONG _size; // size of item
ULONG _typecnt; // number of type infos
PMARSHAL_TYPE_INFO _typeInfo; // type infos
} MARSHAL_INFO, *PMARSHAL_INFO;
typedef struct _DFS_NAME_INFORMATION_ { PVOID pData; ULONG DataSize; UNICODE_STRING Prefix; UNICODE_STRING ShortPrefix; GUID VolumeId; ULONG State; ULONG Type; UNICODE_STRING Comment; FILETIME PrefixTimeStamp; FILETIME StateTimeStamp; FILETIME CommentTimeStamp; ULONG Timeout; ULONG Version; FILETIME LastModifiedTime; } DFS_NAME_INFORMATION, *PDFS_NAME_INFORMATION;
//
// Defines for ReplicaState.
//
#define REPLICA_STORAGE_STATE_OFFLINE 0x1
typedef struct _DFS_REPLICA_INFORMATION__ { PVOID pData; ULONG DataSize; FILETIME ReplicaTimeStamp; ULONG ReplicaState; ULONG ReplicaType; UNICODE_STRING ServerName; UNICODE_STRING ShareName; } DFS_REPLICA_INFORMATION, *PDFS_REPLICA_INFORMATION;
typedef struct _DFS_REPLICA_LIST_INFORMATION_ { PVOID pData; ULONG DataSize; ULONG ReplicaCount; DFS_REPLICA_INFORMATION *pReplicas; } DFS_REPLICA_LIST_INFORMATION, *PDFS_REPLICA_LIST_INFORMATION;
extern MARSHAL_INFO MiFileTime;
#define INIT_FILE_TIME_INFO() \
static MARSHAL_TYPE_INFO _MCode_FileTime[] = { \ _MCode_ul(FILETIME, dwLowDateTime), \ _MCode_ul(FILETIME, dwHighDateTime), \ }; \ MARSHAL_INFO MiFileTime = _mkMarshalInfo(FILETIME, _MCode_FileTime);
//
// Marshalling info for DFS_REPLICA_INFO structure
//
extern MARSHAL_INFO MiDfsReplicaInfo;
#define INIT_DFS_REPLICA_INFO_MARSHAL_INFO() \
static MARSHAL_TYPE_INFO _MCode_DfsReplicaInfo[] = { \ _MCode_struct(DFS_REPLICA_INFORMATION, ReplicaTimeStamp, &MiFileTime), \ _MCode_ul(DFS_REPLICA_INFORMATION, ReplicaState), \ _MCode_ul(DFS_REPLICA_INFORMATION, ReplicaType), \ _MCode_pwstr(DFS_REPLICA_INFORMATION, ServerName), \ _MCode_pwstr(DFS_REPLICA_INFORMATION, ShareName), \ }; \ MARSHAL_INFO MiDfsReplicaInfo = _mkMarshalInfo(DFS_REPLICA_INFORMATION, _MCode_DfsReplicaInfo);
enum DfsRootListType { NewRootList, DeletedRootList, OldRootList, };
#define DFS_REGISTRY_CHILD_NAME_SIZE_MAX MAX_PATH
//
// The unmarshalling routines: the existing registry and AD stores
// store the information in binary blobs, and these routines
// help convert the binary data into meaningful data structures.
//
//+----------------------------------------------------------------------------
//
// Class: DfsStore
//
// Synopsis: This abstract class implements a basic DfsStore
// The DfsStore is derived by the actual store modules
// (such as registry, ad, etc) that implement the store
// specific recognize routines.
//
//-----------------------------------------------------------------------------
class DfsStore: public DfsGeneric { private: CRITICAL_SECTION _Lock; // The lock for this store.
UNICODE_STRING _StoreName; // name of the store.
ULONG _GenerationNumber; // ?? TBD
BOOL _fCritInit;
protected: DfsRootFolder *_DfsRootList; // The roots that this store
// knows about.
DfsRootFolder *_DfsDeletedRootList; // The roots that this store
// knows about.
DfsRootFolder *_DfsOldRootList;
public: DfsStore *pNextRegisteredStore; // the next registered store.
private:
//
// Function AcquireLock: Acquires the lock on the store.
//
DFSSTATUS AcquireLock() { DFSSTATUS Status = ERROR_SUCCESS; EnterCriticalSection(&_Lock); return Status; }
protected:
DFSSTATUS PackGetInformation( ULONG_PTR Info, IN OUT PVOID *ppBuffer, PULONG pSizeRemaining, PMARSHAL_INFO pMarshalInfo );
DFSSTATUS PackSetInformation( ULONG_PTR Info, IN OUT PVOID *ppBuffer, PULONG pSizeRemaining, PMARSHAL_INFO pMarshalInfo );
ULONG PackSizeInformation( ULONG_PTR Info, PMARSHAL_INFO pMarshalInfo );
DFSSTATUS PackGetReplicaInformation( PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo, IN OUT PVOID *ppBuffer, PULONG pSizeRemaining);
DFSSTATUS PackSetReplicaInformation( PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo, IN OUT PVOID *ppBuffer, PULONG pSizeRemaining);
ULONG PackSizeReplicaInformation( PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo );
DFSSTATUS GetRootPhysicalShare( HKEY RootKey, PUNICODE_STRING pRootPhysicalShare );
VOID ReleaseRootPhysicalShare( PUNICODE_STRING pRootPhysicalShare );
DFSSTATUS GetRootLogicalShare( HKEY RootKey, PUNICODE_STRING pRootLogicalShare );
VOID ReleaseRootLogicalShare( PUNICODE_STRING pRootLogicalShare );
DFSSTATUS PackageEnumerationInfo( DWORD Level, DWORD EntryCount, LPBYTE pLinkBuffer, LPBYTE pBuffer, LPBYTE *ppCurrentBuffer, PLONG pSizeRemaining ); //
// Function GetDfsRegistryKey: This function takes a Name as the input,
// and looks up all DFS roots in that namespace.
static DFSSTATUS GetDfsRegistryKey( IN LPWSTR MachineName, IN LPWSTR LocationString, BOOLEAN WritePermission, OUT BOOLEAN *pMachineContacted, OUT PHKEY pDfsRegKey ) { DFSSTATUS Status; HKEY RootKey; BOOLEAN Contacted = FALSE; LPWSTR UseMachineName = NULL; REGSAM DesiredAccess = KEY_READ;
if (WritePermission == TRUE) { DesiredAccess |= KEY_WRITE; }
if (IsEmptyString(MachineName) == FALSE) { UseMachineName = MachineName; }
Status = RegConnectRegistry( UseMachineName, HKEY_LOCAL_MACHINE, &RootKey );
if ( Status == ERROR_SUCCESS ) { Contacted = TRUE;
Status = RegOpenKeyEx( RootKey, LocationString, 0, DesiredAccess, pDfsRegKey );
//
// There appears to be a bug in the registry code. When
// we connect to the local machine, the key that is returned
// in the RegConnectRegistry is HKEY_LOCAL_MACHINE. If we
// then attempt to close it here, it affects other threads
// that are using this code: they get STATUS_INVALID_HANDLE
// in some cases. So, dont close the key if it is
// HKEY_LOCAL_MACHINE.
//
if (RootKey != HKEY_LOCAL_MACHINE) { RegCloseKey( RootKey ); } }
if (pMachineContacted != NULL) { *pMachineContacted = Contacted; } return Status; }
static DFSSTATUS GetNewDfsRegistryKey( IN LPWSTR MachineName, BOOLEAN WritePermission, OUT BOOLEAN *pMachineContacted, OUT PHKEY pDfsRegKey ) { return GetDfsRegistryKey (MachineName, DfsNewRegistryLocation, WritePermission, pMachineContacted, pDfsRegKey ); }
//
// Function ReleaseMetadata: frees up space allocated when we
// got the metadata.
//
VOID ReleaseMetadataBlob( IN PVOID pBuffer ) { if ( pBuffer != NULL ) { delete [] pBuffer; }
return NOTHING; }
DFSSTATUS AllocateMetadataBlob( IN PVOID *ppBlob, IN ULONG BlobSize ) { DFSSTATUS Status = ERROR_SUCCESS;
*ppBlob = (PVOID)new BYTE [ BlobSize ]; if (*ppBlob == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } return Status; }
VOID ReleaseMetadataNameBlob( PVOID pBlob, ULONG BlobSize ) { UNREFERENCED_PARAMETER(BlobSize); ReleaseMetadataBlob( pBlob ); }
VOID ReleaseMetadataReplicaBlob( PVOID pBlob, ULONG BlobSize ) { UNREFERENCED_PARAMETER(BlobSize); ReleaseMetadataBlob( pBlob ); }
DFSSTATUS AllocateMetadataNameBlob( IN PVOID *ppBlob, IN ULONG BlobSize ) { return AllocateMetadataBlob(ppBlob, BlobSize); }
DFSSTATUS AllocateMetadataReplicaBlob( IN PVOID *ppBlob, IN ULONG BlobSize ) { return AllocateMetadataBlob(ppBlob, BlobSize); }
public:
//
// Function DfsStore: the constructor for the store. This initializes
// the critical section, and all the private and public variables
// of the store class.
//
DfsStore(LPWSTR Name, DfsObjectTypeEnumeration ObType, DFSSTATUS *pStatus) : DfsGeneric(ObType) {
USHORT NameLen = 0; DFSSTATUS Status = ERROR_SUCCESS; UNICODE_STRING Temp;
_fCritInit = FALSE; _StoreName.Buffer = NULL;
//
// Create a unicode string from the passed in name, and
// initialize our unicode string name to the passed in name.
//
Status = DfsRtlInitUnicodeStringEx(&Temp, Name); if(Status == ERROR_SUCCESS) { NameLen = wcslen(Name) + 1;
_StoreName.MaximumLength = NameLen * sizeof(WCHAR); _StoreName.Buffer = new WCHAR [NameLen]; if(_StoreName.Buffer == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } }
if(Status == ERROR_SUCCESS) { RtlCopyUnicodeString(&_StoreName, &Temp);
_DfsRootList = NULL; _DfsDeletedRootList = NULL; _DfsOldRootList = NULL; pNextRegisteredStore = NULL;
//
// The generation number exists to detect stale dfs folders.
// more on this later.
//
_GenerationNumber = 1;
_fCritInit = InitializeCriticalSectionAndSpinCount( &_Lock, DFS_CRIT_SPIN_COUNT ); if(!_fCritInit) { Status = GetLastError(); }
}
*pStatus = Status; }
//
// Function ~DfsStore: the destructor of dfsstore. Free up
// the allocated resources.
// This is virtual, so that we call the right order of destructors
// for all the instances of classes derived from DfsStore.
//
virtual ~DfsStore() {
// We could provide a mechanism to run through the list of
// root metadata, and release all of them, but that is
// unnecessary since we dont get rid of stores today.
// Once registered the stores live forever.
//
// Now free up the buffer we had allocated for the storename.
//
if (_StoreName.Buffer != NULL) { delete [] _StoreName.Buffer; }
if(_fCritInit) { DeleteCriticalSection( &_Lock ); }
}
static DFSSTATUS GetOldDfsRegistryKey( IN LPWSTR MachineName, BOOLEAN WritePermission, OUT BOOLEAN *pMachineContacted, OUT PHKEY pDfsRegKey ) { return GetDfsRegistryKey (MachineName, DfsOldRegistryLocation, WritePermission, pMachineContacted, pDfsRegKey ); }
static DFSSTATUS GetOldStandaloneRegistryKey( IN LPWSTR MachineName, BOOLEAN WritePermission, OUT BOOLEAN *pMachineContacted, OUT PHKEY pDfsRegKey ) { DFSSTATUS Status = ERROR_SUCCESS; HKEY DfsKey = NULL; *pDfsRegKey = NULL;
Status = GetOldDfsRegistryKey (MachineName, WritePermission, pMachineContacted, &DfsKey ); if (Status == ERROR_SUCCESS) { *pDfsRegKey = DfsKey; } return Status; }
static DFSSTATUS GetNewStandaloneRegistryKey( IN LPWSTR MachineName, BOOLEAN WritePermission, OUT BOOLEAN *pMachineContacted, OUT PHKEY pDfsRegKey ) { DFSSTATUS Status; HKEY DfsKey;
Status = GetNewDfsRegistryKey (MachineName, WritePermission, pMachineContacted, &DfsKey ); if (Status == ERROR_SUCCESS) { Status = RegOpenKeyEx( DfsKey, DfsStandaloneChild, 0, KEY_READ | (WritePermission ? KEY_WRITE : 0), pDfsRegKey ); RegCloseKey( DfsKey); } return Status; }
static DFSSTATUS GetNewADBlobRegistryKey( IN LPWSTR MachineName, BOOLEAN WritePermission, OUT BOOLEAN *pMachineContacted, OUT PHKEY pDfsRegKey ) { DFSSTATUS Status; HKEY DfsKey;
Status = GetNewDfsRegistryKey (MachineName, WritePermission, pMachineContacted, &DfsKey ); if (Status == ERROR_SUCCESS) { Status = RegOpenKeyEx( DfsKey, DfsADBlobChild, 0, KEY_READ | (WritePermission ? KEY_WRITE : 0), pDfsRegKey ); RegCloseKey( DfsKey); } return Status; }
//
// Function StoreRecognizer: This function takes a Name as the input,
// and looks up all DFS roots in that namespace.
// Since each store has its own mechanisms of identifying a root,
// the base class does not implement the StoreRecognizer. Each of
// the classes that are derived from the DfsStore class are expectged
// to override this function with their own implementation of the
// StoreRecognizer.
//
virtual DFSSTATUS StoreRecognizer(LPWSTR Name) = 0;
virtual DFSSTATUS StoreRecognizer( LPWSTR Name, PUNICODE_STRING Share) = 0;
DFSSTATUS StoreRecognizeNewDfs( LPWSTR DfsNameContext, HKEY DfsKey );
DFSSTATUS StoreRecognizeNewDfs ( LPWSTR DfsNameContext, PUNICODE_STRING pLogicalShare );
//
// Function ReleaseLock: release the store lock.
//
VOID ReleaseLock() { LeaveCriticalSection(&_Lock); return NOTHING; }
//
// Function AcquireWriteLock: Acquire the store lock exclusively.
// Currently all locks are exclusive, but this could change.
//
DFSSTATUS AcquireWriteLock() { return AcquireLock(); }
//
// Function AcquireReadLock: Acquire the store lock shared.
// Currently all locks are exclusive, but this could change.
//
DFSSTATUS AcquireReadLock() { return AcquireLock(); }
//
// Function AddRootFolder: This function takes a RootFolder and
// adds it to the list of known roots for this store.
// Each store instance keeps a list of all the Roots recognized by
// it.
//
// Make sure that we are adding only one root for a given metadata
// name and context, so that if multiple threads are working, only
// one will succeed.
//
//
DFSSTATUS AddRootFolder(DfsRootFolder *pNewRoot, DfsRootListType RootType ) { DFSSTATUS Status = STATUS_SUCCESS; DfsRootFolder *pRoot; DfsRootFolder **ppList;
switch (RootType) { case NewRootList: ppList = &_DfsRootList; break;
case DeletedRootList: ppList = &_DfsDeletedRootList; break;
case OldRootList: ppList = &_DfsOldRootList; break;
default: return STATUS_INVALID_PARAMETER; break; }
Status = AcquireWriteLock(); if ( Status != ERROR_SUCCESS ) return Status;
if ( *ppList == NULL ) { *ppList = pNewRoot; pNewRoot->pNextRoot = pNewRoot; pNewRoot->pPrevRoot = pNewRoot; } else { pRoot = *ppList; Status = ERROR_SUCCESS; do { if ( (_wcsicmp( pRoot->GetRootRegKeyNameString(), pNewRoot->GetRootRegKeyNameString()) == 0) && (_wcsicmp( pRoot->GetNameContextString(), pNewRoot->GetNameContextString() ) == 0) ) { Status = ERROR_FILE_EXISTS; break; } pRoot = pRoot->pNextRoot; } while ( pRoot != *ppList );
if (Status == ERROR_SUCCESS) { pNewRoot->pNextRoot = *ppList; pNewRoot->pPrevRoot = (*ppList)->pPrevRoot; (*ppList)->pPrevRoot->pNextRoot = pNewRoot; (*ppList)->pPrevRoot = pNewRoot; } }
if (Status == ERROR_SUCCESS) { pNewRoot->AcquireReference(); }
ReleaseLock();
return Status; } //
// Function DeleteRootFolder: This function takes a RootFolder and
// removes it from the list of known roots for this store.
// This functions is not supported: any root that has been deleted
// will stay in the root list so that we can get to the statistics
// etc. Future action TBD.
//
DFSSTATUS DeleteRootFolder(DfsRootFolder *pDfsRoot, DfsRootListType RootType ) { DFSSTATUS Status = STATUS_SUCCESS; DfsRootFolder *pRoot; DfsRootFolder **ppList;
switch (RootType) { case NewRootList: ppList = &_DfsRootList; break;
case DeletedRootList: ppList = &_DfsDeletedRootList; break;
case OldRootList: ppList = &_DfsOldRootList; break;
default: return STATUS_INVALID_PARAMETER; break; }
Status = AcquireWriteLock(); if ( Status != ERROR_SUCCESS ) return Status;
for ( pRoot = *ppList; pRoot != NULL; pRoot = pRoot->pNextRoot ) { if (pRoot == pDfsRoot) { if (pRoot->pNextRoot == pRoot) { *ppList = NULL; } else { pRoot->pNextRoot->pPrevRoot = pRoot->pPrevRoot; pRoot->pPrevRoot->pNextRoot = pRoot->pNextRoot; if (pRoot == *ppList) { *ppList = pRoot->pNextRoot; } } pRoot->pNextRoot = NULL; pRoot->pPrevRoot = NULL;
break; } } ReleaseLock();
if (pRoot == NULL) { Status = ERROR_NOT_FOUND; } else { pRoot->ReleaseReference(); }
return Status; }
DFSSTATUS RemoveRootFolder( DfsRootFolder *pRootFolder, BOOLEAN IsPermanent ) { DFSSTATUS LinkDeleteStatus = ERROR_SUCCESS; DFSSTATUS Status = ERROR_SUCCESS;
LinkDeleteStatus = pRootFolder->RemoveAllLinkFolders(IsPermanent);
pRootFolder->pStatistics->DumpStatistics(pRootFolder->GetLogicalShare()); Status = DeleteRootFolder( pRootFolder, NewRootList );
#if 0
if (Status == ERROR_SUCCESS) { Status = AddRootFolder( pRootFolder, DeletedRootList ); } #endif
return Status; }
//
// Function LookupRoot: Takes a Dfs name context and logical share,
// and returns a Root that matches the passed in name context and
// logical share, if one exists.
// Note that the same DFS NC and logical share may exist in more than
// one store (though very unlikely). In this case, the first registered
// store wins.
//
DFSSTATUS LookupRoot( PUNICODE_STRING pMachineName, PUNICODE_STRING pLogicalShare, DfsRootFolder **ppRoot );
//
// Function LookupRoot: Takes a Dfs name context and logical share,
// and returns a Root that matches the passed in name context and
// logical share, if one exists.
// Note that the same DFS NC and logical share may exist in more than
// one store (though very unlikely). In this case, the first registered
// store wins.
//
DFSSTATUS FindFirstRoot( DfsRootFolder **ppRoot ) { DFSSTATUS Status;
Status = AcquireReadLock(); if ( Status != ERROR_SUCCESS ) { return Status; } *ppRoot = _DfsRootList;
if (*ppRoot == NULL) { Status = ERROR_NOT_FOUND; } else { (*ppRoot)->AcquireReference(); }
ReleaseLock();
return Status; }
DFSSTATUS GetRootCount( PULONG pCount) { DFSSTATUS Status; DfsRootFolder *pRoot; ULONG Count = 0;
*pCount = 0;
Status = AcquireReadLock(); if ( Status != ERROR_SUCCESS ) { return Status; } pRoot = _DfsRootList; if (pRoot != NULL) { do { Count++; pRoot = pRoot->pNextRoot; } while ( pRoot != _DfsRootList ); }
*pCount = Count;
ReleaseLock();
return Status; }
ULONG FindReplicaInReplicaList( PDFS_REPLICA_LIST_INFORMATION pReplicaList, LPWSTR Server, LPWSTR Path ) { ULONG Index; PDFS_REPLICA_INFORMATION pReplicaInfo; UNICODE_STRING Target, TargetPath;
DfsRtlInitUnicodeStringEx(&Target, Server); DfsRtlInitUnicodeStringEx(&TargetPath, Path);
for (Index = 0; Index < pReplicaList->ReplicaCount; Index++) { pReplicaInfo = &pReplicaList->pReplicas[Index]; if ( (RtlCompareUnicodeString( &pReplicaInfo->ServerName, &Target, TRUE) == 0) && (RtlCompareUnicodeString( &pReplicaInfo->ShareName, &TargetPath, TRUE) == 0) ) { break; } }
return Index; }
DFSSTATUS DumpStatistics() { DFSSTATUS Status = STATUS_SUCCESS; DfsRootFolder *pRoot; DfsRootFolder **ppList;
ppList = &_DfsRootList;
Status = AcquireWriteLock(); if ( Status != ERROR_SUCCESS ) return Status;
for ( pRoot = *ppList; pRoot != NULL; pRoot = pRoot->pNextRoot ) { pRoot->pStatistics->DumpStatistics(pRoot->GetLogicalShare());
if (pRoot->pNextRoot == _DfsRootList) { break; } } ReleaseLock(); return Status; }
virtual DFSSTATUS AddChild( DFS_METADATA_HANDLE DfsHandle, IN PDFS_NAME_INFORMATION pNameInfo, IN PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo, IN PUNICODE_STRING pMetadataName ) = 0;
virtual DFSSTATUS RemoveChild( DFS_METADATA_HANDLE DfsHandle, LPWSTR ChildName ) = 0;
DFSSTATUS AddChildReplica ( DFS_METADATA_HANDLE DfsHandle, LPWSTR LinkMetadataName, LPWSTR Server, LPWSTR Share );
DFSSTATUS RemoveChildReplica ( DFS_METADATA_HANDLE DfsHandle, LPWSTR LinkMetadataName, LPWSTR Server, LPWSTR Share, PBOOLEAN pLastReplica , BOOLEAN Force = FALSE);
virtual DFSSTATUS EnumerateApiLinks( DFS_METADATA_HANDLE DfsHandle, PUNICODE_STRING pRootName, DWORD Level, LPBYTE pBuffer, LONG BufferSize, LPDWORD pEntriesToRead, LPDWORD pResumeHandle, PLONG pNextSizeRequired ) = 0;
DFSSTATUS GetStoreApiInformation( DFS_METADATA_HANDLE DfsHandle, PUNICODE_STRING pRootName, LPWSTR LinkMetadataName, DWORD Level, LPBYTE pBuffer, LONG BufferSize, PLONG pSizeRequired );
DFSSTATUS SetStoreApiInformation( DFS_METADATA_HANDLE DfsHandle, LPWSTR LinkMetadataName, LPWSTR Server, LPWSTR Share, DWORD Level, LPBYTE pBuffer );
DFSSTATUS GetExtendedAttributes( IN DFS_METADATA_HANDLE DfsHandle, LPWSTR LinkMetadataName, PULONG pAttr);
DFSSTATUS SetExtendedAttributes( IN DFS_METADATA_HANDLE DfsHandle, LPWSTR LinkMetadataName, ULONG pAttr);
//
// Function GetRootFolder: Runs through our list of RootFolders
// and sees if there is any root folder with the matching name.
// Returns a reference root folder, if found.
//
DFSSTATUS GetRootFolder ( LPWSTR DfsNameContext, LPWSTR RootRegistryName, HKEY DfsRootKey, DfsRootFolder **ppRootFolder );
//
// Function GetRootFolder: Runs through our list of RootFolders
// and sees if there is any root folder with the matching name.
// Returns a reference root folder, if found.
//
DFSSTATUS GetRootFolder ( LPWSTR DfsNameContext, LPWSTR RootRegistryName, PUNICODE_STRING pLogicalShare, PUNICODE_STRING pPhysicalShare, DfsRootFolder **ppRootFolder );
//
// Similar to the above, except for being aware that
// the root isn't on the local machine.
//
DFSSTATUS GetRootFolder ( LPWSTR DfsNameContextString, PUNICODE_STRING pLogicalShare, DfsRootFolder **ppRootFolder );
//
// Function CreateNewRootFolder: Creates a new root folder
// for the passed in name context, and logical share.
//
virtual DFSSTATUS CreateNewRootFolder ( LPWSTR MachineName, LPWSTR RootRegKeyName, PUNICODE_STRING pLogicalShare, PUNICODE_STRING pPhysicalShare, DfsRootFolder **pRoot ) = 0;
virtual DFSSTATUS GenerateLinkMetadataName( UUID *pUid, PUNICODE_STRING pLinkMetadataName ) { DFSSTATUS Status = ERROR_SUCCESS; LPWSTR String = NULL; Status = UuidToString( pUid, &String ); if (Status == ERROR_SUCCESS) { Status = DfsRtlInitUnicodeStringEx( pLinkMetadataName, String); } return Status; }
virtual VOID ReleaseLinkMetadataName( PUNICODE_STRING pLinkMetadataName ) { RpcStringFree(&pLinkMetadataName->Buffer );
return; }
DFSSTATUS EnumerateRoots( BOOLEAN DomainRoots, PULONG_PTR pBuffer, PULONG BufferSize, PULONG pEntriesRead, DWORD MaxEntriesToRead, PULONG pCurrentNumRoots, LPDWORD pResumeHandle, PULONG pSizeRequired );
DFSSTATUS AddRootEnumerationInfo( PUNICODE_STRING pVisibleName, PUNICODE_STRING pRootName, DWORD Flavor, PDFS_INFO_300 *ppDfsInfo300, PULONG pBufferSize, PULONG pEntriesRead, PULONG pTotalSize );
DFSSTATUS AddRootEnumerationInfo200( PUNICODE_STRING pRootName, PDFS_INFO_200 *ppDfsInfo300, PULONG pBufferSize, PULONG pEntriesRead, PULONG pTotalSize );
static DFSSTATUS SetupADBlobRootKeyInformation( HKEY DfsKey, LPWSTR DfsLogicalShare, LPWSTR DfsPhysicalShare );
virtual DFSSTATUS GetMetadataNameInformation( IN DFS_METADATA_HANDLE RootHandle, IN LPWSTR MetadataName, OUT PDFS_NAME_INFORMATION *ppInfo );
virtual VOID ReleaseMetadataNameInformation( IN DFS_METADATA_HANDLE DfsHandle, IN PDFS_NAME_INFORMATION pNameInfo );
virtual DFSSTATUS SetMetadataNameInformation( IN DFS_METADATA_HANDLE RootHandle, IN LPWSTR MetadataName, IN PDFS_NAME_INFORMATION pNameInfo );
DFSSTATUS GetMetadataReplicaInformation( IN DFS_METADATA_HANDLE RootHandle, IN LPWSTR MetadataName, OUT PDFS_REPLICA_LIST_INFORMATION *ppInfo );
VOID ReleaseMetadataReplicaInformation( IN DFS_METADATA_HANDLE DfsHandle, IN PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo );
DFSSTATUS SetMetadataReplicaInformation( IN DFS_METADATA_HANDLE RootHandle, IN LPWSTR MetadataName, IN PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo );
DFSSTATUS CreateNameInformationBlob( IN PDFS_NAME_INFORMATION pDfsNameInfo, OUT PVOID *ppBlob, OUT PULONG pDataSize );
virtual DFSSTATUS CreateReplicaListInformationBlob( IN PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo, OUT PVOID *ppBlob, OUT PULONG pDataSize );
virtual DFSSTATUS GetMetadataNameBlob( DFS_METADATA_HANDLE RootHandle, LPWSTR MetadataName, PVOID *ppData, PULONG pDataSize, PFILETIME pLastModifiedTime ) = 0;
virtual DFSSTATUS GetMetadataReplicaBlob( DFS_METADATA_HANDLE RootHandle, LPWSTR MetadataName, PVOID *ppData, PULONG pDataSize, PFILETIME pLastModifiedTime ) = 0;
virtual DFSSTATUS SetMetadataNameBlob( DFS_METADATA_HANDLE RootHandle, LPWSTR MetadataName, PVOID pData, ULONG DataSize ) = 0;
virtual DFSSTATUS SetMetadataReplicaBlob( DFS_METADATA_HANDLE RootHandle, LPWSTR MetadataName, PVOID pData, ULONG DataSize ) = 0;
virtual DFSSTATUS PackGetNameInformation( IN PDFS_NAME_INFORMATION pDfsNameInfo, IN OUT PVOID *ppBuffer, IN OUT PULONG pSizeRemaining) = 0;
virtual ULONG PackSizeNameInformation( IN PDFS_NAME_INFORMATION pDfsNameInfo ) = 0;
virtual DFSSTATUS PackSetNameInformation( IN PDFS_NAME_INFORMATION pDfsNameInfo, IN OUT PVOID *ppBuffer, IN OUT PULONG pSizeRemaining) = 0;
virtual DFSSTATUS GenerateMetadataLogicalName( PUNICODE_STRING pRootName, PUNICODE_STRING pInput, PUNICODE_STRING pOutput ) = 0;
virtual VOID ReleaseMetadataLogicalName( PUNICODE_STRING pName ) = 0;
virtual DFSSTATUS GenerateApiLogicalPath ( IN PUNICODE_STRING pRootName, IN PUNICODE_STRING pMetadataPrefix, IN PUNICODE_STRING pApiLogicalName ) = 0;
virtual VOID ReleaseApiLogicalPath ( PUNICODE_STRING pName ) = 0;
DFSSTATUS GetStoreApiInformationBuffer( IN DFS_METADATA_HANDLE DfsHandle, PUNICODE_STRING pRootName, LPWSTR LinkMetadataName, DWORD Level, LPBYTE *ppBuffer, PLONG pBufferSize );
DFSSTATUS ReleaseStoreApiInformationBuffer( LPBYTE pBuffer ) { delete [] pBuffer; return ERROR_SUCCESS; }
VOID StoreInitializeNameInformation( IN PDFS_NAME_INFORMATION pNameInfo, IN PUNICODE_STRING pLogicalName, UUID *pGuid, IN LPWSTR Comment ) { //
// Zero out our information buffers.
//
RtlZeroMemory( pNameInfo, sizeof(DFS_NAME_INFORMATION) ); pNameInfo->Prefix = *pLogicalName; pNameInfo->ShortPrefix = *pLogicalName; pNameInfo->State = DFS_VOLUME_STATE_OK; pNameInfo->Type = PKT_ENTRY_TYPE_DFS; pNameInfo->Timeout = DEFAULT_LINK_TIMEOUT; pNameInfo->Version = 3; if (pGuid != NULL) { pNameInfo->VolumeId = *pGuid; } DfsRtlInitUnicodeStringEx( &(pNameInfo->Comment), Comment);
return NOTHING; }
VOID StoreInitializeReplicaInformation( IN PDFS_REPLICA_LIST_INFORMATION pReplicaListInfo, IN PDFS_REPLICA_INFORMATION pReplicaInfo, IN LPWSTR ReplicaServer, IN LPWSTR ReplicaPath ) { RtlZeroMemory( pReplicaInfo, sizeof( DFS_REPLICA_INFORMATION ));
RtlZeroMemory( pReplicaListInfo, sizeof( DFS_REPLICA_LIST_INFORMATION ));
if ( (ReplicaServer != NULL) && (ReplicaPath != NULL) ) { DfsRtlInitUnicodeStringEx( &(pReplicaInfo->ServerName), ReplicaServer); DfsRtlInitUnicodeStringEx( &(pReplicaInfo->ShareName), ReplicaPath );
pReplicaInfo->ReplicaState = DFS_STORAGE_STATE_ONLINE; pReplicaInfo->ReplicaType = 2; // dfsdev: hack for backwards compat.
pReplicaListInfo->ReplicaCount = 1; pReplicaListInfo->pReplicas = pReplicaInfo; }
return NOTHING; }
VOID StoreSynchronizer();
DFSSTATUS FindNextRoot( ULONG RootNum, DfsRootFolder **ppRootFolder );
DFSSTATUS LoadServerSiteDataPerRoot(void);
//
// Currently this is a ADBlobStore specific implementation.
// This provides dfs support for domain rename.
virtual DFSSTATUS RenameLinks( IN DFS_METADATA_HANDLE RootHandle, IN PUNICODE_STRING pLinkMetadataName, IN PUNICODE_STRING OldDomainName, IN PUNICODE_STRING NewDomainName) { UNREFERENCED_PARAMETER(RootHandle); UNREFERENCED_PARAMETER(pLinkMetadataName); UNREFERENCED_PARAMETER(OldDomainName); UNREFERENCED_PARAMETER(NewDomainName); return ERROR_INVALID_PARAMETER; }
};
#endif // __DFS_STORE__
|