Bug 464194 - ShellExecuteW and SHParseDisplayName do not exist on wince r=bsmedberg
☠☠ backed out by eec0447b4117 ☠ ☠
authorBrad Lassey <blassey@mozilla.com>
Wed, 03 Dec 2008 08:42:03 -0500
changeset 22245 ba0d099c6eb68ee5ade0e4569e12faaeae92931e
parent 22244 652cba7f3f1da4c44db65ce82bd4daa621f2dc43
child 22246 cb109c0b73f09ae5c7cbb6706b8e298d1408b478
child 22264 eec0447b4117577256ab3f078dc5faf12f2affcc
push id3878
push userblassey@mozilla.com
push dateWed, 03 Dec 2008 13:43:58 +0000
treeherdermozilla-central@20a011760de7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg
bugs464194
milestone1.9.2a1pre
Bug 464194 - ShellExecuteW and SHParseDisplayName do not exist on wince r=bsmedberg
uriloader/exthandler/win/nsMIMEInfoWin.cpp
--- a/uriloader/exthandler/win/nsMIMEInfoWin.cpp
+++ b/uriloader/exthandler/win/nsMIMEInfoWin.cpp
@@ -51,16 +51,26 @@
 #include "nsTArray.h"
 #include "shlobj.h"
 #include "windows.h"
 #include "nsIWindowsRegKey.h"
 #include "nsIProcess.h"
 #include "nsOSHelperAppService.h"
 #include "nsUnicharUtils.h"
 
+#ifdef WINCE 
+#ifdef UNICODE
+#define SHELLEXECUTEINFOW SHELLEXECUTEINFO
+#define ShellExecuteExW ShellExecuteEx
+#else
+#error "we don't support narrow char wince"
+#endif
+#endif
+
+
 NS_IMPL_ISUPPORTS_INHERITED1(nsMIMEInfoWin, nsMIMEInfoBase, nsIPropertyBag)
 
 nsMIMEInfoWin::~nsMIMEInfoWin()
 {
 }
 
 nsresult
 nsMIMEInfoWin::LaunchDefaultWithFile(nsIFile* aFile)
@@ -118,46 +128,56 @@ nsMIMEInfoWin::LaunchWithFile(nsIFile* a
 
         // executable is rundll32, everything else is a list of parameters, 
         // including the dll handler.
         nsCOMPtr<nsILocalFile> locFile(do_QueryInterface(aFile));
 
         if (!GetDllLaunchInfo(executable, locFile, args, PR_FALSE))
           return NS_ERROR_INVALID_ARG;
 
-        int result = (int)
-          ::ShellExecuteW(NULL, NULL, L"rundll32.exe", args.get(),
-                          NULL, SW_SHOWNORMAL);
-        // Returns a value greater than 32 if successful. See msdn.
-        if (result > 32)
+        SHELLEXECUTEINFOW seinfo;
+        memset(&seinfo, 0, sizeof(seinfo));
+        seinfo.cbSize = sizeof(SHELLEXECUTEINFOW);
+        seinfo.fMask  = NULL;
+        seinfo.hwnd   = NULL;
+        seinfo.lpVerb = NULL;
+        seinfo.lpFile = L"rundll32.exe";
+        seinfo.lpParameters =  args.get();
+        seinfo.lpDirectory  = NULL;
+        seinfo.nShow  = SW_SHOWNORMAL;
+        if (ShellExecuteExW(&seinfo))
           return NS_OK;
 
-        switch (result) {
+        switch ((int)seinfo.hInstApp) {
           case 0:
           case SE_ERR_OOM:
             return NS_ERROR_OUT_OF_MEMORY;
-          case ERROR_FILE_NOT_FOUND:
-            return NS_ERROR_FILE_NOT_FOUND;
-          case ERROR_PATH_NOT_FOUND:
-            return NS_ERROR_FILE_UNRECOGNIZED_PATH;
-          case ERROR_BAD_FORMAT:
-            return NS_ERROR_FILE_CORRUPTED;
           case SE_ERR_ACCESSDENIED:
             return NS_ERROR_FILE_ACCESS_DENIED;
           case SE_ERR_ASSOCINCOMPLETE:
           case SE_ERR_NOASSOC:
             return NS_ERROR_UNEXPECTED;
           case SE_ERR_DDEBUSY:
           case SE_ERR_DDEFAIL:
           case SE_ERR_DDETIMEOUT:
             return NS_ERROR_NOT_AVAILABLE;
           case SE_ERR_DLLNOTFOUND:
             return NS_ERROR_FAILURE;
           case SE_ERR_SHARE:
             return NS_ERROR_FILE_IS_LOCKED;
+          default:
+            switch(GetLastError()) {
+              case ERROR_FILE_NOT_FOUND:
+                return NS_ERROR_FILE_NOT_FOUND;
+              case ERROR_PATH_NOT_FOUND:
+                return NS_ERROR_FILE_UNRECOGNIZED_PATH;
+              case ERROR_BAD_FORMAT:
+                return NS_ERROR_FILE_CORRUPTED;
+            }
+
         }
         return NS_ERROR_FILE_EXECUTION_FAILED;
       }
     }
     return LaunchWithIProcess(executable, path);
   }
 
   return NS_ERROR_INVALID_ARG;
