本论坛为只读模式,仅供查阅,不能注册新用户,不能发帖/回帖,有问题可发邮件 xikug.xp (^) gmail.com
查看: 3329|回复: 4

《寒江独钓》透明加密中清除缓存的函数几个疑问 [复制链接]

Rank: 1

发表于 2010-7-9 12:29:22 |显示全部楼层
//也算是一个笔记吧,里面有几个不太清楚的问题请大家指教
  1. //清理缓冲  《寒江独钓》p233
  2. void cfFileCacheClear(PFILE_OBJECT pFileObject)
  3. {
  4.    PFSRTL_COMMON_FCB_HEADER pFcb;
  5.    LARGE_INTEGER liInterval;
  6.    BOOLEAN bNeedReleaseResource = FALSE;
  7.    BOOLEAN bNeedReleasePagingIoResource = FALSE;
  8.    KIRQL irql;
  9.    pFcb = (PFSRTL_COMMON_FCB_HEADER)pFileObject->FsContext;    //从文件对象得到FCB(file control block 文件控制块)
  10.    if(pFcb == NULL)
  11.        return;
  12.    irql = KeGetCurrentIrql();    //得到当前IRQL并保证不大于DISPATCH_LEVEL方可进行
  13.    if (irql >= DISPATCH_LEVEL)    //其后函数需要在小于DISPATCH_LEVEL级别上执行
  14.    {
  15.        return;
  16.    }
  17.    liInterval.QuadPart = -1 * (LONGLONG)50;    //后面需使用的等待时间
  18.    while (TRUE)
  19.    {
  20.        BOOLEAN bBreak = TRUE;
  21.        BOOLEAN bLockedResource = FALSE;
  22.        BOOLEAN bLockedPagingIoResource = FALSE;
  23.        bNeedReleaseResource = FALSE;
  24.        bNeedReleasePagingIoResource = FALSE;
  25.        // 到fcb中去拿锁。
  26.        //测试当前线程是否有指定资源的独占访问权。返回TRUE
  27.        if (pFcb->PagingIoResource)
  28.            bLockedPagingIoResource = ExIsResourceAcquiredExclusiveLite(pFcb->PagingIoResource);
  29.        // 总之一定要拿到这个锁。
  30.        if (pFcb->Resource)        
  31.        {
  32.            bLockedResource = TRUE;
  33.            if (ExIsResourceAcquiredExclusiveLite(pFcb->Resource) == FALSE)   
  34.                //此处不解??为什么要不能互斥获得pFcb->Resource才开始以下处理?
  35.            {
  36.                bNeedReleaseResource = TRUE;    //开始获得资源 并将标识置为真。为其后不能同时获得RESOURCE及PAGERESURCE做释放准备
  37.                                             //不能全部获得两设备必须释放并重新进行获取过程,直到全部获取两资源。
  38.                if (bLockedPagingIoResource)    //此处不解??根据另一资源能否互斥获取来决定获得本资源时等待还是立即返回?
  39.                {
  40.                    if (ExAcquireResourceExclusiveLite(pFcb->Resource, FALSE) == FALSE)
  41.                    {
  42.                        bBreak = FALSE;        //获取失败自然BREAK标记为FALSE,继续循环
  43.                        bNeedReleaseResource = FALSE;    //获取失败,
  44.                        bLockedResource = FALSE;
  45.                    }
  46.                }
  47.                else                    //有独占访问权则互斥获得资源
  48.                    ExAcquireResourceExclusiveLite(pFcb->Resource, TRUE);
  49.            }
  50.        }
  51.       
  52.        if (bLockedPagingIoResource == FALSE)        //获取PAGINGIORESOURCE类似获取RESOURCE
  53.        {
  54.            if (pFcb->PagingIoResource)
  55.            {
  56.                bLockedPagingIoResource = TRUE;
  57.                bNeedReleasePagingIoResource = TRUE;
  58.                if (bLockedResource)
  59.                {
  60.                    if (ExAcquireResourceExclusiveLite(pFcb->PagingIoResource, FALSE) == FALSE)
  61.                    {
  62.                        bBreak = FALSE;
  63.                        bLockedPagingIoResource = FALSE;
  64.                        bNeedReleasePagingIoResource = FALSE;
  65.                    }
  66.                }
  67.                else
  68.                {
  69.                    ExAcquireResourceExclusiveLite(pFcb->PagingIoResource, TRUE);
  70.                }
  71.            }
  72.        }
  73.       
  74.        if (bBreak)        
  75.        {
  76.            break;
  77.        }
  78.       
  79.        //只获得其中一个资源必须释放,防止死锁。等待指定时间后,继续获取
  80.        if (bNeedReleasePagingIoResource)
  81.        {
  82.            ExReleaseResourceLite(pFcb->PagingIoResource);
  83.        }
  84.        if (bNeedReleaseResource)
  85.        {
  86.            ExReleaseResourceLite(pFcb->Resource);        
  87.        }
  88.       
  89.        if (irql == PASSIVE_LEVEL)                //等待指定时间后继续循环
  90.        {
  91.            KeDelayExecutionThread(KernelMode, FALSE, &liInterval);
  92.            //KeDelayExecutionThread must be running at IRQL = PASSIVE_LEVEL.
  93.        }
  94.        else
  95.        {
  96.            //其他IRQL等级下 使用这种方法等待
  97.            KEVENT waitEvent;
  98.            KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
  99.            KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, &liInterval);
  100.        }
  101.    }
  102.    
  103. //互斥获取资源均为刷新缓存做准备。
  104.    if (pFileObject->SectionObjectPointer)
  105.    {
  106.        IO_STATUS_BLOCK ioStatus;
  107.        CcFlushCache(pFileObject->SectionObjectPointer, NULL, 0, &ioStatus);
  108.        if (pFileObject->SectionObjectPointer->ImageSectionObject)
  109.        {
  110.            MmFlushImageSection(pFileObject->SectionObjectPointer,MmFlushForWrite); // MmFlushForDelete
  111.        }
  112.        CcPurgeCacheSection(pFileObject->SectionObjectPointer, NULL, 0, FALSE);
  113.    }
  114.    
  115.    if (bNeedReleasePagingIoResource)
  116.    {
  117.        ExReleaseResourceLite(pFcb->PagingIoResource);
  118.    }
  119.    if (bNeedReleaseResource)
  120.    {
  121.        ExReleaseResourceLite(pFcb->Resource);
  122.    }
  123. }
