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