summaryrefslogtreecommitdiff
path: root/Bus/IvyFileMon/DirectoryChanges.h
diff options
context:
space:
mode:
Diffstat (limited to 'Bus/IvyFileMon/DirectoryChanges.h')
-rw-r--r--Bus/IvyFileMon/DirectoryChanges.h493
1 files changed, 0 insertions, 493 deletions
diff --git a/Bus/IvyFileMon/DirectoryChanges.h b/Bus/IvyFileMon/DirectoryChanges.h
deleted file mode 100644
index b2e41c3..0000000
--- a/Bus/IvyFileMon/DirectoryChanges.h
+++ /dev/null
@@ -1,493 +0,0 @@
-// DirectoryChanges.h: interface for the
-// CDirectoryChangeWatcher and CDirectoryChangeHandler classes.
-//
-// Uses an io completion port and ReadDirectoryChangesW -- this code will only work on
-// Windows NT/2000/XP.
-//
-// The directory being watched must be a directory on a Windows NT/2000/XP machine
-//
-//
-// These classes are based on the FWatch sample program in the SDK.
-//
-//
-// If you get a compile time error that ReadDirectoryChangesW is an undeclared identifier,
-// you'll need to #define _WIN32_WINNT 0x400 in stdafx.h.
-//
-//
-/*******************************************************************
-// *** COPYRIGHT NOTICE ****
-//
-// Copyright 2001. Wes Jones (wesj@hotmail.com)
-//
-// This code is free for use under the following conditions:
-//
-// You may not claim authorship of this code.
-// You may not sell or distrubute this code without author's permission.
-// You are not permitted to sell this code in it's compiled, non-compiled, executable, or any other form.
-// Executable code excepted in the case that it is not sold separately from an application which
-// uses this it. This means you can use this code for your applications as you see fit, but this code may not be sold in any form
-// to others for use in their applications.
-// This copyright notice may not be removed.
-//
-//
-// If this code was NOT obtained by downloading it from www.codeproject.com,
-// or given to you by a friend or coworker, please tell me, & let me know how you got it. There a plenty of lazy bastards that
-// collect source code from the internet, and then sell it as part of
-// a 'Programmer's Library'. Using this code for such a purpose is stricly prohibited.
-//
-// If you'd like to pay me to turn this into an ActiveX/COM object so you
-// can use it in a Visual Basic application, feel free to contact me with an offer,
-// and I will create it for you. Otherwise, here is the source code, and you may make your own
-// ActiveX/COM object, providing that it is not sold separately.
-//
-// No guarantees or warranties are expressed or implied.
-// This code may contain bugs.
-// Warning: May contain matter. If this should come into contact with anti-matter, a violent explosion may occur.
-*******************************************************************/
-
-// Please let me know of any bugs, bug fixes, or enhancements made to this code.
-// If you have ideas for this, and/or tips or admonitions, I would be glad to hear them.
-//
-// See notes at top of DirectoryChanges.cpp modification history and more info.
-//
-//
-//////////////////////////////////////////////////////////////////////
-
-#if !defined(AFX_DIRECTORYCHANGES_H__02E53FDE_CB22_4176_B6D7_DA3675D9F1A6__INCLUDED_)
-#define AFX_DIRECTORYCHANGES_H__02E53FDE_CB22_4176_B6D7_DA3675D9F1A6__INCLUDED_
-
-#if _MSC_VER > 1000
-#pragma once
-#endif // _MSC_VER > 1000
-
-#include <afxmt.h>
-#include <afxtempl.h>
-
-#define READ_DIR_CHANGE_BUFFER_SIZE 4096
-
-class CFileNotifyInformation;//helper class
-class CDirectoryChangeWatcher;
-class CDelayedDirectoryChangeHandler;//helper class...used in implementation
-
-class CDirectoryChangeHandler
-/***********************************
- A class to handle changes to files in a directory.
- The virtual On_Filexxx() functions are called whenever changes are made to a watched directory that is being handled by this object...
- The On_Filexxx() functions execute in the context of the main thread if true is passed to the constructor of CDirectoryChangeWatcher,
- OR they fire in the context of a worker thread if false is passed to the constructor of CDirectoryChangeWatcher
-
- NOTES:
- A CDirectoryChangeHandler can only be used by ONE CDirectoryChangeWatcher object,
- but a CDirectoryChangeWatcher object may use multiple CDirectoryChangeHandler objects.
-
- When this object is destroyed, whatever directories that it was being used to handle directory changes for
- will automatically be 'unwatched'.
-
- The class is reference counted. The reference count is increased every time it is used
- in a (successfull) call to CDirectoryChangeWatcher::WatchDirectory() and is decremented whenever
- the directory becomes 'unwatched'.
-
- The only notifications are File Added, Removed, Modified, and Renamed.
- Even though the CDirectoryChangeWatcher::WatchDirectory (which'll call ReadDirectoryChangesW()) function allows you to specify flags
- to watch for changes to last access time, last write time, attributes changed, etc,
- these changes all map out to On_FileModified() which doesn't specify the type of modification.
-
-
- NOTE: The CDirectoryChangeHandler::On_Filexxx() functions
- are called in the context of the main thread, the thread that called CDirectoryChangeWatcher::WatchDirectory(),
- if you pass true to the constructor of CDirectoryChangeWatcher. This is accomplished via a hidden window,
- and REQUIRES that your app has a message pump.
- For console applications, or applications w/out a message pump, you can pass false to the constructor
- of CDirectoryChangeWatcher, and these notifications will fire in the context of a worker thread. By passing false
- to the constructor of CDirectoryChangeWatcher, you do NOT NEED a message pump in your application.
-
-
-
-************************************/
-{
-public:
-
- CDirectoryChangeHandler();
- virtual ~CDirectoryChangeHandler();
-
- //this class is reference counted
- long AddRef();
- long Release();
- long CurRefCnt()const;
-
-
- BOOL UnwatchDirectory();//causes CDirectoryChangeWatcher::UnwatchDirectory() to be called.
-
- const CString & GetChangedDirectoryName() const { return m_strChangedDirectoryName;}//WARNING: don't use this, this function will be removed in a future release.
- //returns the directory name where the change occured. This contains
- //the last directory to have changed if the same CDirectoryChangeHandler is
- //being used to watch multiple directories. It will return an empty string
- //if no changes have been made to a directory yet. It will always be the
- //name of the currently changed directory(as specified in CDirectoryChangeWatcher::WatchDirectory())
- //if called in the context of one of the
- //On_Filexxx() functions.
-protected:
- //
- // Override these functions:
- // These functions are called when the directory to watch has had a change made to it
- virtual void On_FileAdded(const CString & strFileName); //=0;
- //
- // On_FileAdded()
- //
- // This function is called when a file in one of the watched folders(or subfolders)
- // has been created.
- //
- // For this function to execute you'll need to specify FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME(for directories)
- // when you call CDirectoryChangeWatcher::WatchDirectory()
- //
- virtual void On_FileRemoved(const CString & strFileName);// = 0;
- //
- // On_FileRemoved()
- //
- // This function is called when a file in one of the watched folders(or subfolders)
- // has been deleted(or moved to another directory)
- //
- // For this function to execute you'll need to specify FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME(for directories)
- // when you call CDirectoryChangeWatcher::WatchDirecotry()
- //
-
- virtual void On_FileNameChanged(const CString & strOldFileName, const CString & strNewFileName);// = 0;
- //
- // On_FileNameChanged()
- //
- // This function is called when a file in one of the watched folders(or subfolders)
- // has been renamed.
- //
- //
- // You'll need to specify FILE_NOTIFY_CHANGE_FILE_NAME (or FILE_NOTIFY_CHANGE_DIR_NAME(for directories))
- // when you call CDirectoryChangeWatcher::WatchDirectory()
- //
- //
-
- virtual void On_FileModified(const CString & strFileName);// = 0;
- //
- // On_FileModified()
- //
- // This function is called whenever an attribute specified by the watch
- // filter has changed on a file in the watched directory or
- //
- // Specify any of the following flags when you call CDirectoryChangeWatcher::WatchDirectory()
- //
- //
- // FILE_NOTIFY_CHANGE_ATTRIBUTES
- // FILE_NOTIFY_CHANGE_SIZE
- // FILE_NOTIFY_CHANGE_LAST_WRITE
- // FILE_NOTIFY_CHANGE_LAST_ACCESS
- // FILE_NOTIFY_CHANGE_CREATION (* See Note # 1* )
- // FILE_NOTIFY_CHANGE_SECURITY
- //
- //
- // General Note) Windows tries to optimize some of these notifications. You may not get
- // a notification every single time a file is accessed for example.
- // There's a MS KB article or something on this(sorry forgot which one).
- //
- // Note #1 ) This notification isn't what you might think(FILE_NOTIFY_CHANGE_CREATION).
- // See the help files for ReadDirectoryChangesW...
- // This notifies you of a change to the file's
- // creation time, not when the file is created.
- // Use FILE_NOTIFY_CHANGE_FILE_NAME to know about newly created files.
- //
-
- virtual void On_ReadDirectoryChangesError(DWORD dwError, const CString & strDirectoryName);
- //
- // On_ReadDirectoryChangesError()
- //
- // This function is called when ReadDirectoryChangesW() fails during normal
- // operation (ie: some time after you've called CDirectoryChangeWatcher::WatchDirectory())
- //
- //
- // NOTE: *** READ THIS *** READ THIS *** READ THIS *** READ THIS ***
- //
- // NOTE: If this function has been called, the watched directory has been automatically unwatched.
- // You will not receive any further notifications for that directory until
- // you call CDirectoryChangeWatcher::WatchDirectory() again.
- //
- // On_WatchStopped() will not be called.
-
-
- virtual void On_WatchStarted(DWORD dwError, const CString & strDirectoryName);
- //
- // void On_WatchStarted()
- //
- // This function is called when a directory watch has begun.
- // It will be called whether CDirectoryChangeWatcher::WatchDirectory() is successful or not. Check the dwError parameter.
- //
- // PARAMETERS:
- // DWORD dwError -- 0 if successful, else it's the return value of GetLastError()
- // indicating why the watch failed.
- // const CString & strDirectoryName -- The full path and name of the directory being watched.
-
- virtual void On_WatchStopped(const CString & strDirectoryName);
- //
- // void On_WatchStopped()
- //
- // This function is called when a directory is unwatched (except on the case of the direcotry being unwatched due to an error)
- //
- // WARNING: *** READ THIS *** READ THIS *** READ THIS *** READ THIS ***
- //
- // This function MAY be called before the destructor of CDirectoryChangeWatcher
- // finishes.
- //
- // Be careful if your implementation of this fuction
- // interacts with some sort of a window handle or other object(a class, a file, etc.).
- // It's possible that that object/window handle will NOT be valid anymore the very last time
- // that On_WatchStopped() is called.
- // This scenario is likely if the CDirectoryChangeWatcher instance is currently watching a
- // directory, and it's destructor is called some time AFTER these objects/windows
- // your change handler interacts with have been destroyed.
- //
- // If your CDirectoryChangeHandler derived class interacts w/ a window or other
- // object, it's a good idea to unwatch any directories before the object/window is destroyed.
- // Otherwise, place tests for valid objects/windows in the implementation of this function.
- //
- // Failure to follow either tip can result in a mysterious RTFM error, or a 'Run time errors'
- //
-
- virtual bool On_FilterNotification(DWORD dwNotifyAction, LPCTSTR szFileName, LPCTSTR szNewFileName);
- //
- // bool On_FilterNotification(DWORD dwNotifyAction, LPCTSTR szFileName, LPCTSTR szNewFileName);
- //
- // This function gives your class a chance to filter unwanted notifications.
- //
- // PARAMETERS:
- // DWORD dwNotifyAction -- specifies the event to filter
- // LPCTSTR szFileName -- specifies the name of the file for the event.
- // LPCTSTR szNewFileName -- specifies the new file name of a file that has been renamed.
- //
- // ** szFileName and szNewFileName will always be the full path and file name with extention.
- //
- // RETURN VALUE:
- // return true , and you will receive the notification.
- // return false, and your class will NOT receive the notification.
- //
- // Valid values of dwNotifyAction:
- // FILE_ACTION_ADDED -- On_FileAdded() is about to be called.
- // FILE_ACTION_REMOVED -- On_FileRemoved() is about to be called.
- // FILE_ACTION_MODIFIED -- On_FileModified() is about to be called.
- // FILE_ACTION_RENAMED_OLD_NAME-- On_FileNameChanged() is about to be call.
- //
- //
- // NOTE: When the value of dwNotifyAction is FILE_ACTION_RENAMED_OLD_NAME,
- // szFileName will be the old name of the file, and szNewFileName will
- // be the new name of the renamed file.
- //
- // The default implementation always returns true, indicating that all notifications will
- // be sent.
- //
- // NOTE: This function may or may not be called depending upon the flags you specify to control
- // filter behavior.
- // If you are specifying filters when watching the directory, you will not get this notification
- // if the file name does not pass the filter test, even if this function returns true.
- //
-
- //
- //
- // End Override these functions (ie: don't worry about the rest of this class)
- //
-
- void SetChangedDirectoryName(const CString & strChangedDirName);//please don't use this function, it will be removed in future releases.
-
-private:
- long m_nRefCnt;
-
- CString m_strChangedDirectoryName;//will be removed in a future release.
-
- friend class CDirectoryChangeWatcher;
- friend class CDelayedDirectoryChangeHandler;
- //
- // This class keeps a reference to the CDirectoryChangeHandler
- // that was used when an object of this type is passed
- // to CDirectoryChangeWatcher::WatchDirectory().
- //
- // This way, when the CDirectoryChangeWatcher object is destroyed(or if CDirectoryChangeHandler::UnwatchDirectory() is called)
- // AFTER CDirectoryChangeWatcher::UnwatchDirecotry() or CDirectoryChangeWatcher::UnwatchAllDirectories() is called
- // the directory(or direcotries) that this
- // CDirectoryChangeWatcher object is handling will be automatically unwatched
- // If the CDirectoryChangeWatcher object is destroyed before the CDirectoryChangeHandler objects
- // that are being used with that watcher are destroyed, the reference counting prevents
- // this class from referencing a destructed object.
- // Basically, neither class needs to worry about the lifetime of the other(CDirectoryChangeWatcher && CDirectoryChangeHandler)
- //
-
- long ReferencesWatcher(CDirectoryChangeWatcher * pDirChangeWatcher);
- long ReleaseReferenceToWatcher(CDirectoryChangeWatcher * pDirChangeWatcher);
- CDirectoryChangeWatcher * m_pDirChangeWatcher;
- long m_nWatcherRefCnt; //<-- when this reaches 0, m_pDirChangeWatcher is set to NULL
- CCriticalSection m_csWatcher;
-};
-
-///////////////////////////////////////////////////////////
-
-class CDirectoryChangeWatcher
-/***************************************
- A class to monitor a directory for changes made to files in it, or it's subfolders.
- The class CDirectoryChangeHandler handles the changes. You derive a class from CDirectoryChangeHandler to handle them.
-
-
- This class uses the Win32 API ReadDirectoryChangesW() to watch a directory for file changes.
-
- Multiple directories can be watched simultaneously using a single instance of CDirectoryChangeWatcher.
- Single or multiple instances of CDirectoryChangeHandler object(s) can be used to handle changes to watched directories.
- Directories can be added and removed from the watch dynamically at run time without destroying
- the CDirectoryChangeWatcher object (or CDirectoryChangeHandler object(s).
-
- This class uses a worker thread, an io completion port, and ReadDirectoryChangesW() to monitor changes to a direcory (or subdirectories).
- There will always only be a single thread no matter how many directories are being watched(per instance of CDirectoryChangeHandler)
-
- THREAD ISSUES:
- This class uses worker threads.
- Notifications (calling CDirectoryChangeHandler's virtual functions) are executed
- in the context of either the main thread, OR in a worker thread.
-
- The 'main' thread is the thread that first calls CDirectoryChangeWatcher::WatchDirectory().
- For notifications to execute in the main thread, it's required that the calling thread(usually the main thread)
- has a message pump in order to process the notifications.
-
- For applications w/out a message pump, notifications are executed in the context of a worker thread.
-
- See the constructor for CDirectoryChangeWatcher.
-
-
-****************************************/
-{
-public:
-
- enum { //options for determining the behavior of the filter tests.
- //
- FILTERS_DONT_USE_FILTERS = 1, //never test the include/exclude filters. CDirectoryChangeHandler::On_FilterNotification() is still called.
- FILTERS_CHECK_FULL_PATH = 2, //For the file path: "C:\FolderName\SubFolder\FileName.xyz", the entire path is checked for the filter pattern.
- FILTERS_CHECK_PARTIAL_PATH = 4, //For the file path: "C:\FolderName\SubFolder\FileName.xyz", only "SubFolder\FileName.xyz" is checked against the filter pattern, provided that you are watching the folder "C:\FolderName", and you are also watching subfolders.
- FILTERS_CHECK_FILE_NAME_ONLY = 8, //For the file path: "C:\FolderName\SubFolder\FileName.xyz", only "FileName.xyz" is checked against the filter pattern.
- FILTERS_TEST_HANDLER_FIRST = 16, //test CDirectoryChangeHandler::On_FilterNotification() before checking the include/exclude filters. the default is to check the include/exclude filters first.
- FILTERS_DONT_USE_HANDLER_FILTER = 32, //CDirectoryChangeHander::On_FilterNotification() won't be called.
- FILTERS_NO_WATCHSTART_NOTIFICATION = 64,//CDirectoryChangeHander::On_WatchStarted() won't be called.
- FILTERS_NO_WATCHSTOP_NOTIFICATION = 128,//CDirectoryChangeHander::On_WatchStopped() won't be called.
- FILTERS_DEFAULT_BEHAVIOR = (FILTERS_CHECK_FILE_NAME_ONLY ),
- FILTERS_DONT_USE_ANY_FILTER_TESTS = (FILTERS_DONT_USE_FILTERS | FILTERS_DONT_USE_HANDLER_FILTER),
- FILTERS_NO_WATCH_STARTSTOP_NOTIFICATION = (FILTERS_NO_WATCHSTART_NOTIFICATION | FILTERS_NO_WATCHSTOP_NOTIFICATION)
- };
-
- //ctor/dtor
- CDirectoryChangeWatcher(bool bAppHasGUI = true, DWORD dwFilterFlags = FILTERS_DEFAULT_BEHAVIOR);//see comments in ctor .cpp file.
- virtual ~CDirectoryChangeWatcher();
-
- //
- // Starts a watch on a directory:
- //
- DWORD WatchDirectory(const CString & strDirToWatch,
- DWORD dwChangesToWatchFor,
- CDirectoryChangeHandler * pChangeHandler,
- BOOL bWatchSubDirs = FALSE,
- LPCTSTR szIncludeFilter = NULL,
- LPCTSTR szExcludeFilter = NULL);
-
- BOOL IsWatchingDirectory (const CString & strDirName)const;
- int NumWatchedDirectories()const; //counts # of directories being watched.
-
-
- BOOL UnwatchDirectory(const CString & strDirToStopWatching);//stops watching specified directory.
- BOOL UnwatchAllDirectories();//stops watching ALL watched directories.
-
- DWORD SetFilterFlags(DWORD dwFilterFlags);//sets filter behavior for directories watched AFTER this function has been called.
- DWORD GetFilterFlags()const{return m_dwFilterFlags;}
-
-protected:
-
- virtual void On_ThreadInitialize(){}//All file change notifications has taken place in the context of a worker thread...do any thread initialization here..
- virtual void On_ThreadExit(){}//do thread cleanup here
-
-private:
- friend class CDirectoryChangeHandler;
- BOOL UnwatchDirectory(CDirectoryChangeHandler * pChangeHandler);//called in CDirectoryChangeHandler::~CDirectoryChangeHandler()
-
-
- UINT static MonitorDirectoryChanges(LPVOID lpvThis );//the worker thread that monitors directories.
-
- class CDirWatchInfo
- //this class is used internally by CDirectoryChangeWatcher
- //to help manage the watched directories
- {
- private:
- CDirWatchInfo(); //private & not implemented
- CDirWatchInfo & operator=(const CDirWatchInfo & rhs);//so that they're aren't accidentally used. -- you'll get a linker error
- public:
- CDirWatchInfo(HANDLE hDir, const CString & strDirectoryName,
- CDirectoryChangeHandler * pChangeHandler,
- DWORD dwChangeFilter, BOOL bWatchSubDir,
- bool bAppHasGUI,
- LPCTSTR szIncludeFilter,
- LPCTSTR szExcludeFilter,
- DWORD dwFilterFlags);
- private:
- ~CDirWatchInfo( );//only I can delete myself....use DeleteSelf()
- public:
- void DeleteSelf(CDirectoryChangeWatcher * pWatcher);
-
- DWORD StartMonitor(HANDLE hCompPort);
- BOOL UnwatchDirectory( HANDLE hCompPort );
- protected:
- BOOL SignalShutdown( HANDLE hCompPort );
- BOOL WaitForShutdown();
- public:
- BOOL LockProperties() { return m_cs.Lock(); }
- BOOL UnlockProperties(){ return m_cs.Unlock(); }
-
- CDelayedDirectoryChangeHandler* GetChangeHandler() const;
- CDirectoryChangeHandler * GetRealChangeHandler() const;//the 'real' change handler is your CDirectoryChangeHandler derived class.
- CDirectoryChangeHandler * SetRealDirectoryChangeHandler(CDirectoryChangeHandler * pChangeHandler);
-
- BOOL CloseDirectoryHandle();
-
- //CDirectoryChangeHandler * m_pChangeHandler;
- CDelayedDirectoryChangeHandler * m_pChangeHandler;
- HANDLE m_hDir;//handle to directory that we're watching
- DWORD m_dwChangeFilter;
- BOOL m_bWatchSubDir;
- CString m_strDirName;//name of the directory that we're watching
- CHAR m_Buffer[ READ_DIR_CHANGE_BUFFER_SIZE ];//buffer for ReadDirectoryChangesW
- DWORD m_dwBufLength;//length or returned data from ReadDirectoryChangesW -- ignored?...
- OVERLAPPED m_Overlapped;
- DWORD m_dwReadDirError;//indicates the success of the call to ReadDirectoryChanges()
- CCriticalSection m_cs;
- CEvent m_StartStopEvent;
- enum eRunningState{
- RUNNING_STATE_NOT_SET, RUNNING_STATE_START_MONITORING, RUNNING_STATE_STOP, RUNNING_STATE_STOP_STEP2,
- RUNNING_STATE_STOPPED, RUNNING_STATE_NORMAL
- };
- eRunningState m_RunningState;
- };//end nested class CDirWatchInfo
-
- void ProcessChangeNotifications(IN CFileNotifyInformation & notify_info,
- IN CDirWatchInfo * pdi,
- OUT DWORD & ref_dwReadBuffer_Offset);
- friend class CDirWatchInfo;//so that CDirWatchInfo can call the following function.
- long ReleaseReferenceToWatcher(CDirectoryChangeHandler * pChangeHandler);
-
- BOOL UnwatchDirectoryBecauseOfError(CDirWatchInfo * pWatchInfo);//called in case of error.
- int AddToWatchInfo(CDirWatchInfo * pWatchInfo);
- //
- // functions for retrieving the directory watch info based on different parameters
- //
- CDirWatchInfo * GetDirWatchInfo(IN const CString & strDirName, OUT int & ref_nIdx)const;
- CDirWatchInfo * GetDirWatchInfo(IN CDirWatchInfo * pWatchInfo, OUT int & ref_nIdx)const;
- CDirWatchInfo * GetDirWatchInfo(IN CDirectoryChangeHandler * pChangeHandler, OUT int & ref_nIdx)const;
-
-
- HANDLE m_hCompPort; //i/o completion port
- HANDLE m_hThread; //MonitorDirectoryChanges() thread handle
- DWORD m_dwThreadID;
- CTypedPtrArray<CPtrArray, CDirWatchInfo*> m_DirectoriesToWatch; //holds info about the directories that we're watching.
- CCriticalSection m_csDirWatchInfo;
-
- bool m_bAppHasGUI; //dispatch to main thread, or a worker thread?
- DWORD m_dwFilterFlags;//options for determining the behavior of the filter tests.
-
-};
-
-
-#endif // !defined(AFX_DIRECTORYCHANGES_H__02E53FDE_CB22_4176_B6D7_DA3675D9F1A6__INCLUDED_)