Nearing 0.6.2 release; Windows version now works.
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
0.6.2 (?/??/2010):
|
||||
------------------
|
||||
|
||||
- The change-type ('t' on main menu) option now changes the partition's
|
||||
name *IF* the current name is the generic one for the partition type.
|
||||
If the current name is not the generic name, it is NOT changed.
|
||||
|
||||
- Fixed bug that caused new protective MBR to not be created when the
|
||||
MBR was invalid and the GPT was damaged and the user opts to try to
|
||||
use the GPT data.
|
||||
|
||||
3
Makefile
3
Makefile
@@ -19,9 +19,6 @@ gdisk: $(LIB_OBJS) gdisk.o
|
||||
sgdisk: $(LIB_OBJS) sgdisk.o
|
||||
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib -lpopt -o sgdisk
|
||||
|
||||
wipegpt: $(LIB_OBJS) wipegpt.o
|
||||
$(CXX) $(LIB_OBJS) wipegpt.o -o wipegpt
|
||||
|
||||
lint: #no pre-reqs
|
||||
lint $(SRCS)
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
CC=/usr/bin/i586-mingw32msvc-gcc
|
||||
CXX=/usr/bin/i586-mingw32msvc-g++
|
||||
STRIP=/usr/bin/i586-mingw32msvc-strip
|
||||
CFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -g
|
||||
CXXFLAGS=-O2 -DMINGW -Wuninitialized -Wreturn-type -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
|
||||
CXXFLAGS=-O2 -Wuninitialized -Wreturn-type -D_FILE_OFFSET_BITS=64 -I /usr/local/include -I/opt/local/include -g
|
||||
LIB_NAMES=gptpart bsd parttypes attributes crc32 mbr gpt support diskio diskio-windows
|
||||
LIB_SRCS=$(NAMES:=.cc)
|
||||
LIB_OBJS=$(LIB_NAMES:=.o)
|
||||
@@ -17,16 +18,16 @@ gdisk: $(LIB_OBJS) gdisk.o
|
||||
$(CXX) $(LIB_OBJS) gdisk.o -o gdisk.exe
|
||||
|
||||
sgdisk: $(LIB_OBJS) sgdisk.o
|
||||
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib -lpopt -o sgdisk
|
||||
|
||||
wipegpt: $(LIB_OBJS) wipegpt.o
|
||||
$(CXX) $(LIB_OBJS) wipegpt.o -o wipegpt
|
||||
$(CXX) $(LIB_OBJS) sgdisk.o -L/opt/local/lib -L/usr/local/lib -lpopt -o sgdisk.exe
|
||||
|
||||
lint: #no pre-reqs
|
||||
lint $(SRCS)
|
||||
|
||||
clean: #no pre-reqs
|
||||
rm -f core *.o *~ gdisk sgdisk
|
||||
rm -f core *.o *~ gdisk.exe sgdisk.exe
|
||||
|
||||
strip: #no pre-reqs
|
||||
$(STRIP) gdisk.exe
|
||||
|
||||
# what are the source dependencies
|
||||
depend: $(SRCS)
|
||||
|
||||
6
bsd.cc
6
bsd.cc
@@ -43,12 +43,12 @@ BSDData::~BSDData(void) {
|
||||
// Read BSD disklabel data from the specified device filename. This function
|
||||
// just opens the device file and then calls an overloaded function to do
|
||||
// the bulk of the work. Returns 1 on success, 0 on failure.
|
||||
int BSDData::ReadBSDData(string *device, uint64_t startSector, uint64_t endSector) {
|
||||
int BSDData::ReadBSDData(const string & device, uint64_t startSector, uint64_t endSector) {
|
||||
int allOK = 1;
|
||||
DiskIO myDisk;
|
||||
|
||||
if (*device != "") {
|
||||
if (myDisk.OpenForRead(*device)) {
|
||||
if (device != "") {
|
||||
if (myDisk.OpenForRead(device)) {
|
||||
allOK = ReadBSDData(&myDisk, startSector, endSector);
|
||||
} else {
|
||||
allOK = 0;
|
||||
|
||||
2
bsd.h
2
bsd.h
@@ -72,7 +72,7 @@ class BSDData {
|
||||
public:
|
||||
BSDData(void);
|
||||
~BSDData(void);
|
||||
int ReadBSDData(string *deviceFilename, uint64_t startSector, uint64_t endSector);
|
||||
int ReadBSDData(const string & deviceFilename, uint64_t startSector, uint64_t endSector);
|
||||
int ReadBSDData(DiskIO *myDisk, uint64_t startSector, uint64_t endSector);
|
||||
void ReverseMetaBytes(void);
|
||||
void DisplayBSDData(void);
|
||||
|
||||
@@ -42,9 +42,9 @@ void DiskIO::MakeRealName(void) {
|
||||
if ((colonPos != string::npos) && (colonPos <= 3)) {
|
||||
realFilename = "\\\\.\\physicaldrive";
|
||||
realFilename += userFilename.substr(0, colonPos);
|
||||
} else {
|
||||
realFilename = userFilename;
|
||||
} // if/else
|
||||
printf("Exiting DiskIO::MakeRealName(); translated '%s' ", userFilename.c_str());
|
||||
printf("to '%s'\n", realFilename.c_str());
|
||||
} // DiskIO::MakeRealName()
|
||||
|
||||
// Open the currently on-record file for reading
|
||||
@@ -60,12 +60,11 @@ int DiskIO::OpenForRead(void) {
|
||||
} // if
|
||||
|
||||
if (shouldOpen) {
|
||||
printf("Opening '%s' for reading.\n", realFilename.c_str());
|
||||
fd = CreateFile(realFilename.c_str(),GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (fd == INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fd);
|
||||
fprintf(stderr, "Problem opening %s for reading!\n", realFilename.c_str());
|
||||
cerr << "Problem opening " << realFilename << " for reading!\n";
|
||||
realFilename = "";
|
||||
userFilename = "";
|
||||
isOpen = 0;
|
||||
@@ -94,11 +93,12 @@ int DiskIO::OpenForWrite(void) {
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (fd == INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fd);
|
||||
isOpen = 1;
|
||||
openForWrite = 1;
|
||||
} else {
|
||||
isOpen = 0;
|
||||
openForWrite = 0;
|
||||
errno = GetLastError();
|
||||
} else {
|
||||
isOpen = 1;
|
||||
openForWrite = 1;
|
||||
} // if/else
|
||||
return isOpen;
|
||||
} // DiskIO::OpenForWrite(void)
|
||||
@@ -133,6 +133,7 @@ int DiskIO::GetBlockSize(void) {
|
||||
__out LPDWORD lpTotalNumberOfClusters
|
||||
); */
|
||||
// err = GetDiskFreeSpace(realFilename.c_str(), &junk1, &blockSize, &junk2, &junk3);
|
||||
// Above call is fubared -- returns weird values for blockSize....
|
||||
err = 1;
|
||||
blockSize = 512;
|
||||
|
||||
@@ -142,9 +143,9 @@ int DiskIO::GetBlockSize(void) {
|
||||
// file, so don't display the warning message....
|
||||
// 32-bit code returns EINVAL, I don't know why. I know I'm treading on
|
||||
// thin ice here, but it should be OK in all but very weird cases....
|
||||
if ((errno != ENOTTY) && (errno != EINVAL)) {
|
||||
printf("\aError %d when determining sector size! Setting sector size to %d\n",
|
||||
GetLastError(), SECTOR_SIZE);
|
||||
if (errno != 267) { // 267 is returned on ordinary files
|
||||
cerr << "\aError " << GetLastError() << " when determining sector size! "
|
||||
<< "Setting sector size to " << SECTOR_SIZE << "\n";
|
||||
} // if
|
||||
} // if (err == -1)
|
||||
} // if (isOpen)
|
||||
@@ -155,21 +156,26 @@ int DiskIO::GetBlockSize(void) {
|
||||
// Resync disk caches so the OS uses the new partition table. This code varies
|
||||
// a lot from one OS to another.
|
||||
void DiskIO::DiskSync(void) {
|
||||
int i;
|
||||
DWORD i;
|
||||
GET_LENGTH_INFORMATION buf;
|
||||
|
||||
// If disk isn't open, try to open it....
|
||||
if (!isOpen) {
|
||||
OpenForRead();
|
||||
if (!openForWrite) {
|
||||
OpenForWrite();
|
||||
} // if
|
||||
|
||||
if (isOpen) {
|
||||
#ifndef MINGW
|
||||
sync();
|
||||
#endif
|
||||
#ifdef MINGW
|
||||
printf("Warning: I don't know how to sync disks in Windows! The old partition table is\n"
|
||||
"probably still in use!\n");
|
||||
#endif
|
||||
if (DeviceIoControl(fd, IOCTL_DISK_UPDATE_PROPERTIES, NULL, 0, &buf, sizeof(buf), &i, NULL) == 0) {
|
||||
cout << "Disk synchronization failed! The computer may use the old partition table\n"
|
||||
<< "until you reboot or remove and re-insert the disk!\n";
|
||||
} else {
|
||||
cout << "Disk synchronization succeeded! The computer should now use the new\n"
|
||||
<< "partition table.\n";
|
||||
} // if/else
|
||||
} else {
|
||||
cout << "Unable to open the disk for synchronization operation! The computer will\n"
|
||||
<< "continue to use the old partition table until you reboot or remove and\n"
|
||||
<< "re-insert the disk!\n";
|
||||
} // if (isOpen)
|
||||
} // DiskIO::DiskSync()
|
||||
|
||||
@@ -186,22 +192,11 @@ int DiskIO::Seek(uint64_t sector) {
|
||||
} // if
|
||||
|
||||
if (isOpen) {
|
||||
bytePos = sector * (uint64_t) GetBlockSize();
|
||||
lowBits = (uint32_t) (bytePos / UINT64_C(4294967296));
|
||||
highBits = (uint32_t) (bytePos % UINT64_C(4294967296));
|
||||
seekTo.LowPart = lowBits;
|
||||
seekTo.HighPart = highBits;
|
||||
// seekTo.QuadPart = (LONGLONG) (sector * (uint64_t) GetBlockSize());
|
||||
/* printf("In DiskIO::Seek(), sector = %llu, ", sector);
|
||||
printf("block size = %d, ", GetBlockSize());
|
||||
printf("seekTo.QuadPart = %lld\n", seekTo.QuadPart);
|
||||
printf(" seekTo.LowPart = %lu, ", seekTo.LowPart);
|
||||
printf("seekTo.HighPart = %lu\n", seekTo.HighPart); */
|
||||
seekTo.QuadPart = sector * (uint64_t) GetBlockSize();
|
||||
retval = SetFilePointerEx(fd, seekTo, NULL, FILE_BEGIN);
|
||||
if (retval == 0) {
|
||||
errno = GetLastError();
|
||||
fprintf(stderr, "Error when seeking to %lld! Error is %d\n",
|
||||
seekTo.QuadPart, errno);
|
||||
cerr << "Error when seeking to " << seekTo.QuadPart << "! Error is " << errno << "\n";
|
||||
retval = 0;
|
||||
} // if
|
||||
} // if
|
||||
@@ -235,9 +230,7 @@ int DiskIO::Read(void* buffer, int numBytes) {
|
||||
} // if/else
|
||||
|
||||
// Read the data into temporary space, then copy it to buffer
|
||||
// retval = read(fd, tempSpace, numBlocks * blockSize);
|
||||
ReadFile(fd, tempSpace, numBlocks * blockSize, &retval, NULL);
|
||||
printf("In DiskIO::Read(), have read %d bytes.\n", (int) retval);
|
||||
for (i = 0; i < numBytes; i++) {
|
||||
((char*) buffer)[i] = tempSpace[i];
|
||||
} // for
|
||||
@@ -284,7 +277,6 @@ int DiskIO::Write(void* buffer, int numBytes) {
|
||||
for (i = numBytes; i < numBlocks * blockSize; i++) {
|
||||
tempSpace[i] = 0;
|
||||
} // for
|
||||
// retval = write(fd, tempSpace, numBlocks * blockSize);
|
||||
WriteFile(fd, tempSpace, numBlocks * blockSize, &numWritten, NULL);
|
||||
retval = (int) numWritten;
|
||||
|
||||
@@ -300,8 +292,7 @@ int DiskIO::Write(void* buffer, int numBytes) {
|
||||
// Returns the size of the disk in blocks.
|
||||
uint64_t DiskIO::DiskSize(int *err) {
|
||||
uint64_t sectors = 0; // size in sectors
|
||||
off_t bytes = 0; // size in bytes
|
||||
struct stat64 st;
|
||||
DWORD bytes, moreBytes; // low- and high-order bytes of file size
|
||||
GET_LENGTH_INFORMATION buf;
|
||||
DWORD i;
|
||||
|
||||
@@ -316,30 +307,18 @@ uint64_t DiskIO::DiskSize(int *err) {
|
||||
// on Linux, but I had some problems. IIRC, it ran OK on 32-bit
|
||||
// systems but not on 64-bit. Keep this in mind in case of
|
||||
// 32/64-bit issues on MacOS....
|
||||
/* HANDLE fin;
|
||||
fin = CreateFile(realFilename.c_str(), GENERIC_READ,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); */
|
||||
if (DeviceIoControl(fd, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &buf, sizeof(buf), &i, NULL)) {
|
||||
sectors = (uint64_t) buf.Length.QuadPart / GetBlockSize();
|
||||
// printf("disk_get_size_win32 IOCTL_DISK_GET_LENGTH_INFO = %llu\n",
|
||||
// (long long unsigned) sectors);
|
||||
} else {
|
||||
fprintf(stderr, "Couldn't determine disk size!\n");
|
||||
}
|
||||
*err = 0;
|
||||
} else { // doesn't seem to be a disk device; assume it's an image file....
|
||||
bytes = GetFileSize(fd, &moreBytes);
|
||||
sectors = ((uint64_t) bytes + ((uint64_t) moreBytes) * UINT32_MAX) / GetBlockSize();
|
||||
*err = 0;
|
||||
} // if
|
||||
} else {
|
||||
*err = -1;
|
||||
sectors = 0;
|
||||
} // if/else (isOpen)
|
||||
|
||||
/* // The above methods have failed, so let's assume it's a regular
|
||||
// file (a QEMU image, dd backup, or what have you) and see what
|
||||
// fstat() gives us....
|
||||
if ((sectors == 0) || (*err == -1)) {
|
||||
if (fstat64(fd, &st) == 0) {
|
||||
bytes = (off_t) st.st_size;
|
||||
if ((bytes % UINT64_C(512)) != 0)
|
||||
fprintf(stderr, "Warning: File size is not a multiple of 512 bytes!"
|
||||
" Misbehavior is likely!\n\a");
|
||||
sectors = bytes / UINT64_C(512);
|
||||
} // if
|
||||
} // if */
|
||||
} // if (isOpen)
|
||||
return sectors;
|
||||
} // DiskIO::DiskSize()
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#define __STDC_CONSTANT_MACROS
|
||||
|
||||
#ifdef MINGW
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#define fstat64 fstat
|
||||
@@ -52,7 +52,7 @@ DiskIO::~DiskIO(void) {
|
||||
} // destructor
|
||||
|
||||
// Open a disk device for reading. Returns 1 on success, 0 on failure.
|
||||
int DiskIO::OpenForRead(string filename) {
|
||||
int DiskIO::OpenForRead(const string & filename) {
|
||||
int shouldOpen = 1;
|
||||
|
||||
if (isOpen) { // file is already open
|
||||
@@ -74,7 +74,7 @@ int 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 DiskIO::OpenForWrite(const string & filename) {
|
||||
int retval = 0;
|
||||
|
||||
if ((isOpen) && (openForWrite) && ((filename == realFilename) || (filename == userFilename))) {
|
||||
@@ -151,7 +151,7 @@ int DiskIO::FindAlignment(void) {
|
||||
} // DiskIO::FindAlignment(int) */
|
||||
|
||||
// The same as FindAlignment(int), but opens and closes a device by filename
|
||||
int DiskIO::FindAlignment(string filename) {
|
||||
int DiskIO::FindAlignment(const string & filename) {
|
||||
int fd;
|
||||
int retval = 1;
|
||||
|
||||
|
||||
10
diskio.h
10
diskio.h
@@ -18,7 +18,7 @@
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef MINGW
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#else
|
||||
@@ -52,7 +52,7 @@ class DiskIO {
|
||||
int isOpen;
|
||||
int openForWrite;
|
||||
uint8_t *sectorData;
|
||||
#ifdef MINGW
|
||||
#ifdef _WIN32
|
||||
HANDLE fd;
|
||||
#else
|
||||
int fd;
|
||||
@@ -62,9 +62,9 @@ class DiskIO {
|
||||
~DiskIO(void);
|
||||
|
||||
void MakeRealName(void);
|
||||
int OpenForRead(string filename);
|
||||
int OpenForRead(const string & filename);
|
||||
int OpenForRead(void);
|
||||
int OpenForWrite(string filename);
|
||||
int OpenForWrite(const string & filename);
|
||||
int OpenForWrite(void);
|
||||
void Close();
|
||||
int Seek(uint64_t sector);
|
||||
@@ -73,7 +73,7 @@ class DiskIO {
|
||||
void DiskSync(void); // resync disk caches to use new partitions
|
||||
int GetBlockSize(void);
|
||||
int FindAlignment(void);
|
||||
int FindAlignment(string filename);
|
||||
int FindAlignment(const string & filename);
|
||||
int IsOpen(void) {return isOpen;}
|
||||
int IsOpenForWrite(void) {return openForWrite;}
|
||||
|
||||
|
||||
8
gdisk.8
8
gdisk.8
@@ -2,7 +2,7 @@
|
||||
.\" May be distributed under the GNU General Public License
|
||||
.TH "GDISK" "8" "0.5.3" "Roderick W. Smith" "GPT fdisk Manual"
|
||||
.SH "NAME"
|
||||
gdisk \- Interactive GUID partition table (GPT) manipulator for Linux and Unix
|
||||
gdisk \- Interactive GUID partition table (GPT) manipulator
|
||||
.SH "SYNOPSIS"
|
||||
.BI "gdisk "
|
||||
[ \-l ]
|
||||
@@ -453,10 +453,8 @@ mid-physical-sector, though, performance can suffer on such drives, since
|
||||
important filesystem data structures can span physical sectors on the disk.
|
||||
To minimize such problems, GPT fdisk aligns the start of partitions on the
|
||||
boundary of presumed physical sectors. You can set the number of logical
|
||||
sectors per physical sector with this option. The default is 8, except on
|
||||
Linux 2.6.32 and later, in which case it's read from the disk. A value of 8
|
||||
will result in a tiny amount of wasted disk space on older disks with true
|
||||
512-byte sectors but will otherwise be harmless.
|
||||
sectors per physical sector with this option. The default is 1 on disks
|
||||
smaller than 800GB and 8 on larger disks.
|
||||
|
||||
.TP
|
||||
.B m
|
||||
|
||||
11
gdisk.cc
11
gdisk.cc
@@ -34,6 +34,17 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
if (argc == 2) { // basic usage
|
||||
if (SizesOK()) {
|
||||
#ifdef _WIN32
|
||||
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"
|
||||
<< "************************************************************************\n\n";
|
||||
cout << "Are you SURE you want to continue? ";
|
||||
if (GetYN() != 'Y')
|
||||
exit(0);
|
||||
#endif
|
||||
doMore = theGPT.LoadPartitions(argv[1]);
|
||||
if (doMore) {
|
||||
MainMenu(argv[1], &theGPT);
|
||||
|
||||
32
gpt.cc
32
gpt.cc
@@ -239,7 +239,7 @@ int GPTData::Verify(void) {
|
||||
<< largestSegment << " (" << BytesToSI(largestSegment * (uint64_t) blockSize)
|
||||
<< ") in size\n";
|
||||
} else {
|
||||
cout << "\nIdentified %d problems!\n", problems;
|
||||
cout << "\nIdentified " << problems << " problems!\n";
|
||||
} // if/else
|
||||
|
||||
return (problems);
|
||||
@@ -497,7 +497,7 @@ int GPTData::FindOverlaps(void) {
|
||||
|
||||
for (i = 1; i < mainHeader.numParts; i++) {
|
||||
for (j = 0; j < i; j++) {
|
||||
if (partitions[i].DoTheyOverlap(&partitions[j])) {
|
||||
if (partitions[i].DoTheyOverlap(partitions[j])) {
|
||||
problems++;
|
||||
cout << "\nProblem: partitions " << i + 1 << " and " << j + 1 << " overlap:\n";
|
||||
cout << " Partition " << i + 1 << ": " << partitions[i].GetFirstLBA()
|
||||
@@ -550,7 +550,7 @@ void GPTData::PartitionScan(void) {
|
||||
} // GPTData::PartitionScan()
|
||||
|
||||
// Read GPT data from a disk.
|
||||
int GPTData::LoadPartitions(string deviceFilename) {
|
||||
int GPTData::LoadPartitions(const string & deviceFilename) {
|
||||
int err;
|
||||
int allOK = 1, i;
|
||||
uint64_t firstBlock, lastBlock;
|
||||
@@ -636,7 +636,7 @@ int GPTData::LoadPartitions(string deviceFilename) {
|
||||
// succeeded, 0 if there are obvious problems....
|
||||
int GPTData::ForceLoadGPTData(void) {
|
||||
int allOK = 1, validHeaders;
|
||||
off_t seekTo;
|
||||
uint64_t seekTo;
|
||||
uint8_t* storage;
|
||||
uint32_t newCRC, sizeOfParts;
|
||||
|
||||
@@ -839,7 +839,7 @@ int GPTData::SaveGPTData(int quiet) {
|
||||
char answer, line[256];
|
||||
uint64_t secondTable;
|
||||
uint32_t numParts;
|
||||
off_t offset;
|
||||
uint64_t offset;
|
||||
|
||||
if (device == "") {
|
||||
cerr << "Device not defined.\n";
|
||||
@@ -936,7 +936,7 @@ int GPTData::SaveGPTData(int quiet) {
|
||||
|
||||
// Now seek to near the end to write the secondary GPT....
|
||||
if (allOK) {
|
||||
offset = (off_t) secondTable;
|
||||
offset = (uint64_t) secondTable;
|
||||
if (myDisk.Seek(offset) != 1) {
|
||||
allOK = 0;
|
||||
cerr << "Unable to seek to end of disk! Perhaps the 'e' option on the experts' menu\n"
|
||||
@@ -998,12 +998,11 @@ int GPTData::SaveGPTData(int quiet) {
|
||||
// the main GPT header, the backup GPT header, and the main partition
|
||||
// table; it discards the backup partition table, since it should be
|
||||
// identical to the main partition table on healthy disks.
|
||||
int GPTData::SaveGPTBackup(string filename) {
|
||||
int fd, allOK = 1;
|
||||
int GPTData::SaveGPTBackup(const string & filename) {
|
||||
int allOK = 1;
|
||||
uint32_t numParts;
|
||||
DiskIO backupFile;
|
||||
|
||||
// if ((fd = open(filename, O_WRONLY | O_CREAT, S_IWUSR | S_IRUSR | S_IRGRP | S_IROTH)) != -1) {
|
||||
if (backupFile.OpenForWrite(filename)) {
|
||||
// Reverse the byte order, if necessary....
|
||||
numParts = mainHeader.numParts;
|
||||
@@ -1066,13 +1065,12 @@ int GPTData::SaveGPTBackup(string filename) {
|
||||
// does minimal error checking. It returns 1 if it completed successfully,
|
||||
// 0 if there was a problem. In the latter case, it creates a new empty
|
||||
// set of partitions.
|
||||
int GPTData::LoadGPTBackup(string filename) {
|
||||
int fd, allOK = 1, val;
|
||||
int GPTData::LoadGPTBackup(const string & filename) {
|
||||
int allOK = 1, val;
|
||||
uint32_t numParts, sizeOfEntries, sizeOfParts, newCRC;
|
||||
int littleEndian = 1;
|
||||
DiskIO backupFile;
|
||||
|
||||
// if ((fd = open(filename, O_RDONLY)) != -1) {
|
||||
if (backupFile.OpenForRead(filename)) {
|
||||
if (IsLittleEndian() == 0)
|
||||
littleEndian = 0;
|
||||
@@ -1473,7 +1471,7 @@ WhichToUse GPTData::UseWhichPartitions(void) {
|
||||
cout << "\n**********************************************************************\n"
|
||||
<< "Found invalid GPT and valid BSD disklabel; converting BSD disklabel\n"
|
||||
<< "to GPT format.";
|
||||
if (!justLooking) {
|
||||
if ((!justLooking) && (!beQuiet)) {
|
||||
cout << "\a THIS OPERATON IS POTENTIALLY DESTRUCTIVE! Your first\n"
|
||||
<< "BSD partition will likely be unusable. Exit by typing 'q' if you don't\n"
|
||||
<< "want to convert your BSD partitions to GPT format!";
|
||||
@@ -1493,10 +1491,9 @@ WhichToUse GPTData::UseWhichPartitions(void) {
|
||||
cout << "Found valid GPT with hybrid MBR; using GPT.\n";
|
||||
} // if
|
||||
if ((state == gpt_valid) && (mbrState == invalid)) {
|
||||
cout << "\aFound valid GPT with corrupt MBR; using GPT and will create new\n"
|
||||
cout << "\aFound valid GPT with corrupt MBR; using GPT and will write new\n"
|
||||
<< "protective MBR on save.\n";
|
||||
which = use_gpt;
|
||||
protectiveMBR.MakeProtectiveMBR();
|
||||
} // if
|
||||
if ((state == gpt_valid) && (mbrState == mbr)) {
|
||||
if (!beQuiet) {
|
||||
@@ -1506,7 +1503,6 @@ WhichToUse GPTData::UseWhichPartitions(void) {
|
||||
which = use_mbr;
|
||||
} else if (answer == 2) {
|
||||
which = use_gpt;
|
||||
protectiveMBR.MakeProtectiveMBR();
|
||||
cout << "Using GPT and creating fresh protective MBR.\n";
|
||||
} else which = use_new;
|
||||
} else which = use_abort;
|
||||
@@ -1612,7 +1608,7 @@ int GPTData::XFormDisklabel(int i) {
|
||||
|
||||
// If all is OK, read the disklabel and convert it.
|
||||
if (goOn) {
|
||||
goOn = disklabel.ReadBSDData(&myDisk, partitions[partNum].GetFirstLBA(),
|
||||
goOn = disklabel.ReadBSDData(device, partitions[partNum].GetFirstLBA(),
|
||||
partitions[partNum].GetLastLBA());
|
||||
if ((goOn) && (disklabel.IsDisklabel())) {
|
||||
numDone = XFormDisklabel(&disklabel, startPart);
|
||||
@@ -2053,7 +2049,7 @@ void GPTData::MoveSecondHeaderToEnd() {
|
||||
secondHeader.partitionEntriesLBA = secondHeader.lastUsableLBA + UINT64_C(1);
|
||||
} // GPTData::FixSecondHeaderLocation()
|
||||
|
||||
int GPTData::SetName(uint32_t partNum, string theName) {
|
||||
int GPTData::SetName(uint32_t partNum, const string & theName) {
|
||||
int retval = 1;
|
||||
|
||||
if (!IsFreePartNum(partNum)) {
|
||||
|
||||
12
gpt.h
12
gpt.h
@@ -93,15 +93,15 @@ public:
|
||||
int FindOverlaps(void);
|
||||
|
||||
// Load or save data from/to disk
|
||||
int LoadMBR(string f) {return protectiveMBR.ReadMBRData(f);}
|
||||
int LoadMBR(const string & f) {return protectiveMBR.ReadMBRData(f);}
|
||||
void PartitionScan(void);
|
||||
int LoadPartitions(string deviceFilename);
|
||||
int LoadPartitions(const string & deviceFilename);
|
||||
int ForceLoadGPTData(void);
|
||||
int LoadMainTable(void);
|
||||
int LoadSecondTableAsMain(void);
|
||||
int SaveGPTData(int quiet = 0);
|
||||
int SaveGPTBackup(string filename);
|
||||
int LoadGPTBackup(string filename);
|
||||
int SaveGPTBackup(const string & filename);
|
||||
int LoadGPTBackup(const string & filename);
|
||||
|
||||
// Display data....
|
||||
void ShowAPMState(void);
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
void SortGPT(void);
|
||||
int ClearGPTData(void);
|
||||
void MoveSecondHeaderToEnd();
|
||||
int SetName(uint32_t partNum, string theName = "");
|
||||
int SetName(uint32_t partNum, const string & theName = "");
|
||||
void SetDiskGUID(GUIDData newGUID);
|
||||
int SetPartitionGUID(uint32_t pn, GUIDData theGUID);
|
||||
int ChangePartType(uint32_t pn, uint16_t hexCode);
|
||||
@@ -170,7 +170,7 @@ public:
|
||||
WhichToUse WhichWasUsed(void) {return whichWasUsed;}
|
||||
|
||||
// Endianness functions
|
||||
void ReverseHeaderBytes(struct GPTHeader* header); // for endianness
|
||||
void ReverseHeaderBytes(struct GPTHeader* header);
|
||||
void ReversePartitionBytes(); // for endianness
|
||||
}; // class GPTData
|
||||
|
||||
|
||||
311
gptpart.cc
311
gptpart.cc
@@ -35,17 +35,6 @@ GPTPart::GPTPart(void) {
|
||||
GPTPart::~GPTPart(void) {
|
||||
} // destructor
|
||||
|
||||
// Return partition's name field, converted to a C++ ASCII string
|
||||
string GPTPart::GetName(void) {
|
||||
string theName;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NAME_SIZE; i += 2) {
|
||||
theName += name[i];
|
||||
} // for
|
||||
return theName;
|
||||
} // GPTPart::GetName()
|
||||
|
||||
// Return the gdisk-specific two-byte hex code for the partition
|
||||
uint16_t GPTPart::GetHexType(void) {
|
||||
return typeHelper.GUIDToID(partitionType);
|
||||
@@ -66,18 +55,30 @@ uint64_t GPTPart::GetLengthLBA(void) {
|
||||
return length;
|
||||
} // GPTPart::GetLengthLBA()
|
||||
|
||||
GPTPart & GPTPart::operator=(const GPTPart & orig) {
|
||||
// Return partition's name field, converted to a C++ ASCII string
|
||||
string GPTPart::GetName(void) {
|
||||
string theName;
|
||||
int i;
|
||||
|
||||
partitionType = orig.partitionType;
|
||||
uniqueGUID = orig.uniqueGUID;
|
||||
firstLBA = orig.firstLBA;
|
||||
lastLBA = orig.lastLBA;
|
||||
attributes = orig.attributes;
|
||||
for (i = 0; i < NAME_SIZE; i++)
|
||||
name[i] = orig.name[i];
|
||||
return *this;
|
||||
} // assignment operator
|
||||
theName = "";
|
||||
for (i = 0; i < NAME_SIZE; i += 2) {
|
||||
if (name[i] != '\0')
|
||||
theName += name[i];
|
||||
} // for
|
||||
return theName;
|
||||
} // GPTPart::GetName()
|
||||
|
||||
// Set the type code to the specified one. Also changes the partition
|
||||
// name *IF* the current name is the generic one for the current partition
|
||||
// type.
|
||||
void GPTPart::SetType(struct GUIDData t) {
|
||||
int nameSame = 1, currentLength, i;
|
||||
|
||||
if (GetName() == typeHelper.GUIDToName(partitionType)) {
|
||||
SetName(typeHelper.GUIDToName(t));
|
||||
} // if
|
||||
partitionType = t;
|
||||
} // GPTPart::SetType()
|
||||
|
||||
// Sets the unique GUID to a value of 0 or a random value,
|
||||
// depending on the parameter: 0 = 0, anything else = random
|
||||
@@ -93,138 +94,11 @@ void GPTPart::SetUniqueGUID(int zeroOrRandom) {
|
||||
}
|
||||
} // GPTPart::SetUniqueGUID()
|
||||
|
||||
// Blank (delete) a single partition
|
||||
void GPTPart::BlankPartition(void) {
|
||||
int j;
|
||||
GUIDData zeroGUID;
|
||||
|
||||
zeroGUID.data1 = 0;
|
||||
zeroGUID.data2 = 0;
|
||||
uniqueGUID = zeroGUID;
|
||||
partitionType = zeroGUID;
|
||||
firstLBA = 0;
|
||||
lastLBA = 0;
|
||||
attributes = 0;
|
||||
for (j = 0; j < NAME_SIZE; j++)
|
||||
name[j] = '\0';
|
||||
} // GPTPart::BlankPartition
|
||||
|
||||
// Returns 1 if the two partitions overlap, 0 if they don't
|
||||
int GPTPart::DoTheyOverlap(GPTPart* other) {
|
||||
int theyDo = 0;
|
||||
|
||||
// Don't bother checking unless these are defined (both start and end points
|
||||
// are 0 for undefined partitions, so just check the start points)
|
||||
if ((firstLBA != 0) && (other->firstLBA != 0)) {
|
||||
if ((firstLBA < other->lastLBA) && (lastLBA >= other->firstLBA))
|
||||
theyDo = 1;
|
||||
if ((other->firstLBA < lastLBA) && (other->lastLBA >= firstLBA))
|
||||
theyDo = 1;
|
||||
} // if
|
||||
return (theyDo);
|
||||
} // GPTPart::DoTheyOverlap()
|
||||
|
||||
// Reverse the bytes of integral data types; used on big-endian systems.
|
||||
void GPTPart::ReversePartBytes(void) {
|
||||
ReverseBytes(&partitionType.data1, 8);
|
||||
ReverseBytes(&partitionType.data2, 8);
|
||||
ReverseBytes(&uniqueGUID.data1, 8);
|
||||
ReverseBytes(&uniqueGUID.data2, 8);
|
||||
ReverseBytes(&firstLBA, 8);
|
||||
ReverseBytes(&lastLBA, 8);
|
||||
ReverseBytes(&attributes, 8);
|
||||
} // GPTPart::ReverseBytes()
|
||||
|
||||
// Display summary information; does nothing if the partition is empty.
|
||||
void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
|
||||
string sizeInSI;
|
||||
int i;
|
||||
|
||||
if (firstLBA != 0) {
|
||||
sizeInSI = BytesToSI(blockSize * (lastLBA - firstLBA + 1));
|
||||
cout.width(4);
|
||||
cout << partNum + 1 << " ";
|
||||
cout.width(14);
|
||||
cout << firstLBA << " ";
|
||||
cout.width(14);
|
||||
cout << lastLBA << " ";
|
||||
cout << BytesToSI(blockSize * (lastLBA - firstLBA + 1)) << " ";
|
||||
for (i = 0; i < 9 - sizeInSI.length(); i++) cout << " ";
|
||||
cout.fill('0');
|
||||
cout.width(4);
|
||||
cout.setf(ios::uppercase);
|
||||
cout << hex << typeHelper.GUIDToID(partitionType) << " " << dec;
|
||||
cout.fill(' ');
|
||||
cout.setf(ios::right);
|
||||
cout << GetName().substr(0, 23) << "\n";
|
||||
cout.fill(' ');
|
||||
} // if
|
||||
} // GPTPart::ShowSummary()
|
||||
|
||||
// Show detailed partition information. Does nothing if the partition is
|
||||
// empty (as determined by firstLBA being 0).
|
||||
void GPTPart::ShowDetails(uint32_t blockSize) {
|
||||
uint64_t size;
|
||||
|
||||
if (firstLBA != 0) {
|
||||
cout << "Partition GUID code: " << GUIDToStr(partitionType);
|
||||
cout << " (" << typeHelper.GUIDToName(partitionType) << ")\n";
|
||||
cout << "Partition unique GUID: " << GUIDToStr(uniqueGUID) << "\n";
|
||||
|
||||
cout << "First sector: " << firstLBA << " (at "
|
||||
<< BytesToSI(firstLBA * blockSize) << ")\n";
|
||||
cout << "Last sector: " << lastLBA << " (at "
|
||||
<< BytesToSI(lastLBA * blockSize) << ")\n";
|
||||
size = (lastLBA - firstLBA + 1);
|
||||
cout << "Partition size: " << size << " sectors ("
|
||||
<< BytesToSI(size * ((uint64_t) blockSize)) << ")\n";
|
||||
cout << "Attribute flags: ";
|
||||
cout.fill('0');
|
||||
cout.width(16);
|
||||
cout << right;
|
||||
cout << hex;
|
||||
cout << attributes << "\n";
|
||||
cout << left;
|
||||
cout << dec;
|
||||
cout << "Partition name: " << GetName() << "\n";
|
||||
} // if
|
||||
} // GPTPart::ShowDetails()
|
||||
|
||||
/****************************************
|
||||
* Functions requiring user interaction *
|
||||
****************************************/
|
||||
|
||||
// Change the type code on the partition.
|
||||
void GPTPart::ChangeType(void) {
|
||||
char line[255];
|
||||
char* junk;
|
||||
int typeNum = 0xFFFF;
|
||||
GUIDData newType;
|
||||
|
||||
cout << "Current type is '" << GetNameType() << "'\n";
|
||||
while ((!typeHelper.Valid(typeNum)) && (typeNum != 0)) {
|
||||
cout << "Hex code (L to show codes, 0 to enter raw code, Enter = 0700): ";
|
||||
junk = fgets(line, 255, stdin);
|
||||
sscanf(line, "%X", &typeNum);
|
||||
if ((line[0] == 'L') || (line[0] == 'l'))
|
||||
typeHelper.ShowTypes();
|
||||
if (line[0] == '\n') {
|
||||
typeNum = 0x0700;
|
||||
} // if
|
||||
} // while
|
||||
if (typeNum != 0) // user entered a code, so convert it
|
||||
newType = typeHelper.IDToGUID((uint16_t) typeNum);
|
||||
else // user wants to enter the GUID directly, so do that
|
||||
newType = GetGUID();
|
||||
partitionType = newType;
|
||||
cout << "Changed type of partition to '" << typeHelper.GUIDToName(partitionType) << "'\n";
|
||||
} // GPTPart::ChangeType()
|
||||
|
||||
// Set the name for a partition to theName, or prompt for a name if
|
||||
// theName is empty. 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(string theName) {
|
||||
void GPTPart::SetName(const string & theName) {
|
||||
char newName[NAME_SIZE]; // New name
|
||||
char *junk;
|
||||
int i;
|
||||
@@ -256,6 +130,145 @@ void GPTPart::SetName(string theName) {
|
||||
} // for
|
||||
} // GPTPart::SetName()
|
||||
|
||||
GPTPart & GPTPart::operator=(const GPTPart & orig) {
|
||||
int i;
|
||||
|
||||
partitionType = orig.partitionType;
|
||||
uniqueGUID = orig.uniqueGUID;
|
||||
firstLBA = orig.firstLBA;
|
||||
lastLBA = orig.lastLBA;
|
||||
attributes = orig.attributes;
|
||||
for (i = 0; i < NAME_SIZE; i++)
|
||||
name[i] = orig.name[i];
|
||||
return *this;
|
||||
} // assignment operator
|
||||
|
||||
// Display summary information; does nothing if the partition is empty.
|
||||
void GPTPart::ShowSummary(int partNum, uint32_t blockSize) {
|
||||
string sizeInSI;
|
||||
int i;
|
||||
|
||||
if (firstLBA != 0) {
|
||||
sizeInSI = BytesToSI(blockSize * (lastLBA - firstLBA + 1));
|
||||
cout.width(4);
|
||||
cout << partNum + 1 << " ";
|
||||
cout.width(14);
|
||||
cout << firstLBA << " ";
|
||||
cout.width(14);
|
||||
cout << lastLBA << " ";
|
||||
cout << BytesToSI(blockSize * (lastLBA - firstLBA + 1)) << " ";
|
||||
for (i = 0; i < 9 - sizeInSI.length(); i++) cout << " ";
|
||||
cout.fill('0');
|
||||
cout.width(4);
|
||||
cout.setf(ios::uppercase);
|
||||
cout << hex << typeHelper.GUIDToID(partitionType) << " " << dec;
|
||||
cout.fill(' ');
|
||||
// cout.setf(ios::right);
|
||||
cout << GetName().substr(0, 23) << "\n";
|
||||
cout.fill(' ');
|
||||
} // if
|
||||
} // GPTPart::ShowSummary()
|
||||
|
||||
// Show detailed partition information. Does nothing if the partition is
|
||||
// empty (as determined by firstLBA being 0).
|
||||
void GPTPart::ShowDetails(uint32_t blockSize) {
|
||||
uint64_t size;
|
||||
|
||||
if (firstLBA != 0) {
|
||||
cout << "Partition GUID code: " << GUIDToStr(partitionType);
|
||||
cout << " (" << typeHelper.GUIDToName(partitionType) << ")\n";
|
||||
cout << "Partition unique GUID: " << GUIDToStr(uniqueGUID) << "\n";
|
||||
|
||||
cout << "First sector: " << firstLBA << " (at "
|
||||
<< BytesToSI(firstLBA * blockSize) << ")\n";
|
||||
cout << "Last sector: " << lastLBA << " (at "
|
||||
<< BytesToSI(lastLBA * blockSize) << ")\n";
|
||||
size = (lastLBA - firstLBA + 1);
|
||||
cout << "Partition size: " << size << " sectors ("
|
||||
<< BytesToSI(size * ((uint64_t) blockSize)) << ")\n";
|
||||
cout << "Attribute flags: ";
|
||||
cout.fill('0');
|
||||
cout.width(16);
|
||||
cout << hex;
|
||||
cout << attributes << "\n";
|
||||
cout << dec;
|
||||
cout << "Partition name: " << GetName() << "\n";
|
||||
cout.fill(' ');
|
||||
} // if
|
||||
} // GPTPart::ShowDetails()
|
||||
|
||||
// Blank (delete) a single partition
|
||||
void GPTPart::BlankPartition(void) {
|
||||
int j;
|
||||
GUIDData zeroGUID;
|
||||
|
||||
zeroGUID.data1 = 0;
|
||||
zeroGUID.data2 = 0;
|
||||
uniqueGUID = zeroGUID;
|
||||
partitionType = zeroGUID;
|
||||
firstLBA = 0;
|
||||
lastLBA = 0;
|
||||
attributes = 0;
|
||||
for (j = 0; j < NAME_SIZE; j++)
|
||||
name[j] = '\0';
|
||||
} // GPTPart::BlankPartition
|
||||
|
||||
// Returns 1 if the two partitions overlap, 0 if they don't
|
||||
int GPTPart::DoTheyOverlap(const GPTPart & other) {
|
||||
int theyDo = 0;
|
||||
|
||||
// Don't bother checking unless these are defined (both start and end points
|
||||
// are 0 for undefined partitions, so just check the start points)
|
||||
if ((firstLBA != 0) && (other.firstLBA != 0)) {
|
||||
if ((firstLBA < other.lastLBA) && (lastLBA >= other.firstLBA))
|
||||
theyDo = 1;
|
||||
if ((other.firstLBA < lastLBA) && (other.lastLBA >= firstLBA))
|
||||
theyDo = 1;
|
||||
} // if
|
||||
return (theyDo);
|
||||
} // GPTPart::DoTheyOverlap()
|
||||
|
||||
// Reverse the bytes of integral data types; used on big-endian systems.
|
||||
void GPTPart::ReversePartBytes(void) {
|
||||
ReverseBytes(&partitionType.data1, 8);
|
||||
ReverseBytes(&partitionType.data2, 8);
|
||||
ReverseBytes(&uniqueGUID.data1, 8);
|
||||
ReverseBytes(&uniqueGUID.data2, 8);
|
||||
ReverseBytes(&firstLBA, 8);
|
||||
ReverseBytes(&lastLBA, 8);
|
||||
ReverseBytes(&attributes, 8);
|
||||
} // GPTPart::ReverseBytes()
|
||||
|
||||
/****************************************
|
||||
* Functions requiring user interaction *
|
||||
****************************************/
|
||||
|
||||
// Change the type code on the partition.
|
||||
void GPTPart::ChangeType(void) {
|
||||
char line[255];
|
||||
char* junk;
|
||||
int typeNum = 0xFFFF;
|
||||
GUIDData newType;
|
||||
|
||||
cout << "Current type is '" << GetNameType() << "'\n";
|
||||
while ((!typeHelper.Valid(typeNum)) && (typeNum != 0)) {
|
||||
cout << "Hex code (L to show codes, 0 to enter raw code, Enter = 0700): ";
|
||||
junk = fgets(line, 255, stdin);
|
||||
sscanf(line, "%X", &typeNum);
|
||||
if ((line[0] == 'L') || (line[0] == 'l'))
|
||||
typeHelper.ShowTypes();
|
||||
if (line[0] == '\n') {
|
||||
typeNum = 0x0700;
|
||||
} // if
|
||||
} // while
|
||||
if (typeNum != 0) // user entered a code, so convert it
|
||||
newType = typeHelper.IDToGUID((uint16_t) typeNum);
|
||||
else // user wants to enter the GUID directly, so do that
|
||||
newType = GetGUID();
|
||||
SetType(newType);
|
||||
cout << "Changed type of partition to '" << typeHelper.GUIDToName(partitionType) << "'\n";
|
||||
} // GPTPart::ChangeType()
|
||||
|
||||
/***********************************
|
||||
* Non-class but related functions *
|
||||
***********************************/
|
||||
|
||||
@@ -62,21 +62,21 @@ class GPTPart {
|
||||
string GetName(void);
|
||||
|
||||
// Simple data assignment:
|
||||
void SetType(struct GUIDData t) {partitionType = t;}
|
||||
void SetType(uint16_t hex) {partitionType = typeHelper.IDToGUID(hex);}
|
||||
void SetType(struct GUIDData t);
|
||||
void SetType(uint16_t hex) {SetType(typeHelper.IDToGUID(hex));}
|
||||
void SetUniqueGUID(struct GUIDData u) {uniqueGUID = u;}
|
||||
void SetUniqueGUID(int zeroOrRandom);
|
||||
void SetFirstLBA(uint64_t f) {firstLBA = f;}
|
||||
void SetLastLBA(uint64_t l) {lastLBA = l;}
|
||||
void SetAttributes(uint64_t a) {attributes = a;}
|
||||
void SetName(string n);
|
||||
void SetName(const string & n);
|
||||
|
||||
// Additional functions
|
||||
GPTPart & operator=(const GPTPart & orig);
|
||||
void ShowSummary(int partNum, uint32_t blockSize); // display summary information (1-line)
|
||||
void ShowDetails(uint32_t blockSize); // display detailed information (multi-line)
|
||||
void BlankPartition(void); // empty partition of data
|
||||
int DoTheyOverlap(GPTPart* other); // returns 1 if there's overlap
|
||||
int DoTheyOverlap(const GPTPart & other); // returns 1 if there's overlap
|
||||
void ReversePartBytes(void); // reverse byte order of all integer fields
|
||||
|
||||
// Functions requiring user interaction
|
||||
|
||||
40
mbr.cc
40
mbr.cc
@@ -38,6 +38,7 @@ MBRData::MBRData(void) {
|
||||
srand((unsigned int) time(NULL));
|
||||
numHeads = MAX_HEADS;
|
||||
numSecspTrack = MAX_SECSPERTRACK;
|
||||
myDisk = NULL;
|
||||
EmptyMBR();
|
||||
} // MBRData default constructor
|
||||
|
||||
@@ -48,6 +49,7 @@ MBRData::MBRData(string filename) {
|
||||
state = invalid;
|
||||
numHeads = MAX_HEADS;
|
||||
numSecspTrack = MAX_SECSPERTRACK;
|
||||
myDisk = NULL;
|
||||
|
||||
srand((unsigned int) time(NULL));
|
||||
// Try to read the specified partition table, but if it fails....
|
||||
@@ -55,9 +57,10 @@ MBRData::MBRData(string filename) {
|
||||
EmptyMBR();
|
||||
device = "";
|
||||
} // if
|
||||
} // MBRData(char *filename) constructor
|
||||
} // MBRData(string filename) constructor
|
||||
|
||||
MBRData::~MBRData(void) {
|
||||
// delete myDisk;
|
||||
} // MBRData destructor
|
||||
|
||||
/**********************
|
||||
@@ -68,9 +71,11 @@ MBRData::~MBRData(void) {
|
||||
|
||||
// Read data from MBR. Returns 1 if read was successful (even if the
|
||||
// data isn't a valid MBR), 0 if the read failed.
|
||||
int MBRData::ReadMBRData(string deviceFilename) {
|
||||
int MBRData::ReadMBRData(const string & deviceFilename) {
|
||||
int fd, allOK = 1;
|
||||
|
||||
if (myDisk == NULL)
|
||||
myDisk = new DiskIO;
|
||||
if (myDisk->OpenForRead(deviceFilename)) {
|
||||
ReadMBRData(myDisk);
|
||||
} else {
|
||||
@@ -81,7 +86,7 @@ int MBRData::ReadMBRData(string deviceFilename) {
|
||||
device = deviceFilename;
|
||||
|
||||
return allOK;
|
||||
} // MBRData::ReadMBRData(char* deviceFilename)
|
||||
} // MBRData::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).
|
||||
@@ -93,6 +98,9 @@ void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
|
||||
int err = 1;
|
||||
TempMBR tempMBR;
|
||||
|
||||
if (myDisk != NULL)
|
||||
delete myDisk;
|
||||
|
||||
myDisk = theDisk;
|
||||
|
||||
// Empty existing MBR data, including the logical partitions...
|
||||
@@ -102,7 +110,7 @@ void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
|
||||
if (myDisk->Read(&tempMBR, 512))
|
||||
err = 0;
|
||||
if (err) {
|
||||
cerr << "Problem reading disk in MBRData::ReadMBRData!\n";
|
||||
cerr << "Problem reading disk in MBRData::ReadMBRData()!\n";
|
||||
} else {
|
||||
for (i = 0; i < 440; i++)
|
||||
code[i] = tempMBR.code[i];
|
||||
@@ -183,7 +191,7 @@ void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
|
||||
} // for
|
||||
} // if (hybrid detection code)
|
||||
} // no initial error
|
||||
} // MBRData::ReadMBRData(int fd)
|
||||
} // MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize)
|
||||
|
||||
// This is a recursive function to read all the logical partitions, following the
|
||||
// logical partition linked list from the disk and storing the basic data in the
|
||||
@@ -252,14 +260,16 @@ int MBRData::ReadLogicalPart(uint32_t extendedStart,
|
||||
// Write the MBR data to the default defined device. Note that this writes
|
||||
// ONLY the MBR itself, not the logical partition data.
|
||||
int MBRData::WriteMBRData(void) {
|
||||
int allOK = 1, fd;
|
||||
int allOK = 1;
|
||||
|
||||
if (myDisk->OpenForWrite(device) != 0) {
|
||||
allOK = WriteMBRData(myDisk);
|
||||
} else {
|
||||
allOK = 0;
|
||||
} // if/else
|
||||
myDisk->Close();
|
||||
if (myDisk != NULL) {
|
||||
if (myDisk->OpenForWrite(device) != 0) {
|
||||
allOK = WriteMBRData(myDisk);
|
||||
} else {
|
||||
allOK = 0;
|
||||
} // if/else
|
||||
myDisk->Close();
|
||||
} else allOK = 0;
|
||||
return allOK;
|
||||
} // MBRData::WriteMBRData(void)
|
||||
|
||||
@@ -322,12 +332,12 @@ int MBRData::WriteMBRData(DiskIO *theDisk) {
|
||||
} // for
|
||||
}// if
|
||||
return allOK;
|
||||
} // MBRData::WriteMBRData(DiskIO theDisk)
|
||||
} // MBRData::WriteMBRData(DiskIO *theDisk)
|
||||
|
||||
int MBRData::WriteMBRData(string deviceFilename) {
|
||||
int MBRData::WriteMBRData(const string & deviceFilename) {
|
||||
device = deviceFilename;
|
||||
return WriteMBRData();
|
||||
} // MBRData::WriteMBRData(char* deviceFilename)
|
||||
} // MBRData::WriteMBRData(const string & deviceFilename)
|
||||
|
||||
/********************************************
|
||||
* *
|
||||
|
||||
4
mbr.h
4
mbr.h
@@ -80,7 +80,7 @@ public:
|
||||
~MBRData(void);
|
||||
|
||||
// File I/O functions...
|
||||
int ReadMBRData(string deviceFilename);
|
||||
int ReadMBRData(const string & deviceFilename);
|
||||
void ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1);
|
||||
// ReadLogicalPart() returns last partition # read to logicals[] array,
|
||||
// or -1 if there was a problem....
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
int partNum);
|
||||
int WriteMBRData(void);
|
||||
int WriteMBRData(DiskIO *theDisk);
|
||||
int WriteMBRData(string deviceFilename);
|
||||
int WriteMBRData(const string & deviceFilename);
|
||||
|
||||
// Display data for user...
|
||||
void DisplayMBRData(void);
|
||||
|
||||
@@ -236,6 +236,7 @@ int PartTypes::AddType(uint16_t mbrType, uint64_t guidData1, uint64_t guidData2,
|
||||
// in an ugly way.
|
||||
void PartTypes::ShowTypes(void) {
|
||||
int colCount = 1; // column count
|
||||
int i;
|
||||
AType* thisType = allTypes;
|
||||
|
||||
cout.unsetf(ios::uppercase);
|
||||
@@ -244,17 +245,16 @@ void PartTypes::ShowTypes(void) {
|
||||
cout.fill('0');
|
||||
cout.width(4);
|
||||
cout << hex << thisType->MBRType << " ";
|
||||
cout.fill(' ');
|
||||
cout.setf(ios::left);
|
||||
cout.width(19);
|
||||
cout << ((string) thisType->name).substr(0, 19) << " ";
|
||||
for (i = 0; i < (19 - ((string) thisType->name).substr(0, 19).length()); i ++) cout << " ";
|
||||
if ((colCount % 3) == 0)
|
||||
cout << "\n";
|
||||
colCount++;
|
||||
} // if
|
||||
thisType = thisType->next;
|
||||
} // while
|
||||
cout << "\n";
|
||||
cout.fill(' ');
|
||||
cout << "\n" << dec;
|
||||
} // PartTypes::ShowTypes()
|
||||
|
||||
// Returns 1 if code is a valid extended MBR code, 0 if it's not
|
||||
@@ -323,6 +323,7 @@ struct GUIDData PartTypes::IDToGUID(uint16_t ID) {
|
||||
cout << "Exact type match not found for type code ";
|
||||
cout.width(4);
|
||||
cout << hex << ID << "; assigning type code for\n'Linux/Windows data'\n" << dec;
|
||||
cout.fill(' ');
|
||||
} // if (!found)
|
||||
return theGUID;
|
||||
} // PartTypes::IDToGUID()
|
||||
|
||||
Reference in New Issue
Block a user