nsCOMPtr<nsIZipReader> hZip;
static NS_DEFINE_IID(kZipReaderCID,  NS_ZIPREADER_CID);
extern "C" void RunInstallOnThread(void *data){    nsInstallInfo *installInfo = (nsInstallInfo*)data;    char        *scriptBuffer = nsnull;    PRUint32    scriptLength;    JSRuntime   *rt;    JSContext   *cx;    JSObject    *glob;    nsCOMPtr<nsIZipReader> hZip;    static NS_DEFINE_IID(kIZipReaderIID, NS_IZIPREADER_IID);    static NS_DEFINE_IID(kZipReaderCID,  NS_ZIPREADER_CID);    nsresult rv = nsComponentManager::CreateInstance(kZipReaderCID, nsnull, kIZipReaderIID,                                                     getter_AddRefs(hZip));    if (NS_FAILED(rv))        return;    // we will plan on sending a failure status back from here unless we    // find positive acknowledgement that the script sent the status    PRInt32     finalStatus;    nsCOMPtr<nsIXPIListener> listener;    // lets set up an eventQ so that our xpcom/proxies will not have to:    nsCOMPtr<nsIEventQueue> eventQ;    nsCOMPtr<nsIEventQueueService> eventQService =             do_GetService(kEventQueueServiceCID, &rv);    if (NS_SUCCEEDED(rv))    {        eventQService->CreateMonitoredThreadEventQueue();        eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, getter_AddRefs(eventQ));    }    nsCOMPtr<nsISoftwareUpdate> softwareUpdate =             do_GetService(kSoftwareUpdateCID, &rv);    if (NS_FAILED(rv))    {        NS_WARNING("shouldn't have RunInstall() if we can't get SoftwareUpdate");        return;    }    softwareUpdate->SetActiveListener( installInfo->GetListener() );    softwareUpdate->GetMasterListener(getter_AddRefs(listener));    if(listener)        listener->OnInstallStart( installInfo->GetURL() );    nsCOMPtr<nsIFile> jarpath = installInfo->GetFile();    if (NS_SUCCEEDED(rv))    {        finalStatus = GetInstallScriptFromJarfile( hZip,                                                   jarpath,                                                   installInfo->mPrincipal,                                                   &scriptBuffer,                                                   &scriptLength);        if ( finalStatus == NS_OK && scriptBuffer )        {            PRBool ownRuntime = PR_FALSE;            nsCOMPtr<nsIJSRuntimeService> rtsvc =                     do_GetService("@mozilla.org/js/xpc/RuntimeService;1", &rv);            if(NS_FAILED(rv) || NS_FAILED(rtsvc->GetRuntime(&rt)))            {                // service not available (wizard context?)                // create our own runtime                ownRuntime = PR_TRUE;                rt = JS_Init(4L * 1024L * 1024L);            }            rv = SetupInstallContext( hZip, jarpath,                                      installInfo->GetURL(),                                      installInfo->GetArguments(),                                      installInfo->GetFlags(),                                      installInfo->GetChromeRegistry(),                                      rt, &cx, &glob);            if (NS_SUCCEEDED(rv))            {                // Go ahead and run!!                jsval rval;                jsval installedFiles;                JS_BeginRequest(cx); //Increment JS thread counter associated                                     //with this context                PRBool ok = JS_EvaluateScript(  cx,                                                glob,                                                scriptBuffer,                                                scriptLength,                                                nsnull,                                                0,                                                &rval);                if(!ok)                {                    // problem compiling or running script -- a true SCRIPT_ERROR                    if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) &&                       JSVAL_TO_BOOLEAN(installedFiles))                    {                        nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob);                        a->InternalAbort(nsInstall::SCRIPT_ERROR);                    }                    finalStatus = nsInstall::SCRIPT_ERROR;                }                else                {                    // check to make sure the script sent back a status -- if                    // not the install may have been syntactically correct but                    // left the init/(perform|cancel) transaction open                    if(JS_GetProperty(cx, glob, "_installedFiles", &installedFiles) &&                       JSVAL_TO_BOOLEAN(installedFiles))                    {                        // install items remain in queue, must clean up!                        nsInstall *a = (nsInstall*)JS_GetPrivate(cx, glob);                        a->InternalAbort(nsInstall::MALFORMED_INSTALL);                    }                    jsval sent;                    if ( JS_GetProperty( cx, glob, "_finalStatus", &sent ) )                        finalStatus = JSVAL_TO_INT(sent);                    else                        finalStatus = nsInstall::UNEXPECTED_ERROR;                }                JS_EndRequest(cx); //Decrement JS thread counter                JS_DestroyContextMaybeGC(cx);            }            else            {                // couldn't initialize install context                finalStatus = nsInstall::UNEXPECTED_ERROR;            }            // clean up Runtime if we created it ourselves            if ( ownRuntime )                JS_DestroyRuntime(rt);        }        // force zip archive closed before other cleanup        hZip = 0;    }    else    {        // no path to local jar archive        finalStatus = nsInstall::DOWNLOAD_ERROR;    }    if(listener)        listener->OnInstallDone( installInfo->GetURL(), finalStatus );    if (scriptBuffer) delete [] scriptBuffer;    softwareUpdate->SetActiveListener(0);    softwareUpdate->InstallJarCallBack();}