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