New files to support I/O restructuring and (currently broken) Windows
version.
diff --git a/diskio.cc b/diskio.cc
new file mode 100644
index 0000000..3fc3726
--- /dev/null
+++ b/diskio.cc
@@ -0,0 +1,164 @@
+//
+// C++ Interface: diskio (platform-independent components)
+//
+// Description: Class to handle low-level disk I/O for GPT fdisk
+//
+//
+// Author: Rod Smith <rodsmith@rodsbooks.com>, (C) 2009
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+// This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
+// under the terms of the GNU GPL version 2, as detailed in the COPYING file.
+
+#define __STDC_LIMIT_MACROS
+#define __STDC_CONSTANT_MACROS
+
+#ifdef MINGW
+#include <windows.h>
+#include <winioctl.h>
+#define fstat64 fstat
+#define stat64 stat
+#define S_IRGRP 0
+#define S_IROTH 0
+#else
+#include <sys/ioctl.h>
+#endif
+#include <stdio.h>
+#include <string>
+#include <stdint.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <iostream>
+
+#include "support.h"
+#include "diskio.h"
+
+using namespace std;
+
+DiskIO::DiskIO(void) {
+   userFilename = "";
+   realFilename = "";
+   isOpen = 0;
+   openForWrite = 0;
+   sectorData = NULL;
+} // constructor
+
+DiskIO::~DiskIO(void) {
+   Close();
+   free(sectorData);
+} // destructor
+
+// Open a disk device for reading. Returns 1 on success, 0 on failure.
+int DiskIO::OpenForRead(string filename) {
+   int shouldOpen = 1;
+
+   if (isOpen) { // file is already open
+      if (((realFilename != filename) && (userFilename != filename)) || (openForWrite)) {
+         Close();
+      } else {
+         shouldOpen = 0;
+      } // if/else
+   } // if
+
+   if (shouldOpen) {
+      userFilename = filename;
+      MakeRealName();
+      OpenForRead();
+   } // if
+
+   return isOpen;
+} // DiskIO::OpenForRead(string filename)
+
+// Open a disk for reading and writing by filename.
+// Returns 1 on success, 0 on failure.
+int DiskIO::OpenForWrite(string filename) {
+   int retval = 0;
+
+   if ((isOpen) && (openForWrite) && ((filename == realFilename) || (filename == userFilename))) {
+      retval = 1;
+   } else {
+      userFilename = filename;
+      MakeRealName();
+      retval = OpenForWrite();
+      if (retval == 0) {
+         realFilename = userFilename = "";
+      } // if
+   } // if/else
+   return retval;
+} // DiskIO::OpenForWrite(string filename)
+
+// My original FindAlignment() function (after this one) isn't working, since
+// the BLKPBSZGET ioctl() isn't doing what I expected (it returns 512 even on
+// a WD Advanced Format drive). Therefore, I'm using a simpler function that
+// returns 1-sector alignment for unusual sector sizes and drives smaller than
+// a size defined by SMALLEST_ADVANCED_FORMAT, and 8-sector alignment for
+// larger drives with 512-byte sectors.
+int DiskIO::FindAlignment(void) {
+   int err, result;
+
+   if ((GetBlockSize() == 512) && (DiskSize(&err) >= SMALLEST_ADVANCED_FORMAT)) {
+      result = 8; // play it safe; align for 4096-byte sectors
+   } else {
+      result = 1; // unusual sector size; assume it's the real physical size
+   } // if/else
+   return result;
+} // DiskIO::FindAlignment
+
+// Return the partition alignment value in sectors. Right now this works
+// only for Linux 2.6.32 and later, since I can't find equivalent ioctl()s
+// for OS X or FreeBSD, and the Linux ioctl is new
+/* int DiskIO::FindAlignment(int fd) {
+   int err = -2, errnum = 0, result = 8, physicalSectorSize = 4096;
+   uint64_t diskSize;
+
+   printf("Entering FindAlignment()\n");
+#if defined (__linux__) && defined (BLKPBSZGET)
+   err = ioctl(fd, BLKPBSZGET, &physicalSectorSize);
+   printf("In FindAlignment(), physicalSectorSize = %d, err = %d\n", physicalSectorSize, err);
+//   printf("Tried to get hardware alignment; err is %d, sector size is %d\n", err, physicalSectorSize);
+#else
+   err = -1;
+#endif
+
+   if (err < 0) { // ioctl didn't work; have to guess....
+      if (GetBlockSize(fd) == 512) {
+         result = 8; // play it safe; align for 4096-byte sectors
+} else {
+         result = 1; // unusual sector size; assume it's the real physical size
+} // if/else
+} else { // ioctl worked; compute alignment
+      result = physicalSectorSize / GetBlockSize(fd);
+      // Disks with larger physical than logical sectors must theoretically
+      // have a total disk size that's a multiple of the physical sector
+      // size; however, some such disks have compatibility jumper settings
+      // meant for one-partition MBR setups, and these reduce the total
+      // number of sectors by 1. If such a setting is used, it'll result
+      // in improper alignment, so look for this condition and warn the
+      // user if it's found....
+      diskSize = disksize(fd, &errnum);
+      if ((diskSize % (uint64_t) result) != 0) {
+         fprintf(stderr, "\aWarning! Disk size (%llu) is not a multiple of alignment\n"
+                         "size (%d), but it should be! Check disk manual and jumper settings!\n",
+                         (unsigned long long) diskSize, result);
+} // if
+} // if/else
+   if (result <= 0) // can happen if physical sector size < logical sector size
+      result = 1;
+   return result;
+} // DiskIO::FindAlignment(int) */
+
+// The same as FindAlignment(int), but opens and closes a device by filename
+int DiskIO::FindAlignment(string filename) {
+   int fd;
+   int retval = 1;
+
+   if (!isOpen)
+      OpenForRead(filename);
+   if (isOpen) {
+      retval = FindAlignment();
+   } // if
+   return retval;
+} // DiskIO::FindAlignment(char)