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)// Win8 default browser registration utility.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This tool can register and unregister a given exe as a potential default
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// metro browser on Win8. It does not make the exe become THE default browser,
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// for a mechnism to do this please see open_with_dialog_controller.h.
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(robertshield): By default, this creates a run-time dependency on
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// chrome.exe since it's the only thing we have right now that works as a
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// default viewer process. Investigate extracting the metro init code and
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// building them into a standalone viewer process.
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlbase.h>
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlcom.h>
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <atlctl.h>
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <shellapi.h>
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/at_exit.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/command_line.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/path_service.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/stringprintf.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/test/test_registrar_constants.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "win8/test/test_registrar_resource.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const wchar_t kDelegateExecuteCLSID[] =
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    L"{FC0064A6-D1DE-4A83-92D2-5BB4EEBB70B5}";
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InitializeCommandLineDefaultValues() {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine& command_line = *CommandLine::ForCurrentProcess();
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_line.HasSwitch(win8::test::kTestAppUserModelId))
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line.AppendSwitchNative(win8::test::kTestAppUserModelId,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    win8::test::kDefaultTestAppUserModelId);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_line.HasSwitch(win8::test::kTestExeName))
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line.AppendSwitchNative(win8::test::kTestExeName,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    win8::test::kDefaultTestExeName);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_line.HasSwitch(win8::test::kTestExePath)) {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath exe_path;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    PathService::Get(base::DIR_EXE, &exe_path);
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    exe_path = exe_path.Append(win8::test::kDefaultTestExePath);
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line.AppendSwitchNative(win8::test::kTestExePath,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    exe_path.value());
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!command_line.HasSwitch(win8::test::kTestProgId))
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    command_line.AppendSwitchNative(win8::test::kTestProgId,
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    win8::test::kDefaultTestProgId);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Implementation of an ATL module that provides the necessary replacement
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// values for the default browser .rgs script.
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TestDelegateExecuteModule
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public ATL::CAtlExeModuleT< TestDelegateExecuteModule > {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public :
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef ATL::CAtlExeModuleT<TestDelegateExecuteModule> ParentClass;
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DECLARE_REGISTRY_RESOURCEID(IDR_TESTDELEGATEEXECUTE);
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT RegisterServer(BOOL reg_type_lib) {
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ParentClass::RegisterServer(FALSE);
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual HRESULT AddCommonRGSReplacements(IRegistrarBase* registrar) throw() {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AtlTrace(L"In %hs\n", __FUNCTION__);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    HRESULT hr = ParentClass::AddCommonRGSReplacements(registrar);
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (FAILED(hr))
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return hr;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"DELEGATE_EXECUTE_CLSID", kDelegateExecuteCLSID);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CommandLine& command_line = *CommandLine::ForCurrentProcess();
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"APP_USER_MODEL_ID",
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              command_line.GetSwitchValueNative(
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  win8::test::kTestAppUserModelId).c_str());
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"EXE_NAME",
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              command_line.GetSwitchValueNative(
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  win8::test::kTestExeName).c_str());
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"PROG_ID",
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              command_line.GetSwitchValueNative(
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  win8::test::kTestProgId).c_str());
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 exe_path(
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        command_line.GetSwitchValueNative(win8::test::kTestExePath));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 exe_open_command(
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::StringPrintf(L"\"%ls\" -- %%*", exe_path.c_str()));
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"EXE_OPEN_COMMAND", exe_open_command.c_str());
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 exe_icon(base::StringPrintf(L"%ls,0", exe_path.c_str()));
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"EXE_ICON", exe_icon.c_str());
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 prog_id_open_command(
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        base::StringPrintf(L"\"%ls\" -- \"%%1\"", exe_path.c_str()));
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    registrar->AddReplacement(L"PROG_ID_OPEN_COMMAND",
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              prog_id_open_command.c_str());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ATLASSERT(SUCCEEDED(hr));
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return hr;
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TestDelegateExecuteModule _AtlModule;
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)EXTERN_C const GUID CLSID_TestDefaultBrowserRegistrar;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ATL_NO_VTABLE DECLSPEC_UUID("FC0064A6-D1DE-4A83-92D2-5BB4EEBB70B5")
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TestDefaultBrowserRegistrar
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public CComObjectRootEx<CComSingleThreadModel>,
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      public CComCoClass<TestDefaultBrowserRegistrar,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         &CLSID_TestDefaultBrowserRegistrar> {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DECLARE_REGISTRY_RESOURCEID(IDR_TESTDELEGATEEXECUTE);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  BEGIN_COM_MAP(TestDefaultBrowserRegistrar)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  END_COM_MAP()
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)extern "C" int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int nShowCmd) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::AtExitManager exit_manager;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine::Init(0, NULL);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  InitializeCommandLineDefaultValues();
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HRESULT ret_code = _AtlModule.WinMain(nShowCmd);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ret_code;
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OBJECT_ENTRY_AUTO(__uuidof(TestDefaultBrowserRegistrar),
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  TestDefaultBrowserRegistrar);
142