633 lines
16 KiB
C++
633 lines
16 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
#include "nsPluginHostImpl.h"
|
|
#include <stdio.h>
|
|
#include "prio.h"
|
|
#include "prmem.h"
|
|
#include "ns4xPlugin.h"
|
|
#include "nsMalloc.h" //this is evil...
|
|
#include "nsPluginInstancePeer.h"
|
|
|
|
#ifdef XP_PC
|
|
#include "windows.h"
|
|
#endif
|
|
|
|
static NS_DEFINE_IID(kIPluginInstanceIID, NS_IPLUGININSTANCE_IID);
|
|
|
|
nsPluginTag :: nsPluginTag()
|
|
{
|
|
mNext = nsnull;
|
|
mName = nsnull;
|
|
mDescription = nsnull;
|
|
mMimeType = nsnull;
|
|
mMimeDescription = nsnull;
|
|
mExtensions = nsnull;
|
|
mVariants = 0;
|
|
mMimeTypeArray = nsnull;
|
|
mMimeDescriptionArray = nsnull;
|
|
mExtensionsArray = nsnull;
|
|
mLibrary = nsnull;
|
|
mEntryPoint = nsnull;
|
|
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
|
}
|
|
|
|
nsPluginTag :: ~nsPluginTag()
|
|
{
|
|
if (nsnull != mName)
|
|
{
|
|
PR_Free(mName);
|
|
mName = nsnull;
|
|
}
|
|
|
|
if (nsnull != mDescription)
|
|
{
|
|
PR_Free(mDescription);
|
|
mDescription = nsnull;
|
|
}
|
|
|
|
if (nsnull != mMimeType)
|
|
{
|
|
PR_Free(mMimeType);
|
|
mMimeType = nsnull;
|
|
}
|
|
|
|
if (nsnull != mMimeDescription)
|
|
{
|
|
PR_Free(mMimeDescription);
|
|
mMimeDescription = nsnull;
|
|
}
|
|
|
|
if (nsnull != mExtensions)
|
|
{
|
|
PR_Free(mExtensions);
|
|
mExtensions = nsnull;
|
|
}
|
|
|
|
if (nsnull != mMimeTypeArray)
|
|
{
|
|
PR_Free(mMimeTypeArray);
|
|
mMimeTypeArray = nsnull;
|
|
}
|
|
|
|
if (nsnull != mMimeDescriptionArray)
|
|
{
|
|
PR_Free(mMimeDescriptionArray);
|
|
mMimeDescriptionArray = nsnull;
|
|
}
|
|
|
|
if (nsnull != mExtensionsArray)
|
|
{
|
|
PR_Free(mExtensionsArray);
|
|
mExtensionsArray = nsnull;
|
|
}
|
|
|
|
if (nsnull != mLibrary)
|
|
{
|
|
PR_UnloadLibrary(mLibrary);
|
|
mLibrary = nsnull;
|
|
}
|
|
|
|
mEntryPoint = nsnull;
|
|
}
|
|
|
|
static NS_DEFINE_IID(kIPluginManagerIID, NS_IPLUGINMANAGER_IID);
|
|
static NS_DEFINE_IID(kIPluginHostIID, NS_IPLUGINHOST_IID);
|
|
static NS_DEFINE_IID(kIMallocIID, NS_IMALLOC_IID);
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
|
|
nsPluginHostImpl :: nsPluginHostImpl()
|
|
{
|
|
}
|
|
|
|
nsPluginHostImpl :: ~nsPluginHostImpl()
|
|
{
|
|
if (nsnull != mPluginPath)
|
|
{
|
|
PR_Free(mPluginPath);
|
|
mPluginPath = nsnull;
|
|
}
|
|
|
|
while (nsnull != mPlugins)
|
|
{
|
|
nsPluginTag *temp = mPlugins->mNext;
|
|
delete mPlugins;
|
|
mPlugins = temp;
|
|
}
|
|
|
|
NS_IF_RELEASE(mMalloc);
|
|
}
|
|
|
|
NS_IMPL_ADDREF(nsPluginHostImpl)
|
|
NS_IMPL_RELEASE(nsPluginHostImpl)
|
|
|
|
nsresult nsPluginHostImpl :: QueryInterface(const nsIID& aIID,
|
|
void** aInstancePtrResult)
|
|
{
|
|
NS_PRECONDITION(nsnull != aInstancePtrResult, "null pointer");
|
|
|
|
if (nsnull == aInstancePtrResult)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
if (aIID.Equals(kIPluginManagerIID))
|
|
{
|
|
*aInstancePtrResult = (void *)((nsIPluginManager *)this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aIID.Equals(kIPluginHostIID))
|
|
{
|
|
*aInstancePtrResult = (void *)((nsIPluginHost *)this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aIID.Equals(kIMallocIID))
|
|
{
|
|
*aInstancePtrResult = mMalloc;
|
|
NS_IF_ADDREF(mMalloc);
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aIID.Equals(kISupportsIID))
|
|
{
|
|
*aInstancePtrResult = (void *)((nsISupports *)((nsIPluginHost *)this));
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
nsresult nsPluginHostImpl :: ReloadPlugins(PRBool reloadPages)
|
|
{
|
|
return LoadPlugins();
|
|
}
|
|
|
|
//XXX need to find out score on this one... MMP
|
|
nsresult nsPluginHostImpl :: UserAgent(const char **retstring)
|
|
{
|
|
*retstring = "NGLayout";
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsPluginHostImpl :: GetValue(nsPluginManagerVariable variable, void *value)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsPluginHostImpl :: SetValue(nsPluginManagerVariable variable, void *value)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl :: GetURL(nsISupports* peer, const char* url,
|
|
const char* target,
|
|
void* notifyData, const char* altHost,
|
|
const char* referrer, PRBool forceJSEnabled)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsPluginHostImpl :: PostURL(nsISupports* peer,
|
|
const char* url, const char* target,
|
|
PRUint32 postDataLen, const char* postData,
|
|
PRBool isFile, void* notifyData,
|
|
const char* altHost, const char* referrer,
|
|
PRBool forceJSEnabled,
|
|
PRUint32 postHeadersLength, const char* postHeaders)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsPluginHostImpl :: Init(void)
|
|
{
|
|
nsresult rv;
|
|
|
|
rv = nsMalloc::Create(nsnull, kIMallocIID, (void **)&mMalloc);
|
|
|
|
return rv;
|
|
}
|
|
|
|
nsresult nsPluginHostImpl :: LoadPlugins(void)
|
|
{
|
|
#ifdef XP_PC
|
|
long result;
|
|
HKEY keyloc;
|
|
DWORD type, pathlen;
|
|
char path[2000];
|
|
|
|
path[0] = 0;
|
|
|
|
result = ::RegOpenKeyEx(HKEY_CURRENT_USER,
|
|
"Software\\Netscape\\Netscape Navigator\\Main",
|
|
0, KEY_READ, &keyloc);
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
pathlen = sizeof(path);
|
|
|
|
result = ::RegQueryValueEx(keyloc, "Install Directory",
|
|
NULL, &type, (LPBYTE)&path, &pathlen);
|
|
|
|
if (result == ERROR_SUCCESS)
|
|
{
|
|
strcat(path, "\\Program\\Plugins");
|
|
printf("plugins at: %s\n", path);
|
|
}
|
|
|
|
::RegCloseKey(keyloc);
|
|
}
|
|
|
|
PRDir *dir;
|
|
|
|
dir = PR_OpenDir(path);
|
|
|
|
if (nsnull != dir)
|
|
{
|
|
PRDirEntry *dent;
|
|
char *verbuf = NULL;
|
|
DWORD verbufsize = 0;
|
|
|
|
pathlen = strlen(path);
|
|
mPluginPath = (char *)PR_Malloc(pathlen + 2);
|
|
|
|
if (nsnull != mPluginPath)
|
|
{
|
|
strcpy(mPluginPath, path);
|
|
|
|
mPluginPath[pathlen] = '\\';
|
|
mPluginPath[pathlen + 1] = 0;
|
|
}
|
|
|
|
while (nsnull != mPlugins)
|
|
{
|
|
nsPluginTag *temp = mPlugins->mNext;
|
|
delete mPlugins;
|
|
mPlugins = temp;
|
|
}
|
|
|
|
while (dent = PR_ReadDir(dir, PR_SKIP_BOTH))
|
|
{
|
|
PRInt32 len = strlen(dent->name);
|
|
|
|
if (len > 6) //np*.dll
|
|
{
|
|
if ((0 == stricmp(&dent->name[len - 4], ".dll")) && //ends in '.dll'
|
|
(0 == strnicmp(dent->name, "np", 2))) //starts with 'np'
|
|
{
|
|
PRLibrary *plugin;
|
|
|
|
strcpy(path, mPluginPath);
|
|
strcat(path, dent->name);
|
|
|
|
plugin = PR_LoadLibrary(path);
|
|
|
|
if (NULL != plugin)
|
|
{
|
|
DWORD zerome, versionsize;
|
|
|
|
versionsize = ::GetFileVersionInfoSize(path, &zerome);
|
|
|
|
if (versionsize > 0)
|
|
{
|
|
if (versionsize > verbufsize)
|
|
{
|
|
if (nsnull != verbuf)
|
|
PR_Free(verbuf);
|
|
|
|
verbuf = (char *)PR_Malloc(versionsize);
|
|
verbufsize = versionsize;
|
|
}
|
|
|
|
if ((nsnull != verbuf) && ::GetFileVersionInfo(path, NULL, verbufsize, verbuf))
|
|
{
|
|
char *buf = NULL;
|
|
UINT blen;
|
|
nsPluginTag *plugintag;
|
|
PRBool completetag = PR_FALSE;
|
|
PRInt32 variants;
|
|
|
|
plugintag = new nsPluginTag();
|
|
|
|
while (nsnull != plugintag)
|
|
{
|
|
plugintag->mName = (char *)PR_Malloc(strlen(dent->name) + 1);
|
|
|
|
if (nsnull == plugintag->mName)
|
|
break;
|
|
else
|
|
strcpy(plugintag->mName, dent->name);
|
|
|
|
::VerQueryValue(verbuf,
|
|
TEXT("\\StringFileInfo\\040904E4\\FileDescription"),
|
|
(void **)&buf, &blen);
|
|
|
|
if (NULL == buf)
|
|
break;
|
|
else
|
|
{
|
|
plugintag->mDescription = (char *)PR_Malloc(blen + 1);
|
|
|
|
if (nsnull == plugintag->mDescription)
|
|
break;
|
|
else
|
|
strcpy(plugintag->mDescription, buf);
|
|
}
|
|
|
|
::VerQueryValue(verbuf,
|
|
TEXT("\\StringFileInfo\\040904E4\\MIMEType"),
|
|
(void **)&buf, &blen);
|
|
|
|
if (NULL == buf)
|
|
break;
|
|
else
|
|
{
|
|
plugintag->mMimeType = (char *)PR_Malloc(blen + 1);
|
|
|
|
if (nsnull == plugintag->mMimeType)
|
|
break;
|
|
else
|
|
strcpy(plugintag->mMimeType, buf);
|
|
|
|
buf = plugintag->mMimeType;
|
|
|
|
variants = 1;
|
|
|
|
while (*buf)
|
|
{
|
|
if (*buf == '|')
|
|
variants++;
|
|
|
|
buf++;
|
|
}
|
|
|
|
plugintag->mVariants = variants;
|
|
|
|
plugintag->mMimeTypeArray = (char **)PR_Malloc(variants * sizeof(char *));
|
|
|
|
if (nsnull == plugintag->mMimeTypeArray)
|
|
break;
|
|
else
|
|
{
|
|
variants = 0;
|
|
|
|
plugintag->mMimeTypeArray[variants++] = plugintag->mMimeType;
|
|
|
|
buf = plugintag->mMimeType;
|
|
|
|
while (*buf)
|
|
{
|
|
if (*buf == '|')
|
|
{
|
|
plugintag->mMimeTypeArray[variants++] = buf + 1;
|
|
*buf = 0;
|
|
}
|
|
|
|
buf++;
|
|
}
|
|
}
|
|
}
|
|
|
|
::VerQueryValue(verbuf,
|
|
TEXT("\\StringFileInfo\\040904E4\\FileOpenName"),
|
|
(void **)&buf, &blen);
|
|
|
|
if (NULL == buf)
|
|
break;
|
|
else
|
|
{
|
|
plugintag->mMimeDescription = (char *)PR_Malloc(blen + 1);
|
|
|
|
if (nsnull == plugintag->mMimeDescription)
|
|
break;
|
|
else
|
|
strcpy(plugintag->mMimeDescription, buf);
|
|
|
|
buf = plugintag->mMimeDescription;
|
|
|
|
variants = 1;
|
|
|
|
while (*buf)
|
|
{
|
|
if (*buf == '|')
|
|
variants++;
|
|
|
|
buf++;
|
|
}
|
|
|
|
if (variants != plugintag->mVariants)
|
|
break;
|
|
|
|
plugintag->mMimeDescriptionArray = (char **)PR_Malloc(variants * sizeof(char *));
|
|
|
|
if (nsnull == plugintag->mMimeDescriptionArray)
|
|
break;
|
|
else
|
|
{
|
|
variants = 0;
|
|
|
|
plugintag->mMimeDescriptionArray[variants++] = plugintag->mMimeDescription;
|
|
|
|
buf = plugintag->mMimeDescription;
|
|
|
|
while (*buf)
|
|
{
|
|
if (*buf == '|')
|
|
{
|
|
plugintag->mMimeDescriptionArray[variants++] = buf + 1;
|
|
*buf = 0;
|
|
}
|
|
|
|
buf++;
|
|
}
|
|
}
|
|
}
|
|
|
|
::VerQueryValue(verbuf,
|
|
TEXT("\\StringFileInfo\\040904E4\\FileExtents"),
|
|
(void **)&buf, &blen);
|
|
|
|
if (NULL == buf)
|
|
break;
|
|
else
|
|
{
|
|
plugintag->mExtensions = (char *)PR_Malloc(blen + 1);
|
|
|
|
if (nsnull == plugintag->mExtensions)
|
|
break;
|
|
else
|
|
strcpy(plugintag->mExtensions, buf);
|
|
|
|
buf = plugintag->mExtensions;
|
|
|
|
variants = 1;
|
|
|
|
while (*buf)
|
|
{
|
|
if (*buf == '|')
|
|
variants++;
|
|
|
|
buf++;
|
|
}
|
|
|
|
if (variants != plugintag->mVariants)
|
|
break;
|
|
|
|
plugintag->mExtensionsArray = (char **)PR_Malloc(variants * sizeof(char *));
|
|
|
|
if (nsnull == plugintag->mExtensionsArray)
|
|
break;
|
|
else
|
|
{
|
|
variants = 0;
|
|
|
|
plugintag->mExtensionsArray[variants++] = plugintag->mExtensions;
|
|
|
|
buf = plugintag->mExtensions;
|
|
|
|
while (*buf)
|
|
{
|
|
if (*buf == '|')
|
|
{
|
|
plugintag->mExtensionsArray[variants++] = buf + 1;
|
|
*buf = 0;
|
|
}
|
|
|
|
buf++;
|
|
}
|
|
}
|
|
}
|
|
|
|
completetag = PR_TRUE;
|
|
break;
|
|
}
|
|
|
|
if (PR_FALSE == completetag)
|
|
delete plugintag;
|
|
else
|
|
{
|
|
if (nsnull == PR_FindSymbol(plugin, "NSGetFactory"))
|
|
plugintag->mFlags |= NS_PLUGIN_FLAG_OLDSCHOOL;
|
|
|
|
printf("plugin %s added to list %s\n", plugintag->mName, (plugintag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL) ? "(old school)" : "");
|
|
plugintag->mNext = mPlugins;
|
|
mPlugins = plugintag;
|
|
}
|
|
}
|
|
}
|
|
|
|
PR_UnloadLibrary(plugin);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nsnull != verbuf)
|
|
PR_Free(verbuf);
|
|
|
|
PR_CloseDir(dir);
|
|
}
|
|
|
|
#else
|
|
printf("Don't know how to locate plugins directory on Unix yet...\n");
|
|
#endif
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsPluginHostImpl :: InstantiatePlugin(char *aMimeType, nsIPluginInstance ** aPluginInst)
|
|
{
|
|
nsPluginTag *plugins = mPlugins;
|
|
PRInt32 variants, cnt;
|
|
|
|
while (nsnull != plugins)
|
|
{
|
|
variants = plugins->mVariants;
|
|
|
|
for (cnt = 0; cnt < variants; cnt++)
|
|
{
|
|
if (0 == strcmp(plugins->mMimeTypeArray[cnt], aMimeType))
|
|
break;
|
|
}
|
|
|
|
if (cnt < variants)
|
|
break;
|
|
|
|
plugins = plugins->mNext;
|
|
}
|
|
|
|
if (nsnull != plugins)
|
|
{
|
|
if (nsnull == plugins->mLibrary)
|
|
{
|
|
char path[2000];
|
|
|
|
strcpy(path, mPluginPath);
|
|
strcat(path, plugins->mName);
|
|
|
|
plugins->mLibrary = PR_LoadLibrary(path);
|
|
printf("loaded plugin %s for mime type %s\n", plugins->mName, aMimeType);
|
|
}
|
|
|
|
if (nsnull != plugins->mLibrary)
|
|
{
|
|
if (nsnull == plugins->mEntryPoint)
|
|
{
|
|
//create the plugin object
|
|
|
|
if (plugins->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL)
|
|
{
|
|
nsresult rv = ns4xPlugin::CreatePlugin(plugins->mLibrary, (nsIPlugin **)&plugins->mEntryPoint);
|
|
printf("result of creating plugin adapter: %d\n", rv);
|
|
}
|
|
else
|
|
plugins->mEntryPoint = (nsIPlugin *)PR_FindSymbol(plugins->mLibrary, "NSGetFactory");
|
|
|
|
if (nsnull != plugins->mEntryPoint)
|
|
plugins->mEntryPoint->Initialize((nsISupports *)(nsIPluginManager *)this);
|
|
}
|
|
|
|
if (nsnull != plugins->mEntryPoint)
|
|
{
|
|
//create an instance
|
|
|
|
if (NS_OK == plugins->mEntryPoint->CreateInstance(nsnull, kIPluginInstanceIID, (void **)aPluginInst))
|
|
{
|
|
printf("successfully created plugin instance\n");
|
|
|
|
nsIPluginInstancePeer *peer = new nsPluginInstancePeerImpl();
|
|
|
|
(*aPluginInst)->Initialize(peer);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
return NS_OK;
|
|
}
|
|
else
|
|
{
|
|
printf("unable to find plugin to handle %s\n", aMimeType);
|
|
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
}
|