xulrunner/tools/redit/redit.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/xulrunner/tools/redit/redit.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,187 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.8 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +// System headers (alphabetical)
    1.11 +#include <fcntl.h>
    1.12 +#include <io.h>
    1.13 +#include <share.h>
    1.14 +#include <stdio.h>
    1.15 +#include <stdlib.h>
    1.16 +#include <sys/stat.h>
    1.17 +#include <windows.h>
    1.18 +
    1.19 +// Mozilla headers (alphabetical)
    1.20 +#include "mozilla/FileUtils.h"  // ScopedClose
    1.21 +#include "nsAutoPtr.h"          // nsAutoArrayPtr
    1.22 +
    1.23 +/*
    1.24 +Icon files are made up of:
    1.25 +
    1.26 +IconHeader
    1.27 +IconDirEntry1
    1.28 +IconDirEntry2
    1.29 +...
    1.30 +IconDirEntryN
    1.31 +IconData1
    1.32 +IconData2
    1.33 +...
    1.34 +IconDataN
    1.35 +
    1.36 +Each IconData must be added as a new RT_ICON resource to the exe. Then
    1.37 +an RT_GROUP_ICON resource must be added that contains an equivalent
    1.38 +header:
    1.39 +
    1.40 +IconHeader
    1.41 +IconResEntry1
    1.42 +IconResEntry2
    1.43 +...
    1.44 +IconResEntryN
    1.45 +*/
    1.46 +
    1.47 +#pragma pack(push, 2)
    1.48 +typedef struct
    1.49 +{
    1.50 +  WORD Reserved;
    1.51 +  WORD ResourceType;
    1.52 +  WORD ImageCount;
    1.53 +} IconHeader;
    1.54 +
    1.55 +typedef struct
    1.56 +{
    1.57 +  BYTE Width;
    1.58 +  BYTE Height;
    1.59 +  BYTE Colors;
    1.60 +  BYTE Reserved;
    1.61 +  WORD Planes;
    1.62 +  WORD BitsPerPixel;
    1.63 +  DWORD ImageSize;
    1.64 +  DWORD ImageOffset;
    1.65 +} IconDirEntry;
    1.66 +
    1.67 +typedef struct
    1.68 +{
    1.69 +  BYTE Width;
    1.70 +  BYTE Height;
    1.71 +  BYTE Colors;
    1.72 +  BYTE Reserved;
    1.73 +  WORD Planes;
    1.74 +  WORD BitsPerPixel;
    1.75 +  DWORD ImageSize;
    1.76 +  WORD ResourceID;    // This field is the one difference to above
    1.77 +} IconResEntry;
    1.78 +#pragma pack(pop)
    1.79 +
    1.80 +namespace {
    1.81 +  /**
    1.82 +   * ScopedResourceUpdate is a RAII wrapper for Windows resource updating
    1.83 +   *
    1.84 +   * Instances |EndUpdateResourceW()| their handles when they go out of scope.
    1.85 +   * They pass |TRUE| as the second argument to |EndUpdateResourceW()|, which
    1.86 +   * causes the resource update to be aborted (changes are discarded).
    1.87 +   */
    1.88 +  struct ScopedResourceUpdateTraits
    1.89 +  {
    1.90 +    typedef HANDLE type;
    1.91 +    static type empty() { return nullptr; }
    1.92 +    static void release(type handle) {
    1.93 +      if(nullptr != handle) {
    1.94 +        EndUpdateResourceW(handle, TRUE); // Discard changes
    1.95 +      }
    1.96 +    }
    1.97 +  };
    1.98 +
    1.99 +  typedef mozilla::Scoped<ScopedResourceUpdateTraits> ScopedResourceUpdate;
   1.100 +};
   1.101 +
   1.102 +#ifdef __MINGW32__
   1.103 +extern "C"
   1.104 +#endif
   1.105 +int
   1.106 +wmain(int argc, wchar_t** argv)
   1.107 +{
   1.108 +  if (argc != 3) {
   1.109 +    printf("Usage: redit <exe file> <icon file>\n");
   1.110 +    return 1;
   1.111 +  }
   1.112 +
   1.113 +  mozilla::ScopedClose file;
   1.114 +  if (0 != _wsopen_s(&file.rwget(),
   1.115 +                     argv[2],
   1.116 +                     _O_BINARY | _O_RDONLY,
   1.117 +                     _SH_DENYWR,
   1.118 +                     _S_IREAD)
   1.119 +  || (-1 == file)) {
   1.120 +    fprintf(stderr, "Unable to open icon file.\n");
   1.121 +    return 1;
   1.122 +  }
   1.123 +
   1.124 +  // Load all the data from the icon file
   1.125 +  long filesize = _filelength(file);
   1.126 +  nsAutoArrayPtr<BYTE> data(new BYTE[filesize]);
   1.127 +  if(!data) {
   1.128 +    fprintf(stderr, "Failed to allocate memory for icon file.\n");
   1.129 +    return 1;
   1.130 +  }
   1.131 +  _read(file, data, filesize);
   1.132 +
   1.133 +  IconHeader* header = reinterpret_cast<IconHeader*>(data.get());
   1.134 +
   1.135 +  // Open the target library for updating
   1.136 +  ScopedResourceUpdate updateRes(BeginUpdateResourceW(argv[1], FALSE));
   1.137 +  if (nullptr == updateRes) {
   1.138 +    fprintf(stderr, "Unable to open library for modification.\n");
   1.139 +    return 1;
   1.140 +  }
   1.141 +
   1.142 +  // Allocate the group resource entry
   1.143 +  long groupSize = sizeof(IconHeader)
   1.144 +                 + header->ImageCount * sizeof(IconResEntry);
   1.145 +  nsAutoArrayPtr<BYTE> group(new BYTE[groupSize]);
   1.146 +  if(!group) {
   1.147 +    fprintf(stderr, "Failed to allocate memory for new images.\n");
   1.148 +    return 1;
   1.149 +  }
   1.150 +  memcpy(group, data, sizeof(IconHeader));
   1.151 +
   1.152 +  IconDirEntry* sourceIcon =
   1.153 +                    reinterpret_cast<IconDirEntry*>(data
   1.154 +                                                  + sizeof(IconHeader));
   1.155 +  IconResEntry* targetIcon =
   1.156 +                    reinterpret_cast<IconResEntry*>(group
   1.157 +                                                  + sizeof(IconHeader));
   1.158 +
   1.159 +  for (int id = 1; id <= header->ImageCount; id++) {
   1.160 +    // Add the individual icon
   1.161 +    if (!UpdateResourceW(updateRes, RT_ICON, MAKEINTRESOURCE(id),
   1.162 +                         MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
   1.163 +                         data + sourceIcon->ImageOffset,
   1.164 +                         sourceIcon->ImageSize)) {
   1.165 +      fprintf(stderr, "Unable to update resource (RT_ICON).\n");
   1.166 +      return 1;
   1.167 +    }
   1.168 +    // Copy the data for this icon
   1.169 +    // (note that the structs have different sizes)
   1.170 +    memcpy(targetIcon, sourceIcon, sizeof(IconResEntry));
   1.171 +    targetIcon->ResourceID = id;
   1.172 +    sourceIcon++;
   1.173 +    targetIcon++;
   1.174 +  }
   1.175 +
   1.176 +  if (!UpdateResourceW(updateRes, RT_GROUP_ICON, L"MAINICON",
   1.177 +                       MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL),
   1.178 +                       group, groupSize)) {
   1.179 +    fprintf(stderr, "Unable to update resource (RT_GROUP_ICON).\n");
   1.180 +    return 1;
   1.181 +  }
   1.182 +
   1.183 +  // Save the modifications
   1.184 +  if(!EndUpdateResourceW(updateRes.forget(), FALSE)) {
   1.185 +    fprintf(stderr, "Unable to write changes to library.\n");
   1.186 +    return 1;
   1.187 +  }
   1.188 +
   1.189 +  return 0;
   1.190 +}

mercurial