blob: aa750ad4fba665e99e5747bf00be91a787ee70a5 [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <Windows.h>
#include <Imagehlp.h>
#include <SoftPub.h>
#include <Wintrust.h>
#include <memory>
#include <sstream>
#include <string>
#include "base/const.h"
#include "base/logging.h"
#include "base/run_level.h"
#include "base/util.h"
#include "base/win_util.h"
#include "client/client_interface.h"
#include "renderer/renderer_client.h"
#include "win32/base/file_verifier.h"
#include "win32/base/imm_util.h"
#include "win32/broker/mozc_broker_resource.h"
namespace mozc {
namespace win32 {
namespace {
using std::unique_ptr;
const int kErrorLevelSuccess = 0;
const int kErrorLevelGeneralError = 1;
const int kErrorLevelCorruptedFileDetected = 2;
wstring LoadStringResource(int resource_id) {
wchar_t buffer[4096] = {};
const int copied_chars_without_null =
::LoadString(::GetModuleHandleW(nullptr), resource_id,
buffer, arraysize(buffer));
if (copied_chars_without_null == arraysize(buffer)) {
DLOG(ERROR) << "Message is truncated.";
return L"";
}
return wstring(buffer, copied_chars_without_null);
}
void EnterBackgroundThreadMode() {
// GetCurrentThread returns pseudo handle, which you need not
// to pass CloseHandle.
const HANDLE thread_handle = ::GetCurrentThread();
// Enter low priority mode.
::SetThreadPriority(thread_handle, THREAD_MODE_BACKGROUND_BEGIN);
}
} // namespace
int RunPrelaunchProcesses(int argc, char *argv[]) {
if (RunLevel::IsProcessInJob()) {
return kErrorLevelGeneralError;
}
bool is_service_process = false;
if (!WinUtil::IsServiceProcess(&is_service_process)) {
// Returns DENY conservatively.
return kErrorLevelGeneralError;
}
if (is_service_process) {
return kErrorLevelGeneralError;
}
if (!ImeUtil::IsDefault()) {
// If Mozc is not default, do nothing.
return kErrorLevelSuccess;
}
// To keep performance impact minimum, set current thread as background.
// On Vista and later, all the I/O including page faults well be handled
// in low priority if the thread is marked as background.
EnterBackgroundThreadMode();
const FileVerifier::MozcSystemFile kSourceFiles[] = {
FileVerifier::kMozcServerFile,
FileVerifier::kMozcRendererFile,
FileVerifier::kMozcToolFile,
};
wstringstream missing_files;
wstringstream corrupted_files;
for (size_t i = 0; i < arraysize(kSourceFiles); ++i) {
string fileinfo;
const FileVerifier::IntegrityType integrity_type =
FileVerifier::VerifyIntegrity(kSourceFiles[i], &fileinfo);
switch (integrity_type) {
case FileVerifier::kIntegrityCorrupted: {
wstring wfileinfo;
Util::UTF8ToWide(fileinfo, &wfileinfo);
corrupted_files << L"\r\n " << wfileinfo;
break;
}
case FileVerifier::kIntegrityFileNotFound: {
wstring wfileinfo;
Util::UTF8ToWide(fileinfo, &wfileinfo);
missing_files << L"\r\n " << wfileinfo;
break;
}
}
}
const wstring &corrupted_files_str = corrupted_files.str();
const wstring &missing_files_str = missing_files.str();
if (!corrupted_files_str.empty() || !missing_files_str.empty()) {
wstringstream message;
message << LoadStringResource(IDS_DIALOG_MESSAGE);
if (!corrupted_files_str.empty()) {
message << L"\r\n" << LoadStringResource(IDS_DIALOG_FILE_CORRUPTED)
<< L":" << corrupted_files_str;
}
if (!missing_files_str.empty()) {
message << L"\r\n" << LoadStringResource(IDS_DIALOG_FILE_NOT_FOUND)
<< L":" << missing_files_str;
}
::MessageBoxW(nullptr, message.str().c_str(),
LoadStringResource(IDS_DIALOG_TITLE).c_str(),
MB_OK | MB_ICONERROR | MB_DEFAULT_DESKTOP_ONLY);
return kErrorLevelCorruptedFileDetected;
}
{
unique_ptr<client::ClientInterface> converter_client(
client::ClientFactory::NewClient());
converter_client->set_suppress_error_dialog(true);
converter_client->EnsureConnection();
}
{
unique_ptr<renderer::RendererClient> renderer_client(
new mozc::renderer::RendererClient);
renderer_client->set_suppress_error_dialog(true);
renderer_client->Activate();
}
return kErrorLevelSuccess;
}
} // namespace win32
} // namespace mozc