支持还原功能的磁盘卷过滤驱动代码-2_yeluosong的空间_百度空间

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

drbitmap.c

#include <ntifs.h>
#include <windef.h>
#include "drbitmap.h"

VOID DRBitmapFree (IN PDR_BITMAP bitmap)
{
int i;
PTBITMAP *temp = NULL;

if (NULL != bitmap)
{
   if (NULL != (temp = bitmap->Bitmap))
   {
    for (i = 0; i < bitmap->regionNumber; i++)
    {
     if (*(temp +i) != NULL)
     {
      ExFreePool (*(temp+i));
     }
    }
    ExFreePool(temp);
   }
   ExFreePool (bitmap);
}
}


NTSTATUS DRBitmapInit (
IN DR_BITMAP ** bitmap,
IN ULONG sectorsize,
IN ULONG bytesize,
IN ULONG regionsize,//regionsize须为8的倍数
IN ULONG regionNumber
)
{
int i;
PDR_BITMAP pBitmap = NULL;
PTBITMAP* Temp = NULL;
NTSTATUS status;

if ((NULL == bitmap) || (sectorsize == 0) || (bytesize == 0) || (regionsize == 0) || (regionNumber == 0))
{
   return STATUS_UNSUCCESSFUL;
}
//创建一个DR_BITMAP结构
pBitmap = (PDR_BITMAP)ExAllocatePool (NonPagedPool, sizeof (DR_BITMAP));
if (NULL == pBitmap)
{
   status = STATUS_INSUFFICIENT_RESOURCES;
   goto ERROR;
}

memset (pBitmap, 0, sizeof(DR_BITMAP));

pBitmap->sectorSize = sectorsize;
pBitmap->byteSize = bytesize;
pBitmap->regionSize = regionsize;
pBitmap->regionNumber = regionNumber;
pBitmap->regionReferSize = regionsize * sectorsize;
pBitmap->bitmapReferSize = (__int64) pBitmap->regionReferSize * regionNumber;
//创建bitmap指针数组,用于指向每个region所对应的bitmap
Temp =(PTBITMAP*) ExAllocatePool (NonPagedPool ,sizeof(PTBITMAP)* pBitmap->regionNumber);

if (NULL == Temp)
{
   status = STATUS_INSUFFICIENT_RESOURCES;
   goto ERROR;
}
memset ((PBYTE)Temp,0,sizeof(PTBITMAP)* pBitmap->regionNumber);
*bitmap = pBitmap;
pBitmap->Bitmap = Temp;

status = STATUS_SUCCESS;

ERROR:
if (!NT_SUCCESS (status))
{
   if (NULL != pBitmap)
   {
    ExFreePool (pBitmap);
   }
}

return status;
}

