mirror of https://github.com/tongzx/nt5src
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.
800 lines
20 KiB
800 lines
20 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 2000.
|
|
//
|
|
// File: notifmgr.hxx
|
|
//
|
|
// Contents: Classes to deal with registry and file system change notifications
|
|
//
|
|
// Classes: CCiNotify
|
|
// CCiNotifyMgr
|
|
//
|
|
// History: 14-Jul-97 SitaramR Created from dlnotify.hxx
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#pragma once
|
|
|
|
#include <refcount.hxx>
|
|
#include <regevent.hxx>
|
|
#include <fatnot.hxx>
|
|
#include <rcstrmhd.hxx>
|
|
#include <cimbmgr.hxx>
|
|
|
|
#include "scaninfo.hxx"
|
|
#include "acinotfy.hxx"
|
|
#include "usnlist.hxx"
|
|
#include "usnmgr.hxx"
|
|
|
|
class CiCat;
|
|
class CCiNotifyMgr;
|
|
class CClientDocStore;
|
|
|
|
const LONGLONG sigCiNotify = 0x594649544F4E4943i64; // "CINOTIFY"
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CCiNotify
|
|
//
|
|
// Purpose: A single scope to watch for notifications.
|
|
//
|
|
// History: 1-17-96 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CCiNotify : public CGenericNotify
|
|
{
|
|
public:
|
|
|
|
CCiNotify( CCiNotifyMgr & notifyMgr,
|
|
WCHAR const * wcsScope,
|
|
unsigned cwcScope,
|
|
VOLUMEID volumeId,
|
|
ULONGLONG const & VolumeCreationTime,
|
|
ULONG VolumeSerialNumber,
|
|
FILETIME const & ftLastScan,
|
|
USN usn,
|
|
ULONGLONG const & JournalId,
|
|
BOOL fUsnTreeScan,
|
|
BOOL fDeep = TRUE );
|
|
|
|
~CCiNotify();
|
|
|
|
BOOL IsMatch( const WCHAR * wcsPath, ULONG len ) const;
|
|
|
|
# ifdef CIEXTMODE
|
|
void CiExtDump(void *ciExtSelf);
|
|
# endif
|
|
|
|
BOOL IsValidSig()
|
|
{
|
|
return sigCiNotify == _sigCiNotify;
|
|
}
|
|
|
|
CCiNotifyMgr & GetNotifyMgr() { return _notifyMgr; }
|
|
|
|
void LokRemove()
|
|
{
|
|
Unlink();
|
|
Close();
|
|
Abort();
|
|
}
|
|
|
|
void Abort();
|
|
|
|
virtual void DoIt();
|
|
virtual void ClearNotifyEnabled();
|
|
|
|
void SetLastScanTime( FILETIME const & ft )
|
|
{
|
|
_ftLastScan = ft;
|
|
}
|
|
FILETIME const & GetLastScanTime() const { return _ftLastScan; }
|
|
|
|
USN Usn() { return _usn; }
|
|
void SetUsn( USN usn ) { _usn = usn; }
|
|
|
|
ULONGLONG const & JournalId() const { return _JournalId; }
|
|
void SetJournalId( ULONGLONG const & JournalId ) { _JournalId = JournalId; }
|
|
|
|
VOLUMEID VolumeId() { return _volumeId; }
|
|
|
|
ULONGLONG const & VolumeCreationTime() const { return _VolumeCreationTime; }
|
|
ULONG VolumeSerialNumber() const { return _VolumeSerialNumber; }
|
|
|
|
void SetVolumeInfo( ULONGLONG const & VolumeCreationTime, ULONG VolumeSerialNumber )
|
|
{
|
|
_VolumeCreationTime = VolumeCreationTime;
|
|
_VolumeSerialNumber = VolumeSerialNumber;
|
|
}
|
|
|
|
BOOL FUsnTreeScan() { return _fUsnTreeScan; }
|
|
|
|
void InitUsnTreeScan()
|
|
{
|
|
_fUsnTreeScan = TRUE;
|
|
_usn = 0;
|
|
}
|
|
|
|
void SetUsnTreeScanComplete( USN usnMax )
|
|
{
|
|
// bogus assert: Win4Assert( _fUsnTreeScan );
|
|
|
|
_fUsnTreeScan = FALSE;
|
|
_usn = usnMax;
|
|
}
|
|
|
|
private:
|
|
|
|
const LONGLONG _sigCiNotify; // signature for debugging
|
|
|
|
ULONGLONG _VolumeCreationTime;
|
|
|
|
union
|
|
{
|
|
FILETIME _ftLastScan; // Time of the last successful scan
|
|
|
|
struct
|
|
{
|
|
ULONGLONG _JournalId; // Usn Journal Id
|
|
USN _usn; // Max usn persisted for this volumeId
|
|
};
|
|
};
|
|
|
|
ULONG _VolumeSerialNumber;
|
|
CCiNotifyMgr & _notifyMgr; // CI Notification manager
|
|
VOLUMEID _volumeId; // Volume id
|
|
BOOL _fUsnTreeScan; // True if a usn tree traversal is going
|
|
// on this scope
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CVRootNotify
|
|
//
|
|
// Purpose: Notification on IIS VRoot changes
|
|
//
|
|
// History: 1-20-96 KyleP Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CVRootNotify : public CMetaDataVPathChangeCallBack
|
|
{
|
|
public:
|
|
|
|
CVRootNotify( CiCat & cat,
|
|
CiVRootTypeEnum eType,
|
|
ULONG Instance,
|
|
CCiNotifyMgr & notifyMgr );
|
|
|
|
~CVRootNotify() { DisableNotification(); }
|
|
|
|
SCODE CallBack( BOOL fCancel );
|
|
|
|
void DisableNotification();
|
|
|
|
private:
|
|
|
|
CiVRootTypeEnum _type;
|
|
CiCat & _cat;
|
|
CCiNotifyMgr & _notifyMgr;
|
|
CMetaDataMgr _mdMgr;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CRegistryScopesNotify
|
|
//
|
|
// Purpose: Notification on Scopes registry changes
|
|
//
|
|
// History: 10-16-96 dlee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CRegistryScopesNotify : public CRegNotify
|
|
{
|
|
public:
|
|
|
|
CRegistryScopesNotify( CiCat & cat, CCiNotifyMgr & notifyMgr );
|
|
|
|
~CRegistryScopesNotify();
|
|
|
|
void DoIt();
|
|
|
|
private:
|
|
|
|
CiCat & _cat;
|
|
CCiNotifyMgr & _notifyMgr;
|
|
};
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CCiRegistryNotify
|
|
//
|
|
// Purpose: A notification class for tracking ContentIndex registry
|
|
// changes.
|
|
//
|
|
// History: 12-12-96 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CCiRegistryNotify : public CRegNotify
|
|
{
|
|
public:
|
|
|
|
CCiRegistryNotify( CiCat & cat, CCiNotifyMgr & notifyMgr );
|
|
|
|
~CCiRegistryNotify();
|
|
|
|
void DoIt();
|
|
|
|
private:
|
|
|
|
CiCat & _cat;
|
|
CCiNotifyMgr & _notifyMgr;
|
|
|
|
};
|
|
|
|
|
|
typedef class TDoubleList<CCiNotify> CCiNotifyList;
|
|
typedef class TFwdListIter<CCiNotify, CCiNotifyList> CFwdCiNotifyIter;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CScopeInfo
|
|
//
|
|
// Purpose: Class that holds a scope and the last scan time.
|
|
//
|
|
// History: 4-19-96 srikants Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CScopeInfo
|
|
{
|
|
|
|
public:
|
|
|
|
CScopeInfo( XArray<WCHAR> & xPath,
|
|
ULONGLONG const & VolumeCreationTime,
|
|
ULONG VolumeSerialNumber,
|
|
FILETIME const & ftLastScan )
|
|
: _volumeId(CI_VOLID_USN_NOT_ENABLED),
|
|
_VolumeCreationTime( VolumeCreationTime ),
|
|
_VolumeSerialNumber( VolumeSerialNumber ),
|
|
_ftLastScan( ftLastScan ),
|
|
_fUsnTreeScan(FALSE)
|
|
{
|
|
_pwszScope = xPath.Acquire();
|
|
_scanType = eNoScan;
|
|
}
|
|
|
|
CScopeInfo( XArray<WCHAR> & xPath,
|
|
ULONGLONG const & VolumeCreationTime,
|
|
ULONG VolumeSerialNumber,
|
|
VOLUMEID volumeId,
|
|
USN usn,
|
|
ULONGLONG const & JournalId,
|
|
BOOL fScan )
|
|
: _volumeId(volumeId),
|
|
_VolumeCreationTime( VolumeCreationTime ),
|
|
_VolumeSerialNumber( VolumeSerialNumber ),
|
|
_fUsnTreeScan( fScan ),
|
|
_JournalId( JournalId ),
|
|
_usn( usn )
|
|
{
|
|
_pwszScope = xPath.Acquire();
|
|
_scanType = eNoScan;
|
|
}
|
|
|
|
CScopeInfo( WCHAR const * pwszPath,
|
|
ULONGLONG const & VolumeCreationTime,
|
|
ULONG VolumeSerialNumber,
|
|
FILETIME const & ftLastScan )
|
|
: _volumeId(CI_VOLID_USN_NOT_ENABLED),
|
|
_VolumeCreationTime( VolumeCreationTime ),
|
|
_VolumeSerialNumber( VolumeSerialNumber ),
|
|
_ftLastScan( ftLastScan ),
|
|
_fUsnTreeScan( FALSE )
|
|
{
|
|
Win4Assert( 0 != pwszPath );
|
|
|
|
ULONG len = wcslen( pwszPath );
|
|
_pwszScope = new WCHAR [len+1];
|
|
RtlCopyMemory( _pwszScope, pwszPath, (len+1) * sizeof(WCHAR) );
|
|
|
|
_scanType = eNoScan;
|
|
}
|
|
|
|
CScopeInfo( WCHAR const * pwszPath,
|
|
ULONGLONG const & VolumeCreationTime,
|
|
ULONG VolumeSerialNumber,
|
|
VOLUMEID volumeId,
|
|
USN usn,
|
|
ULONGLONG const & JournalId,
|
|
BOOL fScan )
|
|
: _volumeId(volumeId),
|
|
_VolumeCreationTime( VolumeCreationTime ),
|
|
_VolumeSerialNumber( VolumeSerialNumber ),
|
|
_fUsnTreeScan( fScan ),
|
|
_JournalId( JournalId ),
|
|
_usn( usn )
|
|
{
|
|
Win4Assert( 0 != pwszPath );
|
|
|
|
ULONG len = wcslen( pwszPath );
|
|
_pwszScope = new WCHAR [len+1];
|
|
RtlCopyMemory( _pwszScope, pwszPath, (len+1) * sizeof(WCHAR) );
|
|
|
|
_scanType = eNoScan;
|
|
}
|
|
|
|
~CScopeInfo()
|
|
{
|
|
delete [] _pwszScope;
|
|
}
|
|
|
|
WCHAR const * GetPath() const
|
|
{
|
|
return _pwszScope;
|
|
}
|
|
|
|
WCHAR * AcquirePath()
|
|
{
|
|
WCHAR * pwszTemp = _pwszScope;
|
|
_pwszScope = 0;
|
|
return pwszTemp;
|
|
}
|
|
|
|
void Invalidate()
|
|
{
|
|
delete [] _pwszScope;
|
|
_pwszScope = 0;
|
|
}
|
|
|
|
BOOL IsValid() const { return 0 != _pwszScope; }
|
|
|
|
FILETIME const & GetLastScanTime() const { return _ftLastScan; }
|
|
|
|
void SetLastScanTime( FILETIME const & ft )
|
|
{
|
|
_ftLastScan = ft;
|
|
}
|
|
|
|
VOLUMEID VolumeId() const { return _volumeId; }
|
|
USN Usn() const { return _usn; }
|
|
void SetUsn( USN usn ) { _usn = usn; }
|
|
|
|
ULONGLONG const & JournalId() const { return _JournalId; }
|
|
void SetJournalId( ULONGLONG const & JournalId ) { _JournalId = JournalId; }
|
|
|
|
ULONGLONG const & VolumeCreationTime() const { return _VolumeCreationTime; }
|
|
ULONG VolumeSerialNumber() const { return _VolumeSerialNumber; }
|
|
|
|
void SetVolumeInfo( ULONGLONG const & VolumeCreationTime, ULONG VolumeSerialNumber )
|
|
{
|
|
_VolumeCreationTime = VolumeCreationTime;
|
|
_VolumeSerialNumber = VolumeSerialNumber;
|
|
}
|
|
|
|
BOOL IsScanNeeded() const { return eNoScan != _scanType; }
|
|
BOOL IsFullScan() const { return eFullScan == _scanType; }
|
|
BOOL IsIncrScan() const { return eIncrScan == _scanType; }
|
|
void ClearScanNeeded() { _scanType = eNoScan; }
|
|
void SetScanNeeded( BOOL fFull )
|
|
{
|
|
if ( fFull )
|
|
{
|
|
_scanType = eFullScan;
|
|
}
|
|
else if ( eNoScan == _scanType )
|
|
{
|
|
_scanType = eIncrScan;
|
|
}
|
|
}
|
|
|
|
BOOL FUsnTreeScan() const { return _fUsnTreeScan; }
|
|
void InitUsnTreeScan()
|
|
{
|
|
_fUsnTreeScan = TRUE;
|
|
_usn = 0;
|
|
}
|
|
|
|
void SetUsnTreeScanComplete( USN usnMax )
|
|
{
|
|
Win4Assert( _fUsnTreeScan );
|
|
Win4Assert( _usn == 0 );
|
|
|
|
_fUsnTreeScan = FALSE;
|
|
_usn = usnMax;
|
|
}
|
|
|
|
void ResetForScans()
|
|
{
|
|
_volumeId = CI_VOLID_USN_NOT_ENABLED;
|
|
RtlZeroMemory( &_ftLastScan, sizeof(_ftLastScan) );
|
|
_scanType = eFullScan;
|
|
}
|
|
|
|
void ResetForUsns( VOLUMEID volId, USN const & usnStart = 0 )
|
|
{
|
|
Win4Assert( volId != CI_VOLID_USN_NOT_ENABLED );
|
|
_volumeId = volId;
|
|
_usn = usnStart;
|
|
_fUsnTreeScan = TRUE;
|
|
}
|
|
|
|
private:
|
|
|
|
CScopeInfo( CScopeInfo const & src ) { Win4Assert( !"Don't call me!" ); }
|
|
|
|
enum EScanType
|
|
{
|
|
eNoScan,
|
|
eIncrScan,
|
|
eFullScan
|
|
};
|
|
|
|
ULONGLONG _VolumeCreationTime;
|
|
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
ULONGLONG _JournalId;
|
|
USN _usn;
|
|
};
|
|
|
|
FILETIME _ftLastScan;
|
|
};
|
|
|
|
ULONG _VolumeSerialNumber;
|
|
WCHAR * _pwszScope;
|
|
VOLUMEID _volumeId;
|
|
BOOL _fUsnTreeScan; // True if a usn tree traversal is going
|
|
// on this scope
|
|
EScanType _scanType;
|
|
};
|
|
|
|
DECL_DYNSTACK( CScopeInfoStack, CScopeInfo );
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CCiNotifyMgr
|
|
//
|
|
// Purpose: Manages multiple scope notifications for content index. A
|
|
// single content index can have multiple scopes and each scope
|
|
// needs separate notifications.
|
|
//
|
|
// History: 1-17-96 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#if CIDBG==1
|
|
const LONGLONG eForceNetScanInterval = 2 * 60 * 1000 * 10000; // 2 mins for testing
|
|
#endif // CIDBG==1
|
|
|
|
class CCiNotifyMgr
|
|
{
|
|
enum EEventType { eNone=0x0,
|
|
eKillThread=0x1,
|
|
eAddScopes=0x2,
|
|
eWatchIISVRoots=0x4,
|
|
eWatchRegistryScopes=0x8,
|
|
eWatchCiRegistry=0x10,
|
|
eUnWatchW3VRoots=0x20,
|
|
eUnWatchNNTPVRoots=0x40,
|
|
eUnWatchIMAPVRoots=0x80 };
|
|
|
|
friend class CCiNotifyIter;
|
|
|
|
public:
|
|
|
|
CCiNotifyMgr( CiCat & cicat, CCiScanMgr & scanMgr );
|
|
|
|
~CCiNotifyMgr( );
|
|
|
|
void Resume() { _thrNotify.Resume(); }
|
|
|
|
void AddPath( CScopeInfo const & scopeInfo, BOOL & fSubScopesRemoved );
|
|
|
|
BOOL RemoveScope( const WCHAR * wcsPath );
|
|
|
|
BOOL IsInScope( WCHAR const * pwcsRoot );
|
|
|
|
CMutexSem & GetMutex() { return _mutex; }
|
|
|
|
void AddRef()
|
|
{
|
|
_refCount.AddRef();
|
|
}
|
|
|
|
void Release()
|
|
{
|
|
_refCount.Release();
|
|
}
|
|
|
|
void ProcessChanges( XPtr<CCiAsyncProcessNotify> & xWorker );
|
|
|
|
void ProcessChanges( BYTE const * pbChanges, WCHAR const * pwcsRoot );
|
|
|
|
CCiAsyncProcessNotify * QueryAsyncWorkItem( BYTE const * pbChanges,
|
|
ULONG cbChanges,
|
|
WCHAR const * pwcsRoot );
|
|
void SetupScan( WCHAR const * pwcsRoot );
|
|
|
|
unsigned GetUpdateCount()
|
|
{
|
|
CLock lock(_mutex);
|
|
return _nUpdates;
|
|
}
|
|
|
|
void IncrementUpdateCount( ULONG nUpdates )
|
|
{
|
|
CLock lock(_mutex);
|
|
_nUpdates += nUpdates;
|
|
}
|
|
|
|
void ResetUpdateCount()
|
|
{
|
|
CLock lock(_mutex);
|
|
_nUpdates = 0;
|
|
}
|
|
|
|
void InitiateShutdown();
|
|
void WaitForShutdown();
|
|
|
|
void CancelIISVRootNotify( CiVRootTypeEnum eType );
|
|
|
|
void TrackIISVRoots( BOOL fTrackW3Svc, ULONG W3SvcInstance,
|
|
BOOL fTrackNNTPSvc, ULONG NNTPSvcInstance,
|
|
BOOL fTrackIMAPSvc, ULONG IMAPSvcInstance );
|
|
void TrackScopesInRegistry();
|
|
void TrackCiRegistry();
|
|
|
|
BOOL GetLastScanTime( WCHAR const * pwcsRoot, FILETIME & ft );
|
|
void UpdateLastScanTimes( FILETIME const & ft, CUsnFlushInfoList & usnFlushInfoList );
|
|
|
|
void ForceNetPathScansIf();
|
|
CiCat & GetCatalog() { return _cicat; }
|
|
|
|
BOOL IsRunning() const { return !_fAbort; }
|
|
|
|
private:
|
|
|
|
// methods to deal with notifications.
|
|
static DWORD WINAPI NotifyThread( void * self );
|
|
void _DoNotifications();
|
|
void _KillThread();
|
|
void _LokTellThreadToAddScope();
|
|
void _LokAddScopesNoThrow();
|
|
|
|
void LokWatchIISVServerNoThrow();
|
|
void LokUnWatchIISVServerNoThrow( CVRootNotify * pNotify );
|
|
|
|
void LokWatchRegistryScopesNoThrow();
|
|
void LokWatchCiRegistryNoThrow();
|
|
|
|
void _LokIncrementUpdateCount()
|
|
{
|
|
_nUpdates++;
|
|
}
|
|
|
|
void _LokForceScanNetPaths();
|
|
|
|
CiCat & _cicat;
|
|
CCiScanMgr & _scanMgr;
|
|
CMutexSem _mutex; // Serialize access to the data.
|
|
CCiNotifyList _list; // List of scopes being watched for
|
|
// notifications.
|
|
CRefCount _refCount;
|
|
|
|
unsigned _nUpdates; // Count of updates since the last time
|
|
// scantime is written.
|
|
|
|
BOOL _fAbort; // Flag set to TRUE if should abort
|
|
|
|
LONGLONG _ftLastNetPathScan;
|
|
// Time of the last force scan on
|
|
// network drives with no notifications
|
|
//
|
|
// Notification thread management. System executes the APC in the context
|
|
// of the thread that makes the notification request.
|
|
//
|
|
ULONG _evtType;
|
|
CEventSem _evt;
|
|
CThread _thrNotify;
|
|
CScopeInfoStack _stkScopes;
|
|
|
|
//
|
|
// For processing changes to IIS VRoots
|
|
//
|
|
|
|
XPtr<CVRootNotify> _xW3SvcVRootNotify;
|
|
XPtr<CVRootNotify> _xNNTPSvcVRootNotify;
|
|
XPtr<CVRootNotify> _xIMAPSvcVRootNotify;
|
|
|
|
BOOL _fTrackW3Svc;
|
|
BOOL _fTrackNNTPSvc;
|
|
BOOL _fTrackIMAPSvc;
|
|
ULONG _W3SvcInstance;
|
|
ULONG _NNTPSvcInstance;
|
|
ULONG _IMAPSvcInstance;
|
|
|
|
BOOL _fIISAdminAlive;
|
|
|
|
CRegistryScopesNotify * _pRegistryScopesNotify;
|
|
|
|
CCiRegistryNotify * _pCiRegistryNotify;
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CCiNotifyIter
|
|
//
|
|
// Purpose: An iterator to give successive scopes that are being watched
|
|
// for notifications.
|
|
//
|
|
// History: 1-25-96 srikants Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CCiNotifyIter
|
|
{
|
|
public:
|
|
|
|
CCiNotifyIter( CCiNotifyMgr & notifyMgr ) :
|
|
_notifyMgr(notifyMgr),
|
|
_lock(notifyMgr.GetMutex()),
|
|
_iNotAdded(0),
|
|
_stack(notifyMgr._stkScopes),
|
|
_list(notifyMgr._list),
|
|
_iter(_list)
|
|
{
|
|
_UpdateAtEnd();
|
|
}
|
|
|
|
|
|
BOOL AtEnd() const { return _fAtEnd; }
|
|
|
|
WCHAR const * Get()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->GetPath();
|
|
else
|
|
return _iter->GetScope();
|
|
}
|
|
|
|
void GetLastScanTime( FILETIME & ft )
|
|
{
|
|
if ( _iNotAdded < _stack.Count() )
|
|
RtlZeroMemory( &ft, sizeof(FILETIME) );
|
|
else
|
|
ft = _iter->GetLastScanTime();
|
|
}
|
|
|
|
VOLUMEID VolumeId()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->VolumeId();
|
|
else
|
|
return _iter->VolumeId();
|
|
}
|
|
|
|
ULONGLONG const & VolumeCreationTime()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->VolumeCreationTime();
|
|
else
|
|
return _iter->VolumeCreationTime();
|
|
}
|
|
|
|
ULONG VolumeSerialNumber()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->VolumeSerialNumber();
|
|
else
|
|
return _iter->VolumeSerialNumber();
|
|
}
|
|
|
|
BOOL IsDownlevelVolume()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return ( CI_VOLID_USN_NOT_ENABLED == _stack.Get(_iNotAdded)->VolumeId() );
|
|
else
|
|
return ( CI_VOLID_USN_NOT_ENABLED == _iter->VolumeId() );
|
|
}
|
|
|
|
USN Usn()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->Usn();
|
|
else
|
|
return _iter->Usn();
|
|
}
|
|
|
|
ULONGLONG const & JournalId()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->JournalId();
|
|
else
|
|
return _iter->JournalId();
|
|
}
|
|
|
|
BOOL FUsnTreeScan()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
return _stack.Get(_iNotAdded)->FUsnTreeScan();
|
|
else
|
|
return _iter->FUsnTreeScan();
|
|
}
|
|
|
|
void InitUsnTreeScan()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
_stack.Get(_iNotAdded)->InitUsnTreeScan();
|
|
else
|
|
_iter->InitUsnTreeScan();
|
|
}
|
|
|
|
void SetTreeScanComplete();
|
|
|
|
void SetUsnTreeScanComplete( USN usnMax );
|
|
|
|
void Advance()
|
|
{
|
|
Win4Assert( !AtEnd() );
|
|
|
|
if ( _iNotAdded < _stack.Count() )
|
|
_iNotAdded++;
|
|
else
|
|
_list.Advance(_iter);
|
|
|
|
_UpdateAtEnd();
|
|
}
|
|
|
|
private:
|
|
|
|
CCiNotifyMgr & _notifyMgr;
|
|
CLock _lock;
|
|
|
|
unsigned _iNotAdded;
|
|
BOOL _fAtEnd;
|
|
CScopeInfoStack & _stack;
|
|
CCiNotifyList & _list;
|
|
CFwdCiNotifyIter _iter;
|
|
|
|
void _UpdateAtEnd()
|
|
{
|
|
Win4Assert( _iNotAdded <= _stack.Count() );
|
|
_fAtEnd = _iNotAdded == _stack.Count() && _list.AtEnd(_iter);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
BOOL AreIdenticalPaths( WCHAR const * pwcsPath1, WCHAR const * pwcsPath2 );
|
|
|