From 37c27494b18918a147c8bb687f171600f0bebe1d Mon Sep 17 00:00:00 2001 From: Liu Zheng Date: Fri, 6 Sep 2024 16:34:55 +0800 Subject: [PATCH 1/3] fix: bash command hardening bash command hardening Log: bash command hardening Task: https://pms.uniontech.com/task-view-362031.html --- src/libdbm/util/utils.cpp | 65 ++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/libdbm/util/utils.cpp b/src/libdbm/util/utils.cpp index c01a0a05..d133d592 100644 --- a/src/libdbm/util/utils.cpp +++ b/src/libdbm/util/utils.cpp @@ -20,7 +20,7 @@ #include #ifdef Q_OS_WIN32 -#include +# include #endif static void initQRC() @@ -35,13 +35,13 @@ static void initQRC() namespace Utils { -bool isUft8(const QByteArray& byArr) +bool isUft8(const QByteArray &byArr) { qDebug() << "Checking UTF-8 encoding"; unsigned int nBytes = 0;//UFT8可用1-6个字节编码,ASCII用一个字节 bool bAllAscii = true; - for (int i = 0; i < byArr.length(); ++i) { + for (int i = 0; i < byArr.length(); ++i) { unsigned char chr = static_cast(byArr.at(i)); //ASCII码高位为0 @@ -54,17 +54,13 @@ bool isUft8(const QByteArray& byArr) if (chr >= 0x80) { if (chr >= 0xFC && chr <= 0xFD) { nBytes = 6; - } - else if (chr >= 0xF8) { + } else if (chr >= 0xF8) { nBytes = 5; - } - else if (chr >= 0xF0) { + } else if (chr >= 0xF0) { nBytes = 4; - } - else if (chr >= 0xE0) { + } else if (chr >= 0xE0) { nBytes = 3; - } - else if (chr >= 0xC0) { + } else if (chr >= 0xC0) { nBytes = 2; } else { @@ -74,8 +70,7 @@ bool isUft8(const QByteArray& byArr) nBytes--; } - } - else { + } else { if ((chr & 0xC0) != 0x80) { qDebug() << "Invalid UTF-8 continuation byte"; return false; @@ -90,20 +85,20 @@ bool isUft8(const QByteArray& byArr) return false; } - if (bAllAscii) { //如果全部都是ASCII, 也是UTF8 + if (bAllAscii) { //如果全部都是ASCII, 也是UTF8 return true; } return true; } -bool isGBK(const QByteArray& byArr) +bool isGBK(const QByteArray &byArr) { qDebug() << "Checking GBK encoding"; unsigned int nBytes = 0; bool bAllAscii = true; - for (int i = 0; i < byArr.length(); ++i) { + for (int i = 0; i < byArr.length(); ++i) { unsigned char chr = static_cast(byArr.at(i)); //ASCII码高位为0 @@ -139,7 +134,7 @@ bool isGBK(const QByteArray& byArr) return false; } - if (bAllAscii){ //如果全部都是ASCII, 也是GBK + if (bAllAscii) { //如果全部都是ASCII, 也是GBK return true; } @@ -160,16 +155,16 @@ void loadTranslate() QString tnapplang; QString tnappcoun; QString clangcode = ""; - QStringList allappargs = qApp->arguments(); - QList > oppairs; + QStringList allappargs = qApp->arguments(); + QList> oppairs; for (QList::const_iterator i = allappargs.constBegin(); i < allappargs.constEnd(); ++i) { if (i->count('=') == 1) { - oppairs.append(QPair (i->section('=', 0, 0).simplified(), i->section('=', 1, 1).simplified())); + oppairs.append(QPair(i->section('=', 0, 0).simplified(), i->section('=', 1, 1).simplified())); } } - for (QList >::const_iterator i = oppairs.constBegin(); i < oppairs.constEnd(); ++i) { + for (QList>::const_iterator i = oppairs.constBegin(); i < oppairs.constEnd(); ++i) { if (i->first.contains("lang", Qt::CaseInsensitive)) { clangcode = i->second; tnapplang = clangcode.left(2); @@ -269,7 +264,7 @@ void ClearTargetDev(const QString &targetPath) QMap CommandDfParse() { QProcess df; - df.start("df", QStringList{"-k", "--output=source,used,avail"}); + df.start("df", QStringList { "-k", "--output=source,used,avail" }); df.waitForFinished(-1); QString dfout = df.readAll(); @@ -287,7 +282,7 @@ QMap CommandDfParse() continue; } devInfo.used = static_cast(infos.at(1).toInt() / 1024); - devInfo.total = static_cast((infos.at(2).toInt() + infos.at(1).toInt()) / 1024) ; + devInfo.total = static_cast((infos.at(2).toInt() + infos.at(1).toInt()) / 1024); qDebug() << "device path" << devInfo.path << "used: " << devInfo.used << "total: " << devInfo.total; deviceInfos.insert(devInfo.path, devInfo); } @@ -324,7 +319,7 @@ static QByteArray unescapeLimited(const QString &str) QMap CommandLsblkParse() { QProcess lsblk; - lsblk.start("lsblk", QStringList{"-b", "-p", "-P", "-o", "name,label,size,uuid,fstype,type"}); + lsblk.start("lsblk", QStringList { "-b", "-p", "-P", "-o", "name,label,size,uuid,fstype,type" }); lsblk.waitForFinished(-1); QString line; DeviceInfo info; @@ -360,8 +355,7 @@ QMap CommandLsblkParse() if (!type.compare("disk")) { diskDevPath = info.path; isPart = false; - } - else if (!type.compare("part")){ + } else if (!type.compare("part")) { isPart = true; } else { diskDevPath = ""; @@ -376,8 +370,7 @@ QMap CommandLsblkParse() #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (isUft8(byArr)) { strLabel = QTextCodec::codecForName("UTF-8")->toUnicode(byArr); - } - else if(isGBK(byArr)) { + } else if (isGBK(byArr)) { strLabel = QTextCodec::codecForName("GBK")->toUnicode(byArr); } #else @@ -402,20 +395,19 @@ QMap CommandLsblkParse() info.isDisk = false; info.strDev = diskDevPath; deviceInfos[diskDevPath].children.insert(info.path, info); - } else { // 否则就是 part, 如sdb。 + } else { // 否则就是 part, 如sdb。 info.isDisk = true; info.strDev = ""; deviceInfos.insert(info.path, info); // 记录当前是part的情况 currentPartPath = info.path; } - } while(true); + } while (true); return deviceInfos; } #endif - bool CheckInstallDisk(const QString &targetDev) { qDebug() << "Checking installation disk:" << targetDev; @@ -453,7 +445,7 @@ bool isUsbDisk(const QString &dev) { qDebug() << "Checking if device is USB:" << dev; QString out = XSys::FS::TmpFilePath("diskutil_isusb_out"); - XSys::SynExec("bash", QString("-c \" diskutil info %1 > \"%2\" \" ").arg(dev).arg(out)); + XSys::SynExec("diskutil", QString(" \" info %1 > \"%2\" \" ").arg(dev).arg(out)); QFile outfile(out); outfile.open(QIODevice::ReadOnly); QString info = outfile.readAll(); @@ -473,9 +465,7 @@ QList ListUsbDrives() for (int i = 0; i < extdrivesList.size(); ++i) { QString deviceLetter = extdrivesList.at(i).path().toUpper(); - if (QDir::toNativeSeparators(deviceLetter) != QDir::toNativeSeparators(QDir::rootPath().toUpper()) && !QDir::toNativeSeparators(deviceLetter) - .contains("A:") && !QDir::toNativeSeparators(deviceLetter) - .contains("B:")) { + if (QDir::toNativeSeparators(deviceLetter) != QDir::toNativeSeparators(QDir::rootPath().toUpper()) && !QDir::toNativeSeparators(deviceLetter).contains("A:") && !QDir::toNativeSeparators(deviceLetter).contains("B:")) { if (GetDriveType(LPWSTR(deviceLetter.utf16())) == 2) { qDebug() << "Found removable drive:" << deviceLetter; DeviceInfo info; @@ -521,8 +511,7 @@ QList ListUsbDrives() if (partitionInfo.fstype != "vfat") { needformat = true; - } - else { + } else { needformat = false; } @@ -548,7 +537,7 @@ QList ListUsbDrives() #ifdef Q_OS_MAC QStringList fulldrivelist; QString out = XSys::FS::TmpFilePath("diskutil_out"); - XSys::SynExec("bash", QString("-c \" diskutil list > \"%1\" \" ").arg(out)); + XSys::SynExec("diskutil", QString(" \" list > \"%1\" \" ").arg(out)); QFile outfile(out); outfile.open(QIODevice::ReadOnly); QString diskutilList = outfile.readAll(); From 0f377d5d46285a73941083cee4b9ef5dd9340f55 Mon Sep 17 00:00:00 2001 From: xust Date: Fri, 7 Nov 2025 16:09:28 +0800 Subject: [PATCH 2/3] feat: Support creating bootable USB drives from unpartitioned USB disks - Add automatic partition creation for unpartitioned USB disks using fdisk - Optimize df command to exclude network filesystems (NFS, CIFS, SMBFS, SSHFS, FTPFS, DAVFS) - Improve device scanning logic to skip network-related devices Log: Enable creating bootable USB drives from unpartitioned USB disks and improve disk querying efficiency Bug: https://pms.uniontech.com/bug-view-338629.html --- src/libdbm/installer/qtbaseinstaller.cpp | 33 ++++- src/libdbm/util/deviceinfo.h | 6 +- src/libdbm/util/utils.cpp | 139 ++++++++++++++----- src/vendor/src/libxsys/DiskUtil/DiskUtil.cpp | 58 +++++++- src/vendor/src/libxsys/DiskUtil/DiskUtil.h | 1 + 5 files changed, 195 insertions(+), 42 deletions(-) diff --git a/src/libdbm/installer/qtbaseinstaller.cpp b/src/libdbm/installer/qtbaseinstaller.cpp index fb79faef..8359ae35 100644 --- a/src/libdbm/installer/qtbaseinstaller.cpp +++ b/src/libdbm/installer/qtbaseinstaller.cpp @@ -404,8 +404,37 @@ bool QtBaseInstaller::formatUsb() } if (m_bFormat) { - if (!XSys::DiskUtil::FormatPartion(m_strPartionName)) { - qCritical() << "Failed to format partition"; + QString targetDev = m_strPartionName; + + // 检查是否是 disk 节点(没有分区号) + // disk 节点如:/dev/sdb + // partition 节点如:/dev/sdb1 + bool isDisk = true; + for (int i = targetDev.length() - 1; i >= 0; i--) { + if (targetDev[i].isDigit()) { + isDisk = false; + break; + } + if (targetDev[i] == '/') { + break; + } + } + + // 如果是 disk 节点,需要先创建分区 + if (isDisk) { + qDebug() << "Detected disk device" << targetDev << "without partition, creating partition..."; + if (!XSys::DiskUtil::CreatePartition(targetDev)) { + qCritical() << "Failed to create partition for" << targetDev; + return false; + } + // 使用新创建的分区 + targetDev = targetDev + "1"; + m_strPartionName = targetDev; + qDebug() << "Partition created successfully, using" << targetDev; + } + + // 格式化分区 + if (!XSys::DiskUtil::FormatPartion(targetDev)) { return false; } qInfo() << "Partition formatted successfully"; diff --git a/src/libdbm/util/deviceinfo.h b/src/libdbm/util/deviceinfo.h index f39f381c..faabc321 100644 --- a/src/libdbm/util/deviceinfo.h +++ b/src/libdbm/util/deviceinfo.h @@ -12,14 +12,14 @@ class DeviceInfo { public: DeviceInfo() {} - DeviceInfo(const QString &path, quint32 used, quint32 total, const QString &label) + DeviceInfo(const QString &path, quint64 used, quint64 total, const QString &label) : path(path), used(used), total(total), label(label) { } QString path = ""; - quint32 used = 0; - quint32 total = 0; + quint64 used = 0; + quint64 total = 0; QString label = QObject::tr("Removable Disk"); QString uuid = ""; QString fstype = ""; diff --git a/src/libdbm/util/utils.cpp b/src/libdbm/util/utils.cpp index d133d592..d95d7d64 100644 --- a/src/libdbm/util/utils.cpp +++ b/src/libdbm/util/utils.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -263,8 +264,15 @@ void ClearTargetDev(const QString &targetPath) #ifdef Q_OS_UNIX QMap CommandDfParse() { + qDebug() << "Step 2: Execute df command to get disk usage"; QProcess df; - df.start("df", QStringList { "-k", "--output=source,used,avail" }); + // 排除网络文件系统类型,避免因为远程挂载卡死 + df.start("df", QStringList{"-k", "--output=source,used,avail", + "-x", "nfs", + "-x", "cifs", + "-x", "smbfs", + "-x", "sshfs", + "-x", "ftpfs"}); df.waitForFinished(-1); QString dfout = df.readAll(); @@ -286,6 +294,7 @@ QMap CommandDfParse() qDebug() << "device path" << devInfo.path << "used: " << devInfo.used << "total: " << devInfo.total; deviceInfos.insert(devInfo.path, devInfo); } + qDebug() << "Step 2 completed: df command finished, got" << deviceInfos.size() << "disk info"; return deviceInfos; } @@ -318,15 +327,18 @@ static QByteArray unescapeLimited(const QString &str) QMap CommandLsblkParse() { + qDebug() << "Step 3: Execute lsblk command to get device details"; QProcess lsblk; lsblk.start("lsblk", QStringList { "-b", "-p", "-P", "-o", "name,label,size,uuid,fstype,type" }); lsblk.waitForFinished(-1); + qDebug() << "Step 3 completed: lsblk command finished"; QString line; DeviceInfo info; QString diskDevPath; QMap deviceInfos; // currentPartPath用记录当前的磁盘设备,如sdb QString currentPartPath = ""; + int deviceCount = 0; do { bool isPart = false; line = QString::fromUtf8(lsblk.readLine()); @@ -335,10 +347,12 @@ QMap CommandLsblkParse() QString type; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - QRegExp reg("NAME=\"(.*)\" LABEL=\"(.*)\" SIZE=\"(.*)\" UUID=\"(.*)\" FSTYPE=\"(.*)\" TYPE=\"(.*)\""); + QRegExp reg("NAME=\"(.*)\" LABEL=\"(.*)\" SIZE=\"(\\d+)\" UUID=\"(.*)\" FSTYPE=\"(.*)\" TYPE=\"(.*)\""); if (reg.indexIn(line) >= 0) { + deviceCount++; info.path = reg.cap(1); info.label = reg.cap(2); + info.total = reg.cap(3).toLongLong() * 1024 / 1024; // MB info.uuid = reg.cap(4); info.fstype = reg.cap(5); type = reg.cap(6); @@ -352,6 +366,8 @@ QMap CommandLsblkParse() info.fstype = match.captured(5); type = match.captured(6); #endif + qDebug() << "Parse device" << deviceCount << ":" << info.path << "Type:" << type; + if (!type.compare("disk")) { diskDevPath = info.path; isPart = false; @@ -394,15 +410,18 @@ QMap CommandLsblkParse() if (isPart && !diskDevPath.isEmpty() && (info.path.left(currentPartPath.length()) == currentPartPath)) { info.isDisk = false; info.strDev = diskDevPath; + qDebug() << " Add partition to device" << diskDevPath << ":" << info.path; deviceInfos[diskDevPath].children.insert(info.path, info); } else { // 否则就是 part, 如sdb。 info.isDisk = true; info.strDev = ""; + qDebug() << " Add disk device:" << info.path; deviceInfos.insert(info.path, info); // 记录当前是part的情况 currentPartPath = info.path; } - } while (true); + } while(true); + qDebug() << "Step 2 completed: Parse lsblk output finished, total" << deviceCount << "devices parsed"; return deviceInfos; } @@ -459,6 +478,7 @@ bool isUsbDisk(const QString &dev) QList ListUsbDrives() { qDebug() << "Listing USB drives"; + qDebug() << "Start getting device list"; QList deviceList; #ifdef Q_OS_WIN32 QFileInfoList extdrivesList = QDir::drives(); @@ -479,59 +499,102 @@ QList ListUsbDrives() #ifdef Q_OS_LINUX QDir devlstdir("/dev/disk/by-id/"); QFileInfoList usbfileinfoL = devlstdir.entryInfoList(QDir::NoDotAndDotDot | QDir::Files); + qDebug() << "Step 1: Scan /dev/disk/by-id/ directory, found" << usbfileinfoL.size() << "device files"; + QMap dfDeviceInfos = CommandDfParse(); QMap lsblkDeviceInfos = CommandLsblkParse(); QMap removeDevice; for (int i = 0; i < usbfileinfoL.size(); ++i) { -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - if (usbfileinfoL.at(i).fileName().contains(QRegExp("^usb-\\S{1,}$")) || usbfileinfoL.at(i).fileName().contains(QRegExp("^mmc-\\S{1,}$"))) { -#else - if (usbfileinfoL.at(i).fileName().contains(QRegularExpression("^usb-\\S{1,}$")) || usbfileinfoL.at(i).fileName().contains(QRegularExpression("^mmc-\\S{1,}$"))) { -#endif - QString path = usbfileinfoL.at(i).canonicalFilePath(); - qDebug() << "Found USB/MMC device:" << path; - removeDevice.insert(path, usbfileinfoL.at(i).fileName()); + QString fileName = usbfileinfoL.at(i).fileName(); + QString filePath = usbfileinfoL.at(i).canonicalFilePath(); + + // 过滤USB和MMC设备,但排除网络相关设备 + bool isUsbOrMmc = fileName.contains(QRegExp("^usb-\\S{1,}$")) || fileName.contains(QRegExp("^mmc-\\S{1,}$")); + bool isNetwork = fileName.contains(QRegExp("nfs-|cifs-|smbfs-|sshfs-|ftpfs-|davfs-")); + + if (isUsbOrMmc && !isNetwork) { + removeDevice.insert(filePath, fileName); } } + qDebug() << "Step 4: Filter devices - Found" << removeDevice.size() << "USB/MMC devices from" << usbfileinfoL.size() << "total devices"; + + for (auto it = removeDevice.begin(); it != removeDevice.end(); ++it) { + qDebug() << " Device path:" << it.key() << "Device name:" << it.value(); + } + + qDebug() << "Step 5: Traverse device partitions and filter eligible devices"; + int processedCount = 0; + int validCount = 0; for (auto devicePath : lsblkDeviceInfos.keys()) { + processedCount++; if (!removeDevice.contains(devicePath)) { continue; } + qDebug() << "Processing device" << processedCount << ":" << devicePath << "with" << lsblkDeviceInfos.value(devicePath).children.size() << "partitions"; // find first partition QString strDiskName = devicePath; DeviceInfo diskinfo = lsblkDeviceInfos.value(devicePath); QStringList partitionNames = diskinfo.children.keys(); - foreach (QString strPartionName, partitionNames) { - bool needformat = true; - DeviceInfo partitionInfo = diskinfo.children.value(strPartionName); + if (partitionNames.isEmpty()) { + // 设备没有分区,作为整个磁盘展示 + qDebug() << " Device" << devicePath << "has no partitions, showing as whole disk"; + DeviceInfo wholeDevice = diskinfo; + wholeDevice.isDisk = true; + wholeDevice.strDev = ""; + wholeDevice.label = wholeDevice.label.isEmpty() ? QObject::tr("Removable disk") : wholeDevice.label; + wholeDevice.needFormat = (wholeDevice.fstype != "vfat"); + + DeviceInfo dfinfo = dfDeviceInfos.value(devicePath); + if (wholeDevice.total == 0) + wholeDevice.total = dfinfo.total; + wholeDevice.used = dfinfo.used; + + deviceList.push_back(wholeDevice); + validCount++; + qDebug() << " Added to device list (item" << validCount << "):" << wholeDevice.path + << "Label:" << wholeDevice.label + << "Size:" << wholeDevice.total << "MB" + << "Need format:" << wholeDevice.needFormat; + } else { + // 设备有分区,遍历分区 + foreach (QString strPartionName, partitionNames) { + bool needformat = true; + DeviceInfo partitionInfo = diskinfo.children.value(strPartionName); - if (partitionInfo.fstype != "vfat") { - needformat = true; - } else { - needformat = false; - } + qDebug() << " Check partition" << strPartionName << "filesystem:" << partitionInfo.fstype; - DeviceInfo dfinfo = dfDeviceInfos.value(strPartionName); - if (partitionInfo.label.isEmpty()) { - partitionInfo.label = partitionInfo.path; - } + if (partitionInfo.fstype != "vfat") { + needformat = true; + qDebug() << " Filesystem is not vfat, need format"; + } + else { + needformat = false; + qDebug() << " Filesystem is vfat, no need to format"; + } + + DeviceInfo dfinfo = dfDeviceInfos.value(strPartionName); + if (partitionInfo.label.isEmpty()) { + partitionInfo.label = partitionInfo.path; + } - partitionInfo.used = dfinfo.used; - partitionInfo.total = dfinfo.total; - partitionInfo.target = dfinfo.target; - partitionInfo.needFormat = needformat; - deviceList.push_back(partitionInfo); - qDebug() << "Partition info - Path:" << partitionInfo.path - << "Used:" << partitionInfo.used - << "Total:" << partitionInfo.total - << "Target:" << partitionInfo.target - << "Need format:" << partitionInfo.needFormat; + partitionInfo.used = dfinfo.used; + partitionInfo.total = dfinfo.total; + partitionInfo.target = dfinfo.target; + partitionInfo.needFormat = needformat; + deviceList.push_back(partitionInfo); + validCount++; + qDebug() << " Added to device list (item" << validCount << "):" << partitionInfo.path + << "Size:" << partitionInfo.total << "MB" + << "Need format:" << needformat; + qDebug() << partitionInfo.path << partitionInfo.used << partitionInfo.total << partitionInfo.target << partitionInfo.needFormat; + } } } + qDebug() << "Step 5 completed: Processed" << processedCount << "devices, added" << validCount << "partitions to list"; #endif #ifdef Q_OS_MAC @@ -560,7 +623,15 @@ QList ListUsbDrives() outfile.close(); outfile.remove(); #endif - qInfo() << "Found" << deviceList.size() << "USB devices"; + qDebug() << "Get device list completed: Found" << deviceList.size() << "available devices"; + for (int i = 0; i < deviceList.size(); ++i) { + qDebug() << " Device" << (i+1) << ":" << deviceList.at(i).path + << "Label:" << deviceList.at(i).label + << "Filesystem:" << deviceList.at(i).fstype + << "Size:" << deviceList.at(i).total << "MB" + << "Used:" << deviceList.at(i).used << "MB" + << "Need format:" << deviceList.at(i).needFormat; + } return deviceList; } diff --git a/src/vendor/src/libxsys/DiskUtil/DiskUtil.cpp b/src/vendor/src/libxsys/DiskUtil/DiskUtil.cpp index 3ef8280b..67c677ea 100644 --- a/src/vendor/src/libxsys/DiskUtil/DiskUtil.cpp +++ b/src/vendor/src/libxsys/DiskUtil/DiskUtil.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include #ifdef Q_OS_WIN32 @@ -329,7 +331,8 @@ const QString MountPoint(const QString &targetDev) udev /dev tmpfs /run */ - XSys::Result ret = XSys::SynExec("df", "--output=source,target"); + // 排除网络文件系统类型,避免因为远程挂载导致 df 卡死 + XSys::Result ret = XSys::SynExec("df", "--output=source,target -x cifs -x nfs -x smbfs -x sshfs -x ftpfs -x davfs"); if (!ret.isSuccess()) { qWarning() << "call df failed" << ret.result(); @@ -625,6 +628,54 @@ bool FormatPartion(const QString& targetDev) return XSys::SynExec("mkfs.fat", targetDev).isSuccess(); } +bool CreatePartition(const QString& diskDev) +{ +#ifdef Q_OS_LINUX + // 使用fdisk创建主分区(全盘创建一个主分区) + // o: 创建DOS分区表 + // n: 创建新分区 + // p: 主分区 + // 1: 分区号1 + // 默认起始扇区 + // 默认结束扇区(使用全部空间) + // w: 写入磁盘 + + qDebug() << "Creating partition for disk" << diskDev; + + QString cmd = QString("echo -e 'o\\nn\\np\\n1\\n\\n\\nw' | fdisk ") + diskDev; + XSys::Result result = XSys::SynExec("bash", "-c \"" + cmd + "\""); + + if (!result.isSuccess()) { + qWarning() << "Failed to create partition table with fdisk for" << diskDev; + return false; + } + qDebug() << "Partition table created, reloading kernel partition table..."; + + // 通知内核重新读取分区表 + XSys::SynExec("partprobe", diskDev); + + // 等待分区创建完成 + QThread::sleep(1); + + // 检查分区是否创建成功 + std::string partPath = diskDev.toStdString() + "1"; + struct stat buffer; + bool success = (stat(partPath.c_str(), &buffer) == 0); + + if (success) { + qDebug() << "Partition" << QString::fromStdString(partPath) << "created successfully"; + } else { + qWarning() << "Partition creation verification failed for" << QString::fromStdString(partPath); + } + + return success; +#else + // Windows或其他系统暂不支持自动创建分区 + (void)diskDev; + return false; +#endif +} + QStringList GetPartionOfDisk(const QString& strDisk) { QStringList strPartions; @@ -703,7 +754,7 @@ void SetPartionLabel(const QString& strPartion, const QString& strImage) QString strName = QString("UNKNOWN"); QString strTemp; - if (2 == strValues.size()) { + if (2 <= strValues.size()) { strTemp = strValues.at(1); strTemp = strTemp.trimmed(); } @@ -813,7 +864,7 @@ bool UmountPartion(const QString& strPartionName) bool UmountDisk(const QString &targetDev) { - bool bRet = false; + bool bRet = true; int iIndex = targetDev.lastIndexOf("/"); if (iIndex < 0) { @@ -828,6 +879,7 @@ bool UmountDisk(const QString &targetDev) } QStringList strPartions = GetPartionOfDisk(strKey); + strPartions.append(strKey); foreach (QString strPartion, strPartions) { QString strVal = strPath + strPartion; diff --git a/src/vendor/src/libxsys/DiskUtil/DiskUtil.h b/src/vendor/src/libxsys/DiskUtil/DiskUtil.h index 7d0c9f16..0b289bd0 100644 --- a/src/vendor/src/libxsys/DiskUtil/DiskUtil.h +++ b/src/vendor/src/libxsys/DiskUtil/DiskUtil.h @@ -31,6 +31,7 @@ qint64 GetPartitionFreeSpace(const QString &targetDev); qint64 GetPartitionTotalSpace(const QString &targetDev); QString GetPartitionLabel(const QString &targetDev); bool FormatPartion(const QString& targetDev); +bool CreatePartition(const QString& diskDev); QStringList GetPartionOfDisk(const QString& strDisk); bool SetActivePartion(const QString& strDisk, const QString& strPartion); void SetPartionLabel(const QString& strPartion, const QString& strImage); From b00a503e8cbb77cc21a9615e747022f1d7fa8296 Mon Sep 17 00:00:00 2001 From: xust Date: Tue, 16 Dec 2025 14:41:11 +0800 Subject: [PATCH 3/3] feat: Add Qt5 compilation compatibility - Add conditional compilation for dtk6core/dtkcore in libdbm and service - Add conditional compilation for polkit-qt6-1/polkit-qt5-1 in service - Add Qt5 compatible QString::SkipEmptyParts for Qt < 5.14 - Add DApplicationSettings header include for Qt5 - Add Dtk::Gui namespace for Qt5 DGuiApplicationHelper usage Log: Enable project to compile with both Qt5 and Qt6 environments --- debian/control | 23 ++++++++++++----------- debian/rules | 12 ++++++++---- src/app/main.cpp | 5 +++++ src/app/view/dropframe.cpp | 1 + src/libdbm/util/utils.cpp | 8 ++++---- src/libdbm/vendor.pri | 6 +++++- src/service/vendor.pri | 12 ++++++++++-- src/vendor/src/libxsys/Cmd/Cmd.cpp | 4 ++++ 8 files changed, 49 insertions(+), 22 deletions(-) diff --git a/debian/control b/debian/control index cc4fe686..ce08bc9e 100644 --- a/debian/control +++ b/debian/control @@ -1,17 +1,17 @@ Source: deepin-boot-maker Section: misc Priority: standard -Maintainer: Deepin Packages Builder +Maintainer: Deepin Packages Builder Uploaders: Ma Aiguo , Build-Depends: debhelper-compat (=11), python3, - qt6-base-dev, - qt6-base-dev-tools, - qt6-base-private-dev, - qt6-l10n-tools, - qt6-tools-dev-tools, - qt6-tools-dev, - qt6-svg-dev, + qt6-base-dev | qtbase5-dev, + qt6-base-dev-tools | qtbase5-dev-tools, + qt6-base-private-dev | qtbase5-private-dev, + qt6-l10n-tools | qttools5-dev-tools, + qt6-tools-dev-tools | qttools5-dev-tools, + qt6-tools-dev | qttools5-dev, + qt6-svg-dev | libqt5svg5-dev, pkg-config, libxcb-util0-dev, libmtdev-dev, @@ -20,9 +20,9 @@ Build-Depends: debhelper-compat (=11), libfontconfig-dev, libegl1-mesa-dev, libstartup-notification0-dev, - libdtk6widget-dev, + libdtk6widget-dev | libdtkwidget-dev, libgtest-dev, - libpolkit-qt6-1-dev + libpolkit-qt6-1-dev | libpolkit-qt5-1-dev Standards-Version: 4.5.1 Homepage: https://github.com/linuxdeepin/deepin-boot-maker Vcs-Git: https://salsa.debian.org/pkg-deepin-team/deepin-boot-maker.git @@ -32,7 +32,8 @@ Package: deepin-boot-maker Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, p7zip-full, mtools, udisks2, syslinux [linux-amd64 linux-i386], - syslinux-common [linux-amd64 linux-i386],genisoimage,dde-qt6integration + syslinux-common [linux-amd64 linux-i386], genisoimage, + dde-qt6integration | dde-qt5integration Description: Simple tool for user to create a boot usb stick quickly and easily It's designed to support deepin system iso, it can works for Debian and ubuntu iso too. diff --git a/debian/rules b/debian/rules index 960dc535..6a1e136d 100755 --- a/debian/rules +++ b/debian/rules @@ -1,9 +1,13 @@ #!/usr/bin/make -f -# 设置 Qt6 环境 -export QT_SELECT=qt6 -# 使用系统 PATH 中的 qmake6 -export QMAKE=qmake6 +# 自动检测 Qt 版本,优先使用 Qt6 +ifneq (,$(shell which qmake6 2>/dev/null)) + export QT_SELECT=qt6 + export QMAKE=qmake6 +else + export QT_SELECT=qt5 + export QMAKE=qmake +endif include /usr/share/dpkg/default.mk diff --git a/src/app/main.cpp b/src/app/main.cpp index 5e4cbe47..24a1bcda 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -15,6 +15,11 @@ #include #include +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) +#include +#endif + + DCORE_USE_NAMESPACE DWIDGET_USE_NAMESPACE diff --git a/src/app/view/dropframe.cpp b/src/app/view/dropframe.cpp index efff2735..a3246b1f 100644 --- a/src/app/view/dropframe.cpp +++ b/src/app/view/dropframe.cpp @@ -71,6 +71,7 @@ void DropFrame::paintEvent(QPaintEvent *e) QPixmap pixmap; #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) // Qt5: 使用 DGuiApplicationHelper + using namespace Dtk::Gui; DGuiApplicationHelper::ColorType themeType = DGuiApplicationHelper::instance()->themeType(); if (themeType == DGuiApplicationHelper::LightType) { pixmap = QPixmap(":/theme/light/image/dash.svg").scaled(this->size()); diff --git a/src/libdbm/util/utils.cpp b/src/libdbm/util/utils.cpp index d95d7d64..f3c2f7cc 100644 --- a/src/libdbm/util/utils.cpp +++ b/src/libdbm/util/utils.cpp @@ -15,10 +15,10 @@ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) #include #include -#else -#include #endif +#include + #include #ifdef Q_OS_WIN32 # include @@ -511,8 +511,8 @@ QList ListUsbDrives() QString filePath = usbfileinfoL.at(i).canonicalFilePath(); // 过滤USB和MMC设备,但排除网络相关设备 - bool isUsbOrMmc = fileName.contains(QRegExp("^usb-\\S{1,}$")) || fileName.contains(QRegExp("^mmc-\\S{1,}$")); - bool isNetwork = fileName.contains(QRegExp("nfs-|cifs-|smbfs-|sshfs-|ftpfs-|davfs-")); + bool isUsbOrMmc = fileName.contains(QRegularExpression("^usb-\\S{1,}$")) || fileName.contains(QRegularExpression("^mmc-\\S{1,}$")); + bool isNetwork = fileName.contains(QRegularExpression("nfs-|cifs-|smbfs-|sshfs-|ftpfs-|davfs-")); if (isUsbOrMmc && !isNetwork) { removeDevice.insert(filePath, fileName); diff --git a/src/libdbm/vendor.pri b/src/libdbm/vendor.pri index b192096d..9e897266 100644 --- a/src/libdbm/vendor.pri +++ b/src/libdbm/vendor.pri @@ -2,7 +2,11 @@ include($$PWD/../vendor/env.pri) # QT += dtk6core -PKGCONFIG += dtk6core +versionAtLeast(QT_VERSION, 6.0.0) { + PKGCONFIG += dtk6core +} else { + PKGCONFIG += dtkcore +} unix{ QT += dbus diff --git a/src/service/vendor.pri b/src/service/vendor.pri index 8f0ee35b..b2126a09 100644 --- a/src/service/vendor.pri +++ b/src/service/vendor.pri @@ -3,13 +3,21 @@ include($$PWD/../vendor/env.pri) unix{ QT += dbus CONFIG += link_pkgconfig - PKGCONFIG += dtk6core polkit-qt6-1 + versionAtLeast(QT_VERSION, 6.0.0) { + PKGCONFIG += dtk6core polkit-qt6-1 + } else { + PKGCONFIG += dtkcore polkit-qt5-1 + } } win32{ INCLUDEPATH += $$DTK_INCLUDE\DCore DEPENDPATH += $$DTK_DEPEND\DCore - LIBS += -L$$DTK_LIBRARY -ldtk6core + versionAtLeast(QT_VERSION, 6.0.0) { + LIBS += -L$$DTK_LIBRARY -ldtk6core + } else { + LIBS += -L$$DTK_LIBRARY -ldtkcore + } } ################################################################## diff --git a/src/vendor/src/libxsys/Cmd/Cmd.cpp b/src/vendor/src/libxsys/Cmd/Cmd.cpp index 1f62d247..06f4ca8e 100644 --- a/src/vendor/src/libxsys/Cmd/Cmd.cpp +++ b/src/vendor/src/libxsys/Cmd/Cmd.cpp @@ -25,7 +25,11 @@ static Result runApp(const QString &execPath, const QString &execParam, const QS // app.setStandardOutputFile(outPipePath); // app.setStandardErrorFile(outPipePath); app.setProgram(execPath); +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) QStringList argList = execParam.split(" ", Qt::SkipEmptyParts); +#else + QStringList argList = execParam.split(" ", QString::SkipEmptyParts); +#endif app.setArguments(argList); app.start(); if (!app.waitForStarted()) {