Index: device/bluetooth/bluetooth_adapter_win.cc |
diff --git a/device/bluetooth/bluetooth_adapter_win.cc b/device/bluetooth/bluetooth_adapter_win.cc |
index 5924cd9a433ae428154de364d46c10b43093bb5a..26a9fc5ae01d8ac3122d23b78662076c218d9f12 100644 |
--- a/device/bluetooth/bluetooth_adapter_win.cc |
+++ b/device/bluetooth/bluetooth_adapter_win.cc |
@@ -7,20 +7,58 @@ |
#include "device/bluetooth/bluetooth_adapter_win.h" |
#include <BluetoothAPIs.h> |
+#if defined(_WIN32_WINNT_WIN8) |
+// The Windows 8 SDK defines FACILITY_VISUALCPP in winerror.h. |
+#undef FACILITY_VISUALCPP |
+#endif |
+#include <delayimp.h> |
#include <string> |
#include "base/bind.h" |
#include "base/logging.h" |
#include "base/message_loop.h" |
#include "base/stringprintf.h" |
#include "base/sys_string_conversions.h" |
+#include "base/threading/thread_restrictions.h" |
-# pragma comment(lib, "Bthprops.lib") |
+#pragma comment(lib, "Bthprops.lib") |
+#pragma comment(lib, "delayimp.lib") |
namespace { |
const BLUETOOTH_FIND_RADIO_PARAMS bluetooth_adapter_param = |
{ sizeof(BLUETOOTH_FIND_RADIO_PARAMS) }; |
+// A frame-based exception handler filter function for a handler for exceptions |
+// generated by the Visual C++ delay loader helper function. |
+int FilterVisualCPPExceptions(DWORD exception_code) { |
+ return HRESULT_FACILITY(exception_code) == FACILITY_VISUALCPP ? |
+ EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; |
+} |
+ |
+// Returns true if the machine has a bluetooth stack available. The first call |
+// to this function will involve file IO, so it should be done on an |
+// appropriate thread. This function is not threadsafe. |
+bool HasBluetoothStack() { |
+ static enum { |
+ HBS_UNKNOWN, |
+ HBS_YES, |
+ HBS_NO, |
+ } has_bluetooth_stack = HBS_UNKNOWN; |
+ |
+ if (has_bluetooth_stack == HBS_UNKNOWN) { |
+ base::ThreadRestrictions::AssertIOAllowed(); |
+ HRESULT hr = E_FAIL; |
+ __try { |
+ hr = __HrLoadAllImportsForDll("bthprops.cpl"); |
+ } __except(FilterVisualCPPExceptions(::GetExceptionCode())) { |
+ hr = E_FAIL; |
+ } |
+ has_bluetooth_stack = SUCCEEDED(hr) ? HBS_YES : HBS_NO; |
+ } |
+ |
+ return has_bluetooth_stack == HBS_YES; |
+} |
+ |
} // namespace |
namespace device { |
@@ -94,6 +132,11 @@ void BluetoothAdapterWin::ReadLocalOutOfBandPairingData( |
} |
void BluetoothAdapterWin::UpdateAdapterState() { |
+ // TODO(youngki): Move this check to the earliest point reasonable so that no |
+ // attempts are made to do any bluetooth processing if no BT stack is present. |
+ if (!HasBluetoothStack()) |
+ return; |
+ |
HBLUETOOTH_RADIO_FIND bluetooth_adapter_handle = NULL; |
BLUETOOTH_RADIO_INFO bluetooth_adapter_info = |
{ sizeof(BLUETOOTH_RADIO_INFO), 0 }; |