Bug 667535 - Remove xpcom/proxy use in netwerk/wifi (since this can lead to off-thread scripted QI) (r=dougt)
authorLuke Wagner <luke@mozilla.com>
Wed, 27 Jul 2011 09:26:20 -0700
changeset 74209 169712c5c68b0d32744e101c0fca0776e8650c4f
parent 74194 da50621162f38bf00c3c0815e8e8346b12bf8908
child 74210 0737efca777e16746dd9435bad830164d3f2f5fd
push idunknown
push userunknown
push dateunknown
reviewersdougt
bugs667535
milestone8.0a1
Bug 667535 - Remove xpcom/proxy use in netwerk/wifi (since this can lead to off-thread scripted QI) (r=dougt)
netwerk/wifi/nsWifiMonitor.cpp
netwerk/wifi/nsWifiMonitor.h
netwerk/wifi/nsWifiScannerMac.cpp
netwerk/wifi/nsWifiScannerSolaris.cpp
netwerk/wifi/nsWifiScannerUnix.cpp
netwerk/wifi/nsWifiScannerWin.cpp
--- a/netwerk/wifi/nsWifiMonitor.cpp
+++ b/netwerk/wifi/nsWifiMonitor.cpp
@@ -41,18 +41,18 @@
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMCID.h"
 #include "nsIObserver.h"
 #include "nsIObserverService.h"
 #include "nsWifiMonitor.h"
+#include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "mozilla/Services.h"
 
 using namespace mozilla;
 
 #if defined(PR_LOGGING)
 PRLogModuleInfo *gWifiMonitorLog;
@@ -141,39 +141,143 @@ NS_IMETHODIMP nsWifiMonitor::StopWatchin
     mKeepGoing = PR_FALSE;
     mon.Notify();
     mThread = nsnull;
   }
 
   return NS_OK;
 }
 
+class nsPassErrorToWifiListeners : public nsIRunnable
+{
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+
+  nsPassErrorToWifiListeners(nsAutoPtr<nsCOMArray<nsIWifiListener> > aListeners,
+                             nsresult aResult)
+  : mListeners(aListeners),
+    mResult(aResult)
+  {}
+
+ private:
+  nsAutoPtr<nsCOMArray<nsIWifiListener> > mListeners;
+  nsresult mResult;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsPassErrorToWifiListeners,
+                              nsIRunnable)
+
+NS_IMETHODIMP nsPassErrorToWifiListeners::Run()
+{
+  LOG(("About to send error to the wifi listeners\n"));
+  for (PRInt32 i = 0; i < mListeners->Count(); i++) {
+    nsresult rv = (*mListeners)[i]->OnError(mResult);
+    LOG( ("... sent %d\n", rv));
+  }
+  return NS_OK;
+}
 
 NS_IMETHODIMP nsWifiMonitor::Run()
 {
   LOG(("@@@@@ wifi monitor run called\n"));
 
   nsresult rv = DoScan();
 
   if (mKeepGoing && NS_FAILED(rv)) {
-
-    nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
+    nsAutoPtr<nsCOMArray<nsIWifiListener> > currentListeners(
+                           new nsCOMArray<nsIWifiListener>(mListeners.Length()));
+    if (!currentListeners)
+      return NS_ERROR_OUT_OF_MEMORY;
 
-    // send error
-    for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-      LOG(("About to send error to a listener\n"));
+    for (PRUint32 i = 0; i < mListeners.Length(); i++)
+      currentListeners->AppendObject(mListeners[i].mListener);
 
-      nsCOMPtr<nsIWifiListener> proxy;
-      proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                     NS_GET_IID(nsIWifiListener),
-                                     mListeners[i].mListener,
-                                     NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                     getter_AddRefs(proxy));
+    nsCOMPtr<nsIThread> thread = do_GetMainThread();
+    if (!thread)
+      return NS_ERROR_UNEXPECTED;
 
-      if (proxy) {
-        proxy->OnError(rv);
-        LOG( ("... sent %d\n", rv));
-      }
-    }
+    nsCOMPtr<nsIRunnable> runnable(new nsPassErrorToWifiListeners(currentListeners, rv));
+    if (!runnable)
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    thread->Dispatch(runnable, NS_DISPATCH_SYNC);
   }
 
   return NS_OK;
 }
