📄 filebackupe.cpp
字号:
if ( pPrevChild == NULL )
{
pChild->m_pNextSibling = m_pFirstChild;
m_pFirstChild = pChild;
}
else
{
pChild->m_pNextSibling = pPrevChild->m_pNextSibling;
pPrevChild->m_pNextSibling = pChild;
}
if ( fIsLastName )
return TRUE;
else
return pChild->AddExcludePath(pctsPath + nLen + 1, fUnderIncludePath);
}
}
}
return FALSE;
}
UINT CFileBackupE::CWorkerThreadWrapper::DummyThreadProc(CWorkerThreadWrapper* pThis)
{
UINT nRet = pThis->m_pfnThreadProc(pThis->m_lParam);
if ( nRet == ERROR_SUCCESS )
return pThis->ExitInstance();
else
{
pThis->ExitInstance();
return nRet;
}
}
BOOL CFileBackupE::CFileChangesHandler::InitInstance()
{
if ( CFileBackupE::m_objInitObject.IsNT() )
{
}
else
{
if ( (m_hVxD = CreateFile(_T("\\\\.\\dirmon.vxd"), 0, 0, NULL, 0, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, NULL)) == INVALID_HANDLE_VALUE )
{
#if 0
THROW(new CVxDException(TRUE, ::GetLastError(), _T(".\\dirmon.vxd")));
#else
if ( m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {LOAD_VXD_ERROR, _T(".\\dirmon.vxd"), NULL, ::GetLastError(), 0};
m_pCallback(¶m);
}
#endif
CFileBackupE::m_objInitObject.DebugPrint(_T("CFileBackupE::CFileChangesHandler::InitInstance() FAILED\n"));
return FALSE;
}
}
CFileBackupE::m_objInitObject.DebugPrint(_T("CFileBackupE::CFileChangesHandler::InitInstance()\n"));
return TRUE;
}
DWORD CFileBackupE::CFileChangesHandler::ExitInstance()
{
m_pThread = NULL;
CFileBackupE::m_objInitObject.DebugPrint(_T("CFileBackupE::CFileChangesHandler::ExitInstance()\n"));
return ERROR_SUCCESS;
}
UINT CFileBackupE::CFileChangesHandler::Win9xFileChangesHandlerThreadProc(CFileChangesHandler* pThis)
{
DWORD dwWaitResult;
int nIndex;
UINT nMsg;
WPARAM wParam;
LPARAM lParam;
while ( 1 )
{
dwWaitResult = ::WaitForMultipleObjects(pThis->m_nHandleNumber, pThis->m_arrayHandleBank, FALSE, INFINITE);
if ( dwWaitResult >= WAIT_ABANDONED_0 )
{
if ( (nIndex = dwWaitResult - WAIT_ABANDONED_0) == 0 )
{
// Something wrong with the message queue
break;
}
else
{
// The file handle of directory changed
}
}
else
{
if ( dwWaitResult - WAIT_OBJECT_0 == 0 )
{
// Got new message
if ( pThis->GetFirstMessage(nMsg, wParam, lParam) )
{
switch ( nMsg )
{
case UWM_DESTROY_WORKERTHREAD:
if ( wParam )
{
((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->Win9xStopLoggingFileChanges();
SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
}
else
pThis->Win9xStopLoggingFileChanges();
return ERROR_SUCCESS;
case UWM_START_LOGGING_FILE_CHANGES:
if ( wParam )
{
((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->Win9xStartLoggingFileChanges((CFileFilter*)lParam);
SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
}
else
pThis->Win9xStartLoggingFileChanges((CFileFilter*)lParam);
continue;
case UWM_STOP_LOGGING_FILE_CHANGES:
if ( wParam )
{
((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->Win9xStopLoggingFileChanges();
SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
}
else
pThis->Win9xStopLoggingFileChanges();
continue;
}
}
}
// Check any directory handle is ready
for ( nIndex = 1; nIndex < pThis->m_nHandleNumber; nIndex++ )
if ( WaitForSingleObject(pThis->m_arrayHandleBank[nIndex], 0) == WAIT_OBJECT_0 )
{
// Some file changed
ResetEvent(pThis->m_arrayHandleBank[nIndex]);
}
}
}
return ERROR_SUCCESS;
}
void CFileBackupE::CFileChangesHandler::WinNTHandleDirectoryNameChange(
int nPathnameLength,
CFileFilter::CParsedPathItem* pParsedPathItem,
struct __tag_SpecialParamForWinNTHandleDirectoryNameChange* pExt)
{
}
UINT CFileBackupE::CFileChangesHandler::WinNTFileChangesHandlerThreadProc(CFileChangesHandler* pThis)
{
DWORD dwWaitResult;
int nIndex;
UINT nMsg;
WPARAM wParam;
LPARAM lParam;
time_t tCurrent;
while ( 1 )
{
dwWaitResult = ::WaitForMultipleObjects(pThis->m_nHandleNumber, pThis->m_arrayHandleBank, FALSE, INFINITE);
if ( dwWaitResult >= WAIT_ABANDONED_0 )
{
if ( (nIndex = dwWaitResult - WAIT_ABANDONED_0) == 0 )
{
// Something wrong with the message queue
break;
}
else
{
// The file handle of directory changed
}
}
else
{
tCurrent = time(NULL);
if ( dwWaitResult - WAIT_OBJECT_0 == 0 )
{
// Got new message
if ( pThis->GetFirstMessage(nMsg, wParam, lParam) )
{
switch ( nMsg )
{
case UWM_DESTROY_WORKERTHREAD:
if ( wParam )
{
((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->WinNTStopLoggingFileChanges();
SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
}
else
pThis->WinNTStopLoggingFileChanges();
return ERROR_SUCCESS;
case UWM_START_LOGGING_FILE_CHANGES:
if ( wParam )
{
((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->WinNTStartLoggingFileChanges((CFileFilter*)lParam);
SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
}
else
pThis->WinNTStartLoggingFileChanges((CFileFilter*)lParam);
continue;
case UWM_STOP_LOGGING_FILE_CHANGES:
if ( wParam )
{
((MESSAGE_RESULT*)wParam)->m_dwResult = pThis->WinNTStopLoggingFileChanges();
SetEvent(((MESSAGE_RESULT*)wParam)->m_hFinishedEvent);
}
else
pThis->WinNTStopLoggingFileChanges();
continue;
}
}
}
// Check any directory handle is ready
for ( nIndex = 1; nIndex < pThis->m_nHandleNumber; nIndex++ )
if ( WaitForSingleObject(pThis->m_arrayHandleBank[nIndex], 0) == WAIT_OBJECT_0 )
{
// Some file changed
__tag_ACCESSORY_ITEM* pAccessoryItem = pThis->m_arrayAccessoryBank + nIndex;
PFILE_NOTIFY_INFORMATION pNotifyInfo = (PFILE_NOTIFY_INFORMATION)pAccessoryItem->m_pBuffer;
CFileFilter::CParsedPathItem *pParsedPathItem = pAccessoryItem->m_pParsedPathItemPointer;
LPVOID pPostDataPage = NULL;
PFILECHANGES_INFORMATION pPrevPostInfo, pPostInfo, pTempPostInfo;
LPVOID pTempStringBuffer = CLargeBufferBlockBank::Allocate();
LPVOID pTempStringBufferForDirectory = NULL;
PWCHAR pwsTemp;
PTCHAR ptsTemp;
int nPathnameLength;
int n;
while ( 1 )
{
if ( pNotifyInfo->Action == FILE_ACTION_ADDED || pNotifyInfo->Action == FILE_ACTION_MODIFIED || pNotifyInfo->Action == FILE_ACTION_RENAMED_NEW_NAME )
{
for ( pwsTemp = pNotifyInfo->FileName, n = pNotifyInfo->FileNameLength; n > 0; n-- )
if ( *pwsTemp++ == L'~' )
break;
// Generate Unicode absolute pathname
pwsTemp = (LPWSTR)pTempStringBuffer;
*pwsTemp++ = L'\\';
*pwsTemp++ = L'\\';
*pwsTemp++ = L'?';
*pwsTemp++ = L'\\';
#ifdef UNICODE
lstrcpyW(pwsTemp, (LPCWSTR)pAccessoryItem->m_csPath);
pwsTemp += pAccessoryItem->m_csPath.GetLength();
#else
if ( (pwsTemp += MultiByteToWideChar(CP_THREAD_ACP, 0, (LPCSTR)pAccessoryItem->m_csPath, pAccessoryItem->m_csPath.GetLength() + 1, pwsTemp, CLargeBufferBlockBank::GetBlockSize() - 4 * sizeof(WCHAR))) == (LPCWSTR)pTempStringBuffer + 4 )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_MULTIBYTETOWIDECHAR_ERROR, (LPCTSTR)pAccessoryItem->m_csPath, NULL, ::GetLastError(), 0};
pThis->m_pCallback(¶m);
}
goto NEXT_NOTIFY_INFO;
}
#endif
if ( pAccessoryItem->m_csPath.GetAt(pAccessoryItem->m_csPath.GetLength() - 1) != _T('\\') )
*pwsTemp++ = L'\\';
memcpy(pwsTemp, pNotifyInfo->FileName, pNotifyInfo->FileNameLength);
*pwsTemp++ = NULL;
// Get long pathname and calculate its length
if ( n!= 0 ) // May be short pathname
{
if ( (nPathnameLength = GetLongPathNameW((LPCWSTR)pTempStringBuffer, (LPWSTR)pTempStringBuffer, CLargeBufferBlockBank::GetBlockSize())) == 0 )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_GETLONGPATHNAME_ERROR, (LPCTSTR)pTempStringBuffer, NULL, ::GetLastError(), 0};
#ifndef UNICODE
WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCWSTR)pTempStringBuffer + 4, lstrlenW((LPCWSTR)pTempStringBuffer + 4), (LPSTR)pTempStringBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, NULL);
#endif
pThis->m_pCallback(¶m);
}
goto NEXT_NOTIFY_INFO;
}
}
else // It's long pathname already
nPathnameLength = ((DWORD)pwsTemp - (DWORD)pTempStringBuffer) / sizeof(WCHAR) - 1 - 4;
// check file attributes, because we should treat rename of directory specially
if ( GetFileAttributesW((LPCWSTR)pTempStringBuffer) & FILE_ATTRIBUTE_DIRECTORY )
{
if ( pNotifyInfo->Action == FILE_ACTION_RENAMED_NEW_NAME )
{
CFileFilter::CParsedPathItem* pItem;
#ifdef UNICODE
if ( sizeof(*pPostInfo) + nPathnameLength * sizeof(WCHAR) > CLargeBufferBlockBank::GetBlockSize() )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_PATHNAMETOOLONG_ERROR, (LPCTSTR)pTempStringBuffer + 4, NULL, ERROR_NOT_SUPPORTED, 0};
pThis->m_pCallback(¶m);
}
goto NEXT_NOTIFY_INFO;
}
ptsTemp = (LPWSTR)pTempStringBuffer + 4;
#else
if ( pTempStringBufferForDirectory == NULL )
pTempStringBufferForDirectory = CLargeBufferBlockBank::Allocate();
if ( WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCWSTR)pTempStringBuffer, nPathnameLength + 1, (LPSTR)pTempStringBufferForDirectory, CLargeBufferBlockBank::GetBlockSize(), NULL, NULL) == 0 )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_WIDECHARTOMULTIBYTE_ERROR, (LPCTSTR)pTempStringBuffer, NULL, ::GetLastError(), 0};
pThis->m_pCallback(¶m);
}
goto NEXT_NOTIFY_INFO;
}
ptsTemp = (LPSTR)pTempStringBufferForDirectory;
#endif
switch ( pParsedPathItem->MatchFilePathname(ptsTemp + pAccessoryItem->m_csPath.GetLength() + (pAccessoryItem->m_pParsedPathItemPointer->IsDriveItem() ? 0 : 1), pItem) )
{
case CFileFilter::CParsedPathItem::INCLUDE_ITEM:
{
struct __tag_SpecialParamForWinNTHandleDirectoryNameChange objExt = {(LPWSTR)pTempStringBuffer, (LPTSTR)pTempStringBufferForDirectory, pThis->m_pCallback, &pPostDataPage, &pPrevPostInfo, &pPostInfo};
pThis->WinNTHandleDirectoryNameChange(nPathnameLength, pItem, &objExt);
}
break;
case CFileFilter::CParsedPathItem::INTERMEDIA_ITEM:
{
CList<CFileFilter::CParsedPathItem*, CFileFilter::CParsedPathItem*> objParsedPathItemList;
POSITION pos;
pItem->GetIncludeItems(objParsedPathItemList);
pos = objParsedPathItemList.GetHeadPosition();
while ( pos )
{
pItem = objParsedPathItemList.GetNext(pos);
//pItem-
}
}
}
}
}
else // Normal File
{
#ifdef UNICODE
if ( sizeof(*pPostInfo) + nPathnameLength * sizeof(WCHAR) > CLargeBufferBlockBank::GetBlockSize() )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_PATHNAMETOOLONG_ERROR, (LPCTSTR)pTempStringBuffer + 4, NULL, ERROR_NOT_SUPPORTED, 0};
pThis->m_pCallback(¶m);
}
goto NEXT_NOTIFY_INFO;
}
ptsTemp = (LPWSTR)pTempStringBuffer + 4;
#else
if ( (nPathnameLength = WideCharToMultiByte(CP_THREAD_ACP, 0, (LPCWSTR)pTempStringBuffer + 4, nPathnameLength + 1, (LPSTR)pTempStringBuffer, CLargeBufferBlockBank::GetBlockSize(), NULL, NULL)) == 0 )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_WIDECHARTOMULTIBYTE_ERROR, (LPCTSTR)pTempStringBuffer, NULL, ::GetLastError(), 0};
pThis->m_pCallback(¶m);
}
goto NEXT_NOTIFY_INFO;
}
nPathnameLength--;
ptsTemp = (LPSTR)pTempStringBuffer;
#endif
if ( pParsedPathItem->MatchFilePathname(ptsTemp + pAccessoryItem->m_csPath.GetLength() + (pAccessoryItem->m_pParsedPathItemPointer->IsDriveItem() ? 0 : 1)) )
{
if ( pPostDataPage != NULL )
{
if ( (DWORD)pPostDataPage != (DWORD)pPostInfo )
{
pTempPostInfo = (PFILECHANGES_INFORMATION)pPostDataPage;
do
{
if ( pTempPostInfo->m_nPathnameLength == nPathnameLength && _tcsicmp(pTempPostInfo->m_tsPathname, ptsTemp) == 0 )
goto NEXT_NOTIFY_INFO;
else
pTempPostInfo = pTempPostInfo->m_pNext;
} while ( pTempPostInfo != pPostInfo );
}
if ( (LPBYTE)pPostDataPage + CLargeBufferBlockBank::GetBlockSize() < (LPBYTE)pPostInfo + sizeof(*pPostInfo) + nPathnameLength * sizeof(TCHAR) )
{
ASSERT(pPrevPostInfo != NULL);
pPrevPostInfo->m_pNext = NULL;
if ( !pThis->m_pDatabassAccessThread->PostFileChanges(pPostDataPage) )
{
if ( pThis->m_pCallback )
{
FILEBACKUP_CALLBACK_PARAM param = {CHANGESHANDLER_POSTFILECHANGES_ERROR, NULL, NULL, ::GetLastError(), 0};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -