//-------------------------------------------------------------------------- // // Copyright (C) 1999, Microsoft Corporation // // File: dfsroot.hxx // //-------------------------------------------------------------------------- #ifndef __DFS_UTIL_ROOT__ #define __DFS_UTIL_ROOT__ #include "DfsLink.hxx" #include "dfsStrings.hxx" class DfsRoot : public DfsLink { private: DfsString _RootApiName; ULONG _LinkCount; ULONG _ApiCount; DfsLink *_pLinks; DfsLink *_pLastLink; DfsTarget *_pTargets; PVOID _Handle; BOOLEAN _Writeable; DFS_API_MODE _Mode; ULONG _Version; DFS_UPDATE_STATISTICS _Statistics; struct _DFS_PREFIX_TABLE *_pLinkTable; public: DfsRoot() { _pLinks = NULL; _pTargets = NULL; _pLinkTable = NULL; _pLastLink = NULL; _LinkCount = 0; _ApiCount = 0; _Mode = MODE_API; _Handle = NULL; _Writeable = FALSE; _Version = 4; RtlZeroMemory(&_Statistics, sizeof(DFS_UPDATE_STATISTICS)); } DFSSTATUS Initialize( LPWSTR NameSpace, DFS_API_MODE Mode, LPWSTR DCName ) { DFSSTATUS Status = ERROR_SUCCESS; DFS_API_MODE UseMode = MODE_API; if ((Mode == MODE_DIRECT) || (Mode == MODE_EITHER)) { Status = DfsDirectApiOpen( NameSpace, DCName, &_Handle); if (Status == ERROR_SUCCESS) { UseMode = MODE_DIRECT; } else if (Mode == MODE_EITHER) { Status = ERROR_SUCCESS; UseMode = MODE_API; } } if (Status == ERROR_SUCCESS) { _Mode = UseMode; } return Status; } VOID Close() { DFSSTATUS Status; if (_Mode == MODE_DIRECT) { Status = DfsDirectApiClose( _Handle ); } _Handle = NULL; return NOTHING; } BOOLEAN IsRootWriteable() { return _Writeable; } DFS_API_MODE GetMode() { return _Mode; } DFSSTATUS RootBlobSize( PULONG pBlobSize ) { DFSSTATUS Status = ERROR_NOT_SUPPORTED; *pBlobSize = 0; if (_Handle != NULL) { Status = DfsGetBlobSize(_Handle, pBlobSize); } return Status; } DFSSTATUS RootGetSiteBlob( PVOID *ppBuffer, PULONG pBlobSize ) { DFSSTATUS Status = ERROR_NOT_SUPPORTED; *pBlobSize = 0; if (_Handle != NULL) { Status = DfsGetSiteBlob(_Handle, ppBuffer, pBlobSize); } return Status; } DFSSTATUS RootSetSiteBlob( PVOID pBuffer, ULONG BlobSize ) { DFSSTATUS Status = ERROR_NOT_SUPPORTED; if (_Handle != NULL) { Status = DfsSetSiteBlob(_Handle, pBuffer, BlobSize); } return Status; } DFSSTATUS GetExtendedAttributes( PULONG pAttrib ) { DFSSTATUS Status = ERROR_NOT_SUPPORTED; *pAttrib = 0; if (_Handle != NULL) { Status = DfsExtendedRootAttributes(_Handle, pAttrib, NULL, FALSE); } return Status; } ULONG GetLinkCount() { return _LinkCount; } VOID SetRootWriteable() { _Writeable = TRUE; if (_Handle != NULL) { SetDirectHandleWriteable(_Handle); } } VOID ResetRootWriteable() { _Writeable = FALSE; if (_Handle != NULL) { ResetDirectHandleWriteable(_Handle); } } VOID SetRootApiName( PUNICODE_STRING pRootName) { _RootApiName.SetStringToPointer(pRootName); } DfsString * GetRootApiName() { return &_RootApiName; } DFSSTATUS UpdateMetadata() { DFSSTATUS Status = ERROR_SUCCESS; if (_Mode == MODE_DIRECT) { if (IsRootWriteable()) { Status = DfsDirectApiCommitChanges(_Handle); } else { Status = ERROR_INVALID_PARAMETER; } } return Status; } ~DfsRoot() { // handle all the objects correctly here. Since // this is only a utility, we may not currently care // of this memory leak. } DfsLink * GetFirstLink() { return _pLinks; } ULONG GetVersion() { return _Version; } DFSSTATUS FindMatchingLink( PUNICODE_STRING pLinkName, DfsLink **ppLink ) { NTSTATUS NtStatus; UNICODE_STRING Suffix; if (_pLinkTable == NULL) { return ERROR_NOT_FOUND; } NtStatus = DfsPrefixTableAcquireReadLock( _pLinkTable ); if (NtStatus == STATUS_SUCCESS) { NtStatus = DfsFindUnicodePrefixLocked( _pLinkTable, pLinkName, &Suffix, (PVOID *)ppLink, NULL ); DfsPrefixTableReleaseLock( _pLinkTable ); } return RtlNtStatusToDosError(NtStatus); } ULONG AddLinks(DfsLink *pLink ) { NTSTATUS NtStatus = STATUS_SUCCESS; DFSSTATUS Status = ERROR_SUCCESS; DfsLink *pLastLink; DfsLink *pProcessLink; if (_pLinkTable == NULL) { NtStatus = DfsInitializePrefixTable( &_pLinkTable, FALSE, NULL ); } if (NtStatus == STATUS_SUCCESS) { NtStatus = DfsPrefixTableAcquireWriteLock( _pLinkTable); if (NtStatus == STATUS_SUCCESS) { for (pProcessLink = pLink; (pProcessLink != NULL) && (NtStatus == STATUS_SUCCESS); pProcessLink = pProcessLink->GetNextLink()) { NtStatus = DfsInsertInPrefixTableLocked( _pLinkTable, pProcessLink->GetLinkNameCountedString(), (PVOID)(pProcessLink)); if (NtStatus == STATUS_SUCCESS) { pLastLink = pProcessLink; } _LinkCount++; } DfsPrefixTableReleaseLock(_pLinkTable); } } if (NtStatus == STATUS_SUCCESS) { if (_pLastLink == NULL) { _pLinks = pLink; } else { _pLastLink->AddNextLink(pLink); } _pLastLink = pLastLink; } return RtlNtStatusToDosError(NtStatus); } VOID MarkForDelete() { DfsLink *pLink; for (pLink = _pLinks; pLink != NULL; pLink = pLink->GetNextLink()) { pLink->MarkForDelete(); } } VOID MarkForAddition() { DfsLink *pLink; for (pLink = _pLinks; pLink != NULL; pLink = pLink->GetNextLink()) { pLink->MarkForAddition(); } } PDFS_UPDATE_STATISTICS GetRootStatistics() { return &_Statistics; } VOID ProgressBar( ULONG Link, ULONG ApiCount) { if ((Link > 0) && ((Link % 500) == 0)) { ShowInformation((L".")); } else if ((ApiCount > 0) && ((ApiCount % 20) == 0)) { ShowInformation((L".")); } } DFSSTATUS ApplyApiChanges(LPWSTR RootName, DFS_API_MODE Mode, ULONG Version) { DFSSTATUS Status = ERROR_SUCCESS; DfsLink *pLink; ULONG Link; for (Link = 0, pLink = _pLinks; ((pLink != NULL) && (Status == ERROR_SUCCESS)); Link++, pLink = pLink->GetNextLink()) { BOOLEAN RetryOnce = FALSE; Retry: Status = pLink->ApplyApiChanges( RootName, Mode, Version, &_Statistics); if (Status == 2668) { if (RetryOnce == FALSE) { RetryOnce = TRUE; Version = 3; goto Retry; } } ProgressBar(Link, _Statistics.ApiCount); } return Status; } }; #endif // __DFS_UTIL_ROOT__