注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

dingchaoqun12 的博客

上海股票期货开户

 
 
 

日志

 
 
 
 

请问windows下能不能安装钩子监视指定目录下的所有文件创建/删除等事件 - CSDN论坛 - CSDN.NET  

2012-11-10 16:17:16|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
通过 未公开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; 
}


引文来源  请问windows下能不能安装钩子监视指定目录下的所有文件创建/删除等事件 - CSDN论坛 - CSDN.NET
  评论这张
 
阅读(400)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018