//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
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);