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

📄 dirmon.c

📁 这个是FileBackup的一个组件
💻 C
📖 第 1 页 / 共 4 页
字号:
// DIRMON.c - main module for VxD DIRMON

#define   DEVICE_MAIN
#include  <vtoolsc.h>
#include  "dirmon.h"
#include "ioctlcmd.h"
#undef    DEVICE_MAIN

#define PARSE_FILENAME_FROM_FILENUMBER	0
#define DEBUG_FUNCTION_NAME(func)	dprintf(func "\n")

#define HASH_BITS					7
#define HASH_NUMBER					(1 << HASH_BITS)
#define HASH_BITS_MASK				(HASH_NUMBER - 1)

//	Structure to save file information
struct _tag_PathLinkItem;
typedef struct _tag_FileItem
{
	sfn_t						nFileNumber;
	WORD						wAction;
	DWORD						dwUpdateDosTime;
	CHAR						sFilePathName[MAX_PATH];
	struct _tag_PathLinkItem*	pBasePaths;
	struct _tag_FileItem*		pNext;
} FILEITEM, *PFILEITEM;

//	Structure to save directory information which is being monitored.
typedef struct _tag_DirectoryItem
{
	char						sPathName[MAX_PATH];
	char						sShortPathName[MAX_PATH];
	int							nRefCount;
	struct _tag_DirectoryItem*	pNext;
} DIRECTORYITEM, *PDIRECTORYITEM;

//	Structure to link file item with base path directory items
typedef struct _tag_PathLinkItem
{
	PDIRECTORYITEM				pDirectoryItem;
	PCHAR						psRelativePath;
	struct _tag_PathLinkItem*	pNext;
} PATHLINKITEM, *PPATHLINKITEM;

//	Overlapped structure pointer
SEMHANDLE				g_semOverlapped;
OVERLAPPED*				g_pOverlapped;
PCHAR					g_pOutBuf;
DWORD					g_cbOutBuf;
//	Updated file items list
SEMHANDLE				g_semUpdatedFileItems;
PFILEITEM				g_pUpdatedFileItems;
PFILEITEM				g_pLastUpdatedFileItem;
//	Registered directory items list
SEMHANDLE				g_semDirectoryItems;
PDIRECTORYITEM			g_pDirectoryItems;
DWORD					g_dwDirectoryItems;
//	Opened file items hash table
SEMHANDLE				g_semFileItemHashTable;
PFILEITEM				g_pFileItemHashTable[HASH_NUMBER];
//	Free file items list
SEMHANDLE				g_semFreeFileItems;
PFILEITEM				g_pFreeFileItems;
//	Free path link items list
SEMHANDLE				g_semFreePathLinkItems;
PPATHLINKITEM			g_pFreePathLinkItems;
DWORD					g_dwFreePathLinkItems;

//	Flag if the delete operation should be logged
BOOL					g_fLogDelete;

//	Real service pointers with the hook thunks
ppIFSFileHookFunc g_pPrevIFSHookProc;

Declare_Virtual_Device(DIRMON)

DefineControlHandler(SYS_DYNAMIC_DEVICE_INIT, OnSysDynamicDeviceInit);
DefineControlHandler(SYS_DYNAMIC_DEVICE_EXIT, OnSysDynamicDeviceExit);
DefineControlHandler(W32_DEVICEIOCONTROL, OnW32Deviceiocontrol);

BOOL __cdecl ControlDispatcher(
	DWORD dwControlMessage,
	DWORD EBX,
	DWORD EDX,
	DWORD ESI,
	DWORD EDI,
	DWORD ECX)
{
	START_CONTROL_DISPATCH

		ON_SYS_DYNAMIC_DEVICE_INIT(OnSysDynamicDeviceInit);
		ON_SYS_DYNAMIC_DEVICE_EXIT(OnSysDynamicDeviceExit);
		ON_W32_DEVICEIOCONTROL(OnW32Deviceiocontrol);

	END_CONTROL_DISPATCH

	return TRUE;
}

void InitOverlapped()
{
	g_semOverlapped = Create_Semaphore(0);
	g_pOverlapped = NULL;
	g_pOutBuf = NULL;
	g_cbOutBuf = 0;
	Signal_Semaphore(g_semOverlapped);
}

void DestroyOverlapped()
{
	Wait_Semaphore(g_semOverlapped, BLOCK_SVC_INTS);
	if ( g_pOverlapped )
		LinPageUnLock(PAGENUM(g_pOverlapped), _NPAGES_(g_pOverlapped, sizeof(OVERLAPPED)), PAGEMAPGLOBAL);
	if ( g_pOutBuf )
		LinPageUnLock(PAGENUM(g_pOutBuf), _NPAGES_(g_pOutBuf, g_cbOutBuf), PAGEMAPGLOBAL);
	Destroy_Semaphore(g_semOverlapped);
}

