Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes
nsInstallPatch Class Reference

#include <nsInstallPatch.h>

Inheritance diagram for nsInstallPatch:
Inheritance graph
[legend]
Collaboration diagram for nsInstallPatch:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsInstallPatch (nsInstall *inInstall, const nsString &inVRName, const nsString &inVInfo, const nsString &inJarLocation, nsInstallFolder *folderSpec, const nsString &inPartialPath, PRInt32 *error)
 nsInstallPatch (nsInstall *inInstall, const nsString &inVRName, const nsString &inVInfo, const nsString &inJarLocation, PRInt32 *error)
virtual ~nsInstallPatch ()
PRInt32 Prepare ()
PRInt32 Complete ()
void Abort ()
char * toString ()
PRBool CanUninstall ()
PRBool RegisterPackageNode ()

Protected Attributes

nsInstallmInstall

Private Member Functions

PRInt32 NativePatch (nsIFile *sourceFile, nsIFile *patchfile, nsIFile **newFile)
voidHashFilePath (nsIFile *aPath)

Private Attributes

nsInstallVersionmVersionInfo
nsCOMPtr< nsIFilemTargetFile
nsCOMPtr< nsIFilemPatchFile
nsCOMPtr< nsIFilemPatchedFile
nsStringmJarLocation
nsStringmRegistryName

Detailed Description

Definition at line 51 of file nsInstallPatch.h.


Constructor & Destructor Documentation

nsInstallPatch::nsInstallPatch ( nsInstall inInstall,
const nsString inVRName,
const nsString inVInfo,
const nsString inJarLocation,
nsInstallFolder folderSpec,
const nsString inPartialPath,
PRInt32 error 
)

Definition at line 138 of file nsInstallPatch.cpp.

: nsInstallObject(inInstall)
{
    MOZ_COUNT_CTOR(nsInstallPatch);

    if ((inInstall == nsnull) || (inVRName.IsEmpty()) || (inJarLocation.IsEmpty())) 
    {
        *error = nsInstall::INVALID_ARGUMENTS;
        return;
    }
    
    nsCOMPtr<nsIFile> tmp = folderSpec->GetFileSpec();
    if (!tmp)
    {
        *error = nsInstall::INVALID_ARGUMENTS;
        return;
    }

    mPatchFile      =   nsnull;
    mTargetFile     =   nsnull;
    mPatchedFile    =   nsnull;
    mRegistryName   =   new nsString(inVRName);
    mJarLocation    =   new nsString(inJarLocation);
    mVersionInfo    =   new nsInstallVersion();
    tmp->Clone(getter_AddRefs(mTargetFile));

    if (mRegistryName == nsnull ||
        mJarLocation  == nsnull ||
        mTargetFile   == nsnull ||
        mVersionInfo  == nsnull )
    {
        *error = nsInstall::OUT_OF_MEMORY;
        return;
    }
    
    mVersionInfo->Init(inVInfo);
    
    if(! inPartialPath.IsEmpty())
        mTargetFile->Append(inPartialPath);
}

Here is the call graph for this function:

nsInstallPatch::nsInstallPatch ( nsInstall inInstall,
const nsString inVRName,
const nsString inVInfo,
const nsString inJarLocation,
PRInt32 error 
)

Definition at line 93 of file nsInstallPatch.cpp.

: nsInstallObject(inInstall)
{
    MOZ_COUNT_CTOR(nsInstallPatch);

    char tempTargetFile[MAXREGPATHLEN];

    PRInt32 err = VR_GetPath( NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(inVRName).get()),
                              sizeof(tempTargetFile), tempTargetFile );
    
    if (err != REGERR_OK)
    {
        *error = nsInstall::NO_SUCH_COMPONENT;
        return;
    }
       
    nsCOMPtr<nsILocalFile> tmp;
    NS_NewNativeLocalFile(nsDependentCString(tempTargetFile), PR_TRUE, getter_AddRefs(tmp));

    mPatchFile      =   nsnull;
    mTargetFile     =   nsnull;
    mPatchedFile    =   nsnull;
    mRegistryName   =   new nsString(inVRName);
    mJarLocation    =   new nsString(inJarLocation);
    mVersionInfo    =   new nsInstallVersion();
    tmp->Clone(getter_AddRefs(mTargetFile));
    
    if (mRegistryName == nsnull ||
        mJarLocation  == nsnull ||
        mTargetFile   == nsnull ||
        mVersionInfo  == nsnull )
    {
        *error = nsInstall::OUT_OF_MEMORY;
        return;
    }

    mVersionInfo->Init(inVInfo);
}

Here is the call graph for this function:

