github.com/linuxboot/fiano@v1.2.0/pkg/visitors/dump.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 "fmt" 10 "io" 11 "os" 12 13 "github.com/linuxboot/fiano/pkg/uefi" 14 ) 15 16 // Dump a firmware file using a GUID or a name 17 type Dump struct { 18 // Input 19 Predicate func(f uefi.Firmware) bool 20 21 // Output 22 // The file is written to this writer. 23 W io.Writer 24 } 25 26 // Run just calls the visitor 27 func (v *Dump) Run(f uefi.Firmware) error { 28 return f.Apply(v) 29 } 30 31 // Visit uses find to dump a file to W. 32 func (v *Dump) Visit(f uefi.Firmware) error { 33 // First run "find" to generate a list to dump 34 find := Find{ 35 Predicate: v.Predicate, 36 } 37 if err := find.Run(f); err != nil { 38 return err 39 } 40 41 // There must only be one match. 42 if numMatch := len(find.Matches); numMatch > 1 { 43 return fmt.Errorf("more than one match, only one match allowed! got %v", find.Matches) 44 } else if numMatch == 0 { 45 return errors.New("no matches found") 46 } 47 48 m := find.Matches[0] 49 // TODO: We may need to call assemble here before dumping as the buffer may be empty 50 _, err := v.W.Write(m.Buf()) 51 return err 52 } 53 54 func init() { 55 RegisterCLI("dump", "dump a firmware file", 2, func(args []string) (uefi.Visitor, error) { 56 pred, err := FindFilePredicate(args[0]) 57 if err != nil { 58 return nil, err 59 } 60 61 file, err := os.OpenFile(args[1], os.O_RDWR|os.O_CREATE, 0755) 62 if err != nil { 63 return nil, err 64 } 65 66 // Find all the matching files and replace their inner PE32s. 67 return &Dump{ 68 Predicate: pred, 69 W: file, 70 }, nil 71 }) 72 }