+
+class nsCallWifiListeners : public nsIRunnable
+{
+ public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+
+  nsCallWifiListeners(nsAutoPtr<nsCOMArray<nsIWifiListener> > aListeners,
+                      nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > aAccessPoints)
+  : mListeners(aListeners),
+    mAccessPoints(aAccessPoints)
+  {}
+
+ private:
+  nsAutoPtr<nsCOMArray<nsIWifiListener> > mListeners;
+  nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > mAccessPoints;
+};
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsCallWifiListeners,
+                              nsIRunnable)
+
+NS_IMETHODIMP nsCallWifiListeners::Run()
+{
+  LOG(("About to send data to the wifi listeners\n"));
+  for (PRInt32 i = 0; i < mListeners->Count(); i++) {
+    nsresult rv = (*mListeners)[i]->OnChange(mAccessPoints->Elements(),
+                                             mAccessPoints->Length());
+    LOG( ("... sent %d\n", rv));
+  }
+  return NS_OK;
+}
+
+nsresult
+nsWifiMonitor::CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
+                                 PRBool aAccessPointsChanged)
+{
+    nsAutoPtr<nsCOMArray<nsIWifiListener> > currentListeners(
+                           new nsCOMArray<nsIWifiListener>(mListeners.Length()));
+    if (!currentListeners)
+      return NS_ERROR_OUT_OF_MEMORY;
+
+    {
+      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
+
+      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
+        if (!mListeners[i].mHasSentData || aAccessPointsChanged) {
+          mListeners[i].mHasSentData = PR_TRUE;
+          currentListeners->AppendObject(mListeners[i].mListener);
+        }
+      }
+    }
+
+    if (currentListeners->Count() > 0)
+    {
+      PRUint32 resultCount = aAccessPoints.Count();
+      nsAutoPtr<nsTArray<nsIWifiAccessPoint*> > accessPoints(
+                               new nsTArray<nsIWifiAccessPoint *>(resultCount));
+      if (!accessPoints)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+      for (PRUint32 i = 0; i < resultCount; i++)
+        accessPoints->AppendElement(aAccessPoints[i]);
+
+      nsCOMPtr<nsIThread> thread = do_GetMainThread();
+      if (!thread)
+        return NS_ERROR_UNEXPECTED;
+
+      nsCOMPtr<nsIRunnable> runnable(
+                      new nsCallWifiListeners(currentListeners, accessPoints));
+      if (!runnable)
+        return NS_ERROR_OUT_OF_MEMORY;
+
+      thread->Dispatch(runnable, NS_DISPATCH_SYNC);
+    }
+
+    return NS_OK;
+}
--- a/netwerk/wifi/nsWifiMonitor.h
+++ b/netwerk/wifi/nsWifiMonitor.h
@@ -52,16 +52,18 @@
 #ifndef __nsWifiMonitor__
 #define __nsWifiMonitor__
 
 #if defined(PR_LOGGING)
 extern PRLogModuleInfo *gWifiMonitorLog;
 #endif
 #define LOG(args)     PR_LOG(gWifiMonitorLog, PR_LOG_DEBUG, args)
 
+class nsWifiAccessPoint;
+
 class nsWifiListener
 {
  public:
 
   nsWifiListener(nsIWifiListener* aListener)
   {
     mListener = aListener;
     mHasSentData = PR_FALSE;
@@ -87,16 +89,19 @@ class nsWifiMonitor : nsIRunnable, nsIWi
 
   nsresult DoScan();
 
 #if defined(XP_MACOSX)
   nsresult DoScanWithCoreWLAN();
   nsresult DoScanOld();
 #endif
 
+  nsresult CallWifiListeners(const nsCOMArray<nsWifiAccessPoint> &aAccessPoints,
+                             PRBool aAccessPointsChanged);
+
   PRBool mKeepGoing;
   nsCOMPtr<nsIThread> mThread;
 
   nsTArray<nsWifiListener> mListeners;
 
   mozilla::ReentrantMonitor mReentrantMonitor;
 
 };
--- a/netwerk/wifi/nsWifiScannerMac.cpp
+++ b/netwerk/wifi/nsWifiScannerMac.cpp
@@ -43,17 +43,16 @@
 
 #include "osx_wifi.h"
 
 #include "nsAutoPtr.h"
 #include "nsCOMArray.h"
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
 
 using namespace mozilla;
 
 // defined in osx_corewlan.mm
 // basically relaces accesspoints in the passed reference
@@ -69,65 +68,20 @@ nsWifiMonitor::DoScanWithCoreWLAN()
   nsCOMArray<nsWifiAccessPoint> accessPoints;
 
   do {
     nsresult rv = GetAccessPointsFromWLAN(accessPoints);
     if (NS_FAILED(rv))
       return rv;
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
-    }
+    rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     // wait for some reasonable amount of time.  pref?
     LOG(("waiting on monitor\n"));
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
   while (mKeepGoing);
@@ -204,65 +158,22 @@ nsWifiMonitor::DoScanOld()
 
       ap->setSSID(reinterpret_cast<const char*>(access_point_info->name),
                   access_point_info->nameLen);
 
       accessPoints.AppendObject(ap);
     }
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
+    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    if (NS_FAILED(rv)) {
         dlclose(apple_80211_library);
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
+        return rv;
     }
 
     // wait for some reasonable amount of time.  pref?
     LOG(("waiting on monitor\n"));
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
--- a/netwerk/wifi/nsWifiScannerSolaris.cpp
+++ b/netwerk/wifi/nsWifiScannerSolaris.cpp
@@ -36,17 +36,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
 
 #include "plstr.h"
 #include <glib.h>
 
 #define DLADM_STRSIZE 256
