Changes to sector alignment policies and behavior when restoring a
backup fails
This commit is contained in:
19
CHANGELOG
19
CHANGELOG
@@ -1,3 +1,22 @@
|
|||||||
|
0.6.6 (?/?/2010):
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
- More alignment changes: GPT fdisk now attempts to determine the
|
||||||
|
alignment value based on alignment of current partitions, if any are
|
||||||
|
defined. If no partitions are defined, a default value of 2048 is
|
||||||
|
set. If the computed value is less than 8 on drives over about 596GiB,
|
||||||
|
it's reset to 8, since the drive might be a WD Advanced Format unit
|
||||||
|
that requires an 8-sector (or larger power-of-2) alignment value
|
||||||
|
for proper functioning. The 2048-sector default provides better
|
||||||
|
alignment in some RAID configurations.
|
||||||
|
|
||||||
|
- Changed behavior when a backup restore fails. Previously, GPT fdisk
|
||||||
|
would create a fresh blank set of partitions. Now it does so only
|
||||||
|
if the failure occurs when interpreting the backup's contents; if the
|
||||||
|
user typed the wrong filename, the in-memory data structures aren't
|
||||||
|
touched.
|
||||||
|
|
||||||
|
|
||||||
0.6.5 (3/7/2010):
|
0.6.5 (3/7/2010):
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ void Attributes::ChangeAttributes(void) {
|
|||||||
do {
|
do {
|
||||||
response = GetNumber(0, 64, -1, (string) "Toggle which attribute field (0-63, 64 to exit): ");
|
response = GetNumber(0, 64, -1, (string) "Toggle which attribute field (0-63, 64 to exit): ");
|
||||||
if (response != 64) {
|
if (response != 64) {
|
||||||
bitValue = PowerOf2(NUM_ATR - response - 1); // Find the integer value of the bit
|
bitValue = PowerOf2(uint32_t (NUM_ATR - response - 1)); // Find the integer value of the bit
|
||||||
if ((bitValue & attributes) == bitValue) { // bit is set
|
if ((bitValue & attributes) == bitValue) { // bit is set
|
||||||
attributes -= bitValue; // so unset it
|
attributes -= bitValue; // so unset it
|
||||||
cout << "Have disabled the '" << atNames[response] << "' attribute.\n";
|
cout << "Have disabled the '" << atNames[response] << "' attribute.\n";
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "diskio.h"
|
#include "diskio.h"
|
||||||
|
#include "gpt.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
@@ -93,11 +94,12 @@ int DiskIO::OpenForWrite(const string & filename) {
|
|||||||
// returns 1-sector alignment for unusual sector sizes and drives smaller than
|
// returns 1-sector alignment for unusual sector sizes and drives smaller than
|
||||||
// a size defined by SMALLEST_ADVANCED_FORMAT, and 8-sector alignment for
|
// a size defined by SMALLEST_ADVANCED_FORMAT, and 8-sector alignment for
|
||||||
// larger drives with 512-byte sectors.
|
// larger drives with 512-byte sectors.
|
||||||
int DiskIO::FindAlignment(void) {
|
uint32_t DiskIO::FindAlignment(void) {
|
||||||
int err, result;
|
int err;
|
||||||
|
uint32_t result;
|
||||||
|
|
||||||
if ((GetBlockSize() == 512) && (DiskSize(&err) >= SMALLEST_ADVANCED_FORMAT)) {
|
if ((GetBlockSize() == 512) && (DiskSize(&err) >= SMALLEST_ADVANCED_FORMAT)) {
|
||||||
result = 8; // play it safe; align for 4096-byte sectors
|
result = DEFAULT_ALIGNMENT; // play it safe; align for 4096-byte sectors
|
||||||
} else {
|
} else {
|
||||||
result = 1; // unusual sector size; assume it's the real physical size
|
result = 1; // unusual sector size; assume it's the real physical size
|
||||||
} // if/else
|
} // if/else
|
||||||
|
|||||||
6
diskio.h
6
diskio.h
@@ -35,10 +35,6 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Below constant corresponds to an 800GB disk -- a somewhat arbitrary
|
|
||||||
// cutoff
|
|
||||||
#define SMALLEST_ADVANCED_FORMAT UINT64_C(1677721600)
|
|
||||||
|
|
||||||
/***************************************
|
/***************************************
|
||||||
* *
|
* *
|
||||||
* DiskIO class and related structures *
|
* DiskIO class and related structures *
|
||||||
@@ -71,7 +67,7 @@ class DiskIO {
|
|||||||
int Write(void* buffer, int numBytes);
|
int Write(void* buffer, int numBytes);
|
||||||
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);
|
uint32_t FindAlignment(void);
|
||||||
int FindAlignment(const 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;}
|
||||||
|
|||||||
2
gdisk.8
2
gdisk.8
@@ -458,7 +458,7 @@ 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 1 on disks
|
sectors per physical sector with this option. The default is 1 on disks
|
||||||
smaller than 800GB and 8 on larger disks.
|
smaller than 596 GiB and 8 on larger disks with 512\-byte logical sectors.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B m
|
.B m
|
||||||
|
|||||||
7
gdisk.cc
7
gdisk.cc
@@ -318,6 +318,7 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
|
|||||||
uint32_t pn, temp1, temp2;
|
uint32_t pn, temp1, temp2;
|
||||||
int goOn = 1;
|
int goOn = 1;
|
||||||
GUIDData aGUID;
|
GUIDData aGUID;
|
||||||
|
ostringstream prompt;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cout << "\nExpert command (? for help): ";
|
cout << "\nExpert command (? for help): ";
|
||||||
@@ -355,8 +356,10 @@ void ExpertsMenu(string filename, GPTDataTextUI* theGPT) {
|
|||||||
theGPT->ShowDetails();
|
theGPT->ShowDetails();
|
||||||
break;
|
break;
|
||||||
case 'l': case 'L':
|
case 'l': case 'L':
|
||||||
temp1 = GetNumber(1, 128, 8, (string)
|
prompt.seekp(0);
|
||||||
"Enter the sector alignment value (1-128, default = 8): ");
|
prompt << "Enter the sector alignment value (1-" << MAX_ALIGNMENT << ", default = "
|
||||||
|
<< DEFAULT_ALIGNMENT << "): ";
|
||||||
|
temp1 = GetNumber(1, MAX_ALIGNMENT, DEFAULT_ALIGNMENT, prompt.str());
|
||||||
theGPT->SetAlignment(temp1);
|
theGPT->SetAlignment(temp1);
|
||||||
break;
|
break;
|
||||||
case 'm': case 'M':
|
case 'm': case 'M':
|
||||||
|
|||||||
68
gpt.cc
68
gpt.cc
@@ -14,6 +14,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -641,6 +642,7 @@ int GPTData::LoadPartitions(const string & deviceFilename) {
|
|||||||
if (allOK)
|
if (allOK)
|
||||||
CheckGPTSize();
|
CheckGPTSize();
|
||||||
myDisk.Close();
|
myDisk.Close();
|
||||||
|
ComputeAlignment();
|
||||||
} else {
|
} else {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
} // if/else
|
} // if/else
|
||||||
@@ -1116,20 +1118,20 @@ int GPTData::LoadGPTBackup(const string & filename) {
|
|||||||
if (!LoadPartitionTable(mainHeader, backupFile, (uint64_t) (3 - shortBackup)))
|
if (!LoadPartitionTable(mainHeader, backupFile, (uint64_t) (3 - shortBackup)))
|
||||||
cerr << "Warning! Read error " << errno
|
cerr << "Warning! Read error " << errno
|
||||||
<< " loading partition table; strange behavior now likely!\n";
|
<< " loading partition table; strange behavior now likely!\n";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
} // if/else
|
} // if/else
|
||||||
|
// Something went badly wrong, so blank out partitions
|
||||||
|
if (allOK == 0) {
|
||||||
|
cerr << "Improper backup file! Clearing all partition data!\n";
|
||||||
|
ClearGPTData();
|
||||||
|
protectiveMBR.MakeProtectiveMBR();
|
||||||
|
} // if
|
||||||
} else {
|
} else {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
cerr << "Unable to open file " << filename << " for reading! Aborting!\n";
|
cerr << "Unable to open file " << filename << " for reading! Aborting!\n";
|
||||||
} // if/else
|
} // if/else
|
||||||
|
|
||||||
// Something went badly wrong, so blank out partitions
|
|
||||||
if (allOK == 0) {
|
|
||||||
ClearGPTData();
|
|
||||||
protectiveMBR.MakeProtectiveMBR();
|
|
||||||
} // if
|
|
||||||
return allOK;
|
return allOK;
|
||||||
} // GPTData::LoadGPTBackup()
|
} // GPTData::LoadGPTBackup()
|
||||||
|
|
||||||
@@ -2123,6 +2125,60 @@ int GPTData::IsFreePartNum(uint32_t partNum) {
|
|||||||
return retval;
|
return retval;
|
||||||
} // GPTData::IsFreePartNum()
|
} // GPTData::IsFreePartNum()
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************
|
||||||
|
* *
|
||||||
|
* Change how functions work or return information on them *
|
||||||
|
* *
|
||||||
|
***********************************************************/
|
||||||
|
|
||||||
|
// Set partition alignment value; partitions will begin on multiples of
|
||||||
|
// the specified value
|
||||||
|
void GPTData::SetAlignment(uint32_t n) {
|
||||||
|
uint32_t l2;
|
||||||
|
|
||||||
|
sectorAlignment = n;
|
||||||
|
l2 = (uint32_t) log2(n);
|
||||||
|
if (PowerOf2(l2) != n)
|
||||||
|
cout << "Information: Your alignment value is not a power of 2.\n";
|
||||||
|
} // GPTData::SetAlignment()
|
||||||
|
|
||||||
|
// Compute sector alignment based on the current partitions (if any). Each
|
||||||
|
// partition's starting LBA is examined, and if it's divisible by a power-of-2
|
||||||
|
// value less than the maximum found so far (or 2^31 for the first partition
|
||||||
|
// found), then the alignment value is adjusted down. If the computed
|
||||||
|
// alignment is less than 8 and the disk is bigger than SMALLEST_ADVANCED_FORMAT,
|
||||||
|
// resets it to 8. This is a safety measure for WD Advanced Format and
|
||||||
|
// similar drives. If no partitions are defined, the alignment value is set
|
||||||
|
// to DEFAULT_ALIGNMENT (2048). The result is that new drives are aligned to
|
||||||
|
// 2048-sector multiples but the program won't complain about other alignments
|
||||||
|
// on existing disks unless a smaller-than-8 alignment is used on small disks
|
||||||
|
// (as safety for WD Advanced Format drives).
|
||||||
|
// Returns the computed alignment value.
|
||||||
|
uint32_t GPTData::ComputeAlignment(void) {
|
||||||
|
uint32_t i = 0, found, exponent = 31;
|
||||||
|
uint64_t align = DEFAULT_ALIGNMENT;
|
||||||
|
|
||||||
|
for (i = 0; i < mainHeader.numParts; i++) {
|
||||||
|
if (partitions[i].IsUsed()) {
|
||||||
|
found = 0;
|
||||||
|
while (!found) {
|
||||||
|
align = PowerOf2(exponent);
|
||||||
|
if ((partitions[i].GetFirstLBA() % align) == 0) {
|
||||||
|
found = 1;
|
||||||
|
} else {
|
||||||
|
exponent--;
|
||||||
|
} // if/else
|
||||||
|
} // while
|
||||||
|
} // if
|
||||||
|
} // for
|
||||||
|
if ((align < 8) && (diskSize >= SMALLEST_ADVANCED_FORMAT))
|
||||||
|
align = 8;
|
||||||
|
// cout << "Setting alignment to " << align << "\n";
|
||||||
|
SetAlignment(align);
|
||||||
|
return align;
|
||||||
|
} // GPTData::ComputeAlignment()
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
* *
|
* *
|
||||||
* Endianness support functions *
|
* Endianness support functions *
|
||||||
|
|||||||
19
gpt.h
19
gpt.h
@@ -16,7 +16,7 @@
|
|||||||
#ifndef __GPTSTRUCTS
|
#ifndef __GPTSTRUCTS
|
||||||
#define __GPTSTRUCTS
|
#define __GPTSTRUCTS
|
||||||
|
|
||||||
#define GPTFDISK_VERSION "0.6.5"
|
#define GPTFDISK_VERSION "0.6.6-pre1"
|
||||||
|
|
||||||
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
|
// Constants used by GPTData::PartsToMBR(). MBR_EMPTY must be the lowest-
|
||||||
// numbered value to refer to partition numbers. (Most will be 0 or positive,
|
// numbered value to refer to partition numbers. (Most will be 0 or positive,
|
||||||
@@ -24,6 +24,16 @@
|
|||||||
#define MBR_EFI_GPT -1
|
#define MBR_EFI_GPT -1
|
||||||
#define MBR_EMPTY -2
|
#define MBR_EMPTY -2
|
||||||
|
|
||||||
|
// Default values for sector alignment
|
||||||
|
#define DEFAULT_ALIGNMENT 2048
|
||||||
|
#define MAX_ALIGNMENT 32768
|
||||||
|
|
||||||
|
// Below constant corresponds to an 800GB disk -- a somewhat arbitrary
|
||||||
|
// cutoff
|
||||||
|
//#define SMALLEST_ADVANCED_FORMAT UINT64_C(1677721600)
|
||||||
|
// Now ~596GiB (640MB), since WD has introduced a smaller Advanced Format drive
|
||||||
|
#define SMALLEST_ADVANCED_FORMAT UINT64_C(1250263728)
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class PartNotes;
|
class PartNotes;
|
||||||
@@ -79,7 +89,7 @@ protected:
|
|||||||
int secondPartsCrcOk;
|
int secondPartsCrcOk;
|
||||||
int apmFound; // set to 1 if APM detected
|
int apmFound; // set to 1 if APM detected
|
||||||
int bsdFound; // set to 1 if BSD disklabel detected in MBR
|
int bsdFound; // set to 1 if BSD disklabel detected in MBR
|
||||||
int sectorAlignment; // Start & end partitions at multiples of sectorAlignment
|
uint32_t sectorAlignment; // Start & end partitions at multiples of sectorAlignment
|
||||||
int beQuiet;
|
int beQuiet;
|
||||||
WhichToUse whichWasUsed;
|
WhichToUse whichWasUsed;
|
||||||
|
|
||||||
@@ -177,8 +187,9 @@ public:
|
|||||||
int IsFreePartNum(uint32_t partNum);
|
int IsFreePartNum(uint32_t partNum);
|
||||||
|
|
||||||
// Change how functions work, or return information on same
|
// Change how functions work, or return information on same
|
||||||
void SetAlignment(int n) {sectorAlignment = n;}
|
void SetAlignment(uint32_t n);
|
||||||
int GetAlignment(void) {return sectorAlignment;}
|
uint32_t ComputeAlignment(void); // Set alignment based on current partitions
|
||||||
|
uint32_t GetAlignment(void) {return sectorAlignment;}
|
||||||
void JustLooking(int i = 1) {justLooking = i;}
|
void JustLooking(int i = 1) {justLooking = i;}
|
||||||
void BeQuiet(int i = 1) {beQuiet = i;}
|
void BeQuiet(int i = 1) {beQuiet = i;}
|
||||||
WhichToUse WhichWasUsed(void) {return whichWasUsed;}
|
WhichToUse WhichWasUsed(void) {return whichWasUsed;}
|
||||||
|
|||||||
5
mbr.cc
5
mbr.cc
@@ -85,7 +85,7 @@ int MBRData::ReadMBRData(const string & deviceFilename) {
|
|||||||
canDeleteMyDisk = 1;
|
canDeleteMyDisk = 1;
|
||||||
} // if
|
} // if
|
||||||
if (myDisk->OpenForRead(deviceFilename)) {
|
if (myDisk->OpenForRead(deviceFilename)) {
|
||||||
ReadMBRData(myDisk);
|
allOK = ReadMBRData(myDisk);
|
||||||
} else {
|
} else {
|
||||||
allOK = 0;
|
allOK = 0;
|
||||||
} // if
|
} // if
|
||||||
@@ -101,7 +101,7 @@ int MBRData::ReadMBRData(const string & deviceFilename) {
|
|||||||
// Note that any extended partition(s) present will be explicitly stored
|
// Note that any extended partition(s) present will be explicitly stored
|
||||||
// in the partitions[] array, along with their contained partitions; the
|
// in the partitions[] array, along with their contained partitions; the
|
||||||
// extended container partition(s) should be ignored by other functions.
|
// extended container partition(s) should be ignored by other functions.
|
||||||
void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
|
int MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
|
||||||
int allOK = 1, i, j, logicalNum;
|
int allOK = 1, i, j, logicalNum;
|
||||||
int err = 1;
|
int err = 1;
|
||||||
TempMBR tempMBR;
|
TempMBR tempMBR;
|
||||||
@@ -201,6 +201,7 @@ void MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize) {
|
|||||||
} // for
|
} // for
|
||||||
} // if (hybrid detection code)
|
} // if (hybrid detection code)
|
||||||
} // no initial error
|
} // no initial error
|
||||||
|
return allOK;
|
||||||
} // MBRData::ReadMBRData(DiskIO * theDisk, int checkBlockSize)
|
} // 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
|
||||||
|
|||||||
2
mbr.h
2
mbr.h
@@ -89,7 +89,7 @@ public:
|
|||||||
|
|
||||||
// File I/O functions...
|
// File I/O functions...
|
||||||
int ReadMBRData(const string & deviceFilename);
|
int ReadMBRData(const string & deviceFilename);
|
||||||
void ReadMBRData(DiskIO * theDisk, int checkBlockSize = 1);
|
int 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....
|
||||||
int ReadLogicalPart(uint32_t extendedStart, uint32_t diskOffset,
|
int ReadLogicalPart(uint32_t extendedStart, uint32_t diskOffset,
|
||||||
|
|||||||
8
sgdisk.8
8
sgdisk.8
@@ -149,10 +149,10 @@ sibling. Options available in \fBsgdisk\fR are:
|
|||||||
.B \-a, \-\-set\-alignment=value
|
.B \-a, \-\-set\-alignment=value
|
||||||
Set the sector alignment multiple. GPT fdisk aligns the start of partitions
|
Set the sector alignment multiple. GPT fdisk aligns the start of partitions
|
||||||
to sectors that are multiples of this value, which defaults to 8 on disks
|
to sectors that are multiples of this value, which defaults to 8 on disks
|
||||||
larger than 800GiB with 512\-byte sectors and to 1 on smaller disks or those
|
larger than 596 GiB with 512\-byte logical sectors and to 1 on smaller
|
||||||
with non\-512\-byte sectors. This alignment value is necessary to obtain
|
disks or those with non\-512\-byte sectors. This alignment value is
|
||||||
optimum performance with Western Digital Advanced Format and similar drives
|
necessary to obtain optimum performance with Western Digital Advanced
|
||||||
with larger physical than logical sector sizes.
|
Format and similar drives with larger physical than logical sector sizes.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B \-b, \-\-backup=file
|
.B \-b, \-\-backup=file
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ int main(int argc, char *argv[]) {
|
|||||||
GPTData theGPT;
|
GPTData theGPT;
|
||||||
int opt, numOptions = 0, saveData = 0, neverSaveData = 0;
|
int opt, numOptions = 0, saveData = 0, neverSaveData = 0;
|
||||||
int partNum = 0, deletePartNum = 0, infoPartNum = 0, bsdPartNum = 0, saveNonGPT = 1;
|
int partNum = 0, deletePartNum = 0, infoPartNum = 0, bsdPartNum = 0, saveNonGPT = 1;
|
||||||
int alignment = 8, retval = 0, pretend = 0;
|
int alignment = DEFAULT_ALIGNMENT, retval = 0, pretend = 0;
|
||||||
unsigned int hexCode;
|
unsigned int hexCode;
|
||||||
uint32_t tableSize = 128;
|
uint32_t tableSize = 128;
|
||||||
uint64_t startSector, endSector;
|
uint64_t startSector, endSector;
|
||||||
|
|||||||
@@ -246,11 +246,11 @@ void ReverseBytes(void* theValue, int numBytes) {
|
|||||||
|
|
||||||
// Compute (2 ^ value). Given the return type, value must be 63 or less.
|
// Compute (2 ^ value). Given the return type, value must be 63 or less.
|
||||||
// Used in some bit-fiddling functions
|
// Used in some bit-fiddling functions
|
||||||
uint64_t PowerOf2(int value) {
|
uint64_t PowerOf2(uint32_t value) {
|
||||||
uint64_t retval = 1;
|
uint64_t retval = 1;
|
||||||
int i;
|
uint32_t i;
|
||||||
|
|
||||||
if ((value < 64) && (value >= 0)) {
|
if (value < 64) {
|
||||||
for (i = 0; i < value; i++) {
|
for (i = 0; i < value; i++) {
|
||||||
retval *= 2;
|
retval *= 2;
|
||||||
} // for
|
} // for
|
||||||
|
|||||||
@@ -55,6 +55,6 @@ string BytesToSI(uint64_t size);
|
|||||||
unsigned char StrToHex(const string & input, unsigned int position);
|
unsigned char StrToHex(const string & input, unsigned int position);
|
||||||
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(void* 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(uint32_t value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user