|
1 /* |
|
2 * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
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 <algorithm> |
|
27 #include <fstream> |
|
28 #include "ResourceEditor.h" |
|
29 #include "WinErrorHandling.h" |
|
30 #include "Log.h" |
|
31 |
|
32 |
|
33 ResourceEditor::FileLock::FileLock(const std::wstring& binaryPath) { |
|
34 h = BeginUpdateResource(binaryPath.c_str(), FALSE); |
|
35 if (NULL == h) { |
|
36 JP_THROW(SysError(tstrings::any() << "BeginUpdateResource(" |
|
37 << binaryPath << ") failed", BeginUpdateResource)); |
|
38 } |
|
39 |
|
40 discard(false); |
|
41 } |
|
42 |
|
43 |
|
44 ResourceEditor::FileLock::~FileLock() { |
|
45 if (!EndUpdateResource(h, theDiscard)) { |
|
46 JP_NO_THROW(JP_THROW(SysError(tstrings::any() |
|
47 << "EndUpdateResource(" << h << ") failed.", EndUpdateResource))); |
|
48 } |
|
49 } |
|
50 |
|
51 |
|
52 ResourceEditor::ResourceEditor() { |
|
53 language(MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)).type(unsigned(0)).id(unsigned(0)); |
|
54 } |
|
55 |
|
56 |
|
57 ResourceEditor& ResourceEditor::type(unsigned v) { |
|
58 return type(MAKEINTRESOURCE(v)); |
|
59 } |
|
60 |
|
61 |
|
62 ResourceEditor& ResourceEditor::type(LPCWSTR v) { |
|
63 if (IS_INTRESOURCE(v)) { |
|
64 std::wostringstream printer; |
|
65 printer << L"#" << reinterpret_cast<size_t>(v); |
|
66 theType = printer.str(); |
|
67 theTypePtr = MAKEINTRESOURCE(static_cast<DWORD>(reinterpret_cast<DWORD_PTR>(v))); |
|
68 } else { |
|
69 theType = v; |
|
70 theTypePtr = theType.c_str(); |
|
71 } |
|
72 return *this; |
|
73 } |
|
74 |
|
75 |
|
76 ResourceEditor& ResourceEditor::id(unsigned v) { |
|
77 return id(MAKEINTRESOURCE(v)); |
|
78 } |
|
79 |
|
80 |
|
81 ResourceEditor& ResourceEditor::id(LPCWSTR v) { |
|
82 if (IS_INTRESOURCE(v)) { |
|
83 std::wostringstream printer; |
|
84 printer << L"#" << reinterpret_cast<size_t>(v); |
|
85 theId = printer.str(); |
|
86 } else { |
|
87 theId = v; |
|
88 theIdPtr = theId.c_str(); |
|
89 } |
|
90 return *this; |
|
91 } |
|
92 |
|
93 |
|
94 ResourceEditor& ResourceEditor::apply(const FileLock& dstBinary, |
|
95 std::istream& srcStream, std::streamsize size) { |
|
96 |
|
97 typedef std::vector<BYTE> ByteArray; |
|
98 ByteArray buf; |
|
99 if (size <= 0) { |
|
100 // Read the entire stream. |
|
101 buf = ByteArray((std::istreambuf_iterator<char>(srcStream)), |
|
102 std::istreambuf_iterator<char>()); |
|
103 } else { |
|
104 buf.resize(size_t(size)); |
|
105 srcStream.read(reinterpret_cast<char*>(buf.data()), size); |
|
106 } |
|
107 |
|
108 auto reply = UpdateResource(dstBinary.get(), theTypePtr, theIdPtr, lang, |
|
109 buf.data(), static_cast<DWORD>(buf.size())); |
|
110 if (reply == FALSE) { |
|
111 JP_THROW(SysError("UpdateResource() failed", UpdateResource)); |
|
112 } |
|
113 |
|
114 return *this; |
|
115 } |
|
116 |
|
117 |
|
118 ResourceEditor& ResourceEditor::apply(const FileLock& dstBinary, |
|
119 const std::wstring& srcFile) { |
|
120 std::ifstream input(srcFile, std::ios_base::binary); |
|
121 input.exceptions(std::ios::failbit | std::ios::badbit); |
|
122 return apply(dstBinary, input); |
|
123 } |