1cf200d32Sopenharmony_ci// 2cf200d32Sopenharmony_ci// C++ Implementation: gptpart 3cf200d32Sopenharmony_ci// 4cf200d32Sopenharmony_ci// Description: Class to implement a SINGLE GPT partition 5cf200d32Sopenharmony_ci// 6cf200d32Sopenharmony_ci// 7cf200d32Sopenharmony_ci// Author: Rod Smith <rodsmith@rodsbooks.com>, (C) 2009-2018 8cf200d32Sopenharmony_ci// 9cf200d32Sopenharmony_ci// Copyright: See COPYING file that comes with this distribution 10cf200d32Sopenharmony_ci// 11cf200d32Sopenharmony_ci// 12cf200d32Sopenharmony_ci// This program is copyright (c) 2009 by Roderick W. Smith. It is distributed 13cf200d32Sopenharmony_ci// under the terms of the GNU GPL version 2, as detailed in the COPYING file. 14cf200d32Sopenharmony_ci 15cf200d32Sopenharmony_ci#define __STDC_LIMIT_MACROS 16cf200d32Sopenharmony_ci#ifndef __STDC_CONSTANT_MACROS 17cf200d32Sopenharmony_ci#define __STDC_CONSTANT_MACROS 18cf200d32Sopenharmony_ci#endif 19cf200d32Sopenharmony_ci 20cf200d32Sopenharmony_ci#include <string.h> 21cf200d32Sopenharmony_ci#include <stdio.h> 22cf200d32Sopenharmony_ci#include <iostream> 23cf200d32Sopenharmony_ci#include "gptpart.h" 24cf200d32Sopenharmony_ci#include "attributes.h" 25cf200d32Sopenharmony_ci#ifdef USE_UTF16 26cf200d32Sopenharmony_ci#include <unicode/ustdio.h> 27cf200d32Sopenharmony_ci#else 28cf200d32Sopenharmony_ci#define UnicodeString std::string 29cf200d32Sopenharmony_ci#endif 30cf200d32Sopenharmony_ci 31cf200d32Sopenharmony_ciusing namespace std; 32cf200d32Sopenharmony_ci 33cf200d32Sopenharmony_ciGPTPart::GPTPart(void) { 34cf200d32Sopenharmony_ci partitionType.Zero(); 35cf200d32Sopenharmony_ci uniqueGUID.Zero(); 36cf200d32Sopenharmony_ci firstLBA = 0; 37cf200d32Sopenharmony_ci lastLBA = 0; 38cf200d32Sopenharmony_ci attributes = 0; 39cf200d32Sopenharmony_ci memset(name, 0, NAME_SIZE * sizeof(name[0]) ); 40cf200d32Sopenharmony_ci} // Default constructor 41cf200d32Sopenharmony_ci 42cf200d32Sopenharmony_ciGPTPart::GPTPart(const GPTPart & orig) { 43cf200d32Sopenharmony_ci partitionType = orig.partitionType; 44cf200d32Sopenharmony_ci uniqueGUID = orig.uniqueGUID; 45cf200d32Sopenharmony_ci firstLBA = orig.firstLBA; 46cf200d32Sopenharmony_ci lastLBA = orig.lastLBA; 47cf200d32Sopenharmony_ci attributes = orig.attributes; 48cf200d32Sopenharmony_ci memcpy(name, orig.name, NAME_SIZE * sizeof( name[ 0 ] ) ); 49cf200d32Sopenharmony_ci} // Copy constructor 50cf200d32Sopenharmony_ci 51cf200d32Sopenharmony_ciGPTPart::~GPTPart(void) { 52cf200d32Sopenharmony_ci} // destructor 53cf200d32Sopenharmony_ci 54cf200d32Sopenharmony_ci// Return the gdisk-specific two-byte hex code for the partition 55cf200d32Sopenharmony_ciuint16_t GPTPart::GetHexType(void) const { 56cf200d32Sopenharmony_ci return partitionType.GetHexType(); 57cf200d32Sopenharmony_ci} // GPTPart::GetHexType() 58cf200d32Sopenharmony_ci 59cf200d32Sopenharmony_ci// Return a plain-text description of the partition type (e.g., "Linux/Windows 60cf200d32Sopenharmony_ci// data" or "Linux swap"). 61cf200d32Sopenharmony_cistring GPTPart::GetTypeName(void) { 62cf200d32Sopenharmony_ci return partitionType.TypeName(); 63cf200d32Sopenharmony_ci} // GPTPart::GetNameType() 64cf200d32Sopenharmony_ci 65cf200d32Sopenharmony_ci#ifdef USE_UTF16 66cf200d32Sopenharmony_ci// Return a Unicode description of the partition type (e.g., "Linux/Windows 67cf200d32Sopenharmony_ci// data" or "Linux swap"). 68cf200d32Sopenharmony_ciUnicodeString GPTPart::GetUTypeName(void) { 69cf200d32Sopenharmony_ci return partitionType.UTypeName(); 70cf200d32Sopenharmony_ci} // GPTPart::GetNameType() 71cf200d32Sopenharmony_ci#endif 72cf200d32Sopenharmony_ci 73cf200d32Sopenharmony_ci// Compute and return the partition's length (or 0 if the end is incorrectly 74cf200d32Sopenharmony_ci// set before the beginning). 75cf200d32Sopenharmony_ciuint64_t GPTPart::GetLengthLBA(void) const { 76cf200d32Sopenharmony_ci uint64_t length = 0; 77cf200d32Sopenharmony_ci 78cf200d32Sopenharmony_ci if (firstLBA <= lastLBA) 79cf200d32Sopenharmony_ci length = lastLBA - firstLBA + UINT64_C(1); 80cf200d32Sopenharmony_ci return length; 81cf200d32Sopenharmony_ci} // GPTPart::GetLengthLBA() 82cf200d32Sopenharmony_ci 83cf200d32Sopenharmony_ci#ifdef USE_UTF16 84cf200d32Sopenharmony_ci// Return partition's name field, converted to a Unicode string 85cf200d32Sopenharmony_ciUnicodeString GPTPart::GetDescription(void) { 86cf200d32Sopenharmony_ci return (UChar*) name; 87cf200d32Sopenharmony_ci} // GPTPart::GetDescription() 88cf200d32Sopenharmony_ci#else 89cf200d32Sopenharmony_ci// Return partition's name field, converted to a C++ UTF-8 string 90cf200d32Sopenharmony_cistring GPTPart::GetDescription(void) { 91cf200d32Sopenharmony_ci // convert name to utf32 then to utf8 92cf200d32Sopenharmony_ci string utf8 ; 93cf200d32Sopenharmony_ci size_t pos = 0 ; 94cf200d32Sopenharmony_ci while ( ( pos < NAME_SIZE ) && ( name[ pos ] != 0 ) ) { 95cf200d32Sopenharmony_ci uint16_t cp = name[ pos ++ ] ; 96cf200d32Sopenharmony_ci // first to utf32 97cf200d32Sopenharmony_ci uint32_t uni ; 98cf200d32Sopenharmony_ci if ( cp < 0xd800 || cp > 0xdfff ) { 99cf200d32Sopenharmony_ci uni = cp ; 100cf200d32Sopenharmony_ci } // if 101cf200d32Sopenharmony_ci else if ( cp < 0xdc00 ) { 102cf200d32Sopenharmony_ci // lead surrogate 103cf200d32Sopenharmony_ci uni = ( (uint32_t)( cp & 0x3ff ) ) << 10 ; 104cf200d32Sopenharmony_ci if ( pos >= NAME_SIZE ) { 105cf200d32Sopenharmony_ci // missing trail surrogate, name[] is invalid 106cf200d32Sopenharmony_ci break ; 107cf200d32Sopenharmony_ci } // if 108cf200d32Sopenharmony_ci cp = name[ pos ++ ] ; 109cf200d32Sopenharmony_ci if ( cp < 0xdc00 || cp > 0xdfff ) { 110cf200d32Sopenharmony_ci // invalid trail surrogate, name[] is invalid 111cf200d32Sopenharmony_ci break ; 112cf200d32Sopenharmony_ci } // if 113cf200d32Sopenharmony_ci // trail surrogate 114cf200d32Sopenharmony_ci uni |= cp & 0x3ff ; 115cf200d32Sopenharmony_ci uni += 0x10000 ; 116cf200d32Sopenharmony_ci } // if 117cf200d32Sopenharmony_ci else { 118cf200d32Sopenharmony_ci // unexpected trail surrogate, name[] is invalid 119cf200d32Sopenharmony_ci break ; 120cf200d32Sopenharmony_ci } // if 121cf200d32Sopenharmony_ci // then to utf8 122cf200d32Sopenharmony_ci if ( uni < 0x80 ) { 123cf200d32Sopenharmony_ci utf8 += (char) uni ; 124cf200d32Sopenharmony_ci } // if 125cf200d32Sopenharmony_ci else if ( uni < 0x800 ) { 126cf200d32Sopenharmony_ci utf8 += (char) ( 0xc0 | ( uni >> 6 ) ) ; 127cf200d32Sopenharmony_ci utf8 += (char) ( 0x80 | ( uni & 0x3f ) ) ; 128cf200d32Sopenharmony_ci } // if 129cf200d32Sopenharmony_ci else if ( uni < 0x10000 ) { 130cf200d32Sopenharmony_ci utf8 += (char) ( 0xe0 | ( uni >> 12 ) ) ; 131cf200d32Sopenharmony_ci utf8 += (char) ( 0x80 | ( ( uni >> 6 ) & 0x3f ) ) ; 132cf200d32Sopenharmony_ci utf8 += (char) ( 0x80 | ( uni & 0x3f ) ) ; 133cf200d32Sopenharmony_ci } // if 134cf200d32Sopenharmony_ci else { 135cf200d32Sopenharmony_ci utf8 += (char) ( 0xf0 | ( uni >> 18 ) ) ; 136cf200d32Sopenharmony_ci utf8 += (char) ( 0xe0 | ( ( uni >> 12 ) & 0x3f ) ) ; 137cf200d32Sopenharmony_ci utf8 += (char) ( 0x80 | ( ( uni >> 6 ) & 0x3f ) ) ; 138cf200d32Sopenharmony_ci utf8 += (char) ( 0x80 | ( uni & 0x3f ) ) ; 139cf200d32Sopenharmony_ci } // if 140cf200d32Sopenharmony_ci } 141cf200d32Sopenharmony_ci return utf8 ; 142cf200d32Sopenharmony_ci} // GPTPart::GetDescription(), UTF-8 version 143cf200d32Sopenharmony_ci#endif 144cf200d32Sopenharmony_ci 145cf200d32Sopenharmony_ci// Return 1 if the partition is in use 146cf200d32Sopenharmony_ciint GPTPart::IsUsed(void) { 147cf200d32Sopenharmony_ci return (partitionType != GUIDData("0x00")); 148cf200d32Sopenharmony_ci} // GPTPart::IsUsed() 149cf200d32Sopenharmony_ci 150cf200d32Sopenharmony_ci// Returns MBR_SIZED_GOOD, MBR_SIZED_IFFY, or MBR_SIZED_BAD; see comments 151cf200d32Sopenharmony_ci// in header file for details. 152cf200d32Sopenharmony_ciint GPTPart::IsSizedForMBR(void) { 153cf200d32Sopenharmony_ci int retval = MBR_SIZED_GOOD; 154cf200d32Sopenharmony_ci 155cf200d32Sopenharmony_ci if ((firstLBA > UINT32_MAX) || ((lastLBA - firstLBA) > UINT32_MAX) || (firstLBA > lastLBA)) 156cf200d32Sopenharmony_ci retval = MBR_SIZED_BAD; 157cf200d32Sopenharmony_ci else if (lastLBA > UINT32_MAX) 158cf200d32Sopenharmony_ci retval = MBR_SIZED_IFFY; 159cf200d32Sopenharmony_ci 160cf200d32Sopenharmony_ci return (retval); 161cf200d32Sopenharmony_ci} // GPTPart::IsSizedForMBR() 162cf200d32Sopenharmony_ci 163cf200d32Sopenharmony_ci// Set the type code to the specified one. Also changes the partition 164cf200d32Sopenharmony_ci// name *IF* the current name is the generic one for the current partition 165cf200d32Sopenharmony_ci// type. 166cf200d32Sopenharmony_civoid GPTPart::SetType(PartType t) { 167cf200d32Sopenharmony_ci#ifdef USE_UTF16 168cf200d32Sopenharmony_ci if (GetDescription() == partitionType.UTypeName()) { 169cf200d32Sopenharmony_ci#else 170cf200d32Sopenharmony_ci if (GetDescription() == partitionType.TypeName()) { 171cf200d32Sopenharmony_ci#endif 172cf200d32Sopenharmony_ci SetName(t.TypeName()); 173cf200d32Sopenharmony_ci } // if 174cf200d32Sopenharmony_ci partitionType = t; 175cf200d32Sopenharmony_ci} // GPTPart::SetType() 176cf200d32Sopenharmony_ci 177cf200d32Sopenharmony_ci#ifdef USE_UTF16 178cf200d32Sopenharmony_ci// Set the name for a partition to theName, using a C++-style string as 179cf200d32Sopenharmony_ci// input. 180cf200d32Sopenharmony_civoid GPTPart::SetName(const string & theName) { 181cf200d32Sopenharmony_ci SetName((UnicodeString) theName.c_str()); 182cf200d32Sopenharmony_ci} // GPTPart::SetName() 183cf200d32Sopenharmony_ci 184cf200d32Sopenharmony_ci// Set the name for a partition to theName, using a Unicode string as 185cf200d32Sopenharmony_ci// input. 186cf200d32Sopenharmony_civoid GPTPart::SetName(const UnicodeString & theName) { 187cf200d32Sopenharmony_ci if (theName.isBogus()) { 188cf200d32Sopenharmony_ci cerr << "Bogus UTF-16 name found in GPTPart::SetName()! Name not changed!\n"; 189cf200d32Sopenharmony_ci } else { 190cf200d32Sopenharmony_ci memset(name, 0, NAME_SIZE * sizeof(name[0]) ); 191cf200d32Sopenharmony_ci theName.extractBetween(0, NAME_SIZE, (UChar*) name); 192cf200d32Sopenharmony_ci } // if/else 193cf200d32Sopenharmony_ci} // GPTPart::SetName() 194cf200d32Sopenharmony_ci 195cf200d32Sopenharmony_ci#else 196cf200d32Sopenharmony_ci 197cf200d32Sopenharmony_ci// Set the name for a partition to theName. Note that theName is a 198cf200d32Sopenharmony_ci// standard C++-style ASCII string, although the GUID partition definition 199cf200d32Sopenharmony_ci// requires a UTF-16LE string. This function creates a simple-minded copy 200cf200d32Sopenharmony_ci// for this. 201cf200d32Sopenharmony_civoid GPTPart::SetName(const string & theName) { 202cf200d32Sopenharmony_ci // convert utf8 to utf32 then to utf16le 203cf200d32Sopenharmony_ci size_t len = theName.length() ; 204cf200d32Sopenharmony_ci size_t pos = 0 ; 205cf200d32Sopenharmony_ci for ( size_t i = 0 ; pos < NAME_SIZE && i < len ; ) { 206cf200d32Sopenharmony_ci uint32_t uni ; 207cf200d32Sopenharmony_ci uint8_t cp = theName[ i ++ ] ; 208cf200d32Sopenharmony_ci int todo ; 209cf200d32Sopenharmony_ci if ( cp < 0x80 ) { 210cf200d32Sopenharmony_ci uni = cp ; 211cf200d32Sopenharmony_ci todo = 0 ; 212cf200d32Sopenharmony_ci } // if 213cf200d32Sopenharmony_ci else if ( cp < 0xc0 || cp > 0xf7 ) { 214cf200d32Sopenharmony_ci // invalid byte, theName is broken 215cf200d32Sopenharmony_ci break ; 216cf200d32Sopenharmony_ci } // if 217cf200d32Sopenharmony_ci else if ( cp < 0xe0 ) { 218cf200d32Sopenharmony_ci uni = cp & 0x1f ; 219cf200d32Sopenharmony_ci todo = 1 ; 220cf200d32Sopenharmony_ci } // if 221cf200d32Sopenharmony_ci else if ( cp < 0xf0 ) { 222cf200d32Sopenharmony_ci uni = cp & 0x0f ; 223cf200d32Sopenharmony_ci todo = 2 ; 224cf200d32Sopenharmony_ci } // if 225cf200d32Sopenharmony_ci else { 226cf200d32Sopenharmony_ci uni = cp & 0x7 ; 227cf200d32Sopenharmony_ci todo = 3 ; 228cf200d32Sopenharmony_ci } // if 229cf200d32Sopenharmony_ci while ( todo > 0 ) { 230cf200d32Sopenharmony_ci if ( i >= len ) { 231cf200d32Sopenharmony_ci // missing continuation byte, theName is broken 232cf200d32Sopenharmony_ci goto break_converter ; 233cf200d32Sopenharmony_ci } // if 234cf200d32Sopenharmony_ci cp = theName[ i ++ ] ; 235cf200d32Sopenharmony_ci if ( cp > 0xbf || cp < 0x80 ) { 236cf200d32Sopenharmony_ci // invalid continuation byte, theName is broken 237cf200d32Sopenharmony_ci goto break_converter ; 238cf200d32Sopenharmony_ci } // if 239cf200d32Sopenharmony_ci uni <<= 6 ; 240cf200d32Sopenharmony_ci uni |= cp & 0x3f ; 241cf200d32Sopenharmony_ci todo -- ; 242cf200d32Sopenharmony_ci } // while 243cf200d32Sopenharmony_ci // then to utf16le 244cf200d32Sopenharmony_ci if ( uni < 0x10000 ) { 245cf200d32Sopenharmony_ci name[ pos ] = (uint16_t) uni ; 246cf200d32Sopenharmony_ci pos ++ ; 247cf200d32Sopenharmony_ci } // if 248cf200d32Sopenharmony_ci else { 249cf200d32Sopenharmony_ci if ( pos > NAME_SIZE - 2 ) { 250cf200d32Sopenharmony_ci // not enough room for two surrogates, truncate 251cf200d32Sopenharmony_ci break ; 252cf200d32Sopenharmony_ci } // if 253cf200d32Sopenharmony_ci uni -= 0x10000 ; 254cf200d32Sopenharmony_ci name[ pos ] = (uint16_t)( uni >> 10 ) | 0xd800 ; 255cf200d32Sopenharmony_ci pos ++ ; 256cf200d32Sopenharmony_ci name[ pos ] = (uint16_t)( uni & 0x3ff ) | 0xdc00 ; 257cf200d32Sopenharmony_ci pos ++ ; 258cf200d32Sopenharmony_ci } 259cf200d32Sopenharmony_ci } // for 260cf200d32Sopenharmony_ci break_converter : ; 261cf200d32Sopenharmony_ci // finally fill with zeroes 262cf200d32Sopenharmony_ci while ( pos < NAME_SIZE ) { 263cf200d32Sopenharmony_ci name[ pos ++ ] = 0 ; 264cf200d32Sopenharmony_ci } // while 265cf200d32Sopenharmony_ci} // GPTPart::SetName(), UTF-8 version 266cf200d32Sopenharmony_ci#endif 267cf200d32Sopenharmony_ci 268cf200d32Sopenharmony_ci// Set the name for the partition based on the current GUID partition type 269cf200d32Sopenharmony_ci// code's associated name 270cf200d32Sopenharmony_civoid GPTPart::SetDefaultDescription(void) { 271cf200d32Sopenharmony_ci SetName(partitionType.TypeName()); 272cf200d32Sopenharmony_ci} // GPTPart::SetDefaultDescription() 273cf200d32Sopenharmony_ci 274cf200d32Sopenharmony_ciGPTPart & GPTPart::operator=(const GPTPart & orig) { 275cf200d32Sopenharmony_ci partitionType = orig.partitionType; 276cf200d32Sopenharmony_ci uniqueGUID = orig.uniqueGUID; 277cf200d32Sopenharmony_ci firstLBA = orig.firstLBA; 278cf200d32Sopenharmony_ci lastLBA = orig.lastLBA; 279cf200d32Sopenharmony_ci attributes = orig.attributes; 280cf200d32Sopenharmony_ci memcpy(name, orig.name, NAME_SIZE * sizeof( name[ 0 ] ) ); 281cf200d32Sopenharmony_ci return *this; 282cf200d32Sopenharmony_ci} // assignment operator 283cf200d32Sopenharmony_ci 284cf200d32Sopenharmony_ci// Compare the values, and return a bool result. 285cf200d32Sopenharmony_ci// Because this is intended for sorting and a firstLBA value of 0 denotes 286cf200d32Sopenharmony_ci// a partition that's not in use and so that should be sorted upwards, 287cf200d32Sopenharmony_ci// we return the opposite of the usual arithmetic result when either 288cf200d32Sopenharmony_ci// firstLBA value is 0. 289cf200d32Sopenharmony_cibool GPTPart::operator<(const GPTPart &other) const { 290cf200d32Sopenharmony_ci if (firstLBA && other.firstLBA) 291cf200d32Sopenharmony_ci return (firstLBA < other.firstLBA); 292cf200d32Sopenharmony_ci else 293cf200d32Sopenharmony_ci return (other.firstLBA < firstLBA); 294cf200d32Sopenharmony_ci} // GPTPart::operator<() 295cf200d32Sopenharmony_ci 296cf200d32Sopenharmony_ci// Display summary information; does nothing if the partition is empty. 297cf200d32Sopenharmony_civoid GPTPart::ShowSummary(int partNum, uint32_t blockSize) { 298cf200d32Sopenharmony_ci string sizeInIeee; 299cf200d32Sopenharmony_ci UnicodeString description; 300cf200d32Sopenharmony_ci size_t i; 301cf200d32Sopenharmony_ci 302cf200d32Sopenharmony_ci if (firstLBA != 0) { 303cf200d32Sopenharmony_ci sizeInIeee = BytesToIeee(lastLBA - firstLBA + 1, blockSize); 304cf200d32Sopenharmony_ci cout.fill(' '); 305cf200d32Sopenharmony_ci cout.width(4); 306cf200d32Sopenharmony_ci cout << partNum + 1 << " "; 307cf200d32Sopenharmony_ci cout.width(14); 308cf200d32Sopenharmony_ci cout << firstLBA << " "; 309cf200d32Sopenharmony_ci cout.width(14); 310cf200d32Sopenharmony_ci cout << lastLBA << " "; 311cf200d32Sopenharmony_ci cout << sizeInIeee << " "; 312cf200d32Sopenharmony_ci if (sizeInIeee.length() < 10) 313cf200d32Sopenharmony_ci for (i = 0; i < 10 - sizeInIeee.length(); i++) 314cf200d32Sopenharmony_ci cout << " "; 315cf200d32Sopenharmony_ci cout.fill('0'); 316cf200d32Sopenharmony_ci cout.width(4); 317cf200d32Sopenharmony_ci cout.setf(ios::uppercase); 318cf200d32Sopenharmony_ci cout << hex << partitionType.GetHexType() << " " << dec; 319cf200d32Sopenharmony_ci cout.fill(' '); 320cf200d32Sopenharmony_ci#ifdef USE_UTF16 321cf200d32Sopenharmony_ci GetDescription().extractBetween(0, 23, description); 322cf200d32Sopenharmony_ci cout << description << "\n"; 323cf200d32Sopenharmony_ci#else 324cf200d32Sopenharmony_ci string desc = GetDescription() ; 325cf200d32Sopenharmony_ci size_t n = 0 ; 326cf200d32Sopenharmony_ci size_t i = 0 ; 327cf200d32Sopenharmony_ci size_t len = desc.length() ; 328cf200d32Sopenharmony_ci while ( n < 22 && i < len ) { 329cf200d32Sopenharmony_ci i ++ ; 330cf200d32Sopenharmony_ci if ( i >= len ) { 331cf200d32Sopenharmony_ci // short description 332cf200d32Sopenharmony_ci break ; 333cf200d32Sopenharmony_ci } // if 334cf200d32Sopenharmony_ci // skip continuation bytes 335cf200d32Sopenharmony_ci while ( i < len && ( ( desc[ i ] & 0xC0 ) == 0x80 ) ) { 336cf200d32Sopenharmony_ci // utf8 continuation byte 337cf200d32Sopenharmony_ci i ++ ; 338cf200d32Sopenharmony_ci } // while 339cf200d32Sopenharmony_ci n ++ ; 340cf200d32Sopenharmony_ci } // while 341cf200d32Sopenharmony_ci if ( i < len ) { 342cf200d32Sopenharmony_ci n = 0 ; 343cf200d32Sopenharmony_ci i = 0 ; 344cf200d32Sopenharmony_ci // description is long we will truncate it 345cf200d32Sopenharmony_ci while ( n < 19 && i < len ) { 346cf200d32Sopenharmony_ci i ++ ; 347cf200d32Sopenharmony_ci if ( i >= len ) { 348cf200d32Sopenharmony_ci // should not happen 349cf200d32Sopenharmony_ci break ; 350cf200d32Sopenharmony_ci } // if 351cf200d32Sopenharmony_ci // skip continuation bytes 352cf200d32Sopenharmony_ci while ( i < len && ( ( desc[ i ] & 0xC0 ) == 0x80 ) ) { 353cf200d32Sopenharmony_ci // utf8 continuation byte 354cf200d32Sopenharmony_ci i ++ ; 355cf200d32Sopenharmony_ci } // while 356cf200d32Sopenharmony_ci n ++ ; 357cf200d32Sopenharmony_ci } // while 358cf200d32Sopenharmony_ci } // for 359cf200d32Sopenharmony_ci cout << GetDescription().substr( 0 , i ) ; 360cf200d32Sopenharmony_ci if ( i < len ) cout << "..." ; 361cf200d32Sopenharmony_ci cout << "\n"; 362cf200d32Sopenharmony_ci#endif 363cf200d32Sopenharmony_ci cout.fill(' '); 364cf200d32Sopenharmony_ci } // if 365cf200d32Sopenharmony_ci} // GPTPart::ShowSummary() 366cf200d32Sopenharmony_ci 367cf200d32Sopenharmony_ci// Show detailed partition information. Does nothing if the partition is 368cf200d32Sopenharmony_ci// empty (as determined by firstLBA being 0). 369cf200d32Sopenharmony_civoid GPTPart::ShowDetails(uint32_t blockSize) { 370cf200d32Sopenharmony_ci uint64_t size; 371cf200d32Sopenharmony_ci 372cf200d32Sopenharmony_ci if (firstLBA != 0) { 373cf200d32Sopenharmony_ci cout << "Partition GUID code: " << partitionType; 374cf200d32Sopenharmony_ci cout << " (" << partitionType.TypeName() << ")\n"; 375cf200d32Sopenharmony_ci cout << "Partition unique GUID: " << uniqueGUID << "\n"; 376cf200d32Sopenharmony_ci 377cf200d32Sopenharmony_ci cout << "First sector: " << firstLBA << " (at " 378cf200d32Sopenharmony_ci << BytesToIeee(firstLBA, blockSize) << ")\n"; 379cf200d32Sopenharmony_ci cout << "Last sector: " << lastLBA << " (at " 380cf200d32Sopenharmony_ci << BytesToIeee(lastLBA, blockSize) << ")\n"; 381cf200d32Sopenharmony_ci size = (lastLBA - firstLBA + 1); 382cf200d32Sopenharmony_ci cout << "Partition size: " << size << " sectors (" 383cf200d32Sopenharmony_ci << BytesToIeee(size, blockSize) << ")\n"; 384cf200d32Sopenharmony_ci cout << "Attribute flags: "; 385cf200d32Sopenharmony_ci cout.fill('0'); 386cf200d32Sopenharmony_ci cout.width(16); 387cf200d32Sopenharmony_ci cout << hex; 388cf200d32Sopenharmony_ci cout << attributes << "\n"; 389cf200d32Sopenharmony_ci cout << dec; 390cf200d32Sopenharmony_ci cout << "Partition name: '" << GetDescription() << "'\n"; 391cf200d32Sopenharmony_ci cout.fill(' '); 392cf200d32Sopenharmony_ci } // if 393cf200d32Sopenharmony_ci} // GPTPart::ShowDetails() 394cf200d32Sopenharmony_ci 395cf200d32Sopenharmony_ci// Blank (delete) a single partition 396cf200d32Sopenharmony_civoid GPTPart::BlankPartition(void) { 397cf200d32Sopenharmony_ci uniqueGUID.Zero(); 398cf200d32Sopenharmony_ci partitionType.Zero(); 399cf200d32Sopenharmony_ci firstLBA = 0; 400cf200d32Sopenharmony_ci lastLBA = 0; 401cf200d32Sopenharmony_ci attributes = 0; 402cf200d32Sopenharmony_ci memset(name, 0, NAME_SIZE * sizeof( name[0]) ); 403cf200d32Sopenharmony_ci} // GPTPart::BlankPartition 404cf200d32Sopenharmony_ci 405cf200d32Sopenharmony_ci// Returns 1 if the two partitions overlap, 0 if they don't 406cf200d32Sopenharmony_ciint GPTPart::DoTheyOverlap(const GPTPart & other) { 407cf200d32Sopenharmony_ci // Don't bother checking unless these are defined (both start and end points 408cf200d32Sopenharmony_ci // are 0 for undefined partitions, so just check the start points) 409cf200d32Sopenharmony_ci return firstLBA && other.firstLBA && 410cf200d32Sopenharmony_ci (firstLBA <= other.lastLBA) != (lastLBA < other.firstLBA); 411cf200d32Sopenharmony_ci} // GPTPart::DoTheyOverlap() 412cf200d32Sopenharmony_ci 413cf200d32Sopenharmony_ci// Reverse the bytes of integral data types and of the UTF-16LE name; 414cf200d32Sopenharmony_ci// used on big-endian systems. 415cf200d32Sopenharmony_civoid GPTPart::ReversePartBytes(void) { 416cf200d32Sopenharmony_ci ReverseBytes(&firstLBA, 8); 417cf200d32Sopenharmony_ci ReverseBytes(&lastLBA, 8); 418cf200d32Sopenharmony_ci ReverseBytes(&attributes, 8); 419cf200d32Sopenharmony_ci ReverseNameBytes(); 420cf200d32Sopenharmony_ci} // GPTPart::ReversePartBytes() 421cf200d32Sopenharmony_ci 422cf200d32Sopenharmony_civoid GPTPart::ReverseNameBytes(void) { 423cf200d32Sopenharmony_ci int i; 424cf200d32Sopenharmony_ci 425cf200d32Sopenharmony_ci for (i = 0; i < NAME_SIZE; i ++ ) 426cf200d32Sopenharmony_ci ReverseBytes(name + i, 2); 427cf200d32Sopenharmony_ci} // GPTPart::ReverseNameBytes() 428cf200d32Sopenharmony_ci 429cf200d32Sopenharmony_ci/**************************************** 430cf200d32Sopenharmony_ci * Functions requiring user interaction * 431cf200d32Sopenharmony_ci ****************************************/ 432cf200d32Sopenharmony_ci 433cf200d32Sopenharmony_ci// Change the type code on the partition. Also changes the name if the original 434cf200d32Sopenharmony_ci// name is the generic one for the partition type. 435cf200d32Sopenharmony_civoid GPTPart::ChangeType(void) { 436cf200d32Sopenharmony_ci string line; 437cf200d32Sopenharmony_ci int changeName; 438cf200d32Sopenharmony_ci PartType tempType = PartType::unusedPartType; 439cf200d32Sopenharmony_ci 440cf200d32Sopenharmony_ci#ifdef USE_UTF16 441cf200d32Sopenharmony_ci changeName = (GetDescription() == GetUTypeName()); 442cf200d32Sopenharmony_ci#else 443cf200d32Sopenharmony_ci changeName = (GetDescription() == GetTypeName()); 444cf200d32Sopenharmony_ci#endif 445cf200d32Sopenharmony_ci 446cf200d32Sopenharmony_ci cout << "Current type is " << hex << GetHexType() << dec << " (" << GetTypeName() << ")\n"; 447cf200d32Sopenharmony_ci do { 448cf200d32Sopenharmony_ci cout << "Hex code or GUID (L to show codes, Enter = " << hex << GetHexType() << dec << "): "; 449cf200d32Sopenharmony_ci line = ReadString(); 450cf200d32Sopenharmony_ci if ((line[0] == 'L') || (line[0] == 'l')) { 451cf200d32Sopenharmony_ci partitionType.ShowAllTypes(); 452cf200d32Sopenharmony_ci } else { 453cf200d32Sopenharmony_ci if (line.length() == 0) 454cf200d32Sopenharmony_ci tempType = GetHexType(); 455cf200d32Sopenharmony_ci else 456cf200d32Sopenharmony_ci tempType = line; 457cf200d32Sopenharmony_ci } // if/else 458cf200d32Sopenharmony_ci } while (tempType == PartType::unusedPartType); 459cf200d32Sopenharmony_ci partitionType = tempType; 460cf200d32Sopenharmony_ci cout << "Changed type of partition to '" << partitionType.TypeName() << "'\n"; 461cf200d32Sopenharmony_ci if (changeName) { 462cf200d32Sopenharmony_ci SetDefaultDescription(); 463cf200d32Sopenharmony_ci } // if 464cf200d32Sopenharmony_ci} // GPTPart::ChangeType() 465