mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-28 11:28:38 +00:00
1546 lines
35 KiB
C++
1546 lines
35 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS"
|
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
|
* the License for the specific language governing rights and limitations
|
|
* under the License.
|
|
*
|
|
* The Original Code is Mozilla Communicator client code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape Communications
|
|
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
|
* Netscape Communications Corporation. All Rights Reserved.
|
|
*/
|
|
|
|
|
|
#include "nsSilentDownload.h"
|
|
#include "nsSilentDownloadPrivate.h"
|
|
|
|
#include "nscore.h"
|
|
#include "nsIFactory.h"
|
|
#include "nsISupports.h"
|
|
|
|
#include "nsIComponentManager.h"
|
|
|
|
#include "nsIScriptObjectOwner.h"
|
|
#include "nsIScriptGlobalObject.h"
|
|
|
|
#include "pratom.h"
|
|
#include "prmem.h"
|
|
#include "prio.h"
|
|
#include "mkutils.h"
|
|
#include "prefapi.h"
|
|
|
|
#include "nsIURL.h"
|
|
#include "nsINetlibURL.h"
|
|
#include "nsINetService.h"
|
|
#include "nsIInputStream.h"
|
|
#include "nsIStreamListener.h"
|
|
|
|
#include "nsIDOMSilentDownload.h"
|
|
#include "nsIDOMSilentDownloadTask.h"
|
|
|
|
/* For Javascript Namespace Access */
|
|
#include "nsDOMCID.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsINameSpaceManager.h"
|
|
#include "nsIScriptNameSetRegistry.h"
|
|
#include "nsIScriptNameSpaceManager.h"
|
|
#include "nsIScriptExternalNameSet.h"
|
|
|
|
#include "nsITimer.h"
|
|
#include "nsITimerCallback.h"
|
|
|
|
#include "nsIBrowserWindow.h"
|
|
#include "nsIWebShell.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsCOMPtr.h"
|
|
|
|
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
|
|
|
// Globals
|
|
|
|
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
|
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
|
static NS_DEFINE_IID(kIScriptObjectOwnerIID, NS_ISCRIPTOBJECTOWNER_IID);
|
|
|
|
static NS_DEFINE_IID(kIScriptNameSetRegistryIID, NS_ISCRIPTNAMESETREGISTRY_IID);
|
|
static NS_DEFINE_IID(kCScriptNameSetRegistryCID, NS_SCRIPT_NAMESET_REGISTRY_CID);
|
|
static NS_DEFINE_IID(kIScriptExternalNameSetIID, NS_ISCRIPTEXTERNALNAMESET_IID);
|
|
|
|
static NS_DEFINE_IID(kInetServiceIID, NS_INETSERVICE_IID);
|
|
static NS_DEFINE_IID(kInetServiceCID, NS_NETSERVICE_CID);
|
|
static NS_DEFINE_IID(kInetLibURLIID, NS_INETLIBURL_IID);
|
|
static NS_DEFINE_IID(kIStreamListenerIID, NS_ISTREAMLISTENER_IID);
|
|
|
|
static NS_DEFINE_IID(kBrowserWindowCID, NS_BROWSER_WINDOW_CID);
|
|
static NS_DEFINE_IID(kIBrowserWindowIID, NS_IBROWSER_WINDOW_IID);
|
|
|
|
static NS_DEFINE_IID(kISilentDownloadTaskIID, NS_IDOMSILENTDOWNLOADTASK_IID);
|
|
static NS_DEFINE_IID(kISilentDownloadIID, NS_IDOMSILENTDOWNLOAD_IID);
|
|
static NS_DEFINE_IID(kSilentDownloadCID, NS_SilentDownload_CID);
|
|
static NS_DEFINE_IID(kSilentDownloadTaskCID, NS_SilentDownloadTask_CID);
|
|
static NS_DEFINE_IID(kSilentDownloadFactoryCID, NS_SilentDownloadFactory_CID);
|
|
static NS_DEFINE_IID(kSilentDownloadTaskFactoryCID, NS_SilentDownloadTaskFactory_CID);
|
|
|
|
|
|
|
|
|
|
static PRInt32 gLockCnt = 0;
|
|
static PRInt32 gInstanceCnt = 0;
|
|
|
|
static nsITimer *gTaskTimer = nsnull;
|
|
static nsINetService *gInetService = nsnull;
|
|
static SDL_TaskList *gTasks = nsnull;
|
|
static SDL_TaskList *gNextReadyTask = nsnull;
|
|
|
|
static PRInt32 gByteRange = 0;
|
|
static PRInt32 gInterval = 0xFFFF;
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// static helper meathods
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
static int32
|
|
GetCurrentSize(char *file)
|
|
{
|
|
struct stat in_stat;
|
|
int stat_result = -1;
|
|
stat_result = stat(file, &in_stat);
|
|
if (stat_result == 0) {
|
|
return in_stat.st_size;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static char*
|
|
AssureDir(char* path)
|
|
{
|
|
char *autoupdt_dir = PR_smprintf("%sSilentDL", path);
|
|
if (PR_SUCCESS != PR_Access(autoupdt_dir, PR_ACCESS_WRITE_OK)) {
|
|
if ((PR_MkDir(autoupdt_dir, 0777)) < 0) {
|
|
/* Creation of directory failed. Don't do SilentDownload. */
|
|
return NULL;
|
|
}
|
|
}
|
|
return autoupdt_dir;
|
|
}
|
|
|
|
static void
|
|
GetSilentDownloadDirectory(char* directory)
|
|
{
|
|
if (PREF_OK != PREF_CopyCharPref("SilentDownload.directory", (char**)directory))
|
|
{
|
|
directory = NULL;
|
|
}
|
|
else
|
|
{
|
|
if ((directory) && (XP_STRCMP(directory, "") == 0))
|
|
{
|
|
directory = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
GetSilentDownloadDefaults(PRBool* enabled, PRInt32 *bytes_range, PRInt32 *interval)
|
|
{
|
|
*enabled = PR_FALSE;
|
|
*bytes_range = 0;
|
|
*interval = 0;
|
|
|
|
PREF_GetBoolPref( "SilentDownload.enabled", enabled);
|
|
if (*enabled == PR_FALSE)
|
|
return;
|
|
|
|
|
|
if (PREF_OK != PREF_GetIntPref("SilentDownload.range", bytes_range))
|
|
{
|
|
*bytes_range = 3000;
|
|
}
|
|
|
|
if (PREF_OK != PREF_GetIntPref("SilentDownload.interval", interval))
|
|
{
|
|
*interval = 10000;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
CreateOutFileLocation(char* url, char* directory)
|
|
{
|
|
/* FIX: The outfile that this functions creates must be compatible with
|
|
PR_Open!
|
|
*/
|
|
char* outfile = NULL;
|
|
|
|
char* autoupdt_dir;
|
|
char* slash;
|
|
char* filename;
|
|
char Path[1024 + 1];
|
|
|
|
slash = PL_strrchr(url, '/');
|
|
if (slash != NULL)
|
|
{
|
|
filename = ++slash;
|
|
}
|
|
else
|
|
{
|
|
filename = "prg";
|
|
}
|
|
|
|
|
|
#ifdef XP_UNIX
|
|
|
|
if (directory)
|
|
{
|
|
/* what if the directory already has a / appended to it? */
|
|
PR_snprintf( Path, MAXPATHLEN, "%s/", directory);
|
|
PR_FREEIF(directory);
|
|
}
|
|
else
|
|
{
|
|
directory = getenv("MOZILLA_FIVE_HOME");
|
|
if (directory)
|
|
{
|
|
PR_snprintf( Path, MAXPATHLEN, "%s/", directory);
|
|
}
|
|
else
|
|
{
|
|
extern void fe_GetProgramDirectory( char *, int );
|
|
//fe_GetProgramDirectory( Path, MAXPATHLEN-1 );
|
|
}
|
|
}
|
|
|
|
autoupdt_dir = AssureDir(Path);
|
|
|
|
if (autoupdt_dir != NULL)
|
|
{
|
|
outfile = PR_smprintf("%s/%s", autoupdt_dir, filename);
|
|
PR_FREEIF(autoupdt_dir);
|
|
}
|
|
|
|
#elif defined(WIN32)
|
|
|
|
if (directory)
|
|
{
|
|
PR_snprintf( Path, MAXPATHLEN, "%s\\", directory);
|
|
PR_FREEIF(directory);
|
|
}
|
|
else
|
|
{
|
|
PR_snprintf( Path, MAXPATHLEN, "C:\\Temp\\");
|
|
extern char * FE_GetProgramDirectory(char *buffer, int length);
|
|
//FE_GetProgramDirectory( Path, _MAX_PATH );
|
|
}
|
|
|
|
autoupdt_dir = AssureDir(Path);
|
|
if (autoupdt_dir != NULL)
|
|
{
|
|
outfile = PR_smprintf("%s\\%s", autoupdt_dir, filename);
|
|
PR_FREEIF(autoupdt_dir);
|
|
}
|
|
|
|
#elif defined(MAC)
|
|
|
|
/* XXX: Fix it for Mac with the correct folder */
|
|
|
|
if (directory)
|
|
{
|
|
PR_snprintf( Path, MAXPATHLEN, "%s:", directory);
|
|
PR_FREEIF(directory);
|
|
}
|
|
else
|
|
{
|
|
directory = XP_TempDirName();
|
|
PR_snprintf( Path, MAXPATHLEN, "%s:", directory);
|
|
}
|
|
|
|
outfile = PR_smprintf("%s:%s", Path, filename);
|
|
|
|
#else
|
|
outfile = NULL;
|
|
#endif
|
|
|
|
return outfile;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// nsSilentDownloadManager
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
nsSilentDownloadManager::nsSilentDownloadManager()
|
|
{
|
|
mScriptObject = nsnull;
|
|
|
|
PR_AtomicIncrement(&gInstanceCnt);
|
|
NS_INIT_REFCNT();
|
|
|
|
Startup();
|
|
}
|
|
|
|
|
|
nsSilentDownloadManager::~nsSilentDownloadManager()
|
|
{
|
|
PR_AtomicDecrement(&gInstanceCnt);
|
|
Shutdown();
|
|
}
|
|
|
|
nsresult
|
|
nsSilentDownloadManager::LoadAllTasks(void)
|
|
{
|
|
gNextReadyTask = gTasks;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsSilentDownloadManager::StoreAllTasks(void)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMPL_ADDREF(nsSilentDownloadManager)
|
|
NS_IMPL_RELEASE(nsSilentDownloadManager)
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
{
|
|
if (aInstancePtr == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
// Always NULL result, in case of failure
|
|
*aInstancePtr = NULL;
|
|
|
|
|
|
if ( aIID.Equals(kISilentDownloadIID) )
|
|
{
|
|
nsIDOMSilentDownload* tmp = this;
|
|
*aInstancePtr = (void*)tmp;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
else if ( aIID.Equals(kIScriptObjectOwnerIID))
|
|
{
|
|
nsIScriptObjectOwner* tmp = this;
|
|
*aInstancePtr = (void*)tmp;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
else if ( aIID.Equals(kISupportsIID) )
|
|
{
|
|
|
|
nsIDOMSilentDownload* tmp1 = this;
|
|
nsISupports* tmp2 = tmp1;
|
|
|
|
*aInstancePtr = (void*)tmp2;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
|
{
|
|
nsresult res = NS_OK;
|
|
|
|
if (nsnull == mScriptObject)
|
|
{
|
|
nsIScriptGlobalObject *global = aContext->GetGlobalObject();
|
|
|
|
res = NS_NewScriptSilentDownload(aContext, (nsISupports *)(nsIDOMSilentDownload*)this, global, (void**)&mScriptObject);
|
|
|
|
NS_IF_RELEASE(global);
|
|
}
|
|
|
|
|
|
*aScriptObject = mScriptObject;
|
|
return res;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::SetScriptObject(void *aScriptObject)
|
|
{
|
|
mScriptObject = aScriptObject;
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsSilentDownloadManager::Notify(nsITimer * aTimer)
|
|
{
|
|
/* Fix: maybe some additional check on gNextReadyTask */
|
|
|
|
if (gTasks != NULL && gNextReadyTask != NULL)
|
|
{
|
|
if (! gInetService->AreThereActiveConnections() )
|
|
{
|
|
gNextReadyTask->task->DownloadSelf(gByteRange);
|
|
|
|
if (gNextReadyTask->next == NULL)
|
|
{
|
|
gNextReadyTask = gTasks;
|
|
}
|
|
else
|
|
{
|
|
gNextReadyTask = gNextReadyTask->next;
|
|
}
|
|
}
|
|
}
|
|
|
|
NS_RELEASE(gTaskTimer);
|
|
|
|
if (NS_OK == NS_NewTimer(&gTaskTimer))
|
|
gTaskTimer->Init(this, gInterval);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::Startup()
|
|
{
|
|
PRBool enabled = PR_FALSE;
|
|
|
|
GetSilentDownloadDefaults(&enabled, &gByteRange, &gInterval);
|
|
|
|
if (enabled == PR_FALSE)
|
|
return -1;
|
|
|
|
|
|
/***************************************/
|
|
/* Add us to the Javascript Name Space */
|
|
/***************************************/
|
|
|
|
nsIScriptNameSetRegistry *registry;
|
|
nsresult result = nsServiceManager::GetService(kCScriptNameSetRegistryCID,
|
|
kIScriptNameSetRegistryIID,
|
|
(nsISupports **)®istry);
|
|
if (NS_OK == result)
|
|
{
|
|
nsSilentDownloadNameSet* nameSet = new nsSilentDownloadNameSet();
|
|
registry->AddExternalNameSet(nameSet);
|
|
/* FIX - do we need to release this service? When we do, it get deleted,and our name is lost. */
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* Create an instance of INet so that we can see if the network is busy */
|
|
/************************************************************************/
|
|
|
|
result = nsComponentManager::CreateInstance(kInetServiceCID,
|
|
nsnull,
|
|
kInetServiceIID,
|
|
(void**)&gInetService);
|
|
|
|
if (result != NS_OK)
|
|
return result;
|
|
|
|
/************************/
|
|
/* Load all saved tasks */
|
|
/************************/
|
|
result = LoadAllTasks();
|
|
|
|
if (result != NS_OK)
|
|
return result;
|
|
|
|
/************************/
|
|
/* Start Timer */
|
|
/************************/
|
|
|
|
if (NS_OK == NS_NewTimer(&gTaskTimer))
|
|
gTaskTimer->Init(this, gInterval);
|
|
|
|
return result;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::Shutdown()
|
|
{
|
|
StoreAllTasks();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::Add(nsIDOMSilentDownloadTask* aTask)
|
|
{
|
|
|
|
if (aTask == NULL)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
/* Check to see if we already have this task in our list */
|
|
SDL_TaskList *node = gTasks;
|
|
nsString nodeIDString;
|
|
nsString addIDString;
|
|
|
|
aTask->GetId(addIDString);
|
|
|
|
while (node != NULL)
|
|
{
|
|
node->task->GetId(nodeIDString);
|
|
|
|
if (nodeIDString == addIDString)
|
|
{
|
|
/*we already have this ID in our list, ignore */
|
|
return NS_OK;
|
|
}
|
|
|
|
node = node->next;
|
|
}
|
|
|
|
/* add the task to our list */
|
|
SDL_TaskList* taskNode = (SDL_TaskList*)PR_MALLOC(sizeof(SDL_TaskList));
|
|
|
|
aTask->AddRef();
|
|
|
|
taskNode->next = gTasks;
|
|
taskNode->task = aTask;
|
|
gTasks = taskNode;
|
|
|
|
/* Lets set the next task to run to this one */
|
|
gNextReadyTask = taskNode;
|
|
|
|
aTask->SetState(nsIDOMSilentDownloadTask::SDL_STARTED);
|
|
|
|
return NS_OK;
|
|
}
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::Remove(nsIDOMSilentDownloadTask* aTask)
|
|
{
|
|
if (aTask == NULL)
|
|
return NS_ERROR_FAILURE;
|
|
|
|
/* Remove from our list */
|
|
|
|
SDL_TaskList *node = gTasks;
|
|
SDL_TaskList *lastnode = gTasks;
|
|
nsString nodeIDString;
|
|
nsString doomedIDString;
|
|
|
|
aTask->GetId(doomedIDString);
|
|
|
|
while (node != NULL)
|
|
{
|
|
node->task->GetId(nodeIDString);
|
|
|
|
if (nodeIDString == doomedIDString)
|
|
{
|
|
/* we want to delete this node */
|
|
|
|
if (node == gTasks)
|
|
{
|
|
gTasks = node->next;
|
|
}
|
|
else
|
|
{
|
|
lastnode->next = node->next;
|
|
}
|
|
|
|
node->task->Release();
|
|
PR_DELETE(node);
|
|
break;
|
|
}
|
|
|
|
lastnode = node;
|
|
node = node->next;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::Find(const nsString& aId, nsIDOMSilentDownloadTask** aReturn)
|
|
{
|
|
*aReturn=nsnull;
|
|
|
|
SDL_TaskList *node = gTasks;
|
|
nsString nodeIDString;
|
|
|
|
while (node != NULL)
|
|
{
|
|
node->task->GetId(nodeIDString);
|
|
|
|
if (nodeIDString == aId)
|
|
{
|
|
*aReturn = node->task;
|
|
node->task->AddRef();
|
|
break;
|
|
}
|
|
node = node->next;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::GetByteRange(PRInt32* aByterange)
|
|
{
|
|
*aByterange = gByteRange;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::SetByteRange(PRInt32 aByterange)
|
|
{
|
|
gByteRange = aByterange;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::GetInterval(PRInt32* aInterval)
|
|
{
|
|
*aInterval = gInterval;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManager::SetInterval(PRInt32 aInterval)
|
|
{
|
|
gInterval = aInterval;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// nsSilentDownloadTask
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
nsSilentDownloadTask::nsSilentDownloadTask()
|
|
{
|
|
mScriptObject = nsnull;
|
|
mListener = nsnull;
|
|
mWindow = nsnull;
|
|
mWebShell = nsnull;
|
|
mState = nsIDOMSilentDownloadTask::SDL_NOT_INITED;
|
|
mNextByte = 0;
|
|
|
|
PR_AtomicIncrement(&gInstanceCnt);
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
nsSilentDownloadTask::~nsSilentDownloadTask()
|
|
{
|
|
mListener->Release();
|
|
PR_AtomicDecrement(&gInstanceCnt);
|
|
}
|
|
|
|
|
|
void
|
|
nsSilentDownloadTask::LoadScript(void)
|
|
{
|
|
if (mState == nsIDOMSilentDownloadTask::SDL_NOT_ADDED ||
|
|
mState == nsIDOMSilentDownloadTask::SDL_NOT_INITED )
|
|
return;
|
|
|
|
if (mWindow == nsnull)
|
|
{
|
|
nsresult rv = nsComponentManager::CreateInstance(kBrowserWindowCID, nsnull,
|
|
kIBrowserWindowIID,
|
|
(void**) &mWindow);
|
|
if (rv == NS_OK)
|
|
{
|
|
nsRect rect(0, 0, 275, 300);
|
|
|
|
rv = mWindow->Init(nsnull, nsnull, rect, PRUint32(0), PR_FALSE);
|
|
|
|
if (rv == NS_OK)
|
|
{
|
|
rv = mWindow->GetWebShell(mWebShell);
|
|
mWebShell->LoadURL(mScript.GetUnicode());
|
|
}
|
|
else
|
|
{
|
|
mWindow->Release();
|
|
mWindow=nsnull;
|
|
|
|
mState = nsIDOMSilentDownloadTask::SDL_ERROR;
|
|
SetErrorMsg("Couldn't Open Window");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (mWebShell)
|
|
{
|
|
mWebShell->LoadURL(mScript.GetUnicode());
|
|
}
|
|
else
|
|
{
|
|
mState = nsIDOMSilentDownloadTask::SDL_ERROR;
|
|
SetErrorMsg("Couldn't Open Window");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
NS_IMPL_ADDREF(nsSilentDownloadTask)
|
|
NS_IMPL_RELEASE(nsSilentDownloadTask)
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
{
|
|
if (aInstancePtr == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
// Always NULL result, in case of failure
|
|
*aInstancePtr = NULL;
|
|
|
|
if ( aIID.Equals(kIScriptObjectOwnerIID))
|
|
{
|
|
*aInstancePtr = (void*) ((nsIScriptObjectOwner*)this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
else if ( aIID.Equals(kISilentDownloadTaskIID) )
|
|
{
|
|
*aInstancePtr = (void*) ((nsIDOMSilentDownloadTask*)this);
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
else if ( aIID.Equals(kISupportsIID) )
|
|
{
|
|
*aInstancePtr = (void*)(nsISupports*)(nsIScriptObjectOwner*)this;
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
return NS_NOINTERFACE;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetScriptObject(nsIScriptContext *aContext, void** aScriptObject)
|
|
{
|
|
NS_PRECONDITION(nsnull != aScriptObject, "null arg");
|
|
nsresult res = NS_OK;
|
|
if (nsnull == mScriptObject)
|
|
{
|
|
res = NS_NewScriptSilentDownloadTask( aContext,
|
|
(nsISupports *)(nsIDOMSilentDownloadTask*)this,
|
|
nsnull,
|
|
&mScriptObject);
|
|
}
|
|
|
|
*aScriptObject = mScriptObject;
|
|
return res;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::SetScriptObject(void *aScriptObject)
|
|
{
|
|
mScriptObject = aScriptObject;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::Init(const nsString& aId, const nsString& aUrl, const nsString& aScript)
|
|
{
|
|
char *defaultDirectoryCString = NULL;
|
|
char *urlCString = NULL;
|
|
char *outFileCString = NULL;
|
|
|
|
GetSilentDownloadDirectory(defaultDirectoryCString);
|
|
|
|
mId = aId;
|
|
mUrl = aUrl;
|
|
mScript = aScript;
|
|
|
|
urlCString = aUrl.ToNewCString();
|
|
outFileCString = CreateOutFileLocation(urlCString, defaultDirectoryCString);
|
|
delete[] urlCString;
|
|
|
|
if (outFileCString == NULL)
|
|
{
|
|
SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
SetErrorMsg("Couldn't access destination directory to save file");
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
mOutFile = outFileCString;
|
|
}
|
|
|
|
|
|
mNextByte = GetCurrentSize(outFileCString);
|
|
/* FIX delete outFileCString and defaultDirectoryCString */
|
|
|
|
|
|
if (mNextByte < 0)
|
|
{
|
|
SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
SetErrorMsg("Negative Byte!");
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
/* Everything looks good. Mark as SDL_NOT_ADDED. */
|
|
mState = nsIDOMSilentDownloadTask::SDL_NOT_ADDED;
|
|
|
|
mListener = new nsSilentDownloadListener();
|
|
mListener->SetSilentDownloadInfo(this);
|
|
|
|
nsSilentDownloadManager* sdm = new nsSilentDownloadManager();
|
|
sdm->Add(this);
|
|
delete sdm;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetId(nsString& aId)
|
|
{
|
|
aId = mId;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetUrl(nsString& aUrl)
|
|
{
|
|
aUrl = mUrl;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetScript(nsString& aScript)
|
|
{
|
|
aScript = mScript;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetState(PRInt32* aState)
|
|
{
|
|
*aState = mState;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::SetState(PRInt32 aState)
|
|
{
|
|
/* This function is so that our listener can change the state.
|
|
I would rather not expose this to Javascript if possible*/
|
|
|
|
mState = aState;
|
|
LoadScript();
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetErrorMsg(nsString& aErrorMsg)
|
|
{
|
|
/* This function is so that our listener can change the state.
|
|
I would rather not expose this to Javascript if possible*/
|
|
aErrorMsg = mErrorMsg;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::SetErrorMsg(const nsString& aErrorMsg)
|
|
{
|
|
mErrorMsg = aErrorMsg;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetNextByte(PRInt32* aNext_byte)
|
|
{
|
|
*aNext_byte = mNextByte;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::SetNextByte(PRInt32 aNextByte)
|
|
{
|
|
mNextByte = aNextByte;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::GetOutFile(nsString& aOutFile)
|
|
{
|
|
aOutFile = mOutFile;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::Remove()
|
|
{
|
|
mState = nsIDOMSilentDownloadTask::SDL_NOT_ADDED;
|
|
|
|
mWebShell->Release();
|
|
|
|
mWindow->Close();
|
|
mWindow->Release();
|
|
mWindow = nsnull;
|
|
|
|
nsSilentDownloadManager* sdm = new nsSilentDownloadManager();
|
|
sdm->Remove(this);
|
|
delete sdm;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::Suspend()
|
|
{
|
|
SetState(nsIDOMSilentDownloadTask::SDL_SUSPENDED);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::Resume()
|
|
{
|
|
SetState(nsIDOMSilentDownloadTask::SDL_STARTED);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::DownloadNow()
|
|
{
|
|
SetState(nsIDOMSilentDownloadTask::SDL_DOWNLOADING_NOW);
|
|
DownloadSelf(0);
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTask::DownloadSelf(PRInt32 range)
|
|
{
|
|
long result=0;
|
|
char* byteRangeString=NULL;
|
|
nsIURL *pURL;
|
|
nsILoadAttribs *loadAttr;
|
|
|
|
if (mState != nsIDOMSilentDownloadTask::SDL_STARTED &&
|
|
mState != nsIDOMSilentDownloadTask::SDL_DOWNLOADING_NOW)
|
|
{
|
|
/* We do not have to do a download here. */
|
|
return 0;
|
|
}
|
|
|
|
|
|
// Create the URL object...
|
|
pURL = NULL;
|
|
|
|
result = NS_NewURL(&pURL, mUrl);
|
|
|
|
if (result != NS_OK)
|
|
{
|
|
SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
SetErrorMsg("Couldn't set up download. Out of memory");
|
|
return -1;
|
|
}
|
|
|
|
pURL->GetLoadAttribs(&loadAttr);
|
|
loadAttr->SetLoadType(nsURLLoadBackground);
|
|
|
|
if (mState != nsIDOMSilentDownloadTask::SDL_DOWNLOADING_NOW)
|
|
{
|
|
/* Do Byte Range Stuff */
|
|
byteRangeString = PR_sprintf_append( byteRangeString,
|
|
"bytes=%ld-%ld",
|
|
mNextByte,
|
|
mNextByte+range);
|
|
|
|
loadAttr->SetByteRangeHeader(byteRangeString);
|
|
|
|
PR_FREEIF(byteRangeString);
|
|
|
|
}
|
|
|
|
result = NS_OpenURL(pURL, mListener);
|
|
|
|
/* If the open failed... */
|
|
if (NS_OK != result)
|
|
{
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// nsSilentDownloadImplFactory
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
nsSilentDownloadManagerFactory::nsSilentDownloadManagerFactory(void)
|
|
{
|
|
mRefCnt=0;
|
|
PR_AtomicIncrement(&gInstanceCnt);
|
|
}
|
|
|
|
nsSilentDownloadManagerFactory::~nsSilentDownloadManagerFactory(void)
|
|
{
|
|
PR_AtomicDecrement(&gInstanceCnt);
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManagerFactory::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
{
|
|
if (aInstancePtr == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
// Always NULL result, in case of failure
|
|
*aInstancePtr = NULL;
|
|
|
|
if ( aIID.Equals(kISupportsIID) )
|
|
{
|
|
*aInstancePtr = (void*) this;
|
|
}
|
|
else if ( aIID.Equals(kIFactoryIID) )
|
|
{
|
|
*aInstancePtr = (void*) this;
|
|
}
|
|
|
|
if (aInstancePtr == NULL)
|
|
{
|
|
return NS_ERROR_NO_INTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManagerFactory::AddRef(void)
|
|
{
|
|
return ++mRefCnt;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManagerFactory::Release(void)
|
|
{
|
|
if (--mRefCnt ==0)
|
|
{
|
|
delete this;
|
|
return 0; // Don't access mRefCnt after deleting!
|
|
}
|
|
|
|
return mRefCnt;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManagerFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
{
|
|
if (aResult == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
*aResult = NULL;
|
|
|
|
/* do I have to use iSupports? */
|
|
nsSilentDownloadManager *inst = new nsSilentDownloadManager();
|
|
|
|
if (inst == NULL)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
nsresult result = inst->QueryInterface(aIID, aResult);
|
|
|
|
if (result != NS_OK)
|
|
delete inst;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadManagerFactory::LockFactory(PRBool aLock)
|
|
{
|
|
if (aLock)
|
|
PR_AtomicIncrement(&gLockCnt);
|
|
else
|
|
PR_AtomicDecrement(&gLockCnt);
|
|
|
|
return NS_OK;
|
|
}
|
|
/////////////////////////////////////////////////////////////////////////
|
|
// nsSilentDownloadTaskFactory
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
nsSilentDownloadTaskFactory::nsSilentDownloadTaskFactory(void)
|
|
{
|
|
mRefCnt=0;
|
|
PR_AtomicIncrement(&gInstanceCnt);
|
|
}
|
|
|
|
nsSilentDownloadTaskFactory::~nsSilentDownloadTaskFactory(void)
|
|
{
|
|
PR_AtomicDecrement(&gInstanceCnt);
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTaskFactory::QueryInterface(REFNSIID aIID,void** aInstancePtr)
|
|
{
|
|
if (aInstancePtr == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
// Always NULL result, in case of failure
|
|
*aInstancePtr = NULL;
|
|
|
|
if ( aIID.Equals(kISupportsIID) )
|
|
{
|
|
*aInstancePtr = (void*) this;
|
|
}
|
|
else if ( aIID.Equals(kIFactoryIID) )
|
|
{
|
|
*aInstancePtr = (void*) this;
|
|
}
|
|
|
|
if (aInstancePtr == NULL)
|
|
{
|
|
return NS_ERROR_NO_INTERFACE;
|
|
}
|
|
|
|
AddRef();
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTaskFactory::AddRef(void)
|
|
{
|
|
return ++mRefCnt;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTaskFactory::Release(void)
|
|
{
|
|
if (--mRefCnt ==0)
|
|
{
|
|
delete this;
|
|
return 0; // Don't access mRefCnt after deleting!
|
|
}
|
|
|
|
return mRefCnt;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTaskFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
|
{
|
|
if (aResult == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
*aResult = NULL;
|
|
|
|
/* do I have to use iSupports? */
|
|
nsSilentDownloadTask *inst = new nsSilentDownloadTask();
|
|
|
|
if (inst == NULL)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
|
|
nsresult result = inst->QueryInterface(aIID, aResult);
|
|
|
|
if (result != NS_OK)
|
|
delete inst;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadTaskFactory::LockFactory(PRBool aLock)
|
|
{
|
|
if (aLock)
|
|
PR_AtomicIncrement(&gLockCnt);
|
|
else
|
|
PR_AtomicDecrement(&gLockCnt);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// nsSilentDownloadNameSet
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
nsSilentDownloadNameSet::nsSilentDownloadNameSet()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
nsSilentDownloadNameSet::~nsSilentDownloadNameSet()
|
|
{
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS(nsSilentDownloadNameSet, kIScriptExternalNameSetIID);
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadNameSet::InitializeClasses(nsIScriptContext* aScriptContext)
|
|
{
|
|
nsresult result = NS_OK;
|
|
|
|
result = NS_InitSilentDownloadClass(aScriptContext, nsnull);
|
|
if (NS_OK != result) return result;
|
|
|
|
result = NS_InitSilentDownloadTaskClass(aScriptContext, nsnull);
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadNameSet::AddNameSet(nsIScriptContext* aScriptContext)
|
|
{
|
|
nsresult result = NS_OK;
|
|
nsIScriptNameSpaceManager* manager;
|
|
|
|
result = aScriptContext->GetNameSpaceManager(&manager);
|
|
if (NS_OK == result)
|
|
{
|
|
result = manager->RegisterGlobalName("SilentDownloadTask",
|
|
kSilentDownloadTaskCID,
|
|
PR_TRUE);
|
|
|
|
if (NS_OK != result) return result;
|
|
|
|
result = manager->RegisterGlobalName("SilentDownloadManager",
|
|
kSilentDownloadCID,
|
|
PR_FALSE);
|
|
|
|
|
|
NS_RELEASE(manager);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// nsSilentDownloadListener
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
nsSilentDownloadListener::nsSilentDownloadListener()
|
|
{
|
|
NS_INIT_REFCNT();
|
|
}
|
|
|
|
nsSilentDownloadListener::~nsSilentDownloadListener()
|
|
{
|
|
mSilentDownloadTask->Release();
|
|
|
|
if (mOutFileDesc != NULL)
|
|
PR_Close(mOutFileDesc);
|
|
}
|
|
|
|
|
|
NS_IMPL_ISUPPORTS( nsSilentDownloadListener, kIStreamListenerIID )
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::GetBindInfo(nsIURL* aURL, nsStreamBindingInfo* info)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::OnProgress( nsIURL* aURL,
|
|
PRUint32 Progress,
|
|
PRUint32 ProgressMax)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::OnStatus(nsIURL* aURL,
|
|
const PRUnichar* aMsg)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::OnStartBinding(nsIURL* aURL,
|
|
const char *aContentType)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::OnStopBinding(nsIURL* aURL,
|
|
nsresult status,
|
|
const PRUnichar* aMsg)
|
|
{
|
|
nsresult result = NS_OK;
|
|
PRInt32 content_length = 0;
|
|
PRInt32 server_status = 0;
|
|
PRInt32 nextByte;
|
|
|
|
switch( status )
|
|
{
|
|
|
|
case NS_BINDING_SUCCEEDED:
|
|
/*
|
|
What we are going to is check to see if our nextByte that the task will
|
|
get is passed the content_length of the URL.
|
|
|
|
What happens if there is no content_length?
|
|
*/
|
|
|
|
aURL->GetServerStatus(&server_status);
|
|
|
|
if (server_status == 404)
|
|
{
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
mSilentDownloadTask->SetErrorMsg("Server Error 400.");
|
|
return NS_OK;
|
|
}
|
|
else if (server_status == 500)
|
|
{
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
mSilentDownloadTask->SetErrorMsg("Server Error 500.");
|
|
return NS_OK;
|
|
}
|
|
|
|
aURL->GetContentLength(&content_length);
|
|
|
|
mSilentDownloadTask->GetNextByte(&nextByte);
|
|
|
|
if (content_length <= nextByte || content_length == 0)
|
|
{
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_COMPLETED);
|
|
PR_Close(mOutFileDesc);
|
|
mOutFileDesc=NULL;
|
|
}
|
|
break;
|
|
|
|
case NS_BINDING_FAILED:
|
|
case NS_BINDING_ABORTED:
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
mSilentDownloadTask->SetErrorMsg("Could Not Download.");
|
|
break;
|
|
|
|
default:
|
|
result = NS_ERROR_ILLEGAL_VALUE;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::OnDataAvailable(nsIURL* aURL, nsIInputStream *pIStream, PRUint32 length)
|
|
{
|
|
PRUint32 len;
|
|
PRInt32 nextByte;
|
|
nsresult err;
|
|
char buffer[80];
|
|
|
|
do
|
|
{
|
|
err = pIStream->Read(buffer, 80, &len);
|
|
if (err == NS_OK)
|
|
{
|
|
mSilentDownloadTask->GetNextByte(&nextByte);
|
|
if ( PR_Seek(mOutFileDesc, nextByte, PR_SEEK_SET) == -1 )
|
|
{
|
|
/* Error */
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
mSilentDownloadTask->SetErrorMsg("File Seek Error.");
|
|
return -1;
|
|
}
|
|
|
|
if( PR_Write(mOutFileDesc, buffer, len) == -1 )
|
|
{
|
|
/* Error */
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
mSilentDownloadTask->SetErrorMsg("File Write Error.");
|
|
return -1;
|
|
}
|
|
|
|
mSilentDownloadTask->SetNextByte(nextByte+len);
|
|
}
|
|
} while (len > 0);
|
|
|
|
return 0;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsSilentDownloadListener::SetSilentDownloadInfo(nsIDOMSilentDownloadTask* con)
|
|
{
|
|
nsString aString;
|
|
char *fileName;
|
|
|
|
con->AddRef();
|
|
|
|
mSilentDownloadTask = con;
|
|
mSilentDownloadTask->GetOutFile(aString);
|
|
fileName = aString.ToNewCString();
|
|
|
|
mOutFileDesc = PR_Open(fileName, PR_CREATE_FILE | PR_RDWR, 0644);
|
|
|
|
delete[] fileName;
|
|
|
|
if(mOutFileDesc == NULL)
|
|
{
|
|
mSilentDownloadTask->SetState(nsIDOMSilentDownloadTask::SDL_ERROR);
|
|
mSilentDownloadTask->SetErrorMsg("Could not create OUT file.");
|
|
return NS_OK;
|
|
};
|
|
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// DLL Entry Points:
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
extern "C" NS_EXPORT PRBool
|
|
NSCanUnload(nsISupports* aServMgr)
|
|
{
|
|
return PRBool (gInstanceCnt == 0 && gLockCnt == 0);
|
|
}
|
|
|
|
extern "C" NS_EXPORT nsresult
|
|
NSRegisterSelf(nsISupports* aServMgr, const char *path)
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsIComponentManager* compMgr;
|
|
rv = servMgr->GetService(kComponentManagerCID,
|
|
nsIComponentManager::GetIID(),
|
|
(nsISupports**)&compMgr);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
#ifdef NS_DEBUG
|
|
printf("*** SilentDownload is being registered\n");
|
|
#endif
|
|
|
|
rv = compMgr->RegisterComponent(kSilentDownloadCID, NULL, NULL, path, PR_TRUE, PR_TRUE);
|
|
if (NS_FAILED(rv)) goto done;
|
|
rv = compMgr->RegisterComponent(kSilentDownloadTaskCID, NULL, NULL, path, PR_TRUE, PR_TRUE);
|
|
|
|
done:
|
|
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
|
|
return rv;
|
|
}
|
|
|
|
extern "C" NS_EXPORT nsresult
|
|
NSUnregisterSelf(nsISupports* aServMgr, const char *path)
|
|
{
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIServiceManager> servMgr(do_QueryInterface(aServMgr, &rv));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsIComponentManager* compMgr;
|
|
rv = servMgr->GetService(kComponentManagerCID,
|
|
nsIComponentManager::GetIID(),
|
|
(nsISupports**)&compMgr);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
#ifdef NS_DEBUG
|
|
printf("*** SilentDownload is being unregistered\n");
|
|
#endif
|
|
|
|
rv = compMgr->UnregisterFactory(kSilentDownloadCID, path);
|
|
if (NS_FAILED(rv)) goto done;
|
|
rv = compMgr->UnregisterFactory(kSilentDownloadTaskCID, path);
|
|
|
|
done:
|
|
(void)servMgr->ReleaseService(kComponentManagerCID, compMgr);
|
|
return rv;
|
|
}
|
|
|
|
|
|
|
|
extern "C" NS_EXPORT nsresult
|
|
NSGetFactory(nsISupports* aServMgr,
|
|
const nsCID &aClass,
|
|
const char *aClassName,
|
|
const char *aProgID,
|
|
nsIFactory **aFactory)
|
|
{
|
|
|
|
if (aFactory == NULL)
|
|
{
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
*aFactory = NULL;
|
|
nsISupports *inst;
|
|
|
|
|
|
if ( aClass.Equals(kSilentDownloadCID) )
|
|
{
|
|
inst = new nsSilentDownloadManagerFactory();
|
|
}
|
|
else if ( aClass.Equals(kSilentDownloadTaskCID) )
|
|
{
|
|
inst = new nsSilentDownloadTaskFactory();
|
|
}
|
|
else
|
|
{
|
|
return NS_ERROR_ILLEGAL_VALUE;
|
|
}
|
|
|
|
|
|
if (inst == NULL)
|
|
{
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
}
|
|
|
|
|
|
nsresult res = inst->QueryInterface(kIFactoryIID, (void**) aFactory);
|
|
|
|
if (res != NS_OK)
|
|
{
|
|
delete inst;
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|