C/C++编程解析硬盘分区信息
人狠话不多,直接上代码:
#include <windows.h>
#include <winioctl.h> //DDK驱动开发与控制
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define BufferLength 1024
//将四个连续字节存放的值转为int型
int transtoint(unsigned char a[])
{
int sum = 0;
for(int i=0;i<4;i++){
int m = a[i]/16;
int n = a[i]%16;
float len =16;
//printf(" %d %d ",m,n);
int temp1 = m*(pow(len,7-2*i));
int temp2 = n*(pow(len,6-2*i));
//printf(" %d ",temp);
sum = sum+temp1+temp2;
}
return sum;
}
//十六进制输出
void HexOutput(char* buf, size_t len)
{
unsigned char a = buf[0];
printf("第一字节是:%x\n\n",a);
printf(" 第一部分(引导代码):\n\n");
int flag = 0;
for(size_t i=0; i<len; ++i)
{
unsigned char c = buf[i]; // must use unsigned char to print >128 value
flag++;
if( c< 16)
printf("0%x ", c);
else
printf("%x ", c);
if (i == 445)
{
flag=0;
printf("\n\n 第二部分(分区表):\n");
}
if (i == 509)
{
flag=0;
printf("\n\n 第三部分(结束标志):\n");
}
if ((flag)%16 == 0)
printf("\n");
}
printf("\n<-------------------分区表信息解析------------------->\n\n");
printf("\n\n分区地址和大小分别为: \n\n");
for(int m=445,rank=1;m<509;m+=16,rank++)
{
unsigned char fifth = buf[m+6];//取得第五位标志位
if(fifth<16) //调整输出格式
printf("第%d分区表标志位为: 0%x\n",rank,fifth);
else
printf("第%d分区表标志位为: %x\n",rank,fifth);
if(fifth == 0x00)//当第五位(标志位)是00时,代表分区表信息为空,无分区
{
printf(" 分区表为空\n\n");
}
else{
unsigned char offsetadd[20]={0};
printf("地址:");
for(int n=m+12,t=0;n>m+8,t<4;n--,t++)
{
unsigned char temp = buf[n];
if(temp<16)
printf(" 0%x ",temp);
else
printf(" %x ",temp);
offsetadd[t] = buf[n];
}
//计算地址,转换为十进制扇区数LBA
printf("\n");
int tempadd = transtoint(offsetadd);
printf("\n地址为: %d",tempadd);
printf("\n\n");
printf("大小:");
for(int p=m+16,w=0;p>m+12,w<4;p--,w++)
{
unsigned char temp1 = buf[p];
if(temp1<16)
printf(" 0%x ",temp1);
else
printf(" %x ",temp1);
offsetadd[w] = buf[p];
}
//计算大小,转化为GB单位
printf("\n");
int tempsize = transtoint(offsetadd);
printf("\n大小为: %d 扇区 = %d GB \n",tempsize,tempsize/2/1024/1024);
}
}
printf("\n\n");
}
//函数:对主分区表进行解析,分别得到每个分区的偏移地址以及分区大小
BOOL GetDriveGeometry(DISK_GEOMETRY *pdg,int addr)
{
HANDLE hDevice; // 设备句柄
BOOL bResult; // results flag
DWORD junk; // discard resultscc
char lpBuffer[BufferLength] = {0};
//通过CreateFile来获得设备的句柄
hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive0"), // 设备名称,这里指第一块硬盘
GENERIC_READ, // no access to the drive
FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
//通过DeviceIoControl函数与设备进行IO
bResult = DeviceIoControl(hDevice, // 设备的句柄
IOCTL_DISK_GET_DRIVE_GEOMETRY, // 控制码,指明设备的类型
NULL, 0, // no input buffer
pdg,
sizeof(*pdg), // output buffer 输出,保存磁盘参数信息
&junk, // # bytes returned
(LPOVERLAPPED) NULL); // synchronous I/O
//主引导扇区的位置为0柱面0磁头1扇区
//int BlockAddr = ( 0 * 256 + 0 ) * 63 + 1 - 1; //计算绝对地址
//SetFilePointer(hDevice, (BlockAddr*512), NULL, FILE_BEGIN);
LARGE_INTEGER offset;
offset.QuadPart = (ULONGLONG)addr * (ULONGLONG)512;
SetFilePointer(hDevice,offset.LowPart,&offset.HighPart,FILE_BEGIN);
printf("错误类型代号:%ld\n\n",GetLastError());
DWORD dwCB;
BOOL bRet = ReadFile(hDevice,lpBuffer,512,&dwCB,NULL);
//printf("%x\n\n",lpBuffer);
HexOutput(lpBuffer,512);
CloseHandle(hDevice);
return bResult;
}
extern int add[20];
extern int disknum;
int main()
{
DISK_GEOMETRY pdg; // 保存磁盘参数的结构体
BOOL bResult; // generic results flag
ULONGLONG DiskSize; // size of the drive, in bytes
printf("<-----------------欢迎使用分区读取程序----------------->\n\n");
bResult = GetDriveGeometry (&pdg,0);
if (bResult)
{
printf("柱面数 = %I64d\n", pdg.Cylinders); //柱面数
printf("每柱面的磁道数 = %ld\n", (ULONG) pdg.TracksPerCylinder);//每柱面的磁道数
printf("每磁道扇区数 = %ld\n", (ULONG) pdg.SectorsPerTrack);//每磁道扇区数
printf("每扇区的字节数 = %ld\n", (ULONG) pdg.BytesPerSector); //每扇区的字节数
DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder *
(ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;
printf("磁盘大小 = %I64d (Bytes) = %I64d (Gb)\n", DiskSize,DiskSize / (1024 * 1024 * 1024));
}
else
{
printf ("GetDriveGeometry failed. Error %ld.\n", GetLastError ());
}
system("pause");
return ((int)bResult);
}
运行结果类似于: