summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/win/windows_version.cc20
-rw-r--r--base/win/windows_version.h21
-rw-r--r--chrome/browser/memory_details_win.cc22
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc26
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h5
-rw-r--r--chrome/installer/setup/install_worker.cc23
-rw-r--r--sandbox/src/Wow64.cc50
-rw-r--r--sandbox/src/Wow64.h16
-rw-r--r--sandbox/src/Wow64_64.cc8
-rw-r--r--sandbox/src/interception.cc8
-rw-r--r--sandbox/src/service_resolver_unittest.cc21
-rw-r--r--sandbox/tests/common/controller.cc13
12 files changed, 89 insertions, 144 deletions
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc
index a80688c..9abf1d2 100644
--- a/base/win/windows_version.cc
+++ b/base/win/windows_version.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -68,5 +68,23 @@ void GetServicePackLevel(int* major, int* minor) {
*minor = service_pack_minor;
}
+WOW64Status GetWOW64Status() {
+ static WOW64Status wow64_status =
+ GetWOW64StatusForProcess(GetCurrentProcess());
+ return wow64_status;
+}
+
+WOW64Status GetWOW64StatusForProcess(HANDLE process_handle) {
+ typedef BOOL (WINAPI* IsWow64ProcessFunc)(HANDLE, PBOOL);
+ IsWow64ProcessFunc is_wow64_process = reinterpret_cast<IsWow64ProcessFunc>(
+ GetProcAddress(GetModuleHandle(L"kernel32.dll"), "IsWow64Process"));
+ if (!is_wow64_process)
+ return WOW64_DISABLED;
+ BOOL is_wow64 = FALSE;
+ if (!(*is_wow64_process)(process_handle, &is_wow64))
+ return WOW64_UNKNOWN;
+ return is_wow64 ? WOW64_ENABLED : WOW64_DISABLED;
+}
+
} // namespace win
} // namespace base
diff --git a/base/win/windows_version.h b/base/win/windows_version.h
index 7e281a6..0cfb2c7 100644
--- a/base/win/windows_version.h
+++ b/base/win/windows_version.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,8 @@
#define BASE_WIN_WINDOWS_VERSION_H_
#pragma once
+typedef void* HANDLE;
+
namespace base {
namespace win {
@@ -28,6 +30,23 @@ Version GetVersion();
// Returns the major and minor version of the service pack installed.
void GetServicePackLevel(int* major, int* minor);
+enum WOW64Status {
+ WOW64_DISABLED,
+ WOW64_ENABLED,
+ WOW64_UNKNOWN,
+};
+
+// Returns whether this process is running under WOW64 (the wrapper that allows
+// 32-bit processes to run on 64-bit versions of Windows). This will return
+// WOW64_DISABLED for both "32-bit Chrome on 32-bit Windows" and "64-bit Chrome
+// on 64-bit Windows". WOW64_UNKNOWN means "an error occurred", e.g. the
+// process does not have sufficient access rights to determine this.
+WOW64Status GetWOW64Status();
+
+// Like GetWOW64Status(), but for the supplied handle instead of the current
+// process.
+WOW64Status GetWOW64StatusForProcess(HANDLE process_handle);
+
} // namespace win
} // namespace base
diff --git a/chrome/browser/memory_details_win.cc b/chrome/browser/memory_details_win.cc
index 0e9f063..edb53c8 100644
--- a/chrome/browser/memory_details_win.cc
+++ b/chrome/browser/memory_details_win.cc
@@ -11,6 +11,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/win/scoped_handle.h"
+#include "base/win/windows_version.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_child_process_host.h"
@@ -89,19 +90,13 @@ void MemoryDetails::CollectProcessData(
}
do {
base::ProcessId pid = process_entry.th32ProcessID;
- base::win::ScopedHandle handle(::OpenProcess(
+ base::win::ScopedHandle process_handle(::OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid));
- if (!handle.Get())
+ if (!process_handle.Get())
continue;
- bool is_64bit_process = false;
- // IsWow64Process() returns FALSE for a 32bit process on a 32bit OS.
- // We need to check if the real OS is 64bit.
- if (is_64bit_os) {
- BOOL is_wow64 = FALSE;
- // IsWow64Process() is supported by Windows XP SP2 or later.
- IsWow64Process(handle, &is_wow64);
- is_64bit_process = !is_wow64;
- }
+ bool is_64bit_process = is_64bit_os &&
+ (base::win::GetWOW64StatusForProcess(process_handle) ==
+ base::win::WOW64_DISABLED);
for (unsigned int index2 = 0; index2 < process_data_.size(); index2++) {
if (_wcsicmp(process_data_[index2].process_name.c_str(),
process_entry.szExeFile) != 0)
@@ -117,7 +112,7 @@ void MemoryDetails::CollectProcessData(
info.type = ChildProcessInfo::UNKNOWN_PROCESS;
scoped_ptr<base::ProcessMetrics> metrics;
- metrics.reset(base::ProcessMetrics::CreateProcessMetrics(handle));
+ metrics.reset(base::ProcessMetrics::CreateProcessMetrics(process_handle));
metrics->GetCommittedKBytes(&info.committed);
metrics->GetWorkingSetKBytes(&info.working_set);
@@ -136,7 +131,8 @@ void MemoryDetails::CollectProcessData(
info.type = child_info[child].type;
break;
}
- } else if (GetModuleFileNameEx(handle, NULL, name, MAX_PATH - 1)) {
+ } else if (GetModuleFileNameEx(process_handle, NULL, name,
+ MAX_PATH - 1)) {
std::wstring str_name(name);
scoped_ptr<FileVersionInfo> version_info(
FileVersionInfo::CreateFileVersionInfo(FilePath(str_name)));
diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc
index 2064407..2b97881 100644
--- a/chrome/browser/nacl_host/nacl_process_host.cc
+++ b/chrome/browser/nacl_host/nacl_process_host.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -13,6 +13,7 @@
#include "base/command_line.h"
#include "base/metrics/nacl_histogram.h"
#include "base/utf_string_conversions.h"
+#include "base/win/windows_version.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/logging_chrome.h"
#include "chrome/common/nacl_cmd_line.h"
@@ -58,7 +59,7 @@ NaClProcessHost::NaClProcessHost(
running_on_wow64_(false) {
set_name(url);
#if defined(OS_WIN)
- CheckIsWow64();
+ running_on_wow64_ = (base::win::GetWOW64Status() == base::win::WOW64_ENABLED);
#endif
}
@@ -301,24 +302,3 @@ bool NaClProcessHost::OnMessageReceived(const IPC::Message& msg) {
bool NaClProcessHost::CanShutdown() {
return true;
}
-
-#if defined(OS_WIN)
-// TODO(gregoryd): invoke CheckIsWow64 only once, not for each NaClProcessHost
-typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
-void NaClProcessHost::CheckIsWow64() {
- LPFN_ISWOW64PROCESS fnIsWow64Process;
-
- fnIsWow64Process = (LPFN_ISWOW64PROCESS) GetProcAddress(
- GetModuleHandle(TEXT("kernel32")),
- "IsWow64Process");
-
- if (fnIsWow64Process != NULL) {
- BOOL bIsWow64 = FALSE;
- if (fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) {
- if (bIsWow64) {
- running_on_wow64_ = true;
- }
- }
- }
-}
-#endif
diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h
index 46c5468..b4deaea 100644
--- a/chrome/browser/nacl_host/nacl_process_host.h
+++ b/chrome/browser/nacl_host/nacl_process_host.h
@@ -54,11 +54,6 @@ class NaClProcessHost : public BrowserChildProcessHost {
virtual bool CanShutdown();
-#if defined(OS_WIN)
- // Check whether the browser process is running on WOW64 - Windows only
- void CheckIsWow64();
-#endif
-
private:
ResourceDispatcherHost* resource_dispatcher_host_;
diff --git a/chrome/installer/setup/install_worker.cc b/chrome/installer/setup/install_worker.cc
index 495d3b1..70e1ab6 100644
--- a/chrome/installer/setup/install_worker.cc
+++ b/chrome/installer/setup/install_worker.cc
@@ -19,6 +19,7 @@
#include "base/utf_string_conversions.h"
#include "base/version.h"
#include "base/win/registry.h"
+#include "base/win/windows_version.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/installer/setup/install.h"
#include "chrome/installer/setup/setup_constants.h"
@@ -39,24 +40,6 @@
using base::win::RegKey;
-namespace {
-
-// This method tells if we are running on 64 bit platform so that we can copy
-// one extra exe. If the API call to determine 64 bit fails, we play it safe
-// and return true anyway so that the executable can be copied.
-bool Is64bit() {
- typedef BOOL (WINAPI* WOW_FUNC)(HANDLE, BOOL*);
- BOOL is_64 = FALSE;
-
- HMODULE module = GetModuleHandle(L"kernel32.dll");
- WOW_FUNC is_wow64 = reinterpret_cast<WOW_FUNC>(
- GetProcAddress(module, "IsWow64Process"));
- return (is_wow64 != NULL) &&
- (!(is_wow64)(GetCurrentProcess(), &is_64) || (is_64 != FALSE));
-}
-
-} // namespace
-
namespace installer {
// Local helper to call AddRegisterComDllWorkItems for all DLLs in a set of
@@ -556,7 +539,9 @@ void AddInstallWorkItems(const InstallationState& original_state,
temp_path.value(), WorkItem::NEW_NAME_IF_IN_USE, new_chrome_exe.value());
// Extra executable for 64 bit systems.
- if (Is64bit()) {
+ // NOTE: We check for "not disabled" so that if the API call fails, we play it
+ // safe and copy the executable anyway.
+ if (base::win::GetWOW64Status() != base::win::WOW64_DISABLED) {
install_list->AddMoveTreeWorkItem(
src_path.Append(installer::kWowHelperExe).value(),
target_path.Append(installer::kWowHelperExe).value(),
diff --git a/sandbox/src/Wow64.cc b/sandbox/src/Wow64.cc
index dec5e50..79febe8 100644
--- a/sandbox/src/Wow64.cc
+++ b/sandbox/src/Wow64.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -8,7 +8,7 @@
#include "base/logging.h"
#include "base/scoped_ptr.h"
-#include "sandbox/src/sandbox.h"
+#include "base/win/windows_version.h"
#include "sandbox/src/target_process.h"
namespace {
@@ -80,33 +80,6 @@ Wow64::~Wow64() {
::CloseHandle(continue_load_);
}
-bool Wow64::IsWow64() {
- if (init_)
- return is_wow64_;
-
- is_wow64_ = false;
-
- HMODULE kernel32 = ::GetModuleHandle(sandbox::kKerneldllName);
- if (!kernel32)
- return false;
-
- IsWow64ProcessFunction is_wow64_process = reinterpret_cast<
- IsWow64ProcessFunction>(::GetProcAddress(kernel32, "IsWow64Process"));
-
- init_ = true;
- if (!is_wow64_process)
- return false;
-
- BOOL wow64;
- if (!is_wow64_process(::GetCurrentProcess(), &wow64))
- return false;
-
- if (wow64)
- is_wow64_ = true;
-
- return is_wow64_;
-}
-
// The basic idea is to allocate one page of memory on the child, and initialize
// the first part of it with our version of PatchInfo32. Then launch the helper
// process passing it that address on the child. The helper process will patch
@@ -114,9 +87,8 @@ bool Wow64::IsWow64() {
// first event on the buffer. We'll be waiting on that event and after the 32
// bit version of ntdll is loaded, we'll remove the interception and return to
// our caller.
-bool Wow64::WaitForNtdll(DWORD timeout_ms) {
- DCHECK(!init_);
- if (!IsWow64())
+bool Wow64::WaitForNtdll() {
+ if (base::win::GetWOW64Status() != base::win::WOW64_ENABLED)
return true;
const size_t page_size = 4096;
@@ -151,19 +123,19 @@ bool Wow64::WaitForNtdll(DWORD timeout_ms) {
if (offsetof(PatchInfo32, section) != written)
return false;
- if (!RunWowHelper(buffer, timeout_ms))
+ if (!RunWowHelper(buffer))
return false;
// The child is intercepted on 64 bit, go on and wait for our event.
- if (!DllMapped(timeout_ms))
+ if (!DllMapped())
return false;
// The 32 bit version is available, cleanup the child.
return Restore64Code(child_->Process(), patch_info);
}
-bool Wow64::RunWowHelper(void* buffer, DWORD timeout_ms) {
- COMPILE_ASSERT(sizeof(buffer) <= sizeof(timeout_ms), unsupported_64_bits);
+bool Wow64::RunWowHelper(void* buffer) {
+ COMPILE_ASSERT(sizeof(buffer) <= sizeof DWORD, unsupported_64_bits);
// Get the path to the helper (beside the exe).
wchar_t prog_name[MAX_PATH];
@@ -188,7 +160,7 @@ bool Wow64::RunWowHelper(void* buffer, DWORD timeout_ms) {
NULL, &startup_info, &process_info))
return false;
- DWORD reason = ::WaitForSingleObject(process_info.hProcess, timeout_ms);
+ DWORD reason = ::WaitForSingleObject(process_info.hProcess, INFINITE);
DWORD code;
bool ok = ::GetExitCodeProcess(process_info.hProcess, &code) ? true : false;
@@ -204,14 +176,14 @@ bool Wow64::RunWowHelper(void* buffer, DWORD timeout_ms) {
// First we must wake up the child, then wait for dll loads on the child until
// the one we care is loaded; at that point we must suspend the child again.
-bool Wow64::DllMapped(DWORD timeout_ms) {
+bool Wow64::DllMapped() {
if (1 != ::ResumeThread(child_->MainThread())) {
NOTREACHED();
return false;
}
for (;;) {
- DWORD reason = ::WaitForSingleObject(dll_load_, timeout_ms);
+ DWORD reason = ::WaitForSingleObject(dll_load_, INFINITE);
if (WAIT_TIMEOUT == reason || WAIT_ABANDONED == reason)
return false;
diff --git a/sandbox/src/Wow64.h b/sandbox/src/Wow64.h
index 7ee981a..472297e 100644
--- a/sandbox/src/Wow64.h
+++ b/sandbox/src/Wow64.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,25 +19,21 @@ class TargetProcess;
class Wow64 {
public:
Wow64(TargetProcess* child, HMODULE ntdll)
- : child_(child), ntdll_(ntdll), init_(false), dll_load_(NULL),
- continue_load_(NULL) {}
+ : child_(child), ntdll_(ntdll), dll_load_(NULL), continue_load_(NULL) {}
~Wow64();
// Waits for the 32 bit DLL to get loaded on the child process. This function
// will return immediately if not running under WOW, or launch the helper
// process and wait until ntdll is ready.
- bool WaitForNtdll(DWORD timeout_ms);
-
- // Returns true if this is a 32 bit process running on a 64 bit OS.
- bool IsWow64();
+ bool WaitForNtdll();
private:
// Runs the WOW helper process, passing the address of a buffer allocated on
// the child (one page).
- bool RunWowHelper(void* buffer, DWORD timeout_ms);
+ bool RunWowHelper(void* buffer);
// This method receives "notifications" whenever a DLL is mapped on the child.
- bool DllMapped(DWORD timeout_ms);
+ bool DllMapped();
// Returns true if ntdll.dll is mapped on the child.
bool NtdllPresent();
@@ -46,8 +42,6 @@ class Wow64 {
HMODULE ntdll_; // ntdll on the parent.
HANDLE dll_load_; // Event that is signaled on dll load.
HANDLE continue_load_; // Event to signal to continue execution on the child.
- bool init_; // Initialization control.
- bool is_wow64_; // true on WOW64 environments.
DISALLOW_IMPLICIT_CONSTRUCTORS(Wow64);
};
diff --git a/sandbox/src/Wow64_64.cc b/sandbox/src/Wow64_64.cc
index e188d68..5218077 100644
--- a/sandbox/src/Wow64_64.cc
+++ b/sandbox/src/Wow64_64.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,11 +11,7 @@ namespace sandbox {
Wow64::~Wow64() {
}
-bool Wow64::IsWow64() {
- return false;
-}
-
-bool Wow64::WaitForNtdll(DWORD timeout_ms) {
+bool Wow64::WaitForNtdll() {
return true;
}
diff --git a/sandbox/src/interception.cc b/sandbox/src/interception.cc
index 6636cc3..e9f89dc 100644
--- a/sandbox/src/interception.cc
+++ b/sandbox/src/interception.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -424,9 +424,9 @@ bool InterceptionManager::PatchClientFunctions(DllInterceptionData* thunks,
return false;
}
- Wow64 WowHelper(child_, ntdll_base);
if (base::win::GetVersion() <= base::win::VERSION_VISTA) {
- if (!WowHelper.WaitForNtdll(INFINITE))
+ Wow64 WowHelper(child_, ntdll_base);
+ if (!WowHelper.WaitForNtdll())
return false;
}
@@ -438,7 +438,7 @@ bool InterceptionManager::PatchClientFunctions(DllInterceptionData* thunks,
#endif
ServiceResolverThunk* thunk;
- if (WowHelper.IsWow64())
+ if (base::win::GetWOW64Status() == base::win::WOW64_ENABLED)
thunk = new Wow64ResolverThunk(child_->Process(), relaxed_);
else if (!IsXPSP2OrLater())
thunk = new Win2kResolverThunk(child_->Process(), relaxed_);
diff --git a/sandbox/src/service_resolver_unittest.cc b/sandbox/src/service_resolver_unittest.cc
index 793d4a1..777a5da 100644
--- a/sandbox/src/service_resolver_unittest.cc
+++ b/sandbox/src/service_resolver_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,10 +6,10 @@
#include "base/basictypes.h"
#include "base/scoped_ptr.h"
+#include "base/win/windows_version.h"
#include "sandbox/src/resolver.h"
#include "sandbox/src/sandbox_utils.h"
#include "sandbox/src/service_resolver.h"
-#include "sandbox/src/wow64.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -120,18 +120,11 @@ NTSTATUS PatchNtdllWithResolver(const char* function, bool relaxed,
}
sandbox::ServiceResolverThunk* GetTestResolver(bool relaxed) {
- HMODULE ntdll_base = ::GetModuleHandle(L"ntdll.dll");
- EXPECT_TRUE(NULL != ntdll_base);
- sandbox::Wow64 WowHelper(NULL, ntdll_base);
-
- sandbox::ServiceResolverThunk* resolver;
- if (WowHelper.IsWow64())
- resolver = new Wow64ResolverTest(relaxed);
- else if (!sandbox::IsXPSP2OrLater())
- resolver = new Win2kResolverTest(relaxed);
- else
- resolver = new WinXpResolverTest(relaxed);
- return resolver;
+ if (base::win::GetWOW64Status() == base::win::WOW64_ENABLED)
+ return new Wow64ResolverTest(relaxed);
+ if (!sandbox::IsXPSP2OrLater())
+ return new Win2kResolverTest(relaxed);
+ return new WinXpResolverTest(relaxed);
}
NTSTATUS PatchNtdll(const char* function, bool relaxed) {
diff --git a/sandbox/tests/common/controller.cc b/sandbox/tests/common/controller.cc
index 6e0f080..7efd374 100644
--- a/sandbox/tests/common/controller.cc
+++ b/sandbox/tests/common/controller.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,9 +6,9 @@
#include <string>
+#include "base/win/windows_version.h"
#include "sandbox/src/sandbox_factory.h"
#include "sandbox/src/sandbox_utils.h"
-#include "sandbox/src/wow64.h"
namespace {
@@ -55,11 +55,9 @@ std::wstring MakePathToSysWow64(const wchar_t* name, bool is_obj_man_path) {
namespace sandbox {
std::wstring MakePathToSys(const wchar_t* name, bool is_obj_man_path) {
- Wow64 current_proc(NULL, NULL);
- if (current_proc.IsWow64())
+ if (base::win::GetWOW64Status() == base::win::WOW64_ENABLED)
return MakePathToSysWow64(name, is_obj_man_path);
- else
- return MakePathToSys32(name, is_obj_man_path);
+ return MakePathToSys32(name, is_obj_man_path);
}
BrokerServices* GetBroker() {
@@ -140,8 +138,7 @@ bool TestRunner::AddRuleSys32(TargetPolicy::Semantics semantics,
if (!AddRule(TargetPolicy::SUBSYS_FILES, semantics, win32_path.c_str()))
return false;
- Wow64 current_proc(NULL, NULL);
- if (!current_proc.IsWow64())
+ if (base::win::GetWOW64Status() != base::win::WOW64_ENABLED)
return true;
win32_path = MakePathToSysWow64(pattern, false);