|
|
/*++
Copyright (c) 1992-2001 Microsoft Corporation
Module Name:
dfsmetaloc.c
Abstract:
DFS metadata locating routines.
Author:
Uday Hegde (udayh) 10-May-2001
Revision History:
--*/ #define UNICODE 1
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <shellapi.h>
#include <lm.h>
#define DFS_REGISTRY_CHILD_NAME_SIZE_MAX 4096
LPWSTR DfsRootShareValueName = L"RootShare";
LPWSTR OldRegistryString = L"SOFTWARE\\Microsoft\\DfsHost\\volumes"; LPWSTR NewRegistryString = L"SOFTWARE\\Microsoft\\Dfs\\Roots\\Standalone"; LPWSTR DfsOldStandaloneChild = L"domainroot";
DWORD CheckForShareNameMatch( HKEY DfsKey, LPWSTR ChildName, LPWSTR RootName, PBOOLEAN pMatch) { DWORD Status; HKEY DfsRootKey;
LPWSTR DfsRootShare = NULL; ULONG DataSize, DataType, RootShareLength; *pMatch = FALSE;
Status = RegOpenKeyEx( DfsKey, ChildName, 0, KEY_READ, &DfsRootKey );
if (Status == ERROR_SUCCESS) { Status = RegQueryInfoKey( DfsRootKey, // Key
NULL, // Class string
NULL, // Size of class string
NULL, // Reserved
NULL, // # of subkeys
NULL, // max size of subkey name
NULL, // max size of class name
NULL, // # of values
NULL, // max size of value name
&DataSize, // max size of value data,
NULL, // security descriptor
NULL ); // Last write time
if (Status == ERROR_SUCCESS) { RootShareLength = DataSize; DfsRootShare = (LPWSTR) malloc(DataSize); if (DfsRootShare == NULL) { Status = ERROR_NOT_ENOUGH_MEMORY; } else { Status = RegQueryValueEx( DfsRootKey, DfsRootShareValueName, NULL, &DataType, (LPBYTE)DfsRootShare, &RootShareLength);
if (Status == ERROR_SUCCESS) { if (_wcsicmp(DfsRootShare, RootName) == 0) { *pMatch = TRUE; } } free(DfsRootShare); } } RegCloseKey( DfsRootKey ); }
//
// we may be dealing with a new key here: which is just being setup.
// return success if any of the above returned error not found.
//
if ((Status == ERROR_NOT_FOUND) || (Status == ERROR_FILE_NOT_FOUND)) { Status = ERROR_SUCCESS; }
return Status; }
DWORD DfsGetMatchingChild( HKEY DfsKey, LPWSTR RootName, LPWSTR FoundChild, PBOOLEAN pMatch ) { DWORD Status; ULONG ChildNum = 0;
do { //
// For each child, get the child name.
//
DWORD ChildNameLen = DFS_REGISTRY_CHILD_NAME_SIZE_MAX; WCHAR ChildName[DFS_REGISTRY_CHILD_NAME_SIZE_MAX];
//
// Now enumerate the children, starting from the first child.
//
Status = RegEnumKeyEx( DfsKey, ChildNum, ChildName, &ChildNameLen, NULL, NULL, NULL, NULL );
ChildNum++;
if ( Status == ERROR_SUCCESS ) {
Status = CheckForShareNameMatch( DfsKey, ChildName, RootName, pMatch ); if ((Status == ERROR_SUCCESS) && (*pMatch == TRUE)) { wcscpy(FoundChild, ChildName); break; } } } while (Status == ERROR_SUCCESS);
//
// If we ran out of children, then return success code.
//
if (Status == ERROR_NO_MORE_ITEMS) { Status = ERROR_SUCCESS; }
return Status; }
DWORD CreateShareNameToReturn ( LPWSTR Child1, LPWSTR Child2, LPWSTR *pReturnName ) { DWORD Status; ULONG LengthNeeded = 0; PVOID BufferToReturn;
if (Child1 != NULL) { LengthNeeded += sizeof(WCHAR); LengthNeeded += (DWORD) (wcslen(Child1) * sizeof(WCHAR)); } if (Child2 != NULL) { LengthNeeded += sizeof(WCHAR); LengthNeeded += (DWORD) (wcslen(Child2) * sizeof(WCHAR)); } LengthNeeded += sizeof(WCHAR);
Status = NetApiBufferAllocate( LengthNeeded, &BufferToReturn );
if (Status == ERROR_SUCCESS) { if (Child1 != NULL) { wcscpy(BufferToReturn, Child1); } if (Child2 != NULL) { wcscat(BufferToReturn, L"\\"); wcscat(BufferToReturn, Child2); } *pReturnName = BufferToReturn; }
return Status; }
DWORD DfsCheckNewStandaloneRoots( LPWSTR RootName, LPWSTR *pMetadataNameLocation ) { BOOLEAN Found; HKEY DfsKey; WCHAR ChildName[MAX_PATH]; DWORD Status;
Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, NewRegistryString, 0, KEY_READ, &DfsKey ); if (Status == ERROR_SUCCESS) { Status = DfsGetMatchingChild( DfsKey, RootName, ChildName, &Found );
if (Status == ERROR_SUCCESS) { if (Found) { Status = CreateShareNameToReturn(NewRegistryString, ChildName, pMetadataNameLocation ); } else { Status = ERROR_NOT_FOUND; } } RegCloseKey( DfsKey ); }
return Status; }
DWORD DfsCheckOldStandaloneRoot( LPWSTR RootName, LPWSTR *pMetadataNameLocation ) { BOOLEAN Found; HKEY DfsKey; DWORD Status;
Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE, NewRegistryString, 0, KEY_READ, &DfsKey ); if (Status == ERROR_SUCCESS) { Status = CheckForShareNameMatch( DfsKey, DfsOldStandaloneChild, RootName, &Found );
if (Status == ERROR_SUCCESS) { if (Found) { Status = CreateShareNameToReturn( OldRegistryString, DfsOldStandaloneChild, pMetadataNameLocation ); } else { Status = ERROR_NOT_FOUND; } } RegCloseKey( DfsKey ); } return Status; }
DWORD GetDfsRootMetadataLocation( LPWSTR RootName, LPWSTR *pMetadataNameLocation ) { DWORD Status;
Status = DfsCheckNewStandaloneRoots( RootName, pMetadataNameLocation );
if (Status == ERROR_NOT_FOUND) { Status = DfsCheckOldStandaloneRoot( RootName, pMetadataNameLocation ); } return Status; }
VOID ReleaseDfsRootMetadataLocation( LPWSTR Buffer ) { NetApiBufferFree(Buffer); }
#if 0
_cdecl main( int argc, char *argv[]) { LPWSTR CommandLine; LPWSTR *argvw; int argcw,i; LPWSTR out; DWORD Status;
//
// Get the command line in Unicode
//
CommandLine = GetCommandLine();
argvw = CommandLineToArgvW(CommandLine, &argcw); printf("Argvw is %wS\n", argvw[1]);
Status = GetDfsRootMetadataLocation( argvw[1], &out );
printf("Status is %x out is %ws\n", Status, out); if (Status == ERROR_SUCCESS) { ReleaseDfsRootMetadataLocation(out); } exit(0); } #endif
|