⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dirmon.c

📁 这个是FileBackup的一个组件
💻 C
📖 第 1 页 / 共 4 页
字号:
	PPATHLINKITEM pPrevPathLinkItem, pPathLinkItem;

	Wait_Semaphore(g_semFreePathLinkItems, BLOCK_SVC_INTS);
	pPathLinkItem = g_pFreePathLinkItems;
	while ( pPathLinkItem )
	{
		pPrevPathLinkItem = pPathLinkItem;
		pPathLinkItem = pPathLinkItem->pNext;
		HeapFree(pPrevPathLinkItem, 0);
	}
	Destroy_Semaphore(g_semFreePathLinkItems);
}

PPATHLINKITEM AllocatePathLinkItem()
{
	PPATHLINKITEM pPathLinkItem;

	Wait_Semaphore(g_semFreePathLinkItems, BLOCK_SVC_INTS);
	if ( (pPathLinkItem = g_pFreePathLinkItems) )
	{
		g_pFreePathLinkItems = g_pFreePathLinkItems->pNext;
		g_dwFreePathLinkItems--;
		Signal_Semaphore(g_semFreePathLinkItems);
	}
	else
	{
		Signal_Semaphore(g_semFreePathLinkItems);
		if ( !(pPathLinkItem = HeapAllocate(sizeof(*pPathLinkItem), 0)) )
			return NULL;
	}
	memset(pPathLinkItem, 0, sizeof(*pPathLinkItem));
	return pPathLinkItem;
}

BOOL AllocatePathLinkItemForActionRenamed(PPATHLINKITEM* pPathLinkItem1, PPATHLINKITEM* pPathLinkItem2)
{
	BOOL fRet = FALSE;

	Wait_Semaphore(g_semFreePathLinkItems, BLOCK_SVC_INTS);
	if ( g_dwFreePathLinkItems >= 2 )
	{
		*pPathLinkItem1 = g_pFreePathLinkItems;
		*pPathLinkItem2 = g_pFreePathLinkItems->pNext;
		g_pFreePathLinkItems = (*pPathLinkItem2)->pNext;
		g_dwFreePathLinkItems -= 2;
		fRet = TRUE;
	}
	Signal_Semaphore(g_semFreePathLinkItems);
	return fRet;
}

BOOL PrepareFreePathLinkItemN(DWORD n)
{
	DWORD dwCount = n;
	PPATHLINKITEM pFirstPathLinkItem = HeapAllocate(sizeof(*pFirstPathLinkItem), 0);
	PPATHLINKITEM pPathLinkItem = pFirstPathLinkItem;

	if ( !pPathLinkItem )
		return FALSE;
	while ( --dwCount > 0 )
		if ( (pPathLinkItem->pNext = HeapAllocate(sizeof(*pPathLinkItem), 0)) )
			pPathLinkItem = pPathLinkItem->pNext;
		else
			break;
	Wait_Semaphore(g_semFreePathLinkItems, BLOCK_SVC_INTS);
	pPathLinkItem->pNext = g_pFreePathLinkItems;
	g_pFreePathLinkItems = pFirstPathLinkItem;
	g_dwFreePathLinkItems += n - dwCount;
	Signal_Semaphore(g_semFreePathLinkItems);
	return dwCount == 0;
}

BOOL PrepareFreePathLinkItem()
{
	if ( g_dwFreePathLinkItems < g_dwDirectoryItems )
		return PrepareFreePathLinkItemN(g_dwDirectoryItems - g_dwFreePathLinkItems);
	else
		return TRUE;
}

BOOL PrepareFreePathLinkItemForActionRenamed()
{
	if ( g_dwFreePathLinkItems < g_dwDirectoryItems * 2 )
		return PrepareFreePathLinkItemN(g_dwDirectoryItems * 2 - g_dwFreePathLinkItems);
	else
		return TRUE;
}

void FreePathLinkItems(PPATHLINKITEM pStartPathLinkItem, PPATHLINKITEM pEndPathLinkItem)
{
	PPATHLINKITEM pLastPathLinkItem = pStartPathLinkItem;
	DWORD dwCount = 1;

	while ( pLastPathLinkItem->pNext != pEndPathLinkItem )
	{
		pLastPathLinkItem = pLastPathLinkItem->pNext;
		dwCount++;
	}
	Wait_Semaphore(g_semFreePathLinkItems, BLOCK_SVC_INTS);
	pLastPathLinkItem->pNext = g_pFreePathLinkItems;
	g_pFreePathLinkItems = pStartPathLinkItem;
	g_dwFreePathLinkItems += dwCount;
	Signal_Semaphore(g_semFreePathLinkItems);
}

