264 lines
8.4 KiB
C++
264 lines
8.4 KiB
C++
// ==========================================================================
|
|
// Class Implementation : COXWatchedDir
|
|
// ==========================================================================
|
|
|
|
// Source file : OXWatchedDir.cpp
|
|
|
|
// Version: 9.3
|
|
|
|
// This software along with its related components, documentation and files ("The Libraries")
|
|
// is © 1994-2007 The Code Project (1612916 Ontario Limited) and use of The Libraries is
|
|
// governed by a software license agreement ("Agreement"). Copies of the Agreement are
|
|
// available at The Code Project (www.codeproject.com), as part of the package you downloaded
|
|
// to obtain this file, or directly from our office. For a copy of the license governing
|
|
// this software, you may contact us at legalaffairs@codeproject.com, or by calling 416-849-8900.
|
|
|
|
// //////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "stdafx.h"
|
|
#include "OXWatchedDir.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// COXWatchedDir
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Definition of static members
|
|
#if defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
DWORD COXWatchedDir::dwBytesReturned = 0;
|
|
// --- Used only in the call of the ReadDirectoryChangesW() function
|
|
#endif // defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
|
|
// Data members -------------------------------------------------------------
|
|
// protected:
|
|
// CString m_sPath;
|
|
// --- Directory to be watched
|
|
|
|
// BOOL m_bWatchSubTree;
|
|
// --- Flag for monitoring directory or directory tree
|
|
|
|
// DWORD m_dwWatchFilter;
|
|
// --- Filter conditions to watch for
|
|
|
|
// HWND m_hwndWindowToNotify;
|
|
// --- Handle of the window to be notified
|
|
|
|
// BOOL m_bPost;
|
|
// --- Flag for posting or sending
|
|
|
|
// HANDLE m_hEvent;
|
|
// --- Handle of the event to be signaled
|
|
|
|
// #if defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
// BOOL m_bExtended;
|
|
// --- Is extended info availanle
|
|
|
|
// HANDLE m_hDirectory;
|
|
// --- Handle to the directory to be watched
|
|
|
|
// LPVOID m_lpBuffer;
|
|
// --- Pointer to the buffer to receive the read results
|
|
|
|
// DWORD m_nBufferLength;
|
|
// --- Length of lpBuffer
|
|
|
|
// OVERLAPPED* m_pOverlapped;
|
|
// --- Pointer to overlapped structure
|
|
// #endif // defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
|
|
// private:
|
|
|
|
// Member functions ---------------------------------------------------------
|
|
// public:
|
|
// protected:
|
|
|
|
COXWatchedDir::COXWatchedDir(CString sPath, BOOL bWatchSubTree, DWORD dwWatchFilter, BOOL bExtended)
|
|
// --- In : sPath: the path to be watched
|
|
// bWatchSubTree: indicates whether to watch subtree or not
|
|
// dwWatchFilter: specifys which type of changes should be reported
|
|
// For possible values see public data members Notification types
|
|
// bExtended: if TRUE - extended info is available
|
|
// --- Out :
|
|
// --- Returns :
|
|
// --- Effect : constructs the object
|
|
:
|
|
m_sPath(sPath),
|
|
m_bWatchSubTree(bWatchSubTree),
|
|
m_dwWatchFilter(dwWatchFilter),
|
|
m_hwndWindowToNotify(NULL),
|
|
m_bPost(TRUE),
|
|
m_hEvent(NULL)
|
|
#if defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
// Extended info is supported
|
|
,
|
|
m_bExtended(bExtended),
|
|
m_hDirectory(NULL),
|
|
m_lpBuffer(NULL),
|
|
m_nBufferLength(0),
|
|
m_pOverlapped(NULL)
|
|
{
|
|
}
|
|
#else
|
|
{
|
|
UNUSED_ALWAYS(bExtended);
|
|
}
|
|
#endif // defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
|
|
COXWatchedDir::~COXWatchedDir()
|
|
// --- In :
|
|
// --- Out :
|
|
// --- Returns :
|
|
// --- Effect : Object destructor
|
|
{
|
|
#if defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
if(m_bExtended)
|
|
{
|
|
if(!HasOverlappedIoCompleted(m_pOverlapped))
|
|
{
|
|
::CancelIo(m_hDirectory);
|
|
}
|
|
|
|
delete m_pOverlapped;
|
|
::CloseHandle(m_hEvent);
|
|
::CloseHandle(m_hDirectory);
|
|
delete [] m_lpBuffer;
|
|
}
|
|
else
|
|
#endif // defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
|
|
::FindCloseChangeNotification(m_hEvent);
|
|
}
|
|
|
|
BOOL COXWatchedDir::FindFirstHandle(HRESULT& rhrResult)
|
|
// --- In :
|
|
// --- Out : rhrResult: HERESULT of the last operation inside the function
|
|
// --- Returns : TRUE if object is successfuly initialized
|
|
// --- Effect : Initializes the object and creates the handle used for wait functions
|
|
{
|
|
rhrResult = ERROR_SUCCESS;
|
|
|
|
#if defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
// Extended info is supported
|
|
|
|
if(m_bExtended)
|
|
{ // Extended info will be supported
|
|
m_nBufferLength = sizeof(FILE_NOTIFY_INFORMATION) + _MAX_PATH * sizeof(TCHAR) * 2;
|
|
m_lpBuffer = new char[m_nBufferLength];
|
|
|
|
// Create directory handle
|
|
m_hDirectory = ::CreateFile(m_sPath, // pointer to the file name
|
|
FILE_LIST_DIRECTORY, // access (read-write) mode
|
|
FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE, // share mode
|
|
NULL, // security descriptor
|
|
OPEN_EXISTING, // how to create
|
|
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, // file attributes
|
|
NULL); // file with attributes to copy
|
|
if(m_hDirectory != INVALID_HANDLE_VALUE)
|
|
{ //... Directory handle is created.
|
|
m_hEvent = ::CreateEvent(NULL, // pointer to security attributes
|
|
TRUE, // flag for manual-reset event
|
|
FALSE, // flag for initial state
|
|
NULL); // pointer to event-object name
|
|
// In this case unnamed event
|
|
if(m_hEvent != NULL)
|
|
{ // ... Event created.
|
|
m_pOverlapped = new OVERLAPPED;
|
|
m_pOverlapped->hEvent = m_hEvent;
|
|
BOOL bRetVal = ::ReadDirectoryChangesW(
|
|
m_hDirectory, // handle to the directory to be watched
|
|
m_lpBuffer, // pointer to the buffer to receive the read results
|
|
m_nBufferLength, // length of lpBuffer
|
|
m_bWatchSubTree, // flag for monitoring directory or directory tree
|
|
m_dwWatchFilter, // filter conditions to watch for
|
|
&dwBytesReturned,// number of bytes returned. For asynchronous calls, this parameter is undefined
|
|
m_pOverlapped, // pointer to structure needed for overlapped I/O
|
|
NULL); //FileIOCompletionRoutine); // pointer to completion routine
|
|
if(bRetVal != FALSE)
|
|
{ // It's OK
|
|
return TRUE;
|
|
}
|
|
else
|
|
{ // Something wrong. Do cleanup and try FindFirstChangeNotification
|
|
rhrResult = HRESULT_FROM_WIN32(::GetLastError());
|
|
}
|
|
delete m_pOverlapped;
|
|
m_pOverlapped = NULL;
|
|
|
|
::CloseHandle(m_hEvent);
|
|
m_hEvent = NULL;
|
|
}
|
|
else
|
|
{ //if(m_hEvent != NULL)
|
|
rhrResult = HRESULT_FROM_WIN32(::GetLastError());
|
|
}
|
|
::CloseHandle(m_hDirectory);
|
|
m_hDirectory = NULL;
|
|
}
|
|
else
|
|
{ // if(m_hDirectory !=0 )
|
|
rhrResult = HRESULT_FROM_WIN32(::GetLastError());
|
|
}
|
|
delete [] m_lpBuffer;
|
|
m_lpBuffer = NULL;
|
|
m_nBufferLength = 0;
|
|
m_bExtended = FALSE;
|
|
}
|
|
#endif // defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
|
|
|
|
// No extended information is suported. Try FindFirstChangeNotification()
|
|
m_hEvent = ::FindFirstChangeNotification(m_sPath, // pointer to name of directory to watch
|
|
m_bWatchSubTree, // flag for monitoring directory or directory tree
|
|
m_dwWatchFilter); // filter conditions to watch for
|
|
if(m_hEvent != INVALID_HANDLE_VALUE)
|
|
{
|
|
// OK
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
rhrResult = HRESULT_FROM_WIN32(::GetLastError());
|
|
m_hEvent = NULL;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL COXWatchedDir::FindNextHandle(HANDLE& hHandle)
|
|
// --- In :
|
|
// --- Out : rhrResult: HERESULT of the last operation inside the function
|
|
// --- Returns : TRUE if success
|
|
// --- Effect : Reinitializes the handle used for wait functions
|
|
{
|
|
#if defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
// Extended info is supported
|
|
if(m_bExtended)
|
|
{
|
|
::ResetEvent(hHandle);
|
|
return ::ReadDirectoryChangesW(m_hDirectory, // handle to the directory to be watched
|
|
m_lpBuffer, // pointer to the buffer to receive the read results
|
|
m_nBufferLength, // length of lpBuffer
|
|
m_bWatchSubTree, // flag for monitoring directory or directory tree
|
|
m_dwWatchFilter, // filter conditions to watch for
|
|
&dwBytesReturned, // number of bytes returned. For asynchronous calls, this parameter is undefined
|
|
m_pOverlapped, // pointer to structure needed for overlapped I/O
|
|
NULL); // pointer to completion routine
|
|
}
|
|
else
|
|
#endif // defined(_UNICODE) && (_WIN32_WINNT >= 0x400)
|
|
|
|
return ::FindNextChangeNotification(hHandle);
|
|
}
|
|
|
|
|
|
// private:
|
|
|
|
// //////////////////////////////////////////////////////////////////////////
|
|
|