Add support for hard drive nodes
This commit is contained in:
parent
2e97936133
commit
23ec82f4ec
6 changed files with 132 additions and 1 deletions
2
base.go
2
base.go
|
@ -30,6 +30,8 @@ const EndOfEntireDevicePath DeviceNodeSubType = 0xFF
|
||||||
|
|
||||||
const ACPISubType DeviceNodeSubType = 1
|
const ACPISubType DeviceNodeSubType = 1
|
||||||
|
|
||||||
|
const HardDriveSubType DeviceNodeSubType = 1
|
||||||
|
|
||||||
type DevicePathNode interface {
|
type DevicePathNode interface {
|
||||||
Type() DeviceNodeType
|
Type() DeviceNodeType
|
||||||
SubType() DeviceNodeSubType
|
SubType() DeviceNodeSubType
|
||||||
|
|
5
go.mod
5
go.mod
|
@ -2,7 +2,10 @@ module git.faercol.me/faercol/devicepath
|
||||||
|
|
||||||
go 1.20
|
go 1.20
|
||||||
|
|
||||||
require github.com/stretchr/testify v1.8.4
|
require (
|
||||||
|
github.com/google/uuid v1.3.1
|
||||||
|
github.com/stretchr/testify v1.8.4
|
||||||
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -1,5 +1,7 @@
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||||
|
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
|
105
harddrive.go
Normal file
105
harddrive.go
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
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
|
||||||
|
}
|
18
harddrive_test.go
Normal file
18
harddrive_test.go
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
package devicepath_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"git.faercol.me/faercol/devicepath"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestHDParseString(t *testing.T) {
|
||||||
|
t.Run("GPT", func(t *testing.T) {
|
||||||
|
expected := "HD(1,GPT,16f06d01-50da-6544-86bd-f3457f980086,0x1000,0x96000)"
|
||||||
|
var dev devicepath.HardDriveDevicePath
|
||||||
|
require.NoError(t, dev.ParseString(expected))
|
||||||
|
assert.Equal(t, expected, dev.String())
|
||||||
|
})
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ var prefixTypeAssociation = map[string]nodeGenerator{
|
||||||
sataPrefix: func() DevicePathNode { return &SataDevicePath{} },
|
sataPrefix: func() DevicePathNode { return &SataDevicePath{} },
|
||||||
pciPrefix: func() DevicePathNode { return &PCIDevicePath{} },
|
pciPrefix: func() DevicePathNode { return &PCIDevicePath{} },
|
||||||
pciRootPrefix: func() DevicePathNode { return &PCIRootDevicePath{} },
|
pciRootPrefix: func() DevicePathNode { return &PCIRootDevicePath{} },
|
||||||
|
hdPrefix: func() DevicePathNode { return &HardDriveDevicePath{} },
|
||||||
}
|
}
|
||||||
|
|
||||||
func Parsenode(raw string) (DevicePathNode, error) {
|
func Parsenode(raw string) (DevicePathNode, error) {
|
||||||
|
|
Loading…
Reference in a new issue