New release: 0.4.0
This version adds support for FreeBSD and big-endian systems. It also adds support for BSD disklabels and an assortment of other changes, improvements, and bug fixes.
This commit is contained in:
28
CHANGELOG
28
CHANGELOG
@@ -1,6 +1,34 @@
|
|||||||
|
0.4.0:
|
||||||
|
------
|
||||||
|
|
||||||
|
- Added support for BSD disklabels. The program can now convert disks that
|
||||||
|
use "raw" disklabels, with the caveat that the first partition will
|
||||||
|
almost certainly need to be deleted because it'll overlap the main GPT
|
||||||
|
header; and convert disklabels contained within a GPT (or a former MBR,
|
||||||
|
converted to GPT) partition. In the latter case, the 'b' main menu option
|
||||||
|
is used.
|
||||||
|
|
||||||
|
- Added support for compiling on FreeBSD.
|
||||||
|
|
||||||
|
- Fixed bug that could cause crashes or incomplete sorts when sorting
|
||||||
|
the partition table.
|
||||||
|
|
||||||
|
- New partitions, including converted ones, now take on the name of the
|
||||||
|
partition type as a default name.
|
||||||
|
|
||||||
|
- Reorganized some code; created a separate C++ class for GPT partitions
|
||||||
|
(GPTPart), which replaced a struct and enabled moving code from the
|
||||||
|
bloated GPTData class into GPTPart.
|
||||||
|
|
||||||
|
- Fixed a bug that produced spurious warnings about unknown sector sizes
|
||||||
|
when loading a backup file.
|
||||||
|
|
||||||
0.3.5:
|
0.3.5:
|
||||||
------
|
------
|
||||||
|
|
||||||
|
Note: This version was not officially publicly released; I wanted to test
|
||||||
|
the big-endian support while developing 0.4.0.
|
||||||
|
|
||||||
- Tweaked the disk type identification code to warn users to re-sync their
|
- Tweaked the disk type identification code to warn users to re-sync their
|
||||||
hybrid MBRs when one is detected.
|
hybrid MBRs when one is detected.
|
||||||
|
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -3,7 +3,7 @@ CXX=g++
|
|||||||
#CFLAGS=-O2 -fpack-struct
|
#CFLAGS=-O2 -fpack-struct
|
||||||
CFLAGS=-O2 -fpack-struct -D_FILE_OFFSET_BITS=64 -g
|
CFLAGS=-O2 -fpack-struct -D_FILE_OFFSET_BITS=64 -g
|
||||||
CXXFLAGS=-O2 -fpack-struct -D_FILE_OFFSET_BITS=64 -g
|
CXXFLAGS=-O2 -fpack-struct -D_FILE_OFFSET_BITS=64 -g
|
||||||
LIB_NAMES=support crc32 mbr gpt parttypes attributes
|
LIB_NAMES=support crc32 gptpart mbr gpt bsd parttypes attributes
|
||||||
LIB_SRCS=$(NAMES:=.cc)
|
LIB_SRCS=$(NAMES:=.cc)
|
||||||
LIB_OBJS=$(LIB_NAMES:=.o)
|
LIB_OBJS=$(LIB_NAMES:=.o)
|
||||||
LIB_HEADERS=$(LIB_NAMES:=.h)
|
LIB_HEADERS=$(LIB_NAMES:=.h)
|
||||||
|
|||||||
14
README
14
README
@@ -13,6 +13,9 @@ include:
|
|||||||
* The ability to convert MBR-partitioned disks in-place to GPT format,
|
* The ability to convert MBR-partitioned disks in-place to GPT format,
|
||||||
without losing data
|
without losing data
|
||||||
|
|
||||||
|
* The ability to convert BSD disklabels in-place to create GPT
|
||||||
|
partitions, without losing data
|
||||||
|
|
||||||
* The ability to specify sector-exact partition sizes
|
* The ability to specify sector-exact partition sizes
|
||||||
|
|
||||||
* More flexible specification of filesystem type code GUIDs, which
|
* More flexible specification of filesystem type code GUIDs, which
|
||||||
@@ -27,6 +30,9 @@ include:
|
|||||||
* The MBR boot loader code is left alone (GNU Parted tends to
|
* The MBR boot loader code is left alone (GNU Parted tends to
|
||||||
wipe it out with every change)
|
wipe it out with every change)
|
||||||
|
|
||||||
|
* The ability to create a hybrid MBR, which permits GPT-unaware
|
||||||
|
OSes to access up to three GPT partitions on the disk
|
||||||
|
|
||||||
Of course, gdisk isn't without its limitations. Most notably, it lacks the
|
Of course, gdisk isn't without its limitations. Most notably, it lacks the
|
||||||
filesystem awareness and filesystem-related features of GNU Parted. You
|
filesystem awareness and filesystem-related features of GNU Parted. You
|
||||||
can't resize a partition's filesystem or create a partition with a
|
can't resize a partition's filesystem or create a partition with a
|
||||||
@@ -60,10 +66,10 @@ with >2TiB drives, though.
|
|||||||
|
|
||||||
My main development platform is a system running the 64-bit version of
|
My main development platform is a system running the 64-bit version of
|
||||||
Ubuntu 8.04. I've also tested on 64-bit OpenSuSE, 32-bit Fedora 10, 32-bit
|
Ubuntu 8.04. I've also tested on 64-bit OpenSuSE, 32-bit Fedora 10, 32-bit
|
||||||
Ubuntu 6.10, 64-bit Gentoo, 32-bit PowerPC Linux, and 32-bit Intel-based
|
Ubuntu 6.10, 64-bit Gentoo, 32-bit PowerPC Linux, 32-bit Intel-based Mac
|
||||||
Mac OS X. Problems relating to 64-bit integers on the 32-bit Linux have
|
OS X, and 64-bit Fedora 7.1. Problems relating to 64-bit integers on the
|
||||||
been common during development and may crop up in the future. The Mac OS
|
32-bit Linux have been common during development and may crop up in the
|
||||||
X and big-endian (PowerPC) support is new.
|
future. The Mac OS X, FreeBSD, and big-endian (PowerPC) support are new.
|
||||||
|
|
||||||
Redistribution
|
Redistribution
|
||||||
--------------
|
--------------
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
// Class to manage partition attribute codes. These are binary bit fields,
|
// Class to manage partition attribute codes. These are binary bit fields,
|
||||||
// of which only three are currently (2/2009) documented on Wikipedia.
|
// of which only three are currently (2/2009) documented on Wikipedia.
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
#define __STDC_CONSTANT_MACROS
|
#define __STDC_CONSTANT_MACROS
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
1
crc32.cc
1
crc32.cc
@@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
/* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab().
|
/* crc_tab[] -- this crcTable is being build by chksum_crc32GenTab().
|
||||||
* so make sure, you call it before using the other
|
* so make sure, you call it before using the other
|
||||||
|
|||||||
47
gdisk.8
47
gdisk.8
@@ -1,13 +1,15 @@
|
|||||||
.\" Copyright 2009 Roderick W. Smith (rodsmith@rodsbooks.com)
|
.\" Copyright 2009 Roderick W. Smith (rodsmith@rodsbooks.com)
|
||||||
.\" May be distributed under the GNU General Public License
|
.\" May be distributed under the GNU General Public License
|
||||||
.TH GDISK 8 "August 2009" "Linux 2.6" "GPT fdisk Manual"
|
.TH GDISK 8 "August 2009" "0.4.0" "GPT fdisk Manual"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
gdisk \- GPT partition table manipulator for Linux
|
gdisk \- GPT partition table manipulator for Linux and Unix
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.BI "gdisk "
|
.BI "gdisk "
|
||||||
[ \-l ]
|
[ \-l ]
|
||||||
.I device
|
.I device
|
||||||
|
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
|
|
||||||
Hard disks can be divided into one or more segments, known as
|
Hard disks can be divided into one or more segments, known as
|
||||||
.IR partitions .
|
.IR partitions .
|
||||||
This division is described in the
|
This division is described in the
|
||||||
@@ -110,7 +112,7 @@ program employs a user interface similar to that of Linux's
|
|||||||
but
|
but
|
||||||
.B "gdisk"
|
.B "gdisk"
|
||||||
modifies GPT partitions. It also has the capability of transforming MBR
|
modifies GPT partitions. It also has the capability of transforming MBR
|
||||||
partitions into GPT partitions. Like the original
|
partitions or BSD disklabels into GPT partitions. Like the original
|
||||||
.B fdisk
|
.B fdisk
|
||||||
program,
|
program,
|
||||||
.B gdisk
|
.B gdisk
|
||||||
@@ -120,8 +122,9 @@ save your partitions.
|
|||||||
|
|
||||||
.B gdisk
|
.B gdisk
|
||||||
is a text-mode menu-driven program for creation and manipulation of
|
is a text-mode menu-driven program for creation and manipulation of
|
||||||
partition tables. It will automatically convert an MBR partition table to
|
partition tables. It will automatically convert an MBR partition table or
|
||||||
GPT format, or will load a GPT partition table. When used with the
|
BSD disklabel stored without an MBR carrier partition to GPT format, or
|
||||||
|
will load a GPT partition table. When used with the
|
||||||
.IR "\-l"
|
.IR "\-l"
|
||||||
command-line option, the program displays the current partition table and
|
command-line option, the program displays the current partition table and
|
||||||
then exits.
|
then exits.
|
||||||
@@ -173,6 +176,13 @@ will note that
|
|||||||
.B "gdisk"
|
.B "gdisk"
|
||||||
lacks the options and limitations associated with CHS geometries.
|
lacks the options and limitations associated with CHS geometries.
|
||||||
|
|
||||||
|
For best results, you should always use an OS-specific partition table
|
||||||
|
program. For example, you should make Mac OS X partitions with the Mac OS
|
||||||
|
X Disk Utility
|
||||||
|
program and Linux partitions with the Linux
|
||||||
|
.B "gdisk"
|
||||||
|
or GNU Parted program.
|
||||||
|
|
||||||
Upon start,
|
Upon start,
|
||||||
.B gdisk
|
.B gdisk
|
||||||
attempts to identify the partition type in use on the specified disk. If it
|
attempts to identify the partition type in use on the specified disk. If it
|
||||||
@@ -180,10 +190,14 @@ finds valid GPT data,
|
|||||||
.B gdisk
|
.B gdisk
|
||||||
will use it. If
|
will use it. If
|
||||||
.B gdisk
|
.B gdisk
|
||||||
finds a valid MBR but no GPT data, it will attempt to convert the MBR into
|
finds a valid MBR or BSD disklabel but no GPT data, it will attempt to
|
||||||
GPT form. Upon exiting with the 'w' option,
|
convert the MBR or disklabel into GPT form. (BSD disklabels are likely to
|
||||||
|
have unusable first and/or final partitions because they overlap with the
|
||||||
|
GPT data structures, though.) GPT fdisk can identify, but not use data in,
|
||||||
|
Apple Partition Map (APM) disks, which are used on 680x0- and PowerPC-based
|
||||||
|
Macintoshes. Upon exiting with the 'w' option,
|
||||||
.B gdisk
|
.B gdisk
|
||||||
will then replace the MBR with a GPT.
|
will then replace the MBR or disklabel with a GPT.
|
||||||
.IR "This action is potentially dangerous!"
|
.IR "This action is potentially dangerous!"
|
||||||
Your system may become unbootable, and partition type codes may become
|
Your system may become unbootable, and partition type codes may become
|
||||||
corrupted if the disk uses unrecognized type codes. Boot problems are
|
corrupted if the disk uses unrecognized type codes. Boot problems are
|
||||||
@@ -257,13 +271,26 @@ Most interactions with
|
|||||||
occur with its interactive text-mode menus. The main menu provides the
|
occur with its interactive text-mode menus. The main menu provides the
|
||||||
following options:
|
following options:
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B b
|
||||||
|
Convert BSD partitions into GPT partitions. This option works on BSD
|
||||||
|
disklabels held within GPT (or converted MBR) partitions. Converted
|
||||||
|
partitions' type codes are likely to need manual adjustment.
|
||||||
|
.B gdisk
|
||||||
|
will attempt to convert BSD disklabels stored on the main disk when
|
||||||
|
launched, but this conversion is likely to produce first and/or last
|
||||||
|
partitions that are unusable. The many BSD variants means that the
|
||||||
|
probability of GPT fdisk being unable to convert a BSD disklabel are high
|
||||||
|
compared to the likelihood of problems with an MBR conversion.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B c
|
.B c
|
||||||
Change the GPT name of a partition. This name is encoded as a UTF-16
|
Change the GPT name of a partition. This name is encoded as a UTF-16
|
||||||
string, but
|
string, but
|
||||||
.B gdisk
|
.B gdisk
|
||||||
supports only ASCII characters as names. For the most part, Linux ignores
|
supports only ASCII characters as names. For the most part, Linux ignores
|
||||||
the partition name, but it may be important in some OSes.
|
the partition name, but it may be important in some OSes. GPT fdisk sets
|
||||||
|
a default name based on the partition type code.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B d
|
.B d
|
||||||
@@ -342,7 +369,7 @@ Sort partition entries. GPT partition numbers need not match the order of
|
|||||||
partitions on the disk. If you want them to match, you can use this option.
|
partitions on the disk. If you want them to match, you can use this option.
|
||||||
Note that some partitioning utilities, such as GNU Parted, will sort
|
Note that some partitioning utilities, such as GNU Parted, will sort
|
||||||
partitions whenever they make changes. Such changes will be reflected in
|
partitions whenever they make changes. Such changes will be reflected in
|
||||||
your Linux device filenames, so you may need to edit
|
your device filenames, so you may need to edit
|
||||||
.IR "/etc/fstab"
|
.IR "/etc/fstab"
|
||||||
if you use this option.
|
if you use this option.
|
||||||
|
|
||||||
|
|||||||
12
gdisk.cc
12
gdisk.cc
@@ -4,6 +4,9 @@
|
|||||||
//
|
//
|
||||||
// by Rod Smith, February 2009
|
// by Rod Smith, February 2009
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
//#include <iostream>
|
//#include <iostream>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -24,7 +27,7 @@ int main(int argc, char* argv[]) {
|
|||||||
int doMore = 1;
|
int doMore = 1;
|
||||||
char* device = NULL;
|
char* device = NULL;
|
||||||
|
|
||||||
printf("GPT fdisk (gdisk) version 0.3.5\n\n");
|
printf("GPT fdisk (gdisk) version 0.4.0\n\n");
|
||||||
|
|
||||||
if (argc == 2) { // basic usage
|
if (argc == 2) { // basic usage
|
||||||
if (SizesOK()) {
|
if (SizesOK()) {
|
||||||
@@ -65,9 +68,9 @@ int DoCommand(char* filename, struct GPTData* theGPT) {
|
|||||||
fgets(line, 255, stdin);
|
fgets(line, 255, stdin);
|
||||||
sscanf(line, "%c", &command);
|
sscanf(line, "%c", &command);
|
||||||
switch (command) {
|
switch (command) {
|
||||||
/* case 'b': case 'B':
|
case 'b': case 'B':
|
||||||
GetGUID();
|
theGPT->XFormDisklabel();
|
||||||
break; */
|
break;
|
||||||
case 'c': case 'C':
|
case 'c': case 'C':
|
||||||
if (theGPT->GetPartRange(&temp1, &temp2) > 0)
|
if (theGPT->GetPartRange(&temp1, &temp2) > 0)
|
||||||
theGPT->SetName(theGPT->GetPartNum());
|
theGPT->SetName(theGPT->GetPartNum());
|
||||||
@@ -125,6 +128,7 @@ int DoCommand(char* filename, struct GPTData* theGPT) {
|
|||||||
} // DoCommand()
|
} // DoCommand()
|
||||||
|
|
||||||
void ShowCommands(void) {
|
void ShowCommands(void) {
|
||||||
|
printf("b\tconvert BSD disklabel partitions\n");
|
||||||
printf("c\tchange a partition's name\n");
|
printf("c\tchange a partition's name\n");
|
||||||
printf("d\tdelete a partition\n");
|
printf("d\tdelete a partition\n");
|
||||||
printf("i\tshow detailed information on a partition\n");
|
printf("i\tshow detailed information on a partition\n");
|
||||||
|
|||||||
49
gpt.h
49
gpt.h
@@ -1,34 +1,21 @@
|
|||||||
/* gpt.h -- GPT and data structure definitions, types, and
|
/* gpt.h -- GPT and data structure definitions, types, and
|
||||||
functions */
|
functions */
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "parttypes.h"
|
#include "parttypes.h"
|
||||||
#include "mbr.h"
|
#include "mbr.h"
|
||||||
|
#include "bsd.h"
|
||||||
|
#include "gptpart.h"
|
||||||
|
|
||||||
#ifndef __GPTSTRUCTS
|
#ifndef __GPTSTRUCTS
|
||||||
#define __GPTSTRUCTS
|
#define __GPTSTRUCTS
|
||||||
|
|
||||||
#define GPT_SIGNATURE UINT64_C(0x5452415020494645)
|
|
||||||
// Signatures for Apple (APM) disks, multiplied by 0x100000000
|
|
||||||
#define APM_SIGNATURE1 UINT64_C(0x00004D5000000000)
|
|
||||||
#define APM_SIGNATURE2 UINT64_C(0x0000535400000000)
|
|
||||||
|
|
||||||
/* Number and size of GPT entries... */
|
|
||||||
#define NUM_GPT_ENTRIES 128
|
|
||||||
#define GPT_SIZE 128
|
|
||||||
/* Offset, in 512-byte sectors, for GPT table and partition data.
|
|
||||||
Note this is above two multiplied together, divided by 512, with 2
|
|
||||||
added
|
|
||||||
#define GPT_OFFSET (((NUM_GPT_ENTRIES * GPT_SIZE) / SECTOR_SIZE) + 2)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define HEADER_SIZE 92
|
|
||||||
|
|
||||||
#define GPT_RESERVED 420
|
|
||||||
#define NAME_SIZE 72
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -42,7 +29,7 @@ using namespace std;
|
|||||||
enum GPTValidity {gpt_valid, gpt_corrupt, gpt_invalid};
|
enum GPTValidity {gpt_valid, gpt_corrupt, gpt_invalid};
|
||||||
|
|
||||||
// Which set of partition data to use
|
// Which set of partition data to use
|
||||||
enum WhichToUse {use_gpt, use_mbr, use_new};
|
enum WhichToUse {use_gpt, use_mbr, use_bsd, use_new};
|
||||||
|
|
||||||
// Header (first 512 bytes) of GPT table
|
// Header (first 512 bytes) of GPT table
|
||||||
struct GPTHeader {
|
struct GPTHeader {
|
||||||
@@ -63,20 +50,11 @@ struct GPTHeader {
|
|||||||
unsigned char reserved2[GPT_RESERVED];
|
unsigned char reserved2[GPT_RESERVED];
|
||||||
}; // struct GPTHeader
|
}; // struct GPTHeader
|
||||||
|
|
||||||
struct GPTPartition {
|
|
||||||
struct GUIDData partitionType;
|
|
||||||
struct GUIDData uniqueGUID;
|
|
||||||
uint64_t firstLBA;
|
|
||||||
uint64_t lastLBA;
|
|
||||||
uint64_t attributes;
|
|
||||||
unsigned char name[NAME_SIZE];
|
|
||||||
}; // struct GPTPartition
|
|
||||||
|
|
||||||
// Data in GPT format
|
// Data in GPT format
|
||||||
class GPTData {
|
class GPTData {
|
||||||
protected:
|
protected:
|
||||||
struct GPTHeader mainHeader;
|
struct GPTHeader mainHeader;
|
||||||
struct GPTPartition *partitions;
|
struct GPTPart *partitions;
|
||||||
struct GPTHeader secondHeader;
|
struct GPTHeader secondHeader;
|
||||||
MBRData protectiveMBR;
|
MBRData protectiveMBR;
|
||||||
char device[256]; // device filename
|
char device[256]; // device filename
|
||||||
@@ -87,6 +65,8 @@ protected:
|
|||||||
int secondCrcOk;
|
int secondCrcOk;
|
||||||
int mainPartsCrcOk;
|
int mainPartsCrcOk;
|
||||||
int secondPartsCrcOk;
|
int secondPartsCrcOk;
|
||||||
|
int apmFound; // set to 1 if APM detected
|
||||||
|
int bsdFound; // set to 1 if BSD disklabel detected in MBR
|
||||||
// uint32_t units; // display units, in multiples of sectors
|
// uint32_t units; // display units, in multiples of sectors
|
||||||
PartTypes typeHelper;
|
PartTypes typeHelper;
|
||||||
public:
|
public:
|
||||||
@@ -95,6 +75,9 @@ public:
|
|||||||
~GPTData(void);
|
~GPTData(void);
|
||||||
int SetGPTSize(uint32_t numEntries);
|
int SetGPTSize(uint32_t numEntries);
|
||||||
int CheckGPTSize(void);
|
int CheckGPTSize(void);
|
||||||
|
void ShowAPMState(void);
|
||||||
|
void ShowGPTState(void);
|
||||||
|
void PartitionScan(int fd);
|
||||||
int LoadPartitions(char* deviceFilename);
|
int LoadPartitions(char* deviceFilename);
|
||||||
int ForceLoadGPTData(int fd);
|
int ForceLoadGPTData(int fd);
|
||||||
int LoadMainTable(void);
|
int LoadMainTable(void);
|
||||||
@@ -112,7 +95,9 @@ public:
|
|||||||
uint64_t FindLastAvailable(uint64_t start);
|
uint64_t FindLastAvailable(uint64_t start);
|
||||||
uint64_t FindLastInFree(uint64_t start);
|
uint64_t FindLastInFree(uint64_t start);
|
||||||
int IsFree(uint64_t sector);
|
int IsFree(uint64_t sector);
|
||||||
int XFormPartitions(MBRData* origParts);
|
int XFormPartitions(void);
|
||||||
|
int XFormDisklabel(int OnGptPart = -1);
|
||||||
|
int XFormDisklabel(BSDData* disklabel, int startPart);
|
||||||
void SortGPT(void);
|
void SortGPT(void);
|
||||||
int ClearGPTData(void);
|
int ClearGPTData(void);
|
||||||
void ChangePartType(void);
|
void ChangePartType(void);
|
||||||
@@ -135,6 +120,8 @@ public:
|
|||||||
int SaveGPTBackup(char* filename);
|
int SaveGPTBackup(char* filename);
|
||||||
int LoadGPTBackup(char* filename);
|
int LoadGPTBackup(char* filename);
|
||||||
int DestroyGPT(void); // Returns 1 if user proceeds
|
int DestroyGPT(void); // Returns 1 if user proceeds
|
||||||
|
|
||||||
|
// Endianness functions
|
||||||
void ReverseHeaderBytes(struct GPTHeader* header); // for endianness
|
void ReverseHeaderBytes(struct GPTHeader* header); // for endianness
|
||||||
void ReversePartitionBytes(); // for endianness
|
void ReversePartitionBytes(); // for endianness
|
||||||
|
|
||||||
@@ -150,8 +137,6 @@ public:
|
|||||||
|
|
||||||
// Function prototypes....
|
// Function prototypes....
|
||||||
void BlankPartition(struct GPTPartition* partition);
|
void BlankPartition(struct GPTPartition* partition);
|
||||||
//int XFormType(uint8_t oldType, struct GUIDData* newType, int partNum);
|
|
||||||
void QuickSortGPT(struct GPTPartition* partitions, int start, int finish);
|
|
||||||
int TheyOverlap(struct GPTPartition* first, struct GPTPartition* second);
|
int TheyOverlap(struct GPTPartition* first, struct GPTPartition* second);
|
||||||
void ChangeGPTType(struct GPTPartition* part);
|
void ChangeGPTType(struct GPTPartition* part);
|
||||||
int SizesOK(void);
|
int SizesOK(void);
|
||||||
|
|||||||
171
mbr.cc
171
mbr.cc
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
/* By Rod Smith, January to February, 2009 */
|
/* By Rod Smith, January to February, 2009 */
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
#define __STDC_CONSTANT_MACROS
|
#define __STDC_CONSTANT_MACROS
|
||||||
|
|
||||||
@@ -118,9 +121,10 @@ int MBRData::ReadMBRData(char* deviceFilename) {
|
|||||||
} // MBRData::ReadMBRData(char* deviceFilename)
|
} // MBRData::ReadMBRData(char* deviceFilename)
|
||||||
|
|
||||||
// Read data from MBR.
|
// Read data from MBR.
|
||||||
void MBRData::ReadMBRData(int fd) {
|
void MBRData::ReadMBRData(int fd, int checkBlockSize) {
|
||||||
int allOK = 1, i, maxLogicals = 0;
|
int allOK = 1, i, j, maxLogicals = 0;
|
||||||
int err;
|
int err;
|
||||||
|
TempMBR tempMBR;
|
||||||
|
|
||||||
// Clear logical partition array
|
// Clear logical partition array
|
||||||
for (i = 0; i < NUM_LOGICALS; i++) {
|
for (i = 0; i < NUM_LOGICALS; i++) {
|
||||||
@@ -136,39 +140,51 @@ void MBRData::ReadMBRData(int fd) {
|
|||||||
logicals[i].lengthLBA = UINT32_C(0);
|
logicals[i].lengthLBA = UINT32_C(0);
|
||||||
} // for
|
} // for
|
||||||
|
|
||||||
read(fd, code, 440);
|
err = lseek64(fd, 0, SEEK_SET);
|
||||||
read(fd, &diskSignature, 4);
|
err = read(fd, &tempMBR, 512);
|
||||||
read(fd, &nulls, 2);
|
for (i = 0; i < 440; i++)
|
||||||
read(fd, partitions, 64);
|
code[i] = tempMBR.code[i];
|
||||||
read(fd, &MBRSignature, 2);
|
diskSignature = tempMBR.diskSignature;
|
||||||
|
nulls = tempMBR.nulls;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
partitions[i].status = tempMBR.partitions[i].status;
|
||||||
|
partitions[i].partitionType = tempMBR.partitions[i].partitionType;
|
||||||
|
partitions[i].firstLBA = tempMBR.partitions[i].firstLBA;
|
||||||
|
partitions[i].lengthLBA = tempMBR.partitions[i].lengthLBA;
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
partitions[i].firstSector[j] = tempMBR.partitions[i].firstSector[j];
|
||||||
|
partitions[i].lastSector[j] = tempMBR.partitions[i].lastSector[j];
|
||||||
|
} // for j...
|
||||||
|
} // for i...
|
||||||
|
MBRSignature = tempMBR.MBRSignature;
|
||||||
|
|
||||||
// Reverse the byte order, if necessary
|
// Reverse the byte order, if necessary
|
||||||
if (IsLittleEndian() == 0) {
|
if (IsLittleEndian() == 0) {
|
||||||
ReverseBytes((char*) &diskSignature, 4);
|
ReverseBytes(&diskSignature, 4);
|
||||||
ReverseBytes((char*) &nulls, 2);
|
ReverseBytes(&nulls, 2);
|
||||||
ReverseBytes((char*) &MBRSignature, 2);
|
ReverseBytes(&MBRSignature, 2);
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
ReverseBytes((char*) &partitions[i].firstLBA, 4);
|
ReverseBytes(&partitions[i].firstLBA, 4);
|
||||||
ReverseBytes((char*) &partitions[i].lengthLBA, 4);
|
ReverseBytes(&partitions[i].lengthLBA, 4);
|
||||||
} // for
|
} // for
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
if (MBRSignature != MBR_SIGNATURE) {
|
if (MBRSignature != MBR_SIGNATURE) {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
state = invalid;
|
state = invalid;
|
||||||
fprintf(stderr, "MBR signature invalid; read 0x%04X, but should be 0x%04X\n",
|
} // if
|
||||||
(unsigned int) MBRSignature, (unsigned int) MBR_SIGNATURE);
|
|
||||||
} /* if */
|
|
||||||
|
|
||||||
// Find disk size
|
// Find disk size
|
||||||
diskSize = disksize(fd, &err);
|
diskSize = disksize(fd, &err);
|
||||||
|
|
||||||
// Find block size
|
// Find block size
|
||||||
if ((blockSize = GetBlockSize(fd)) == -1) {
|
if (checkBlockSize) {
|
||||||
blockSize = SECTOR_SIZE;
|
if ((blockSize = GetBlockSize(fd)) == -1) {
|
||||||
printf("Unable to determine sector size; assuming %lu bytes!\n",
|
blockSize = SECTOR_SIZE;
|
||||||
(unsigned long) SECTOR_SIZE);
|
printf("Unable to determine sector size; assuming %lu bytes!\n",
|
||||||
} // if
|
(unsigned long) SECTOR_SIZE);
|
||||||
|
} // if
|
||||||
|
} // if (checkBlockSize)
|
||||||
|
|
||||||
// Load logical partition data, if any is found....
|
// Load logical partition data, if any is found....
|
||||||
if (allOK) {
|
if (allOK) {
|
||||||
@@ -242,33 +258,55 @@ int MBRData::WriteMBRData(void) {
|
|||||||
// Save the MBR data to a file. Note that this function writes ONLY the
|
// Save the MBR data to a file. Note that this function writes ONLY the
|
||||||
// MBR data, not the logical partitions (if any are defined).
|
// MBR data, not the logical partitions (if any are defined).
|
||||||
void MBRData::WriteMBRData(int fd) {
|
void MBRData::WriteMBRData(int fd) {
|
||||||
int i;
|
int i, j;
|
||||||
|
TempMBR tempMBR;
|
||||||
|
|
||||||
// Reverse the byte order, if necessary
|
// Reverse the byte order, if necessary
|
||||||
if (IsLittleEndian() == 0) {
|
if (IsLittleEndian() == 0) {
|
||||||
ReverseBytes((char*) &diskSignature, 4);
|
ReverseBytes(&diskSignature, 4);
|
||||||
ReverseBytes((char*) &nulls, 2);
|
ReverseBytes(&nulls, 2);
|
||||||
ReverseBytes((char*) &MBRSignature, 2);
|
ReverseBytes(&MBRSignature, 2);
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
ReverseBytes((char*) &partitions[i].firstLBA, 4);
|
ReverseBytes(&partitions[i].firstLBA, 4);
|
||||||
ReverseBytes((char*) &partitions[i].lengthLBA, 4);
|
ReverseBytes(&partitions[i].lengthLBA, 4);
|
||||||
} // for
|
} // for
|
||||||
} // if
|
} // if
|
||||||
|
|
||||||
write(fd, code, 440);
|
// Copy MBR data to a 512-byte data structure for writing, to
|
||||||
|
// work around a FreeBSD limitation....
|
||||||
|
for (i = 0; i < 440; i++)
|
||||||
|
tempMBR.code[i] = code[i];
|
||||||
|
tempMBR.diskSignature = diskSignature;
|
||||||
|
tempMBR.nulls = nulls;
|
||||||
|
tempMBR.MBRSignature = MBRSignature;
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
tempMBR.partitions[i].status = partitions[i].status;
|
||||||
|
tempMBR.partitions[i].partitionType = partitions[i].partitionType;
|
||||||
|
tempMBR.partitions[i].firstLBA = partitions[i].firstLBA;
|
||||||
|
tempMBR.partitions[i].lengthLBA = partitions[i].lengthLBA;
|
||||||
|
for (j = 0; j < 3; j++) {
|
||||||
|
tempMBR.partitions[i].firstSector[j] = partitions[i].firstSector[j];
|
||||||
|
tempMBR.partitions[i].lastSector[j] = partitions[i].lastSector[j];
|
||||||
|
} // for j...
|
||||||
|
} // for i...
|
||||||
|
|
||||||
|
// Now write that data structure...
|
||||||
|
write(fd, &tempMBR, 512);
|
||||||
|
|
||||||
|
/* write(fd, code, 440);
|
||||||
write(fd, &diskSignature, 4);
|
write(fd, &diskSignature, 4);
|
||||||
write(fd, &nulls, 2);
|
write(fd, &nulls, 2);
|
||||||
write(fd, partitions, 64);
|
write(fd, partitions, 64);
|
||||||
write(fd, &MBRSignature, 2);
|
write(fd, &MBRSignature, 2); */
|
||||||
|
|
||||||
// Reverse the byte order, if necessary
|
// Reverse the byte order back, if necessary
|
||||||
if (IsLittleEndian() == 0) {
|
if (IsLittleEndian() == 0) {
|
||||||
ReverseBytes((char*) &diskSignature, 4);
|
ReverseBytes(&diskSignature, 4);
|
||||||
ReverseBytes((char*) &nulls, 2);
|
ReverseBytes(&nulls, 2);
|
||||||
ReverseBytes((char*) &MBRSignature, 2);
|
ReverseBytes(&MBRSignature, 2);
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
ReverseBytes((char*) &partitions[i].firstLBA, 4);
|
ReverseBytes(&partitions[i].firstLBA, 4);
|
||||||
ReverseBytes((char*) &partitions[i].lengthLBA, 4);
|
ReverseBytes(&partitions[i].lengthLBA, 4);
|
||||||
} // for
|
} // for
|
||||||
}// if
|
}// if
|
||||||
} // MBRData::WriteMBRData(int fd)
|
} // MBRData::WriteMBRData(int fd)
|
||||||
@@ -293,11 +331,11 @@ int MBRData::ReadLogicalPart(int fd, uint32_t extendedStart,
|
|||||||
(unsigned long) offset);
|
(unsigned long) offset);
|
||||||
partNum = -1;
|
partNum = -1;
|
||||||
} else if (IsLittleEndian() != 1) { // Reverse byte ordering of some data....
|
} else if (IsLittleEndian() != 1) { // Reverse byte ordering of some data....
|
||||||
ReverseBytes((char*) &ebr.MBRSignature, 2);
|
ReverseBytes(&ebr.MBRSignature, 2);
|
||||||
ReverseBytes((char*) &ebr.partitions[0].firstLBA, 4);
|
ReverseBytes(&ebr.partitions[0].firstLBA, 4);
|
||||||
ReverseBytes((char*) &ebr.partitions[0].lengthLBA, 4);
|
ReverseBytes(&ebr.partitions[0].lengthLBA, 4);
|
||||||
ReverseBytes((char*) &ebr.partitions[1].firstLBA, 4);
|
ReverseBytes(&ebr.partitions[1].firstLBA, 4);
|
||||||
ReverseBytes((char*) &ebr.partitions[1].lengthLBA, 4);
|
ReverseBytes(&ebr.partitions[1].lengthLBA, 4);
|
||||||
} // if/else/if
|
} // if/else/if
|
||||||
|
|
||||||
if (ebr.MBRSignature != MBR_SIGNATURE) {
|
if (ebr.MBRSignature != MBR_SIGNATURE) {
|
||||||
@@ -356,14 +394,19 @@ void MBRData::DisplayMBRData(void) {
|
|||||||
BytesToSI(diskSize * (uint64_t) blockSize, tempStr));
|
BytesToSI(diskSize * (uint64_t) blockSize, tempStr));
|
||||||
} // MBRData::DisplayMBRData()
|
} // MBRData::DisplayMBRData()
|
||||||
|
|
||||||
// Create a protective MBR
|
// Create a protective MBR. Clears the boot loader area if clearBoot > 0.
|
||||||
void MBRData::MakeProtectiveMBR(void) {
|
void MBRData::MakeProtectiveMBR(int clearBoot) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Initialize variables
|
// Initialize variables
|
||||||
nulls = 0;
|
nulls = 0;
|
||||||
MBRSignature = MBR_SIGNATURE;
|
MBRSignature = MBR_SIGNATURE;
|
||||||
|
|
||||||
|
if (clearBoot > 0) {
|
||||||
|
for (i = 0; i < 440; i++)
|
||||||
|
code[i] = (uint8_t) 0;
|
||||||
|
} // if
|
||||||
|
|
||||||
partitions[0].status = UINT8_C(0); // Flag the protective part. as unbootable
|
partitions[0].status = UINT8_C(0); // Flag the protective part. as unbootable
|
||||||
|
|
||||||
// Write CHS data. This maxes out the use of the disk, as much as
|
// Write CHS data. This maxes out the use of the disk, as much as
|
||||||
@@ -467,23 +510,24 @@ struct MBRRecord* MBRData::GetPartition(int i) {
|
|||||||
return thePart;
|
return thePart;
|
||||||
} // GetPartition()
|
} // GetPartition()
|
||||||
|
|
||||||
// Displays the state, as a word, on stdout. Used for debugging
|
// Displays the state, as a word, on stdout. Used for debugging & to
|
||||||
|
// tell the user about the MBR state when the program launches....
|
||||||
void MBRData::ShowState(void) {
|
void MBRData::ShowState(void) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case invalid:
|
case invalid:
|
||||||
printf("invalid");
|
printf(" MBR: not present\n");
|
||||||
break;
|
break;
|
||||||
case gpt:
|
case gpt:
|
||||||
printf("gpt");
|
printf(" MBR: protective\n");
|
||||||
break;
|
break;
|
||||||
case hybrid:
|
case hybrid:
|
||||||
printf("hybrid");
|
printf(" MBR: hybrid\n");
|
||||||
break;
|
break;
|
||||||
case mbr:
|
case mbr:
|
||||||
printf("mbr");
|
printf(" MBR: MBR only\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unknown -- bug!");
|
printf("\a MBR: unknown -- bug!\n");
|
||||||
break;
|
break;
|
||||||
} // switch
|
} // switch
|
||||||
} // MBRData::ShowState()
|
} // MBRData::ShowState()
|
||||||
@@ -602,3 +646,36 @@ uint32_t MBRData::GetLength(int i) {
|
|||||||
retval = UINT32_C(0);
|
retval = UINT32_C(0);
|
||||||
return retval;
|
return retval;
|
||||||
} // MBRData::GetLength()
|
} // MBRData::GetLength()
|
||||||
|
|
||||||
|
// Return the MBR data as a GPT partition....
|
||||||
|
GPTPart MBRData::AsGPT(int i) {
|
||||||
|
MBRRecord* origPart;
|
||||||
|
GPTPart newPart;
|
||||||
|
uint8_t origType;
|
||||||
|
uint64_t firstSector, lastSector;
|
||||||
|
char tempStr[NAME_SIZE];
|
||||||
|
|
||||||
|
newPart.BlankPartition();
|
||||||
|
origPart = GetPartition(i);
|
||||||
|
if (origPart != NULL) {
|
||||||
|
origType = origPart->partitionType;
|
||||||
|
|
||||||
|
// don't convert extended, hybrid protective, or null (non-existent)
|
||||||
|
// partitions (Note similar protection is in GPTData::XFormPartitions(),
|
||||||
|
// but I want it here too in case I call this function in another
|
||||||
|
// context in the future....)
|
||||||
|
if ((origType != 0x05) && (origType != 0x0f) && (origType != 0x85) &&
|
||||||
|
(origType != 0x00) && (origType != 0xEE)) {
|
||||||
|
firstSector = (uint64_t) origPart->firstLBA;
|
||||||
|
newPart.SetFirstLBA(firstSector);
|
||||||
|
lastSector = firstSector + (uint64_t) origPart->lengthLBA;
|
||||||
|
if (lastSector > 0) lastSector--;
|
||||||
|
newPart.SetLastLBA(lastSector);
|
||||||
|
newPart.SetType(((uint16_t) origType) * 0x0100);
|
||||||
|
newPart.SetUniqueGUID(1);
|
||||||
|
newPart.SetAttributes(0);
|
||||||
|
newPart.SetName((unsigned char*) newPart.GetNameType(tempStr));
|
||||||
|
} // if
|
||||||
|
} // if
|
||||||
|
return newPart;
|
||||||
|
} // MBRData::AsGPT()
|
||||||
|
|||||||
21
mbr.h
21
mbr.h
@@ -1,8 +1,12 @@
|
|||||||
/* mbr.h -- MBR data structure definitions, types, and functions */
|
/* mbr.h -- MBR data structure definitions, types, and functions */
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include "gptpart.h"
|
||||||
|
|
||||||
#ifndef __MBRSTRUCTS
|
#ifndef __MBRSTRUCTS
|
||||||
#define __MBRSTRUCTS
|
#define __MBRSTRUCTS
|
||||||
@@ -32,6 +36,17 @@ struct MBRRecord {
|
|||||||
uint32_t lengthLBA;
|
uint32_t lengthLBA;
|
||||||
}; // struct MBRRecord
|
}; // struct MBRRecord
|
||||||
|
|
||||||
|
// Create a 512-byte data structure into which the MBR can be loaded in one
|
||||||
|
// go, for the benefit of FreeBSD which seems to flake out when loading
|
||||||
|
// from block devices in multiples other than the block size....
|
||||||
|
struct TempMBR {
|
||||||
|
uint8_t code[440];
|
||||||
|
uint32_t diskSignature;
|
||||||
|
uint16_t nulls;
|
||||||
|
struct MBRRecord partitions[4];
|
||||||
|
uint16_t MBRSignature;
|
||||||
|
}; // struct TempMBR
|
||||||
|
|
||||||
// Extended Boot Record (EBR) data, used to hold one logical partition's
|
// Extended Boot Record (EBR) data, used to hold one logical partition's
|
||||||
// data within an extended partition. Includes pointer to next record for
|
// data within an extended partition. Includes pointer to next record for
|
||||||
// in-memory linked-list access. This is similar to MBRData, but with a
|
// in-memory linked-list access. This is similar to MBRData, but with a
|
||||||
@@ -75,7 +90,7 @@ public:
|
|||||||
void EmptyMBR(int clearBootloader = 1);
|
void EmptyMBR(int clearBootloader = 1);
|
||||||
void SetDiskSize(uint64_t ds) {diskSize = ds;}
|
void SetDiskSize(uint64_t ds) {diskSize = ds;}
|
||||||
int ReadMBRData(char* deviceFilename);
|
int ReadMBRData(char* deviceFilename);
|
||||||
void ReadMBRData(int fd);
|
void ReadMBRData(int fd, int checkBlockSize = 1);
|
||||||
int WriteMBRData(void);
|
int WriteMBRData(void);
|
||||||
void WriteMBRData(int fd);
|
void WriteMBRData(int fd);
|
||||||
// ReadLogicalPart() returns last partition # read to logicals[] array,
|
// ReadLogicalPart() returns last partition # read to logicals[] array,
|
||||||
@@ -83,8 +98,9 @@ public:
|
|||||||
int ReadLogicalPart(int fd, uint32_t extendedStart, uint32_t diskOffset,
|
int ReadLogicalPart(int fd, uint32_t extendedStart, uint32_t diskOffset,
|
||||||
int partNum);
|
int partNum);
|
||||||
void DisplayMBRData(void);
|
void DisplayMBRData(void);
|
||||||
void MakeProtectiveMBR(void);
|
void MakeProtectiveMBR(int clearBoot = 0);
|
||||||
MBRValidity GetValidity(void) {return state;}
|
MBRValidity GetValidity(void) {return state;}
|
||||||
|
void ShowValidity(void);
|
||||||
void ShowState(void);
|
void ShowState(void);
|
||||||
void MakePart(int num, uint32_t startLBA, uint32_t lengthLBA, int type = 0x07,
|
void MakePart(int num, uint32_t startLBA, uint32_t lengthLBA, int type = 0x07,
|
||||||
int bootable = 0);
|
int bootable = 0);
|
||||||
@@ -99,6 +115,7 @@ public:
|
|||||||
uint8_t GetType(int i);
|
uint8_t GetType(int i);
|
||||||
uint32_t GetFirstSector(int i);
|
uint32_t GetFirstSector(int i);
|
||||||
uint32_t GetLength(int i);
|
uint32_t GetLength(int i);
|
||||||
|
GPTPart AsGPT(int i);
|
||||||
}; // struct MBRData
|
}; // struct MBRData
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
// Class to manage partition type codes -- a slight variant on MBR type
|
// Class to manage partition type codes -- a slight variant on MBR type
|
||||||
// codes, GUID type codes, and associated names.
|
// codes, GUID type codes, and associated names.
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
#define __STDC_CONSTANT_MACROS
|
#define __STDC_CONSTANT_MACROS
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
22
support.cc
22
support.cc
@@ -3,6 +3,9 @@
|
|||||||
// Primarily by Rod Smith, February 2009, but with a few functions
|
// Primarily by Rod Smith, February 2009, but with a few functions
|
||||||
// copied from other sources (see attributions below).
|
// copied from other sources (see attributions below).
|
||||||
|
|
||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#define __STDC_LIMIT_MACROS
|
#define __STDC_LIMIT_MACROS
|
||||||
#define __STDC_CONSTANT_MACROS
|
#define __STDC_CONSTANT_MACROS
|
||||||
|
|
||||||
@@ -176,8 +179,12 @@ int GetBlockSize(int fd) {
|
|||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
err = ioctl(fd, DKIOCGETBLOCKSIZE, &result);
|
err = ioctl(fd, DKIOCGETBLOCKSIZE, &result);
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
err = ioctl(fd, DIOCGSECTORSIZE, &result);
|
||||||
#else
|
#else
|
||||||
err = ioctl(fd, BLKSSZGET, &result);
|
err = ioctl(fd, BLKSSZGET, &result);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (result != 512) {
|
if (result != 512) {
|
||||||
@@ -319,15 +326,17 @@ int IsLittleEndian(void) {
|
|||||||
} // IsLittleEndian()
|
} // IsLittleEndian()
|
||||||
|
|
||||||
// Reverse the byte order of theValue; numBytes is number of bytes
|
// Reverse the byte order of theValue; numBytes is number of bytes
|
||||||
void ReverseBytes(char* theValue, int numBytes) {
|
void ReverseBytes(void* theValue, int numBytes) {
|
||||||
|
char* origValue;
|
||||||
char* tempValue;
|
char* tempValue;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
origValue = (char*) theValue;
|
||||||
tempValue = (char*) malloc(numBytes);
|
tempValue = (char*) malloc(numBytes);
|
||||||
for (i = 0; i < numBytes; i++)
|
for (i = 0; i < numBytes; i++)
|
||||||
tempValue[i] = theValue[i];
|
tempValue[i] = origValue[i];
|
||||||
for (i = 0; i < numBytes; i++)
|
for (i = 0; i < numBytes; i++)
|
||||||
theValue[i] = tempValue[numBytes - i - 1];
|
origValue[i] = tempValue[numBytes - i - 1];
|
||||||
free(tempValue);
|
free(tempValue);
|
||||||
} // ReverseBytes()
|
} // ReverseBytes()
|
||||||
|
|
||||||
@@ -345,6 +354,7 @@ uint64_t PowerOf2(int value) {
|
|||||||
return retval;
|
return retval;
|
||||||
} // PowerOf2()
|
} // PowerOf2()
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************************
|
/**************************************************************************************
|
||||||
* *
|
* *
|
||||||
* Below functions are lifted from various sources, as documented in comments before *
|
* Below functions are lifted from various sources, as documented in comments before *
|
||||||
@@ -366,6 +376,11 @@ uint64_t disksize(int fd, int *err) {
|
|||||||
// 32/64-bit issues on MacOS....
|
// 32/64-bit issues on MacOS....
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
*err = ioctl(fd, DKIOCGETBLOCKCOUNT, §ors);
|
*err = ioctl(fd, DKIOCGETBLOCKCOUNT, §ors);
|
||||||
|
#else
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
*err = ioctl(fd, DIOCGMEDIASIZE, &sz);
|
||||||
|
b = GetBlockSize(fd);
|
||||||
|
sectors = sz / b;
|
||||||
#else
|
#else
|
||||||
*err = ioctl(fd, BLKGETSIZE, &sz);
|
*err = ioctl(fd, BLKGETSIZE, &sz);
|
||||||
if (*err) {
|
if (*err) {
|
||||||
@@ -378,6 +393,7 @@ uint64_t disksize(int fd, int *err) {
|
|||||||
sectors = sz;
|
sectors = sz;
|
||||||
else
|
else
|
||||||
sectors = (b >> 9);
|
sectors = (b >> 9);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return sectors;
|
return sectors;
|
||||||
}
|
}
|
||||||
|
|||||||
24
support.h
24
support.h
@@ -1,8 +1,11 @@
|
|||||||
|
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
|
||||||
|
under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#if defined (__FreeBSD__) || defined (__APPLE__)
|
||||||
// Darwin (Mac OS) only: disk IOCTLs are different, and there is no lseek64
|
// Darwin (Mac OS) only: disk IOCTLs are different, and there is no lseek64
|
||||||
// This used to use __DARWIN_UNIX03 rather than __APPLE__, but __APPLE__
|
// This used to use __DARWIN_UNIX03 rather than __APPLE__, but __APPLE__
|
||||||
// is more general. If the code fails to work on older versions of OS X/
|
// is more general. If the code fails to work on older versions of OS X/
|
||||||
@@ -23,6 +26,23 @@
|
|||||||
// Set this as a default
|
// Set this as a default
|
||||||
#define SECTOR_SIZE UINT32_C(512)
|
#define SECTOR_SIZE UINT32_C(512)
|
||||||
|
|
||||||
|
// Signatures for Apple (APM) disks, multiplied by 0x100000000
|
||||||
|
#define APM_SIGNATURE1 UINT64_C(0x00004D5000000000)
|
||||||
|
#define APM_SIGNATURE2 UINT64_C(0x0000535400000000)
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
* Some GPT constants.... *
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
#define GPT_SIGNATURE UINT64_C(0x5452415020494645)
|
||||||
|
|
||||||
|
// Number and size of GPT entries...
|
||||||
|
#define NUM_GPT_ENTRIES 128
|
||||||
|
#define GPT_SIZE 128
|
||||||
|
#define HEADER_SIZE 92
|
||||||
|
#define GPT_RESERVED 420
|
||||||
|
#define NAME_SIZE 72
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// a GUID
|
// a GUID
|
||||||
@@ -39,7 +59,7 @@ int GetBlockSize(int fd);
|
|||||||
char* GUIDToStr(struct GUIDData theGUID, char* theString);
|
char* GUIDToStr(struct GUIDData theGUID, char* theString);
|
||||||
GUIDData GetGUID(void);
|
GUIDData GetGUID(void);
|
||||||
int IsLittleEndian(void); // Returns 1 if CPU is little-endian, 0 if it's big-endian
|
int IsLittleEndian(void); // Returns 1 if CPU is little-endian, 0 if it's big-endian
|
||||||
void ReverseBytes(char* theValue, int numBytes); // Reverses byte-order of theValue
|
void ReverseBytes(void* theValue, int numBytes); // Reverses byte-order of theValue
|
||||||
uint64_t PowerOf2(int value);
|
uint64_t PowerOf2(int value);
|
||||||
|
|
||||||
uint64_t disksize(int fd, int* err);
|
uint64_t disksize(int fd, int* err);
|
||||||
|
|||||||
Reference in New Issue
Block a user