|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 2000.
//
// File: CatArray.cxx
//
// Contents: Catalog array, for user mode content index
//
// History: 22-Dec-92 KyleP Split from vquery.cxx
// 11-Oct-96 dlee added catalog name support
//
//--------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <catarray.hxx>
#include <ciregkey.hxx>
#include <regacc.hxx>
#include <docstore.hxx>
#include <imprsnat.hxx>
#include <eventlog.hxx>
#include <cievtmsg.h>
#include "cicat.hxx"
#include <dbgproxy.hxx>
#include <query.hxx>
#include <srequest.hxx>
#include <removcat.hxx>
CCatArray Catalogs;
//+---------------------------------------------------------------------------
//
// Member: COldCatState::COldCatState, public
//
// Synopsis: Constructor
//
// Arguments: [dwOldState] -- old state of the catalog
// [wcsCatName] -- name of the catalog
// [wcVol] -- volume letter
//
// History: 15-Jul-98 KitmanH Created
//
//----------------------------------------------------------------------------
COldCatState::COldCatState( DWORD dwOldState, WCHAR const * wcsCatName, WCHAR wcVol ) : _dwOldState(dwOldState), _cStopCount(1) { RtlZeroMemory( _aVol, sizeof _aVol );
if ( 0 != wcVol ) _aVol[toupper(wcVol) - L'A'] = 1;
_xCatName.Init( wcslen( wcsCatName ) + 1 ); RtlCopyMemory( _xCatName.Get(), wcsCatName, _xCatName.SizeOf() ); }
//+---------------------------------------------------------------------------
//
// Member: CCatArray::CCatArray, public
//
// Synopsis: Constructor for array to handle switching drives for catalogs
//
// History: 07-May-92 AmyA Lifted from vquery.cxx
// 02-Jun-92 KyleP Added UNC support.
// 12-Jun-92 KyleP Lifted from citest.cxx
//
//----------------------------------------------------------------------------
CCatArray::CCatArray() : _aDocStores(0), _pDrvNotifArray(0), _fInit(FALSE), _mutex(FALSE) { }
//+---------------------------------------------------------------------------
//
// Member: CCatArray::Init, public
//
// Synopsis: Initializer for catalogs array
//
// History: 20 May 99 AlanW Created
//
//----------------------------------------------------------------------------
void CCatArray::Init() { _mutex.Init(); _fInit = TRUE; }
//+---------------------------------------------------------------------------
//
// Member: CCatArray::~CCatArray, public
//
// Synopsis: Destructor for array to handle switching drives for catalogs
//
// History: 07-May-92 AmyA Lifted from vquery.cxx
// 02-Jun-92 KyleP Added UNC support.
// 12-Jun-92 KyleP Lifted from citest.cxx
//
//----------------------------------------------------------------------------
extern HANDLE gmem_hHeap;
CCatArray::~CCatArray() { //
// If the global object was initialized (not just constructed) and the
// global heap is still around (we aren't after the process detach and
// unwinding global objects from _CRT_INIT on shutdown, clean up.
//
if ( _fInit && ( 0 != gmem_hHeap ) ) { CLock lockx( _mutex ); _pDrvNotifArray = 0; ClearStopArray(); Flush();
_fInit = FALSE; } else { //
// Zero out the dynarrays so they aren't deleted since the heap
// is gone by now.
//
// Just acquire them and leak the memory on purpose because the
// process is going away anyway.
//
_aDocStores.AcquireAll(); _aStoppedCatalogs.Acquire(); } } //~CCatArray
//+-------------------------------------------------------------------------
//
// Member: CCatArray::Flush, public
//
// Synopsis: Close all open catalogs
//
// History: 03-Sep-93 KyleP Created
//
// Notes: This is a dangerous operation. It should only be called
// when no-one is accessing any indexes.
//
//--------------------------------------------------------------------------
void CCatArray::Flush() { if (! _fInit) return;
CLock lock( _mutex );
TRY { // Close all the open docstores
for ( unsigned i = 0; i < _aDocStores.Count(); i++ ) { Win4Assert( 0 != _aDocStores[i] ); _aDocStores[i]->Shutdown(); }
// Delete registry entries for auto-mounted catalogs
if ( 0 != _pDrvNotifArray ) { BOOL aDrives[ RTL_MAX_DRIVE_LETTERS ]; RtlZeroMemory( aDrives, sizeof aDrives );
_pDrvNotifArray->GetAutoMountDrives( aDrives );
for ( WCHAR x = 0; x < RTL_MAX_DRIVE_LETTERS; x++ ) { if ( aDrives[x] ) { CRemovableCatalog cat( L'A' + x ); cat.Destroy(); } } } } CATCH( CException, e ) { Win4Assert( !"unexpected exception when shutting down a docstore" ); } END_CATCH
_aDocStores.Free(); } //Flush
//+-------------------------------------------------------------------------
//
// Member: CCatArray::FlushOne, public
//
// Synopsis: Close one catalog
//
// Arguments: [pDocStore] -- Pointer to the docstore to be flushed
//
// History: 27-Apr-98 KitmanH Created
//
// Notes: This is a dangerous operation. It should only be called
// when no-one is accessing any indexes. If this wasn't
// downlevel scaffolding we'd have to perform some serious
// serialization and refcounting here.
//
//--------------------------------------------------------------------------
void CCatArray::FlushOne( ICiCDocStore * pDocStore ) { CLock lock( _mutex );
for ( unsigned i = 0; i < _aDocStores.Count(); i++ ) { Win4Assert( 0 != _aDocStores[i] );
if ( _aDocStores[i] == pDocStore) { _aDocStores[i]->Shutdown();
CClientDocStore * p = _aDocStores.AcquireAndShrink(i); p->Release(); return; } } } //FlushOne
//+---------------------------------------------------------------------------
//
// Member: CCatArray::GetDocStore, public
//
// Synopsis: Returns a PCatalog by either using an existing catalog or
// creating a new one. Returns 0 if a catalog couldn't be
// found or created.
//
// Arguments: [pwcPathOrName] -- Root of the catalog or friendly name
//
// History: 07-May-92 AmyA Lifted from vquery.cxx
// 22-May-92 AmyA Added TRY/CATCH
// 02-Jun-92 KyleP Added UNC support.
// 12-Jun-92 KyleP Lifted from citest.cxx
// 29-Sep-94 KyleP Added ofs proxy support
// 1-16-97 srikants Changed to return DocStore.
//
//----------------------------------------------------------------------------
CClientDocStore * CCatArray::GetDocStore( WCHAR const * pwcPathOrName, BOOL fMustExist ) { BOOL fPath = wcschr( pwcPathOrName, L':' ) || wcschr( pwcPathOrName, L'\\' ); return GetNamedDocStore( pwcPathOrName, fPath ? 0 : pwcPathOrName, FALSE, // read-only
fMustExist ); } //GetDocStore
//+---------------------------------------------------------------------------
//
// Function: CatalogPathToName
//
// Synopsis: Enumerates catalogs looking for a named catalog whose
// location matches the given path.
//
// Arguments: [pwcPath] -- Path to look for
// [pwcName] -- Returns the catalog name
//
// Returns: S_OK if a match was found, S_FALSE otherwise.
//
// History: 22-Jun-98 dlee created
//
//----------------------------------------------------------------------------
SCODE CatalogPathToName( WCHAR const * pwcPath, WCHAR * pwcName ) { BOOL fFound = FALSE;
HKEY hKey; if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE, wcsRegCatalogsSubKey, 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey ) ) { SRegKey xKey( hKey ); DWORD iSubKey = 0;
do { FILETIME ft; WCHAR awcName[MAX_PATH]; DWORD cwcName = sizeof awcName / sizeof WCHAR; LONG err = RegEnumKeyEx( hKey, iSubKey, awcName, &cwcName, 0, 0, 0, &ft );
// either error or end of enumeration
if ( ERROR_SUCCESS != err ) break;
iSubKey++;
HKEY hCatName; if ( ERROR_SUCCESS == RegOpenKeyEx( hKey, awcName, 0, KEY_QUERY_VALUE, &hCatName ) ) { SRegKey xCatNameKey( hCatName );
// Check if the catalog is inactive and can be ignored
WCHAR awcKey[MAX_PATH]; wcscpy( awcKey, wcsRegJustCatalogsSubKey ); wcscat( awcKey, L"\\" ); wcscat( awcKey, awcName );
CRegAccess reg( RTL_REGISTRY_CONTROL, awcKey ); BOOL fInactive = reg.Read( wcsCatalogInactive, CI_CATALOG_INACTIVE_DEFAULT );
if ( !fInactive ) { WCHAR awcPath[MAX_PATH]; DWORD cbPath = sizeof awcPath; if ( ERROR_SUCCESS == RegQueryValueEx( hCatName, wcsCatalogLocation, 0, 0, (BYTE *)awcPath, &cbPath ) ) { int cwc = wcslen( awcPath ) - 1; if ( ( cwc >= 0 ) && ( L'\\' == awcPath[ cwc ] ) ) awcPath[ cwc ] = 0;
if ( !_wcsicmp( awcPath, pwcPath ) ) { fFound = TRUE; wcscpy( pwcName, awcName ); break; } } } } } while ( TRUE ); }
return fFound ? S_OK : S_FALSE; } //CatalogPathToName
//+---------------------------------------------------------------------------
//
// Member: CCatArray::GetNamedDocStore, public
//
// Synopsis: Returns a PCatalog by either using an existing catalog or
// creating a new one. Returns 0 if a catalog couldn't be
// found or created.
//
// Arguments: [pwcPath] -- Root of the catalog
// [pwcName] -- 0 or name of the catalog (optional param)
// [fMustExist] -- If TRUE, the catalog must exist unless
// it is the null catalog. If FALSE, the
// catalog can be opened.
//
// History: 12-Oct-96 dlee created
// 1-16-97 srikants Changed to return DocStore.
// 16-Feb-2000 KLam Make sure path is good before using it
//
//----------------------------------------------------------------------------
CClientDocStore * CCatArray::GetNamedDocStore( WCHAR const * pwcPath, WCHAR const * pwcName, BOOL fOpenForReadOnly, BOOL fMustExist ) { WCHAR awcPath[ MAX_PATH ];
Win4Assert ( 0 != pwcPath );
unsigned len = wcslen( pwcPath ); RtlCopyMemory( awcPath, pwcPath, ( len + 1 ) * sizeof WCHAR );
// Get rid of trailing slash.
Win4Assert ( len > 0 && len < MAX_PATH ); if ( len > 0 && awcPath[ len - 1 ] == '\\' ) awcPath[ len - 1 ] = 0;
// make a complete path including \catalog.wci
WCHAR awcCompletePath[ MAX_PATH ]; wcscpy( awcCompletePath, awcPath ); wcscat( awcCompletePath, CAT_DIR );
BOOL fNullCatalog = !wcscmp( pwcPath, CINULLCATALOG );
CLock lock( _mutex );
// Look for previous use of catalog path or name.
for ( unsigned i = 0; i < _aDocStores.Count(); i++ ) { Win4Assert( 0 != _aDocStores[i] );
const WCHAR *pwcCatName = _aDocStores[i]->GetName(); CiCat * pCat = _aDocStores[i]->GetCiCat(); const WCHAR *pwcCatPath = ( 0 == pCat ) ? 0 : pCat->GetCatDir();
ciDebugOut(( DEB_ITRACE, "pwcPath: '%ws'\n", pwcPath )); ciDebugOut(( DEB_ITRACE, "pwcName: '%ws'\n", pwcName )); ciDebugOut(( DEB_ITRACE, "pwcCatName: '%ws'\n", pwcCatName )); ciDebugOut(( DEB_ITRACE, "pwcCatPath: '%ws'\n", pwcCatPath )); ciDebugOut(( DEB_ITRACE, "awcPath: '%ws'\n", awcPath )); ciDebugOut(( DEB_ITRACE, "awcCompletePath: '%ws'\n", awcCompletePath ));
if ( ( fNullCatalog && ( 0 == pwcCatName ) ) || ( ( 0 != pwcCatPath ) && ( 0 == _wcsicmp( awcCompletePath, pwcCatPath ) ) ) || ( ( ( 0 != pwcCatName ) && ( 0 != pwcName ) && ( 0 == _wcsicmp( pwcName, pwcCatName ) ) ) ) ) return _aDocStores[i]; }
//
// We will let the special case of NullCatalog percolate through
// so we can create it only if the registry entry IsCatalogActive
// says we should activate it.
//
if ( fMustExist && !fNullCatalog) return 0;
// Try to fault the catalog in by name or path
WCHAR awcName[ MAX_PATH ];
if ( !fMustExist ) { // Can we fault-in a named catalog?
if ( L':' != awcPath[1] ) { HKEY hCatName; WCHAR awcCat[ MAX_PATH ]; wcscpy( awcCat, wcsRegCatalogsSubKey ); wcscat( awcCat, L"\\" ); wcscat( awcCat, pwcName );
ciDebugOut(( DEB_ITRACE, "attempting to fault-in %ws\n", awcCat ));
if ( ERROR_SUCCESS != RegOpenKeyEx( HKEY_LOCAL_MACHINE, awcCat, 0, KEY_QUERY_VALUE, &hCatName ) ) return 0;
SRegKey xCatName( hCatName ); DWORD cbPath = sizeof awcPath; if ( ERROR_SUCCESS != RegQueryValueEx( hCatName, wcsCatalogLocation, 0, 0, (BYTE *)awcPath, &cbPath ) ) return 0;
// Trim trailing backslash
int cwc = wcslen( awcPath ) - 1; if ( ( cwc >= 0 ) && ( L'\\' == awcPath[ cwc ] ) ) awcPath[ cwc ] = 0; } else if ( ( 0 == pwcName ) || ( L':' == pwcName[1] ) ) { // no name, just a path in both fields -- inverse lookup
if ( S_FALSE == CatalogPathToName( awcPath, awcName ) ) return 0;
pwcName = awcName; } }
// Catalog name instead of a path? If so, fail the lookup since
// catalogs can only be really opened by path.
if ( L':' != awcPath[1] ) return 0;
TRY { BOOL fInactive = FALSE;
// We want the null catalog's registry entry to be looked up using
// friendly name.
WCHAR const *pwcCatName = fNullCatalog ? pwcPath : pwcName;
// Check if the catalog is marked as inactive. Don't do this
// in the constructor of CiCat -- it would be after a few
// threads are created and lots of activity has started.
if ( 0 != pwcCatName ) { WCHAR awcKey[MAX_PATH]; wcscpy( awcKey, wcsRegJustCatalogsSubKey ); wcscat( awcKey, L"\\" ); wcscat( awcKey, pwcCatName );
CRegAccess reg( RTL_REGISTRY_CONTROL, awcKey ); fInactive = reg.Read( wcsCatalogInactive, CI_CATALOG_INACTIVE_DEFAULT ); }
if ( !fInactive ) { CImpersonateSystem impersonate;
// Have we reached the maximum # of docstores?
if ( _aDocStores.Count() >= GetMaxCatalogs() ) { ciDebugOut(( DEB_WARN, "can't open %ws, out of catalogs!\n", pwcName ));
TRY { CEventLog eventLog( 0, wcsCiEventSource ); CEventItem item( EVENTLOG_WARNING_TYPE, CI_SERVICE_CATEGORY, MSG_CI_TOO_MANY_CATALOGS, 1 );
item.AddArg( awcPath ); eventLog.ReportEvent( item ); } CATCH( CException, e ) { // if we can't log the event, ignore
} END_CATCH
return 0; //Expensive, but who cares?
}
XPtr<CClientDocStore> xDocStore;
if (fNullCatalog) xDocStore.Set( new CClientDocStore() ); else xDocStore.Set( new CClientDocStore( awcPath, fOpenForReadOnly, *_pDrvNotifArray, pwcName ) );
_aDocStores.Add( xDocStore.GetPointer(), _aDocStores.Count() ); xDocStore.Acquire(); } } CATCH( CException, e ) { // ignore catalogs that can't be opened
} END_CATCH
if ( i < _aDocStores.Count() ) return _aDocStores[i]; else return 0; } //GetNamedDocStore
//+---------------------------------------------------------------------------
//
// Member: CCatArray::GetOne, public
//
// Synopsis: Returns a PCatalog by either using an existing catalog or
// creating a new one. Returns 0 if a catalog couldn't be
// found or created.
//
// Arguments: [pwcPathOrName] -- Root of the catalog or friendly name
//
// History: 07-May-92 AmyA Lifted from vquery.cxx
// 22-May-92 AmyA Added TRY/CATCH
// 02-Jun-92 KyleP Added UNC support.
// 12-Jun-92 KyleP Lifted from citest.cxx
// 29-Sep-94 KyleP Added ofs proxy support
//
//----------------------------------------------------------------------------
PCatalog * CCatArray::GetOne ( WCHAR const * pwcPathOrName ) { CClientDocStore * pDocStore = GetDocStore( pwcPathOrName ); return pDocStore ? pDocStore->GetCiCat() : 0; } //GetOne
//+---------------------------------------------------------------------------
//
// Member: CCatArray::GetNamedOne, public
//
// Synopsis: Returns a PCatalog by either using an existing catalog or
// creating a new one. Returns 0 if a catalog couldn't be
// found or created.
//
// Arguments: [pwcPath] -- Root of the catalog
// [pwcName] -- 0 or name of the catalog (optional param)
//
// History: 12-Oct-96 dlee created
//
//----------------------------------------------------------------------------
PCatalog * CCatArray::GetNamedOne( WCHAR const * pwcPath, WCHAR const * pwcName, BOOL fOpenForReadOnly, BOOL fNoQuery ) { CClientDocStore * pDocStore = GetNamedDocStore( pwcPath, pwcName, fOpenForReadOnly ); if ( pDocStore ) { if ( fNoQuery ) pDocStore->SetNoQuery(); else pDocStore->UnSetNoQuery(); }
return pDocStore ? pDocStore->GetCiCat() : 0; } //GetNamedOne
//+-------------------------------------------------------------------------
//
// Member: AddStoppedCat, public
//
// Synopsis: Add an item of COldCatState into the _aStopCatalogs array
//
// Arguments: [dwOldState] -- Old state of a docstore
// [wcsCatName] -- Catalog name of the docstore
// [wcVol] -- Letter of the volume on which the catalog resides
//
// History: 07-July-98 KitmanH Created
// 10-July-98 KitmanH Don't add an item with same CatName
// more than once
// 23-July-98 KitmanH Add volume letter on which the catalog
// resides
//
//--------------------------------------------------------------------------
void CCatArray::AddStoppedCat( DWORD dwOldState, WCHAR const * wcsCatName, WCHAR wcVol ) { XPtrST<COldCatState> xOldState( new COldCatState( dwOldState, wcsCatName, wcVol) );
CLock lockx( _mutex ); _aStoppedCatalogs.Add( xOldState.GetPointer(), _aStoppedCatalogs.Count() ); xOldState.Acquire(); } //AddStoppedCat
//+-------------------------------------------------------------------------
//
// Member: CCatArray::LokFindCat, private
//
// Synopsis: returns the index of the catalog in the _aStoppedcatalogs
// Array
//
// Arguments: [wcsCatName] -- name of the catalog
//
// History: 23-July-98 KitmanH Created
//
//--------------------------------------------------------------------------
DWORD CCatArray::FindCat( WCHAR const * wcsCatName ) { Win4Assert( _mutex.IsHeld() );
for ( unsigned i = 0; i < _aStoppedCatalogs.Count(); i++ ) { COldCatState * pOldState = _aStoppedCatalogs.Get(i);
if ( !(_wcsicmp( pOldState->GetCatName(), wcsCatName ) ) ) return i; }
return -1; } //FindCat
//+-------------------------------------------------------------------------
//
// Member: CCatArray::GetOldState, public
//
// Synopsis: returns the old state of a catalog before the volume was locked
//
// Arguments: [wcsCatName] -- catalog name
//
// Returns: old state of a catalog
//
// History: 07-July-98 KitmanH Created
//
//--------------------------------------------------------------------------
DWORD CCatArray::GetOldState( WCHAR const * wcsCatName ) { CLock lockx( _mutex ); DWORD i = FindCat(wcsCatName);
if ( -1 != i ) return (_aStoppedCatalogs.Get(i)->GetOldState() ); else return -1; } //GetOldState
//+-------------------------------------------------------------------------
//
// Member: CCatArray::RmFromStopArray, public
//
// Synopsis: remove the catalog from the stop array
//
// Arguments: [wcsCatName] -- name of the catalog
//
// History: 05-May-98 KitmanH Created
//
//--------------------------------------------------------------------------
void CCatArray::RmFromStopArray( WCHAR const * wcsCatName ) { CLock lockx( _mutex ); DWORD i = FindCat( wcsCatName );
if ( -1 != i ) { delete _aStoppedCatalogs.Get(i); _aStoppedCatalogs.Remove(i); ciDebugOut(( DEB_ITRACE, "Catalog %ws is deleted from Array\n", wcsCatName )); } } //RmFromStopArray
//+-------------------------------------------------------------------------
//
// Member: CCatArray::IsCatStopped, public
//
// Synopsis: check if the catalog has been stopped
//
// Arguments: [wcsCatName] -- name of the catalog
//
// History: 05-May-98 KitmanH Created
//
//--------------------------------------------------------------------------
BOOL CCatArray::IsCatStopped( WCHAR const * wcsCatName ) { CLock lockx( _mutex ); DWORD i = FindCat( wcsCatName );
if ( -1 != i ) { ciDebugOut(( DEB_ITRACE, "Catalog %ws is Stopped\n", wcsCatName )); return TRUE; } else return FALSE; } //IsCatStopped
//+-------------------------------------------------------------------------
//
// Member: ClearStopArray, public
//
// Synopsis: clear the contents in the _aStoppedCatalogs array
//
// History: 05-May-98 KitmanH Created
// 08-July-98 KitmanH ReWrited
//
// Note: _aStoppedCatalogs now stores the old state with the cat name
//
//--------------------------------------------------------------------------
void CCatArray::ClearStopArray() { CLock lockx( _mutex );
for ( unsigned i = 0; i < _aStoppedCatalogs.Count(); i++ ) { ciDebugOut(( DEB_ITRACE, "ClearStopArray: i is %d\n", i )); COldCatState * pOldState = _aStoppedCatalogs.Get(i); delete pOldState; }
_aStoppedCatalogs.Clear(); } //ClearStopArray
//+-------------------------------------------------------------------------
//
// Member: CCatArray::IncStopCount, public
//
// Synopsis: Increment the _cStopCount and set the appropriate element
// in the volume array
//
// Arguments: [wcsCatName] -- name of the catalog
// [wcVol] -- volume letter
//
// History: 24-Aug-98 KitmanH Created
//
//--------------------------------------------------------------------------
BOOL CCatArray::IncStopCount( WCHAR const * wcsCatName, WCHAR wcVol ) { ciDebugOut(( DEB_ITRACE, "IncStopCount %wc\n", wcVol )); CLock lockx( _mutex );
DWORD i = FindCat( wcsCatName );
if ( -1 != i ) { COldCatState * pOldState = _aStoppedCatalogs.Get(i); pOldState->IncStopCountAndSetVol( wcVol ); return TRUE; } else return FALSE; } //IncStop
//+-------------------------------------------------------------------------
//
// Funtion: DriveHasCatalog
//
// Synopsis: Checks if there is a catalog.wci directory on the root
// of the volume.
//
// Arguments: [wc] -- the volume to check
//
// History: 16-Apr-99 dlee Created
//
//--------------------------------------------------------------------------
BOOL DriveHasCatalog( WCHAR wc ) { BOOL fCat = FALSE;
WCHAR wszVolumePath[] = L"\\\\.\\a:"; wszVolumePath[4] = wc;
HANDLE hVolume = CreateFile( wszVolumePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if ( hVolume != INVALID_HANDLE_VALUE ) { SWin32Handle xHandleVolume( hVolume );
//
// Is there media in the drive? This check avoids possible hard-error
// popups prompting for media.
//
ULONG ulSequence; DWORD cb = sizeof(ULONG);
BOOL fOk = DeviceIoControl( hVolume, IOCTL_STORAGE_CHECK_VERIFY, 0, 0, &ulSequence, sizeof(ulSequence), &cb, 0 );
if ( fOk ) { WCHAR awcCatDir[ MAX_PATH ]; wcscpy( awcCatDir, L"c:\\" ); wcscat( awcCatDir, CAT_DIR ); // catalog.wci
awcCatDir[0] = wc;
WIN32_FILE_ATTRIBUTE_DATA fData; if ( GetFileAttributesEx( awcCatDir, GetFileExInfoStandard, &fData ) ) { // Is the catalog path a file or a directory?
fCat = ( 0 != ( fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ); } }
}
ciDebugOut(( DEB_ITRACE, "catalog on drive %wc? %s\n", wc, fCat ? "yes" : "no" ));
return fCat; } //DriveHasCatalog
//+---------------------------------------------------------------------------
//
// Member: CCatArray::TryToStartCatalogOnRemovableVol
//
// Synopsis: Attempts to open a catalog on the root of the volume.
//
// Arguments: [wcVol] -- Volume letter
// [pRequestQ] -- Pointer to the RequestQueue
//
// History: 16-Apr-99 dlee Created
//
//----------------------------------------------------------------------------
void CCatArray::TryToStartCatalogOnRemovableVol( WCHAR wcVol, CRequestQueue * pRequestQ ) { Win4Assert( IsRemovableDrive( wcVol ) );
if ( DriveHasCatalog( wcVol ) ) { ciDebugOut(( DEB_ITRACE, "opening temporary catalog\n" ));
// Make the registry entries
CRemovableCatalog cat( wcVol ); cat.Create();
WCHAR awcName[MAX_PATH]; cat.MakeCatalogName( awcName ); CClientDocStore *p = GetDocStore( awcName, FALSE ); } } //TryToStartCatalogOnRemovableVol
//+---------------------------------------------------------------------------
//
// Member: CCatArray::StartCatalogsOnVol
//
// Synopsis: Restore all catalogs on the volume specified to its previous
// state before the volume was locked.
//
// Arguments: [wcVol] -- Volume letter
// [pRequestQ] -- Pointer to the RequestQueue
//
// History: 09-03-98 kitmanh Created
//
//----------------------------------------------------------------------------
void CCatArray::StartCatalogsOnVol( WCHAR wcVol, CRequestQueue * pRequestQ ) { ciDebugOut(( DEB_ITRACE, "StartCatalogsOnVol %wc\n", wcVol )); CLock lock( _mutex );
SCWorkItem newItem; RtlZeroMemory( &newItem, sizeof newItem );
BOOL fOpenedCatalogs = FALSE;
for ( unsigned i = 0 ; i < _aStoppedCatalogs.Count(); i++ ) { COldCatState * pOldCatState = _aStoppedCatalogs.Get(i);
if ( pOldCatState->IsVolSet( wcVol ) ) { if ( 1 == pOldCatState->GetStopCount() ) { ciDebugOut(( DEB_ITRACE, "Catalog %ws : pOldCatState->GetStopCount() is == 1\n", pOldCatState->GetCatName() ));
WCHAR const * awcName = pOldCatState->GetCatName();
DWORD dwOldState = pOldCatState->GetOldState();
if ( -1 != dwOldState ) { ciDebugOut(( DEB_ITRACE, "dwOldState for %ws is %d\n", awcName, dwOldState )); fOpenedCatalogs = TRUE;
if ( !( (CICAT_READONLY & dwOldState) || (CICAT_STOPPED & dwOldState) ) ) { if ( 0 != (CICAT_NO_QUERY & dwOldState) ) { newItem.type = eNoQuery; newItem.fNoQueryRW = TRUE; } else if ( 0 != (CICAT_WRITABLE & dwOldState) ) { newItem.type = eCatW; } else { Win4Assert( !"Undefined CICAT state" ); }
newItem.pDocStore = 0; pRequestQ->AddSCItem( &newItem, awcName ); } else if ( 0 != (CICAT_READONLY & dwOldState) ) //readonly
{ newItem.type = eCatRO; newItem.pDocStore = 0; pRequestQ->AddSCItem( &newItem, awcName ); } } } else { ciDebugOut(( DEB_ITRACE, "Catalog %ws: pOldCatState->GetStopCount() is %d\n", pOldCatState->GetCatName(), pOldCatState->GetStopCount() ));
Win4Assert( 1 < pOldCatState->GetStopCount() ); // Decreament stopcount
pOldCatState->UnSetVol( wcVol ); pOldCatState->DecStopCount(); } } }
//
// If we didn't open any catalogs on the volume and it's a removable
// volume with a catalog.wci directory in the root, make a temporary
// entry in the registry and open the catalog read-only. Close the
// catalog and remove the registry entries when the volume is ejected.
//
if ( !fOpenedCatalogs ) { if ( IsRemovableDrive( wcVol ) && DriveHasCatalog( wcVol ) ) { ciDebugOut(( DEB_ITRACE, "trying to opening temporary catalog\n" ));
// Make the registry entries
CRemovableCatalog cat( wcVol ); cat.Create();
// Tell the request queue to open the catalog
newItem.type = eCatRO; newItem.pDocStore = 0; newItem.fNoQueryRW = FALSE; WCHAR awcName[MAX_PATH]; cat.MakeCatalogName( awcName ); newItem.StoppedCat = awcName; pRequestQ->AddSCItem( &newItem, awcName ); } else { //
// File a null work item so the request queue won't close
// connections to all query clients.
//
newItem.type = eNoCatWork; pRequestQ->AddSCItem( &newItem, L"" ); } } } //StartCatalogsOnVol
|