github.com/linuxboot/fiano@v1.2.0/pkg/visitors/parsedir.go (about)

     1  // Copyright 2018 the LinuxBoot Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package visitors
     6  
     7  import (
     8  	"errors"
     9  	"os"
    10  	"path/filepath"
    11  
    12  	"github.com/linuxboot/fiano/pkg/uefi"
    13  )
    14  
    15  // ParseDir creates the firmware tree and reads the binaries from the provided directory
    16  type ParseDir struct {
    17  	BasePath string
    18  }
    19  
    20  // Run is not actually implemented cause we can't fit the interface
    21  func (v *ParseDir) Run(f uefi.Firmware) error {
    22  	return errors.New("func Run for ParseDir is not implemented, do not use")
    23  }
    24  
    25  // Parse parses a directory and creates the tree.
    26  func (v *ParseDir) Parse() (uefi.Firmware, error) {
    27  	// Read in the json and construct the tree.
    28  	jsonbuf, err := os.ReadFile(filepath.Join(v.BasePath, "summary.json"))
    29  	if err != nil {
    30  		return nil, err
    31  	}
    32  	f, err := uefi.UnmarshalFirmware(jsonbuf)
    33  	if err != nil {
    34  		return nil, err
    35  	}
    36  
    37  	if err = f.Apply(v); err != nil {
    38  		return nil, err
    39  	}
    40  	return f, nil
    41  }
    42  
    43  func (v *ParseDir) readBuf(ExtractPath string) ([]byte, error) {
    44  	if ExtractPath != "" {
    45  		return os.ReadFile(filepath.Join(v.BasePath, ExtractPath))
    46  	}
    47  	return nil, nil
    48  }
    49  
    50  // Visit applies the ParseDir visitor to any Firmware type.
    51  func (v *ParseDir) Visit(f uefi.Firmware) error {
    52  	var err error
    53  	var fBuf []byte
    54  	switch f := f.(type) {
    55  
    56  	case *uefi.FirmwareVolume:
    57  		fBuf, err = v.readBuf(f.ExtractPath)
    58  
    59  	case *uefi.File:
    60  		fBuf, err = v.readBuf(f.ExtractPath)
    61  
    62  	case *uefi.Section:
    63  		fBuf, err = v.readBuf(f.ExtractPath)
    64  
    65  	case *uefi.NVar:
    66  		if f.IsValid() {
    67  			var fValBuf []byte
    68  			fValBuf, err = v.readBuf(f.ExtractPath)
    69  			fBuf = append(make([]byte, f.DataOffset), fValBuf...)
    70  		} else {
    71  			fBuf, err = v.readBuf(f.ExtractPath)
    72  		}
    73  
    74  	case *uefi.FlashDescriptor:
    75  		fBuf, err = v.readBuf(f.ExtractPath)
    76  
    77  	case *uefi.BIOSRegion:
    78  		fBuf, err = v.readBuf(f.ExtractPath)
    79  
    80  	case *uefi.MERegion:
    81  		fBuf, err = v.readBuf(f.ExtractPath)
    82  
    83  	case *uefi.RawRegion:
    84  		fBuf, err = v.readBuf(f.ExtractPath)
    85  
    86  	case *uefi.BIOSPadding:
    87  		fBuf, err = v.readBuf(f.ExtractPath)
    88  	}
    89  
    90  	if err != nil {
    91  		return err
    92  	}
    93  	f.SetBuf(fBuf)
    94  
    95  	return f.ApplyChildren(v)
    96  }