From bc926a6e4553d1ac4aa9ddeb2a8c446bb7c5aeb5 Mon Sep 17 00:00:00 2001 From: lianwei Date: Mon, 20 May 2024 10:20:02 +0800 Subject: [PATCH 1/2] gptfdisk: adapt 1.0.10 Signed-off-by: lianwei --- NEWS | 41 ++++++++++++++++++ cgdisk.8 | 12 +++--- current.spec | 8 ++-- diskio-unix.cc | 6 ++- diskio-windows.cc | 9 ++-- fixparts.8 | 8 ++-- gdisk.8 | 21 ++++++--- gpt.cc | 77 +++++++++++++++++++++++++-------- gpt.h | 2 + gptcl.cc | 25 ++++++++--- gptcurses.cc | 15 ++++--- gpttext.cc | 28 +++++++++++- gpttext.h | 1 + guid.cc | 2 +- parttypes.cc | 106 ++++++++++++++++++++++++++++++++++++++++++++++ sgdisk.8 | 35 ++++++++++----- support.cc | 15 +++++-- support.h | 2 +- 18 files changed, 338 insertions(+), 75 deletions(-) diff --git a/NEWS b/NEWS index c7add56..b6343b3 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,44 @@ +1.0.10 (2/19/2024): +------------------- + +- Fixed problem that caused sgdisk to crash with errors about being unable + to read the disk's partition table when compiled with the latest popt + (commit 740, which is pre-release as I type; presumably version 1.19 and + later once released). + +- Updated guid.cc to deal with minor change in libuuid. + +- Fixed potential NULL derefernce bug in sgdisk. Thanks to Damian Kurek + for this fix. + +- The partition number of "0" can now be used to reference newly-created + partitions when the --largest-new=0 option to sgdisk is used. Thanks to + David JoaquĆ­n Shourabi Porcel for this improvement. + +- Make explicit casts in gptcurses.cc to eliminate compiler warnings about + mis-matched types in printw() statements. + +- Minor code cleanup based on valgrind analysis. + +- In previous versions, GPT fdisk accepted only integer values for partition + start points, end points, and sizes, and it interpreted decimal values + incorrectly. That is, if you typed "+9.5G" as the partition end point, + you'd end up with something just 9 sectors in size. This version now + truncates decimal numbers to their integral values, so you'd get a 9 GiB + partition instead. + +- Changes to optimize disk handling, particularly on Windows, courtesy of + Frediano Ziglio. + +- Added numerous new partition type codes from Discoverable Partitions + Specification + (https://uapi-group.org/specifications/specs/discoverable_partitions_specification/). + +- Added new sgdisk -k/--move-backup-table and gdisk k (on the experts' menu) + option to relocate the backup partition table. This is the counterpart of + the sgdisk -j/--move-main-table and gdisk j (on the experts' menu) option + to move the main partition table. This code comes from Niklas Gollenstede. + 1.0.9 (4/14/2022): ------------------ diff --git a/cgdisk.8 b/cgdisk.8 index e3b5cb4..0a46442 100644 --- a/cgdisk.8 +++ b/cgdisk.8 @@ -1,6 +1,6 @@ -.\" Copyright 2011-2022 Roderick W. Smith (rodsmith@rodsbooks.com) +.\" Copyright 2011-2024 Roderick W. Smith (rodsmith@rodsbooks.com) .\" May be distributed under the GNU General Public License -.TH "CGDISK" "8" "1.0.9" "Roderick W. Smith" "GPT fdisk Manual" +.TH "CGDISK" "8" "1.0.10" "Roderick W. Smith" "GPT fdisk Manual" .SH "NAME" cgdisk \- Curses-based GUID partition table (GPT) manipulator .SH "SYNOPSIS" @@ -25,7 +25,7 @@ disks. For information on MBR vs. GPT, as well as GPT terminology and structure, see the extended GPT fdisk documentation at -\fIhttp://www.rodsbooks.com/gdisk/\fR or consult Wikipedia. +\fIhttps://www.rodsbooks.com/gdisk/\fR or consult Wikipedia. The \fBcgdisk\fR program employs a user interface similar to that of Linux's \fBcfdisk\fR, but \fBcgdisk\fR modifies GPT partitions. It also has the @@ -389,11 +389,11 @@ Contributors: .BR sgdisk (8), .BR fixparts (8). -\fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR +\fIhttps://en.wikipedia.org/wiki/GUID_Partition_Table\fR -\fIhttp://developer.apple.com/technotes/tn2006/tn2166.html\fR +\fIhttps://developer.apple.com/technotes/tn2006/tn2166.html\fR -\fIhttp://www.rodsbooks.com/gdisk/\fR +\fIhttps://www.rodsbooks.com/gdisk/\fR .SH "AVAILABILITY" The \fBcgdisk\fR command is part of the \fIGPT fdisk\fR package and is diff --git a/current.spec b/current.spec index a912894..bdbe6c0 100644 --- a/current.spec +++ b/current.spec @@ -1,12 +1,12 @@ Summary: GPT partitioning and MBR repair software Name: gptfdisk -Version: 1.0.9 +Version: 1.0.10 Release: 1%{?dist} License: GPLv2 URL: http://www.rodsbooks.com/gdisk Group: Applications/System -Source: http://www.rodsbooks.com/gdisk/gptfdisk-1.0.9.tar.gz +Source: http://www.rodsbooks.com/gdisk/gptfdisk-1.0.10.tar.gz BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) %description @@ -81,5 +81,5 @@ provides a few additional partition manipulation features. %changelog -* Thu Apr 14 2022 R Smith - 1.0.9 -- Created spec file for 1.0.9 release +* Mon Feb 19 2024 R Smith - 1.0.10 +- Created spec file for 1.0.10 release diff --git a/diskio-unix.cc b/diskio-unix.cc index 53f60f0..fc03b8e 100644 --- a/diskio-unix.cc +++ b/diskio-unix.cc @@ -39,8 +39,12 @@ using namespace std; -#ifdef __APPLE__ +#if defined(__APPLE__) || defined(__linux__) #define off64_t off_t +#define stat64 stat +#define fstat64 fstat +#define lstat64 lstat +#define lseek64 lseek #endif // Returns the official "real" name for a shortened version of same. diff --git a/diskio-windows.cc b/diskio-windows.cc index 6e64113..15e6c5a 100644 --- a/diskio-windows.cc +++ b/diskio-windows.cc @@ -65,7 +65,6 @@ int DiskIO::OpenForRead(void) { fd = CreateFile(realFilename.c_str(),GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fd == INVALID_HANDLE_VALUE) { - CloseHandle(fd); cerr << "Problem opening " << realFilename << " for reading!\n"; realFilename = ""; userFilename = ""; @@ -96,13 +95,11 @@ int DiskIO::OpenForWrite(void) { // Preceding call can fail when creating backup files; if so, try // again with different option... if (fd == INVALID_HANDLE_VALUE) { - CloseHandle(fd); fd = CreateFile(realFilename.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); } // if if (fd == INVALID_HANDLE_VALUE) { - CloseHandle(fd); isOpen = 0; openForWrite = 0; errno = GetLastError(); @@ -116,8 +113,10 @@ int DiskIO::OpenForWrite(void) { // Close the disk device. Note that this does NOT erase the stored filenames, // so the file can be re-opened without specifying the filename. void DiskIO::Close(void) { - if (isOpen) - CloseHandle(fd); + if (isOpen) { + CloseHandle(fd); + fd = INVALID_HANDLE_VALUE; + } isOpen = 0; openForWrite = 0; } // DiskIO::Close() diff --git a/fixparts.8 b/fixparts.8 index da7462a..aaa0c3e 100644 --- a/fixparts.8 +++ b/fixparts.8 @@ -1,6 +1,6 @@ -.\" Copyright 2011-2022 Roderick W. Smith (rodsmith@rodsbooks.com) +.\" Copyright 2011-2024 Roderick W. Smith (rodsmith@rodsbooks.com) .\" May be distributed under the GNU General Public License -.TH "FIXPARTS" "8" "1.0.9" "Roderick W. Smith" "FixParts Manual" +.TH "FIXPARTS" "8" "1.0.10" "Roderick W. Smith" "FixParts Manual" .SH "NAME" fixparts \- MBR partition table repair utility .SH "SYNOPSIS" @@ -273,9 +273,9 @@ Contributors: .BR gdisk (8), .BR sgdisk (8). -\fIhttp://en.wikipedia.org/wiki/Master_boot_record\fR +\fIhttps://en.wikipedia.org/wiki/Master_boot_record\fR -\fIhttp://www.rodsbooks.com/fixparts/\fR +\fIhttps://www.rodsbooks.com/fixparts/\fR .SH "AVAILABILITY" The \fBfixparts\fR command is part of the \fIGPT fdisk\fR package and is diff --git a/gdisk.8 b/gdisk.8 index b826b89..2048af5 100644 --- a/gdisk.8 +++ b/gdisk.8 @@ -1,6 +1,6 @@ -.\" Copyright 2011-2022 Roderick W. Smith (rodsmith@rodsbooks.com) +.\" Copyright 2011-2024 Roderick W. Smith (rodsmith@rodsbooks.com) .\" May be distributed under the GNU General Public License -.TH "GDISK" "8" "1.0.9" "Roderick W. Smith" "GPT fdisk Manual" +.TH "GDISK" "8" "1.0.10" "Roderick W. Smith" "GPT fdisk Manual" .SH "NAME" gdisk \- Interactive GUID partition table (GPT) manipulator .SH "SYNOPSIS" @@ -27,7 +27,7 @@ recovery options require you to understand the distinctions between the main and backup data, as well as between the GPT headers and the partition tables. For information on MBR vs. GPT, as well as GPT terminology and structure, see the extended \fBgdisk\fR documentation at -\fIhttp://www.rodsbooks.com/gdisk/\fR or consult Wikipedia. +\fIhttps://www.rodsbooks.com/gdisk/\fR or consult Wikipedia. The \fBgdisk\fR program employs a user interface similar to that of Linux's \fBfdisk\fR, but \fBgdisk\fR modifies GPT partitions. It also has the @@ -486,7 +486,14 @@ system\-on\-chip (SoC) is hard\-coded to read boot code from sector 2. I recommend against adjusting this value unless doing so is absolutely necessary. -.TP +.TP +.B k +Adjust the location of the backup partition table. This partition table is +normally located just before the backup metadata at the end of the disk, but +it may need to be moved in some very rare cases. I recommend against +adjusting this value unless doing so is absolutely necessary. + +.TP .B l Change the sector alignment value. Disks with more logical sectors per physical sectors (such as modern Advanced Format drives), some RAID @@ -702,11 +709,11 @@ Contributors: .BR sgdisk (8), .BR fixparts (8). -\fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR +\fIhttps://en.wikipedia.org/wiki/GUID_Partition_Table\fR -\fIhttp://developer.apple.com/technotes/tn2006/tn2166.html\fR +\fIhttps://developer.apple.com/technotes/tn2006/tn2166.html\fR -\fIhttp://www.rodsbooks.com/gdisk/\fR +\fIhttps://www.rodsbooks.com/gdisk/\fR .SH "AVAILABILITY" The \fBgdisk\fR command is part of the \fIGPT fdisk\fR package and is diff --git a/gpt.cc b/gpt.cc index f721da5..602a8ac 100644 --- a/gpt.cc +++ b/gpt.cc @@ -3,7 +3,7 @@ /* By Rod Smith, initial coding January to February, 2009 */ -/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed +/* This program is copyright (c) 2009-2024 by Roderick W. Smith. It is distributed under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ #define __STDC_LIMIT_MACROS @@ -82,6 +82,7 @@ GPTData::GPTData(void) { beQuiet = 0; whichWasUsed = use_new; mainHeader.numParts = 0; + mainHeader.firstUsableLBA = 0; mainHeader.lastUsableLBA = 0; numParts = 0; SetGPTSize(NUM_GPT_ENTRIES); @@ -346,6 +347,13 @@ int GPTData::Verify(void) { << "but is generally ill-advised. Using 'j' on the experts' menu can adjust this\n" << "gap.\n"; } // if + if (secondHeader.partitionEntriesLBA != diskSize - GetTableSizeInSectors() - 1) { + cout << "\nWarning: There is a gap between the secondary partition table (ending at sector\n" + << secondHeader.partitionEntriesLBA + GetTableSizeInSectors() - 1 + << ") and the secondary metadata (sector " << mainHeader.backupLBA << ").\n" + << "This is helpful in some exotic configurations, but is generally ill-advised.\n" + << "Using 'k' on the experts' menu can adjust this gap.\n"; + } // if if (mainHeader.partitionEntriesLBA + GetTableSizeInSectors() != mainHeader.firstUsableLBA) { cout << "\nWarning: There is a gap between the main partition table (ending sector " << mainHeader.partitionEntriesLBA + GetTableSizeInSectors() - 1 << ")\n" @@ -835,25 +843,27 @@ int GPTData::LoadPartitions(const string & deviceFilename) { int err, allOK = 1; MBRValidity mbrState; - if (myDisk.OpenForRead(deviceFilename)) { - err = myDisk.OpenForWrite(deviceFilename); - if ((err == 0) && (!justLooking)) { - cout << "\aNOTE: Write test failed with error number " << errno - << ". It will be impossible to save\nchanges to this disk's partition table!\n"; + if (!justLooking) { + if (myDisk.OpenForRead(deviceFilename)) { + err = myDisk.OpenForWrite(deviceFilename); + if (err == 0) { + cout << "\aNOTE: Write test failed with error number " << errno + << ". It will be impossible to save\nchanges to this disk's partition table!\n"; #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) - cout << "You may be able to enable writes by exiting this program, typing\n" - << "'sysctl kern.geom.debugflags=16' at a shell prompt, and re-running this\n" - << "program.\n"; + cout << "You may be able to enable writes by exiting this program, typing\n" + << "'sysctl kern.geom.debugflags=16' at a shell prompt, and re-running this\n" + << "program.\n"; #endif #if defined (__APPLE__) - cout << "You may need to deactivate System Integrity Protection to use this program. See\n" - << "https://www.quora.com/How-do-I-turn-off-the-rootless-in-OS-X-El-Capitan-10-11\n" - << "for more information.\n"; + cout << "You may need to deactivate System Integrity Protection to use this program. See\n" + << "https://www.quora.com/How-do-I-turn-off-the-rootless-in-OS-X-El-Capitan-10-11\n" + << "for more information.\n"; #endif - cout << "\n"; - } // if - myDisk.Close(); // Close and re-open read-only in case of bugs - } else allOK = 0; // if + cout << "\n"; + } // if + myDisk.Close(); // Close and re-open read-only in case of bugs + } else allOK = 0; // if + } if (allOK && myDisk.OpenForRead(deviceFilename)) { // store disk information.... @@ -1502,7 +1512,7 @@ int GPTData::DestroyGPT(void) { cerr << "Warning! GPT main partition table not overwritten! Error is " << errno << "\n"; allOK = 0; } // if write failed - } // if + } // if if (!myDisk.Seek(secondHeader.partitionEntriesLBA)) allOK = 0; if (allOK) { @@ -1913,6 +1923,23 @@ int GPTData::MoveMainTable(uint64_t pteSector) { return retval; } // GPTData::MoveMainTable() +// Change the start sector for the secondary partition table. +// Returns 1 on success, 0 on failure +int GPTData::MoveSecondTable(uint64_t pteSector) { + uint64_t pteSize = GetTableSizeInSectors(); + int retval = 1; + + if ((pteSector > FindLastUsedLBA()) && ((pteSector + pteSize) < diskSize)) { + secondHeader.partitionEntriesLBA = pteSector; // (RebuildSecondHeader actually replaces this with lastUsableLBA+1) + mainHeader.lastUsableLBA = secondHeader.partitionEntriesLBA - UINT64_C(1); + RebuildSecondHeader(); + } else { + cerr << "Unable to set the secondary partition table's location to " << pteSector << "!\n"; + retval = 0; + } // if/else + return retval; +} // GPTData::MoveSecondTable() + // Blank the partition array void GPTData::BlankPartitions(void) { uint32_t i; @@ -2287,7 +2314,7 @@ uint64_t GPTData::FindFirstAvailable(uint64_t start) { } // GPTData::FindFirstAvailable() // Returns the LBA of the start of the first partition on the disk (by -// sector number), or 0 if there are no partitions defined. +// sector number), or UINT64_MAX if there are no partitions defined. uint64_t GPTData::FindFirstUsedLBA(void) { uint32_t i; uint64_t firstFound = UINT64_MAX; @@ -2300,6 +2327,20 @@ uint64_t GPTData::FindFirstUsedLBA(void) { return firstFound; } // GPTData::FindFirstUsedLBA() +// Returns the LBA of the end of the last partition on the disk (by +// sector number), or 0 if there are no partitions defined. +uint64_t GPTData::FindLastUsedLBA(void) { + uint32_t i; + uint64_t lastFound = 0; + + for (i = 0; i < numParts; i++) { + if ((partitions[i].IsUsed()) && (partitions[i].GetFirstLBA() > lastFound)) { + lastFound = partitions[i].GetLastLBA(); + } // if + } // for + return lastFound; +} // GPTData::FindLastUsedLBA() + // Finds the first available sector in the largest block of unallocated // space on the disk. Returns 0 if there are no available blocks left uint64_t GPTData::FindFirstInLargest(void) { diff --git a/gpt.h b/gpt.h index 5d19372..9e53559 100644 --- a/gpt.h +++ b/gpt.h @@ -142,6 +142,7 @@ public: // Adjust GPT structures WITHOUT user interaction... int SetGPTSize(uint32_t numEntries, int fillGPTSectors = 1); int MoveMainTable(uint64_t pteSector); + int MoveSecondTable(uint64_t pteSector); void BlankPartitions(void); int DeletePartition(uint32_t partNum); uint32_t CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector); @@ -181,6 +182,7 @@ public: // Find information about free space uint64_t FindFirstAvailable(uint64_t start = 0); uint64_t FindFirstUsedLBA(void); + uint64_t FindLastUsedLBA(void); uint64_t FindFirstInLargest(void); uint64_t FindLastAvailable(); uint64_t FindLastInFree(uint64_t start, bool align = false); diff --git a/gptcl.cc b/gptcl.cc index 34c9421..13bfb36 100644 --- a/gptcl.cc +++ b/gptcl.cc @@ -1,7 +1,7 @@ /* Implementation of GPTData class derivative with popt-based command line processing - Copyright (C) 2010-2022 Roderick W. Smith + Copyright (C) 2010-2024 Roderick W. Smith This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -68,7 +68,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { int opt, numOptions = 0, saveData = 0, neverSaveData = 0; int partNum = 0, newPartNum = -1, saveNonGPT = 1, retval = 0, pretend = 0; int byteSwapPartNum = 0; - uint64_t low, high, startSector, endSector, sSize, mainTableLBA; + uint64_t low, high, startSector, endSector, sSize, mainTableLBA, secondTableLBA; uint64_t temp; // temporary variable; free to use in any case char *device; string cmd, typeGUID, name; @@ -85,7 +85,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { {"recompute-chs", 'C', POPT_ARG_NONE, NULL, 'C', "recompute CHS values in protective/hybrid MBR", ""}, {"delete", 'd', POPT_ARG_INT, &deletePartNum, 'd', "delete a partition", "partnum"}, {"display-alignment", 'D', POPT_ARG_NONE, NULL, 'D', "show number of sectors per allocation block", ""}, - {"move-second-header", 'e', POPT_ARG_NONE, NULL, 'e', "move second header to end of disk", ""}, + {"move-second-header", 'e', POPT_ARG_NONE, NULL, 'e', "move second/backup header to end of disk", ""}, {"end-of-largest", 'E', POPT_ARG_NONE, NULL, 'E', "show end of largest free block", ""}, {"first-in-largest", 'f', POPT_ARG_NONE, NULL, 'f', "show start of the largest free block", ""}, {"first-aligned-in-largest", 'F', POPT_ARG_NONE, NULL, 'F', "show start of the largest free block, aligned", ""}, @@ -94,7 +94,8 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { {"hybrid", 'h', POPT_ARG_STRING, &hybrids, 'h', "create hybrid MBR", "partnum[:partnum...][:EE]"}, {"info", 'i', POPT_ARG_INT, &infoPartNum, 'i', "show detailed information on partition", "partnum"}, {"align-end", 'I', POPT_ARG_NONE, NULL, 'I', "align partition end points", ""}, - {"move-main-table", 'j', POPT_ARG_INT, &mainTableLBA, 'j', "adjust the location of the main partition table", "sector"}, + {"move-main-table", 'j', POPT_ARG_INT, &mainTableLBA, 'j', "change the start sector of the main partition table", "sector"}, + {"move-backup-table", 'k', POPT_ARG_INT, &secondTableLBA, 'k', "change the start sector of the second/backup partition table", "sector"}, {"load-backup", 'l', POPT_ARG_STRING, &backupFile, 'l', "load GPT backup from file", "file"}, {"list-types", 'L', POPT_ARG_NONE, NULL, 'L', "list known partition types", ""}, {"gpttombr", 'm', POPT_ARG_STRING, &mbrParts, 'm', "convert GPT to MBR", "partnum[:partnum...]"}, @@ -156,9 +157,10 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { // Assume first non-option argument is the device filename.... device = (char*) poptGetArg(poptCon); - poptResetContext(poptCon); if (device != NULL) { + device = strdup(device); + poptResetContext(poptCon); JustLooking(); // reset as necessary BeQuiet(); // Tell called functions to be less verbose & interactive if (LoadPartitions((string) device)) { @@ -287,6 +289,14 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { neverSaveData = 1; } // if/else break; + case 'k': + if (MoveSecondTable(secondTableLBA)) { + JustLooking(0); + saveData = 1; + } else { + neverSaveData = 1; + } // if/else + break; case 'l': LoadBackupFile(backupFile, saveData, neverSaveData); free(backupFile); @@ -331,8 +341,10 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { startSector = FindFirstInLargest(); Align(&startSector); endSector = FindLastInFree(startSector, alignEnd); - if (largestPartNum <= 0) + if (largestPartNum <= 0) { largestPartNum = FindFirstFreePart() + 1; + newPartNum = largestPartNum - 1; + } if (CreatePartition(largestPartNum - 1, startSector, endSector)) { saveData = 1; } else { @@ -498,6 +510,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) { cerr << "Error encountered; not saving changes.\n"; retval = 4; } // if + free(device); } // if (device != NULL) poptFreeContext(poptCon); return retval; diff --git a/gptcurses.cc b/gptcurses.cc index 8b0ae91..543f41f 100644 --- a/gptcurses.cc +++ b/gptcurses.cc @@ -1,7 +1,7 @@ /* * Implementation of GPTData class derivative with curses-based text-mode * interaction - * Copyright (C) 2011-2022 Roderick W. Smith + * Copyright (C) 2011-2024 Roderick W. Smith * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -333,13 +333,13 @@ void GPTDataCurses::ShowInfo(int partNum) { printw("Partition GUID code: %s (%s)\n", partitions[partNum].GetType().AsString().c_str(), partitions[partNum].GetTypeName().c_str()); printw("Partition unique GUID: %s\n", partitions[partNum].GetUniqueGUID().AsString().c_str()); - printw("First sector: %lld (at %s)\n", partitions[partNum].GetFirstLBA(), + printw("First sector: %llu (at %s)\n", (long long unsigned int) partitions[partNum].GetFirstLBA(), BytesToIeee(partitions[partNum].GetFirstLBA(), blockSize).c_str()); - printw("Last sector: %lld (at %s)\n", partitions[partNum].GetLastLBA(), + printw("Last sector: %llu (at %s)\n", (long long unsigned int) partitions[partNum].GetLastLBA(), BytesToIeee(partitions[partNum].GetLastLBA(), blockSize).c_str()); size = partitions[partNum].GetLastLBA() - partitions[partNum].GetFirstLBA() + 1; - printw("Partition size: %lld sectors (%s)\n", size, BytesToIeee(size, blockSize).c_str()); - printw("Attribute flags: %016llx\n", partitions[partNum].GetAttributes().GetAttributes()); + printw("Partition size: %llu sectors (%s)\n", (long long unsigned int) size, BytesToIeee(size, blockSize).c_str()); + printw("Attribute flags: %016llx\n", (long long unsigned int) partitions[partNum].GetAttributes().GetAttributes()); #ifdef USE_UTF16 partitions[partNum].GetDescription().extract(0, NAME_SIZE , temp, NAME_SIZE ); printw("Partition name: '%s'\n", temp); @@ -447,7 +447,8 @@ void GPTDataCurses::MakeNewPart(void) { clrtoeol(); newFirstLBA = currentSpace->firstLBA; Align(&newFirstLBA); - printw("First sector (%lld-%lld, default = %lld): ", newFirstLBA, currentSpace->lastLBA, newFirstLBA); + printw("First sector (%llu-%llu, default = %llu): ", (long long unsigned int) newFirstLBA, + (long long unsigned int) currentSpace->lastLBA, (long long unsigned int) newFirstLBA); echo(); getnstr(inLine, 79); noecho(); @@ -461,7 +462,7 @@ void GPTDataCurses::MakeNewPart(void) { while ((newLastLBA > currentSpace->lastLBA) || (newLastLBA < newFirstLBA)) { move(LINES - 3, 0); clrtoeol(); - printw("Size in sectors or {KMGTP} (default = %lld): ", size); + printw("Size in sectors or {KMGTP} (default = %llu): ", (long long unsigned int) size); echo(); getnstr(inLine, 79); noecho(); diff --git a/gpttext.cc b/gpttext.cc index 170a169..f651918 100644 --- a/gpttext.cc +++ b/gpttext.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2010-2022 + Copyright (C) 2010-2024 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -186,6 +186,8 @@ void GPTDataTextUI::MoveMainTable(void) { uint64_t maxValue = FindFirstUsedLBA() - pteSize; ostringstream prompt; + if (maxValue == UINT64_MAX - pteSize) + maxValue = FindLastAvailable() - pteSize; cout << "Currently, main partition table begins at sector " << mainHeader.partitionEntriesLBA << " and ends at sector " << mainHeader.partitionEntriesLBA + pteSize - 1 << "\n"; prompt << "Enter new starting location (2 to " << maxValue << "; default is 2; 1 to abort): "; @@ -197,6 +199,26 @@ void GPTDataTextUI::MoveMainTable(void) { } // if } // GPTDataTextUI::MoveMainTable() +// Move the backup partition table. +void GPTDataTextUI::MoveSecondTable(void) { + uint64_t newStart, pteSize = GetTableSizeInSectors(); + uint64_t minValue = FindLastUsedLBA() + 1; + uint64_t maxValue = diskSize - 1 - pteSize; + ostringstream prompt; + + cout << "Currently, backup partition table begins at sector " << secondHeader.partitionEntriesLBA + << " and ends at\n" + << "sector " << secondHeader.partitionEntriesLBA + pteSize - 1 << "\n"; + prompt << "Enter new starting location (" << minValue << " to " << maxValue << + "; default is " << maxValue << "; 1 to abort): "; + newStart = GetNumber(minValue, maxValue, maxValue, prompt.str()); + if (newStart != secondHeader.partitionEntriesLBA) { + GPTData::MoveSecondTable(newStart); + } else { + cout << "Aborting change!\n"; + } // if +} // GPTDataTextUI::MoveSecondTable() + // Interactively create a partition void GPTDataTextUI::CreatePartition(void) { uint64_t firstBlock, firstInLargest, lastBlock, sector, origSector, lastAligned; @@ -873,6 +895,9 @@ void GPTDataTextUI::ExpertsMenu(string filename) { case 'j': case 'J': MoveMainTable(); break; + case 'k': case 'K': + MoveSecondTable(); + break; case 'l': case 'L': prompt.seekp(0); prompt << "Enter the sector alignment value (1-" << MAX_ALIGNMENT << ", default = " @@ -946,6 +971,7 @@ void GPTDataTextUI::ShowExpertCommands(void) { cout << "h\trecompute CHS values in protective/hybrid MBR\n"; cout << "i\tshow detailed information on a partition\n"; cout << "j\tmove the main partition table\n"; + cout << "k\tmove the backup partition table\n"; cout << "l\tset the sector alignment value\n"; cout << "m\treturn to main menu\n"; cout << "n\tcreate a new protective MBR\n"; diff --git a/gpttext.h b/gpttext.h index 32e2f88..8ed6274 100644 --- a/gpttext.h +++ b/gpttext.h @@ -41,6 +41,7 @@ class GPTDataTextUI : public GPTData { uint32_t GetPartNum(void); void ResizePartitionTable(void); void MoveMainTable(void); + void MoveSecondTable(void); void CreatePartition(void); void DeletePartition(void); void ChangePartType(void); diff --git a/guid.cc b/guid.cc index e3e495c..c4a3f23 100644 --- a/guid.cc +++ b/guid.cc @@ -143,7 +143,7 @@ void GUIDData::Zero(void) { void GUIDData::Randomize(void) { int i, uuidGenerated = 0; -#ifdef _UUID_UUID_H +#if defined (_UUID_UUID_H) || defined (_UL_LIBUUID_UUID_H) uuid_generate(uuidData); ReverseBytes(&uuidData[0], 4); ReverseBytes(&uuidData[4], 2); diff --git a/parttypes.cc b/parttypes.cc index 5807d18..28d757e 100644 --- a/parttypes.cc +++ b/parttypes.cc @@ -167,6 +167,112 @@ void PartType::AddAllTypes(void) { AddType(0x831A, "C215D751-7BCD-4649-BE90-6627490A4C05", "Linux ARM32 /usr verity"); AddType(0x831B, "6E11A4E7-FBCA-4DED-B9E9-E1A512BB664E", "Linux ARM64 /usr verity"); AddType(0x831C, "6A491E03-3BE7-4545-8E38-83320E0EA880", "Linux IA-64 /usr verity"); + AddType(0x831D, "6523F8AE-3EB1-4E2A-A05A-18B695AE656F", "Linux Alpha root (/)"); + AddType(0x831E, "D27F46ED-2919-4CB8-BD25-9531F3C16534", "Linux ARC root (/)"); + AddType(0x831F, "77055800-792C-4F94-B39A-98C91B762BB6", "Linux LoongArch root (/)"); + AddType(0x8320, "E9434544-6E2C-47CC-BAE2-12D6DEAFB44C", "Linux MIPS-32 BE root (/)"); + AddType(0x8321, "D113AF76-80EF-41B4-BDB6-0CFF4D3D4A25", "Linux MIPS-64 BE root (/)"); + AddType(0x8322, "37C58C8A-D913-4156-A25F-48B1B64E07F0", "Linux MIPS-32 LE root (/)"); + AddType(0x8323, "700BDA43-7A34-4507-B179-EEB93D7A7CA3", "Linux MIPS-64 LE root (/)"); + AddType(0x8324, "1AACDB3B-5444-4138-BD9E-E5C2239B2346", "Linux PA-RISC root (/)"); + AddType(0x8325, "1DE3F1EF-FA98-47B5-8DCD-4A860A654D78", "Linux PowerPC-32 root (/)"); + AddType(0x8326, "912ADE1D-A839-4913-8964-A10EEE08FBD2", "Linux PowerPC-64 BE root (/)"); + AddType(0x8327, "C31C45E6-3F39-412E-80FB-4809C4980599", "Linux PowerPC-64 LE root (/)"); + AddType(0x8328, "60D5A7FE-8E7D-435C-B714-3DD8162144E1", "Linux RISC-V-32 root (/)"); + AddType(0x8329, "72EC70A6-CF74-40E6-BD49-4BDA08E8F224", "Linux RISC-V-64 root (/)"); + AddType(0x832A, "08A7ACEA-624C-4A20-91E8-6E0FA67D23F9", "Linux s390 root (/)"); + AddType(0x832B, "5EEAD9A9-FE09-4A1E-A1D7-520D00531306", "Linux s390x root (/)"); + AddType(0x832C, "C50CDD70-3862-4CC3-90E1-809A8C93EE2C", "Linux TILE-Gx root (/)"); + AddType(0x832D, "E18CF08C-33EC-4C0D-8246-C6C6FB3DA024", "Linux Alpha /usr"); + AddType(0x832E, "7978A683-6316-4922-BBEE-38BFF5A2FECC", "Linux ARC /usr"); + AddType(0x832F, "E611C702-575C-4CBE-9A46-434FA0BF7E3F", "Linux LoongArch /usr"); + AddType(0x8330, "773B2ABC-2A99-4398-8BF5-03BAAC40D02B", "Linux MIPS-32 BE /usr"); + AddType(0x8331, "57E13958-7331-4365-8E6E-35EEEE17C61B", "Linux MIPS-64 BE /usr"); + AddType(0x8332, "0F4868E9-9952-4706-979F-3ED3A473E947", "Linux MIPS-32 LE /usr"); + AddType(0x8333, "C97C1F32-BA06-40B4-9F22-236061B08AA8", "Linux MIPS-64 LE /usr"); + AddType(0x8334, "DC4A4480-6917-4262-A4EC-DB9384949F25", "Linux PA-RISC /usr"); + AddType(0x8335, "7D14FEC5-CC71-415D-9D6C-06BF0B3C3EAF", "Linux PowerPC-32 /usr"); + AddType(0x8336, "2C9739E2-F068-46B3-9FD0-01C5A9AFBCCA", "Linux PowerPC-64 BE /usr"); + AddType(0x8337, "15BB03AF-77E7-4D4A-B12B-C0D084F7491C", "Linux PowerPC-64 LE /usr"); + AddType(0x8338, "B933FB22-5C3F-4F91-AF90-E2BB0FA50702", "Linux RISC-V-32 /usr"); + AddType(0x8339, "BEAEC34B-8442-439B-A40B-984381ED097D", "Linux RISC-V-64 /usr"); + AddType(0x833A, "CD0F869B-D0FB-4CA0-B141-9EA87CC78D66", "Linux s390 /usr"); + AddType(0x833B, "8A4F5770-50AA-4ED3-874A-99B710DB6FEA", "Linux s390x /usr"); + AddType(0x833C, "55497029-C7C1-44CC-AA39-815ED1558630", "Linux TILE-Gx /usr"); + AddType(0x833D, "FC56D9E9-E6E5-4C06-BE32-E74407CE09A5", "Linux Alpha root verity"); + AddType(0x833E, "24B2D975-0F97-4521-AFA1-CD531E421B8D", "Linux ARC root verity"); + AddType(0x833F, "F3393B22-E9AF-4613-A948-9D3BFBD0C535", "Linux LoongArch root verity"); + AddType(0x8340, "7A430799-F711-4C7E-8E5B-1D685BD48607", "Linux MIPS-32 BE root verity"); + AddType(0x8341, "579536F8-6A33-4055-A95A-DF2D5E2C42A8", "Linux MIPS-64 BE root verity"); + AddType(0x8342, "D7D150D2-2A04-4A33-8F12-16651205FF7B", "Linux MIPS-32 LE root verity"); + AddType(0x8343, "16B417F8-3E06-4F57-8DD2-9B5232F41AA6", "Linux MIPS-64 LE root verity"); + AddType(0x8344, "D212A430-FBC5-49F9-A983-A7FEEF2B8D0E", "Linux PA-RISC root verity"); + AddType(0x8345, "906BD944-4589-4AAE-A4E4-DD983917446A", "Linux PowerPC-64 LE root verity"); + AddType(0x8346, "9225A9A3-3C19-4D89-B4F6-EEFF88F17631", "Linux PowerPC-64 BE root verity"); + AddType(0x8347, "98CFE649-1588-46DC-B2F0-ADD147424925", "Linux PowerPC-32 root verity"); + AddType(0x8348, "AE0253BE-1167-4007-AC68-43926C14C5DE", "Linux RISC-V-32 root verity"); + AddType(0x8349, "B6ED5582-440B-4209-B8DA-5FF7C419EA3D", "Linux RISC-V-64 root verity"); + AddType(0x834A, "7AC63B47-B25C-463B-8DF8-B4A94E6C90E1", "Linux s390 root verity"); + AddType(0x834B, "B325BFBE-C7BE-4AB8-8357-139E652D2F6B", "Linux s390x root verity"); + AddType(0x834C, "966061EC-28E4-4B2E-B4A5-1F0A825A1D84", "Linux TILE-Gx root verity"); + AddType(0x834D, "8CCE0D25-C0D0-4A44-BD87-46331BF1DF67", "Linux Alpha /usr verity"); + AddType(0x834E, "FCA0598C-D880-4591-8C16-4EDA05C7347C", "Linux ARC /usr verity"); + AddType(0x834F, "F46B2C26-59AE-48F0-9106-C50ED47F673D", "Linux LoongArch /usr verity"); + AddType(0x8350, "6E5A1BC8-D223-49B7-BCA8-37A5FCCEB996", "Linux MIPS-32 BE /usr verity"); + AddType(0x8351, "81CF9D90-7458-4DF4-8DCF-C8A3A404F09B", "Linux MIPS-64 BE /usr verity"); + AddType(0x8352, "46B98D8D-B55C-4E8F-AAB3-37FCA7F80752", "Linux MIPS-32 LE /usr verity"); + AddType(0x8353, "3C3D61FE-B5F3-414D-BB71-8739A694A4EF", "Linux MIPS-64 LE /usr verity"); + AddType(0x8354, "5843D618-EC37-48D7-9F12-CEA8E08768B2", "Linux PA-RISC /usr verity"); + AddType(0x8355, "EE2B9983-21E8-4153-86D9-B6901A54D1CE", "Linux PowerPC-64 LE /usr verity"); + AddType(0x8356, "BDB528A5-A259-475F-A87D-DA53FA736A07", "Linux PowerPC-64 BE /usr verity"); + AddType(0x8357, "DF765D00-270E-49E5-BC75-F47BB2118B09", "Linux PowerPC-32 /usr verity"); + AddType(0x8358, "CB1EE4E3-8CD0-4136-A0A4-AA61A32E8730", "Linux RISC-V-32 /usr verity"); + AddType(0x8359, "8F1056BE-9B05-47C4-81D6-BE53128E5B54", "Linux RISC-V-64 /usr verity"); + AddType(0x835A, "B663C618-E7BC-4D6D-90AA-11B756BB1797", "Linux s390 /usr verity"); + AddType(0x835B, "31741CC4-1A2A-4111-A581-E00B447D2D06", "Linux s390x /usr verity"); + AddType(0x835C, "2FB4BF56-07FA-42DA-8132-6B139F2026AE", "Linux TILE-Gx /usr verity"); + AddType(0x835D, "D46495B7-A053-414F-80F7-700C99921EF8", "Linux Alpha root verity signature"); + AddType(0x835E, "143A70BA-CBD3-4F06-919F-6C05683A78BC", "Linux ARC root verity signature"); + AddType(0x835F, "42B0455F-EB11-491D-98D3-56145BA9D037", "Linux ARM32 root verity signature"); + AddType(0x8360, "6DB69DE6-29F4-4758-A7A5-962190F00CE3", "Linux ARM64 root verity signature"); + AddType(0x8361, "E98B36EE-32BA-4882-9B12-0CE14655F46A", "Linux IA-64 root verity signature"); + AddType(0x8362, "5AFB67EB-ECC8-4F85-AE8E-AC1E7C50E7D0", "Linux LoongArch root verity signature"); + AddType(0x8363, "BBA210A2-9C5D-45EE-9E87-FF2CCBD002D0", "Linux MIPS-32 BE root verity signature"); + AddType(0x8364, "43CE94D4-0F3D-4999-8250-B9DEAFD98E6E", "Linux MIPS-64 BE root verity signature"); + AddType(0x8365, "C919CC1F-4456-4EFF-918C-F75E94525CA5", "Linux MIPS-32 LE root verity signature"); + AddType(0x8366, "904E58EF-5C65-4A31-9C57-6AF5FC7C5DE7", "Linux MIPS-64 LE root verity signature"); + AddType(0x8367, "15DE6170-65D3-431C-916E-B0DCD8393F25", "Linux PA-RISC root verity signature"); + AddType(0x8368, "D4A236E7-E873-4C07-BF1D-BF6CF7F1C3C6", "Linux PowerPC-64 LE root verity signature"); + AddType(0x8369, "F5E2C20C-45B2-4FFA-BCE9-2A60737E1AAF", "Linux PowerPC-64 BE root verity signature"); + AddType(0x836A, "1B31B5AA-ADD9-463A-B2ED-BD467FC857E7", "Linux PowerPC-32 root verity signature"); + AddType(0x836B, "3A112A75-8729-4380-B4CF-764D79934448", "Linux RISC-V-32 root verity signature"); + AddType(0x836C, "EFE0F087-EA8D-4469-821A-4C2A96A8386A", "Linux RISC-V-64 root verity signature"); + AddType(0x836D, "3482388E-4254-435A-A241-766A065F9960", "Linux s390 root verity signature"); + AddType(0x836E, "C80187A5-73A3-491A-901A-017C3FA953E9", "Linux s390x root verity signature"); + AddType(0x836F, "B3671439-97B0-4A53-90F7-2D5A8F3AD47B", "Linux TILE-Gx root verity signature"); + AddType(0x8370, "41092B05-9FC8-4523-994F-2DEF0408B176", "Linux x86-64 root verity signature"); + AddType(0x8371, "5996FC05-109C-48DE-808B-23FA0830B676", "Linux x86 root verity signature"); + AddType(0x8372, "5C6E1C76-076A-457A-A0FE-F3B4CD21CE6E", "Linux Alpha /usr verity signature"); + AddType(0x8373, "94F9A9A1-9971-427A-A400-50CB297F0F35", "Linux ARC /usr verity signature"); + AddType(0x8374, "D7FF812F-37D1-4902-A810-D76BA57B975A", "Linux ARM32 /usr verity signature"); + AddType(0x8375, "C23CE4FF-44BD-4B00-B2D4-B41B3419E02A", "Linux ARM64 /usr verity signature"); + AddType(0x8376, "8DE58BC2-2A43-460D-B14E-A76E4A17B47F", "Linux IA-64 /usr verity signature"); + AddType(0x8377, "B024F315-D330-444C-8461-44BBDE524E99", "Linux LoongArch /usr verity signature"); + AddType(0x8378, "97AE158D-F216-497B-8057-F7F905770F54", "Linux MIPS-32 BE /usr verity signature"); + AddType(0x8379, "05816CE2-DD40-4AC6-A61D-37D32DC1BA7D", "Linux MIPS-64 BE /usr verity signature"); + AddType(0x837A, "3E23CA0B-A4BC-4B4E-8087-5AB6A26AA8A9", "Linux MIPS-32 LE /usr verity signature"); + AddType(0x837B, "F2C2C7EE-ADCC-4351-B5C6-EE9816B66E16", "Linux MIPS-64 LE /usr verity signature"); + AddType(0x837C, "450DD7D1-3224-45EC-9CF2-A43A346D71EE", "Linux PA-RISC /usr verity signature"); + AddType(0x837D, "C8BFBD1E-268E-4521-8BBA-BF314C399557", "Linux PowerPC-64 LE /usr verity signature"); + AddType(0x837E, "0B888863-D7F8-4D9E-9766-239FCE4D58AF", "Linux PowerPC-64 BE /usr verity signature"); + AddType(0x837F, "7007891D-D371-4A80-86A4-5CB875B9302E", "Linux PowerPC-32 /usr verity signature"); + AddType(0x8380, "C3836A13-3137-45BA-B583-B16C50FE5EB4", "Linux RISC-V-32 /usr verity signature"); + AddType(0x8381, "D2F9000A-7A18-453F-B5CD-4D32F77A7B32", "Linux RISC-V-64 /usr verity signature"); + AddType(0x8382, "17440E4F-A8D0-467F-A46E-3912AE6EF2C5", "Linux s390 /usr verity signature"); + AddType(0x8383, "3F324816-667B-46AE-86EE-9B0C0C6C11B4", "Linux s390x /usr verity signature"); + AddType(0x8384, "4EDE75E2-6CCC-4CC8-B9C7-70334B087510", "Linux TILE-Gx /usr verity signature"); + AddType(0x8385, "E7BB33FB-06CF-4E81-8273-E543B413E2E2", "Linux x86-64 /usr verity signature"); + AddType(0x8386, "974A71C0-DE41-43C3-BE5D-5C5CCD1AD2C0", "Linux x86 /usr verity signature"); // Used by Intel Rapid Start technology AddType(0x8400, "D3BFE2DE-3DAF-11DF-BA40-E3A556D89593", "Intel Rapid Start"); diff --git a/sgdisk.8 b/sgdisk.8 index b966a13..b0757f3 100644 --- a/sgdisk.8 +++ b/sgdisk.8 @@ -1,6 +1,6 @@ -.\" Copyright 2011-2022 Roderick W. Smith (rodsmith@rodsbooks.com) +.\" Copyright 2011-2024 Roderick W. Smith (rodsmith@rodsbooks.com) .\" May be distributed under the GNU General Public License -.TH "SGDISK" "8" "1.0.9" "Roderick W. Smith" "GPT fdisk Manual" +.TH "SGDISK" "8" "1.0.10" "Roderick W. Smith" "GPT fdisk Manual" .SH "NAME" sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix .SH "SYNOPSIS" @@ -23,7 +23,7 @@ recovery options require you to understand the distinctions between the main and backup data, as well as between the GPT headers and the partition tables. For information on MBR vs. GPT, as well as GPT terminology and structure, see the extended \fBgdisk\fR documentation at -\fIhttp://www.rodsbooks.com/gdisk/\fR or consult Wikipedia. +\fIhttps://www.rodsbooks.com/gdisk/\fR or consult Wikipedia. The \fBsgdisk\fR program employs a user interface that's based entirely on the command line, making it suitable for use in scripts or by experts who @@ -304,14 +304,24 @@ with the current final partition being aligned, and if \fBsgdisk\fR is asked to create a partition in that space, then it will \fBnot\fR be end\-aligned. .TP -.B \-j, \-\-adjust\-main\-table=sector -Adjust the location of the main partition table. This value is normally 2, +.B \-j, \-\-move\-main\-table=sector +Sets the start sector of the main partition table. This value is normally 2, but it may need to be increased in some cases, such as when a system\-on\-chip (SoC) is hard\-coded to read boot code from sector 2. I recommend against adjusting this value unless doing so is absolutely necessary. -.TP +.TP +.B \-k, \-\-move\-backup\-table=sector +Sets the start sector of the second/backup partition table. The backup table +is usually placed just before the last sector, which holds the backup header. +The default value is thus the size of the disk, minus one, minus the total +size of the partition table (in sectors, usually 32). +There are probably very few reasons to ever change this, and while the EFI +standard does not mandate it, most tooling assumes the backup table to be at +the very end of the disk. + +.TP .B \-l, \-\-load\-backup=file Load partition data from a backup file. This option is the reverse of the \fI\-b\fR option. Note that restoring partition data from anything @@ -370,8 +380,11 @@ to use the first available partition number. Subsequent uses of the .B \-N, \-\-largest\-new=num Create a new partition that fills the largest available block of space on the disk. You can use the \fI\-a\fR (\fI\-\-set\-alignment\fR) option to -adjust the alignment, if desired. A num value of 0 causes the program to -use the first available partition number. +adjust the alignment, if desired. A num value of 0 causes the program to use +the first available partition number. Subsequent uses of the \fI\-A\fR +(\fI\-\-attributes\fR), \fI\-c\fR (\fI\-\-change\-name\fR), \fI\-t\fR +(\fI\-\-typecode\fR), and \fI\-u\fR (\fI\-\-partition\-guid\fR) options may +also use \fI0\fR to refer to the same partition. .TP .B \-o, \-\-clear @@ -632,11 +645,11 @@ Contributors: .BR sfdisk (8), .BR fixparts (8). -\fIhttp://en.wikipedia.org/wiki/GUID_Partition_Table\fR +\fIhttps://en.wikipedia.org/wiki/GUID_Partition_Table\fR -\fIhttp://developer.apple.com/technotes/tn2006/tn2166.html\fR +\fIhttps://developer.apple.com/technotes/tn2006/tn2166.html\fR -\fIhttp://www.rodsbooks.com/gdisk/\fR +\fIhttps://www.rodsbooks.com/gdisk/\fR .SH "AVAILABILITY" The \fBsgdisk\fR command is part of the \fIGPT fdisk\fR package and is diff --git a/support.cc b/support.cc index 393427c..4449364 100644 --- a/support.cc +++ b/support.cc @@ -3,7 +3,7 @@ // Primarily by Rod Smith, February 2009, but with a few functions // copied from other sources (see attributions below). -/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed +/* This program is copyright (c) 2009-2024 by Roderick W. Smith. It is distributed under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ #define __STDC_LIMIT_MACROS @@ -128,6 +128,8 @@ char GetYN(void) { // inValue works out to something outside the range low-high, returns the // computed value; the calling function is responsible for checking the // validity of this value. +// If inValue contains a decimal number (e.g., "9.5G"), quietly truncate it +// (to "9G" in this example). // NOTE: There's a difference in how GCC and VC++ treat oversized values // (say, "999999999999999999999") read via the ">>" operator; GCC turns // them into the maximum value for the type, whereas VC++ turns them into @@ -162,7 +164,15 @@ uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, badInput = 1; inString >> response >> suffix; suffix = toupper(suffix); - + foundAt = suffixes.find(suffix); + // If suffix is invalid, try to find a valid one. Done because users + // sometimes enter decimal numbers; when they do, suffix becomes + // '.', and we need to truncate the number and find the real suffix. + while (foundAt > (suffixes.length() - 1) && inString.peek() != -1) { + inString >> suffix; + foundAt = suffixes.find(suffix); + suffix = toupper(suffix); + } // If no response, or if response == 0, use default (def) if ((inValue.length() == 0) || (response == 0)) { response = def; @@ -171,7 +181,6 @@ uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, } // if // Find multiplication and division factors for the suffix - foundAt = suffixes.find(suffix); if (foundAt != string::npos) { bytesPerUnit = UINT64_C(1) << (10 * (foundAt + 1)); mult = bytesPerUnit / sSize; diff --git a/support.h b/support.h index 8ba9ad1..fd1cd32 100644 --- a/support.h +++ b/support.h @@ -8,7 +8,7 @@ #include #include -#define GPTFDISK_VERSION "1.0.9" +#define GPTFDISK_VERSION "1.0.10" #if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__) // Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64 -- Gitee From b9ee45f36524cf346f1107ddf569eb31f5cb797b Mon Sep 17 00:00:00 2001 From: lianwei Date: Mon, 20 May 2024 10:52:50 +0800 Subject: [PATCH 2/2] gptfdisk: reformat Signed-off-by: lianwei --- diskio-windows.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/diskio-windows.cc b/diskio-windows.cc index 15e6c5a..4278e93 100644 --- a/diskio-windows.cc +++ b/diskio-windows.cc @@ -113,9 +113,9 @@ int DiskIO::OpenForWrite(void) { // Close the disk device. Note that this does NOT erase the stored filenames, // so the file can be re-opened without specifying the filename. void DiskIO::Close(void) { - if (isOpen) { - CloseHandle(fd); - fd = INVALID_HANDLE_VALUE; + if (isOpen) { + CloseHandle(fd); + fd = INVALID_HANDLE_VALUE; } isOpen = 0; openForWrite = 0; -- Gitee