wince文件监控方式

最近需要做wince下文件监控,总结了一下方法。当然有的方法比较难,鉴于能力和时间有限,就没有去尝试。

方法:
1.  虚拟文件系统驱动
此方法可以参照windows 下的filemon,网上很多分析的文章,这里就不列举了。
此方法也是作者认为比较难的方法,所以没有花精力去尝试。

2.  HOOK API
此方法可以找到例子
http://www.drdobbs.com/index.jhtml 
此头大牛的sourcecode 下的 Dr. Dobb's Journal  链接下的2003 的0310.zip
不过代码中拿到windows mobile5以上版本运行需要些许改动,将HINSTANCE SpyEngine::LoadHookDllIntoProcess(HANDLE p_hProcess)方法的CallbackInfo.m_pFunction赋值哪一行稍作改动,CallbackInfo.m_pFunction = (FARPROC)GetProcAddress(GetModuleHandle( _T("coredll.dll") ),_T("LoadLibraryW") );
因为不知名的原因,在mobile5以上,m_pSystemAPISets[SH_WIN32]->m_ppMethods[W32_LoadLibraryW];无法得到正确的地址。所以换个方法即可。
注:暂时没找到如何使用SetWindowsHookEx方法监控文件操作的消息。希望哪位知道的大牛指点一二。

3.  消息机制
从windows的文件通知消息获取系统的文件操作。但是貌似这是文件操作已经完成,才通知我的。这只能监视,却不能完全的控制。至于消息机制有很多方法。
例如,以下这几个很多论坛都转载过的方法。
转自:http://group.gimoo.net/review/159052 
================================================================= 

通过 未公开API SHChangeNotifyRegister 实现 

================================================================= 
Windows 内部有两个未公开的函数(注:在最新的MSDN中,已经公开了这两个函数),分别叫做SHChangeNotifyRegister和 SHChangeNotifyDeregister,可以实现以上的功能。这两个函数位于Shell32.dll中,是用序号方式导出的。这就是为什么我 们用VC自带的Depends工具察看Shell32.dll时,找不到这两个函数的原因。SHChangeNotifyRegister的导出序号是 2;而SHChangeNotifyDeregister的导出序号是4。 
SHChangeNotifyRegister可以把指定的窗口添加到系统的消息监视链中,这样窗口就能接收到来自文件系统或者Shell的通知了。而对 应的另一个函数,SHChangeNotifyDeregister,则用来取消监视钩挂。SHChangeNotifyRegister的原型和相关参 数如下: 
ULONG SHChangeNotifyRegister 
(        
HWND hwnd, 
int  fSources, 
LONG fEvents, 
UINT    wMsg, 
Int cEntries, 
SHChangeNotifyEntry *pfsne 
); 
其中: 
hwnd 
将要接收改变或通知消息的窗口的句柄。 
fSource 
指示接收消息的事件类型,将是下列值的一个或多个(注:这些标志没有被包括在任何头文件中,使用者须在自己的程序中加以定义或者直接使用其对应的数值) 
SHCNRF_InterruptLevel 
0x0001。接收来自文件系统的中断级别通知消息。 
SHCNRF_ShellLevel 
0x0002。接收来自Shell的Shell级别通知消息。 
SHCNRF_RecursiveInterrupt 
0x1000。接收目录下所有子目录的中断事件。此标志必须和SHCNRF_InterruptLevel 标志合在一起使用。当使用该标志时,必须同时设置对应的SHChangeNotifyEntry结构体中的fRecursive成员为TRUE(此结构体 由函数的最后一个参数pfsne指向),这样通知消息在目录树上是递归的。 
SHCNRF_NewDelivery 
0x8000。接收到的消息使用共享内存。必须先调用SHChangeNotification_Lock,然后才能存取实际的数据,完成后调用 SHChangeNotification_Unlock函数释放内存。 
fEvents 
要捕捉的事件,其所有可能的值请参见MSDN中关于SHChangeNotify函数的注解。 
wMsg 
产生对应的事件后,发往窗口的消息。 
cEntries 
pfsne指向的数组的成员的个数。 
pfsne 
SHChangeNotifyEntry 结构体数组的起始指针。此结构体承载通知消息,其成员个数必须设置成1,否则SHChangeNotifyRegister或者 SHChangeNotifyDeregister将不能正常工作(但是据我试验,如果cEntries设为大于1的值,依然可以注册成功,不知何故)。 
如果函数调用成功,则返回一个整型注册标志号,否则将返回0。同时系统就会将hwnd指定的窗口加入到操作监视链中,当有文件操作发生时,系统会向 hwnd标识的窗口发送wMsg指定的消息,我们只要在程序中加入对该消息的处理函数就可以实现对系统操作的监视了。 
如果要退出程序监视,就要调用另外一个未公开得函数SHChangeNotifyDeregister来取消程序监视。该函数的原型如下:
BOOL SHChangeNotifyDeregister(ULONG ulID); 
其中ulID指定了要注销的监视注册标志号,如果卸载成功,返回TRUE,否则返回FALSE。 
================================================================= 

