mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <windows.h>
#include <dbt.h>
#include <QThread>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class Thread;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void my_log(QString str);
void my_log1(QString str);
void WriteToFile(const char* fileName, const char* str);
wchar_t MydwordTowchar_t(DWORD i);
void AddusbToChoice(wchar_t letter);
void DelusbToChoice(wchar_t letter);
int WriteSector(int startsector, int numberofsector, char *buffer);
char * ReadSector(int startsector, int numberofsectors);
DWORD GetTotalSector(QString szPath);
int GetPhysicalDriveNumber(char cDriveName );
int ChangeStringDriveNameToDriveNumber();
private:
//UsbConfig usbConfig;
char FirstDriveFromMask(ULONG unitmask);
DWORD GetDesignatedDiskFreeSpace(const QString &szPath);
DWORD GetSystemDiskPhysicalNumber();
int GetPhysicalDriveFromPartitionLetter(wchar_t letter);
DWORD FormatVolume(wchar_t letter);
DWORD GetDriveGeometry(const wchar_t*disk, DISK_GEOMETRY *pdg);
int DestroyDisk(DWORD disk);
int CreateDisk(DWORD disk, WORD partNum);
public slots:
void DealThreadMsgInt(int value);
void DealThreadMsgQString(QString value);
protected:
bool nativeEvent(const QByteArray &eventType, void *message, long *result);
private slots:
void on_pushButton_format_clicked();
void on_pushButton_sdcard_clicked();
void on_pushButton_fub_clicked();
void on_pushButton_start_clicked();
void on_radioButton_s32v_clicked();
void on_radioButton_imx6_clicked();
void on_textBrowser_log_textChanged();
void on_textBrowser_log1_textChanged();
void on_comboBox_emmc1_currentIndexChanged(const QString &arg1);
void on_comboBox_emmc_currentIndexChanged(const QString &arg1);
public:
Ui::MainWindow *ui;
//write tool
QString m_log;
QString m_pathDriver;
QString m_strDriveSize;
QString sdcard_strFilePath;
QString fub_strFilePath;
QString fub_strFileName;
int progress_bar;
DWORD Sdcard_StartWriteSector{8}; //2个扇区为1k
DWORD m_dwStartWriteSector;
int m_nPhysicalNumber{0};
int m_dwDriveNumber{0x100};
BOOL m_isWritting{false};
BOOL m_isFormating{false};
Thread * m_workThread{nullptr};
//format tool
int m_sysdiskNumber{0};
int m_seldiskNumber{1};
QString m_strDriveSize1;
QString m_log1;
QString m_pathDriver1;
};
class Thread : public QThread
{
Q_OBJECT
public:
Thread(MainWindow *p):pm(p){};
~Thread(){};
signals:
void msgPrgress(int value);
void msgPrgress(QString value);
private:
void run();
private:
MainWindow* pm;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QtSerialPort/QSerialPortInfo>
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <QMessageBox>
#include <QFileDialog>
#include <QFile>
#define VOLUMEDISKSIZE (sizeof(VOLUME_DISK_EXTENTS))
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->comboBox_emmc->setCurrentText("");
ui->comboBox_emmc1->setCurrentText("");
ui->tabWidget->setCurrentIndex(0);
ui->radioButton_s32v->setChecked(true);
m_sysdiskNumber = GetSystemDiskPhysicalNumber();
for(wchar_t i =L'A';i<L'Z';i++)
{
AddusbToChoice(i);
}
}
MainWindow::~MainWindow()
{
delete ui;
m_workThread->deleteLater();
}
void MainWindow::my_log(QString str)
{
m_log +=str;
m_log += "\r";
ui->textBrowser_log->setText(m_log);
}
void MainWindow::my_log1(QString str1)
{
m_log1 +=str1;
m_log1 += "\r";
ui->textBrowser_log1->setText(m_log1);
}
char MainWindow::FirstDriveFromMask(ULONG unitmask)
{
char i;
for (i = 0; i < 26; ++i)
{
if (unitmask & 0x1)
break;
unitmask = unitmask >> 1;
}
return (i + 'A');
}
DWORD MainWindow::GetDesignatedDiskFreeSpace(const QString &szPath)
{
DWORD dwTotalDiskSpace, dwFreeDiskSpace, dwUsedDiskSpace;
ULARGE_INTEGER uiFreeBytesAvailableToCaller;
ULARGE_INTEGER uiTotalNumberOfBytes;
ULARGE_INTEGER uiTotalNumberOfFreeBytes;
const wchar_t * encodedName = reinterpret_cast<const wchar_t *>(szPath.utf16());
if (GetDiskFreeSpaceEx(encodedName, &uiFreeBytesAvailableToCaller,
&uiTotalNumberOfBytes,
&uiTotalNumberOfFreeBytes))
{
dwTotalDiskSpace = (DWORD)(uiTotalNumberOfBytes.QuadPart / 1024 / 1024);
dwFreeDiskSpace = (DWORD)(uiFreeBytesAvailableToCaller.QuadPart >> 20);
dwUsedDiskSpace = dwTotalDiskSpace - dwFreeDiskSpace;
QString str=QString("磁盘%1总空间%2MB, 已用%3MB, 可用%4MB").arg(szPath).arg(dwTotalDiskSpace).arg(dwUsedDiskSpace).arg(dwFreeDiskSpace);
my_log(str);
my_log1(str);
return dwTotalDiskSpace;
}
return -1;
}
DWORD MainWindow::GetSystemDiskPhysicalNumber()
{
wchar_t diskLetter[50];
DWORD diskNumber;
DWORD ret = GetSystemDirectory(diskLetter, sizeof(diskLetter));
if (ret <= 0)
{
MessageBoxA(NULL,"获取系统盘目录失败!!", "错误", NULL);
return (DWORD)-1;
}
diskNumber = GetPhysicalDriveFromPartitionLetter(diskLetter[0]);
return diskNumber;
}
int MainWindow::GetPhysicalDriveFromPartitionLetter(wchar_t 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
wchar_t _devicename[] = TEXT("\\\\.\\A:");
_devicename[4] = letter;
hDevice = CreateFile(_devicename, // 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
{
return -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
{
(void)CloseHandle(hDevice);
return -1;
}
//printf("%d %d %d\n\n", number.DeviceType, number.DeviceNumber, number.PartitionNumber);
(void)CloseHandle(hDevice);
return number.DeviceNumber;
}
DWORD MainWindow::FormatVolume(wchar_t letter)
{
DWORD ret = -1;
wchar_t commod[] = L"format Z: /fs:fat32 /Q /Y";
commod[7] = letter;
size_t convertedChars = 0;
size_t dByteNum = sizeof(commod) / sizeof(wchar_t) + 1;
char* dest = new char[dByteNum];
if (wcstombs_s(&convertedChars, dest, dByteNum, commod, _TRUNCATE) == 0)
{
WriteToFile("DiskPartition.bat", dest);
Sleep(1000);
ShellExecute(NULL, NULL, L"DiskPartition.bat", NULL, NULL, SW_HIDE);
Sleep(1000);
ret = 1;
}
return ret;
}
DWORD MainWindow::GetDriveGeometry(const wchar_t *disk, DISK_GEOMETRY *pdg)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL bResult; // results flag
DWORD junk; // discard results
hDevice = CreateFile(disk, // 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 DWORD(-1);
}
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 0;
}
int MainWindow::DestroyDisk(DWORD disk)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL result; // results flag
DWORD readed; // discard results
wchar_t diskPath[] = L"\\\\.\\PhysicalDrive1";
diskPath[17] = MydwordTowchar_t(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
{
return -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 -1;
}
//fresh the partition table
result = DeviceIoControl(hDevice,IOCTL_DISK_UPDATE_PROPERTIES,NULL,0,
NULL,0,&readed,NULL);
if (!result)
{
(void)CloseHandle(hDevice);
return -1;
}
(void)CloseHandle(hDevice);
return true;
}
int MainWindow::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;
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;
wchar_t diskPath[] = L"\\\\.\\PhysicalDrive1";
diskPath[17] = MydwordTowchar_t(disk);
actualPartNum = (BYTE)partNum;
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
{
return -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)
{
(void)CloseHandle(hDevice);
return -1;
}
//fresh the partition table
result = DeviceIoControl(hDevice,IOCTL_DISK_UPDATE_PROPERTIES,
NULL,0,NULL,0,&readed,NULL);
if (!result)
{
(void)CloseHandle(hDevice);
return -1;
}
//Now create the partitions
ret = GetDriveGeometry(diskPath, &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 / actualPartNum;
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 -1;
}
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
for (i = 0; i < actualPartNum; i++){
dl->PartitionEntry[i].PartitionStyle = PARTITION_STYLE_MBR;
dl->PartitionEntry[i].StartingOffset.QuadPart = 60*1024*1024 + //开头空出60M空间
(partSize.QuadPart * i) + ((LONGLONG)(pdg.SectorsPerTrack) * (LONGLONG)(pdg.BytesPerSector)); //32256
dl->PartitionEntry[i].PartitionLength.QuadPart = partSize.QuadPart - 60 * 1024 * 1024 -
((LONGLONG)(pdg.SectorsPerTrack) * (LONGLONG)(pdg.BytesPerSector));
dl->PartitionEntry[i].PartitionNumber = i + 1;
dl->PartitionEntry[i].RewritePartition = TRUE;
dl->PartitionEntry[i].Mbr.PartitionType = PARTITION_FAT32;
dl->PartitionEntry[i].Mbr.BootIndicator = FALSE;
dl->PartitionEntry[i].Mbr.RecognizedPartition = TRUE;
dl->PartitionEntry[i].Mbr.HiddenSectors =
pdg.SectorsPerTrack + (DWORD)((partSize.QuadPart / sectorSize) * i);
}
//execute the layout
result = DeviceIoControl(hDevice,IOCTL_DISK_SET_DRIVE_LAYOUT_EX,dl,
layoutStructSize,NULL,0,&readed,NULL);
if (!result)
{
free(dl);
(void)CloseHandle(hDevice);
return -1;
}
//fresh the partition table
result = DeviceIoControl(hDevice,IOCTL_DISK_UPDATE_PROPERTIES,
NULL,0,NULL,0,&readed,NULL);
if (!result)
{
free(dl);
(void)CloseHandle(hDevice);
return -1;
}
free(dl);
(void)CloseHandle(hDevice);
Sleep(3000); //wait the operations take effect
return true;
}
void MainWindow::DealThreadMsgInt(int value)
{
ui->progressBar->setValue(value);
}
void MainWindow::DealThreadMsgQString(QString value)
{
m_log +=value;
m_log += "\r";
ui->textBrowser_log->setText(m_log);
}
int MainWindow::WriteSector(int startsector, int numberofsectors, char *buffer)
{
wchar_t temp2[20];
LARGE_INTEGER startbytes;
QString StringTemp;
// All msdos data structures must be packed on a 1 byte boundary
#pragma pack (1)
struct
{
DWORD StartingSector ;
WORD NumberOfSectors ;
DWORD pBuffer;
}ControlBlock;
#pragma pack ()
#pragma pack (1)
typedef struct _DIOC_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS ;
#pragma pack ()
HANDLE hDevice ;
DIOC_REGISTERS reg ;
BOOL fResult ;
DWORD cb ;
// Creating handle to vwin32.vxd (win 9x)
hDevice = CreateFile ( TEXT("\\\\.\\vwin32"),
0,
0,
NULL,
0,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
if ( hDevice == INVALID_HANDLE_VALUE )
{
// win NT/2K/XP code
HANDLE hDevice;
DWORD byteswrite;
wchar_t _devicename[30];
if (m_nPhysicalNumber == 0 )
return FALSE;
swprintf(_devicename,30,TEXT("\\\\.\\PhysicalDrive%d"), m_nPhysicalNumber);
// Creating a handle to disk drive using CreateFile () function ..
hDevice = CreateFile(_devicename,
GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0 , NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return FALSE;
startbytes.LowPart = ((startsector&0x7fffff) << 9);
if (startsector&0xff800000)
startbytes.HighPart = ((startsector&0xff800000)>>23);
else
startbytes.HighPart = 0;
// Setting the pointer to point to the start of the sector we want to read ..
SetFilePointerEx (hDevice, startbytes, NULL, FILE_BEGIN);
//SetFilePointer (hDevice, ((startsector&0x7fffff) << 9), NULL, FILE_BEGIN);
if (!WriteFile (hDevice, buffer, 512*numberofsectors, &byteswrite, NULL) )
return FALSE;
if (byteswrite != (512*(DWORD)numberofsectors))
{
swprintf(temp2,20,L"%d sectors",byteswrite);
StringTemp =QString::fromWCharArray(temp2);
MessageBoxA(NULL,"Only copy a part ","ERROR",NULL);
return FALSE;
}
}
else
{
return FALSE;
}
CloseHandle(hDevice);
return TRUE;
}
char * MainWindow::ReadSector(int startsector, int numberofsectors)
{
// All msdos data structures must be packed on a 1 byte boundary
#pragma pack (1)
struct
{
DWORD StartingSector ;
WORD NumberOfSectors ;
DWORD pBuffer;
}ControlBlock;
#pragma pack ()
#pragma pack (1)
typedef struct _DIOC_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS ;
#pragma pack ()
char* buffer = (char*)malloc (512*numberofsectors);
HANDLE hDevice ;
DIOC_REGISTERS reg ;
BOOL fResult ;
DWORD cb ;
// Creating handle to vwin32.vxd (win 9x)
hDevice = CreateFile ( TEXT("\\\\.\\vwin32"),
0,
0,
NULL,
0,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
if ( hDevice == INVALID_HANDLE_VALUE )
{
// win NT/2K/XP code
HANDLE hDevice;
DWORD bytesread;
wchar_t _devicename[] = TEXT("\\\\.\\A:");
_devicename[4] += m_dwDriveNumber;
// Creating a handle to disk drive using CreateFile () function ..
hDevice = CreateFile(_devicename,
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
free(buffer);
buffer = NULL;
goto finish;
}
// Setting the pointer to point to the start of the sector we want to read ..
SetFilePointer (hDevice, (startsector*512), NULL, FILE_BEGIN);
if (!ReadFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL) )
{
free(buffer);
buffer = NULL;
goto finish;
}
}
else
{
free(buffer);
buffer = NULL;
goto finish;
}
finish:
CloseHandle(hDevice);
return buffer;
}
DWORD MainWindow::GetTotalSector(QString szPath)
{
struct _DISK_GEOMETRY_EX
{ DISK_GEOMETRY Geometry;
LARGE_INTEGER DiskSize;
UCHAR Data[1];
} DiskEX;
HANDLE hDevice;
DWORD bytesReturned;
DWORD totalSector = 0;
DWORD bRet;
wchar_t _devicename[] = TEXT("\\\\.\\A:");
_devicename[4]=szPath.utf16()[0];
// Creating a handle to disk drive using CreateFile () function ..
hDevice = CreateFile(_devicename,
GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return FALSE;
bRet = DeviceIoControl(
hDevice, // handle to device
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, // dwIoControlCode
NULL, // lpInBuffer
0, // nInBufferSize
(LPVOID) &DiskEX, // output buffer
sizeof(DiskEX), // size of output buffer
(LPDWORD) &bytesReturned , // number of bytes returned
NULL // OVERLAPPED structure
);
if (bRet == 0)
{
return FALSE;
}
if ( DiskEX.DiskSize.HighPart != 0 )
{
totalSector = ((DiskEX.DiskSize.HighPart) << 23);
}
totalSector |= (DiskEX.DiskSize.LowPart >> 9);
return totalSector;
}
int MainWindow::GetPhysicalDriveNumber(char cDriveName )
{
HANDLE hDevice;
DWORD dwOut;
BOOL bRet;
wchar_t vcDriveName[ 40 ];
VOLUME_DISK_EXTENTS* pstVolumeData;
int iDiskNumber;
// alloc memory
pstVolumeData = ( VOLUME_DISK_EXTENTS * ) malloc( VOLUMEDISKSIZE );
if( pstVolumeData == NULL )
{
return -1;
}
//
swprintf( vcDriveName,7,TEXT("\\\\?\\%c:"), cDriveName );
// Open Device
hDevice = CreateFile( vcDriveName, GENERIC_READ, FILE_SHARE_READ |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if( hDevice == INVALID_HANDLE_VALUE )
{
return -1;
}
// Call Device Io Control
bRet = DeviceIoControl( hDevice, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL, 0, pstVolumeData, VOLUMEDISKSIZE, &dwOut, NULL );
if( bRet == FALSE )
{
free( pstVolumeData );
return -1;
}
CloseHandle( hDevice );
// Disk number is lower than 1 is failed.
if( pstVolumeData->NumberOfDiskExtents < 1 )
{
free( pstVolumeData );
return -1;
}
iDiskNumber = pstVolumeData->Extents[0].DiskNumber;
free( pstVolumeData );
return iDiskNumber;
}
int MainWindow::ChangeStringDriveNameToDriveNumber()
{
DWORD dwReturnValue = TRUE;
if ( m_pathDriver == "D:\\")
m_dwDriveNumber = 3; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "E:\\")
m_dwDriveNumber = 4; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "F:\\")
m_dwDriveNumber = 5; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "G:\\")
m_dwDriveNumber = 6; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "H:\\")
m_dwDriveNumber = 7; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "I:\\")
m_dwDriveNumber = 8; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "J:\\")
m_dwDriveNumber = 9; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "K:\\")
m_dwDriveNumber = 10; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "L:\\")
m_dwDriveNumber = 11; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "M:\\")
m_dwDriveNumber = 12; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "N:\\")
m_dwDriveNumber = 13; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "O:\\")
m_dwDriveNumber = 14; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "P:\\")
m_dwDriveNumber = 15; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "Q:\\")
m_dwDriveNumber = 16; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "R:\\")
m_dwDriveNumber = 17; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "S:\\")
m_dwDriveNumber = 18; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "T:\\")
m_dwDriveNumber = 19; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "U:\\")
m_dwDriveNumber = 20; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "V:\\")
m_dwDriveNumber = 21; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "W:\\")
m_dwDriveNumber = 22; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "X:\\")
m_dwDriveNumber = 23; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "Y:\\")
m_dwDriveNumber = 24; // driver number [0=A, 1=B, 2=C, 3=D ....]
else if ( m_pathDriver == "Z:\\")
m_dwDriveNumber = 25; // driver number [0=A, 1=B, 2=C, 3=D ....]
else
dwReturnValue = FALSE;
return dwReturnValue;
}
wchar_t MainWindow::MydwordTowchar_t(DWORD i)
{
wchar_t ch = L'0';
if(i<10)
{
ch = QString("%1").arg(i).utf16()[0];
}
return ch;
}
void MainWindow::AddusbToChoice(wchar_t letter)
{
char ch = letter;
//int n = GetPhysicalDriveFromPartitionLetter(letter);
int n = GetPhysicalDriveNumber(ch);
if(n > 0 && n != m_sysdiskNumber)
{
QString temp = QString("%1").arg(QChar(letter))+":\\";
ui->comboBox_emmc->addItem(temp);
ui->comboBox_emmc1->addItem(temp);
}
}
void MainWindow::DelusbToChoice(wchar_t letter)
{
int index = ui->comboBox_emmc->findText(QString("%1:\\").arg(QChar(letter)));
ui->comboBox_emmc->removeItem(index);
ui->comboBox_emmc1->removeItem(index);
ui->comboBox_emmc->setCurrentIndex(-1);
ui->comboBox_emmc1->setCurrentIndex(-1);
}
void MainWindow::WriteToFile(const char* fileName, const char* str)
{
std::filebuf fb;
if (fb.open(fileName, std::ios::out) == NULL)
{
my_log("选择磁盘失败,请重新扫描,并选择相应磁盘.");
return;
}
std::ostream os(&fb);
os << str;
fb.close();
}
bool MainWindow::nativeEvent(const QByteArray &eventType, void *message, long *result)
{
Q_UNUSED(eventType);
*result = 0;
MSG* msg = reinterpret_cast<MSG*>(message);
int msgType = msg->message;
if (msgType == WM_DEVICECHANGE) {
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)msg->lParam;
switch (msg->wParam)
{
case DBT_DEVICETYPESPECIFIC:
{
qDebug() << "DBT_DEVICETYPESPECIFIC ";
break;
}
case DBT_DEVICEARRIVAL:
if (lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if (lpdbv->dbcv_flags == 0)
{
// 插入U盘,此处可以做你想做的事
// lpdbv->dbcv_unitmask
//即盘符标志位,1bit,0为A,1为B,10为C,11为D…以此类推
qDebug() << "USB_insert";
QString USBDisk = QString(FirstDriveFromMask(lpdbv->dbcv_unitmask));
m_seldiskNumber = GetPhysicalDriveFromPartitionLetter(USBDisk.utf16()[0]);
AddusbToChoice(USBDisk.utf16()[0]);
ui->comboBox_emmc->setCurrentText(USBDisk+":\\");
ui->comboBox_emmc1->setCurrentText(USBDisk+":\\");
my_log("移动设备:"+USBDisk+"盘插入");
my_log1("移动设备:"+USBDisk+"盘插入");
//qDebug() << "USB_Arrived and The USBDisk is: "<<USBDisk;
m_pathDriver = USBDisk + ":\\";
m_pathDriver1 = m_pathDriver;
DWORD driveSize = GetTotalSector(m_pathDriver);
driveSize = driveSize/2/1024;
if (driveSize <= 0 || driveSize > 240800)
{
MessageBox(NULL,TEXT("获取磁盘大小失败!!"), TEXT("错误"), NULL);
}
else
{
QString uint = driveSize > 1024 ? "GB" : "MB";
float size = driveSize >= 1024 ? float(driveSize)/1024.0f : driveSize;
m_strDriveSize = QString::number(size,'f',2) + uint;
ui->lineEdit_size->setText(m_strDriveSize);
ui->lineEdit_size1->setText(m_strDriveSize);
}
}
}
//qDebug() << "DBT_DEVICEARRIVAL";
break;
case DBT_DEVICEREMOVECOMPLETE:
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
if (lpdbv -> dbcv_flags == 0)
{
qDebug() << "USB_delete";
QString USBDisk = QString(FirstDriveFromMask(lpdbv->dbcv_unitmask));
DelusbToChoice(USBDisk.utf16()[0]);
m_pathDriver = "";
m_pathDriver1 = m_pathDriver;
my_log("移动设备:"+USBDisk+"盘已拔出");
my_log1("移动设备:"+USBDisk+"盘已拔出");
ui->comboBox_emmc->setCurrentText(USBDisk+":\\盘已拔出");
ui->comboBox_emmc1->setCurrentText(USBDisk+":\\盘已拔出");
ui->lineEdit_size->setText("");
ui->lineEdit_size1->setText("");
}
}
break;
}
}
return false;
}
void MainWindow::on_pushButton_start_clicked()
{
if(m_isWritting||m_isFormating )
{
MessageBox(NULL,TEXT("正在进行烧录或格式化\n中,请稍后再行操作!!"), TEXT("提示"), NULL);
return;
}
char *pMBRBuffer = NULL;
wchar_t temp[6];
QString strMBR;
if (!ChangeStringDriveNameToDriveNumber())
{
MessageBox(NULL,TEXT("请选择TF卡!!"),TEXT("错误"),NULL);
return ;
}
ui->progressBar->setRange(0,100);
progress_bar = 0;
ui->progressBar->setValue(progress_bar);
if( (m_nPhysicalNumber = GetPhysicalDriveNumber( char((char)(m_dwDriveNumber)+97) )) == -1)
{
MessageBox(NULL,TEXT("非TF卡或TF卡不可读!!"),TEXT("错误"),NULL);
return ;
}
pMBRBuffer = ReadSector(0,1); // read MBR sector.
if (pMBRBuffer == NULL )
{
MessageBox(NULL,TEXT("读取扇区失败,请先尝试\n用分区工具进行分区!! "),TEXT("错误"),NULL);
return ;
}
else
{
temp[0] = pMBRBuffer[0x52];
temp[1] = pMBRBuffer[0x53];
temp[2] = pMBRBuffer[0x54];
temp[3] = pMBRBuffer[0x55];
temp[4] = pMBRBuffer[0x56];
temp[5] = '\0';
strMBR = QString::fromWCharArray(temp);
if ( strMBR != "FAT32")
{
MessageBox(NULL,TEXT("磁盘不是FAT32格式!!"),TEXT("错误"),NULL);
return ;
}
}
if (sdcard_strFilePath.isEmpty())
{
MessageBox(NULL,TEXT("未选择sdcard系统\n包,请重新选择!!"), TEXT("错误"), NULL);
return;
}
progress_bar+=10;
ui->progressBar->setValue(progress_bar);
if(!m_workThread)
{
m_workThread = new Thread(this);
connect(m_workThread,&Thread::started,[this]{
m_isWritting = true;
});
connect(m_workThread,&Thread::finished,[this]{
disconnect(m_workThread,SIGNAL(msgPrgress(int)),this,SLOT(DealThreadMsgInt(int)));
disconnect(m_workThread,SIGNAL(msgPrgress(QString)),this,SLOT(DealThreadMsgQString(QString)));
m_isWritting = false;
m_workThread->deleteLater();
m_workThread = nullptr;
});
connect(m_workThread,SIGNAL(msgPrgress(int)),this,SLOT(DealThreadMsgInt(int)));
connect(m_workThread,SIGNAL(msgPrgress(QString)),this,SLOT(DealThreadMsgQString(QString)));
m_workThread->start();
}
}
void MainWindow::on_pushButton_format_clicked()
{
if(m_isWritting||m_isFormating )
{
MessageBox(NULL,TEXT("正在进行烧录或格式化\n中,请稍后再行操作!!"), TEXT("提示"), NULL);
goto END;
}
if(ui->comboBox_emmc1->currentText().isEmpty() || ui->lineEdit_size1->text().isEmpty())
{
MessageBox(NULL,TEXT("请选择一个磁盘开始格式化!!"), TEXT("错误"), NULL);
goto END;
}
if (m_seldiskNumber > 9 && m_seldiskNumber <= 0)
{
MessageBox(NULL,TEXT("磁盘数过多(不可多于9个)或\n选择了系统所在盘!!"), TEXT("错误"), NULL);
goto END;
}
m_isFormating = true;
if (DestroyDisk(m_seldiskNumber) < 0)
{
MessageBox(NULL,TEXT("删除磁盘分区失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
goto END;
}
if (!CreateDisk(m_seldiskNumber, 1))
{
MessageBox(NULL,TEXT("创建分区失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
goto END;
}
if(FormatVolume(m_pathDriver1.utf16()[0])< 0)
{
MessageBox(NULL,TEXT("格式化分区失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
goto END;
}
my_log1("已分区格式化完成!!");
MessageBox(NULL,TEXT("一键格式化完成!!"), TEXT("提示"), NULL);
END:
m_isFormating = FALSE;
return;
}
void MainWindow::on_pushButton_sdcard_clicked()
{
sdcard_strFilePath = QFileDialog::QFileDialog::getOpenFileName(this, tr("Open File"),
"./",
tr("sdcard(*.sdcard);;All(*.*)"));
ui->lineEdit_sdcard->setText(sdcard_strFilePath);
}
void MainWindow::on_pushButton_fub_clicked()
{
fub_strFilePath = QFileDialog::getOpenFileName(this, tr("Open File"),
"./",
tr("fub(*.fub);;All(*.*)"));
int index =fub_strFilePath.lastIndexOf('/');
fub_strFileName = fub_strFilePath.right(fub_strFilePath.length()-index-1);
ui->lineEdit_fub->setText(fub_strFilePath);
}
void MainWindow::on_radioButton_s32v_clicked()
{
Sdcard_StartWriteSector = 8;
my_log("你已选择平台 S32V.");
}
void MainWindow::on_radioButton_imx6_clicked()
{
Sdcard_StartWriteSector = 2;
my_log("你已选择平台 IMX6.");
}
void MainWindow::on_textBrowser_log_textChanged()
{
ui->textBrowser_log->moveCursor(QTextCursor::End);
}
void MainWindow::on_textBrowser_log1_textChanged()
{
ui->textBrowser_log1->moveCursor(QTextCursor::End);
}
void MainWindow::on_comboBox_emmc_currentIndexChanged(const QString &arg1)
{
m_pathDriver = arg1;
if(m_pathDriver.isEmpty()) return;
ChangeStringDriveNameToDriveNumber();
if( (m_nPhysicalNumber = GetPhysicalDriveNumber( char((char)(m_dwDriveNumber)+97) )) == -1)
{
MessageBox(NULL,TEXT("非TF卡或TF卡不可读!!"),TEXT("错误"),NULL);
ui->comboBox_emmc->setCurrentText("");
return;
}
DWORD driveSize = GetTotalSector(m_pathDriver);
driveSize = driveSize/2/1024;
if (driveSize <= 0 || driveSize > 240800)
{
MessageBox(NULL,TEXT("获取磁盘大小失败!!"), TEXT("错误"), NULL);
ui->comboBox_emmc->setCurrentText("");
return;
}
else
{
QString uint = driveSize > 1024 ? " GB" : " MB";
float size = driveSize >= 1024 ? float(driveSize)/1024.0f : driveSize;
m_strDriveSize = QString::number(size,'f',2) + uint;
ui->lineEdit_size->setText(m_strDriveSize);
my_log("你已选择"+m_pathDriver+"总大小 "+ m_strDriveSize);
}
}
void MainWindow::on_comboBox_emmc1_currentIndexChanged(const QString &arg1)
{
m_pathDriver1 = arg1;
if(m_pathDriver1.isEmpty()) return;
m_seldiskNumber = GetPhysicalDriveFromPartitionLetter(m_pathDriver1.utf16()[0]);
if (m_seldiskNumber == -1)
{
MessageBox(NULL,TEXT("获取磁盘失败,请确认此盘是\n否存在或以管理员权限重新\n运行程序!!"), TEXT("错误"), NULL);
ui->comboBox_emmc1->setCurrentText("");
return;
}
else if (m_seldiskNumber == m_sysdiskNumber)
{
MessageBox(NULL,TEXT("系统所在的本地盘不能作\n为格式化对象,请重新选择!!"), TEXT("错误"), NULL);
ui->comboBox_emmc1->setCurrentText("");
return;
}
DWORD driveSize = GetTotalSector(m_pathDriver1);
driveSize = driveSize/2/1024;
if (driveSize <= 0 || driveSize > 240800)
{
MessageBox(NULL,TEXT("获取磁盘大小失败!!"), TEXT("错误"), NULL);
return;
}
else
{
QString uint = driveSize > 1024 ? " GB" : " MB";
float size = driveSize >= 1024 ? float(driveSize)/1024.0f : driveSize;
m_strDriveSize1 = QString::number(size,'f',2) + uint;
ui->lineEdit_size1->setText(m_strDriveSize1);
my_log1("你已选择"+m_pathDriver1+"总大小 "+ m_strDriveSize1);
}
}
void Thread::run()
{
int count_succeed = 0;
int count_expect = 0;
wchar_t sectors[9];
count_expect++;
QFile s_sdcardFile(pm->sdcard_strFilePath);
if(!s_sdcardFile.open(QIODevice::ReadOnly))
{
MessageBox(NULL,TEXT("无法打开sdcard文件,请以管理员\n权限重新运行程序!!"), L"错误", NULL);
_exit(-1);
}
pm->progress_bar += 20; //30
emit msgPrgress(pm->progress_bar);
Sleep(1000);
pm->m_dwStartWriteSector = pm->Sdcard_StartWriteSector;
QByteArray s_pbWriteBuffer = s_sdcardFile.readAll();
if (s_pbWriteBuffer.size()<=1)
{
MessageBox(NULL,TEXT("读取文件失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
_exit(-1);
}
pm->progress_bar += 10; //40
emit msgPrgress(pm->progress_bar);
Sleep(1000);
QString m_strFromSector,m_strToSector;
swprintf(sectors, 9, L"%d", pm->m_dwStartWriteSector);
m_strFromSector = QString::fromWCharArray(sectors);
swprintf(sectors, 9, L"%d", pm->m_dwStartWriteSector + (s_pbWriteBuffer.size() / 512) + 1);
m_strToSector = QString::fromWCharArray(sectors);
emit msgPrgress("烧写 sdcard :" + m_strFromSector + " 到 " + m_strToSector);
if (!pm->WriteSector(pm->m_dwStartWriteSector, s_pbWriteBuffer.size() / 512, s_pbWriteBuffer.data()))
{
MessageBox(NULL,TEXT("sdcard烧写失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
_exit(-1);
}
s_sdcardFile.close();
emit msgPrgress("sdcard烧写完成 !");
count_succeed++;
pm->progress_bar += 20; //60
emit msgPrgress(pm->progress_bar);
Sleep(1000);
if (!pm->fub_strFilePath.isEmpty())
{
count_expect++;
QFile f_fubFile(pm->fub_strFilePath);
if (!f_fubFile.open(QIODevice::ReadOnly))
{
MessageBox(NULL,TEXT("无法打开Fub文件,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
_exit(-1);
}
pm->progress_bar += 10; //70
emit msgPrgress(pm->progress_bar);
Sleep(500);
s_pbWriteBuffer.clear();
s_pbWriteBuffer = f_fubFile.readAll();
if (s_pbWriteBuffer.size()<=1)
{
MessageBox(NULL,TEXT("读取文件失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
_exit(-1);
}
pm->progress_bar += 10; //80
emit msgPrgress(pm->progress_bar);
Sleep(500);
//wirte fub to autofuture
QDir autofuturedir;
QString csPath;
csPath = pm->m_pathDriver + "autofuture";
if (!autofuturedir.exists(csPath))
{
autofuturedir.mkpath(csPath);//不存在则创建
}
csPath += "\\"; csPath += pm->fub_strFileName;
emit msgPrgress( "烧写fub文件到autofuture目录下 !");
QFile MyWriteFile(csPath);
if (!MyWriteFile.open(QIODevice::WriteOnly|QIODevice::Truncate))
{
MessageBox(NULL,TEXT("无法生成Fub文件,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
_exit(-1);
}
MyWriteFile.write(s_pbWriteBuffer.data(), s_pbWriteBuffer.size());
MyWriteFile.close();
f_fubFile.close();
emit msgPrgress( "fub文件烧写完成 !");
count_succeed++;
pm->progress_bar += 20; //100
emit msgPrgress(pm->progress_bar);
}
else
{
pm->progress_bar += 40; //100
emit msgPrgress(pm->progress_bar);
}
if (count_expect == count_succeed){
MessageBox(NULL,TEXT("恭喜,烧写成功!!"), TEXT("提示"), NULL);
}
else{
MessageBox(NULL,TEXT("烧写失败,请以管理员\n权限重新运行程序!!"), TEXT("错误"), NULL);
_exit(-1);
}
}
来源:oschina
链接:https://my.oschina.net/urlove/blog/4314738