GPT - GUID Partition Table
Install via npm
$ npm install --save gpt
Used by
Related Modules
What can I do with this?
- Format disks / images
- Fix a partition table, recover a deleted partition
- Recover the GUID Partition Table from its backup
- Locate partitions which are inaccessible / ignored by the OS
- Verify the integrity of the primary GPT against its backup
Usage
var GPT = require( 'gpt' )
NOTE: For brevity in the examples, error handling may be omitted, and synchronous methods used.
Examples
The following usage examples are consolidated into example/verify.js and runnable, where device
would be a block device (i.e. /dev/rdisk2
on Mac OS, \\.\PhysicalDrive2
on Windows, or /dev/sdb
on Linux);
sudo node example/verify.js <device>
Example output
Master Boot Record: MODERN {
physicalDrive: 0,
timestamp: { seconds: 0, minutes: 0, hours: 0 },
signature: 0,
copyProtected: false,
partitions:
[ Partition {
status: 0,
type: 238,
sectors: 60751871,
firstLBA: 1,
firstCHS: CHS { cylinder: 1023, head: 255, sector: 62 },
lastCHS: CHS { cylinder: 1023, head: 255, sector: 62 } },
Partition {
status: 0,
type: 0,
sectors: 0,
firstLBA: 0,
firstCHS: CHS { cylinder: 0, head: 0, sector: 0 },
lastCHS: CHS { cylinder: 0, head: 0, sector: 0 } },
Partition {
status: 0,
type: 0,
sectors: 0,
firstLBA: 0,
firstCHS: CHS { cylinder: 0, head: 0, sector: 0 },
lastCHS: CHS { cylinder: 0, head: 0, sector: 0 } },
Partition {
status: 0,
type: 0,
sectors: 0,
firstLBA: 0,
firstCHS: CHS { cylinder: 0, head: 0, sector: 0 },
lastCHS: CHS { cylinder: 0, head: 0, sector: 0 } } ],
code:
[ Code {
offset: 0,
data:
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... > },
Code {
offset: 224,
data:
<Buffer 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ... > } ] }
EFI Parition: Partition {
status: 0,
type: 238,
sectors: 60751871,
firstLBA: 1,
firstCHS: CHS { cylinder: 1023, head: 255, sector: 62 },
lastCHS: CHS { cylinder: 1023, head: 255, sector: 62 } }
Primary: GPT {
blockSize: 512,
guid: 'D871C3D8-25BA-4792-BE54-171138CFA926',
revision: 65536,
headerSize: 92,
headerChecksum: 1129732062,
currentLBA: 1,
backupLBA: 60751871,
firstLBA: 34,
lastLBA: 60751838,
tableOffset: 2,
entries: 128,
entrySize: 128,
tableChecksum: 4191805727,
partitions:
[ PartitionEntry {
type: 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B',
guid: 'BC7E4D81-59CC-40A6-84BF-43253C95AE0D',
name: 'EFI System Partition',
firstLBA: 40,
lastLBA: 409639,
attr: 0 },
PartitionEntry {
type: 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
guid: '1885EDDC-5F6E-45CD-8C5C-E0485563F3CC',
name: '',
firstLBA: 411648,
lastLBA: 60749823,
attr: 0 } ] }
Backup: GPT {
blockSize: 512,
guid: 'D871C3D8-25BA-4792-BE54-171138CFA926',
revision: 65536,
headerSize: 92,
headerChecksum: 4122036460,
currentLBA: 60751871,
backupLBA: 1,
firstLBA: 34,
lastLBA: 60751838,
tableOffset: 60751839,
entries: 128,
entrySize: 128,
tableChecksum: 4191805727,
partitions:
[ PartitionEntry {
type: 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B',
guid: 'BC7E4D81-59CC-40A6-84BF-43253C95AE0D',
name: 'EFI System Partition',
firstLBA: 40,
lastLBA: 409639,
attr: 0 },
PartitionEntry {
type: 'EBD0A0A2-B9E5-4433-87C0-68B6B72699C7',
guid: '1885EDDC-5F6E-45CD-8C5C-E0485563F3CC',
name: '',
firstLBA: 411648,
lastLBA: 60749823,
attr: 0 } ] }
[OK]
Finding the EFI Partition
The indicator for a GPT formatted device is a protective or hybrid Master Boot Record, containing a partition marked with a type of either 0xEE
or 0xEF
respectively. Thus we need to read & parse the MBR to determine whether a GPT is present or not:
var MBR = require( 'mbr' )
function readMBR() {
var buffer = Buffer.alloc( 512 )
fs.readSync( fd, buffer, 0, buffer.length, 0 )
return MBR.parse( buffer )
}
var mbr = readMBR()
var efiPart = mbr.getEFIPart()
if( efiPart == null ) {
console.log( 'No EFI partition found' )
}
Reading the Primary GPT
function readPrimaryGPT( efiPart ) {
var gpt = new GPT({ blockSize: 512 })
var offset = efiPart.type == 0xEE ?
efiPart.firstLBA * gpt.blockSize :
gpt.blockSize
var buffer = Buffer.alloc( 33 * gpt.blockSize )
fs.readSync( fd, buffer, 0, buffer.length, offset )
return GPT.parse( buffer )
}
var primaryGPT = readPrimaryGPT( efiPart )
NOTE: Reading & parsing a GPT like above will just work in most cases, but to cover all situations (i.e. padding between header & table, custom table entry sizes, etc.), see the "Accounting for everything" example below:
Accounting for everything
function readPrimaryGPT( efiPart ) {
var gpt = new GPT({ blockSize: 512 })
var offset = efiPart.type == 0xEE ?
efiPart.firstLBA * gpt.blockSize :
gpt.blockSize
var headerBuffer = Buffer.alloc( gpt.blockSize )
fs.readSync( fd, headerBuffer, 0, headerBuffer.length, offset )
gpt.parseHeader( headerBuffer )
var tableBuffer = Buffer.alloc( gpt.tableSize )
var tableOffset = gpt.tableOffset * gpt.blockSize
fs.readSync( fd, tableBuffer, 0, tableBuffer.length, tableOffset )
gpt.parseTable( tableBuffer, 0, gpt.blockSize )
gpt.parseTable( tableBuffer, gpt.blockSize, gpt.tableSize )
return gpt
}
var primaryGPT = readPrimaryGPT( efiPart )
Reading the Backup GPT
function readBackupGPT(primaryGPT) {
var backupGPT = new GPT({ blockSize: primaryGPT.blockSize })
var buffer = Buffer.alloc( 33 * primaryGPT.blockSize )
var offset = ( ( primaryGPT.backupLBA - 32 ) * blockSize )
fs.readSync( fd, buffer, 0, buffer.length, offset )
backupGPT.parseBackup( buffer )
return backupGPT
}
var backupGPT = readBackupGPT(primaryGPT)
Accounting for everything
function readBackupGPT(primaryGPT) {
var backupGPT = new GPT({ blockSize: primaryGPT.blockSize })
return backupGPT
}
var backupGPT = readBackupGPT(primaryGPT)
Verifying the GPT
var isPrimaryValid = primaryGPT.verify()
var isBackupValid = backupGPT.verify()
var checksumsMatch = primaryGPT.tableChecksum === backupGPT.tableChecksum &&
primaryGPT.headerChecksum !== backupGPT.headerChecksum
if( isPrimaryValid && isBackupValid && checksumsMatch ) {
console.log('Everything\'s alright')
}
Creating a GPT
var gpt = new GPT({
blockSize: 512,
guid: '00000000-0000-0000-0000-000000000000'
headerSize: 92,
currentLBA: 1n,
backupLBA: 123456n,
firstLBA: 34n,
lastLBA: 556789n,
tableOffset: 2n,
entries: 128,
entrySize: 128,
})
gpt.partitions.push( new GPT.PartitionEntry({
type: 'C12A7328-F81F-11D2-BA4B-00A0C93EC93B',
guid: 'BC7E4D81-59CC-40A6-84BF-43253C95AE0D',
name: 'EFI System Partition',
firstLBA: 40n,
lastLBA: 409639n,
}))
Writing the GPT
You can either let the module create the buffers for you;
var primaryGPTBuffer = gpt.write()
var backupGPTBuffer = gpt.writeBackupFromPrimary()
Or pass in a buffer & optional offset (i.e. to write MBR & primary GPT in one go);
var buffer = Buffer.alloc( blockSize + ( 33 * blockSize ) )
var backupGPTBuffer = Buffer.alloc( 33 * blockSize )
mbr.write( buffer )
gpt.write( buffer, blockSize )
gpt.writeBackupFromPrimary( backupGPTBuffer )
fs.writeSync( fd, buffer, 0, buffer.length, 0 )
fs.writeSync( fd, backupGPTBuffer, 0, backupGPTBuffer.length, gpt.backupLBA * blockSize )