Update to 0.3.4 version of the program
This commit is contained in:
27
CHANGELOG
27
CHANGELOG
@@ -1,3 +1,30 @@
|
|||||||
|
0.3.4:
|
||||||
|
------
|
||||||
|
|
||||||
|
- Fixed bug that enabled (possibly accidental) entry of MBR type codes of
|
||||||
|
0x00 in GPTData::MakeHybrid(). The fix also enables entry of default
|
||||||
|
type code by pressing the Enter key when prompted. Applied a similar
|
||||||
|
fix to the entry of the type code for the second protective partition,
|
||||||
|
if one is used.
|
||||||
|
|
||||||
|
- Fixed a typo: "sectors" was spelled "sectprs" in one spot!
|
||||||
|
|
||||||
|
- Fixed bug that caused default entry for end sector to be refused if an
|
||||||
|
initial value using a plus sign (e.g., "+20G") was also refused.
|
||||||
|
|
||||||
|
0.3.3:
|
||||||
|
------
|
||||||
|
|
||||||
|
- Gave users control over the way MBR partitions are assigned to slots in a
|
||||||
|
hybrid MBR setup; the original method (putting the 0xEE partition after
|
||||||
|
the real partitions) works well for non-boot disks, but both GRUB and
|
||||||
|
GRUB2 become confused by this type of setup, so it needs changing.
|
||||||
|
|
||||||
|
- Changed "blocks" to "sectors" in GPT and MBR table displays.
|
||||||
|
|
||||||
|
- Added "Boot" column to MBR table display; shows an asterisk (*) when the
|
||||||
|
partition's status is bootable.
|
||||||
|
|
||||||
0.3.2:
|
0.3.2:
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|||||||
2
gdisk.8
2
gdisk.8
@@ -510,7 +510,7 @@ entering data. When only one option is possible,
|
|||||||
usually bypasses the prompt entirely.
|
usually bypasses the prompt entirely.
|
||||||
|
|
||||||
.SH BUGS
|
.SH BUGS
|
||||||
As of August of 2009 (version 0.3.2),
|
As of August of 2009 (version 0.3.3),
|
||||||
.B gdisk
|
.B gdisk
|
||||||
should be considered early beta software. Known bugs and
|
should be considered early beta software. Known bugs and
|
||||||
limitations include:
|
limitations include:
|
||||||
|
|||||||
2
gdisk.cc
2
gdisk.cc
@@ -24,7 +24,7 @@ int main(int argc, char* argv[]) {
|
|||||||
int doMore = 1;
|
int doMore = 1;
|
||||||
char* device = NULL;
|
char* device = NULL;
|
||||||
|
|
||||||
printf("GPT fdisk (gdisk) version 0.3.2\n\n");
|
printf("GPT fdisk (gdisk) version 0.3.4\n\n");
|
||||||
|
|
||||||
if (argc == 2) { // basic usage
|
if (argc == 2) { // basic usage
|
||||||
if (SizesOK()) {
|
if (SizesOK()) {
|
||||||
|
|||||||
58
gpt.cc
58
gpt.cc
@@ -209,8 +209,11 @@ int GPTData::LoadPartitions(char* deviceFilename) {
|
|||||||
CheckGPTSize();
|
CheckGPTSize();
|
||||||
} else {
|
} else {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
fprintf(stderr, "Problem opening %s for reading!\n",
|
fprintf(stderr, "Problem opening %s for reading! Error is %d\n",
|
||||||
deviceFilename);
|
deviceFilename, errno);
|
||||||
|
if (errno == EACCES) { // User is probably not running as root
|
||||||
|
fprintf(stderr, "You must run this program as root or use sudo!\n");
|
||||||
|
} // if
|
||||||
} // if/else
|
} // if/else
|
||||||
return (allOK);
|
return (allOK);
|
||||||
} // GPTData::LoadPartitions()
|
} // GPTData::LoadPartitions()
|
||||||
@@ -466,14 +469,14 @@ void GPTData::DisplayGPTData(void) {
|
|||||||
totalFree = FindFreeBlocks(&i, &temp);
|
totalFree = FindFreeBlocks(&i, &temp);
|
||||||
printf("Total free space is %llu sectors (%s)\n", totalFree,
|
printf("Total free space is %llu sectors (%s)\n", totalFree,
|
||||||
BytesToSI(totalFree * (uint64_t) blockSize, sizeInSI));
|
BytesToSI(totalFree * (uint64_t) blockSize, sizeInSI));
|
||||||
printf("\nNumber Start (block) End (block) Size Code Name\n");
|
printf("\nNumber Start (sector) End (sector) Size Code Name\n");
|
||||||
for (i = 0; i < mainHeader.numParts; i++) {
|
for (i = 0; i < mainHeader.numParts; i++) {
|
||||||
if (partitions[i].firstLBA != 0) {
|
if (partitions[i].firstLBA != 0) {
|
||||||
BytesToSI(blockSize * (partitions[i].lastLBA - partitions[i].firstLBA + 1),
|
BytesToSI(blockSize * (partitions[i].lastLBA - partitions[i].firstLBA + 1),
|
||||||
sizeInSI);
|
sizeInSI);
|
||||||
printf("%4d %14lu %14lu ", i + 1, (unsigned long) partitions[i].firstLBA,
|
printf("%4d %14lu %14lu", i + 1, (unsigned long) partitions[i].firstLBA,
|
||||||
(unsigned long) partitions[i].lastLBA);
|
(unsigned long) partitions[i].lastLBA);
|
||||||
printf(" %-10s %04X ", sizeInSI,
|
printf(" %-10s %04X ", sizeInSI,
|
||||||
typeHelper.GUIDToID(partitions[i].partitionType));
|
typeHelper.GUIDToID(partitions[i].partitionType));
|
||||||
j = 0;
|
j = 0;
|
||||||
while ((partitions[i].name[j] != '\0') && (j < 44)) {
|
while ((partitions[i].name[j] != '\0') && (j < 44)) {
|
||||||
@@ -517,7 +520,7 @@ void GPTData::ShowPartDetails(uint32_t partNum) {
|
|||||||
partitions[partNum].lastLBA,
|
partitions[partNum].lastLBA,
|
||||||
BytesToSI(partitions[partNum].lastLBA * blockSize, temp));
|
BytesToSI(partitions[partNum].lastLBA * blockSize, temp));
|
||||||
size = (partitions[partNum].lastLBA - partitions[partNum].firstLBA + 1);
|
size = (partitions[partNum].lastLBA - partitions[partNum].firstLBA + 1);
|
||||||
printf("Partition size: %llu sectprs (%s)\n", (unsigned long long)
|
printf("Partition size: %llu sectors (%s)\n", (unsigned long long)
|
||||||
size, BytesToSI(size * ((uint64_t) blockSize), temp));
|
size, BytesToSI(size * ((uint64_t) blockSize), temp));
|
||||||
printf("Attribute flags: %016llx\n", (unsigned long long)
|
printf("Attribute flags: %016llx\n", (unsigned long long)
|
||||||
partitions[partNum].attributes);
|
partitions[partNum].attributes);
|
||||||
@@ -1312,9 +1315,10 @@ uint64_t GPTData::FindFreeBlocks(int *numSegments, uint64_t *largestSegment) {
|
|||||||
void GPTData::MakeHybrid(void) {
|
void GPTData::MakeHybrid(void) {
|
||||||
uint32_t partNums[3];
|
uint32_t partNums[3];
|
||||||
char line[255];
|
char line[255];
|
||||||
int numParts, i, j, typeCode, bootable;
|
int numParts, i, j, typeCode, bootable, mbrNum;
|
||||||
uint64_t length;
|
uint64_t length;
|
||||||
char fillItUp = 'M'; // fill extra partition entries? (Yes/No/Maybe)
|
char fillItUp = 'M'; // fill extra partition entries? (Yes/No/Maybe)
|
||||||
|
char eeFirst; // Whether EFI GPT (0xEE) partition comes first in table
|
||||||
|
|
||||||
printf("\nWARNING! Hybrid MBRs are flaky and potentially dangerous! If you decide not\n"
|
printf("\nWARNING! Hybrid MBRs are flaky and potentially dangerous! If you decide not\n"
|
||||||
"to use one, just hit the Enter key at the below prompt and your MBR\n"
|
"to use one, just hit the Enter key at the below prompt and your MBR\n"
|
||||||
@@ -1332,21 +1336,31 @@ void GPTData::MakeHybrid(void) {
|
|||||||
// alone....
|
// alone....
|
||||||
protectiveMBR.EmptyMBR(0);
|
protectiveMBR.EmptyMBR(0);
|
||||||
protectiveMBR.SetDiskSize(diskSize);
|
protectiveMBR.SetDiskSize(diskSize);
|
||||||
|
printf("Place EFI GPT (0xEE) partition first in MBR (good for GRUB)? ");
|
||||||
|
eeFirst = GetYN();
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
for (i = 0; i < numParts; i++) {
|
for (i = 0; i < numParts; i++) {
|
||||||
j = partNums[i] - 1;
|
j = partNums[i] - 1;
|
||||||
printf("Creating entry for partition #%d\n", j + 1);
|
printf("\nCreating entry for partition #%d\n", j + 1);
|
||||||
if ((j >= 0) && (j < mainHeader.numParts)) {
|
if ((j >= 0) && (j < mainHeader.numParts)) {
|
||||||
if (partitions[j].lastLBA < UINT32_MAX) {
|
if (partitions[j].lastLBA < UINT32_MAX) {
|
||||||
printf("Enter an MBR hex code (suggested %02X): ",
|
do {
|
||||||
typeHelper.GUIDToID(partitions[j].partitionType) / 256);
|
printf("Enter an MBR hex code (default %02X): ",
|
||||||
fgets(line, 255, stdin);
|
typeHelper.GUIDToID(partitions[j].partitionType) / 256);
|
||||||
sscanf(line, "%x", &typeCode);
|
fgets(line, 255, stdin);
|
||||||
|
sscanf(line, "%x", &typeCode);
|
||||||
|
if (line[0] == '\n')
|
||||||
|
typeCode = typeHelper.GUIDToID(partitions[j].partitionType) / 256;
|
||||||
|
} while ((typeCode <= 0) || (typeCode > 255));
|
||||||
printf("Set the bootable flag? ");
|
printf("Set the bootable flag? ");
|
||||||
bootable = (GetYN() == 'Y');
|
bootable = (GetYN() == 'Y');
|
||||||
length = partitions[j].lastLBA - partitions[j].firstLBA + UINT64_C(1);
|
length = partitions[j].lastLBA - partitions[j].firstLBA + UINT64_C(1);
|
||||||
protectiveMBR.MakePart(i, (uint32_t) partitions[j].firstLBA,
|
if (eeFirst == 'Y')
|
||||||
|
mbrNum = i + 1;
|
||||||
|
else
|
||||||
|
mbrNum = i;
|
||||||
|
protectiveMBR.MakePart(mbrNum, (uint32_t) partitions[j].firstLBA,
|
||||||
(uint32_t) length, typeCode, bootable);
|
(uint32_t) length, typeCode, bootable);
|
||||||
} else { // partition out of range
|
} else { // partition out of range
|
||||||
printf("Partition %d ends beyond the 2TiB limit of MBR partitions; omitting it.\n",
|
printf("Partition %d ends beyond the 2TiB limit of MBR partitions; omitting it.\n",
|
||||||
@@ -1365,7 +1379,11 @@ void GPTData::MakeHybrid(void) {
|
|||||||
// gptsync utility does. This is because Windows seems to choke on
|
// gptsync utility does. This is because Windows seems to choke on
|
||||||
// disks with a 0xEE partition in the first slot and subsequent
|
// disks with a 0xEE partition in the first slot and subsequent
|
||||||
// additional partitions, unless it boots from the disk.
|
// additional partitions, unless it boots from the disk.
|
||||||
protectiveMBR.MakePart(numParts, 1, protectiveMBR.FindLastInFree(1), 0xEE);
|
if (eeFirst == 'Y')
|
||||||
|
mbrNum = 0;
|
||||||
|
else
|
||||||
|
mbrNum = numParts;
|
||||||
|
protectiveMBR.MakePart(mbrNum, 1, protectiveMBR.FindLastInFree(1), 0xEE);
|
||||||
|
|
||||||
// ... and for good measure, if there are any partition spaces left,
|
// ... and for good measure, if there are any partition spaces left,
|
||||||
// optionally create more protective EFI partitions to cover as much
|
// optionally create more protective EFI partitions to cover as much
|
||||||
@@ -1373,18 +1391,20 @@ void GPTData::MakeHybrid(void) {
|
|||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (protectiveMBR.GetType(i) == 0x00) { // unused entry....
|
if (protectiveMBR.GetType(i) == 0x00) { // unused entry....
|
||||||
if (fillItUp == 'M') {
|
if (fillItUp == 'M') {
|
||||||
printf("Unused partition space(s) found. Use one to protect more partitions? ");
|
printf("\nUnused partition space(s) found. Use one to protect more partitions? ");
|
||||||
fillItUp = GetYN();
|
fillItUp = GetYN();
|
||||||
typeCode = 0x00; // use this to flag a need to get type code
|
typeCode = 0x00; // use this to flag a need to get type code
|
||||||
} // if
|
} // if
|
||||||
if (fillItUp == 'Y') {
|
if (fillItUp == 'Y') {
|
||||||
if (typeCode == 0x00) {
|
while ((typeCode <= 0) || (typeCode > 255)) {
|
||||||
printf("Enter an MBR hex code (EE is EFI GPT, but may confuse MacOS): ");
|
printf("Enter an MBR hex code (EE is EFI GPT, but may confuse MacOS): ");
|
||||||
// Comment on above: Mac OS treats disks with more than one
|
// Comment on above: Mac OS treats disks with more than one
|
||||||
// 0xEE MBR partition as MBR disks, not as GPT disks.
|
// 0xEE MBR partition as MBR disks, not as GPT disks.
|
||||||
fgets(line, 255, stdin);
|
fgets(line, 255, stdin);
|
||||||
sscanf(line, "%x", &typeCode);
|
sscanf(line, "%x", &typeCode);
|
||||||
} // if (typeCode == 0x00)
|
if (line[0] == '\n')
|
||||||
|
typeCode = 0;
|
||||||
|
} // while
|
||||||
protectiveMBR.MakeBiggestPart(i, typeCode); // make a partition
|
protectiveMBR.MakeBiggestPart(i, typeCode); // make a partition
|
||||||
} // if (fillItUp == 'Y')
|
} // if (fillItUp == 'Y')
|
||||||
} // if unused entry
|
} // if unused entry
|
||||||
|
|||||||
10
mbr.cc
10
mbr.cc
@@ -265,13 +265,19 @@ int MBRData::ReadLogicalPart(int fd, uint32_t extendedStart,
|
|||||||
void MBRData::DisplayMBRData(void) {
|
void MBRData::DisplayMBRData(void) {
|
||||||
int i;
|
int i;
|
||||||
char tempStr[255];
|
char tempStr[255];
|
||||||
|
char bootCode;
|
||||||
|
|
||||||
printf("MBR disk identifier: 0x%08X\n", (unsigned int) diskSignature);
|
printf("MBR disk identifier: 0x%08X\n", (unsigned int) diskSignature);
|
||||||
printf("MBR partitions:\n");
|
printf("MBR partitions:\n");
|
||||||
printf("Number\t Start (block)\t Length (blocks)\tType\n");
|
printf("Number\t Boot\t Start (sector)\t Length (sectors)\tType\n");
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (partitions[i].lengthLBA != 0) {
|
if (partitions[i].lengthLBA != 0) {
|
||||||
printf("%4d\t%13lu\t%15lu \t0x%02X\n", i + 1, (unsigned long) partitions[i].firstLBA,
|
if (partitions[i].status && 0x80) // it's bootable
|
||||||
|
bootCode = '*';
|
||||||
|
else
|
||||||
|
bootCode = ' ';
|
||||||
|
printf("%4d\t %c\t%13lu\t%15lu \t0x%02X\n", i + 1, bootCode,
|
||||||
|
(unsigned long) partitions[i].firstLBA,
|
||||||
(unsigned long) partitions[i].lengthLBA, partitions[i].partitionType);
|
(unsigned long) partitions[i].lengthLBA, partitions[i].partitionType);
|
||||||
} // if
|
} // if
|
||||||
} // for
|
} // for
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ uint64_t GetLastSector(uint64_t low, uint64_t high, char prompt[]) {
|
|||||||
if (num <= 0) {
|
if (num <= 0) {
|
||||||
response = (unsigned long long) high;
|
response = (unsigned long long) high;
|
||||||
suffix = ' ';
|
suffix = ' ';
|
||||||
|
plusFlag = 0;
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
// Set multiplier based on suffix
|
// Set multiplier based on suffix
|
||||||
@@ -124,7 +125,7 @@ uint64_t GetLastSector(uint64_t low, uint64_t high, char prompt[]) {
|
|||||||
response *= (unsigned long long) mult;
|
response *= (unsigned long long) mult;
|
||||||
if (plusFlag == 1) {
|
if (plusFlag == 1) {
|
||||||
response = response + (unsigned long long) low - 1;
|
response = response + (unsigned long long) low - 1;
|
||||||
} // if/else
|
} // if
|
||||||
} // while
|
} // while
|
||||||
return ((uint64_t) response);
|
return ((uint64_t) response);
|
||||||
} // GetLastSector()
|
} // GetLastSector()
|
||||||
|
|||||||
Reference in New Issue
Block a user