void ParsedPath2PathName(path_t pParsedPath, int nDrive, int nCodePage, CHAR psPathName[MAX_PATH])
{
	int nStartPos = 0;
	_QWORD qdResult;

	if ( nDrive != 0xFF )
	{
		psPathName[0] = nDrive - 1 + 'A';
		psPathName[1] = ':';
		nStartPos = 2;
	}
	UniToBCSPath(psPathName + nStartPos, pParsedPath->pp_elements, MAX_PATH - 1, nCodePage == BCS_OEM ? BCS_OEM : BCS_WANSI, &qdResult);
}

BOOL SFN2PathName(sfn_t nFileNumber, int nDrive, int nResType, int nCodePage, pioreq pIOreq, CHAR psPathName[MAX_PATH])
{
	ifsreq objIFSreq;
	CHAR cBuf[MAX_PATH * sizeof(unsigned short) + 2 * sizeof(unsigned short)];
	path_t pParsedPath = (path_t)cBuf;

	memcpy(&objIFSreq, pIOreq, sizeof(objIFSreq));
	objIFSreq.ifsir.ir_flags = ENUMH_GETFILENAME;
	objIFSreq.ifsir.ir_ppath = pParsedPath;
	if ( (*g_pPrevIFSHookProc)(objIFSreq.ifs_hndl->hf_misc->hm_func[HM_ENUMHANDLE], IFSFN_ENUMHANDLE, nDrive, nResType, nCodePage, (pioreq)&objIFSreq) == ERROR_SUCCESS )
	{
		ParsedPath2PathName(pParsedPath, nDrive, nCodePage, psPathName);
		return TRUE;
	}
	else
		return FALSE;
}

BOOL IsMonitoredEx(PFILEITEM pFileItem)
{
	if ( g_pDirectoryItems != NULL && PrepareFreePathLinkItem() )
	{
		BOOL fRet = FALSE;
		PDIRECTORYITEM pDirectoryItem;
		PCHAR psFilePathName;
		PCHAR psPathName, psShortPathName;
		PPATHLINKITEM pPathLinkItem, pPathLinkItems = NULL;

		Wait_Semaphore(g_semDirectoryItems, BLOCK_SVC_INTS);
		pDirectoryItem = g_pDirectoryItems;
		while ( pDirectoryItem )
		{
			psFilePathName = pFileItem->sFilePathName;
			psPathName = pDirectoryItem->sPathName;
			psShortPathName = pDirectoryItem->sShortPathName;
			while ( *psPathName )
			{
				if ( psFilePathName[*psPathName] == '\\' && strnicmp(psPathName + 1, psFilePathName, *psPathName) == 0 )
					psFilePathName += *psPathName + 1;
				else if ( psFilePathName[*psShortPathName] == '\\' && strnicmp(psShortPathName + 1, psFilePathName, *psShortPathName) == 0 )
					psFilePathName += *psShortPathName + 1;
				else
					break;
				psPathName += *psPathName + 1;
				psShortPathName += *psShortPathName + 1;
			}
//	Beware! HeapAllocate, which could bring re-entrance, may be invoked by AllocatePathLinkItem
			if ( !*psPathName && (pPathLinkItem = AllocatePathLinkItem()) )
			{
				pPathLinkItem->pDirectoryItem = pDirectoryItem;
				pPathLinkItem->psRelativePath = psFilePathName;
				pPathLinkItem->pNext = pPathLinkItems;
				pPathLinkItems = pPathLinkItem;
				dprintf("IsMonitoredEx: %s", psFilePathName);
				fRet = TRUE;
			}
			pDirectoryItem = pDirectoryItem->pNext;
		}
		Signal_Semaphore(g_semDirectoryItems);
		if ( fRet )
			pFileItem->pBasePaths = pPathLinkItems;
		return fRet;
	}
	else
		return FALSE;
}

