diff options
author | Rod Smith <rodsmith@rodsbooks.com> | 2022-01-29 10:51:02 -0500 |
---|---|---|
committer | Rod Smith <rodsmith@rodsbooks.com> | 2022-01-29 10:51:02 -0500 |
commit | fd60f743628e16180daf3b1719974fa4dadf8f90 (patch) | |
tree | dcad6ad1cc1d304a2c4c3d1bd1d4315e4dad62e6 | |
parent | 43b3df969cbbf3da0c043afdc9939da97bbd8d68 (diff) | |
download | sgdisk-fd60f743628e16180daf3b1719974fa4dadf8f90.tar.gz |
Add end-alignment feature.
-rw-r--r-- | NEWS | 10 | ||||
-rw-r--r-- | cgdisk.8 | 9 | ||||
-rw-r--r-- | gdisk.8 | 16 | ||||
-rw-r--r-- | gpt.cc | 34 | ||||
-rw-r--r-- | gpt.h | 4 | ||||
-rw-r--r-- | gptcl.cc | 15 | ||||
-rw-r--r-- | gptcl.h | 3 | ||||
-rw-r--r-- | gptcurses.cc | 19 | ||||
-rw-r--r-- | gpttext.cc | 36 | ||||
-rw-r--r-- | gpttext.h | 3 | ||||
-rw-r--r-- | sgdisk.8 | 19 | ||||
-rw-r--r-- | support.cc | 40 | ||||
-rw-r--r-- | support.h | 7 |
13 files changed, 141 insertions, 74 deletions
@@ -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): ----------------- @@ -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 @@ -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 @@ -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; @@ -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); @@ -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)) { @@ -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.... @@ -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); @@ -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 @@ -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.... |