private static Stream OpenResource(this SafeModuleHandle module, IntPtr resourceHandle) { IntPtr globalHandle = UnsafeNativeMethods.LoadResource(module, resourceHandle); if (globalHandle == IntPtr.Zero) { throw new IOException("Failed to load resource.", new Win32Exception()); } long size = UnsafeNativeMethods.SizeofResource(module, resourceHandle); if (size == 0) { throw new IOException("Unable to retrieve resource size.", new Win32Exception()); } IntPtr data = UnsafeNativeMethods.LockResource(globalHandle); if (data == IntPtr.Zero) { throw new IOException("Failed to lock resource.", new Win32Exception()); } var resource = new SafeResourceBuffer(data, size); return(new UnmanagedMemoryStream(resource, 0, size)); }
private static SafeResourceBuffer GetResourceBuffer(HandleRef hModule, UIntPtr lpName, UIntPtr lpType) { IntPtr hresinfo = FindResource(hModule, lpName, lpType); if (hresinfo == IntPtr.Zero) { int error = Marshal.GetLastWin32Error(); if (error >= ERROR_RESOURCE_DATA_NOT_FOUND && error <= ERROR_RESOURCE_LANG_NOT_FOUND) { Win32Exception ex = new Win32Exception(error); throw new KeyNotFoundException(ex.Message, ex); } throw new Win32Exception(error); } uint size = SizeofResource(hModule, hresinfo); if (size == 0) { throw new Win32Exception(); } IntPtr hresdata = LoadResource(hModule, hresinfo); if (hresdata == IntPtr.Zero) { throw new Win32Exception(); } SafeResourceBuffer result = LockResource(hresdata); if (result == null || result.IsInvalid) { throw new OutOfMemoryException(); } result.Initialize(size); return(result); }
private static Icon LoadIconFromResource(UIntPtr lpIconName) { HandleRef hmodule = new HandleRef(null, GetModuleHandle(null)); uint totalsize; RESOURCE_ICONDIRENTRY[] entries; SafeResourceBuffer[] entrybuffers; RESOURCE_ICONDIR dir; using (SafeResourceBuffer buffer = GetResourceBuffer(hmodule, lpIconName, MAKEINTRESOURCE(RT_GROUP_ICON))) { dir = buffer.Read <RESOURCE_ICONDIR>(0); if (dir.idReserved != 0 || dir.idType != IMAGE_ICON || dir.idCount == 0) { throw new InvalidDataException("There is no icon directory in resource data."); } entries = new RESOURCE_ICONDIRENTRY[dir.idCount]; entrybuffers = new SafeResourceBuffer[dir.idCount]; uint entrysize = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIRENTRY)); ulong offset = (uint)Marshal.SizeOf(typeof(RESOURCE_ICONDIR)) - entrysize; totalsize = (uint)(Marshal.SizeOf(typeof(ICONDIR)) + (Marshal.SizeOf(typeof(ICONDIRENTRY)) * (dir.idCount - 1))); entries[0] = dir.idEntries; for (int i = 0; i < dir.idCount; i++, offset += entrysize) { if (i > 0) { entries[i] = buffer.Read <RESOURCE_ICONDIRENTRY>(offset); } uint iconsize = entries[i].dwBytesInRes; SafeResourceBuffer entrybuffer = GetResourceBuffer(hmodule, MAKEINTRESOURCE(entries[i].nID), MAKEINTRESOURCE(RT_ICON)); if (iconsize != entrybuffer.ByteLength) { throw new InvalidDataException("Reported resource size is not equal to the icon size."); } entrybuffers[i] = entrybuffer; totalsize += iconsize; } } using (SafeLocalAllocHandle iconbuffer = SafeLocalAlloc(LMEM_ZEROINIT | LMEM_FIXED, totalsize)) { using (UnmanagedMemoryStream outstream = iconbuffer.ToStream(FileAccess.ReadWrite)) { ICONDIR icondir = new ICONDIR(dir); iconbuffer.Write(0, icondir); uint iconoffset = icondir.idEntries.dwImageOffset; outstream.Position = iconoffset; uint entrysize = (uint)Marshal.SizeOf(typeof(ICONDIRENTRY)); ulong offset = (uint)Marshal.SizeOf(typeof(ICONDIR)); ICONDIRENTRY entry = icondir.idEntries; for (int i = 0; i < dir.idCount; i++, offset += entrysize) { if (i > 0) { entry = new ICONDIRENTRY(entries[i], iconoffset); iconbuffer.Write(offset, entry); } using (UnmanagedMemoryStream instream = entrybuffers[i].ToStream()) { instream.CopyTo(outstream); } if (outstream.Position != (iconoffset + entry.dwBytesInRes)) { throw new InvalidOperationException(); } iconoffset += entry.dwBytesInRes; } outstream.Position = 0; return(new Icon(outstream)); } } }