using System;
using System.Runtime.InteropServices;
namespace Vanara.PInvoke
{
public static partial class Kernel32
{
/// Retrieves a handle that can be used by the UpdateResource function to add, delete, or replace resources in a binary module.
///
/// Type: LPCTSTR
///
/// The binary file in which to update resources. An application must be able to obtain write-access to this file; the file referenced by pFileName
/// cannot be currently executing. If pFileName does not specify a full path, the system searches for the file in the current directory.
///
///
///
/// Type: BOOL
///
/// Indicates whether to delete the pFileName parameter's existing resources. If this parameter is TRUE, existing resources are deleted and the
/// updated file includes only resources added with the UpdateResource function. If this parameter is FALSE, the updated file includes
/// existing resources unless they are explicitly deleted or replaced by using UpdateResource.
///
///
///
/// Type: HANDLE
///
/// If the function succeeds, the return value is a handle that can be used by the UpdateResource and EndUpdateResource functions. The
/// return value is NULL if the specified file is not a PE, the file does not exist, or the file cannot be opened for writing. To get extended
/// error information, call GetLastError.
///
///
// HANDLE WINAPI BeginUpdateResource( _In_ LPCTSTR pFileName, _In_ BOOL bDeleteExistingResources);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms648030(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms648030")]
public static extern UpdateResourceHandle BeginUpdateResource(string pFileName, [MarshalAs(UnmanagedType.Bool)] bool bDeleteExistingResources);
/// Commits or discards changes made prior to a call to UpdateResource.
///
/// Type: HANDLE
/// A module handle returned by the BeginUpdateResource function, and used by UpdateResource, referencing the file to be updated.
///
///
/// Type: BOOL
///
/// Indicates whether to write the resource updates to the file. If this parameter is TRUE, no changes are made. If it is FALSE, the
/// changes are made: the resource updates will take effect.
///
///
///
/// Type: BOOL
///
/// Returns TRUE if the function succeeds; FALSE otherwise. If the function succeeds and fDiscard is TRUE, then no resource updates
/// are made to the file; otherwise all successful resource updates are made to the file. To get extended error information, call GetLastError.
///
///
// BOOL WINAPI EndUpdateResource( _In_ HANDLE hUpdate, _In_ BOOL fDiscard);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms648032(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms648032")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EndUpdateResource([In] UpdateResourceHandle hUpdate, [MarshalAs(UnmanagedType.Bool)] bool fDiscard);
///
/// Adds, deletes, or replaces a resource in a portable executable (PE) file. There are some restrictions on resource updates in files that contain
/// Resource Configuration (RC Config) data: language-neutral (LN) files and language-specific resource (.mui) files.
///
///
/// Type: HANDLE
/// A module handle returned by the BeginUpdateResource function, referencing the file to be updated.
///
///
/// Type: LPCTSTR
///
/// The resource type to be updated. Alternatively, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is an integer value
/// representing a predefined resource type. If the first character of the string is a pound sign (#), then the remaining characters represent a decimal
/// number that specifies the integer identifier of the resource type. For example, the string "#258" represents the identifier 258.
///
/// For a list of predefined resource types, see Resource Types.
///
///
/// Type: LPCTSTR
///
/// The name of the resource to be updated. Alternatively, rather than a pointer, this parameter can be MAKEINTRESOURCE(ID), where ID is a
/// resource ID. When creating a new resource do not use a string that begins with a '#' character for this parameter.
///
///
///
/// Type: WORD
///
/// The language identifier of the resource to be updated. For a list of the primary language identifiers and sublanguage identifiers that make up a
/// language identifier, see the MAKELANGID macro.
///
///
///
/// Type: LPVOID
///
/// The resource data to be inserted into the file indicated by hUpdate. If the resource is one of the predefined types, the data must be valid and
/// properly aligned. Note that this is the raw binary data to be stored in the file indicated by hUpdate, not the data provided by LoadIcon,
/// LoadString, or other resource-specific load functions. All data containing strings or text must be in Unicode format. lpData must not point to
/// ANSI data.
///
/// If lpData is NULL and cbData is 0, the specified resource is deleted from the file indicated by hUpdate.
///
///
/// Type: DWORD
/// The size, in bytes, of the resource data at lpData.
///
///
/// Type: BOOL
/// Returns TRUE if successful or FALSE otherwise. To get extended error information, call GetLastError.
///
// BOOL WINAPI UpdateResource( _In_ HANDLE hUpdate, _In_ LPCTSTR lpType, _In_ LPCTSTR lpName, _In_ WORD wLanguage, _In_opt_ LPVOID lpData, _In_ DWORD cbData);
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms648049(v=vs.85).aspx
[DllImport(Lib.Kernel32, SetLastError = true, CharSet = CharSet.Auto)]
[PInvokeData("Winbase.h", MSDNShortId = "ms648049")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool UpdateResource([In] UpdateResourceHandle hUpdate, string lpType, string lpName, ushort wLanguage, [In] IntPtr lpData, uint cbData);
/// Provides a handle that can be used by UpdateResource.
[StructLayout(LayoutKind.Sequential)]
public struct UpdateResourceHandle : IHandle
{
private IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public UpdateResourceHandle(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static UpdateResourceHandle NULL => new UpdateResourceHandle(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(UpdateResourceHandle h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator UpdateResourceHandle(IntPtr h) => new UpdateResourceHandle(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(UpdateResourceHandle h1, UpdateResourceHandle h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(UpdateResourceHandle h1, UpdateResourceHandle h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is UpdateResourceHandle h ? handle == h.handle : false;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
}
}