Example #1
0
        // updates file resource using provided resource type, name and data
        private static void InjectResource(string outputPath, ushort resourceType,
                                           ushort resourceName, byte[] resourceData)
        {
            var updateHandle = PInvoke.BeginUpdateResource(outputPath);

            if (updateHandle == IntPtr.Zero)
            {
                var ex      = PInvoke.GetLastWin32Exception();
                var message = string.Format(Localization.InjectResourceBeginUpdateResource,
                                            outputPath, ex.Message);
                throw new IOException(message, ex);
            }

            if (!PInvoke.UpdateResource(updateHandle, resourceType,
                                        resourceName, resourceData))
            {
                PInvoke.DiscardUpdateResource(updateHandle);
                var ex      = PInvoke.GetLastWin32Exception();
                var message = string.Format(Localization.InjectResourceUpdateResource,
                                            outputPath, ex.Message);
                throw new IOException(message, ex);
            }

            if (!PInvoke.CompleteUpdateResource(updateHandle))
            {
                var ex      = PInvoke.GetLastWin32Exception();
                var message = string.Format(Localization.InjectResourceCompleteUpdateResource,
                                            outputPath, ex.Message);
                throw new IOException(message, ex);
            }
        }
Example #2
0
        private static IntPtr BeginUpdateResource(string outputPath)
        {
            var updateHandle = PInvoke.BeginUpdateResource(outputPath);

            if (updateHandle == IntPtr.Zero)
            {
                var ex      = PInvoke.GetLastWin32Exception();
                var message = string.Format(Localization.WriteOutputBeginUpdateResource,
                                            outputPath, ex.Message);
                throw new IOException(message, ex);
            }

            return(updateHandle);
        }
Example #3
0
        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();
            }
        }