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.
412 lines
9.2 KiB
412 lines
9.2 KiB
//--------------------------------------------------------------------------
|
|
//
|
|
// 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__
|