BOOL IsMonitoredExForActionRenamed(PFILEITEM pFileItem1)
{
	PFILEITEM pFileItem2 = pFileItem1->pNext;

	if ( g_pDirectoryItems != NULL && PrepareFreePathLinkItemForActionRenamed() )
	{
		BOOL fRet = FALSE;

		PDIRECTORYITEM pDirectoryItem;
		PCHAR psFilePathName1, psFilePathName2;
		PCHAR psPathName1, psPathName2, psShortPathName1, psShortPathName2;
		PPATHLINKITEM pPathLinkItem1, pPathLinkItem2, pPathLinkItems1 = NULL, pPathLinkItems2 = NULL;

		Wait_Semaphore(g_semDirectoryItems, BLOCK_SVC_INTS);
		pDirectoryItem = g_pDirectoryItems;
		while ( pDirectoryItem )
		{
			psPathName1 = psPathName2 = pDirectoryItem->sPathName;
			psShortPathName1 = psShortPathName2 = pDirectoryItem->sShortPathName;
			psFilePathName1 = pFileItem1->sFilePathName;
			while ( *psPathName1 )
			{
				if ( psFilePathName1[*psPathName1] == '\\' && strnicmp(psPathName1 + 1, psFilePathName1, *psPathName1) == 0 )
					psFilePathName1 += *psPathName1 + 1;
				else if ( psFilePathName1[*psShortPathName1] == '\\' && strnicmp(psShortPathName1 + 1, psFilePathName1, *psShortPathName1) == 0 )
					psFilePathName1 += *psShortPathName1 + 1;
				else
					break;
				psPathName1 += *psPathName1 + 1;
				psShortPathName1 += *psShortPathName1 + 1;
			}
			psFilePathName2 = pFileItem2->sFilePathName;
			while ( *psPathName2 )
			{
				if ( psFilePathName2[*psPathName2] == '\\' && strnicmp(psPathName2 + 1, psFilePathName2, *psPathName2) == 0 )
					psFilePathName2 += *psPathName2 + 1;
				else if ( psFilePathName2[*psShortPathName2] == '\\' && strnicmp(psShortPathName2 + 1, psFilePathName2, *psShortPathName2) == 0 )
					psFilePathName2 += *psShortPathName2 + 1;
				else
					break;
				psPathName2 += *psPathName2 + 1;
				psShortPathName2 += *psShortPathName2 + 1;
			}
			if ( (!*psPathName1 || !*psPathName2) && AllocatePathLinkItemForActionRenamed(&pPathLinkItem1, &pPathLinkItem2) )
			{
				if ( !*psPathName1 )
				{
					pPathLinkItem1->pDirectoryItem = pDirectoryItem;
					pPathLinkItem1->psRelativePath = psFilePathName1;
					pPathLinkItem1->pNext = pPathLinkItems1;
					pPathLinkItems1 = pPathLinkItem1;
					dprintf("IsMonitoredExForActionRenamed (1): %s", psFilePathName1);
				}
				if ( !*psPathName2 )
				{
					pPathLinkItem2->pDirectoryItem = pDirectoryItem;
					pPathLinkItem2->psRelativePath = psFilePathName2;
					pPathLinkItem2->pNext = pPathLinkItems2;
					pPathLinkItems2 = pPathLinkItem2;
					dprintf("IsMonitoredExForActionRenamed (2): %s", psFilePathName2);
				}
				fRet = TRUE;
			}
			pDirectoryItem = pDirectoryItem->pNext;
		}
		Signal_Semaphore(g_semDirectoryItems);
		if ( fRet )
		{
			pFileItem1->pBasePaths = pPathLinkItems1;
			pFileItem2->pBasePaths = pPathLinkItems2;
		}
		return fRet;
	}
	else
		return FALSE;
}