@@ -223,22 +243,24 @@ nsMIMEInfoWin::GetProperty(const nsAStri
 
     rv = GetIconURLVariant(executable, _retval);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
+#ifndef WINCE
 typedef HRESULT (STDMETHODCALLTYPE *MySHParseDisplayName)
                  (PCWSTR pszName,
                   IBindCtx *pbc,
                   LPITEMIDLIST *ppidl,
                   SFGAOF sfgaoIn,
                   SFGAOF *psfgaoOut);
+#endif
 
 // this implementation was pretty much copied verbatime from 
 // Tony Robinson's code in nsExternalProtocolWin.cpp
 nsresult
 nsMIMEInfoWin::LoadUriInternal(nsIURI * aURL)
 {
   nsresult rv = NS_OK;
 
@@ -257,54 +279,59 @@ nsMIMEInfoWin::LoadUriInternal(nsIURI * 
 
     // Some versions of windows (Win2k before SP3, Win XP before SP1)
     // crash in ShellExecute on long URLs (bug 161357).
     // IE 5 and 6 support URLS of 2083 chars in length, 2K is safe
     const PRUint32 maxSafeURL(2048);
     if (urlSpec.Length() > maxSafeURL)
       return NS_ERROR_FAILURE;
 
+    HMODULE hDll = NULL;
+
+    static const PRUnichar cmdVerb[] = L"open";
+    SHELLEXECUTEINFOW sinfo;
+    memset(&sinfo, 0, sizeof(sinfo));
+    sinfo.cbSize   = sizeof(sinfo);
+#ifdef WINCE
+    sinfo.fMask   = NULL;
+#else
+    sinfo.fMask    = SEE_MASK_FLAG_DDEWAIT |
+                     SEE_MASK_FLAG_NO_UI ;
+#endif
+    sinfo.hwnd     = NULL;
+    sinfo.lpVerb   = (LPWSTR)&cmdVerb;
+    sinfo.nShow    = SW_SHOWNORMAL;
+
+#ifndef WINCE
     LPITEMIDLIST pidl;
     SFGAOF sfgao;
     
     // Bug 394974
-    HMODULE hDll = ::LoadLibraryW(L"shell32.dll");
+    hDll = ::LoadLibraryW(L"shell32.dll");
     MySHParseDisplayName pMySHParseDisplayName = NULL;
     // Version 6.0 and higher
-    if (pMySHParseDisplayName = 
-          (MySHParseDisplayName)::GetProcAddress(hDll,
-                                                 "SHParseDisplayName")) {
-      if (SUCCEEDED(pMySHParseDisplayName(NS_ConvertUTF8toUTF16(urlSpec).get(),
-                                          NULL, &pidl, 0, &sfgao))) {
-        static const PRUnichar cmdVerb[] = L"open";
-        SHELLEXECUTEINFOW sinfo;
-        memset(&sinfo, 0, sizeof(sinfo));
-        sinfo.cbSize   = sizeof(sinfo);
-        sinfo.fMask    = SEE_MASK_FLAG_DDEWAIT |
-                         SEE_MASK_FLAG_NO_UI |
-                         SEE_MASK_INVOKEIDLIST;
-        sinfo.hwnd     = NULL;
-        sinfo.lpVerb   = (LPWSTR)&cmdVerb;
-        sinfo.nShow    = SW_SHOWNORMAL;
+    if ((pMySHParseDisplayName = (MySHParseDisplayName)
+         ::GetProcAddress(hDll, "SHParseDisplayName")) &&
+        (SUCCEEDED(pMySHParseDisplayName(NS_ConvertUTF8toUTF16(urlSpec).get(),
+                                         NULL, &pidl, 0, &sfgao)))) {
         sinfo.lpIDList = pidl;
-        
-        BOOL result = ShellExecuteExW(&sinfo);
-
-        CoTaskMemFree(pidl);
+        sinfo.fMask |= SEE_MASK_INVOKEIDLIST;
+    } else 
+#endif
+    {
+      sinfo.lpFile =  NS_ConvertUTF8toUTF16(urlSpec).get();
+    }
+    BOOL result = ShellExecuteExW(&sinfo);
+    if (!result || ((int)sinfo.hInstApp) < 32)
+      rv = NS_ERROR_FAILURE;
 
-        if (!result || ((int)sinfo.hInstApp) < 32)
-          rv = NS_ERROR_FAILURE;
-      }
-    } else {
-      // Version of shell32.dll < 6.0
-      int r = (int) ::ShellExecuteW(NULL, L"open", NS_ConvertUTF8toUTF16(urlSpec).get(),
-                                    NULL, NULL, SW_SHOWNORMAL);
-      if (r < 32)
-        rv = NS_ERROR_FAILURE;
-    }
+#ifndef WINCE
+    if (pidl)
+      CoTaskMemFree(pidl);
+#endif
     if (hDll) 
       ::FreeLibrary(hDll);
   }
 
   return rv;
 }
 
 // Given a path to a local file, return its nsILocalHandlerApp instance.