悲剧膜拜一句话刷新缓存

悲剧膜拜一句话刷新缓存

前两天苦恼于如何刷新缓存,本来打算按照正常思路直接找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_VIOLATION



try_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去了….


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值