Back to index

lightning-sunbird  0.9+nobinonly
nsPluginsDirOS2.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Mozilla OS/2 libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * John Fairhurst, <john_fairhurst@iname.com>.
00018  * Portions created by the Initial Developer are Copyright (C) 1998
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 // OS/2 plugin-loading code.
00038 
00039 #define INCL_DOS
00040 #define INCL_DOSERRORS
00041 #include <os2.h>
00042 
00043 #include "nsPluginsDir.h"
00044 #include "prlink.h"
00045 #include "plstr.h"
00046 #include "prmem.h"
00047 #include "nsPluginDefs.h"
00048 
00049 #include "nsString.h"
00050 
00051 /* Load a string stored as RCDATA in a resource segment */
00052 /* Returned string needs to be PR_Free'd by caller */
00053 static char *LoadRCDATAString( HMODULE hMod, ULONG resid)
00054 {
00055    APIRET rc;
00056    ULONG  ulSize = 0;
00057    char  *string = 0;
00058 
00059    rc = DosQueryResourceSize( hMod, RT_RCDATA, resid, &ulSize);
00060 
00061    if( rc == NO_ERROR)
00062    {
00063       char *readOnlyString = 0;
00064       rc = DosGetResource( hMod, RT_RCDATA, resid, (void**) &readOnlyString);
00065 
00066       /* allow for 0-termination if user hasn't got it right */
00067       if( readOnlyString[ ulSize - 1] != '\0')
00068          ulSize++;
00069 
00070       if( rc == NO_ERROR)
00071       {
00072          /* copy string & zero-terminate */
00073          string = (char*) PR_Malloc( ulSize);
00074          memcpy( string, readOnlyString, ulSize - 1);
00075          string[ ulSize - 1] = '\0';
00076 
00077          DosFreeResource( readOnlyString);
00078       }
00079    }
00080 
00081    return string;
00082 }
00083 
00084 static PRUint32 CalculateVariantCount(char* mimeTypes)
00085 {
00086   PRUint32 variants = 1;
00087 
00088   if(mimeTypes == nsnull)
00089     return 0;
00090 
00091   char* index = mimeTypes;
00092   while (*index)
00093   {
00094     if (*index == '|')
00095     variants++;
00096 
00097     ++index;
00098   }
00099   return variants;
00100 }
00101 
00102 static char** MakeStringArray(PRUint32 variants, char* data)
00103 {
00104   if((variants <= 0) || (data == nsnull))
00105     return nsnull;
00106 
00107   char ** array = (char **)PR_Calloc(variants, sizeof(char *));
00108   if(array == nsnull)
00109     return nsnull;
00110 
00111   char * start = data;
00112   for(PRUint32 i = 0; i < variants; i++)
00113   {
00114     char * p = PL_strchr(start, '|');
00115     if(p != nsnull)
00116       *p = 0;
00117 
00118     array[i] = PL_strdup(start);
00119     start = ++p;
00120   }
00121   return array;
00122 }
00123 
00124 static void FreeStringArray(PRUint32 variants, char ** array)
00125 {
00126   if((variants == 0) || (array == nsnull))
00127     return;
00128 
00129   for(PRUint32 i = 0; i < variants; i++)
00130   {
00131     if(array[i] != nsnull)
00132     {
00133       PL_strfree(array[i]);
00134       array[i] = nsnull;
00135     }
00136   }
00137   PR_Free(array);
00138 }
00139 
00140 // nsPluginsDir class
00141 
00142 PRBool nsPluginsDir::IsPluginFile(nsIFile* file)
00143 {
00144     nsCAutoString leaf;
00145     if (NS_FAILED(file->GetNativeLeafName(leaf)))
00146         return PR_FALSE;
00147 
00148     const char *leafname = leaf.get();
00149     
00150     if( nsnull != leafname)
00151     {
00152       int len = strlen( leafname);
00153       if( len > 6 &&                 // np*.dll
00154           (0 == strnicmp( &(leafname[len - 4]), ".dll", 4)) &&
00155           (0 == strnicmp( leafname, "np", 2)))
00156       {
00157         return PR_TRUE;
00158       }
00159     }
00160     return PR_FALSE;
00161 }
00162 
00163 // nsPluginFile implementation
00164 
00165 nsPluginFile::nsPluginFile(nsIFile* file)
00166 : mPlugin(file)
00167 {}
00168 
00169 nsPluginFile::~nsPluginFile()
00170 {}
00171 
00172 // Loads the plugin into memory using NSPR's shared-library loading
00173 nsresult nsPluginFile::LoadPlugin( PRLibrary *&outLibrary)
00174 {
00175     if (!mPlugin)
00176       return NS_ERROR_NULL_POINTER;
00177    
00178     nsCAutoString temp;
00179     mPlugin->GetNativePath(temp);
00180 
00181     outLibrary = PR_LoadLibrary(temp.get());
00182     return outLibrary == nsnull ? NS_ERROR_FAILURE : NS_OK;
00183 }
00184 
00185 // Obtains all of the information currently available for this plugin.
00186 nsresult nsPluginFile::GetPluginInfo( nsPluginInfo &info)
00187 {
00188    nsresult   rc = NS_ERROR_FAILURE;
00189    HMODULE    hPlug = 0; // Need a HMODULE to query resource statements
00190    char       failure[ CCHMAXPATH] = "";
00191    APIRET     ret;
00192 
00193    const char* path;
00194    nsCAutoString temp;
00195    mPlugin->GetNativePath(temp);
00196    path = temp.get();
00197    ret = DosLoadModule( failure, CCHMAXPATH, path, &hPlug);
00198 
00199    while( ret == NO_ERROR)
00200    {
00201       info.fPluginInfoSize = sizeof( nsPluginInfo);
00202 
00203       info.fName = LoadRCDATAString( hPlug, NS_INFO_ProductName);
00204 
00205       // get description (doesn't matter if it's missing)...
00206       info.fDescription = LoadRCDATAString( hPlug, NS_INFO_FileDescription);
00207 
00208       char * mimeType = LoadRCDATAString( hPlug, NS_INFO_MIMEType);
00209       if( nsnull == mimeType) break;
00210 
00211       char * mimeDescription = LoadRCDATAString( hPlug, NS_INFO_FileOpenName);
00212       if( nsnull == mimeDescription) break;
00213 
00214       char * extensions = LoadRCDATAString( hPlug, NS_INFO_FileExtents);
00215       if( nsnull == extensions) break;
00216 
00217       info.fVariantCount = CalculateVariantCount(mimeType);
00218 
00219       info.fMimeTypeArray = MakeStringArray(info.fVariantCount, mimeType);
00220       if( info.fMimeTypeArray == nsnull) break;
00221 
00222       info.fMimeDescriptionArray = MakeStringArray(info.fVariantCount, mimeDescription);
00223       if( nsnull == info.fMimeDescriptionArray) break;
00224 
00225       info.fExtensionArray = MakeStringArray(info.fVariantCount, extensions);
00226       if( nsnull == info.fExtensionArray) break;
00227 
00228       info.fFileName = PL_strdup(path);
00229 
00230       rc = NS_OK;
00231       break;
00232    }
00233 
00234    if( 0 != hPlug)
00235       DosFreeModule( hPlug);
00236 
00237    return rc;
00238 }
00239 
00240 nsresult nsPluginFile::FreePluginInfo(nsPluginInfo& info)
00241 {
00242    if(info.fName != nsnull)
00243      PL_strfree(info.fName);
00244  
00245    if(info.fDescription != nsnull)
00246      PL_strfree(info.fDescription);
00247  
00248    if(info.fMimeTypeArray != nsnull)
00249      FreeStringArray(info.fVariantCount, info.fMimeTypeArray);
00250  
00251    if(info.fMimeDescriptionArray != nsnull)
00252      FreeStringArray(info.fVariantCount, info.fMimeDescriptionArray);
00253  
00254    if(info.fExtensionArray != nsnull)
00255      FreeStringArray(info.fVariantCount, info.fExtensionArray);
00256  
00257    memset((void *)&info, 0, sizeof(info));
00258  
00259    return NS_OK;
00260 }