void SetOverlapped(PIOCTLPARAMS p)
{
	PCHAR pBasePageOverlapped;
	PCHAR pBasePageOutBuf;
	OVERLAPPED *pOverlapped, *pOldOverlapped = NULL;
	PCHAR pOutBuf, pOldOutBuf;
	DWORD cbOutBuf = p->dioc_cbOutBuf, cbOldOutBuf;

	pBasePageOverlapped = (PCHAR)LinPageLock(PAGENUM(p->dioc_ovrlp), _NPAGES_(p->dioc_ovrlp, sizeof(OVERLAPPED)), PAGEMAPGLOBAL);
	pOverlapped = (OVERLAPPED*)(pBasePageOverlapped+((ULONG)p->dioc_ovrlp & 0xfff));
	pBasePageOutBuf = (PCHAR)LinPageLock(PAGENUM(p->dioc_OutBuf), _NPAGES_(p->dioc_OutBuf, cbOutBuf), PAGEMAPGLOBAL);
	pOutBuf = pBasePageOutBuf+((ULONG)p->dioc_OutBuf & 0xfff);
	dprintf("pBasePageOutBuf = 0x%08X, pOutBuf = 0x%08X, p->dioc_OutBuf = 0x%08X\n", pBasePageOutBuf, pOutBuf, p->dioc_OutBuf);
	Wait_Semaphore(g_semOverlapped, BLOCK_SVC_INTS);
	if ( g_pOverlapped )
	{
		pOldOverlapped = g_pOverlapped;
		pOldOutBuf = g_pOutBuf;
		cbOldOutBuf = g_cbOutBuf;
	}
	g_pOverlapped = pOverlapped;
	g_pOutBuf = pOutBuf;
	g_cbOutBuf = cbOutBuf;
	Signal_Semaphore(g_semOverlapped);
	if ( pOldOverlapped )
	{
		LinPageUnLock(PAGENUM(pOldOverlapped), _NPAGES_(pOldOverlapped, sizeof(OVERLAPPED)), PAGEMAPGLOBAL);
		LinPageUnLock(PAGENUM(pOldOutBuf), _NPAGES_(pOldOutBuf, sizeof(cbOldOutBuf)), PAGEMAPGLOBAL);
	}
}

void CancelOverlapped()
{
	OVERLAPPED *pOldOverlapped = NULL;
	PCHAR pOldOutBuf;
	DWORD cbOldOutBuf;

	Wait_Semaphore(g_semOverlapped, BLOCK_SVC_INTS);
	if ( g_pOverlapped )
	{
		pOldOverlapped = g_pOverlapped;		g_pOverlapped = NULL;
		pOldOutBuf = g_pOutBuf;				g_pOutBuf = NULL;
		cbOldOutBuf = g_cbOutBuf;			g_cbOutBuf = 0;
	}
	Signal_Semaphore(g_semOverlapped);
	if ( pOldOverlapped )
	{
		LinPageUnLock(PAGENUM(pOldOverlapped), _NPAGES_(pOldOverlapped, sizeof(OVERLAPPED)), PAGEMAPGLOBAL);
		LinPageUnLock(PAGENUM(pOldOutBuf), _NPAGES_(pOldOutBuf, sizeof(cbOldOutBuf)), PAGEMAPGLOBAL);
	}
}