复制代码

文中的几处疑惑还是来自自己对API运用的不熟悉
if (ExIsResourceAcquiredExclusiveLite(pFcb->Resource) == FALSE)   
               //此处不解??为什么要不能互斥获得pFcb->Resource才开始以下处理?


if (bLockedPagingIoResource)    //此处不解??根据另一资源能否互斥获取来决定获得本资源时等待还是立即返回?


那么会不会出现 ExIsResourceAcquiredExclusiveLite 得出互斥获取两资源均为真
而没有运行ExIsResourceAcquiredExclusiveLite来获得资源便来到BREAK处跳出了??

Rank: 1

发表于 2010-7-11 15:07:14 |显示全部楼层
关键是这句
  // 总之一定要拿到这个锁。

如果已经拿到锁,就不用循环了,如果
if (ExIsResourceAcquiredExclusiveLite(pFcb->Resource) == FALSE)   
则说明没拿到锁,则要继续拿锁,如果加锁成功,则不继续acquir了,直接break出来了

Rank: 1

发表于 2010-7-11 21:18:14 |显示全部楼层
根据我的理解
if (ExIsResourceAcquiredExclusiveLite(pFcb->Resource) == FALSE)    是测试是否能够互斥的获得资源 而不是互斥获得资源
而且非要确定不能互斥拿到RESOURCE才能进行? 我觉得应该是确定能够互斥获得资源才去获得资源
而且ExIsResourceAcquiredExclusiveLite(pFcb->Resource)
ExIsResourceAcquiredExclusiveLite(pFcb->PagingIoResource) 都为真 也就是都可以互斥获得资源时
代码并不执行ExAcquireResourceExclusiveLite 来获得资源直接来到下面并break跳出

是我理解错误还是代码有误?

Rank: 1

发表于 2010-7-12 18:47:49 |显示全部楼层
The ExIsResourceAcquiredExclusiveLite routine returns whether the current thread has exclusive access to a given resource.

当前线程是否已经获得了锁

Rank: 1

发表于 2010-7-13 00:38:18 |显示全部楼层
英语不好 潜意识认为哪个是测试是否有资源互斥访问权限
而不是是否互斥获得资源
现在明确了。  谢谢各位
您需要登录后才可以回帖 登录 | 立即加入

Archiver|手机版|第8个男人 - 论坛为只读模式,仅供查阅

GMT+8, 2019-6-26 14:57 , Processed in 0.022921 second(s), 8 queries .

Design by pvo.cn

© 2011 Pvo Inc.

回顶部