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