NTSTATUS DRBitmapSet (
IN PDR_BITMAP bitmap,
IN LARGE_INTEGER offset,
IN unsigned long length
)
{
__int64 i = 0, j = 0, AlignBegin = 0 , AlignEnd = 0;
unsigned long regionPos = 0, regionPosEnd = 0, regionleft = 0;
unsigned long ByteNum = 0, BytePos = 0, BitPos = 0;
NTSTATUS status;

//获得访问范围所在的区块
regionPos = (unsigned long)(offset.QuadPart / (__int64)bitmap->regionReferSize);
regionPosEnd = (unsigned long)((offset.QuadPart + (__int64)length)/(__int64)bitmap->regionReferSize);
//为每个区块分配一个bitmap
for (i = regionPos; i <= regionPosEnd; i++)
{
   if (NULL == *(bitmap->Bitmap + i))
   {
    *(bitmap->Bitmap + i) = ExAllocatePool (NonPagedPool, bitmap->regionSize / 8);
    if (NULL == *(bitmap->Bitmap + i))
    {
     status = STATUS_INSUFFICIENT_RESOURCES;
     goto ERROR;
    }else
    {
     memset ((PBYTE)*(bitmap->Bitmap + i), 0 , bitmap->regionSize / 8);
    }
   }
}
//将访问范围开头不能对齐的bitmap置位
for (i = 0; i < (__int64)length ; i += bitmap->sectorSize)
{
   regionPos = (unsigned long)(offset.QuadPart / (__int64)bitmap->regionReferSize);
   regionleft = (unsigned long)(offset.QuadPart % (__int64)bitmap->regionReferSize);
   BytePos = regionleft / bitmap->sectorSize / bitmap->byteSize;
   BitPos = regionleft / bitmap->sectorSize % bitmap->byteSize;
   if (BitPos == 0)
   {
    AlignBegin = offset.QuadPart + i;//此时前段已经对齐
    break;
   }
   *(*(bitmap->Bitmap + regionPos)+BytePos) |= bitmapMask[BitPos];
}
//若访问范围只有几个sector,且他们对应的bitmap位均在同一字节,则AlignBegin未被设置
if (AlignBegin == 0)
{
   return STATUS_SUCCESS;
}
//将访问范围结尾不能对齐的bitmap置位
for (i = offset.QuadPart + (__int64)length ; i >= offset.QuadPart ; i -= bitmap->sectorSize)
{
   regionPos = (unsigned long)(i / (__int64)bitmap->regionReferSize);
   regionleft = (unsigned long)(i % (__int64)bitmap->regionReferSize);
   BytePos = regionleft / bitmap->sectorSize / bitmap->byteSize;
   BitPos = regionleft / bitmap->sectorSize % bitmap->byteSize;
   if (BitPos == 0)
   {
    AlignEnd = i;//此时后段已经对齐
    break;
   }
   *(*(bitmap->Bitmap + regionPos)+BytePos) |= bitmapMask[BitPos];
}


//AlignBegin == AlignEnd表示经过以上两轮设置后,头尾相碰,即全部设置完毕
if (AlignBegin == AlignEnd)
{
   return STATUS_SUCCESS;
}
//处理AlignEnd - AlignBegin != 0的情况
while (TRUE)
{
   regionPos = (unsigned long)(AlignBegin / (__int64)bitmap->regionReferSize);
   regionPosEnd = (unsigned long)(AlignEnd / (__int64)bitmap->regionReferSize);

   if( regionPos == regionPosEnd)
   { // AlignEnd AlignBegin在同一区域,只需要把他们之间的sector对应的bitmap位置位即可
    regionPos = (unsigned long)(AlignBegin / (__int64)bitmap->regionReferSize);
    regionleft = (unsigned long)(AlignBegin % (__int64)bitmap->regionReferSize);
    BytePos = regionleft / bitmap->sectorSize / bitmap->byteSize;
    ByteNum =(unsigned long)((AlignEnd - AlignBegin) / (__int64)bitmap->sectorSize / (__int64)bitmap->byteSize);
    memset ((*(bitmap->Bitmap + regionPos)+BytePos), 0xff, ByteNum);
    break;
   }else
   {
    // AlignEnd AlignBegin不在同一区域,需把AlignBegin及其后当前区域所有sector置位
    regionleft = (unsigned long)(AlignBegin % (__int64)bitmap->regionReferSize);
    BytePos = regionleft / bitmap->sectorSize / bitmap->byteSize;
    ByteNum = bitmap->regionSize / bitmap->byteSize - BytePos;
    memset ((*(bitmap->Bitmap + regionPos)+BytePos), 0xff, ByteNum);
    AlignBegin += (__int64)ByteNum * (__int64)bitmap->byteSize * (__int64)bitmap->sectorSize;
   }
}
return STATUS_SUCCESS;

ERROR:
return status;
}

NTSTATUS DRBitmapCombine (
IN PDR_BITMAP bitmap,
IN LARGE_INTEGER offset,
IN unsigned long length,
OUT PVOID bufInOut,//对应于设备输出数据的缓冲
IN PVOID bufIn//对应于转存文件输出数据的缓冲
)
{
unsigned long i;
unsigned long RegionPos = 0, RegionLeft = 0;
unsigned long SectorNum = 0, BytePos = 0, BitPos = 0;
NTSTATUS status;

if((NULL == bitmap) || (length == 0) || (bufInOut == NULL) || (NULL == bufIn))
{
   status = STATUS_UNSUCCESSFUL;
   goto ERROR;
}

for (i = 0; i < length; i += bitmap->sectorSize)
{
   RegionPos = (unsigned long)((offset.QuadPart + (__int64)i)/(__int64)bitmap->regionReferSize);
   RegionLeft = (unsigned long)((offset.QuadPart + (__int64)i)%(__int64)bitmap->regionReferSize);
   SectorNum = RegionLeft / bitmap->sectorSize;
   BytePos = SectorNum / bitmap->byteSize;
   BitPos = SectorNum % bitmap->byteSize;
   //将转存在转存文件的数据拷贝到设备输出数据的缓冲区,实现合并
   if ((NULL != *(bitmap->Bitmap + RegionPos)) && (*(*(bitmap->Bitmap + RegionPos)+BytePos) & bitmapMask[BitPos]))
   {
    memcpy ((PBYTE)bufInOut + i, (PBYTE)bufIn, bitmap->sectorSize);
   }
}
status = STATUS_SUCCESS;
ERROR:
return status;
}

unsigned long DRBitmapTest (
IN PDR_BITMAP bitmap,
IN LARGE_INTEGER offset,
IN unsigned long length
)
{
unsigned long i,flag = 0;
unsigned long RegionPos = 0, RegionLeft = 0;
unsigned long SectorNum = 0, BytePos = 0, BitPos = 0;

if((NULL == bitmap) || (length == 0))
{
   flag = 0;
   goto ERROR;
}
//对范围内的bitmap进行位检测
for (i = 0; i < length; i += bitmap->sectorSize)
{
   RegionPos = (unsigned long)((offset.QuadPart + (__int64)i)/(__int64)bitmap->regionReferSize);
   RegionLeft = (unsigned long)((offset.QuadPart + (__int64)i)%(__int64)bitmap->regionReferSize);
   SectorNum = RegionLeft / bitmap->sectorSize;
   BytePos = SectorNum / bitmap->byteSize;
   BitPos = SectorNum % bitmap->byteSize;
  
   if ((NULL != *(bitmap->Bitmap + RegionPos)) && (*(*(bitmap->Bitmap + RegionPos)+BytePos) & bitmapMask[BitPos]))
   {
    flag |= 0x2;//若范围内对应的所有bitmap位均为1,则flag =0x2,表示访问均发生在转存文件
   }else
   {
    flag |= 0x1;//若范围内对应的所有bitmap位均为0,则flag =0x1,表示访问均发生在磁盘卷上
   }

   if (flag == 3)//若以上两者兼而有之,则flag = 0x3
   {
    break;
   }
}

ERROR:
return flag;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

drbitmap.h

#define ALL_IN_BITMAP 0x2
#define NONE_IN_BITMAP 0x1
#define SOME_IN_BITMAP 0x3
typedef UCHAR TBITMAP, *PTBITMAP;
typedef UCHAR BYTE, *PBYTE;
#pragma pack(1)
typedef struct _BITMAP
{
//这个卷中的每个扇区有多少字节,这同样也说明了bitmap中一个位所对应的字节数
    unsigned long sectorSize;
//每个byte里面有几个bit,一般情况下是8
    unsigned long byteSize;
//每个块由多少个Sector构成,
    unsigned long regionSize;
//这个bitmap总共有多少个块
    unsigned long regionNumber;
//这个块对应了多少个实际的byte,这个数字应该是sectorSize*regionSize
    unsigned long regionReferSize;
//这个bitmap对应了多少个实际的byte,这个数字应该是sectorSize*regionSize*regionNumber
    __int64 bitmapReferSize;
//指向bitmap存储空间的指针
    TBITMAP** Bitmap;
//用于存取bitmap的锁
    void* lockBitmap;
} DR_BITMAP, * PDR_BITMAP;
#pragma pack()

static TBITMAP bitmapMask[8] =
{
//需要用到的bitmap的位掩码
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};

unsigned long DRBitmapTest (
IN PDR_BITMAP bitmap,
IN LARGE_INTEGER offset,
IN unsigned long length
);

NTSTATUS DRBitmapCombine (
IN PDR_BITMAP bitmap,
IN LARGE_INTEGER offset,
IN unsigned long length,
OUT PVOID bufInOut,
IN PVOID bufIn);
NTSTATUS DRBitmapSet (
IN PDR_BITMAP bitmap,
IN LARGE_INTEGER offset,
IN unsigned long length
);
NTSTATUS DRBitmapInit (
IN DR_BITMAP ** bitmap,
IN ULONG sectorsize,
IN ULONG bytesize,
IN ULONG regionsize,
IN ULONG regionNumber);

VOID DRBitmapFree (IN PDR_BITMAP bitmap);

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

diskrestore.h
typedef struct _DR_FILDEV_EXTENSION
{
//卷名
WCHAR VolumeName;
//卷的保护状态
BOOL Protect;
//这个卷的总大小
LARGE_INTEGER TotalSizeOfVolume;
//这个卷文件系统上每个簇的大小
DWORD SizeOfCluster;
//这个卷每个扇区的大小
DWORD SizeOfSector;
//此卷设备对应的过滤设备的设备对象
PDEVICE_OBJECT FilterDevObj;
//此卷过滤设备对象对应的下层设备对象
PDEVICE_OBJECT LowerDevObj;
//此卷过滤设备对象对应的物理设备对象
PDEVICE_OBJECT PhysicalDevObj;
//此结构是否已经初始化完毕
BOOL InitializeCompleted;
//保护此卷所使用的Bitmap对象
PDR_BITMAP Bitmap;
//用于转存文件的句柄
HANDLE StoreFile;
//处理请求队列的线程的事件
KEVENT RequestEvent;
//转存使用的请求队列
LIST_ENTRY RequestList;
//转存使用的请求队列对应的锁
KSPIN_LOCK RequestLock;
//处理请求队列线程的句柄
PVOID ThreadObject;
//处理请求队列线程的结束标志
BOOL ThreadTerminateFlag;
//关机分页电源请求的计数事件
KEVENT PagingPathCountEvent;
//关机分页电源请求的次数
ULONG PagingPathCount;
} DR_FILDEV_EXTENSION, *PDR_FILDEV_EXTENSION;

//用于传递给DeviceControl回调函数的结构
typedef struct _VOLUME_CONTEXT
{
PDR_FILDEV_EXTENSION pDevExt;
PKEVENT pEvent;
} VOLUME_CONTEXT, *PVOLUME_CONTEXT;

#pragma pack(1)
typedef struct _DP_FAT16_BOOT_SECTOR
{
UCHAR   JMPInstruction[3];
UCHAR   OEM[8];
USHORT   BytesPerSector;
UCHAR   SectorsPerCluster;
USHORT   ReservedSectors;
UCHAR   NumberOfFATs;
USHORT   RootEntries;
USHORT   Sectors;
UCHAR   MediaDescriptor;
USHORT   SectorsPerFAT;
USHORT   SectorsPerTrack;
USHORT   Heads;
DWORD   HiddenSectors;
DWORD   LargeSectors;
UCHAR   PhysicalDriveNumber;
UCHAR   CurrentHead;
} DP_FAT16_BOOT_SECTOR, *PDP_FAT16_BOOT_SECTOR;

typedef struct _DP_FAT32_BOOT_SECTOR
{
UCHAR   JMPInstruction[3];
UCHAR   OEM[8];
USHORT   BytesPerSector;
UCHAR   SectorsPerCluster;
USHORT   ReservedSectors;
UCHAR   NumberOfFATs;
USHORT   RootEntries;
USHORT   Sectors;
UCHAR   MediaDescriptor;
USHORT   SectorsPerFAT;
USHORT   SectorsPerTrack;
USHORT   Heads;
DWORD   HiddenSectors;
DWORD   LargeSectors;
DWORD   LargeSectorsPerFAT;
UCHAR   Data[24];
UCHAR   PhysicalDriveNumber;
UCHAR   CurrentHead;
} DP_FAT32_BOOT_SECTOR, *PDP_FAT32_BOOT_SECTOR;

typedef struct _DP_NTFS_BOOT_SECTOR
{
UCHAR   Jump[3];      //0
UCHAR   FSID[8];      //3
USHORT   BytesPerSector;     //11
UCHAR   SectorsPerCluster;    //13
USHORT   ReservedSectors;    //14
UCHAR   Mbz1;       //16  
USHORT   Mbz2;       //17
USHORT   Reserved1;      //19
UCHAR   MediaDesc;      //21
USHORT   Mbz3;       //22
USHORT   SectorsPerTrack;    //24
USHORT   Heads;       //26
ULONG   HiddenSectors;     //28
ULONG   Reserved2[2];     //32
ULONGLONG TotalSectors;     //40
ULONGLONG MftStartLcn;     //48
ULONGLONG Mft2StartLcn;     //56
}DP_NTFS_BOOT_SECTOR, *PDP_NTFS_BOOT_SECTOR;
#pragma pack()

VOID DrReinitializeRoutine (
IN PDRIVER_OBJECT DriverObject,
IN PVOID Context,
IN ULONG Count
);
NTSTATUS DRAddDevice (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysiclDeviceObject
);
NTSTATUS PowerDispatchRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp);

NTSTATUS DRSynIoCallDriver (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);

NTSTATUS DRSynCompletion (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);


NTSTATUS PnpDispatchRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS DevControlDispatchRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
NTSTATUS DrDeviceCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID pContext
);
NTSTATUS DRQueryVolumeInformation (
IN PDEVICE_OBJECT DeviceObject,
OUT LARGE_INTEGER* TotalSize,
OUT PVOID ClusterSize,
OUT PVOID SectorSize
);
NTSTATUS DRQueryCompletionRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);
NTSTATUS ReadWriteDispatchRoutine (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP pIrp
);
VOID DrThreadRoutine (IN PVOID StartContext);
NTSTATUS DrUnload (PDRIVER_OBJECT DriverObject);
NTSTATUS DispatchRoutine (PDEVICE_OBJECT DeviceObject, PIRP Irp);



郑重声明:资讯 【支持还原功能的磁盘卷过滤驱动代码-2_yeluosong的空间_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——