3.下面是几个主要更改的函数了:
//获取磁盘卷信息
NTSTATUS
flt_getVolumeInfo(WCHAR volume, PVOLUME_INFO info)
{
NTSTATUS status;
HANDLE fileHandle;
UNICODE_STRING fileName;
OBJECT_ATTRIBUTES oa;
IO_STATUS_BLOCK IoStatusBlock;
WCHAR volumeDosName[50];
BYTE DBR[512] = { 0 };
ULONG DBRLength = 512;
PDP_NTFS_BOOT_SECTOR pNtfsBootSector = (PDP_NTFS_BOOT_SECTOR)DBR;
PDP_FAT32_BOOT_SECTOR pFat32BootSector = (PDP_FAT32_BOOT_SECTOR)DBR;
LARGE_INTEGER readOffset = { 0 };
TRKF_FILE_SYSTEM_TYPE type;
swprintf(volumeDosName, L"
\\??\\%c:", volume);
RtlInitUnicodeString(&fileName, volumeDosName);
InitializeObjectAttributes(&oa,
&fileName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = flt_GetFileSystemBpbInfo(&fileName, DBR, 512, &type);
status = ZwCreateFile(&fileHandle,
GENERIC_ALL | SYNCHRONIZE,
&oa,
&IoStatusBlock,
NULL,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT, // 同步读写
NULL,
0);
dprintf("open %wZ ret 0x%x\n", &fileName, status);
if (NT_SUCCESS(status))
{
IO_STATUS_BLOCK ioBlock;
PARTITION_INFORMATION partitionInfo;
ULONG buff[256];
PVOLUME_DISK_EXTENTS diskExtents;
diskExtents = (PVOLUME_DISK_EXTENTS)buff;
// 得到此卷所在的硬盘号,不考虑跨盘卷
status = ZwDeviceIoControlFile( fileHandle,
NULL,
NULL,
NULL,
&ioBlock,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL,
0,
diskExtents,
sizeof(buff)
);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(fileHandle, Executive, KernelMode, FALSE, 0L);
status = ioBlock.Status;
}
if (NT_SUCCESS(status))
{
info->diskNumber = diskExtents->Extents[0].DiskNumber;
// 得到下层设备
info->LowerDevObj = _lowerDeviceObject[info->diskNumber];
}
// 得到此卷的一类型,在物理硬盘的上的偏移等信息
status = ZwDeviceIoControlFile( fileHandle,
NULL,
NULL,
NULL,
&ioBlock,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&partitionInfo,
sizeof(partitionInfo)
);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(fileHandle, Executive, KernelMode, FALSE, 0L);
status = ioBlock.Status;
}
if (NT_SUCCESS(status))
{
info->partitionNumber = partitionInfo.PartitionNumber;
info->partitionType = partitionInfo.PartitionType;
info->physicalStartingOffset = partitionInfo.StartingOffset.QuadPart;
info->bootIndicator = partitionInfo.BootIndicator;
}
if (NT_SUCCESS(status))
{
switch(type)
{
case TRKF_NTFS:
{
info->bytesPerCluster = pNtfsBootSector->BytesPerSector * pNtfsBootSector->SectorsPerCluster;
info->bytesPerSector = pNtfsBootSector->BytesPerSector;
info->bytesTotal = pNtfsBootSector->TotalSectors * pNtfsBootSector->BytesPerSector;
info->HiddenSector = pNtfsBootSector->HiddenSectors + pNtfsBootSector->ReservedSectors;
info->firstDataSector = 0;
info->sectorCount = pNtfsBootSector->TotalSectors;
info->VolumeType = type;
info->SectorsPerCluster = pNtfsBootSector->SectorsPerCluster;
info->StartLcn = pNtfsBootSector->MftStartLcn;
break;
}
case TRKF_FAT32:
{
ULONG uSectorPerFat = pFat32BootSector->SectorPerFat == 0 ? pFat32BootSector->SectorsPerFAT: pFat32BootSector->SectorPerFat;
ULONG uTotalSectors = pFat32BootSector->BigTotalSectors == 0 ? pFat32BootSector->TotalSectors:pFat32BootSector->BigTotalSectors;
info->bytesPerCluster = pFat32BootSector->BytesPerSector * pFat32BootSector->SectorsPerCluster;
info->bytesPerSector = pFat32BootSector->BytesPerSector;
info->bytesTotal = uTotalSectors * pFat32BootSector->BytesPerSector;
info->HiddenSector = uSectorPerFat * pFat32BootSector->FatNum + pFat32BootSector->ReservedSectors;
info->firstDataSector = info->HiddenSector;
info->sectorCount = uTotalSectors;
info->VolumeType = type;
info->StartLcn = pFat32BootSector->RootDir1stCluster;
info->SectorsPerCluster = pFat32BootSector->SectorsPerCluster;
break;
}
}
}
}
if (fileHandle != NULL)
ZwClose(fileHandle);
return status;
}
////////////////////////////////////////////////////////////////////////
NTSTATUS flt_GetFileSystemBpbInfo(IN PUNICODE_STRING uVolumeDosName,
OUT void* lpBpbBuffer,
IN DWORD dwSize,
OUT TRKF_FILE_SYSTEM_TYPE* theType)
{
NTSTATUS status = STATUS_SUCCESS;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES oa;
HANDLE fileHandle = NULL;
BYTE DBR[512] = { 0 };
ULONG DBRLength = 512;
PDP_NTFS_BOOT_SECTOR pNtfsBootSector = (PDP_NTFS_BOOT_SECTOR)DBR;
PDP_FAT32_BOOT_SECTOR pFat32BootSector = (PDP_FAT32_BOOT_SECTOR)DBR;
LARGE_INTEGER readOffset = { 0 };
__try
{
if (uVolumeDosName == NULL ||
uVolumeDosName->Length == 0||
lpBpbBuffer == NULL||
dwSize == 0)
{
return STATUS_UNSUCCESSFUL;
}
InitializeObjectAttributes(&oa,
uVolumeDosName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = ZwCreateFile(&fileHandle,
GENERIC_READ | SYNCHRONIZE,
&oa,
&IoStatusBlock,
NULL,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT, // 同步读写
NULL,
0);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock.Status;
}
else if (NT_SUCCESS(status))
{
IO_STATUS_BLOCK IoStatusBlock2;
status = ZwReadFile(fileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock2,
DBR,
dwSize,
0,
NULL);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock2.Status;
}
else if (NT_SUCCESS(status))
{
if (*(DWORD*)NTFS*** == *(DWORD*)&DBR[NTFS_SIG_OFFSET])
{
RtlCopyMemory(lpBpbBuffer, DBR, dwSize);
*theType = TRKF_NTFS;
}
else if (*(DWORD*)FAT32*** == *(DWORD*)&DBR[FAT32_SIG_OFFSET])
{
RtlCopyMemory(lpBpbBuffer, DBR, dwSize);
*theType = TRKF_FAT32;
}
else
{
RtlCopyMemory(lpBpbBuffer, DBR, dwSize);
*theType = TRKF_OTHER;
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
_finished:
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock.Status;
}
if (fileHandle)
{
ZwClose(fileHandle);
}
return status;
}
__except(0)
{
if (fileHandle)
{
ZwClose(fileHandle);
}
return STATUS_UNSUCCESSFUL;
}
return status;
}
///获取文件系统位图信息
NTSTATUS flt_GetFileSystemBitmap(IN PUNICODE_STRING uVolumeDosName,
OUT PVOLUME_BITMAP_BUFFER* lpBitMap)
{
NTSTATUS status = STATUS_SUCCESS;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES oa;
HANDLE fileHandle = NULL;
BYTE DBR[512] = { 0 };
ULONG DBRLength = 512;
PDP_NTFS_BOOT_SECTOR pNtfsBootSector = (PDP_NTFS_BOOT_SECTOR)DBR;
PDP_FAT32_BOOT_SECTOR pFat32BootSector = (PDP_FAT32_BOOT_SECTOR)DBR;
LARGE_INTEGER readOffset = { 0 };
__try
{
if (uVolumeDosName == NULL ||
uVolumeDosName->Length == 0)
{
return STATUS_UNSUCCESSFUL;
}
InitializeObjectAttributes(&oa,
uVolumeDosName,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
status = ZwCreateFile(&fileHandle,
GENERIC_READ | SYNCHRONIZE,
&oa,
&IoStatusBlock,
NULL,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock.Status;
}
else if (NT_SUCCESS(status))
{
IO_STATUS_BLOCK IoStatusBlock2;
status = ZwReadFile(fileHandle,
NULL,
NULL,
NULL,
&IoStatusBlock2,
DBR,
DBRLength,
0,
NULL);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock2.Status;
}
else if (NT_SUCCESS(status))
{
if (*(DWORD*)NTFS*** == *(DWORD*)&DBR[NTFS_SIG_OFFSET])
{
char szbuffer[1024] = {0};
LONGLONG BitmapSector ;
IO_STATUS_BLOCK ios;
char* lpBimapRundata = NULL;
BitmapSector = GetBitmapFileSector(pNtfsBootSector);
lpBimapRundata = FindFileRecord(szbuffer,
BitmapSector,
0x80,
fileHandle,
pNtfsBootSector,
&ios);
if (lpBimapRundata != NULL)
{
char *lpCluseterArray = GetBitmap80Attr(lpBimapRundata);
if ( lpCluseterArray != NULL)
{
if (GetClusterList(lpCluseterArray,pNtfsBootSector,lpBitMap,fileHandle,
&ios))
{
status = STATUS_SUCCESS;
goto _finished;
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else if (*(DWORD*)FAT32*** == *(DWORD*)&DBR[FAT32_SIG_OFFSET])
{
status = GetFatTableInfo((DP_FAT32_BOOT_SECTOR*) DBR, lpBitMap, fileHandle);
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock.Status;
}
else if (status == STATUS_SUCCESS)
{
status = STATUS_SUCCESS;
goto _finished;
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
//走到这里,可能是其它任何文件系统,但是不是windows认识的文件系统,我们统一返回错
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
}
else
{
status = STATUS_UNSUCCESSFUL;
goto _finished;
}
_finished:
if (status == STATUS_PENDING)
{
KeWaitForSingleObject(&fileHandle, Executive, KernelMode, FALSE, NULL);
status = IoStatusBlock.Status;
}
if (fileHandle)
{
ZwClose(fileHandle);
}
return status;
}
__except(0)
{
if (fileHandle)
{
ZwClose(fileHandle);
}
return STATUS_UNSUCCESSFUL;
}
return status;
}
//初始化位图
NTSTATUS
flt_initVolumeLogicBitMap(PVOLUME_INFO volumeInfo)
{
NTSTATUS status;
PVOLUME_BITMAP_BUFFER bitMap = NULL;
// 逻辑位图大小
ULONGLONG logicBitMapMaxSize = 0;
ULONGLONG index = 0;
ULONGLONG i = 0;
ULONGLONG Clusters = 0;
ULONGLONG Sectors = 0;
status = flt_getVolumeInfo(volumeInfo->volume, volumeInfo);
if (!NT_SUCCESS(status))
{
return status;
}
status = flt_getVolumeBitmapInfo(volumeInfo->volume, &bitMap);
if (!NT_SUCCESS(status))
{
return status;
}
// 获取此卷上有多少个扇区, 用bytesTotal这个比较准确,如果用其它的比如fsinfo,会少几个扇区发现
volumeInfo->sectorCount = volumeInfo->bytesTotal / volumeInfo->bytesPerSector;
// 得到逻辑位图的大小bytes
logicBitMapMaxSize = (volumeInfo->sectorCount / 8) + 1;
// 上次扫描的空闲簇的位置
volumeInfo->last_scan_index = 0;
dprintf("------------------------\n");
dprintf("extend cluster = %08I64d physicalStartingOffset = 0x%08I64x bitMapSize = 0x%I64x\n"
"bytesPerSector = %d bytesPerCluster = %d sectorsPerCluster = %d\n",
volumeInfo->firstDataSector, volumeInfo->physicalStartingOffset, logicBitMapMaxSize,
volumeInfo->bytesPerSector, volumeInfo->bytesPerCluster, volumeInfo->SectorsPerCluster);
Clusters =volumeInfo->sectorCount / volumeInfo->SectorsPerCluster;
Sectors = volumeInfo->sectorCount;
if (volumeInfo->VolumeType == TRKF_NTFS)
{
// 以扇区为单位的位图
if (!NT_SUCCESS(DPBitMap_Create(&volumeInfo->bitMap_Redirect, Sectors, SLOT_SIZE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
// 以簇为单位的位图
if (!NT_SUCCESS(DPBitMap_Create(&volumeInfo->bitMap_Protect, Clusters, SLOT_SIZE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
// 以扇区为单位的位图, 如果一次申请内存过大,会失败,用dpbitmap申请不连续的内存
if (!NT_SUCCESS(DPBitMap_Create(&volumeInfo->bitMap_Free, volumeInfo->bytesTotal / volumeInfo->bytesPerSector, SLOT_SIZE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
for (i = 0; i < volumeInfo->HiddenSector; i++)
{
if (!NT_SUCCESS(DPBitMap_Set(volumeInfo->bitMap_Free, i, TRUE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
}
for (i = 0; i < bitMap->BitmapSize.QuadPart; i++)
{
if (bitmap_test((PULONG)&bitMap->Buffer, i))
{
ULONGLONG j = 0;
ULONGLONG base = (i * volumeInfo->SectorsPerCluster);
for (j = 0; j < volumeInfo->SectorsPerCluster; j++)
{
if (!NT_SUCCESS(DPBitMap_Set(volumeInfo->bitMap_Free, base + j, TRUE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
}
}
}
/*
{
BYTE* lpbuffer = bitMap->Buffer;
ULONGLONG i = 0;
for (i = 0 ; i < (ULONGLONG)bitMap->BitmapSize.QuadPart; i++)
{
ULONG bit = 1;
ULONG j = 0;
for (j = 1; j < 8; j++)
{
if ((lpbuffer[i] & bit ) != 0)
{
ULONGLONG base = bit + (i * 8) - 1;//计算对应占用的簇号
ULONGLONG uSector = base * volumeInfo->SectorsPerCluster;
ULONG Index = 0;
for (Index = 0; Index < volumeInfo->SectorsPerCluster; Index++)
{
if (!NT_SUCCESS(DPBitMap_Set(volumeInfo->bitMap_Free,uSector + Index, TRUE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild ;
}
}
}
bit <<= j;
}
}
} */
}
else if (volumeInfo->VolumeType == TRKF_FAT32)
{
// 以扇区为单位的位图
if (!NT_SUCCESS(DPBitMap_Create(&volumeInfo->bitMap_Redirect, Sectors, SLOT_SIZE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
// 以簇为单位的位图
if (!NT_SUCCESS(DPBitMap_Create(&volumeInfo->bitMap_Protect, Clusters, SLOT_SIZE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
// 以扇区为单位的位图, 如果一次申请内存过大,会失败,用dpbitmap申请不连续的内存
if (!NT_SUCCESS(DPBitMap_Create(&volumeInfo->bitMap_Free, Sectors, SLOT_SIZE)))
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
for (i = 0; i < volumeInfo->firstDataSector ; i++)
{
if (DPBitMap_Set(volumeInfo->bitMap_Free, i, TRUE) == STATUS_UNSUCCESSFUL)
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
}
{
PULONG lpBitmap = (PULONG)bitMap->Buffer;
ULONG j = 2;
for ( j = 3; j < (ULONG)bitMap->BitmapSize.QuadPart / 4; j++)
{
ULONGLONG uCluster = 0;
ULONGLONG uSector = 0;
ULONGLONG base = 0;
if (((ULONG)lpBitmap[j] >= (ULONG)2) && ((ULONG)lpBitmap[j] <= (ULONG)0x0FFFFFFE))
{
//FAT i 获取该文件的扇区号
if (($DIRTY == (ULONG)lpBitmap[j])|| ((ULONG)0xFFFFFFFF == lpBitmap[j]))
{
continue;
}
else if (((ULONG)$BAD == lpBitmap[j]))
{
base = (ULONG)(j) * volumeInfo->SectorsPerCluster;
}
else
{
if (((ULONG)$END) == lpBitmap[j])//结束簇
base = (ULONG)(lpBitmap[j - 1])* volumeInfo->SectorsPerCluster;
else
base = (ULONG)(lpBitmap[j]) * volumeInfo->SectorsPerCluster;
}
for ( uSector = 0; uSector < volumeInfo->SectorsPerCluster; uSector++)
{
if (DPBitMap_Set(volumeInfo->bitMap_Free, base + uSector, TRUE) != STATUS_SUCCESS)
{
status = STATUS_UNSUCCESSFUL;
goto __faild;
}
}
}
}
lpBitmap = NULL;
}
}
else
{
status = STATUS_UNRECOGNIZED_VOLUME;
goto __faild ;
}
if (volumeInfo->bootIndicator)
{
setBitmapDirectRWFile(volumeInfo->volume,
(*NtBuildNumber >= 2600) ? L"
\\Windows\\bootstat.dat" : L"
\\WINNT\\bootstat.dat",
volumeInfo->bitMap_Protect);
}
// 页面文件
setBitmapDirectRWFile(volumeInfo->volume, L"
\\pagefile.sys", volumeInfo->bitMap_Protect);
setBitmapDirectRWFile(volumeInfo->volume, L"
\\hiberfil.sys", volumeInfo->bitMap_Protect);
RtlInitializeGenericTable(&volumeInfo->redirectMap, CompareRoutine, AllocateRoutine, FreeRoutine, NULL);
status = STATUS_SUCCESS;
__faild:
if (!NT_SUCCESS(status))
{
if (volumeInfo->bitMap_Redirect)
{
DPBitMap_Free(volumeInfo->bitMap_Redirect);
volumeInfo->bitMap_Redirect = NULL;
}
if (volumeInfo->bitMap_Protect)
{
DPBitMap_Free(volumeInfo->bitMap_Protect);
volumeInfo->bitMap_Protect = NULL;
}
if (volumeInfo->bitMap_Free)
{
DPBitMap_Free(volumeInfo->bitMap_Free);
volumeInfo->bitMap_Free = NULL;
}
}
__free_Safe(bitMap);
return STATUS_SUCCESS;
}
自己比较菜吧,总之是拆东墙补西墙。。。。好歹凑合着能用了。牛人看了,就不要喷了!