public PeContainer(string filename, ushort groupIconName) { ValidateFilename(filename); // load pe var datafile = PInvoke.LoadDatafile(filename); if (datafile == IntPtr.Zero) throw new Win32Exception("Unable to load datafile", PInvoke.GetLastWin32Exception()); using (var disposableUpdate = new PInvoke.DisposableHandle(datafile, PInvoke.FreeLibrary)) { // load group icon data var groupIconBytes = PInvoke.LoadResourceBytes(datafile, (ushort)PInvoke.ResourceType.GROUP_ICON, groupIconName); // parse directory from data Directory = new PeDirectory(groupIconBytes); Images = new IconImage[Directory.Entries.Length]; // parse images from data for (var i = 0; i < Directory.Entries.Length; i++) { var imageBytes = PInvoke.LoadResourceBytes(datafile, (ushort)PInvoke.ResourceType.ICON, Directory.Entries[i].Id); Images[i] = new IconImage(imageBytes); } disposableUpdate.SuppressDispose(); } }
private static void WriteInjectOutput(InjectArgs args) { // load resource data var resourceData = ReadResource(args.ResourcePath); // try to copy pe TryCopySource(args.SourcePath, args.OutputPath); // update pe var updateHandle = BeginUpdateResource(args.OutputPath); using (var updateDisposable = new PInvoke.DisposableHandle(updateHandle, h => PInvoke.DiscardUpdateResource(updateHandle))) { UpdateResource(updateHandle, args.ResourceType, args.ResourceName, resourceData, args.OutputPath); CompleteUpdateResource(updateHandle, args.OutputPath); updateDisposable.SuppressDispose(); } }
public void ToFile(string filename, ushort groupIconName, bool arrange = true, bool overwrite = false) { ValidateFilename(filename); Validate(); var oldDirectory = GetOldDirectory(filename, groupIconName); if (overwrite && oldDirectory != null) throw new ArgumentException("Group Icon already exists", "groupIconName"); if (arrange) Arrange(filename, groupIconName); else { var indexedEntries = Directory.Entries. Select((e, i) => new KeyValuePair<int, PeDirectoryEntry>(i, e)).ToArray(); if (indexedEntries.Any(ie1 => indexedEntries.Any(ie2 => ie1.Key != ie2.Key && ie1.Value.Id == ie2.Value.Id))) throw new InvalidOperationException("Directory Entries contain the same Id"); } var datafile = PInvoke.LoadDatafile(filename); if (datafile == IntPtr.Zero) throw new Win32Exception("Unable to load datafile", PInvoke.GetLastWin32Exception()); var busyIconNames = GetBusyIconNames(filename, groupIconName); if (!arrange) { if (busyIconNames.Any(n => Directory.Entries.Any(e => e.Id == n))) throw new InvalidOperationException("Datafile already contains icons with Directory Entries Id"); } var updateHandle = PInvoke.BeginUpdateResource(filename); if (updateHandle == IntPtr.Zero) throw new Win32Exception("Unable to begin update datafile", PInvoke.GetLastWin32Exception()); using (var disposableUpdate = new PInvoke.DisposableHandle(updateHandle, PInvoke.DiscardUpdateResource)) { var groupIconBytes = Directory.ToBytes(); // update group icon if (!PInvoke.UpdateResource(updateHandle, (ushort)PInvoke.ResourceType.GROUP_ICON, groupIconName, groupIconBytes)) throw new Win32Exception("Unable to update group icon", PInvoke.GetLastWin32Exception()); // update icons for (var i = 0; i < Directory.Entries.Length; i++) if (!PInvoke.UpdateResource(updateHandle, (ushort)PInvoke.ResourceType.ICON, Directory.Entries[i].Id, Images[i].ToBytes())) throw new Win32Exception("Unable to update icon", PInvoke.GetLastWin32Exception()); // delete icons if (oldDirectory != null) { var deleteNames = oldDirectory.Entries.Select(e => e.Id).Except(Directory.Entries.Select(e => e.Id)).ToArray(); foreach (var deleteName in deleteNames) if (!PInvoke.DeleteResource(updateHandle, (ushort)PInvoke.ResourceType.ICON, deleteName)) throw new Win32Exception("Unable to remove icon", PInvoke.GetLastWin32Exception()); } if (!PInvoke.CompleteUpdateResource(updateHandle)) throw new Win32Exception("Unable to complete update datafile", PInvoke.GetLastWin32Exception()); disposableUpdate.SuppressDispose(); } }
private static void WriteDeleteOutput(DeleteArgs args) { // try copy pe TryCopySource(args.SourcePath, args.OutputPath); // update pe var updateHandle = BeginUpdateResource(args.OutputPath); using (var updateDisposable = new PInvoke.DisposableHandle(updateHandle, h => PInvoke.DiscardUpdateResource(updateHandle))) { DeleteResource(updateHandle, args.ResourceType, args.ResourceName, args.OutputPath); CompleteUpdateResource(updateHandle, args.OutputPath); updateDisposable.SuppressDispose(); } }