VC++ 读写MBR, 以及写扩展分区,以及写uboot的方法

这篇文章并没有写完,还有如何格式化成ext4,如何烧录system,img等都还没有完善.文章大部分来自网络,自己只是改写部分内容(如扩展分区的写入,uboot的写入,防擦写系统盘,).
本文主要是对TF卡进行操作.

// testMBRDlg.cpp : implementation file

//

#include "stdafx.h"
#include "testMBR.h"
#include "testMBRDlg.h"

//#include <Ntdddisk.h>



#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define  DISK_PATH_LEN   512
#define  SAVEFILE   "mbr.bak"

#define  SECTOR_SIZE     512


/
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
    CAboutDlg();

// Dialog Data
    //{{AFX_DATA(CAboutDlg)
    enum { IDD = IDD_ABOUTBOX };
    //}}AFX_DATA

    // ClassWizard generated virtual function overrides
    //{{AFX_VIRTUAL(CAboutDlg)
    protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
    //}}AFX_VIRTUAL

// Implementation
protected:
    //{{AFX_MSG(CAboutDlg)
    //}}AFX_MSG
    DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
    //{{AFX_DATA_INIT(CAboutDlg)
    //}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CAboutDlg)
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
    //{{AFX_MSG_MAP(CAboutDlg)
        // No message handlers
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CTestMBRDlg dialog

CTestMBRDlg::CTestMBRDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CTestMBRDlg::IDD, pParent)
{
    //{{AFX_DATA_INIT(CTestMBRDlg)
    m_strEDIT = _T("");
    m_combobox = _T("1");
    //}}AFX_DATA_INIT
    // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CTestMBRDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CTestMBRDlg)
    DDX_Control(pDX, IDC_EDIT_DPT, m_strdpt);
    DDX_Control(pDX, IDC_COMBO_NAME, m_CtrlCombo);
    DDX_Text(pDX, IDC_EDIT_DPT, m_strEDIT);
    DDX_CBString(pDX, IDC_COMBO_NAME, m_combobox);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CTestMBRDlg, CDialog)
    //{{AFX_MSG_MAP(CTestMBRDlg)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDC_BUTTON_READ, OnButtonRead)
    ON_BN_CLICKED(IDC_BUTTON_CLS, OnButtonCls)
    ON_BN_CLICKED(IDC_BUTTON_WRITEDPT, OnButtonWritedpt)
    ON_BN_CLICKED(IDC_BUTTON_DEL_DPT, OnButtonDelDpt)
    ON_BN_CLICKED(IDC_BUTTON_READ_MBR, OnButtonReadMbr)
    ON_BN_CLICKED(IDC_BUTTON_CREATE_DPT, OnButtonCreateDpt)
    ON_BN_CLICKED(IDC_BUTTON_PHYSICAL_INFO, OnButtonPhysicalInfo)
    ON_BN_CLICKED(IDC_BUTTON_CLERA_MBR, OnButtonCleraMbr)
    ON_BN_CLICKED(IDC_BUTTON_WRITE_UBOOT, OnButtonWriteUboot)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CTestMBRDlg message handlers

BOOL CTestMBRDlg::OnInitDialog()
{
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    ASSERT(IDM_ABOUTBOX < 0xF000);

    CMenu* pSysMenu = GetSystemMenu(FALSE);
    if (pSysMenu != NULL)
    {
        CString strAboutMenu;
        strAboutMenu.LoadString(IDS_ABOUTBOX);
        if (!strAboutMenu.IsEmpty())
        {
            pSysMenu->AppendMenu(MF_SEPARATOR);
            pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
        }
    }

    // Set the icon for this dialog.  The framework does this automatically
    //  when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE);            // Set big icon
    SetIcon(m_hIcon, FALSE);        // Set small icon
    
    // TODO: Add extra initialization here
    CDialog::SetWindowText("MBR是启动引导程序,请谨慎操作!");   
//     m_strEDIT="edit";   
//     UpdateData(false);


    ListDrv();

    return TRUE;  // return TRUE  unless you set the focus to a control
}

void CTestMBRDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else
    {
        CDialog::OnSysCommand(nID, lParam);
    }
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CTestMBRDlg::OnPaint()
{
    if (IsIconic())
    {
        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle
        int cxIcon = GetSystemMetrics(SM_CXICON);
        int cyIcon = GetSystemMetrics(SM_CYICON);
        CRect rect;
        GetClientRect(&rect);
        int x = (rect.Width() - cxIcon + 1) / 2;
        int y = (rect.Height() - cyIcon + 1) / 2;

        // Draw the icon
        dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
        CDialog::OnPaint();
    }
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CTestMBRDlg::OnQueryDragIcon()
{
    return (HCURSOR) m_hIcon;
}

//-------------------------------


void CTestMBRDlg::OnButtonRepair()    
{   
    int disk_num = CheckSysDisk();
    if (disk_num ==-1)
        return ;
    
    CString disk_char;   
    disk_char.Format("%d",disk_num);                    //转换成字符串类型   
    CDialog::SetWindowText(disk_char);   
    
    //读取正确MBR文件   
    unsigned char *buff=(unsigned char*)malloc(SECTOR_SIZE + 1);   //存正确MBR   
    unsigned char *DPT=(unsigned char*)malloc(SECTOR_SIZE + 1);    //存正确的DPT   
    memset(buff, 0, SECTOR_SIZE + 1);
    memset(DPT, 0, SECTOR_SIZE + 1);
    HANDLE filehandle = CreateFile(SAVEFILE,   
        GENERIC_READ,   
        FILE_SHARE_READ|FILE_SHARE_WRITE,   
        NULL,   
        OPEN_ALWAYS,   
        FILE_ATTRIBUTE_NORMAL,   
        NULL);   
    DWORD byte1;   
    ReadFile(filehandle,buff,SECTOR_SIZE,&byte1,NULL);   
    CloseHandle(filehandle);   
//    ReadSectors(0,1,disk_char,DPT);                   //读选定磁盘001扇区   
//    for(int i=446;i<=512;i++){buff[i]=DPT[i];}   
    //写入磁盘001扇区   
    WriteSectors(0,1,disk_char,buff);   
    MessageBox("该驱动器MBR修复完成!",NULL,MB_OK);   
    free (buff);
    free (DPT);
}   
   
// void CTestMBRDlg::OnButtonOk()    
// {   
//     // TODO: Add your control notification handler code here   
//     CDialog::OnCancel();   
// }   
   
BOOL CTestMBRDlg::OnButtonReadDPT(BOOL flg_bak)    
{   
    // TODO: Add your control notification handler code here   
    char savecontent[2049]={0};
    int sv_count = 0;
    CString DriveName;
    m_CtrlCombo.GetWindowText(DriveName);
    if (DriveName == "")
    {
        m_strdpt.SetWindowText("Please choose disk!");
        return FALSE;
    }

    int disk_num=GetPhysicalDriveFromPartitionLetter(DriveName);  //获取驱动器号   
    CString disk_char;   
    disk_char.Format("%d",disk_num);                    //转换成字符串类型   
    unsigned char *buffDPT=(unsigned char*)malloc(SECTOR_SIZE + 1);   
    memset(buffDPT,0, SECTOR_SIZE + 1);
    ReadSectors(0,1,disk_char,buffDPT);
    
    if (flg_bak == TRUE)
    {
        CFile  cf;
        CFileFind  findfile;
        BOOL isExist = findfile.FindFile(SAVEFILE);
        if (isExist)
            cf.Remove(SAVEFILE);
        
        CFile f;  //kk for back
        f.Open(SAVEFILE,CFile::modeCreate|CFile::modeWrite);
        f.Write(buffDPT, SECTOR_SIZE);
        f.Flush();
        f.Close();
    }

    CString DPT;   //kk for show to edit
    m_strEDIT=BcdToAsc(buffDPT,SECTOR_SIZE);   
    m_strdpt.SetWindowText(m_strEDIT);  

    free (buffDPT);
    return TRUE;
}   
   

CString CTestMBRDlg::BcdToAsc(unsigned char *BCD, int bytes)   
{   
//    unsigned char  h=0,l=0,hh=0xF0,ll=0x0F;   
//     unsigned char *DPT_ASC=(unsigned char*)malloc(bytes*2);   
//     memset(DPT_ASC,0, bytes*2);
//     for (int i = 0,j=0;i <512; i++)    
//     {   
//         h=BCD[i];   
//         l=BCD[i];   
//         h=h & hh;   
//         l=l & ll;   
//         h=h>>4;   
//         if(h<=9)h=h+48;   
//         else h=h+55;   
//         if(l<=9)l=l+48;   
//         else l=l+55;   
//         DPT_ASC[j]=h;   
//         DPT_ASC[j+1]=l;
//         j=j+2;   
//     }   

    char cBuf[4096]={0};
    unsigned char bBuf[4096]={0};
    memcpy(bBuf, BCD, bytes);

    for (DWORD ii = 0; ii < 512; ii++) {
        sprintf(cBuf, "%s%02X ", cBuf, bBuf[ii]);
        if ((ii % 16) == 15)
            sprintf(cBuf, "%s\r\n", cBuf);
        else if ((ii % 16) == 7)
            sprintf(cBuf, "%s- ", cBuf);
    }
    
    CString DPT;   
    DPT.Format("%s",cBuf);


 //   DPT.Format("%s",DPT_ASC);   
//    free (DPT_ASC);
    return DPT;   
}   
   
unsigned CTestMBRDlg::ReadSectors(DWORD LBA,DWORD NumOfSectors,CString DriveNum, unsigned char *buff)   
{   
/*    unsigned char *buff=(unsigned char*)malloc(512*NumOfSectors); */  
    char devName[] = "\\\\.\\PhysicalDrive";   
    HANDLE hDev = CreateFile(devName+DriveNum, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);   
    if (hDev == INVALID_HANDLE_VALUE) MessageBox("不存在的磁盘或磁盘错误!",NULL,MB_OK);   
    SetFilePointer(hDev,SECTOR_SIZE*LBA, 0, FILE_BEGIN);   
    DWORD dwCB;   
    ReadFile(hDev,buff,SECTOR_SIZE*NumOfSectors,&dwCB, NULL);   
    CloseHandle(hDev);   
    return 0;   
}   
   
DWORD CTestMBRDlg::WriteSectors(DWORD LBA,DWORD NumOfSectors,CString DriveNum,unsigned char*buff)   
{   
    char devName[] = "\\\\.\\PhysicalDrive";   
    HANDLE hDev = CreateFile(devName+DriveNum, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);   
    if (hDev == INVALID_HANDLE_VALUE) MessageBox("不存在的磁盘或磁盘错误!",NULL,MB_OK);   
    SetFilePointer(hDev,512*LBA, 0, FILE_BEGIN);   
    DWORD dwCB;   
    WriteFile(hDev,buff,512*NumOfSectors,&dwCB, NULL);   
    CloseHandle(hDev);   
    return dwCB;
}  

void CTestMBRDlg::OnButtonRead()
{
    // TODO: Add your control notification handler code here
    OnButtonReadDPT(TRUE);

    //char devName[10]={0};
//     CString CSdevName;
//     m_CtrlCombo.GetWindowText(CSdevName);
//     IsIDE(CSdevName);

}




int CTestMBRDlg::ListDrv()
{
    DWORD dwDriveStrlen=0;
    dwDriveStrlen=GetLogicalDriveStrings(0,NULL);
    TCHAR *szDriveName=new char[dwDriveStrlen];
    memset (szDriveName, 0, sizeof(szDriveName));
    TCHAR *pDriveName=NULL;
    CString infodrv;

    ((CComboBox*)GetDlgItem(IDC_COMBO_NAME))->ResetContent();//消除现有所有内容
//     for(int i=1;i<=100;i++)
//     {
//         strTemp.Format("%d",i);
//         ((CComboBox*)GetDlgItem(IDC_COMBO_NAME))->AddString(strTemp);
//    }


    if(GetLogicalDriveStrings(dwDriveStrlen,szDriveName))
    {
        pDriveName=szDriveName;
        while(*pDriveName!=NULL)
        {
            switch(GetDriveType(pDriveName))
            {
            case DRIVE_UNKNOWN :
                //infodrv.Format( "%s是未知的盘盘",pDriveName);
                break;
            case DRIVE_NO_ROOT_DIR:
                //infodrv.Format("%s是无效的盘",pDriveName);
                break;
            case DRIVE_REMOVABLE:
                //infodrv.Format("%s是可移动磁盘",pDriveName);
                infodrv.Format("%s",pDriveName);
                infodrv.Replace(":\\","");
                ((CComboBox*)GetDlgItem(IDC_COMBO_NAME))->AddString(infodrv);
                break;
            case DRIVE_FIXED:
                //infodrv.Format("%s是固定磁盘",pDriveName);

                infodrv.Format("%s",pDriveName);
                infodrv.Replace(":\\","");
                ((CComboBox*)GetDlgItem(IDC_COMBO_NAME))->AddString(infodrv);
                break;
            case DRIVE_REMOTE:
                //infodrv.Format("%s是网络磁盘",pDriveName);
                break;
            case DRIVE_CDROM:
                //infodrv.Format("%s是光驱",pDriveName);
                break;
            case DRIVE_RAMDISK:
                //infodrv.Format("%s是RAM盘",pDriveName);
                break;
            }
            pDriveName+=lstrlen(pDriveName)+1;
        }
    }
    else
    {
        m_strdpt.SetWindowText("获取磁盘失败!-_-!!");
    }
    free (szDriveName);
    return 0;
}



/******************************************************************************

* Function: get disk's physical number from its drive letter

*           e.g. C-->0 (C: is on disk0)

* input: letter, drive letter

* output: N/A

* return: Succeed, disk number

*         Fail, -1

******************************************************************************/

DWORD CTestMBRDlg::GetPhysicalDriveFromPartitionLetter(CString letter)

{

    HANDLE hDevice;               // handle to the drive to be examined

    BOOL result;                 // results flag

    DWORD readed;                   // discard results

    STORAGE_DEVICE_NUMBER number;   //use this to get disk numbers

    CHAR path[DISK_PATH_LEN];

    sprintf(path, "\\\\.\\%s:", letter.GetBuffer(letter.GetLength()));
     letter.ReleaseBuffer();

 //   sprintf(path, "\\\\.\\%c:", 'C');

    hDevice = CreateFile(path, // drive to open

                         GENERIC_READ | GENERIC_WRITE,    // 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 attribute

    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive

    {

        fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());

        return DWORD(-1);

    }

 

    result = DeviceIoControl(

                hDevice,                // handle to device

                IOCTL_STORAGE_GET_DEVICE_NUMBER, // dwIoControlCode

                NULL,                            // lpInBuffer

                0,                               // nInBufferSize

                &number,           // output buffer

                sizeof(number),         // size of output buffer

                &readed,       // number of bytes returned

                NULL      // OVERLAPPED structure

            );

    if (!result) // fail

    {

        fprintf(stderr, "IOCTL_STORAGE_GET_DEVICE_NUMBER Error: %ld\n", GetLastError());

        (void)CloseHandle(hDevice);

        return (DWORD)-1;

    }

    //printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);

    (void)CloseHandle(hDevice);

    return number.DeviceNumber;

}

void CTestMBRDlg::OnButtonCls()
{
    // TODO: Add your control notification handler code here
    m_strdpt.SetWindowText("");
}

void CTestMBRDlg::OnButtonWritedpt()
{
    // TODO: Add your control notification handler code here
    OnButtonRepair();
    OnButtonReadDPT(FALSE);
}


/******************************************************************************

  * Function: get the number of disk which the system installed on
 
    * input: N/A
    
      * output: N/A
      
        * return: Succeed, disk number
        
          *         Fail, -1
          
******************************************************************************/

DWORD CTestMBRDlg::GetSystemDiskPhysicalNumber(void)

{
    
    CHAR sysPath[DISK_PATH_LEN];
    
    CHAR diskLetter;
    
    DWORD diskNumber;
    
    
    
    DWORD ret = GetSystemDirectory(sysPath, sizeof(sysPath));
    
    if (ret == 0)
        
    {
        
        fprintf(stderr, "GetSystemDirectory() Error: %ld\n", GetLastError());
        
        return (DWORD)-1;
        
    }
    
    diskLetter = sysPath[0];
    
    diskNumber = GetPhysicalDriveFromPartitionLetter(diskLetter);
    
    return diskNumber;
    
}


/******************************************************************************
* Function: delete the partition layout of the disk
* input: disk, disk name
* output: N/A
* return: Succeed, 0
*         Fail, -1
******************************************************************************/
DWORD CTestMBRDlg::DestroyDisk(DWORD disk)
{
    HANDLE hDevice;               // handle to the drive to be examined
    BOOL result;                  // results flag
    DWORD readed;                 // discard results
    CHAR diskPath[DISK_PATH_LEN];
    
    sprintf(diskPath, "\\\\.\\PhysicalDrive%d", disk);
    
    hDevice = CreateFile(
        diskPath, // drive to open
        GENERIC_READ | GENERIC_WRITE,     // 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 attribute
        );
    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
    {
        fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
        return DWORD(-1);
    }
    
    result = DeviceIoControl(
        hDevice,               // handle to device
        IOCTL_DISK_DELETE_DRIVE_LAYOUT, // dwIoControlCode
        NULL,                           // lpInBuffer
        0,                              // nInBufferSize
        NULL,                           // lpOutBuffer
        0,                              // nOutBufferSize
        &readed,      // number of bytes returned
        NULL        // OVERLAPPED structure
        );
    if (!result)
    {
        //fprintf(stderr, "IOCTL_DISK_DELETE_DRIVE_LAYOUT Error: %ld\n", GetLastError());
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
    
    //fresh the partition table
    result = DeviceIoControl(
        hDevice,
        IOCTL_DISK_UPDATE_PROPERTIES,
        NULL,
        0,
        NULL,
        0,
        &readed,
        NULL
        );
    if (!result)
    {
        fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
    
    (void)CloseHandle(hDevice);
    return 0;
}

void CTestMBRDlg::OnButtonDelDpt()
{
    // TODO: Add your control notification handler code here
    int disk_num = CheckSysDisk();
    if (disk_num ==-1)
        return ;

    DestroyDisk(disk_num);
    
    OnButtonReadDPT(FALSE);
    
}

void CTestMBRDlg::OnButtonReadMbr()
{
    // TODO: Add your control notification handler code here
    OnButtonReadDPT(FALSE);
}


BOOL CTestMBRDlg::GetDriveGeometry(HANDLE hDevice, DISK_GEOMETRY *pdg)
{
//    HANDLE hDevice;               // handle to the drive to be examined
    BOOL bResult;                  // results flag
    DWORD junk;                   // discard results
    
//     char devName[] = "\\\\.\\PhysicalDrive";   
//
//     hDevice = CreateFile(devName+DriveNum, // drive
//         0,                // no access to the drive
//         FILE_SHARE_READ | // share mode
//         FILE_SHARE_WRITE,
//         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);
//     }
    
    bResult = DeviceIoControl(hDevice, // device to be queried
        IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, // operation to perform
        NULL, 0, // no input buffer
        pdg, sizeof(*pdg),     // output buffer
        &junk,                 // # bytes returned
        (LPOVERLAPPED) NULL); // synchronous I/O
    
//    CloseHandle(hDevice);
    
    return (bResult);
}


/******************************************************************************
* Function: initialize the disk and create partitions
* input: disk, disk name
*        parNum, partition number
* output: N/A
* return: Succeed, 0
*         Fail, -1
******************************************************************************/
DWORD CTestMBRDlg::CreateDisk(DWORD disk, WORD partNum)
{
    HANDLE hDevice;               // handle to the drive to be examined
    BOOL result;                  // results flag
    DWORD readed;                 // discard results
    DWORD ret;
    WORD i;
    CHAR diskPath[DISK_PATH_LEN];
    DISK_GEOMETRY pdg;
    DWORD sectorSize;
    DWORD signature;
    LARGE_INTEGER diskSize;
    LARGE_INTEGER partSize;
    BYTE actualPartNum;
 
    DWORD layoutStructSize;
    DRIVE_LAYOUT_INFORMATION_EX *dl;
    CREATE_DISK newDisk;
 
    sprintf(diskPath, "\\\\.\\PhysicalDrive%d", disk);
 
    actualPartNum = 8;
//kk    actualPartNum = 4;
//     if (partNum > actualPartNum)
//     {
//         return (WORD)-1;
//     }
 
    hDevice = CreateFile(
                diskPath,
                GENERIC_READ|GENERIC_WRITE,
                FILE_SHARE_READ|FILE_SHARE_WRITE,
                NULL,           //default security attributes
                OPEN_EXISTING, // disposition
                0,              // file attributes
                NULL
                );
    if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
    {
        fprintf(stderr, "CreateFile() Error: %ld\n", GetLastError());
        return DWORD(-1);
    }
 
    // Create primary partition MBR
    newDisk.PartitionStyle = PARTITION_STYLE_MBR;
    signature = (DWORD)time(NULL);     //get signature from current time
    newDisk.Mbr.Signature = signature;

 
    result = DeviceIoControl(
                hDevice,
                IOCTL_DISK_CREATE_DISK,
                &newDisk,
                sizeof(CREATE_DISK),
                NULL,
                0,
                &readed,
                NULL
                );
    if (!result)
    {
        fprintf(stderr, "IOCTL_DISK_CREATE_DISK Error: %ld\n", GetLastError());
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
 
    //fresh the partition table
    result = DeviceIoControl(
                hDevice,
                IOCTL_DISK_UPDATE_PROPERTIES,
                NULL,
                0,
                NULL,
                0,
                &readed,
                NULL
                );
    if (!result)
    {
        fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
 
    //Now create the partitions
    ret = GetDriveGeometry(hDevice, &pdg);
    if ((DWORD)-1 == ret)
    {
        return ret;
    }


    sectorSize = pdg.BytesPerSector;
    diskSize.QuadPart = pdg.Cylinders.QuadPart * pdg.TracksPerCylinder *
                        pdg.SectorsPerTrack * pdg.BytesPerSector;       //calculate the disk size;
    partSize.QuadPart = diskSize.QuadPart / partNum;
 
    layoutStructSize = sizeof(DRIVE_LAYOUT_INFORMATION_EX) + (actualPartNum - 1) * sizeof(PARTITION_INFORMATION_EX);
    dl = (DRIVE_LAYOUT_INFORMATION_EX*)malloc(layoutStructSize);
    if (NULL == dl)
    {
        (void)CloseHandle(hDevice);
        return (WORD)-1;
    }
    //kk add
    long M_SIZE                = 1024 * 1024;
    long UBOOT_SIZE            = 4 ;  //4M
    long BOOT_SIZE            = 8 ;  //8M
    long RECOVERY_SIZE        = 8 ;  //8M
    long SYSTEM_SIZE        = 20 ; //512M
    long CACHE_SIZE            = 20 ; //512M
    long MACADDR_SIZE        = 8 ;   //8M
    long MISC_SIZE            = 8 ;   //8M
    long EXTEN_TOTAL_SIZE    = 56;
    long DATA_SIZE            = 400;        

 
    dl->PartitionStyle = (DWORD)PARTITION_STYLE_MBR;
    dl->PartitionCount = actualPartNum;
    dl->Mbr.Signature = signature;
 
    //clear the unused partitions
    for (i = 0; i < actualPartNum; i++){
        dl->PartitionEntry[i].RewritePartition = 1;
        dl->PartitionEntry[i].Mbr.PartitionType = PARTITION_ENTRY_UNUSED;
    }
    //set the profile of the partitions

    //boot
    dl->PartitionEntry[0].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[0].StartingOffset.QuadPart = UBOOT_SIZE * M_SIZE;
    dl->PartitionEntry[0].PartitionLength.QuadPart = BOOT_SIZE * M_SIZE;
    dl->PartitionEntry[0].PartitionNumber = 0 + 1;
    dl->PartitionEntry[0].RewritePartition = TRUE;
    dl->PartitionEntry[0].Mbr.PartitionType = /*PARTITION_IFS;*/0x83;
    dl->PartitionEntry[0].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[0].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[0].Mbr.HiddenSectors =UBOOT_SIZE * M_SIZE / 512;


    //recovery
    dl->PartitionEntry[1].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[1].StartingOffset.QuadPart =( UBOOT_SIZE +  BOOT_SIZE) * M_SIZE;
    dl->PartitionEntry[1].PartitionLength.QuadPart = RECOVERY_SIZE * M_SIZE;/*partSize.QuadPart;*/
    dl->PartitionEntry[1].PartitionNumber = 1 + 1;
    dl->PartitionEntry[1].RewritePartition = TRUE;
    dl->PartitionEntry[1].Mbr.PartitionType = /*PARTITION_IFS;*/ 0x83;
    dl->PartitionEntry[1].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[1].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[1].Mbr.HiddenSectors =( UBOOT_SIZE +  BOOT_SIZE ) * M_SIZE / 512;



    //extend
    dl->PartitionEntry[2].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[2].StartingOffset.QuadPart = ( UBOOT_SIZE +  BOOT_SIZE  + RECOVERY_SIZE ) * M_SIZE;
    dl->PartitionEntry[2].PartitionLength.QuadPart = EXTEN_TOTAL_SIZE * M_SIZE;/*partSize.QuadPart;*/
    dl->PartitionEntry[2].PartitionNumber = 2 + 1;
    dl->PartitionEntry[2].RewritePartition = TRUE;
    dl->PartitionEntry[2].Mbr.PartitionType = /*PARTITION_IFS;*/ PARTITION_EXTENDED;
    dl->PartitionEntry[2].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[2].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[2].Mbr.HiddenSectors =
        (UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE ) * M_SIZE / 512;
    
    //data
    dl->PartitionEntry[3].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[3].StartingOffset.QuadPart =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE +  EXTEN_TOTAL_SIZE ) * M_SIZE;
    dl->PartitionEntry[3].PartitionLength.QuadPart = DATA_SIZE * M_SIZE;  //data partitons
    dl->PartitionEntry[3].PartitionNumber = 3 + 1;
    dl->PartitionEntry[3].RewritePartition = TRUE;
    dl->PartitionEntry[3].Mbr.PartitionType =  0x83; /*PARTITION_XINT13_EXTENDED*/;
    dl->PartitionEntry[3].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[3].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[3].Mbr.HiddenSectors =
         ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE +  EXTEN_TOTAL_SIZE) * M_SIZE / 512;




    dl->PartitionEntry[4].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[4].StartingOffset.QuadPart = ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE ) * M_SIZE;
    dl->PartitionEntry[4].PartitionLength.QuadPart = SYSTEM_SIZE * M_SIZE;   //system partitions
    dl->PartitionEntry[4].PartitionNumber = 4 + 1;
    dl->PartitionEntry[4].RewritePartition = TRUE;
    dl->PartitionEntry[4].Mbr.PartitionType = 0x83;
    dl->PartitionEntry[4].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[4].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[4].Mbr.HiddenSectors =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE ) * M_SIZE / 512 ;
    
    
    
    dl->PartitionEntry[5].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[5].StartingOffset.QuadPart = ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE + SYSTEM_SIZE) * M_SIZE ;
    dl->PartitionEntry[5].PartitionLength.QuadPart = CACHE_SIZE * M_SIZE;   //cache partitions
    dl->PartitionEntry[5].PartitionNumber = 5 + 1;
    dl->PartitionEntry[5].RewritePartition = TRUE;
    dl->PartitionEntry[5].Mbr.PartitionType = 0x83;
    dl->PartitionEntry[5].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[5].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[5].Mbr.HiddenSectors =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE + SYSTEM_SIZE ) * M_SIZE / 512;
    
    
    
    
    dl->PartitionEntry[6].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[6].StartingOffset.QuadPart =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE + SYSTEM_SIZE + CACHE_SIZE ) * M_SIZE;
    dl->PartitionEntry[6].PartitionLength.QuadPart = MACADDR_SIZE * M_SIZE;   //macaddr partitions
    dl->PartitionEntry[6].PartitionNumber = 6 + 1;
    dl->PartitionEntry[6].RewritePartition = TRUE;
    dl->PartitionEntry[6].Mbr.PartitionType = 0x83;
    dl->PartitionEntry[6].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[6].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[6].Mbr.HiddenSectors =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE + SYSTEM_SIZE + CACHE_SIZE ) * M_SIZE / 512;
    
    
    
    
    dl->PartitionEntry[7].PartitionStyle = PARTITION_STYLE_MBR;
    dl->PartitionEntry[7].StartingOffset.QuadPart =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE + SYSTEM_SIZE + CACHE_SIZE + MACADDR_SIZE ) * M_SIZE;
    dl->PartitionEntry[7].PartitionLength.QuadPart = MISC_SIZE * M_SIZE;   //misc partitions
    dl->PartitionEntry[7].PartitionNumber = 7 + 1;
    dl->PartitionEntry[7].RewritePartition = TRUE;
    dl->PartitionEntry[7].Mbr.PartitionType = 0x83;
    dl->PartitionEntry[7].Mbr.BootIndicator = FALSE;
    dl->PartitionEntry[7].Mbr.RecognizedPartition = TRUE;
    dl->PartitionEntry[7].Mbr.HiddenSectors =
        ( UBOOT_SIZE +  BOOT_SIZE + RECOVERY_SIZE + SYSTEM_SIZE + CACHE_SIZE + MACADDR_SIZE ) * M_SIZE/ 512;


    //execute the layout
    result = DeviceIoControl(
                hDevice,
                IOCTL_DISK_SET_DRIVE_LAYOUT_EX,
                dl,
                layoutStructSize,
                NULL,
                0,
                &readed,
                NULL
                );
    if (!result)
    {
        fprintf(stderr, "IOCTL_DISK_SET_DRIVE_LAYOUT_EX Error: %ld\n", GetLastError());
        free(dl);
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }
 
    //fresh the partition table
    result = DeviceIoControl(
                hDevice,
                IOCTL_DISK_UPDATE_PROPERTIES,
                NULL,
                0,
                NULL,
                0,
                &readed,
                NULL
                );
    if (!result)
    {
        fprintf(stderr, "IOCTL_DISK_UPDATE_PROPERTIES Error: %ld\n", GetLastError());
        free(dl);
        (void)CloseHandle(hDevice);
        return DWORD(-1);
    }

    (void)CloseHandle(hDevice);
    Sleep(3000);            //wait the operations take effect
    return 0;
}

