106 lines
2.2 KiB
Go
106 lines
2.2 KiB
Go
|
package devicepath
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/google/uuid"
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
hdLength uint16 = 2
|
||
|
hdPrefix string = "HD"
|
||
|
)
|
||
|
|
||
|
func signatureTypeToStr(val uint8) string {
|
||
|
switch val {
|
||
|
case 1:
|
||
|
return "MBR"
|
||
|
default:
|
||
|
return "GPT"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func formatSignature(signature [16]byte, signatureType uint8) string {
|
||
|
switch signatureType {
|
||
|
case 1: // MBR
|
||
|
return fmt.Sprintf("%x", signature[:4]) // only stored on the first 4 bytes
|
||
|
default: // default is GPT
|
||
|
parsedUID, _ := uuid.FromBytes(signature[:])
|
||
|
return parsedUID.String()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type HardDriveDevicePath struct {
|
||
|
partitionNumber uint32
|
||
|
partitionStart uint64
|
||
|
partitionSize uint64
|
||
|
partitionSignature [16]byte
|
||
|
// partitionFormat uint8
|
||
|
signatureType uint8
|
||
|
}
|
||
|
|
||
|
func (hp *HardDriveDevicePath) Type() DeviceNodeType {
|
||
|
return MediaDevicePath
|
||
|
}
|
||
|
|
||
|
func (hp *HardDriveDevicePath) SubType() DeviceNodeSubType {
|
||
|
return HardDriveSubType
|
||
|
}
|
||
|
|
||
|
func (hp *HardDriveDevicePath) String() string {
|
||
|
return fmt.Sprintf("%s(%d,%s,%s,0x%x,0x%x)", hdPrefix, hp.partitionNumber, signatureTypeToStr(hp.signatureType), formatSignature(hp.partitionSignature, hp.signatureType), hp.partitionStart, hp.partitionSize)
|
||
|
}
|
||
|
|
||
|
func (hp *HardDriveDevicePath) Bytes() []byte {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (hp *HardDriveDevicePath) ParseString(raw string) error {
|
||
|
if !checkStringFormat(raw, hdPrefix, -1) {
|
||
|
return ErrMalformedString
|
||
|
}
|
||
|
args := strings.Split(raw[len(hdPrefix)+1:len(raw)-1], ",")
|
||
|
if len(args) != 5 {
|
||
|
return errors.New("unexpected number of arguments")
|
||
|
}
|
||
|
|
||
|
if partNumber, err := strconv.ParseUint(args[0], 10, 32); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
hp.partitionNumber = uint32(partNumber)
|
||
|
}
|
||
|
|
||
|
switch args[1] {
|
||
|
case "MBR":
|
||
|
return errors.New("MBR partitions not yet supported")
|
||
|
default:
|
||
|
hp.signatureType = 2
|
||
|
}
|
||
|
|
||
|
if uid, err := uuid.Parse(args[2]); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
if dat, err := uid.MarshalBinary(); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
hp.partitionSignature = [16]byte(dat)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if start, err := strconv.ParseUint(args[3], 0, 64); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
hp.partitionStart = start
|
||
|
}
|
||
|
|
||
|
if size, err := strconv.ParseUint(args[4], 0, 64); err != nil {
|
||
|
return err
|
||
|
} else {
|
||
|
hp.partitionSize = size
|
||
|
}
|
||
|
return nil
|
||
|
}
|