summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.freebsd4
-rw-r--r--NEWS17
-rw-r--r--README24
-rw-r--r--README.Windows18
-rw-r--r--attributes.cc2
-rw-r--r--basicmbr.cc60
-rw-r--r--basicmbr.h5
-rw-r--r--current.spec8
-rw-r--r--diskio-windows.cc7
-rw-r--r--fixparts.84
-rw-r--r--fixparts.cc106
-rw-r--r--gdisk.826
-rw-r--r--gpt.cc9
-rw-r--r--gpt.h2
-rw-r--r--gptpart.cc106
-rw-r--r--gptpart.h8
-rw-r--r--gpttext.cc57
-rw-r--r--gpttext.h4
-rw-r--r--guid.cc2
-rw-r--r--mbr.cc10
-rw-r--r--mbr.h1
-rw-r--r--mbrpart.cc2
-rw-r--r--parttypes.cc26
-rw-r--r--parttypes.h7
-rw-r--r--sgdisk.815
-rw-r--r--sgdisk.cc5
-rw-r--r--support.h2
27 files changed, 270 insertions, 267 deletions
diff --git a/Makefile.freebsd b/Makefile.freebsd
index 92dcb0b..783dd7d 100644
--- a/Makefile.freebsd
+++ b/Makefile.freebsd
@@ -13,10 +13,10 @@ DEPEND= makedepend $(CXXFLAGS)
all: gdisk sgdisk fixparts
gdisk: $(LIB_OBJS) gdisk.o gpttext.o
- $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -luuid -o gdisk
+ $(CXX) $(LIB_OBJS) gdisk.o gpttext.o -L/usr/local/lib $(LDFLAGS) -licuio -luuid -o gdisk
sgdisk: $(LIB_OBJS) sgdisk.o
- $(CXX) $(LIB_OBJS) sgdisk.o -L/usr/local/lib $(LDFLAGS) -luuid -lpopt -o sgdisk
+ $(CXX) $(LIB_OBJS) sgdisk.o -L/usr/local/lib $(LDFLAGS) -luuid -licuio -lpopt -o sgdisk
fixparts: $(MBR_LIB_OBJS) fixparts.o
$(CXX) $(MBR_LIB_OBJS) fixparts.o -L/usr/local/lib $(LDFLAGS) -o fixparts
diff --git a/NEWS b/NEWS
index 678b913..7932515 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,18 @@
-0.7.1 (?/?/2011):
------------------
+0.7.1 (3/21/2011):
+------------------
+
+- Added support for proper UTF-16LE partition names rather than the
+ "shortcut" that properly encoded only ASCII names. This support works
+ only in Linux, FreeBSD, and OS X, though, at least for the moment.
+ Although it's possible to compile this support into Windows when using
+ Visual C++, it doesn't seem to work properly. Since using this feature
+ would require distributing the ICU libraries with the Windows binary,
+ thus bloating the binary package's size to no effect, I've disabled it in
+ my standard Windows build, at least for now.
+
+- Added check to fixparts to keep it from operating on devices that
+ lack an existing MBR signature. (In 0.7.0, it could write an empty
+ MBR data structure to a device on which it was mistakenly launched.)
- Fixed bug that caused the protective MBR to not be written when
restoring a backup of the GPT data.
diff --git a/README b/README
index 56c6a6b..3449210 100644
--- a/README
+++ b/README
@@ -4,8 +4,8 @@ by Roderick W. Smith, rodsmith@rodsbooks.com
Introduction
------------
-This binary archive includes the source code for three related disk
-partitioning programs:
+This package includes the source code for three related disk partitioning
+programs:
- gdisk -- This program is modeled after Linux fdisk, but it operates on
GUID Partition Table (GPT) disks rather than the Master Boot Record (MBR)
@@ -62,8 +62,7 @@ and sgdisk include:
* A user interface that's familiar to long-time users of Linux
fdisk (gdisk only)
-* The MBR boot loader code is left alone (GNU Parted tends to
- wipe it out with every change)
+* The MBR boot loader code is left alone
* The ability to create a hybrid MBR, which permits GPT-unaware
OSes to access up to three GPT partitions on the disk
@@ -95,7 +94,7 @@ that the OS sees.
I've observed four causes of these symptoms, three of which FixParts can
correct:
-- Old GPT data -- If a disk is used as a GPT disk and then re-used as an
+* Old GPT data -- If a disk is used as a GPT disk and then re-used as an
MBR disk, the GPT data may be incompletely erased. This happens if the
disk is repartitioned with fdisk or the Microsoft Windows installer, for
instance. (Tools based on libparted correctly remove the old GPT data
@@ -104,12 +103,12 @@ correct:
data, this erasure occurs immediately, unlike other changes the program
makes.
-- Mis-sized extended partitions -- Some tools create an extended partition
+* Mis-sized extended partitions -- Some tools create an extended partition
that's too large, typically ending after the last sector of the disk.
FixParts automatically corrects this problem (if you use the 'w' option
to save the partition table).
-- Primary partitions inside an extended partition -- Some utilities create
+* Primary partitions inside an extended partition -- Some utilities create
or move primary partitions to within the range covered by the extended
partition. FixParts can usually correct this problem by turning the
primary partition into a logical partition or by changing one or more
@@ -117,7 +116,7 @@ correct:
possible, though, at least not without deleting or resizing other
partitions.
-- Leftover RAID data -- If a disk is used in a RAID array and then re-used
+* Leftover RAID data -- If a disk is used in a RAID array and then re-used
as a non-RAID disk, some utilities can become confused and fail to see
the disk. FixParts can NOT correct this problem. You must destroy the old
RAID data, or possibly remove the dmraid package from the system, to fix
@@ -130,7 +129,7 @@ omitting it), you can't create new partitions with the program. If you're
used to partitioning disks, particularly with Linux fdisk, two unusual
features of FixParts require elaboration:
-- No extended partitions -- Internally, FixParts reads the partition table
+* No extended partitions -- Internally, FixParts reads the partition table
and discards data on any extended partition(s) it finds. When you save
the partition table, the program generates a new extended partition. This
design means that the program automatically corrects many problems
@@ -139,7 +138,7 @@ features of FixParts require elaboration:
it keeps track of the requirements and prevents you from creating illegal
layouts, such as a primary between two logicals.
-- Partition numbering -- In most Linux tools, partitions 1-4 are primaries
+* Partition numbering -- In most Linux tools, partitions 1-4 are primaries
and partitions 5 and up are logicals. Although a legal partition table
loaded into FixParts will initially conform to this convention, some
types of damaged table might not, and various changes you make can also
@@ -162,8 +161,9 @@ used.) In addition, note these requirements:
e2fsprogs-libuuid port must be installed.
* The ICU library (http://site.icu-project.org) is required on all
- platforms. This library is normally installed in Linux, but you may need
- to install the development headers (libicu-dev or something similar).
+ 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 sgdisk program also requires the popt library and its development
files (headers). Most Linux distributions install popt by default, but
diff --git a/README.Windows b/README.Windows
index fa57484..3194838 100644
--- a/README.Windows
+++ b/README.Windows
@@ -88,10 +88,19 @@ for disks and partitions, not to the GUIDs used to identify partition type
codes; those are standardized and are handled correctly by all versions of
GPT fdisk.
+The Windows binaries I've compiled do not support Unicode UTF-16LE GPT
+partition names. This feature was added to version 0.7.1 of the software
+for Linux, FreeBSD, and OS X, and with changes to some #ifndef lines in the
+source files, it can be compiled for Windows; however, it seems to do
+little good in Windows because of Command Prompt window and/or ICU library
+limitations. Thus, I've omitted this support in the interests of
+simplifying the binary distribution, since including it would mean
+distributing the ICU libraries.
+
Source Code and Compilation Issues
----------------------------------
-I have successfully compiled GPT fdisk using two different Windows
+I have successfully compiled GPT fdisk using three different Windows
compilers:
- MinGW (http://www.mingw.org), and in particular its Linux-hosted
@@ -109,8 +118,11 @@ compilers:
all the *.cc files except diskio-unix.cc, sgdisk.cc, and whichever
program file you intend to NOT build (gdisk.cc or fixparts.cc).
-The MinGW compiler produces much larger executables than does the MS
-compiler. The resulting binaries seem to work equally well, but my testing
+- Microsoft Visual C++ 2010 Express -- This compiler works much like the
+ 2008 version, although I didn't need to add a third-party stdint.h file.
+
+The MinGW compiler produces much larger executables than do the MS
+compilers. The resulting binaries seem to work equally well, but my testing
has been minimal.
I've also attempted to compile the code with OpenWatcom 1.8, but this
diff --git a/attributes.cc b/attributes.cc
index 0abed40..45de56e 100644
--- a/attributes.cc
+++ b/attributes.cc
@@ -223,4 +223,4 @@ bool Attributes::OperateOnAttributes(const uint32_t partNum, const string& attri
ostream & operator<<(ostream & os, const Attributes & data) {
os << data.GetAttributes();
return os;
-} // operator<<() \ No newline at end of file
+} // operator<<()
diff --git a/basicmbr.cc b/basicmbr.cc
index 4f2fa34..12ec92b 100644
--- a/basicmbr.cc
+++ b/basicmbr.cc
@@ -874,7 +874,6 @@ int BasicMBRData::SpaceBeforeAllLogicals(void) {
do {
if ((partitions[i].GetStartLBA() > 0) && (partitions[i].GetInclusion() == LOGICAL)) {
allOK = allOK && (SectorUsedAs(partitions[i].GetStartLBA() - 1) == EBR);
-// allOK = allOK && IsFree(partitions[i].GetStartLBA() - 1);
} // if
i++;
} while (allOK && (i < MAX_MBR_PARTS));
@@ -1080,37 +1079,12 @@ int BasicMBRData::SetInclusionwChecks(int num, int inclStatus) {
// providing a function to do this deliberately at the user's command.
// This function does nothing if the partition's length is 0.
void BasicMBRData::RecomputeCHS(int partNum) {
-// uint64_t firstLBA, lengthLBA;
-
partitions[partNum].RecomputeCHS();
-/* firstLBA = (uint64_t) partitions[partNum].firstLBA;
- lengthLBA = (uint64_t) partitions[partNum].lengthLBA;
-
- if (lengthLBA > 0) {
- LBAtoCHS(firstLBA, partitions[partNum].firstSector);
- LBAtoCHS(firstLBA + lengthLBA - 1, partitions[partNum].lastSector);
- } // if */
} // BasicMBRData::RecomputeCHS()
-// Swap the contents of two partitions.
-// Returns 1 if successful, 0 if either partition is out of range
-// (that is, not a legal number; either or both can be empty).
-// Note that if partNum1 = partNum2 and this number is in range,
-// it will be considered successful.
-int BasicMBRData::SwapPartitions(uint32_t partNum1, uint32_t partNum2) {
- MBRPart temp;
- int allOK = 1;
-
- if ((partNum1 < MAX_MBR_PARTS) && (partNum2 < MAX_MBR_PARTS)) {
- if (partNum1 != partNum2) {
- temp = partitions[partNum1];
- partitions[partNum1] = partitions[partNum2];
- partitions[partNum2] = temp;
- } // if
- } else allOK = 0; // partition numbers are valid
- return allOK;
-} // BasicMBRData::SwapPartitions()
-
+// Sorts the partitions starting with partition #start. This function
+// does NOT pay attention to primary/logical assignment, which is
+// critical when writing the partitions.
void BasicMBRData::SortMBR(int start) {
if ((start < MAX_MBR_PARTS) && (start >= 0))
sort(partitions + start, partitions + MAX_MBR_PARTS);
@@ -1167,15 +1141,6 @@ void BasicMBRData::OmitOverlaps() {
} // for (i...)
} // BasicMBRData::OmitOverlaps()
-/* // Omits all partitions; used as starting point in MakeItLegal()
-void BasicMBRData::OmitAll(void) {
- int i;
-
- for (i = 0; i < MAX_MBR_PARTS; i++) {
- partitions[i].SetInclusion(NONE);
- } // for
-} // BasicMBRData::OmitAll() */
-
// Convert as many partitions into logicals as possible, except for
// the first partition, if possible.
void BasicMBRData::MaximizeLogicals() {
@@ -1206,8 +1171,8 @@ void BasicMBRData::MaximizePrimaries() {
while ((num < 4) && (i < MAX_MBR_PARTS)) {
if ((partitions[i].GetInclusion() == NONE) && (partitions[i].CanBePrimary())) {
partitions[i].SetInclusion(PRIMARY);
- num++;
- UpdateCanBeLogical();
+ num++;
+ UpdateCanBeLogical();
} // if
i++;
} // while
@@ -1254,7 +1219,6 @@ void BasicMBRData::MakeLogicalsContiguous(void) {
void BasicMBRData::MakeItLegal(void) {
if (!IsLegal()) {
DeleteOversizedParts();
-// OmitAll();
MaximizeLogicals();
MaximizePrimaries();
if (!AreLogicalsContiguous())
@@ -1406,6 +1370,7 @@ uint64_t BasicMBRData::FindLastInFree(uint64_t start) {
nearestStart = diskSize - 1;
else
nearestStart = UINT32_MAX - 1;
+
for (i = 0; i < 4; i++) {
if ((nearestStart > partitions[i].GetStartLBA()) &&
(partitions[i].GetStartLBA() > start)) {
@@ -1449,19 +1414,6 @@ int BasicMBRData::SectorUsedAs(uint64_t sector, int topPartNum) {
return usedAs;
} // BasicMBRData::SectorUsedAs()
-/* // Returns 1 if the specified sector is unallocated, 0 if it's
-// allocated.
-int BasicMBRData::IsFree(uint64_t sector, int topPartNum) {
- int i, isFree = 1;
-
- for (i = 0; i < topPartNum; i++) {
- if ((partitions[i].GetStartLBA() <= sector) && (partitions[i].GetLastLBA() >= sector)
- && (partitions[i].GetInclusion() != NONE))
- isFree = 0;
- } // for
- return isFree;
-} // BasicMBRData::IsFree() */
-
/******************************************************
* *
* Functions that extract data on specific partitions *
diff --git a/basicmbr.h b/basicmbr.h
index 6587af0..6d4de72 100644
--- a/basicmbr.h
+++ b/basicmbr.h
@@ -123,9 +123,7 @@ public:
void DeletePartition(int i);
int SetInclusionwChecks(int num, int inclStatus);
void RecomputeCHS(int partNum);
- int SwapPartitions(uint32_t partNum1, uint32_t partNum2);
void SortMBR(int start = 0);
-// void QuickSortMBR(int start, int finish);
int DeleteOversizedParts();
int DeleteExtendedParts();
void OmitOverlaps(void);
@@ -153,7 +151,6 @@ public:
// User interaction functions....
int DoMenu(const string& prompt = "\nMBR command (? for help): ");
void ShowCommands(void);
-
-}; // struct BasicMBRData
+}; // class BasicMBRData
#endif
diff --git a/current.spec b/current.spec
index 3ae7f6c..b0fa691 100644
--- a/current.spec
+++ b/current.spec
@@ -1,11 +1,11 @@
Summary: GPT partitioning and MBR repair software
Name: gptfdisk
-Version: 0.7.0
+Version: 0.7.1
Release: 1%{?dist}
License: GPLv2
URL: http://www.rodsbooks.com/gdisk
Group: Applications/System
-Source: http://www.rodsbooks.com/gdisk/gptfdisk-0.7.0.tgz
+Source: http://www.rodsbooks.com/gdisk/gptfdisk-0.7.1.tgz
BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
%description
@@ -77,5 +77,5 @@ provides a few additional partition manipulation features.
%changelog
-* Fri Mar 11 2011 R Smith <rodsmith@rodsbooks.com> - 0.7.0
-- Created spec file for 0.7.0 release
+* Mon Mar 21 2011 R Smith <rodsmith@rodsbooks.com> - 0.7.1
+- Created spec file for 0.7.1 release
diff --git a/diskio-windows.cc b/diskio-windows.cc
index b79884c..938d7ec 100644
--- a/diskio-windows.cc
+++ b/diskio-windows.cc
@@ -133,11 +133,12 @@ int DiskIO::GetBlockSize(void) {
} // if
if (isOpen) {
- if (DeviceIoControl(fd, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &geom, sizeof(geom), &retBytes, NULL)) {
+ if (DeviceIoControl(fd, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0,
+ &geom, sizeof(geom), &retBytes, NULL)) {
blockSize = geom.Geometry.BytesPerSector;
- } else { // was probably an ordinary file; set default value....
+ } else { // was probably an ordinary file; set default value....
blockSize = SECTOR_SIZE;
- } // if/else
+ } // if/else
} // if (isOpen)
return (blockSize);
diff --git a/fixparts.8 b/fixparts.8
index e11a1a5..23970fb 100644
--- a/fixparts.8
+++ b/fixparts.8
@@ -1,6 +1,6 @@
.\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "FIXPARTS" "8" "0.7.0" "Roderick W. Smith" "FixParts Manual"
+.TH "FIXPARTS" "8" "0.7.1" "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.0), \fBfixparts\fR
+As of March 2011 (version 0.7.1), \fBfixparts\fR
should be considered beta software. Known bugs and limitations include:
.TP
diff --git a/fixparts.cc b/fixparts.cc
index 8a7c7d0..318c65e 100644
--- a/fixparts.cc
+++ b/fixparts.cc
@@ -20,11 +20,14 @@
using namespace std;
+void DoMBR(BasicMBRData & mbrTable);
+
int main(int argc, char* argv[]) {
BasicMBRData mbrTable;
string device;
- int doItAgain;
+ cout << "FixParts " << GPTFDISK_VERSION << "\n";
+
switch (argc) {
case 1:
cout << "Type device filename, or press <Enter> to exit: ";
@@ -40,41 +43,72 @@ int main(int argc, char* argv[]) {
exit(1);
} // switch
- cout << "FixParts " << GPTFDISK_VERSION << "\n";
cout << "\nLoading MBR data from " << device << "\n";
- if (mbrTable.ReadMBRData(device)) {
- if (mbrTable.CheckForGPT() > 0) {
- if ((mbrTable.GetValidity() == hybrid) || (mbrTable.GetValidity() == gpt)) {
- cerr << "\nThis disk appears to be a GPT disk. Use GNU Parted or GPT fdisk on it!\n";
- cerr << "Exiting!\n\n";
- exit(1);
- } else {
- cout << "\nNOTICE: GPT signatures detected on the disk, but no 0xEE protective "
- << "partition!\nThe GPT signatures are probably left over from a previous "
- << "partition table.\nDo you want to delete them (if you answer 'Y', this "
- << "will happen\nimmediately)? ";
- if (GetYN() == 'Y') {
- cout << "Erasing GPT data!\n";
- if (mbrTable.BlankGPTData() != 1)
- cerr << "GPT signature erasure failed!\n";
- } // if
- } // if/else
- } // if
- mbrTable.MakeItLegal();
- do {
- doItAgain = 0;
- if (mbrTable.DoMenu() > 0) {
- cout << "\nFinal checks complete. About to write MBR data. THIS WILL OVERWRITE EXISTING\n"
- << "PARTITIONS!!\n\nDo you want to proceed? ";
- if (GetYN() == 'Y') {
- mbrTable.WriteMBRData();
- mbrTable.DiskSync();
- doItAgain = 0;
- } else {
- doItAgain = 1;
- } // else
- } // if
- } while (doItAgain);
- } // if read OK
+ if (!mbrTable.ReadMBRData(device)) {
+ cerr << "\nUnable to read MBR data from '" << device << "'! Exiting!\n\n";
+ exit(1);
+ } // if
+
+ // This switch() statement weeds out disks with GPT signatures and non-MBR
+ // disks so we don't accidentally damage them....
+ switch(mbrTable.GetValidity()) {
+ case hybrid: case gpt:
+ cerr << "\nThis disk appears to be a GPT disk. Use GNU Parted or GPT fdisk on it!\n";
+ cerr << "Exiting!\n\n";
+ exit(1);
+ break;
+ case invalid:
+ cerr << "\nCannot find valid MBR data on '" << device << "'! Exiting!\n\n";
+ exit(1);
+ break;
+ case mbr:
+ DoMBR(mbrTable);
+ break;
+ default:
+ cerr << "\nCannot determine the validity of the disk on '" << device
+ << "'! Exiting!\n\n";
+ exit(1);
+ break;
+ } // switch()
return 0;
} // main()
+
+// Do the bulk of the processing on actual MBR disks. First checks for old
+// GPT data (note this is different from the earlier check; this one only
+// looks for the GPT signatures in the main and backup GPT area, not for
+// a protective partition in the MBR, which we know is NOT present, since
+// if it were, this function would NOT be called!) and offers to destroy
+// it, if found; then makes sure the partitions are in a consistent and
+// legal state; then presents the MBR menu and, if it returns a "1" value
+// (meaning the user opted to write changes), writes the table to disk.
+void DoMBR(BasicMBRData & mbrTable) {
+ int doItAgain;
+
+ if (mbrTable.CheckForGPT() > 0) {
+ cout << "\nNOTICE: GPT signatures detected on the disk, but no 0xEE protective "
+ << "partition!\nThe GPT signatures are probably left over from a previous "
+ << "partition table.\nDo you want to delete them (if you answer 'Y', this "
+ << "will happen\nimmediately)? ";
+ if (GetYN() == 'Y') {
+ cout << "Erasing GPT data!\n";
+ if (mbrTable.BlankGPTData() != 1)
+ cerr << "GPT signature erasure failed!\n";
+ } // if
+ } // if
+
+ mbrTable.MakeItLegal();
+ do {
+ doItAgain = 0;
+ if (mbrTable.DoMenu() > 0) {
+ cout << "\nFinal checks complete. About to write MBR data. THIS WILL OVERWRITE "
+ << "EXISTING\nPARTITIONS!!\n\nDo you want to proceed? ";
+ if (GetYN() == 'Y') {
+ mbrTable.WriteMBRData();
+ mbrTable.DiskSync();
+ doItAgain = 0;
+ } else {
+ doItAgain = 1;
+ } // else
+ } // if
+ } while (doItAgain);
+} // DoMBR()
diff --git a/gdisk.8 b/gdisk.8
index f872f2b..2b29ea9 100644
--- a/gdisk.8
+++ b/gdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "GDISK" "8" "0.7.0" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "GDISK" "8" "0.7.1" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
gdisk \- Interactive GUID partition table (GPT) manipulator
.SH "SYNOPSIS"
@@ -152,12 +152,12 @@ to encourage its use.
.TP
.B c
Change the GPT name of a partition. This name is encoded as a UTF\-16
-string, but \fBgdisk\fR
-supports only ASCII characters as names. For the most part, Linux ignores
-the partition name, but it may be important in some OSes. GPT fdisk sets
-a default name based on the partition type code. Note that the GPT partition
-name is different from the filesystem name, which is encoded in the filesystem's
-data structures.
+string, but proper entry and display of anything beyond basic ASCII values
+requires suitable locale and font support. For the most part, Linux ignores
+the partition name, but it may be important in some OSes. GPT fdisk sets a
+default name based on the partition type code. Note that the GPT partition
+name is different from the filesystem name, which is encoded in the
+filesystem's data structures.
.TP
.B d
@@ -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.0), \fBgdisk\fR
+As of March 2011 (version 0.7.1), \fBgdisk\fR
should be considered beta software. Known bugs and limitations include:
.TP
@@ -590,10 +590,12 @@ alignment.
.TP
.B *
-Only ASCII characters are supported in the partition name field. If an
-existing partition uses non\-ASCII UTF\-16 characters, they're likely to be
-corrupted in the 'i' and 'p' menu options' displays; however, they should be
-preserved when loading and saving partitions.
+In the Windows version, only ASCII characters are supported in the
+partition name field. If an existing partition uses non\-ASCII UTF\-16
+characters, they're likely to be corrupted in the 'i' and 'p' menu options'
+displays; however, they should be preserved when loading and saving
+partitions. Binaries for Linux, FreeBSD, and OS X support full UTF-16
+partition names.
.TP
.B *
diff --git a/gpt.cc b/gpt.cc
index ea0a0a3..9c62f4e 100644
--- a/gpt.cc
+++ b/gpt.cc
@@ -1057,6 +1057,7 @@ int GPTData::SaveGPTBackup(const string & filename) {
RecomputeCRCs();
protectiveMBR.WriteMBRData(&backupFile);
+ protectiveMBR.SetDisk(&myDisk);
if (allOK) {
// MBR write closed disk, so re-open and seek to end....
@@ -1768,12 +1769,16 @@ void GPTData::MoveSecondHeaderToEnd() {
secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
} // GPTData::FixSecondHeaderLocation()
+// Sets the partition's name to the specified UnicodeString without
+// user interaction.
+// Returns 1 on success, 0 on failure (invalid partition number).
int GPTData::SetName(uint32_t partNum, const UnicodeString & theName) {
int retval = 1;
- if (!IsFreePartNum(partNum)) {
+ if (IsUsedPartNum(partNum))
partitions[partNum].SetName(theName);
- } else retval = 0;
+ else
+ retval = 0;
return retval;
} // GPTData::SetName
diff --git a/gpt.h b/gpt.h
index 41fa3d1..a5d6c01 100644
--- a/gpt.h
+++ b/gpt.h
@@ -150,7 +150,7 @@ public:
int SwapPartitions(uint32_t partNum1, uint32_t partNum2);
int ClearGPTData(void);
void MoveSecondHeaderToEnd();
- int SetName(uint32_t partNum, const UnicodeString & theName = "");
+ int SetName(uint32_t partNum, const UnicodeString & theName);
void SetDiskGUID(GUIDData newGUID);
int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
void RandomizeGUIDs(void);
diff --git a/gptpart.cc b/gptpart.cc
index b5bf771..838680b 100644
--- a/gptpart.cc
+++ b/gptpart.cc
@@ -4,7 +4,7 @@
// Description: Class to implement a SINGLE GPT partition
//
//
-// Author: Rod Smith <rodsmith@rodsbooks.com>, (C) 2009
+// Author: Rod Smith <rodsmith@rodsbooks.com>, (C) 2009-2011
//
// Copyright: See COPYING file that comes with this distribution
//
@@ -15,9 +15,14 @@
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
+#ifndef _WIN32
+#include <unicode/ustdio.h>
+#else
+#define UnicodeString string
+#endif
+
#include <string.h>
#include <stdio.h>
-#include <unicode/ustdio.h>
#include <iostream>
#include "gptpart.h"
#include "attributes.h"
@@ -51,10 +56,6 @@ string GPTPart::GetTypeName(void) {
// data" or "Linux swap").
UnicodeString GPTPart::GetUTypeName(void) {
return partitionType.UTypeName();
-/* UnicodeString temp;
-
- temp = temp.fromUTF8(partitionType.TypeName());
- return temp; */
} // GPTPart::GetNameType()
// Compute and return the partition's length (or 0 if the end is incorrectly
@@ -67,7 +68,13 @@ uint64_t GPTPart::GetLengthLBA(void) const {
return length;
} // GPTPart::GetLengthLBA()
-/* // Return partition's name field, converted to a C++ ASCII string
+#ifndef _WIN32
+// Return partition's name field, converted to a Unicode string
+UnicodeString GPTPart::GetDescription(void) {
+ return (UChar*) name;
+} // GPTPart::GetDescription()
+#else
+// Return partition's name field, converted to a C++ ASCII string
string GPTPart::GetDescription(void) {
string theName;
int i;
@@ -78,21 +85,8 @@ string GPTPart::GetDescription(void) {
theName += name[i];
} // for
return theName;
-} // GPTPart::GetDescription() */
-
-UnicodeString GPTPart::GetDescription(void) {
- UnicodeString theName;
- UChar *temp;
- int i;
-
- theName = "";
- temp = (UChar*) name;
- for (i = 0; i < NAME_SIZE / 2; i++) {
- if (temp[i] != '\0')
- theName += temp[i];
- } // for
- return theName;
-} // GPTPart::GetDescription()
+} // GPTPart::GetDescription() (Windows version)
+#endif
// Return 1 if the partition is in use
int GPTPart::IsUsed(void) {
@@ -109,33 +103,40 @@ void GPTPart::SetType(PartType t) {
partitionType = t;
} // GPTPart::SetType()
-// Set the name for a partition to theName, or prompt for a name if
-// theName is empty, using a C++-style string as input.
-void GPTPart::SetName(string theName) {
- UnicodeString uString;
-
- uString = theName.c_str();
- SetName(uString);
+#ifndef _WIN32
+// Set the name for a partition to theName, using a C++-style string as
+// input.
+void GPTPart::SetName(const string & theName) {
+ SetName((UnicodeString) theName.c_str());
} // GPTPart::SetName()
-// Set the name for a partition to theName, or prompt for a name
-// if theName is empty, using a Unicode string as input.
-void GPTPart::SetName(UnicodeString theName) {
- int i;
- UChar temp[NAME_SIZE / 2];
-
- if (theName == "") { // No name specified, so get one from the user
- cout << "Enter name: ";
- theName = ReadUString();
- } // if
-
- // Copy the C++-style string from newName into a form that the GPT
- // table will accept....
- memset(temp, 0, NAME_SIZE);
- for (i = 0; i < theName.length(); i++)
- temp[i] = theName[i];
- memcpy(name, temp, NAME_SIZE);
+// Set the name for a partition to theName, using a Unicode string as
+// input.
+void GPTPart::SetName(const UnicodeString & theName) {
+ if (theName.isBogus()) {
+ cerr << "Bogus UTF-16 name found in GPTPart::SetName()! Name not changed!\n";
+ } else {
+ memset(name, 0, NAME_SIZE);
+ 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
+// for this.
+void GPTPart::SetName(const string & theName) {
+ int i, length;
+
+ if (theName.length() < (NAME_SIZE / 2))
+ length = theName.length();
+ else
+ length = NAME_SIZE / 2;
+ memset(name, 0, NAME_SIZE);
+ for (i = 0; i < length; i++)
+ name[i * 2] = theName[i];
+} // GPTPart::SetName(), Windows version
+#endif
// Set the name for the partition based on the current GUID partition type
// code's associated name
@@ -189,13 +190,12 @@ void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
cout.setf(ios::uppercase);
cout << hex << partitionType.GetHexType() << " " << dec;
cout.fill(' ');
-// description = GetDescription();
- GetDescription().extractBetween(0, 24, description);
+#ifndef _WIN32
+ GetDescription().extractBetween(0, 23, description);
cout << description << "\n";
-// for (i = 0; i < 23; i++)
-// cout << (char) description.;
-// cout << GetDescription().tempSubString(0, 23) << "\n";
-// cout << GetDescription().substr(0, 23) << "\n";
+#else
+ cout << GetDescription().substr(0, 23) << "\n";
+#endif
cout.fill(' ');
} // if
} // GPTPart::ShowSummary()
@@ -223,7 +223,7 @@ void GPTPart::ShowDetails(uint32_t blockSize) {
cout << hex;
cout << attributes << "\n";
cout << dec;
- cout << "Partition name: " << GetDescription() << "\n";
+ cout << "Partition name: '" << GetDescription() << "'\n";
cout.fill(' ');
} // if
} // GPTPart::ShowDetails()
diff --git a/gptpart.h b/gptpart.h
index d47f505..2686229 100644
--- a/gptpart.h
+++ b/gptpart.h
@@ -61,7 +61,6 @@ class GPTPart {
uint64_t GetLengthLBA(void) const;
Attributes GetAttributes(void) {return attributes;}
void ShowAttributes(uint32_t partNum) {attributes.ShowAttributes(partNum);}
-// string GetDescription(void);
UnicodeString GetDescription(void);
int IsUsed(void);
@@ -74,9 +73,10 @@ class GPTPart {
void SetLastLBA(uint64_t l) {lastLBA = l;}
void SetAttributes(uint64_t a) {attributes = a;}
void SetAttributes(void) {attributes.ChangeAttributes();}
- void SetName(string theName);
- void SetName(UnicodeString theName);
-// void SetName(UChar *theName);
+ void SetName(const string & theName);
+#ifndef _WIN32
+ void SetName(const UnicodeString & theName);
+#endif
void SetDefaultDescription(void);
// Additional functions
diff --git a/gpttext.cc b/gpttext.cc
index 0b02672..55fbdbb 100644
--- a/gpttext.cc
+++ b/gpttext.cc
@@ -1,5 +1,5 @@
/*
- Copyright (C) <2010> <Roderick W. Smith>
+ Copyright (C) 2010-2011 <Roderick W. Smith>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,7 +29,6 @@
#include <cstdio>
#include "attributes.h"
#include "gpttext.h"
-//#include "gptpartnotes.h"
#include "support.h"
using namespace std;
@@ -295,15 +294,29 @@ void GPTDataTextUI::ChangeUniqueGuid(void) {
// Partition attributes seem to be rarely used, but I want a way to
// adjust them for completeness....
void GPTDataTextUI::SetAttributes(uint32_t partNum) {
-// Attributes theAttr;
-
partitions[partNum].SetAttributes();
-/* theAttr = partitions[partNum].GetAttributes();
-// theAttr.SetAttributes(partitions[partNum].GetAttributes());
- theAttr.ChangeAttributes();
- partitions[partNum].SetAttributes(theAttr.GetAttributes()); */
} // GPTDataTextUI::SetAttributes()
+// Prompts the user for a partition name and sets the partition's
+// name. Returns 1 on success, 0 on failure (invalid partition
+// number). (Note that the function skips prompting when an
+// invalid partition number is detected.)
+int GPTDataTextUI::SetName(uint32_t partNum) {
+ UnicodeString theName = "";
+ int retval = 1;
+
+ if (IsUsedPartNum(partNum)) {
+ cout << "Enter name: ";
+ theName = ReadUString();
+ partitions[partNum].SetName(theName);
+ } else {
+ cerr << "Invalid partition number (" << partNum << ")\n";
+ retval = 0;
+ } // if/else
+
+ return retval;
+} // GPTDataTextUI::SetName()
+
// Ask user for two partition numbers and swap them in the table. Note that
// this just reorders table entries; it doesn't adjust partition layout on
// the disk.
@@ -477,13 +490,15 @@ int GPTDataTextUI::XFormToMBR(void) {
return protectiveMBR.DoMenu();
} // GPTDataTextUI::XFormToMBR()
-/*********************************************************************
- * *
- * The following doesn't really belong in the class, since it's MBR- *
- * specific, but it's also user I/O-related, so I want to keep it in *
- * this file.... *
- * *
- *********************************************************************/
+/********************************
+ * *
+ * Non-class support functions. *
+ * *
+ ********************************/
+
+// GetMBRTypeCode() doesn't really belong in the class, since it's MBR-
+// specific, but it's also user I/O-related, so I want to keep it in
+// this file....
// Get an MBR type code from the user and return it
int GetMBRTypeCode(int defType) {
@@ -505,3 +520,15 @@ int GetMBRTypeCode(int defType) {
cout.fill(' ');
return typeCode;
} // GetMBRTypeCode
+
+// Note: ReadUString() is here rather than in support.cc so that the ICU
+// libraries need not be linked to fixparts.
+
+// Reads a Unicode string from stdin, returning it as an ICU-style string.
+// Note that the returned string will NOT include the carriage return
+// entered by the user. Relies on the ICU constructor from a string
+// encoded in the current codepage to work.
+UnicodeString ReadUString(void) {
+ return ReadString().c_str();
+} // ReadUString()
+
diff --git a/gpttext.h b/gpttext.h
index 33b7486..553efa2 100644
--- a/gpttext.h
+++ b/gpttext.h
@@ -1,6 +1,6 @@
/*
<one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
+ Copyright (C) 2010-2011 Roderick W. Smith
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,6 +47,7 @@ class GPTDataTextUI : public GPTData {
void ChangePartType(void);
void ChangeUniqueGuid(void);
void SetAttributes(uint32_t partNum);
+ int SetName(uint32_t partNum);
int SwapPartitions(void);
int DestroyGPTwPrompt(void); // Returns 1 if user proceeds
void ShowDetails(void);
@@ -55,5 +56,6 @@ class GPTDataTextUI : public GPTData {
}; // class GPTDataTextUI
int GetMBRTypeCode(int defType);
+UnicodeString ReadUString(void);
#endif // __GPTDATATEXT_H
diff --git a/guid.cc b/guid.cc
index b9d102b..4073375 100644
--- a/guid.cc
+++ b/guid.cc
@@ -5,7 +5,7 @@
// Implements the GUIDData data structure and support methods
//
//
-// Author: Rod Smith <rodsmith@rodsbooks.com>, (C) 2010
+// Author: Rod Smith <rodsmith@rodsbooks.com>, (C) 2010-2011
//
// Copyright: See COPYING file that comes with this distribution
//
diff --git a/mbr.cc b/mbr.cc
index 5a36fa0..372d7f0 100644
--- a/mbr.cc
+++ b/mbr.cc
@@ -66,16 +66,6 @@ void MBRData::MakeProtectiveMBR(int clearBoot) {
} // if/else
partitions[0].SetInclusion(PRIMARY);
- // Write CHS data. This maxes out the use of the disk, as much as
- // possible -- even to the point of exceeding the capacity of sub-8GB
- // disks. The EFI spec says to use 0xffffff as the ending value,
- // although normal MBR disks max out at 0xfeffff. FWIW, both GNU Parted
- // and Apple's Disk Utility use 0xfeffff, and the latter puts that
- // value in for the FIRST sector, too!
-/* LBAtoCHS(1, partitions[0].firstSector);
- if (LBAtoCHS(partitions[0].lengthLBA, partitions[0].lastSector) == 0)
- partitions[0].lastSector[0] = 0xFF; */
-
state = gpt;
} // MBRData::MakeProtectiveMBR()
diff --git a/mbr.h b/mbr.h
index 5f9e0ee..9377c12 100644
--- a/mbr.h
+++ b/mbr.h
@@ -30,7 +30,6 @@ public:
MBRData(void) {}
MBRData(string deviceFilename) : BasicMBRData(deviceFilename) {}
MBRData & operator=(const BasicMBRData & orig);
-// MBRData & operator=(const MBRData & orig);
// Functions to create, delete, or change partitions
// Pass EmptyMBR 1 to clear the boot loader code, 0 to leave it intact
diff --git a/mbrpart.cc b/mbrpart.cc
index f0e4f90..c721f3f 100644
--- a/mbrpart.cc
+++ b/mbrpart.cc
@@ -346,4 +346,4 @@ void MBRPart::ShowData(int isGpt) {
cout.width(2);
cout.fill('0');
cout << hex << (int) partitionType << dec << "\n";
-} // MBRPart::ShowData() \ No newline at end of file
+} // MBRPart::ShowData()
diff --git a/parttypes.cc b/parttypes.cc
index 99de500..662a278 100644
--- a/parttypes.cc
+++ b/parttypes.cc
@@ -357,29 +357,3 @@ int PartType::Valid(uint16_t code) const {
} // while
return found;
} // PartType::Valid()
-
-/********************************
- * *
- * Non-class support functions. *
- * *
- ********************************/
-
-// Note: ReadUString() is here rather than in support.cc so that the ICU
-// libraries need not be linked to fixparts.
-
-// Reads a Unicode string from stdin, returning it as a ICU-style string.
-// Note that the returned string will NOT include the carriage return
-// entered by the user.
-UnicodeString ReadUString(void) {
- UnicodeString inString = "", oneWord;
-
- do {
- cin >> oneWord;
- if (inString.length() > 0)
- inString += " ";
- inString += oneWord;
- } while (cin.peek() != '\n');
- cin.get(); // discard CR
- return inString;
-} // ReadUString()
-
diff --git a/parttypes.h b/parttypes.h
index 77ed851..73c66e2 100644
--- a/parttypes.h
+++ b/parttypes.h
@@ -3,8 +3,11 @@
#include <stdint.h>
#include <stdlib.h>
-#include <unicode/unistr.h>
+#ifndef _WIN32
#include <unicode/ustream.h>
+#else
+#define UnicodeString string
+#endif
#include <string>
#include "support.h"
#include "guid.h"
@@ -61,6 +64,4 @@ public:
int Valid(uint16_t code) const;
};
-UnicodeString ReadUString(void);
-
#endif
diff --git a/sgdisk.8 b/sgdisk.8
index 6e8b2d3..8dbbab5 100644
--- a/sgdisk.8
+++ b/sgdisk.8
@@ -1,6 +1,6 @@
.\" Copyright 2011 Roderick W. Smith (rodsmith@rodsbooks.com)
.\" May be distributed under the GNU General Public License
-.TH "SGDISK" "8" "0.7.0" "Roderick W. Smith" "GPT fdisk Manual"
+.TH "SGDISK" "8" "0.7.1" "Roderick W. Smith" "GPT fdisk Manual"
.SH "NAME"
sgdisk \- Command\-line GUID partition table (GPT) manipulator for Linux and Unix
.SH "SYNOPSIS"
@@ -182,8 +182,8 @@ will reflect GPT fdisk's first\-pass interpretation of the GPT.
.TP
.B \-c, \-\-change\-name=partnum:name
Change the GPT name of a partition. This name is encoded as a UTF\-16
-string, but \fBsgdisk\fR
-supports only ASCII characters as names. For the most part, Linux ignores
+string, but proper entry and display of anything beyond basic ASCII values
+requires suitable locale and font support. For the most part, Linux ignores
the partition name, but it may be important in some OSes. GPT fdisk sets
a default name based on the partition type code. If you want to set a name
that includes a space, enclose it in quotation marks, as in
@@ -470,7 +470,7 @@ Non\-GPT disk detected and no \fI\-g\fR option
.B 4
An error prevented saving changes
.SH "BUGS"
-As of March 2011 (version 0.7.00), \fBsgdisk\fR
+As of March 2011 (version 0.7.1), \fBsgdisk\fR
should be considered beta software. Known bugs and limitations include:
.TP
@@ -496,13 +496,6 @@ alignment.
.TP
.B *
-Only ASCII characters are supported in the partition name field. If an
-existing partition uses non\-ASCII UTF\-16 characters, they're likely to be
-corrupted in the 'i' and 'p' menu options' displays; however, they should be
-preserved when loading and saving partitions.
-
-.TP
-.B *
The program can load only up to 128 partitions (4 primary partitions and
124 logical partitions) when converting from MBR format. This limit can
be raised by changing the \fI#define MAX_MBR_PARTS\fR line in the
diff --git a/sgdisk.cc b/sgdisk.cc
index 83cb663..6b9429b 100644
--- a/sgdisk.cc
+++ b/sgdisk.cc
@@ -52,7 +52,7 @@ int main(int argc, char *argv[]) {
char *newPartInfo = NULL, *typeCode = NULL, *partName = NULL;
char *backupFile = NULL, *twoParts = NULL, *hybrids = NULL, *mbrParts;
char *partGUID = NULL, *diskGUID = NULL, *outDevice = NULL;
- string cmd, typeGUID;
+ string cmd, typeGUID, name;
PartType typeHelper;
poptContext poptCon;
@@ -178,7 +178,8 @@ int main(int argc, char *argv[]) {
case 'c':
theGPT.JustLooking(0);
partNum = (int) GetInt(partName, 1) - 1;
- if (theGPT.SetName(partNum, (UnicodeString) GetString(partName, 2).c_str())) {
+ name = GetString(partName, 2);
+ if (theGPT.SetName(partNum, (UnicodeString) name.c_str())) {
saveData = 1;
} else {
cerr << "Unable to set partition " << partNum + 1
diff --git a/support.h b/support.h
index 290b737..c7dd7d1 100644
--- a/support.h
+++ b/support.h
@@ -8,7 +8,7 @@
#ifndef __GPTSUPPORT
#define __GPTSUPPORT
-#define GPTFDISK_VERSION "0.7.1-pre2"
+#define GPTFDISK_VERSION "0.7.1"
#if defined (__FreeBSD__) || defined (__FreeBSD_kernel__) || defined (__APPLE__)
// Darwin (Mac OS) only: disk IOCTLs are different, and there is no lseek64