• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CheckHR(HRESULT hr,const char * message)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 
MakeHString(const string16 & str)26 HSTRING MakeHString(const 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 
MakeStdWString(HSTRING hstring)35 string16 MakeStdWString(HSTRING hstring) {
36   const wchar_t* str;
37   UINT32 size = 0;
38   str = ::WindowsGetStringRawBuffer(hstring, &size);
39   if (!size)
40     return string16();
41   return 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 
CompareProperties(winfoundtn::IPropertyValue * lhs,winfoundtn::IPropertyValue * rhs,INT32 * result)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 
GetArgumentsFromShortcut(const base::FilePath & shortcut,string16 * arguments)172 bool GetArgumentsFromShortcut(const base::FilePath& shortcut,
173                               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);
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 
ReadArgumentsFromPinnedTaskbarShortcut()203 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     string16 arguments;
218     if (GetArgumentsFromShortcut(shortcut, &arguments)) {
219       return arguments;
220     }
221   }
222 
223   return L"";
224 }
225 
226 }  // namespace winrt_utils
227