File: media_device.go

package info (click to toggle)
golang-github-foxboron-go-uefi 0.0~git20250207.69fb7db-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,140 kB
  • sloc: makefile: 29; sh: 14
file content (105 lines) | stat: -rw-r--r-- 2,557 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package device

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"io"
	"log"

	"github.com/foxboron/go-uefi/efi/util"
)

// Subtypes of Media Device
// Section 10.3.5 - Media Device Path
const (
	_ DevicePathSubType = iota
	HardDriveDevicePath
	CDRomDevicePath
	VendorMediaDevicePath
	FilePathDevicePath
	MediaProtocolDevicePath
	PIWGFirmwareDevicePath
)

type HardDriveMediaDevicePath struct {
	EFIDevicePath
	PartitionNumber    uint32
	PartitionStart     [8]byte
	PartitionSize      [8]byte
	PartitionSignature [16]byte
	PartitionFormat    uint8
	SignatureType      uint8
}

func (h HardDriveMediaDevicePath) Format() string {
	format := []string{"MBR", "GPT"}
	if h.PartitionNumber == 0 {
		return fmt.Sprintf("HD(%d,%s,%x)",
			h.PartitionNumber,
			format[h.PartitionFormat-1],
			h.PartitionSignature)
	}
	return fmt.Sprintf("HD(%d,%s,%s,0x%x,0x%x)",
		h.PartitionNumber,
		format[h.PartitionFormat-1],
		util.BytesToGUID(h.PartitionSignature[:]).Format(),
		binary.LittleEndian.Uint64(h.PartitionStart[:]),
		binary.LittleEndian.Uint64(h.PartitionSize[:]))
}

type FileTypeMediaDevicePath struct {
	EFIDevicePath
	PathName string
}

func (f FileTypeMediaDevicePath) Format() string {
	return fmt.Sprintf("File(%s)", f.PathName)
}

type FirmwareFielMediaDevicePath struct {
	EFIDevicePath
	FirmwareFileName [16]byte
}

func (f FirmwareFielMediaDevicePath) Format() string {
	return "No format"
}

func ParseMediaDevicePath(f io.Reader, efi *EFIDevicePath) (EFIDevicePaths, error) {
	var err error
	switch efi.SubType {
	case HardDriveDevicePath:
		m := HardDriveMediaDevicePath{EFIDevicePath: *efi}
		for _, b := range []interface{}{
			&m.PartitionNumber,
			&m.PartitionStart,
			&m.PartitionSize,
			&m.PartitionSignature,
			&m.PartitionFormat,
			&m.SignatureType,
		} {
			if err := binary.Read(f, binary.LittleEndian, b); err != nil {
				return nil, fmt.Errorf("Couldn't parse Harddrive Device Path: %w", err)
			}
		}
		return m, nil
	case FilePathDevicePath:
		file := FileTypeMediaDevicePath{EFIDevicePath: *efi}
		b := util.ReadNullString(f)
		file.PathName, err = util.ParseUtf16Var(bytes.NewBuffer(b))
		if err != nil {
			return nil, err
		}
		return file, nil
	case PIWGFirmwareDevicePath:
		file := FirmwareFielMediaDevicePath{EFIDevicePath: *efi}
		if err := binary.Read(f, binary.LittleEndian, &file.FirmwareFileName); err != nil {
			return nil, fmt.Errorf("Couldn't parse PIWG Firmware Device Path: %w", err)
		}
		return file, nil
	default:
		log.Printf("Not implemented MediaDevicePath type: %x", efi.SubType)
	}
	return nil, nil
}