Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 // |
| 11 // In order to be really small the app doesn't link against the CRT and | 11 // In order to be really small the app doesn't link against the CRT and |
| 12 // defines the following compiler/linker flags: | 12 // defines the following compiler/linker flags: |
| 13 // EnableIntrinsicFunctions="true" compiler: /Oi | 13 // EnableIntrinsicFunctions="true" compiler: /Oi |
| 14 // BasicRuntimeChecks="0" | 14 // BasicRuntimeChecks="0" |
| 15 // BufferSecurityCheck="false" compiler: /GS- | 15 // BufferSecurityCheck="false" compiler: /GS- |
| 16 // EntryPointSymbol="MainEntryPoint" linker: /ENTRY | 16 // EntryPointSymbol="MainEntryPoint" linker: /ENTRY |
| 17 // IgnoreAllDefaultLibraries="true" linker: /NODEFAULTLIB | 17 // IgnoreAllDefaultLibraries="true" linker: /NODEFAULTLIB |
| 18 // OptimizeForWindows98="1" liker: /OPT:NOWIN98 | 18 // OptimizeForWindows98="1" liker: /OPT:NOWIN98 |
| 19 // linker: /SAFESEH:NO | 19 // linker: /SAFESEH:NO |
| 20 | 20 |
| 21 // have the linker merge the sections, saving us ~500 bytes. | 21 // have the linker merge the sections, saving us ~500 bytes. |
| 22 #pragma comment(linker, "/MERGE:.rdata=.text") | 22 #pragma comment(linker, "/MERGE:.rdata=.text") |
| 23 | 23 |
| 24 #include <windows.h> | 24 #include <windows.h> |
| 25 #include <sddl.h> | |
| 25 #include <shellapi.h> | 26 #include <shellapi.h> |
| 26 #include <stdlib.h> | 27 #include <stdlib.h> |
| 27 | 28 |
| 28 #include "chrome/installer/mini_installer/appid.h" | 29 #include "chrome/installer/mini_installer/appid.h" |
| 29 #include "chrome/installer/mini_installer/configuration.h" | 30 #include "chrome/installer/mini_installer/configuration.h" |
| 30 #include "chrome/installer/mini_installer/decompress.h" | 31 #include "chrome/installer/mini_installer/decompress.h" |
| 31 #include "chrome/installer/mini_installer/exit_code.h" | 32 #include "chrome/installer/mini_installer/exit_code.h" |
| 32 #include "chrome/installer/mini_installer/mini_installer_constants.h" | 33 #include "chrome/installer/mini_installer/mini_installer_constants.h" |
| 33 #include "chrome/installer/mini_installer/mini_string.h" | 34 #include "chrome/installer/mini_installer/mini_string.h" |
| 34 #include "chrome/installer/mini_installer/pe_resource.h" | 35 #include "chrome/installer/mini_installer/pe_resource.h" |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 // Store the location where we'll append the id. | 557 // Store the location where we'll append the id. |
| 557 size_t end = work_dir->length(); | 558 size_t end = work_dir->length(); |
| 558 | 559 |
| 559 // Check if we'll have enough buffer space to continue. | 560 // Check if we'll have enough buffer space to continue. |
| 560 // The name of the directory will use up 11 chars and then we need to append | 561 // The name of the directory will use up 11 chars and then we need to append |
| 561 // the trailing backslash and a terminator. We've already added the prefix | 562 // the trailing backslash and a terminator. We've already added the prefix |
| 562 // to the buffer, so let's just make sure we've got enough space for the rest. | 563 // to the buffer, so let's just make sure we've got enough space for the rest. |
| 563 if ((work_dir->capacity() - end) < (_countof("fffff.tmp") + 1)) | 564 if ((work_dir->capacity() - end) < (_countof("fffff.tmp") + 1)) |
| 564 return false; | 565 return false; |
| 565 | 566 |
| 566 // Generate a unique id. We only use the lowest 20 bits, so take the top | 567 // Add an ACL if supported by the filesystem. |
| 567 // 12 bits and xor them with the lower bits. | 568 SECURITY_ATTRIBUTES sa = {0}; |
|
grt (UTC plus 2)
2015/12/03 21:38:32
nit: i prefer {} since {0} doesn't mean "initializ
jschuh
2015/12/04 00:40:27
Ah, good point.
| |
| 568 DWORD id = ::GetTickCount(); | 569 sa.nLength = sizeof(SECURITY_ATTRIBUTES); |
| 569 id ^= (id >> 12); | 570 DWORD flags; |
| 571 if (GetVolumeInformation(work_dir->get(), nullptr, 0, nullptr, nullptr, | |
| 572 &flags, nullptr, 0) && | |
| 573 (flags & FILE_PERSISTENT_ACLS)) { | |
| 574 static const wchar_t sddl[] = | |
| 575 L"D:AI(A;ID;FA;;;BA)" // Admin: Full control. | |
| 576 L"(A;OICIIOID;GA;;;BA)" | |
| 577 L"(A;ID;FA;;;SY)" // System: Full control. | |
| 578 L"(A;OICIIOID;GA;;;SY)" | |
| 579 L"(A;ID;FA;;;CO)"; // Owner: Full control. | |
| 580 L"(A;OICIIOID;GA;;;CO)"; | |
| 581 if (!ConvertStringSecurityDescriptorToSecurityDescriptor( | |
| 582 sddl, SDDL_REVISION, &sa.lpSecurityDescriptor, NULL)) { | |
| 583 return false; | |
|
grt (UTC plus 2)
2015/12/03 21:38:32
how about falling through to the previous case if
jschuh
2015/12/04 00:40:27
This is one of those must-never-fail sort of thing
| |
| 584 } | |
| 585 } | |
| 570 | 586 |
| 571 int max_attempts = 10; | 587 bool result = false; |
| 572 while (max_attempts--) { | 588 unsigned int id; |
| 589 rand_s(&id); | |
|
grt (UTC plus 2)
2015/12/03 21:38:32
we link with /NODEFAULTLIB. will this work?
jschuh
2015/12/04 00:40:27
Switched it to call RtlGenRandom() directly.
| |
| 590 for (int max_attempts = 10; max_attempts; --max_attempts) { | |
| 573 // This converts 'id' to a string in the format "78563412" on windows | 591 // This converts 'id' to a string in the format "78563412" on windows |
| 574 // because of little endianness, but we don't care since it's just | 592 // because of little endianness, but we don't care since it's just |
| 575 // a name. | 593 // a name. |
| 576 if (!HexEncode(&id, sizeof(id), work_dir->get() + end, | 594 if (!HexEncode(&id, 3, work_dir->get() + end, work_dir->capacity() - end)) { |
|
grt (UTC plus 2)
2015/12/03 21:38:32
nit: omit braces
jschuh
2015/12/04 00:40:28
Switched it back to sizeof.
| |
| 577 work_dir->capacity() - end)) { | 595 break; |
| 578 return false; | |
| 579 } | 596 } |
| 580 | 597 |
| 581 // We only want the first 5 digits to remain within the 8.3 file name | 598 // We only want the first 5 digits to remain within the 8.3 file name |
| 582 // format (compliant with previous implementation). | 599 // format (compliant with previous implementation). |
| 583 work_dir->truncate_at(end + 5); | 600 work_dir->truncate_at(end + 5); |
| 584 | 601 |
| 585 // for consistency with the previous implementation which relied on | 602 // for consistency with the previous implementation which relied on |
| 586 // GetTempFileName, we append the .tmp extension. | 603 // GetTempFileName, we append the .tmp extension. |
| 587 work_dir->append(L".tmp"); | 604 work_dir->append(L".tmp"); |
| 588 if (::CreateDirectory(work_dir->get(), NULL)) { | 605 |
| 606 if (::CreateDirectory(work_dir->get(), | |
| 607 sa.lpSecurityDescriptor ? &sa : nullptr)) { | |
| 589 // Yay! Now let's just append the backslash and we're done. | 608 // Yay! Now let's just append the backslash and we're done. |
| 590 return work_dir->append(L"\\"); | 609 result = work_dir->append(L"\\"); |
| 610 break; | |
| 591 } | 611 } |
| 592 ++id; // Try a different name. | 612 ++id; // Try a different name. |
| 593 } | 613 } |
| 594 | 614 |
| 595 return false; | 615 if (sa.lpSecurityDescriptor) |
| 616 LocalFree(sa.lpSecurityDescriptor); | |
| 617 return result; | |
| 596 } | 618 } |
| 597 | 619 |
| 598 // Creates and returns a temporary directory in |work_dir| that can be used to | 620 // Creates and returns a temporary directory in |work_dir| that can be used to |
| 599 // extract mini_installer payload. |work_dir| ends with a path separator. | 621 // extract mini_installer payload. |work_dir| ends with a path separator. |
| 600 bool GetWorkDir(HMODULE module, PathString* work_dir) { | 622 bool GetWorkDir(HMODULE module, PathString* work_dir) { |
| 601 PathString base_path; | 623 PathString base_path; |
| 602 DWORD len = ::GetTempPath(static_cast<DWORD>(base_path.capacity()), | 624 DWORD len = ::GetTempPath(static_cast<DWORD>(base_path.capacity()), |
| 603 base_path.get()); | 625 base_path.get()); |
| 604 if (!len || len >= base_path.capacity() || | 626 if (!len || len >= base_path.capacity() || |
| 605 !CreateWorkDir(base_path.get(), work_dir)) { | 627 !CreateWorkDir(base_path.get(), work_dir)) { |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 834 #pragma function(memset) | 856 #pragma function(memset) |
| 835 void* memset(void* dest, int c, size_t count) { | 857 void* memset(void* dest, int c, size_t count) { |
| 836 void* start = dest; | 858 void* start = dest; |
| 837 while (count--) { | 859 while (count--) { |
| 838 *reinterpret_cast<char*>(dest) = static_cast<char>(c); | 860 *reinterpret_cast<char*>(dest) = static_cast<char>(c); |
| 839 dest = reinterpret_cast<char*>(dest) + 1; | 861 dest = reinterpret_cast<char*>(dest) + 1; |
| 840 } | 862 } |
| 841 return start; | 863 return start; |
| 842 } | 864 } |
| 843 } // extern "C" | 865 } // extern "C" |
| OLD | NEW |