0.7.1 release version
diff --git a/Makefile.freebsd b/Makefile.freebsd
index 92dcb0b..783dd7d 100644
--- a/Makefile.freebsd
+++ b/Makefile.freebsd
@@ -13,10 +13,10 @@
 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 @@
 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 @@
 * 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 @@
 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 @@
   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 @@
   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 @@
 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 @@
   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 @@
   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 @@
 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 @@
   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 @@
 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 @@
    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 @@
 // 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 @@
    } // 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 @@
    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::MakeItLegal(void) {
    if (!IsLegal()) {
       DeleteOversizedParts();
-//      OmitAll();
       MaximizeLogicals();
       MaximizePrimaries();
       if (!AreLogicalsContiguous())
@@ -1406,6 +1370,7 @@
       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 @@
    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 @@
    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 @@
    // 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 @@
 
 
 %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 @@
    } // 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 @@
 .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 @@
          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 @@
 .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 @@
 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 @@
 
 .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 @@
       RecomputeCRCs();
 
       protectiveMBR.WriteMBRData(&backupFile);
+      protectiveMBR.SetDisk(&myDisk);
 
       if (allOK) {
          // MBR write closed disk, so re-open and seek to end....
@@ -1768,12 +1769,16 @@
    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 @@
    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 @@
 // 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 @@
    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 @@
          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 @@
    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 @@
       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 @@
       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 @@
       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 @@
       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 @@
 // 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 @@
    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 @@
    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 @@
       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
 
 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 @@
    } // 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 @@
    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 @@
    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 @@
    } // 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 @@
    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 @@
 .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 @@
 .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 @@
 
 .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 @@
    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 @@
                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