15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "stdafx.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/metro_driver.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <roerrorapi.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shobjidl.h> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/at_exit.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging_win.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_comptr.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/winrt_utils.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(USE_AURA) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "win8/metro_driver/chrome_app_view.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(siggi): Move this to GYP. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "runtimeobject.lib") 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LONG WINAPI ErrorReportingHandler(EXCEPTION_POINTERS* ex_info) { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // See roerrorapi.h for a description of the 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // exception codes and parameters. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD code = ex_info->ExceptionRecord->ExceptionCode; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG_PTR* info = ex_info->ExceptionRecord->ExceptionInformation; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (code == EXCEPTION_RO_ORIGINATEERROR) { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 msg(reinterpret_cast<wchar_t*>(info[2]), info[1]); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "VEH: Metro error 0x" << std::hex << info[0] << ": " << msg; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (code == EXCEPTION_RO_TRANSFORMERROR) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string16 msg(reinterpret_cast<wchar_t*>(info[3]), info[2]); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "VEH: Metro old error 0x" << std::hex << info[0] 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " new error 0x" << info[1] << ": " << msg; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EXCEPTION_CONTINUE_SEARCH; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(robertshield): This GUID is hard-coded in a bunch of places that 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// don't allow explicit includes. Find a single place for it to live. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// {7FE69228-633E-4f06-80C1-527FEA23E3A7} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const GUID kChromeTraceProviderName = { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0x7fe69228, 0x633e, 0x4f06, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 0x80, 0xc1, 0x52, 0x7f, 0xea, 0x23, 0xe3, 0xa7 } }; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if !defined(COMPONENT_BUILD) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Required for base initialization. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(siggi): This should be handled better, as this way our at exit 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// registrations will run under the loader's lock. However, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// once metro_driver is merged into Chrome.dll, this will go away anyhow. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::AtExitManager at_exit; 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" __declspec(dllexport) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int InitMetro(LPTHREAD_START_ROUTINE thread_proc, void* context) { 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the command line. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandLine::Init(0, NULL); 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging::LoggingSettings settings; 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG; 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch logging::InitLogging(settings); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NDEBUG) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetMinLogLevel(logging::LOG_ERROR); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::SetMinLogLevel(logging::LOG_VERBOSE); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the error reporting flags to always raise an exception, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which is then processed by our vectored exception handling 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // above to log the error message. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) winfoundtn::Diagnostics::SetErrorReportingFlags( 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) winfoundtn::Diagnostics::UseSetErrorInfo | 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) winfoundtn::Diagnostics::ForceExceptions); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE registration = 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::AddVectoredExceptionHandler(TRUE, ErrorReportingHandler); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Enable trace control and transport through event tracing for Windows. 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) logging::LogEventProvider::Initialize(kChromeTraceProviderName); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "InitMetro"; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswrw::RoInitializeWrapper ro_initializer(RO_INIT_MULTITHREADED); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(ro_initializer, "RoInitialize failed"); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mswr::ComPtr<winapp::Core::ICoreApplication> core_app; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = winrt_utils::CreateActivationFactory( 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RuntimeClass_Windows_ApplicationModel_Core_CoreApplication, 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_app.GetAddressOf()); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckHR(hr, "Failed to create app factory"); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 1; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) auto view_factory = mswr::Make<ChromeAppViewFactory>( 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) core_app.Get(), thread_proc, context); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = core_app->Run(view_factory.Get()); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "exiting InitMetro, hr=" << hr; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(NDEBUG) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::RemoveVectoredExceptionHandler(registration); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Activates the application known by |app_id|. Returns, among other things, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// E_APPLICATION_NOT_REGISTERED if |app_id| identifies Chrome and Chrome is not 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the default browser. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern "C" __declspec(dllexport) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ActivateApplication(const wchar_t* app_id) { 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IApplicationActivationManager> activator; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SUCCEEDED(hr)) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD pid = 0; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = activator->ActivateApplication(app_id, L"", AO_NONE, &pid); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 125