/// <summary> /// Delete a resource from the WinPE image. /// Important note: If the target resource was added via ADD or UPDATE /// in this class (and via BeginUpdateResource in general), this process /// fails with an error 87 (bad parameter). /// I have no idea why at this point. /// If the resource in question already existed within the file (defined at /// compile time, for instance), then there usually is no problem deleting it. /// </summary> /// <param name="ResType"></param> /// <param name="ResName"></param> /// <param name="wLanguage"></param> /// <remarks></remarks> public void Delete(object ResType, object ResName, short wLanguage = 0) { int Result; // Warning!!! Optional parameters not supported IntPtr hUpdate = ResourceAPIs.BeginUpdateResource(this.FileName, 0); if (hUpdate.ToInt32() == 0) { throw new ResWriteCantOpenException(this.FileName, Marshal.GetLastWin32Error()); } if (ResType is string) { // Restype is a resource name if (ResName is string) { Result = ResourceAPIs.UpdateResource(hUpdate, ResType.ToString().ToUpper(), ResName.ToString().ToUpper(), wLanguage, IntPtr.Zero, 0); } else { Result = ResourceAPIs.UpdateResource(hUpdate, ResType.ToString().ToUpper(), int.Parse(ResName.ToString()), wLanguage, IntPtr.Zero, 0); } } else { // Restype is a numeric resource ID if (ResName is string) { Result = ResourceAPIs.UpdateResource(hUpdate, int.Parse(ResType.ToString()), ResName.ToString().ToUpper(), wLanguage, IntPtr.Zero, 0); } else { Result = ResourceAPIs.UpdateResource(hUpdate, int.Parse(ResType.ToString()), int.Parse(ResName.ToString()), wLanguage, IntPtr.Zero, 0); } } if (Result == 0) { throw new ResWriteCantDeleteException(Marshal.GetLastWin32Error()); } Result = ResourceAPIs.EndUpdateResource(hUpdate, 0); if (Result == 0) { throw new ResWriteCantEndException(Marshal.GetLastWin32Error()); } }
// '' <summary> // '' Update a resource using a raw byte buffer // '' </summary> // '' <param name="ResType"></param> // '' <param name="ResName"></param> // '' <param name="wLanguage"></param> // '' <param name="NewValue"></param> // '' <remarks></remarks> public void Update(object ResType, object ResName, short wLanguage, ref List <byte> NewValue) { int Result; IntPtr hUpdate = ResourceAPIs.BeginUpdateResource(this.FileName, 0); if (hUpdate == IntPtr.Zero) { throw new ResWriteCantOpenException(this.FileName, Marshal.GetLastWin32Error()); } // guarantee data is aligned to 4 byte boundary // not sure if this is strictly necessary, but it's documented int l = NewValue.Count; int Mod = (l % 4); if ((Mod > 0)) { l += 4 - Mod; } byte[] buf = new byte[l]; NewValue.ToArray().CopyTo(buf, 0); // important note, The Typename and Resourcename are // written as UPPER CASE. I'm not sure why but this appears to // be required for the FindResource and FindResourceEx API calls to // be able to work properly. Otherwise, they'll never find the resource // entries... if (ResType is string) { // Restype is a resource type name if (ResName is string) { Result = ResourceAPIs.UpdateResource(hUpdate, ResType.ToString().ToUpper(), ResName.ToString().ToUpper(), wLanguage, buf, l); } else { Result = ResourceAPIs.UpdateResource(hUpdate, ResType.ToString().ToUpper(), int.Parse(ResName.ToString()), wLanguage, buf, l); } } else { // Restype is a numeric resource ID if (ResName is string) { Result = ResourceAPIs.UpdateResource(hUpdate, int.Parse(ResType.ToString()), ResName.ToString().ToUpper(), wLanguage, buf, l); } else { Result = ResourceAPIs.UpdateResource(hUpdate, int.Parse(ResType.ToString()), int.Parse(ResName.ToString()), wLanguage, buf, l); } } if ((Result == 0)) { throw new ResWriteCantUpdateException(Marshal.GetLastWin32Error()); } Result = ResourceAPIs.EndUpdateResource(hUpdate, 0); if ((Result == 0)) { throw new ResWriteCantEndException(Marshal.GetLastWin32Error()); } }