#include #include #include #include #include #include #include #include #include #include #include #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; }