C/C++解析硬盘分区信息

来源:互联网 发布:心经 张爱玲 知乎 编辑:程序博客网 时间:2024/06/10 05:43

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

运行结果类似于:
主分区
主分区
主分区
总硬盘

0 0