bug 607121 - convert plugin info strings from windows-1252 to unicode. r=jmathies a=roc
authorJonathan Kew <jfkthame@gmail.com>
Tue, 11 Jan 2011 11:17:01 +0000
changeset 60287 3f8bee2e48a728b438053ea78b64766342f436b5
parent 60286 119ef8681a16fd7eb79d515cebaa4800faab4bf3
child 60288 57eb3d4405930d4905e47b45a458e4a958075f66
push idunknown
push userunknown
push dateunknown
reviewersjmathies, roc
bugs607121
milestone2.0b10pre
bug 607121 - convert plugin info strings from windows-1252 to unicode. r=jmathies a=roc
modules/plugin/base/src/nsPluginsDirWin.cpp
--- a/modules/plugin/base/src/nsPluginsDirWin.cpp
+++ b/modules/plugin/base/src/nsPluginsDirWin.cpp
@@ -54,31 +54,66 @@
 
 #include "nsString.h"
 #include "nsILocalFile.h"
 #include "nsUnicharUtils.h"
 #include "nsSetDllDirectory.h"
 
 /* Local helper functions */
 
-static char* GetKeyValue(WCHAR* verbuf, WCHAR* key)
+static char* GetKeyValue(void* verbuf, const WCHAR* key,
+                         UINT language, UINT codepage)
 {
+  WCHAR keybuf[64]; // plenty for the template below, with the longest key
+                    // we use (currently "FileDescription")
+  const WCHAR keyFormat[] = L"\\StringFileInfo\\%04X%04X\\%s";
   WCHAR *buf = NULL;
   UINT blen;
 
-  ::VerQueryValueW(verbuf, key, (void **)&buf, &blen);
+  if (_snwprintf_s(keybuf, NS_ARRAY_LENGTH(keybuf), _TRUNCATE,
+                   keyFormat, language, codepage, key) < 0)
+  {
+    NS_NOTREACHED("plugin info key too long for buffer!");
+    return nsnull;
+  }
 
-  if (buf) {
-    return PL_strdup(NS_ConvertUTF16toUTF8(buf).get());
+  if (::VerQueryValueW(verbuf, keybuf, (void **)&buf, &blen) == 0 ||
+      buf == nsnull || blen == 0)
+  {
+    return nsnull;
+  }
+
+  // copy the WCHAR cp1252 output from VerQueryValueW into a
+  // byte buffer so that we can use MultiByteToWideChar on it
+  nsCString bstr;
+  for (UINT i = 0; i < blen; ++i) {
+    bstr.Append((char)buf[i]);
   }
 
-  return nsnull;
+  // determine number of Unicode character to be generated
+  int ulen = ::MultiByteToWideChar(codepage, MB_PRECOMPOSED,
+                                   bstr.BeginReading(), bstr.Length(),
+                                   nsnull, 0);
+  if (ulen == 0) {
+    return nsnull;
+  }
+
+  nsString ustr;
+  ustr.SetLength(ulen);
+  if (ustr.Length() < (unsigned)ulen) {
+    return nsnull;
+  }
+
+  (void)::MultiByteToWideChar(codepage, MB_PRECOMPOSED,
+                              bstr.BeginReading(), bstr.Length(),
+                              ustr.BeginWriting(), ustr.Length());
+  return PL_strdup(NS_ConvertUTF16toUTF8(ustr).get());
 }
 
-static char* GetVersion(WCHAR* verbuf)
+static char* GetVersion(void* verbuf)
 {
   VS_FIXEDFILEINFO *fileInfo;
   UINT fileInfoLen;
 
   ::VerQueryValueW(verbuf, L"\\", (void **)&fileInfo, &fileInfoLen);
 
   if (fileInfo) {
     return PR_smprintf("%ld.%ld.%ld.%ld",
@@ -315,17 +350,17 @@ nsresult nsPluginFile::LoadPlugin(PRLibr
  * Obtains all of the information currently available for this plugin.
  */
 nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info, PRLibrary **outLibrary)
 {
   *outLibrary = nsnull;
 
   nsresult rv = NS_OK;
   DWORD zerome, versionsize;
-  WCHAR* verbuf = nsnull;
+  void* verbuf = nsnull;
 
   if (!mPlugin)
     return NS_ERROR_NULL_POINTER;
 
   nsAutoString fullPath;
   if (NS_FAILED(rv = mPlugin->GetPath(fullPath)))
     return rv;
 
@@ -341,28 +376,31 @@ nsresult nsPluginFile::GetPluginInfo(nsP
   LPWSTR lpFilepath = const_cast<LPWSTR>(fullPath.get());
 #else
   LPCWSTR lpFilepath = fullPath.get();
 #endif
 
   versionsize = ::GetFileVersionInfoSizeW(lpFilepath, &zerome);
 
   if (versionsize > 0)
-    verbuf = (WCHAR*)PR_Malloc(versionsize);
+    verbuf = PR_Malloc(versionsize);
   if (!verbuf)
     return NS_ERROR_OUT_OF_MEMORY;
 
   if (::GetFileVersionInfoW(lpFilepath, NULL, versionsize, verbuf))
   {
-    info.fName = GetKeyValue(verbuf, L"\\StringFileInfo\\040904E4\\ProductName");
-    info.fDescription = GetKeyValue(verbuf, L"\\StringFileInfo\\040904E4\\FileDescription");
-
-    char *mimeType = GetKeyValue(verbuf, L"\\StringFileInfo\\040904E4\\MIMEType");
-    char *mimeDescription = GetKeyValue(verbuf, L"\\StringFileInfo\\040904E4\\FileOpenName");
-    char *extensions = GetKeyValue(verbuf, L"\\StringFileInfo\\040904E4\\FileExtents");
+    // TODO: get appropriately-localized info from plugin file
+    UINT lang = 1033; // language = English
+    UINT cp = 1252;   // codepage = Western
+    info.fName = GetKeyValue(verbuf, L"ProductName", lang, cp);
+    info.fDescription = GetKeyValue(verbuf, L"FileDescription", lang, cp);
+ 
+    char *mimeType = GetKeyValue(verbuf, L"MIMEType", lang, cp);
+    char *mimeDescription = GetKeyValue(verbuf, L"FileOpenName", lang, cp);
+    char *extensions = GetKeyValue(verbuf, L"FileExtents", lang, cp);
 
     info.fVariantCount = CalculateVariantCount(mimeType);
     info.fMimeTypeArray = MakeStringArray(info.fVariantCount, mimeType);
     info.fMimeDescriptionArray = MakeStringArray(info.fVariantCount, mimeDescription);
     info.fExtensionArray = MakeStringArray(info.fVariantCount, extensions);
     info.fFullPath = PL_strdup(NS_ConvertUTF16toUTF8(fullPath).get());
     info.fFileName = PL_strdup(NS_ConvertUTF16toUTF8(fileName).get());
     info.fVersion = GetVersion(verbuf);