static char* GetPluginString(short id, short index) { Str255 str; ::GetIndString(str, id, index); return p2cstrdup(str); }
static char* GetNextPluginStringFromHandle(Handle h, short *index) { char *ret = p2cstrdup((unsigned char*)(*h + *index)); *index += (ret ? PL_strlen(ret) : 0) + 1; return ret; }
/** * Obtains all of the information currently available for this plugin. */ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) { // clear out the info, except for the first field. memset(&info.fName, 0, sizeof(info) - sizeof(PRUint32)); // need to open the plugin's resource file and read some resources. short refNum = OpenPluginResource(); if (refNum >= 0) { if (info.fPluginInfoSize >= sizeof(nsPluginInfo)) { // 'STR#', 126, 2 => plugin name. info.fName = GetPluginString(126, 2); // 'STR#', 126, 1 => plugin description. info.fDescription = GetPluginString(126, 1); nsCString path; mPlugin->GetNativePath(path); FSSpec spec; toFSSpec(mPlugin, spec); info.fFileName = p2cstrdup(spec.name); info.fFullPath = PL_strdup(path.get()); CFBundleRef bundle = getPluginBundle(path.get()); if (bundle) { info.fBundle = PR_TRUE; CFRelease(bundle); } else info.fBundle = PR_FALSE; // It's possible that our plugin has 2 special extra entry points that'll give us more // mime type info. Quicktime does this to get around the need of having admin rights // to change mime info in the resource fork. We need to use this info instead of the // resource. See bug 113464. BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, NULL, NULL}; if (pLibrary) { // First, check for NP_GetMIMEDescription NP_GETMIMEDESCRIPTION pfnGetMimeDesc = (NP_GETMIMEDESCRIPTION)PR_FindSymbol(pLibrary, NP_GETMIMEDESCRIPTION_NAME); if (pfnGetMimeDesc) { nsresult rv = ParsePluginMimeDescription(pfnGetMimeDesc(), info); if (NS_SUCCEEDED(rv)) { // if we could parse the mime types from NP_GetMIMEDescription, ::CloseResFile(refNum); // we've got what we need, close the resource, we're done return rv; } } // Next check for mime info from BP_GetSupportedMIMETypes BP_GETSUPPORTEDMIMETYPES pfnMime = (BP_GETSUPPORTEDMIMETYPES)PR_FindSymbol(pLibrary, "BP_GetSupportedMIMETypes"); if (pfnMime && noErr == pfnMime(&mi, 0) && mi.typeStrings) { info.fVariantCount = (**(short**)mi.typeStrings) / 2; ::HLock(mi.typeStrings); if (mi.infoStrings) // it's possible some plugins have infoStrings missing ::HLock(mi.infoStrings); } } // Last, we couldn't get info from an extra entry point for some reason, // Lets get info from normal resources if (!info.fVariantCount) { mi.typeStrings = ::Get1Resource('STR#', 128); if (mi.typeStrings) { info.fVariantCount = (**(short**)mi.typeStrings) / 2; ::DetachResource(mi.typeStrings); ::HLock(mi.typeStrings); } else { // Don't add this plugin because no mime types could be found ::CloseResFile(refNum); return NS_ERROR_FAILURE; } mi.infoStrings = ::Get1Resource('STR#', 127); if (mi.infoStrings) { ::DetachResource(mi.infoStrings); ::HLock(mi.infoStrings); } } // fill-in rest of info struct int variantCount = info.fVariantCount; info.fMimeTypeArray = new char*[variantCount]; info.fExtensionArray = new char*[variantCount]; if (mi.infoStrings) info.fMimeDescriptionArray = new char*[variantCount]; short mimeIndex = 2, descriptionIndex = 2; for (int i = 0; i < variantCount; i++) { info.fMimeTypeArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); info.fExtensionArray[i] = GetNextPluginStringFromHandle(mi.typeStrings, &mimeIndex); if (mi.infoStrings) info.fMimeDescriptionArray[i] = GetNextPluginStringFromHandle(mi.infoStrings, &descriptionIndex); } ::HUnlock(mi.typeStrings); ::DisposeHandle(mi.typeStrings); if (mi.infoStrings) { ::HUnlock(mi.infoStrings); ::DisposeHandle(mi.infoStrings); } } ::CloseResFile(refNum); } return NS_OK; }