示例#1
0
// called whenever global preferences change or a file is
// added or removed from gFileHistory (in order to keep
// the list of recently opened documents in sync)
bool Save()
{
    // don't save preferences without the proper permission
    if (!HasPermission(Perm_SavePreferences))
        return false;

    /* mark currently shown files as visible */
    for (size_t i = 0; i < gWindows.Count(); i++) {
        UpdateCurrentFileDisplayStateForWin(gWindows.At(i));
    }

    // remove entries which should (no longer) be remembered
    gFileHistory.Purge(!gGlobalPrefs->rememberStatePerDocument);
    // update display mode and zoom fields from internal values
    str::ReplacePtr(&gGlobalPrefs->defaultDisplayMode, conv::FromDisplayMode(gGlobalPrefs->defaultDisplayModeEnum));
    conv::FromZoom(&gGlobalPrefs->defaultZoom, gGlobalPrefs->defaultZoomFloat);

    ScopedMem<WCHAR> path(GetSettingsPath());
    CrashIf(!path);
    if (!path)
        return false;
    size_t prevPrefsDataSize;
    ScopedMem<char> prevPrefsData(file::ReadAll(path, &prevPrefsDataSize));

    if (!gGlobalPrefs->rememberStatePerDocument || !gGlobalPrefs->rememberOpenedFiles) {
        for (DisplayState **ds = gGlobalPrefs->fileStates->IterStart(); ds; ds = gGlobalPrefs->fileStates->IterNext()) {
            (*ds)->useDefaultState = true;
        }
        // prevent unnecessary settings from being written out
        uint16_t fieldCount = 0;
        while (++fieldCount <= dimof(gFileStateFields)) {
            // count the number of fields up to and including useDefaultState
            if (gFileStateFields[fieldCount - 1].offset == offsetof(FileState, useDefaultState))
                break;
        }
        // restore the correct fieldCount ASAP after serialization
        gFileStateInfo.fieldCount = fieldCount;
    }

    size_t prefsDataSize;
    ScopedMem<char> prefsData(SerializeStruct(&gGlobalPrefsInfo, gGlobalPrefs, prevPrefsData, &prefsDataSize));

    if (!gGlobalPrefs->rememberStatePerDocument || !gGlobalPrefs->rememberOpenedFiles)
        gFileStateInfo.fieldCount = dimof(gFileStateFields);

    CrashIf(!prefsData || 0 == prefsDataSize);
    if (!prefsData || 0 == prefsDataSize)
        return false;

    // only save if anything's changed at all
    if (prevPrefsDataSize == prefsDataSize && str::Eq(prefsData, prevPrefsData))
        return true;

    FileTransaction trans;
    bool ok = trans.WriteAll(path, prefsData, prefsDataSize) && trans.Commit();
    if (!ok)
        return false;
    gGlobalPrefs->lastPrefUpdate = file::GetModificationTime(path);
    return true;
}
示例#2
0
bool SaveFileModifictions(const WCHAR *filePath, Vec<PageAnnotation> *list)
{
    if (!list)
        return false;

    ScopedMem<WCHAR> modificationsPath(str::Join(filePath, SMX_FILE_EXT));
    str::Str<char> data;
    size_t offset = 0;

    ScopedMem<char> prevData(file::ReadAll(modificationsPath, NULL));
    Vec<PageAnnotation> *prevList = ParseFileModifications(prevData);
    if (prevList) {
        // in the case of an update, append changed annotations to the existing ones
        // (don't rewrite the existing ones in case they're by a newer version which
        // added annotation types and properties this version doesn't know anything about)
        for (; offset < prevList->Count() && prevList->At(offset) == list->At(offset); offset++);
        CrashIf(offset != prevList->Count());
        data.AppendAndFree(prevData.StealData());
        delete prevList;
    }
    else {
        data.AppendFmt("# SumatraPDF: modifications to \"%S\"\r\n", path::GetBaseName(filePath));
    }
    data.Append("\r\n");

    if (list->Count() == offset)
        return true; // nothing (new) to save

    data.AppendFmt("[@%s]\r\n", prevList ? "update" : "meta");
    data.AppendFmt("version = %s\r\n", SMX_CURR_VERSION);
    int64 size = file::GetSize(filePath);
    if (0 <= size && size <= UINT_MAX)
        data.AppendFmt("filesize = %u\r\n", (UINT)size);
    SYSTEMTIME time;
    GetSystemTime(&time);
    data.AppendFmt("timestamp = %04d-%02d-%02dT%02d:%02d:%02dZ\r\n",
        time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond);
    data.Append("\r\n");

    for (size_t i = offset; i < list->Count(); i++) {
        PageAnnotation& annot = list->At(i);
        switch (annot.type) {
        case Annot_Highlight: data.Append("[highlight]\r\n"); break;
        case Annot_Underline: data.Append("[underline]\r\n"); break;
        case Annot_StrikeOut: data.Append("[strikeout]\r\n"); break;
        case Annot_Squiggly:  data.Append("[squiggly]\r\n");  break;
        default: continue;
        }
        data.AppendFmt("page = %d\r\n", annot.pageNo);
        data.AppendFmt("rect = %g %g %g %g\r\n", annot.rect.x, annot.rect.y, annot.rect.dx, annot.rect.dy);
        data.AppendFmt("color = #%02x%02x%02x\r\n", annot.color.r, annot.color.g, annot.color.b);
        data.AppendFmt("opacity = %g\r\n", annot.color.a / 255.f);
        data.Append("\r\n");
    }
    data.RemoveAt(data.Size() - 2, 2);

    FileTransaction trans;
    return trans.WriteAll(modificationsPath, data.LendData(), data.Size()) && trans.Commit();
}
示例#3
0
bool Save(const WCHAR *filepath, SerializableGlobalPrefs& globalPrefs,
          FileHistory& fileHistory, Favorites* favs)
{
    CrashIf(!filepath);
    if (!filepath) return false;

    size_t dataLen;
    ScopedMem<char> data(SerializePrefs(globalPrefs, fileHistory, favs, &dataLen));
    if (!data)
        return false;

    assert(dataLen > 0);
    FileTransaction trans;
    bool ok = trans.WriteAll(filepath, data, dataLen) && trans.Commit();
    if (ok)
        globalPrefs.lastPrefUpdate = file::GetModificationTime(filepath);
    return ok;
}
示例#4
0
static bool ExtractFiles(lzma::SimpleArchive *archive)
{
    lzma::FileInfo *fi;
    char *uncompressed;

    FileTransaction trans;
    for (int i = 0; gPayloadData[i].fileName; i++) {
        if (!gPayloadData[i].install)
            continue;
        int idx = lzma::GetIdxFromName(archive, gPayloadData[i].fileName);
        if (-1 == idx) {
            NotifyFailed(_TR("Some files to be installed are damaged or missing"));
            return false;
        }

        fi = &archive->files[idx];
        uncompressed = lzma::GetFileDataByIdx(archive, idx, nullptr);
        if (!uncompressed) {
            NotifyFailed(_TR("The installer has been corrupted. Please download it again.\nSorry for the inconvenience!"));
            return false;
        }
        ScopedMem<WCHAR> filePath(str::conv::FromUtf8(fi->name));
        ScopedMem<WCHAR> extPath(path::Join(gGlobalData.installDir, filePath));
        bool ok = trans.WriteAll(extPath, uncompressed, fi->uncompressedSize);
        free(uncompressed);
        if (!ok) {
            ScopedMem<WCHAR> msg(str::Format(_TR("Couldn't write %s to disk"), filePath));
            NotifyFailed(msg);
            return false;
        }
        trans.SetModificationTime(extPath, fi->ftModified);

        ProgressStep();
    }

    return trans.Commit();
}
示例#5
0
static bool InstallCopyFiles()
{
    // extract all payload files one by one (transacted, if possible)
    ZipFile archive(GetOwnPath());
    FileTransaction trans;

    for (int i = 0; gPayloadData[i].filepath; i++) {
        // skip files that are only uninstalled
        if (!gPayloadData[i].install)
            continue;
        ScopedMem<WCHAR> filepathT(str::conv::FromUtf8(gPayloadData[i].filepath));

        size_t size;
        ScopedMem<char> data(archive.GetFileData(filepathT, &size));
        if (!data) {
            NotifyFailed(L"Some files to be installed are damaged or missing");
            return false;
        }

        ScopedMem<WCHAR> extpath(path::Join(gGlobalData.installDir, path::GetBaseName(filepathT)));
        bool ok = trans.WriteAll(extpath, data, size);
        if (!ok) {
            ScopedMem<WCHAR> msg(str::Format(L"Couldn't write %s to disk", filepathT));
            NotifyFailed(msg);
            return false;
        }

        // set modification time to original value
        FILETIME ftModified = archive.GetFileTime(filepathT);
        trans.SetModificationTime(extpath, ftModified);

        ProgressStep();
    }

    return trans.Commit();
}
示例#6
0
static bool InstallCopyFiles()
{
    FileInfo fileInfos[32];

    HRSRC resSrc = FindResource(ghinst, MAKEINTRESOURCE(1), RT_RCDATA);
    CrashIf(!resSrc);
    HGLOBAL res = LoadResource(NULL, resSrc);
    CrashIf(!res);
    const uint8_t *data = (const uint8_t*)LockResource(res);
    DWORD dataSize = SizeofResource(NULL, resSrc);

    // extract all payload files one by one (transacted, if possible)
    FileTransaction trans;

    const int32_t *idata = (const int32_t*)data;
    int32_t fileCount = *idata++;
    CrashIf(fileCount >= dimof(fileInfos));
    int32_t off = 0;
    for (int32_t i = 0; i < fileCount; i++) {
        fileInfos[i].off = off;
        fileInfos[i].sizeUncompressed = *idata++;
        fileInfos[i].sizeCompressed = *idata++;
        off += fileInfos[i].sizeCompressed;
        data = (const uint8_t*)idata;
        fileInfos[i].name = (const char*)data;
        while (*data) {
            ++data;
        }
        ++data;
        idata = (const int32_t*)data;
    }

    uint8_t *dst;
    for (int32_t i = 0; i < fileCount; i++) {
        ScopedMem<WCHAR> filepathT(str::conv::FromUtf8(fileInfos[i].name));
        int32_t srcLen = fileInfos[i].sizeCompressed;
        off = fileInfos[i].off;
        const uint8_t *src = data + off;
        unsigned dstLen;
        dst = decodeLZMA((uint8_t*)src, (unsigned)srcLen, &dstLen);
        CrashIf(dstLen != (unsigned)fileInfos[i].sizeUncompressed);
        ScopedMem<WCHAR> extpath(path::Join(gGlobalData.installDir, path::GetBaseName(filepathT)));
        bool ok = trans.WriteAll(extpath, dst, dstLen);
        if (!ok) {
            ScopedMem<WCHAR> msg(str::Format(_TR("Couldn't write %s to disk"), filepathT));
            NotifyFailed(msg);
            goto Error;
        }
        free(dst);

        // set modification time to original value
        //FILETIME ftModified = archive.GetFileTime(filepathT);
        //trans.SetModificationTime(extpath, ftModified);

        ProgressStep();
    }

    UnlockResource(res);
    return trans.Commit();
Error:
    UnlockResource(res);
    return false;
}