コード例 #1
0
NS_IMETHODIMP nsExternalProtocolHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval)
{
  // Only try to return a channel if we have a protocol handler for the url.
  // nsOSHelperAppService::LoadUriInternal relies on this to check trustedness
  // for some platforms at least.  (win uses ::ShellExecute and unix uses
  // gnome_url_show.)
  PRBool haveExternalHandler = HaveExternalProtocolHandler(aURI);
  if (haveExternalHandler)
  {
    nsCOMPtr<nsIChannel> channel;
    NS_NEWXPCOM(channel, nsExtProtocolChannel);
    if (!channel) return NS_ERROR_OUT_OF_MEMORY;

    ((nsExtProtocolChannel*) channel.get())->SetURI(aURI);
    channel->SetOriginalURI(aURI);

    if (_retval)
    {
      *_retval = channel;
      NS_IF_ADDREF(*_retval);
      return NS_OK;
    }
  }

  return NS_ERROR_UNKNOWN_PROTOCOL;
}
コード例 #2
0
static NS_IMETHODIMP
nsNativeKeyBindingsConstructor(nsISupports *aOuter, REFNSIID aIID,
                               void **aResult,
                               NativeKeyBindingsType aKeyBindingsType)
{
    nsresult rv;

    nsNativeKeyBindings *inst;

    *aResult = NULL;
    if (NULL != aOuter) {
        rv = NS_ERROR_NO_AGGREGATION;
        return rv;
    }

    NS_NEWXPCOM(inst, nsNativeKeyBindings);
    if (NULL == inst) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        return rv;
    }
    NS_ADDREF(inst);
    inst->Init(aKeyBindingsType);
    rv = inst->QueryInterface(aIID, aResult);
    NS_RELEASE(inst);

    return rv;
}
コード例 #3
0
// This special constructor for the inline spell checker asks the inline
// spell checker if we can create spell checking objects at all (ie, if there
// are any dictionaries loaded) before trying to create one. The static
// CanEnableInlineSpellChecking caches the value so this will be faster (we
// have to run this code for every edit box we create, as well as for every
// right click in those edit boxes).
static NS_IMETHODIMP
mozInlineSpellCheckerConstructor(nsISupports *aOuter, REFNSIID aIID,
                                 void **aResult)
{
  if (! mozInlineSpellChecker::CanEnableInlineSpellChecking())
    return NS_ERROR_FAILURE;

  nsresult rv;

  mozInlineSpellChecker* inst;

  *aResult = NULL;
  if (NULL != aOuter) {
    rv = NS_ERROR_NO_AGGREGATION;
    return rv;
  }

  NS_NEWXPCOM(inst, mozInlineSpellChecker);
  if (NULL == inst) {
    rv = NS_ERROR_OUT_OF_MEMORY;
    return rv;
  }
  NS_ADDREF(inst);
  rv = inst->QueryInterface(aIID, aResult);
  NS_RELEASE(inst);

  return rv;
}
コード例 #4
0
static NS_IMETHODIMP
nsNativeThemeGTKConstructor(nsISupports *aOuter, REFNSIID aIID,
                            void **aResult)
{
    nsresult rv;
    nsNativeThemeGTK * inst;

    if (gDisableNativeTheme)
        return NS_ERROR_NO_INTERFACE;

    *aResult = NULL;
    if (NULL != aOuter) {
        rv = NS_ERROR_NO_AGGREGATION;
        return rv;
    }

    NS_NEWXPCOM(inst, nsNativeThemeGTK);
    if (NULL == inst) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        return rv;
    }
    NS_ADDREF(inst);
    rv = inst->QueryInterface(aIID, aResult);
    NS_RELEASE(inst);

    return rv;
}
コード例 #5
0
/* virtual */ nsStandardURL*
nsResURL::StartClone()
{
    nsResURL *clone;
    NS_NEWXPCOM(clone, nsResURL);
    return clone;
}
コード例 #6
0
nsMsgSendReport::nsMsgSendReport()
{
  PRUint32 i;
  for (i = 0; i <= SEND_LAST_PROCESS; i ++)
    NS_NEWXPCOM(mProcessReport[i], nsMsgProcessReport);

  Reset(); 
}
コード例 #7
0
ファイル: imgTools.cpp プロジェクト: MozillaOnline/gecko-dev
NS_IMETHODIMP imgTools::DecodeImageData(nsIInputStream* aInStr,
                                        const nsACString& aMimeType,
                                        imgIContainer **aContainer)
{
  nsresult rv;

  NS_ENSURE_ARG_POINTER(aInStr);
  // If the caller didn't provide a container, create one
  if (!*aContainer) {
    NS_NEWXPCOM(*aContainer, imgContainer);
    if (!*aContainer)
      return NS_ERROR_OUT_OF_MEMORY;
    NS_ADDREF(*aContainer);
  }

  // Initialize the container. If we're using the one from the caller, we
  // require that it not be initialized
  nsCString mimeType(aMimeType);
  rv = (*aContainer)->Init(nsnull, mimeType.get(), imgIContainer::INIT_FLAG_NONE);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<nsIInputStream> inStream = aInStr;
  if (!NS_InputStreamIsBuffered(aInStr)) {
    nsCOMPtr<nsIInputStream> bufStream;
    rv = NS_NewBufferedInputStream(getter_AddRefs(bufStream), aInStr, 1024);
    if (NS_SUCCEEDED(rv))
      inStream = bufStream;
  }

  // Figure out how much data we've been passed
  PRUint32 length;
  rv = inStream->Available(&length);
  NS_ENSURE_SUCCESS(rv, rv);

  // Send the source data to the container. WriteToContainer always
  // consumes everything it gets.
  PRUint32 bytesRead;
  rv = inStream->ReadSegments(imgContainer::WriteToContainer,
                              static_cast<void*>(*aContainer),
                              length, &bytesRead);
  NS_ENSURE_SUCCESS(rv, rv);


  // Let the container know we've sent all the data
  rv = (*aContainer)->SourceDataComplete();
  NS_ENSURE_SUCCESS(rv, rv);

  // All done
  return NS_OK;
}
コード例 #8
0
NS_IMETHODIMP nsIconProtocolHandler::NewURI(const nsACString &aSpec,
                                            const char *aOriginCharset, // ignored
                                            nsIURI *aBaseURI,
                                            nsIURI **result) 
{
  
  nsCOMPtr<nsIURI> uri;
  NS_NEWXPCOM(uri, nsMozIconURI);
  if (!uri) return NS_ERROR_OUT_OF_MEMORY;

  nsresult rv = uri->SetSpec(aSpec);
  if (NS_FAILED(rv)) return rv;

  NS_ADDREF(*result = uri);
  return NS_OK;
}
コード例 #9
0
NS_IMETHODIMP
nsMsgXFVirtualFolderDBView::CloneDBView(nsIMessenger *aMessengerInstance, nsIMsgWindow *aMsgWindow,
                                        nsIMsgDBViewCommandUpdater *aCmdUpdater, nsIMsgDBView **_retval)
{
  nsMsgXFVirtualFolderDBView* newMsgDBView;
  NS_NEWXPCOM(newMsgDBView, nsMsgXFVirtualFolderDBView);

  if (!newMsgDBView)
    return NS_ERROR_OUT_OF_MEMORY;

  nsresult rv = CopyDBView(newMsgDBView, aMessengerInstance, aMsgWindow, aCmdUpdater);
  NS_ENSURE_SUCCESS(rv,rv);

  NS_IF_ADDREF(*_retval = newMsgDBView);
  return NS_OK;
}
コード例 #10
0
nsresult
NS_NewXBLContentSink(nsIXMLContentSink** aResult,
                     nsIDocument* aDoc,
                     nsIURI* aURI,
                     nsISupports* aContainer)
{
  NS_ENSURE_ARG_POINTER(aResult);

  nsXBLContentSink* it;
  NS_NEWXPCOM(it, nsXBLContentSink);
  NS_ENSURE_TRUE(it, NS_ERROR_OUT_OF_MEMORY);

  nsCOMPtr<nsIXMLContentSink> kungFuDeathGrip = it;
  nsresult rv = it->Init(aDoc, aURI, aContainer);
  NS_ENSURE_SUCCESS(rv, rv);

  return CallQueryInterface(it, aResult);
}
コード例 #11
0
/*virtual*/ nsresult 
sbGStreamerMediacoreFactory::OnCreate(const nsAString &aInstanceName, 
                                    sbIMediacore **_retval)
{
  nsRefPtr<sbGStreamerMediacore> mediacore;
  NS_NEWXPCOM(mediacore, sbGStreamerMediacore);
  NS_ENSURE_TRUE(mediacore, NS_ERROR_OUT_OF_MEMORY);

  nsresult rv = mediacore->Init();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = mediacore->SetInstanceName(aInstanceName);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = CallQueryInterface(mediacore.get(), _retval);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
コード例 #12
0
NS_IMETHODIMP
nsResProtocolHandler::NewURI(const nsACString &aSpec,
                             const char *aCharset,
                             nsIURI *aBaseURI,
                             nsIURI **result)
{
    nsresult rv;

    nsResURL *resURL;
    NS_NEWXPCOM(resURL, nsResURL);
    if (!resURL)
        return NS_ERROR_OUT_OF_MEMORY;
    NS_ADDREF(resURL);

    rv = resURL->Init(nsIStandardURL::URLTYPE_STANDARD, -1, aSpec, aCharset, aBaseURI);
    if (NS_SUCCEEDED(rv))
        rv = CallQueryInterface(resURL, result);
    NS_RELEASE(resURL);
    return rv;
}
コード例 #13
0
NS_IMETHODIMP
sbCDDeviceController::GetCompatibility(nsIPropertyBag *aParams,
                                       sbIDeviceCompatibility **aRetVal)
{
  NS_ENSURE_ARG_POINTER(aParams);
  NS_ENSURE_ARG_POINTER(aRetVal);

  nsresult rv;

  // Create the device compatibility object.
  nsRefPtr<sbDeviceCompatibility> deviceCompatibility;
  NS_NEWXPCOM(deviceCompatibility, sbDeviceCompatibility);
  NS_ENSURE_TRUE(deviceCompatibility, NS_ERROR_OUT_OF_MEMORY);

  // Get the device type.
  nsCOMPtr<nsIVariant> property;
  rv = aParams->GetProperty(NS_LITERAL_STRING("DeviceType"),
                            getter_AddRefs(property));
  NS_ENSURE_SUCCESS(rv, rv);

  nsString deviceType;
  rv = property->GetAsAString(deviceType);
  NS_ENSURE_SUCCESS(rv, rv);

  if (deviceType.EqualsLiteral("CD")) {
    rv = deviceCompatibility->Init(
        sbIDeviceCompatibility::COMPATIBLE_ENHANCED_SUPPORT,
        sbIDeviceCompatibility::PREFERENCE_SELECTED);
  }
  else {
    rv = deviceCompatibility->Init(sbIDeviceCompatibility::INCOMPATIBLE,
                                   sbIDeviceCompatibility::PREFERENCE_UNKNOWN);
  }

  NS_ENSURE_SUCCESS(rv, rv);

  // Return results.
  NS_ADDREF(*aRetVal = deviceCompatibility);
  return NS_OK;
}
コード例 #14
0
ファイル: nsGfxFactoryPh.cpp プロジェクト: rn10950/RetroZilla
static nsresult nsScriptableRegionConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
    nsresult rv;

    nsIScriptableRegion *inst;

    if ( NULL == aResult )
    {
        rv = NS_ERROR_NULL_POINTER;
        return rv;
    }
    *aResult = NULL;
    if (NULL != aOuter)
    {
        rv = NS_ERROR_NO_AGGREGATION;
        return rv;
    }
    // create an nsRegionPh and get the scriptable region from it
    nsCOMPtr <nsIRegion> rgn;
    NS_NEWXPCOM(rgn, nsRegionPh);
    nsCOMPtr<nsIScriptableRegion> scriptableRgn;
    if (rgn != nsnull)
    {
        scriptableRgn = new nsScriptableRegion(rgn);
        inst = scriptableRgn;
    }
    if (NULL == inst)
    {
        rv = NS_ERROR_OUT_OF_MEMORY;
        return rv;
    }
    NS_ADDREF(inst);
    // release our variable above now that we have created our owning
    // reference - we don't want this to go out of scope early!
    scriptableRgn = nsnull;
    rv = inst->QueryInterface(aIID, aResult);
    NS_RELEASE(inst);

    return rv;
}
コード例 #15
0
/*static*/ nsresult
sbDeviceEventBeforeAddedData::CreateEventBeforeAddedData(
                                sbIDevice *aDevice,
                                sbIDeviceEventBeforeAddedData **aBeforeAddedData)
{
  NS_ENSURE_ARG_POINTER(aDevice);
  NS_ENSURE_ARG_POINTER(aBeforeAddedData);

  nsRefPtr<sbDeviceEventBeforeAddedData> beforeAddedData;
  NS_NEWXPCOM(beforeAddedData, sbDeviceEventBeforeAddedData);

  nsresult rv = beforeAddedData->Init(aDevice);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<sbIDeviceEventBeforeAddedData> retval = 
    do_QueryInterface(beforeAddedData, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  retval.forget(aBeforeAddedData);

  return NS_OK;
}
コード例 #16
0
NS_IMETHODIMP
sbLocalDatabaseMediaListBase::GetItemCountByProperty(const nsAString & aPropertyID,
                                                     const nsAString & aPropertyValue,
                                                     PRUint32 *_retval)
{
  NS_ENSURE_ARG_POINTER(_retval);

  nsRefPtr<sbLocalMediaListBaseEnumerationListener> enumerator;
  NS_NEWXPCOM(enumerator, sbLocalMediaListBaseEnumerationListener);
  NS_ENSURE_TRUE(enumerator, NS_ERROR_OUT_OF_MEMORY);

  nsresult rv = enumerator->Init();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = EnumerateItemsByProperty(aPropertyID,
                                aPropertyValue,
                                enumerator,
                                sbIMediaList::ENUMERATIONTYPE_LOCKING);
  NS_ENSURE_SUCCESS(rv, rv);

  return enumerator->GetArrayLength(_retval);
}
コード例 #17
0
ファイル: nsImageBoxFrame.cpp プロジェクト: ahadzi/celtx
NS_IMETHODIMP
nsImageBoxFrame::Init(nsIContent*      aContent,
                      nsIFrame*        aParent,
                      nsIFrame*        aPrevInFlow)
{
  if (!mListener) {
    nsImageBoxListener *listener;
    NS_NEWXPCOM(listener, nsImageBoxListener);
    NS_ADDREF(listener);
    listener->SetFrame(this);
    listener->QueryInterface(NS_GET_IID(imgIDecoderObserver), getter_AddRefs(mListener));
    NS_RELEASE(listener);
  }

  mSuppressStyleCheck = PR_TRUE;
  nsresult rv = nsLeafBoxFrame::Init(aContent, aParent, aPrevInFlow);
  mSuppressStyleCheck = PR_FALSE;

  UpdateLoadFlags();
  UpdateImage();

  return rv;
}
コード例 #18
0
static nsresult nsScriptableRegionConstructor(nsISupports *aOuter, REFNSIID aIID, void **aResult)
{
  nsresult rv;

  nsIScriptableRegion *inst = nsnull;

  if ( NULL == aResult )
  {
    rv = NS_ERROR_NULL_POINTER;
    return rv;
  }
  *aResult = NULL;
  if (NULL != aOuter)
  {
    rv = NS_ERROR_NO_AGGREGATION;
    return rv;
  }
  // create an nsRegionXlib and get the scriptable region from it
  nsCOMPtr <nsIRegion> rgn;
  NS_NEWXPCOM(rgn, nsRegionXlib);
  if (rgn != nsnull)
  {
    nsCOMPtr<nsIScriptableRegion> scriptableRgn = new nsScriptableRegion(rgn);
    inst = scriptableRgn;
  }
  if (NULL == inst)
  {
    rv = NS_ERROR_OUT_OF_MEMORY;
    return rv;
  }
  NS_ADDREF(inst);
  rv = inst->QueryInterface(aIID, aResult);
  NS_RELEASE(inst);

  return rv;
}
コード例 #19
0
NS_IMETHODIMP
sbLocalDatabaseMediaListBase::GetItemsByProperties(sbIPropertyArray *aProperties,
                                                   nsIArray **_retval)
{
  NS_ENSURE_ARG_POINTER(aProperties);
  NS_ENSURE_ARG_POINTER(_retval);

  nsRefPtr<sbLocalMediaListBaseEnumerationListener> enumerator;
  NS_NEWXPCOM(enumerator, sbLocalMediaListBaseEnumerationListener);
  NS_ENSURE_TRUE(enumerator, NS_ERROR_OUT_OF_MEMORY);

  nsresult rv = enumerator->Init();
  NS_ENSURE_SUCCESS(rv, rv);

  rv = EnumerateItemsByProperties(aProperties,
                                  enumerator,
                                  sbIMediaList::ENUMERATIONTYPE_LOCKING);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = enumerator->GetArray(_retval);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
コード例 #20
0
NS_IMETHODIMP 
sbDeviceFirmwareUpdater::RecoveryUpdate(sbIDevice *aDevice, 
                                        sbIDeviceFirmwareUpdate *aFirmwareUpdate,
                                        PRUint32 aDeviceVendorID,
                                        PRUint32 aDeviceProductID,
                                        sbIDeviceEventListener *aListener)
{
  LOG(("[sbDeviceFirmwareUpdater] - RecoveryUpdate"));

  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_FALSE(mIsShutdown, NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
  NS_ENSURE_ARG_POINTER(aDevice);

  nsresult rv = NS_ERROR_UNEXPECTED;

  nsCOMPtr<sbIDeviceFirmwareHandler> handler = 
    GetRunningHandler(aDevice, 
                      aDeviceVendorID, 
                      aDeviceProductID, 
                      aListener, 
                      PR_TRUE);

  nsAutoMonitor mon(mMonitor);

  sbDeviceFirmwareHandlerStatus *handlerStatus = GetHandlerStatus(handler);
  NS_ENSURE_TRUE(handlerStatus, NS_ERROR_OUT_OF_MEMORY);

  sbDeviceFirmwareHandlerStatus::handlerstatus_t status = 
    sbDeviceFirmwareHandlerStatus::STATUS_NONE;
  rv = handlerStatus->GetStatus(&status);
  NS_ENSURE_SUCCESS(rv, rv);

  if(status != sbDeviceFirmwareHandlerStatus::STATUS_NONE &&
     status != sbDeviceFirmwareHandlerStatus::STATUS_FINISHED) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<sbIDeviceEventTarget> eventTarget = do_QueryInterface(aDevice, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = eventTarget->AddEventListener(this);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = PutRunningHandler(aDevice, handler);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = handlerStatus->SetOperation(sbDeviceFirmwareHandlerStatus::OP_RECOVERY);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = handlerStatus->SetStatus(sbDeviceFirmwareHandlerStatus::STATUS_WAITING_FOR_START);
  NS_ENSURE_SUCCESS(rv, rv);

  mon.Exit();

  // This will determine if we need to cache the firmware update
  // or if it's already cached.
  PRBool needsCaching = PR_FALSE;

  // This will be the actual final firmware update we use.
  nsCOMPtr<sbIDeviceFirmwareUpdate> firmwareUpdate;

  // 'Default' firmware update, this may end up being the firmware update
  // passed in as an argument
  nsCOMPtr<sbIDeviceFirmwareUpdate> defaultFirmwareUpdate;

  // Cached firmware update
  nsCOMPtr<sbIDeviceFirmwareUpdate> cachedFirmwareUpdate;
  rv = GetCachedFirmwareUpdate(aDevice, getter_AddRefs(cachedFirmwareUpdate));
  LOG(("Using cached firmware update? %s", 
       NS_SUCCEEDED(rv) ? "true" : "false"));

  // No firmware update passed, use default one.
  if(!aFirmwareUpdate) {
    rv = handler->GetDefaultFirmwareUpdate(getter_AddRefs(defaultFirmwareUpdate));
    NS_ENSURE_SUCCESS(rv, rv);
  }
  else {
    //
    // Use specific firmware updated passed. In this case we assume 
    // it's available and has already been cached into the firmware cache
    // via a download.
    //
    // This isn't totally awesome, it would be nice to instead check the path
    // of the firmware image and see if it's in the firmware cache path already
    // or not. But even then one would have to make sure it's in the exact
    // path for the firmware cache for the device.
    //
    firmwareUpdate = aFirmwareUpdate;
    needsCaching = PR_FALSE;
  }

  // Check to make sure the cached firmware image is the same name
  // as the default one. If not, we need to delete the cached one and use
  // the default one. We'll also check the filesizes, if they don't match
  // we're going to prefer the default firmware instead.
  if(cachedFirmwareUpdate && defaultFirmwareUpdate) {
    nsCOMPtr<nsIFile> cachedFile;
    rv = cachedFirmwareUpdate->GetFirmwareImageFile(getter_AddRefs(cachedFile));
    NS_ENSURE_SUCCESS(rv, rv);

    nsCOMPtr<nsIFile> defaultFile;
    rv = defaultFirmwareUpdate->GetFirmwareImageFile(getter_AddRefs(defaultFile));
    NS_ENSURE_SUCCESS(rv, rv);

    nsString cachedFileName, defaultFileName;
    rv = cachedFile->GetLeafName(cachedFileName);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = defaultFile->GetLeafName(defaultFileName);
    NS_ENSURE_SUCCESS(rv, rv);

    PRInt64 cachedFileSize = 0;
    rv = cachedFile->GetFileSize(&cachedFileSize);
    NS_ENSURE_SUCCESS(rv, rv);

    PRInt64 defaultFileSize = 0;
    rv = defaultFile->GetFileSize(&defaultFileSize);
    NS_ENSURE_SUCCESS(rv, rv);

    if((cachedFileName != defaultFileName) || 
       (cachedFileName == defaultFileName && cachedFileSize != defaultFileSize)) {
      nsCOMPtr<nsIFile> cacheDir;
      rv = cachedFile->GetParent(getter_AddRefs(cacheDir));
      NS_ENSURE_SUCCESS(rv, rv);

      rv = cachedFile->Remove(PR_FALSE);
      NS_ENSURE_SUCCESS(rv, rv);

      nsCOMPtr<nsISimpleEnumerator> cacheDirEntries;
      rv = cacheDir->GetDirectoryEntries(getter_AddRefs(cacheDirEntries));
      NS_ENSURE_SUCCESS(rv, rv);

      PRBool hasMore = PR_FALSE;
      rv = cacheDirEntries->HasMoreElements(&hasMore);
      NS_ENSURE_SUCCESS(rv, rv);

      while(hasMore) {
        nsCOMPtr<nsIFile> file;
        rv = cacheDirEntries->GetNext(getter_AddRefs(file));
        NS_ENSURE_SUCCESS(rv, rv);

        PRBool isFile = PR_FALSE;
        rv = file->IsFile(&isFile);
        NS_ENSURE_SUCCESS(rv, rv);
        
        if(isFile) {
          rv = file->Remove(PR_FALSE);
          NS_ENSURE_SUCCESS(rv, rv);
        }

        rv = cacheDirEntries->HasMoreElements(&hasMore);
        NS_ENSURE_SUCCESS(rv, rv);
      }
        
      firmwareUpdate = defaultFirmwareUpdate;
      needsCaching = PR_TRUE;
    }
    else {
      firmwareUpdate = cachedFirmwareUpdate;
      needsCaching = PR_FALSE;
    }
  }
  else if(cachedFirmwareUpdate) {
    firmwareUpdate = cachedFirmwareUpdate;
  }
  else if(defaultFirmwareUpdate) {
    firmwareUpdate = defaultFirmwareUpdate;
    needsCaching = PR_TRUE;
  }
  else {
    return NS_ERROR_UNEXPECTED;
  }

  //
  // This isn't great to have to do this on the Main Thread
  // but the components required to cache the firmware update
  // are inherently NOT thread-safe and proxying to the main 
  // thread causes A LOT of badness as it pumps the main thread
  // at a really bad time almost EVERYTIME.
  //
  // Long term we'd probably want to do this copy in an async 
  // manner and then call this method again after the file has been cached.
  //
  // Yes, this sucks if it's a 100MB firmware image. But that's really, really
  // really, really rare :)
  //
  if(needsCaching) {
    nsString deviceModel;
    rv = handler->GetDeviceModelNumber(deviceModel);
    NS_ENSURE_SUCCESS(rv, rv);

    nsString deviceVendor;
    rv = handler->GetDeviceVendor(deviceVendor);
    NS_ENSURE_SUCCESS(rv, rv);

    if(deviceModel.IsVoid() || deviceVendor.IsVoid()) {
      nsCOMPtr<sbIDeviceFirmwareUpdate> cachedFirmwareUpdate;
      rv = sbDeviceFirmwareDownloader::CacheFirmwareUpdate(aDevice,
                                                           firmwareUpdate, 
                                                           getter_AddRefs(cachedFirmwareUpdate));
      NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
      nsString deviceCacheDirName(deviceVendor);
      deviceCacheDirName.AppendLiteral(" ");
      deviceCacheDirName += deviceModel;

      nsCOMPtr<sbIDeviceFirmwareUpdate> cachedFirmwareUpdate;
      rv = sbDeviceFirmwareDownloader::CacheFirmwareUpdate(aDevice,
                                                           deviceCacheDirName,
                                                           firmwareUpdate, 
                                                           getter_AddRefs(cachedFirmwareUpdate));
      NS_ENSURE_SUCCESS(rv, rv);
    }

    cachedFirmwareUpdate.swap(firmwareUpdate);
  }

  nsRefPtr<sbDeviceFirmwareUpdaterRunner> runner;
  NS_NEWXPCOM(runner, sbDeviceFirmwareUpdaterRunner);
  NS_ENSURE_TRUE(runner, NS_ERROR_OUT_OF_MEMORY);

  rv = runner->Init(aDevice, firmwareUpdate, handler, PR_TRUE);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = mThreadPool->Dispatch(runner, NS_DISPATCH_NORMAL);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
コード例 #21
0
NS_IMETHODIMP 
sbDeviceFirmwareUpdater::DownloadUpdate(sbIDevice *aDevice, 
                                        PRBool aVerifyFirmwareUpdate, 
                                        sbIDeviceEventListener *aListener)
{
  LOG(("[sbDeviceFirmwareUpdater] - DownloadUpdate"));

  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_FALSE(mIsShutdown, NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
  NS_ENSURE_ARG_POINTER(aDevice);

  nsresult rv = NS_ERROR_UNEXPECTED;

  nsCOMPtr<sbIDeviceFirmwareHandler> handler = 
    GetRunningHandler(aDevice, 0, 0, aListener, PR_TRUE);

  nsString deviceModel;
  rv = handler->GetDeviceModelNumber(deviceModel);
  NS_ENSURE_SUCCESS(rv, rv);

  nsString deviceVendor;
  rv = handler->GetDeviceVendor(deviceVendor);
  NS_ENSURE_SUCCESS(rv, rv);

  nsAutoMonitor mon(mMonitor);
  
  sbDeviceFirmwareHandlerStatus *handlerStatus = GetHandlerStatus(handler);
  NS_ENSURE_TRUE(handlerStatus, NS_ERROR_OUT_OF_MEMORY);

  sbDeviceFirmwareHandlerStatus::handlerstatus_t status = 
    sbDeviceFirmwareHandlerStatus::STATUS_NONE;
  rv = handlerStatus->GetStatus(&status);
  NS_ENSURE_SUCCESS(rv, rv);

  if(status != sbDeviceFirmwareHandlerStatus::STATUS_NONE &&
     status != sbDeviceFirmwareHandlerStatus::STATUS_FINISHED) {
    return NS_ERROR_FAILURE;
  }

  nsCOMPtr<sbIDeviceEventTarget> eventTarget = do_QueryInterface(aDevice, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = eventTarget->AddEventListener(this);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = PutRunningHandler(aDevice, handler);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = handlerStatus->SetOperation(sbDeviceFirmwareHandlerStatus::OP_DOWNLOAD);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = handlerStatus->SetStatus(sbDeviceFirmwareHandlerStatus::STATUS_WAITING_FOR_START);
  NS_ENSURE_SUCCESS(rv, rv);

  mon.Exit();

  nsRefPtr<sbDeviceFirmwareDownloader> downloader;
  NS_NEWXPCOM(downloader, sbDeviceFirmwareDownloader);
  NS_ENSURE_TRUE(downloader, NS_ERROR_OUT_OF_MEMORY);

  if(deviceModel.IsVoid() || deviceVendor.IsVoid()) {
    rv = downloader->Init(aDevice,
                          aListener,
                          handler);
    NS_ENSURE_SUCCESS(rv, rv);
  }
  else {
    nsString deviceCacheDirName(deviceVendor);
    deviceCacheDirName.AppendLiteral(" ");
    deviceCacheDirName += deviceModel;

    rv = downloader->Init(aDevice,
                          deviceCacheDirName,
                          aListener,
                          handler);
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Firmware Downloader is responsible for sending all necessary events.
  rv = downloader->Start();
  NS_ENSURE_SUCCESS(rv, rv);

  nsCOMPtr<sbIFileDownloaderListener> listener;
  if(mDownloaders.Get(aDevice, getter_AddRefs(listener))) {
    sbDeviceFirmwareDownloader *downloader = 
      reinterpret_cast<sbDeviceFirmwareDownloader *>(listener.get());
    
    rv = downloader->Cancel();
    NS_ENSURE_SUCCESS(rv, rv);

    mDownloaders.Remove(aDevice);
  }

  PRBool success = mDownloaders.Put(aDevice, downloader);
  NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);

  return NS_OK;
}
コード例 #22
0
/*virtual*/ nsresult 
sbGStreamerMediacoreFactory::OnGetCapabilities(
                             sbIMediacoreCapabilities **aCapabilities)
{
  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
  nsAutoMonitor mon(mMonitor);

  // TODO: This function is now a _huge_ mess. We should talk to product about
  // what files we want to import / etc, some time soon - e.g. the current
  // approach is to treat anything even vaguely-plausibly audio-related as
  // audio (even if we can't play it!), but to only import a small list of fixed
  // extensions for videos (excluding many things we might be able to play).

  nsresult rv;
  if (!mCapabilities) {
    nsRefPtr<sbMediacoreCapabilities> caps;
    NS_NEWXPCOM(caps, sbMediacoreCapabilities);
    NS_ENSURE_TRUE(caps, NS_ERROR_OUT_OF_MEMORY);

    rv = caps->Init();
    NS_ENSURE_SUCCESS(rv, rv);

    // Build a big list of extensions based on everything gstreamer knows about,
    // plus some known ones, minus a few known non-media-file extensions that
    // gstreamer has typefinders for.

    nsCOMPtr<nsIPrefBranch> rootPrefBranch =
      do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    nsTArray<nsString> audioExtensions;
    nsTArray<nsString> videoExtensions;
    
    // XXX Mook: we have a silly list of blacklisted extensions because we don't
    // support them and we're being stupid and guessing things based on them.
    // This crap should really look for a plugin that may possibly actually decode
    // these things, or something better.  Whatever the real solution is, this
    // isn't it :(
    nsCString blacklistExtensions;
    { // for scope
      const char defaultBlacklistExtensions[] =
        "txt,htm,html,xml,pdf,cpl,msstyles,scr,sys,ocx,bz2,gz,zip,Z,rar,tar,dll,"
        "exe,a,bmp,png,gif,jpeg,jpg,jpe,tif,tiff,xpm,dat,swf,swfl,stm,cgi,sf,xcf,"
        "far,wvc,mpc,mpp,mp+,ra,rm,rmvb";
      char* blacklistExtensionsPtr = nsnull;
      rv = rootPrefBranch->GetCharPref(BLACKLIST_EXTENSIONS_PREF,
                                       &blacklistExtensionsPtr);
      if (NS_SUCCEEDED(rv)) {
        blacklistExtensions.Adopt(blacklistExtensionsPtr);
      } else {
        blacklistExtensions.Assign(defaultBlacklistExtensions);
      }
      blacklistExtensions.Insert(',', 0);
      blacklistExtensions.Append(',');
      LOG(("sbGStreamerMediacoreFactory: blacklisted extensions: %s\n",
           blacklistExtensions.BeginReading()));
    }

    const char *extraAudioExtensions[] = {"m4r", "m4p", "oga",
                                          "ogg", "aac", "3gp"};
#ifdef XP_WIN
    const char *extraWindowsAudioExtensions[] = {"wma" };
#endif

    { // for scope

      // Per bug 19550 -
      // Severly limit the video extensions that are imported by default to:
      //   * ogv (all platforms)
      //   * wmv (windows only)
      //   * mp4/m4v/mov (w/ qtvideowrapper plugin)
      //   * divx/avi/mkv (w/ ewmpeg4dec plugin)
      videoExtensions.AppendElement(NS_LITERAL_STRING("ogv"));
#ifdef XP_WIN
      videoExtensions.AppendElement(NS_LITERAL_STRING("wmv"));
#endif

      char* knownVideoExtensionsPtr = nsnull;
      rv = rootPrefBranch->GetCharPref(VIDEO_EXTENSIONS_PREF,
                                       &knownVideoExtensionsPtr);
      if (NS_SUCCEEDED(rv)) {
        // The override video extension pref contains a CSV string.
        nsString_Split(NS_ConvertUTF8toUTF16(knownVideoExtensionsPtr),
                       NS_LITERAL_STRING(","),
                       videoExtensions);
      }

#ifdef PR_LOGGING
      nsString videoExtensionStr;
      for (PRUint32 i = 0; i < videoExtensions.Length(); i++) {
        videoExtensionStr.Append(videoExtensions[i]);
        if (i < videoExtensions.Length() - 1) {
          videoExtensionStr.AppendLiteral(", ");
        }
      }

      LOG(("sbGStreamerMediacoreFactory: video file extensions: %s\n",
            videoExtensionStr.get()));
#endif

      // Check for the 'qtvideowrapper' plugin to add mp4/m4v extensions.
      PRBool foundQTPlugin = PR_FALSE;
      GstPlugin *plugin = gst_default_registry_find_plugin("qtvideowrapper");
      if (plugin) {
        foundQTPlugin = PR_TRUE;
        videoExtensions.AppendElement(NS_LITERAL_STRING("mp4"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("m4v"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("mov"));
        gst_object_unref(plugin);
      }

      // Check for the 'ewmpeg4dec' plugin to add divx/avi extensions.
      plugin = gst_default_registry_find_plugin("ewmpeg4dec");
      if (plugin) {
        videoExtensions.AppendElement(NS_LITERAL_STRING("divx"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("avi"));
        videoExtensions.AppendElement(NS_LITERAL_STRING("mkv"));

        // This plugin will also handle "mp4" and "m4v", only append those
        // extensions if they haven't been added already.
        if (!foundQTPlugin) {
          videoExtensions.AppendElement(NS_LITERAL_STRING("mp4"));
          videoExtensions.AppendElement(NS_LITERAL_STRING("m4v"));
        }

        gst_object_unref(plugin);
      }
    }

    GList *walker, *list;

    list = gst_type_find_factory_get_list ();
    walker = list;
    while (walker) {
      GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walker->data);
      gboolean blacklisted = FALSE;
      const gchar* factoryName = gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory));
      gboolean isAudioFactory = g_str_has_prefix(factoryName, "audio/");

      gchar **factoryexts = gst_type_find_factory_get_extensions (factory);
      if (factoryexts) {
        while (*factoryexts) {
          gboolean isAudioExtension = isAudioFactory;
          nsCString extension(*factoryexts);
          nsCString delimitedExtension(extension);
          delimitedExtension.Insert(',', 0);
          delimitedExtension.Append(',');
          
          blacklisted = (blacklistExtensions.Find(delimitedExtension) != -1);
          #if PR_LOGGING
            if (blacklisted) {
                LOG(("sbGStreamerMediacoreFactory: Ignoring extension '%s'", *factoryexts));
            }
          #endif /* PR_LOGGING */

          if (!blacklisted && isAudioExtension) {
            audioExtensions.AppendElement(NS_ConvertUTF8toUTF16(*factoryexts));
            LOG(("sbGStreamerMediacoreFactory: registering audio extension %s\n",
                  *factoryexts));
          }

          factoryexts++;
        }
      }
      walker = g_list_next (walker);
    }
    g_list_free (list);

    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(extraAudioExtensions); i++) {
      nsString ext = NS_ConvertUTF8toUTF16(extraAudioExtensions[i]);
      if(!audioExtensions.Contains(ext))
        audioExtensions.AppendElement(ext);
    }

#if XP_WIN
    for (unsigned int i = 0; i < NS_ARRAY_LENGTH(extraWindowsAudioExtensions); i++) {
      nsString ext = NS_ConvertUTF8toUTF16(extraWindowsAudioExtensions[i]);
      if(!audioExtensions.Contains(ext))
        audioExtensions.AppendElement(ext);
    }
#endif

    rv = caps->SetAudioExtensions(audioExtensions);
    NS_ENSURE_SUCCESS(rv, rv);

    // Audio playback is always allowed.
    rv = caps->SetSupportsAudioPlayback(PR_TRUE);
    NS_ENSURE_SUCCESS(rv, rv);

    PRBool videoDisabled = PR_FALSE;
    rv = rootPrefBranch->GetBoolPref(
                                    "songbird.mediacore.gstreamer.disablevideo",
                                    &videoDisabled);
    NS_ENSURE_SUCCESS(rv, rv);
    if (!videoDisabled) {
      rv = caps->SetVideoExtensions(videoExtensions);
      NS_ENSURE_SUCCESS(rv, rv);

      rv = caps->SetSupportsVideoPlayback(PR_TRUE);
      NS_ENSURE_SUCCESS(rv, rv);
    }

    mCapabilities = caps;
  }

  rv = CallQueryInterface(mCapabilities.get(), aCapabilities);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
コード例 #23
0
/**
 * See sbIMediaList
 */
NS_IMETHODIMP
sbLocalDatabaseMediaListBase::EnumerateItemsByProperties(sbIPropertyArray* aProperties,
                                                         sbIMediaListEnumerationListener* aEnumerationListener,
                                                         PRUint16 aEnumerationType)
{
  NS_ENSURE_ARG_POINTER(aProperties);
  NS_ENSURE_ARG_POINTER(aEnumerationListener);

  PRUint32 propertyCount;
  nsresult rv = aProperties->GetLength(&propertyCount);
  NS_ENSURE_SUCCESS(rv, rv);

  // It doesn't make sense to call this method without specifying any properties
  // so it is probably a caller error if we have none.
  NS_ENSURE_STATE(propertyCount);

  // The guidArray needs AddFilter called only once per property with an
  // enumerator that contains all the values. We were given an array of
  // id/value pairs, so this is a little tricky. We make a hash table that
  // uses the property id for a key and an array of values as its data. Then
  // we load the arrays in a loop and finally call AddFilter as an enumeration
  // function.

  sbStringArrayHash propertyHash;

  // Init with the propertyCount as the number of buckets to create. This will
  // probably be too many, but it's likely less than the default of 16.
  propertyHash.Init(propertyCount);

  nsCOMPtr<sbIPropertyManager> propMan =
    do_GetService(SB_PROPERTYMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  // Load the hash table with properties from the array.
  for (PRUint32 index = 0; index < propertyCount; index++) {

    // Get the property.
    nsCOMPtr<sbIProperty> property;
    rv = aProperties->GetPropertyAt(index, getter_AddRefs(property));
    SB_CONTINUE_IF_FAILED(rv);

    // Get the id of the property. This will be the key for the hash table.
    nsString propertyID;
    rv = property->GetId(propertyID);
    SB_CONTINUE_IF_FAILED(rv);

    // Get the string array associated with the key. If it doesn't yet exist
    // then we need to create it.
    sbStringArray* stringArray;
    bool arrayExists = propertyHash.Get(propertyID, &stringArray);
    if (!arrayExists) {
      NS_NEWXPCOM(stringArray, sbStringArray);
      SB_CONTINUE_IF_FALSE(stringArray);

      // Try to add the array to the hash table.
      bool success = propertyHash.Put(propertyID, stringArray);
      if (!success) {
        NS_WARNING("Failed to add string array to property hash!");

        // Make sure to delete the new array, otherwise it will leak.
        NS_DELETEXPCOM(stringArray);
        continue;
      }
    }
    NS_ASSERTION(stringArray, "Must have a valid pointer here!");

    // Now we need a slot for the property value.
    nsString* valueString = stringArray->AppendElement();
    SB_CONTINUE_IF_FALSE(valueString);

    // Make the value sortable and assign it
    nsCOMPtr<sbIPropertyInfo> info;
    rv = propMan->GetPropertyInfo(propertyID, getter_AddRefs(info));
    SB_CONTINUE_IF_FAILED(rv);

    nsAutoString value;
    rv = property->GetValue(value);
    SB_CONTINUE_IF_FAILED(rv);

    nsAutoString sortableValue;
    rv = info->MakeSortable(value, *valueString);
    SB_CONTINUE_IF_FAILED(rv);
  }

  switch (aEnumerationType) {

    case sbIMediaList::ENUMERATIONTYPE_LOCKING: {
      NS_ENSURE_TRUE(mFullArrayMonitor, NS_ERROR_FAILURE);
      nsAutoMonitor mon(mFullArrayMonitor);

      // Don't reenter!
      NS_ENSURE_FALSE(mLockedEnumerationActive, NS_ERROR_FAILURE);
      mLockedEnumerationActive = PR_TRUE;

      PRUint16 stepResult;
      rv = aEnumerationListener->OnEnumerationBegin(this, &stepResult);

      if (NS_SUCCEEDED(rv)) {
        if (stepResult == sbIMediaListEnumerationListener::CONTINUE) {
          rv = EnumerateItemsByPropertiesInternal(&propertyHash,
                                                  aEnumerationListener);
        }
        else {
          // The user cancelled the enumeration.
          rv = NS_ERROR_ABORT;
        }
      }

      mLockedEnumerationActive = PR_FALSE;

    } break; // ENUMERATIONTYPE_LOCKING

    case sbIMediaList::ENUMERATIONTYPE_SNAPSHOT: {
      PRUint16 stepResult;
      rv = aEnumerationListener->OnEnumerationBegin(this, &stepResult);

      if (NS_SUCCEEDED(rv)) {
        if (stepResult == sbIMediaListEnumerationListener::CONTINUE) {
          rv = EnumerateItemsByPropertiesInternal(&propertyHash,
                                                  aEnumerationListener);
        }
        else {
          // The user cancelled the enumeration.
          rv = NS_ERROR_ABORT;
        }
      }
    } break; // ENUMERATIONTYPE_SNAPSHOT

    default: {
      NS_NOTREACHED("Invalid enumeration type");
      rv = NS_ERROR_INVALID_ARG;
    } break;
  }

  aEnumerationListener->OnEnumerationEnd(this, rv);
  return NS_OK;
}
コード例 #24
0
NS_IMETHODIMP 
sbDeviceFirmwareUpdater::ApplyUpdate(sbIDevice *aDevice, 
                                     sbIDeviceFirmwareUpdate *aFirmwareUpdate, 
                                     sbIDeviceEventListener *aListener)
{
  LOG(("[sbDeviceFirmwareUpdater] - ApplyUpdate"));

  NS_ENSURE_TRUE(mMonitor, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_FALSE(mIsShutdown, NS_ERROR_ILLEGAL_DURING_SHUTDOWN);
  NS_ENSURE_ARG_POINTER(aDevice);
  NS_ENSURE_ARG_POINTER(aFirmwareUpdate);

  nsresult rv = NS_ERROR_UNEXPECTED;

  nsCOMPtr<sbIDeviceFirmwareHandler> handler = 
    GetRunningHandler(aDevice, 0, 0, aListener, PR_TRUE);

  nsAutoMonitor mon(mMonitor);

  sbDeviceFirmwareHandlerStatus *handlerStatus = GetHandlerStatus(handler);
  NS_ENSURE_TRUE(handlerStatus, NS_ERROR_OUT_OF_MEMORY);

  sbDeviceFirmwareHandlerStatus::handlerstatus_t status = 
    sbDeviceFirmwareHandlerStatus::STATUS_NONE;
  rv = handlerStatus->GetStatus(&status);
  NS_ENSURE_SUCCESS(rv, rv);

  if(status != sbDeviceFirmwareHandlerStatus::STATUS_NONE &&
     status != sbDeviceFirmwareHandlerStatus::STATUS_FINISHED) {
    return NS_ERROR_FAILURE;
  }


  nsCOMPtr<sbIDeviceEventTarget> eventTarget = do_QueryInterface(aDevice, &rv);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = eventTarget->AddEventListener(this);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = PutRunningHandler(aDevice, handler);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = handlerStatus->SetOperation(sbDeviceFirmwareHandlerStatus::OP_UPDATE);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = handlerStatus->SetStatus(sbDeviceFirmwareHandlerStatus::STATUS_WAITING_FOR_START);
  NS_ENSURE_SUCCESS(rv, rv);

  mon.Exit();

  nsRefPtr<sbDeviceFirmwareUpdaterRunner> runner;
  NS_NEWXPCOM(runner, sbDeviceFirmwareUpdaterRunner);
  NS_ENSURE_TRUE(runner, NS_ERROR_OUT_OF_MEMORY);

  rv = runner->Init(aDevice, aFirmwareUpdate, handler);
  NS_ENSURE_SUCCESS(rv, rv);

  rv = mThreadPool->Dispatch(runner, NS_DISPATCH_NORMAL);
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
コード例 #25
0
// typedef PRBool
// (* nsHashtableEnumFunc)
//      (nsHashKey *aKey, void *aData, void* aClosure);
PRBool
CheckLDAPOperationResult(nsHashKey *aKey, void *aData, void* aClosure)
{
    int lderrno;
    nsresult rv;
    PRInt32 returnCode;
    LDAPMessage *msgHandle;
    nsCOMPtr<nsILDAPMessage> msg;
    PRBool operationFinished = PR_TRUE;
    struct timeval timeout = { 0, 0 }; 
    PRIntervalTime sleepTime = PR_MillisecondsToInterval(40);

    // we need to access some of the connection loop's objects
    //
    nsLDAPConnectionLoop *loop = 
        static_cast<nsLDAPConnectionLoop *>(aClosure);

    // get the console service so we can log messages
    //
    nsCOMPtr<nsIConsoleService> consoleSvc = 
        do_GetService(kConsoleServiceContractId, &rv);
    if (NS_FAILED(rv)) {
        NS_ERROR("CheckLDAPOperationResult() couldn't get console service");
        return NS_ERROR_FAILURE;
    }

    returnCode = ldap_result(loop->mRawConn->mConnectionHandle,
                             aKey->HashCode(), LDAP_MSG_ONE,
                                 &timeout, &msgHandle);

        // if we didn't error or timeout, create an nsILDAPMessage
        //      
        switch (returnCode) {

        case 0: // timeout

            // the connection may not exist yet.  sleep for a while
            // to avoid a problem where the LDAP connection/thread isn't 
            // ready quite yet, and we want to avoid a very busy loop.
            //
            PR_Sleep(sleepTime);
            return PR_TRUE;

        case -1: // something went wrong 

        lderrno = ldap_get_lderrno(loop->mRawConn->mConnectionHandle, 0, 0);

            // Sleep briefly, to avoid a very busy loop again.
            //
            PR_Sleep(sleepTime);

            switch (lderrno) {

            case LDAP_SERVER_DOWN:
                // We might want to shutdown the thread here, but it has
                // implications to the user of the nsLDAPConnection, so
                // for now we just ignore it. It's up to the owner of
                // the nsLDAPConnection to detect the error, and then
                // create a new connection.
                //
                PR_LOG(gLDAPLogModule, PR_LOG_DEBUG, 
                       ("CheckLDAPOperationResult(): ldap_result returned" 
                        " LDAP_SERVER_DOWN"));
                break;

            case LDAP_DECODING_ERROR:
                consoleSvc->LogStringMessage(
                    NS_LITERAL_STRING("LDAP: WARNING: decoding error; possible corrupt data received").get());
                NS_WARNING("CheckLDAPOperationResult(): ldaperrno = "
                           "LDAP_DECODING_ERROR after ldap_result()");
                break;

            case LDAP_NO_MEMORY:
                NS_ERROR("CheckLDAPOperationResult(): Couldn't allocate memory"
                         " while getting async operation result");
                // punt and hope things work out better next time around
                break;

            case LDAP_PARAM_ERROR:
                // I think it's possible to hit a race condition where we're
                // continuing to poll for a result after the C SDK connection
                // has removed the operation because the connection has gone
                // dead.  In theory we should fix this.  Practically, it's
                // unclear to me whether it matters.
                //
                NS_WARNING("CheckLDAPOperationResult(): ldap_result returned"
                           " LDAP_PARAM_ERROR");
                break;

            default:
                NS_ERROR("CheckLDAPOperationResult(): lderrno set to "
                           "unexpected value after ldap_result() "
                           "call in nsLDAPConnection::Run()");
                PR_LOG(gLDAPLogModule, PR_LOG_ERROR, 
                       ("lderrno = 0x%x", lderrno));
                break;
            }
            break;

        case LDAP_RES_SEARCH_ENTRY:
        case LDAP_RES_SEARCH_REFERENCE:
            // XXX what should we do with LDAP_RES_SEARCH_EXTENDED?

            // not done yet, so we shouldn't remove the op from the conn q
            operationFinished = PR_FALSE;

            // fall through to default case

        default: // initialize the message and call the callback

            // we want nsLDAPMessage specifically, not a compatible, since
            // we're sharing native objects used by the LDAP C SDK
            //
            nsLDAPMessage *rawMsg;
            NS_NEWXPCOM(rawMsg, nsLDAPMessage);
            if (!rawMsg) {
            NS_ERROR("CheckLDAPOperationResult(): couldn't allocate memory"
                     " for new LDAP message; search entry dropped");
                // punt and hope things work out better next time around
                break;
            }

            // initialize the message, using a protected method not available
            // through nsILDAPMessage (which is why we need the raw pointer)
            //
            rv = rawMsg->Init(loop->mRawConn, msgHandle);

            // now let the scoping mechanisms provided by nsCOMPtr manage
            // the reference for us.
            //
            msg = rawMsg;
            
            switch (rv) {

            case NS_OK: {
                PRInt32 errorCode;
                rawMsg->GetErrorCode(&errorCode);
                // maybe a version error, e.g., using v3 on a v2 server.
                // if we're using v3, try v2.
                //
                if (errorCode == LDAP_PROTOCOL_ERROR && 
                   loop->mRawConn->mVersion == nsILDAPConnection::VERSION3) {
                    nsCAutoString password;
                    loop->mRawConn->mVersion = nsILDAPConnection::VERSION2;
                    ldap_set_option(loop->mRawConn->mConnectionHandle,
                          LDAP_OPT_PROTOCOL_VERSION, &loop->mRawConn->mVersion);
                    nsCOMPtr <nsILDAPOperation> operation = 
                      static_cast<nsILDAPOperation *>(static_cast<nsISupports *>(aData));
                    // we pass in an empty password to tell the operation that 
                    // it should use the cached password.
                    //
                    rv = operation->SimpleBind(password);
                    if (NS_SUCCEEDED(rv)) {
                        operationFinished = PR_FALSE;
                        // we don't want to notify callers that we're done...
                        return PR_TRUE;
                    }
                }
                
                // If we're midway through a SASL Bind, we need to continue
                // without letting our caller know what we're up to!
                //
                if (errorCode == LDAP_SASL_BIND_IN_PROGRESS) {
                    struct berval *creds;
                    ldap_parse_sasl_bind_result(
                      loop->mRawConn->mConnectionHandle, msgHandle, 
                      &creds, 0);

                    nsCOMPtr <nsILDAPOperation> operation =
                      static_cast<nsILDAPOperation *>
                      (static_cast<nsISupports *>(aData));

                    rv = operation->SaslStep(creds->bv_val, creds->bv_len);
                    if (NS_SUCCEEDED(rv)) {
                        return PR_TRUE;
                    }
                }
            }
            break;

            case NS_ERROR_LDAP_DECODING_ERROR:
                consoleSvc->LogStringMessage(
                    NS_LITERAL_STRING("LDAP: WARNING: decoding error; possible corrupt data received").get());
            NS_WARNING("CheckLDAPOperationResult(): ldaperrno = "
                           "LDAP_DECODING_ERROR after ldap_result()");
            return PR_TRUE;

            case NS_ERROR_OUT_OF_MEMORY:
                // punt and hope things work out better next time around
            return PR_TRUE;

            case NS_ERROR_ILLEGAL_VALUE:
            case NS_ERROR_UNEXPECTED:
            default:
                // shouldn't happen; internal error
                //
            NS_ERROR("CheckLDAPOperationResult(): nsLDAPMessage::Init() "
                           "returned unexpected value.");

                // punt and hope things work out better next time around
            return PR_TRUE;
            }

            // invoke the callback on the nsILDAPOperation corresponding to 
            // this message
            //
        rv = loop->mRawConn->InvokeMessageCallback(msgHandle, msg, 
                                                    operationFinished);
            if (NS_FAILED(rv)) {
            NS_ERROR("CheckLDAPOperationResult(): error invoking message"
                     " callback");
                // punt and hope things work out better next time around
            return PR_TRUE;
            }

            break;
        }       

    return PR_TRUE;
}