fsnotify.cpp
来自「WinCE5.0部分核心源码」· C++ 代码 · 共 972 行 · 第 1/3 页
CPP
972 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include <windows.h>
#include "fsnotify.h"
HANDLE g_hNotifyAPI = NULL;
CRITICAL_SECTION g_csMain;
NOTVOLENTRY *g_pRootVolume = NULL;
#ifdef UNDER_CE
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
CONST PFNVOID apfnFindNotify[3] = {
(PFNVOID)NotifyCloseEvent,
(PFNVOID)NULL,
(PFNVOID)NotifyReset,
};
CONST DWORD asigFindNotify[3] = {
FNSIG1(DW), // FindClose
FNSIG0(), //
FNSIG2(DW, PTR) // FindNextFileW
};
#endif
#ifndef UNDER_CE
#define FILE_NOTIFY_CHANGE_CEGETINFO 0x80000000
#endif
void AddFileToEvent(NOTEVENTENTRY *pEvent, WCHAR *szFileName, DWORD dwFlags, DWORD dwAction);
void CheckEventOnPath(NOTEVENTENTRY *pEvent, BOOL bSubTree, BOOL bPath);
void NotifyHandleChangeEx(HANDLE hVolume, HANDLE h, DWORD dwFlags, DWORD dwAction);
HANDLE FindNotifyHandleOnDirectory( NOTDIRENTRY *pDirectory, HANDLE hEvent)
{
HANDLE hNotify = NULL;
while(pDirectory) {
NOTEVENTENTRY *pEvent = pDirectory->pEvents;
while(pEvent) {
if (pEvent->hEvent == hEvent) {
hNotify = pEvent->hNotify;
break;
}
pEvent = pEvent->pNext;
}
if (hNotify || (pDirectory->pChild && (hNotify = FindNotifyHandleOnDirectory(pDirectory->pChild, hEvent)))) {
break;
}
pDirectory = pDirectory->pNext;
}
return hNotify;
}
HANDLE GetNotifiyHandle(HANDLE hEvent)
{
HANDLE hNotify = NULL;
EnterCriticalSection( &g_csMain);
NOTVOLENTRY *pVolume = g_pRootVolume;
while(pVolume) {
ENTERNOTIFY( pVolume);
NOTEVENTENTRY *pEvent = pVolume->pEvents;
while(pEvent) {
if (pEvent->hEvent == hEvent) {
hNotify = pEvent->hNotify;
break;
}
pEvent = pEvent->pNext;
}
if (hNotify || (pVolume->pDirEntry && (hNotify = FindNotifyHandleOnDirectory( pVolume->pDirEntry, hEvent)))) {
EXITNOTIFY(pVolume);
break;
}
EXITNOTIFY(pVolume);
pVolume = pVolume->pNextVolume;
}
LeaveCriticalSection( &g_csMain);
return hNotify;
}
inline BOOL IsValidData(HANDLE h, DWORD dwSig)
{
BOOL bRet = TRUE;
NOTHANDLEENTRY *pHandle = (NOTHANDLEENTRY *)h;
if (!h || (h == INVALID_HANDLE_VALUE)) {
bRet = FALSE;
}
if (bRet) {
__try {
if (pHandle->dwSig != dwSig)
bRet = FALSE;
} __except(EXCEPTION_EXECUTE_HANDLER) {
bRet = FALSE;
}
}
return bRet;
}
NOTDIRENTRY *CreateDirEntry(WCHAR *szName, HANDLE hVolume)
{
NOTDIRENTRY *pDirEntry = new NOTDIRENTRY;
if (!pDirEntry) {
return NULL;
}
DWORD dwSize = (wcslen(szName)+1)*sizeof(WCHAR);
pDirEntry->dwSig = NOT_DIR_SIG;
pDirEntry->pChild = NULL;
pDirEntry->pParent = NULL;
pDirEntry->pNext = NULL;
pDirEntry->pPrevious = NULL;
pDirEntry->pHandles = NULL;
pDirEntry->hVolume = hVolume;
pDirEntry->pEvents = NULL;
pDirEntry->szDirectory = new WCHAR[dwSize];
if (pDirEntry->szDirectory) {
memcpy( pDirEntry->szDirectory, szName, dwSize);
}
return pDirEntry;
}
HANDLE NotifyCreateVolume( WCHAR *szNotifyPoint)
{
DWORD dwSize = (wcslen(szNotifyPoint)+1)*sizeof(WCHAR);
NOTVOLENTRY *pVolume = new NOTVOLENTRY;
if (!pVolume) {
return INVALID_HANDLE_VALUE;
}
InitializeCriticalSection(&pVolume->cs);
pVolume->dwSig = NOT_VOL_SIG;
pVolume->pDirEntry = NULL;
pVolume->szVolumeName = new WCHAR[dwSize];
pVolume->pHandles = NULL;
pVolume->pEvents = NULL;
pVolume->pNextVolume = NULL;
if (pVolume->szVolumeName) {
memcpy( pVolume->szVolumeName, szNotifyPoint, dwSize);
}
#ifdef UNDER_CE
if (!g_hNotifyAPI) {
InitializeCriticalSection( &g_csMain);
g_hNotifyAPI = CreateAPISet("FNOT", ARRAY_SIZE(apfnFindNotify), (const PFNVOID * )apfnFindNotify, asigFindNotify);
RegisterAPISet(g_hNotifyAPI, HT_FIND | REGISTER_APISET_TYPE);
}
EnterCriticalSection( &g_csMain);
if (g_pRootVolume) {
pVolume->pNextVolume = g_pRootVolume;
}
g_pRootVolume = pVolume;
LeaveCriticalSection( &g_csMain);
#endif
return (HANDLE)pVolume;
}
void DeleteHandles(NOTHANDLEENTRY *pHandles)
{
while(pHandles) {
NOTHANDLEENTRY *pHandle;
pHandle = pHandles;
pHandles = pHandle->pNext;
if (pHandle->szFileName)
delete [] pHandle->szFileName;
delete pHandle;
}
}
void DeleteFileInfos(NOTEVENTENTRY *pEvent)
{
while (pEvent->pFileInfo) {
NOTFILEINFO *pFileInfo;
pFileInfo = pEvent->pFileInfo;
pEvent->pFileInfo = pFileInfo->pNext;
delete [] pFileInfo->szFileName;
delete pFileInfo;
}
}
void DeleteEvents(NOTEVENTENTRY *pEvents)
{
while(pEvents) {
NOTEVENTENTRY *pEvent;
pEvent = pEvents;
DeleteFileInfos(pEvent);
pEvents = pEvent->pNext;
#ifdef UNDER_CE
SetHandleOwner( pEvent->hEvent, GetCurrentProcess());
#endif
// NKDbgPrintfW( L"Deleting event %08X\r\n", pEvent->hEvent);
CloseHandle( pEvent->hEvent);
pEvent->hEvent = NULL;
delete pEvent;
}
}
void ClearEvents(NOTEVENTENTRY *pEvents)
{
NOTEVENTENTRY *pEvent = pEvents;
while(pEvent) {
pEvent->pVolume = NULL;
pEvent = pEvent->pNext;
}
AddFileToEvent( pEvents,
L"\\",
FILE_NOTIFY_CHANGE_DIR_NAME,
FILE_ACTION_REMOVED);
CheckEventOnPath(pEvents, TRUE, TRUE);
}
void DeleteNotDirEntry(NOTDIRENTRY *pNotify)
{
pNotify->pParent = NULL;
while(pNotify) {
DeleteHandles( pNotify->pHandles);
ClearEvents( pNotify->pEvents);
NOTDIRENTRY *pNext;
if (pNotify->pChild) {
DeleteNotDirEntry(pNotify->pChild);
}
pNext = pNotify->pNext;
pNotify->pPrevious = NULL;
if (pNotify->szDirectory) {
delete [] pNotify->szDirectory;
}
delete pNotify;
pNotify = pNext;
}
}
#if 0
WCHAR g_szDumpPath[MAX_PATH];
void DumpDirEntry(NOTDIRENTRY *pNotify)
{
pNotify->pParent = NULL;
while(pNotify) {
if (!pNotify->bDepth) {
wcscpy( g_szDumpPath, L"\\");
wcscat( g_szDumpPath, pNotify->szDirectory);
} else {
wcscat(g_szDumpPath, L"\\");
wcscat(g_szDumpPath, pNotify->szDirectory);
}
if (pNotify->pChild) {
DumpDirEntry(pNotify->pChild);
}
if (!pNotify->bDepth) {
// NKDbgPrintfW( L"%s\r\n",szPath);
}
pNotify = pNotify->pNext;
}
}
#endif
void NotifyDeleteVolume(HANDLE hVolume)
{
NOTVOLENTRY *pVolume = (NOTVOLENTRY *)hVolume;
if (pVolume) {
ENTERNOTIFY(hVolume);
if (pVolume->pDirEntry) {
#if 0
DumpDirEntry(pVolume->pDirEntry);
#endif
DeleteNotDirEntry( pVolume->pDirEntry);
}
DeleteHandles(pVolume->pHandles);
ClearEvents(pVolume->pEvents);
EXITNOTIFY(hVolume);
EnterCriticalSection( &g_csMain);
if (g_pRootVolume == pVolume) {
g_pRootVolume = pVolume->pNextVolume;
} else {
NOTVOLENTRY * pCurVolume = g_pRootVolume;
while(pCurVolume) {
if (pCurVolume->pNextVolume == pVolume) {
pCurVolume->pNextVolume = pVolume->pNextVolume;
break;
}
pCurVolume = pCurVolume->pNextVolume;
}
}
LeaveCriticalSection( &g_csMain);
DeleteCriticalSection(&pVolume->cs);
if (pVolume->szVolumeName) {
delete [] pVolume->szVolumeName;
}
delete pVolume;
}
}
NOTDIRENTRY *InsertOrFindDirEntry(HANDLE hVolume,const WCHAR *szFullPath, WCHAR **pszFileName, BOOL bPath, BOOL bFind, BOOL *pbSubTree = NULL)
{
NOTVOLENTRY *pVolume = (NOTVOLENTRY *)hVolume;
NOTDIRENTRY *pDirectory = pVolume->pDirEntry;
WCHAR *szPath = NULL;
while(*szFullPath && (*szFullPath == L'\\'))
szFullPath++;
szPath = new WCHAR[wcslen(szFullPath)+1];
if (!szPath) {
return NULL;
}
wcscpy( szPath, szFullPath);
WCHAR *szCurrent = szPath;
NOTDIRENTRY *pParent = NULL;
NOTDIRENTRY *pCurrent = NULL;
if (pszFileName)
*pszFileName = NULL;
BYTE bDepth = 0;
while(*szCurrent) {
WCHAR *szTemp = szCurrent;
while(*szTemp && (*szTemp != L'\\'))
szTemp++;
if (*szTemp || bPath) {
if (*szTemp) {
*szTemp = L'\0';
szTemp++;
} else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?