void CTestMBRDlg::OnButtonCreateDpt()
{
    // TODO: Add your control notification handler code here

    int disk_num = CheckSysDisk();
    if (disk_num ==-1)
        return ;

    CreateDisk(disk_num, 8);
    OnButtonReadDPT(FALSE);
}

int CTestMBRDlg::CheckSysDisk()
{
    CString DriveName;
    m_CtrlCombo.GetWindowText(DriveName);
    if (DriveName == "")
    {
        m_strdpt.SetWindowText("pls choose disk!");
        return -1;
    }
    
    int disk_num=GetPhysicalDriveFromPartitionLetter(DriveName);  //获取驱动器号  
    
    int sys_num = GetSystemDiskPhysicalNumber();
    if ( disk_num == sys_num )
    {
        m_strdpt.SetWindowText("STOP! You don't write system disk MBR.");
        return -1;
    }
    return disk_num;
}

BOOL CTestMBRDlg::GetPhysicalDriveInfo(int disknum, DISK_GEOMETRY *pdg)
{
    HANDLE hDevice;               // handle to the drive to be examined
    BOOL bResult;                 // results flag
    DWORD junk;                   // discard results
    
    CHAR diskPath[DISK_PATH_LEN];
    
    sprintf(diskPath, "\\\\.\\PhysicalDrive%d", disknum);
    hDevice = CreateFile(diskPath,  // drive to open
        0,                // no access to the drive
        FILE_SHARE_READ | // share mode
        FILE_SHARE_WRITE,
        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);
    }
    
    bResult = DeviceIoControl(hDevice,     // device to be queried
        IOCTL_DISK_GET_DRIVE_GEOMETRY,     // operation to perform
        NULL, 0,               // no input buffer
        pdg, sizeof(*pdg),     // output buffer
        &junk,                 // # bytes returned
        (LPOVERLAPPED) NULL);  // synchronous I/O
    
    CloseHandle(hDevice);
    
    return (bResult);

}

