📄 dirmon.c
字号:
// 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 + -