|
|
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <shellapi.h>
#include "dfsadmin.h"
DFSSTATUS AddRootToPrefixTable( struct _DFS_PREFIX_TABLE **ppTable, PROOT_DEF pRoot );
PLINK_DEF CreateNewLinkEntry( LPWSTR LinkName );
PTARGET_DEF CreateNewTargetEntry( LPWSTR ServerName, LPWSTR ShareName, ULONG State );
PLINK_DEF GetLinkEntry( struct _DFS_PREFIX_TABLE *pTable, LPWSTR NameString );
PTARGET_DEF GetTargetEntry( PLINK_DEF pLink, LPWSTR ServerName, LPWSTR ShareName );
PLINK_DEF MergeLinkInfo( PDFS_INFO_4 pBuf, struct _DFS_PREFIX_TABLE *pPrefixTable );
DFSSTATUS DfsMerge ( PROOT_DEF pRoot, LPWSTR NameSpace ) { LPBYTE pBuffer = NULL; DWORD ResumeHandle = 0; DWORD EntriesRead = 0; DWORD PrefMaxLen = -1; DWORD Level = 4; DFSSTATUS Status; NTSTATUS NtStatus; PDFS_INFO_4 pCurrentBuffer; DWORD i;
PLINK_DEF pGrownLinks = NULL, pLink; struct _DFS_PREFIX_TABLE *pPrefixTable;
Status = AddRootToPrefixTable( &pPrefixTable, pRoot ); if (Status != ERROR_SUCCESS) { printf("DfsVerify: create prefix table failed %x\n", Status); return Status; }
if (DebugOut) { fwprintf(DebugOut, L"Contacting %wS for enumeration \n", NameSpace); }
Status = NetDfsEnum( NameSpace, Level, PrefMaxLen, &pBuffer, &EntriesRead, &ResumeHandle);
if (DebugOut) { fwprintf(DebugOut, L"Enumeration for %wS is complete %d entries\n", NameSpace, EntriesRead); } if (Status != ERROR_SUCCESS) { printf("Export: cannot enum %wS: error %x\n", NameSpace, Status); return Status; }
pCurrentBuffer = (PDFS_INFO_4)pBuffer;
NtStatus = DfsPrefixTableAcquireWriteLock( pPrefixTable); if (NtStatus != STATUS_SUCCESS) { printf("Unable to take prefix table lock, %x\n", NtStatus); return NtStatus; }
for (i = 0; i < EntriesRead; i++) { pLink = MergeLinkInfo( pCurrentBuffer, pPrefixTable); if (pLink != NULL) { if (pGrownLinks == NULL) { pGrownLinks = pRoot->pLinks; } NEXT_LINK_OBJECT(pLink) = pGrownLinks; pGrownLinks = pLink; }
pCurrentBuffer++; } DfsPrefixTableReleaseLock(pPrefixTable); if (pGrownLinks != NULL) { pRoot->pLinks = pGrownLinks; } return Status; }
PTARGET_DEF CreateNewTargetEntry( LPWSTR ServerName, LPWSTR ShareName, ULONG State ) { DFSSTATUS Status; UNICODE_STRING TargetName; PTARGET_DEF pTarget = NULL;
Status = DfsCreateUnicodePathString( &TargetName, 2, // unc path: 2 leading sep.
ServerName, ShareName ); if (Status == ERROR_SUCCESS) { pTarget = CreateTargetDef(IN_NAMESPACE, TargetName.Buffer, State);
DfsFreeUnicodeString(&TargetName); }
return pTarget; }
PLINK_DEF CreateNewLinkEntry( LPWSTR LinkName ) { PLINK_DEF pLink;
pLink = CreateLinkDef(IN_NAMESPACE, LinkName, NULL);
return pLink; }
VOID UpdateLinkEntry( PLINK_DEF pLink, ULONG State, ULONG Timeout, LPWSTR Comment ) { if (State != 0) { AddObjectStateValue(&pLink->BaseObject, State); } if (Timeout != 0) { AddObjectTimeoutValue(&pLink->BaseObject, Timeout); } if (Comment != NULL) { AddObjectComment(&pLink->BaseObject, Comment); } }
DFSSTATUS AddRootToPrefixTable( struct _DFS_PREFIX_TABLE **ppTable, PROOT_DEF pRoot ) { struct _DFS_PREFIX_TABLE *pTable = NULL; NTSTATUS NtStatus; PLINK_DEF pLink; UNICODE_STRING LinkName; ULONG Links = 0;
NtStatus = DfsInitializePrefixTable( &pTable, FALSE, NULL );
if (NtStatus != STATUS_SUCCESS) { return NtStatus; }
NtStatus = DfsPrefixTableAcquireWriteLock( pTable); if (NtStatus != STATUS_SUCCESS) { printf("Unable to take prefix table lock, %x\n", NtStatus); return NtStatus; } for (pLink = pRoot->pLinks; pLink != NULL; pLink = NEXT_LINK_OBJECT(pLink)) { RtlInitUnicodeString(&LinkName, pLink->LinkObjectName); NtStatus = DfsInsertInPrefixTableLocked( pTable, &LinkName, (PVOID)(pLink) ); if (NtStatus == STATUS_SUCCESS) { pLink->LinkObjectFlags |= IN_TABLE; } else { printf(" AddRootToPrefixTable: Link %wZ, Status 0x%x\n, Links %d", &LinkName, NtStatus, Links);
break; } Links++; } DfsPrefixTableReleaseLock(pTable); *ppTable = pTable; return NtStatus; }
DFSSTATUS DeletePrefixTable( struct _DFS_PREFIX_TABLE *pTable, PROOT_DEF pRoot ) { PLINK_DEF pLink; NTSTATUS NtStatus; UNICODE_STRING LinkName;
NtStatus = DfsPrefixTableAcquireWriteLock( pTable); if (NtStatus != STATUS_SUCCESS) { printf("Unable to take prefix table lock, %x\n", NtStatus); return NtStatus; } for (pLink = pRoot->pLinks; pLink != NULL; pLink = NEXT_LINK_OBJECT(pLink)) { if ((pLink->LinkObjectFlags & IN_TABLE) == TRUE) { RtlInitUnicodeString(&LinkName, pLink->LinkObjectName); NtStatus = DfsRemoveFromPrefixTableLocked( pTable, &LinkName, (PVOID)(pLink) ); if (NtStatus == STATUS_SUCCESS) { pLink->LinkObjectFlags &= ~IN_TABLE; } else { break; } } } DfsPrefixTableReleaseLock(pTable); DfsDereferencePrefixTable( pTable );
return NtStatus;
}
PLINK_DEF GetLinkEntry( struct _DFS_PREFIX_TABLE *pTable, LPWSTR NameString ) { NTSTATUS Status; UNICODE_STRING Name; UNICODE_STRING Suffix; PLINK_DEF pLink;
RtlInitUnicodeString( &Name, NameString ); Status = DfsFindUnicodePrefixLocked( pTable, &Name, &Suffix, &pLink, NULL );
if (Status == STATUS_SUCCESS) { return pLink; } if (Status != STATUS_OBJECT_PATH_NOT_FOUND) { printf("GetLinkEntry: unexpected status %x\n", Status); } return NULL; }
PTARGET_DEF GetTargetEntry( PLINK_DEF pLink, LPWSTR ServerName, LPWSTR ShareName ) { PTARGET_DEF pTarget, pReturn = NULL; UNICODE_STRING TargetName; DFSSTATUS Status;
Status = DfsCreateUnicodePathString( &TargetName, 2, // unc path: 2 leading sep.
ServerName, ShareName ); if (Status != ERROR_SUCCESS) { printf("GetTargetEntry: failed to create string\n"); return NULL; }
for (pTarget = pLink->LinkObjectTargets; pTarget != NULL; pTarget = pTarget->NextTarget) { if (_wcsicmp(TargetName.Buffer, pTarget->Name) == 0) { pReturn = pTarget; break;
} }
DfsFreeUnicodeString(&TargetName);
return pReturn; }
PLINK_DEF MergeLinkInfo( PDFS_INFO_4 pBuf, struct _DFS_PREFIX_TABLE *pPrefixTable ) { PLINK_DEF pLink, pReturn = NULL; DWORD i; PDFS_STORAGE_INFO pStorage; UNICODE_STRING LinkName, ServerName, ShareName, Remains; DFSSTATUS Status; PTARGET_DEF pTargetList = NULL, pTarget;
RtlInitUnicodeString( &LinkName, pBuf->EntryPath);
if (DebugOut) { fwprintf(DebugOut, L"Link %ws in namespace, with %d targets.Merging\n",
pBuf->EntryPath, pBuf->NumberOfStorages);
} Status = DfsGetPathComponents(&LinkName, &ServerName, &ShareName, &Remains);
if (Remains.Length == 0) { return NULL; } if ((pLink = GetLinkEntry(pPrefixTable, Remains.Buffer)) == NULL) { pLink = CreateNewLinkEntry(Remains.Buffer); UpdateLinkEntry( pLink, pBuf->State, pBuf->Timeout, pBuf->Comment); pReturn = pLink; }
SetObjectInNameSpace(pLink); for(i = 0, pStorage = pBuf->Storage; i < pBuf->NumberOfStorages; i++, pStorage = pBuf->Storage+i) {
if ((pTarget = GetTargetEntry(pLink, pStorage->ServerName, pStorage->ShareName)) == NULL) { pTarget = CreateNewTargetEntry(pStorage->ServerName, pStorage->ShareName, pStorage->State); if (pTargetList == NULL) { pTargetList = pLink->LinkObjectTargets; } if (pTarget != NULL) { pTarget->NextTarget = pTargetList; } pTargetList = pTarget; } SetInNameSpace(pTarget); } if (pTargetList != NULL) { pLink->LinkObjectTargets = pTargetList; }
return pReturn; }
|