?? filebackupe.h
字號:
}
inline void PostMessage(UINT nMsg, WPARAM wParam, LPARAM lParam) { m_objMessageQueue.PostMessage(nMsg, wParam, lParam); }
inline BOOL SetPriority(int nPriority)
{
return m_pThread ? m_pThread->SetThreadPriority(nPriority) : FALSE;
}
inline BOOL IsThreadAvailable() const { return m_pThread != NULL; }
protected:
static UINT DummyThreadProc(CWorkerThreadWrapper* pThis);
inline BOOL GetFirstMessage(UINT& nMsg, WPARAM& wParam, LPARAM& lParam) { return m_objMessageQueue.GetFirstMessage(nMsg, wParam, lParam); }
inline HANDLE GetSemaphore() const { return m_objMessageQueue.GetSemaphore(); }
protected:
AFX_THREADPROC m_pfnThreadProc;
LPVOID m_lParam;
CWinThread* m_pThread;
CMessageQueue m_objMessageQueue;
};
class CDatabaseAccessThread;
class CFileChangesHandler : public CWorkerThreadWrapper
{
public:
inline CFileChangesHandler(LPFILEBACKUP_CALLBACK pCallback, CDatabaseAccessThread* pDatabaseAccessThread) : CWorkerThreadWrapper(), m_pCallback(pCallback), m_pDatabassAccessThread(pDatabaseAccessThread), m_fIsLogging(FALSE), m_hVxD(INVALID_HANDLE_VALUE)
{
m_arrayHandleBank[0] = GetSemaphore();
m_nHandleNumber = 1;
}
virtual BOOL InitInstance();
virtual DWORD ExitInstance();
inline BOOL CreateThread(int nPriority = THREAD_PRIORITY_BELOW_NORMAL)
{
return CWorkerThreadWrapper::CreateThread((AFX_THREADPROC)(CFileBackupE::m_objInitObject.IsNT() ? CFileChangesHandler::WinNTFileChangesHandlerThreadProc : CFileChangesHandler::Win9xFileChangesHandlerThreadProc), this, nPriority);
}
inline DWORD TerminateThread(DWORD dwTimeout = 5000)
{
if ( m_pThread )
{
MESSAGE_RESULT objResult;
DWORD dwWaitResult;
if ( (objResult.m_hFinishedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL )
AfxThrowResourceException();
CWorkerThreadWrapper::PostMessage(UWM_DESTROY_WORKERTHREAD, (WPARAM)&objResult, NULL);
if ( (dwWaitResult = WaitForSingleObject(objResult.m_hFinishedEvent, dwTimeout)) != WAIT_OBJECT_0 )
{
CloseHandle(objResult.m_hFinishedEvent);
m_pThread = NULL;
return dwWaitResult;
}
else
{
CloseHandle(objResult.m_hFinishedEvent);
m_pThread = NULL;
return objResult.m_dwResult;
}
}
else
return ERROR_ACCESS_DENIED;
}
inline DWORD StartLogging(CFileFilter* pFileFilter, DWORD dwTimeout = 500)
{
if ( !pFileFilter )
return ERROR_INVALID_PARAMETER;
else if ( m_pThread )
{
MESSAGE_RESULT objResult;
DWORD dwWaitResult;
if ( m_fIsLogging )
StopLogging(dwTimeout);
if ( (objResult.m_hFinishedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL )
AfxThrowResourceException();
CWorkerThreadWrapper::PostMessage(UWM_START_LOGGING_FILE_CHANGES, (WPARAM)&objResult, (LPARAM)pFileFilter);
if ( (dwWaitResult = WaitForSingleObject(objResult.m_hFinishedEvent, dwTimeout)) != WAIT_OBJECT_0 )
{
CloseHandle(objResult.m_hFinishedEvent);
return dwWaitResult;
}
else
{
CloseHandle(objResult.m_hFinishedEvent);
return objResult.m_dwResult;
}
}
else
return ERROR_ACCESS_DENIED;
}
inline DWORD StopLogging(DWORD dwTimeout = 500)
{
if ( m_pThread )
{
MESSAGE_RESULT objResult;
DWORD dwWaitResult;
if ( (objResult.m_hFinishedEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL )
AfxThrowResourceException();
CWorkerThreadWrapper::PostMessage(UWM_STOP_LOGGING_FILE_CHANGES, (WPARAM)&objResult, NULL);
if ( (dwWaitResult = WaitForSingleObject(objResult.m_hFinishedEvent, dwTimeout)) != WAIT_OBJECT_0 )
{
CloseHandle(objResult.m_hFinishedEvent);
return dwWaitResult;
}
else
{
CloseHandle(objResult.m_hFinishedEvent);
return objResult.m_dwResult;
}
}
else
return ERROR_ACCESS_DENIED;
}
inline DWORD SetFileFilter(CFileFilter* pFileFilter, DWORD dwTimeout = 500) { return StartLogging(pFileFilter, dwTimeout); }
protected:
static UINT Win9xFileChangesHandlerThreadProc(CFileChangesHandler* pThis);
static UINT WinNTFileChangesHandlerThreadProc(CFileChangesHandler* pThis);
inline DWORD Win9xStartLoggingFileChanges(CFileFilter* pFileFilter)
{
CFileFilter::CParsedPathItem *pDriveItem, *pItem;
CString csBasePath;
TCHAR tsShortPathname[MAX_PATH];
int nShortPathnameLength;
if ( m_fIsLogging )
Win9xStopLoggingFileChanges();
#if 0
DWORD dwDataBufferLength;
dwDataBufferLength = 0;
pDriveItem = pFileFilter->GetFirstAvailableDrive();
while ( pDriveItem )
if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
{
CreateDirectory(csBasePath, NULL);
dwDataBufferLength += csBasePath.GetLength() + GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname)) + 2;
}
if ( dwDataBufferLength )
{
#ifndef UNICODE
char* pBuf = new char[++dwDataBufferLength];
PCHAR pChar = pBuf;
#else
char* pBuf = new char[++dwDataBufferLength * sizeof(WCHAR)];
int nCharCount = 0;
#endif
pDriveItem = pFileFilter->GetFirstAvailableDrive();
while ( pDriveItem )
{
if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
{
#ifndef UNICODE
strcpy(pChar, (LPCTSTR)csBasePath);
pChar += csBasePath.GetLength() + 1;
if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
{
strcpy(pChar, tsShortPathname);
pChar += nShortPathnameLength + 1;
}
else
*pChar++ = NULL;
#else
nCharCount += ::WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCTSTR)csBasePath, csBasePath.GetLength() + 1, pBuf + nCharCount, dwDataBufferLength * sizeof(WCHAR) - nCharCount, NULL, NULL);
if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
nCharCount += ::WideCharToMultiByte(CP_THREAD_ACP, 0, tsShortPathname, nShortPathnameLength + 1, pBuf + nCharCount, dwDataBufferLength * sizeof(WCHAR) - nCharCount, NULL, NULL);
else
pBuf[nCharCount++] = NULL;
#endif
}
}
#ifndef UNICODE
*pChar++ = NULL;
#else
pBuf[nCharCount++] = NULL;
#endif
if ( DeviceIoControl(m_hVxD, DIRMON_StartLogging, pBuf, dwDataBufferLength, NULL, 0, NULL, NULL) )
{
if ( (m_arrayHandleBank[1] = m_arrayAccessoryBank[1].m_objOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL )
{
m_arrayAccessoryBank[1].m_pBuffer = CLargeBufferBlockBank::Allocate();
if ( DeviceIoControl(m_hVxD, DIRMON_ReadChange, NULL, 0, m_arrayAccessoryBank[1].m_pBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, &m_arrayAccessoryBank[1].m_objOverlapped) )
{
m_arrayAccessoryBank[1].m_pParsedPathItemPointer = pItem;
m_arrayAccessoryBank[1].m_csPath = csBasePath;
m_nHandleNumber = 2;
}
else
{
DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
CloseHandle(m_arrayAccessoryBank[1].m_objOverlapped.hEvent);
CLargeBufferBlockBank::Free(m_arrayAccessoryBank[1].m_pBuffer);
}
}
else
DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
}
delete[] pBuf;
}
#else
char pBuf[MAX_PATH * 26 * 2];
char* pChar = pBuf;
pDriveItem = pFileFilter->GetFirstAvailableDrive();
while ( pDriveItem )
if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
{
CreateDirectory(csBasePath, NULL);
#ifndef UNICODE
strcpy(pChar, (LPCTSTR)csBasePath);
pChar += csBasePath.GetLength() + 1;
if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
{
strcpy(pChar, tsShortPathname);
pChar += nShortPathnameLength + 1;
}
else
*pChar++ = NULL;
#else
pChar += ::WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCTSTR)csBasePath, csBasePath.GetLength() + 1, pChar, sizeof(pBuf) - (pChar - pBuf), NULL, NULL);
if ( (nShortPathnameLength = ::GetShortPathName((LPCTSTR)csBasePath, tsShortPathname, sizeof(tsShortPathname))) != 0 )
pChar += ::WideCharToMultiByte(CP_THREAD_ACP, 0, tsShortPathname, nShortPathnameLength + 1, pChar, sizeof(pBuf) - (pChar - pBuf), NULL, NULL);
else
*pChar++ = NULL;
#endif
}
if ( pChar != pBuf )
{
*pChar++ = NULL;
if ( DeviceIoControl(m_hVxD, DIRMON_StartLogging, pBuf, pChar - pBuf, NULL, 0, NULL, NULL) )
{
if ( (m_arrayHandleBank[1] = m_arrayAccessoryBank[1].m_objOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) != NULL )
{
m_arrayAccessoryBank[1].m_pBuffer = CLargeBufferBlockBank::Allocate();
if ( DeviceIoControl(m_hVxD, DIRMON_ReadChange, NULL, 0, m_arrayAccessoryBank[1].m_pBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, &m_arrayAccessoryBank[1].m_objOverlapped) )
{
m_arrayAccessoryBank[1].m_pParsedPathItemPointer = pItem;
m_arrayAccessoryBank[1].m_csPath = csBasePath;
m_nHandleNumber = 2;
}
else
{
DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
CloseHandle(m_arrayAccessoryBank[1].m_objOverlapped.hEvent);
CLargeBufferBlockBank::Free(m_arrayAccessoryBank[1].m_pBuffer);
}
}
else
DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL);
}
}
#endif
if ( m_nHandleNumber > 1 )
{
m_pFileFilter = pFileFilter;
m_fIsLogging = TRUE;
return ERROR_SUCCESS;
}
else
return ERROR_NOT_READY;
}
inline DWORD Win9xStopLoggingFileChanges()
{
if ( m_fIsLogging )
{
DWORD dwRet = ERROR_SUCCESS;
// Actually, it's not necessary to call CancelReadChange, because StopLogging does it automatically.
// Keep this line just for more clear process.
if ( !DeviceIoControl(m_hVxD, DIRMON_CancelReadChange, NULL, 0, NULL, 0, NULL, NULL) )
dwRet = GetLastError();
if ( !DeviceIoControl(m_hVxD, DIRMON_StopLogging, NULL, 0, NULL, 0, NULL, NULL) )
dwRet = GetLastError();
if ( !CloseHandle(m_arrayAccessoryBank[1].m_objOverlapped.hEvent) )
dwRet = GetLastError();
m_arrayAccessoryBank[1].m_csPath.Empty();
CLargeBufferBlockBank::Free(m_arrayAccessoryBank[1].m_pBuffer);
m_nHandleNumber = 1;
m_fIsLogging = FALSE;
return dwRet;
}
else
return ERROR_SUCCESS;
}
inline DWORD WinNTStartLoggingFileChanges(CFileFilter* pFileFilter)
{
CFileFilter::CParsedPathItem *pDriveItem, *pItem;
CString csBasePath;
if ( m_fIsLogging )
WinNTStopLoggingFileChanges();
pDriveItem = pFileFilter->GetFirstAvailableDrive();
while ( pDriveItem )
{
if ( pFileFilter->GetNextAvailableDriveBasePath(pDriveItem, csBasePath, pItem) )
{
CreateDirectory(csBasePath, NULL);
if ( (m_arrayAccessoryBank[m_nHandleNumber].m_hFile = CreateFile(csBasePath, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL))
== INVALID_HANDLE_VALUE )
continue;
if ( (m_arrayHandleBank[m_nHandleNumber] = m_arrayAccessoryBank[m_nHandleNumber].m_objOverlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))
== NULL )
{
CloseHandle(m_arrayAccessoryBank[m_nHandleNumber].m_hFile);
continue;
}
m_arrayAccessoryBank[m_nHandleNumber].m_pBuffer = CLargeBufferBlockBank::Allocate();
if ( !ReadDirectoryChangesW(m_arrayAccessoryBank[m_nHandleNumber].m_hFile, m_arrayAccessoryBank[m_nHandleNumber].m_pBuffer, CLargeBufferBlockBank::GetBlockSize(), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE, NULL, &m_arrayAccessoryBank[m_nHandleNumber].m_objOverlapped, NULL) )
{
CloseHandle(m_arrayAccessoryBank[m_nHandleNumber].m_hFile);
CloseHandle(m_arrayAccessoryBank[m_nHandleNumber].m_objOverlapped.hEvent);
CLargeBufferBlockBank::Free(m_arrayAccessoryBank[m_nHandleNumber].m_pBuffer);
continue;
}
m_arrayAccessoryBank[m_nHandleNumber].m_pParsedPathItemPointer = pItem;
m_arrayAccessoryBank[m_nHandleNumber].m_csPath = csBasePath;
m_nHandleNumber++;
}
}
if ( m_nHandleNumber > 1 )
{
m_pFileFilter = pFileFilter;
m_fIsLogging = TRUE;
return ERROR_SUCCESS;
}
else
return ERROR_NOT_READY;
}
inline DWORD WinNTStopLoggingFileChanges()
{
if ( m_fIsLogging )
{
DWORD dwRet = ERROR_SUCCESS;
int i;
for ( i = 1; i < m_nHandleNumber; i++ )
{
if ( !CancelIo(m_arrayAccessoryBank[i].m_hFile) )
dwRet = GetLastError();
if ( !CloseHandle(m_arrayAccessoryBank[i].m_hFile) )
dwRet = GetLastError();
if ( !CloseHandle(m_arrayAccessoryBank[i].m_objOverlapped.hEvent) )
dwRet = GetLastError();
m_arrayAccessoryBank[i].m_csPath.Empty();
CLargeBufferBlockBank::Free(m_arrayAccessoryBank[i].m_pBuffer);
}
m_nHandleNumber = 1;
m_fIsLogging = FALSE;
return dwRet;
}
else
return ERROR_SUCCESS;
}
struct __tag_SpecialParamForWinNTHandleDirectoryNameChange
{
LPWSTR pStringBuffer1;
LPTSTR pStringBuffer2;
LPFILEBACKUP_CALLBACK pCallback;
LPVOID* ppPostDataPage;
PFILECHANGES_INFORMATION* ppPrevPostInfo;
PFILECHANGES_INFORMATION* pPostInfo;
};
void WinNTHandleDirectoryNameChange(
int nPathnameLength,
CFileFilter::CParsedPathItem* pParsedPathItem,
struct __tag_SpecialParamForWinNTHandleDirectoryNameChange* pExt);
protected:
HANDLE m_hVxD;
HANDLE m_arrayHandleBank[32];
class __tag_ACCESSORY_ITEM { // Actually I want to declare a struct
public:
__tag_ACCESSORY_ITEM() : m_hFile(NULL), m_pParsedPathItemPointer(NULL), m_pBuffer(NULL)
{
m_objOverlapped.Internal = m_objOverlapped.InternalHigh = 0;
m_objOverlapped.Pointer = m_objOverlapped.hEvent = NULL;
}
public:
HANDLE m_hFile;
CString m_csPath;
CFileFilter::CParsedPathItem* m_pParsedPathItemPointer;
LPVOID m_pBuffer;
OVERLAPPED m_objOverlapped;
} m_arrayAccessoryBank[32];
int m_nHandleNumber;
BOOL m_fIsLogging;
CFileFilter* m_pFileFilter;
CDatabaseAccessThread* m_pDatabassAccessThread;
LPFILEBACKUP_CALLBACK m_pCallback;
};
class CFileCopyThreadWrapper : public CWorkerThreadWrapper
{
public:
inline CFileCopyThreadWrapper(LPFILEBACKUP_CALLBACK pCallback, CDatabaseAccessThread* pDatabaseAccessThread) : CWorkerThreadWrapper(), m_pCallback(pCallback), m_pDatabaseAccessThread(pDatabaseAccessTh
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -