悲剧膜拜一句话刷新缓存

来源:互联网 发布:帝国cms 文件权限 编辑:程序博客网 时间:2024/05/17 03:40
悲剧膜拜一句话刷新缓存

前两天苦恼于如何刷新缓存,本来打算按照正常思路直接找CcFlushxx和MmFlushXX的参数,也就是遍历CcVACBs,尚未尝试不知是否可行之际无意发现Azy大牛博客上最后一篇文章写得一句话刷新缓存。膜拜之,我思路还是太窄了~

HANDLE hFile = CreateFile(L"\\\\.\\C:", GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

先用sudami的工具在磁盘级删除了一个文件,然后运行以下代码

HANDLE hFile = CreateFile(L"\\\\.\\C:", GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

printf("Finish! handle is 0x%x\n",hFile);

printf("%d\n",GetLastError());

运行后明显停滞了一会儿,然后返回错误码

ERROR_SHARING_VIOLATION    32 

The process cannot access the file because it is being used by another process.

D:\WinDDK\6001.18002\Tools\other\i386>winERROR 32

32 ERROR_SHARING_VIOLATION <--> 0xc0000043 STATUS_SHARING_VIOLATION

再用资源管理器一看,文件果然没了~~

弱小的心灵受到了严重打击。于是研究了一下。

把上面代码加上FILE_SHARE_WRITE标记,就刷不上了,看来问题就是在dwShareMode这个参数上。

CreateFile的流程前两天记录过了。。从CreateFile一路检查到IopParseDevice,都没发现对dwShareMode有任何处理,先是openPacket->ShareAccess = (USHORT) ShareAccess 进入对象管理器,

然后跟着 irpSp->Parameters.Create.ShareAccess = op->ShareAccess; 发出Irp

从NT4 的NTFS中可以看到,(注释翻译的很矬。。)


NtfsFsdCreate:if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_DASD_OPEN )) {Status = NtfsCommonVolumeOpen( IrpContext, Irp );NtfsCommonVolumeOpen:if (!FlagOn( IrpSp->Parameters.Create.ShareAccess,FILE_SHARE_WRITE | FILE_SHARE_DELETE )){////  Do a quick test of the volume cleanup count if this opener won't//  share with anyone.  We can safely examine the cleanup count without//  further synchronization because we are guaranteed to have the//  Vcb exclusive at this point.////没有设置写和删除的共享位,要快速检测卷的CleanupCount//我们不需要同步处理就可以安全测试这个计数,因为在这时我们能保证VBP独占?//CleanupCount 是未清理的句柄计数,如果有的话表明被别人打开了。if (!FlagOn( IrpSp->Parameters.Create.ShareAccess, FILE_SHARE_READ) &&Vcb->CleanupCount != 0){//没有共享读,直接返回STATUS_SHARING_VIOLATIONtry_return( Status = STATUS_SHARING_VIOLATION );}////  Go ahead and flush and purge the volume.  Then test to see if all//  of the user file objects were closed.////刷新卷,测试是否所有的用户态文件对象都关闭了Status = NtfsFlushVolume( IrpContext, Vcb, TRUE, TRUE, TRUE, FALSE );////  If the flush and purge was successful but there are still file objects//  that block this open it is possible that the FspClose thread is//  blocked behind the Vcb.  Drop the Fcb and Vcb to allow this thread//  to get in and then reacquire them.  This will give this Dasd open//  another chance to succeed on the first try.////如果刷新  清理卷  依然后文件对象阻碍我们打开,FIXME:可能是 FspClose 线程在VCB之后被阻碍?//释放FCB VCB ,执行线程并重新获得XCB。这回有第二次机会去打开?SharingViolation = FALSE;if (FlagOn( IrpSp->Parameters.Create.ShareAccess, FILE_SHARE_READ)) {if (Vcb->ReadOnlyCloseCount != (Vcb->CloseCount - Vcb->SystemFileCloseCount)) {SharingViolation = TRUE;}} else if (Vcb->CloseCount != Vcb->SystemFileCloseCount) {SharingViolation = TRUE;}。。。。后面还有一大堆操作来尝试让这次irp成功,当然了,是成功不了的。。在这里调用了NtfsFlushVolume,晕,以前我都没发现这个函数。。XP下似乎复杂了,不过从IDA来看 ,对于dwShareMode的检查和调用NtfsFlushVolume并没有变咧。。额~~~去搞Hard Link 和Junction去了….