@@ -166,65 +165,20 @@ nsWifiMonitor::DoScan()
   nsCOMArray<nsWifiAccessPoint> accessPoints;
 
   while (mKeepGoing) {
 
     accessPoints.Clear();
     do_dladm(accessPoints);
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      MonitorAutoEnter mon(mMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
-    }
+    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     LOG(("waiting on monitor\n"));
 
     MonitorAutoEnter mon(mMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
 
   return NS_OK;
--- a/netwerk/wifi/nsWifiScannerUnix.cpp
+++ b/netwerk/wifi/nsWifiScannerUnix.cpp
@@ -39,20 +39,20 @@
 
 #include "iwlib.h"
 
 #include "dlfcn.h"
 
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
+#include "nsThreadUtils.h"
 
 using namespace mozilla;
 
 
 typedef int (*iw_open_t)(void);
 
 typedef void (*iw_enum_t)(int	skfd,
 			  iw_enum_handler fn,
@@ -118,113 +118,81 @@ static int scan_wifi(int skfd, char* ifn
 
   accessPoints->AppendObject(ap);
   return 0;
 }
 
 nsresult
 nsWifiMonitor::DoScan()
 {
-  void* iwlib_handle = dlopen("libiw.so", RTLD_NOW);
+  static void* iwlib_handle = NULL;
+
   if (!iwlib_handle) {
-    iwlib_handle = dlopen("libiw.so.29", RTLD_NOW);
+    iwlib_handle = dlopen("libiw.so", RTLD_NOW);
     if (!iwlib_handle) {
-      iwlib_handle = dlopen("libiw.so.30", RTLD_NOW);
+      iwlib_handle = dlopen("libiw.so.29", RTLD_NOW);
       if (!iwlib_handle) {
-        LOG(("Could not load libiw\n"));
-        return NS_ERROR_NOT_AVAILABLE;
+        iwlib_handle = dlopen("libiw.so.30", RTLD_NOW);
+        if (!iwlib_handle) {
+          LOG(("Could not load libiw\n"));
+          return NS_ERROR_NOT_AVAILABLE;
+        }
       }
     }
   }
   else {
     LOG(("Loaded libiw\n"));
   }
 
-  iw_open_t iw_open = (iw_open_t) dlsym(iwlib_handle, "iw_sockets_open");
-  iw_enum_t iw_enum = (iw_enum_t) dlsym(iwlib_handle, "iw_enum_devices");
-  iw_stats_t iw_stats = (iw_stats_t)dlsym(iwlib_handle, "iw_get_stats");
+  static iw_open_t iw_open = NULL;
+  if (!iw_open)
+    iw_open = (iw_open_t) dlsym(iwlib_handle, "iw_sockets_open");
+
+  static iw_enum_t iw_enum = NULL;
+  if (!iw_enum)
+    iw_enum = (iw_enum_t) dlsym(iwlib_handle, "iw_enum_devices");
+
+  static iw_stats_t iw_stats = NULL;
+  if (!iw_stats)
+    iw_stats = (iw_stats_t)dlsym(iwlib_handle, "iw_get_stats");
 
   if (!iw_open || !iw_enum || !iw_stats) {
-    dlclose(iwlib_handle);
     LOG(("Could not load a symbol from iwlib.so\n"));
     return NS_ERROR_FAILURE;
   }
 
   int skfd = (*iw_open)();
 
   if (skfd < 0) {
-    dlclose(iwlib_handle);
+    LOG(("Could not iw_open\n"));
     return NS_ERROR_FAILURE;
   }
 
+  struct SocketsGuard {
+    int skfd;
+    SocketsGuard(int skfd) : skfd(skfd) {}
+    ~SocketsGuard() { iw_sockets_close(skfd); }
+  } guard(skfd);
+
   nsCOMArray<nsWifiAccessPoint> lastAccessPoints;
   nsCOMArray<nsWifiAccessPoint> accessPoints;
 
   char* args[] = {(char*) &accessPoints, (char*) iw_stats, nsnull };
 
   while (mKeepGoing) {
-
     accessPoints.Clear();
 
     (*iw_enum)(skfd, &scan_wifi, args, 1);
 
     PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-    nsCOMArray<nsIWifiListener> currentListeners;
-
-    {
-      ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-      for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-        if (!mListeners[i].mHasSentData || accessPointsChanged) {
-          mListeners[i].mHasSentData = PR_TRUE;
-          currentListeners.AppendObject(mListeners[i].mListener);
-        }
-      }
-    }
-
     ReplaceArray(lastAccessPoints, accessPoints);
 
-    if (currentListeners.Count() > 0)
-    {
-      PRUint32 resultCount = lastAccessPoints.Count();
-      nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-      if (!result) {
-        dlclose(iwlib_handle);
-        return NS_ERROR_OUT_OF_MEMORY;
-      }
-
-      for (PRUint32 i = 0; i < resultCount; i++)
-        result[i] = lastAccessPoints[i];
-
-      for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-        LOG(("About to send data to the wifi listeners\n"));
-
-        nsCOMPtr<nsIWifiListener> proxy;
-        nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-        proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                       NS_GET_IID(nsIWifiListener),
-                                       currentListeners[i],
-                                       NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                       getter_AddRefs(proxy));
-        if (!proxy) {
-          LOG(("There is no proxy available.  this should never happen\n"));
-        }
-        else
-        {
-          nsresult rv = proxy->OnChange(result, resultCount);
-          LOG( ("... sent %d\n", rv));
-        }
-      }
-
-      nsMemory::Free(result);
-    }
+    nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+    NS_ENSURE_SUCCESS(rv, rv);
 
     LOG(("waiting on monitor\n"));
 
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mon.Wait(PR_SecondsToInterval(60));
   }
 
-  iw_sockets_close(skfd);
-
   return NS_OK;
 }
