VirtualBox

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

Last change on this file since 48669 was 44529, checked in by vboxsync, 12 years ago

header (C) fixes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.0 KB
Line 
1/* $Id: VBoxStubBld.cpp 44529 2013-02-04 15:54:15Z vboxsync $ */
2/** @file
3 * VBoxStubBld - VirtualBox's Windows installer stub builder.
4 */
5
6/*
7 * Copyright (C) 2009-2010 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* Header Files *
20*******************************************************************************/
21#include <windows.h>
22#include <shellapi.h>
23#include <strsafe.h>
24
25#include <VBox/version.h>
26
27#include "VBoxStubBld.h"
28
29HRESULT GetFile (const char* pszFilePath,
30 HANDLE* phFile,
31 DWORD* pdwFileSize)
32{
33 HRESULT hr = S_OK;
34 *phFile = ::CreateFile(pszFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
35 if (INVALID_HANDLE_VALUE == *phFile)
36 {
37 hr = HRESULT_FROM_WIN32(GetLastError());
38 }
39 else
40 {
41 *pdwFileSize = ::GetFileSize(*phFile, NULL);
42 if (!*pdwFileSize)
43 {
44 hr = HRESULT_FROM_WIN32(GetLastError());
45 }
46 }
47 return hr;
48}
49
50HRESULT UpdateResource(HANDLE hFile,
51 const char* pszFilePath,
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, pszFilePath, dwFileSize,
104 hResourceUpdate, szResourceType, szResourceId);
105 if (FAILED(hr))
106 {
107 printf("ERROR: Error updating resource for file %s!", pszFilePath);
108 break;
109 }
110 }
111
112 } while (0);
113
114
115 if (INVALID_HANDLE_VALUE != hFile)
116 {
117 ::CloseHandle(hFile);
118 hFile = INVALID_HANDLE_VALUE;
119 }
120
121 return hr;
122}
123
124static char * MyPathFilename(const char *pszPath)
125{
126 const char *psz = pszPath;
127 const char *pszName = pszPath;
128
129 for (;; psz++)
130 {
131 switch (*psz)
132 {
133 /* handle separators. */
134 case ':':
135 pszName = psz + 1;
136 break;
137
138 case '\\':
139 case '/':
140 pszName = psz + 1;
141 break;
142
143 /* the end */
144 case '\0':
145 if (*pszName)
146 return (char *)(void *)pszName;
147 return NULL;
148 }
149 }
150
151 /* will never get here */
152 return NULL;
153}
154
155
156int main (int argc, char* argv[])
157{
158 HRESULT hr = S_OK;
159 int rc = 0;
160
161 char szSetupStub[_MAX_PATH] = {"VBoxStub.exe"};
162 char szOutput[_MAX_PATH] = {"VirtualBox-MultiArch.exe"};
163 HANDLE hUpdate = NULL;
164
165 do
166 {
167 printf(VBOX_PRODUCT " Stub Builder v%d.%d.%d.%d\n",
168 VBOX_VERSION_MAJOR, VBOX_VERSION_MINOR, VBOX_VERSION_BUILD, VBOX_SVN_REV);
169
170 if (argc < 2)
171 printf("WARNING: No parameters given! Using default values!\n");
172
173 VBOXSTUBBUILDPKG stbBuildPkg[VBOXSTUB_MAX_PACKAGES] = {0};
174 VBOXSTUBPKG stbPkg[VBOXSTUB_MAX_PACKAGES] = {0};
175 VBOXSTUBPKGHEADER stbHeader =
176 {
177 "vbox$tub", /* File magic. */
178 1, /* Version. */
179 0 /* No files yet. */
180 };
181
182 for (int i=1; i<argc; i++)
183 {
184 if (0 == stricmp(argv[i], "-out") && argc > i+1)
185 {
186 hr = ::StringCchCopy(szOutput, _MAX_PATH, argv[i+1]);
187 i++;
188 }
189
190 else if (0 == stricmp(argv[i], "-stub") && argc > i+1)
191 {
192 hr = ::StringCchCopy(szSetupStub, _MAX_PATH, argv[i+1]);
193 i++;
194 }
195
196 else if (0 == stricmp(argv[i], "-target-all") && argc > i+1)
197 {
198 hr = ::StringCchCopy(stbBuildPkg[stbHeader.byCntPkgs].szSourcePath, _MAX_PATH, argv[i+1]);
199 stbBuildPkg[stbHeader.byCntPkgs].byArch = VBOXSTUBPKGARCH_ALL;
200 stbHeader.byCntPkgs++;
201 i++;
202 }
203
204 else if (0 == stricmp(argv[i], "-target-x86") && argc > i+1)
205 {
206 hr = ::StringCchCopy(stbBuildPkg[stbHeader.byCntPkgs].szSourcePath, _MAX_PATH, argv[i+1]);
207 stbBuildPkg[stbHeader.byCntPkgs].byArch = VBOXSTUBPKGARCH_X86;
208 stbHeader.byCntPkgs++;
209 i++;
210 }
211
212 else if (0 == stricmp(argv[i], "-target-amd64") && argc > i+1)
213 {
214 hr = ::StringCchCopy(stbBuildPkg[stbHeader.byCntPkgs].szSourcePath, _MAX_PATH, argv[i+1]);
215 stbBuildPkg[stbHeader.byCntPkgs].byArch = VBOXSTUBPKGARCH_AMD64;
216 stbHeader.byCntPkgs++;
217 i++;
218 }
219 else
220 {
221 printf("ERROR: Invalid parameter: %s\n", argv[i]);
222 hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
223 break;
224 }
225 if (FAILED(hr))
226 {
227 printf("ERROR: StringCchCopy failed: %#x\n", hr);
228 break;
229 }
230 }
231 if (FAILED(hr))
232 break;
233
234 if (stbHeader.byCntPkgs <= 0)
235 {
236 printf("ERROR: No packages defined! Exiting.\n");
237 break;
238 }
239
240 printf("Stub: %s\n", szSetupStub);
241 printf("Output: %s\n", szOutput);
242 printf("# Packages: %d\n", stbHeader.byCntPkgs);
243
244 if (!::CopyFile(szSetupStub, szOutput, FALSE))
245 {
246 hr = HRESULT_FROM_WIN32(GetLastError());
247 printf("ERROR: Could not create stub loader: 0x%08x\n", hr);
248 break;
249 }
250
251 hUpdate = ::BeginUpdateResource(szOutput, FALSE);
252
253 PVBOXSTUBPKG pPackage = stbPkg;
254 char szHeaderName[_MAX_PATH] = {0};
255 size_t iLen = 0;
256
257 for (BYTE i=0; i<stbHeader.byCntPkgs; i++)
258 {
259 printf("Integrating (Platform %d): %s\n", stbBuildPkg[i].byArch, stbBuildPkg[i].szSourcePath);
260
261 /* Construct resource name. */
262 hr = ::StringCchPrintf(pPackage->szResourceName, _MAX_PATH, "BIN_%02d", i);
263 pPackage->byArch = stbBuildPkg[i].byArch;
264
265 /* Construct final name used when extracting. */
266 hr = ::StringCchCopy(pPackage->szFileName, _MAX_PATH, MyPathFilename(stbBuildPkg[i].szSourcePath));
267
268 /* Integrate header into binary. */
269 hr = ::StringCchPrintf(szHeaderName, _MAX_PATH, "HDR_%02d", i);
270 hr = UpdateResource(hUpdate, RT_RCDATA, szHeaderName, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), pPackage, sizeof(VBOXSTUBPKG));
271
272 /* Integrate file into binary. */
273 hr = IntegrateFile(hUpdate, RT_RCDATA, pPackage->szResourceName, stbBuildPkg[i].szSourcePath);
274 if (FAILED(hr))
275 {
276 printf("ERROR: Could not integrate binary %s (%s): 0x%08x\n",
277 pPackage->szResourceName, pPackage->szFileName, hr);
278 rc = 1;
279 }
280
281 pPackage++;
282 }
283
284 if (FAILED(hr))
285 break;
286
287 if (!::UpdateResource(hUpdate, RT_RCDATA, "MANIFEST", MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), &stbHeader, sizeof(VBOXSTUBPKGHEADER)))
288 {
289 hr = HRESULT_FROM_WIN32(GetLastError());
290 break;
291 }
292
293 if (!::EndUpdateResource(hUpdate, FALSE))
294 {
295 hr = HRESULT_FROM_WIN32(GetLastError());
296 break;
297 }
298
299 printf("Integration done!\n");
300
301 } while (0);
302
303 hUpdate = NULL;
304
305 if (FAILED(hr))
306 {
307 printf("ERROR: Building failed! Last error: %d\n", GetLastError());
308 rc = 1;
309 }
310 return rc;
311}
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