123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /*
- * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- * its contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #if ENABLE(NETSCAPE_PLUGIN_API)
- #import "WebNetscapePluginPackage.h"
- #import "WebTypesInternal.h"
- #import "WebKitLogging.h"
- #import "WebKitNSStringExtras.h"
- #import "WebNSFileManagerExtras.h"
- #import "WebNSObjectExtras.h"
- #import <WebCore/npruntime_impl.h>
- #import <wtf/RetainPtr.h>
- #if USE(PLUGIN_HOST_PROCESS)
- #import "NetscapePluginHostManager.h"
- using namespace WebKit;
- #endif
- using namespace WebCore;
- #define PluginNameOrDescriptionStringNumber 126
- #define MIMEDescriptionStringNumber 127
- #define MIMEListStringStringNumber 128
- @interface WebNetscapePluginPackage (Internal)
- - (void)_unloadWithShutdown:(BOOL)shutdown;
- @end
- @implementation WebNetscapePluginPackage
- - (ResFileRefNum)openResourceFile
- {
- return CFBundleOpenBundleResourceMap(cfBundle.get());
- }
- - (void)closeResourceFile:(ResFileRefNum)resRef
- {
- CFBundleCloseBundleResourceMap(cfBundle.get(), resRef);
- }
- #if COMPILER(CLANG)
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- #endif
- - (NSString *)stringForStringListID:(SInt16)stringListID andIndex:(SInt16)index
- {
- // Get resource, and dereference the handle.
- Handle stringHandle = Get1Resource('STR#', stringListID);
- if (stringHandle == NULL) {
- return nil;
- }
- unsigned char *p = (unsigned char *)*stringHandle;
- if (!p)
- return nil;
-
- // Check the index against the length of the string list, then skip the length.
- if (index < 1 || index > *(SInt16 *)p)
- return nil;
- p += sizeof(SInt16);
-
- // Skip any strings that come before the one we are looking for.
- while (--index)
- p += 1 + *p;
-
- // Convert the one we found into an NSString.
- return [[[NSString alloc] initWithBytes:(p + 1) length:*p encoding:[NSString _web_encodingForResource:stringHandle]] autorelease];
- }
- - (BOOL)getPluginInfoFromResources
- {
- SInt16 resRef = [self openResourceFile];
- if (resRef == -1)
- return NO;
-
- UseResFile(resRef);
- if (ResError() != noErr)
- return NO;
- NSString *MIME, *extensionsList, *description;
- NSArray *extensions;
- unsigned i;
-
- for (i=1; 1; i+=2) {
- MIME = [[self stringForStringListID:MIMEListStringStringNumber
- andIndex:i] lowercaseString];
- if (!MIME)
- break;
- MimeClassInfo mimeClassInfo;
- mimeClassInfo.type = String(MIME).lower();
- extensionsList = [[self stringForStringListID:MIMEListStringStringNumber andIndex:i+1] lowercaseString];
- if (extensionsList) {
- extensions = [extensionsList componentsSeparatedByString:@","];
- for (NSUInteger j = 0; j < [extensions count]; ++j)
- mimeClassInfo.extensions.append((NSString *)[extensions objectAtIndex:j]);
- }
-
- description = [self stringForStringListID:MIMEDescriptionStringNumber
- andIndex:pluginInfo.mimes.size() + 1];
- mimeClassInfo.desc = description;
- pluginInfo.mimes.append(mimeClassInfo);
- }
- NSString *filename = [(NSString *)path lastPathComponent];
- pluginInfo.file = filename;
-
- description = [self stringForStringListID:PluginNameOrDescriptionStringNumber andIndex:1];
- if (!description)
- description = filename;
- pluginInfo.desc = description;
-
-
- NSString *theName = [self stringForStringListID:PluginNameOrDescriptionStringNumber andIndex:2];
- if (!theName)
- theName = filename;
- pluginInfo.name = theName;
- pluginInfo.isApplicationPlugin = false;
-
- [self closeResourceFile:resRef];
-
- return YES;
- }
- #if COMPILER(CLANG)
- #pragma clang diagnostic pop
- #endif
- - (BOOL)_initWithPath:(NSString *)pluginPath
- {
- resourceRef = -1;
-
- OSType type = 0;
- if (!cfBundle)
- return NO;
- CFBundleGetPackageInfo(cfBundle.get(), &type, NULL);
-
- if (type != FOUR_CHAR_CODE('BRPL'))
- return NO;
- #if USE(PLUGIN_HOST_PROCESS)
- RetainPtr<CFArrayRef> archs = adoptCF(CFBundleCopyExecutableArchitectures(cfBundle.get()));
- if ([(NSArray *)archs.get() containsObject:[NSNumber numberWithInteger:NSBundleExecutableArchitectureX86_64]])
- pluginHostArchitecture = CPU_TYPE_X86_64;
- else if ([(NSArray *)archs.get() containsObject:[NSNumber numberWithInteger:NSBundleExecutableArchitectureI386]])
- pluginHostArchitecture = CPU_TYPE_X86;
- else
- return NO;
- #else
- RetainPtr<CFURLRef> executableURL = adoptCF(CFBundleCopyExecutableURL(cfBundle.get()));
- if (!executableURL)
- return NO;
- NSFileHandle *executableFile = [NSFileHandle fileHandleForReadingAtPath:[(NSURL *)executableURL.get() path]];
- NSData *data = [executableFile readDataOfLength:512];
- [executableFile closeFile];
- if (![self isNativeLibraryData:data])
- return NO;
- #endif
- if (![self getPluginInfoFromPLists] && ![self getPluginInfoFromResources])
- return NO;
-
- return YES;
- }
- - (id)initWithPath:(NSString *)pluginPath
- {
- if (!(self = [super initWithPath:pluginPath]))
- return nil;
-
- // Initializing a plugin package can cause it to be loaded. If there was an error initializing the plugin package,
- // ensure that it is unloaded before deallocating it (WebBasePluginPackage requires & asserts this).
- if (![self _initWithPath:pluginPath]) {
- [self _unloadWithShutdown:YES];
- [self release];
- return nil;
- }
-
- return self;
- }
- #if USE(PLUGIN_HOST_PROCESS)
- - (cpu_type_t)pluginHostArchitecture
- {
- return pluginHostArchitecture;
- }
- - (void)createPropertyListFile
- {
- NetscapePluginHostManager::shared().createPropertyListFile(path, pluginHostArchitecture, [self bundleIdentifier]);
- }
- #endif
- - (void)unload
- {
- [self _unloadWithShutdown:YES];
- }
- - (BOOL)_tryLoad
- {
- NP_GetEntryPointsFuncPtr NP_GetEntryPoints = NULL;
- NP_InitializeFuncPtr NP_Initialize = NULL;
- NPError npErr;
- #if !LOG_DISABLED
- CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
- CFAbsoluteTime currentTime;
- CFAbsoluteTime duration;
- #endif
- LOG(Plugins, "%f Load timing started for: %@", start, (NSString *)[self pluginInfo].name);
- if (isLoaded)
- return YES;
-
- if (!CFBundleLoadExecutable(cfBundle.get()))
- return NO;
- #if !LOG_DISABLED
- currentTime = CFAbsoluteTimeGetCurrent();
- duration = currentTime - start;
- #endif
- LOG(Plugins, "%f CFBundleLoadExecutable took %f seconds", currentTime, duration);
- isLoaded = YES;
- NP_Initialize = (NP_InitializeFuncPtr)CFBundleGetFunctionPointerForName(cfBundle.get(), CFSTR("NP_Initialize"));
- NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)CFBundleGetFunctionPointerForName(cfBundle.get(), CFSTR("NP_GetEntryPoints"));
- NP_Shutdown = (NPP_ShutdownProcPtr)CFBundleGetFunctionPointerForName(cfBundle.get(), CFSTR("NP_Shutdown"));
- if (!NP_Initialize || !NP_GetEntryPoints || !NP_Shutdown)
- return NO;
- #if COMPILER(CLANG)
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wdeprecated-declarations"
- #endif
- // Plugins (at least QT) require that you call UseResFile on the resource file before loading it.
- resourceRef = [self openResourceFile];
- if (resourceRef != -1) {
- UseResFile(resourceRef);
- }
- #if COMPILER(CLANG)
- #pragma clang diagnostic pop
- #endif
- browserFuncs.version = NP_VERSION_MINOR;
- browserFuncs.size = sizeof(NPNetscapeFuncs);
- browserFuncs.geturl = NPN_GetURL;
- browserFuncs.posturl = NPN_PostURL;
- browserFuncs.requestread = NPN_RequestRead;
- browserFuncs.newstream = NPN_NewStream;
- browserFuncs.write = NPN_Write;
- browserFuncs.destroystream = NPN_DestroyStream;
- browserFuncs.status = NPN_Status;
- browserFuncs.uagent = NPN_UserAgent;
- browserFuncs.memalloc = NPN_MemAlloc;
- browserFuncs.memfree = NPN_MemFree;
- browserFuncs.memflush = NPN_MemFlush;
- browserFuncs.reloadplugins = NPN_ReloadPlugins;
- browserFuncs.geturlnotify = NPN_GetURLNotify;
- browserFuncs.posturlnotify = NPN_PostURLNotify;
- browserFuncs.getvalue = NPN_GetValue;
- browserFuncs.setvalue = NPN_SetValue;
- browserFuncs.invalidaterect = NPN_InvalidateRect;
- browserFuncs.invalidateregion = NPN_InvalidateRegion;
- browserFuncs.forceredraw = NPN_ForceRedraw;
- browserFuncs.getJavaEnv = NPN_GetJavaEnv;
- browserFuncs.getJavaPeer = NPN_GetJavaPeer;
- browserFuncs.pushpopupsenabledstate = NPN_PushPopupsEnabledState;
- browserFuncs.poppopupsenabledstate = NPN_PopPopupsEnabledState;
- browserFuncs.pluginthreadasynccall = NPN_PluginThreadAsyncCall;
- browserFuncs.getvalueforurl = NPN_GetValueForURL;
- browserFuncs.setvalueforurl = NPN_SetValueForURL;
- browserFuncs.getauthenticationinfo = NPN_GetAuthenticationInfo;
- browserFuncs.scheduletimer = NPN_ScheduleTimer;
- browserFuncs.unscheduletimer = NPN_UnscheduleTimer;
- browserFuncs.popupcontextmenu = NPN_PopUpContextMenu;
- browserFuncs.convertpoint = NPN_ConvertPoint;
- browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
- browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
- browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
- browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
- browserFuncs.identifierisstring = _NPN_IdentifierIsString;
- browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
- browserFuncs.intfromidentifier = _NPN_IntFromIdentifier;
- browserFuncs.createobject = _NPN_CreateObject;
- browserFuncs.retainobject = _NPN_RetainObject;
- browserFuncs.releaseobject = _NPN_ReleaseObject;
- browserFuncs.hasmethod = _NPN_HasMethod;
- browserFuncs.invoke = _NPN_Invoke;
- browserFuncs.invokeDefault = _NPN_InvokeDefault;
- browserFuncs.evaluate = _NPN_Evaluate;
- browserFuncs.hasproperty = _NPN_HasProperty;
- browserFuncs.getproperty = _NPN_GetProperty;
- browserFuncs.setproperty = _NPN_SetProperty;
- browserFuncs.removeproperty = _NPN_RemoveProperty;
- browserFuncs.setexception = _NPN_SetException;
- browserFuncs.enumerate = _NPN_Enumerate;
- browserFuncs.construct = _NPN_Construct;
- #if !LOG_DISABLED
- CFAbsoluteTime initializeStart = CFAbsoluteTimeGetCurrent();
- #endif
- LOG(Plugins, "%f NP_Initialize timing started", initializeStart);
- npErr = NP_Initialize(&browserFuncs);
- if (npErr != NPERR_NO_ERROR)
- return NO;
- #if !LOG_DISABLED
- currentTime = CFAbsoluteTimeGetCurrent();
- duration = currentTime - initializeStart;
- #endif
- LOG(Plugins, "%f NP_Initialize took %f seconds", currentTime, duration);
- pluginFuncs.size = sizeof(NPPluginFuncs);
- npErr = NP_GetEntryPoints(&pluginFuncs);
- if (npErr != NPERR_NO_ERROR)
- return NO;
- pluginSize = pluginFuncs.size;
- pluginVersion = pluginFuncs.version;
- if (pluginFuncs.javaClass)
- LOG(LiveConnect, "%@: mach-o entry point for NPP_GetJavaClass = %p", (NSString *)[self pluginInfo].name, pluginFuncs.javaClass);
- else
- LOG(LiveConnect, "%@: no entry point for NPP_GetJavaClass", (NSString *)[self pluginInfo].name);
- #if !LOG_DISABLED
- currentTime = CFAbsoluteTimeGetCurrent();
- duration = currentTime - start;
- #endif
- LOG(Plugins, "%f Total load time: %f seconds", currentTime, duration);
- return YES;
- }
- - (BOOL)load
- {
- if ([self _tryLoad])
- return [super load];
- [self _unloadWithShutdown:NO];
- return NO;
- }
- - (NPPluginFuncs *)pluginFuncs
- {
- return &pluginFuncs;
- }
- - (NPNetscapeFuncs *)browserFuncs
- {
- return &browserFuncs;
- }
- - (void)wasRemovedFromPluginDatabase:(WebPluginDatabase *)database
- {
- [super wasRemovedFromPluginDatabase:database];
-
- // Unload when removed from final plug-in database
- if ([pluginDatabases count] == 0)
- [self _unloadWithShutdown:YES];
- }
- - (void)open
- {
- instanceCount++;
-
- // Handle the case where all instances close a plug-in package, but another
- // instance opens the package before it is unloaded (which only happens when
- // the plug-in database is refreshed)
- needsUnload = NO;
-
- if (!isLoaded) {
- // Should load when the first instance opens the plug-in package
- ASSERT(instanceCount == 1);
- [self load];
- }
- }
- - (void)close
- {
- ASSERT(instanceCount > 0);
- instanceCount--;
- if (instanceCount == 0 && needsUnload)
- [self _unloadWithShutdown:YES];
- }
- - (BOOL)supportsSnapshotting
- {
- if ([self bundleIdentifier] != "com.macromedia.Flash Player.plugin")
- return YES;
-
- // Flash has a bogus Info.plist entry for CFBundleVersionString, so use CFBundleShortVersionString.
- NSString *versionString = (NSString *)CFDictionaryGetValue(CFBundleGetInfoDictionary(cfBundle.get()), CFSTR("CFBundleShortVersionString"));
-
- if (![versionString hasPrefix:@"10.1"])
- return YES;
-
- // Some prerelease versions of Flash 10.1 crash when sent a drawRect event using the CA drawing model: <rdar://problem/7739922>
- return CFStringCompare((CFStringRef)versionString, CFSTR("10.1.53.60"), kCFCompareNumerically) != kCFCompareLessThan;
- }
- @end
- @implementation WebNetscapePluginPackage (Internal)
- - (void)_unloadWithShutdown:(BOOL)shutdown
- {
- if (!isLoaded)
- return;
-
- LOG(Plugins, "Unloading %@...", (NSString *)pluginInfo.name);
- // Cannot unload a plug-in package while an instance is still using it
- if (instanceCount > 0) {
- needsUnload = YES;
- return;
- }
- if (shutdown && NP_Shutdown)
- NP_Shutdown();
- if (resourceRef != -1)
- [self closeResourceFile:resourceRef];
- LOG(Plugins, "Plugin Unloaded");
- isLoaded = NO;
- }
- @end
- #endif
|