2025-04-27 07:49:33 -04:00

461 lines
12 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//+----------------------------------------------------------------------------
//
// Copyright (C) 1996, Microsoft Corporation
//
// File: cstorage.cxx
//
// Contents: Implementation of CStorageDirectory class. This implementation
// provides a basic mechanism to create, delete, and lookup
// Prefix -> Storage Object Name mappings.
//
// Classes: CStorageDirectory
//
// Functions:
//
// History: Sept 18, 1996 Milans Created
//
//-----------------------------------------------------------------------------
#include "headers.hxx"
#pragma hdrstop
#include "dfsmsrv.h"
//+----------------------------------------------------------------------------
//
// Function: CStorageDirectory::CStorageDirectory
//
// Synopsis: Constructor for CStorageDirectory
//
//-----------------------------------------------------------------------------
CStorageDirectory::CStorageDirectory(
DWORD *pdwErr)
{
IDfsVolInlineDebOut((
DEB_TRACE, "CStorageDirectory::+CStorageDirectory(0x%x)\n",
this));
#if DBG
if (DfsSvcVerbose)
DbgPrint("CStorageDirectory::CStorageDirectory()\n");
#endif
if (!DfsInitializeUnicodePrefix(&_PrefixTable)) {
*pdwErr = ERROR_OUTOFMEMORY;
} else {
*pdwErr = ERROR_SUCCESS;
}
_cEntries = 0;
}
//+----------------------------------------------------------------------------
//
// Function: CStorageDirectory::~CStorageDirectory
//
// Synopsis: Destructor for CStorageDirectory
//
//-----------------------------------------------------------------------------
CStorageDirectory::~CStorageDirectory()
{
PNAME_PAGE pNamePage;
PNAME_PAGE pNextPage;
LPWSTR wszObject, wszPrefix;
UNICODE_STRING TempString;
BOOLEAN Restart, Success;
IDfsVolInlineDebOut((
DEB_TRACE, "CStorageDirectory::~CStorageDirectory(0x%x)\n",
this));
#if DBG
if (DfsSvcVerbose)
DbgPrint("CStorageDirectory::~CStorageDirectory()\n");
#endif
wszObject = (LPWSTR) DfsNextUnicodePrefix( &_PrefixTable, TRUE );
while (wszObject != NULL) {
#if DBG
if (DfsSvcVerbose)
DbgPrint("CStorageDirectory::~CStorageDirectory:deleting object@0x%x\n", wszObject);
#endif
wszPrefix = wszObject + wcslen(wszObject) + 1;
RtlInitUnicodeString(&TempString, wszPrefix );
Success = DfsRemoveUnicodePrefix( &_PrefixTable, &TempString );
if (Success == TRUE) {
delete [] wszObject;
Restart = TRUE;
}
else {
Restart = FALSE;
}
wszObject = (LPWSTR) DfsNextUnicodePrefix( &_PrefixTable, Restart );
}
for (pNamePage = _PrefixTable.NamePageList.pFirstPage;
pNamePage;
pNamePage = pNextPage
) {
pNextPage = pNamePage->pNextPage;
#if DBG
if (DfsSvcVerbose)
DbgPrint("CStorageDirectory::~CStorageDirectory: Releasing NamePage@0x%x\n", pNamePage);
#endif
free(pNamePage);
}
}
//+----------------------------------------------------------------------------
//
// Function: CStorageDirectory::GetObjectForPrefix
//
// Synopsis: Given a prefix, returns the name of the Dfs Manager volume
// object which describes the volume.
//
// Arguments: [wszPrefix] -- The prefix (ie, EntryPath) to look up.
// [fExactMatchRequired] -- wszPrefix must match exactly with
// the EntryPath property of the returned volume object.
// [pwszObject] -- Name of the volume object that describes the
// EntryPath. Memory for this is allocated via new
// [pcbMatchedLength] -- On successful return, contains the
// number of BYTES of wszPrefix that matched an entry
// in the directory.
//
// Returns: [S_OK] -- Successfully found name of volume object.
//
// [DFS_E_NO_SUCH_VOLUME] -- Unable to find volume for given
// wszPrefix.
//
// [ERROR_OUTOFMEMORY] -- Unable to allocate memory for the object
// name.
//
//-----------------------------------------------------------------------------
DWORD
CStorageDirectory::GetObjectForPrefix(
LPCWSTR wszPrefix,
const BOOLEAN fExactMatchRequired,
LPWSTR *pwszObject,
LPDWORD pcbMatchedLength)
{
UNICODE_STRING ustrPrefix, ustrRem;
LPWSTR wszObject;
DWORD dwErr;
*pwszObject = NULL;
RtlInitUnicodeString( &ustrPrefix, wszPrefix );
ustrRem.Length = ustrRem.MaximumLength = 0;
ustrRem.Buffer = NULL;
wszObject = (LPWSTR) DfsFindUnicodePrefix(
&_PrefixTable,
&ustrPrefix,
&ustrRem);
if (wszObject == NULL || (fExactMatchRequired && ustrRem.Length != 0)) {
dwErr = NERR_DfsNoSuchVolume;
} else {
*pwszObject = new WCHAR [wcslen(wszObject) + 1];
if (*pwszObject != NULL) {
wcscpy(*pwszObject, wszObject);
*pcbMatchedLength = ustrPrefix.Length - ustrRem.Length;
dwErr = ERROR_SUCCESS;
} else {
dwErr = ERROR_OUTOFMEMORY;
}
}
return( dwErr );
}
//+----------------------------------------------------------------------------
//
// Function: CStorageDirectory::GetObjectByIndex
//
// Synopsis: Returns the i'th object name in the directory.
//
// Arguments: [iStart] -- The 0 based index of the object name to return.
// If this value is ~0, the "next" object name is
// returned.
//
// [pwszObject] -- On successful return, a pointer to the
// buffer containing the object name is returned here.
// Memory is allocated via new.
//
// Returns: [ERROR_SUCCESS] -- Successfully returning ith object.
//
// [ERROR_NO_MORE_ITEMS] -- No more entries
//
// [ERROR_OUTOFMEMORY] -- Unable to allocate memory.
//
//-----------------------------------------------------------------------------
DWORD
CStorageDirectory::GetObjectByIndex(
DWORD iStart,
LPWSTR *pwszObject)
{
DWORD dwErr;
DWORD i;
LPWSTR wszNextObject;
//
// position ourselves
//
if (iStart == ~0) {
wszNextObject = (LPWSTR) DfsNextUnicodePrefix(&_PrefixTable, FALSE);
} else {
wszNextObject = (LPWSTR) DfsNextUnicodePrefix(&_PrefixTable, TRUE);
for (i = 0; (i < iStart) && (wszNextObject != NULL); i++) {
wszNextObject = (LPWSTR) DfsNextUnicodePrefix(
&_PrefixTable,
FALSE);
}
}
if (wszNextObject != NULL) {
*pwszObject = new WCHAR[ wcslen(wszNextObject) + 1 ];
if (*pwszObject != NULL) {
wcscpy( *pwszObject, wszNextObject );
dwErr = ERROR_SUCCESS;
} else {
dwErr = ERROR_OUTOFMEMORY;
}
} else {
dwErr = ERROR_NO_MORE_ITEMS;
}
return( dwErr );
}
//+----------------------------------------------------------------------------
//
// Function: CStorageDirectory::_InsertIfNeeded
//
// Synopsis: Associates a given prefix with the given object name,
// iff no mapping already exists.
//
// Arguments: [wszPrefix] -- The prefix to associate with.
// [wszObject] -- The object name to associate.
//
// Returns: [ERROR_SUCCESS] -- If successfully inserted, or mapping was already
// known.
//
// [NERR_DfsInconsistent] -- Found another object that already
// maps to the given prefix.
//
// [ERROR_OUTOFMEMORY] -- Unable to allocate memory.
//
//-----------------------------------------------------------------------------
DWORD
CStorageDirectory::_InsertIfNeeded(
LPCWSTR wszPrefix,
LPCWSTR wszObject)
{
DWORD dwErr;
UNICODE_STRING ustrPrefix, ustrRem;
LPWSTR wszExistingObject, wszInsertObject, wszInsertPrefix;
ustrRem.Length = ustrRem.MaximumLength = 0;
ustrRem.Buffer = NULL;
RtlInitUnicodeString( &ustrPrefix, wszPrefix );
wszExistingObject = (LPWSTR) DfsFindUnicodePrefix(
&_PrefixTable,
&ustrPrefix,
&ustrRem);
if (wszExistingObject != NULL && ustrRem.Length == 0) {
//
// Found existing mapping - see if its for the same object
//
if (_wcsicmp(wszExistingObject, wszObject) == 0) {
dwErr = ERROR_SUCCESS;
} else {
dwErr = NERR_DfsInconsistent;
}
} else {
wszInsertObject = new WCHAR [ wcslen(wszObject) + 1 + wcslen(wszPrefix) + 1];
if (wszInsertObject != NULL) {
wcscpy( wszInsertObject, wszObject );
wszInsertPrefix = wszInsertObject + wcslen(wszObject) + 1;
wcscpy(wszInsertPrefix, wszPrefix);
if (DfsInsertUnicodePrefix(
&_PrefixTable, &ustrPrefix, (PVOID) wszInsertObject)) {
dwErr = ERROR_SUCCESS;
_cEntries++;
} else {
delete [] wszInsertObject;
dwErr = ERROR_OUTOFMEMORY;
}
} else {
dwErr = ERROR_OUTOFMEMORY;
}
}
return( dwErr );
}
//+----------------------------------------------------------------------------
//
// Function: CStorageDirectory::_Delete
//
// Synopsis: Deletes an association between the given prefix and its
// object path.
//
// Arguments: [wszPrefix] -- The prefix to remove
//
// Returns: [ERROR_SUCCESS] -- successfully deleted association.
//
// [NERR_DfsNoSuchVolume] -- Unable to find an association for
// the prefix.
//
// [NERR_DfsInconsistent] -- Found the prefix, but unable to
// delete. This should never happen! Asserts on checked
// builds
//
//-----------------------------------------------------------------------------
DWORD
CStorageDirectory::_Delete(
LPWSTR wszPrefix)
{
DWORD dwErr;
UNICODE_STRING ustrPrefix, ustrRem;
LPWSTR wszObject;
ustrRem.Length = ustrRem.MaximumLength = 0;
ustrRem.Buffer = NULL;
RtlInitUnicodeString( &ustrPrefix, wszPrefix );
wszObject = (LPWSTR) DfsFindUnicodePrefix(
&_PrefixTable,
&ustrPrefix,
&ustrRem );
if (wszObject != NULL && ustrRem.Length == 0) {
if (DfsRemoveUnicodePrefix( &_PrefixTable, &ustrPrefix )) {
delete [] wszObject;
_cEntries--;
dwErr = ERROR_SUCCESS;
} else {
dwErr = NERR_DfsInconsistent;
ASSERT( FALSE && "Unexpected error removing prefix!\n" );
}
} else {
dwErr = NERR_DfsNoSuchVolume;
}
return( dwErr );
}
DWORD
DfsmOpenStorage(
IN LPCWSTR lpwszFileName,
OUT CStorage **ppDfsmStorage)
{
DWORD dwErr;
IDfsVolInlineDebOut((DEB_TRACE, "DfsmOpenStorage(%ws)\n", lpwszFileName));
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
dwErr = DfsmOpenLdapStorage(lpwszFileName, ppDfsmStorage);
} else {
dwErr = DfsmOpenRegStorage(lpwszFileName, ppDfsmStorage);
}
IDfsVolInlineDebOut((DEB_TRACE, "DfsmOpenStorage() exit\n"));
return( dwErr );
}
DWORD
DfsmCreateStorage(
IN LPCWSTR lpwszFileName,
OUT CStorage **ppDfsmStorage)
{
if (ulDfsManagerType == DFS_MANAGER_FTDFS) {
return( DfsmCreateLdapStorage(lpwszFileName, ppDfsmStorage) );
} else {
return( DfsmCreateRegStorage(lpwszFileName, ppDfsmStorage) );
}
}