|
|
//+----------------------------------------------------------------------------
//
// Copyright (C) 2000, Microsoft Corporation
//
// File: DfsReferral.cxx
//
// Contents: This file contains the functionality to generate a referral
//
//
// History: Jan 16 2001, Authors: RohanP/UdayH
//
//-----------------------------------------------------------------------------
#include "DfsReferral.hxx"
#include "Align.h"
#include "dfstrusteddomain.hxx"
#include "dfsadsiapi.hxx"
#include "DfsDomainInformation.hxx"
#include "DomainControllerSupport.hxx"
#include "dfsreferral.tmh" // logging
DFSSTATUS DfsGetCompatRootFolder( PUNICODE_STRING pName, DfsRootFolder **ppNewRoot );
DFSSTATUS DfsLookupCompatFolder( DfsRootFolder *pRoot, PUNICODE_STRING pName, PUNICODE_STRING pRemainingName, DfsFolder **ppFolder ) { DFSSTATUS Status = ERROR_SUCCESS;
//
// if the rest of the name is empty, we need the root folder
// itself, so acquire a reference on the root folder and return it
// as a folder.
//
if (pName->Length == 0) { *ppFolder = (DfsFolder *)pRoot; pRoot->AcquireReference(); } else { Status = pRoot->LookupFolderByLogicalName( pName, pRemainingName, ppFolder ); }
return Status; }
//+-------------------------------------------------------------------------
//
// Function: DfsGetRootFolder
//
// Arguments: pName - The logical name
// pRemainingName - the name beyond the root
// ppRoot - the Dfs root found.
//
// Returns: ERROR_SUCCESS
// Error code otherwise
//
//
// Description: This routine runs through all the stores and looks up
// a root with the matching name context and share name.
// If multiple stores have the same share, the highest
// priority store wins (the store registered first is the
// highest priority store)
// A referenced root is returned, and the caller is
// responsible for releasing the reference.
//
//--------------------------------------------------------------------------
DFSSTATUS DfsGetCompatReferralData( PUNICODE_STRING pName, PUNICODE_STRING pRemainingName, DfsFolderReferralData **ppReferralData, PBOOLEAN pCacheHit ) { DfsRootFolder *pNewRoot = NULL; DfsFolder *pFolder = NULL; DFSSTATUS Status = ERROR_SUCCESS; UNICODE_STRING ServerName, ShareName, Rest;
//
// Break up the path into name components.
//
Status = DfsGetPathComponents( pName, &ServerName, &ShareName, &Rest );
//
// Now find the Root folder for the name, and then lookup the link
// folder using the rest of the name.
//
if (Status == ERROR_SUCCESS) { Status = DfsCheckRootADObjectExistence( NULL, &ShareName, NULL );
}
if (Status == ERROR_SUCCESS) { Status = DfsGetCompatRootFolder( &ShareName, &pNewRoot ); if (Status == ERROR_SUCCESS) { Status = DfsLookupCompatFolder( pNewRoot, &Rest, pRemainingName, &pFolder ); //
//Generate the referral data so we can create a referral
// to return to the client.
//
if (Status == ERROR_SUCCESS) { Status = pFolder->GetReferralData( ppReferralData, pCacheHit, FALSE );
pFolder->ReleaseReference(); } //
// We had created this root folder temporarily, just so we
// can get the referral information. we dont want this root
// to live forever.
// So remove all the link folders in the root, being careful
// that we dont delete any directories if this machine is hosting
// this root itself.
//
// We then release the reference on the root to delete it.
//
pNewRoot->RemoveAllLinkFolders(FALSE); pNewRoot->ReleaseReference();
if (Status == ERROR_SUCCESS) { (*ppReferralData)->SetTime(); (*ppReferralData)->DetachFromFolder(); } } }
return Status; }
DFSSTATUS DfsGetRootReferralData( PUNICODE_STRING pShareName, PUNICODE_STRING pRemainingName, PUNICODE_STRING pRest, DfsFolderReferralData **ppReferralData, PBOOLEAN pCacheHit ) { DfsRootFolder *pNewRoot = NULL; DfsFolder *pFolder = NULL; DFSSTATUS Status = ERROR_SUCCESS;
//
// Now find the Root folder for the name, and then lookup the link
// folder using the rest of the name.
//
Status = DfsGetCompatRootFolder( pShareName, &pNewRoot ); if (Status == ERROR_SUCCESS) { Status = DfsLookupCompatFolder( pNewRoot, pRest, pRemainingName, &pFolder ); //
//Generate the referral data so we can create a referral
// to return to the client.
//
if (Status == ERROR_SUCCESS) { Status = pFolder->GetReferralData( ppReferralData, pCacheHit, FALSE );
pFolder->ReleaseReference(); }
//
// We had created this root folder temporarily, just so we
// can get the referral information. we dont want this root
// to live forever.
// So remove all the link folders in the root, being careful
// that we dont delete any directories if this machine is hosting
// this root itself.
//
// We then release the reference on the root to delete it.
//
pNewRoot->RemoveAllLinkFolders(FALSE); pNewRoot->ReleaseReference();
if (Status == ERROR_SUCCESS) { (*ppReferralData)->SetTime(); (*ppReferralData)->DetachFromFolder(); } }
return Status; }
DFSSTATUS DfsGetRootReferralDataEx( PUNICODE_STRING pName, PUNICODE_STRING pRemainingName, DfsFolderReferralData **ppReferralData, PBOOLEAN pCacheHit) {
DFSSTATUS Status = ERROR_SUCCESS; UNICODE_STRING ServerName, ShareName, Rest;
do {
//
// Break up the path into name components.
//
Status = DfsGetPathComponents( pName, &ServerName, &ShareName, &Rest ); if(Status != ERROR_SUCCESS) { break; }
Status = DfsGetRootReferralData(&ShareName, pRemainingName, &Rest, ppReferralData, pCacheHit );
if(Status != ERROR_SUCCESS) { break; }
}while (0);
return Status; }
|