6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 // iconswap.cpp : Defines the entry point for the console application. 27 // 28 29 //Define Windows compatibility requirements 30 //XP or later 31 #define WINVER 0x0501 32 #define _WIN32_WINNT 0x0501 33 34 #include <tchar.h> 35 #include <stdio.h> 36 #include <windows.h> 37 #include <stdlib.h> 38 #include <iostream> 39 #include <malloc.h> 40 #include <sys/types.h> 41 #include <sys/stat.h> 42 #include <io.h> 43 #include <strsafe.h> 44 #include <Shellapi.h> 45 46 47 // http://msdn.microsoft.com/en-us/library/ms997538.aspx 48 49 typedef struct _ICONDIRENTRY { 50 BYTE bWidth; 51 BYTE bHeight; 52 BYTE bColorCount; 53 BYTE bReserved; 54 WORD wPlanes; 55 WORD wBitCount; 56 DWORD dwBytesInRes; 57 DWORD dwImageOffset; 58 } ICONDIRENTRY, * LPICONDIRENTRY; 59 60 typedef struct _ICONDIR { 61 WORD idReserved; 62 WORD idType; 63 WORD idCount; 64 ICONDIRENTRY idEntries[1]; 65 } ICONDIR, * LPICONDIR; 66 67 // #pragmas are used here to insure that the structure's 68 // packing in memory matches the packing of the EXE or DLL. 69 #pragma pack(push) 70 #pragma pack(2) 71 typedef struct _GRPICONDIRENTRY { 72 BYTE bWidth; 73 BYTE bHeight; 74 BYTE bColorCount; 75 BYTE bReserved; 76 WORD wPlanes; 77 WORD wBitCount; 78 DWORD dwBytesInRes; 79 WORD nID; 80 } GRPICONDIRENTRY, * LPGRPICONDIRENTRY; 81 #pragma pack(pop) 82 83 #pragma pack(push) 84 #pragma pack(2) 85 typedef struct _GRPICONDIR { 86 WORD idReserved; 87 WORD idType; 88 WORD idCount; 89 GRPICONDIRENTRY idEntries[1]; 90 } GRPICONDIR, * LPGRPICONDIR; 91 #pragma pack(pop) 92 93 void PrintError() 94 { 95 LPVOID message; 96 DWORD error = GetLastError(); 97 98 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | 99 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 100 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 101 (LPTSTR) &message, 0, NULL); 102 103 wprintf(L"%s\n", (__wchar_t *) message); // VS2017 - FIXME 104 LocalFree(message); 105 } 106 107 bool ChangeIcon(_TCHAR* iconFileName, _TCHAR* executableFileName) 108 { 109 bool result = false; 110 111 DWORD dwData = 1; 112 WORD language = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); 113 114 _TCHAR* iconExtension = wcsrchr(iconFileName, '.'); 115 if (iconExtension == NULL || wcscmp(iconExtension, L".ico") != 0) { 116 wprintf(L"Unknown icon format - please provide .ICO file.\n"); 117 return result; 118 } 119 120 HANDLE icon = CreateFile(iconFileName, GENERIC_READ, 0, NULL, 121 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 122 if (icon == INVALID_HANDLE_VALUE) { 123 PrintError(); 124 return result; 125 } 126 127 // Reading .ICO file 128 WORD idReserved, idType, idCount; 129 130 DWORD dwBytesRead; 131 ReadFile(icon, &idReserved, sizeof(WORD), &dwBytesRead, NULL); 132 ReadFile(icon, &idType, sizeof(WORD), &dwBytesRead, NULL); 133 ReadFile(icon, &idCount, sizeof(WORD), &dwBytesRead, NULL); 134 135 LPICONDIR lpid = (LPICONDIR)malloc( 136 sizeof(ICONDIR) + (sizeof(ICONDIRENTRY) * (idCount - 1))); 137 138 if (lpid == NULL) { 139 CloseHandle(icon); 140 wprintf(L"Unknown error.\n"); 141 } 142 143 lpid->idReserved = idReserved; 144 lpid->idType = idType; 145 lpid->idCount = idCount; 146 147 ReadFile(icon, &lpid->idEntries[0], sizeof(ICONDIRENTRY) * lpid->idCount, 148 &dwBytesRead, NULL); 149 150 151 LPGRPICONDIR lpgid = (LPGRPICONDIR)malloc( 152 sizeof(GRPICONDIR) + (sizeof(GRPICONDIRENTRY) * (idCount - 1))); 153 154 if (lpid == NULL) { 155 CloseHandle(icon); 156 free(lpid); 157 wprintf(L"Unknown error.\n"); 158 } 159 160 lpgid->idReserved = idReserved; 161 lpgid->idType = idType; 162 lpgid->idCount = idCount; 163 164 for(int i = 0; i < lpgid->idCount; i++) 165 { 166 lpgid->idEntries[i].bWidth = lpid->idEntries[i].bWidth; 167 lpgid->idEntries[i].bHeight = lpid->idEntries[i].bHeight; 168 lpgid->idEntries[i].bColorCount = lpid->idEntries[i].bColorCount; 169 lpgid->idEntries[i].bReserved = lpid->idEntries[i].bReserved; 170 lpgid->idEntries[i].wPlanes = lpid->idEntries[i].wPlanes; 171 lpgid->idEntries[i].wBitCount = lpid->idEntries[i].wBitCount; 172 lpgid->idEntries[i].dwBytesInRes = lpid->idEntries[i].dwBytesInRes; 173 lpgid->idEntries[i].nID = i + 1; 174 } 175 176 // Store images in .EXE 177 HANDLE update = BeginUpdateResource( executableFileName, FALSE ); 178 179 if (update == NULL) { 180 free(lpid); 181 free(lpgid); 182 CloseHandle(icon); 183 PrintError(); 184 return result; 185 } 186 187 for(int i = 0; i < lpid->idCount; i++) 188 { 189 LPBYTE lpBuffer = (LPBYTE)malloc(lpid->idEntries[i].dwBytesInRes); 190 SetFilePointer(icon, lpid->idEntries[i].dwImageOffset, 191 NULL, FILE_BEGIN); 192 ReadFile(icon, lpBuffer, lpid->idEntries[i].dwBytesInRes, 193 &dwBytesRead, NULL); 194 if (!UpdateResource(update, RT_ICON, 195 MAKEINTRESOURCE(lpgid->idEntries[i].nID), 196 language, &lpBuffer[0], lpid->idEntries[i].dwBytesInRes)) 197 { 198 free(lpBuffer); 199 free(lpid); 200 free(lpgid); 201 CloseHandle(icon); 202 PrintError(); 203 return result; 204 } 205 free(lpBuffer); 206 } 207 208 free(lpid); 209 CloseHandle(icon); 210 211 if (!UpdateResource(update, RT_GROUP_ICON, 212 MAKEINTRESOURCE(1), language, &lpgid[0], 213 (sizeof(WORD) * 3) + (sizeof(GRPICONDIRENTRY) * lpgid->idCount))) 214 { 215 free(lpgid); 216 PrintError(); 217 return result; 218 } 219 220 free(lpgid); 221 222 if (EndUpdateResource(update, FALSE) == FALSE) { 223 PrintError(); 224 return result; 225 } 226 227 result = true; 228 return result; 229 } | 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <stdio.h> 27 #include <windows.h> 28 #include <stdlib.h> 29 #include <string> 30 #include <malloc.h> 31 32 using namespace std; 33 34 // http://msdn.microsoft.com/en-us/library/ms997538.aspx 35 36 typedef struct _ICONDIRENTRY { 37 BYTE bWidth; 38 BYTE bHeight; 39 BYTE bColorCount; 40 BYTE bReserved; 41 WORD wPlanes; 42 WORD wBitCount; 43 DWORD dwBytesInRes; 44 DWORD dwImageOffset; 45 } ICONDIRENTRY, * LPICONDIRENTRY; 46 47 typedef struct _ICONDIR { 48 WORD idReserved; 49 WORD idType; 50 WORD idCount; 51 ICONDIRENTRY idEntries[1]; 52 } ICONDIR, * LPICONDIR; 53 54 // #pragmas are used here to insure that the structure's 55 // packing in memory matches the packing of the EXE or DLL. 56 #pragma pack(push) 57 #pragma pack(2) 58 59 typedef struct _GRPICONDIRENTRY { 60 BYTE bWidth; 61 BYTE bHeight; 62 BYTE bColorCount; 63 BYTE bReserved; 64 WORD wPlanes; 65 WORD wBitCount; 66 DWORD dwBytesInRes; 67 WORD nID; 68 } GRPICONDIRENTRY, * LPGRPICONDIRENTRY; 69 #pragma pack(pop) 70 71 #pragma pack(push) 72 #pragma pack(2) 73 74 typedef struct _GRPICONDIR { 75 WORD idReserved; 76 WORD idType; 77 WORD idCount; 78 GRPICONDIRENTRY idEntries[1]; 79 } GRPICONDIR, * LPGRPICONDIR; 80 #pragma pack(pop) 81 82 void PrintError() { 83 LPVOID message = NULL; 84 DWORD error = GetLastError(); 85 86 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | 87 FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error, 88 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 89 (LPTSTR) & message, 0, NULL) != 0) { 90 printf("%S", (LPTSTR) message); 91 LocalFree(message); 92 } 93 } 94 95 // Note: We do not check here that iconTarget is valid icon. 96 // Java code will already do this for us. 97 98 bool ChangeIcon(wstring iconTarget, wstring launcher) { 99 WORD language = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); 100 101 HANDLE icon = CreateFile(iconTarget.c_str(), GENERIC_READ, 0, NULL, 102 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 103 if (icon == INVALID_HANDLE_VALUE) { 104 PrintError(); 105 return false; 106 } 107 108 // Reading .ICO file 109 WORD idReserved, idType, idCount; 110 111 DWORD dwBytesRead; 112 ReadFile(icon, &idReserved, sizeof (WORD), &dwBytesRead, NULL); 113 ReadFile(icon, &idType, sizeof (WORD), &dwBytesRead, NULL); 114 ReadFile(icon, &idCount, sizeof (WORD), &dwBytesRead, NULL); 115 116 LPICONDIR lpid = (LPICONDIR) malloc( 117 sizeof (ICONDIR) + (sizeof (ICONDIRENTRY) * (idCount - 1))); 118 if (lpid == NULL) { 119 CloseHandle(icon); 120 printf("Error: Failed to allocate memory\n"); 121 return false; 122 } 123 124 lpid->idReserved = idReserved; 125 lpid->idType = idType; 126 lpid->idCount = idCount; 127 128 ReadFile(icon, &lpid->idEntries[0], sizeof (ICONDIRENTRY) * lpid->idCount, 129 &dwBytesRead, NULL); 130 131 LPGRPICONDIR lpgid = (LPGRPICONDIR) malloc( 132 sizeof (GRPICONDIR) + (sizeof (GRPICONDIRENTRY) * (idCount - 1))); 133 if (lpid == NULL) { 134 CloseHandle(icon); 135 free(lpid); 136 printf("Error: Failed to allocate memory\n"); 137 return false; 138 } 139 140 lpgid->idReserved = idReserved; 141 lpgid->idType = idType; 142 lpgid->idCount = idCount; 143 144 for (int i = 0; i < lpgid->idCount; i++) { 145 lpgid->idEntries[i].bWidth = lpid->idEntries[i].bWidth; 146 lpgid->idEntries[i].bHeight = lpid->idEntries[i].bHeight; 147 lpgid->idEntries[i].bColorCount = lpid->idEntries[i].bColorCount; 148 lpgid->idEntries[i].bReserved = lpid->idEntries[i].bReserved; 149 lpgid->idEntries[i].wPlanes = lpid->idEntries[i].wPlanes; 150 lpgid->idEntries[i].wBitCount = lpid->idEntries[i].wBitCount; 151 lpgid->idEntries[i].dwBytesInRes = lpid->idEntries[i].dwBytesInRes; 152 lpgid->idEntries[i].nID = i + 1; 153 } 154 155 // Store images in .EXE 156 HANDLE update = BeginUpdateResource(launcher.c_str(), FALSE); 157 if (update == NULL) { 158 free(lpid); 159 free(lpgid); 160 CloseHandle(icon); 161 PrintError(); 162 return false; 163 } 164 165 for (int i = 0; i < lpid->idCount; i++) { 166 LPBYTE lpBuffer = (LPBYTE) malloc(lpid->idEntries[i].dwBytesInRes); 167 SetFilePointer(icon, lpid->idEntries[i].dwImageOffset, 168 NULL, FILE_BEGIN); 169 ReadFile(icon, lpBuffer, lpid->idEntries[i].dwBytesInRes, 170 &dwBytesRead, NULL); 171 if (!UpdateResource(update, RT_ICON, 172 MAKEINTRESOURCE(lpgid->idEntries[i].nID), 173 language, &lpBuffer[0], lpid->idEntries[i].dwBytesInRes)) { 174 free(lpBuffer); 175 free(lpid); 176 free(lpgid); 177 CloseHandle(icon); 178 PrintError(); 179 return false; 180 } 181 free(lpBuffer); 182 } 183 184 free(lpid); 185 CloseHandle(icon); 186 187 if (!UpdateResource(update, RT_GROUP_ICON, 188 MAKEINTRESOURCE(1), language, &lpgid[0], 189 (sizeof (WORD) * 3) + (sizeof (GRPICONDIRENTRY) * lpgid->idCount))) { 190 free(lpgid); 191 PrintError(); 192 return false; 193 } 194 195 free(lpgid); 196 197 if (EndUpdateResource(update, FALSE) == FALSE) { 198 PrintError(); 199 return false; 200 } 201 202 return true; 203 } |