Add end-alignment feature.
This commit is contained in:
10
NEWS
10
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):
|
||||
-----------------
|
||||
|
||||
|
||||
9
cgdisk.8
9
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
|
||||
|
||||
16
gdisk.8
16
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
|
||||
|
||||
34
gpt.cc
34
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;
|
||||
|
||||
4
gpt.h
4
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);
|
||||
|
||||
15
gptcl.cc
15
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)) {
|
||||
|
||||
3
gptcl.h
3
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;
|
||||
|
||||
|
||||
17
gptcurses.cc
17
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
|
||||
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....
|
||||
|
||||
36
gpttext.cc
36
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(§or)) {
|
||||
@@ -239,15 +239,15 @@ void GPTDataTextUI::CreatePartition(void) {
|
||||
if (!beQuiet)
|
||||
cout << "Use 'l' on the experts' menu to adjust alignment\n";
|
||||
} // if
|
||||
// Align(§or); // 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.... *
|
||||
|
||||
@@ -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);
|
||||
|
||||
17
sgdisk.8
17
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]]
|
||||
@@ -288,6 +291,18 @@ unique GUID and the translation of \fBsgdisk\fR's
|
||||
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,
|
||||
|
||||
40
support.cc
40
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))
|
||||
|
||||
@@ -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....
|
||||
|
||||
Reference in New Issue
Block a user