using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.IO;
namespace Vestris.ResourceLib
{
///
/// VS_VERSIONINFO
/// This structure depicts the organization of data in a file-version resource. It is the root structure
/// that contains all other file-version information structures.
/// http://msdn.microsoft.com/en-us/library/aa914916.aspx
///
public class VersionResource : Resource
{
ResourceTableHeader _header = new ResourceTableHeader("VS_VERSION_INFO");
FixedFileInfo _fixedfileinfo = new FixedFileInfo();
private Dictionary _resources = new Dictionary();
///
/// The resource header.
///
public ResourceTableHeader Header
{
get
{
return _header;
}
}
///
/// A dictionary of resource tables.
///
public Dictionary Resources
{
get
{
return _resources;
}
}
///
/// An existing version resource.
///
/// Module handle.
/// Resource ID.
/// Resource type.
/// Resource name.
/// Language ID.
/// Resource size.
public VersionResource(IntPtr hModule, IntPtr hResource, ResourceId type, ResourceId name, UInt16 language, int size)
: base(hModule, hResource, type, name, language, size)
{
}
///
/// A new language-netural version resource.
///
public VersionResource()
: base(IntPtr.Zero,
IntPtr.Zero,
new ResourceId(Kernel32.ResourceTypes.RT_VERSION),
new ResourceId(1),
ResourceUtil.USENGLISHLANGID,
0)
{
_header.Header = new Kernel32.RESOURCE_HEADER(_fixedfileinfo.Size);
}
///
/// Read a version resource from a previously loaded module.
///
/// Module handle.
/// Pointer to the beginning of the resource.
/// Pointer to the end of the resource.
internal override IntPtr Read(IntPtr hModule, IntPtr lpRes)
{
_resources.Clear();
IntPtr pFixedFileInfo = _header.Read(lpRes);
if (_header.Header.wValueLength != 0)
{
_fixedfileinfo = new FixedFileInfo();
_fixedfileinfo.Read(pFixedFileInfo);
}
IntPtr pChild = ResourceUtil.Align(pFixedFileInfo.ToInt32() + _header.Header.wValueLength);
while (pChild.ToInt32() < (lpRes.ToInt32() + _header.Header.wLength))
{
ResourceTableHeader rc = new ResourceTableHeader(pChild);
switch (rc.Key)
{
case "StringFileInfo":
StringFileInfo sr = new StringFileInfo(pChild);
rc = sr;
break;
default:
rc = new VarFileInfo(pChild);
break;
}
_resources.Add(rc.Key, rc);
pChild = ResourceUtil.Align(pChild.ToInt32() + rc.Header.wLength);
}
return new IntPtr(lpRes.ToInt32() + _header.Header.wLength);
}
///
/// String representation of the file version.
///
public string FileVersion
{
get
{
return _fixedfileinfo.FileVersion;
}
set
{
_fixedfileinfo.FileVersion = value;
}
}
///
/// String representation of the protect version.
///
public string ProductVersion
{
get
{
return _fixedfileinfo.ProductVersion;
}
set
{
_fixedfileinfo.ProductVersion = value;
}
}
///
/// Write this version resource to a binary stream.
///
/// Binary stream.
internal override void Write(BinaryWriter w)
{
long headerPos = w.BaseStream.Position;
_header.Write(w);
if (_fixedfileinfo != null)
{
_fixedfileinfo.Write(w);
}
Dictionary.Enumerator resourceEnum = _resources.GetEnumerator();
while (resourceEnum.MoveNext())
{
resourceEnum.Current.Value.Write(w);
}
ResourceUtil.WriteAt(w, w.BaseStream.Position - headerPos, headerPos);
}
///
/// Returns an entry within this resource table.
///
/// Entry key.
/// A resource table.
public ResourceTableHeader this[string key]
{
get
{
return Resources[key];
}
set
{
Resources[key] = value;
}
}
///
/// Return string representation of the version resource.
///
///
public override string ToString()
{
StringBuilder sb = new StringBuilder();
if (_fixedfileinfo != null)
{
sb.Append(_fixedfileinfo.ToString());
}
sb.AppendLine("BEGIN");
Dictionary.Enumerator resourceEnum = _resources.GetEnumerator();
while (resourceEnum.MoveNext())
{
sb.Append(resourceEnum.Current.Value.ToString(1));
}
sb.AppendLine("END");
return sb.ToString();
}
}
}