Definition at line 186 of file nsInstallPatch.cpp.

{
    if (mVersionInfo)
        delete mVersionInfo;

    //if (mTargetFile)
    //    delete mTargetFile;

    if (mJarLocation)
        delete mJarLocation;
    
    if (mRegistryName)
        delete mRegistryName;

    //if (mPatchedFile)
    //    delete mPatchedFile;
    
    //if (mPatchFile)
    //    delete mPatchFile;

    MOZ_COUNT_DTOR(nsInstallPatch);
}

Member Function Documentation

void nsInstallPatch::Abort ( ) [virtual]

Implements nsInstallObject.

Definition at line 352 of file nsInstallPatch.cpp.

{
    PRBool flagEquals;
    nsCOMPtr<nsIFile> fileName = nsnull;
    //nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) ); //nsIFileXXX: nsFilePath?
    nsVoidKey ikey( HashFilePath( mTargetFile ));

    mInstall->GetPatch(&ikey, getter_AddRefs(fileName));

    fileName->Equals(mPatchedFile, &flagEquals);
    if (fileName != nsnull && (flagEquals) )
    {
        DeleteFileNowOrSchedule( mPatchedFile );
    }
}

Here is the call graph for this function:

Implements nsInstallObject.

Definition at line 394 of file nsInstallPatch.cpp.

{
    return PR_FALSE;
}

Implements nsInstallObject.

Definition at line 294 of file nsInstallPatch.cpp.

{  
    PRBool flagEquals;

    if ((mInstall == nsnull) || (mVersionInfo == nsnull) || (mPatchedFile == nsnull) || (mTargetFile == nsnull)) 
    {
        return nsInstall::INVALID_ARGUMENTS;
    }
    
    PRInt32 err = nsInstall::SUCCESS;

    nsCOMPtr<nsIFile> fileName = nsnull;
    //nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) )  );//nsIFileXXX: nsFilePath?
    nsVoidKey ikey( HashFilePath( mTargetFile ));
    
    mInstall->GetPatch(&ikey, getter_AddRefs(fileName));
    
    if (fileName == nsnull)
    {
        err = nsInstall::UNEXPECTED_ERROR;
    }
    else
    {
      fileName->Equals(mPatchedFile, &flagEquals);
      if (flagEquals) 
      {
        // the patch has not been superceded--do final replacement
        err = ReplaceFileNowOrSchedule( mPatchedFile, mTargetFile, 0);
        if ( 0 == err || nsInstall::REBOOT_NEEDED == err ) 
        {
            nsString tempVersionString;
            mVersionInfo->ToString(tempVersionString);
            
            nsCAutoString tempPath;
            mTargetFile->GetNativePath(tempPath);

            // DO NOT propogate version registry errors, it will abort 
            // FinalizeInstall() leaving things hosed. These piddly errors
            // aren't worth that.
            VR_Install( NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(*mRegistryName).get()),
                        NS_CONST_CAST(char *, tempPath.get()),
                        NS_CONST_CAST(char *, NS_ConvertUCS2toUTF8(tempVersionString).get()),
                        PR_FALSE );
        }
        else
        {
            err = nsInstall::UNEXPECTED_ERROR;
        }
      }
      else
      {
        // nothing -- old intermediate patched file was
        // deleted by a superceding patch
      }
    }
    return err;
}

Here is the call graph for this function:

void * nsInstallPatch::HashFilePath ( nsIFile aPath) [private]

Definition at line 714 of file nsInstallPatch.cpp.

{
    PRUint32 rv = 0;

    nsCAutoString cPath;
    aPath->GetNativePath(cPath);
    
    if (!cPath.IsEmpty())
    {
        char  ch;
        const char* pathIndex = cPath.get();

        while ((ch = *pathIndex++) != 0) 
        {
            // FYI: rv = rv*37 + ch
            rv = ((rv << 5) + (rv << 2) + rv) + ch;
        }
    }

    return (void*)rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsInstallPatch::NativePatch ( nsIFile sourceFile,
nsIFile patchfile,
nsIFile **  newFile 
) [private]

Definition at line 407 of file nsInstallPatch.cpp.

{

       PRBool flagExists;
  nsresult rv;
  DIFFDATA      *dd;
       PRInt32                status                = GDIFF_ERR_MEM;
       char              *tmpurl             = NULL;
       //nsFileSpec  *outFileSpec = new nsFileSpec; 
  //nsFileSpec  *tempSrcFile = new nsFileSpec;   // TODO: do you need to free?
  nsCOMPtr<nsIFile> outFileSpec;
  nsCOMPtr<nsIFile> tempSrcFile;
  nsCOMPtr<nsILocalFile> uniqueSrcFile;
  nsCOMPtr<nsILocalFile> patchFileLocal = do_QueryInterface(patchFile, &rv);
  
  nsCAutoString realfile;
  sourceFile->GetNativePath(realfile);

  sourceFile->Clone(getter_AddRefs(outFileSpec));

       dd = (DIFFDATA *)PR_Calloc( 1, sizeof(DIFFDATA));
       if (dd != NULL)
       {
              dd->databuf = (uchar*)PR_Malloc(BUFSIZE);
              if (dd->databuf == NULL) 
              {
                     status = GDIFF_ERR_MEM;
                     goto cleanup;
              }


              dd->bufsize = BUFSIZE;

              // validate patch header & check for special instructions
    // we're just reading, the 0400 is an annotation.
    patchFileLocal->OpenNSPRFileDesc(PR_RDONLY, 0400, &dd->fDiff);

              if (dd->fDiff != NULL)
              {
                     status = gdiff_parseHeader(dd);
              } 
    else 
    {
                     status = GDIFF_ERR_ACCESS;
              }


    // in case we need to unbind Win32 images OR encode Mac file
    if (( dd->bWin32BoundImage || dd->bMacAppleSingle) && (status == GDIFF_OK ))
    {
        // make an unique tmp file  (FILENAME-src.EXT)
        nsAutoString leafName;
        rv = sourceFile->GetLeafName(leafName);

        NS_NAMED_LITERAL_STRING(tmpName, "-src");

        PRInt32 i;
        if ((i = leafName.RFindChar('.')) > 0)
        {
            // build the temp filename for which to unbind the file to.
            // eg: if the filename is bind.dll, the temp src filename would
            //     be bind-src.dll
            nsAutoString ext;
            nsAutoString fName;
            // get the extension
            leafName.Right(ext, (leafName.Length() - i) );
            // get the filename - extension
            leafName.Left(fName, (leafName.Length() - (leafName.Length() - i)));
            // build the temp filename with '-src' at the end of filename,
            // but before extension
            leafName.Assign(fName);
            leafName.Append(tmpName);
            leafName.Append(ext);
        } else {
            // no extension found, just append '-src' to the end of filename
            leafName.Append(tmpName);
        }
        
    
        rv = sourceFile->Clone(getter_AddRefs(tempSrcFile));  //Clone the sourceFile
        tempSrcFile->SetLeafName(leafName); //Append the new leafname
        uniqueSrcFile = do_QueryInterface(tempSrcFile, &rv);
        uniqueSrcFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);

#ifdef WIN32
        // unbind Win32 images

        nsCAutoString unboundFile;
        uniqueSrcFile->GetNativePath(unboundFile);

        if (su_unbind(NS_CONST_CAST(char*, realfile.get()), NS_CONST_CAST(char*,unboundFile.get())))  //
        {
            // un-binding worked, save the tmp name for later
            uniqueSrcFile->GetNativePath(realfile);
        }
        else
        {
            status = GDIFF_ERR_MEM;
        }
        unboundFile.Truncate();
#endif
#ifdef XP_MAC
   // Encode src file, and put into temp file
        FSSpec sourceSpec, tempSpec;
        nsCOMPtr<nsILocalFileMac> tempSourceFile;
        tempSourceFile = do_QueryInterface(sourceFile, &rv);
        tempSourceFile->GetFSSpec(&sourceSpec);
    
        status = PAS_EncodeFile(&sourceSpec, &tempSpec);   

        if (status == noErr)
        {
            // set
            tempSrcFile->GetNativePath(realfile);
        }
#endif
    }

    if (status != NS_OK)
    goto cleanup;

    // make a unique file at the same location of our source file  (FILENAME-ptch.EXT)
    NS_NAMED_LITERAL_STRING(patchFileName, "-ptch");
    nsAutoString newFileName;
    sourceFile->GetLeafName(newFileName);

    PRInt32 index;
    if ((index = newFileName.RFindChar('.')) > 0)
    {
        nsAutoString extention;
        nsAutoString fileName;
        newFileName.Right(extention, (newFileName.Length() - index) );        
        newFileName.Left(fileName, (newFileName.Length() - (newFileName.Length() - index)));
        newFileName = fileName + patchFileName + extention;

    }
    else
    {
        newFileName += patchFileName;
    }


    outFileSpec->SetLeafName(newFileName);  //Set new leafname
    nsCOMPtr<nsILocalFile> outFileLocal = do_QueryInterface(outFileSpec, &rv); 
    outFileLocal->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);

    // apply patch to the source file
    //dd->fSrc = PR_Open ( realfile, PR_RDONLY, 0666);
    //dd->fOut = PR_Open ( outFile, PR_RDWR|PR_CREATE_FILE|PR_TRUNCATE, 0666);
    nsCOMPtr<nsILocalFile> realFileLocal = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);;
    realFileLocal->InitWithNativePath(realfile);

    // it's ok for people in the group to modify these files later, but it wouldn't be good for just anyone.
    realFileLocal->OpenNSPRFileDesc(PR_RDONLY, 0664, &dd->fSrc);
    outFileLocal->OpenNSPRFileDesc(PR_RDWR|PR_CREATE_FILE|PR_TRUNCATE, 0664, &dd->fOut);

    if (dd->fSrc != NULL && dd->fOut != NULL)
    {
        status = gdiff_validateFile (dd, SRCFILE);

        // specify why diff failed
        if (status == GDIFF_ERR_CHECKSUM)
            status = GDIFF_ERR_CHECKSUM_TARGET;

        if (status == GDIFF_OK)
            status = gdiff_ApplyPatch(dd);

        if (status == GDIFF_OK)
            status = gdiff_validateFile (dd, OUTFILE);

        if (status == GDIFF_ERR_CHECKSUM)
            status = GDIFF_ERR_CHECKSUM_RESULT;

        rv = outFileSpec->Clone(newFile);
    } 
    else 
    {
        status = GDIFF_ERR_ACCESS;
    }
  }



