15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome_frame/com_message_event.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComMessageEvent::ComMessageEvent() { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComMessageEvent::~ComMessageEvent() { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ComMessageEvent::Initialize(IOleContainer* container, 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& message, 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& origin, 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& event_type) { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_IF(WARNING, !container) << __FUNCTION__ << " no container"; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_ = message; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) origin_ = origin; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_ = event_type; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // May remain NULL if container not IE 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IHTMLEventObj> basic_event; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IHTMLDocument2> doc; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fetching doc may fail in non-IE containers 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and container might be NULL in some applications. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (container) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) container->QueryInterface(doc.Receive()); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::win::ScopedComPtr<IHTMLDocument4> doc4; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc4.QueryFrom(doc); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(doc4); // supported by IE5.5 and higher 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc4) { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IHTMLEventObj5 is only supported in IE8 and later, so we provide our 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // own (minimalistic) implementation of it. 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc4->createEventObject(NULL, basic_event.Receive()); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(basic_event); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) basic_event_ = basic_event; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP ComMessageEvent::GetTypeInfoCount(UINT* info) { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't DCHECK as python scripts might still call this function 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inadvertently. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Not implemented: " << __FUNCTION__; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_NOTIMPL; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP ComMessageEvent::GetTypeInfo(UINT which_info, LCID lcid, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ITypeInfo** type_info) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "Not implemented: " << __FUNCTION__; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_NOTIMPL; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP ComMessageEvent::GetIDsOfNames(REFIID iid, LPOLESTR* names, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT count_names, LCID lcid, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISPID* dispids) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = S_OK; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that since we're using LowerCaseEqualsASCII for string comparison, 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the second argument _must_ be all lower case. I.e. we cannot compare 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // against L"messagePort" since it has a capital 'P'. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (UINT i = 0; SUCCEEDED(hr) && i < count_names; ++i) { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* name_begin = names[i]; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* name_end = name_begin + wcslen(name_begin); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (LowerCaseEqualsASCII(name_begin, name_end, "data")) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispids[i] = DISPID_MESSAGE_EVENT_DATA; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LowerCaseEqualsASCII(name_begin, name_end, "origin")) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispids[i] = DISPID_MESSAGE_EVENT_ORIGIN; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LowerCaseEqualsASCII(name_begin, name_end, "lasteventid")) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispids[i] = DISPID_MESSAGE_EVENT_LAST_EVENT_ID; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LowerCaseEqualsASCII(name_begin, name_end, "source")) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispids[i] = DISPID_MESSAGE_EVENT_SOURCE; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LowerCaseEqualsASCII(name_begin, name_end, "messageport")) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispids[i] = DISPID_MESSAGE_EVENT_MESSAGE_PORT; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LowerCaseEqualsASCII(name_begin, name_end, "type")) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dispids[i] = DISPID_MESSAGE_EVENT_TYPE; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (basic_event_) { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = basic_event_->GetIDsOfNames(IID_IDispatch, &names[i], 1, lcid, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &dispids[i]); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = DISP_E_MEMBERNOTFOUND; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FAILED(hr)) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "member not found: " << names[i] 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << base::StringPrintf(L"0x%08X", hr); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)STDMETHODIMP ComMessageEvent::Invoke(DISPID dispid, REFIID iid, LCID lcid, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WORD flags, DISPPARAMS* params, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VARIANT* result, EXCEPINFO* excepinfo, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UINT* arg_err) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr = DISP_E_MEMBERNOTFOUND; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (dispid) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DISPID_MESSAGE_EVENT_DATA: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = GetStringProperty(flags, UTF8ToWide(message_).c_str(), result); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DISPID_MESSAGE_EVENT_ORIGIN: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = GetStringProperty(flags, UTF8ToWide(origin_).c_str(), result); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DISPID_MESSAGE_EVENT_TYPE: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = GetStringProperty(flags, UTF8ToWide(type_).c_str(), result); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DISPID_MESSAGE_EVENT_LAST_EVENT_ID: 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = GetStringProperty(flags, L"", result); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DISPID_MESSAGE_EVENT_SOURCE: 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case DISPID_MESSAGE_EVENT_MESSAGE_PORT: 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & DISPATCH_PROPERTYGET) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->vt = VT_NULL; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = S_OK; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = DISP_E_TYPEMISMATCH; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (basic_event_) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = basic_event_->Invoke(dispid, iid, lcid, flags, params, result, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) excepinfo, arg_err); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HRESULT ComMessageEvent::GetStringProperty(WORD flags, const wchar_t* value, 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VARIANT* result) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!result) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return E_INVALIDARG; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRESULT hr; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flags & DISPATCH_PROPERTYGET) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->vt = VT_BSTR; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result->bstrVal = ::SysAllocString(value); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = S_OK; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) hr = DISP_E_TYPEMISMATCH; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return hr; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 162