PFILEITEM WriteDataToBuffer(PFILEITEM pFirstFileItem, const PFILEITEM pLastFileItem, PCHAR pBuf, DWORD dwBufLen, PDWORD pdwWrittenBytes)
{
	DWORD dwSpareBytes = dwBufLen;
	PPATHLINKITEM pPathLinkItem, pNextPathLinkItem;
	PDIRCHANGEITEM pDirChangeItem = (PDIRCHANGEITEM)pBuf, pPrevDirChangeItem = NULL;
	DWORD dwFilePathNameLen;
	DWORD dwDirChangeItemLen;
	PFILEITEM pPrevFileItem;

	PFILEITEM pSecondFileItem;
	PPATHLINKITEM pPathLinkItem2, pNextPathLinkItem2;
	PDIRCHANGEITEM pDirChangeItem2;
	DWORD dwFilePathNameLen2;
	DWORD dwDirChangeItemLen2;

	while ( pFirstFileItem )
	{
		if ( pFirstFileItem->wAction != DIRMON_ACTION_RENAMED_OLD_NAME )
		{
			dwFilePathNameLen = strlen(pFirstFileItem->sFilePathName);
			pPathLinkItem = pFirstFileItem->pBasePaths;
			while ( pPathLinkItem )
			{
				pNextPathLinkItem = pPathLinkItem->pNext;

				dwDirChangeItemLen = sizeof(*pDirChangeItem) + dwFilePathNameLen - (pPathLinkItem->psRelativePath - pFirstFileItem->sFilePathName);
				if ( dwDirChangeItemLen > dwSpareBytes )
				{
					if ( pFirstFileItem->pBasePaths != pPathLinkItem )
					{
						FreePathLinkItems(pFirstFileItem->pBasePaths, pPathLinkItem);
						pFirstFileItem->pBasePaths = pPathLinkItem;
					}
					goto WriteDataToBuffer_Return;
				}
				pDirChangeItem->wNextEntryOffset = dwDirChangeItemLen;
				pDirChangeItem->wAction = pFirstFileItem->wAction;
				pDirChangeItem->dwDosTime = pFirstFileItem->dwUpdateDosTime;
				pDirChangeItem->dwDirectoryItem = (DWORD)pPathLinkItem->pDirectoryItem;
				strcpy(pDirChangeItem->sRelativePathName, pPathLinkItem->psRelativePath);

				pPrevDirChangeItem = pDirChangeItem;
				pDirChangeItem = (PDIRCHANGEITEM)((PCHAR)pDirChangeItem + dwDirChangeItemLen);
				dwSpareBytes -= dwDirChangeItemLen;
				pPathLinkItem = pNextPathLinkItem;
			}
			pPrevFileItem = pFirstFileItem;
			pFirstFileItem = pFirstFileItem->pNext;
			FreeFileItem(pPrevFileItem);
		}
		else
		{
			pSecondFileItem = pFirstFileItem->pNext;

			dwFilePathNameLen = strlen(pFirstFileItem->sFilePathName);
			dwFilePathNameLen2 = strlen(pSecondFileItem->sFilePathName);
			pPathLinkItem = pFirstFileItem->pBasePaths;
			pPathLinkItem2 = pSecondFileItem->pBasePaths;
			while ( pPathLinkItem )
			{
				pNextPathLinkItem = pPathLinkItem->pNext;
				pNextPathLinkItem2 = pPathLinkItem2->pNext;
				dwDirChangeItemLen = dwDirChangeItemLen2 = 0;

				if ( pPathLinkItem->pDirectoryItem && pPathLinkItem2->pDirectoryItem )
				{
					dwDirChangeItemLen = sizeof(*pDirChangeItem) + dwFilePathNameLen - (pPathLinkItem->psRelativePath - pFirstFileItem->sFilePathName);
					dwDirChangeItemLen2 = sizeof(*pDirChangeItem2) + dwFilePathNameLen2 - (pPathLinkItem2->psRelativePath - pSecondFileItem->sFilePathName);
					pDirChangeItem2 = (PDIRCHANGEITEM)((PCHAR)pDirChangeItem + dwDirChangeItemLen);
					if ( dwDirChangeItemLen + dwDirChangeItemLen2 > dwSpareBytes )
					{
						if ( pFirstFileItem->pBasePaths != pPathLinkItem )
						{
							FreePathLinkItems(pFirstFileItem->pBasePaths, pPathLinkItem);
							pFirstFileItem->pBasePaths = pPathLinkItem;
							FreePathLinkItems(pSecondFileItem->pBasePaths, pPathLinkItem2);
							pSecondFileItem->pBasePaths = pPathLinkItem2;
						}
						goto WriteDataToBuffer_Return;
					}
					pDirChangeItem->wNextEntryOffset = dwDirChangeItemLen;
					pDirChangeItem2->wNextEntryOffset = dwDirChangeItemLen2;
					pDirChangeItem->wAction = DIRMON_ACTION_RENAMED_OLD_NAME;
					pDirChangeItem2->wAction = DIRMON_ACTION_RENAMED_NEW_NAME;
					pDirChangeItem2->dwDosTime = pDirChangeItem->dwDosTime = pFirstFileItem->dwUpdateDosTime;
					pDirChangeItem2->dwDirectoryItem = pDirChangeItem->dwDirectoryItem = (DWORD)pPathLinkItem->pDirectoryItem;
					strcpy(pDirChangeItem->sRelativePathName, pPathLinkItem->psRelativePath);
					strcpy(pDirChangeItem2->sRelativePathName, pPathLinkItem2->psRelativePath);

					pPrevDirChangeItem = pDirChangeItem2;
					pDirChangeItem = (PDIRCHANGEITEM)((PCHAR)pDirChangeItem2 + dwDirChangeItemLen2);
					dwSpareBytes -= dwDirChangeItemLen + dwDirChangeItemLen2;
				}
				else if ( pPathLinkItem->pDirectoryItem )
				{
					dwDirChangeItemLen = sizeof(*pDirChangeItem) + dwFilePathNameLen - (pPathLinkItem->psRelativePath - pFirstFileItem->sFilePathName);
					if ( dwDirChangeItemLen > dwSpareBytes )
					{
						if ( pFirstFileItem->pBasePaths != pPathLinkItem )
						{
							FreePathLinkItems(pFirstFileItem->pBasePaths, pPathLinkItem);
							pFirstFileItem->pBasePaths = pPathLinkItem;
							FreePathLinkItems(pSecondFileItem->pBasePaths, pPathLinkItem2);
							pSecondFileItem->pBasePaths = pPathLinkItem2;
						}
						goto WriteDataToBuffer_Return;
					}
					pDirChangeItem->wNextEntryOffset = dwDirChangeItemLen;
					pDirChangeItem->wAction = DIRMON_ACTION_REMOVED;
					pDirChangeItem->dwDosTime = pFirstFileItem->dwUpdateDosTime;
					pDirChangeItem->dwDirectoryItem = (DWORD)pPathLinkItem->pDirectoryItem;
					strcpy(pDirChangeItem->sRelativePathName, pPathLinkItem->psRelativePath);

					pPrevDirChangeItem = pDirChangeItem;
					pDirChangeItem = (PDIRCHANGEITEM)((PCHAR)pDirChangeItem + dwDirChangeItemLen);
					dwSpareBytes -= dwDirChangeItemLen;
				}
				else if ( pPathLinkItem2->pDirectoryItem )
				{
					dwDirChangeItemLen2 = sizeof(*pDirChangeItem2) + dwFilePathNameLen2 - (pPathLinkItem2->psRelativePath - pSecondFileItem->sFilePathName);
					pDirChangeItem2 = pDirChangeItem;
					if ( dwDirChangeItemLen2 > dwSpareBytes )
					{
						if ( pFirstFileItem->pBasePaths != pPathLinkItem )
						{
							FreePathLinkItems(pFirstFileItem->pBasePaths, pPathLinkItem);
							pFirstFileItem->pBasePaths = pPathLinkItem;
							FreePathLinkItems(pSecondFileItem->pBasePaths, pPathLinkItem2);
							pSecondFileItem->pBasePaths = pPathLinkItem2;
						}
						goto WriteDataToBuffer_Return;
					}
					pDirChangeItem2->wNextEntryOffset = dwDirChangeItemLen2;
					pDirChangeItem2->wAction = DIRMON_ACTION_ADDED;
					pDirChangeItem2->dwDosTime = pFirstFileItem->dwUpdateDosTime;
					pDirChangeItem2->dwDirectoryItem = (DWORD)pPathLinkItem2->pDirectoryItem;
					strcpy(pDirChangeItem2->sRelativePathName, pPathLinkItem2->psRelativePath);

					pPrevDirChangeItem = pDirChangeItem2;
					pDirChangeItem = (PDIRCHANGEITEM)((PCHAR)pDirChangeItem2 + dwDirChangeItemLen2);
					dwSpareBytes -= dwDirChangeItemLen2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -