Commit 420630cb authored by Guillaume Delacour's avatar Guillaume Delacour

Imported Upstream version 0.7.2

parent ae73c664
CC=gcc
CXX=g++
CFLAGS+=-D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16
#CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64
LDFLAGS+=
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
#LIB_SRCS=$(NAMES:=.cc)
LIB_OBJS=$(LIB_NAMES:=.o)
MBR_LIB_OBJS=$(MBR_LIBS:=.o)
LIB_HEADERS=$(LIB_NAMES:=.h)
......@@ -14,10 +14,12 @@ DEPEND= makedepend $(CXXFLAGS)
all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -licuio -luuid -o gdisk
# $(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -luuid -o gdisk
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o $(LDFLAGS) -licuio -licuuc -luuid -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -licuio -luuid -lpopt -o sgdisk
# $(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -luuid -lpopt -o sgdisk
$(CXX) $(LIB_OBJS) sgdisk.o $(LDFLAGS) -licuio -licuuc -luuid -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts
......
CC=gcc
CXX=g++
CFLAGS+=-D_FILE_OFFSET_BITS=64
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -I/usr/local/include
CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16 -I/usr/local/include
#CXXFLAGS+=-Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include
LDFLAGS+=
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
......@@ -14,9 +15,11 @@ all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -licuio -luuid -o gdisk
# $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -luuid -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -L/usr/local/lib $(LDFLAGS) -luuid -licuio -lpopt -o sgdisk
# $(CXX) $(LIB_OBJS) sgdisk.o -L/usr/local/lib $(LDFLAGS) -luuid -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o -L/usr/local/lib $(LDFLAGS) -o fixparts
......
CC=gcc
CXX=g++
CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g
CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -D USE_UTF16 -I/sw/include -I/usr/local/include -I/opt/local/include -g
#CXXFLAGS=-O2 -Wall -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
LIB_NAMES=crc32 support guid gptpart mbrpart basicmbr mbr gpt bsd parttypes attributes diskio diskio-unix
MBR_LIBS=support diskio diskio-unix basicmbr mbrpart
#LIB_SRCS=$(NAMES:=.cc)
......@@ -12,11 +13,13 @@ DEPEND= makedepend $(CFLAGS)
all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gpttext.o gdisk.o
$(CXX) $(LIB_OBJS) -L/usr/local/lib -licuuc -licuio -licudata gpttext.o gdisk.o -o gdisk
gdisk: $(LIB_OBJS) gpttext.o gdisk.o
# $(CXX) $(LIB_OBJS) gpttext.o gdisk.o -o gdisk
$(CXX) $(LIB_OBJS) -L/usr/lib -licucore gpttext.o gdisk.o -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib -licudata -licuio -licuuc -lpopt -o sgdisk
# $(CXX) $(LIB_OBJS) sgdisk.o -L/sw/lib -lpopt -o sgdisk
$(CXX) $(LIB_OBJS) sgdisk.o -L/sw/lib -licucore -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o $(LDFLAGS) -o fixparts
......
......@@ -15,7 +15,7 @@ DEPEND= makedepend $(CFLAGS)
all: gdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o -luuid -static-libgcc -o gdisk.exe
$(CXX) $(LIB_OBJS) gdisk.o gpttext.o -lrpcrt4 -static-libgcc -o gdisk.exe
sgdisk: $(LIB_OBJS) sgdisk.o
$(CXX) $(LIB_OBJS) sgdisk.o -lpopt -static-libgcc -o sgdisk.exe
......
0.7.2 (6/26/2011):
------------------
- The Windows version now (finally!) generates proper GUIDs rather than a
purely random number. This fixes a bug that caused Windows 7 to crash
when converting a disk from MBR format (but, oddly, not when creating a
fresh partition table or doing various other things).
- Added a warning when an MBR partition is discarded because it's too
big for the disk.
- Changed warning to Windows users about the dangers of converting to GPT
so that it appears only on disks that aren't already in GPT form.
- Fixed bug that caused bogus "3" values to pad the ends of partition names
on some disks (particularly those created by Microsoft's disk
partitioning tools).
- Made compilation without Unicode support possible (see README file)
- Made default filesystem type code OS-dependent (based on the compilation
platform).
- Added new Linux-only filesystem partition type GUID code,
0FC63DAF-8483-4772-8E79-3D69D8477DE4 (8300 entry code). Also changed name
of the EBD0A0A2-B9E5-4433-87C0-68B6B72699C7 (0700 entry code) to
"Microsoft basic data").
- Fixed a bug that caused an incorrect code to be set for active/bootable
partitions when generating a hybrid MBR.
- Enable entry of hex codes that begin with "0x" for both GPT and MBR
partitions.
- Fixed bug that caused the boot loader code to be lost when creating a
hybrid MBR.
- Fixed bug in sector input code that could produce improper values
if the user inputs ridiculously large "+" values.
0.7.1 (3/21/2011):
------------------
......
......@@ -160,19 +160,26 @@ used.) In addition, note these requirements:
called uuid-dev or something similar to get the headers. On FreeBSD, the
e2fsprogs-libuuid port must be installed.
* The ICU library (http://site.icu-project.org) is required on all
platforms except Windows. This library is normally installed in Linux,
but you may need to install the development headers (libicu-dev or
something similar).
* The ICU library (http://site.icu-project.org), which provides support for
Unicode partition names, is recommended on all
platforms except Windows. This library is normally installed in Linux and
OS X, but you may need to install the development headers (libicu-dev or
something similar in Linux; or the libicu36-dev Fink package in OS X). To
compile without ICU support, you must modify the Makefile: Remove the
"-D USE_UTF16" part from the CXXFLAGS line and remove references to
-licuio, -licuuc, -licudata, and -licucore (details vary between
platforms) from the compilation options. Suitable lines are present, but
commented out, in the Makefile, Makefile.mac, and Makefile.bsd files.
* The sgdisk program also requires the popt library and its development
files (headers). Most Linux distributions install popt by default, but
you may need to install a package called popt-dev, popt-devel, or
something similar to obtain the header files. Mac OS users can find a
version of popt for Mac OS from http://popt.darwinports.com; however,
you'll first need to install DarwinPorts (instructions exist on the
preceding page). Alternatively, you can compile gdisk alone, without
sgdisk; gdisk doesn't require popt.
version of popt for Mac OS from Drawin Ports (http://popt.darwinports.com)
or Fink (http://www.finkproject.org); however, you'll first need to
install DarwinPorts or Fink (instructions exist on the relevant projects'
pages). Alternatively, you can compile gdisk alone, without sgdisk; gdisk
doesn't require popt.
When all the necessary development tools and libraries are installed, you
can uncompress the package and type "make" at the command prompt in the
......@@ -192,17 +199,17 @@ Caveats
THIS SOFTWARE IS BETA SOFTWARE! IF IT WIPES OUT YOUR HARD DISK OR EATS YOUR
CAT, DON'T BLAME ME! To date, I've tested the software on several USB flash
drives, a handful of PATA and SATA hard disks, and several virtual disks in
the QEMU and VirtualBox environments. Many others have now used the
software on their computers, as well. I believe all data-corruption bugs to
be squashed, but I know full well that the odds of my missing something are
high. This is particularly true for large drives; my only direct testing
with such disks is with virtual QEMU disks. I've received user reports of
success with RAID arrays over 2TiB in size, though.
drives, physical hard disks, and virtual disks in the QEMU and VirtualBox
environments. Many others have now used the software on their computers, as
well. I believe all data-corruption bugs to be squashed, but I know full well
that the odds of my missing something are high. This is particularly true for
large (over-2TiB) drives; my only direct testing with such disks is with
virtual QEMU and VirtualBox disks. I've received user reports of success with
RAID arrays over 2TiB in size, though.
My main development platform is a system running the 64-bit version of
Gentoo Linux (previously Ubuntu 8.04). I've also tested on several other
32- and 64-bit Linux distributions Intel-based Mac OS X 10.5 and 10.6,
32- and 64-bit Linux distributions, Intel-based Mac OS X 10.5 and 10.6,
64-bit FreeBSD 7.1, and Windows 7.
Redistribution
......
......@@ -84,6 +84,10 @@ BasicMBRData & BasicMBRData::operator=(const BasicMBRData & orig) {
state = orig.state;
myDisk = new DiskIO;
if (myDisk == NULL) {
cerr << "Unable to allocate memory in BasicMBRData::operator=()! Terminating!\n";
exit(1);
} // if
if (orig.myDisk != NULL)
myDisk->OpenForRead(orig.myDisk->GetName());
......@@ -106,6 +110,10 @@ int BasicMBRData::ReadMBRData(const string & deviceFilename) {
if (myDisk == NULL) {
myDisk = new DiskIO;
if (myDisk == NULL) {
cerr << "Unable to allocate memory in BasicMBRData::ReadMBRData()! Terminating!\n";
exit(1);
} // if
canDeleteMyDisk = 1;
} // if
if (myDisk->OpenForRead(deviceFilename)) {
......@@ -122,9 +130,9 @@ int BasicMBRData::ReadMBRData(const string & deviceFilename) {
// Read data from MBR. If checkBlockSize == 1 (the default), the block
// size is checked; otherwise it's set to the default (512 bytes).
// Note that any extended partition(s) present will be explicitly stored
// in the partitions[] array, along with their contained partitions; the
// extended container partition(s) should be ignored by other functions.
// Note that any extended partition(s) present will be omitted from
// in the partitions[] array; these partitions must be re-created when
// the partition table is saved in MBR format.
int BasicMBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
int allOK = 1, i, logicalNum = 0;
int err = 1;
......@@ -1092,7 +1100,8 @@ void BasicMBRData::SortMBR(int start) {
// Delete any partitions that are too big to fit on the disk
// or that are too big for MBR (32-bit limits).
// This really deletes the partitions by setting values to 0.
// This deletes the partitions by setting values to 0, not just
// by setting them as being omitted.
// Returns the number of partitions deleted in this way.
int BasicMBRData::DeleteOversizedParts() {
int num = 0, i;
......@@ -1100,6 +1109,8 @@ int BasicMBRData::DeleteOversizedParts() {
for (i = 0; i < MAX_MBR_PARTS; i++) {
if ((partitions[i].GetStartLBA() > diskSize) || (partitions[i].GetLastLBA() > diskSize) ||
(partitions[i].GetStartLBA() > UINT32_MAX) || (partitions[i].GetLengthLBA() > UINT32_MAX)) {
cerr << "\aWarning: Deleting oversized partition #" << i + 1 << "! Start = "
<< partitions[i].GetStartLBA() << ", length = " << partitions[i].GetLengthLBA() << "\n";
partitions[i].Empty();
num++;
} // if
......@@ -1497,7 +1508,8 @@ MBRPart* BasicMBRData::GetPartition(int i) {
// if the return value is >0, or possibly >=0 depending on intentions.)
int BasicMBRData::DoMenu(const string& prompt) {
int goOn = 1, quitting = 0, retval, num, haveShownInfo = 0;
unsigned int hexCode = 0x00;
unsigned int hexCode;
string tempStr;
do {
cout << prompt;
......@@ -1547,10 +1559,13 @@ int BasicMBRData::DoMenu(const string& prompt) {
break;
case 't': case 'T':
num = GetNumber(1, MAX_MBR_PARTS, 1, "Partition to change type code: ") - 1;
hexCode = 0x00;
if (partitions[num].GetLengthLBA() > 0) {
while ((hexCode <= 0) || (hexCode > 255)) {
cout << "Enter an MBR hex code: ";
hexCode = StrToHex(ReadString(), 0);
tempStr = ReadString();
if (IsHex(tempStr))
sscanf(tempStr.c_str(), "%x", &hexCode);
} // while
partitions[num].SetType(hexCode);
} // if
......
......@@ -18,8 +18,6 @@
using namespace std;
class PartNotes;
/****************************************
* *
* MBRData class and related structures *
......
......@@ -134,6 +134,10 @@ int BSDData::ReadBSDData(DiskIO *theDisk, uint64_t startSector, uint64_t endSect
// If the state is good, go ahead and load the main partition data....
if (state == bsd) {
partitions = new struct BSDRecord[numParts * sizeof(struct BSDRecord)];
if (partitions == NULL) {
cerr << "Unable to allocate memory in BSDData::ReadBSDData()! Terminating!\n";
exit(1);
} // if
for (i = 0; i < numParts; i++) {
// Once again, we use the buffer, but index it using a BSDRecord
// pointer (dangerous, but effective)....
......@@ -319,7 +323,7 @@ GPTPart BSDData::AsGPT(int i) {
case 27: // FreeBSD ZFS
guid.SetType(0xa504); break;
default:
guid.SetType(0x0700); break;
guid.SetType(0xa503); break;
} // switch
// Set the partition name to the name of the type code....
guid.SetName(guid.GetTypeName());
......
Summary: GPT partitioning and MBR repair software
Name: gptfdisk
Version: 0.7.1
Version: 0.7.2
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
Group: Applications/System
Source: http://www.rodsbooks.com/gdisk/gptfdisk-0.7.1.tgz
Source: http://www.rodsbooks.com/gdisk/gptfdisk-0.7.2.tar.gz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description
......@@ -77,5 +77,5 @@ provides a few additional partition manipulation features.
%changelog
* Mon Mar 21 2011 R Smith <rodsmith@rodsbooks.com> - 0.7.1
- Created spec file for 0.7.1 release
* Sun Jun 26 2011 R Smith <rodsmith@rodsbooks.com> - 0.7.2
- Created spec file for 0.7.2 release
......@@ -230,7 +230,8 @@ void DiskIO::DiskSync(void) {
platformFound++;
#endif
#ifdef __linux__
sleep(2);
sleep(1); // Theoretically unnecessary, but ioctl() fails sometimes if omitted....
fsync(fd);
i = ioctl(fd, BLKRRPART);
if (i)
cout << "Warning: The kernel is still using the old partition table.\n"
......@@ -290,6 +291,10 @@ int DiskIO::Read(void* buffer, int numBytes) {
numBlocks++;
tempSpace = new char [numBlocks * blockSize];
} // if/else
if (tempSpace == NULL) {
cerr << "Unable to allocate memory in DiskIO::Read()! Terminating!\n";
exit(1);
} // if
// Read the data into temporary space, then copy it to buffer
retval = read(fd, tempSpace, numBlocks * blockSize);
......@@ -328,7 +333,11 @@ int DiskIO::Write(void* buffer, int numBytes) {
if ((numBytes % blockSize) != 0) numBlocks++;
tempSpace = new char [numBlocks * blockSize];
} // if/else
if (tempSpace == NULL) {
cerr << "Unable to allocate memory in DiskIO::Write()! Terminating!\n";
exit(1);
} // if
// Copy the data to my own buffer, then write it
memcpy(tempSpace, buffer, numBytes);
for (i = numBytes; i < numBlocks * blockSize; i++) {
......
......@@ -230,7 +230,11 @@ int DiskIO::Read(void* buffer, int numBytes) {
numBlocks++;
tempSpace = new char [numBlocks * blockSize];
} // if/else
if (tempSpace == NULL) {
cerr << "Unable to allocate memory in DiskIO::Read()! Terminating!\n";
exit(1);
} // if
// Read the data into temporary space, then copy it to buffer
ReadFile(fd, tempSpace, numBlocks * blockSize, &retval, NULL);
for (i = 0; i < numBytes; i++) {
......@@ -271,6 +275,10 @@ int DiskIO::Write(void* buffer, int numBytes) {
if ((numBytes % blockSize) != 0) numBlocks++;
tempSpace = new char [numBlocks * blockSize];
} // if/else
if (tempSpace == NULL) {
cerr << "Unable to allocate memory in DiskIO::Write()! Terminating!\n";
exit(1);
} // if
// Copy the data to my own buffer, then write it
for (i = 0; i < numBytes; i++) {
......
.\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
.TH "FIXPARTS" "8" "0.7.1" "Roderick W. Smith" "FixParts Manual"
.TH "FIXPARTS" "8" "0.7.2" "Roderick W. Smith" "FixParts Manual"
.SH "NAME"
fixparts \- MBR partition table repair utility
.SH "SYNOPSIS"
......@@ -202,7 +202,7 @@ see a summary of available options.
.PP
.SH "BUGS"
As of March 2011 (version 0.7.1), \fBfixparts\fR
As of June 2011 (version 0.7.2), \fBfixparts\fR
should be considered beta software. Known bugs and limitations include:
.TP
......
.\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
.TH "GDISK" "8" "0.7.1" "Roderick W. Smith" "GPT fdisk Manual"
.TH "GDISK" "8" "0.7.2" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
......@@ -34,8 +34,8 @@ The \fBgdisk\fR program employs a user interface similar to that of Linux's
capability of transforming MBR partitions or BSD disklabels into GPT
partitions. Like the original \fBfdisk\fR program, \fBgdisk\fR does not
modify disk structures until you explicitly write them to disk, so if you
make a mistake, you can exit from the program with the 'q' option to save
your partitions.
make a mistake, you can exit from the program with the 'q' option to leave
your partitions unmodified.
Ordinarily, \fBgdisk\fR operates on disk device files, such as
\fI/dev/sda\fR or \fI/dev/hda\fR under Linux, \fI/dev/disk0\fR under
......@@ -177,19 +177,19 @@ displays this information for a single partition.
.TP
.B l
Display a summary of partition types. GPT uses a GUID to identify
partition types for particular OSes and purposes. For ease of data entry,
\fBgdisk\fR compresses these into two\-byte (four\-digit hexadecimal)
values that are related to their equivalent MBR codes. Specifically, the
MBR code is multiplied by hexadecimal 0x0100. For instance, the code for
Linux swap space in MBR is 0x82, and it's 0x8200 in \fBgdisk\fR.
A one\-to\-one correspondence is impossible, though. Most notably, many DOS,
Windows, and Linux data partition codes correspond to a single GPT code
(entered as 0x0700 in \fBgdisk\fR). Some OSes use a single MBR code but
employ many more codes in GPT. For these, \fBgdisk\fR
adds code numbers sequentially, such as 0xa500 for a FreeBSD disklabel,
0xa501 for FreeBSD boot, 0xa502 for FreeBSD swap, and so on. Note that
these two\-byte codes are unique to \fBgdisk\fR.
Display a summary of partition types. GPT uses a GUID to identify partition
types for particular OSes and purposes. For ease of data entry, \fBgdisk\fR
compresses these into two\-byte (four\-digit hexadecimal) values that are
related to their equivalent MBR codes. Specifically, the MBR code is
multiplied by hexadecimal 0x0100. For instance, the code for Linux swap
space in MBR is 0x82, and it's 0x8200 in \fBgdisk\fR. A one\-to\-one
correspondence is impossible, though. Most notably, the codes for all
varieties of FAT and NTFS partition correspond to a single GPT code
(entered as 0x0700 in \fBsgdisk\fR). Some OSes use a single MBR code but
employ many more codes in GPT. For these, \fBgdisk\fR adds code numbers
sequentially, such as 0xa500 for a FreeBSD disklabel, 0xa501 for FreeBSD
boot, 0xa502 for FreeBSD swap, and so on. Note that these two\-byte codes
are unique to \fBgdisk\fR.
.TP
.B n
......@@ -561,7 +561,7 @@ entering data. When only one option is possible, \fBgdisk\fR
usually bypasses the prompt entirely.
.SH "BUGS"
As of March 2011 (version 0.7.1), \fBgdisk\fR
As of June 2011 (version 0.7.2), \fBgdisk\fR
should be considered beta software. Known bugs and limitations include:
.TP
......
......@@ -38,19 +38,22 @@ int main(int argc, char* argv[]) {
switch (argc) {
case 1:
WinWarning();
cout << "Type device filename, or press <Enter> to exit: ";
device = ReadString();
if (device.length() == 0)
exit(0);
else if (theGPT.LoadPartitions(device)) {
if (theGPT.GetState() != use_gpt)
WinWarning();
MainMenu(device, &theGPT);
} // if/elseif
break;
case 2: // basic usage
WinWarning();
if (theGPT.LoadPartitions(argv[1]))
if (theGPT.LoadPartitions(argv[1])) {
if (theGPT.GetState() != use_gpt)
WinWarning();
MainMenu(argv[1], &theGPT);
} // if
break;
case 3: // usage with "-l" option
if (strcmp(argv[1], "-l") == 0) {
......@@ -433,8 +436,8 @@ void WinWarning(void) {
cout << "\a************************************************************************\n"
<< "Most versions of Windows cannot boot from a GPT disk, and most varieties\n"
<< "prior to Vista cannot read GPT disks. Therefore, you should exit now\n"
<< "unless you understand the implications of converting MBR to GPT, editing\n"
<< "an existing GPT disk, or creating a new GPT disk layout!\n"
<< "unless you understand the implications of converting MBR to GPT or creating\n"
<< "a new GPT disk layout!\n"
<< "************************************************************************\n\n";
cout << "Are you SURE you want to continue? ";
if (GetYN() != 'Y')
......
......@@ -122,15 +122,14 @@ GPTData & GPTData::operator=(const GPTData & orig) {
delete[] partitions;
partitions = new GPTPart [numParts];
if (partitions != NULL) {
for (i = 0; i < numParts; i++) {
partitions[i] = orig.partitions[i];
}
} else {
numParts = 0;
if (partitions == NULL) {
cerr << "Error! Could not allocate memory for partitions in GPTData::operator=()!\n"
<< "Continuing, but strange problems may occur!\n";
} // if/else
<< "Terminating!\n";
exit(1);
} // if
for (i = 0; i < numParts; i++) {
partitions[i] = orig.partitions[i];
}
return *this;
} // GPTData::operator=()
......@@ -912,6 +911,10 @@ int GPTData::CheckTable(struct GPTHeader *header) {
if (myDisk.Seek(header->partitionEntriesLBA)) {
sizeOfParts = header->numParts * header->sizeOfPartitionEntries;
storage = new uint8_t[sizeOfParts];
if (storage == NULL) {
cerr << "Could not allocate memory in GPTData::CheckTable()! Terminating!\n";
exit(1);
} // if
if (myDisk.Read(storage, sizeOfParts) != (int) sizeOfParts) {
cerr << "Warning! Error " << errno << " reading partition table for CRC check!\n";
} else {
......@@ -1223,6 +1226,10 @@ int GPTData::DestroyGPT(void) {
allOK = 0;
tableSize = numParts * mainHeader.sizeOfPartitionEntries;
emptyTable = new uint8_t[tableSize];
if (emptyTable == NULL) {
cerr << "Could not allocate memory in GPTData::CheckTable()! Terminating!\n";
exit(1);
} // if
memset(emptyTable, 0, tableSize);
if (allOK) {
sum = myDisk.Write(emptyTable, tableSize);
......@@ -1604,7 +1611,7 @@ int GPTData::SetGPTSize(uint32_t numEntries) {
if (diskSize > 0)
CheckGPTSize();
} else { // Bad memory allocation
cerr << "Error allocating memory for partition table!\n";
cerr << "Error allocating memory for partition table! Size is unchanged!\n";
allOK = 0;
} // if/else
} // if/else
......@@ -1662,7 +1669,7 @@ uint32_t GPTData::CreatePartition(uint32_t partNum, uint64_t startSector, uint64
if (FindLastInFree(startSector) >= endSector) {
partitions[partNum].SetFirstLBA(startSector);
partitions[partNum].SetLastLBA(endSector);
partitions[partNum].SetType(0x0700);
partitions[partNum].SetType(DEFAULT_TYPE);
partitions[partNum].RandomizeUniqueGUID();
} else retval = 0; // if free space until endSector
} else retval = 0; // if startSector is free
......@@ -1851,10 +1858,9 @@ void GPTData::RecomputeCHS(void) {
// was unchanged.
int GPTData::Align(uint64_t* sector) {
int retval = 0, sectorOK = 0;
uint64_t earlier, later, testSector, original;
uint64_t earlier, later, testSector;
if ((*sector % sectorAlignment) != 0) {
original = *sector;
earlier = (*sector / sectorAlignment) * sectorAlignment;
later = earlier + (uint64_t) sectorAlignment;
......@@ -2324,11 +2330,6 @@ int SizesOK(void) {
cerr << "PartType is " << sizeof(GUIDData) << " bytes, should be 16 bytes; aborting!\n";
allOK = 0;
} // if
// Determine endianness; warn user if running on big-endian (PowerPC, etc.) hardware
// if (IsLittleEndian() == 0) {
// cerr << "\aRunning on big-endian hardware. Big-endian support is new and poorly"
// " tested!\n";
// } // if
return (allOK);
} // SizesOK()
......@@ -26,8 +26,6 @@
using namespace std;
class PartNotes;
/****************************************
* *
* GPTData class and related structures *
......@@ -139,7 +137,6 @@ public:
virtual int XFormDisklabel(uint32_t partNum);
int XFormDisklabel(BSDData* disklabel);
int OnePartToMBR(uint32_t gptPart, int mbrPart); // add one partition to MBR. Returns 1 if successful
int PartsToMBR(PartNotes * notes);
// Adjust GPT structures WITHOUT user interaction...
int SetGPTSize(uint32_t numEntries);
......@@ -158,9 +155,10 @@ public:
void MakeProtectiveMBR(void) {protectiveMBR.MakeProtectiveMBR();}
void RecomputeCHS(void);
int Align(uint64_t* sector);
// Return data about the GPT structures....
void SetProtectiveMBR(BasicMBRData & newMBR) {protectiveMBR = newMBR;}
// Return data about the GPT structures....
WhichToUse GetState(void) {return whichWasUsed;}
int GetPartRange(uint32_t* low, uint32_t* high);
int FindFirstFreePart(void);
uint32_t GetNumParts(void) {return mainHeader.numParts;}
......
......@@ -15,7 +15,7 @@
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#ifndef _WIN32
#ifdef USE_UTF16
#include <unicode/ustdio.h>
#else
#define UnicodeString string
......@@ -68,7 +68,7 @@ uint64_t GPTPart::GetLengthLBA(void) const {
return length;
} // GPTPart::GetLengthLBA()
#ifndef _WIN32
#ifdef USE_UTF16
// Return partition's name field, converted to a Unicode string
UnicodeString GPTPart::GetDescription(void) {
return (UChar*) name;
......@@ -77,13 +77,13 @@ UnicodeString GPTPart::GetDescription(void) {
// Return partition's name field, converted to a C++ ASCII string
string GPTPart::GetDescription(void) {
string theName;
int i;
int i = 0;
theName = "";
for (i = 0; i < NAME_SIZE; i += 2) {
if (name[i] != '\0')
theName += name[i];
} // for
while ((i < NAME_SIZE) && (name[i] != '\0')) {
theName += name[i];
i+=2;
} // while
return theName;
} // GPTPart::GetDescription() (Windows version)
#endif
......@@ -103,7 +103,7 @@ void GPTPart::SetType(PartType t) {
partitionType = t;
} // GPTPart::SetType()
#ifndef _WIN32
#ifdef USE_UTF16
// Set the name for a partition to theName, using a C++-style string as
// input.
void GPTPart::SetName(const string & theName) {
......@@ -120,7 +120,9 @@ void GPTPart::SetName(const UnicodeString & theName) {
theName.extractBetween(0, NAME_SIZE / 2 - 1, (UChar*) name);
} // if/else
} // GPTPart::SetName()
#else
// Set the name for a partition to theName. 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
......@@ -190,7 +192,7 @@ void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
cout.setf(ios::uppercase);
cout << hex << partitionType.GetHexType() << " " << dec;
cout.fill(' ');
#ifndef _WIN32
#ifdef USE_UTF16
GetDescription().extractBetween(0, 23, description);
cout << description << "\n";
#else
......@@ -273,13 +275,13 @@ void GPTPart::ChangeType(void) {
cout << "Current type is '" << GetTypeName() << "'\n";
do {
cout << "Hex code or GUID (L to show codes, Enter = 0700): ";
cout << "Hex code or GUID (L to show codes, Enter = " << hex << DEFAULT_TYPE << dec << "): ";
line = ReadString();
if ((line[0] == 'L') || (line[0] == 'l')) {
partitionType.ShowAllTypes();
} else {
if (line.length() == 0)
tempType = 0x0700;
tempType= DEFAULT_TYPE;
else
tempType = line;
} // if/else
......
......@@ -74,7 +74,7 @@ class GPTPart {
void SetAttributes(uint64_t a) {attributes = a;}
void SetAttributes(void) {attributes.ChangeAttributes();}
void SetName(const string & theName);
#ifndef _WIN32
#ifdef USE_UTF16
void SetName(const UnicodeString & theName);
#endif
void SetDefaultDescription(void);
......
......@@ -400,7 +400,11 @@ void GPTDataTextUI::MakeHybrid(void) {
<< "just hit the Enter key at the below prompt and your MBR partition table will\n"
<< "be untouched.\n\n\a";
hybridMBR.SetDisk(&myDisk);
// Use a local MBR structure, copying from protectiveMBR to keep its
// boot loader code intact....
hybridMBR = protectiveMBR;
hybridMBR.EmptyMBR(0);
// Now get the numbers of up to three partitions to add to the
// hybrid MBR....
cout << "Type from one to three GPT partition numbers, separated by spaces, to be\n"
......@@ -424,9 +428,9 @@ void GPTDataTextUI::MakeHybrid(void) {
hybridPart.SetInclusion(PRIMARY);
cout << "Set the bootable flag? ";
if (GetYN() == 'Y')
hybridPart.SetStatus(1);
hybridPart.SetStatus(0x80);
else
hybridPart.SetStatus(0);
hybridPart.SetStatus(0x00);
hybridPart.SetInclusion(PRIMARY);
} else {
cerr << "\nGPT partition #" << j + 1 << " does not exist; skipping.\n";
......@@ -478,7 +482,7 @@ void GPTDataTextUI::MakeHybrid(void) {
int GPTDataTextUI::XFormToMBR(void) {
uint32_t i;
protectiveMBR.EmptyMBR();
protectiveMBR.EmptyMBR(0);
for (i = 0; i < numParts; i++) {
if (partitions[i].IsUsed()) {
protectiveMBR.MakePart(i, partitions[i].GetFirstLBA(),
......
......@@ -128,20 +128,35 @@ void GUIDData::Zero(void) {
// Set a completely random GUID value....
// The uuid_generate() function returns a value that needs to have its
// first three fields byte-reversed to conform to Intel's GUID layout.
// If that function isn't defined (e.g., on Windows), set a completely
// random GUID -- not completely kosher, but it doesn't seem to cause
// any problems (so far...)
// The Windows UuidCreate() function doesn't need this adjustment. If
// neither function is defined, or if UuidCreate() fails, set a completely
// random GUID -- not completely kosher, but it works on most platforms
// (immediately after creating the UUID on Windows 7 being an important
// exception).
void GUIDData::Randomize(void) {
int i, uuidGenerated = 0;
#ifdef _UUID_UUID_H