--- a/netwerk/wifi/nsWifiScannerWin.cpp
+++ b/netwerk/wifi/nsWifiScannerWin.cpp
@@ -44,17 +44,16 @@
 
 #include <ntddndis.h>
 #include "winioctl.h"
 #include "stdlib.h"
 
 #include "nsWifiMonitor.h"
 #include "nsWifiAccessPoint.h"
 
-#include "nsIProxyObjectManager.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIMutableArray.h"
 
 using namespace mozilla;
 
 nsresult
 nsWifiMonitor::DoScan()
@@ -146,63 +145,20 @@ nsWifiMonitor::DoScan()
       // Free interface_list.
       (*WlanFreeMemory)(interface_list);
 
       // Close the handle.
       (*WlanCloseHandle)(wlan_handle, NULL);
 
 
       PRBool accessPointsChanged = !AccessPointsEqual(accessPoints, lastAccessPoints);
-      nsCOMArray<nsIWifiListener> currentListeners;
-
-      {
-        ReentrantMonitorAutoEnter mon(mReentrantMonitor);
-
-        for (PRUint32 i = 0; i < mListeners.Length(); i++) {
-          if (!mListeners[i].mHasSentData || accessPointsChanged) {
-            mListeners[i].mHasSentData = PR_TRUE;
-            currentListeners.AppendObject(mListeners[i].mListener);
-          }
-        }
-      }
-
       ReplaceArray(lastAccessPoints, accessPoints);
 
-      if (currentListeners.Count() > 0) {
-        PRUint32 resultCount = lastAccessPoints.Count();
-        nsIWifiAccessPoint** result = static_cast<nsIWifiAccessPoint**> (nsMemory::Alloc(sizeof(nsIWifiAccessPoint*) * resultCount));
-        if (!result)
-          return NS_ERROR_OUT_OF_MEMORY;
-
-        for (PRUint32 i = 0; i < resultCount; i++)
-          result[i] = lastAccessPoints[i];
-
-        for (PRInt32 i = 0; i < currentListeners.Count(); i++) {
-
-          LOG(("About to send data to the wifi listeners\n"));
-
-          nsCOMPtr<nsIWifiListener> proxy;
-          nsCOMPtr<nsIProxyObjectManager> proxyObjMgr = do_GetService("@mozilla.org/xpcomproxy;1");
-          proxyObjMgr->GetProxyForObject(NS_PROXY_TO_MAIN_THREAD,
-                                         NS_GET_IID(nsIWifiListener),
-                                         currentListeners[i],
-                                         NS_PROXY_SYNC | NS_PROXY_ALWAYS,
-                                         getter_AddRefs(proxy));
-          if (!proxy) {
-            LOG(("There is no proxy available.  this should never happen\n"));
-          }
-          else
-          {
-            nsresult rv = proxy->OnChange(result, resultCount);
-            LOG( ("... sent %d\n", rv));
-          }
-        }
-
-        nsMemory::Free(result);
-      }
+      nsresult rv = CallWifiListeners(lastAccessPoints, accessPointsChanged);
+      NS_ENSURE_SUCCESS(rv, rv);
 
       // wait for some reasonable amount of time.  pref?
       LOG(("waiting on monitor\n"));
 
       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       mon.Wait(PR_SecondsToInterval(60));
     }
     while (mKeepGoing);