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.
260 lines
6.7 KiB
260 lines
6.7 KiB
#include <stdio.h>
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <shellapi.h>
|
|
#include <winldap.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <dfslink.hxx>
|
|
#include <dfsroot.hxx>
|
|
#include <dfstarget.hxx>
|
|
|
|
|
|
#include "dfsutil.hxx"
|
|
#include "dfspathname.hxx"
|
|
|
|
#define INFO4(x, y) (((PDFS_INFO_4)x)->y)
|
|
#define INFO3(x, y) (((PDFS_INFO_3)x)->y)
|
|
#define DFS_INFO(x, y, Level) ((Level == 4) ? INFO4(x, y) : INFO3(x, y))
|
|
#define SIZEOF_DFS_INFO(Level) ((Level == 4) ? sizeof(DFS_INFO_4) : sizeof(DFS_INFO_3))
|
|
|
|
DFSSTATUS
|
|
DfsUpdateLinkFromBuffer(
|
|
PUNICODE_STRING pName,
|
|
PVOID pBuf,
|
|
ULONG Level,
|
|
BOOLEAN SiteAware,
|
|
DfsLink *pLink )
|
|
{
|
|
DWORD i;
|
|
PDFS_STORAGE_INFO pStorage;
|
|
DFSSTATUS Status;
|
|
|
|
DebugInformation((L"Link %ws in namespace, with %d targets\n",
|
|
DFS_INFO(pBuf, EntryPath, Level),
|
|
DFS_INFO(pBuf, NumberOfStorages, Level)));
|
|
|
|
Status = pLink->SetLinkName(pName);
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = pLink->SetLinkComment(DFS_INFO(pBuf, Comment, Level));
|
|
}
|
|
pLink->SetLinkState(DFS_INFO(pBuf, State, Level));
|
|
if (Level == 4)
|
|
{
|
|
pLink->SetLinkTimeout(INFO4(pBuf, Timeout));
|
|
}
|
|
else
|
|
{
|
|
pLink->SetLinkTimeout(300);
|
|
}
|
|
|
|
|
|
for(i = 0, pStorage = DFS_INFO(pBuf, Storage, Level);
|
|
i < DFS_INFO(pBuf, NumberOfStorages, Level);
|
|
i++, pStorage = DFS_INFO(pBuf, Storage, Level) + i)
|
|
{
|
|
|
|
DfsTarget *pTarget;
|
|
|
|
pTarget = new DfsTarget;
|
|
if (pTarget == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
|
|
Status = pTarget->SetTargetServer(pStorage->ServerName,
|
|
SiteAware);
|
|
}
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = pTarget->SetTargetFolder(pStorage->ShareName);
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
pTarget->SetTargetState(pStorage->State);
|
|
|
|
pLink->AddTarget(pTarget);
|
|
}
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
DFSSTATUS
|
|
DfsBuildNameSpaceInformation (
|
|
DfsPathName *pNameSpace,
|
|
LPWSTR UseDC,
|
|
DFS_API_MODE Mode,
|
|
BOOLEAN SiteAware,
|
|
DfsRoot **ppRoot )
|
|
{
|
|
LPBYTE pBuffer = NULL;
|
|
DWORD ResumeHandle = 0;
|
|
DWORD EntriesRead = 0;
|
|
DWORD PrefMaxLen = -1;
|
|
DWORD Level = 4;
|
|
DFSSTATUS Status = ERROR_SUCCESS;
|
|
PVOID pCurrentBuffer = NULL;
|
|
DWORD i = 0;
|
|
|
|
LPWSTR UseName = pNameSpace->GetPathString();
|
|
|
|
|
|
DfsRoot *pRoot = NULL;
|
|
DfsLink *pLink = NULL, *pStartLink = NULL, *pLastLink = NULL;
|
|
ULONG LinkCount = 0;
|
|
|
|
pRoot = new DfsRoot;
|
|
if (pRoot == NULL)
|
|
{
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
Status = pRoot->Initialize( UseName, Mode, UseDC );
|
|
if (Status != ERROR_SUCCESS)
|
|
{
|
|
delete pRoot;
|
|
return Status;
|
|
}
|
|
|
|
DebugInformation((L"Contacting %wS for enumeration \n", UseName));
|
|
|
|
|
|
Status = DfsApiEnumerate( pRoot->GetMode(),
|
|
UseName,
|
|
Level,
|
|
PrefMaxLen,
|
|
&pBuffer,
|
|
&EntriesRead,
|
|
&ResumeHandle);
|
|
|
|
//
|
|
// if this failed, retry at level 3.
|
|
//
|
|
if ((Status != ERROR_SUCCESS) &&
|
|
(Status != ERROR_NO_MORE_ITEMS))
|
|
{
|
|
Level--;
|
|
|
|
Status = DfsApiEnumerate( pRoot->GetMode(),
|
|
UseName,
|
|
Level,
|
|
PrefMaxLen,
|
|
&pBuffer,
|
|
&EntriesRead,
|
|
&ResumeHandle);
|
|
|
|
}
|
|
|
|
DebugInformation((L"Enumeration for %wS is complete %d entries, status 0x%x\n",
|
|
UseName,
|
|
EntriesRead,
|
|
Status));
|
|
|
|
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
pCurrentBuffer = (PVOID)pBuffer;
|
|
|
|
for (i = 0;
|
|
((i < EntriesRead) && (Status == ERROR_SUCCESS));
|
|
i++)
|
|
{
|
|
UNICODE_STRING LinkName, ServerName, ShareName, Remains;
|
|
|
|
RtlInitUnicodeString( &LinkName,
|
|
DFS_INFO(pCurrentBuffer, EntryPath, Level));
|
|
|
|
Status = DfsGetPathComponents(&LinkName,
|
|
&ServerName,
|
|
&ShareName,
|
|
&Remains);
|
|
|
|
if (Remains.Length == 0)
|
|
{
|
|
if (ShareName.Length != 0)
|
|
{
|
|
Status = DfsUpdateLinkFromBuffer( &LinkName,
|
|
pCurrentBuffer,
|
|
Level,
|
|
SiteAware,
|
|
pRoot );
|
|
}
|
|
else
|
|
{
|
|
Status = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pLink = new DfsLink;
|
|
if (pLink == NULL)
|
|
{
|
|
Status = ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
Status = DfsUpdateLinkFromBuffer( &Remains,
|
|
pCurrentBuffer,
|
|
Level,
|
|
SiteAware,
|
|
pLink );
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
LinkCount++;
|
|
|
|
if (pStartLink == NULL)
|
|
{
|
|
pStartLink = pLink;
|
|
}
|
|
else
|
|
{
|
|
pLastLink->AddNextLink(pLink);
|
|
}
|
|
pLastLink = pLink;
|
|
}
|
|
}
|
|
pCurrentBuffer = (PVOID)((ULONG_PTR)pCurrentBuffer + SIZEOF_DFS_INFO(Level));
|
|
}
|
|
}
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
pRoot->AddLinks(pStartLink);
|
|
}
|
|
|
|
|
|
if (Status == ERROR_SUCCESS)
|
|
{
|
|
*ppRoot = pRoot;
|
|
}
|
|
else
|
|
{
|
|
if(pRoot)
|
|
{
|
|
delete pRoot;
|
|
}
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|