// Copyright (c) 2009 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 "chrome_frame/np_browser_functions.h" #include "base/logging.h" namespace npapi { // global function pointers (within this namespace) for the NPN functions. union NpVersion { struct { uint8 major; uint8 minor; } v; uint16 version; }; NpVersion g_version = {0}; NPN_GetURLProcPtr g_geturl = NULL; NPN_PostURLProcPtr g_posturl = NULL; NPN_RequestReadProcPtr g_requestread = NULL; NPN_NewStreamProcPtr g_newstream = NULL; NPN_WriteProcPtr g_write = NULL; NPN_DestroyStreamProcPtr g_destroystream = NULL; NPN_StatusProcPtr g_status = NULL; NPN_UserAgentProcPtr g_useragent = NULL; NPN_MemAllocProcPtr g_memalloc = NULL; NPN_MemFreeProcPtr g_memfree = NULL; NPN_MemFlushProcPtr g_memflush = NULL; NPN_ReloadPluginsProcPtr g_reloadplugins = NULL; NPN_GetJavaEnvProcPtr g_getJavaEnv = NULL; NPN_GetJavaPeerProcPtr g_getJavaPeer = NULL; NPN_GetURLNotifyProcPtr g_geturlnotify = NULL; NPN_PostURLNotifyProcPtr g_posturlnotify = NULL; NPN_GetValueProcPtr g_getvalue = NULL; NPN_SetValueProcPtr g_setvalue = NULL; NPN_InvalidateRectProcPtr g_invalidaterect = NULL; NPN_InvalidateRegionProcPtr g_invalidateregion = NULL; NPN_ForceRedrawProcPtr g_forceredraw = NULL; NPN_GetStringIdentifierProcPtr g_getstringidentifier = NULL; NPN_GetStringIdentifiersProcPtr g_getstringidentifiers = NULL; NPN_GetIntIdentifierProcPtr g_getintidentifier = NULL; NPN_IdentifierIsStringProcPtr g_identifierisstring = NULL; NPN_UTF8FromIdentifierProcPtr g_utf8fromidentifier = NULL; NPN_IntFromIdentifierProcPtr g_intfromidentifier = NULL; NPN_CreateObjectProcPtr g_createobject = NULL; NPN_RetainObjectProcPtr g_retainobject = NULL; NPN_ReleaseObjectProcPtr g_releaseobject = NULL; NPN_InvokeProcPtr g_invoke = NULL; NPN_InvokeDefaultProcPtr g_invoke_default = NULL; NPN_EvaluateProcPtr g_evaluate = NULL; NPN_GetPropertyProcPtr g_getproperty = NULL; NPN_SetPropertyProcPtr g_setproperty = NULL; NPN_RemovePropertyProcPtr g_removeproperty = NULL; NPN_HasPropertyProcPtr g_hasproperty = NULL; NPN_HasMethodProcPtr g_hasmethod = NULL; NPN_ReleaseVariantValueProcPtr g_releasevariantvalue = NULL; NPN_SetExceptionProcPtr g_setexception = NULL; NPN_PushPopupsEnabledStateProcPtr g_pushpopupsenabledstate = NULL; NPN_PopPopupsEnabledStateProcPtr g_poppopupsenabledstate = NULL; NPN_EnumerateProcPtr g_enumerate = NULL; NPN_PluginThreadAsyncCallProcPtr g_pluginthreadasynccall = NULL; NPN_ConstructProcPtr g_construct = NULL; NPN_GetValueForURLProcPtr g_getvalueforurl = NULL; NPN_SetValueForURLProcPtr g_setvalueforurl = NULL; NPN_GetAuthenticationInfoProcPtr g_getauthenticationinfo = NULL; // Must be called prior to calling any of the browser functions below. void InitializeBrowserFunctions(NPNetscapeFuncs* functions) { CHECK(functions); DCHECK(g_geturl == NULL || g_geturl == functions->geturl); g_version.version = functions->version; g_geturl = functions->geturl; g_posturl = functions->posturl; g_requestread = functions->requestread; g_newstream = functions->newstream; g_write = functions->write; g_destroystream = functions->destroystream; g_status = functions->status; g_useragent = functions->uagent; g_memalloc = functions->memalloc; g_memfree = functions->memfree; g_memflush = functions->memflush; g_reloadplugins = functions->reloadplugins; g_getJavaEnv = functions->getJavaEnv; g_getJavaPeer = functions->getJavaPeer; g_geturlnotify = functions->geturlnotify; g_posturlnotify = functions->posturlnotify; g_getvalue = functions->getvalue; g_setvalue = functions->setvalue; g_invalidaterect = functions->invalidaterect; g_invalidateregion = functions->invalidateregion; g_forceredraw = functions->forceredraw; g_getstringidentifier = functions->getstringidentifier; g_getstringidentifiers = functions->getstringidentifiers; g_getintidentifier = functions->getintidentifier; g_identifierisstring = functions->identifierisstring; g_utf8fromidentifier = functions->utf8fromidentifier; g_intfromidentifier = functions->intfromidentifier; g_createobject = functions->createobject; g_retainobject = functions->retainobject; g_releaseobject = functions->releaseobject; g_invoke = functions->invoke; g_invoke_default = functions->invokeDefault; g_evaluate = functions->evaluate; g_getproperty = functions->getproperty; g_setproperty = functions->setproperty; g_removeproperty = functions->removeproperty; g_hasproperty = functions->hasproperty; g_hasmethod = functions->hasmethod; g_releasevariantvalue = functions->releasevariantvalue; g_setexception = functions->setexception; g_pushpopupsenabledstate = functions->pushpopupsenabledstate; g_poppopupsenabledstate = functions->poppopupsenabledstate; g_enumerate = functions->enumerate; g_pluginthreadasynccall = functions->pluginthreadasynccall; g_construct = functions->construct; if (g_version.v.minor >= NPVERS_HAS_URL_AND_AUTH_INFO) { g_getvalueforurl = functions->getvalueforurl; g_setvalueforurl = functions->setvalueforurl; g_getauthenticationinfo = functions->getauthenticationinfo; } } void UninitializeBrowserFunctions() { g_version.version = 0; // We skip doing this in the official build as it doesn't serve much purpose // during shutdown. The reason for it being here in the other types of builds // is to spot potential browser bugs whereby the browser leaves living objects // in our DLL after shutdown has been called. In theory those objects could // trigger a call to the browser functions after shutdown has been called // and for non official builds we want that to simply crash. // For official builds we leave the function pointers around since they // continue to valid. g_geturl = NULL; g_posturl = NULL; g_requestread = NULL; g_newstream = NULL; g_write = NULL; g_destroystream = NULL; g_status = NULL; g_useragent = NULL; g_memalloc = NULL; g_memfree = NULL; g_memflush = NULL; g_reloadplugins = NULL; g_getJavaEnv = NULL; g_getJavaPeer = NULL; g_geturlnotify = NULL; g_posturlnotify = NULL; g_getvalue = NULL; g_setvalue = NULL; g_invalidaterect = NULL; g_invalidateregion = NULL; g_forceredraw = NULL; g_getstringidentifier = NULL; g_getstringidentifiers = NULL; g_getintidentifier = NULL; g_identifierisstring = NULL; g_utf8fromidentifier = NULL; g_intfromidentifier = NULL; g_createobject = NULL; g_retainobject = NULL; g_releaseobject = NULL; g_invoke = NULL; g_invoke_default = NULL; g_evaluate = NULL; g_getproperty = NULL; g_setproperty = NULL; g_removeproperty = NULL; g_hasproperty = NULL; g_hasmethod = NULL; g_releasevariantvalue = NULL; g_setexception = NULL; g_pushpopupsenabledstate = NULL; g_poppopupsenabledstate = NULL; g_enumerate = NULL; g_pluginthreadasynccall = NULL; g_construct = NULL; g_getvalueforurl = NULL; g_setvalueforurl = NULL; g_getauthenticationinfo = NULL; } bool IsInitialized() { // We only check one function for convenience. return g_getvalue != NULL; } // Function stubs for functions that the host browser implements. uint8 VersionMinor() { return g_version.v.minor; } uint8 VersionMajor() { return g_version.v.major; } NPError GetURL(NPP instance, const char* URL, const char* window) { DCHECK(IsInitialized()) << __FUNCTION__; return g_geturl(instance, URL, window); } NPError PostURL(NPP instance, const char* URL, const char* window, uint32 len, const char* buf, NPBool file) { DCHECK(IsInitialized()) << __FUNCTION__; return g_posturl(instance, URL, window, len, buf, file); } NPError RequestRead(NPStream* stream, NPByteRange* rangeList) { DCHECK(IsInitialized()) << __FUNCTION__; return g_requestread(stream, rangeList); } NPError NewStream(NPP instance, NPMIMEType type, const char* window, NPStream** stream) { DCHECK(IsInitialized()) << __FUNCTION__; return g_newstream(instance, type, window, stream); } int32 Write(NPP instance, NPStream* stream, int32 len, void* buffer) { DCHECK(IsInitialized()) << __FUNCTION__; return g_write(instance, stream, len, buffer); } NPError DestroyStream(NPP instance, NPStream* stream, NPReason reason) { DCHECK(IsInitialized()) << __FUNCTION__; return g_destroystream(instance, stream, reason); } void Status(NPP instance, const char* message) { DCHECK(IsInitialized()) << __FUNCTION__; return g_status(instance, message); } const char* UserAgent(NPP instance) { DCHECK(IsInitialized()) << __FUNCTION__; return g_useragent(instance); } void* MemAlloc(uint32 size) { DCHECK(IsInitialized()) << __FUNCTION__; return g_memalloc(size); } void MemFree(void* ptr) { DCHECK(IsInitialized()) << __FUNCTION__; return g_memfree(ptr); } uint32 MemFlush(uint32 size) { DCHECK(IsInitialized()) << __FUNCTION__; return g_memflush(size); } void ReloadPlugins(NPBool reloadPages) { DCHECK(IsInitialized()) << __FUNCTION__; return g_reloadplugins(reloadPages); } void* GetJavaEnv() { DCHECK(IsInitialized()) << __FUNCTION__; return g_getJavaEnv(); } void* GetJavaPeer(NPP instance) { DCHECK(IsInitialized()) << __FUNCTION__; return g_getJavaPeer(instance); } NPError GetURLNotify(NPP instance, const char* URL, const char* window, void* notifyData) { DCHECK(IsInitialized()) << __FUNCTION__; return g_geturlnotify(instance, URL, window, notifyData); } NPError PostURLNotify(NPP instance, const char* URL, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) { DCHECK(IsInitialized()) << __FUNCTION__; return g_posturlnotify(instance, URL, window, len, buf, file, notifyData); } NPError GetValue(NPP instance, NPNVariable variable, void* ret_value) { DCHECK(IsInitialized()) << __FUNCTION__; return g_getvalue(instance, variable, ret_value); } NPError SetValue(NPP instance, NPPVariable variable, void* value) { DCHECK(IsInitialized()) << __FUNCTION__; return g_setvalue(instance, variable, value); } void InvalidateRect(NPP instance, NPRect* rect) { DCHECK(IsInitialized()) << __FUNCTION__; return g_invalidaterect(instance, rect); } void InvalidateRegion(NPP instance, NPRegion region) { DCHECK(IsInitialized()) << __FUNCTION__; return g_invalidateregion(instance, region); } void ForceRedraw(NPP instance) { DCHECK(IsInitialized()) << __FUNCTION__; return g_forceredraw(instance); } void ReleaseVariantValue(NPVariant* variant) { DCHECK(IsInitialized()) << __FUNCTION__; return g_releasevariantvalue(variant); } NPIdentifier GetStringIdentifier(const NPUTF8* name) { DCHECK(IsInitialized()) << __FUNCTION__; return g_getstringidentifier(name); } void GetStringIdentifiers(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers) { DCHECK(IsInitialized()) << __FUNCTION__; return g_getstringidentifiers(names, nameCount, identifiers); } NPIdentifier GetIntIdentifier(int32_t intid) { DCHECK(IsInitialized()) << __FUNCTION__; return g_getintidentifier(intid); } int32_t IntFromIdentifier(NPIdentifier identifier) { DCHECK(IsInitialized()) << __FUNCTION__; return g_intfromidentifier(identifier); } bool IdentifierIsString(NPIdentifier identifier) { DCHECK(IsInitialized()) << __FUNCTION__; return g_identifierisstring(identifier); } NPUTF8* UTF8FromIdentifier(NPIdentifier identifier) { DCHECK(IsInitialized()) << __FUNCTION__; return g_utf8fromidentifier(identifier); } NPObject* CreateObject(NPP instance, NPClass* aClass) { DCHECK(IsInitialized()) << __FUNCTION__; return g_createobject(instance, aClass); } NPObject* RetainObject(NPObject* obj) { DCHECK(IsInitialized()) << __FUNCTION__; return g_retainobject(obj); } void ReleaseObject(NPObject* obj) { DCHECK(IsInitialized()) << __FUNCTION__; return g_releaseobject(obj); } bool Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant* args, unsigned argCount, NPVariant* result) { DCHECK(IsInitialized()) << __FUNCTION__; return g_invoke(npp, obj, methodName, args, argCount, result); } bool InvokeDefault(NPP npp, NPObject* obj, const NPVariant* args, unsigned argCount, NPVariant* result) { DCHECK(IsInitialized()) << __FUNCTION__; return g_invoke_default(npp, obj, args, argCount, result); } bool Evaluate(NPP npp, NPObject* obj, NPString* script, NPVariant* result) { DCHECK(IsInitialized()) << __FUNCTION__; return g_evaluate(npp, obj, script, result); } bool GetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, NPVariant* result) { DCHECK(IsInitialized()) << __FUNCTION__; return g_getproperty(npp, obj, propertyName, result); } bool SetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, const NPVariant* value) { DCHECK(IsInitialized()) << __FUNCTION__; return g_setproperty(npp, obj, propertyName, value); } bool HasProperty(NPP npp, NPObject* npobj, NPIdentifier propertyName) { DCHECK(IsInitialized()) << __FUNCTION__; return g_hasproperty(npp, npobj, propertyName); } bool HasMethod(NPP npp, NPObject* npobj, NPIdentifier methodName) { DCHECK(IsInitialized()) << __FUNCTION__; return g_hasmethod(npp, npobj, methodName); } bool RemoveProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) { DCHECK(IsInitialized()) << __FUNCTION__; return g_removeproperty(npp, obj, propertyName); } void SetException(NPObject* obj, const NPUTF8* message) { DCHECK(IsInitialized()) << __FUNCTION__; return g_setexception(obj, message); } void PushPopupsEnabledState(NPP npp, NPBool enabled) { DCHECK(IsInitialized()) << __FUNCTION__; return g_pushpopupsenabledstate(npp, enabled); } void PopPopupsEnabledState(NPP npp) { DCHECK(IsInitialized()) << __FUNCTION__; return g_poppopupsenabledstate(npp); } bool Enumerate(NPP npp, NPObject* obj, NPIdentifier** identifier, uint32_t* count) { DCHECK(IsInitialized()) << __FUNCTION__; return g_enumerate(npp, obj, identifier, count); } void PluginThreadAsyncCall(NPP instance, void (*func)(void*), void* userData) { DCHECK(IsInitialized()) << __FUNCTION__; return g_pluginthreadasynccall(instance, func, userData); } bool Construct(NPP npp, NPObject* obj, const NPVariant* args, uint32_t argCount, NPVariant* result) { DCHECK(IsInitialized()) << __FUNCTION__; return g_construct(npp, obj, args, argCount, result); } NPError GetValueForURL(NPP instance, NPNURLVariable variable, const char* url, char** value, uint32* len) { DCHECK(IsInitialized()) << __FUNCTION__; DCHECK(npapi::VersionMinor() >= NPVERS_HAS_URL_AND_AUTH_INFO); if (!g_getvalueforurl) { NOTREACHED(); return NPERR_INCOMPATIBLE_VERSION_ERROR; } return g_getvalueforurl(instance, variable, url, value, len); } NPError SetValueForURL(NPP instance, NPNURLVariable variable, const char* url, const char* value, uint32 len) { DCHECK(IsInitialized()) << __FUNCTION__; DCHECK(npapi::VersionMinor() >= NPVERS_HAS_URL_AND_AUTH_INFO); if (g_setvalueforurl) { NOTREACHED(); return NPERR_INCOMPATIBLE_VERSION_ERROR; } return g_setvalueforurl(instance, variable, url, value, len); } NPError GetAuthenticationInfo(NPP instance, const char* protocol, const char* host, int32 port, const char* scheme, const char *realm, char** username, uint32* ulen, char** password, uint32* plen) { DCHECK(IsInitialized()) << __FUNCTION__; DCHECK(npapi::VersionMinor() >= NPVERS_HAS_URL_AND_AUTH_INFO); if (g_getauthenticationinfo) { NOTREACHED(); return NPERR_INCOMPATIBLE_VERSION_ERROR; } return g_getauthenticationinfo(instance, protocol, host, port, scheme, realm, username, ulen, password, plen); } std::string StringFromIdentifier(NPIdentifier identifier) { std::string ret; NPUTF8* utf8 = UTF8FromIdentifier(identifier); if (utf8) { ret = utf8; MemFree(utf8); } return ret; } } // namespace npapi void AllocateStringVariant(const std::string& str, NPVariant* var) { DCHECK(var); int len = str.length(); NPUTF8* buffer = reinterpret_cast(npapi::MemAlloc(len + 1)); if (buffer) { buffer[len] = '\0'; memcpy(buffer, str.c_str(), len); STRINGN_TO_NPVARIANT(buffer, len, *var); } else { NULL_TO_NPVARIANT(*var); } }