void GetUpdatedFileItems(PFILEITEM* ppFirstFileItem, PFILEITEM* ppLastFileItem);
void ReturnUpdatedFileItems(PFILEITEM pFirstFileItem, PFILEITEM pLastFileItem);
PFILEITEM WriteDataToBuffer(PFILEITEM pFirstFileItem, const PFILEITEM pLastFileItem, PCHAR pBuf, DWORD dwBufLen, PDWORD pdwWrittenBytes);
BOOL ReturnOverlapped()
{
	OVERLAPPED* pOverlapped;
	PCHAR pOutBuf;
	DWORD cbOutBuf;
	DWORD dwWrittenBytes;

	Wait_Semaphore(g_semOverlapped, BLOCK_SVC_INTS);
	pOverlapped = g_pOverlapped;	g_pOverlapped = NULL;
	pOutBuf = g_pOutBuf;			g_pOutBuf = NULL;
	cbOutBuf = g_cbOutBuf;			g_cbOutBuf = 0;
	Signal_Semaphore(g_semOverlapped);

	if ( pOverlapped )
	{
		PFILEITEM pFirstFileItem, pLastFileItem;

		dprintf("1. g_pUpdatedFileItems = 0x%08X\n", g_pUpdatedFileItems);
		GetUpdatedFileItems(&pFirstFileItem, &pLastFileItem);
		dprintf("2. g_pUpdatedFileItems = 0x%08X\n", g_pUpdatedFileItems);
		if ( (pFirstFileItem = WriteDataToBuffer(pFirstFileItem, pLastFileItem, pOutBuf, cbOutBuf, &dwWrittenBytes)) )
		{
			dprintf("pOutBuf = 0x%08X, cbOutBuf = %d, dwWrittenBytes = %d\n", pOutBuf, cbOutBuf, dwWrittenBytes);
			ReturnUpdatedFileItems(pFirstFileItem, pLastFileItem);
		}
		else
		{
			dprintf("pOutBuf = 0x%08X, cbOutBuf = %d, dwWrittenBytes = %d\n", pOutBuf, cbOutBuf, dwWrittenBytes);
		}
		dprintf("3. g_pUpdatedFileItems = 0x%08X\n", g_pUpdatedFileItems);
		pOverlapped->O_InternalHigh = dwWrittenBytes;
		VWIN32_DIOCCompletionRoutine(pOverlapped->O_Internal);
		LinPageUnLock(PAGENUM(pOverlapped), _NPAGES_(pOverlapped, sizeof(OVERLAPPED)), PAGEMAPGLOBAL);
		LinPageUnLock(PAGENUM(pOutBuf), _NPAGES_(pOutBuf, sizeof(cbOutBuf)), PAGEMAPGLOBAL);
		return TRUE;
	}
		return FALSE;
}

void InitUpdatedFileItemsList()
{
	g_semUpdatedFileItems = Create_Semaphore(0);
	g_pLastUpdatedFileItem = g_pUpdatedFileItems = NULL;
	Signal_Semaphore(g_semUpdatedFileItems);
}

void DestroyUpdatedFileItemsList()
{
	PFILEITEM pPrevFileItem, pFileItem;
	PPATHLINKITEM pPrevPathLinkItem, pPathLinkItem;

	Wait_Semaphore(g_semUpdatedFileItems, BLOCK_SVC_INTS);
	pFileItem = g_pUpdatedFileItems;
	while ( pFileItem )
	{
		pPrevFileItem = pFileItem;
		pFileItem = pFileItem->pNext;
		pPathLinkItem = pPrevFileItem->pBasePaths;
		while ( pPathLinkItem )
		{
			pPrevPathLinkItem = pPathLinkItem;
			pPathLinkItem = pPathLinkItem->pNext;
			HeapFree(pPrevPathLinkItem, 0);
		}
		HeapFree(pPrevFileItem, 0);
	}
	Destroy_Semaphore(g_semUpdatedFileItems);
}

void AppendUpdatedFileItem(PFILEITEM pFileItem)
{
	BOOL fSignal = !g_pUpdatedFileItems;

	Wait_Semaphore(g_semUpdatedFileItems, BLOCK_SVC_INTS);
	pFileItem->pNext = NULL;
	if ( g_pUpdatedFileItems )
	{
		g_pLastUpdatedFileItem->pNext = pFileItem;
		g_pLastUpdatedFileItem = pFileItem;
	}
	else
		g_pUpdatedFileItems = g_pLastUpdatedFileItem = pFileItem;
	Signal_Semaphore(g_semUpdatedFileItems);
	if ( !ReturnOverlapped() && fSignal )
		SignalID((DWORD)&g_semUpdatedFileItems);
}

void AppendUpdatedFileItemForActionRenamed(PFILEITEM pFileItem)
{
	BOOL fSignal = !g_pUpdatedFileItems;

	Wait_Semaphore(g_semUpdatedFileItems, BLOCK_SVC_INTS);
	pFileItem->pNext->pNext = NULL;
	if ( g_pUpdatedFileItems )
		g_pLastUpdatedFileItem->pNext = pFileItem;
	else
		g_pUpdatedFileItems = pFileItem;
	g_pLastUpdatedFileItem = pFileItem->pNext;
	Signal_Semaphore(g_semUpdatedFileItems);
	if ( !ReturnOverlapped() && fSignal )
		SignalID((DWORD)&g_semUpdatedFileItems);
}

