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.
 
 
 
 
 
 

256 lines
8.1 KiB

//+----------------------------------------------------------------------------
//
// Copyright (C) 1995, Microsoft Corporation
//
// File: dfsclustersupport.cxx
//
// Contents: DfsClusterSupport
//
// Classes:
//
//-----------------------------------------------------------------------------
#include "DfsClusterSupport.hxx"
typedef struct _DFS_CLUSTER_CONTEXT {
PUNICODE_STRING pShareName;
PUNICODE_STRING pVSName ;
} DFS_CLUSTER_CONTEXT;
DWORD
ClusterCallBackFunction(
HRESOURCE hSelf,
HRESOURCE hResource,
PVOID Context)
{
UNREFERENCED_PARAMETER( hSelf );
HKEY HKey = NULL;
HKEY HParamKey = NULL;
ULONG NameSize = MAX_PATH;
WCHAR ClusterName[MAX_PATH];
DFS_CLUSTER_CONTEXT *pContext = (DFS_CLUSTER_CONTEXT *)Context;
LPWSTR ResShareName = NULL;
UNICODE_STRING VsName;
DWORD Status = ERROR_SUCCESS;
DWORD TempStatus;
DWORD Value = 0;
HKey = GetClusterResourceKey(hResource, KEY_READ);
if (HKey == NULL)
{
Status = GetLastError();
return Status;
}
TempStatus = ClusterRegOpenKey( HKey,
L"Parameters",
KEY_READ,
&HParamKey );
ClusterRegCloseKey( HKey );
//
// Apparently there can be (small) window during which a resource may not
// have the Parameters key set. In such a case, we should keep enumerating,
// so don't return an error.
//
if (TempStatus != ERROR_SUCCESS)
{
return ERROR_SUCCESS;
}
// Find the logical share name to see if that's what we've been looking for.
ResShareName = ResUtilGetSzValue( HParamKey,
L"ShareName" );
//
// It is possible for a Share resource to be configured without the sharename parameter
// set. In such a case this function shouldn't return an error; we need to keep enumerating.
//
if (ResShareName != NULL)
{
Status = DfsRtlInitUnicodeStringEx(&VsName, ResShareName);
if(Status == ERROR_SUCCESS)
{
if (pContext->pShareName->Length == VsName.Length)
{
//
// Look to see if this is a dfs root. It is legitimate to find
// this property not set, so don't propagate the return status. We shouldn't terminate
// our enumeration just because this property doesn't exist on this resource.
//
TempStatus = ResUtilGetDwordValue(HParamKey, L"IsDfsRoot", &Value, 0);
if ((ERROR_SUCCESS == TempStatus) &&
(Value == 1))
{
if (_wcsnicmp(pContext->pShareName->Buffer,
VsName.Buffer,
VsName.Length) == 0)
{
//
// We've found what we wanted. Grab the virtual-cluster name
// and return that in a separately allocated string.
// We know for a fact that the dfs root name can't be
// longer than MAX_PATH. So we don't bother checking for
// ERROR_MORE_DATA.
//
if ((GetClusterResourceNetworkName( hResource,
ClusterName,
&NameSize )) == TRUE)
{
ASSERT(pContext->pVSName->Buffer == NULL);
Status = DfsCreateUnicodeStringFromString( pContext->pVSName,
ClusterName );
//
// Return ERROR_NO_MORE_ITEMS to ResUtilEnumResources so that
// the enumeration will get terminated, but the return status to
// GetRootClusterInformation will be SUCCESS.
//
if (Status == ERROR_SUCCESS)
{
Status = ERROR_NO_MORE_ITEMS;
}
}
else
{
// Return this error and terminate the enumeration.
Status = GetLastError();
ASSERT( Status != ERROR_MORE_DATA );
}
}
}
}
}
LocalFree( ResShareName );
}
ClusterRegCloseKey( HParamKey );
return Status;
}
#if 0
DoNotUse()
{
DWORD Status = ERROR_SUCCESS;
DWORD BufSize = ClusDocEx_DEFAULT_CB;
LPVOID pOutBuffer = NULL;
DWORD ControlCode = CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES;
pOutBuffer = new BYTE [ BufSize ];
if( pOutBuffer == NULL )
{
Status = ERROR_NOT_ENOUGH_MEMORY;
}
if (Status == ERROR_SUCCESS)
{
Status = ClusterResourceControl( hResource, // resource handle
NULL,
ControlCode,
NULL, // input buffer (not used)
0, // input buffer size (not used)
pOutBuffer, // output buffer: property list
OutBufferSize, // allocated buffer size (bytes)
pBytesReturned );
dwResult = ResUtilFindDwordProperty( lpPropList,
cbPropListSize,
lpszPropName,
lpdwPropValue );
}
}
#endif
//
// Guarantees that the pVSName is allocated upon SUCCESS.
// Caller needs to free it with DfsFreeUnicodeString.
//
DWORD
GetRootClusterInformation(
PUNICODE_STRING pShareName,
PUNICODE_STRING pVSName )
{
DWORD Status;
DFS_CLUSTER_CONTEXT Context;
(VOID)RtlInitUnicodeString( pVSName, NULL );
Context.pShareName = pShareName;
Context.pVSName = pVSName;
Status = ResUtilEnumResources(NULL,
L"File Share",
ClusterCallBackFunction,
(PVOID)&Context );
//
// ClusterCallbackFunction above returns ERROR_NO_MORE_ITEMS
// to ResUtilEnumResources to terminate the enumeration. ResUtilEnumResources
// converts that error code to SUCCESS. So, under the current behavior it isn't possible
// for us to have allocated the VSName and still get an error. The following is a feeble
// attempt to not be dependent on that unadvertised behavior.
//
if ((Status != ERROR_SUCCESS) &&
(pVSName->Buffer != NULL))
{
// If we've allocated a VSName, we have succeeded.
Status = ERROR_SUCCESS;
}
/*
// xxx Longhorn
else if (Status == ERROR_SUCCESS &&
pVSName->Buffer == NULL)
{
// Always return some error when the VSName isn't allocated.
Status = ERROR_NOT_FOUND;
}
*/
return Status;
}
DFSSTATUS
DfsClusterInit(
PBOOLEAN pIsCluster )
{
DFSSTATUS Status = ERROR_SUCCESS;
DWORD ClusterState;
*pIsCluster = FALSE;
Status = GetNodeClusterState( NULL, // local node
&ClusterState );
if (Status == ERROR_SUCCESS)
{
if ( (ClusterStateRunning == ClusterState) ||
(ClusterStateNotRunning == ClusterState) )
{
*pIsCluster = TRUE;
}
}
return Status;
}