void CTestMBRDlg::OnButtonPhysicalInfo()
{
    // TODO: Add your control notification handler code here
    char savecontent[2049]={0};
    int sv_count = 0;
    CString DriveName;
    m_CtrlCombo.GetWindowText(DriveName);
    if (DriveName == "")
    {
        m_strdpt.SetWindowText("Please choose disk!");
        return ;
    }
    
    int disk_num=GetPhysicalDriveFromPartitionLetter(DriveName);  //获取驱动器号   
    DISK_GEOMETRY pdg;

    GetPhysicalDriveInfo( disk_num, &pdg);
    

    
    ULONGLONG DiskSize;
    CString tmpcs;

    DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder * (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector;

    tmpcs.Format(" \r\n    \
    Cylinders = %I64d\r\n    \
    Tracks per cylinder = %ld\r\n    \
    Sectors per track = %ld\r\n    \
    Bytes per sector = %ld\r\n    \
     Disk size = %I64d (Bytes) = %I64d (Mb)\r\n ",    \
    pdg.Cylinders,    \
    (ULONG) pdg.TracksPerCylinder,    \
    (ULONG) pdg.SectorsPerTrack,    \
    (ULONG) pdg.BytesPerSector , \
    DiskSize,\
    DiskSize / (1024 * 1024));
    
    m_strdpt.SetWindowText(tmpcs);


}

void CTestMBRDlg::OnButtonCleraMbr()
{

    int disk_num = CheckSysDisk();
    if (disk_num ==-1)
        return ;
    

    CString disk_char;   
    disk_char.Format("%d",disk_num);                    //转换成字符串类型   
    
    unsigned char *buff=(unsigned char*)malloc(SECTOR_SIZE + 1);   //存正确MBR   
    memset(buff, 0, SECTOR_SIZE + 1);

    //写入磁盘001扇区   
    WriteSectors(0,1,disk_char,buff);   
    
    OnButtonReadDPT(FALSE);
}

void CTestMBRDlg::OnButtonWriteUboot()
{
    // TODO: Add your control notification handler code here


    int disk_num = CheckSysDisk();
    if (disk_num ==-1)
        return ;

    CString disk_char;   
    disk_char.Format("%d",disk_num);
 

    //清除uboot param
    unsigned char *buff=(unsigned char*)malloc(SECTOR_SIZE * 16 + 1);   //存正确MBR   
    memset(buff, 0, SECTOR_SIZE* 16 + 1);
    WriteSectors(1536,16,disk_char,buff);

    //将uboot.bin 空1M,读到buff_uboot里
    unsigned char * buff_uboot = (unsigned char*)malloc(SECTOR_SIZE * 4096 + 1);
    memset(buff_uboot,0, SECTOR_SIZE * 4096 + 1);
    HANDLE filehandle = CreateFile("u-boot.bin",   
        GENERIC_READ,   
        FILE_SHARE_READ|FILE_SHARE_WRITE,   
        NULL,   
        OPEN_ALWAYS,   
        FILE_ATTRIBUTE_NORMAL,   
        NULL);   
    DWORD byte1;   
    SetFilePointer(filehandle, 512*2, 0, FILE_BEGIN);
    ReadFile(filehandle,buff_uboot,SECTOR_SIZE * 4096 ,&byte1,NULL);   
    CloseHandle(filehandle);   

    //写入分区里
    WriteSectors(2,4096,disk_char,buff_uboot);
    m_strdpt.SetWindowText("ok,write uboot finish!");
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值