Back to index

lightning-sunbird  0.9+nobinonly
Functions
ScheduledTasks.cpp File Reference
#include "nscore.h"
#include "nsXPIDLString.h"
#include "nsInstall.h"
#include "prmem.h"
#include "ScheduledTasks.h"
#include "InstallCleanupDefines.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#include "nsAppDirectoryServiceDefs.h"

Go to the source code of this file.

Functions

static nsresult GetPersistentStringFromSpec (nsIFile *inSpec, nsACString &string)
nsresult GetRegFilePath (nsACString &regFilePath)
PRInt32 DeleteFileNowOrSchedule (nsIFile *filename)
PRInt32 ScheduleFileForDeletion (nsIFile *filename)
PRInt32 ReplaceFileNow (nsIFile *aReplacementFile, nsIFile *aDoomedFile)
PRInt32 ReplaceFileNowOrSchedule (nsIFile *aReplacementFile, nsIFile *aDoomedFile, PRInt32 aMode)
void DeleteScheduledFiles (HREG)
void ReplaceScheduledFiles (HREG)
void PerformScheduledTasks (HREG reg)

Function Documentation

Definition at line 174 of file ScheduledTasks.cpp.

{
    PRBool flagExists;  
    PRInt32 result = nsInstall::SUCCESS;

    filename->Remove(PR_FALSE);
    filename->Exists(&flagExists);
    if (flagExists)
        result = ScheduleFileForDeletion(filename);
 
    return result;
} 

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 111 of file InstallCleanup.cpp.

{
    REGERR  err;
    RKEY    key;
    REGENUM state = 0;
    int rv = DONE;

    /* perform scheduled file deletions  */
    if (REGERR_OK == NR_RegGetKey(reg,ROOTKEY_PRIVATE,REG_DELETE_LIST_KEY,&key))
    {
        // the delete key exists, so we loop through its children
        // and try to delete all the listed files

        char    namebuf[MAXREGNAMELEN];
        char    valbuf[MAXREGPATHLEN];

        while (REGERR_OK == NR_RegEnumEntries( reg, key, &state, namebuf,
                                               sizeof(namebuf), 0 ) )
        {
            uint32 bufsize = sizeof(valbuf); // gets changed, must reset
            err = NR_RegGetEntry( reg, key, namebuf, valbuf, &bufsize );
            if ( err == REGERR_OK )
            {
                rv = NativeDeleteFile(valbuf);
                if (rv == DONE)
                    NR_RegDeleteEntry( reg, key, namebuf);
            }
        }

        /* delete list node if empty */
        state = 0;
        err = NR_RegEnumEntries(reg, key, &state, namebuf, sizeof(namebuf), 0);
        if ( err == REGERR_NOMORE )
        {
            NR_RegDeleteKey(reg, ROOTKEY_PRIVATE, REG_DELETE_LIST_KEY);
            rv = DONE;
        }
        else
        {
            rv = TRY_LATER;
        }
    }
    return rv;
}

Here is the call graph for this function:

static nsresult GetPersistentStringFromSpec ( nsIFile inSpec,
nsACString &  string 
) [static]

Definition at line 53 of file ScheduledTasks.cpp.

