Bug 513742: Remove support for DDE from toolkit. r=jimm
☠☠ backed out by 3d8dd3615c45 ☠ ☠
authorDave Townsend <dtownsend@oxymoronical.com>
Tue, 22 Jan 2019 14:48:43 -0800
changeset 520630 4ef3cc37f719d02443a2058192fdb4c61d3e3dca
parent 520629 276ca640adc8ff16ff3ff7252e8aa5016205b1e0
child 520631 84e8066625fd72fdb1eb6eab85621ae842fe91b4
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs513742
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 513742: Remove support for DDE from toolkit. r=jimm Differential Revision: https://phabricator.services.mozilla.com/D19075
toolkit/xre/nsAppRunner.cpp
toolkit/xre/nsINativeAppSupport.idl
toolkit/xre/nsNativeAppSupportBase.cpp
toolkit/xre/nsNativeAppSupportUnix.cpp
toolkit/xre/nsNativeAppSupportWin.cpp
toolkit/xre/nsNativeAppSupportWin.h
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -420,80 +420,16 @@ static ArgResult CheckArg(const char* aA
  * Will not remove flag if found.
  *
  * @param aArg the parameter to check. Must be lowercase.
  */
 static ArgResult CheckArgExists(const char* aArg) {
   return CheckArg(aArg, nullptr, CheckArgFlag::None);
 }
 
-#if defined(XP_WIN)
-/**
- * Check for a commandline flag from the windows shell and remove it from the
- * argv used when restarting. Flags MUST be in the form -arg.
- *
- * @param aArg the parameter to check. Must be lowercase.
- */
-static ArgResult CheckArgShell(const char* aArg) {
-  char** curarg = gRestartArgv + 1;  // skip argv[0]
-
-  while (*curarg) {
-    char* arg = curarg[0];
-
-    if (arg[0] == '-') {
-      ++arg;
-
-      if (strimatch(aArg, arg)) {
-        do {
-          *curarg = *(curarg + 1);
-          ++curarg;
-        } while (*curarg);
-
-        --gRestartArgc;
-
-        return ARG_FOUND;
-      }
-    }
-
-    ++curarg;
-  }
-
-  return ARG_NONE;
-}
-
-/**
- * Enabled Native App Support to process DDE messages when the app needs to
- * restart and the app has been launched by the Windows shell to open an url.
- * When aWait is false this will process the DDE events manually. This prevents
- * Windows from displaying an error message due to the DDE message not being
- * acknowledged.
- */
-static void ProcessDDE(nsINativeAppSupport* aNative, bool aWait) {
-  // When the app is launched by the windows shell the windows shell
-  // expects the app to be available for DDE messages and if it isn't
-  // windows displays an error dialog. To prevent the error the DDE server
-  // is enabled and pending events are processed when the app needs to
-  // restart after it was launched by the shell with the requestpending
-  // argument. The requestpending pending argument is removed to
-  // differentiate it from being launched when an app restart is not
-  // required.
-  ArgResult ar;
-  ar = CheckArgShell("requestpending");
-  if (ar == ARG_FOUND) {
-    aNative->Enable();  // enable win32 DDE responses
-    if (aWait) {
-      // This is just a guesstimate based on testing different values.
-      // If count is 8 or less windows will display an error dialog.
-      int32_t count = 20;
-      SpinEventLoopUntil([&]() { return --count < 0; });
-    }
-  }
-}
-#endif
-
 bool gSafeMode = false;
 
 /**
  * The nsXULAppInfo object implements nsIFactory so that it can be its own
  * singleton.
  */
 class nsXULAppInfo : public nsIXULAppInfo,
                      public nsIObserver,
@@ -1639,17 +1575,17 @@ static void SetupLauncherProcessPref() {
 
 #endif  // XP_WIN
 
 // If aBlankCommandLine is true, then the application will be launched with a
 // blank command line instead of being launched with the same command line that
 // it was initially started with.
 static nsresult LaunchChild(nsINativeAppSupport* aNative,
                             bool aBlankCommandLine = false) {
-  aNative->Quit();  // release DDE mutex, if we're holding it
+  aNative->Quit();  // destroy message window
 
   // Restart this process by exec'ing it into the current process
   // if supported by the platform.  Otherwise, use NSPR.
 
 #ifdef MOZ_JPROF
   // make sure JPROF doesn't think we're E10s
   unsetenv("JPROF_SLAVE");
 #endif
@@ -1908,22 +1844,16 @@ static ReturnAbortOnError ShowProfileMan
     rv = xpcom.SetWindowCreator(aNative);
     NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
 
 #ifdef XP_MACOSX
     CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv,
                                                true);
 #endif
 
-#ifdef XP_WIN
-    // we don't have to wait here because profile manager window will pump
-    // and DDE message will be handled
-    ProcessDDE(aNative, false);
-#endif
-
     {  // extra scoping is needed so we release these components before xpcom
        // shutdown
       nsCOMPtr<nsIWindowWatcher> windowWatcher(
           do_GetService(NS_WINDOWWATCHER_CONTRACTID));
       nsCOMPtr<nsIDialogParamBlock> ioParamBlock(
           do_CreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID));
       nsCOMPtr<nsIMutableArray> dlgArray(
           do_CreateInstance(NS_ARRAY_CONTRACTID));
--- a/toolkit/xre/nsINativeAppSupport.idl
+++ b/toolkit/xre/nsINativeAppSupport.idl
@@ -3,20 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  
 #include "nsISupports.idl"
 
 /* nsINativeAppSupport
  *
  * This "pseudo" (in the XPCOM sense) interface provides for
- * platform-specific general application support:
- *  o It manages the details of the simple DDE communication 
- *    supported on the Win32 platform (it is the addition of this 
- *    item that prompted the creation of this interface.
+ * platform-specific general application support
  *
  * Due to the nature of the beast, this interface is not a full-blown
  * XPCOM component.  The primary reason is that objects that implement
  * this interface generally must be operational *before* XPCOM (or any
  * of the rest of Mozilla) are initialized.  As a result, this 
  * interface is instantiated by somewhat unconventional means.
  *
  * To create the implementor of this interface, you call the function
@@ -34,70 +31,28 @@
  *          such cases, the returned nsresult indicates whether the
  *          reason to exit is due to an error or not.
  *
  *          Win32 Note: In the case of starting a second instance
  *                      of this executable, this function will return
  *                      PR_FALSE and nsresult==NS_OK.  This means that
  *                      the command line arguments have been
  *                      successfully passed to the instance of the
- *                      application acting as a DDE server.
- *
- *  stop - You call this to inform the native app support that the
- *         application *wishes* to terminate.  If the returned boolean
- *         value is PR_FALSE, then the application should continue
- *         (as if there were still additional top-level windows open).
- *         
- *         Win32 Note: If this is the instance of the application
- *                     acting as the DDE server, and there are current
- *                     DDE conversations active with other instances
- *                     acting as DDE clients, then this function will
- *                     return PR_FALSE.
- * 
- *  quit - Like Stop, but this method *forces* termination (or more 
- *         precisely, indicates that the application is about to be
- *         terminated regardless of what a call to Stop might have
- *         returned.
- *
- *         This method is intended to be called when the user selects
- *         the "Quit" option (close all windows and exit).
- *
- *         Win32 Note: Stop is problematic in the case of "Quit" (close
- *                     all windows and exit the application) because
- *                     either we don't Quit or (potentially) we lose
- *                     requests coming from other instances of the
- *                     application.  The strategy is to give preference
- *                     to the user's explicit Quit request.  In the
- *                     unlikely event that a request is pending from
- *                     another instance of the application, then such
- *                     requests are essentially ignored.  This is
- *                     roughly equivalent to handling that request by
- *                     opening a new window, followed by immediately
- *                     closing it.  Since this is the same as if the
- *                     request came in immediately before the Quit
- *                     call (versus immediately after it), no harm.
- *
- *                     There is an exposure here: Upon return from this
- *                     function, any DDE connect request (for Mozilla)
- *                     will fail and other instances of the application
- *                     will start up as a DDE server.  In that case,
- *                     those instances may do things that conflict with
- *                     the subsequent shutting down of the instance that
- *                     is quitting.  For this reason, the call to Quit
- *                     should be deferred as long as possible.
+ *                      application acting as a remote server.
+ *  quit - Informs the native app support that the application is stopping. The
+ *         app support should disable any functionality enabled by start.
  *
  *  onLastWindowClosing -  Called when the last window is closed. Used as a
  *                         "soft" shutdown, passwords are flushed.
  */
 
 interface nsIXULWindow;
 
 [scriptable, uuid(5fdf8480-1f98-11d4-8077-00600811a9c3)]
 interface nsINativeAppSupport : nsISupports {
     // Startup/shutdown.
     boolean start();
     void    enable();
-    boolean stop();
     void    quit();
 
     void onLastWindowClosing();
     void ReOpen();
 };
--- a/toolkit/xre/nsNativeAppSupportBase.cpp
+++ b/toolkit/xre/nsNativeAppSupportBase.cpp
@@ -16,23 +16,16 @@ NS_IMETHODIMP
 nsNativeAppSupportBase::Start(bool *result) {
   *result = true;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNativeAppSupportBase::Enable() { return NS_OK; }
 
-// Stop answer defaults to OK.
-NS_IMETHODIMP
-nsNativeAppSupportBase::Stop(bool *result) {
-  *result = true;
-  return NS_OK;
-}
-
 NS_IMETHODIMP
 nsNativeAppSupportBase::Quit() { return NS_OK; }
 
 NS_IMETHODIMP
 nsNativeAppSupportBase::ReOpen() { return NS_OK; }
 
 NS_IMETHODIMP
 nsNativeAppSupportBase::OnLastWindowClosing() { return NS_OK; }
--- a/toolkit/xre/nsNativeAppSupportUnix.cpp
+++ b/toolkit/xre/nsNativeAppSupportUnix.cpp
@@ -130,17 +130,16 @@ class nsNativeAppSupportUnix : public ns
     // this goes out of scope after "web-workers-shutdown" async shutdown phase
     // so it's safe to disconnect here (i.e. the application won't lose data)
     DisconnectFromSM();
   };
 
   void DisconnectFromSM();
 #endif
   NS_IMETHOD Start(bool *aRetVal) override;
-  NS_IMETHOD Stop(bool *aResult) override;
   NS_IMETHOD Enable() override;
 
  private:
 #if MOZ_X11
   static void SaveYourselfCB(SmcConn smc_conn, SmPointer client_data,
                              int save_style, Bool shutdown, int interact_style,
                              Bool fast);
   static void DieCB(SmcConn smc_conn, SmPointer client_data);
@@ -647,23 +646,16 @@ nsNativeAppSupportUnix::Start(bool *aRet
 
   g_free(client_id);
 #endif /* MOZ_X11 */
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
-nsNativeAppSupportUnix::Stop(bool *aResult) {
-  NS_ENSURE_ARG(aResult);
-  *aResult = true;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsNativeAppSupportUnix::Enable() { return NS_OK; }
 
 nsresult NS_CreateNativeAppSupport(nsINativeAppSupport **aResult) {
   nsNativeAppSupportBase *native = new nsNativeAppSupportUnix();
   if (!native) return NS_ERROR_OUT_OF_MEMORY;
 
   *aResult = native;
   NS_ADDREF(*aResult);
--- a/toolkit/xre/nsNativeAppSupportWin.cpp
+++ b/toolkit/xre/nsNativeAppSupportWin.cpp
@@ -39,17 +39,16 @@
 #include "nsIWindowMediator.h"
 #include "nsNativeCharsetUtils.h"
 #include "nsIAppStartup.h"
 #include "mozilla/Assertions.h"
 #include "mozilla/dom/Location.h"
 
 #include <windows.h>
 #include <shellapi.h>
-#include <ddeml.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <io.h>
 #include <direct.h>
 #include <fcntl.h>
 
 using namespace mozilla;
 
@@ -62,268 +61,85 @@ static nsresult GetMostRecentWindow(cons
       do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv));
   if (NS_FAILED(rv)) return rv;
 
   if (med) return med->GetMostRecentWindow(aType, aWindow);
 
   return NS_ERROR_FAILURE;
 }
 
-static void activateWindow(mozIDOMWindowProxy *win) {
-  // Try to get native window handle.
-  HWND hwnd = hwndForDOMWindow(win);
-  if (hwnd) {
-    // Restore the window if it is minimized.
-    if (::IsIconic(hwnd)) {
-      ::ShowWindow(hwnd, SW_RESTORE);
-    }
-    // Use the OS call, if possible.
-    ::SetForegroundWindow(hwnd);
-  } else {
-    // Use internal method.
-    nsCOMPtr<nsPIDOMWindowOuter> piWin = nsPIDOMWindowOuter::From(win);
-    piWin->Focus();
-  }
-}
-
-#ifdef DEBUG_law
-#  undef MOZ_DEBUG_DDE
-#  define MOZ_DEBUG_DDE 1
-#endif
-
 // Simple Win32 mutex wrapper.
 struct Win32Mutex {
   explicit Win32Mutex(const char16_t *name)
       : mName(name), mHandle(0), mState(-1) {
     mHandle = CreateMutexW(0, FALSE, mName.get());
-#if MOZ_DEBUG_DDE
-    printf("CreateMutex error = 0x%08X\n", (int)GetLastError());
-#endif
   }
   ~Win32Mutex() {
     if (mHandle) {
       // Make sure we release it if we own it.
       Unlock();
 
       BOOL rc MOZ_MAYBE_UNUSED = CloseHandle(mHandle);
-#if MOZ_DEBUG_DDE
-      if (!rc) {
-        printf("CloseHandle error = 0x%08X\n", (int)GetLastError());
-      }
-#endif
     }
   }
   BOOL Lock(DWORD timeout) {
     if (mHandle) {
-#if MOZ_DEBUG_DDE
-      printf("Waiting (%d msec) for DDE mutex...\n", (int)timeout);
-#endif
       mState = WaitForSingleObject(mHandle, timeout);
-#if MOZ_DEBUG_DDE
-      printf("...wait complete, result = 0x%08X, GetLastError=0x%08X\n",
-             (int)mState, (int)::GetLastError());
-#endif
       return mState == WAIT_OBJECT_0 || mState == WAIT_ABANDONED;
     } else {
       return FALSE;
     }
   }
   void Unlock() {
     if (mHandle && mState == WAIT_OBJECT_0) {
-#if MOZ_DEBUG_DDE
-      printf("Releasing DDE mutex\n");
-#endif
       ReleaseMutex(mHandle);
       mState = -1;
     }
   }
 
  private:
   nsString mName;
   HANDLE mHandle;
   DWORD mState;
 };
 
-/* DDE Notes
- *
- * This section describes the Win32 DDE service implementation for
- * Mozilla.  DDE is used on Win32 platforms to communicate between
- * separate instances of mozilla.exe (or other Mozilla-based
- * executables), or, between the Win32 desktop shell and Mozilla.
- *
- * The first instance of Mozilla will become the "server" and
- * subsequent executables (and the shell) will use DDE to send
- * requests to that process.  The requests are DDE "execute" requests
- * that pass the command line arguments.
- *
- * Mozilla registers the DDE application "Mozilla" and currently
- * supports only the "WWW_OpenURL" topic.  This should be reasonably
- * compatible with applications that interfaced with Netscape
- * Communicator (and its predecessors?).  Note that even that topic
- * may not be supported in a compatible fashion as the command-line
- * options for Mozilla are different than for Communiator.
- *
- * It is imperative that at most one instance of Mozilla execute in
- * "server mode" at any one time.  The "native app support" in Mozilla
- * on Win32 ensures that only the server process performs XPCOM
- * initialization (that is not required for subsequent client processes
- * to communicate with the server process).
- *
- * To guarantee that only one server starts up, a Win32 "mutex" is used
- * to ensure only one process executes the server-detection code.  That
- * code consists of initializing DDE and doing a DdeConnect to Mozilla's
- * application/topic.  If that connection succeeds, then a server process
- * must be running already.
- *
- * Otherwise, no server has started.  In that case, the current process
- * calls DdeNameService to register that application/topic.  Only at that
- * point does the mutex get released.
- *
- * There are a couple of subtleties that one should be aware of:
- *
- * 1. It is imperative that DdeInitialize be called only after the mutex
- *    lock has been obtained.  The reason is that at shutdown, DDE
- *    notifications go out to all initialized DDE processes.  Thus, if
- *    the mutex is owned by a terminating intance of Mozilla, then
- *    calling DdeInitialize and then WaitForSingleObject will cause the
- *    DdeUninitialize from the terminating process to "hang" until the
- *    process waiting for the mutex times out (and can then service the
- *    notification that the DDE server is terminating).  So, don't mess
- *    with the sequence of things in the startup/shutdown logic.
- *
- * 2. All mutex requests are made with a reasonably long timeout value and
- *    are designed to "fail safe" (i.e., a timeout is treated as failure).
- *
- * 3. An attempt has been made to minimize the degree to which the main
- *    Mozilla application logic needs to be aware of the DDE mechanisms
- *    implemented herein.  As a result, this module surfaces a very
- *    large-grained interface, consisting of simple start/stop methods.
- *    As a consequence, details of certain scenarios can be "lost."
- *    Particularly, incoming DDE requests can arrive after this module
- *    initiates the DDE server, but before Mozilla is initialized to the
- *    point where those requests can be serviced (e.g., open a browser
- *    window to a particular URL).  Since the client process sends the
- *    request early on, it may not be prepared to respond to that error.
- *    Thus, such situations may fail silently.  The design goal is that
- *    they fail harmlessly.  Refinements on this point will be made as
- *    details emerge (and time permits).
- */
+class MessageWindow;
 
-/* Update 2001 March
- *
- * A significant DDE bug in Windows is causing Mozilla to get wedged at
- * startup.  This is detailed in Bugzill bug 53952
- * (http://bugzilla.mozilla.org/show_bug.cgi?id=53952).
- *
- * To resolve this, we are using a new strategy:
- *   o Use a "message window" to detect that Mozilla is already running and
- *     to pass requests from a second instance back to the first;
- *   o Run only as a "DDE server" (not as DDE client); this avoids the
- *     problematic call to DDEConnect().
- *
- * We still use the mutex semaphore to protect the code that detects
- * whether Mozilla is already running.
- */
-
-/* Update 2007 January
- *
- * A change in behavior was implemented in July 2004 which made the
- * application on launch to add and on quit to remove the ddexec registry key.
- * See bug 246078.
- * Windows Vista has changed the methods used to set an application as default
- * and the new methods are incompatible with removing the ddeexec registry key.
- * See bug 353089.
- *
- * OS DDE Sequence:
- * 1. OS checks if the dde name is registered.
- * 2. If it is registered the OS sends a DDE request with the WWW_OpenURL topic
- *    and the params as specified in the default value of the ddeexec registry
- *    key for the verb (e.g. open).
- * 3. If it isn't registered the OS launches the executable defined in the
- *    verb's (e.g. open) command registry key.
- * 4. If the ifexec registry key is not present the OS sends a DDE request with
- *    the WWW_OpenURL topic and the params as specified in the default value of
- *    the ddeexec registry key for the verb (e.g. open).
- * 5. If the ifexec registry key is present the OS sends a DDE request with the
- *    WWW_OpenURL topic and the params as specified in the ifexec registry key
- *    for the verb (e.g. open).
- *
- * Application DDE Sequence:
- * 1. If the application is running a DDE request is received with the
- *    WWW_OpenURL topic and the params as specified in the default value of the
- *    ddeexec registry key (e.g. "%1",,0,0,,,, where '%1' is the url to open)
- *    for the verb (e.g. open).
- * 2. If the application is not running it is launched with the --requestPending
- *    and the --url argument.
- * 2.1  If the application does not need to restart and the --requestPending
- *      argument is present the accompanying url will not be used. Instead the
- *      application will wait for the DDE message to open the url.
- * 2.2  If the application needs to restart the --requestPending argument is
- *      removed from the arguments used to restart the application and the url
- *      will be handled normally.
- *
- * Note: Due to a bug in IE the ifexec key should not be used (see bug 355650).
+/*
+ * This code implements remoting a command line to an existing instance. It uses
+ * a "message window" to detect that Mozilla is already running and to pass
+ * the command line of a new instance to the already running instance.
+ * We use the mutex semaphore to protect the code that detects whether Mozilla
+ * is already running.
  */
 
 class nsNativeAppSupportWin : public nsNativeAppSupportBase,
                               public nsIObserver {
  public:
   NS_DECL_NSIOBSERVER
   NS_DECL_ISUPPORTS_INHERITED
 
   // Overrides of base implementation.
   NS_IMETHOD Start(bool *aResult) override;
-  NS_IMETHOD Stop(bool *aResult) override;
   NS_IMETHOD Quit() override;
   NS_IMETHOD Enable() override;
-  // The "old" Start method (renamed).
-  NS_IMETHOD StartDDE();
   // Utility function to handle a Win32-specific command line
   // option: "--console", which dynamically creates a Windows
   // console.
   void CheckConsole();
 
  private:
   ~nsNativeAppSupportWin() {}
   static void HandleCommandLine(const char *aCmdLineString,
                                 nsIFile *aWorkingDir, uint32_t aState);
-  static HDDEDATA CALLBACK HandleDDENotification(UINT uType, UINT uFmt,
-                                                 HCONV hconv, HSZ hsz1,
-                                                 HSZ hsz2, HDDEDATA hdata,
-                                                 ULONG_PTR dwData1,
-                                                 ULONG_PTR dwData2);
-  static void ParseDDEArg(HSZ args, int index, nsString &string);
-  static void ParseDDEArg(const WCHAR *args, int index, nsString &aString);
-  static HDDEDATA CreateDDEData(DWORD value);
-  static HDDEDATA CreateDDEData(LPBYTE value, DWORD len);
-  static bool InitTopicStrings();
-  static int FindTopic(HSZ topic);
-  static void ActivateLastWindow();
-  static nsresult OpenWindow(const char *urlstr, const char *args);
-  static nsresult OpenBrowserWindow();
-  static void SetupSysTrayIcon();
-  static void RemoveSysTrayIcon();
 
-  static int mConversations;
-  enum {
-    topicOpenURL,
-    topicActivate,
-    topicCancelProgress,
-    topicVersion,
-    topicRegisterViewer,
-    topicUnRegisterViewer,
-    topicGetWindowInfo,
-    // Note: Insert new values above this line!!!!!
-    topicCount  // Count of the number of real topics
-  };
-  static HSZ mApplication, mTopics[topicCount];
-  static DWORD mInstance;
   static bool mCanHandleRequests;
   static char16_t mMutexName[];
-  friend struct MessageWindow;
+  friend class MessageWindow;
+  static MessageWindow *mMsgWindow;
 };  // nsNativeAppSupportWin
 
 NS_INTERFACE_MAP_BEGIN(nsNativeAppSupportWin)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
 NS_INTERFACE_MAP_END_INHERITING(nsNativeAppSupportBase)
 
 NS_IMPL_ADDREF_INHERITED(nsNativeAppSupportWin, nsNativeAppSupportBase)
 NS_IMPL_RELEASE_INHERITED(nsNativeAppSupportWin, nsNativeAppSupportBase)
@@ -386,48 +202,38 @@ nsresult NS_CreateNativeAppSupport(nsINa
 
   *aResult = pNative;
   NS_ADDREF(*aResult);
 
   return NS_OK;
 }
 
 // Constants
-#define MOZ_DDE_APPLICATION "Mozilla"
 #define MOZ_MUTEX_NAMESPACE L"Local\\"
 #define MOZ_STARTUP_MUTEX_NAME L"StartupMutex"
-#define MOZ_DDE_START_TIMEOUT 30000
-#define MOZ_DDE_STOP_TIMEOUT 15000
-#define MOZ_DDE_EXEC_TIMEOUT 15000
-
-// The array entries must match the enum ordering!
-const char *const topicNames[] = {"WWW_OpenURL",        "WWW_Activate",
-                                  "WWW_CancelProgress", "WWW_Version",
-                                  "WWW_RegisterViewer", "WWW_UnRegisterViewer",
-                                  "WWW_GetWindowInfo"};
+#define MOZ_MUTEX_START_TIMEOUT 30000
 
 // Static member definitions.
-int nsNativeAppSupportWin::mConversations = 0;
-HSZ nsNativeAppSupportWin::mApplication = 0;
-HSZ nsNativeAppSupportWin::mTopics[nsNativeAppSupportWin::topicCount] = {0};
-DWORD nsNativeAppSupportWin::mInstance = 0;
+char16_t nsNativeAppSupportWin::mMutexName[128] = {0};
 bool nsNativeAppSupportWin::mCanHandleRequests = false;
-
-char16_t nsNativeAppSupportWin::mMutexName[128] = {0};
+MessageWindow *nsNativeAppSupportWin::mMsgWindow = nullptr;
 
 // Message window encapsulation.
-struct MessageWindow {
+class MessageWindow final {
+ public:
   // ctor/dtor are simplistic
   MessageWindow() {
     // Try to find window.
     mHandle = ::FindWindowW(className(), 0);
   }
 
+  ~MessageWindow() = default;
+
   // Act like an HWND.
-  operator HWND() { return mHandle; }
+  HWND handle() { return mHandle; }
 
   // Class name: appName + "MessageWindow"
   static const wchar_t *className() {
     static wchar_t classNameBuffer[128];
     static wchar_t *mClassName = 0;
     if (!mClassName) {
       ::_snwprintf(classNameBuffer,
                    128,  // size of classNameBuffer in PRUnichars
@@ -462,20 +268,16 @@ struct MessageWindow {
                                               WS_CAPTION,  // style
                                               0, 0, 0, 0,  // x, y, cx, cy
                                               0,           // parent
                                               0,           // menu
                                               0,           // instance
                                               0)),         // create struct
                    NS_ERROR_FAILURE);
 
-#if MOZ_DEBUG_DDE
-    printf("Message window = 0x%08X\n", (int)mHandle);
-#endif
-
     return NS_OK;
   }
 
   // Destory:  Get rid of window and reset mHandle.
   NS_IMETHOD Destroy() {
     nsresult retval = NS_OK;
 
     if (mHandle) {
@@ -519,67 +321,59 @@ struct MessageWindow {
   // Window proc.
   static LRESULT CALLBACK WindowProc(HWND msgWindow, UINT msg, WPARAM wp,
                                      LPARAM lp) {
     if (msg == WM_COPYDATA) {
       if (!nsNativeAppSupportWin::mCanHandleRequests) return FALSE;
 
       // This is an incoming request.
       COPYDATASTRUCT *cds = (COPYDATASTRUCT *)lp;
-#if MOZ_DEBUG_DDE
-      printf("Incoming request: %s\n", (const char *)cds->lpData);
-#endif
       nsCOMPtr<nsIFile> workingDir;
 
       if (1 >= cds->dwData) {
         char *wdpath = (char *)cds->lpData;
         // skip the command line, and get the working dir of the
         // other process, which is after the first null char
         while (*wdpath) ++wdpath;
 
         ++wdpath;
 
-#ifdef MOZ_DEBUG_DDE
-        printf("Working dir: %s\n", wdpath);
-#endif
-
         NS_NewLocalFile(NS_ConvertUTF8toUTF16(wdpath), false,
                         getter_AddRefs(workingDir));
       }
       (void)nsNativeAppSupportWin::HandleCommandLine(
           (char *)cds->lpData, workingDir, nsICommandLine::STATE_REMOTE_AUTO);
 
       // Get current window and return its window handle.
       nsCOMPtr<mozIDOMWindowProxy> win;
       GetMostRecentWindow(0, getter_AddRefs(win));
       return win ? (LRESULT)hwndForDOMWindow(win) : 0;
     }
     return DefWindowProc(msgWindow, msg, wp, lp);
   }
 
  private:
   HWND mHandle;
-};  // struct MessageWindow
+};  // class MessageWindow
 
 /* Start: Tries to find the "message window" to determine if it
  *        exists.  If so, then Mozilla is already running.  In that
  *        case, we use the handle to the "message" window and send
  *        a request corresponding to this process's command line
  *        options.
  *
  *        If not, then this is the first instance of Mozilla.  In
  *        that case, we create and set up the message window.
  *
  *        The checking for existence of the message window must
  *        be protected by use of a mutex semaphore.
  */
 NS_IMETHODIMP
 nsNativeAppSupportWin::Start(bool *aResult) {
   NS_ENSURE_ARG(aResult);
-  NS_ENSURE_TRUE(mInstance == 0, NS_ERROR_NOT_INITIALIZED);
   NS_ENSURE_STATE(gAppData);
 
   if (getenv("MOZ_NO_REMOTE")) {
     *aResult = true;
     return NS_OK;
   }
 
   nsresult rv = NS_ERROR_FAILURE;
@@ -590,174 +384,64 @@ nsNativeAppSupportWin::Start(bool *aResu
   // Build mutex name from app name.
   ::_snwprintf(
       reinterpret_cast<wchar_t *>(mMutexName),
       sizeof mMutexName / sizeof(char16_t), L"%s%s%s", MOZ_MUTEX_NAMESPACE,
       static_cast<const wchar_t *>(NS_ConvertUTF8toUTF16(gAppData->name).get()),
       MOZ_STARTUP_MUTEX_NAME);
   Win32Mutex startupLock = Win32Mutex(mMutexName);
 
-  NS_ENSURE_TRUE(startupLock.Lock(MOZ_DDE_START_TIMEOUT), NS_ERROR_FAILURE);
+  NS_ENSURE_TRUE(startupLock.Lock(MOZ_MUTEX_START_TIMEOUT), NS_ERROR_FAILURE);
 
   // Search for existing message window.
-  MessageWindow msgWindow;
-  if ((HWND)msgWindow) {
+  mMsgWindow = new MessageWindow();
+  if (mMsgWindow->handle()) {
     // We are a client process.  Pass request to message window.
-    rv = msgWindow.SendRequest();
+    rv = mMsgWindow->SendRequest();
   } else {
     // We will be server.
-    rv = msgWindow.Create();
+    rv = mMsgWindow->Create();
     if (NS_SUCCEEDED(rv)) {
-      // Start up DDE server.
-      this->StartDDE();
       // Tell caller to spin message loop.
       *aResult = true;
     }
   }
 
   startupLock.Unlock();
 
   return rv;
 }
 
-bool nsNativeAppSupportWin::InitTopicStrings() {
-  for (int i = 0; i < topicCount; i++) {
-    if (!(mTopics[i] = DdeCreateStringHandleA(
-              mInstance, const_cast<char *>(topicNames[i]), CP_WINANSI))) {
-      return false;
-    }
-  }
-  return true;
-}
-
-int nsNativeAppSupportWin::FindTopic(HSZ topic) {
-  for (int i = 0; i < topicCount; i++) {
-    if (DdeCmpStringHandles(topic, mTopics[i]) == 0) {
-      return i;
-    }
-  }
-  return -1;
-}
-
-// Start DDE server.
-//
-// This used to be the Start() method when we were using DDE as the
-// primary IPC mechanism between secondary Mozilla processes and the
-// initial "server" process.
-//
-// Now, it simply initializes the DDE server.  The caller must check
-// that this process is to be the server, and, must acquire the DDE
-// startup mutex semaphore prior to calling this routine.  See ::Start(),
-// above.
-NS_IMETHODIMP
-nsNativeAppSupportWin::StartDDE() {
-  NS_ENSURE_TRUE(mInstance == 0, NS_ERROR_NOT_INITIALIZED);
-
-  // Initialize DDE.
-  NS_ENSURE_TRUE(DMLERR_NO_ERROR ==
-                     DdeInitialize(&mInstance,
-                                   nsNativeAppSupportWin::HandleDDENotification,
-                                   APPCLASS_STANDARD, 0),
-                 NS_ERROR_FAILURE);
-
-  // Allocate DDE strings.
-  NS_ENSURE_TRUE(
-      (mApplication = DdeCreateStringHandleA(
-           mInstance, (char *)(const char *)gAppData->name, CP_WINANSI)) &&
-          InitTopicStrings(),
-      NS_ERROR_FAILURE);
-
-  // Next step is to register a DDE service.
-  NS_ENSURE_TRUE(DdeNameService(mInstance, mApplication, 0, DNS_REGISTER),
-                 NS_ERROR_FAILURE);
-
-#if MOZ_DEBUG_DDE
-  printf("DDE server started\n");
-#endif
-
-  return NS_OK;
-}
-
-// If no DDE conversations are pending, terminate DDE.
-NS_IMETHODIMP
-nsNativeAppSupportWin::Stop(bool *aResult) {
-  NS_ENSURE_ARG(aResult);
-  NS_ENSURE_TRUE(mInstance, NS_ERROR_NOT_INITIALIZED);
-
-  nsresult rv = NS_OK;
-  *aResult = true;
-
-  Win32Mutex ddeLock(mMutexName);
-
-  if (ddeLock.Lock(MOZ_DDE_STOP_TIMEOUT)) {
-    if (mConversations == 0) {
-      this->Quit();
-    } else {
-      *aResult = false;
-    }
-
-    ddeLock.Unlock();
-  } else {
-    // No DDE application name specified, but that's OK.  Just
-    // forge ahead.
-    *aResult = true;
-  }
-
-  return rv;
-}
-
 NS_IMETHODIMP
 nsNativeAppSupportWin::Observe(nsISupports *aSubject, const char *aTopic,
                                const char16_t *aData) {
   if (strcmp(aTopic, "quit-application") == 0) {
     Quit();
   } else {
     NS_ERROR("Unexpected observer topic.");
   }
 
   return NS_OK;
 }
 
-// Terminate DDE regardless.
 NS_IMETHODIMP
 nsNativeAppSupportWin::Quit() {
+  if (!mMsgWindow) {
+    return NS_OK;
+  }
+
   // If another process wants to look for the message window, they need
   // to wait to hold the lock, in which case they will not find the
   // window as we will destroy ours under our lock.
   // When the mutex goes off the stack, it is unlocked via destructor.
   Win32Mutex mutexLock(mMutexName);
-  NS_ENSURE_TRUE(mutexLock.Lock(MOZ_DDE_START_TIMEOUT), NS_ERROR_FAILURE);
-
-  // If we've got a message window to receive IPC or new window requests,
-  // get rid of it as we are shutting down.
-  // Note:  Destroy calls DestroyWindow, which will only work on a window
-  //  created by the same thread.
-  MessageWindow mw;
-  mw.Destroy();
+  NS_ENSURE_TRUE(mutexLock.Lock(MOZ_MUTEX_START_TIMEOUT), NS_ERROR_FAILURE);
 
-  if (mInstance) {
-    // Unregister application name.
-    DdeNameService(mInstance, mApplication, 0, DNS_UNREGISTER);
-    // Clean up strings.
-    if (mApplication) {
-      DdeFreeStringHandle(mInstance, mApplication);
-      mApplication = 0;
-    }
-    for (int i = 0; i < topicCount; i++) {
-      if (mTopics[i]) {
-        DdeFreeStringHandle(mInstance, mTopics[i]);
-        mTopics[i] = 0;
-      }
-    }
-    DdeUninitialize(mInstance);
-    mInstance = 0;
-#if MOZ_DEBUG_DDE
-    printf("DDE server stopped\n");
-#endif
-  }
+  mMsgWindow->Destroy();
+  delete mMsgWindow;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNativeAppSupportWin::Enable() {
   mCanHandleRequests = true;
 
@@ -766,429 +450,16 @@ nsNativeAppSupportWin::Enable() {
     obs->AddObserver(this, "quit-application", false);
   } else {
     NS_ERROR("No observer service?");
   }
 
   return NS_OK;
 }
 
-#if MOZ_DEBUG_DDE
-// Macro to generate case statement for a given XTYP value.
-#  define XTYP_CASE(t) \
-    case t:            \
-      result = #t;     \
-      break
-
-static nsCString uTypeDesc(UINT uType) {
-  nsCString result;
-  switch (uType) {
-    XTYP_CASE(XTYP_ADVSTART);
-    XTYP_CASE(XTYP_CONNECT);
-    XTYP_CASE(XTYP_ADVREQ);
-    XTYP_CASE(XTYP_REQUEST);
-    XTYP_CASE(XTYP_WILDCONNECT);
-    XTYP_CASE(XTYP_ADVDATA);
-    XTYP_CASE(XTYP_EXECUTE);
-    XTYP_CASE(XTYP_POKE);
-    XTYP_CASE(XTYP_ADVSTOP);
-    XTYP_CASE(XTYP_CONNECT_CONFIRM);
-    XTYP_CASE(XTYP_DISCONNECT);
-    XTYP_CASE(XTYP_ERROR);
-    XTYP_CASE(XTYP_MONITOR);
-    XTYP_CASE(XTYP_REGISTER);
-    XTYP_CASE(XTYP_XACT_COMPLETE);
-    XTYP_CASE(XTYP_UNREGISTER);
-    default:
-      result = "XTYP_?????";
-  }
-  return result;
-}
-
-static nsCString hszValue(DWORD instance, HSZ hsz) {
-  // Extract string from HSZ.
-  nsCString result("[");
-  DWORD len = DdeQueryString(instance, hsz, nullptr, nullptr, CP_WINANSI);
-  if (len) {
-    char buffer[256];
-    DdeQueryString(instance, hsz, buffer, sizeof buffer, CP_WINANSI);
-    result += buffer;
-  }
-  result += "]";
-  return result;
-}
-#endif
-
-// Utility function to escape double-quotes within a string.
-static void escapeQuotes(nsAString &aString) {
-  int32_t offset = -1;
-  while (1) {
-    // Find next '"'.
-    offset = aString.FindChar('"', ++offset);
-    if (offset == kNotFound) {
-      // No more quotes, exit.
-      break;
-    } else {
-      // Insert back-slash ahead of the '"'.
-      aString.Insert(char16_t('\\'), offset);
-      // Increment offset because we just inserted a slash
-      offset++;
-    }
-  }
-  return;
-}
-
-HDDEDATA CALLBACK nsNativeAppSupportWin::HandleDDENotification(
-    UINT uType,           // transaction type
-    UINT uFmt,            // clipboard data format
-    HCONV hconv,          // handle to the conversation
-    HSZ hsz1,             // handle to a string
-    HSZ hsz2,             // handle to a string
-    HDDEDATA hdata,       // handle to a global memory object
-    ULONG_PTR dwData1,    // transaction-specific data
-    ULONG_PTR dwData2) {  // transaction-specific data
-
-  if (!mCanHandleRequests) return 0;
-
-#if MOZ_DEBUG_DDE
-  printf("DDE: uType  =%s\n", uTypeDesc(uType).get());
-  printf("     uFmt   =%u\n", (unsigned)uFmt);
-  printf("     hconv  =%08x\n", (int)hconv);
-  printf("     hsz1   =%08x:%s\n", (int)hsz1, hszValue(mInstance, hsz1).get());
-  printf("     hsz2   =%08x:%s\n", (int)hsz2, hszValue(mInstance, hsz2).get());
-  printf("     hdata  =%08x\n", (int)hdata);
-  printf("     dwData1=%08x\n", (int)dwData1);
-  printf("     dwData2=%08x\n", (int)dwData2);
-#endif
-
-  HDDEDATA result = 0;
-  if (uType & XCLASS_BOOL) {
-    switch (uType) {
-      case XTYP_CONNECT:
-        // Make sure its for our service/topic.
-        if (FindTopic(hsz1) != -1) {
-          // We support this connection.
-          result = (HDDEDATA)1;
-        }
-        break;
-      case XTYP_CONNECT_CONFIRM:
-        // We don't care about the conversation handle, at this point.
-        result = (HDDEDATA)1;
-        break;
-    }
-  } else if (uType & XCLASS_DATA) {
-    if (uType == XTYP_REQUEST) {
-      switch (FindTopic(hsz1)) {
-        case topicOpenURL: {
-          // Open a given URL...
-
-          // Get the URL from the first argument in the command.
-          nsAutoString url;
-          ParseDDEArg(hsz2, 0, url);
-
-          // Read the 3rd argument in the command to determine if a
-          // new window is to be used.
-          nsAutoString windowID;
-          ParseDDEArg(hsz2, 2, windowID);
-          // "" means to open the URL in a new window.
-          if (windowID.IsEmpty()) {
-            url.InsertLiteral(u"mozilla -new-window ", 0);
-          } else {
-            url.InsertLiteral(u"mozilla -url ", 0);
-          }
-
-#if MOZ_DEBUG_DDE
-          printf("Handling dde XTYP_REQUEST request: [%s]...\n",
-                 NS_ConvertUTF16toUTF8(url).get());
-#endif
-          // Now handle it.
-          HandleCommandLine(NS_ConvertUTF16toUTF8(url).get(), nullptr,
-                            nsICommandLine::STATE_REMOTE_EXPLICIT);
-
-          // Return pseudo window ID.
-          result = CreateDDEData(1);
-          break;
-        }
-        case topicGetWindowInfo: {
-          // This topic has to get the current URL, get the current
-          // page title and then format the output into the DDE
-          // return string.  The return value is "URL","Page Title",
-          // "Window ID" however the window ID is not used for this
-          // command, therefore it is returned as a null string
-
-          // This isn't really a loop.  We just use "break"
-          // statements to bypass the remaining steps when
-          // something goes wrong.
-          do {
-            // Get most recently used Nav window.
-            nsCOMPtr<mozIDOMWindowProxy> navWin;
-            GetMostRecentWindow(u"navigator:browser", getter_AddRefs(navWin));
-            nsCOMPtr<nsPIDOMWindowOuter> piNavWin = do_QueryInterface(navWin);
-            if (!piNavWin) {
-              // There is not a window open
-              break;
-            }
-
-            // Get content window.
-            nsCOMPtr<nsPIDOMWindowOuter> internalContent =
-                nsGlobalWindowOuter::Cast(piNavWin)->GetContent();
-            if (!internalContent) {
-              break;
-            }
-            // Get location.
-            RefPtr<dom::Location> location = internalContent->GetLocation();
-            if (!location) {
-              break;
-            }
-            // Get href for URL.
-            nsAutoString url;
-            if (NS_FAILED(location->GetHref(url))) {
-              break;
-            }
-            // Escape any double-quotes.
-            escapeQuotes(url);
-
-            // Now for the title...
-
-            // Get the base window from the doc shell...
-            nsCOMPtr<nsIBaseWindow> baseWindow =
-                do_QueryInterface(internalContent->GetDocShell());
-            if (!baseWindow) {
-              break;
-            }
-            // And from the base window we can get the title.
-            nsString title;
-            if (!baseWindow) {
-              break;
-            }
-            baseWindow->GetTitle(title);
-            // Escape any double-quotes in the title.
-            escapeQuotes(title);
-
-            // Use a string buffer for the output data, first
-            // save a quote.
-            nsAutoCString outpt(NS_LITERAL_CSTRING("\""));
-            // Now copy the URL converting the Unicode string
-            // to a single-byte ASCII string
-            nsAutoCString tmpNativeStr;
-            NS_CopyUnicodeToNative(url, tmpNativeStr);
-            outpt.Append(tmpNativeStr);
-            // Add the "," used to separate the URL and the page
-            // title
-            outpt.Append(NS_LITERAL_CSTRING("\",\""));
-            // Now copy the current page title to the return string
-            NS_CopyUnicodeToNative(title, tmpNativeStr);
-            outpt.Append(tmpNativeStr);
-            // Fill out the return string with the remainin ",""
-            outpt.Append(NS_LITERAL_CSTRING("\",\"\""));
-
-            // Create a DDE handle to a char string for the data
-            // being returned, this copies and creates a "shared"
-            // copy of the DDE response until the calling APP
-            // reads it and says it can be freed.
-            result = CreateDDEData((LPBYTE)(const char *)outpt.get(),
-                                   outpt.Length() + 1);
-#if MOZ_DEBUG_DDE
-            printf("WWW_GetWindowInfo->%s\n", outpt.get());
-#endif
-          } while (false);
-          break;
-        }
-        case topicActivate: {
-          // Activate a Nav window...
-          nsAutoString windowID;
-          ParseDDEArg(hsz2, 0, windowID);
-          // 4294967295 is decimal for 0xFFFFFFFF which is also a
-          //   correct value to do that Activate last window stuff
-          if (windowID.EqualsLiteral("-1") ||
-              windowID.EqualsLiteral("4294967295")) {
-            // We only support activating the most recent window (or a new one).
-            ActivateLastWindow();
-            // Return pseudo window ID.
-            result = CreateDDEData(1);
-          }
-          break;
-        }
-        case topicVersion: {
-          // Return version.  We're restarting at 1.0!
-          DWORD version = 1 << 16;  // "1.0"
-          result = CreateDDEData(version);
-          break;
-        }
-        case topicRegisterViewer: {
-          // Register new viewer (not implemented).
-          result = CreateDDEData(false);
-          break;
-        }
-        case topicUnRegisterViewer: {
-          // Unregister new viewer (not implemented).
-          result = CreateDDEData(false);
-          break;
-        }
-        default:
-          break;
-      }
-    } else if (uType & XTYP_POKE) {
-      switch (FindTopic(hsz1)) {
-        case topicCancelProgress: {
-          // "Handle" progress cancel (actually, pretty much ignored).
-          result = (HDDEDATA)DDE_FACK;
-          break;
-        }
-        default:
-          break;
-      }
-    }
-  } else if (uType & XCLASS_FLAGS) {
-    if (uType == XTYP_EXECUTE) {
-      // Prove that we received the request.
-      DWORD bytes;
-      LPBYTE request = DdeAccessData(hdata, &bytes);
-#if MOZ_DEBUG_DDE
-      printf("Handling dde request: [%s]...\n", (char *)request);
-#endif
-
-      nsAutoString url;
-      ParseDDEArg((const WCHAR *)request, 0, url);
-
-      // Read the 3rd argument in the command to determine if a
-      // new window is to be used.
-      nsAutoString windowID;
-      ParseDDEArg((const WCHAR *)request, 2, windowID);
-
-      // "" means to open the URL in a new window.
-      if (windowID.IsEmpty()) {
-        url.InsertLiteral(u"mozilla -new-window ", 0);
-      } else {
-        url.InsertLiteral(u"mozilla -url ", 0);
-      }
-#if MOZ_DEBUG_DDE
-      printf("Handling dde XTYP_REQUEST request: [%s]...\n",
-             NS_ConvertUTF16toUTF8(url).get());
-#endif
-      // Now handle it.
-      HandleCommandLine(NS_ConvertUTF16toUTF8(url).get(), nullptr,
-                        nsICommandLine::STATE_REMOTE_EXPLICIT);
-
-      // Release the data.
-      DdeUnaccessData(hdata);
-      result = (HDDEDATA)DDE_FACK;
-    } else {
-      result = (HDDEDATA)DDE_FNOTPROCESSED;
-    }
-  } else if (uType & XCLASS_NOTIFICATION) {
-  }
-#if MOZ_DEBUG_DDE
-  printf("DDE result=%d (0x%08X)\n", (int)result, (int)result);
-#endif
-  return result;
-}
-
-// Utility function to advance to end of quoted string.
-// p+offset must point to the comma preceding the arg on entry.
-// On return, p+result points to the closing '"' (or end of the string
-// if the closing '"' is missing) if the arg is quoted.  If the arg
-// is not quoted, then p+result will point to the first character
-// of the arg.
-static int32_t advanceToEndOfQuotedArg(const WCHAR *p, int32_t offset,
-                                       int32_t len) {
-  // Check whether the current arg is quoted.
-  if (p[++offset] == '"') {
-    // Advance past the closing quote.
-    while (offset < len && p[++offset] != '"') {
-      // If the current character is a backslash, then the
-      // next character can't be a *real* '"', so skip it.
-      if (p[offset] == '\\') {
-        offset++;
-      }
-    }
-  }
-  return offset;
-}
-
-void nsNativeAppSupportWin::ParseDDEArg(const WCHAR *args, int index,
-                                        nsString &aString) {
-  if (args) {
-    nsDependentString temp(args);
-
-    // offset points to the comma preceding the desired arg.
-    int32_t offset = -1;
-    // Skip commas till we get to the arg we want.
-    while (index--) {
-      // If this arg is quoted, then go to closing quote.
-      offset = advanceToEndOfQuotedArg(args, offset, temp.Length());
-      // Find next comma.
-      offset = temp.FindChar(',', offset);
-      if (offset == kNotFound) {
-        // No more commas, give up.
-        aString = args;
-        return;
-      }
-    }
-    // The desired argument starts just past the preceding comma,
-    // which offset points to, and extends until the following
-    // comma (or the end of the string).
-    //
-    // Since the argument might be enclosed in quotes, we need to
-    // deal with that before searching for the terminating comma.
-    // We advance offset so it ends up pointing to the start of
-    // the argument we want.
-    int32_t end = advanceToEndOfQuotedArg(args, offset++, temp.Length());
-    // Find next comma (or end of string).
-    end = temp.FindChar(',', end);
-    if (end == kNotFound) {
-      // Arg is the rest of the string.
-      end = temp.Length();
-    }
-    // Extract result.
-    aString.Assign(args + offset, end - offset);
-  }
-  return;
-}
-
-// Utility to parse out argument from a DDE item string.
-void nsNativeAppSupportWin::ParseDDEArg(HSZ args, int index,
-                                        nsString &aString) {
-  DWORD argLen = DdeQueryStringW(mInstance, args, nullptr, 0, CP_WINUNICODE);
-  // there wasn't any string, so return empty string
-  if (!argLen) return;
-  nsAutoString temp;
-  // Ensure result's buffer is sufficiently big.
-  temp.SetLength(argLen);
-  // Now get the string contents.
-  DdeQueryString(mInstance, args,
-                 reinterpret_cast<wchar_t *>(temp.BeginWriting()),
-                 temp.Length(), CP_WINUNICODE);
-  // Parse out the given arg.
-  ParseDDEArg(temp.get(), index, aString);
-  return;
-}
-
-HDDEDATA nsNativeAppSupportWin::CreateDDEData(DWORD value) {
-  return CreateDDEData((LPBYTE)&value, sizeof value);
-}
-
-HDDEDATA nsNativeAppSupportWin::CreateDDEData(LPBYTE value, DWORD len) {
-  HDDEDATA result =
-      DdeCreateDataHandle(mInstance, value, len, 0, mApplication, CF_TEXT, 0);
-  return result;
-}
-
-void nsNativeAppSupportWin::ActivateLastWindow() {
-  nsCOMPtr<mozIDOMWindowProxy> navWin;
-  GetMostRecentWindow(u"navigator:browser", getter_AddRefs(navWin));
-  if (navWin) {
-    // Activate that window.
-    activateWindow(navWin);
-  } else {
-    // Need to create a Navigator window, then.
-    OpenBrowserWindow();
-  }
-}
-
 void nsNativeAppSupportWin::HandleCommandLine(const char *aCmdLineString,
                                               nsIFile *aWorkingDir,
                                               uint32_t aState) {
   nsresult rv;
 
   int justCounting = 1;
   char **argv = 0;
   // Flags, etc.
@@ -1334,37 +605,16 @@ void nsNativeAppSupportWin::HandleComman
   if (NS_FAILED(rv)) {
     NS_ERROR("Error initializing command line.");
     return;
   }
 
   cmdLine->Run();
 }
 
-nsresult nsNativeAppSupportWin::OpenWindow(const char *urlstr,
-                                           const char *args) {
-  nsresult rv = NS_ERROR_FAILURE;
-
-  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
-  nsCOMPtr<nsISupportsCString> sarg(
-      do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
-  if (sarg) sarg->SetData(nsDependentCString(args));
-
-  if (wwatch && sarg) {
-    nsCOMPtr<mozIDOMWindowProxy> newWindow;
-    rv = wwatch->OpenWindow(0, urlstr, "_blank", "chrome,dialog=no,all", sarg,
-                            getter_AddRefs(newWindow));
-#if MOZ_DEBUG_DDE
-  } else {
-    printf("Get WindowWatcher (or create string) failed\n");
-#endif
-  }
-  return rv;
-}
-
 HWND hwndForDOMWindow(mozIDOMWindowProxy *window) {
   if (!window) {
     return 0;
   }
   nsCOMPtr<nsPIDOMWindowOuter> pidomwindow = nsPIDOMWindowOuter::From(window);
 
   nsCOMPtr<nsIBaseWindow> ppBaseWindow =
       do_QueryInterface(pidomwindow->GetDocShell());
@@ -1372,69 +622,8 @@ HWND hwndForDOMWindow(mozIDOMWindowProxy
     return 0;
   }
 
   nsCOMPtr<nsIWidget> ppWidget;
   ppBaseWindow->GetMainWidget(getter_AddRefs(ppWidget));
 
   return (HWND)(ppWidget->GetNativeData(NS_NATIVE_WIDGET));
 }
-
-nsresult nsNativeAppSupportWin::OpenBrowserWindow() {
-  nsresult rv = NS_OK;
-
-  // Open the argument URL in the most recently used Navigator window.
-  // If there is no Nav window, open a new one.
-
-  // If at all possible, hand the request off to the most recent
-  // browser window.
-
-  nsCOMPtr<mozIDOMWindowProxy> navWin;
-  GetMostRecentWindow(u"navigator:browser", getter_AddRefs(navWin));
-
-  // This isn't really a loop.  We just use "break" statements to fall
-  // out to the OpenWindow call when things go awry.
-  do {
-    // If caller requires a new window, then don't use an existing one.
-    if (!navWin) {
-      // Have to open a new one.
-      break;
-    }
-
-    nsCOMPtr<nsIBrowserDOMWindow> bwin;
-    {  // scope a bunch of temporary cruft used to generate bwin
-      nsCOMPtr<nsIWebNavigation> navNav(do_GetInterface(navWin));
-      nsCOMPtr<nsIDocShellTreeItem> navItem(do_QueryInterface(navNav));
-      if (navItem) {
-        nsCOMPtr<nsIDocShellTreeItem> rootItem;
-        navItem->GetRootTreeItem(getter_AddRefs(rootItem));
-        nsCOMPtr<nsPIDOMWindowOuter> rootWin =
-            rootItem ? rootItem->GetWindow() : nullptr;
-        nsCOMPtr<nsIDOMChromeWindow> chromeWin(do_QueryInterface(rootWin));
-        if (chromeWin) chromeWin->GetBrowserDOMWindow(getter_AddRefs(bwin));
-      }
-    }
-    if (bwin) {
-      nsCOMPtr<nsIURI> uri;
-      NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:blank"), 0, 0);
-      if (uri) {
-        nsCOMPtr<mozIDOMWindowProxy> container;
-        rv = bwin->OpenURI(uri, 0, nsIBrowserDOMWindow::OPEN_DEFAULTWINDOW,
-                           nsIBrowserDOMWindow::OPEN_EXTERNAL,
-                           nsContentUtils::GetSystemPrincipal(),
-                           getter_AddRefs(container));
-        if (NS_SUCCEEDED(rv)) return NS_OK;
-      }
-    }
-
-    NS_ERROR("failed to hand off external URL to extant window");
-  } while (false);
-
-  // open a new window if caller requested it or if anything above failed
-
-  char *argv[] = {0};
-  nsCOMPtr<nsICommandLineRunner> cmdLine(new nsCommandLine());
-
-  rv = cmdLine->Init(0, argv, nullptr, nsICommandLine::STATE_REMOTE_EXPLICIT);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return cmdLine->Run();
-}
--- a/toolkit/xre/nsNativeAppSupportWin.h
+++ b/toolkit/xre/nsNativeAppSupportWin.h
@@ -10,25 +10,16 @@
  *
  * This file, and the generated .h, are only needed on Win32 platforms.
  */
 
 // Constants identifying Win32 "native" resources.
 
 #ifdef MOZ_PHOENIX
 
-// Splash screen dialog ID.
-#  define IDD_SPLASH 100
-
-// Splash screen bitmap ID.
-#  define IDB_SPLASH 101
-
-// DDE application name
-#  define ID_DDE_APPLICATION_NAME 102
-
 #  define IDI_APPICON 1
 #  define IDI_DOCUMENT 2
 #  define IDI_NEWWINDOW 3
 #  define IDI_NEWTAB 4
 #  define IDI_PBMODE 5
 #  ifndef IDI_APPLICATION
 #    define IDI_APPLICATION 32512
 #  endif