Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

428 lines
12 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1991 - 2000.
//
// File: VMap.hxx
//
// Contents: Virtual <--> physical path map.
//
// Classes: CVMap
//
// History: 05-Feb-96 KyleP Created
//
//----------------------------------------------------------------------------
#pragma once
#include <catalog.hxx>
#include <prcstob.hxx>
#include <smatch.hxx>
#include <cimbmgr.hxx>
const unsigned INVALID_VMAP_INDEX = 0xFFFFFFFF;
//+-------------------------------------------------------------------------
//
// Class: CVMapDesc
//
// Purpose: Description of single scope mapping
//
// History: 05-Feb-96 KyleP Created
//
//--------------------------------------------------------------------------
class CVMapDesc
{
public:
inline CVMapDesc();
void Init( WCHAR const * pVRoot,
ULONG ccVRoot,
WCHAR const * pPRoot,
ULONG ccPRoot,
ULONG idParent,
BOOL fAutomatic,
CiVRootTypeEnum eType,
BOOL fIsIndexed,
BOOL fNonIndexedVDir );
inline unsigned PhysicalMatchLen( WCHAR const * path ) const;
inline BOOL IsInPhysicalScope( WCHAR const * root, unsigned cc ) const;
BOOL IsVirtualMatch( WCHAR const * pVPath, unsigned ccVPath ) const;
BOOL IsPhysicalMatch( WCHAR const * pVPath, unsigned ccVPath ) const;
inline ULONG Parent() const { return _idParent; }
inline void SetParent( ULONG idParent ) { _idParent = idParent; }
inline BOOL IsFree() { return (0 == _ccVScope); }
inline void Delete() { _ccVScope = 0; }
inline WCHAR const * PhysicalPath() const { return _wcPScope; }
inline ULONG PhysicalLength() const { return _ccPScope; }
inline WCHAR const * VirtualPath() const { return _wcVScope; }
inline ULONG VirtualLength() const { return _ccVScope; }
inline void SetAutomatic() { _Type |= PCatalog::AutomaticRoot; }
inline void ClearAutomatic() { _Type &= ~PCatalog::AutomaticRoot; }
inline BOOL IsAutomatic() const { return (_Type & PCatalog::AutomaticRoot); }
inline void SetManual() { _Type |= PCatalog::ManualRoot; }
inline void ClearManual() { _Type &= ~PCatalog::ManualRoot; }
inline BOOL IsManual() const { return (_Type & PCatalog::ManualRoot); }
inline void ClearInUse() { _Type &= ~PCatalog::UsedRoot; }
inline BOOL IsInUse() const { return (_Type & PCatalog::UsedRoot); }
inline BOOL IsNNTP() const { return 0 != (_Type & PCatalog::NNTPRoot); }
inline BOOL IsIMAP() const { return 0 != (_Type & PCatalog::IMAPRoot); }
inline BOOL IsW3() const { return !IsNNTP() && !IsIMAP(); }
inline BOOL IsNonIndexedVDir() const { return 0 != (_Type & PCatalog::NonIndexedVDir); }
inline void SetNonIndexedVDir() { _Type |= PCatalog::NonIndexedVDir; }
inline void ClearNonIndexedVDir() { _Type &= ~PCatalog::NonIndexedVDir; }
inline ULONG RootType() { return _Type; }
private:
ULONG _ccVScope;
WCHAR _wcVScope[MAX_PATH]; // Virtual scope
// IIS currently doesn't allow paths greater
// than MAX_PATH. This is not a good reason for we to also not
// support, but there are lot of complications right now, like
// in place serialization of variable data, so currently we have the
// MAX_PATH restriction of VPaths and for scopes.
ULONG _ccPScope;
WCHAR _wcPScope[MAX_PATH]; // Physical scope
ULONG _idParent; // Link to parent (INVALID_VMAP_INDEX --> top level)
ULONG _Type;
};
//+-------------------------------------------------------------------------
//
// Class: CVMap
//
// Purpose: Virtual/Physical path map
//
// History: 05-Feb-96 KyleP Created
//
//--------------------------------------------------------------------------
class CVMap
{
public:
CVMap();
BOOL Init( PRcovStorageObj * obj );
void Empty();
BOOL Add( WCHAR const * vroot,
WCHAR const * root,
BOOL fAutomatic,
ULONG & idNew,
CiVRootTypeEnum eType,
BOOL fVRoot,
BOOL fIsIndexed );
BOOL Remove( WCHAR const * vroot,
BOOL fOnlyIfAutomatic,
ULONG & idOld,
ULONG & idNew,
CiVRootTypeEnum eType,
BOOL fVRoot );
void MarkClean();
BOOL IsClean() const { return !_fDirty; }
inline BOOL IsInPhysicalScope( ULONG id, WCHAR const * root, unsigned cc );
ULONG PhysicalPathToId( WCHAR const * path );
BOOL VirtualToPhysicalRoot( WCHAR const * pwcVRoot,
unsigned ccVRoot,
CLowerFunnyPath & lcaseFunnyPRoot,
unsigned & ccPRoot );
BOOL VirtualToPhysicalRoot( WCHAR const * pwcVPath,
unsigned ccVPath,
XGrowable<WCHAR> & xwcsVRoot,
unsigned & ccVRoot,
CLowerFunnyPath & lcaseFunnyPRoot,
unsigned & ccPRoot,
unsigned & iBmk );
BOOL VirtualToAllPhysicalRoots( WCHAR const * pwcVPath,
unsigned ccVPath,
XGrowable<WCHAR> & xwcsVRoot,
unsigned & ccVRoot,
CLowerFunnyPath & lcaseFunnyPRoot,
unsigned & ccPRoot,
ULONG & ulType,
unsigned & iBmk );
ULONG EnumerateRoot( XGrowable<WCHAR> & xwcVRoot,
unsigned & ccVRoot,
CLowerFunnyPath & lcaseFunnyPRoot,
unsigned & ccPRoot,
unsigned & iBmk );
BOOL DoesPhysicalRootExist( WCHAR const * pwcPRoot );
inline CVMapDesc const & GetDesc( ULONG id ) const;
//
// Path chaining.
//
inline ULONG Parent( ULONG id ) const;
inline ULONG FindNthRemoved( ULONG id, unsigned cSkip ) const;
BOOL IsNonIndexedVDir( ULONG id ) const
{
if ( INVALID_VMAP_INDEX == id )
return FALSE;
return _aMap[id].IsNonIndexedVDir();
}
ULONG GetExcludeParent( ULONG id ) const
{
Win4Assert( id < _aExcludeParent.Count() );
return _aExcludeParent[ id ];
}
BOOL IsAnExcludeParent( ULONG id ) const
{
if ( INVALID_VMAP_INDEX == id )
return FALSE;
for ( unsigned x = 0; x < _aExcludeParent.Count(); x++ )
if ( _aExcludeParent[x] == id )
return TRUE;
return FALSE;
}
private:
ULONG PhysicalPathToId( WCHAR const * path, BOOL fNonIndexedVDirs );
void DumpVMap();
void RecomputeNonIndexedInfo();
BOOL _fDirty; // TRUE if vmap went down dirty
CMutexSem _mutex;
CDynArrayInPlace<CVMapDesc> _aMap;
CDynArrayInPlace<ULONG> _aExcludeParent;
XPtr<PRcovStorageObj> _xrsoMap;
};
//+-------------------------------------------------------------------------
//
// Member: CVMapDesc::PhysicalMatchLen, private
//
// Synopsis: Compares input with physical path
//
// Arguments: [pPPath] -- Physical path.
//
// Returns: 0 if [pPPath] does not match physical path complete to
// the end of the short of the two. On success returns
// length of physical path.
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline unsigned CVMapDesc::PhysicalMatchLen( WCHAR const * pPPath ) const
{
Win4Assert( *pPPath );
//
// Compare strings.
//
unsigned i = 0;
while ( *pPPath && i < _ccPScope && *pPPath == _wcPScope[i] )
{
i++;
pPPath++;
}
//
// Adjust for possible lack of terminating backslash.
//
if ( 0 == *pPPath )
{
if ( *(pPPath - 1) == L'\\' )
return _ccPScope;
else
{
if ( _wcPScope[i] == L'\\' )
return _ccPScope;
else
return 0;
}
}
else
{
if ( i >= _ccPScope )
return _ccPScope;
else
return 0;
}
}
//+-------------------------------------------------------------------------
//
// Member: CVMapDesc::CVMapDesc, private
//
// Synopsis: Constructor
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline CVMapDesc::CVMapDesc()
: _ccVScope( 0 ),
_ccPScope( 0 )
{
}
//+-------------------------------------------------------------------------
//
// Member: CVMapDesc::IsInPhysicalScope, public
//
// Synopsis: Compares input with physical path
//
// Arguments: [root] -- Physical path.
// [cc] -- Size, in chars, of [root]
//
// Returns: TRUE if [root] is within physical scope.
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline BOOL CVMapDesc::IsInPhysicalScope( WCHAR const * root, unsigned cc ) const
{
Win4Assert( root[cc-1] != L'\\' );
CScopeMatch Match( _wcPScope, _ccPScope );
//
// Be careful not to match root of scope.
//
return Match.IsInScope( root, cc ) && (_ccPScope != cc + 1);
}
//+-------------------------------------------------------------------------
//
// Member: CVMap::IsInPhysicalScope, public
//
// Synopsis: Compares input with physical path
//
// Arguments: [id] -- Id of virtual/physical scope
// [root] -- Physical path.
// [cc] -- Size, in chars, of [root]
//
// Returns: TRUE if [root] is within physical scope.
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline BOOL CVMap::IsInPhysicalScope( ULONG id, WCHAR const * root, unsigned cc )
{
CLock lock(_mutex);
Win4Assert( id < _aMap.Count() );
return _aMap[id].IsInPhysicalScope( root, cc );
}
//+-------------------------------------------------------------------------
//
// Member: CVMap::Parent, public
//
// Arguments: [id] -- Id of virtual/physical scope
//
// Returns: Virtual/physical id of parent.
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline ULONG CVMap::Parent( ULONG id ) const
{
Win4Assert( id < _aMap.Count() );
return _aMap[id].Parent();
}
//+-------------------------------------------------------------------------
//
// Member: CVMap::FindNthRemoved, public
//
// Synopsis: Walks up virtual root chain to the Nth link.
//
// Arguments: [id] -- Id of starting virtual/physical scope
// [cSkip] -- Number of links to skip
//
// Returns: Virtual/physical id of Nth parent.
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline ULONG CVMap::FindNthRemoved( ULONG id, unsigned cSkip ) const
{
Win4Assert( id == INVALID_VMAP_INDEX || id < _aMap.Count() );
while ( id != INVALID_VMAP_INDEX && !_aMap[id].IsFree() && cSkip > 0 )
{
id = _aMap[id].Parent();
cSkip--;
}
if ( INVALID_VMAP_INDEX != id && _aMap[id].IsFree() )
id = INVALID_VMAP_INDEX;
return id;
}
//+-------------------------------------------------------------------------
//
// Member: CVMap::GetDesc, public
//
// Arguments: [id] -- Id of virtual/physical scope
//
// Returns: Scope descriptor for [id]
//
// History: 07-Feb-96 KyleP Created.
//
//--------------------------------------------------------------------------
inline CVMapDesc const & CVMap::GetDesc( ULONG id ) const
{
Win4Assert( id < _aMap.Count() );
return _aMap[id];
}