Skip to content

Commit b7e3f0e

Browse files
authored
Added ParseVersionResourcesForEntries to support files with multiple product versions. (#105)
1 parent 3be4db6 commit b7e3f0e

File tree

1 file changed

+83
-46
lines changed

1 file changed

+83
-46
lines changed

version.go

+83-46
Original file line numberDiff line numberDiff line change
@@ -315,66 +315,103 @@ func (pe *File) ParseVersionResources() (map[string]string, error) {
315315
directory := e.Directory.Entries[0].Directory
316316

317317
for _, e := range directory.Entries {
318-
ver, err := pe.parseVersionInfo(e)
318+
m, err := pe.parseVersionEntry(e, vers)
319319
if err != nil {
320-
return vers, err
321-
}
322-
ff, err := pe.parseFixedFileInfo(e)
323-
if err != nil {
324-
return vers, err
320+
return m, err
325321
}
322+
}
323+
}
324+
return vers, nil
325+
}
326+
327+
func (pe *File) parseVersionEntry(e ResourceDirectoryEntry, vers map[string]string) (map[string]string, error) {
328+
ver, err := pe.parseVersionInfo(e)
329+
if err != nil {
330+
return vers, err
331+
}
332+
ff, err := pe.parseFixedFileInfo(e)
333+
if err != nil {
334+
return vers, err
335+
}
326336

327-
offset := ff.GetStringFileInfoOffset(e)
337+
offset := ff.GetStringFileInfoOffset(e)
328338

339+
for {
340+
f, n, err := pe.parseStringFileInfo(offset, e)
341+
if err != nil || f.Length == 0 {
342+
break
343+
}
344+
345+
switch n {
346+
case StringFileInfoString:
347+
tableOffset := f.GetStringTableOffset(offset)
329348
for {
330-
f, n, err := pe.parseStringFileInfo(offset, e)
331-
if err != nil || f.Length == 0 {
349+
table, err := pe.parseStringTable(tableOffset, e)
350+
if err != nil {
332351
break
333352
}
334-
335-
switch n {
336-
case StringFileInfoString:
337-
tableOffset := f.GetStringTableOffset(offset)
338-
for {
339-
table, err := pe.parseStringTable(tableOffset, e)
340-
if err != nil {
341-
break
342-
}
343-
stringOffset := table.GetStringOffset(tableOffset, e)
344-
for stringOffset < tableOffset+uint32(table.Length) {
345-
k, v, l, err := pe.parseString(stringOffset, e)
346-
if err != nil {
347-
break
348-
}
349-
vers[k] = v
350-
if l == 0 {
351-
stringOffset = tableOffset + uint32(table.Length)
352-
} else {
353-
stringOffset = stringOffset + uint32(l)
354-
}
355-
}
356-
// handle potential infinite loops
357-
if uint32(table.Length)+tableOffset > tableOffset {
358-
break
359-
}
360-
if tableOffset > uint32(f.Length) {
361-
break
362-
}
353+
stringOffset := table.GetStringOffset(tableOffset, e)
354+
for stringOffset < tableOffset+uint32(table.Length) {
355+
k, v, l, err := pe.parseString(stringOffset, e)
356+
if err != nil {
357+
break
363358
}
364-
case VarFileInfoString:
359+
vers[k] = v
360+
if l == 0 {
361+
stringOffset = tableOffset + uint32(table.Length)
362+
} else {
363+
stringOffset = stringOffset + uint32(l)
364+
}
365+
}
366+
// handle potential infinite loops
367+
if uint32(table.Length)+tableOffset > tableOffset {
365368
break
366-
default:
369+
}
370+
if tableOffset > uint32(f.Length) {
367371
break
368372
}
373+
}
374+
case VarFileInfoString:
375+
break
376+
default:
377+
break
378+
}
369379

370-
offset += uint32(f.Length)
380+
offset += uint32(f.Length)
371381

372-
// StringFileInfo/VarFileinfo structs consumed?
373-
if offset >= uint32(ver.Length) {
374-
break
375-
}
382+
// StringFileInfo/VarFileinfo structs consumed?
383+
if offset >= uint32(ver.Length) {
384+
break
385+
}
386+
}
387+
return nil, nil
388+
}
389+
390+
// ParseVersionResourcesForEntries parses file version strings from the version resource
391+
// directory. This directory contains several structures starting with VS_VERSION_INFO
392+
// with references to children StringFileInfo structures. In addition, StringFileInfo
393+
// contains the StringTable structure with String entries describing the name and value
394+
// of each file version strings.
395+
func (pe *File) ParseVersionResourcesForEntries() ([]map[string]string, error) {
396+
var allVersions []map[string]string
397+
if pe.opts.OmitResourceDirectory {
398+
return allVersions, nil
399+
}
400+
for _, e := range pe.Resources.Entries {
401+
if e.ID != VersionResourceType {
402+
continue
403+
}
404+
405+
directory := e.Directory.Entries[0].Directory
406+
407+
for _, e := range directory.Entries {
408+
vers := make(map[string]string)
409+
allVersions = append(allVersions, vers)
410+
_, err := pe.parseVersionEntry(e, vers)
411+
if err != nil {
412+
return allVersions, err
376413
}
377414
}
378415
}
379-
return vers, nil
416+
return allVersions, nil
380417
}

0 commit comments

Comments
 (0)