summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRod Smith <rodsmith@rodsbooks.com>2022-01-29 10:51:02 -0500
committerRod Smith <rodsmith@rodsbooks.com>2022-01-29 10:51:02 -0500
commitfd60f743628e16180daf3b1719974fa4dadf8f90 (patch)
treedcad6ad1cc1d304a2c4c3d1bd1d4315e4dad62e6
parent43b3df969cbbf3da0c043afdc9939da97bbd8d68 (diff)
downloadsgdisk-fd60f743628e16180daf3b1719974fa4dadf8f90.tar.gz
Add end-alignment feature.
-rw-r--r--NEWS10
-rw-r--r--cgdisk.89
-rw-r--r--gdisk.816
-rw-r--r--gpt.cc34
-rw-r--r--gpt.h4
-rw-r--r--gptcl.cc15
-rw-r--r--gptcl.h3
-rw-r--r--gptcurses.cc19
-rw-r--r--gpttext.cc36
-rw-r--r--gpttext.h3
-rw-r--r--sgdisk.819
-rw-r--r--support.cc40
-rw-r--r--support.h7
13 files changed, 141 insertions, 74 deletions
diff --git a/NEWS b/NEWS
index 4009a5b..201eff8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,17 @@
-1.0.9 (?/?/2021):
+1.0.9 (?/?/2022):
-----------------
- Removed stray debugging code that caused "partNum is {x}" to be printed
when changing a partition's name with sgdisk (-c/--change-name).
+- Added support for aligning partitions' end points, as well as their start
+ points. This support affects the default partition size when using 'n' in
+ gdisk; it affects the default partition size in cgdisk; and it's activated
+ by the new '-I' option in sgdisk. See the programs' respective man pages
+ for details. This feature is intended to help with LUKS2 encryption, which
+ reacts badly to partitions that are not sized as exact multiples of the
+ encryption block size.
+
1.0.8 (6/9/2021):
-----------------
diff --git a/cgdisk.8 b/cgdisk.8
index 998b8f4..0b51fc1 100644
--- a/cgdisk.8
+++ b/cgdisk.8
@@ -186,8 +186,13 @@ new disks, GPT fdisk attempts to align partitions on 1 MiB boundaries
performance for all of these disk types. On pre\-partitioned disks, GPT
fdisk attempts to identify the alignment value used on that disk, but will
set 8-sector alignment on disks larger than 300 GB even if lesser alignment
-values are detected. In either case, it can be changed by using this
-option.
+values are detected. In either case, it can be changed by using this option.
+The alignment value also affects the default end sector value when creating
+a new partition; it will be aligned to one less than a multiple of the
+alignment value, when possible. This should keep partitions a multiple of
+the alignment value in size. Some disk encryption tools require partitions
+to be sized to some value, typically 4096 bytes, so the default alignment of
+1 MiB works well for them.
.TP
.B Backup
diff --git a/gdisk.8 b/gdisk.8
index 50bc6c6..75a3e82 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -210,7 +210,8 @@ default start sector, or \fI\fB\-200M\fR\fR to specify a point 200MiB
before the last available sector. Pressing the Enter key with no input
specifies the default value, which is the start of the largest available
block for the start sector and the end of the same block for the end
-sector.
+sector. Default start and end points may be adjusted to optimize partition
+alignment.
.TP
.B o
@@ -491,13 +492,18 @@ Change the sector alignment value. Disks with more logical sectors per
physical sectors (such as modern Advanced Format drives), some RAID
configurations, and many SSD devices, can suffer performance problems if
partitions are not aligned properly for their internal data structures. On
-new disks, GPT fdisk attempts to align partitions on 1 MiB boundaries
-(2048\-sectors on disks with 512-byte sectors) by default, which optimizes
+new disks, GPT fdisk attempts to align partitions on 1 MiB boundaries (2048
+sectors on disks with 512-byte sectors) by default, which optimizes
performance for all of these disk types. On pre\-partitioned disks, GPT
fdisk attempts to identify the alignment value used on that disk, but will
set 8-sector alignment on disks larger than 300 GB even if lesser alignment
-values are detected. In either case, it can be changed by using this
-option.
+values are detected. In either case, it can be changed by using this option.
+The alignment value also affects the default end sector value when creating
+a new partition; it will be aligned to one less than a multiple of the
+alignment value, if possible. This should keep partitions a multiple of the
+alignment value in size. Some disk encryption tools require partitions to be
+sized to some value, typically 4096 bytes, so the default alignment of 1 MiB
+works well for them.
.TP
.B m
diff --git a/gpt.cc b/gpt.cc
index 51d482c..5ccc5c5 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-2018 by Roderick W. Smith. It is distributed
+/* This program is copyright (c) 2009-2022 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
@@ -410,6 +410,11 @@ int GPTData::Verify(void) {
<< "in degraded performance on some modern (2009 and later) hard disks.\n";
alignProbs++;
} // if
+ if ((partitions[i].IsUsed()) && ((partitions[i].GetLastLBA() + 1) % testAlignment) != 0) {
+ cout << "\nCaution: Partition " << i + 1 << " doesn't end on a "
+ << testAlignment << "-sector boundary. This may\nresult "
+ << "in problems with some disk encryption tools.\n";
+ } // if
} // for
if (alignProbs > 0)
cout << "\nConsult http://www.ibm.com/developerworks/linux/library/l-4kb-sector-disks/\n"
@@ -2334,18 +2339,28 @@ uint64_t GPTData::FindLastAvailable(void) {
} // GPTData::FindLastAvailable()
// Find the last available block in the free space pointed to by start.
-uint64_t GPTData::FindLastInFree(uint64_t start) {
- uint64_t nearestStart;
+// If align == true, returns the last sector that's aligned on the
+// system alignment value (unless that's less than the start value);
+// if align == false, returns the last available block regardless of
+// alignment. (The align variable is set to false by default.)
+uint64_t GPTData::FindLastInFree(uint64_t start, bool align) {
+ uint64_t nearestEnd, endPlus;
uint32_t i;
- nearestStart = mainHeader.lastUsableLBA;
+ nearestEnd = mainHeader.lastUsableLBA;
for (i = 0; i < numParts; i++) {
- if ((nearestStart > partitions[i].GetFirstLBA()) &&
+ if ((nearestEnd > partitions[i].GetFirstLBA()) &&
(partitions[i].GetFirstLBA() > start)) {
- nearestStart = partitions[i].GetFirstLBA() - 1;
+ nearestEnd = partitions[i].GetFirstLBA() - 1;
} // if
} // for
- return (nearestStart);
+ if (align) {
+ endPlus = nearestEnd + 1;
+ if (Align(&endPlus) && IsFree(endPlus - 1) && (endPlus > start)) {
+ nearestEnd = endPlus - 1;
+ } // if
+ } // if
+ return (nearestEnd);
} // GPTData::FindLastInFree()
// Finds the total number of free blocks, the number of segments in which
@@ -2422,7 +2437,10 @@ int GPTData::IsUsedPartNum(uint32_t partNum) {
***********************************************************/
// Set partition alignment value; partitions will begin on multiples of
-// the specified value
+// the specified value, and the default end values will be set so that
+// partition sizes are multiples of this value in cgdisk and gdisk, too.
+// (In sgdisk, end-alignment is done only if the '-I' command-line option
+// is used.)
void GPTData::SetAlignment(uint32_t n) {
if (n > 0) {
sectorAlignment = n;
diff --git a/gpt.h b/gpt.h
index 9ba013b..cf05f59 100644
--- a/gpt.h
+++ b/gpt.h
@@ -1,7 +1,7 @@
/* gpt.h -- GPT and data structure definitions, types, and
functions */
-/* This program is copyright (c) 2009-2011 by Roderick W. Smith. It is distributed
+/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
#ifndef __GPTSTRUCTS
@@ -185,7 +185,7 @@ public:
uint64_t FindFirstUsedLBA(void);
uint64_t FindFirstInLargest(void);
uint64_t FindLastAvailable();
- uint64_t FindLastInFree(uint64_t start);
+ uint64_t FindLastInFree(uint64_t start, bool align = false);
uint64_t FindFreeBlocks(uint32_t *numSegments, uint64_t *largestSegment);
int IsFree(uint64_t sector, uint32_t *partNum = NULL);
int IsFreePartNum(uint32_t partNum);
diff --git a/gptcl.cc b/gptcl.cc
index 2e75db7..3995093 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-2014 Roderick W. Smith
+ Copyright (C) 2010-2022 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
@@ -30,6 +30,7 @@ GPTDataCL::GPTDataCL(void) {
attributeOperation = backupFile = partName = hybrids = newPartInfo = NULL;
mbrParts = twoParts = outDevice = typeCode = partGUID = diskGUID = NULL;
alignment = DEFAULT_ALIGNMENT;
+ alignEnd = false;
deletePartNum = infoPartNum = largestPartNum = bsdPartNum = 0;
tableSize = GPT_SIZE;
} // GPTDataCL constructor
@@ -90,6 +91,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
{"randomize-guids", 'G', POPT_ARG_NONE, NULL, 'G', "randomize disk and partition GUIDs", ""},
{"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"},
{"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", ""},
@@ -272,6 +274,9 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
case 'i':
ShowPartDetails(infoPartNum - 1);
break;
+ case 'I':
+ alignEnd = true;
+ break;
case 'j':
if (MoveMainTable(mainTableLBA)) {
JustLooking(0);
@@ -307,9 +312,9 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
newPartNum = FindFirstFreePart();
low = FindFirstInLargest();
Align(&low);
- high = FindLastInFree(low);
- startSector = IeeeToInt(GetString(newPartInfo, 2), sSize, low, high, low);
- endSector = IeeeToInt(GetString(newPartInfo, 3), sSize, startSector, high, high);
+ high = FindLastInFree(low, alignEnd);
+ startSector = IeeeToInt(GetString(newPartInfo, 2), sSize, low, high, sectorAlignment, low);
+ endSector = IeeeToInt(GetString(newPartInfo, 3), sSize, startSector, high, sectorAlignment, high);
if (CreatePartition(newPartNum, startSector, endSector)) {
saveData = 1;
} else {
@@ -323,7 +328,7 @@ int GPTDataCL::DoOptions(int argc, char* argv[]) {
JustLooking(0);
startSector = FindFirstInLargest();
Align(&startSector);
- endSector = FindLastInFree(startSector);
+ endSector = FindLastInFree(startSector, alignEnd);
if (largestPartNum <= 0)
largestPartNum = FindFirstFreePart() + 1;
if (CreatePartition(largestPartNum - 1, startSector, endSector)) {
diff --git a/gptcl.h b/gptcl.h
index 610ca5f..183b846 100644
--- a/gptcl.h
+++ b/gptcl.h
@@ -1,7 +1,7 @@
/*
Implementation of GPTData class derivative with popt-based command
line processing
- Copyright (C) 2010-2013 Roderick W. Smith
+ Copyright (C) 2010-2022 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
@@ -34,6 +34,7 @@ class GPTDataCL : public GPTData {
char *newPartInfo, *mbrParts, *twoParts, *outDevice, *typeCode;
char *partGUID, *diskGUID;
int alignment, deletePartNum, infoPartNum, largestPartNum, bsdPartNum;
+ bool alignEnd;
uint32_t tableSize;
poptContext poptCon;
diff --git a/gptcurses.cc b/gptcurses.cc
index 1fbaad2..2ffcf4f 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-2018 Roderick W. Smith
+ * Copyright (C) 2011-2022 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
@@ -430,12 +430,18 @@ void GPTDataCurses::Verify(void) {
// Create a new partition in the space pointed to by currentSpace.
void GPTDataCurses::MakeNewPart(void) {
- uint64_t size, newFirstLBA = 0, newLastLBA = 0;
+ uint64_t size, newFirstLBA = 0, newLastLBA = 0, lastAligned;
int partNum;
char inLine[80];
move(LINES - 4, 0);
clrtobot();
+ lastAligned = currentSpace->lastLBA + 1;
+ Align(&lastAligned);
+ lastAligned--;
+ // Discard end-alignment attempt if it's giving us an invalid end point....
+ if (!IsFree(lastAligned))
+ lastAligned = currentSpace->lastLBA;
while ((newFirstLBA < currentSpace->firstLBA) || (newFirstLBA > currentSpace->lastLBA)) {
move(LINES - 4, 0);
clrtoeol();
@@ -445,10 +451,13 @@ void GPTDataCurses::MakeNewPart(void) {
echo();
getnstr(inLine, 79);
noecho();
- newFirstLBA = IeeeToInt(inLine, blockSize, currentSpace->firstLBA, currentSpace->lastLBA, newFirstLBA);
+ newFirstLBA = IeeeToInt(inLine, blockSize, currentSpace->firstLBA, currentSpace->lastLBA, sectorAlignment, newFirstLBA);
Align(&newFirstLBA);
} // while
- size = currentSpace->lastLBA - newFirstLBA + 1;
+ if (newFirstLBA > lastAligned)
+ size = currentSpace->lastLBA - newFirstLBA + 1;
+ else
+ size = lastAligned - newFirstLBA + 1;
while ((newLastLBA > currentSpace->lastLBA) || (newLastLBA < newFirstLBA)) {
move(LINES - 3, 0);
clrtoeol();
@@ -456,7 +465,7 @@ void GPTDataCurses::MakeNewPart(void) {
echo();
getnstr(inLine, 79);
noecho();
- newLastLBA = newFirstLBA + IeeeToInt(inLine, blockSize, 1, size, size) - 1;
+ newLastLBA = newFirstLBA + IeeeToInt(inLine, blockSize, 1, size, sectorAlignment, size) - 1;
} // while
partNum = FindFirstFreePart();
if (CreatePartition(partNum, newFirstLBA, newLastLBA)) { // created OK; set type code & name....
diff --git a/gpttext.cc b/gpttext.cc
index b1d9361..170a169 100644
--- a/gpttext.cc
+++ b/gpttext.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2010-2018 <Roderick W. Smith>
+ Copyright (C) 2010-2022 <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
@@ -199,7 +199,7 @@ void GPTDataTextUI::MoveMainTable(void) {
// Interactively create a partition
void GPTDataTextUI::CreatePartition(void) {
- uint64_t firstBlock, firstInLargest, lastBlock, sector, origSector;
+ uint64_t firstBlock, firstInLargest, lastBlock, sector, origSector, lastAligned;
uint32_t firstFreePart = 0;
ostringstream prompt1, prompt2, prompt3;
int partNum;
@@ -229,7 +229,7 @@ void GPTDataTextUI::CreatePartition(void) {
prompt2 << "First sector (" << firstBlock << "-" << lastBlock << ", default = "
<< firstInLargest << ") or {+-}size{KMGTP}: ";
do {
- sector = GetSectorNum(firstBlock, lastBlock, firstInLargest, blockSize, prompt2.str());
+ sector = GetSectorNum(firstBlock, lastBlock, firstInLargest, prompt2.str());
} while (IsFree(sector) == 0);
origSector = sector;
if (Align(&sector)) {
@@ -239,15 +239,15 @@ void GPTDataTextUI::CreatePartition(void) {
if (!beQuiet)
cout << "Use 'l' on the experts' menu to adjust alignment\n";
} // if
- // Align(&sector); // Align sector to correct multiple
firstBlock = sector;
// Get last block for new partitions...
- lastBlock = FindLastInFree(firstBlock);
+ lastBlock = FindLastInFree(firstBlock, false);
+ lastAligned = FindLastInFree(firstBlock, true);
prompt3 << "Last sector (" << firstBlock << "-" << lastBlock << ", default = "
- << lastBlock << ") or {+-}size{KMGTP}: ";
+ << lastAligned << ") or {+-}size{KMGTP}: ";
do {
- sector = GetSectorNum(firstBlock, lastBlock, lastBlock, blockSize, prompt3.str());
+ sector = GetSectorNum(firstBlock, lastBlock, lastAligned, prompt3.str());
} while (IsFree(sector) == 0);
lastBlock = sector;
@@ -548,6 +548,28 @@ int GPTDataTextUI::XFormToMBR(void) {
return protectiveMBR.DoMenu();
} // GPTDataTextUI::XFormToMBR()
+// Obtains a sector number, between low and high, from the
+// user, accepting values prefixed by "+" to add sectors to low,
+// or the same with "K", "M", "G", "T", or "P" as suffixes to add
+// kibibytes, mebibytes, gibibytes, tebibytes, or pebibytes,
+// respectively. If a "-" prefix is used, use the high value minus
+// the user-specified number of sectors (or KiB, MiB, etc.). Use the
+// def value as the default if the user just hits Enter.
+uint64_t GPTDataTextUI::GetSectorNum(uint64_t low, uint64_t high, uint64_t def,
+ const string & prompt) {
+ uint64_t response;
+ char line[255];
+
+ do {
+ cout << prompt;
+ cin.getline(line, 255);
+ if (!cin.good())
+ exit(5);
+ response = IeeeToInt(line, blockSize, low, high, sectorAlignment, def);
+ } while ((response < low) || (response > high));
+ return response;
+} // GPTDataTextUI::GetSectorNum()
+
/******************************************************
* *
* Display informational messages for the user.... *
diff --git a/gpttext.h b/gpttext.h
index 6bd22cf..36a17f9 100644
--- a/gpttext.h
+++ b/gpttext.h
@@ -1,6 +1,6 @@
/*
Implementation of GPTData class derivative with basic text-mode interaction
- Copyright (C) 2010-2018 Roderick W. Smith
+ Copyright (C) 2010-2022 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
@@ -55,6 +55,7 @@ class GPTDataTextUI : public GPTData {
void ShowDetails(void);
void MakeHybrid(void);
int XFormToMBR(void); // convert GPT to MBR, wiping GPT afterwards. Returns 1 if successful
+ uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, const string & prompt);
// An informational function....
void WarnAboutIffyMBRPart(int partNum);
diff --git a/sgdisk.8 b/sgdisk.8
index c878348..23fc943 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -154,7 +154,10 @@ to sectors that are multiples of this value, which defaults to 1 MiB (2048
on disks with 512-byte sectors) on freshly formatted disks. This alignment
value is necessary to obtain optimum performance with Western Digital
Advanced Format and similar drives with larger physical than logical sector
-sizes, with some types of RAID arrays, and with SSD devices.
+sizes, with some types of RAID arrays, and with SSD devices. When the
+\fI\-I\fR option is used, this same alignment value is used to determine
+partition end points; but partitions end at one less than a multiple of this
+value, to keep the partition length a multiple of this value.
.TP
.B \-A, \-\-attributes=list|[partnum:show|or|nand|xor|=|set|clear|toggle|get[:bitnum|hexbitmask]]
@@ -280,7 +283,7 @@ is usually correct for Windows partitions. If the active/bootable flag should
be set, you must do so in another program, such as \fBfdisk\fR. The \fBgdisk\fR
program offers additional hybrid MBR creation options.
-.TP
+.TP
.B \-i, \-\-info=partnum
Show detailed partition information. The summary information produced by
the \fI\-p\fR command necessarily omits many details, such as the partition's
@@ -289,6 +292,18 @@ internal partition type code to a plain type name. The \fI\-i\fR option
displays this information for a single partition.
.TP
+.B \-I, \-\-align\-end
+When possible, align the end points of partitions to one less than a
+multiple of the alignment value. When both start and end points are aligned,
+partitions should be multiples of the alignment value in size, which is
+necessary for some partition encryption tools to function correctly. This
+option applies to all partitions created \fBafter\fR this option on the
+command line. Note that this alignment is not always possible; for instance,
+if the free space at the end of a disk is less than the alignment value,
+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,
but it may need to be increased in some cases, such as when a
diff --git a/support.cc b/support.cc
index 99fdffe..0d3bd6f 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-2018 by Roderick W. Smith. It is distributed
+/* This program is copyright (c) 2009-2022 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
@@ -113,34 +113,11 @@ char GetYN(void) {
return response;
} // GetYN(void)
-// Obtains a sector number, between low and high, from the
-// user, accepting values prefixed by "+" to add sectors to low,
-// or the same with "K", "M", "G", "T", or "P" as suffixes to add
-// kilobytes, megabytes, gigabytes, terabytes, or petabytes,
-// respectively. If a "-" prefix is used, use the high value minus
-// the user-specified number of sectors (or KiB, MiB, etc.). Use the
-// def value as the default if the user just hits Enter. The sSize is
-// the sector size of the device.
-uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize,
- const string & prompt) {
- uint64_t response;
- char line[255];
-
- do {
- cout << prompt;
- cin.getline(line, 255);
- if (!cin.good())
- exit(5);
- response = IeeeToInt(line, sSize, low, high, def);
- } while ((response < low) || (response > high));
- return response;
-} // GetSectorNum()
-
// Convert an IEEE-1541-2002 value (K, M, G, T, P, or E) to its equivalent in
// number of sectors. If no units are appended, interprets as the number
// of sectors; otherwise, interprets as number of specified units and
// converts to sectors. For instance, with 512-byte sectors, "1K" converts
-// to 2. If value includes a "+", adds low and subtracts 1; if SIValue
+// to 2. If value includes a "+", adds low and subtracts 1; if inValue
// inclues a "-", subtracts from high. If IeeeValue is empty, returns def.
// Returns final sector value. In case inValue is invalid, returns 0 (a
// sector value that's always in use on GPT and therefore invalid); and if
@@ -153,7 +130,7 @@ uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize,
// 0 values. The result is that IeeeToInt() returns UINT64_MAX when
// compiled with GCC (and so the value is rejected), whereas when VC++
// is used, the default value is returned.
-uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, uint64_t def) {
+uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high, uint32_t sectorAlignment, uint64_t def) {
uint64_t response = def, bytesPerUnit, mult = 1, divide = 1;
size_t foundAt = 0;
char suffix = ' ', plusFlag = ' ';
@@ -208,11 +185,12 @@ uint64_t IeeeToInt(string inValue, uint64_t sSize, uint64_t low, uint64_t high,
} // if/elseif
if (plusFlag == '+') {
- // Recompute response based on low part of range (if default == high
- // value, which should be the case when prompting for the end of a
- // range) or the defaut value (if default != high, which should be
- // the case for the first sector of a partition).
- if (def == high) {
+ // Recompute response based on low part of range (if default is within
+ // sectorAlignment sectors of high, which should be the case when
+ // prompting for the end of a range) or the defaut value (if default is
+ // further away from the high value, which should be the case for the
+ // first sector of a partition).
+ if ((high - def) < sectorAlignment) {
if (response > 0)
response--;
if (response > (UINT64_MAX - low))
diff --git a/support.h b/support.h
index 3648c4e..a61ddf4 100644
--- a/support.h
+++ b/support.h
@@ -1,4 +1,4 @@
-/* This program is copyright (c) 2009-2018 by Roderick W. Smith. It is distributed
+/* This program is copyright (c) 2009-2022 by Roderick W. Smith. It is distributed
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
#ifndef __GPTSUPPORT
@@ -8,7 +8,7 @@
#include <stdlib.h>
#include <string>
-#define GPTFDISK_VERSION "1.0.8"
+#define GPTFDISK_VERSION "1.0.8.2"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) & FreeBSD: disk IOCTLs are different, and there is no lseek64
@@ -74,8 +74,7 @@ using namespace std;
string ReadString(void);
uint64_t GetNumber(uint64_t low, uint64_t high, uint64_t def, const string & prompt);
char GetYN(void);
-uint64_t GetSectorNum(uint64_t low, uint64_t high, uint64_t def, uint64_t sSize, const std::string& prompt);
-uint64_t IeeeToInt(string IeeeValue, uint64_t sSize, uint64_t low, uint64_t high, uint64_t def = 0);
+uint64_t IeeeToInt(string IeeeValue, uint64_t sSize, uint64_t low, uint64_t high, uint32_t sectorAlignment, uint64_t def = 0);
string BytesToIeee(uint64_t size, uint32_t sectorSize);
unsigned char StrToHex(const string & input, unsigned int position);
int IsHex(string input); // Returns 1 if input can be hexadecimal number....