Index: base/win/win_util.cc |
diff --git a/base/win/win_util.cc b/base/win/win_util.cc |
index c5b06c48f8a10ce55206c7ec992fa61f6036de90..7b4f61279146169649b88ec79577d96ccb75f245 100644 |
--- a/base/win/win_util.cc |
+++ b/base/win/win_util.cc |
@@ -19,11 +19,14 @@ |
#include <signal.h> |
#include <stdlib.h> |
+#include "base/base_switches.h" |
+#include "base/command_line.h" |
#include "base/lazy_instance.h" |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/strings/string_util.h" |
#include "base/strings/stringprintf.h" |
+#include "base/strings/utf_string_conversions.h" |
#include "base/threading/thread_restrictions.h" |
#include "base/win/metro.h" |
#include "base/win/registry.h" |
@@ -32,13 +35,16 @@ |
#include "base/win/scoped_propvariant.h" |
#include "base/win/windows_version.h" |
+namespace base { |
+namespace win { |
+ |
namespace { |
// Sets the value of |property_key| to |property_value| in |property_store|. |
bool SetPropVariantValueForPropertyStore( |
IPropertyStore* property_store, |
const PROPERTYKEY& property_key, |
- const base::win::ScopedPropVariant& property_value) { |
+ const ScopedPropVariant& property_value) { |
DCHECK(property_store); |
HRESULT result = property_store->SetValue(property_key, property_value.get()); |
@@ -48,31 +54,56 @@ bool SetPropVariantValueForPropertyStore( |
} |
void __cdecl ForceCrashOnSigAbort(int) { |
- *((int*)0) = 0x1337; |
+ *((volatile int*)0) = 0x1337; |
} |
const wchar_t kWindows8OSKRegPath[] = |
L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" |
L"\\LocalServer32"; |
+} // namespace |
+ |
// Returns true if a physical keyboard is detected on Windows 8 and up. |
// Uses the Setup APIs to enumerate the attached keyboards and returns true |
// if the keyboard count is 1 or more.. While this will work in most cases |
// it won't work if there are devices which expose keyboard interfaces which |
// are attached to the machine. |
-bool IsKeyboardPresentOnSlate() { |
+bool IsKeyboardPresentOnSlate(std::string* reason) { |
+ bool result = false; |
+ |
+ if (GetVersion() < VERSION_WIN7) { |
+ *reason = "Detection not supported"; |
+ return false; |
+ } |
+ |
// This function is only supported for Windows 8 and up. |
- DCHECK(base::win::GetVersion() >= base::win::VERSION_WIN8); |
+ if (CommandLine::ForCurrentProcess()->HasSwitch( |
+ switches::kDisableUsbKeyboardDetect)) { |
+ if (reason) |
+ *reason = "Detection disabled"; |
+ return false; |
+ } |
// This function should be only invoked for machines with touch screens. |
if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) |
!= NID_INTEGRATED_TOUCH) { |
- return true; |
+ if (reason) { |
+ *reason += "NID_INTEGRATED_TOUCH\n"; |
+ result = true; |
+ } else { |
+ return true; |
+ } |
} |
// If the device is docked, the user is treating the device as a PC. |
- if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) |
- return true; |
+ if (GetSystemMetrics(SM_SYSTEMDOCKED) != 0) { |
+ if (reason) { |
+ *reason += "SM_SYSTEMDOCKED\n"; |
+ result = true; |
+ } else { |
+ return true; |
+ } |
+ } |
// To determine whether a keyboard is present on the device, we do the |
// following:- |
@@ -103,7 +134,13 @@ bool IsKeyboardPresentOnSlate() { |
// If there is no auto rotation sensor or rotation is not supported in |
// the current configuration, then we can assume that this is a desktop |
// or a traditional laptop. |
- return true; |
+ if (reason) { |
+ *reason += (auto_rotation_state & AR_NOSENSOR) ? "AR_NOSENSOR\n" |
+ : "AR_NOT_SUPPORTED\n"; |
+ result = true; |
+ } else { |
+ return true; |
+ } |
} |
} |
@@ -114,8 +151,15 @@ bool IsKeyboardPresentOnSlate() { |
POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); |
if (((role == PlatformRoleMobile) || (role == PlatformRoleSlate)) && |
- (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) |
- return false; |
+ (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0)) { |
+ if (reason) { |
+ *reason += (role == PlatformRoleMobile) ? "PlatformRoleMobile\n" |
+ : "PlatformRoleSlate\n"; |
+ // Don't change result here if it's already true. |
+ } else { |
+ return false; |
+ } |
+ } |
const GUID KEYBOARD_CLASS_GUID = |
{ 0x4D36E96B, 0xE325, 0x11CE, |
@@ -124,13 +168,15 @@ bool IsKeyboardPresentOnSlate() { |
// Query for all the keyboard devices. |
HDEVINFO device_info = |
SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); |
- if (device_info == INVALID_HANDLE_VALUE) |
- return false; |
+ if (device_info == INVALID_HANDLE_VALUE) { |
+ if (reason) |
+ *reason += "No keyboard info\n"; |
+ return result; |
+ } |
// Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If |
// the count is more than 1 we assume that a keyboard is present. This is |
// under the assumption that there will always be one keyboard device. |
- int keyboard_count = 0; |
for (DWORD i = 0;; ++i) { |
SP_DEVINFO_DATA device_info_data = { 0 }; |
device_info_data.cbSize = sizeof(device_info_data); |
@@ -146,23 +192,24 @@ bool IsKeyboardPresentOnSlate() { |
if (status == CR_SUCCESS) { |
// To reduce the scope of the hack we only look for ACPI and HID\\VID |
// prefixes in the keyboard device ids. |
- if (StartsWith(device_id, L"ACPI", false) || |
- StartsWith(device_id, L"HID\\VID", false)) { |
- keyboard_count++; |
+ if (StartsWith(device_id, L"ACPI", CompareCase::INSENSITIVE_ASCII) || |
+ StartsWith(device_id, L"HID\\VID", CompareCase::INSENSITIVE_ASCII)) { |
+ if (reason) { |
+ *reason += "device: "; |
+ *reason += WideToUTF8(device_id); |
+ *reason += '\n'; |
+ } |
+ // The heuristic we are using is to check the count of keyboards and |
+ // return true if the API's report one or more keyboards. Please note |
+ // that this will break for non keyboard devices which expose a |
+ // keyboard PDO. |
+ result = true; |
} |
} |
} |
- // The heuristic we are using is to check the count of keyboards and return |
- // true if the API's report one or more keyboards. Please note that this |
- // will break for non keyboard devices which expose a keyboard PDO. |
- return keyboard_count >= 1; |
+ return result; |
} |
-} // namespace |
- |
-namespace base { |
-namespace win { |
- |
static bool g_crash_on_process_detach = false; |
void GetNonClientMetrics(NONCLIENTMETRICS_XP* metrics) { |
@@ -181,7 +228,7 @@ bool GetUserSidString(std::wstring* user_sid) { |
HANDLE token = NULL; |
if (!::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &token)) |
return false; |
- base::win::ScopedHandle token_scoped(token); |
+ ScopedHandle token_scoped(token); |
DWORD size = sizeof(TOKEN_USER) + SECURITY_MAX_SID_SIZE; |
scoped_ptr<BYTE[]> user_bytes(new BYTE[size]); |
@@ -226,11 +273,11 @@ bool UserAccountControlIsEnabled() { |
// This can be slow if Windows ends up going to disk. Should watch this key |
// for changes and only read it once, preferably on the file thread. |
// http://code.google.com/p/chromium/issues/detail?id=61644 |
- base::ThreadRestrictions::ScopedAllowIO allow_io; |
+ ThreadRestrictions::ScopedAllowIO allow_io; |
- base::win::RegKey key(HKEY_LOCAL_MACHINE, |
- L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", |
- KEY_READ); |
+ RegKey key(HKEY_LOCAL_MACHINE, |
+ L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", |
+ KEY_READ); |
DWORD uac_enabled; |
if (key.ReadValueDW(L"EnableLUA", &uac_enabled) != ERROR_SUCCESS) |
return true; |
@@ -284,20 +331,20 @@ static const char16 kAutoRunKeyPath[] = |
bool AddCommandToAutoRun(HKEY root_key, const string16& name, |
const string16& command) { |
- base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); |
+ RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); |
return (autorun_key.WriteValue(name.c_str(), command.c_str()) == |
ERROR_SUCCESS); |
} |
bool RemoveCommandFromAutoRun(HKEY root_key, const string16& name) { |
- base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); |
+ RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_SET_VALUE); |
return (autorun_key.DeleteValue(name.c_str()) == ERROR_SUCCESS); |
} |
bool ReadCommandFromAutoRun(HKEY root_key, |
const string16& name, |
string16* command) { |
- base::win::RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE); |
+ RegKey autorun_key(root_key, kAutoRunKeyPath, KEY_QUERY_VALUE); |
return (autorun_key.ReadValue(name.c_str(), command) == ERROR_SUCCESS); |
} |
@@ -326,8 +373,8 @@ bool IsTabletDevice() { |
if (GetSystemMetrics(SM_MAXIMUMTOUCHES) == 0) |
return false; |
- base::win::Version version = base::win::GetVersion(); |
- if (version == base::win::VERSION_XP) |
+ Version version = GetVersion(); |
+ if (version == VERSION_XP) |
return (GetSystemMetrics(SM_TABLETPC) != 0); |
// If the device is docked, the user is treating the device as a PC. |
@@ -339,7 +386,7 @@ bool IsTabletDevice() { |
POWER_PLATFORM_ROLE role = PowerDeterminePlatformRole(); |
bool mobile_power_profile = (role == PlatformRoleMobile); |
bool slate_power_profile = false; |
- if (version >= base::win::VERSION_WIN8) |
+ if (version >= VERSION_WIN8) |
slate_power_profile = (role == PlatformRoleSlate); |
if (mobile_power_profile || slate_power_profile) |
@@ -349,14 +396,13 @@ bool IsTabletDevice() { |
} |
bool DisplayVirtualKeyboard() { |
- if (base::win::GetVersion() < base::win::VERSION_WIN8) |
+ if (GetVersion() < VERSION_WIN8) |
return false; |
- if (IsKeyboardPresentOnSlate()) |
+ if (IsKeyboardPresentOnSlate(nullptr)) |
return false; |
- static base::LazyInstance<string16>::Leaky osk_path = |
- LAZY_INSTANCE_INITIALIZER; |
+ static LazyInstance<string16>::Leaky osk_path = LAZY_INSTANCE_INITIALIZER; |
if (osk_path.Get().empty()) { |
// We need to launch TabTip.exe from the location specified under the |
@@ -367,9 +413,8 @@ bool DisplayVirtualKeyboard() { |
// We don't want to launch TabTip.exe from |
// c:\program files (x86)\common files\microsoft shared\ink. This path is |
// normally found on 64 bit Windows. |
- base::win::RegKey key(HKEY_LOCAL_MACHINE, |
- kWindows8OSKRegPath, |
- KEY_READ | KEY_WOW64_64KEY); |
+ RegKey key(HKEY_LOCAL_MACHINE, kWindows8OSKRegPath, |
+ KEY_READ | KEY_WOW64_64KEY); |
DWORD osk_path_length = 1024; |
if (key.ReadValue(NULL, |
WriteInto(&osk_path.Get(), osk_path_length), |
@@ -410,7 +455,7 @@ bool DisplayVirtualKeyboard() { |
common_program_files_path = common_program_files_wow6432.get(); |
DCHECK(!common_program_files_path.empty()); |
} else { |
- base::win::ScopedCoMem<wchar_t> common_program_files; |
+ ScopedCoMem<wchar_t> common_program_files; |
if (FAILED(SHGetKnownFolderPath(FOLDERID_ProgramFilesCommon, 0, NULL, |
&common_program_files))) { |
return false; |
@@ -432,7 +477,7 @@ bool DisplayVirtualKeyboard() { |
} |
bool DismissVirtualKeyboard() { |
- if (base::win::GetVersion() < base::win::VERSION_WIN8) |
+ if (GetVersion() < VERSION_WIN8) |
return false; |
// We dismiss the virtual keyboard by generating the ESC keystroke |
@@ -474,21 +519,21 @@ void SetDomainStateForTesting(bool state) { |
} |
bool MaybeHasSHA256Support() { |
- const base::win::OSInfo* os_info = base::win::OSInfo::GetInstance(); |
+ const OSInfo* os_info = OSInfo::GetInstance(); |
- if (os_info->version() == base::win::VERSION_PRE_XP) |
+ if (os_info->version() == VERSION_PRE_XP) |
return false; // Too old to have it and this OS is not supported anyway. |
- if (os_info->version() == base::win::VERSION_XP) |
+ if (os_info->version() == VERSION_XP) |
return os_info->service_pack().major >= 3; // Windows XP SP3 has it. |
// Assume it is missing in this case, although it may not be. This category |
// includes Windows XP x64, and Windows Server, where a hotfix could be |
// deployed. |
- if (os_info->version() == base::win::VERSION_SERVER_2003) |
+ if (os_info->version() == VERSION_SERVER_2003) |
return false; |
- DCHECK(os_info->version() >= base::win::VERSION_VISTA); |
+ DCHECK(os_info->version() >= VERSION_VISTA); |
return true; // New enough to have SHA-256 support. |
} |