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 HardDriveSubType DeviceNodeSubType = 1
|
||||
|
||||
type DevicePathNode interface {
|
||||
Type() DeviceNodeType
|
||||
SubType() DeviceNodeSubType
|
||||
|
|
5
go.mod
5
go.mod
|
@ -2,7 +2,10 @@ module git.faercol.me/faercol/devicepath
|
|||
|
||||
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 (
|
||||
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/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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
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{} },
|
||||
pciPrefix: func() DevicePathNode { return &PCIDevicePath{} },
|
||||
pciRootPrefix: func() DevicePathNode { return &PCIRootDevicePath{} },
|
||||
hdPrefix: func() DevicePathNode { return &HardDriveDevicePath{} },
|
||||
}
|
||||
|
||||
func Parsenode(raw string) (DevicePathNode, error) {
|
||||
|
|
Loading…
Reference in a new issue