JD2022-TU1/main/extern/Vestris.ResourceLib/1.2/Source/ResourceLib/Resource.cs

317 lines
9.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.IO;
namespace Vestris.ResourceLib
{
/// <summary>
/// A version resource.
/// </summary>
public abstract class Resource
{
/// <summary>
/// Resource type.
/// </summary>
protected ResourceId _type;
/// <summary>
/// Resource name.
/// </summary>
protected ResourceId _name;
/// <summary>
/// Resource language.
/// </summary>
protected UInt16 _language;
/// <summary>
/// Loaded binary nodule.
/// </summary>
protected IntPtr _hModule = IntPtr.Zero;
/// <summary>
/// Pointer to the resource.
/// </summary>
protected IntPtr _hResource = IntPtr.Zero;
/// <summary>
/// Resource size.
/// </summary>
protected int _size = 0;
/// <summary>
/// Version resource size in bytes.
/// </summary>
public int Size
{
get
{
return _size;
}
}
/// <summary>
/// Language ID.
/// </summary>
public UInt16 Language
{
get
{
return _language;
}
set
{
_language = value;
}
}
/// <summary>
/// Resource type.
/// </summary>
public ResourceId Type
{
get
{
return _type;
}
}
/// <summary>
/// String representation of the resource type.
/// </summary>
public string TypeName
{
get
{
return _type.IsIntResource()
? _type.ResourceType.ToString()
: _type.Name;
}
}
/// <summary>
/// Resource name.
/// </summary>
public ResourceId Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
/// <summary>
/// A new resource.
/// </summary>
internal Resource()
{
}
/// <summary>
/// A structured resource embedded in an executable module.
/// </summary>
/// <param name="hModule">Module handle.</param>
/// <param name="hResource">Resource handle.</param>
/// <param name="type">Resource type.</param>
/// <param name="name">Resource name.</param>
/// <param name="language">Language ID.</param>
/// <param name="size">Resource size.</param>
internal Resource(IntPtr hModule, IntPtr hResource, ResourceId type, ResourceId name, UInt16 language, int size)
{
_hModule = hModule;
_type = type;
_name = name;
_language = language;
_hResource = hResource;
_size = size;
LockAndReadResource(hModule, hResource);
}
/// <summary>
/// Lock and read the resource.
/// </summary>
/// <param name="hModule">Module handle.</param>
/// <param name="hResource">Resource handle.</param>
internal void LockAndReadResource(IntPtr hModule, IntPtr hResource)
{
if (hResource == IntPtr.Zero)
return;
IntPtr lpRes = Kernel32.LockResource(hResource);
if (lpRes == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
Read(hModule, lpRes);
}
/// <summary>
/// Load a resource from an executable (.exe or .dll) file.
/// </summary>
/// <param name="filename">An executable (.exe or .dll) file.</param>
public virtual void LoadFrom(string filename)
{
LoadFrom(filename, _type, _name, _language);
}
/// <summary>
/// Load a resource from an executable (.exe or .dll) file.
/// </summary>
/// <param name="filename">An executable (.exe or .dll) file.</param>
/// <param name="name">Resource name.</param>
/// <param name="type">Resource type.</param>
/// <param name="lang">Resource language.</param>
internal void LoadFrom(string filename, ResourceId type, ResourceId name, UInt16 lang)
{
IntPtr hModule = IntPtr.Zero;
try
{
hModule = Kernel32.LoadLibraryEx(filename, IntPtr.Zero,
Kernel32.DONT_RESOLVE_DLL_REFERENCES | Kernel32.LOAD_LIBRARY_AS_DATAFILE);
LoadFrom(hModule, type, name, lang);
}
finally
{
if (hModule != IntPtr.Zero)
Kernel32.FreeLibrary(hModule);
}
}
/// <summary>
/// Load a resource from an executable (.exe or .dll) module.
/// </summary>
/// <param name="hModule">An executable (.exe or .dll) module.</param>
/// <param name="type">Resource type.</param>
/// <param name="name">Resource name.</param>
/// <param name="lang">Resource language.</param>
internal void LoadFrom(IntPtr hModule, ResourceId type, ResourceId name, UInt16 lang)
{
if (IntPtr.Zero == hModule)
throw new Win32Exception(Marshal.GetLastWin32Error());
IntPtr hRes = Kernel32.FindResourceEx(hModule, type.Id, name.Id, lang);
if (IntPtr.Zero == hRes)
throw new Win32Exception(Marshal.GetLastWin32Error());
IntPtr hGlobal = Kernel32.LoadResource(hModule, hRes);
if (IntPtr.Zero == hGlobal)
throw new Win32Exception(Marshal.GetLastWin32Error());
IntPtr lpRes = Kernel32.LockResource(hGlobal);
if (lpRes == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
_size = Kernel32.SizeofResource(hModule, hRes);
if (_size <= 0)
throw new Win32Exception(Marshal.GetLastWin32Error());
_type = type;
_name = name;
_language = lang;
Read(hModule, lpRes);
}
/// <summary>
/// Read a resource from a previously loaded module.
/// </summary>
/// <param name="hModule">Module handle.</param>
/// <param name="lpRes">Pointer to the beginning of the resource.</param>
/// <returns>Pointer to the end of the resource.</returns>
internal abstract IntPtr Read(IntPtr hModule, IntPtr lpRes);
/// <summary>
/// Write the resource to a memory stream.
/// </summary>
/// <param name="w">Binary stream.</param>
internal abstract void Write(BinaryWriter w);
/// <summary>
/// Return resource data.
/// </summary>
/// <returns>Resource data.</returns>
public byte[] WriteAndGetBytes()
{
MemoryStream ms = new MemoryStream();
BinaryWriter w = new BinaryWriter(ms, Encoding.Default);
Write(w);
w.Close();
return ms.ToArray();
}
/// <summary>
/// Save a resource.
/// </summary>
/// <param name="filename">Name of an executable file (.exe or .dll).</param>
public virtual void SaveTo(string filename)
{
SaveTo(filename, _type, _name, _language);
}
/// <summary>
/// Save a resource to an executable (.exe or .dll) file.
/// </summary>
/// <param name="filename">Path to an executable file.</param>
/// <param name="name">Resource name.</param>
/// <param name="type">Resource type.</param>
/// <param name="langid">Language id.</param>
internal void SaveTo(string filename, ResourceId type, ResourceId name, UInt16 langid)
{
byte[] data = WriteAndGetBytes();
SaveTo(filename, type, name, langid, data);
}
/// <summary>
/// Delete a resource from an executable (.exe or .dll) file.
/// </summary>
/// <param name="filename">Path to an executable file.</param>
public virtual void DeleteFrom(string filename)
{
Delete(filename, _type, _name, _language);
}
/// <summary>
/// Delete a resource from an executable (.exe or .dll) file.
/// </summary>
/// <param name="filename">Path to an executable file.</param>
/// <param name="name">Resource name.</param>
/// <param name="type">Resource type.</param>
/// <param name="lang">Resource language.</param>
internal static void Delete(string filename, ResourceId type, ResourceId name, UInt16 lang)
{
SaveTo(filename, type, name, lang, null);
}
/// <summary>
/// Save a resource to an executable (.exe or .dll) file.
/// </summary>
/// <param name="filename">Path to an executable file.</param>
/// <param name="name">Resource name.</param>
/// <param name="type">Resource type.</param>
/// <param name="lang">Resource language.</param>
/// <param name="data">Resource data.</param>
internal static void SaveTo(string filename, ResourceId type, ResourceId name, UInt16 lang, byte[] data)
{
IntPtr h = Kernel32.BeginUpdateResource(filename, false);
if (h == IntPtr.Zero)
throw new Win32Exception(Marshal.GetLastWin32Error());
if (!Kernel32.UpdateResource(h, type.Id, name.Id,
lang, data, (data == null ? 0 : (uint)data.Length)))
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
if (!Kernel32.EndUpdateResource(h, false))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
}