Mozilla/mozilla/modules/plugin/base/src/nsPluginsDirWin.cpp
blassey%mozilla.com 135828a746 backing out: switching narrow char system calls to wide char in windows b=418703
git-svn-id: svn://10.0.0.236/trunk@247585 18797224-902f-48f8-a5cc-f745e15eee43
2008-03-11 22:46:32 +00:00

328 lines
8.3 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
nsPluginsDirWin.cpp
Windows implementation of the nsPluginsDir/nsPluginsFile classes.
by Alex Musil
*/
#include "nsPluginsDir.h"
#include "prlink.h"
#include "plstr.h"
#include "prmem.h"
#include "prprf.h"
#include "windows.h"
#include "winbase.h"
#include "nsString.h"
///////////////////////////////////////////////////////////////////////////
/* Local helper functions */
static char* GetKeyValue(char* verbuf, char* key)
{
char *buf = NULL;
UINT blen;
::VerQueryValue(verbuf,
TEXT(key),
(void **)&buf, &blen);
if(buf != NULL)
{
#ifdef WINCE
// On windows CE, the verbuf is wide and the shunt
// layer can't do much about it. So, here we
// convert the wide string.
return PL_strdup(NS_ConvertUTF16toUTF8((PRUnichar*)buf).get());
#else
return PL_strdup(buf);
#endif
}
return nsnull;
}
static PRUint32 CalculateVariantCount(char* mimeTypes)
{
PRUint32 variants = 1;
if(mimeTypes == NULL)
return 0;
char* index = mimeTypes;
while (*index)
{
if (*index == '|')
variants++;
++index;
}
return variants;
}
static char** MakeStringArray(PRUint32 variants, char* data)
{
// The number of variants has been calculated based on the mime
// type array. Plugins are not explicitely required to match
// this number in two other arrays: file extention array and mime
// description array, and some of them actually don't.
// We should handle such situations gracefully
if((variants <= 0) || (data == NULL))
return NULL;
char ** array = (char **)PR_Calloc(variants, sizeof(char *));
if(array == NULL)
return NULL;
char * start = data;
for(PRUint32 i = 0; i < variants; i++)
{
char * p = PL_strchr(start, '|');
if(p != NULL)
*p = 0;
array[i] = PL_strdup(start);
if(p == NULL)
{
// nothing more to look for, fill everything left
// with empty strings and break
while(++i < variants)
array[i] = PL_strdup("");
break;
}
start = ++p;
}
return array;
}
static void FreeStringArray(PRUint32 variants, char ** array)
{
if((variants == 0) || (array == NULL))
return;
for(PRUint32 i = 0; i < variants; i++)
{
if(array[i] != NULL)
{
PL_strfree(array[i]);
array[i] = NULL;
}
}
PR_Free(array);
}
///////////////////////////////////////////////////////////////////////////
/* nsPluginsDir implementation */
PRBool nsPluginsDir::IsPluginFile(nsIFile* file)
{
PRBool ret = PR_FALSE;
nsCAutoString path;
if (NS_FAILED(file->GetNativePath(path)))
return PR_FALSE;
const char *pathname = path.get();
const char* filename;
char* extension;
PRUint32 len;
// this is most likely a path, so skip to the filename
filename = PL_strrchr(pathname, '\\');
if(filename)
++filename;
else
filename = pathname;
len = PL_strlen(filename);
// the filename must be: "np*.dll"
extension = PL_strrchr(filename, '.');
if(extension)
++extension;
if(len > 5)
{
if(!PL_strncasecmp(filename, "np", 2) && !PL_strcasecmp(extension, "dll"))
return PR_TRUE;
}
return ret;
}
///////////////////////////////////////////////////////////////////////////
/* nsPluginFile implementation */
nsPluginFile::nsPluginFile(nsIFile* file)
: mPlugin(file)
{
// nada
}
nsPluginFile::~nsPluginFile()
{
// nada
}
/**
* Loads the plugin into memory using NSPR's shared-library loading
* mechanism. Handles platform differences in loading shared libraries.
*/
nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
{
// How can we convert to a full path names for using with NSPR?
if (!mPlugin)
return NS_ERROR_NULL_POINTER;
nsCAutoString temp;
mPlugin->GetNativePath(temp);
char* index;
char* pluginFolderPath = PL_strdup(temp.get());
index = PL_strrchr(pluginFolderPath, '\\');
*index = 0;
BOOL restoreOrigDir = FALSE;
char aOrigDir[MAX_PATH + 1];
DWORD dwCheck = ::GetCurrentDirectory(sizeof(aOrigDir), aOrigDir);
NS_ASSERTION(dwCheck <= MAX_PATH + 1, "Error in Loading plugin");
if (dwCheck <= MAX_PATH + 1)
{
restoreOrigDir = ::SetCurrentDirectory(pluginFolderPath);
NS_ASSERTION(restoreOrigDir, "Error in Loading plugin");
}
outLibrary = PR_LoadLibrary(temp.get());
if (restoreOrigDir)
{
BOOL bCheck = ::SetCurrentDirectory(aOrigDir);
NS_ASSERTION(bCheck, "Error in Loading plugin");
}
PL_strfree(pluginFolderPath);
return NS_OK;
}
/**
* Obtains all of the information currently available for this plugin.
*/
nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info)
{
nsresult res = NS_OK;
DWORD zerome, versionsize;
char* verbuf = nsnull;
const char* path;
if (!mPlugin)
return NS_ERROR_NULL_POINTER;
nsCAutoString temp;
mPlugin->GetNativePath(temp);
path = temp.get();
versionsize = ::GetFileVersionInfoSize((char*)path, &zerome);
if (versionsize > 0)
verbuf = (char *)PR_Malloc(versionsize);
if(!verbuf)
return NS_ERROR_OUT_OF_MEMORY;
if(::GetFileVersionInfo((char*)path, NULL, versionsize, verbuf))
{
info.fName = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\ProductName");
info.fDescription = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\FileDescription");
char *mimeType = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\MIMEType");
char *mimeDescription = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\FileOpenName");
char *extensions = GetKeyValue(verbuf, "\\StringFileInfo\\040904E4\\FileExtents");
info.fVariantCount = CalculateVariantCount(mimeType);
info.fMimeTypeArray = MakeStringArray(info.fVariantCount, mimeType);
info.fMimeDescriptionArray = MakeStringArray(info.fVariantCount, mimeDescription);
info.fExtensionArray = MakeStringArray(info.fVariantCount, extensions);
info.fFileName = PL_strdup(path);
PL_strfree(mimeType);
PL_strfree(mimeDescription);
PL_strfree(extensions);
}
else
res = NS_ERROR_FAILURE;
PR_Free(verbuf);
return res;
}
nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info)
{
if(info.fName != NULL)
PL_strfree(info.fName);
if(info.fDescription != NULL)
PL_strfree(info.fDescription);
if(info.fMimeTypeArray != NULL)
FreeStringArray(info.fVariantCount, info.fMimeTypeArray);
if(info.fMimeDescriptionArray != NULL)
FreeStringArray(info.fVariantCount, info.fMimeDescriptionArray);
if(info.fExtensionArray != NULL)
FreeStringArray(info.fVariantCount, info.fExtensionArray);
if(info.fFileName != NULL)
PL_strfree(info.fFileName);
ZeroMemory((void *)&info, sizeof(info));
return NS_OK;
}