gecko-dev/xpinstall/wizard/mac/src/XPInstallGlue.c

332 lines
9.4 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* The contents of this file are subject to the Netscape Public License
* Version 1.1 (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, released March
* 31, 1998.
*
* The Initial Developer of the Original Code is Netscape Communications
* Corporation. Portions created by Netscape are Copyright (C) 1999
* Netscape Communications Corporation. All Rights Reserved.
*
* Contributors:
* Samir Gehani <sgehani@netscape.com>
*/
#include "MacInstallWizard.h"
#define XP_MAC 1
#include "xpistub.h"
/*-----------------------------------------------------------*
* XPInstall Glue
*-----------------------------------------------------------*/
/* XPI Stub Entry Points */
typedef nsresult (*XPI_InitProc)(const FSSpec& aXPIStubDir, const FSSpec& aProgramDir,
pfnXPIStart startCB,
pfnXPIProgress progressCB,
pfnXPIFinal finalCB);
typedef nsresult (*XPI_InstallProc)(const FSSpec& file, const char* args,long flags);
typedef nsresult (*XPI_ExitProc)();
/* XPI Run APIs */
OSErr LoadXPIStub(XPI_InitProc* pfnInit,
XPI_InstallProc* pfnInstall,
XPI_ExitProc* pfnExit,
CFragConnectionID* connID,
FSSpec& aTargetDir);
Boolean UnloadXPIStub(CFragConnectionID* connID);
OSErr RunXPI(FSSpec&, XPI_InstallProc*);
Boolean IsArchiveXPI(StringPtr archive);
/* Progress Bar Callbacks */
void xpicbStart(const char *URL, const char* UIName);
void xpicbProgress(const char* msg, PRInt32 val, PRInt32 max);
void xpicbFinal(const char *URL, PRInt32 finalStatus);
#define XPI_ERR_CHECK(_call) \
rv = _call; \
if (NS_FAILED(rv)) \
{ \
ErrorHandler(); \
return rv; \
}
#ifdef MIW_DEBUG
#define XPISTUB_DLL "\pxpistubDebug.shlb"
#else
#define XPISTUB_DLL "\pxpistub.shlb"
#endif
static Boolean bMaxDiscovered = false;
void
xpicbStart(const char *URL, const char* UIName)
{
Rect r;
Str255 installingStr;
if (gControls->tw->progressMsg)
{
HLock((Handle)gControls->tw->progressMsg);
SetRect(&r, (*gControls->tw->progressMsg)->viewRect.left,
(*gControls->tw->progressMsg)->viewRect.top,
(*gControls->tw->progressMsg)->viewRect.right,
(*gControls->tw->progressMsg)->viewRect.bottom );
HUnlock((Handle)gControls->tw->progressMsg);
/* Installing <UIName> */
GetIndString(installingStr, rStringList, sInstalling);
EraseRect(&r);
if (installingStr[0] > 0)
TESetText(&installingStr[1], installingStr[0], gControls->tw->progressMsg);
if (UIName)
TEInsert(UIName, strlen(UIName), gControls->tw->progressMsg);
TEUpdate(&r, gControls->tw->progressMsg);
}
return;
}
void
xpicbProgress(const char* msg, PRInt32 val, PRInt32 max)
{
Boolean indeterminateFlag = false;
Rect r;
Str255 installingStr, fileStr, ofStr;
char *valStr, *maxStr;
GrafPtr oldPort;
GetPort(&oldPort);
if (gWPtr)
{
SetPort(gWPtr);
if (gControls->tw->progressBar)
{
if (max!=0 && !bMaxDiscovered)
{
SetControlData(gControls->tw->progressBar, kControlNoPart, kControlProgressBarIndeterminateTag,
sizeof(indeterminateFlag), (Ptr) &indeterminateFlag);
SetControlMaximum(gControls->tw->progressBar, max);
bMaxDiscovered = true;
}
else if (!bMaxDiscovered)
{
if (gWPtr)
IdleControls(gWPtr);
if (gControls->tw->xpiProgressMsg)
{
HLock((Handle)gControls->tw->xpiProgressMsg);
SetRect(&r, (*gControls->tw->xpiProgressMsg)->viewRect.left,
(*gControls->tw->xpiProgressMsg)->viewRect.top,
(*gControls->tw->xpiProgressMsg)->viewRect.right,
(*gControls->tw->xpiProgressMsg)->viewRect.bottom );
HUnlock((Handle)gControls->tw->xpiProgressMsg);
if (msg)
{
EraseRect(&r);
TESetText(msg, strlen(msg), gControls->tw->xpiProgressMsg);
TEUpdate(&r, gControls->tw->xpiProgressMsg);
}
}
}
if (bMaxDiscovered)
{
SetControlValue(gControls->tw->progressBar, val);
if (gControls->tw->xpiProgressMsg)
{
GetIndString(installingStr, rStringList, sInstalling);
GetIndString(fileStr, rStringList, sFileSp);
GetIndString(ofStr, rStringList, sSpOfSp);
HLock((Handle)gControls->tw->xpiProgressMsg);
SetRect(&r, (*gControls->tw->xpiProgressMsg)->viewRect.left,
(*gControls->tw->xpiProgressMsg)->viewRect.top,
(*gControls->tw->xpiProgressMsg)->viewRect.right,
(*gControls->tw->xpiProgressMsg)->viewRect.bottom );
HUnlock((Handle)gControls->tw->xpiProgressMsg);
valStr = ltoa(val);
maxStr = ltoa(max);
EraseRect(&r);
if (valStr && maxStr)
{
TESetText(&installingStr[1], installingStr[0], gControls->tw->xpiProgressMsg);
TEInsert(&fileStr[1], fileStr[0], gControls->tw->xpiProgressMsg);
TEInsert(valStr, strlen(valStr), gControls->tw->xpiProgressMsg);
TEInsert(&ofStr[1], ofStr[0], gControls->tw->xpiProgressMsg);
TEInsert(maxStr, strlen(maxStr), gControls->tw->xpiProgressMsg);
TEUpdate(&r, gControls->tw->xpiProgressMsg);
}
if (valStr)
free(valStr);
if (maxStr)
free(maxStr);
}
}
}
}
SetPort(oldPort);
return;
}
void
xpicbFinal(const char *URL, PRInt32 finalStatus)
{
// TO DO
bMaxDiscovered = false;
return;
}
OSErr
RunAllXPIs(short vRefNum, long dirID)
{
OSErr err = noErr;
FSSpec tgtDirSpec, xpiStubDirSpec, xpiSpec;
XPI_InitProc xpi_initProc;
XPI_InstallProc xpi_installProc;
XPI_ExitProc xpi_exitProc;
CFragConnectionID connID;
nsresult rv = NS_OK;
StringPtr pcurrArchive;
int i, compsDone = 0, instChoice = gControls->opt->instChoice-1;;
Boolean isCurrXPI = false;
err = FSMakeFSSpec(vRefNum, dirID, 0, &xpiStubDirSpec); /* temp dir */
err = FSMakeFSSpec(gControls->opt->vRefNum, gControls->opt->dirID, 0, &tgtDirSpec); /* program dir */
ERR_CHECK_RET(LoadXPIStub(&xpi_initProc, &xpi_installProc, &xpi_exitProc, &connID, xpiStubDirSpec), err);
XPI_ERR_CHECK(xpi_initProc( xpiStubDirSpec, tgtDirSpec, xpicbStart, xpicbProgress, xpicbFinal ));
// enumerate through all .xpi's
// loop through 0 to kMaxComponents
for(i=0; i<kMaxComponents; i++)
{
// general test: if component in setup type
if ( (gControls->cfg->st[instChoice].comp[i] == kInSetupType) &&
(compsDone < gControls->cfg->st[instChoice].numComps) )
{
// if custom and selected, or not custom setup type
// add file to buffer
if ( ((instChoice == gControls->cfg->numSetupTypes-1) &&
(gControls->cfg->comp[i].selected == true)) ||
(instChoice < gControls->cfg->numSetupTypes-1) )
{
HLock(gControls->cfg->comp[i].archive);
pcurrArchive = CToPascal(*gControls->cfg->comp[i].archive);
HUnlock(gControls->cfg->comp[i].archive);
isCurrXPI = IsArchiveXPI(pcurrArchive);
err = FSMakeFSSpec(vRefNum, dirID, pcurrArchive, &xpiSpec);
if (err==noErr && isCurrXPI)
RunXPI(xpiSpec, &xpi_installProc);
if (pcurrArchive)
DisposePtr((Ptr) pcurrArchive);
compsDone++;
}
}
else if (compsDone >= gControls->cfg->st[instChoice].numComps)
break;
}
xpi_exitProc();
UnloadXPIStub(&connID);
return err;
}
OSErr
RunXPI(FSSpec& aXPI, XPI_InstallProc *xpi_installProc)
{
nsresult rv;
OSErr err = noErr;
long flags = 0x1000; /* XPI_NO_NEW_THREAD = 0x1000 from nsISoftwareUpdate.h */
rv = (*xpi_installProc)( aXPI, "", flags );
if (NS_FAILED(rv))
return -1;
return err;
}
/*-------------------------------------------------------------------
* XPI Stub Load/Unload
*-------------------------------------------------------------------*/
OSErr
LoadXPIStub(XPI_InitProc* pfnInit, XPI_InstallProc* pfnInstall, XPI_ExitProc* pfnExit,
CFragConnectionID* connID, FSSpec& aTargetDir)
{
OSErr err;
FSSpec fslib;
Str63 fragName = XPISTUB_DLL;
Ptr mainAddr, symAddr;
Str255 errName;
CFragSymbolClass symClass;
long tgtDirID;
Boolean isDir;
err = FSpGetDirectoryID( &aTargetDir, &tgtDirID, &isDir );
if (err!=noErr)
return err;
else if (!isDir)
return paramErr;
err = FSMakeFSSpec(aTargetDir.vRefNum, tgtDirID, fragName, &fslib);
if (err!=noErr)
return err;
err = GetDiskFragment(&fslib, 0, kCFragGoesToEOF, nil, /*kPrivateCFragCopy*/kReferenceCFrag, connID, &mainAddr, errName);
if ( err == noErr && *connID != NULL)
{
ERR_CHECK_RET( FindSymbol(*connID, "\pXPI_Init", &symAddr, &symClass), err );
*pfnInit = (XPI_InitProc) symAddr;
ERR_CHECK_RET( FindSymbol(*connID, "\pXPI_Install", &symAddr, &symClass), err);
*pfnInstall = (XPI_InstallProc) symAddr;
ERR_CHECK_RET( FindSymbol(*connID, "\pXPI_Exit", &symAddr, &symClass), err);
*pfnExit = (XPI_ExitProc) symAddr;
}
return err;
}
Boolean
UnloadXPIStub(CFragConnectionID* connID)
{
if ((connID != NULL) && (*connID != NULL))
{
CloseConnection(connID);
*connID = NULL;
return true;
}
return false;
}
Boolean
IsArchiveXPI(StringPtr archive)
{
long len = *archive;
char *extStart = (char*)(&archive[1] + len - 4); /* extension length of ".xpi" = 4 */
if (strncmp(extStart, ".xpi", 4) == 0)
return true;
return false;
}