void LaunchWithSumatra(InstanceData *data, const char *url_utf8)
{
    if (!file::Exists(data->filepath))
        plogf("sp: NPP_StreamAsFile() error: file doesn't exist");

    ScopedMem<WCHAR> url(str::conv::FromUtf8(url_utf8));
    // escape quotation marks and backslashes for CmdLineParser.cpp's ParseQuoted
    if (str::FindChar(url, '"')) {
        WStrVec parts;
        parts.Split(url, L"\"");
        url.Set(parts.Join(L"%22"));
    }
    if (str::EndsWith(url, L"\\")) {
        url[str::Len(url) - 1] = '\0';
        url.Set(str::Join(url, L"%5c"));
    }
    // prevent overlong URLs from making LaunchProcess fail
    if (str::Len(url) > 4096)
        url.Set(NULL);

    ScopedMem<WCHAR> cmdLine(str::Format(L"\"%s\" -plugin \"%s\" %d \"%s\"",
        data->exepath, url ? url : L"", (HWND)data->npwin->window, data->filepath));
    data->hProcess = LaunchProcess(cmdLine);
    if (!data->hProcess)
    {
        plogf("sp: NPP_StreamAsFile() error: couldn't run SumatraPDF!");
        data->message = _TR("Error: Couldn't run SumatraPDF!");
    }
}
static void ParseCommandLine(WCHAR *cmdLine)
{
    WStrVec argList;
    ParseCmdLine(cmdLine, argList);

#define is_arg(param) str::EqI(arg + 1, TEXT(param))
#define is_arg_with_param(param) (is_arg(param) && i < argList.Count() - 1)

    // skip the first arg (exe path)
    for (size_t i = 1; i < argList.Count(); i++) {
        WCHAR *arg = argList.At(i);
        if ('-' != *arg && '/' != *arg)
            continue;

        if (is_arg("s"))
            gGlobalData.silent = true;
        else if (is_arg_with_param("d"))
            str::ReplacePtr(&gGlobalData.installDir, argList.At(++i));
#ifndef BUILD_UNINSTALLER
        else if (is_arg("register"))
            gGlobalData.registerAsDefault = true;
        else if (is_arg_with_param("opt")) {
            WCHAR *opts = argList.At(++i);
            str::ToLower(opts);
            str::TransChars(opts, L" ;", L",,");
            WStrVec optlist;
            optlist.Split(opts, L",", true);
            if (optlist.Contains(L"pdffilter"))
                gGlobalData.installPdfFilter = true;
            if (optlist.Contains(L"pdfpreviewer"))
                gGlobalData.installPdfPreviewer = true;
            // uninstall the deprecated browser plugin if it's not
            // explicitly listed (only applies if the /opt flag is used)
            if (!optlist.Contains(L"plugin"))
                gGlobalData.keepBrowserPlugin = false;
        }
        else if (is_arg("x")) {
            gGlobalData.justExtractFiles = true;
            // silently extract files to the current directory (if /d isn't used)
            gGlobalData.silent = true;
            if (!gGlobalData.installDir)
                str::ReplacePtr(&gGlobalData.installDir, L".");
        }
        else if (is_arg("autoupdate")) {
            gGlobalData.autoUpdate = true;
        }
#endif
        else if (is_arg("h") || is_arg("help") || is_arg("?"))
            gGlobalData.showUsageAndQuit = true;
#ifdef ENABLE_CRASH_TESTING
        else if (is_arg("crash")) {
            // will induce crash when 'Install' button is pressed
            // for testing crash handling
            gForceCrash = true;
        }
#endif
    }
}
/* Make a string safe to be displayed as a menu item
   (preserving all & so that they don't get swallowed)
   Caller needs to free() the result. */
