diff options
author | srs5694 <srs5694@users.sourceforge.net> | 2010-01-28 21:10:52 -0500 |
---|---|---|
committer | srs5694 <srs5694@users.sourceforge.net> | 2010-01-28 21:10:52 -0500 |
commit | 0a6973119c9e9984ad47a6da3231e8d16f996c5c (patch) | |
tree | 456b81b56315eca6ac64688db34cbb0a25a87f41 /gptpart.cc | |
parent | 91544e13fb56ef339277a8f73f761ff004b2e74f (diff) | |
download | sgdisk-0a6973119c9e9984ad47a6da3231e8d16f996c5c.tar.gz |
Nearing 0.6.2 release; Windows version now works.
Diffstat (limited to 'gptpart.cc')
-rw-r--r-- | gptpart.cc | 213 |
1 files changed, 113 insertions, 100 deletions
@@ -35,17 +35,6 @@ GPTPart::GPTPart(void) { GPTPart::~GPTPart(void) { } // destructor -// Return partition's name field, converted to a C++ ASCII string -string GPTPart::GetName(void) { - string theName; - int i; - - for (i = 0; i < NAME_SIZE; i += 2) { - theName += name[i]; - } // for - return theName; -} // GPTPart::GetName() - // Return the gdisk-specific two-byte hex code for the partition uint16_t GPTPart::GetHexType(void) { return typeHelper.GUIDToID(partitionType); @@ -66,18 +55,30 @@ uint64_t GPTPart::GetLengthLBA(void) { return length; } // GPTPart::GetLengthLBA() -GPTPart & GPTPart::operator=(const GPTPart & orig) { +// Return partition's name field, converted to a C++ ASCII string +string GPTPart::GetName(void) { + string theName; int i; - partitionType = orig.partitionType; - uniqueGUID = orig.uniqueGUID; - firstLBA = orig.firstLBA; - lastLBA = orig.lastLBA; - attributes = orig.attributes; - for (i = 0; i < NAME_SIZE; i++) - name[i] = orig.name[i]; - return *this; -} // assignment operator + theName = ""; + for (i = 0; i < NAME_SIZE; i += 2) { + if (name[i] != '\0') + theName += name[i]; + } // for + return theName; +} // GPTPart::GetName() + +// Set the type code to the specified one. Also changes the partition +// name *IF* the current name is the generic one for the current partition +// type. +void GPTPart::SetType(struct GUIDData t) { + int nameSame = 1, currentLength, i; + + if (GetName() == typeHelper.GUIDToName(partitionType)) { + SetName(typeHelper.GUIDToName(t)); + } // if + partitionType = t; +} // GPTPart::SetType() // Sets the unique GUID to a value of 0 or a random value, // depending on the parameter: 0 = 0, anything else = random @@ -93,47 +94,54 @@ void GPTPart::SetUniqueGUID(int zeroOrRandom) { } } // GPTPart::SetUniqueGUID() -// Blank (delete) a single partition -void GPTPart::BlankPartition(void) { - int j; - GUIDData zeroGUID; +// Set the name for a partition to theName, or prompt for a name if +// theName is empty. Note that theName is a standard C++-style ASCII +// string, although the GUID partition definition requires a UTF-16LE +// string. This function creates a simple-minded copy for this. +void GPTPart::SetName(const string & theName) { + char newName[NAME_SIZE]; // New name + char *junk; + int i; - zeroGUID.data1 = 0; - zeroGUID.data2 = 0; - uniqueGUID = zeroGUID; - partitionType = zeroGUID; - firstLBA = 0; - lastLBA = 0; - attributes = 0; - for (j = 0; j < NAME_SIZE; j++) - name[j] = '\0'; -} // GPTPart::BlankPartition + // Blank out new name string, just to be on the safe side.... + for (i = 0; i < NAME_SIZE; i++) + newName[i] = '\0'; -// Returns 1 if the two partitions overlap, 0 if they don't -int GPTPart::DoTheyOverlap(GPTPart* other) { - int theyDo = 0; + if (theName == "") { // No name specified, so get one from the user + cout << "Enter name: "; + junk = fgets(newName, NAME_SIZE / 2, stdin); - // Don't bother checking unless these are defined (both start and end points - // are 0 for undefined partitions, so just check the start points) - if ((firstLBA != 0) && (other->firstLBA != 0)) { - if ((firstLBA < other->lastLBA) && (lastLBA >= other->firstLBA)) - theyDo = 1; - if ((other->firstLBA < lastLBA) && (other->lastLBA >= firstLBA)) - theyDo = 1; + // Input is likely to include a newline, so remove it.... + i = strlen(newName); + if (newName[i - 1] == '\n') + newName[i - 1] = '\0'; + } else { + strcpy(newName, theName.substr(0, NAME_SIZE / 2).c_str()); } // if - return (theyDo); -} // GPTPart::DoTheyOverlap() -// Reverse the bytes of integral data types; used on big-endian systems. -void GPTPart::ReversePartBytes(void) { - ReverseBytes(&partitionType.data1, 8); - ReverseBytes(&partitionType.data2, 8); - ReverseBytes(&uniqueGUID.data1, 8); - ReverseBytes(&uniqueGUID.data2, 8); - ReverseBytes(&firstLBA, 8); - ReverseBytes(&lastLBA, 8); - ReverseBytes(&attributes, 8); -} // GPTPart::ReverseBytes() + // Copy the C-style ASCII string from newName into a form that the GPT + // table will accept.... + for (i = 0; i < NAME_SIZE; i++) { + if ((i % 2) == 0) { + name[i] = newName[(i / 2)]; + } else { + name[i] = '\0'; + } // if/else + } // for +} // GPTPart::SetName() + +GPTPart & GPTPart::operator=(const GPTPart & orig) { + int i; + + partitionType = orig.partitionType; + uniqueGUID = orig.uniqueGUID; + firstLBA = orig.firstLBA; + lastLBA = orig.lastLBA; + attributes = orig.attributes; + for (i = 0; i < NAME_SIZE; i++) + name[i] = orig.name[i]; + return *this; +} // assignment operator // Display summary information; does nothing if the partition is empty. void GPTPart::ShowSummary(int partNum, uint32_t blockSize) { @@ -155,7 +163,7 @@ void GPTPart::ShowSummary(int partNum, uint32_t blockSize) { cout.setf(ios::uppercase); cout << hex << typeHelper.GUIDToID(partitionType) << " " << dec; cout.fill(' '); - cout.setf(ios::right); +// cout.setf(ios::right); cout << GetName().substr(0, 23) << "\n"; cout.fill(' '); } // if @@ -172,24 +180,65 @@ void GPTPart::ShowDetails(uint32_t blockSize) { cout << "Partition unique GUID: " << GUIDToStr(uniqueGUID) << "\n"; cout << "First sector: " << firstLBA << " (at " - << BytesToSI(firstLBA * blockSize) << ")\n"; + << BytesToSI(firstLBA * blockSize) << ")\n"; cout << "Last sector: " << lastLBA << " (at " - << BytesToSI(lastLBA * blockSize) << ")\n"; + << BytesToSI(lastLBA * blockSize) << ")\n"; size = (lastLBA - firstLBA + 1); cout << "Partition size: " << size << " sectors (" - << BytesToSI(size * ((uint64_t) blockSize)) << ")\n"; + << BytesToSI(size * ((uint64_t) blockSize)) << ")\n"; cout << "Attribute flags: "; cout.fill('0'); cout.width(16); - cout << right; cout << hex; cout << attributes << "\n"; - cout << left; cout << dec; cout << "Partition name: " << GetName() << "\n"; + cout.fill(' '); } // if } // GPTPart::ShowDetails() +// Blank (delete) a single partition +void GPTPart::BlankPartition(void) { + int j; + GUIDData zeroGUID; + + zeroGUID.data1 = 0; + zeroGUID.data2 = 0; + uniqueGUID = zeroGUID; + partitionType = zeroGUID; + firstLBA = 0; + lastLBA = 0; + attributes = 0; + for (j = 0; j < NAME_SIZE; j++) + name[j] = '\0'; +} // GPTPart::BlankPartition + +// Returns 1 if the two partitions overlap, 0 if they don't +int GPTPart::DoTheyOverlap(const GPTPart & other) { + int theyDo = 0; + + // Don't bother checking unless these are defined (both start and end points + // are 0 for undefined partitions, so just check the start points) + if ((firstLBA != 0) && (other.firstLBA != 0)) { + if ((firstLBA < other.lastLBA) && (lastLBA >= other.firstLBA)) + theyDo = 1; + if ((other.firstLBA < lastLBA) && (other.lastLBA >= firstLBA)) + theyDo = 1; + } // if + return (theyDo); +} // GPTPart::DoTheyOverlap() + +// Reverse the bytes of integral data types; used on big-endian systems. +void GPTPart::ReversePartBytes(void) { + ReverseBytes(&partitionType.data1, 8); + ReverseBytes(&partitionType.data2, 8); + ReverseBytes(&uniqueGUID.data1, 8); + ReverseBytes(&uniqueGUID.data2, 8); + ReverseBytes(&firstLBA, 8); + ReverseBytes(&lastLBA, 8); + ReverseBytes(&attributes, 8); +} // GPTPart::ReverseBytes() + /**************************************** * Functions requiring user interaction * ****************************************/ @@ -216,46 +265,10 @@ void GPTPart::ChangeType(void) { newType = typeHelper.IDToGUID((uint16_t) typeNum); else // user wants to enter the GUID directly, so do that newType = GetGUID(); - partitionType = newType; + SetType(newType); cout << "Changed type of partition to '" << typeHelper.GUIDToName(partitionType) << "'\n"; } // GPTPart::ChangeType() -// Set the name for a partition to theName, or prompt for a name if -// theName is empty. Note that theName is a standard C++-style ASCII -// string, although the GUID partition definition requires a UTF-16LE -// string. This function creates a simple-minded copy for this. -void GPTPart::SetName(string theName) { - char newName[NAME_SIZE]; // New name - char *junk; - int i; - - // Blank out new name string, just to be on the safe side.... - for (i = 0; i < NAME_SIZE; i++) - newName[i] = '\0'; - - if (theName == "") { // No name specified, so get one from the user - cout << "Enter name: "; - junk = fgets(newName, NAME_SIZE / 2, stdin); - - // Input is likely to include a newline, so remove it.... - i = strlen(newName); - if (newName[i - 1] == '\n') - newName[i - 1] = '\0'; - } else { - strcpy(newName, theName.substr(0, NAME_SIZE / 2).c_str()); - } // if - - // Copy the C-style ASCII string from newName into a form that the GPT - // table will accept.... - for (i = 0; i < NAME_SIZE; i++) { - if ((i % 2) == 0) { - name[i] = newName[(i / 2)]; - } else { - name[i] = '\0'; - } // if/else - } // for -} // GPTPart::SetName() - /*********************************** * Non-class but related functions * ***********************************/ |