mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-09 12:51:09 +02:00
The inclusions were removed with the following very crude script and the
resulting breakage was fixed up by hand. The manual fixups did either
revert the changes done by the script, replace a generic header with a more
specific one or replace a header with a forward declaration.
find . -name "*.idl" | grep -v web-platform | grep -v third_party | while read path; do
interfaces=$(grep "^\(class\|interface\).*:.*" "$path" | cut -d' ' -f2)
if [ -n "$interfaces" ]; then
if [[ "$interfaces" == *$'\n'* ]]; then
regexp="\("
for i in $interfaces; do regexp="$regexp$i\|"; done
regexp="${regexp%%\\\|}\)"
else
regexp="$interfaces"
fi
interface=$(basename "$path")
rg -l "#include.*${interface%%.idl}.h" . | while read path2; do
hits=$(grep -v "#include.*${interface%%.idl}.h" "$path2" | grep -c "$regexp" )
if [ $hits -eq 0 ]; then
echo "Removing ${interface} from ${path2}"
grep -v "#include.*${interface%%.idl}.h" "$path2" > "$path2".tmp
mv -f "$path2".tmp "$path2"
fi
done
fi
done
Differential Revision: https://phabricator.services.mozilla.com/D55442
--HG--
extra : moz-landing-system : lando
527 lines
18 KiB
C++
527 lines
18 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/*
|
|
nsPluginsDirDarwin.cpp
|
|
|
|
Mac OS X implementation of the nsPluginsDir/nsPluginsFile classes.
|
|
|
|
by Patrick C. Beard.
|
|
*/
|
|
|
|
#include "GeckoChildProcessHost.h"
|
|
#include "base/process_util.h"
|
|
|
|
#include "prlink.h"
|
|
#include "prnetdb.h"
|
|
#include "nsXPCOM.h"
|
|
|
|
#include "nsPluginsDir.h"
|
|
#include "nsNPAPIPlugin.h"
|
|
#include "nsPluginsDirUtils.h"
|
|
|
|
#include "mozilla/UniquePtr.h"
|
|
|
|
#include "nsCocoaFeatures.h"
|
|
#include "nsExceptionHandler.h"
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <Carbon/Carbon.h>
|
|
#include <CoreServices/CoreServices.h>
|
|
#include <mach-o/loader.h>
|
|
#include <mach-o/fat.h>
|
|
|
|
typedef NS_NPAPIPLUGIN_CALLBACK(const char*, NP_GETMIMEDESCRIPTION)();
|
|
typedef NS_NPAPIPLUGIN_CALLBACK(OSErr, BP_GETSUPPORTEDMIMETYPES)(
|
|
BPSupportedMIMETypes* mimeInfo, UInt32 flags);
|
|
|
|
/*
|
|
** Returns a CFBundleRef if the path refers to a Mac OS X bundle directory.
|
|
** The caller is responsible for calling CFRelease() to deallocate.
|
|
*/
|
|
static CFBundleRef getPluginBundle(const char* path) {
|
|
CFBundleRef bundle = nullptr;
|
|
CFStringRef pathRef =
|
|
::CFStringCreateWithCString(nullptr, path, kCFStringEncodingUTF8);
|
|
if (pathRef) {
|
|
CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(
|
|
nullptr, pathRef, kCFURLPOSIXPathStyle, true);
|
|
if (bundleURL) {
|
|
bundle = ::CFBundleCreate(nullptr, bundleURL);
|
|
::CFRelease(bundleURL);
|
|
}
|
|
::CFRelease(pathRef);
|
|
}
|
|
return bundle;
|
|
}
|
|
|
|
bool nsPluginsDir::IsPluginFile(nsIFile* file) {
|
|
nsCString fileName;
|
|
file->GetNativeLeafName(fileName);
|
|
/*
|
|
* Don't load the VDP fake plugin, to avoid tripping a bad bug in OS X
|
|
* 10.5.3 (see bug 436575).
|
|
*/
|
|
if (!strcmp(fileName.get(), "VerifiedDownloadPlugin.plugin")) {
|
|
NS_WARNING(
|
|
"Preventing load of VerifiedDownloadPlugin.plugin (see bug 436575)");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Caller is responsible for freeing returned buffer.
|
|
static char* CFStringRefToUTF8Buffer(CFStringRef cfString) {
|
|
const char* buffer = ::CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
|
|
if (buffer) {
|
|
return PL_strdup(buffer);
|
|
}
|
|
|
|
int64_t bufferLength =
|
|
::CFStringGetMaximumSizeForEncoding(::CFStringGetLength(cfString),
|
|
kCFStringEncodingUTF8) +
|
|
1;
|
|
char* newBuffer = static_cast<char*>(moz_xmalloc(bufferLength));
|
|
|
|
if (!::CFStringGetCString(cfString, newBuffer, bufferLength,
|
|
kCFStringEncodingUTF8)) {
|
|
free(newBuffer);
|
|
return nullptr;
|
|
}
|
|
|
|
newBuffer =
|
|
static_cast<char*>(moz_xrealloc(newBuffer, strlen(newBuffer) + 1));
|
|
return newBuffer;
|
|
}
|
|
|
|
class AutoCFTypeObject {
|
|
public:
|
|
explicit AutoCFTypeObject(CFTypeRef aObject) { mObject = aObject; }
|
|
~AutoCFTypeObject() { ::CFRelease(mObject); }
|
|
|
|
private:
|
|
CFTypeRef mObject;
|
|
};
|
|
|
|
static Boolean MimeTypeEnabled(CFDictionaryRef mimeDict) {
|
|
if (!mimeDict) {
|
|
return true;
|
|
}
|
|
|
|
CFTypeRef value;
|
|
if (::CFDictionaryGetValueIfPresent(mimeDict, CFSTR("WebPluginTypeEnabled"),
|
|
&value)) {
|
|
if (value && ::CFGetTypeID(value) == ::CFBooleanGetTypeID()) {
|
|
return ::CFBooleanGetValue(static_cast<CFBooleanRef>(value));
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static CFDictionaryRef ParsePlistForMIMETypesFilename(CFBundleRef bundle) {
|
|
CFTypeRef mimeFileName = ::CFBundleGetValueForInfoDictionaryKey(
|
|
bundle, CFSTR("WebPluginMIMETypesFilename"));
|
|
if (!mimeFileName || ::CFGetTypeID(mimeFileName) != ::CFStringGetTypeID()) {
|
|
return nullptr;
|
|
}
|
|
|
|
FSRef homeDir;
|
|
if (::FSFindFolder(kUserDomain, kCurrentUserFolderType, kDontCreateFolder,
|
|
&homeDir) != noErr) {
|
|
return nullptr;
|
|
}
|
|
|
|
CFURLRef userDirURL = ::CFURLCreateFromFSRef(kCFAllocatorDefault, &homeDir);
|
|
if (!userDirURL) {
|
|
return nullptr;
|
|
}
|
|
|
|
AutoCFTypeObject userDirURLAutorelease(userDirURL);
|
|
CFStringRef mimeFilePath = ::CFStringCreateWithFormat(
|
|
kCFAllocatorDefault, nullptr, CFSTR("Library/Preferences/%@"),
|
|
static_cast<CFStringRef>(mimeFileName));
|
|
if (!mimeFilePath) {
|
|
return nullptr;
|
|
}
|
|
|
|
AutoCFTypeObject mimeFilePathAutorelease(mimeFilePath);
|
|
CFURLRef mimeFileURL = ::CFURLCreateWithFileSystemPathRelativeToBase(
|
|
kCFAllocatorDefault, mimeFilePath, kCFURLPOSIXPathStyle, false,
|
|
userDirURL);
|
|
if (!mimeFileURL) {
|
|
return nullptr;
|
|
}
|
|
|
|
AutoCFTypeObject mimeFileURLAutorelease(mimeFileURL);
|
|
SInt32 errorCode = 0;
|
|
CFDataRef mimeFileData = nullptr;
|
|
Boolean result = ::CFURLCreateDataAndPropertiesFromResource(
|
|
kCFAllocatorDefault, mimeFileURL, &mimeFileData, nullptr, nullptr,
|
|
&errorCode);
|
|
if (!result) {
|
|
return nullptr;
|
|
}
|
|
|
|
AutoCFTypeObject mimeFileDataAutorelease(mimeFileData);
|
|
if (errorCode != 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
CFPropertyListRef propertyList = ::CFPropertyListCreateFromXMLData(
|
|
kCFAllocatorDefault, mimeFileData, kCFPropertyListImmutable, nullptr);
|
|
if (!propertyList) {
|
|
return nullptr;
|
|
}
|
|
|
|
AutoCFTypeObject propertyListAutorelease(propertyList);
|
|
if (::CFGetTypeID(propertyList) != ::CFDictionaryGetTypeID()) {
|
|
return nullptr;
|
|
}
|
|
|
|
CFTypeRef mimeTypes = ::CFDictionaryGetValue(
|
|
static_cast<CFDictionaryRef>(propertyList), CFSTR("WebPluginMIMETypes"));
|
|
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() ||
|
|
::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0) {
|
|
return nullptr;
|
|
}
|
|
|
|
return static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
|
|
}
|
|
|
|
static void ParsePlistPluginInfo(nsPluginInfo& info, CFBundleRef bundle) {
|
|
CFDictionaryRef mimeDict = ParsePlistForMIMETypesFilename(bundle);
|
|
|
|
if (!mimeDict) {
|
|
CFTypeRef mimeTypes = ::CFBundleGetValueForInfoDictionaryKey(
|
|
bundle, CFSTR("WebPluginMIMETypes"));
|
|
if (!mimeTypes || ::CFGetTypeID(mimeTypes) != ::CFDictionaryGetTypeID() ||
|
|
::CFDictionaryGetCount(static_cast<CFDictionaryRef>(mimeTypes)) == 0)
|
|
return;
|
|
mimeDict = static_cast<CFDictionaryRef>(::CFRetain(mimeTypes));
|
|
}
|
|
|
|
AutoCFTypeObject mimeDictAutorelease(mimeDict);
|
|
int mimeDictKeyCount = ::CFDictionaryGetCount(mimeDict);
|
|
|
|
// Allocate memory for mime data
|
|
int mimeDataArraySize = mimeDictKeyCount * sizeof(char*);
|
|
info.fMimeTypeArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
|
|
memset(info.fMimeTypeArray, 0, mimeDataArraySize);
|
|
info.fExtensionArray = static_cast<char**>(moz_xmalloc(mimeDataArraySize));
|
|
memset(info.fExtensionArray, 0, mimeDataArraySize);
|
|
info.fMimeDescriptionArray =
|
|
static_cast<char**>(moz_xmalloc(mimeDataArraySize));
|
|
memset(info.fMimeDescriptionArray, 0, mimeDataArraySize);
|
|
|
|
// Allocate memory for mime dictionary keys and values
|
|
mozilla::UniquePtr<CFTypeRef[]> keys(new CFTypeRef[mimeDictKeyCount]);
|
|
mozilla::UniquePtr<CFTypeRef[]> values(new CFTypeRef[mimeDictKeyCount]);
|
|
|
|
info.fVariantCount = 0;
|
|
|
|
::CFDictionaryGetKeysAndValues(mimeDict, keys.get(), values.get());
|
|
for (int i = 0; i < mimeDictKeyCount; i++) {
|
|
CFTypeRef mimeString = keys[i];
|
|
if (!mimeString || ::CFGetTypeID(mimeString) != ::CFStringGetTypeID()) {
|
|
continue;
|
|
}
|
|
CFTypeRef mimeDict = values[i];
|
|
if (mimeDict && ::CFGetTypeID(mimeDict) == ::CFDictionaryGetTypeID()) {
|
|
if (!MimeTypeEnabled(static_cast<CFDictionaryRef>(mimeDict))) {
|
|
continue;
|
|
}
|
|
info.fMimeTypeArray[info.fVariantCount] =
|
|
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(mimeString));
|
|
if (!info.fMimeTypeArray[info.fVariantCount]) {
|
|
continue;
|
|
}
|
|
CFTypeRef extensions = ::CFDictionaryGetValue(
|
|
static_cast<CFDictionaryRef>(mimeDict), CFSTR("WebPluginExtensions"));
|
|
if (extensions && ::CFGetTypeID(extensions) == ::CFArrayGetTypeID()) {
|
|
int extensionCount =
|
|
::CFArrayGetCount(static_cast<CFArrayRef>(extensions));
|
|
CFMutableStringRef extensionList =
|
|
::CFStringCreateMutable(kCFAllocatorDefault, 0);
|
|
for (int j = 0; j < extensionCount; j++) {
|
|
CFTypeRef extension =
|
|
::CFArrayGetValueAtIndex(static_cast<CFArrayRef>(extensions), j);
|
|
if (extension && ::CFGetTypeID(extension) == ::CFStringGetTypeID()) {
|
|
if (j > 0) ::CFStringAppend(extensionList, CFSTR(","));
|
|
::CFStringAppend(static_cast<CFMutableStringRef>(extensionList),
|
|
static_cast<CFStringRef>(extension));
|
|
}
|
|
}
|
|
info.fExtensionArray[info.fVariantCount] =
|
|
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(extensionList));
|
|
::CFRelease(extensionList);
|
|
}
|
|
CFTypeRef description =
|
|
::CFDictionaryGetValue(static_cast<CFDictionaryRef>(mimeDict),
|
|
CFSTR("WebPluginTypeDescription"));
|
|
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
|
|
info.fMimeDescriptionArray[info.fVariantCount] =
|
|
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
|
|
}
|
|
info.fVariantCount++;
|
|
}
|
|
}
|
|
|
|
nsPluginFile::nsPluginFile(nsIFile* spec) : pLibrary(nullptr), mPlugin(spec) {}
|
|
|
|
nsPluginFile::~nsPluginFile() {}
|
|
|
|
nsresult nsPluginFile::LoadPlugin(PRLibrary** outLibrary) {
|
|
if (!mPlugin) return NS_ERROR_NULL_POINTER;
|
|
|
|
// 64-bit NSPR does not (yet) support bundles. So in 64-bit builds we need
|
|
// (for now) to load the bundle's executable. However this can cause
|
|
// problems: CFBundleCreate() doesn't run the bundle's executable's
|
|
// initialization code, while NSAddImage() and dlopen() do run it. So using
|
|
// NSPR's dyld loading mechanisms here (NSAddImage() or dlopen()) can cause
|
|
// a bundle's initialization code to run earlier than expected, and lead to
|
|
// crashes. See bug 577967.
|
|
#ifdef __LP64__
|
|
char executablePath[PATH_MAX];
|
|
executablePath[0] = '\0';
|
|
nsAutoCString bundlePath;
|
|
mPlugin->GetNativePath(bundlePath);
|
|
CFStringRef pathRef = ::CFStringCreateWithCString(nullptr, bundlePath.get(),
|
|
kCFStringEncodingUTF8);
|
|
if (pathRef) {
|
|
CFURLRef bundleURL = ::CFURLCreateWithFileSystemPath(
|
|
nullptr, pathRef, kCFURLPOSIXPathStyle, true);
|
|
if (bundleURL) {
|
|
CFBundleRef bundle = ::CFBundleCreate(nullptr, bundleURL);
|
|
if (bundle) {
|
|
CFURLRef executableURL = ::CFBundleCopyExecutableURL(bundle);
|
|
if (executableURL) {
|
|
if (!::CFURLGetFileSystemRepresentation(
|
|
executableURL, true, (UInt8*)&executablePath, PATH_MAX))
|
|
executablePath[0] = '\0';
|
|
::CFRelease(executableURL);
|
|
}
|
|
::CFRelease(bundle);
|
|
}
|
|
::CFRelease(bundleURL);
|
|
}
|
|
::CFRelease(pathRef);
|
|
}
|
|
#else
|
|
nsAutoCString bundlePath;
|
|
mPlugin->GetNativePath(bundlePath);
|
|
const char* executablePath = bundlePath.get();
|
|
#endif
|
|
|
|
*outLibrary = PR_LoadLibrary(executablePath);
|
|
pLibrary = *outLibrary;
|
|
if (!pLibrary) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
#ifdef DEBUG
|
|
printf("[loaded plugin %s]\n", bundlePath.get());
|
|
#endif
|
|
return NS_OK;
|
|
}
|
|
|
|
static char* p2cstrdup(StringPtr pstr) {
|
|
int len = pstr[0];
|
|
char* cstr = static_cast<char*>(moz_xmalloc(len + 1));
|
|
memmove(cstr, pstr + 1, len);
|
|
cstr[len] = '\0';
|
|
return cstr;
|
|
}
|
|
|
|
static char* GetNextPluginStringFromHandle(Handle h, short* index) {
|
|
char* ret = p2cstrdup((unsigned char*)(*h + *index));
|
|
*index += (ret ? strlen(ret) : 0) + 1;
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Obtains all of the information currently available for this plugin.
|
|
*/
|
|
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info,
|
|
PRLibrary** outLibrary) {
|
|
*outLibrary = nullptr;
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
// clear out the info, except for the first field.
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
// Try to get a bundle reference.
|
|
nsAutoCString path;
|
|
if (NS_FAILED(rv = mPlugin->GetNativePath(path))) return rv;
|
|
CFBundleRef bundle = getPluginBundle(path.get());
|
|
|
|
// fill in full path
|
|
info.fFullPath = PL_strdup(path.get());
|
|
|
|
// fill in file name
|
|
nsAutoCString fileName;
|
|
if (NS_FAILED(rv = mPlugin->GetNativeLeafName(fileName))) return rv;
|
|
info.fFileName = PL_strdup(fileName.get());
|
|
|
|
// Get fName
|
|
if (bundle) {
|
|
CFTypeRef name =
|
|
::CFBundleGetValueForInfoDictionaryKey(bundle, CFSTR("WebPluginName"));
|
|
if (name && ::CFGetTypeID(name) == ::CFStringGetTypeID())
|
|
info.fName = CFStringRefToUTF8Buffer(static_cast<CFStringRef>(name));
|
|
}
|
|
|
|
// Get fDescription
|
|
if (bundle) {
|
|
CFTypeRef description = ::CFBundleGetValueForInfoDictionaryKey(
|
|
bundle, CFSTR("WebPluginDescription"));
|
|
if (description && ::CFGetTypeID(description) == ::CFStringGetTypeID())
|
|
info.fDescription =
|
|
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(description));
|
|
}
|
|
|
|
// Get fVersion
|
|
if (bundle) {
|
|
// Look for the release version first
|
|
CFTypeRef version = ::CFBundleGetValueForInfoDictionaryKey(
|
|
bundle, CFSTR("CFBundleShortVersionString"));
|
|
if (!version) // try the build version
|
|
version =
|
|
::CFBundleGetValueForInfoDictionaryKey(bundle, kCFBundleVersionKey);
|
|
if (version && ::CFGetTypeID(version) == ::CFStringGetTypeID())
|
|
info.fVersion =
|
|
CFStringRefToUTF8Buffer(static_cast<CFStringRef>(version));
|
|
}
|
|
|
|
// The last thing we need to do is get MIME data
|
|
// fVariantCount, fMimeTypeArray, fExtensionArray, fMimeDescriptionArray
|
|
|
|
// First look for data in a bundle plist
|
|
if (bundle) {
|
|
ParsePlistPluginInfo(info, bundle);
|
|
::CFRelease(bundle);
|
|
if (info.fVariantCount > 0) return NS_OK;
|
|
}
|
|
|
|
// Don't load "fbplugin" or any plugins whose name starts with "fbplugin_"
|
|
// (Facebook plugins) if we're running on OS X 10.10 (Yosemite) or later.
|
|
// A "fbplugin" file crashes on load, in the call to LoadPlugin() below.
|
|
// See bug 1086977.
|
|
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
|
if (fileName.EqualsLiteral("fbplugin") ||
|
|
StringBeginsWith(fileName, NS_LITERAL_CSTRING("fbplugin_"))) {
|
|
nsAutoCString msg;
|
|
msg.AppendPrintf("Preventing load of %s (see bug 1086977)",
|
|
fileName.get());
|
|
NS_WARNING(msg.get());
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// The block above assumes that "fbplugin" is the filename of the plugin
|
|
// to be blocked, or that the filename starts with "fbplugin_". But we
|
|
// don't yet know for sure if this is always true. So for the time being
|
|
// record extra information in our crash logs.
|
|
CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::Bug_1086977,
|
|
fileName);
|
|
}
|
|
|
|
// It's possible that our plugin has 2 entry points that'll give us 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.
|
|
|
|
// Sadly we have to load the library for this to work.
|
|
rv = LoadPlugin(outLibrary);
|
|
|
|
if (nsCocoaFeatures::OnYosemiteOrLater()) {
|
|
// If we didn't crash in LoadPlugin(), remove the annotation so we don't
|
|
// sow confusion.
|
|
CrashReporter::RemoveCrashReportAnnotation(
|
|
CrashReporter::Annotation::Bug_1086977);
|
|
}
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// Try to get data from NP_GetMIMEDescription
|
|
if (pLibrary) {
|
|
NP_GETMIMEDESCRIPTION pfnGetMimeDesc =
|
|
(NP_GETMIMEDESCRIPTION)PR_FindFunctionSymbol(
|
|
pLibrary, NP_GETMIMEDESCRIPTION_NAME);
|
|
if (pfnGetMimeDesc) ParsePluginMimeDescription(pfnGetMimeDesc(), info);
|
|
if (info.fVariantCount) return NS_OK;
|
|
}
|
|
|
|
// We'll fill this in using BP_GetSupportedMIMETypes and/or resource fork data
|
|
BPSupportedMIMETypes mi = {kBPSupportedMIMETypesStructVers_1, nullptr,
|
|
nullptr};
|
|
|
|
// Try to get data from BP_GetSupportedMIMETypes
|
|
if (pLibrary) {
|
|
BP_GETSUPPORTEDMIMETYPES pfnMime =
|
|
(BP_GETSUPPORTEDMIMETYPES)PR_FindFunctionSymbol(
|
|
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);
|
|
}
|
|
}
|
|
|
|
// Fill in the info struct based on the data in the BPSupportedMIMETypes
|
|
// struct
|
|
int variantCount = info.fVariantCount;
|
|
info.fMimeTypeArray =
|
|
static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
|
|
info.fExtensionArray =
|
|
static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
|
|
if (mi.infoStrings) {
|
|
info.fMimeDescriptionArray =
|
|
static_cast<char**>(moz_xmalloc(variantCount * sizeof(char*)));
|
|
}
|
|
short mimeIndex = 2;
|
|
short 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);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info) {
|
|
free(info.fName);
|
|
free(info.fDescription);
|
|
int variantCount = info.fVariantCount;
|
|
for (int i = 0; i < variantCount; i++) {
|
|
free(info.fMimeTypeArray[i]);
|
|
free(info.fExtensionArray[i]);
|
|
free(info.fMimeDescriptionArray[i]);
|
|
}
|
|
free(info.fMimeTypeArray);
|
|
free(info.fMimeDescriptionArray);
|
|
free(info.fExtensionArray);
|
|
free(info.fFileName);
|
|
free(info.fFullPath);
|
|
free(info.fVersion);
|
|
|
|
return NS_OK;
|
|
}
|