From cc72c11f4f705064ae34cd37d75983f419632dbc Mon Sep 17 00:00:00 2001 From: kichik Date: Wed, 3 Oct 2007 13:31:56 +0000 Subject: [PATCH] moved icon related functions to icon.cpp git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@5304 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/SConscript | 1 + Source/build.cpp | 1 + Source/icon.cpp | 273 ++++++++++++++++++++++++++++++++++++++++++++++ Source/icon.h | 30 +++++ Source/script.cpp | 1 + Source/util.cpp | 263 -------------------------------------------- Source/util.h | 10 -- 7 files changed, 306 insertions(+), 273 deletions(-) create mode 100644 Source/icon.cpp create mode 100644 Source/icon.h diff --git a/Source/SConscript b/Source/SConscript index 8d94a9c1..505e4383 100644 --- a/Source/SConscript +++ b/Source/SConscript @@ -10,6 +10,7 @@ makensis_files = Split(""" dirreader.cpp fileform.cpp growbuf.cpp + icon.cpp lang.cpp lineparse.cpp makenssi.cpp diff --git a/Source/build.cpp b/Source/build.cpp index 1b6e1688..e0362021 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -26,6 +26,7 @@ #include "writer.h" #include "crc32.h" #include "manifest.h" +#include "icon.h" #include diff --git a/Source/icon.cpp b/Source/icon.cpp new file mode 100644 index 00000000..a2f332a5 --- /dev/null +++ b/Source/icon.cpp @@ -0,0 +1,273 @@ +#include "Platform.h" +#include "util.h" +#include "lang.h" + +#include +#include + +using namespace std; + +extern int g_display_errors; +extern FILE *g_output; + +// Icon editing structures +typedef struct { + WORD wReserved; + WORD wIsIcon; + WORD wCount; +} IconGroupHeader; + +typedef struct { + BYTE bWidth; + BYTE bHeight; + BYTE bPaletteEntries; + BYTE bReserved; + WORD wPlanes; + WORD wBitsPerPixel; + DWORD dwRawSize; + DWORD dwImageOffset; +} FileIconGroupEntry; + +typedef struct { + BYTE bWidth; + BYTE bHeight; + BYTE bPaletteEntries; + BYTE bReserved; + WORD wPlanes; + WORD wBitsPerPixel; + DWORD dwRawSize; + WORD wRsrcId; +} RsrcIconGroupEntry; + +#define SIZEOF_RSRC_ICON_GROUP_ENTRY 14 + +static FILE * open_icon(const char* filename, IconGroupHeader *igh) +{ + FILE* f = FOPEN(filename, "rb"); + if (!f) + throw runtime_error("can't open file"); + + if (!fread(igh, sizeof(IconGroupHeader), 1, f)) + throw runtime_error("unable to read file"); + + FIX_ENDIAN_INT16_INPLACE(igh->wIsIcon); + FIX_ENDIAN_INT16_INPLACE(igh->wReserved); + FIX_ENDIAN_INT16_INPLACE(igh->wCount); + + if (igh->wIsIcon != 1 || igh->wReserved != 0) + throw runtime_error("invalid icon file"); + + return f; +} + +// replace_icon, must get an initialized resource editor +void replace_icon(CResourceEditor* re, WORD wIconId, const char* filename) +{ + IconGroupHeader igh, *new_igh; + FILE *f = open_icon(filename, &igh); + + BYTE* rsrcIconGroup = (BYTE*)malloc(sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY); + if (!rsrcIconGroup) throw bad_alloc(); + + CopyMemory(rsrcIconGroup, &igh, sizeof(IconGroupHeader)); + + new_igh = (IconGroupHeader *) rsrcIconGroup; + FIX_ENDIAN_INT16_INPLACE(new_igh->wIsIcon); + FIX_ENDIAN_INT16_INPLACE(new_igh->wReserved); + FIX_ENDIAN_INT16_INPLACE(new_igh->wCount); + + RsrcIconGroupEntry* ige = (RsrcIconGroupEntry*)(rsrcIconGroup + sizeof(IconGroupHeader)); + + int i = 1; + + // Delete old icons + while (re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i++), NSIS_DEFAULT_LANG, 0, 0)); + + for (i = 0; i < igh.wCount; i++) { + fread(ige, sizeof(FileIconGroupEntry)-sizeof(DWORD), 1, f); + + DWORD dwRawSize = FIX_ENDIAN_INT32(ige->dwRawSize); + + ige->wRsrcId = FIX_ENDIAN_INT16(i + 1); + + DWORD dwOffset; + fread(&dwOffset, sizeof(DWORD), 1, f); + + FIX_ENDIAN_INT32_INPLACE(dwOffset); + + fpos_t pos; + fgetpos(f, &pos); + + if (fseek(f, dwOffset, SEEK_SET)) { + free(rsrcIconGroup); + throw runtime_error("corrupted icon file, too small"); + } + BYTE* iconData = (BYTE*)malloc(dwRawSize); + if (!iconData) { + free(rsrcIconGroup); + throw bad_alloc(); + } + fread(iconData, sizeof(BYTE), dwRawSize, f); + re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i+1), NSIS_DEFAULT_LANG, iconData, dwRawSize); + free(iconData); + + fsetpos(f, &pos); + + // Seems like the compiler refuses to increase the pointer by just 14. + // If you'll replace this line by ige++ you will get unwanted results. + ige = (RsrcIconGroupEntry*)((BYTE*)ige + SIZEOF_RSRC_ICON_GROUP_ENTRY); + } + + fclose(f); + + re->UpdateResourceA(RT_GROUP_ICON, MAKEINTRESOURCE(wIconId), NSIS_DEFAULT_LANG, rsrcIconGroup, sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY); + + free(rsrcIconGroup); +} + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +// returns the data of the uninstaller icon that should replace the installer icon data +unsigned char* generate_uninstall_icon_data(const char* filename, size_t &size) +{ + int i; + + IconGroupHeader igh; + FILE *f = open_icon(filename, &igh); + + int iNewIconSize = 0; + FileIconGroupEntry ige; + + DWORD* offsets = (DWORD*)malloc(sizeof(DWORD)*igh.wCount); + DWORD* rawSizes = (DWORD*)malloc(sizeof(DWORD)*igh.wCount); + if (!offsets || !rawSizes) throw bad_alloc(); + + for (i = 0; i < igh.wCount; i++) { + if (!fread(&ige, sizeof(FileIconGroupEntry), 1, f)) throw runtime_error("unable to read file"); + offsets[i] = ige.dwImageOffset; + rawSizes[i] = ige.dwRawSize; + iNewIconSize += FIX_ENDIAN_INT32(ige.dwRawSize); + } + + // Before each icon come two DWORDs, one for size and the other for offset (set later) + // The last size is 0, no offset + iNewIconSize += sizeof(DWORD)*(1 + igh.wCount*2); + + BYTE* pbUninstIcon = (BYTE*)malloc(iNewIconSize); + if (!pbUninstIcon) throw bad_alloc(); + + BYTE* seeker = pbUninstIcon; + + for (i = 0; i < igh.wCount; i++) { + *(DWORD*)seeker = rawSizes[i]; + seeker += sizeof(DWORD); + *(DWORD*)seeker = 0; + seeker += sizeof(DWORD); + fseek(f, FIX_ENDIAN_INT32(offsets[i]), SEEK_SET); + fread(seeker, 1, FIX_ENDIAN_INT32(rawSizes[i]), f); + seeker += FIX_ENDIAN_INT32(rawSizes[i]); + } + + // This is how we know there are no more icons (size = 0) + *(DWORD*)seeker = 0; + + free(offsets); + free(rawSizes); + + size = iNewIconSize; + + return pbUninstIcon; +} + +// Added by Amir Szekely 11th July 2002 +#define MY_ASSERT(x, y) if (x) {if (g_display_errors) fprintf(g_output,"\nError finding icon resources: %s -- failing!\n", y);return 0;} + +int find_in_dir(PRESOURCE_DIRECTORY rd, WORD id) { + WORD i = FIX_ENDIAN_INT16(rd->Header.NumberOfNamedEntries); + WORD l = i + FIX_ENDIAN_INT16(rd->Header.NumberOfIdEntries); + + for (; i < l; i++) { + if (FIX_ENDIAN_INT16(rd->Entries[i].UName.Id) == id) { + return i; + } + } + + return -1; +} + +// Fill the array of icons for uninstall with their offsets +// Returns zero on failure +int generate_unicons_offsets(unsigned char* exeHeader, size_t exeHeaderSize, unsigned char* uninstIconData) { + DWORD dwResourceSectionVA; + + PIMAGE_NT_HEADERS ntHeaders = CResourceEditor::GetNTHeaders(exeHeader); + PRESOURCE_DIRECTORY rdRoot = CResourceEditor::GetResourceDirectory(exeHeader, exeHeaderSize, ntHeaders, &dwResourceSectionVA); + + int idx = find_in_dir(rdRoot, (WORD) (long) RT_ICON); + MY_ASSERT(idx < 0, "no icons found"); + MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rdEntry = rdRoot->Entries[idx]; + FIX_ENDIAN_INT32_INPLACE(rdEntry.UOffset.OffsetToData); + MY_ASSERT(!rdEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory"); + + PRESOURCE_DIRECTORY rdIcons = PRESOURCE_DIRECTORY(rdEntry.UOffset.DirectoryOffset.OffsetToDirectory + DWORD(rdRoot)); + + MY_ASSERT((size_t)rdIcons - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer"); + + WORD wNumberOfEntries = FIX_ENDIAN_INT16(rdIcons->Header.NumberOfIdEntries); + + MY_ASSERT(wNumberOfEntries == 0, "no icons found"); + + for (WORD i = 0; i < wNumberOfEntries; i++) { // Icons dir can't have named entries + MY_IMAGE_RESOURCE_DIRECTORY_ENTRY icoEntry = rdIcons->Entries[i]; + FIX_ENDIAN_INT32_INPLACE(icoEntry.UOffset.OffsetToData); + + MY_ASSERT(!icoEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory"); + PRESOURCE_DIRECTORY rd = PRESOURCE_DIRECTORY(icoEntry.UOffset.DirectoryOffset.OffsetToDirectory + DWORD(rdRoot)); + + MY_ASSERT((size_t)rd - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer"); + + MY_IMAGE_RESOURCE_DIRECTORY_ENTRY datEntry = rd->Entries[0]; + FIX_ENDIAN_INT32_INPLACE(datEntry.UOffset.OffsetToData); + + MY_ASSERT(datEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory"); + + PIMAGE_RESOURCE_DATA_ENTRY rde = PIMAGE_RESOURCE_DATA_ENTRY(datEntry.UOffset.OffsetToData + DWORD(rdRoot)); + + MY_ASSERT((size_t)rde - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer"); + + // find icon to replace + LPBYTE seeker = uninstIconData; + while (*seeker) { + DWORD dwSize = *(DWORD*)seeker; + seeker += sizeof(DWORD); + DWORD dwOffset = *(DWORD*)seeker; + // if we haven't set the offset yet and the size is the same, it's a match + if (!dwOffset && dwSize == rde->Size) + break; + + seeker += FIX_ENDIAN_INT32(dwSize) + sizeof(DWORD); + + // reached the end of the list and no match + MY_ASSERT(!*seeker, "installer, uninstaller icon size mismatch - see the Icon instruction's documentation for more information"); + } + + // Set offset + DWORD dwOffset = FIX_ENDIAN_INT32(rde->OffsetToData) + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader); + *(LPDWORD) seeker = FIX_ENDIAN_INT32(dwOffset); + + MY_ASSERT(dwOffset > exeHeaderSize || dwOffset < (DWORD)rdRoot - (DWORD)exeHeader, "invalid data offset - icon resource probably compressed"); + } + + LPBYTE seeker = uninstIconData; + while (*seeker) { + DWORD dwSize = *(DWORD*)seeker; + seeker += sizeof(DWORD); + DWORD dwOffset = *(DWORD*)seeker; + seeker += sizeof(DWORD); + // offset isn't set which means we found no match for this one + MY_ASSERT(!dwOffset, "installer, uninstaller number of icons doesn't match - see the Icon instruction's documentation for more information"); + seeker += FIX_ENDIAN_INT32(dwSize); + } + + return 1; +} +#endif // NSIS_CONFIG_UNINSTALL_SUPPORT \ No newline at end of file diff --git a/Source/icon.h b/Source/icon.h new file mode 100644 index 00000000..08634a3f --- /dev/null +++ b/Source/icon.h @@ -0,0 +1,30 @@ +/* + * icon.h + * + * This file is a part of NSIS. + * + * Copyright (C) 1999-2007 Nullsoft and Contributors + * + * Licensed under the zlib/libpng license (the "License"); + * you may not use this file except in compliance with the License. + * + * Licence details can be found in the file COPYING. + * + * This software is provided 'as-is', without any express or implied + * warranty. + */ + +#ifndef _ICON_H_ +#define _ICON_H_ + +// reads icon file filename and places its icons in the resource wIconId using resource editor re +void replace_icon(CResourceEditor* re, WORD wIconId, const char* filename); + +#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT +// returns the data of the uninstaller icon (inside filename) that should replace the installer icon data +unsigned char* generate_uninstall_icon_data(const char* filename, size_t &size); +// Fill the array of icons for uninstall with their offsets +int generate_unicons_offsets(unsigned char* exeHeader, size_t exeHeaderSize, unsigned char* uninstIconData); +#endif//NSIS_CONFIG_UNINSTALL_SUPPORT + +#endif//_ICON_H_ diff --git a/Source/script.cpp b/Source/script.cpp index 05b583f4..34b23807 100644 --- a/Source/script.cpp +++ b/Source/script.cpp @@ -26,6 +26,7 @@ #include "lang.h" #include "dirreader.h" #include "version.h" +#include "icon.h" #include "exehead/resource.h" #include // for assert(3) #include diff --git a/Source/util.cpp b/Source/util.cpp index c1d7c69a..25e515e6 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -130,269 +130,6 @@ int update_bitmap(CResourceEditor* re, WORD id, const char* filename, int width/ return 0; } -// Added by Amir Szekely 8th July 2002 -// Icon editing structures -typedef struct { - WORD wReserved; - WORD wIsIcon; - WORD wCount; -} IconGroupHeader; - -typedef struct { - BYTE bWidth; - BYTE bHeight; - BYTE bPaletteEntries; - BYTE bReserved; - WORD wPlanes; - WORD wBitsPerPixel; - DWORD dwRawSize; - DWORD dwImageOffset; -} FileIconGroupEntry; - -typedef struct { - BYTE bWidth; - BYTE bHeight; - BYTE bPaletteEntries; - BYTE bReserved; - WORD wPlanes; - WORD wBitsPerPixel; - DWORD dwRawSize; - WORD wRsrcId; -} RsrcIconGroupEntry; - -#define SIZEOF_RSRC_ICON_GROUP_ENTRY 14 - -static FILE * open_icon(const char* filename, IconGroupHeader *igh) -{ - FILE* f = FOPEN(filename, "rb"); - if (!f) - throw runtime_error("can't open file"); - - if (!fread(igh, sizeof(IconGroupHeader), 1, f)) - throw runtime_error("unable to read file"); - - FIX_ENDIAN_INT16_INPLACE(igh->wIsIcon); - FIX_ENDIAN_INT16_INPLACE(igh->wReserved); - FIX_ENDIAN_INT16_INPLACE(igh->wCount); - - if (igh->wIsIcon != 1 || igh->wReserved != 0) - throw runtime_error("invalid icon file"); - - return f; -} - -// replace_icon, must get an initialized resource editor -void replace_icon(CResourceEditor* re, WORD wIconId, const char* filename) -{ - IconGroupHeader igh, *new_igh; - FILE *f = open_icon(filename, &igh); - - BYTE* rsrcIconGroup = (BYTE*)malloc(sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY); - if (!rsrcIconGroup) throw bad_alloc(); - - CopyMemory(rsrcIconGroup, &igh, sizeof(IconGroupHeader)); - - new_igh = (IconGroupHeader *) rsrcIconGroup; - FIX_ENDIAN_INT16_INPLACE(new_igh->wIsIcon); - FIX_ENDIAN_INT16_INPLACE(new_igh->wReserved); - FIX_ENDIAN_INT16_INPLACE(new_igh->wCount); - - RsrcIconGroupEntry* ige = (RsrcIconGroupEntry*)(rsrcIconGroup + sizeof(IconGroupHeader)); - - int i = 1; - - // Delete old icons - while (re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i++), NSIS_DEFAULT_LANG, 0, 0)); - - for (i = 0; i < igh.wCount; i++) { - fread(ige, sizeof(FileIconGroupEntry)-sizeof(DWORD), 1, f); - - DWORD dwRawSize = FIX_ENDIAN_INT32(ige->dwRawSize); - - ige->wRsrcId = FIX_ENDIAN_INT16(i + 1); - - DWORD dwOffset; - fread(&dwOffset, sizeof(DWORD), 1, f); - - FIX_ENDIAN_INT32_INPLACE(dwOffset); - - fpos_t pos; - fgetpos(f, &pos); - - if (fseek(f, dwOffset, SEEK_SET)) { - free(rsrcIconGroup); - throw runtime_error("corrupted icon file, too small"); - } - BYTE* iconData = (BYTE*)malloc(dwRawSize); - if (!iconData) { - free(rsrcIconGroup); - throw bad_alloc(); - } - fread(iconData, sizeof(BYTE), dwRawSize, f); - re->UpdateResourceA(RT_ICON, MAKEINTRESOURCE(i+1), NSIS_DEFAULT_LANG, iconData, dwRawSize); - free(iconData); - - fsetpos(f, &pos); - - // Seems like the compiler refuses to increase the pointer by just 14. - // If you'll replace this line by ige++ you will get unwanted results. - ige = (RsrcIconGroupEntry*)((BYTE*)ige + SIZEOF_RSRC_ICON_GROUP_ENTRY); - } - - fclose(f); - - re->UpdateResourceA(RT_GROUP_ICON, MAKEINTRESOURCE(wIconId), NSIS_DEFAULT_LANG, rsrcIconGroup, sizeof(IconGroupHeader) + igh.wCount*SIZEOF_RSRC_ICON_GROUP_ENTRY); - - free(rsrcIconGroup); -} - -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT -// returns the data of the uninstaller icon that should replace the installer icon data -unsigned char* generate_uninstall_icon_data(const char* filename, size_t &size) -{ - int i; - - IconGroupHeader igh; - FILE *f = open_icon(filename, &igh); - - int iNewIconSize = 0; - FileIconGroupEntry ige; - - DWORD* offsets = (DWORD*)malloc(sizeof(DWORD)*igh.wCount); - DWORD* rawSizes = (DWORD*)malloc(sizeof(DWORD)*igh.wCount); - if (!offsets || !rawSizes) throw bad_alloc(); - - for (i = 0; i < igh.wCount; i++) { - if (!fread(&ige, sizeof(FileIconGroupEntry), 1, f)) throw runtime_error("unable to read file"); - offsets[i] = ige.dwImageOffset; - rawSizes[i] = ige.dwRawSize; - iNewIconSize += FIX_ENDIAN_INT32(ige.dwRawSize); - } - - // Before each icon come two DWORDs, one for size and the other for offset (set later) - // The last size is 0, no offset - iNewIconSize += sizeof(DWORD)*(1 + igh.wCount*2); - - BYTE* pbUninstIcon = (BYTE*)malloc(iNewIconSize); - if (!pbUninstIcon) throw bad_alloc(); - - BYTE* seeker = pbUninstIcon; - - for (i = 0; i < igh.wCount; i++) { - *(DWORD*)seeker = rawSizes[i]; - seeker += sizeof(DWORD); - *(DWORD*)seeker = 0; - seeker += sizeof(DWORD); - fseek(f, FIX_ENDIAN_INT32(offsets[i]), SEEK_SET); - fread(seeker, 1, FIX_ENDIAN_INT32(rawSizes[i]), f); - seeker += FIX_ENDIAN_INT32(rawSizes[i]); - } - - // This is how we know there are no more icons (size = 0) - *(DWORD*)seeker = 0; - - free(offsets); - free(rawSizes); - - size = iNewIconSize; - - return pbUninstIcon; -} - -// Added by Amir Szekely 11th July 2002 -#define MY_ASSERT(x, y) if (x) {if (g_display_errors) fprintf(g_output,"\nError finding icon resources: %s -- failing!\n", y);return 0;} - -int find_in_dir(PRESOURCE_DIRECTORY rd, WORD id) { - WORD i = FIX_ENDIAN_INT16(rd->Header.NumberOfNamedEntries); - WORD l = i + FIX_ENDIAN_INT16(rd->Header.NumberOfIdEntries); - - for (; i < l; i++) { - if (FIX_ENDIAN_INT16(rd->Entries[i].UName.Id) == id) { - return i; - } - } - - return -1; -} - -// Fill the array of icons for uninstall with their offsets -// Returns zero on failure -int generate_unicons_offsets(unsigned char* exeHeader, size_t exeHeaderSize, unsigned char* uninstIconData) { - DWORD dwResourceSectionVA; - - PIMAGE_NT_HEADERS ntHeaders = CResourceEditor::GetNTHeaders(exeHeader); - PRESOURCE_DIRECTORY rdRoot = CResourceEditor::GetResourceDirectory(exeHeader, exeHeaderSize, ntHeaders, &dwResourceSectionVA); - - int idx = find_in_dir(rdRoot, (WORD) (long) RT_ICON); - MY_ASSERT(idx < 0, "no icons found"); - MY_IMAGE_RESOURCE_DIRECTORY_ENTRY rdEntry = rdRoot->Entries[idx]; - FIX_ENDIAN_INT32_INPLACE(rdEntry.UOffset.OffsetToData); - MY_ASSERT(!rdEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory"); - - PRESOURCE_DIRECTORY rdIcons = PRESOURCE_DIRECTORY(rdEntry.UOffset.DirectoryOffset.OffsetToDirectory + DWORD(rdRoot)); - - MY_ASSERT((size_t)rdIcons - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer"); - - WORD wNumberOfEntries = FIX_ENDIAN_INT16(rdIcons->Header.NumberOfIdEntries); - - MY_ASSERT(wNumberOfEntries == 0, "no icons found"); - - for (WORD i = 0; i < wNumberOfEntries; i++) { // Icons dir can't have named entries - MY_IMAGE_RESOURCE_DIRECTORY_ENTRY icoEntry = rdIcons->Entries[i]; - FIX_ENDIAN_INT32_INPLACE(icoEntry.UOffset.OffsetToData); - - MY_ASSERT(!icoEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory"); - PRESOURCE_DIRECTORY rd = PRESOURCE_DIRECTORY(icoEntry.UOffset.DirectoryOffset.OffsetToDirectory + DWORD(rdRoot)); - - MY_ASSERT((size_t)rd - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer"); - - MY_IMAGE_RESOURCE_DIRECTORY_ENTRY datEntry = rd->Entries[0]; - FIX_ENDIAN_INT32_INPLACE(datEntry.UOffset.OffsetToData); - - MY_ASSERT(datEntry.UOffset.DirectoryOffset.DataIsDirectory, "bad resource directory"); - - PIMAGE_RESOURCE_DATA_ENTRY rde = PIMAGE_RESOURCE_DATA_ENTRY(datEntry.UOffset.OffsetToData + DWORD(rdRoot)); - - MY_ASSERT((size_t)rde - (size_t)exeHeader > exeHeaderSize, "corrupted EXE - invalid pointer"); - - // find icon to replace - LPBYTE seeker = uninstIconData; - while (*seeker) { - DWORD dwSize = *(DWORD*)seeker; - seeker += sizeof(DWORD); - DWORD dwOffset = *(DWORD*)seeker; - // if we haven't set the offset yet and the size is the same, it's a match - if (!dwOffset && dwSize == rde->Size) - break; - - seeker += FIX_ENDIAN_INT32(dwSize) + sizeof(DWORD); - - // reached the end of the list and no match - MY_ASSERT(!*seeker, "installer, uninstaller icon size mismatch - see the Icon instruction's documentation for more information"); - } - - // Set offset - DWORD dwOffset = FIX_ENDIAN_INT32(rde->OffsetToData) + DWORD(rdRoot) - dwResourceSectionVA - DWORD(exeHeader); - *(LPDWORD) seeker = FIX_ENDIAN_INT32(dwOffset); - - MY_ASSERT(dwOffset > exeHeaderSize || dwOffset < (DWORD)rdRoot - (DWORD)exeHeader, "invalid data offset - icon resource probably compressed"); - } - - LPBYTE seeker = uninstIconData; - while (*seeker) { - DWORD dwSize = *(DWORD*)seeker; - seeker += sizeof(DWORD); - DWORD dwOffset = *(DWORD*)seeker; - seeker += sizeof(DWORD); - // offset isn't set which means we found no match for this one - MY_ASSERT(!dwOffset, "installer, uninstaller number of icons doesn't match - see the Icon instruction's documentation for more information"); - seeker += FIX_ENDIAN_INT32(dwSize); - } - - return 1; -} -#endif // NSIS_CONFIG_UNINSTALL_SUPPORT - #ifndef _WIN32 char *CharPrev(const char *s, const char *p) { if (!s || !p || p < s) diff --git a/Source/util.h b/Source/util.h index 98c17189..9f1a480e 100644 --- a/Source/util.h +++ b/Source/util.h @@ -36,16 +36,6 @@ extern void dopause(void); // If width or height are specified it will also make sure the bitmap is in that size int update_bitmap(CResourceEditor* re, WORD id, const char* filename, int width=0, int height=0, int maxbpp=0); -// reads icon file filename and places its icons in the resource wIconId using resource editor re -void replace_icon(CResourceEditor* re, WORD wIconId, const char* filename); - -#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT -// returns the data of the uninstaller icon (inside filename) that should replace the installer icon data -unsigned char* generate_uninstall_icon_data(const char* filename, size_t &size); -// Fill the array of icons for uninstall with their offsets -int generate_unicons_offsets(unsigned char* exeHeader, size_t exeHeaderSize, unsigned char* uninstIconData); -#endif//NSIS_CONFIG_UNINSTALL_SUPPORT - size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm); bool GetDLLVersion(const std::string& filepath, DWORD& high, DWORD& low);