Leaked source code of windows server 2003
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.
 
 
 
 
 
 

276 lines
7.9 KiB

//+----------------------------------------------------------------------------
//
// 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;
}