// copied from github.com/akavel/rsrc // LICENSE: MIT // Copyright 2013-2014 The rsrc Authors. (https://github.com/akavel/rsrc/blob/master/AUTHORS) func writeCoff(coff *coff.Coff, fnameout string) error { out, err := os.Create(fnameout) if err != nil { return err } defer out.Close() w := binutil.Writer{W: out} // write the resulting file to disk binutil.Walk(coff, func(v reflect.Value, path string) error { if binutil.Plain(v.Kind()) { w.WriteLE(v.Interface()) return nil } vv, ok := v.Interface().(binutil.SizedReader) if ok { w.WriteFromSized(vv) return binutil.WALK_SKIP } return nil }) if w.Err != nil { return fmt.Errorf("Error writing output file: %s", w.Err) } return nil }
func (coff *Coff) freezeRDATA() { var offset, diroff, stringsoff uint32 binutil.Walk(coff, func(v reflect.Value, path string) error { diroff = coff.freezeCommon1(path, offset, diroff) RE := regexp.MustCompile const N = `\[(\d+)\]` m := matcher{} //TODO: adjust symbol pointers //TODO: fill Symbols.Name, .Value switch { case m.Find(path, RE("^/Data"+N+"$")): n := m[0] coff.Symbols[1+n].Value = offset - diroff // FIXME: is it ok? sz := uint64(coff.Data[n].Size()) binary.LittleEndian.PutUint64(coff.Symbols[0].Auxiliaries[0][0:8], binary.LittleEndian.Uint64(coff.Symbols[0].Auxiliaries[0][0:8])+sz) case path == "/StringsHeader": stringsoff = offset case m.Find(path, RE("^/Strings"+N+"$")): binary.LittleEndian.PutUint32(coff.Symbols[m[0]+1].Name[4:8], offset-stringsoff) } return freezeCommon2(v, &offset) }) coff.SectionHeader32.PointerToRelocations = 0 }
// Walk writes the data buffer with hexidecimal data from the structs func (vi *VersionInfo) Walk() { // Create a buffer var b bytes.Buffer w := binutil.Writer{W: &b} // Write to the buffer binutil.Walk(vi.Structure, func(v reflect.Value, path string) error { if binutil.Plain(v.Kind()) { w.WriteLE(v.Interface()) } return nil }) vi.Buffer = b }
func writeCoffTo(w io.WriteCloser, coff *coff.Coff) error { bw := binutil.Writer{W: w} // write the resulting file to disk binutil.Walk(coff, func(v reflect.Value, path string) error { if binutil.Plain(v.Kind()) { bw.WriteLE(v.Interface()) return nil } vv, ok := v.Interface().(binutil.SizedReader) if ok { bw.WriteFromSized(vv) return binutil.WALK_SKIP } return nil }) err := bw.Err if closeErr := w.Close(); closeErr != nil && err == nil { err = closeErr } return err }
func (coff *Coff) freezeRSRC() { leafwalker := make(chan *DirEntry) go func() { for _, dir1 := range coff.Dir.Dirs { // resource type for _, dir2 := range dir1.Dirs { // resource ID for i := range dir2.DirEntries { // resource lang leafwalker <- &dir2.DirEntries[i] } } } }() var offset, diroff uint32 binutil.Walk(coff, func(v reflect.Value, path string) error { diroff = coff.freezeCommon1(path, offset, diroff) RE := regexp.MustCompile const N = `\[(\d+)\]` m := matcher{} switch { case m.Find(path, RE("^/Dir/Dirs"+N+"$")): coff.Dir.DirEntries[m[0]].OffsetToData = MASK_SUBDIRECTORY | (offset - diroff) case m.Find(path, RE("^/Dir/Dirs"+N+"/Dirs"+N+"$")): coff.Dir.Dirs[m[0]].DirEntries[m[1]].OffsetToData = MASK_SUBDIRECTORY | (offset - diroff) case m.Find(path, RE("^/DataEntries"+N+"$")): direntry := <-leafwalker direntry.OffsetToData = offset - diroff case m.Find(path, RE("^/DataEntries"+N+"/OffsetToData$")): coff.Relocations[m[0]].RVA = offset - diroff case m.Find(path, RE("^/Data"+N+"$")): coff.DataEntries[m[0]].OffsetToData = offset - diroff } return freezeCommon2(v, &offset) }) }