12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "device/bluetooth/bluetooth_init_win.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_restrictions.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// A frame-based exception handler filter function for a handler for exceptions
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// generated by the Visual C++ delay loader helper function.
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int FilterVisualCPPExceptions(DWORD exception_code) {
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return HRESULT_FACILITY(exception_code) == FACILITY_VISUALCPP ?
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH;
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace device {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace bluetooth_init_win {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool HasBluetoothStack() {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static enum {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HBS_UNKNOWN,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HBS_YES,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HBS_NO,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } has_bluetooth_stack = HBS_UNKNOWN;
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (has_bluetooth_stack == HBS_UNKNOWN) {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::ThreadRestrictions::AssertIOAllowed();
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HRESULT hr = E_FAIL;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    __try {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hr = __HrLoadAllImportsForDll("bthprops.cpl");
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } __except(FilterVisualCPPExceptions(::GetExceptionCode())) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      hr = E_FAIL;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    has_bluetooth_stack = SUCCEEDED(hr) ? HBS_YES : HBS_NO;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return has_bluetooth_stack == HBS_YES;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace bluetooth_init_win
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace device