1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
41 Windows implementation of the nsPluginsDir/nsPluginsFile classes.
46 #include "nsPluginsDir.h"
57 ///////////////////////////////////////////////////////////////////////////
59 /* Local helper functions */
61 static char* GetKeyValue(char* verbuf
, char* key
)
66 ::VerQueryValue(verbuf
,
68 (void **)&buf
, &blen
);
73 // On windows CE, the verbuf is wide and the shunt
74 // layer can't do much about it. So, here we
75 // convert the wide string.
76 return PL_strdup(NS_ConvertUTF16toUTF8((PRUnichar
*)buf
).get());
78 return PL_strdup(buf
);
85 static char* GetVersion(char* verbuf
)
87 VS_FIXEDFILEINFO
*fileInfo
;
90 ::VerQueryValue(verbuf
,
92 (void **)&fileInfo
, &fileInfoLen
);
96 return PR_smprintf("%ld.%ld.%ld.%ld",
97 HIWORD(fileInfo
->dwFileVersionMS
),
98 LOWORD(fileInfo
->dwFileVersionMS
),
99 HIWORD(fileInfo
->dwFileVersionLS
),
100 LOWORD(fileInfo
->dwFileVersionLS
));
106 static PRUint32
CalculateVariantCount(char* mimeTypes
)
108 PRUint32 variants
= 1;
110 if(mimeTypes
== NULL
)
113 char* index
= mimeTypes
;
124 static char** MakeStringArray(PRUint32 variants
, char* data
)
126 // The number of variants has been calculated based on the mime
127 // type array. Plugins are not explicitely required to match
128 // this number in two other arrays: file extention array and mime
129 // description array, and some of them actually don't.
130 // We should handle such situations gracefully
132 if((variants
<= 0) || (data
== NULL
))
135 char ** array
= (char **)PR_Calloc(variants
, sizeof(char *));
141 for(PRUint32 i
= 0; i
< variants
; i
++)
143 char * p
= PL_strchr(start
, '|');
147 array
[i
] = PL_strdup(start
);
151 // nothing more to look for, fill everything left
152 // with empty strings and break
153 while(++i
< variants
)
154 array
[i
] = PL_strdup("");
164 static void FreeStringArray(PRUint32 variants
, char ** array
)
166 if((variants
== 0) || (array
== NULL
))
169 for(PRUint32 i
= 0; i
< variants
; i
++)
173 PL_strfree(array
[i
]);
179 ///////////////////////////////////////////////////////////////////////////
181 /* nsPluginsDir implementation */
183 PRBool
nsPluginsDir::IsPluginFile(nsIFile
* file
)
185 PRBool ret
= PR_FALSE
;
187 if (NS_FAILED(file
->GetNativePath(path
)))
190 const char *pathname
= path
.get();
191 const char* filename
;
194 // this is most likely a path, so skip to the filename
195 filename
= PL_strrchr(pathname
, '\\');
201 len
= PL_strlen(filename
);
202 // the filename must be: "np*.dll"
203 extension
= PL_strrchr(filename
, '.');
209 if(!PL_strncasecmp(filename
, "np", 2) && !PL_strcasecmp(extension
, "dll"))
215 ///////////////////////////////////////////////////////////////////////////
217 /* nsPluginFile implementation */
219 nsPluginFile::nsPluginFile(nsIFile
* file
)
225 nsPluginFile::~nsPluginFile()
231 * Loads the plugin into memory using NSPR's shared-library loading
232 * mechanism. Handles platform differences in loading shared libraries.
234 nsresult
nsPluginFile::LoadPlugin(PRLibrary
* &outLibrary
)
236 // How can we convert to a full path names for using with NSPR?
238 return NS_ERROR_NULL_POINTER
;
241 mPlugin
->GetNativePath(temp
);
244 char* pluginFolderPath
= PL_strdup(temp
.get());
246 index
= PL_strrchr(pluginFolderPath
, '\\');
249 BOOL restoreOrigDir
= FALSE
;
250 char aOrigDir
[MAX_PATH
+ 1];
251 DWORD dwCheck
= ::GetCurrentDirectory(sizeof(aOrigDir
), aOrigDir
);
252 NS_ASSERTION(dwCheck
<= MAX_PATH
+ 1, "Error in Loading plugin");
254 if (dwCheck
<= MAX_PATH
+ 1)
256 restoreOrigDir
= ::SetCurrentDirectory(pluginFolderPath
);
257 NS_ASSERTION(restoreOrigDir
, "Error in Loading plugin");
260 outLibrary
= PR_LoadLibrary(temp
.get());
264 BOOL bCheck
= ::SetCurrentDirectory(aOrigDir
);
265 NS_ASSERTION(bCheck
, "Error in Loading plugin");
268 PL_strfree(pluginFolderPath
);
274 * Obtains all of the information currently available for this plugin.
276 nsresult
nsPluginFile::GetPluginInfo(nsPluginInfo
& info
)
278 nsresult res
= NS_OK
;
279 DWORD zerome
, versionsize
;
280 char* verbuf
= nsnull
;
285 return NS_ERROR_NULL_POINTER
;
288 mPlugin
->GetNativePath(temp
);
291 versionsize
= ::GetFileVersionInfoSize((char*)path
, &zerome
);
293 verbuf
= (char *)PR_Malloc(versionsize
);
295 return NS_ERROR_OUT_OF_MEMORY
;
297 if(::GetFileVersionInfo((char*)path
, NULL
, versionsize
, verbuf
))
299 info
.fName
= GetKeyValue(verbuf
, "\\StringFileInfo\\040904E4\\ProductName");
300 info
.fDescription
= GetKeyValue(verbuf
, "\\StringFileInfo\\040904E4\\FileDescription");
302 char *mimeType
= GetKeyValue(verbuf
, "\\StringFileInfo\\040904E4\\MIMEType");
303 char *mimeDescription
= GetKeyValue(verbuf
, "\\StringFileInfo\\040904E4\\FileOpenName");
304 char *extensions
= GetKeyValue(verbuf
, "\\StringFileInfo\\040904E4\\FileExtents");
306 info
.fVariantCount
= CalculateVariantCount(mimeType
);
307 info
.fMimeTypeArray
= MakeStringArray(info
.fVariantCount
, mimeType
);
308 info
.fMimeDescriptionArray
= MakeStringArray(info
.fVariantCount
, mimeDescription
);
309 info
.fExtensionArray
= MakeStringArray(info
.fVariantCount
, extensions
);
310 info
.fFileName
= PL_strdup(path
);
311 info
.fVersion
= GetVersion(verbuf
);
313 PL_strfree(mimeType
);
314 PL_strfree(mimeDescription
);
315 PL_strfree(extensions
);
318 res
= NS_ERROR_FAILURE
;
326 nsresult
nsPluginFile::FreePluginInfo(nsPluginInfo
& info
)
328 if(info
.fName
!= NULL
)
329 PL_strfree(info
.fName
);
331 if(info
.fDescription
!= NULL
)
332 PL_strfree(info
.fDescription
);
334 if(info
.fMimeTypeArray
!= NULL
)
335 FreeStringArray(info
.fVariantCount
, info
.fMimeTypeArray
);
337 if(info
.fMimeDescriptionArray
!= NULL
)
338 FreeStringArray(info
.fVariantCount
, info
.fMimeDescriptionArray
);
340 if(info
.fExtensionArray
!= NULL
)
341 FreeStringArray(info
.fVariantCount
, info
.fExtensionArray
);
343 if(info
.fFileName
!= NULL
)
344 PL_strfree(info
.fFileName
);
346 if(info
.fVersion
!= NULL
)
347 PL_strfree(info
.fVersion
);
349 ZeroMemory((void *)&info
, sizeof(info
));