diff options
Diffstat (limited to 'webkit/activex_shim/activex_util.cc')
-rw-r--r-- | webkit/activex_shim/activex_util.cc | 476 |
1 files changed, 0 insertions, 476 deletions
diff --git a/webkit/activex_shim/activex_util.cc b/webkit/activex_shim/activex_util.cc deleted file mode 100644 index 4b16764..0000000 --- a/webkit/activex_shim/activex_util.cc +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/activex_shim/activex_util.h" - -#include <exdisp.h> -#include <math.h> -#include <ocmm.h> - -#include "base/scoped_comptr_win.h" -#include "base/string_util.h" -#include "webkit/activex_shim/npp_impl.h" -#include "webkit/activex_shim/activex_plugin.h" - -using std::string; -using std::wstring; - -namespace activex_shim { - -#ifdef TRACK_INTERFACE - -namespace { -struct IIDToName { - IID iid; - const char* name; -}; -} // namespace - -#define MAP_IID_TO_NAME(name) {IID_##name, #name}, - -// Map frequently used iid to names. If unknown, return "Unknown:{xxxx-..}". -static string MapIIDToName(REFIID iid) { - IIDToName const well_known_interface_names[] = { - MAP_IID_TO_NAME(IUnknown) - MAP_IID_TO_NAME(IDispatch) - MAP_IID_TO_NAME(IParseDisplayName) - MAP_IID_TO_NAME(IOleContainer) - MAP_IID_TO_NAME(IOleWindow) - MAP_IID_TO_NAME(IOleInPlaceUIWindow) - MAP_IID_TO_NAME(IOleInPlaceFrame) - MAP_IID_TO_NAME(IHTMLDocument) - MAP_IID_TO_NAME(IHTMLDocument2) - MAP_IID_TO_NAME(IHTMLWindow2) - MAP_IID_TO_NAME(IOleClientSite) - MAP_IID_TO_NAME(IOleControlSite) - MAP_IID_TO_NAME(IOleInPlaceSite) - MAP_IID_TO_NAME(IOleInPlaceSiteEx) - MAP_IID_TO_NAME(IOleInPlaceSiteWindowless) - MAP_IID_TO_NAME(IServiceProvider) - MAP_IID_TO_NAME(IBindHost) - MAP_IID_TO_NAME(IWebBrowserApp) - MAP_IID_TO_NAME(ITimerService) - }; - for (int i = 0; i < arraysize(well_known_interface_names); ++i) { - if (well_known_interface_names[i].iid == iid) - return well_known_interface_names[i].name; - } - LPOLESTR sz = NULL; - StringFromIID(iid, &sz); - string res = string("Unknown:") + WideToUTF8(sz); - CoTaskMemFree(sz); - return res; -} - -void TrackQueryInterface(REFIID iid, bool succeeded, - const char* from_function) { - string name = MapIIDToName(iid); - if (succeeded) { - LOG(INFO) << "Successfully Queried: " << name << " in " \ - << from_function; - } else { - LOG(WARNING) << "Failed to Query: " << name << " in " \ - << from_function; - } -} - -#endif // #ifdef TRACK_INTERFACE - -bool NPIdentifierToWString(NPIdentifier name, wstring* ret) { - if (!g_browser->identifierisstring(name)) - return false; - - NPUTF8* str = g_browser->utf8fromidentifier(name); - *ret = UTF8ToWide(str); - g_browser->memfree(str); - - return true; -} - -bool DispGetID(IDispatch* disp, const wchar_t* name, DISPID* dispid) { - if (disp == NULL) - return false; - HRESULT hr = disp->GetIDsOfNames(IID_NULL, const_cast<LPOLESTR*>(&name), 1, - LOCALE_SYSTEM_DEFAULT, dispid); - if (FAILED(hr)) - return false; - return true; -} - -// Get the ITypeInfo of the dispatch interface and look for the FUNCDESC of -// the member. If not found or disp is NULL, return false. -static bool DispGetFuncDesc(IDispatch* disp, const wchar_t* name, - FUNCDESC* func) { - if (disp == NULL) - return false; - bool res = false; - ScopedComPtr<ITypeInfo> tpi; - TYPEATTR* typeattr = NULL; - do { - HRESULT hr = disp->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, tpi.Receive()); - if (FAILED(hr)) - break; - hr = tpi->GetTypeAttr(&typeattr); - if (FAILED(hr)) - break; - - MEMBERID memid; - hr = tpi->GetIDsOfNames(const_cast<LPOLESTR*>(&name), 1, &memid); - if (FAILED(hr)) - break; - - for (int i = 0; i < typeattr->cFuncs && !res; i++) { - FUNCDESC* funcdesc = NULL; - hr = tpi->GetFuncDesc(i, &funcdesc); - if (FAILED(hr)) - continue; - if (memid == funcdesc->memid) { - *func = *funcdesc; - res = true; - } - tpi->ReleaseFuncDesc(funcdesc); - } - } while(false); - if (tpi && typeattr) - tpi->ReleaseTypeAttr(typeattr); - return res; -} - -bool DispIsMethodOrProperty(IDispatch* disp, const wchar_t* name, - bool checkmethod) { - FUNCDESC funcdesc; - if (DispGetFuncDesc(disp, name, &funcdesc)) { - // If it has multiple params, for PROPERTYGET, we have to treat it like a - // method, because the scripting engine will not handle properties with - // parameters. - bool is_method = funcdesc.invkind == INVOKE_FUNC || funcdesc.cParams > 0; - return checkmethod == is_method; - } else { - // If it does not have a FUNCDESC, it should be a variable (property) if it - // has a dispid. - DISPID dispid; - if (DispGetID(disp, name, &dispid)) - return checkmethod == false; - else - return false; - } -} - -bool DispSetProperty(IDispatch* disp, const wchar_t* name, - const VARIANT& rvalue) { - if (disp == NULL) - return false; - - DISPID dispid; - if (!DispGetID(disp, name, &dispid)) - return false; - DISPPARAMS params = {0}; - params.cArgs = 1; - params.rgvarg = const_cast<VARIANTARG*>(&rvalue); - DISPID dispid_named = DISPID_PROPERTYPUT; - params.cNamedArgs = 1; - params.rgdispidNamedArgs = &dispid_named; - - unsigned int argerr; - ScopedVariant result; - HRESULT hr = disp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, - DISPATCH_PROPERTYPUT, ¶ms, &result, NULL, - &argerr); - return SUCCEEDED(hr); -} - -bool DispInvoke(IDispatch* disp, const wchar_t* name, VARIANT* args, - int arg_count, VARIANT* result) { - if (disp == NULL) - return false; - - unsigned int invoke_option; - DISPID dispid; - FUNCDESC funcdesc; - if (DispGetFuncDesc(disp, name, &funcdesc)) { - dispid = funcdesc.memid; - switch (funcdesc.invkind) { - case INVOKE_FUNC: - invoke_option = DISPATCH_METHOD; - break; - case INVOKE_PROPERTYGET: - invoke_option = DISPATCH_PROPERTYGET; - break; - default: - return false; - } - } else { - // Could be a variable if it doesn't have a FUNCDESC. - if (DispGetID(disp, name, &dispid)) - invoke_option = DISPATCH_PROPERTYGET; - else - return false; - } - VariantInit(result); - DISPPARAMS params = {0}; - params.cArgs = arg_count; - params.rgvarg = args; - unsigned int argerr; - - HRESULT hr = disp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, - invoke_option, ¶ms, result, NULL, &argerr); - return SUCCEEDED(hr); -} - -// If the given interface is safe for the flag, return true. Otherwise -// try to enable the safety option for the flag, return true if succeeded. -bool TestAndSetObjectSafetyOption(IObjectSafety* object_safety, - const IID& iid, DWORD flag) { - DWORD supported_options = 0, enabled_options = 0; - HRESULT hr = object_safety->GetInterfaceSafetyOptions(iid, - &supported_options, - &enabled_options); - if (SUCCEEDED(hr)) { - if (enabled_options & flag) { - return true; - } else if (supported_options & flag) { - hr = object_safety->SetInterfaceSafetyOptions(iid, flag, flag); - if (SUCCEEDED(hr)) - return true; - } - } - return false; -} - -unsigned long GetAndSetObjectSafetyOptions(IUnknown* control) { - if (!control) - return 0; - - // If we have the interface then check that first. - ScopedComPtr<IObjectSafety> object_safety; - object_safety.QueryFrom(control); - if (!object_safety) - return 0; - - unsigned long ret = 0; - - // Some controls only claim IPersistPropertyBag is safe. The best way - // would be checking if an interface is safe only when we use it. In reality - // this is sufficient enough, considering we have a whitelist. - static IID persist_iids[] = {IID_IPersist, IID_IPersistPropertyBag, - IID_IPersistPropertyBag2}; - for (int i = 0; i < arraysize(persist_iids); ++i) { - if (TestAndSetObjectSafetyOption(object_safety, persist_iids[i], - INTERFACESAFE_FOR_UNTRUSTED_DATA)) { - ret |= SAFE_FOR_INITIALIZING; - break; - } - } - if (TestAndSetObjectSafetyOption(object_safety, IID_IDispatch, - INTERFACESAFE_FOR_UNTRUSTED_CALLER)) - ret |= SAFE_FOR_SCRIPTING; - - return ret; -} - -unsigned long GetRegisteredObjectSafetyOptions(const CLSID& clsid) { - unsigned long ret = 0; - HRESULT hr; - ScopedComPtr<ICatInformation> cat_info; - hr = cat_info.CreateInstance(CLSID_StdComponentCategoriesMgr, - NULL, CLSCTX_INPROC_SERVER); - DCHECK(SUCCEEDED(hr)); - if (FAILED(hr)) - return ret; - - hr = cat_info->IsClassOfCategories(clsid, 1, &CATID_SafeForInitializing, - 0, NULL); - if (hr == S_OK) - ret |= SAFE_FOR_INITIALIZING; - hr = cat_info->IsClassOfCategories(clsid, 1, &CATID_SafeForScripting, - 0, NULL); - if (hr == S_OK) - ret |= SAFE_FOR_SCRIPTING; - - return ret; -} - -namespace { -// To allow only querying once for most frequently used device caps. -struct DeviceCaps { - DeviceCaps() { - inited_ = false; - } - long GetLogPixelX() { - Use(); - return log_pixel_x; - } - long GetLogPixelY() { - Use(); - return log_pixel_y; - } - private: - // Purposely make this inline. - void Use() { - if (!inited_) - Init(); - } - void Init(); - - bool inited_; - long log_pixel_x; - long log_pixel_y; -}; - -void DeviceCaps::Init() { - HDC dc = ::GetWindowDC(NULL); - log_pixel_x = ::GetDeviceCaps(dc, LOGPIXELSX); - log_pixel_y = ::GetDeviceCaps(dc, LOGPIXELSY); - ::ReleaseDC(NULL, dc); - inited_ = true; -} -} // namespace - -static DeviceCaps g_devicecaps; - -long ScreenToHimetricX(long x) { - return MulDiv(x, kHimetricPerInch, g_devicecaps.GetLogPixelX()); -} - -long ScreenToHimetricY(long y) { - return MulDiv(y, kHimetricPerInch, g_devicecaps.GetLogPixelY()); -} - -void ScreenToHimetric(long cx, long cy, SIZE* size) { - size->cx = ScreenToHimetricX(cx); - size->cy = ScreenToHimetricY(cy); -} - -bool VariantToNPVariant(DispatchObject* obj, const VARIANT* vt, - NPVariant* npv) { - // TODO(ruijiang): Support more types when necessary. - switch(vt->vt) { - case VT_BSTR: { - npv->type = NPVariantType_String; - if (vt->bstrVal == NULL) { - npv->value.stringValue.UTF8Characters = NULL; - npv->value.stringValue.UTF8Length = 0; - return true; - } - string s; - s = WideToUTF8(vt->bstrVal); - // We need to let browser allocate this memory because this will go - // out of our control and be used/released by the browser. - npv->value.stringValue.UTF8Characters = - static_cast<NPUTF8*>(g_browser->memalloc((uint32)s.size())); - memcpy(static_cast<void*>(const_cast<NPUTF8*>( - npv->value.stringValue.UTF8Characters)), - s.c_str(), s.size()); - npv->value.stringValue.UTF8Length = static_cast<uint32>(s.size()); - return true; - } - case VT_DISPATCH: { - SpawnedDispatchObject* disp_object = - new SpawnedDispatchObject(vt->pdispVal, obj->root()); - npv->type = NPVariantType_Object; - npv->value.objectValue = disp_object->GetScriptableNPObject(); - return true; - } - // All integer types. - case VT_I1: - case VT_I2: - case VT_I4: - case VT_INT: - case VT_UI1: - case VT_UI2: - case VT_UI4: - case VT_UINT: { - ScopedVariant tmp; - if (FAILED(VariantChangeType(&tmp, vt, 0, VT_I4))) - return false; - npv->type = NPVariantType_Int32; - npv->value.intValue = tmp.lVal; - return true; - } - // Float number types. - case VT_I8: - case VT_UI8: - case VT_CY: - case VT_R4: - case VT_R8: { - ScopedVariant tmp; - if (FAILED(VariantChangeType(&tmp, vt, 0, VT_R8))) - return false; - npv->type = NPVariantType_Double; - npv->value.doubleValue = tmp.dblVal; - return true; - } - case VT_BOOL: { - npv->type = NPVariantType_Bool; - npv->value.boolValue = vt->boolVal != VARIANT_FALSE; - return true; - } - case VT_NULL: { - npv->type = NPVariantType_Null; - return true; - } - case VT_EMPTY: { - npv->type = NPVariantType_Void; - return true; - } - default: { - return false; - } - } -} - -bool NPVariantToVariant(const NPVariant* npv, VARIANT* vt) { - VariantInit(vt); - switch(npv->type) { - case NPVariantType_String: - vt->vt = VT_BSTR; - if (npv->value.stringValue.UTF8Length > 0) { - string str; - str.assign(npv->value.stringValue.UTF8Characters, - npv->value.stringValue.UTF8Length); - vt->bstrVal = SysAllocString(UTF8ToWide(str.c_str()).c_str()); - } else { - vt->bstrVal = NULL; - } - return true; - case NPVariantType_Int32: - vt->vt = VT_I4; - vt->intVal = npv->value.intValue; - return true; - case NPVariantType_Double: - vt->vt = VT_R8; - vt->dblVal = npv->value.doubleValue; - return true; - case NPVariantType_Bool: - vt->vt = VT_BOOL; - vt->boolVal = npv->value.boolValue ? VARIANT_TRUE : VARIANT_FALSE; - return true; - case NPVariantType_Null: - vt->vt = VT_NULL; - return true; - case NPVariantType_Void: - // According to: http://developer.mozilla.org/en/docs/NPVariant - // Void type corresponds to JavaScript type: undefined, which means - // no value has been assigned. Thus VT_EMPTY is the best variant matches - // void. - vt->vt = VT_EMPTY; - return true; - case NPVariantType_Object: - // TODO(ruijiang): We probably need to convert NP object to IDispatch, - // which would be a pretty hard job. (consider the many interfaces of - // IHTML*). - return false; - default: - return false; - } -} - -wchar_t* CoTaskMemAllocString(const std::wstring& s) { - size_t cb = (s.size() + 1) * sizeof(wchar_t); - LPOLESTR p = static_cast<LPOLESTR>(CoTaskMemAlloc(cb)); - memcpy(p, s.c_str(), cb); - return p; -} - -} // namespace activex_shim |