1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "winrt_utils.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/win/scoped_com_initializer.h"
13 #include "base/win/scoped_comptr.h"
14 #include "chrome/installer/util/browser_distribution.h"
15 #include "chrome/installer/util/install_util.h"
17 void CheckHR(HRESULT hr
, const char* message
) {
20 PLOG(DFATAL
) << message
<< ", hr = " << std::hex
<< hr
;
22 PLOG(DFATAL
) << "COM ERROR" << ", hr = " << std::hex
<< hr
;
26 HSTRING
MakeHString(const base::string16
& str
) {
28 if (FAILED(::WindowsCreateString(str
.c_str(), static_cast<UINT32
>(str
.size()),
30 PLOG(DFATAL
) << "Hstring creation failed";
35 base::string16
MakeStdWString(HSTRING hstring
) {
38 str
= ::WindowsGetStringRawBuffer(hstring
, &size
);
40 return base::string16();
41 return base::string16(str
, size
);
46 #define IMPLEMENT_CREATE_PROPERTY(Name, Type) \
47 HRESULT Create ## Name ## Property(Type value, \
48 winfoundtn::IPropertyValue** prop) { \
49 mswr::ComPtr<winfoundtn::IPropertyValueStatics> property_value_statics; \
50 HRESULT hr = winrt_utils::CreateActivationFactory( \
51 RuntimeClass_Windows_Foundation_PropertyValue, \
52 property_value_statics.GetAddressOf()); \
53 CheckHR(hr, "Can't create IPropertyValueStatics"); \
54 hr = property_value_statics->Create ## Name ( \
56 reinterpret_cast<IInspectable**>(prop)); \
57 CheckHR(hr, "Failed to create Property"); \
61 #define COMPARE_ATOMIC_PROPERTY_VALUES(Name, Type) \
63 hr = lhs->Get ## Name (&lhs_value); \
64 CheckHR(hr, "Can't get value for lhs"); \
66 hr = rhs->Get ## Name (&rhs_value); \
67 CheckHR(hr, "Can't get value for rhs"); \
68 if (lhs_value < rhs_value) \
70 else if (lhs_value > rhs_value) \
78 namespace winrt_utils
{
80 IMPLEMENT_CREATE_PROPERTY(String
, HSTRING
);
81 IMPLEMENT_CREATE_PROPERTY(Int16
, INT16
);
82 IMPLEMENT_CREATE_PROPERTY(Int32
, INT32
);
83 IMPLEMENT_CREATE_PROPERTY(Int64
, INT64
);
84 IMPLEMENT_CREATE_PROPERTY(UInt8
, UINT8
);
85 IMPLEMENT_CREATE_PROPERTY(UInt16
, UINT16
);
86 IMPLEMENT_CREATE_PROPERTY(UInt32
, UINT32
);
87 IMPLEMENT_CREATE_PROPERTY(UInt64
, UINT64
);
89 HRESULT
CompareProperties(winfoundtn::IPropertyValue
* lhs
,
90 winfoundtn::IPropertyValue
* rhs
,
92 if (result
== nullptr) {
93 PLOG(DFATAL
) << "Invalid argument to CompareProperties.";
102 winfoundtn::PropertyType lhs_property_type
;
103 HRESULT hr
= lhs
->get_Type(&lhs_property_type
);
105 PLOG(DFATAL
) << "Can't get property type for lhs, hr=" << std::hex
<< hr
;
108 winfoundtn::PropertyType rhs_property_type
;
109 hr
= rhs
->get_Type(&rhs_property_type
);
110 CheckHR(hr
, "Can't get property type for rhs");
112 if (lhs_property_type
!= rhs_property_type
)
115 switch (lhs_property_type
) {
116 case winfoundtn::PropertyType::PropertyType_String
: {
117 mswrw::HString lhs_string
;
118 hr
= lhs
->GetString(lhs_string
.GetAddressOf());
119 CheckHR(hr
, "Can't get string for lhs");
121 mswrw::HString rhs_string
;
122 hr
= rhs
->GetString(rhs_string
.GetAddressOf());
123 CheckHR(hr
, "Can't get string for rhs");
125 hr
= WindowsCompareStringOrdinal(
126 lhs_string
.Get(), rhs_string
.Get(), result
);
129 case winfoundtn::PropertyType::PropertyType_Char16
: {
130 COMPARE_ATOMIC_PROPERTY_VALUES(Char16
, wchar_t);
133 case winfoundtn::PropertyType::PropertyType_Double
: {
134 COMPARE_ATOMIC_PROPERTY_VALUES(Double
, double);
137 case winfoundtn::PropertyType::PropertyType_Int16
: {
138 COMPARE_ATOMIC_PROPERTY_VALUES(Int16
, INT16
);
141 case winfoundtn::PropertyType::PropertyType_Int32
: {
142 COMPARE_ATOMIC_PROPERTY_VALUES(Int32
, INT32
);
145 case winfoundtn::PropertyType::PropertyType_Int64
: {
146 COMPARE_ATOMIC_PROPERTY_VALUES(Int64
, INT64
);
149 case winfoundtn::PropertyType::PropertyType_UInt8
: {
150 COMPARE_ATOMIC_PROPERTY_VALUES(UInt8
, UINT8
);
153 case winfoundtn::PropertyType::PropertyType_UInt16
: {
154 COMPARE_ATOMIC_PROPERTY_VALUES(UInt16
, UINT16
);
157 case winfoundtn::PropertyType::PropertyType_UInt32
: {
158 COMPARE_ATOMIC_PROPERTY_VALUES(UInt32
, UINT32
);
161 case winfoundtn::PropertyType::PropertyType_UInt64
: {
162 COMPARE_ATOMIC_PROPERTY_VALUES(UInt64
, UINT64
);
172 bool GetArgumentsFromShortcut(const base::FilePath
& shortcut
,
173 base::string16
* arguments
) {
175 base::win::ScopedComPtr
<IShellLink
> i_shell_link
;
176 bool is_resolved
= false;
179 base::win::ScopedCOMInitializer sta_com_initializer
;
181 // Get pointer to the IShellLink interface
182 result
= i_shell_link
.CreateInstance(CLSID_ShellLink
, NULL
,
183 CLSCTX_INPROC_SERVER
);
184 if (SUCCEEDED(result
)) {
185 base::win::ScopedComPtr
<IPersistFile
> persist
;
186 // Query IShellLink for the IPersistFile interface
187 result
= persist
.QueryFrom(i_shell_link
.get());
188 if (SUCCEEDED(result
)) {
189 WCHAR temp_arguments
[MAX_PATH
];
190 // Load the shell link
191 result
= persist
->Load(shortcut
.value().c_str(), STGM_READ
);
192 if (SUCCEEDED(result
)) {
193 result
= i_shell_link
->GetArguments(temp_arguments
, MAX_PATH
);
194 *arguments
= temp_arguments
;
203 base::string16
ReadArgumentsFromPinnedTaskbarShortcut() {
204 wchar_t path_buffer
[MAX_PATH
] = {};
206 if (SUCCEEDED(SHGetFolderPath(NULL
, CSIDL_APPDATA
, NULL
,
207 SHGFP_TYPE_CURRENT
, path_buffer
))) {
208 base::FilePath
shortcut(path_buffer
);
209 shortcut
= shortcut
.Append(
210 L
"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar");
212 BrowserDistribution
* dist
= BrowserDistribution::GetDistribution();
213 base::string16 link_name
= dist
->GetShortcutName(
214 BrowserDistribution::SHORTCUT_CHROME
) + installer::kLnkExt
;
215 shortcut
= shortcut
.Append(link_name
);
217 base::string16 arguments
;
218 if (GetArgumentsFromShortcut(shortcut
, &arguments
)) {
226 } // namespace winrt_utils