Files
cloudpods/pkg/hostman/hostdeployer/uefi/devpath.go

99 lines
2.4 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package uefi
import (
"encoding/binary"
"fmt"
)
// DevicePathType constants
const (
DevicePathTypeHardware = 0x01
DevicePathTypeACPI = 0x02
DevicePathTypeMessaging = 0x03
DevicePathTypeMedia = 0x04
DevicePathTypeEnd = 0x7F
)
// DevicePathElement represents a UEFI device path element
type DevicePathElement struct {
devType byte
subType byte
data []byte
}
func (e *DevicePathElement) String() string {
return fmt.Sprintf("devType %v, subType %v", e.devType, e.subType)
}
// Type returns the device path type
func (e *DevicePathElement) Type() byte {
return e.devType
}
// SubType returns the device path subtype
func (e *DevicePathElement) SubType() byte {
return e.subType
}
// ParseDevicePathElements parses a device path from binary data
func ParseDevicePathElements(data []byte) ([]*DevicePathElement, error) {
if len(data) == 0 {
return nil, fmt.Errorf("empty device path data")
}
var elements []*DevicePathElement
pos := 0
for pos < len(data) {
// Check if we have enough data for the header
if pos+4 > len(data) {
return nil, fmt.Errorf("truncated device path data")
}
// Parse header
devType := data[pos]
subType := data[pos+1]
length := binary.LittleEndian.Uint16(data[pos+2 : pos+4])
// Validate length
if length < 4 {
return nil, fmt.Errorf("invalid device path element length")
}
// Check if we have enough data for the element
if pos+int(length) > len(data) {
return nil, fmt.Errorf("truncated device path element")
}
// Check if this is the end of the device path
if devType == DevicePathTypeEnd {
break
}
element := &DevicePathElement{
devType: devType,
subType: subType,
data: data[pos+4 : pos+int(length)],
}
elements = append(elements, element)
pos += int(length)
}
return elements, nil
}