WCHAR *ToSafeString(const WCHAR *str)
{
    if (!str::FindChar(str, '&'))
        return str::Dup(str);

    WStrVec ampSplitter;
    ampSplitter.Split(str, L"&");
    return ampSplitter.Join(L"&&");
}
Exemple #4
0
void DumpProperties(BaseEngine *engine, bool fullDump)
{
    Out("\t<Properties\n");
    ScopedMem<char> str;
    str.Set(Escape(str::Dup(engine->FileName())));
    Out("\t\tFilePath=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_Title)));
    if (str)
        Out("\t\tTitle=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_Subject)));
    if (str)
        Out("\t\tSubject=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_Author)));
    if (str)
        Out("\t\tAuthor=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_Copyright)));
    if (str)
        Out("\t\tCopyright=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_CreationDate)));
    if (str)
        Out("\t\tCreationDate=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_ModificationDate)));
    if (str)
        Out("\t\tModDate=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_CreatorApp)));
    if (str)
        Out("\t\tCreator=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_PdfProducer)));
    if (str)
        Out("\t\tPdfProducer=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_PdfVersion)));
    if (str)
        Out("\t\tPdfVersion=\"%s\"\n", str.Get());
    str.Set(Escape(engine->GetProperty(Prop_PdfFileStructure)));
    if (str)
        Out("\t\tPdfFileStructure=\"%s\"\n", str.Get());
    if (!engine->AllowsPrinting())
        Out("\t\tPrintingAllowed=\"no\"\n");
    if (!engine->AllowsCopyingText())
        Out("\t\tCopyingTextAllowed=\"no\"\n");
    if (engine->IsImageCollection())
        Out("\t\tImageCollection=\"yes\"\n");
    if (engine->PreferredLayout())
        Out("\t\tPreferredLayout=\"%d\"\n", engine->PreferredLayout());
    Out("\t/>\n");

    if (fullDump) {
        ScopedMem<WCHAR> fontlist(engine->GetProperty(Prop_FontList));
        if (fontlist) {
            WStrVec fonts;
            fonts.Split(fontlist, L"\n");
            str.Set(Escape(fonts.Join(L"\n\t\t")));
            Out("\t<FontList>\n\t\t%s\n\t</FontList>\n", str.Get());
        }
    }
}
static bool SetupPluginMode(CommandLineInfo& i)
{
    if (!IsWindow(i.hwndPluginParent) || i.fileNames.Count() == 0)
        return false;

    gPluginURL = i.pluginURL;
    if (!gPluginURL)
        gPluginURL = i.fileNames.At(0);

    assert(i.fileNames.Count() == 1);
    while (i.fileNames.Count() > 1) {
        free(i.fileNames.Pop());
    }
    i.reuseInstance = i.exitWhenDone = false;
    gGlobalPrefs->reuseInstance = false;
    // always display the toolbar when embedded (as there's no menubar in that case)
    gGlobalPrefs->showToolbar = true;
    // never allow esc as a shortcut to quit
    gGlobalPrefs->escToExit = false;
    // never show the sidebar by default
    gGlobalPrefs->showToc = false;
    if (DM_AUTOMATIC == gGlobalPrefs->defaultDisplayModeEnum) {
        // if the user hasn't changed the default display mode,
        // display documents as single page/continuous/fit width
        // (similar to Adobe Reader, Google Chrome and how browsers display HTML)
        gGlobalPrefs->defaultDisplayModeEnum = DM_CONTINUOUS;
        gGlobalPrefs->defaultZoomFloat = ZOOM_FIT_WIDTH;
    }
    // use fixed page UI for all document types (so that the context menu always
    // contains all plugin specific entries and the main window is never closed)
    gGlobalPrefs->ebookUI.useFixedPageUI = gGlobalPrefs->chmUI.useFixedPageUI = true;

    // extract some command line arguments from the URL's hash fragment where available
    // see http://www.adobe.com/devnet/acrobat/pdfs/pdf_open_parameters.pdf#nameddest=G4.1501531
    if (i.pluginURL && str::FindChar(i.pluginURL, '#')) {
        ScopedMem<WCHAR> args(str::Dup(str::FindChar(i.pluginURL, '#') + 1));
        str::TransChars(args, L"#", L"&");
        WStrVec parts;
        parts.Split(args, L"&", true);
        for (size_t k = 0; k < parts.Count(); k++) {
            WCHAR *part = parts.At(k);
            int pageNo;
            if (str::StartsWithI(part, L"page=") && str::Parse(part + 4, L"=%d%$", &pageNo))
                i.pageNumber = pageNo;
            else if (str::StartsWithI(part, L"nameddest=") && part[10])
                str::ReplacePtr(&i.destName, part + 10);
            else if (!str::FindChar(part, '=') && part[0])
                str::ReplacePtr(&i.destName, part);
        }
    }

    return true;
}
static void ApplyPrintSettings(const WCHAR *settings, int pageCount, Vec<PRINTPAGERANGE> &ranges,
                               Print_Advanced_Data &advanced, LPDEVMODE devMode) {
    WStrVec rangeList;
    if (settings)
        rangeList.Split(settings, L",", true);

    for (size_t i = 0; i < rangeList.Count(); i++) {
        int val;
        PRINTPAGERANGE pr;
        if (str::Parse(rangeList.At(i), L"%d-%d%$", &pr.nFromPage, &pr.nToPage)) {
            pr.nFromPage = limitValue(pr.nFromPage, (DWORD)1, (DWORD)pageCount);
            pr.nToPage = limitValue(pr.nToPage, (DWORD)1, (DWORD)pageCount);
            ranges.Append(pr);
        } else if (str::Parse(rangeList.At(i), L"%d%$", &pr.nFromPage)) {
            pr.nFromPage = pr.nToPage = limitValue(pr.nFromPage, (DWORD)1, (DWORD)pageCount);
            ranges.Append(pr);
        } else if (str::EqI(rangeList.At(i), L"even"))
            advanced.range = PrintRangeEven;
        else if (str::EqI(rangeList.At(i), L"odd"))
            advanced.range = PrintRangeOdd;
        else if (str::EqI(rangeList.At(i), L"noscale"))
            advanced.scale = PrintScaleNone;
        else if (str::EqI(rangeList.At(i), L"shrink"))
            advanced.scale = PrintScaleShrink;
        else if (str::EqI(rangeList.At(i), L"fit"))
            advanced.scale = PrintScaleFit;
        else if (str::Parse(rangeList.At(i), L"%dx%$", &val) && 0 < val && val < 1000)
            devMode->dmCopies = (short)val;
        else if (str::EqI(rangeList.At(i), L"simplex"))
            devMode->dmDuplex = DMDUP_SIMPLEX;
        else if (str::EqI(rangeList.At(i), L"duplex") || str::EqI(rangeList.At(i), L"duplexlong"))
            devMode->dmDuplex = DMDUP_VERTICAL;
        else if (str::EqI(rangeList.At(i), L"duplexshort"))
            devMode->dmDuplex = DMDUP_HORIZONTAL;
        else if (str::EqI(rangeList.At(i), L"color"))
            devMode->dmColor = DMCOLOR_COLOR;
        else if (str::EqI(rangeList.At(i), L"monochrome"))
            devMode->dmColor = DMCOLOR_MONOCHROME;
        else if (str::StartsWithI(rangeList.At(i), L"bin="))
            devMode->dmDefaultSource = GetPaperSourceByName(rangeList.At(i) + 4, devMode);
        else if (str::StartsWithI(rangeList.At(i), L"paper="))
            devMode->dmPaperSize = GetPaperByName(rangeList.At(i) + 6);
    }

    if (ranges.Count() == 0) {
        PRINTPAGERANGE pr = { 1, (DWORD)pageCount };
        ranges.Append(pr);
    }
}
static void ParseCommandLine(WCHAR *cmdLine)
{
    WStrVec argList;
    ParseCmdLine(cmdLine, argList);

#define is_arg(param) str::EqI(arg + 1, TEXT(param))
#define is_arg_with_param(param) (is_arg(param) && i < argList.Count() - 1)

    // skip the first arg (exe path)
    for (size_t i = 1; i < argList.Count(); i++) {
        WCHAR *arg = argList.At(i);
        if ('-' != *arg && '/' != *arg)
            continue;

        if (is_arg("s"))
            gGlobalData.silent = true;
        else if (is_arg_with_param("d"))
            str::ReplacePtr(&gGlobalData.installDir, argList.At(++i));
#ifndef BUILD_UNINSTALLER
        else if (is_arg("register"))
            gGlobalData.registerAsDefault = true;
        else if (is_arg_with_param("opt")) {
            WCHAR *opts = argList.At(++i);
            str::ToLower(opts);
            str::TransChars(opts, L" ;", L",,");
            WStrVec optlist;
            optlist.Split(opts, L",", true);
            if (optlist.Find(L"plugin") != -1)
                gGlobalData.installBrowserPlugin = true;
            if (optlist.Find(L"pdffilter") != -1)
                gGlobalData.installPdfFilter = true;
            if (optlist.Find(L"pdfpreviewer") != -1)
                gGlobalData.installPdfPreviewer = true;
        }
#endif
        else if (is_arg("h") || is_arg("help") || is_arg("?"))
            gGlobalData.showUsageAndQuit = true;
#ifdef ENABLE_CRASH_TESTING
        else if (is_arg("crash")) {
            // will induce crash when 'Install' button is pressed
            // for testing crash handling
            gForceCrash = true;
        }
#endif
    }
}
Exemple #8
0
static void ApplyPrintSettings(const WCHAR *settings, int pageCount, Vec<PRINTPAGERANGE>& ranges, Print_Advanced_Data& advanced, LPDEVMODE devMode)
{
    WStrVec rangeList;
    if (settings)
        rangeList.Split(settings, L",", true);

    for (size_t i = 0; i < rangeList.Count(); i++) {
        int val;
        PRINTPAGERANGE pr;
        if (str::Parse(rangeList.At(i), L"%d-%d%$", &pr.nFromPage, &pr.nToPage)) {
            pr.nFromPage = limitValue(pr.nFromPage, (DWORD)1, (DWORD)pageCount);
            pr.nToPage = limitValue(pr.nToPage, (DWORD)1, (DWORD)pageCount);
            ranges.Append(pr);
        }
        else if (str::Parse(rangeList.At(i), L"%d%$", &pr.nFromPage)) {
            pr.nFromPage = pr.nToPage = limitValue(pr.nFromPage, (DWORD)1, (DWORD)pageCount);
            ranges.Append(pr);
        }
        else if (str::Eq(rangeList.At(i), L"even"))
            advanced.range = PrintRangeEven;
        else if (str::Eq(rangeList.At(i), L"odd"))
            advanced.range = PrintRangeOdd;
        else if (str::Eq(rangeList.At(i), L"noscale"))
            advanced.scale = PrintScaleNone;
        else if (str::Eq(rangeList.At(i), L"shrink"))
            advanced.scale = PrintScaleShrink;
        else if (str::Eq(rangeList.At(i), L"fit"))
            advanced.scale = PrintScaleFit;
        else if (str::Eq(rangeList.At(i), L"compat"))
            advanced.asImage = true;
        else if (str::Parse(rangeList.At(i), L"%dx%$", &val) && 0 < val && val < 1000)
            devMode->dmCopies = (short)val;
        else if (str::Eq(rangeList.At(i), L"duplex") || str::Eq(rangeList.At(i), L"duplexlong"))
            devMode->dmDuplex = DMDUP_VERTICAL;
        else if (str::Eq(rangeList.At(i), L"duplexshort"))
            devMode->dmDuplex = DMDUP_HORIZONTAL;
    }

    if (ranges.Count() == 0) {
        PRINTPAGERANGE pr = { 1, pageCount };
        ranges.Append(pr);
    }
}
// parses a list of page ranges such as 1,3-5,7- (i..e all but pages 2 and 6)
// into an interable list (returns nullptr on parsing errors)
// caller must delete the result
bool ParsePageRanges(const WCHAR* ranges, Vec<PageRange>& result) {
    if (!ranges)
        return false;

    WStrVec rangeList;
    rangeList.Split(ranges, L",", true);
    rangeList.SortNatural();

    for (size_t i = 0; i < rangeList.size(); i++) {
        int start, end;
        if (str::Parse(rangeList.at(i), L"%d-%d%$", &start, &end) && 0 < start && start <= end)
            result.Append(PageRange(start, end));
        else if (str::Parse(rangeList.at(i), L"%d-%$", &start) && 0 < start)
            result.Append(PageRange(start, INT_MAX));
        else if (str::Parse(rangeList.at(i), L"%d%$", &start) && 0 < start)
            result.Append(PageRange(start, start));
        else
            return false;
    }

    return result.size() > 0;
}
Exemple #10
0
static WCHAR *FormatPdfFileStructure(Doc doc)
{
    ScopedMem<WCHAR> fstruct(doc.GetProperty(Prop_PdfFileStructure));
    if (str::IsEmpty(fstruct.Get()))
        return NULL;
    WStrVec parts;
    parts.Split(fstruct, L",", true);
    
    WStrVec props;

    if (parts.Find(L"linearized") != -1)
        props.Push(str::Dup(_TR("Fast Web View")));
    if (parts.Find(L"tagged") != -1)
        props.Push(str::Dup(_TR("Tagged PDF")));
    if (parts.Find(L"PDFX") != -1)
        props.Push(str::Dup(L"PDF/X (ISO 15930)"));
    if (parts.Find(L"PDFA1") != -1)
        props.Push(str::Dup(L"PDF/A (ISO 19005)"));
    if (parts.Find(L"PDFE1") != -1)
        props.Push(str::Dup(L"PDF/E (ISO 24517)"));

    return props.Join(L", ");
}
static WCHAR *FormatPdfFileStructure(Controller *ctrl)
{
    ScopedMem<WCHAR> fstruct(ctrl->GetProperty(Prop_PdfFileStructure));
    if (str::IsEmpty(fstruct.Get()))
        return nullptr;
    WStrVec parts;
    parts.Split(fstruct, L",", true);

    WStrVec props;

    if (parts.Contains(L"linearized"))
        props.Push(str::Dup(_TR("Fast Web View")));
    if (parts.Contains(L"tagged"))
        props.Push(str::Dup(_TR("Tagged PDF")));
    if (parts.Contains(L"PDFX"))
        props.Push(str::Dup(L"PDF/X (ISO 15930)"));
    if (parts.Contains(L"PDFA1"))
        props.Push(str::Dup(L"PDF/A (ISO 19005)"));
    if (parts.Contains(L"PDFE1"))
        props.Push(str::Dup(L"PDF/E (ISO 24517)"));

    return props.Join(L", ");
}
Exemple #12
0
static void ApplyPrintSettings(const WCHAR *settings, int pageCount, Vec<PRINTPAGERANGE>& ranges, Print_Advanced_Data& advanced)
{
    WStrVec rangeList;
    if (settings)
        rangeList.Split(settings, L",", true);

    for (size_t i = 0; i < rangeList.Count(); i++) {
        PRINTPAGERANGE pr;
        if (str::Parse(rangeList.At(i), L"%d-%d%$", &pr.nFromPage, &pr.nToPage)) {
            pr.nFromPage = limitValue(pr.nFromPage, (DWORD)1, (DWORD)pageCount);
            pr.nToPage = limitValue(pr.nToPage, (DWORD)1, (DWORD)pageCount);
            ranges.Append(pr);
        }
        else if (str::Parse(rangeList.At(i), L"%d%$", &pr.nFromPage)) {
            pr.nFromPage = pr.nToPage = limitValue(pr.nFromPage, (DWORD)1, (DWORD)pageCount);
            ranges.Append(pr);
        }
        else if (str::Eq(rangeList.At(i), L"even"))
            advanced.range = PrintRangeEven;
        else if (str::Eq(rangeList.At(i), L"odd"))
            advanced.range = PrintRangeOdd;
        else if (str::Eq(rangeList.At(i), L"noscale"))
            advanced.scale = PrintScaleNone;
        else if (str::Eq(rangeList.At(i), L"shrink"))
            advanced.scale = PrintScaleShrink;
        else if (str::Eq(rangeList.At(i), L"fit"))
            advanced.scale = PrintScaleFit;
        else if (str::Eq(rangeList.At(i), L"compat"))
            advanced.asImage = true;
    }

    if (ranges.Count() == 0) {
        PRINTPAGERANGE pr = { 1, pageCount };
        ranges.Append(pr);
    }
}
Exemple #13
0
static WCHAR *GetGhostscriptPath()
{
    WCHAR *gsProducts[] = {
        L"AFPL Ghostscript",
        L"Aladdin Ghostscript",
        L"GPL Ghostscript",
        L"GNU Ghostscript",
    };

    // find all installed Ghostscript versions
    WStrVec versions;
    REGSAM access = KEY_READ | KEY_WOW64_32KEY;
TryAgain64Bit:
    for (int i = 0; i < dimof(gsProducts); i++) {
        HKEY hkey;
        ScopedMem<WCHAR> keyName(str::Join(L"Software\\", gsProducts[i]));
        if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyName, 0, access, &hkey) != ERROR_SUCCESS)
            continue;
        WCHAR subkey[32];
        for (DWORD ix = 0; RegEnumKey(hkey, ix, subkey, dimof(subkey)) == ERROR_SUCCESS; ix++)
            versions.Append(str::Dup(subkey));
        RegCloseKey(hkey);
    }
    if ((access & KEY_WOW64_32KEY)) {
        // also look for 64-bit Ghostscript versions under 64-bit Windows
        access = KEY_READ | KEY_WOW64_64KEY;
#ifndef _WIN64
        // (unless this is 32-bit Windows)
        if (IsRunningInWow64())
#endif
        goto TryAgain64Bit;
    }
    versions.SortNatural();

    // return the path to the newest installation
    for (size_t ix = versions.Count(); ix > 0; ix--) {
        for (int i = 0; i < dimof(gsProducts); i++) {
            ScopedMem<WCHAR> keyName(str::Format(L"Software\\%s\\%s",
                                                 gsProducts[i], versions.At(ix - 1)));
            ScopedMem<WCHAR> GS_DLL(ReadRegStr(HKEY_LOCAL_MACHINE, keyName, L"GS_DLL"));
            if (!GS_DLL)
                continue;
            ScopedMem<WCHAR> dir(path::GetDir(GS_DLL));
            ScopedMem<WCHAR> exe(path::Join(dir, L"gswin32c.exe"));
            if (file::Exists(exe))
                return exe.StealData();
            exe.Set(path::Join(dir, L"gswin64c.exe"));
            if (file::Exists(exe))
                return exe.StealData();
        }
    }

    // if Ghostscript isn't found in the Registry, try finding it in the %PATH%
    DWORD size = GetEnvironmentVariable(L"PATH", NULL, 0);
    ScopedMem<WCHAR> envpath(AllocArray<WCHAR>(size));
    if (size > 0 && envpath) {
        GetEnvironmentVariable(L"PATH", envpath, size);
        WStrVec paths;
        paths.Split(envpath, L";", true);
        for (size_t ix = 0; ix < paths.Count(); ix++) {
            ScopedMem<WCHAR> exe(path::Join(paths.At(ix), L"gswin32c.exe"));
            if (file::Exists(exe))
                return exe.StealData();
            exe.Set(path::Join(paths.At(ix), L"gswin64c.exe"));
            if (file::Exists(exe))
                return exe.StealData();
        }
    }

    return NULL;
}