< prev index next >

src/jdk.jpackage/windows/native/libjpackage/IconSwap.cpp

Print this page




   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 }
< prev index next >