#ifdef XP_MAC
  if ( dd->bMacAppleSingle && status == GDIFF_OK ) 
 {
        // create another file, so that we can decode somewhere
        //nsFileSpec anotherName = *outFileSpec;
        nsCOMPtr<nsILocalFile> anotherName;
        nsCOMPtr<nsIFile> bsTemp;
        
        outFileSpec->Clone(getter_AddRefs(bsTemp));   //Clone because we'll be changing the name
        anotherName = do_QueryInterface(bsTemp, &rv); //Set the old name
        anotherName->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);

              // Close the out file so that we can read it            
              PR_Close( dd->fOut );
              dd->fOut = NULL;
              
              FSSpec outSpec;
              FSSpec anotherSpec;
              nsCOMPtr<nsILocalFileMac> outSpecMacSpecific;
              nsCOMPtr<nsILocalFileMac> anotherNameMacSpecific;
              
              anotherNameMacSpecific = do_QueryInterface(anotherName, &rv); //set value to nsILocalFileMac (sheesh)
              outSpecMacSpecific = do_QueryInterface(outFileSpec, &rv); //ditto 
              
              anotherNameMacSpecific->GetFSSpec(&anotherSpec);
              outSpecMacSpecific->GetFSSpec(&outSpec);
              
              outFileSpec->Exists(&flagExists);
              if ( flagExists )
              {
                  PRInt64 fileSize;
                  outFileSpec->GetFileSize(&fileSize);
              }
              
                     
        status =  PAS_DecodeFile(&outSpec, &anotherSpec);
              if (status != noErr)
              {
                     goto cleanup;
        }
              
        nsCOMPtr<nsIFile> parent;
        
        outFileSpec->GetParent(getter_AddRefs(parent));
        outFileSpec->Remove(PR_FALSE);

        nsAutoString leaf;
        anotherName->GetLeafName(leaf);
        anotherName->CopyTo(parent, leaf);
        anotherName->Clone(newFile);
       }
       
#endif 


cleanup:
    if ( dd != NULL ) 
    {
        if ( dd->fSrc != nsnull )
            PR_Close( dd->fSrc );

        if ( dd->fDiff != nsnull )
            PR_Close( dd->fDiff );

        if ( dd->fOut != nsnull )
            PR_Close( dd->fOut );

        if ( status != GDIFF_OK )
        //XP_FileRemove( outfile, outtype );
            newFile = NULL;

        PR_FREEIF( dd->databuf );
        PR_FREEIF( dd->oldChecksum );
        PR_FREEIF( dd->newChecksum );
        PR_DELETE(dd);
    }

    if ( tmpurl != NULL ) {
        //XP_FileRemove( tmpurl, xpURL );
        tmpurl = NULL;
        PR_DELETE( tmpurl );
    }

    if (tempSrcFile)
    {
        tempSrcFile->Exists(&flagExists);
        if (flagExists)
            tempSrcFile->Remove(PR_FALSE);
    }

    /* lets map any GDIFF error to nice SU errors */

    switch (status)
    {
        case GDIFF_OK:
                break;
        case GDIFF_ERR_HEADER:
        case GDIFF_ERR_BADDIFF:
        case GDIFF_ERR_OPCODE:
        case GDIFF_ERR_CHKSUMTYPE:
            status = nsInstall::PATCH_BAD_DIFF;
            break;
        case GDIFF_ERR_CHECKSUM_TARGET:
            status = nsInstall::PATCH_BAD_CHECKSUM_TARGET;
            break;
        case GDIFF_ERR_CHECKSUM_RESULT:
            status = nsInstall::PATCH_BAD_CHECKSUM_RESULT;
            break;
        case GDIFF_ERR_OLDFILE:
        case GDIFF_ERR_ACCESS:
        case GDIFF_ERR_MEM:
        case GDIFF_ERR_UNKNOWN:
        default:
            status = nsInstall::UNEXPECTED_ERROR;
            break;
    }

    return status;

    // return -1;    //old return value
}

