root/honeybow/trunk/mwwatcher/src/DirectoryChanges.h

Revision 670, 22.8 kB (checked in by chengyu, 2 years ago)

honeybow sensor mwwatcher component first public release.

Line 
1 // DirectoryChanges.h
2 //
3 // Interface for the CDirectoryChangeWatcher and CDirectoryChangeHandler classes.
4 // Copyright (C) 2001. Wes Jones (wesj@hotmail.com)
5 //
6 // This code is free for use under the following conditions:
7 //
8 //      1. You may not claim authorship of this code.
9 //      2. You may not sell or distrubute this code without author's permission.
10 //      3. You are not permitted to sell this code in it's compiled, non-compiled, executable,
11 //         or any other form.
12 //      4. Executable code excepted in the case that it is not sold separately from an application
13 //         which uses this it. This means you can use this code for your applications as you
14 //         see fit, but this code may not be sold in any form to others for use in their applications.
15 //      5. This copyright notice may not be removed.
16 //      6. Sell this code as part of a 'Programmer's Library' is stricly prohibited.
17 //
18 // If you'd like to pay me to turn this into an ActiveX/COM object so you can use it in
19 // a Visual Basic application, feel free to contact me with an offer, and I will create
20 // it for you. Otherwise, here is the source code, and you may make your own ActiveX/COM
21 // object, providing that it is not sold separately.
22 //
23 // No guarantees or warranties are expressed or implied.
24 // This code may contain bugs.
25 //
26 // Warning: May contain matter. If this should come into contact with anti-matter,
27 // a violent explosion may occur.
28 //
29 // Please let me know of any bugs, bug fixes, or enhancements made to this code.
30 // If you have ideas for this, and/or tips or admonitions, I would be glad to hear them.
31 //
32 // See notes at top of DirectoryChanges.cpp modification history and more info.
33 //
34 ////////////////////////////////////////////////////////////////////////////////////////
35 //
36
37 #if !defined(AFX_DIRECTORYCHANGES_H__02E53FDE_CB22_4176_B6D7_DA3675D9F1A6__INCLUDED_)
38 #define AFX_DIRECTORYCHANGES_H__02E53FDE_CB22_4176_B6D7_DA3675D9F1A6__INCLUDED_
39
40 #if _MSC_VER > 1000
41 #pragma once
42 #endif // _MSC_VER > 1000
43
44 #include <afxmt.h>
45 #include <afxtempl.h>
46 #include <stdio.h>
47
48 #define READ_DIR_CHANGE_BUFFER_SIZE 4096
49
50 class CFileNotifyInformation;//helper class
51 class CDirectoryChangeWatcher;
52 class CDelayedDirectoryChangeHandler;//helper class...used in implementation
53
54 class CDirectoryChangeHandler
55 /***********************************
56  A class to handle changes to files in a directory. 
57  The virtual On_Filexxx() functions are called whenever changes are made to a watched directory that is being handled by this object...
58  The On_Filexxx() functions execute in the context of the main thread if true is passed to the constructor of CDirectoryChangeWatcher,
59  OR they fire in the context of a worker thread if false is passed to the constructor of CDirectoryChangeWatcher
60
61   NOTES:
62                 A CDirectoryChangeHandler can only be used by ONE CDirectoryChangeWatcher object,
63                 but a CDirectoryChangeWatcher object may use multiple CDirectoryChangeHandler objects.
64
65         When this object is destroyed, whatever directories that it was being used to handle directory changes for
66         will automatically be 'unwatched'.
67
68         The class is reference counted.  The reference count is increased every time it is used
69         in a (successfull) call to CDirectoryChangeWatcher::WatchDirectory() and is decremented whenever
70         the directory becomes 'unwatched'.
71
72    The only notifications are File Added, Removed, Modified, and Renamed.
73    Even though the CDirectoryChangeWatcher::WatchDirectory (which'll call ReadDirectoryChangesW()) function allows you to specify flags
74    to watch for changes to last access time, last write time, attributes changed, etc,
75    these changes all map out to On_FileModified() which doesn't specify the type of modification.
76
77
78   NOTE:   The CDirectoryChangeHandler::On_Filexxx() functions
79                   are called in the context of the main thread, the thread that called CDirectoryChangeWatcher::WatchDirectory(),
80                   if you pass true to the constructor of CDirectoryChangeWatcher. This is accomplished via a hidden window,
81                   and REQUIRES that your app has a message pump.
82                   For console applications, or applications w/out a message pump, you can pass false to the constructor
83                   of CDirectoryChangeWatcher, and these notifications will fire in the context of a worker thread.  By passing false
84                   to the constructor of CDirectoryChangeWatcher, you do NOT NEED a message pump in your application.
85
86
87
88 ************************************/
89 {
90 public:
91
92         CDirectoryChangeHandler();
93         virtual ~CDirectoryChangeHandler();
94
95         //this class is reference counted
96         long AddRef();
97         long Release();
98         long CurRefCnt()const;
99
100
101         BOOL UnwatchDirectory();//causes CDirectoryChangeWatcher::UnwatchDirectory() to be called.
102         
103         const CString & GetChangedDirectoryName() const { return m_strChangedDirectoryName;}//WARNING: don't use this, this function will be removed in a future release.
104                                                                 //returns the directory name where the change occured.  This contains
105                                                            //the last directory to have changed if the same CDirectoryChangeHandler is
106                                                            //being used to watch multiple directories. It will return an empty string
107                                                            //if no changes have been made to a directory yet.   It will always be the
108                                                            //name of the currently changed directory(as specified in CDirectoryChangeWatcher::WatchDirectory())
109                                                            //if called in the context of one of the
110                                                            //On_Filexxx() functions.
111 protected:
112         //
113         //      Override these functions:
114         //      These functions are called when the directory to watch has had a change made to it
115         virtual void On_FileAdded(const CString & strFileName); //=0;
116                         //
117                         //      On_FileAdded()
118                         //
119                         //      This function is called when a file in one of the watched folders(or subfolders)
120                         //      has been created.
121                         //
122                         //      For this function to execute you'll need to specify FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME(for directories)
123                         //  when you call CDirectoryChangeWatcher::WatchDirectory()
124                         //
125         virtual void On_FileRemoved(const CString & strFileName);// = 0;
126                         //
127                         //      On_FileRemoved()
128                         //
129                         //      This function is called when a file in one of the watched folders(or subfolders)
130                         //      has been deleted(or moved to another directory)
131                         //
132                         //      For this function to execute you'll need to specify FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_DIR_NAME(for directories)
133                         //  when you call CDirectoryChangeWatcher::WatchDirecotry()
134                         //
135
136         virtual void On_FileNameChanged(const CString & strOldFileName, const CString & strNewFileName);// = 0;
137                         //
138                         //      On_FileNameChanged()
139                         //
140                         //      This function is called when a file in one of the watched folders(or subfolders)
141                         //      has been renamed.
142                         //
143                         //
144                         //      You'll need to specify FILE_NOTIFY_CHANGE_FILE_NAME (or FILE_NOTIFY_CHANGE_DIR_NAME(for directories))
145                         //      when you call CDirectoryChangeWatcher::WatchDirectory()
146                         //
147                         //     
148
149         virtual void On_FileModified(const CString & strFileName);// = 0;
150                         //
151                         //      On_FileModified()
152                         //
153                         //      This function is called whenever an attribute specified by the watch
154                         //      filter has changed on a file in the watched directory or
155                         //
156                         //      Specify any of the following flags when you call CDirectoryChangeWatcher::WatchDirectory()
157                         // 
158                         //
159                         //      FILE_NOTIFY_CHANGE_ATTRIBUTES
160                         //      FILE_NOTIFY_CHANGE_SIZE
161                         //      FILE_NOTIFY_CHANGE_LAST_WRITE
162                         //      FILE_NOTIFY_CHANGE_LAST_ACCESS
163                         //      FILE_NOTIFY_CHANGE_CREATION (* See Note # 1* )
164                         //      FILE_NOTIFY_CHANGE_SECURITY
165                         //
166                         //     
167                         //      General Note)  Windows tries to optimize some of these notifications.  You may not get
168                         //                                 a notification every single time a file is accessed for example. 
169                         //                                 There's a MS KB article or something on this(sorry forgot which one).
170                         //
171                         //      Note #1 )   This notification isn't what you might think(FILE_NOTIFY_CHANGE_CREATION).
172                         //                              See the help files for ReadDirectoryChangesW...
173                         //                              This notifies you of a change to the file's
174                         //                              creation time, not when the file is created. 
175                         //                              Use FILE_NOTIFY_CHANGE_FILE_NAME to know about newly created files.
176                         //
177
178         virtual void On_ReadDirectoryChangesError(DWORD dwError, const CString & strDirectoryName);
179                         //
180                         //      On_ReadDirectoryChangesError()
181                         //
182                         //      This function is called when ReadDirectoryChangesW() fails during normal
183                         //      operation (ie: some time after you've called CDirectoryChangeWatcher::WatchDirectory())
184                         //
185                         //
186                         //      NOTE:  *** READ THIS *** READ THIS *** READ THIS *** READ THIS ***
187                         //
188                         //      NOTE: If this function has been called, the watched directory has been automatically unwatched.
189                         //                      You will not receive any further notifications for that directory until
190                         //                      you call CDirectoryChangeWatcher::WatchDirectory() again.
191                         //
192                         //      On_WatchStopped() will not be called.
193
194
195         virtual void On_WatchStarted(DWORD dwError, const CString & strDirectoryName);
196                         //
197                         //      void On_WatchStarted()
198                         //
199                         //      This function is called when a directory watch has begun. 
200                         //      It will be called whether CDirectoryChangeWatcher::WatchDirectory() is successful or not. Check the dwError parameter.
201                         //
202                         //      PARAMETERS:
203                         //      DWORD dwError                                    -- 0 if successful, else it's the return value of GetLastError()
204                         //                                                                              indicating why the watch failed.
205                         //      const CString & strDirectoryName -- The full path and name of the directory being watched.
206         
207         virtual void On_WatchStopped(const CString & strDirectoryName);
208                         //
209                         //      void On_WatchStopped()
210                         //
211                         //      This function is called when a directory is unwatched (except on the case of the direcotry being unwatched due to an error)
212                         //
213                         //      WARNING:  *** READ THIS *** READ THIS *** READ THIS *** READ THIS ***
214                         //
215                         //      This function MAY be called before the destructor of CDirectoryChangeWatcher
216                         //      finishes. 
217                         //
218                         //      Be careful if your implementation of this fuction
219                         //      interacts with some sort of a window handle or other object(a class, a file, etc.). 
220                         //      It's possible that that object/window handle will NOT be valid anymore the very last time
221                         //      that On_WatchStopped() is called. 
222                         //      This scenario is likely if the CDirectoryChangeWatcher instance is currently watching a
223                         //      directory, and it's destructor is called some time AFTER these objects/windows
224                         //      your change handler interacts with have been destroyed.
225                         //     
226                         //      If your CDirectoryChangeHandler derived class interacts w/ a window or other
227                         //      object, it's a good idea to unwatch any directories before the object/window is destroyed.
228                         //      Otherwise, place tests for valid objects/windows in the implementation of this function.
229                         //
230                         //  Failure to follow either tip can result in a mysterious RTFM error, or a 'Run time errors'
231                         //
232
233         virtual bool On_FilterNotification(DWORD dwNotifyAction, LPCTSTR szFileName, LPCTSTR szNewFileName);
234                         //
235                         //      bool On_FilterNotification(DWORD dwNotifyAction, LPCTSTR szFileName, LPCTSTR szNewFileName);
236                         //
237                         //      This function gives your class a chance to filter unwanted notifications.
238                         //
239                         //      PARAMETERS:
240                         //                      DWORD   dwNotifyAction  -- specifies the event to filter
241                         //                      LPCTSTR szFileName              -- specifies the name of the file for the event.
242                         //                      LPCTSTR szNewFileName   -- specifies the new file name of a file that has been renamed.
243                         //
244                         //                      **      szFileName and szNewFileName will always be the full path and file name with extention.
245                         //
246                         //      RETURN VALUE:
247                         //                      return true , and you will receive the notification.
248                         //                      return false, and your class will NOT receive the notification.
249                         //
250                         //      Valid values of dwNotifyAction:
251                         //              FILE_ACTION_ADDED                       -- On_FileAdded() is about to be called.
252                         //              FILE_ACTION_REMOVED                     -- On_FileRemoved() is about to be called.
253                         //              FILE_ACTION_MODIFIED            -- On_FileModified() is about to be called.
254                         //              FILE_ACTION_RENAMED_OLD_NAME-- On_FileNameChanged() is about to be call.
255                         //
256                         //       
257                         //      NOTE:  When the value of dwNotifyAction is FILE_ACTION_RENAMED_OLD_NAME,
258                         //                      szFileName will be the old name of the file, and szNewFileName will
259                         //                      be the new name of the renamed file.
260                         //
261                         //  The default implementation always returns true, indicating that all notifications will
262                         //      be sent.
263                         //
264                         //      NOTE:   This function may or may not be called depending upon the flags you specify to control
265                         //                      filter behavior.
266                         //                      If you are specifying filters when watching the directory, you will not get this notification
267                         //                      if the file name does not pass the filter test, even if this function returns true.
268                         //
269         virtual void On_FileUploaded(const CString & strFileName);
270                        
271         //
272         //
273         //      End Override these functions (ie: don't worry about the rest of this class)
274         //
275         
276         void SetChangedDirectoryName(const CString & strChangedDirName);//please don't use this function, it will be removed in future releases.
277         
278         BOOL FtpAddFile(const CString &strFileName);
279
280         BOOL isInBlackList(const CString &strFileName);
281         BOOL isInWhiteList(const CString &strFileName);
282
283 private:
284         long m_nRefCnt;
285        
286         CString m_strChangedDirectoryName;//will be removed in a future release.
287
288         friend class CDirectoryChangeWatcher;
289         friend class CDelayedDirectoryChangeHandler;
290         //
291         //      This class keeps a reference to the CDirectoryChangeHandler
292         //      that was used when an object of this type is passed
293         //      to CDirectoryChangeWatcher::WatchDirectory().
294         //
295         //      This way, when the CDirectoryChangeWatcher object is destroyed(or if CDirectoryChangeHandler::UnwatchDirectory() is called)
296         //      AFTER CDirectoryChangeWatcher::UnwatchDirecotry() or CDirectoryChangeWatcher::UnwatchAllDirectories() is called
297         //      the directory(or direcotries) that this
298         //      CDirectoryChangeWatcher object is handling will be automatically unwatched
299         //      If the CDirectoryChangeWatcher object is destroyed before the CDirectoryChangeHandler objects
300         //      that are being used with that watcher are destroyed, the reference counting prevents
301         //      this class from referencing a destructed object.
302         //      Basically, neither class needs to worry about the lifetime of the other(CDirectoryChangeWatcher && CDirectoryChangeHandler)
303         //
304
305         long  ReferencesWatcher(CDirectoryChangeWatcher * pDirChangeWatcher);
306         long  ReleaseReferenceToWatcher(CDirectoryChangeWatcher * pDirChangeWatcher);
307         CDirectoryChangeWatcher * m_pDirChangeWatcher;
308         long   m_nWatcherRefCnt; //<-- when this reaches 0, m_pDirChangeWatcher is set to NULL
309         CCriticalSection m_csWatcher;
310 };
311
312 ///////////////////////////////////////////////////////////
313
314 class CDirectoryChangeWatcher 
315 /***************************************
316         A class to monitor a directory for changes made to files in it, or it's subfolders.
317         The class CDirectoryChangeHandler handles the changes. You derive a class from CDirectoryChangeHandler to handle them.
318
319
320         This class uses the Win32 API ReadDirectoryChangesW() to watch a directory for file changes.
321
322         Multiple directories can be watched simultaneously using a single instance of CDirectoryChangeWatcher.
323         Single or multiple instances of CDirectoryChangeHandler object(s) can be used to handle changes to watched directories.
324         Directories can be added and removed from the watch dynamically at run time without destroying
325         the CDirectoryChangeWatcher object (or CDirectoryChangeHandler object(s).
326
327         This class uses a worker thread, an io completion port, and ReadDirectoryChangesW() to monitor changes to a direcory (or subdirectories).
328         There will always only be a single thread no matter how many directories are being watched(per instance of CDirectoryChangeHandler)
329
330         THREAD ISSUES:
331     This class uses worker threads.
332         Notifications (calling CDirectoryChangeHandler's virtual functions) are executed
333         in the context of either the main thread, OR in a worker thread.
334
335         The 'main' thread is the thread that first calls CDirectoryChangeWatcher::WatchDirectory().
336         For notifications to execute in the main thread, it's required that the calling thread(usually the main thread)
337         has a message pump in order to process the notifications.
338
339         For applications w/out a message pump, notifications are executed in the context of a worker thread.
340
341         See the constructor for CDirectoryChangeWatcher.
342
343  
344 ****************************************/
345 {
346 public:
347
348         enum    {  //options for determining the behavior of the filter tests.
349                            //
350                            FILTERS_DONT_USE_FILTERS             = 1, //never test the include/exclude filters. CDirectoryChangeHandler::On_FilterNotification() is still called.
351                            FILTERS_CHECK_FULL_PATH              = 2, //For the file path: "C:\FolderName\SubFolder\FileName.xyz", the entire path is checked for the filter pattern.
352                            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.
353                            FILTERS_CHECK_FILE_NAME_ONLY = 8, //For the file path: "C:\FolderName\SubFolder\FileName.xyz", only "FileName.xyz" is checked against the filter pattern.
354                            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.
355                            FILTERS_DONT_USE_HANDLER_FILTER = 32, //CDirectoryChangeHander::On_FilterNotification() won't be called.
356                            FILTERS_NO_WATCHSTART_NOTIFICATION = 64,//CDirectoryChangeHander::On_WatchStarted() won't be called.
357                            FILTERS_NO_WATCHSTOP_NOTIFICATION  = 128,//CDirectoryChangeHander::On_WatchStopped() won't be called.
358                            FILTERS_DEFAULT_BEHAVIOR     = (FILTERS_CHECK_FILE_NAME_ONLY ),
359                            FILTERS_DONT_USE_ANY_FILTER_TESTS = (FILTERS_DONT_USE_FILTERS | FILTERS_DONT_USE_HANDLER_FILTER),
360                            FILTERS_NO_WATCH_STARTSTOP_NOTIFICATION = (FILTERS_NO_WATCHSTART_NOTIFICATION | FILTERS_NO_WATCHSTOP_NOTIFICATION)
361                         };
362
363         //ctor/dtor
364         CDirectoryChangeWatcher(bool bAppHasGUI = true, DWORD dwFilterFlags = FILTERS_DEFAULT_BEHAVIOR);//see comments in ctor .cpp file.
365         virtual ~CDirectoryChangeWatcher();
366
367         //
368         //      Starts a watch on a directory:
369         //
370         DWORD   WatchDirectory(const CString & strDirToWatch,
371                                                    DWORD dwChangesToWatchFor,
372                                                    CDirectoryChangeHandler * pChangeHandler,
373                                                    BOOL bWatchSubDirs = FALSE,
374                                                    LPCTSTR szIncludeFilter = NULL,
375                                                    LPCTSTR szExcludeFilter = NULL);
376
377         BOOL    IsWatchingDirectory (const CString & strDirName)const;
378         int             NumWatchedDirectories()const; //counts # of directories being watched.
379
380        
381         BOOL    UnwatchDirectory(const CString & strDirToStopWatching);//stops watching specified directory.
382         BOOL    UnwatchAllDirectories();//stops watching ALL watched directories.
383
384         DWORD   SetFilterFlags(DWORD dwFilterFlags);//sets filter behavior for directories watched AFTER this function has been called.
385         DWORD   GetFilterFlags()const{return m_dwFilterFlags;}
386
387 protected:
388        
389         virtual void On_ThreadInitialize(){}//All file change notifications has taken place in the context of a worker thread...do any thread initialization here..
390         virtual void On_ThreadExit(){}//do thread cleanup here
391         
392 private:
393         friend class CDirectoryChangeHandler;
394         BOOL UnwatchDirectory(CDirectoryChangeHandler * pChangeHandler);//called in CDirectoryChangeHandler::~CDirectoryChangeHandler()
395
396
397         UINT static MonitorDirectoryChanges(LPVOID lpvThis );//the worker thread that monitors directories.
398         
399         class CDirWatchInfo
400                 //this class is used internally by CDirectoryChangeWatcher
401                 //to help manage the watched directories
402         {
403         private:
404                 CDirWatchInfo();                //private & not implemented
405                 CDirWatchInfo & operator=(const CDirWatchInfo & rhs);//so that they're aren't accidentally used. -- you'll get a linker error
406         public:
407                 CDirWatchInfo(HANDLE hDir, const CString & strDirectoryName,
408                                           CDirectoryChangeHandler * pChangeHandler,
409                                           DWORD dwChangeFilter, BOOL bWatchSubDir,
410                                           bool bAppHasGUI,
411                                           LPCTSTR szIncludeFilter,
412                                           LPCTSTR szExcludeFilter,
413                                           DWORD dwFilterFlags);
414         private:
415                 ~CDirWatchInfo( );//only I can delete myself....use DeleteSelf()
416         public:
417                 void DeleteSelf(CDirectoryChangeWatcher * pWatcher);
418                
419                 DWORD StartMonitor(HANDLE hCompPort);
420                 BOOL UnwatchDirectory( HANDLE hCompPort );
421         protected:
422                 BOOL SignalShutdown( HANDLE hCompPort );
423                 BOOL WaitForShutdown();                   
424         public:
425                 BOOL LockProperties() { return m_cs.Lock(); }
426                 BOOL UnlockProperties(){ return m_cs.Unlock();  }
427
428                 CDelayedDirectoryChangeHandler* GetChangeHandler() const;
429                 CDirectoryChangeHandler * GetRealChangeHandler() const;//the 'real' change handler is your CDirectoryChangeHandler derived class.
430                 CDirectoryChangeHandler * SetRealDirectoryChangeHandler(CDirectoryChangeHandler * pChangeHandler);
431                
432                 BOOL CloseDirectoryHandle();
433                
434                 //CDirectoryChangeHandler * m_pChangeHandler;
435                 CDelayedDirectoryChangeHandler * m_pChangeHandler;
436                 HANDLE      m_hDir;//handle to directory that we're watching
437                 DWORD           m_dwChangeFilter;
438                 BOOL            m_bWatchSubDir;
439                 CString     m_strDirName;//name of the directory that we're watching
440                 CHAR        m_Buffer[ READ_DIR_CHANGE_BUFFER_SIZE ];//buffer for ReadDirectoryChangesW
441                 DWORD       m_dwBufLength;//length or returned data from ReadDirectoryChangesW -- ignored?...
442                 OVERLAPPED  m_Overlapped;
443                 DWORD           m_dwReadDirError;//indicates the success of the call to ReadDirectoryChanges()
444                 CCriticalSection m_cs;
445                 CEvent          m_StartStopEvent;
446                 enum eRunningState{
447                          RUNNING_STATE_NOT_SET, RUNNING_STATE_START_MONITORING, RUNNING_STATE_STOP, RUNNING_STATE_STOP_STEP2,
448                           RUNNING_STATE_STOPPED, RUNNING_STATE_NORMAL
449                          };
450                 eRunningState m_RunningState;
451                 };//end nested class CDirWatchInfo
452
453         void ProcessChangeNotifications(IN CFileNotifyInformation & notify_info,
454                                                                         IN CDirWatchInfo * pdi,
455                                                                         OUT DWORD & ref_dwReadBuffer_Offset);
456         friend class CDirWatchInfo;//so that CDirWatchInfo can call the following function.
457         long ReleaseReferenceToWatcher(CDirectoryChangeHandler * pChangeHandler);
458
459         BOOL    UnwatchDirectoryBecauseOfError(CDirWatchInfo * pWatchInfo);//called in case of error.
460         int             AddToWatchInfo(CDirWatchInfo * pWatchInfo);
461         //
462         //      functions for retrieving the directory watch info based on different parameters
463         //
464         CDirWatchInfo * GetDirWatchInfo(IN const CString & strDirName, OUT int & ref_nIdx)const;
465         CDirWatchInfo * GetDirWatchInfo(IN CDirWatchInfo * pWatchInfo, OUT int & ref_nIdx)const;
466         CDirWatchInfo * GetDirWatchInfo(IN CDirectoryChangeHandler * pChangeHandler, OUT int & ref_nIdx)const;
467        
468
469         HANDLE m_hCompPort;     //i/o completion port
470         HANDLE m_hThread;       //MonitorDirectoryChanges() thread handle
471         DWORD  m_dwThreadID;
472         CTypedPtrArray<CPtrArray, CDirWatchInfo*> m_DirectoriesToWatch; //holds info about the directories that we're watching.
473         CCriticalSection m_csDirWatchInfo;
474
475         bool    m_bAppHasGUI; //dispatch to main thread, or a worker thread?
476         DWORD   m_dwFilterFlags;//options for determining the behavior of the filter tests.
477 };
478
479
480 #endif // !defined(AFX_DIRECTORYCHANGES_H__02E53FDE_CB22_4176_B6D7_DA3675D9F1A6__INCLUDED_)
Note: See TracBrowser for help on using the browser.