通过 FindFirstChangeNotification 实现 

================================================================= 


FindFirstChangeNotification函数创建一个更改通知句柄并设置初始更改通知过滤条件. 
当一个在指定目录或子目录下发生的更改符合过滤条件时,等待通知句柄则成功。 
该函数原型为: 
HANDLE FindFirstChangeNotification( 
LPCTSTR lpPathName, //目录名 
BOOL bWatchSubtree, // 监视选项 
DWORD dwNotifyFilter // 过滤条件 
); 

当下列情况之一发生时,WaitForMultipleObjects函数返回 
1.一个或者全部指定的对象在信号状态(signaled state) 
2.到达超时间隔 


例程如下: 
DWORD dwWaitStatus; 
HANDLE dwChangeHandles[2]; 

//监视C:\Windows目录下的文件创建和删除 

dwChangeHandles[0] = FindFirstChangeNotification( 
"C:\\WINDOWS", // directory to watch 
FALSE, // do not watch the subtree 
FILE_NOTIFY_CHANGE_FILE_NAME); // watch file name changes 

if (dwChangeHandles[0] == INVALID_HANDLE_VALUE) 
ExitProcess(GetLastError()); 

//监视C:\下子目录树的文件创建和删除 

dwChangeHandles[1] = FindFirstChangeNotification( 
"C:\\", // directory to watch 
TRUE, // watch the subtree 
FILE_NOTIFY_CHANGE_DIR_NAME); // watch dir. name changes 

if (dwChangeHandles[1] == INVALID_HANDLE_VALUE) 
ExitProcess(GetLastError()); 

// Change notification is set. Now wait on both notification 
// handles and refresh accordingly. 

while (TRUE) 


// Wait for notification. 

dwWaitStatus = WaitForMultipleObjects(2, dwChangeHandles,FALSE, INFINITE); 

switch (dwWaitStatus) 

case WAIT_OBJECT_0: 

//在C:\WINDOWS目录中创建或删除文件 。 
//刷新该目录及重启更改通知(change notification). 

AfxMessageBox("RefreshDirectory"); 
if ( FindNextChangeNotification(dwChangeHandles[0]) == FALSE ) 
ExitProcess(GetLastError()); 
break; 

case WAIT_OBJECT_0 1: 
//在C:\WINDOWS目录中创建或删除文件 。 
//刷新该目录树及重启更改通知(change notification). 

AfxMessageBox("RefreshTree"); 
if (FindNextChangeNotification(dwChangeHandles[1]) == FALSE) 
ExitProcess(GetLastError()); 
break; 

default: 
ExitProcess(GetLastError()); 




================================================================= 

通过 ReadDirectoryChangesW 实现 

================================================================= 

bool Monitor() 



HANDLE hFile  =  CreateFile( 
"c:\\", 
GENERIC_READ|GENERIC_WRITE, 
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, 
NULL, 
OPEN_EXISTING, 
FILE_FLAG_BACKUP_SEMANTICS, 
NULL 
); 
if(  INVALID_HANDLE_VALUE  ==  hFile  )  return  false; 

char  buf[  2*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH)  ]; 
FILE_NOTIFY_INFORMATION*  pNotify=(FILE_NOTIFY_INFORMATION  *)buf; 
DWORD  BytesReturned; 
while(true) 

if(  ReadDirectoryChangesW(  hFile, 
pNotify, 
sizeof(buf), 
true, 
FILE_NOTIFY_CHANGE_FILE_NAME| 
FILE_NOTIFY_CHANGE_DIR_NAME| 
FILE_NOTIFY_CHANGE_ATTRIBUTES| 
FILE_NOTIFY_CHANGE_SIZE| 
FILE_NOTIFY_CHANGE_LAST_WRITE| 
FILE_NOTIFY_CHANGE_LAST_ACCESS| 
FILE_NOTIFY_CHANGE_CREATION| 
FILE_NOTIFY_CHANGE_SECURITY, 
&BytesReturned, 
NULL, 
NULL  )  ) 

char  tmp[MAX_PATH],  str1[MAX_PATH],  str2[MAX_PATH]; 
memset(  tmp,  0,  sizeof(tmp)  ); 
WideCharToMultiByte(  CP_ACP,0,pNotify->FileName,pNotify->FileNameLength/2,tmp,99,NULL,NULL  ); 
strcpy(  str1,  tmp  ); 

if(  0  !=  pNotify->NextEntryOffset  ) 

PFILE_NOTIFY_INFORMATION  p  =  (PFILE_NOTIFY_INFORMATION)((char*)pNotify+pNotify->NextEntryOffset); 
memset(  tmp,  0,  sizeof(tmp)  ); 
WideCharToMultiByte(  CP_ACP,0,p->FileName,p->FileNameLength/2,tmp,99,NULL,NULL  ); 
strcpy(  str2,  tmp  ); 


// your process 

else 

break; 



return true; 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值