Here is the call graph for this function:

Here is the caller graph for this function:

Implements nsInstallObject.

Definition at line 210 of file nsInstallPatch.cpp.

{
    PRInt32 err;
    PRBool deleteOldSrc, flagExists, flagIsFile;
    
    if (mTargetFile == nsnull)
        return  nsInstall::INVALID_ARGUMENTS;

    mTargetFile->Exists(&flagExists);
    if (flagExists)
    {
        mTargetFile->IsFile(&flagIsFile);
        if (flagIsFile)
        {
            err = nsInstall::SUCCESS;
        }
        else
        {
            err = nsInstall::IS_DIRECTORY;
        }
    }
    else
    {
        err = nsInstall::DOES_NOT_EXIST;
    }

    if (err != nsInstall::SUCCESS)
    {   
        return err;
    }

    err =  mInstall->ExtractFileFromJar(*mJarLocation, mTargetFile, getter_AddRefs(mPatchFile));
   
    
    nsCOMPtr<nsIFile> fileName = nsnull;
    //nsVoidKey ikey( HashFilePath( nsFilePath(*mTargetFile) ) );//nsIFileXXX: nsFilePath?
    nsVoidKey ikey( HashFilePath( mTargetFile ));

    mInstall->GetPatch(&ikey, getter_AddRefs(fileName));

    if (fileName != nsnull) 
    {
        deleteOldSrc = PR_TRUE;
    } 
    else 
    {
        fileName     = mTargetFile;
        deleteOldSrc = PR_FALSE;
    }

    err = NativePatch(  fileName,           // the file to patch
                        mPatchFile,         // the patch that was extracted from the jarfile
                        getter_AddRefs(mPatchedFile));     // the new patched file
    
    // clean up extracted diff data file
    mPatchFile->Exists(&flagExists);
    if ( (mPatchFile != nsnull) && (flagExists) )
    {
        mPatchFile->Remove(PR_FALSE);
    }


    if (err != nsInstall::SUCCESS)
    {   
        // clean up tmp patched file since patching failed
      mPatchFile->Exists(&flagExists);
                if ((mPatchedFile != nsnull) && (flagExists))
      {
                         mPatchedFile->Remove(PR_FALSE);
      }
              return err;
    }

    PR_ASSERT(mPatchedFile != nsnull);
    mInstall->AddPatch(&ikey, mPatchedFile );

    if ( deleteOldSrc ) 
    {
    DeleteFileNowOrSchedule(fileName );
    }
  
    return err;
}

Here is the call graph for this function:

Implements nsInstallObject.

Definition at line 400 of file nsInstallPatch.cpp.

{
    return PR_TRUE;
}
char * nsInstallPatch::toString ( ) [virtual]

Implements nsInstallObject.

Definition at line 368 of file nsInstallPatch.cpp.

{
         char* buffer = new char[1024];
    char* rsrcVal = nsnull;

    if (buffer == nsnull || !mInstall)
        return buffer;

    if (mTargetFile != nsnull)
    {
        rsrcVal = mInstall->GetResourcedString(NS_LITERAL_STRING("Patch"));

        if (rsrcVal)
        {
            nsCAutoString temp;
            mTargetFile->GetNativePath(temp);
            sprintf( buffer, rsrcVal, temp.get()); 
            nsCRT::free(rsrcVal);
        }
    }

       return buffer;
}

Here is the call graph for this function:


Member Data Documentation

nsInstall* nsInstallObject::mInstall [protected, inherited]

Definition at line 69 of file nsInstallObject.h.

Definition at line 89 of file nsInstallPatch.h.

Definition at line 87 of file nsInstallPatch.h.

Definition at line 86 of file nsInstallPatch.h.

Definition at line 90 of file nsInstallPatch.h.

Definition at line 85 of file nsInstallPatch.h.

Definition at line 83 of file nsInstallPatch.h.


The documentation for this class was generated from the following files: