Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(239)

Side by Side Diff: chrome/installer/mini_installer/mini_installer.cc

Issue 2559053002: Instrument setup.exe in the SyzyAsan builds.
Patch Set: BL compress syzyasan_rtl.dll Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // mini_installer.exe is the first exe that is run when chrome is being 5 // mini_installer.exe is the first exe that is run when chrome is being
6 // installed or upgraded. It is designed to be extremely small (~5KB with no 6 // installed or upgraded. It is designed to be extremely small (~5KB with no
7 // extra resources linked) and it has two main jobs: 7 // extra resources linked) and it has two main jobs:
8 // 1) unpack the resources (possibly decompressing some) 8 // 1) unpack the resources (possibly decompressing some)
9 // 2) run the real installer (setup.exe) with appropriate flags. 9 // 2) run the real installer (setup.exe) with appropriate flags.
10 // 10 //
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 // This structure passes data back and forth for the processing 53 // This structure passes data back and forth for the processing
54 // of resource callbacks. 54 // of resource callbacks.
55 struct Context { 55 struct Context {
56 // Input to the call back method. Specifies the dir to save resources. 56 // Input to the call back method. Specifies the dir to save resources.
57 const wchar_t* base_path; 57 const wchar_t* base_path;
58 // First output from call back method. Full path of Chrome archive. 58 // First output from call back method. Full path of Chrome archive.
59 PathString* chrome_resource_path; 59 PathString* chrome_resource_path;
60 // Second output from call back method. Full path of Setup archive/exe. 60 // Second output from call back method. Full path of Setup archive/exe.
61 PathString* setup_resource_path; 61 PathString* setup_resource_path;
62 #if defined(SYZYASAN)
63 PathString* syzyasan_resource_path;
64 #endif
62 }; 65 };
63 66
64 // TODO(grt): Frame this in terms of whether or not the brand supports 67 // TODO(grt): Frame this in terms of whether or not the brand supports
65 // integation with Omaha, where Google Update is the Google-specific fork of 68 // integation with Omaha, where Google Update is the Google-specific fork of
66 // the open-source Omaha project. 69 // the open-source Omaha project.
67 #if defined(GOOGLE_CHROME_BUILD) 70 #if defined(GOOGLE_CHROME_BUILD)
68 // Opens the Google Update ClientState key. If |binaries| is false, opens the 71 // Opens the Google Update ClientState key. If |binaries| is false, opens the
69 // key for Google Chrome or Chrome SxS (canary). If |binaries| is true and an 72 // key for Google Chrome or Chrome SxS (canary). If |binaries| is true and an
70 // existing multi-install Chrome is being updated, opens the key for the 73 // existing multi-install Chrome is being updated, opens the key for the
71 // multi-install binaries; otherwise, returns false. 74 // multi-install binaries; otherwise, returns false.
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 !full_path.append(name) || 287 !full_path.append(name) ||
285 !resource.WriteToDisk(full_path.get())) 288 !resource.WriteToDisk(full_path.get()))
286 return FALSE; 289 return FALSE;
287 290
288 if (StrStartsWith(name, kChromeArchivePrefix)) { 291 if (StrStartsWith(name, kChromeArchivePrefix)) {
289 if (!ctx->chrome_resource_path->assign(full_path.get())) 292 if (!ctx->chrome_resource_path->assign(full_path.get()))
290 return FALSE; 293 return FALSE;
291 } else if (StrStartsWith(name, kSetupPrefix)) { 294 } else if (StrStartsWith(name, kSetupPrefix)) {
292 if (!ctx->setup_resource_path->assign(full_path.get())) 295 if (!ctx->setup_resource_path->assign(full_path.get()))
293 return FALSE; 296 return FALSE;
297 #if defined(SYZYASAN)
298 } else if (StrStartsWith(name, kSyzyAsanRuntimePrefix)) {
299 if (!ctx->syzyasan_resource_path->assign(full_path.get()))
300 return FALSE;
301 #endif
294 } else { 302 } else {
295 // Resources should either start with 'chrome' or 'setup'. We don't handle 303 // Resources should either start with 'chrome' or 'setup'. We don't handle
296 // anything else. 304 // anything else.
297 return FALSE; 305 return FALSE;
298 } 306 }
299 307
300 return TRUE; 308 return TRUE;
301 } 309 }
302 310
303 #if defined(COMPONENT_BUILD) 311 #if defined(COMPONENT_BUILD) || defined(SYZYASAN)
304 // An EnumResNameProc callback that writes the resource |name| to disk in the 312 // An EnumResNameProc callback that writes the resource |name| to disk in the
305 // directory |base_path_ptr| (which must end with a path separator). 313 // directory |base_path_ptr| (which must end with a path separator).
306 BOOL CALLBACK WriteResourceToDirectory(HMODULE module, 314 BOOL CALLBACK WriteResourceToDirectory(HMODULE module,
307 const wchar_t* type, 315 const wchar_t* type,
308 wchar_t* name, 316 wchar_t* name,
309 LONG_PTR base_path_ptr) { 317 LONG_PTR base_path_ptr) {
310 const wchar_t* base_path = reinterpret_cast<const wchar_t*>(base_path_ptr); 318 const wchar_t* base_path = reinterpret_cast<const wchar_t*>(base_path_ptr);
311 PathString full_path; 319 PathString full_path;
312 320
313 PEResource resource(name, type, module); 321 PEResource resource(name, type, module);
(...skipping 10 matching lines...) Expand all
324 // - Resource type 'B7', compressed using LZMA (*.7z) 332 // - Resource type 'B7', compressed using LZMA (*.7z)
325 // - Resource type 'BL', compressed using LZ (*.ex_) 333 // - Resource type 'BL', compressed using LZ (*.ex_)
326 // - Resource type 'BN', uncompressed (*.exe) 334 // - Resource type 'BN', uncompressed (*.exe)
327 // If setup.exe is present in more than one form, the precedence order is 335 // If setup.exe is present in more than one form, the precedence order is
328 // BN < BL < B7 336 // BN < BL < B7
329 // For more details see chrome/tools/build/win/create_installer_archive.py. 337 // For more details see chrome/tools/build/win/create_installer_archive.py.
330 // For component builds (where setup.ex_ is always used), all files stored as 338 // For component builds (where setup.ex_ is always used), all files stored as
331 // uncompressed 'BN' resources are also extracted. This is generally the set of 339 // uncompressed 'BN' resources are also extracted. This is generally the set of
332 // DLLs/resources needed by setup.exe to run. 340 // DLLs/resources needed by setup.exe to run.
333 ProcessExitResult UnpackBinaryResources(const Configuration& configuration, 341 ProcessExitResult UnpackBinaryResources(const Configuration& configuration,
334 HMODULE module, const wchar_t* base_path, 342 HMODULE module,
335 PathString* archive_path, 343 Context* context) {
336 PathString* setup_path) {
337 // Generate the setup.exe path where we patch/uncompress setup resource. 344 // Generate the setup.exe path where we patch/uncompress setup resource.
338 PathString setup_dest_path; 345 PathString setup_dest_path;
339 if (!setup_dest_path.assign(base_path) || 346 if (!setup_dest_path.assign(context->base_path) ||
340 !setup_dest_path.append(kSetupExe)) 347 !setup_dest_path.append(kSetupExe))
341 return ProcessExitResult(PATH_STRING_OVERFLOW); 348 return ProcessExitResult(PATH_STRING_OVERFLOW);
342 349
343 // Prepare the input to OnResourceFound method that needs a location where
344 // it will write all the resources.
345 Context context = {
346 base_path,
347 archive_path,
348 setup_path,
349 };
350
351 // Get the resources of type 'B7' (7zip archive). 350 // Get the resources of type 'B7' (7zip archive).
352 // We need a chrome archive to do the installation. So if there 351 // We need a chrome archive to do the installation. So if there
353 // is a problem in fetching B7 resource, just return an error. 352 // is a problem in fetching B7 resource, just return an error.
354 if (!::EnumResourceNames(module, kLZMAResourceType, OnResourceFound, 353 if (!::EnumResourceNames(module, kLZMAResourceType, OnResourceFound,
355 reinterpret_cast<LONG_PTR>(&context))) { 354 reinterpret_cast<LONG_PTR>(context))) {
356 return ProcessExitResult(UNABLE_TO_EXTRACT_CHROME_ARCHIVE, 355 return ProcessExitResult(UNABLE_TO_EXTRACT_CHROME_ARCHIVE,
357 ::GetLastError()); 356 ::GetLastError());
358 } 357 }
359 if (archive_path->length() == 0) { 358 if (context->chrome_resource_path->length() == 0) {
360 return ProcessExitResult(UNABLE_TO_EXTRACT_CHROME_ARCHIVE); 359 return ProcessExitResult(UNABLE_TO_EXTRACT_CHROME_ARCHIVE);
361 } 360 }
362 361
363 ProcessExitResult exit_code = ProcessExitResult(SUCCESS_EXIT_CODE); 362 ProcessExitResult exit_code = ProcessExitResult(SUCCESS_EXIT_CODE);
364 363
365 // If we found setup 'B7' resource (used for differential updates), handle 364 // If we found setup 'B7' resource (used for differential updates), handle
366 // it. Note that this is only for Chrome; Chromium installs are always 365 // it. Note that this is only for Chrome; Chromium installs are always
367 // "full" installs. 366 // "full" installs.
368 if (setup_path->length() > 0) { 367 if (context->setup_resource_path->length() > 0) {
369 CommandString cmd_line; 368 CommandString cmd_line;
370 PathString exe_path; 369 PathString exe_path;
371 // Get the path to setup.exe first. 370 // Get the path to setup.exe first.
372 exit_code = GetPreviousSetupExePath(configuration, exe_path.get(), 371 exit_code = GetPreviousSetupExePath(configuration, exe_path.get(),
373 exe_path.capacity()); 372 exe_path.capacity());
374 if (exit_code.IsSuccess()) { 373 if (exit_code.IsSuccess()) {
375 if (!cmd_line.append(exe_path.get()) || 374 if (!cmd_line.append(exe_path.get()) || !cmd_line.append(L" --") ||
376 !cmd_line.append(L" --") || 375 !cmd_line.append(kCmdUpdateSetupExe) || !cmd_line.append(L"=\"") ||
377 !cmd_line.append(kCmdUpdateSetupExe) || 376 !cmd_line.append(context->setup_resource_path->get()) ||
378 !cmd_line.append(L"=\"") || 377 !cmd_line.append(L"\" --") || !cmd_line.append(kCmdNewSetupExe) ||
379 !cmd_line.append(setup_path->get()) || 378 !cmd_line.append(L"=\"") || !cmd_line.append(setup_dest_path.get()) ||
380 !cmd_line.append(L"\" --") ||
381 !cmd_line.append(kCmdNewSetupExe) ||
382 !cmd_line.append(L"=\"") ||
383 !cmd_line.append(setup_dest_path.get()) ||
384 !cmd_line.append(L"\"")) { 379 !cmd_line.append(L"\"")) {
385 exit_code = ProcessExitResult(COMMAND_STRING_OVERFLOW); 380 exit_code = ProcessExitResult(COMMAND_STRING_OVERFLOW);
386 } 381 }
387 } 382 }
388 383
389 // Get any command line option specified for mini_installer and pass them 384 // Get any command line option specified for mini_installer and pass them
390 // on to setup.exe. 385 // on to setup.exe.
391 AppendCommandLineFlags(configuration.command_line(), &cmd_line); 386 AppendCommandLineFlags(configuration.command_line(), &cmd_line);
392 387
393 if (exit_code.IsSuccess()) 388 if (exit_code.IsSuccess())
394 exit_code = RunProcessAndWait(exe_path.get(), cmd_line.get()); 389 exit_code = RunProcessAndWait(exe_path.get(), cmd_line.get());
395 390
396 if (!exit_code.IsSuccess()) 391 if (!exit_code.IsSuccess())
397 DeleteFile(setup_path->get()); 392 DeleteFile(context->setup_resource_path->get());
398 else if (!setup_path->assign(setup_dest_path.get())) 393 else if (!context->setup_resource_path->assign(setup_dest_path.get()))
399 exit_code = ProcessExitResult(PATH_STRING_OVERFLOW); 394 exit_code = ProcessExitResult(PATH_STRING_OVERFLOW);
400 395
401 return exit_code; 396 return exit_code;
402 } 397 }
403 398
404 // setup.exe wasn't sent as 'B7', lets see if it was sent as 'BL' 399 // setup.exe wasn't sent as 'B7', lets see if it was sent as 'BL'
405 // (compressed setup). 400 // (compressed setup).
406 if (!::EnumResourceNames(module, kLZCResourceType, OnResourceFound, 401 if (!::EnumResourceNames(module, kLZCResourceType, OnResourceFound,
407 reinterpret_cast<LONG_PTR>(&context))) { 402 reinterpret_cast<LONG_PTR>(context))) {
408 return ProcessExitResult(UNABLE_TO_EXTRACT_SETUP_BL, ::GetLastError()); 403 return ProcessExitResult(UNABLE_TO_EXTRACT_SETUP_BL, ::GetLastError());
409 } 404 }
410 if (setup_path->length() == 0) { 405 if (context->setup_resource_path->length() == 0) {
411 // Neither setup_patch.packed.7z nor setup.ex_ was found. 406 // Neither setup_patch.packed.7z nor setup.ex_ was found.
412 return ProcessExitResult(UNABLE_TO_EXTRACT_SETUP); 407 return ProcessExitResult(UNABLE_TO_EXTRACT_SETUP);
413 } 408 }
414 409
415 // Uncompress LZ compressed resource. Setup is packed with 'MSCF' 410 // Uncompress LZ compressed resource. Setup is packed with 'MSCF'
416 // as opposed to old DOS way of 'SZDD'. Hence we don't use LZCopy. 411 // as opposed to old DOS way of 'SZDD'. Hence we don't use LZCopy.
417 bool success = 412 bool success = mini_installer::Expand(context->setup_resource_path->get(),
418 mini_installer::Expand(setup_path->get(), setup_dest_path.get()); 413 setup_dest_path.get());
419 ::DeleteFile(setup_path->get()); 414 ::DeleteFile(context->setup_resource_path->get());
420 if (success) { 415 if (success) {
421 if (!setup_path->assign(setup_dest_path.get())) { 416 if (!context->setup_resource_path->assign(setup_dest_path.get())) {
422 ::DeleteFile(setup_dest_path.get()); 417 ::DeleteFile(setup_dest_path.get());
423 exit_code = ProcessExitResult(PATH_STRING_OVERFLOW); 418 exit_code = ProcessExitResult(PATH_STRING_OVERFLOW);
424 } 419 }
425 } else { 420 } else {
426 exit_code = ProcessExitResult(UNABLE_TO_EXTRACT_SETUP_EXE); 421 exit_code = ProcessExitResult(UNABLE_TO_EXTRACT_SETUP_EXE);
427 } 422 }
428 423
424 #if defined(SYZYASAN)
425 PathString syzyasan_dest_path;
426 if (!syzyasan_dest_path.assign(context->base_path) ||
427 !syzyasan_dest_path.append(L"syzyasan_rtl.dll")) {
428 return ProcessExitResult(PATH_STRING_OVERFLOW);
429 }
430 success = mini_installer::Expand(context->syzyasan_resource_path->get(),
Sébastien Marchand 2017/04/05 21:07:02 This probably could be moved into a function, not
431 syzyasan_dest_path.get());
432 ::DeleteFile(context->syzyasan_resource_path->get());
433 if (success) {
434 if (!context->syzyasan_resource_path->assign(syzyasan_dest_path.get())) {
435 ::DeleteFile(syzyasan_dest_path.get());
436 exit_code = ProcessExitResult(PATH_STRING_OVERFLOW);
437 }
438 } else {
439 // TODO(sebmarchand): Add a new exit code for syzyasan_rtl.dll?
440 exit_code = ProcessExitResult(UNABLE_TO_EXTRACT_SETUP_EXE);
441 }
442 #endif
443
429 #if defined(COMPONENT_BUILD) 444 #if defined(COMPONENT_BUILD)
430 if (exit_code.IsSuccess()) { 445 if (exit_code.IsSuccess()) {
431 // Extract the (uncompressed) modules required by setup.exe. 446 // Extract the (uncompressed) modules required by setup.exe.
432 if (!::EnumResourceNames(module, kBinResourceType, WriteResourceToDirectory, 447 if (!::EnumResourceNames(module, kBinResourceType, WriteResourceToDirectory,
433 reinterpret_cast<LONG_PTR>(base_path))) { 448 reinterpret_cast<LONG_PTR>(base_path))) {
434 return ProcessExitResult(UNABLE_TO_EXTRACT_SETUP, ::GetLastError()); 449 return ProcessExitResult(UNABLE_TO_EXTRACT_SETUP, ::GetLastError());
435 } 450 }
436 } 451 }
437 #endif 452 #endif
438 453
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 // Set the magic suffix in registry to try full installer next time. We ignore 852 // Set the magic suffix in registry to try full installer next time. We ignore
838 // any errors here and we try to set the suffix for user level unless 853 // any errors here and we try to set the suffix for user level unless
839 // GoogleUpdateIsMachine=1 is present in the environment or --system-level is 854 // GoogleUpdateIsMachine=1 is present in the environment or --system-level is
840 // on the command line in which case we set it for system level instead. This 855 // on the command line in which case we set it for system level instead. This
841 // only applies to the Google Chrome distribution. 856 // only applies to the Google Chrome distribution.
842 SetInstallerFlags(configuration); 857 SetInstallerFlags(configuration);
843 #endif 858 #endif
844 859
845 PathString archive_path; 860 PathString archive_path;
846 PathString setup_path; 861 PathString setup_path;
847 exit_code = UnpackBinaryResources(configuration, module, base_path.get(), 862 #if defined(SYZYASAN)
848 &archive_path, &setup_path); 863 PathString syzyasan_rtl_path;
864 #endif
865 Context context = {
866 base_path.get(),
867 &archive_path,
868 &setup_path,
869 #if defined(SYZYASAN)
870 &syzyasan_rtl_path,
871 #endif
872 };
873 exit_code = UnpackBinaryResources(configuration, module, &context);
849 874
850 // While unpacking the binaries, we paged in a whole bunch of memory that 875 // While unpacking the binaries, we paged in a whole bunch of memory that
851 // we don't need anymore. Let's give it back to the pool before running 876 // we don't need anymore. Let's give it back to the pool before running
852 // setup. 877 // setup.
853 ::SetProcessWorkingSetSize(::GetCurrentProcess(), (SIZE_T)-1, (SIZE_T)-1); 878 ::SetProcessWorkingSetSize(::GetCurrentProcess(), (SIZE_T)-1, (SIZE_T)-1);
854 879
855 if (exit_code.IsSuccess()) 880 if (exit_code.IsSuccess())
856 exit_code = RunSetup(configuration, archive_path.get(), setup_path.get()); 881 exit_code = RunSetup(configuration, archive_path.get(), setup_path.get());
857 882
858 if (ShouldDeleteExtractedFiles()) 883 if (ShouldDeleteExtractedFiles())
859 DeleteExtractedFiles(base_path.get(), archive_path.get(), setup_path.get()); 884 DeleteExtractedFiles(base_path.get(), archive_path.get(), setup_path.get());
860 885
861 #if defined(GOOGLE_CHROME_BUILD) 886 #if defined(GOOGLE_CHROME_BUILD)
862 WriteInstallResults(configuration, exit_code); 887 WriteInstallResults(configuration, exit_code);
863 #endif 888 #endif
864 889
865 return exit_code; 890 return exit_code;
866 } 891 }
867 892
868 } // namespace mini_installer 893 } // namespace mini_installer
OLDNEW
« no previous file with comments | « chrome/installer/mini_installer/BUILD.gn ('k') | chrome/installer/mini_installer/mini_installer_constants.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698