VirtualBox

source: vbox/trunk/src/VBox/Installer/win/StubBld/VBoxStubBld.cpp@ 67772

Last change on this file since 67772 was 63124, checked in by vboxsync, 8 years ago

warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: VBoxStubBld.cpp 63124 2016-08-07 03:41:14Z vboxsync $ */
2/** @file
3 * VBoxStubBld - VirtualBox's Windows installer stub builder.
4 */
5
6/*
7 * Copyright (C) 2009-2016 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#include <iprt/win/windows.h>
23#include <shellapi.h>
24#include <strsafe.h>
25
26#include <VBox/version.h>
27
28#include "VBoxStubBld.h"
29
30HRESULT GetFile (const char* pszFilePath,
31 HANDLE* phFile,
32 DWORD* pdwFileSize)
33{
34 HRESULT hr = S_OK;
35 *phFile = ::CreateFile(pszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
36 if (INVALID_HANDLE_VALUE == *phFile)
37 {
38 hr = HRESULT_FROM_WIN32(GetLastError());
39 }
40 else
41 {
42 *pdwFileSize = ::GetFileSize(*phFile, NULL);
43 if (!*pdwFileSize)
44 {
45 hr = HRESULT_FROM_WIN32(GetLastError());
46 }
47 }
48 return hr;
49}
50
51HRESULT UpdateResource(HANDLE hFile,
52 DWORD dwFileSize,
53 HANDLE hResourceUpdate,
54 const char *szResourceType,
55 const char *szResourceId)
56{
57 HRESULT hr = S_OK;
58 PVOID pvFile = NULL;
59 HANDLE hMap = NULL;
60
61 hMap = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
62 pvFile = ::MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, dwFileSize);
63 if (!::UpdateResourceA(hResourceUpdate, szResourceType, szResourceId,
64 MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pvFile, dwFileSize))
65 {
66 hr = HRESULT_FROM_WIN32(GetLastError());
67 }
68
69 if (pvFile)
70 {
71 ::UnmapViewOfFile(pvFile);
72 pvFile = NULL;
73 }
74
75 if (hMap)
76 {
77 ::CloseHandle(hMap);
78 hMap = NULL;
79 }
80
81 return hr;
82}
83
84HRESULT IntegrateFile (HANDLE hResourceUpdate,
85 const char* szResourceType,
86 const char* szResourceId,
87 const char* pszFilePath)
88{
89 HRESULT hr = S_OK;
90 HANDLE hFile = INVALID_HANDLE_VALUE;
91 DWORD dwFileSize = 0;
92
93 do
94 {
95 hr = GetFile(pszFilePath, &hFile, &dwFileSize);
96 if (FAILED(hr))
97 {
98 hr = HRESULT_FROM_WIN32(GetLastError());
99 break;
100 }
101 else
102 {
103 hr = UpdateResource(hFile, dwFileSize, hResourceUpdate, szResourceType, szResourceId);
104 if (FAILED(hr))
105 {
106 printf("ERROR: Error updating resource for file %s!", pszFilePath);
107 break;
108 }
109 }
110
111 } while (0);
112
113
114 if (INVALID_HANDLE_VALUE != hFile)
115 {
116 ::CloseHandle(hFile);
117 hFile = INVALID_HANDLE_VALUE;
118 }
119
120 return hr;
121}
122
123static char * MyPathFilename(const char *pszPath)
124{
125 const char *psz = pszPath;
126 const char *pszName = pszPath;
127
128 for (;; psz++)
129 {
130 switch (*psz)
131 {
132 /* handle separators. */
133 case ':':
134 pszName = psz + 1;
135 break;
136
137 case '\\':
138 case '/':
139 pszName = psz + 1;
140 break;
141
142 /* the end */
143 case '\0':
144 if (*pszName)
145 return (char *)(void *)pszName;
146 return NULL;
147 }
148 }
149
150 /* will never get here */
151}
152
153
154int main (int argc, char* argv[])
155{
156 HRESULT hr = S_OK;
157 int rc = 0;
158
159 char szSetupStub[_MAX_PATH] = {"VBoxStub.exe"};
160 char szOutput[_MAX_PATH] = {"VirtualBox-MultiArch.exe"};
161 HANDLE hUpdate = NULL;
162
163 do
164 {
165 printf(VBOX_PRODUCT " Stub Builder v%d.%d.%d.%d\n",
166 VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV);
167
168 if (argc < 2)
169 printf("WARNING: No parameters given! Using default values!\n");
170
171 VBOXSTUBBUILDPKG stbBuildPkg[VBOXSTUB_MAX_PACKAGES] = {0};
172 VBOXSTUBPKG stbPkg[VBOXSTUB_MAX_PACKAGES] = {0};
173 VBOXSTUBPKGHEADER stbHeader =
174 {
175 "vbox$tub", /* File magic. */
176 1, /* Version. */
177 0 /* No files yet. */
178 };
179
180 for (int i=1; i<argc; i++)
181 {
182 if (0 == stricmp(argv[i], "-out") && argc > i+1)
183 {
184 hr = ::StringCchCopy(szOutput, _MAX_PATH, argv[i+1]);
185 i++;
186 }
187
188 else if (0 == stricmp(argv[i], "-stub") && argc > i+1)
189 {
190 hr = ::StringCchCopy(szSetupStub, _MAX_PATH, argv[i+1]);
191 i++;
192 }
193
194 else if (0 == stricmp(argv[i], "-target-all") && argc > i+1)
195 {
196 hr = ::StringCchCopy(stbBuildPkg[stbHeader.byCntPkgs].szSourcePath, _MAX_PATH, argv[i+1]);
197 stbBuildPkg[stbHeader.byCntPkgs].byArch = VBOXSTUBPKGARCH_ALL;
198 stbHeader.byCntPkgs++;
199 i++;
200 }
201
202 else if (0 == stricmp(argv[i], "-target-x86") && argc > i+1)
203 {
204 hr = ::StringCchCopy(stbBuildPkg[stbHeader.byCntPkgs].szSourcePath, _MAX_PATH, argv[i+1]);
205 stbBuildPkg[stbHeader.byCntPkgs].byArch = VBOXSTUBPKGARCH_X86;
206 stbHeader.byCntPkgs++;
207 i++;
208 }
209
210 else if (0 == stricmp(argv[i], "-target-amd64") && argc > i+1)
211 {
212 hr = ::StringCchCopy(stbBuildPkg[stbHeader.byCntPkgs].szSourcePath, _MAX_PATH, argv[i+1]);
213 stbBuildPkg[stbHeader.byCntPkgs].byArch = VBOXSTUBPKGARCH_AMD64;
214 stbHeader.byCntPkgs++;
215 i++;
216 }
217 else
218 {
219 printf("ERROR: Invalid parameter: %s\n", argv[i]);
220 hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
221 break;
222 }
223 if (FAILED(hr))
224 {
225 printf("ERROR: StringCchCopy failed: %#x\n", hr);
226 break;
227 }
228 }
229 if (FAILED(hr))
230 break;
231
232 if (stbHeader.byCntPkgs <= 0)
233 {
234 printf("ERROR: No packages defined! Exiting.\n");
235 break;
236 }
237
238 printf("Stub: %s\n", szSetupStub);
239 printf("Output: %s\n", szOutput);
240 printf("# Packages: %d\n", stbHeader.byCntPkgs);
241
242 if (!::CopyFile(szSetupStub, szOutput, FALSE))
243 {
244 hr = HRESULT_FROM_WIN32(GetLastError());
245 printf("ERROR: Could not create stub loader: 0x%08x\n", hr);
246 break;
247 }
248
249 hUpdate = ::BeginUpdateResource(szOutput, FALSE);
250
251 PVBOXSTUBPKG pPackage = stbPkg;
252 char szHeaderName[_MAX_PATH] = {0};
253
254 for (BYTE i=0; i<stbHeader.byCntPkgs; i++)
255 {
256 printf("Integrating (Platform %d): %s\n", stbBuildPkg[i].byArch, stbBuildPkg[i].szSourcePath);
257
258 /* Construct resource name. */
259 hr = ::StringCchPrintf(pPackage->szResourceName, _MAX_PATH, "BIN_%02d", i);
260 pPackage->byArch = stbBuildPkg[i].byArch;
261
262 /* Construct final name used when extracting. */
263 hr = ::StringCchCopy(pPackage->szFileName, _MAX_PATH, MyPathFilename(stbBuildPkg[i].szSourcePath));
264
265 /* Integrate header into binary. */
266 hr = ::StringCchPrintf(szHeaderName, _MAX_PATH, "HDR_%02d", i);
267 hr = UpdateResource(hUpdate, RT_RCDATA, szHeaderName, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pPackage, sizeof(VBOXSTUBPKG));
268
269 /* Integrate file into binary. */
270 hr = IntegrateFile(hUpdate, RT_RCDATA, pPackage->szResourceName, stbBuildPkg[i].szSourcePath);
271 if (FAILED(hr))
272 {
273 printf("ERROR: Could not integrate binary %s (%s): 0x%08x\n",
274 pPackage->szResourceName, pPackage->szFileName, hr);
275 rc = 1;
276 }
277
278 pPackage++;
279 }
280
281 if (FAILED(hr))
282 break;
283
284 if (!::UpdateResource(hUpdate, RT_RCDATA, "MANIFEST", MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &stbHeader, sizeof(VBOXSTUBPKGHEADER)))
285 {
286 hr = HRESULT_FROM_WIN32(GetLastError());
287 break;
288 }
289
290 if (!::EndUpdateResource(hUpdate, FALSE))
291 {
292 hr = HRESULT_FROM_WIN32(GetLastError());
293 break;
294 }
295
296 printf("Integration done!\n");
297
298 } while (0);
299
300 hUpdate = NULL;
301
302 if (FAILED(hr))
303 {
304 printf("ERROR: Building failed! Last error: %d\n", GetLastError());
305 rc = 1;
306 }
307 return rc;
308}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette