devicepath/harddrive.go

105 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
}