{
    nsresult rv;

    nsCOMPtr<nsILocalFile> LocalFile = do_QueryInterface(inSpec, &rv);

    if (NS_SUCCEEDED(rv)) {
        rv = LocalFile->GetNativePath(string);
    } 
    else {
        string.Truncate();
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult GetRegFilePath ( nsACString &  regFilePath)

Definition at line 134 of file ScheduledTasks.cpp.

{
    nsresult rv;
    nsCOMPtr<nsILocalFile> iFileUtilityPath;
    //Get the program directory
    nsCOMPtr<nsIProperties> directoryService = 
             do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
    if (NS_FAILED(rv))
        return nsnull;

    if (nsSoftwareUpdate::GetProgramDirectory()) // In the stub installer
    {
        nsCOMPtr<nsIFile> tmp;
        rv = nsSoftwareUpdate::GetProgramDirectory()->Clone(getter_AddRefs(tmp));

        if (NS_FAILED(rv) || !tmp) 
            return nsnull;

#if defined (XP_MAC)
        tmp->AppendNative(ESSENTIAL_FILES);
#endif
        iFileUtilityPath = do_QueryInterface(tmp);
    }
    else
    {
        rv = directoryService->Get(NS_APP_INSTALL_CLEANUP_DIR,
                                  NS_GET_IID(nsIFile),
                                  getter_AddRefs(iFileUtilityPath));
    }
    if (NS_FAILED(rv) || !iFileUtilityPath) 
        return nsnull;

    iFileUtilityPath->AppendNative(CLEANUP_REGISTRY);

    //Yes, we know using GetPath is buggy on the Mac.
    //When libreg is fixed to accept nsIFiles we'll change this to match.
    return iFileUtilityPath->GetNativePath(regFilePath);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 479 of file ScheduledTasks.cpp.

Here is the call graph for this function:

PRInt32 ReplaceFileNow ( nsIFile aReplacementFile,
nsIFile aDoomedFile 
)

Definition at line 238 of file ScheduledTasks.cpp.

{
    PRBool flagExists, flagRenamedDoomedFileExists, flagIsEqual;
    nsCOMPtr<nsIFile> replacementFile;
    nsresult rv;

    // make a clone of aReplacement file so we touch affect callers
    aReplacementFile->Clone(getter_AddRefs(replacementFile));

    // replacement file must exist, doomed file doesn't have to
    replacementFile->Exists(&flagExists);
    if ( !flagExists )
        return nsInstall::DOES_NOT_EXIST;

    // don't have to do anything if the files are the same
    replacementFile->Equals(aDoomedFile, &flagIsEqual);
    if ( flagIsEqual )
        return nsInstall::SUCCESS;


    PRInt32 result = nsInstall::ACCESS_DENIED;

    // first try to rename the doomed file out of the way (if it exists)
    nsCOMPtr<nsIFile>      renamedDoomedFile;
    nsCOMPtr<nsILocalFile> tmpLocalFile;
    
    aDoomedFile->Clone(getter_AddRefs(renamedDoomedFile));
    renamedDoomedFile->Exists(&flagRenamedDoomedFileExists);
    if ( flagRenamedDoomedFileExists )
    {
#ifdef XP_MACOSX
        // If we clone an nsIFile, and move the clone, the FSRef of the *original*
        // file is not what you would expect - it points to the moved file. This
        // is despite the fact that the two FSRefs are independent objects. Until
        // the OS X file impl is changed to not use FSRefs, need to do this (see
        // bug 200024).
        nsCOMPtr<nsILocalFile> doomedFileLocal = do_QueryInterface(aDoomedFile);
        nsCAutoString doomedFilePath;
        rv = doomedFileLocal->GetNativePath(doomedFilePath);
        if (NS_FAILED(rv))
            return nsInstall::UNEXPECTED_ERROR;
#endif

        tmpLocalFile = do_QueryInterface(renamedDoomedFile, &rv); // Convert to an nsILocalFile

        //get the doomedLeafname so we can convert its extension to .old
        nsAutoString doomedLeafname;
        nsCAutoString uniqueLeafName;
        tmpLocalFile->GetLeafName(doomedLeafname);

        // do not RFind on the native charset! UTF8 or Unicode are OK
        PRInt32 extpos = doomedLeafname.RFindChar('.');
        if (extpos != -1)
        {
            // We found the extension; 
            doomedLeafname.Truncate(extpos + 1); //strip off the old extension
        }
        doomedLeafname.AppendLiteral("old");
        
        //Now reset the doomedLeafname
        tmpLocalFile->SetLeafName(doomedLeafname);
        tmpLocalFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0644);
        tmpLocalFile->GetNativeLeafName(uniqueLeafName);//this is the new "unique" doomedLeafname

        rv = aDoomedFile->Clone(getter_AddRefs(renamedDoomedFile));// Reset renamedDoomed file so aDoomedfile
                                                                   // isn't changed during the MoveTo call
        if (NS_FAILED(rv))
            result = nsInstall::UNEXPECTED_ERROR;
        else
        {
            rv = renamedDoomedFile->MoveToNative(nsnull, uniqueLeafName);        
            if (NS_FAILED(rv))
            {
                // MoveToNative() failing is OK.  It simply means that the file
                // was locked in memory and needs to be replaced on browser
                // shutdown or system reboot.
                //
                // Since renamedDoomedFile->MoveToNative() failed, it created a
                // 0 byte '-old' file that needs to be cleaned up.
                tmpLocalFile->Remove(PR_FALSE);
            }
            else
            {
                // The implementation of MoveToNative() on some platforms (osx and win32) resets
                // the object to the 'moved to' filename.  This is incorrect behavior.  This
                // implementation will be fixed in the future.  We need to take into account that
                // fix by setting renamedDoomedFile to the filename that it was moved to above.
                // See bug 200024.
                //
                // renamedDoomedFile needs to be reset because it's used later on in this
                // function.
                rv = renamedDoomedFile->SetNativeLeafName(uniqueLeafName);        
                if (NS_FAILED(rv))
                    result = nsInstall::UNEXPECTED_ERROR;
            }
        }

#ifdef XP_MACOSX
        rv = doomedFileLocal->InitWithNativePath(doomedFilePath);
        if (NS_FAILED(rv))
            result = nsInstall::UNEXPECTED_ERROR;
#endif

        if (result == nsInstall::UNEXPECTED_ERROR)
            return result;
    }


    // if aDoomedFile is still in the way, give up and return result.
    aDoomedFile->Exists(&flagExists);
    if ( flagExists )
        return result;

    nsCOMPtr<nsIFile> parentofDoomedFile;
    nsCAutoString doomedLeafname;

    rv = aDoomedFile->GetParent(getter_AddRefs(parentofDoomedFile));
    if ( NS_SUCCEEDED(rv) )
        rv = aDoomedFile->GetNativeLeafName(doomedLeafname);
    if ( NS_SUCCEEDED(rv) )
    {
        rv = replacementFile->MoveToNative(parentofDoomedFile, doomedLeafname);
        // The implementation of MoveToNative() on some platforms (osx and win32) resets
        // the object to the 'moved to' filename.  This is incorrect behavior.  This
        // implementation will be fixed in the future.  We need to take into account that
        // fix by setting replacementFile to the filename that it was moved to above.
        // See bug 200024.
        //
        // However, since replacementFile is a clone of aReplacementFile and is also
        // not used beyond here, there's no need to set the path+leafname to what
        // it was MoveToNative()'ed to.
    }

    if (NS_SUCCEEDED(rv))
    {
        if (flagRenamedDoomedFileExists)
        {
            // we replaced the old file OK, now we have to
            // get rid of it if it was renamed out of the way
            result = DeleteFileNowOrSchedule( renamedDoomedFile );
        }
    }
    else
    {
        // couldn't rename file, try to put old file back
        renamedDoomedFile->MoveToNative(nsnull, doomedLeafname);
        // No need to reset remanedDoomedFile after a MoveToNative() call
        // because renamedDoomedFile is not used beyond here.
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 ReplaceFileNowOrSchedule ( nsIFile aReplacementFile,
nsIFile aDoomedFile,
PRInt32  aMode 
)

Definition at line 395 of file ScheduledTasks.cpp.

{
    PRInt32 result = ReplaceFileNow( aReplacementFile, aDoomedFile );

    if ( result == nsInstall::ACCESS_DENIED )
    {
        // if we couldn't replace the file schedule it for later
#ifdef _WINDOWS
        if ( (aMode & WIN_SYSTEM_FILE) && 
             (ReplaceWindowsSystemFile(aReplacementFile, aDoomedFile) == 0) )
                return nsInstall::REBOOT_NEEDED;
#endif

        RKEY    listkey;
        RKEY    filekey;
        HREG    reg;
        REGERR  err;

        nsCAutoString regFilePath;
        GetRegFilePath(regFilePath);
        if ( REGERR_OK == NR_RegOpen(NS_CONST_CAST(char*, regFilePath.get()), &reg) ) 
        {
            err = NR_RegAddKey( reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY, &listkey );
            if ( err == REGERR_OK ) 
            {
                char     valname[20];
                REGERR   err2;

                err = NR_RegGetUniqueName( reg, valname, sizeof(valname) );
                if ( err == REGERR_OK )
                {
                    err = NR_RegAddKey( reg, listkey, valname, &filekey );
                    if ( REGERR_OK == err )
                    {
                        nsCAutoString srcowner;
                        nsCAutoString destowner;
                        nsresult rv = GetPersistentStringFromSpec(aReplacementFile, srcowner);
                        nsresult rv2 = GetPersistentStringFromSpec(aDoomedFile, destowner);
                        if ( NS_SUCCEEDED(rv) && NS_SUCCEEDED(rv2) )
                        {
                            const char *fsrc  = srcowner.get();
                            const char *fdest = destowner.get();
                            err = NR_RegSetEntry( reg, filekey, 
                                                  REG_REPLACE_SRCFILE,
                                                  REGTYPE_ENTRY_BYTES, 
                                                  (void*)fsrc, 
                                                  strlen(fsrc)+sizeof('\0'));

                            err2 = NR_RegSetEntry(reg, filekey,
                                                  REG_REPLACE_DESTFILE,
                                                  REGTYPE_ENTRY_BYTES,
                                                  (void*)fdest,
                                                  strlen(fdest)+sizeof('\0'));

                            if ( err == REGERR_OK && err2 == REGERR_OK )
                            {
                                result = nsInstall::REBOOT_NEEDED;
                                nsSoftwareUpdate::NeedCleanup();
                            }
                            else
                                NR_RegDeleteKey( reg, listkey, valname );
                        }
                    }
                }
            }
            NR_RegClose(reg);
        }
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 56 of file InstallCleanup.cpp.

{
    RKEY    key;
    int rv = DONE;

    /* replace files if any listed */
    if (REGERR_OK == NR_RegGetKey(reg,ROOTKEY_PRIVATE,REG_REPLACE_LIST_KEY,&key))
    {
        char keyname[MAXREGNAMELEN];
        char doomedFile[MAXREGPATHLEN];
        char srcFile[MAXREGPATHLEN];

        uint32 bufsize;
        REGENUM state = 0;
        while (REGERR_OK == NR_RegEnumSubkeys( reg, key, &state, 
                               keyname, sizeof(keyname), REGENUM_CHILDREN))
        {
            bufsize = sizeof(srcFile);
            REGERR err1 = NR_RegGetEntry( reg, (RKEY)state,
                               REG_REPLACE_SRCFILE, &srcFile, &bufsize);

            bufsize = sizeof(doomedFile);
            REGERR err2 = NR_RegGetEntry( reg, (RKEY)state,
                               REG_REPLACE_DESTFILE, &doomedFile, &bufsize);

            if ( err1 == REGERR_OK && err2 == REGERR_OK )
            {
                int result = NativeReplaceFile( srcFile, doomedFile );
                if (result == DONE)
                {
                    // This one is done
                    NR_RegDeleteKey( reg, key, keyname );
                }
            }
        }

        /* delete list node if empty */
        state = 0;
        if (REGERR_NOMORE == NR_RegEnumSubkeys( reg, key, &state, keyname,
                                     sizeof(keyname), REGENUM_CHILDREN ))
        {
            NR_RegDeleteKey(reg, ROOTKEY_PRIVATE, REG_REPLACE_LIST_KEY);
            rv = DONE;
        }
        else
        {
            rv = TRY_LATER;
        }
    }
    return rv;
}

Here is the call graph for this function:

Definition at line 187 of file ScheduledTasks.cpp.

{
    // could not delete, schedule it for later

    RKEY newkey;
    HREG reg;
    REGERR  err;
    PRInt32 result = nsInstall::UNEXPECTED_ERROR;

    nsCAutoString path;
    GetRegFilePath(path);
    err = NR_RegOpen(NS_CONST_CAST(char*, path.get()), &reg);

    if ( err == REGERR_OK )
    {
        err = NR_RegAddKey(reg,ROOTKEY_PRIVATE,REG_DELETE_LIST_KEY,&newkey);
        if ( err == REGERR_OK )
        {
            char    valname[20];

            err = NR_RegGetUniqueName( reg, valname, sizeof(valname) );
            if ( err == REGERR_OK )
            {
                nsCAutoString nameowner;
                nsresult rv = GetPersistentStringFromSpec(filename, nameowner);
                if ( NS_SUCCEEDED(rv) && !nameowner.IsEmpty() )
                {
                    const char *fnamestr = nameowner.get();
                    err = NR_RegSetEntry( reg, newkey, valname, 
                                          REGTYPE_ENTRY_BYTES, 
                                          (void*)fnamestr, 
                                          strlen(fnamestr)+sizeof('\0'));

                    if ( err == REGERR_OK )
                    {
                         result = nsInstall::REBOOT_NEEDED;
                         nsSoftwareUpdate::NeedCleanup();
                    }
                }
            }
        }

        NR_RegClose(reg);
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function: