OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "stdafx.h" | |
6 #include "winrt_utils.h" | |
7 | |
8 #include <shlobj.h> | |
9 | |
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" | |
16 | |
17 void CheckHR(HRESULT hr, const char* message) { | |
18 if (FAILED(hr)) { | |
19 if (message) | |
20 PLOG(DFATAL) << message << ", hr = " << std::hex << hr; | |
21 else | |
22 PLOG(DFATAL) << "COM ERROR" << ", hr = " << std::hex << hr; | |
23 } | |
24 } | |
25 | |
26 HSTRING MakeHString(const base::string16& str) { | |
27 HSTRING hstr; | |
28 if (FAILED(::WindowsCreateString(str.c_str(), static_cast<UINT32>(str.size()), | |
29 &hstr))) { | |
30 PLOG(DFATAL) << "Hstring creation failed"; | |
31 } | |
32 return hstr; | |
33 } | |
34 | |
35 base::string16 MakeStdWString(HSTRING hstring) { | |
36 const wchar_t* str; | |
37 UINT32 size = 0; | |
38 str = ::WindowsGetStringRawBuffer(hstring, &size); | |
39 if (!size) | |
40 return base::string16(); | |
41 return base::string16(str, size); | |
42 } | |
43 | |
44 namespace { | |
45 | |
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 ( \ | |
55 value, \ | |
56 reinterpret_cast<IInspectable**>(prop)); \ | |
57 CheckHR(hr, "Failed to create Property"); \ | |
58 return hr; \ | |
59 } | |
60 | |
61 #define COMPARE_ATOMIC_PROPERTY_VALUES(Name, Type) \ | |
62 Type lhs_value; \ | |
63 hr = lhs->Get ## Name (&lhs_value); \ | |
64 CheckHR(hr, "Can't get value for lhs"); \ | |
65 Type rhs_value; \ | |
66 hr = rhs->Get ## Name (&rhs_value); \ | |
67 CheckHR(hr, "Can't get value for rhs"); \ | |
68 if (lhs_value < rhs_value) \ | |
69 *result = -1; \ | |
70 else if (lhs_value > rhs_value) \ | |
71 *result = 1; \ | |
72 else \ | |
73 *result = 0; \ | |
74 hr = S_OK | |
75 | |
76 } // namespace | |
77 | |
78 namespace winrt_utils { | |
79 | |
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); | |
88 | |
89 HRESULT CompareProperties(winfoundtn::IPropertyValue* lhs, | |
90 winfoundtn::IPropertyValue* rhs, | |
91 INT32* result) { | |
92 if (result == nullptr) { | |
93 PLOG(DFATAL) << "Invalid argument to CompareProperties."; | |
94 return E_INVALIDARG; | |
95 } | |
96 | |
97 if (lhs == rhs) { | |
98 *result = 0; | |
99 return S_OK; | |
100 } | |
101 | |
102 winfoundtn::PropertyType lhs_property_type; | |
103 HRESULT hr = lhs->get_Type(&lhs_property_type); | |
104 if (FAILED(hr)) { | |
105 PLOG(DFATAL) << "Can't get property type for lhs, hr=" << std::hex << hr; | |
106 } | |
107 | |
108 winfoundtn::PropertyType rhs_property_type; | |
109 hr = rhs->get_Type(&rhs_property_type); | |
110 CheckHR(hr, "Can't get property type for rhs"); | |
111 | |
112 if (lhs_property_type != rhs_property_type) | |
113 return E_INVALIDARG; | |
114 | |
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"); | |
120 | |
121 mswrw::HString rhs_string; | |
122 hr = rhs->GetString(rhs_string.GetAddressOf()); | |
123 CheckHR(hr, "Can't get string for rhs"); | |
124 | |
125 hr = WindowsCompareStringOrdinal( | |
126 lhs_string.Get(), rhs_string.Get(), result); | |
127 break; | |
128 } | |
129 case winfoundtn::PropertyType::PropertyType_Char16: { | |
130 COMPARE_ATOMIC_PROPERTY_VALUES(Char16, wchar_t); | |
131 break; | |
132 } | |
133 case winfoundtn::PropertyType::PropertyType_Double: { | |
134 COMPARE_ATOMIC_PROPERTY_VALUES(Double, double); | |
135 break; | |
136 } | |
137 case winfoundtn::PropertyType::PropertyType_Int16: { | |
138 COMPARE_ATOMIC_PROPERTY_VALUES(Int16, INT16); | |
139 break; | |
140 } | |
141 case winfoundtn::PropertyType::PropertyType_Int32: { | |
142 COMPARE_ATOMIC_PROPERTY_VALUES(Int32, INT32); | |
143 break; | |
144 } | |
145 case winfoundtn::PropertyType::PropertyType_Int64: { | |
146 COMPARE_ATOMIC_PROPERTY_VALUES(Int64, INT64); | |
147 break; | |
148 } | |
149 case winfoundtn::PropertyType::PropertyType_UInt8: { | |
150 COMPARE_ATOMIC_PROPERTY_VALUES(UInt8, UINT8); | |
151 break; | |
152 } | |
153 case winfoundtn::PropertyType::PropertyType_UInt16: { | |
154 COMPARE_ATOMIC_PROPERTY_VALUES(UInt16, UINT16); | |
155 break; | |
156 } | |
157 case winfoundtn::PropertyType::PropertyType_UInt32: { | |
158 COMPARE_ATOMIC_PROPERTY_VALUES(UInt32, UINT32); | |
159 break; | |
160 } | |
161 case winfoundtn::PropertyType::PropertyType_UInt64: { | |
162 COMPARE_ATOMIC_PROPERTY_VALUES(UInt64, UINT64); | |
163 break; | |
164 } | |
165 default: { | |
166 hr = E_NOTIMPL; | |
167 } | |
168 } | |
169 return hr; | |
170 } | |
171 | |
172 bool GetArgumentsFromShortcut(const base::FilePath& shortcut, | |
173 base::string16* arguments) { | |
174 HRESULT result; | |
175 base::win::ScopedComPtr<IShellLink> i_shell_link; | |
176 bool is_resolved = false; | |
177 | |
178 | |
179 base::win::ScopedCOMInitializer sta_com_initializer; | |
180 | |
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; | |
195 is_resolved = true; | |
196 } | |
197 } | |
198 } | |
199 | |
200 return is_resolved; | |
201 } | |
202 | |
203 base::string16 ReadArgumentsFromPinnedTaskbarShortcut() { | |
204 wchar_t path_buffer[MAX_PATH] = {}; | |
205 | |
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"); | |
211 | |
212 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | |
213 base::string16 link_name = dist->GetShortcutName( | |
214 BrowserDistribution::SHORTCUT_CHROME) + installer::kLnkExt; | |
215 shortcut = shortcut.Append(link_name); | |
216 | |
217 base::string16 arguments; | |
218 if (GetArgumentsFromShortcut(shortcut, &arguments)) { | |
219 return arguments; | |
220 } | |
221 } | |
222 | |
223 return L""; | |
224 } | |
225 | |
226 } // namespace winrt_utils | |
OLD | NEW |