xulrunner/tools/redit/redit.cpp

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 // System headers (alphabetical)
     8 #include <fcntl.h>
     9 #include <io.h>
    10 #include <share.h>
    11 #include <stdio.h>
    12 #include <stdlib.h>
    13 #include <sys/stat.h>
    14 #include <windows.h>
    16 // Mozilla headers (alphabetical)
    17 #include "mozilla/FileUtils.h"  // ScopedClose
    18 #include "nsAutoPtr.h"          // nsAutoArrayPtr
    20 /*
    21 Icon files are made up of:
    23 IconHeader
    24 IconDirEntry1
    25 IconDirEntry2
    26 ...
    27 IconDirEntryN
    28 IconData1
    29 IconData2
    30 ...
    31 IconDataN
    33 Each IconData must be added as a new RT_ICON resource to the exe. Then
    34 an RT_GROUP_ICON resource must be added that contains an equivalent
    35 header:
    37 IconHeader
    38 IconResEntry1
    39 IconResEntry2
    40 ...
    41 IconResEntryN
    42 */
    44 #pragma pack(push, 2)
    45 typedef struct
    46 {
    47   WORD Reserved;
    48   WORD ResourceType;
    49   WORD ImageCount;
    50 } IconHeader;
    52 typedef struct
    53 {
    54   BYTE Width;
    55   BYTE Height;
    56   BYTE Colors;
    57   BYTE Reserved;
    58   WORD Planes;
    59   WORD BitsPerPixel;
    60   DWORD ImageSize;
    61   DWORD ImageOffset;
    62 } IconDirEntry;
    64 typedef struct
    65 {
    66   BYTE Width;
    67   BYTE Height;
    68   BYTE Colors;
    69   BYTE Reserved;
    70   WORD Planes;
    71   WORD BitsPerPixel;
    72   DWORD ImageSize;
    73   WORD ResourceID;    // This field is the one difference to above
    74 } IconResEntry;
    75 #pragma pack(pop)
    77 namespace {
    78   /**
    79    * ScopedResourceUpdate is a RAII wrapper for Windows resource updating
    80    *
    81    * Instances |EndUpdateResourceW()| their handles when they go out of scope.
    82    * They pass |TRUE| as the second argument to |EndUpdateResourceW()|, which
    83    * causes the resource update to be aborted (changes are discarded).
    84    */
    85   struct ScopedResourceUpdateTraits
    86   {
    87     typedef HANDLE type;
    88     static type empty() { return nullptr; }
    89     static void release(type handle) {
    90       if(nullptr != handle) {
    91         EndUpdateResourceW(handle, TRUE); // Discard changes
    92       }
    93     }
    94   };
    96   typedef mozilla::Scoped<ScopedResourceUpdateTraits> ScopedResourceUpdate;
    97 };
    99 #ifdef __MINGW32__
   100 extern "C"
   101 #endif
   102 int
   103 wmain(int argc, wchar_t** argv)
   104 {
   105   if (argc != 3) {
   106     printf("Usage: redit <exe file> <icon file>\n");
   107     return 1;
   108   }
   110   mozilla::ScopedClose file;
   111   if (0 != _wsopen_s(&file.rwget(),
   112                      argv[2],
   113                      _O_BINARY | _O_RDONLY,
   114                      _SH_DENYWR,
   115                      _S_IREAD)
   116   || (-1 == file)) {
   117     fprintf(stderr, "Unable to open icon file.\n");
   118     return 1;
   119   }
   121   // Load all the data from the icon file
   122   long filesize = _filelength(file);
   123   nsAutoArrayPtr<BYTE> data(new BYTE[filesize]);
   124   if(!data) {
   125     fprintf(stderr, "Failed to allocate memory for icon file.\n");
   126     return 1;
   127   }
   128   _read(file, data, filesize);
   130   IconHeader* header = reinterpret_cast<IconHeader*>(data.get());
   132   // Open the target library for updating
   133   ScopedResourceUpdate updateRes(BeginUpdateResourceW(argv[1], FALSE));
   134   if (nullptr == updateRes) {
   135     fprintf(stderr, "Unable to open library for modification.\n");
   136     return 1;
   137   }
   139   // Allocate the group resource entry
   140   long groupSize = sizeof(IconHeader)
   141                  + header->ImageCount * sizeof(IconResEntry);
   142   nsAutoArrayPtr<BYTE> group(new BYTE[groupSize]);
   143   if(!group) {
   144     fprintf(stderr, "Failed to allocate memory for new images.\n");
   145     return 1;
   146   }
   147   memcpy(group, data, sizeof(IconHeader));
   149   IconDirEntry* sourceIcon =
   150                     reinterpret_cast<IconDirEntry*>(data
   151                                                   + sizeof(IconHeader));
   152   IconResEntry* targetIcon =
   153                     reinterpret_cast<IconResEntry*>(group
   154                                                   + sizeof(IconHeader));
   156   for (int id = 1; id <= header->ImageCount; id++) {
   157     // Add the individual icon
   158     if (!UpdateResourceW(updateRes, RT_ICON, MAKEINTRESOURCE(id),
   159                          MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
   160                          data + sourceIcon->ImageOffset,
   161                          sourceIcon->ImageSize)) {
   162       fprintf(stderr, "Unable to update resource (RT_ICON).\n");
   163       return 1;
   164     }
   165     // Copy the data for this icon
   166     // (note that the structs have different sizes)
   167     memcpy(targetIcon, sourceIcon, sizeof(IconResEntry));
   168     targetIcon->ResourceID = id;
   169     sourceIcon++;
   170     targetIcon++;
   171   }
   173   if (!UpdateResourceW(updateRes, RT_GROUP_ICON, L"MAINICON",
   174                        MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
   175                        group, groupSize)) {
   176     fprintf(stderr, "Unable to update resource (RT_GROUP_ICON).\n");
   177     return 1;
   178   }
   180   // Save the modifications
   181   if(!EndUpdateResourceW(updateRes.forget(), FALSE)) {
   182     fprintf(stderr, "Unable to write changes to library.\n");
   183     return 1;
   184   }
   186   return 0;
   187 }

mercurial