Home | History | Annotate | Download | only in metro_driver
      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