1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <windows.h> 6 7 #include "chrome/installer/util/logging_installer.h" 8 9 #include "base/command_line.h" 10 #include "base/file_util.h" 11 #include "base/files/file.h" 12 #include "base/files/file_path.h" 13 #include "base/logging.h" 14 #include "base/logging_win.h" 15 #include "base/path_service.h" 16 #include "base/strings/string_util.h" 17 #include "base/strings/utf_string_conversions.h" 18 #include "base/win/scoped_handle.h" 19 #include "chrome/installer/util/master_preferences.h" 20 #include "chrome/installer/util/master_preferences_constants.h" 21 #include "chrome/installer/util/util_constants.h" 22 23 // {93BCE0BF-3FAF-43b1-9E28-BEB6FAB5ECE7} 24 static const GUID kSetupTraceProvider = { 0x93bce0bf, 0x3faf, 0x43b1, 25 { 0x9e, 0x28, 0xbe, 0xb6, 0xfa, 0xb5, 0xec, 0xe7 } }; 26 27 namespace installer { 28 29 // This should be true for the period between the end of 30 // InitInstallerLogging() and the beginning of EndInstallerLogging(). 31 bool installer_logging_ = false; 32 33 TruncateResult TruncateLogFileIfNeeded(const base::FilePath& log_file) { 34 TruncateResult result = LOGFILE_UNTOUCHED; 35 36 int64 log_size = 0; 37 if (base::GetFileSize(log_file, &log_size) && 38 log_size > kMaxInstallerLogFileSize) { 39 // Cause the old log file to be deleted when we are done with it. 40 uint32 file_flags = base::File::FLAG_OPEN | 41 base::File::FLAG_READ | 42 base::File::FLAG_SHARE_DELETE | 43 base::File::FLAG_DELETE_ON_CLOSE; 44 base::File old_log_file(log_file, file_flags); 45 46 if (old_log_file.IsValid()) { 47 result = LOGFILE_DELETED; 48 base::FilePath tmp_log(log_file.value() + FILE_PATH_LITERAL(".tmp")); 49 // Note that base::Move will attempt to replace existing files. 50 if (base::Move(log_file, tmp_log)) { 51 int64 offset = log_size - kTruncatedInstallerLogFileSize; 52 std::string old_log_data(kTruncatedInstallerLogFileSize, 0); 53 int bytes_read = old_log_file.Read(offset, 54 &old_log_data[0], 55 kTruncatedInstallerLogFileSize); 56 if (bytes_read > 0 && 57 (bytes_read == base::WriteFile(log_file, &old_log_data[0], 58 bytes_read) || 59 base::PathExists(log_file))) { 60 result = LOGFILE_TRUNCATED; 61 } 62 } 63 } else if (base::DeleteFile(log_file, false)) { 64 // Couldn't get sufficient access to the log file, optimistically try to 65 // delete it. 66 result = LOGFILE_DELETED; 67 } 68 } 69 70 return result; 71 } 72 73 74 void InitInstallerLogging(const installer::MasterPreferences& prefs) { 75 if (installer_logging_) 76 return; 77 78 installer_logging_ = true; 79 80 bool value = false; 81 if (prefs.GetBool(installer::master_preferences::kDisableLogging, 82 &value) && value) { 83 return; 84 } 85 86 base::FilePath log_file_path(GetLogFilePath(prefs)); 87 TruncateLogFileIfNeeded(log_file_path); 88 89 logging::LoggingSettings settings; 90 settings.logging_dest = logging::LOG_TO_FILE; 91 settings.log_file = log_file_path.value().c_str(); 92 logging::InitLogging(settings); 93 94 if (prefs.GetBool(installer::master_preferences::kVerboseLogging, 95 &value) && value) { 96 logging::SetMinLogLevel(logging::LOG_VERBOSE); 97 } else { 98 logging::SetMinLogLevel(logging::LOG_ERROR); 99 } 100 101 // Enable ETW logging. 102 logging::LogEventProvider::Initialize(kSetupTraceProvider); 103 } 104 105 void EndInstallerLogging() { 106 logging::CloseLogFile(); 107 108 installer_logging_ = false; 109 } 110 111 base::FilePath GetLogFilePath(const installer::MasterPreferences& prefs) { 112 std::string path; 113 prefs.GetString(installer::master_preferences::kLogFile, &path); 114 if (!path.empty()) 115 return base::FilePath(base::UTF8ToWide(path)); 116 117 static const base::FilePath::CharType kLogFilename[] = 118 FILE_PATH_LITERAL("chrome_installer.log"); 119 120 // Fallback to current directory if getting the temp directory fails. 121 base::FilePath tmp_path; 122 ignore_result(PathService::Get(base::DIR_TEMP, &tmp_path)); 123 return tmp_path.Append(kLogFilename); 124 } 125 126 } // namespace installer 127