📄 diskrw.cpp
字号:
#include "stdafx.h"
#include "diskrw.h"
#include "windows.h"
#include <winioctl.h>
#include <setupapi.h>
#include <devguid.h>
#include <regstr.h>
#pragma comment(lib,"Setupapi.lib")
#define DEBUG_LOG
#ifdef DEBUG_LOG
#define log_printf(x) printf x
#else
#define log_printf(x)
#endif
/////////////////////////////////////////////////////////////////////////////
#define DISK_PART_TABLE_NUM 4
#define RD_BUFFER_SIZE 512
#define BOOT_SECTOR_SIZE 512
#define UINT8 unsigned char
#define UINT16 unsigned short
#define UINT32 unsigned int
#define UINT64 __int64
#define uint8 unsigned char
#define uint16 unsigned short
#define uint32 unsigned int
#define uint64 __int64
#define UCHAR unsigned char
#define USHORT unsigned short
#define ULONG unsigned int
#define ULONGLONG __int64
#pragma pack(1)
typedef struct{
UINT8 Flag; //00h
UINT8 StartTrack; //01h
UINT8 StartSector; //02h
UINT8 StartCylinder; //03h
UINT8 SysFlag; //04h
UINT8 EndTrack; //05h
UINT8 EndSector; //06h
UINT8 EndCylinder; //07h
UINT32 SectorAddress; //08h
UINT32 NumberOfSector; //0ch
}DISK_PART;
typedef struct{ //Offset Size Field Required Value for BitLocker
UINT8 Reserved[3];
UINT8 Signature[8]; //0x003 8 Signature ‘-‘,’F’,’V’,’E’,’-‘,’F’,’S’,’-‘
UINT16 BytesPerSector; //0x00B 2 BytesPerSector
UINT8 SectorsPerCluster; //0x00D 1 SectorsPerCluster One of 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 or 0x80
UINT16 ReservedClusters; //0x00E 2 ReservedClusters 0x0000
UINT8 FatCount; //0x010 1 FatCount 0x00
UINT16 RootEntries; //0x011 2 RootEntries 0x0000
UINT16 Sectors; //0x013 2 Sectors 0x0000
UINT8 MediaType; //0x015 1 Media Type
UINT16 SectorsPerFat; //0x016 2 SectorsPerFat 0x0000
UINT16 SectorsPerTrack; //0x018 2 SectorsPerTrack
UINT16 NumberOfTrackHead; //0x1a 2 NumberOfTrackHead
UINT32 NumberOfHiddenSectors; //0x1c 4 NumberOfHiddenSectors
UINT32 LargeSectors; //0x020 4 LargeSectors 0x00000000
UINT16 NumberOfPhyDriver; //0x024 2
UINT8 SignOfExtBoot; //0x026 1
UINT32 SerialOfVolume; //0x027 4
UINT8 LabelOfVolume[11]; //0x02b 11
UINT16 SerialOfFileSystem; //0x036 2
UINT32 MetadataLcn[2]; //0x038 8 MetadataLcn
}BPB;
#pragma pack()
/////////////////////////////////////////////////////////////////////////////
DISK_GEOMETRY Geometry;
int TotalPartTableNum = 0;
void dumpDiskPartTable(DISK_PART *pPart)
{
#ifdef DEBUG_LOG
if(pPart == NULL)
return;
if(TotalPartTableNum == 0)
{
printf("\n\n [%3s] %s %s %s %s %s %s %s %s %s %s",
"No.", "Flag",
"STck", "SSec", "SCyl",
"SysF",
"ETck", "ESec", "ECyl",
"SectorAddr", "NumOfSector");
}
if(pPart->SysFlag != 0)
{
TotalPartTableNum++;
printf("\n %3d %2Xh %3d %3d %3d %02Xh %3d %3d %3d",
TotalPartTableNum, pPart->Flag,
pPart->StartTrack, pPart->StartSector, pPart->StartCylinder,
pPart->SysFlag,
pPart->EndTrack, pPart->EndSector, pPart->EndCylinder);
printf(" %8Xh", pPart->SectorAddress);
printf(" %8Xh", pPart->NumberOfSector);
printf(" %3d,%03d(MB)",pPart->NumberOfSector/2/1024/1000, (pPart->NumberOfSector/2/1024)%1000);
}
#endif
}
/////////////////////////////////////////////////////////////////////////////
void dump(unsigned char *pBuf, int leng)
{
int index;
for(index=0; index<leng; index++)
{
if(index%0x10==0)
printf("\n[%04x]: ", index);
else if(index%8==0)
printf("- ");
printf("%02X ", *pBuf++);
}
}
/****************************************************************************
****************************************************************************/
char *TpmDeviceDescript[]={
"Trusted Platform Module",
"BitLocker Drive Encryption Filter Driver"
};
int DetectTpmDevice(void)
{
HDEVINFO hDevInfo;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i;
int j, res = 0;
// Create a HDEVINFO with all present devices.
hDevInfo = SetupDiGetClassDevs(NULL,
0, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES );
if (hDevInfo == INVALID_HANDLE_VALUE)
{
return -1;
}
// Enumerate through all devices in Set.
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR buffer = NULL;
DWORD buffersize = 0;
//
// Call function with null to begin with,
// then use the returned buffer size
// to Alloc the buffer. Keep calling until
// success or an unknown failure.
//
while (!SetupDiGetDeviceRegistryProperty(
hDevInfo,
&DeviceInfoData,
SPDRP_DEVICEDESC,//SPDRP_FRIENDLYNAME,//SPDRP_HARDWAREID,//SPDRP_DEVICEDESC,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer)
LocalFree(buffer);
buffer = (char*)LocalAlloc(LPTR,buffersize);
}
else
{
break;
}
}
for(j=0; j<sizeof(TpmDeviceDescript)/sizeof(char *); j++)
{
if(!strncmp(TpmDeviceDescript[j], buffer, strlen(TpmDeviceDescript[j])))
{
res = 1;
goto DetectTpmDeviceEnd;
}
}
if (buffer)
LocalFree(buffer);
}
if ( GetLastError()!=NO_ERROR && GetLastError()!=ERROR_NO_MORE_ITEMS )
{
return -1;
}
DetectTpmDeviceEnd:
SetupDiDestroyDeviceInfoList(hDevInfo);
return res;
}
/****************************************************************************
****************************************************************************/
char buf[256];
char hexArr[]="0123456789ABCDEF";
char dispFormatStr[]="\n %21s : %s";
char dispFormatInt[]="\n %21s : %Xh";
char dispFormatIntD[]="\n %21s : %d";
char dispFormatIntL[]="\n %21s : %ld";
char dispFormatIntH[]="\n %21s : %lXh";
char *bin2string(int length, unsigned char dat[])
{
int i,j;
for(i=0,j=0; i<length; i++)
{
buf[j++] = hexArr[(dat[i]>>4)&0x0f];
buf[j++] = hexArr[dat[i]&0x0f];
}
buf[j] = '\0';
return buf;
}
char *getString(int length, unsigned char dat[])
{
int i;
for(i=0; i<length; i++)
{
buf[i] = dat[i];
}
buf[i] = '\0';
return buf;
}
int detectBitLockDriver(BPB *pBpb)
{
if(pBpb == NULL)
return 0;
if((!memcmp(pBpb->Signature,"-FVE-FS-", 8)) /*|| (!memcmp(pBpb->Signature,"NTFS", 4))*/ )
if((pBpb->SectorsPerCluster==1) || (pBpb->SectorsPerCluster==2) ||
(pBpb->SectorsPerCluster==4) || (pBpb->SectorsPerCluster==8) ||
(pBpb->SectorsPerCluster==0x10) || (pBpb->SectorsPerCluster==0x20) ||
(pBpb->SectorsPerCluster==0x40) || (pBpb->SectorsPerCluster==0x80))
if(pBpb->ReservedClusters==0)
if(pBpb->FatCount==0)
if(pBpb->RootEntries==0)
if(pBpb->Sectors==0)
if(pBpb->SectorsPerFat==0)
if(pBpb->LargeSectors==0)
return 1;
else
log_printf(("\n pBpb->LargeSectors = %d", pBpb->LargeSectors));
else
log_printf(("\n pBpb->SectorsPerFat = %d", pBpb->SectorsPerFat));
else
log_printf(("\n pBpb->Sectors = %d", pBpb->Sectors));
else
log_printf(("\n pBpb->RootEntries = %d", pBpb->RootEntries));
else
log_printf(("\n pBpb->FatCount = %d", pBpb->FatCount));
else
log_printf(("\n pBpb->ReservedClusters = %d", pBpb->ReservedClusters));
else
log_printf(("\n pBpb->SectorsPerCluster = %d", pBpb->SectorsPerCluster));
else
log_printf(("\n pBpb->Signature = %s", bin2string(8, pBpb->Signature)));
return 0;
}
/****************************************************************************
****************************************************************************/
int readSectors(HANDLE diskHandle, __int64 ReadStartSector, int dwReadSize, char *pBuf)
{
long readOffsetH;
long readOffsetL;
int res;
unsigned long BytesRead;
//printf("\n readSectors(%lx,", ReadStartSector); printf("%x)", dwReadSize);
readOffsetH = (long)(ReadStartSector>>32);
readOffsetL = (long)(ReadStartSector&0xffffffff);
res = ::SetFilePointer(diskHandle, readOffsetL, &readOffsetH, FILE_BEGIN);
if (res == -1)
{
printf(" SetFilePointer Error = %xh", GetLastError());
return res;
}
// 5) read sector from disk
res = ::ReadFile(diskHandle, pBuf, dwReadSize, &BytesRead, NULL);
if (res == 0)
{
printf(" ReadFile Error = %xh", GetLastError());
return res;
}
return res;
}
/****************************************************************************
****************************************************************************/
int readPhyDisk(int phyDiskId, int &partNum, char *bootSectors)
{
char diskString[64];
HANDLE diskHandle;
DWORD dwOutBytes;
int res;
__int64 ReadStartSector=0;
char *pBuffer;
char *pBuffer1;
sprintf(diskString, "\\\\.\\PhysicalDrive%d", phyDiskId);
partNum = 0;
if(bootSectors == NULL)
return -1;
// 1) Open Disk
diskHandle = ::CreateFile(diskString, //
GENERIC_READ | GENERIC_WRITE, //
FILE_SHARE_READ | FILE_SHARE_WRITE, //
NULL, //
OPEN_EXISTING, //
0, //
NULL); //
if(diskHandle == INVALID_HANDLE_VALUE)
{
printf("\nOpen Disk[%d] Fail !", phyDiskId);
return -1;
}
// 2) LockVolume;
res = ::DeviceIoControl(diskHandle, //
FSCTL_LOCK_VOLUME, //
NULL, 0, //
NULL, 0, //
&dwOutBytes, //
(LPOVERLAPPED)NULL); //
if(res == 0)
{
printf("\nLockVolume Disk[%d] Fail !", phyDiskId);
return -1;
}
// 3) get disk parameters
res = ::DeviceIoControl(diskHandle, //
IOCTL_DISK_GET_DRIVE_GEOMETRY, //
NULL, 0, //
&Geometry, sizeof(DISK_GEOMETRY), //
&dwOutBytes, //
(LPOVERLAPPED)NULL); //
if(res == 0)
{
printf("\nGeometry Disk[%d] Fail !", phyDiskId);
return -1;
}
// 4) read MBR
pBuffer = bootSectors;
memset(pBuffer, 0, BOOT_SECTOR_SIZE);
res = readSectors(diskHandle, ReadStartSector, BOOT_SECTOR_SIZE, pBuffer);
if((res==-1)||(res==0))
return res;
partNum++;
// 5) read partition information
int index, hasSubPartTable=0;
DISK_PART *pDiskPart;
pDiskPart = (DISK_PART *)&pBuffer[0x1BE];
log_printf(("\n check partition ..."));
if(((UINT8)pBuffer[0x1fe]==(UINT8)0x55)&&((UINT8)pBuffer[0x1ff]==(UINT8)0xaa))
{
for(index=0; index<DISK_PART_TABLE_NUM; index++)
{
if(pDiskPart[index].Flag == 0x80) //active prime partition
hasSubPartTable = 1;
dumpDiskPartTable(&pDiskPart[index]);
}
}
else
log_printf((" []= %02Xh %02Xh", (UINT8)pBuffer[0x1fe], (UINT8)pBuffer[0x1ff]));
if(hasSubPartTable)
{
log_printf(("\n read partition ..."));
pBuffer1 = pBuffer;
for(int i=0; i<DISK_PART_TABLE_NUM; i++)
if(pDiskPart[i].SysFlag != 0)
{
pBuffer1 += BOOT_SECTOR_SIZE;
memset(pBuffer1, 0, BOOT_SECTOR_SIZE);
ReadStartSector = pDiskPart[i].SectorAddress;
ReadStartSector *= Geometry.BytesPerSector;
res = readSectors(diskHandle, ReadStartSector, BOOT_SECTOR_SIZE, pBuffer1);
if((res==-1)||(res==0))
return res;
partNum++;
if((pDiskPart[i].SysFlag == 0x05) || (pDiskPart[i].SysFlag == 0x0F)) //extend disk
{
log_printf((" [%d] has extend partition.", i));
}
}
}
else
{
log_printf(("no partition."));
}
// 6) UnlockVolume
res = ::DeviceIoControl(diskHandle, //
FSCTL_UNLOCK_VOLUME, //
NULL, 0, //
NULL, 0, //
&dwOutBytes, //
(LPOVERLAPPED)NULL); //
if(res == 0)
{
printf("\nUnlockVolume Disk[%d] Fail !", phyDiskId);
return -1;
}
// 7) close
res = ::CloseHandle(diskHandle);
if(res == 0)
{
printf("\nCloseHandle Disk[%d] Fail !", phyDiskId);
return -1;
}
return res;
}
int DetectBitLockerPartition(int diskId)
{
int res;
int BitLockPartitionDetect, index, partNum;
BPB *pBpb;
char buffer[8192];
res = readPhyDisk(diskId, partNum, buffer);
log_printf(("\n\n readPhyDisk(%d) = %Xh", diskId, res));
if(res != 1)
return 0;
#ifdef DEBUG_LOG
char filename[64];
FILE *fp;
if(res == 1)
{
sprintf(filename, "disk_%d.dat", diskId);
log_printf(("\n partNum = %d", partNum));
fp = fopen(filename, "wb");
if(fp != NULL)
{
fwrite(buffer, partNum*BOOT_SECTOR_SIZE, 1, fp);
fclose(fp);
}
}
#endif
BitLockPartitionDetect = 0;
for(index=0; index<partNum; index++)
{
pBpb = (BPB *)&buffer[index*BOOT_SECTOR_SIZE];
BitLockPartitionDetect = detectBitLockDriver(pBpb);
if(BitLockPartitionDetect)
{
log_printf(("\n\tBitLockPartition found."));
break;
}
}
return BitLockPartitionDetect;
}
/****************************************************************************
****************************************************************************/
int main(int argc, char* argv[], char* envp[])
{
int nRetCode = 0;
int diskId=0, TmpDetect=0, BitLockPartitionDetect=0;
TmpDetect = DetectTpmDevice();
printf("\n DetectTpmDevice() %s !", (TmpDetect==1?"found":"not found"));
for(diskId=0; diskId<4; diskId++)
{
BitLockPartitionDetect = DetectBitLockerPartition(diskId);
printf("\n DetectBitLockerPartition() %s !", (TmpDetect==1?"found":"not found"));
printf("\n\tBitLocker %s", ((TmpDetect && BitLockPartitionDetect)?"Enabled!":"Disabled."));
}
return nRetCode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -