Skip to content

Commit

Permalink
Added -F option to sgdisk
Browse files Browse the repository at this point in the history
  • Loading branch information
srs5694 committed Sep 25, 2010
1 parent 82f3f0b commit 5a08175
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 109 deletions.
4 changes: 2 additions & 2 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
0.6.11 (??/??/2010):
--------------------

- Changed partition type code entry in gdisk so that it directly
accepts GUID values rather than requiring typing "0" to do so.
- Streamlined GUID code entry in gdisk; it no longer offers the option
to enter GUIDs in separate segments.

- The -t option to sgdisk now accepts GUID values as well as the
sgdisk/gdisk-specific two-byte hex codes.
Expand Down
20 changes: 16 additions & 4 deletions gdisk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
char* junk;
uint32_t pn, temp1, temp2;
int goOn = 1, i;
char guidStr[255];
GUIDData aGUID;
ostringstream prompt;

Expand All @@ -337,8 +338,14 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
case 'c': case 'C':
if (theGPT->GetPartRange(&temp1, &temp2) > 0) {
pn = theGPT->GetPartNum();
cout << "Enter the partition's new unique GUID:\n";
theGPT->SetPartitionGUID(pn, aGUID.GetGUIDFromUser());
cout << "Enter the partition's new unique GUID ('R' to randomize): ";
junk = fgets(guidStr, 255, stdin);
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetPartitionGUID(pn, (GUIDData) guidStr);
cout << "New GUID is " << theGPT->operator[](pn).GetUniqueGUID() << "\n";
} else {
cout << "GUID is too short!\n";
} // if/else
} else cout << "No partitions\n";
break;
case 'd': case 'D':
Expand All @@ -353,8 +360,13 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
theGPT->RandomizeGUIDs();
break;
case 'g': case 'G':
cout << "Enter the disk's unique GUID:\n";
theGPT->SetDiskGUID(aGUID.GetGUIDFromUser());
cout << "Enter the disk's unique GUID ('R' to randomize): ";
junk = fgets(guidStr, 255, stdin);
if ((strlen(guidStr) >= 33) || (guidStr[0] == 'R') || (guidStr[0] == 'r')) {
theGPT->SetDiskGUID((GUIDData) guidStr);
cout << "The new disk GUID is " << theGPT->GetDiskGUID() << "\n";
} else
cout << "GUID is too short!\n";
break;
case 'h': case 'H':
theGPT->RecomputeCHS();
Expand Down
50 changes: 27 additions & 23 deletions gpt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ int GPTData::Verify(void) {
} // if
if ((mainHeader.diskGUID != secondHeader.diskGUID)) {
problems++;
cout << "\nProblem: main header's disk GUID (" << mainHeader.diskGUID.AsString()
cout << "\nProblem: main header's disk GUID (" << mainHeader.diskGUID
<< ") doesn't\nmatch the backup GPT header's disk GUID ("
<< secondHeader.diskGUID.AsString() << ")\n"
<< secondHeader.diskGUID << ")\n"
<< "You should use the 'b' or 'd' option on the recovery & transformation menu to\n"
<< "select one or the other header.\n";
} // if
Expand Down Expand Up @@ -1268,7 +1268,7 @@ void GPTData::DisplayGPTData(void) {
cout << "Disk " << device << ": " << diskSize << " sectors, "
<< BytesToSI(diskSize * blockSize) << "\n";
cout << "Logical sector size: " << blockSize << " bytes\n";
cout << "Disk identifier (GUID): " << mainHeader.diskGUID.AsString() << "\n";
cout << "Disk identifier (GUID): " << mainHeader.diskGUID << "\n";
cout << "Partition table holds up to " << numParts << " entries\n";
cout << "First usable sector is " << mainHeader.firstUsableLBA
<< ", last usable sector is " << mainHeader.lastUsableLBA << "\n";
Expand Down Expand Up @@ -1661,9 +1661,14 @@ int GPTData::DeletePartition(uint32_t partNum) {
// Returns 1 if the operation was successful, 0 if a problem was discovered.
uint32_t GPTData::CreatePartition(uint32_t partNum, uint64_t startSector, uint64_t endSector) {
int retval = 1; // assume there'll be no problems
uint64_t origSector = startSector;

if (IsFreePartNum(partNum)) {
Align(&startSector); // Align sector to correct multiple
if (Align(&startSector)) {
cout << "Information: Moved requested sector from " << origSector << " to "
<< startSector << " in\norder to align on " << sectorAlignment
<< "-sector boundaries.\n";
} // if
if (IsFree(startSector) && (startSector <= endSector)) {
if (FindLastInFree(startSector) >= endSector) {
partitions[partNum].SetFirstLBA(startSector);
Expand Down Expand Up @@ -1891,7 +1896,6 @@ int GPTData::Align(uint64_t* sector) {

if ((*sector % sectorAlignment) != 0) {
original = *sector;
retval = 1;
earlier = (*sector / sectorAlignment) * sectorAlignment;
later = earlier + (uint64_t) sectorAlignment;

Expand All @@ -1905,6 +1909,7 @@ int GPTData::Align(uint64_t* sector) {
} while ((sectorOK == 1) && (testSector < *sector));
if (sectorOK == 1) {
*sector = earlier;
retval = 1;
} // if
} // if firstUsableLBA check

Expand All @@ -1917,25 +1922,9 @@ int GPTData::Align(uint64_t* sector) {
} while ((sectorOK == 1) && (testSector > *sector));
if (sectorOK == 1) {
*sector = later;
retval = 1;
} // if
} // if

// If sector was changed successfully, inform the user of this fact.
// Otherwise, notify the user that it couldn't be done....
if (sectorOK == 1) {
cout << "Information: Moved requested sector from " << original << " to "
<< *sector << " in\norder to align on " << sectorAlignment
<< "-sector boundaries.\n";
if (!beQuiet)
cout << "Use 'l' on the experts' menu to adjust alignment\n";
} else {
cout << "Information: Sector not aligned on " << sectorAlignment
<< "-sector boundary and could not be moved.\n"
<< "If you're using a Western Digital Advanced Format or similar disk with\n"
<< "underlying 4096-byte sectors or certain types of RAID array, performance\n"
<< "may suffer.\n";
retval = 0;
} // if/else
} // if
return retval;
} // GPTData::Align()
Expand Down Expand Up @@ -2259,12 +2248,27 @@ void GPTData::ReversePartitionBytes() {
// Validate partition number
bool GPTData::ValidPartNum (const uint32_t partNum) {
if (partNum >= numParts) {
cerr << "Partition number out of range: " << (signed) partNum << endl;
cerr << "Partition number out of range: " << partNum << "\n";
return false;
} // if
return true;
} // GPTData::ValidPartNum

// Return a single partition for inspection (not modification!) by other
// functions.
const GPTPart & GPTData::operator[](uint32_t partNum) const {
if (partNum >= numParts) {
cerr << "Partition number out of range: " << partNum << "\n";
partNum = 0;
} // if
return partitions[partNum];
} // operator[]

// Return (not for modification!) the disk's GUID value
const GUIDData & GPTData::GetDiskGUID(void) const {
return mainHeader.diskGUID;
} // GPTData::GetDiskGUID()

// Manage attributes for a partition, based on commands passed to this function.
// (Function is non-interactive.)
// Returns 1 if a modification command succeeded, 0 if the command should not have
Expand Down
6 changes: 3 additions & 3 deletions gpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#ifndef __GPTSTRUCTS
#define __GPTSTRUCTS

#define GPTFDISK_VERSION "0.6.11-pre2"
#define GPTFDISK_VERSION "0.6.11-pre3"

// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
// numbered value to refer to partition numbers. (Most will be 0 or positive,
Expand Down Expand Up @@ -177,10 +177,10 @@ class GPTData {
uint64_t GetSecondPartsLBA(void) {return secondHeader.partitionEntriesLBA;}
uint64_t GetFirstUsableLBA(void) {return mainHeader.firstUsableLBA;}
uint64_t GetLastUsableLBA(void) {return mainHeader.lastUsableLBA;}
uint64_t GetPartFirstLBA(uint32_t i) {return partitions[i].GetFirstLBA();}
uint64_t GetPartLastLBA(uint32_t i) {return partitions[i].GetLastLBA();}
uint32_t CountParts(void);
bool ValidPartNum (const uint32_t partNum);
const GPTPart & operator[](uint32_t partNum) const;
const GUIDData & GetDiskGUID(void) const;

// Find information about free space
uint64_t FindFirstAvailable(uint64_t start = 0);
Expand Down
4 changes: 2 additions & 2 deletions gptpart.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ void GPTPart::ShowDetails(uint32_t blockSize) {
uint64_t size;

if (firstLBA != 0) {
cout << "Partition GUID code: " << partitionType.AsString();
cout << "Partition GUID code: " << partitionType;
cout << " (" << partitionType.TypeName() << ")\n";
cout << "Partition unique GUID: " << uniqueGUID.AsString() << "\n";
cout << "Partition unique GUID: " << uniqueGUID << "\n";

cout << "First sector: " << firstLBA << " (at "
<< BytesToSI(firstLBA * blockSize) << ")\n";
Expand Down
6 changes: 3 additions & 3 deletions gptpart.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,9 @@ class GPTPart {
PartType & GetType(void) {return partitionType;}
uint16_t GetHexType(void);
string GetTypeName(void);
GUIDData GetUniqueGUID(void) {return uniqueGUID;}
uint64_t GetFirstLBA(void) {return firstLBA;}
uint64_t GetLastLBA(void) {return lastLBA;}
const GUIDData GetUniqueGUID(void) const {return uniqueGUID;}
uint64_t GetFirstLBA(void) const {return firstLBA;}
uint64_t GetLastLBA(void) const {return lastLBA;}
uint64_t GetLengthLBA(void);
uint64_t GetAttributes(void) {return attributes;}
string GetDescription(void);
Expand Down
12 changes: 10 additions & 2 deletions gpttext.cc
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void GPTDataTextUI::ResizePartitionTable(void) {

// Interactively create a partition
void GPTDataTextUI::CreatePartition(void) {
uint64_t firstBlock, firstInLargest, lastBlock, sector;
uint64_t firstBlock, firstInLargest, lastBlock, sector, origSector;
uint32_t firstFreePart = 0;
ostringstream prompt1, prompt2, prompt3;
int partNum;
Expand Down Expand Up @@ -211,7 +211,15 @@ void GPTDataTextUI::CreatePartition(void) {
do {
sector = GetSectorNum(firstBlock, lastBlock, firstInLargest, prompt2.str());
} while (IsFree(sector) == 0);
Align(&sector); // Align sector to correct multiple
origSector = sector;
if (Align(&sector)) {
cout << "Information: Moved requested sector from " << origSector << " to "
<< sector << " in\norder to align on " << sectorAlignment
<< "-sector boundaries.\n";
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...
Expand Down
3 changes: 3 additions & 0 deletions gpttext.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class GPTDataTextUI : public GPTData {
GPTDataTextUI(string filename);
~GPTDataTextUI(void);

// This one needs to be explicitly defined, even though it does nothing new....
const GPTPart & operator[](uint32_t partNum) {return GPTData::operator[](partNum);}

// Extended (interactive) versions of some base-class functions
WhichToUse UseWhichPartitions(void);
int XFormDisklabel(void);
Expand Down
70 changes: 20 additions & 50 deletions guid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define __STDC_CONSTANT_MACROS

#include <stdio.h>
#include <time.h>
#include <string>
#include <iostream>
#include "guid.h"
Expand All @@ -23,6 +24,7 @@
using namespace std;

GUIDData::GUIDData(void) {
srand(time(0));
Zero();
} // constructor

Expand Down Expand Up @@ -119,52 +121,6 @@ GUIDData & GUIDData::operator=(const char * orig) {
return operator=((string) orig);
} // GUIDData::operator=(const char * orig)

// Read a GUIDData from stdin, prompting the user along the way for the
// correct form. This is a bit more flexible than it claims; it parses
// any entry of 32 or 36 characters as a GUID (
GUIDData & GUIDData::GetGUIDFromUser(void) {
string part1, part2, part3, part4, part5;
char line[255];
int entered = 0;

cout << "\nA GUID is entered in five segments of from two to six bytes, with\n"
<< "dashes between segments.\n";
cout << "Enter the entire GUID, a four-byte hexadecimal number for the first segment, or\n"
<< "'R' to generate the entire GUID randomly: ";
cin.get(line, 255);
part1 = DeleteSpaces(line);

// If user entered 'r' or 'R', generate GUID randomly....
if ((part1[0] == 'r') || (part1[0] == 'R')) {
Randomize();
entered = 1;
} // if user entered 'R' or 'r'

// If string length is right for whole entry, try to parse it....
if (((part1.length() == 36) || (part1.length() == 32)) && (entered == 0)) {
operator=(part1);
entered = 1;
} // if

// If neither of the above methods of entry was used, use prompted
// entry....
if (entered == 0) {
cout << "Enter a two-byte hexadecimal number for the second segment: ";
cin >> part2;
cout << "Enter a two-byte hexadecimal number for the third segment: ";
cin >> part3;
cout << "Enter a two-byte hexadecimal number for the fourth segment: ";
cin >> part4;
cout << "Enter a six-byte hexadecimal number for the fifth segment: ";
cin >> part5;
operator=(part1 += (string) "-" += part2 += (string) "-" += part3
+= (string) "-" += part4 += (string) "-" += part5);
} // if/else
cin.ignore(255, '\n');
cout << "New GUID: " << AsString() << "\n";
return *this;
} // GUIDData::GetGUIDData(void)

// Erase the contents of the GUID
void GUIDData::Zero(void) {
int i;
Expand All @@ -189,12 +145,12 @@ void GUIDData::Randomize(void) {
#else
int i;
for (i = 0; i < 16; i++)
uuidData[i] = rand();
uuidData[i] = (unsigned char) (256.0 * (rand() / (RAND_MAX + 1.0)));
#endif
} // GUIDData::Randomize

// Equality operator; returns 1 if the GUIDs are equal, 0 if they're unequal
int GUIDData::operator==(const GUIDData & orig) {
int GUIDData::operator==(const GUIDData & orig) const {
int retval = 1; // assume they're equal
int i;

Expand All @@ -206,12 +162,12 @@ int GUIDData::operator==(const GUIDData & orig) {
} // GUIDData::operator==

// Inequality operator; returns 1 if the GUIDs are unequal, 0 if they're equal
int GUIDData::operator!=(const GUIDData & orig) {
int GUIDData::operator!=(const GUIDData & orig) const {
return !operator==(orig);
} // GUIDData::operator!=

// Return the GUID as a string, suitable for display to the user.
string GUIDData::AsString(void) {
string GUIDData::AsString(void) const {
char theString[40];

sprintf(theString,
Expand All @@ -237,3 +193,17 @@ string GUIDData::DeleteSpaces(string s) {
} // if
return s;
} // GUIDData::DeleteSpaces()

/*******************************
* *
* Non-class support functions *
* *
*******************************/

// Display a GUID as a string....
ostream & operator<<(ostream & os, const GUIDData & data) {
string asString;

os << data.AsString();
return os;
} // GUIDData::operator<<()
9 changes: 5 additions & 4 deletions guid.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,17 @@ class GUIDData {
GUIDData & operator=(const GUIDData & orig);
GUIDData & operator=(const string & orig);
GUIDData & operator=(const char * orig);
GUIDData & GetGUIDFromUser(void);
void Zero(void);
void Randomize(void);

// Data tests....
int operator==(const GUIDData & orig);
int operator!=(const GUIDData & orig);
int operator==(const GUIDData & orig) const;
int operator!=(const GUIDData & orig) const;

// Data retrieval....
string AsString(void);
string AsString(void) const;
}; // class GUIDData

ostream & operator<<(ostream & os, const GUIDData & data);

#endif
Loading

0 comments on commit 5a08175

Please sign in to comment.