void GetUpdatedFileItems(PFILEITEM* ppFirstFileItem, PFILEITEM* ppLastFileItem)
{
	Wait_Semaphore(g_semUpdatedFileItems, BLOCK_SVC_INTS);
	*ppFirstFileItem = g_pUpdatedFileItems;
	*ppLastFileItem = g_pLastUpdatedFileItem;
	g_pLastUpdatedFileItem = g_pUpdatedFileItems = NULL;
	Signal_Semaphore(g_semUpdatedFileItems);
}

void ReturnUpdatedFileItems(PFILEITEM pFirstFileItem, PFILEITEM pLastFileItem)
{
	Wait_Semaphore(g_semUpdatedFileItems, BLOCK_SVC_INTS);
	pLastFileItem->pNext = g_pUpdatedFileItems;
	g_pUpdatedFileItems = pFirstFileItem;
	Signal_Semaphore(g_semUpdatedFileItems);
}

void InitDirectoryItemsList()
{
	g_semDirectoryItems = Create_Semaphore(0);
	g_pDirectoryItems = NULL;
	g_dwDirectoryItems = 0;
	Signal_Semaphore(g_semDirectoryItems);
}

void DestroyDirectoryItemsList()
{
	PDIRECTORYITEM pPrevDirectoryItem, pDirectoryItem;

	Wait_Semaphore(g_semDirectoryItems, BLOCK_SVC_INTS);
	pDirectoryItem = g_pDirectoryItems;
	while ( pDirectoryItem )
	{
		pPrevDirectoryItem = pDirectoryItem;
		pDirectoryItem = pDirectoryItem->pNext;
		HeapFree(pPrevDirectoryItem, 0);
	}
	Destroy_Semaphore(g_semDirectoryItems);
}

#if defined(DEBUG) && DEBUG
/*
void dprintdirectoryitem(PDIRECTORYITEM pDirectoryItem)
{
	char buf1[MAX_PATH], buf2[MAX_PATH], *p1, *p2;
	p1 = buf1;
	p2 = pDirectoryItem->sPathName;
	while ( *p2 )
	{
		sprintf(p1, "(%d)", (int)*p2);
		p1 += strlen(p1);
		memcpy(p1, p2 + 1, *p2);
		p1 += *p2;
		*p1 = 0;
		p2 += *p2 + 1;
	}
	p1 = buf2;
	p2 = pDirectoryItem->sShortPathName;
	while ( *p2 )
	{
		sprintf(p1, "(%d)", (int)*p2);
		p1 += strlen(p1);
		memcpy(p1, p2 + 1, *p2);
		p1 += *p2;
		*p1 = 0;
		p2 += *p2 + 1;
	}
	dprintf("Insert monitor path: %s (%s)\n", buf1, buf2);
}
*/
void dprintdirectoryitem(char* pstr, PDIRECTORYITEM pDirectoryItem)
{
	char buf1[MAX_PATH], buf2[MAX_PATH], *p1, *p2;
	p1 = buf1;
	p2 = pDirectoryItem->sPathName;
	while ( *p2 )
	{
		sprintf(p1, "(%d)", (int)*p2);
		p1 += strlen(p1);
		memcpy(p1, p2 + 1, *p2);
		p1 += *p2;
		*p1 = 0;
		p2 += *p2 + 1;
	}
	p1 = buf2;
	p2 = pDirectoryItem->sShortPathName;
	while ( *p2 )
	{
		sprintf(p1, "(%d)", (int)*p2);
		p1 += strlen(p1);
		memcpy(p1, p2 + 1, *p2);
		p1 += *p2;
		*p1 = 0;
		p2 += *p2 + 1;
	}
	dprintf("%s: %s (%s)\n", pstr, buf1, buf2);
}
#else
	#define dprintdirectoryitem(x)
#endif

PDIRECTORYITEM AllocateAndAppendDirectoryItem(PCHAR pPath)
{
	PDIRECTORYITEM pDirectoryItem;

	if ( (pDirectoryItem = HeapAllocate(sizeof(*pDirectoryItem), 0)) )
	{
		PCHAR pDest, pBackSlash;
		PDIRECTORYITEM pTempDirectoryItem;

		pBackSlash = pDirectoryItem->sPathName;
		pDest = pBackSlash + 1;
		while ( *pPath )
		{
			if ( *pPath != '\\' )
				*pDest++ = *pPath++;
			else
			{
				*pBackSlash = pDest - pBackSlash - 1;
				pBackSlash = pDest++;
				pPath++;
			}
		}
		if ( (*pBackSlash = pDest - pBackSlash - 1) )
			*pDest = 0;
		pPath++;
		pBackSlash = pDirectoryItem->sShortPathName;
		pDest = pBackSlash + 1;

⌨️ 快捷键说明

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