这篇文章并没有写完,还有如何格式化成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!");
}