2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #import <WebKit/WebNetscapePluginPackage.h>
31 #import <WebKit/WebKitLogging.h>
32 #import <WebKit/WebKitNSStringExtras.h>
33 #import <WebKit/WebNSObjectExtras.h>
35 #import "WebNetscapeDeprecatedFunctions.h"
37 #import <JavaScriptCore/npruntime_impl.h>
39 typedef void (* FunctionPointer) (void);
40 typedef void (* TransitionVector) (void);
41 static FunctionPointer functionPointerForTVector(TransitionVector);
42 static TransitionVector tVectorForFunctionPointer(FunctionPointer);
44 #define PluginNameOrDescriptionStringNumber 126
45 #define MIMEDescriptionStringNumber 127
46 #define MIMEListStringStringNumber 128
48 #define RealPlayerAppIndentifier @"com.RealNetworks.RealOne Player"
49 #define RealPlayerPluginFilename @"RealPlayer Plugin"
51 @interface WebNetscapePluginPackage (Internal)
52 - (void)_unloadWithShutdown:(BOOL)shutdown;
55 @implementation WebNetscapePluginPackage
60 // The Shockwave plugin requires a valid file in CurApRefNum.
61 // But it doesn't seem to matter what file it is.
62 // If we're called inside a Cocoa application which won't have a
63 // CurApRefNum, we set it to point to the system resource file.
64 if (WebLMGetCurApRefNum() == -1) {
65 // To get the refNum for the system resource file, we have to do
66 // UseResFile(kSystemResFile) and then look at CurResFile().
67 short savedCurResFile = CurResFile();
68 UseResFile(kSystemResFile);
69 WebLMSetCurApRefNum(CurResFile());
70 UseResFile(savedCurResFile);
75 - (SInt16)openResourceFile
81 return CFBundleOpenBundleResourceMap(cfBundle);
83 err = FSPathMakeRef((const UInt8 *)[path fileSystemRepresentation], &fref, NULL);
87 return FSOpenResFile(&fref, fsRdPerm);
91 - (void)closeResourceFile:(SInt16)resRef
94 CFBundleCloseBundleResourceMap(cfBundle, resRef);
99 - (NSString *)stringForStringListID:(SInt16)stringListID andIndex:(SInt16)index
101 // Get resource, and dereference the handle.
102 Handle stringHandle = Get1Resource('STR#', stringListID);
103 if (stringHandle == NULL) {
106 unsigned char *p = (unsigned char *)*stringHandle;
110 // Check the index against the length of the string list, then skip the length.
111 if (index < 1 || index > *(SInt16 *)p)
115 // Skip any strings that come before the one we are looking for.
119 // Convert the one we found into an NSString.
120 return [[[NSString alloc] initWithBytes:(p + 1) length:*p encoding:[NSString _web_encodingForResource:stringHandle]] autorelease];
123 - (BOOL)getPluginInfoFromResources
125 SInt16 resRef = [self openResourceFile];
130 if (ResError() != noErr)
133 NSString *MIME, *extensionsList, *description;
137 NSMutableDictionary *MIMEToExtensionsDictionary = [NSMutableDictionary dictionary];
138 NSMutableDictionary *MIMEToDescriptionDictionary = [NSMutableDictionary dictionary];
141 MIME = [[self stringForStringListID:MIMEListStringStringNumber
142 andIndex:i] lowercaseString];
146 extensionsList = [[self stringForStringListID:MIMEListStringStringNumber andIndex:i+1] lowercaseString];
147 if (extensionsList) {
148 extensions = [extensionsList componentsSeparatedByString:@","];
149 [MIMEToExtensionsDictionary setObject:extensions forKey:MIME];
151 // DRM and WMP claim MIMEs without extensions. Use a @"" extension in this case.
152 [MIMEToExtensionsDictionary setObject:[NSArray arrayWithObject:@""] forKey:MIME];
154 description = [self stringForStringListID:MIMEDescriptionStringNumber
155 andIndex:[MIMEToExtensionsDictionary count]];
157 [MIMEToDescriptionDictionary setObject:description forKey:MIME];
159 [MIMEToDescriptionDictionary setObject:@"" forKey:MIME];
162 [self setMIMEToDescriptionDictionary:MIMEToDescriptionDictionary];
163 [self setMIMEToExtensionsDictionary:MIMEToExtensionsDictionary];
165 NSString *filename = [self filename];
167 description = [self stringForStringListID:PluginNameOrDescriptionStringNumber andIndex:1];
169 description = filename;
170 [self setPluginDescription:description];
173 NSString *theName = [self stringForStringListID:PluginNameOrDescriptionStringNumber andIndex:2];
176 [self setName:theName];
178 [self closeResourceFile:resRef];
183 - (BOOL)_initWithPath:(NSString *)pluginPath
192 CFBundleGetPackageInfo(cfBundle, &type, NULL);
194 // Single-file plug-in with resource fork
197 type = [[[NSFileManager defaultManager] fileAttributesAtPath:path traverseLink:YES] fileHFSTypeCode];
205 if (type != FOUR_CHAR_CODE('BRPL'))
208 // Check if the executable is Mach-O or CFM.
210 NSFileHandle *executableFile = [NSFileHandle fileHandleForReadingAtPath:[bundle executablePath]];
211 NSData *data = [executableFile readDataOfLength:512];
212 [executableFile closeFile];
213 // Check the length of the data before calling memcmp. We think this fixes 3782543.
214 if (data == nil || [data length] < 8)
216 isCFM = memcmp([data bytes], "Joy!peff", 8) == 0;
222 if (![self isNativeLibraryData:data])
226 if (![self getPluginInfoFromPLists] && ![self getPluginInfoFromResources])
232 - (id)initWithPath:(NSString *)pluginPath
234 if (!(self = [super initWithPath:pluginPath]))
237 // Initializing a plugin package can cause it to be loaded. If there was an error initializing the plugin package,
238 // ensure that it is unloaded before deallocating it (WebBasePluginPackage requires & asserts this).
239 if (![self _initWithPath:pluginPath]) {
240 [self _unloadWithShutdown:YES];
248 - (WebExecutableType)executableType
251 return WebCFMExecutableType;
253 return WebMachOExecutableType;
256 - (void)launchRealPlayer
258 CFURLRef appURL = NULL;
259 OSStatus error = LSFindApplicationForInfo(kLSUnknownCreator, (CFStringRef)RealPlayerAppIndentifier, NULL, NULL, &appURL);
261 LSLaunchURLSpec URLSpec;
262 bzero(&URLSpec, sizeof(URLSpec));
263 URLSpec.launchFlags = kLSLaunchDefaults | kLSLaunchDontSwitch;
264 URLSpec.appURL = appURL;
265 LSOpenFromURLSpec(&URLSpec, NULL);
272 NP_GetEntryPointsFuncPtr NP_GetEntryPoints = NULL;
273 NP_InitializeFuncPtr NP_Initialize = NULL;
274 MainFuncPtr pluginMainFunc = NULL;
278 CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
280 LOG(Plugins, "%f Load timing started for: %@", start, [self name]);
286 if (!CFBundleLoadExecutable(cfBundle))
289 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
290 CFAbsoluteTime duration = currentTime - start;
292 LOG(Plugins, "%f CFBundleLoadExecutable took %f seconds", currentTime, duration);
296 pluginMainFunc = (MainFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("main") );
300 NP_Initialize = (NP_InitializeFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_Initialize"));
301 NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_GetEntryPoints"));
302 NPP_Shutdown = (NPP_ShutdownProcPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_Shutdown"));
303 if (!NP_Initialize || !NP_GetEntryPoints || !NPP_Shutdown)
308 // CFM is not supported in 64-bit
316 err = FSPathMakeRef((UInt8 *)[path fileSystemRepresentation], &fref, NULL);
318 LOG_ERROR("FSPathMakeRef failed. Error=%d", err);
321 err = FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
323 LOG_ERROR("FSGetCatalogInfo failed. Error=%d", err);
326 err = WebGetDiskFragment(&spec, 0, kCFragGoesToEOF, nil, kPrivateCFragCopy, &connID, (Ptr *)&pluginMainFunc, nil);
328 LOG_ERROR("WebGetDiskFragment failed. Error=%d", err);
332 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
333 CFAbsoluteTime duration = currentTime - start;
335 LOG(Plugins, "%f WebGetDiskFragment took %f seconds", currentTime, duration);
338 pluginMainFunc = (MainFuncPtr)functionPointerForTVector((TransitionVector)pluginMainFunc);
339 if (!pluginMainFunc) {
343 // NOTE: pluginMainFunc is freed after it is called. Be sure not to return before that.
346 #endif /* __LP64__ */
349 // Plugins (at least QT) require that you call UseResFile on the resource file before loading it.
350 resourceRef = [self openResourceFile];
351 if (resourceRef != -1) {
352 UseResFile(resourceRef);
355 // swap function tables
357 browserFuncs.version = NP_VERSION_MINOR;
358 browserFuncs.size = sizeof(NPNetscapeFuncs);
359 browserFuncs.geturl = (NPN_GetURLProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetURL);
360 browserFuncs.posturl = (NPN_PostURLProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_PostURL);
361 browserFuncs.requestread = (NPN_RequestReadProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_RequestRead);
362 browserFuncs.newstream = (NPN_NewStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_NewStream);
363 browserFuncs.write = (NPN_WriteProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_Write);
364 browserFuncs.destroystream = (NPN_DestroyStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_DestroyStream);
365 browserFuncs.status = (NPN_StatusProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_Status);
366 browserFuncs.uagent = (NPN_UserAgentProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_UserAgent);
367 browserFuncs.memalloc = (NPN_MemAllocProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_MemAlloc);
368 browserFuncs.memfree = (NPN_MemFreeProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_MemFree);
369 browserFuncs.memflush = (NPN_MemFlushProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_MemFlush);
370 browserFuncs.reloadplugins = (NPN_ReloadPluginsProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_ReloadPlugins);
371 browserFuncs.geturlnotify = (NPN_GetURLNotifyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetURLNotify);
372 browserFuncs.posturlnotify = (NPN_PostURLNotifyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_PostURLNotify);
373 browserFuncs.getvalue = (NPN_GetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetValue);
374 browserFuncs.setvalue = (NPN_SetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_SetValue);
375 browserFuncs.invalidaterect = (NPN_InvalidateRectProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_InvalidateRect);
376 browserFuncs.invalidateregion = (NPN_InvalidateRegionProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_InvalidateRegion);
377 browserFuncs.forceredraw = (NPN_ForceRedrawProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_ForceRedraw);
378 browserFuncs.getJavaEnv = (NPN_GetJavaEnvProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetJavaEnv);
379 browserFuncs.getJavaPeer = (NPN_GetJavaPeerProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetJavaPeer);
381 browserFuncs.releasevariantvalue = (NPN_ReleaseVariantValueProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_ReleaseVariantValue);
382 browserFuncs.getstringidentifier = (NPN_GetStringIdentifierProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetStringIdentifier);
383 browserFuncs.getstringidentifiers = (NPN_GetStringIdentifiersProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetStringIdentifiers);
384 browserFuncs.getintidentifier = (NPN_GetIntIdentifierProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetIntIdentifier);
385 browserFuncs.identifierisstring = (NPN_IdentifierIsStringProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_IdentifierIsString);
386 browserFuncs.utf8fromidentifier = (NPN_UTF8FromIdentifierProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_UTF8FromIdentifier);
387 browserFuncs.createobject = (NPN_CreateObjectProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_CreateObject);
388 browserFuncs.retainobject = (NPN_RetainObjectProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_RetainObject);
389 browserFuncs.releaseobject = (NPN_ReleaseObjectProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_ReleaseObject);
390 browserFuncs.invoke = (NPN_InvokeProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_Invoke);
391 browserFuncs.invokeDefault = (NPN_InvokeDefaultProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_InvokeDefault);
392 browserFuncs.evaluate = (NPN_EvaluateProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_Evaluate);
393 browserFuncs.getproperty = (NPN_GetPropertyProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetProperty);
394 browserFuncs.setproperty = (NPN_SetPropertyProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_SetProperty);
395 browserFuncs.removeproperty = (NPN_RemovePropertyProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_RemoveProperty);
396 browserFuncs.setexception = (NPN_SetExceptionProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_SetException);
399 CFAbsoluteTime mainStart = CFAbsoluteTimeGetCurrent();
401 LOG(Plugins, "%f main timing started", mainStart);
402 NPP_ShutdownProcPtr shutdownFunction;
403 npErr = pluginMainFunc(&browserFuncs, &pluginFuncs, &shutdownFunction);
404 NPP_Shutdown = (NPP_ShutdownProcPtr)functionPointerForTVector((TransitionVector)shutdownFunction);
406 // Don't free pluginMainFunc if we got it from a bundle because it is owned by CFBundle in that case.
407 free(pluginMainFunc);
409 // Workaround for 3270576. The RealPlayer plug-in fails to load if its preference file is out of date.
410 // Launch the RealPlayer application to refresh the file.
411 if (npErr != NPERR_NO_ERROR) {
412 if (npErr == NPERR_MODULE_LOAD_FAILED_ERROR && [[self filename] isEqualToString:RealPlayerPluginFilename])
413 [self launchRealPlayer];
417 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
418 CFAbsoluteTime duration = currentTime - mainStart;
420 LOG(Plugins, "%f main took %f seconds", currentTime, duration);
422 pluginSize = pluginFuncs.size;
423 pluginVersion = pluginFuncs.version;
424 LOG(Plugins, "pluginMainFunc: %d, size=%d, version=%d", npErr, pluginSize, pluginVersion);
426 NPP_New = (NPP_NewProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.newp);
427 NPP_Destroy = (NPP_DestroyProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.destroy);
428 NPP_SetWindow = (NPP_SetWindowProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.setwindow);
429 NPP_NewStream = (NPP_NewStreamProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.newstream);
430 NPP_DestroyStream = (NPP_DestroyStreamProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.destroystream);
431 NPP_StreamAsFile = (NPP_StreamAsFileProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.asfile);
432 NPP_WriteReady = (NPP_WriteReadyProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.writeready);
433 NPP_Write = (NPP_WriteProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.write);
434 NPP_Print = (NPP_PrintProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.print);
435 NPP_HandleEvent = (NPP_HandleEventProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.event);
436 NPP_URLNotify = (NPP_URLNotifyProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.urlnotify);
437 NPP_GetValue = (NPP_GetValueProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.getvalue);
438 NPP_SetValue = (NPP_SetValueProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.setvalue);
440 // LiveConnect support
441 NPP_GetJavaClass = (NPP_GetJavaClassProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.javaClass);
442 if (NPP_GetJavaClass) {
443 LOG(LiveConnect, "%@: CFM entry point for NPP_GetJavaClass = %p", [self name], NPP_GetJavaClass);
445 LOG(LiveConnect, "%@: no entry point for NPP_GetJavaClass", [self name]);
449 // no function pointer conversion necessary for mach-o
450 browserFuncs.version = NP_VERSION_MINOR;
451 browserFuncs.size = sizeof(NPNetscapeFuncs);
452 browserFuncs.geturl = NPN_GetURL;
453 browserFuncs.posturl = NPN_PostURL;
454 browserFuncs.requestread = NPN_RequestRead;
455 browserFuncs.newstream = NPN_NewStream;
456 browserFuncs.write = NPN_Write;
457 browserFuncs.destroystream = NPN_DestroyStream;
458 browserFuncs.status = NPN_Status;
459 browserFuncs.uagent = NPN_UserAgent;
460 browserFuncs.memalloc = NPN_MemAlloc;
461 browserFuncs.memfree = NPN_MemFree;
462 browserFuncs.memflush = NPN_MemFlush;
463 browserFuncs.reloadplugins = NPN_ReloadPlugins;
464 browserFuncs.geturlnotify = NPN_GetURLNotify;
465 browserFuncs.posturlnotify = NPN_PostURLNotify;
466 browserFuncs.getvalue = NPN_GetValue;
467 browserFuncs.setvalue = NPN_SetValue;
468 browserFuncs.invalidaterect = NPN_InvalidateRect;
469 browserFuncs.invalidateregion = NPN_InvalidateRegion;
470 browserFuncs.forceredraw = NPN_ForceRedraw;
471 browserFuncs.getJavaEnv = NPN_GetJavaEnv;
472 browserFuncs.getJavaPeer = NPN_GetJavaPeer;
474 browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
475 browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
476 browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
477 browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
478 browserFuncs.identifierisstring = _NPN_IdentifierIsString;
479 browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
480 browserFuncs.createobject = _NPN_CreateObject;
481 browserFuncs.retainobject = _NPN_RetainObject;
482 browserFuncs.releaseobject = _NPN_ReleaseObject;
483 browserFuncs.invoke = _NPN_Invoke;
484 browserFuncs.invokeDefault = _NPN_InvokeDefault;
485 browserFuncs.evaluate = _NPN_Evaluate;
486 browserFuncs.getproperty = _NPN_GetProperty;
487 browserFuncs.setproperty = _NPN_SetProperty;
488 browserFuncs.removeproperty = _NPN_RemoveProperty;
489 browserFuncs.setexception = _NPN_SetException;
492 CFAbsoluteTime initializeStart = CFAbsoluteTimeGetCurrent();
494 LOG(Plugins, "%f NP_Initialize timing started", initializeStart);
495 npErr = NP_Initialize(&browserFuncs);
496 if (npErr != NPERR_NO_ERROR)
499 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
500 CFAbsoluteTime duration = currentTime - initializeStart;
502 LOG(Plugins, "%f NP_Initialize took %f seconds", currentTime, duration);
504 npErr = NP_GetEntryPoints(&pluginFuncs);
505 if (npErr != NPERR_NO_ERROR)
508 pluginSize = pluginFuncs.size;
509 pluginVersion = pluginFuncs.version;
511 NPP_New = pluginFuncs.newp;
512 NPP_Destroy = pluginFuncs.destroy;
513 NPP_SetWindow = pluginFuncs.setwindow;
514 NPP_NewStream = pluginFuncs.newstream;
515 NPP_DestroyStream = pluginFuncs.destroystream;
516 NPP_StreamAsFile = pluginFuncs.asfile;
517 NPP_WriteReady = pluginFuncs.writeready;
518 NPP_Write = pluginFuncs.write;
519 NPP_Print = pluginFuncs.print;
520 NPP_HandleEvent = pluginFuncs.event;
521 NPP_URLNotify = pluginFuncs.urlnotify;
522 NPP_GetValue = pluginFuncs.getvalue;
523 NPP_SetValue = pluginFuncs.setvalue;
525 // LiveConnect support
526 NPP_GetJavaClass = pluginFuncs.javaClass;
527 if (NPP_GetJavaClass){
528 LOG(LiveConnect, "%@: mach-o entry point for NPP_GetJavaClass = %p", [self name], NPP_GetJavaClass);
530 LOG(LiveConnect, "%@: no entry point for NPP_GetJavaClass", [self name]);
535 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
536 CFAbsoluteTime duration = currentTime - start;
538 LOG(Plugins, "%f Total load time: %f seconds", currentTime, duration);
543 [self _unloadWithShutdown:NO];
547 - (NPP_SetWindowProcPtr)NPP_SetWindow
549 return NPP_SetWindow;
552 - (NPP_NewProcPtr)NPP_New
557 - (NPP_DestroyProcPtr)NPP_Destroy
562 - (NPP_NewStreamProcPtr)NPP_NewStream
564 return NPP_NewStream;
567 - (NPP_StreamAsFileProcPtr)NPP_StreamAsFile
569 return NPP_StreamAsFile;
571 - (NPP_DestroyStreamProcPtr)NPP_DestroyStream
573 return NPP_DestroyStream;
576 - (NPP_WriteReadyProcPtr)NPP_WriteReady
578 return NPP_WriteReady;
580 - (NPP_WriteProcPtr)NPP_Write
585 - (NPP_HandleEventProcPtr)NPP_HandleEvent
587 return NPP_HandleEvent;
590 -(NPP_URLNotifyProcPtr)NPP_URLNotify
592 return NPP_URLNotify;
595 -(NPP_GetValueProcPtr)NPP_GetValue
600 -(NPP_SetValueProcPtr)NPP_SetValue
605 -(NPP_PrintProcPtr)NPP_Print
610 - (void)wasRemovedFromPluginDatabase:(WebPluginDatabase *)database
612 [super wasRemovedFromPluginDatabase:database];
614 // Unload when removed from final plug-in database
615 if ([pluginDatabases count] == 0)
616 [self _unloadWithShutdown:YES];
623 // Handle the case where all instances close a plug-in package, but another
624 // instance opens the package before it is unloaded (which only happens when
625 // the plug-in database is refreshed)
629 // Should load when the first instance opens the plug-in package
630 ASSERT(instanceCount == 1);
637 ASSERT(instanceCount > 0);
639 if (instanceCount == 0 && needsUnload)
640 [self _unloadWithShutdown:YES];
646 // function pointer converters
648 FunctionPointer functionPointerForTVector(TransitionVector tvp)
650 const uint32 temp[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
651 uint32 *newGlue = NULL;
654 newGlue = (uint32 *)malloc(sizeof(temp));
655 if (newGlue != NULL) {
657 for (i = 0; i < 6; i++) newGlue[i] = temp[i];
658 newGlue[0] |= ((uintptr_t)tvp >> 16);
659 newGlue[1] |= ((uintptr_t)tvp & 0xFFFF);
660 MakeDataExecutable(newGlue, sizeof(temp));
664 return (FunctionPointer)newGlue;
667 TransitionVector tVectorForFunctionPointer(FunctionPointer fp)
669 FunctionPointer *newGlue = NULL;
671 newGlue = (FunctionPointer *)malloc(2 * sizeof(FunctionPointer));
672 if (newGlue != NULL) {
677 return (TransitionVector)newGlue;
680 @implementation WebNetscapePluginPackage (Internal)
682 - (void)_unloadWithShutdown:(BOOL)shutdown
687 LOG(Plugins, "Unloading %@...", name);
689 // Cannot unload a plug-in package while an instance is still using it
690 if (instanceCount > 0) {
695 if (shutdown && NPP_Shutdown)
698 if (resourceRef != -1)
699 [self closeResourceFile:resourceRef];
702 CFBundleUnloadExecutable(cfBundle);
705 // CFM is not supported in 64-bit
706 WebCloseConnection(&connID);
710 LOG(Plugins, "Plugin Unloaded");