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 15 void CheckHR(HRESULT hr, const char* message) { 16 if (FAILED(hr)) { 17 if (message) 18 PLOG(DFATAL) << message << ", hr = " << std::hex << hr; 19 else 20 PLOG(DFATAL) << "COM ERROR" << ", hr = " << std::hex << hr; 21 } 22 } 23 24 HSTRING MakeHString(const string16& str) { 25 HSTRING hstr; 26 if (FAILED(::WindowsCreateString(str.c_str(), static_cast<UINT32>(str.size()), 27 &hstr))) { 28 PLOG(DFATAL) << "Hstring creation failed"; 29 } 30 return hstr; 31 } 32 33 string16 MakeStdWString(HSTRING hstring) { 34 const wchar_t* str; 35 UINT32 size = 0; 36 str = ::WindowsGetStringRawBuffer(hstring, &size); 37 if (!size) 38 return string16(); 39 return string16(str, size); 40 } 41 42 namespace { 43 44 #define IMPLEMENT_CREATE_PROPERTY(Name, Type) \ 45 HRESULT Create ## Name ## Property(Type value, \ 46 winfoundtn::IPropertyValue** prop) { \ 47 mswr::ComPtr<winfoundtn::IPropertyValueStatics> property_value_statics; \ 48 HRESULT hr = winrt_utils::CreateActivationFactory( \ 49 RuntimeClass_Windows_Foundation_PropertyValue, \ 50 property_value_statics.GetAddressOf()); \ 51 CheckHR(hr, "Can't create IPropertyValueStatics"); \ 52 hr = property_value_statics->Create ## Name ## ( \ 53 value, \ 54 reinterpret_cast<IInspectable**>(prop)); \ 55 CheckHR(hr, "Failed to create Property"); \ 56 return hr; \ 57 } 58 59 #define COMPARE_ATOMIC_PROPERTY_VALUES(Name, Type) \ 60 Type lhs_value; \ 61 hr = lhs->Get ## Name ##(&lhs_value); \ 62 CheckHR(hr, "Can't get value for lhs"); \ 63 Type rhs_value; \ 64 hr = rhs->Get ## Name ##(&rhs_value); \ 65 CheckHR(hr, "Can't get value for rhs"); \ 66 if (lhs_value < rhs_value) \ 67 *result = -1; \ 68 else if (lhs_value > rhs_value) \ 69 *result = 1; \ 70 else \ 71 *result = 0; \ 72 hr = S_OK 73 74 } // namespace 75 76 namespace winrt_utils { 77 78 IMPLEMENT_CREATE_PROPERTY(String, HSTRING); 79 IMPLEMENT_CREATE_PROPERTY(Int16, INT16); 80 IMPLEMENT_CREATE_PROPERTY(Int32, INT32); 81 IMPLEMENT_CREATE_PROPERTY(Int64, INT64); 82 IMPLEMENT_CREATE_PROPERTY(UInt8, UINT8); 83 IMPLEMENT_CREATE_PROPERTY(UInt16, UINT16); 84 IMPLEMENT_CREATE_PROPERTY(UInt32, UINT32); 85 IMPLEMENT_CREATE_PROPERTY(UInt64, UINT64); 86 87 HRESULT CompareProperties(winfoundtn::IPropertyValue* lhs, 88 winfoundtn::IPropertyValue* rhs, 89 INT32* result) { 90 if (result == nullptr) { 91 PLOG(DFATAL) << "Invalid argument to CompareProperties."; 92 return E_INVALIDARG; 93 } 94 95 if (lhs == rhs) { 96 *result = 0; 97 return S_OK; 98 } 99 100 winfoundtn::PropertyType lhs_property_type; 101 HRESULT hr = lhs->get_Type(&lhs_property_type); 102 if (FAILED(hr)) { 103 PLOG(DFATAL) << "Can't get property type for lhs, hr=" << std::hex << hr; 104 } 105 106 winfoundtn::PropertyType rhs_property_type; 107 hr = rhs->get_Type(&rhs_property_type); 108 CheckHR(hr, "Can't get property type for rhs"); 109 110 if (lhs_property_type != rhs_property_type) 111 return E_INVALIDARG; 112 113 switch (lhs_property_type) { 114 case winfoundtn::PropertyType::PropertyType_String: { 115 mswrw::HString lhs_string; 116 hr = lhs->GetString(lhs_string.GetAddressOf()); 117 CheckHR(hr, "Can't get string for lhs"); 118 119 mswrw::HString rhs_string; 120 hr = rhs->GetString(rhs_string.GetAddressOf()); 121 CheckHR(hr, "Can't get string for rhs"); 122 123 hr = WindowsCompareStringOrdinal( 124 lhs_string.Get(), rhs_string.Get(), result); 125 break; 126 } 127 case winfoundtn::PropertyType::PropertyType_Char16: { 128 COMPARE_ATOMIC_PROPERTY_VALUES(Char16, wchar_t); 129 break; 130 } 131 case winfoundtn::PropertyType::PropertyType_Double: { 132 COMPARE_ATOMIC_PROPERTY_VALUES(Double, double); 133 break; 134 } 135 case winfoundtn::PropertyType::PropertyType_Int16: { 136 COMPARE_ATOMIC_PROPERTY_VALUES(Int16, INT16); 137 break; 138 } 139 case winfoundtn::PropertyType::PropertyType_Int32: { 140 COMPARE_ATOMIC_PROPERTY_VALUES(Int32, INT32); 141 break; 142 } 143 case winfoundtn::PropertyType::PropertyType_Int64: { 144 COMPARE_ATOMIC_PROPERTY_VALUES(Int64, INT64); 145 break; 146 } 147 case winfoundtn::PropertyType::PropertyType_UInt8: { 148 COMPARE_ATOMIC_PROPERTY_VALUES(UInt8, UINT8); 149 break; 150 } 151 case winfoundtn::PropertyType::PropertyType_UInt16: { 152 COMPARE_ATOMIC_PROPERTY_VALUES(UInt16, UINT16); 153 break; 154 } 155 case winfoundtn::PropertyType::PropertyType_UInt32: { 156 COMPARE_ATOMIC_PROPERTY_VALUES(UInt32, UINT32); 157 break; 158 } 159 case winfoundtn::PropertyType::PropertyType_UInt64: { 160 COMPARE_ATOMIC_PROPERTY_VALUES(UInt64, UINT64); 161 break; 162 } 163 default: { 164 hr = E_NOTIMPL; 165 } 166 } 167 return hr; 168 } 169 170 bool GetArgumentsFromShortcut(const base::FilePath& shortcut, 171 string16* arguments) { 172 HRESULT result; 173 base::win::ScopedComPtr<IShellLink> i_shell_link; 174 bool is_resolved = false; 175 176 177 base::win::ScopedCOMInitializer sta_com_initializer; 178 179 // Get pointer to the IShellLink interface 180 result = i_shell_link.CreateInstance(CLSID_ShellLink, NULL, 181 CLSCTX_INPROC_SERVER); 182 if (SUCCEEDED(result)) { 183 base::win::ScopedComPtr<IPersistFile> persist; 184 // Query IShellLink for the IPersistFile interface 185 result = persist.QueryFrom(i_shell_link); 186 if (SUCCEEDED(result)) { 187 WCHAR temp_arguments[MAX_PATH]; 188 // Load the shell link 189 result = persist->Load(shortcut.value().c_str(), STGM_READ); 190 if (SUCCEEDED(result)) { 191 result = i_shell_link->GetArguments(temp_arguments, MAX_PATH); 192 *arguments = temp_arguments; 193 is_resolved = true; 194 } 195 } 196 } 197 198 return is_resolved; 199 } 200 201 string16 ReadArgumentsFromPinnedTaskbarShortcut() { 202 wchar_t path_buffer[MAX_PATH] = {}; 203 204 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 205 SHGFP_TYPE_CURRENT, path_buffer))) { 206 base::FilePath shortcut(path_buffer); 207 shortcut = shortcut.Append( 208 L"Microsoft\\Internet Explorer\\Quick Launch\\User Pinned\\TaskBar"); 209 210 // TODO(robertshield): Get this stuff from BrowserDistribution. 211 #if defined(GOOGLE_CHROME_BUILD) 212 shortcut = shortcut.Append(L"Google Chrome.lnk"); 213 #else 214 shortcut = shortcut.Append(L"Chromium.lnk"); 215 #endif 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