Ejemplo n.º 1
0
 ~ScopeDisableDEP() { DisableDataExecution(); }
Ejemplo n.º 2
0
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int retCode = 1;    // by default it's error

#ifdef DEBUG
    // Memory leak detection (only enable _CRTDBG_LEAK_CHECK_DF for
    // regular termination so that leaks aren't checked on exceptions,
    // aborts, etc. where some clean-up might not take place)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF);
    //_CrtSetBreakAlloc(421);
    TryLoadMemTrace();
#endif

    //BenchMD5();

    DisableDataExecution();
    // ensure that C functions behave consistently under all OS locales
    // (use Win32 functions where localized input or output is desired)
    setlocale(LC_ALL, "C");

    RunUnitTests();

    // don't show system-provided dialog boxes when accessing files on drives
    // that are not mounted (e.g. a: drive without floppy or cd rom drive
    // without a cd).
    SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
    srand((unsigned int)time(NULL));

    // don't bother sending crash reports when running under Wine
    // as they're not helpful
    if (!RunningUnderWine()) {
        ScopedMem<TCHAR> symDir;
        ScopedMem<TCHAR> tmpDir(path::GetTempPath());
        if (tmpDir)
            symDir.Set(path::Join(tmpDir, _T("SumatraPDF-symbols")));
        else
            symDir.Set(AppGenDataFilename(_T("SumatraPDF-symbols")));
        ScopedMem<TCHAR> crashDumpPath(AppGenDataFilename(CRASH_DUMP_FILE_NAME));
        InstallCrashHandler(crashDumpPath, symDir);
    }

    ScopedOle ole;
    InitAllCommonControls();
    ScopedGdiPlus gdiPlus(true);
    mui::Initialize();
    uimsg::Initialize();

    ScopedMem<TCHAR> prefsFilename(GetPrefsFileName());
    if (!file::Exists(prefsFilename)) {
        // guess the ui language on first start
        CurrLangNameSet(Trans::GuessLanguage());
        gFavorites = new Favorites();
    } else {
        assert(gFavorites == NULL);
        Prefs::Load(prefsFilename, gGlobalPrefs, gFileHistory, &gFavorites);
        CurrLangNameSet(gGlobalPrefs.currentLanguage);
    }
    prefsFilename.Set(NULL);

    CommandLineInfo i;
    GetCommandLineInfo(i);

    if (i.showConsole)
        RedirectIOToConsole();
    if (i.makeDefault)
        AssociateExeWithPdfExtension();
    if (i.pathsToBenchmark.Count() > 0) {
        BenchFileOrDir(i.pathsToBenchmark);
        if (i.showConsole)
            system("pause");
    }
    if (i.exitImmediately)
        goto Exit;
    gCrashOnOpen = i.crashOnOpen;

    gGlobalPrefs.bgColor = i.bgColor;
    gGlobalPrefs.fwdSearch.offset = i.fwdSearch.offset;
    gGlobalPrefs.fwdSearch.width = i.fwdSearch.width;
    gGlobalPrefs.fwdSearch.color = i.fwdSearch.color;
    gGlobalPrefs.fwdSearch.permanent = i.fwdSearch.permanent;
    gGlobalPrefs.escToExit = i.escToExit;
    gGlobalPrefs.cbxR2L = i.cbxR2L;
    gPolicyRestrictions = GetPolicies(i.restrictedUse);
    gRenderCache.colorRange[0] = i.colorRange[0];
    gRenderCache.colorRange[1] = i.colorRange[1];
    DebugGdiPlusDevice(gUseGdiRenderer);
    DebugAlternateChmEngine(!gUseEbookUI);

    if (i.inverseSearchCmdLine) {
        str::ReplacePtr(&gGlobalPrefs.inverseSearchCmdLine, i.inverseSearchCmdLine);
        gGlobalPrefs.enableTeXEnhancements = true;
    }
    CurrLangNameSet(i.lang);

    if (!RegisterWinClass(hInstance))
        goto Exit;
    if (!InstanceInit(hInstance, nCmdShow))
        goto Exit;

    if (i.hwndPluginParent) {
        if (!SetupPluginMode(i))
            goto Exit;
    }

    if (i.printerName) {
        // note: this prints all PDF files. Another option would be to
        // print only the first one
        for (size_t n = 0; n < i.fileNames.Count(); n++) {
            bool ok = PrintFile(i.fileNames.At(n), i.printerName, !i.silent, i.printSettings);
            if (!ok)
                retCode++;
        }
        --retCode; // was 1 if no print failures, turn 1 into 0
        goto Exit;
    }

    if (i.fileNames.Count() == 0 && gGlobalPrefs.rememberOpenedFiles && gGlobalPrefs.showStartPage) {
        // make the shell prepare the image list, so that it's ready when the first window's loaded
        SHFILEINFO sfi;
        SHGetFileInfo(_T(".pdf"), 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
    }

    WindowInfo *win = NULL;
    bool isFirstWin = true;

    for (size_t n = 0; n < i.fileNames.Count(); n++) {
        if (i.reuseInstance && !i.printDialog) {
            OpenUsingDde(i.fileNames.At(n), i, isFirstWin);
        } else {
            win = LoadOnStartup(i.fileNames.At(n), i, isFirstWin);
            if (!win) {
                retCode++;
                continue;
            }
            if (i.printDialog)
                OnMenuPrint(win, i.exitOnPrint);
        }
        isFirstWin = false;
    }
    if (i.fileNames.Count() > 0 && isFirstWin) {
        // failed to create any window, even though there
        // were files to load (or show a failure message for)
        goto Exit;
    }

    if (i.reuseInstance && !i.printDialog || i.printDialog && i.exitOnPrint)
        goto Exit;

    if (isFirstWin) {
        win = CreateAndShowWindowInfo();
        if (!win)
            goto Exit;
    }

    UpdateUITextForLanguage(); // needed for RTL languages
    if (isFirstWin)
        UpdateToolbarAndScrollbarState(*win);

    // Make sure that we're still registered as default,
    // if the user has explicitly told us to be
    if (gGlobalPrefs.pdfAssociateShouldAssociate && win)
        RegisterForPdfExtentions(win->hwndFrame);

    if (gGlobalPrefs.enableAutoUpdate && gWindows.Count() > 0)
        AutoUpdateCheckAsync(gWindows.At(0)->hwndFrame, true);

#ifndef THREAD_BASED_FILEWATCH
    const UINT_PTR timerID = SetTimer(NULL, -1, FILEWATCH_DELAY_IN_MS, NULL);
#endif

    if (i.stressTestPath) {
        gIsStressTesting = true;
        StartStressTest(win, i.stressTestPath, i.stressTestFilter,
                        i.stressTestRanges, i.stressTestCycles, &gRenderCache);
    }

    retCode = RunMessageLoop();

#ifndef THREAD_BASED_FILEWATCH
    KillTimer(NULL, timerID);
#endif

    CleanUpThumbnailCache(gFileHistory);

Exit:
    while (gWindows.Count() > 0) {
        DeleteWindowInfo(gWindows.At(0));
    }
    while (gEbookWindows.Count() > 0) {
        DeleteEbookWindow(gEbookWindows.At(0), true);
    }

#ifndef DEBUG
    // leave all the remaining clean-up to the OS
    // (as recommended for a quick exit)
    ExitProcess(retCode);
#endif

    DeleteObject(gBrushNoDocBg);
    DeleteObject(gBrushLogoBg);
    DeleteObject(gBrushAboutBg);
    DeleteObject(gDefaultGuiFont);
    DeleteBitmap(gBitmapReloadingCue);

    delete gFavorites;

    mui::Destroy();

    DrainUiMsgQueue();
    uimsg::Destroy();

    // it's still possible to crash after this (destructors of static classes,
    // atexit() code etc.) point, but it's very unlikely
    if (!RunningUnderWine())
        UninstallCrashHandler();

#ifdef DEBUG
    // output leaks after all destructors of static objects have run
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif

    return retCode;
}
Ejemplo n.º 3
0
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int retCode = 1;    // by default it's error

#ifdef DEBUG
    // Memory leak detection (only enable _CRTDBG_LEAK_CHECK_DF for
    // regular termination so that leaks aren't checked on exceptions,
    // aborts, etc. where some clean-up might not take place)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF);
    //_CrtSetBreakAlloc(421);
    TryLoadMemTrace();
#endif

    DisableDataExecution();
    // ensure that C functions behave consistently under all OS locales
    // (use Win32 functions where localized input or output is desired)
    setlocale(LC_ALL, "C");
    // don't show system-provided dialog boxes when accessing files on drives
    // that are not mounted (e.g. a: drive without floppy or cd rom drive
    // without a cd).
    SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);

#if defined(DEBUG) || defined(SVN_PRE_RELEASE_VER)
    if (str::StartsWith(lpCmdLine, "/tester")) {
        extern int TesterMain(); // in Tester.cpp
        return TesterMain();
    }

    if (str::StartsWith(lpCmdLine, "/regress")) {
        extern int RegressMain(); // in Regress.cpp
        return RegressMain();
    }
#endif
#ifdef SUPPORTS_AUTO_UPDATE
    if (str::StartsWith(lpCmdLine, "-autoupdate")) {
        bool quit = AutoUpdateMain();
        if (quit)
            return 0;
    }
#endif

    RunUnitTests();

    srand((unsigned int)time(NULL));

    {
        ScopedMem<WCHAR> symDir;
        ScopedMem<WCHAR> tmpDir(path::GetTempPath());
        if (tmpDir)
            symDir.Set(path::Join(tmpDir, L"SumatraPDF-symbols"));
        else
            symDir.Set(AppGenDataFilename(L"SumatraPDF-symbols"));
        ScopedMem<WCHAR> crashDumpPath(AppGenDataFilename(CRASH_DUMP_FILE_NAME));
        InstallCrashHandler(crashDumpPath, symDir);
    }

    ScopedOle ole;
    InitAllCommonControls();
    ScopedGdiPlus gdiPlus(true);
    mui::Initialize();
    uitask::Initialize();

    LoadPrefs();

    CommandLineInfo i;
    GetCommandLineInfo(i);

    SetCurrentLang(i.lang ? i.lang : gGlobalPrefs->currLangCode);

    if (i.showConsole)
        RedirectIOToConsole();
    if (i.makeDefault)
        AssociateExeWithPdfExtension();
    if (i.pathsToBenchmark.Count() > 0) {
        BenchFileOrDir(i.pathsToBenchmark);
        if (i.showConsole)
            system("pause");
    }
    if (i.exitImmediately)
        goto Exit;
    gCrashOnOpen = i.crashOnOpen;

    gUserPrefs->mainWindowBackground = i.bgColor;
    if (gUserPrefs->forwardSearch.highlightColor != i.forwardSearch.highlightColor ||
        gUserPrefs->forwardSearch.highlightOffset != i.forwardSearch.highlightOffset ||
        gUserPrefs->forwardSearch.highlightPermanent != i.forwardSearch.highlightPermanent ||
        gUserPrefs->forwardSearch.highlightWidth != i.forwardSearch.highlightWidth) {
        gGlobalPrefs->enableTeXEnhancements = true;
    }
    gUserPrefs->forwardSearch = i.forwardSearch;
    gUserPrefs->escToExit = i.escToExit;
    gGlobalPrefs->cbxR2L = i.cbxR2L;
    gPolicyRestrictions = GetPolicies(i.restrictedUse);
    gRenderCache.colorRange[0] = i.colorRange[0];
    gRenderCache.colorRange[1] = i.colorRange[1];
    DebugGdiPlusDevice(gUseGdiRenderer);
    DebugAlternateChmEngine(gUserPrefs->ebookUI.traditionalEbookUI);

    if (i.inverseSearchCmdLine) {
        str::ReplacePtr(&gGlobalPrefs->inverseSearchCmdLine, i.inverseSearchCmdLine);
        gGlobalPrefs->enableTeXEnhancements = true;
    }

    if (!RegisterWinClass(hInstance))
        goto Exit;
    if (!InstanceInit(hInstance, nCmdShow))
        goto Exit;

    if (i.hwndPluginParent) {
        if (!SetupPluginMode(i))
            goto Exit;
    }

    if (i.printerName) {
        // note: this prints all PDF files. Another option would be to
        // print only the first one
        for (size_t n = 0; n < i.fileNames.Count(); n++) {
            bool ok = PrintFile(i.fileNames.At(n), i.printerName, !i.silent, i.printSettings);
            if (!ok)
                retCode++;
        }
        --retCode; // was 1 if no print failures, turn 1 into 0
        goto Exit;
    }

    if (i.fileNames.Count() == 0 && gGlobalPrefs->rememberOpenedFiles && gGlobalPrefs->showStartPage) {
        // make the shell prepare the image list, so that it's ready when the first window's loaded
        SHFILEINFO sfi;
        SHGetFileInfo(L".pdf", 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
    }

    if (!i.reuseInstance && gUserPrefs->reuseInstance && FindWindow(FRAME_CLASS_NAME, 0))
        i.reuseInstance = true;

    WindowInfo *win = NULL;
    bool isFirstWin = true;

    for (size_t n = 0; n < i.fileNames.Count(); n++) {
        if (i.reuseInstance && !i.printDialog) {
            OpenUsingDde(i.fileNames.At(n), i, isFirstWin);
        } else {
            win = LoadOnStartup(i.fileNames.At(n), i, isFirstWin);
            if (!win) {
                retCode++;
                continue;
            }
            if (i.printDialog)
                OnMenuPrint(win, i.exitWhenDone);
        }
        isFirstWin = false;
    }
    if (i.fileNames.Count() > 0 && isFirstWin) {
        // failed to create any window, even though there
        // were files to load (or show a failure message for)
        goto Exit;
    }

    if (i.reuseInstance && !i.printDialog || i.printDialog && i.exitWhenDone)
        goto Exit;

    if (isFirstWin) {
        win = CreateAndShowWindowInfo();
        if (!win)
            goto Exit;
    }

    UpdateUITextForLanguage(); // needed for RTL languages
    if (isFirstWin)
        UpdateToolbarAndScrollbarState(*win);

    // Make sure that we're still registered as default,
    // if the user has explicitly told us to be
    if (gGlobalPrefs->pdfAssociateShouldAssociate && win)
        RegisterForPdfExtentions(win->hwndFrame);

    if (gGlobalPrefs->enableAutoUpdate && gWindows.Count() > 0)
        AutoUpdateCheckAsync(gWindows.At(0)->hwndFrame, true);

    if (i.stressTestPath)
        StartStressTest(&i, win, &gRenderCache);

    if (gFileHistory.Get(0)) {
        gFileExistenceChecker = new FileExistenceChecker();
        gFileExistenceChecker->Start();
    }

    retCode = RunMessageLoop();

    CleanUpThumbnailCache(gFileHistory);

Exit:
    while (gWindows.Count() > 0) {
        DeleteWindowInfo(gWindows.At(0));
    }
    while (gEbookWindows.Count() > 0) {
        DeleteEbookWindow(gEbookWindows.At(0), true);
    }

#ifndef DEBUG

    // leave all the remaining clean-up to the OS
    // (as recommended for a quick exit)
    ExitProcess(retCode);

#else

    CrashIf(gFileExistenceChecker);

    DeleteObject(gBrushNoDocBg);
    DeleteObject(gBrushLogoBg);
    DeleteObject(gBrushAboutBg);
    DeleteObject(gDefaultGuiFont);
    DeleteBitmap(gBitmapReloadingCue);

    gFileHistory.UpdateStatesSource(NULL);
    DeleteGlobalPrefs(gGlobalPrefs);

    mui::Destroy();
    uitask::Destroy();
    trans::Destroy();

    // it's still possible to crash after this (destructors of static classes,
    // atexit() code etc.) point, but it's very unlikely
    UninstallCrashHandler();

    // output leaks after all destructors of static objects have run
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    return retCode;
#endif
}
Ejemplo n.º 4
0
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    int retCode = 1;    // by default it's error

#ifdef DEBUG
    // Memory leak detection (only enable _CRTDBG_LEAK_CHECK_DF for
    // regular termination so that leaks aren't checked on exceptions,
    // aborts, etc. where some clean-up might not take place)
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF);
    //_CrtSetBreakAlloc(421);
    TryLoadMemTrace();
#endif

    DisableDataExecution();
    // ensure that C functions behave consistently under all OS locales
    // (use Win32 functions where localized input or output is desired)
    setlocale(LC_ALL, "C");
    // don't show system-provided dialog boxes when accessing files on drives
    // that are not mounted (e.g. a: drive without floppy or cd rom drive
    // without a cd).
    SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);

#if defined(DEBUG) || defined(SVN_PRE_RELEASE_VER)
    if (str::StartsWith(lpCmdLine, "/tester")) {
        extern int TesterMain(); // in Tester.cpp
        return TesterMain();
    }

    if (str::StartsWith(lpCmdLine, "/regress")) {
        extern int RegressMain(); // in Regress.cpp
        return RegressMain();
    }
#endif
#ifdef SUPPORTS_AUTO_UPDATE
    if (str::StartsWith(lpCmdLine, "-autoupdate")) {
        bool quit = AutoUpdateMain();
        if (quit)
            return 0;
    }
#endif

    srand((unsigned int)time(NULL));

    // load uiautomationcore.dll before installing crash handler (i.e. initializing
    // dbghelp.dll), so that we get function names/offsets in GetCallstack()
    uia::Initialize();
#ifdef DEBUG
    dbghelp::RememberCallstackLogs();
#endif

    SetupCrashHandler();

    ScopedOle ole;
    InitAllCommonControls();
    ScopedGdiPlus gdiPlus(true);
    mui::Initialize();
    uitask::Initialize();

    prefs::Load();

    CommandLineInfo i(GetCommandLine());

    SetCurrentLang(i.lang ? i.lang : gGlobalPrefs->uiLanguage);

    // This allows ad-hoc comparison of gdi, gdi+ and gdi+ quick when used
    // in layout
#if 0
    RedirectIOToConsole();
    BenchEbookLayout(L"C:\\kjk\\downloads\\pg12.mobi");
    system("pause");
    goto Exit;
#endif

    if (i.showConsole) {
        RedirectIOToConsole();
        RedirectDllIOToConsole();
    }
    if (i.makeDefault)
        AssociateExeWithPdfExtension();
    if (i.pathsToBenchmark.Count() > 0) {
        BenchFileOrDir(i.pathsToBenchmark);
        if (i.showConsole)
            system("pause");
    }
    if (i.exitImmediately)
        goto Exit;
    gCrashOnOpen = i.crashOnOpen;

    gPolicyRestrictions = GetPolicies(i.restrictedUse);
    GetFixedPageUiColors(gRenderCache.textColor, gRenderCache.backgroundColor);
    DebugGdiPlusDevice(gUseGdiRenderer);

    if (!RegisterWinClass())
        goto Exit;

    CrashIf(hInstance != GetModuleHandle(NULL));
    if (!InstanceInit(nCmdShow))
        goto Exit;

    if (i.hwndPluginParent) {
        if (!SetupPluginMode(i))
            goto Exit;
    }

    if (i.printerName) {
        // note: this prints all PDF files. Another option would be to
        // print only the first one
        for (size_t n = 0; n < i.fileNames.Count(); n++) {
            bool ok = PrintFile(i.fileNames.At(n), i.printerName, !i.silent, i.printSettings);
            if (!ok)
                retCode++;
        }
        --retCode; // was 1 if no print failures, turn 1 into 0
        goto Exit;
    }

    bool showStartPage = i.fileNames.Count() == 0 && gGlobalPrefs->rememberOpenedFiles && gGlobalPrefs->showStartPage;
    if (showStartPage) {
        // make the shell prepare the image list, so that it's ready when the first window's loaded
        SHFILEINFO sfi;
        SHGetFileInfo(L".pdf", 0, &sfi, sizeof(sfi), SHGFI_SYSICONINDEX | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES);
    }

    if (gGlobalPrefs->reopenOnce) {
        WStrVec moreFileNames;
        ParseCmdLine(gGlobalPrefs->reopenOnce, moreFileNames);
        moreFileNames.Reverse();
        for (WCHAR **fileName = moreFileNames.IterStart(); fileName; fileName = moreFileNames.IterNext()) {
            i.fileNames.Append(*fileName);
        }
        moreFileNames.RemoveAt(0, moreFileNames.Count());
        str::ReplacePtr(&gGlobalPrefs->reopenOnce, NULL);
    }

    HANDLE hMutex = NULL;
    HWND hPrevWnd = NULL;
    if (i.printDialog || i.stressTestPath || gPluginMode) {
        // TODO: pass print request through to previous instance?
    }
    else if (i.reuseDdeInstance) {
        hPrevWnd = FindWindow(FRAME_CLASS_NAME, NULL);
    }
    else if (gGlobalPrefs->reuseInstance || gGlobalPrefs->useTabs) {
        hPrevWnd = FindPrevInstWindow(&hMutex);
    }
    if (hPrevWnd) {
        for (size_t n = 0; n < i.fileNames.Count(); n++) {
            OpenUsingDde(hPrevWnd, i.fileNames.At(n), i, 0 == n);
        }
        goto Exit;
    }

    WindowInfo *win = NULL;
    for (size_t n = 0; n < i.fileNames.Count(); n++) {
        win = LoadOnStartup(i.fileNames.At(n), i, !win);
        if (!win) {
            retCode++;
            continue;
        }
        if (i.printDialog)
            OnMenuPrint(win, i.exitWhenDone);
    }
    if (i.fileNames.Count() > 0 && !win) {
        // failed to create any window, even though there
        // were files to load (or show a failure message for)
        goto Exit;
    }
    if (i.printDialog && i.exitWhenDone)
        goto Exit;

    if (!win) {
        win = CreateAndShowWindowInfo();
        if (!win)
            goto Exit;
    }

    UpdateUITextForLanguage(); // needed for RTL languages
    if (win->IsAboutWindow()) {
        // TODO: shouldn't CreateAndShowWindowInfo take care of this?
        UpdateToolbarAndScrollbarState(*win);
    }

    // Make sure that we're still registered as default,
    // if the user has explicitly told us to be
    if (gGlobalPrefs->associatedExtensions)
        RegisterForPdfExtentions(win->hwndFrame);

    if (i.stressTestPath) {
        // don't save file history and preference changes
        gPolicyRestrictions = (gPolicyRestrictions | Perm_RestrictedUse) & ~Perm_SavePreferences;
        RebuildMenuBarForWindow(win);
        StartStressTest(&i, win, &gRenderCache);
    }

    if (gGlobalPrefs->checkForUpdates)
        UpdateCheckAsync(win, true);

    // only hide newly missing files when showing the start page on startup
    if (showStartPage && gFileHistory.Get(0)) {
        gFileExistenceChecker = new FileExistenceChecker();
        gFileExistenceChecker->Start();
    }
    // call this once it's clear whether Perm_SavePreferences has been granted
    prefs::RegisterForFileChanges();

    retCode = RunMessageLoop();

    SafeCloseHandle(&hMutex);
    CleanUpThumbnailCache(gFileHistory);

Exit:
    prefs::UnregisterForFileChanges();

    while (gWindows.Count() > 0) {
        DeleteWindowInfo(gWindows.At(0));
    }

#ifndef DEBUG

    // leave all the remaining clean-up to the OS
    // (as recommended for a quick exit)
    ExitProcess(retCode);

#else

    DeleteObject(GetDefaultGuiFont());
    DeleteBitmap(gBitmapReloadingCue);
    DeleteSplitterBrush();

    // wait for FileExistenceChecker to terminate
    // (which should be necessary only very rarely)
    while (gFileExistenceChecker) {
        Sleep(10);
        uitask::DrainQueue();
    }

    mui::Destroy();
    uitask::Destroy();
    trans::Destroy();

    SaveCallstackLogs();
    dbghelp::FreeCallstackLogs();

    // must be after uitask::Destroy() because we might have queued prefs::Reload()
    // which crashes if gGlobalPrefs is freed
    gFileHistory.UpdateStatesSource(NULL);
    DeleteGlobalPrefs(gGlobalPrefs);

    // it's still possible to crash after this (destructors of static classes,
    // atexit() code etc.) point, but it's very unlikely
    UninstallCrashHandler();

    // output leaks after all destructors of static objects have run
    _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

    return retCode;
#endif
}
Ejemplo n.º 5
0
int main(int argc, char **argv)
{
    setlocale(LC_ALL, "C");
    DisableDataExecution();

    WStrVec argList;
    ParseCmdLine(GetCommandLine(), argList);
    if (argList.Count() < 2) {
Usage:
        ErrOut("%s <filename> [-pwd <password>][-full][-alt][-render <path-%%d.tga>]\n",
            path::GetBaseName(argList.At(0)));
        return 0;
    }

    ScopedMem<WCHAR> filePath;
    WIN32_FIND_DATA fdata;
    HANDLE hfind = FindFirstFile(argList.At(1), &fdata);
    if (INVALID_HANDLE_VALUE != hfind) {
        ScopedMem<WCHAR> dir(path::GetDir(argList.At(1)));
        filePath.Set(path::Join(dir, fdata.cFileName));
        FindClose(hfind);
    }
    else {
        // embedded documents are referred to by an invalid path
        // containing more information after a colon (e.g. "C:\file.pdf:3:0")
        filePath.Set(str::Dup(argList.At(1)));
    }

    bool fullDump = false;
    WCHAR *password = NULL;
    WCHAR *renderPath = NULL;
    bool useAlternateHandlers = false;
    bool loadOnly = false;
    int breakAlloc = 0;

    for (size_t i = 2; i < argList.Count(); i++) {
        if (str::Eq(argList.At(i), L"-full"))
            fullDump = true;
        else if (str::Eq(argList.At(i), L"-pwd") && i + 1 < argList.Count())
            password = argList.At(++i);
        else if (str::Eq(argList.At(i), L"-render") && i + 1 < argList.Count())
            renderPath = argList.At(++i);
        else if (str::Eq(argList.At(i), L"-alt"))
            useAlternateHandlers = true;
        else if (str::Eq(argList.At(i), L"-loadonly"))
            loadOnly = true;
#ifdef DEBUG
        else if (str::Eq(argList.At(i), L"-breakalloc") && i + 1 < argList.Count())
            breakAlloc = _wtoi(argList.At(++i));
#endif
        else
            goto Usage;
    }

#ifdef DEBUG
    if (breakAlloc) {
        _CrtSetBreakAlloc(breakAlloc);
        if (!IsDebuggerPresent())
            MessageBox(NULL, L"Keep your debugger ready for the allocation breakpoint...", L"EngineDump", MB_ICONINFORMATION);
    }
#endif

    // optionally use GDI+ rendering for PDF/XPS and the original ChmEngine for CHM
    DebugGdiPlusDevice(useAlternateHandlers);
    DebugAlternateChmEngine(!useAlternateHandlers);

    ScopedGdiPlus gdiPlus;
    DocType engineType;
    PasswordHolder pwdUI(password);
    BaseEngine *engine = EngineManager::CreateEngine(true, filePath, &pwdUI, &engineType);
    if (!engine) {
        ErrOut("Error: Couldn't create an engine for %s!\n", path::GetBaseName(filePath));
        return 1;
    }
    if (!loadOnly)
        DumpData(engine, fullDump);
    if (renderPath)
        RenderDocument(engine, renderPath);
    delete engine;

#ifdef DEBUG
    // report memory leaks on stderr for engines that shouldn't leak
    if (engineType != Engine_DjVu) {
        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    }
#endif

    return 0;
}
Ejemplo n.º 6
0
int main(int argc, char **argv)
{
    setlocale(LC_ALL, "C");
    DisableDataExecution();

    WStrVec argList;
    ParseCmdLine(GetCommandLine(), argList);
    if (argList.Count() < 2) {
Usage:
        ErrOut("%s [-pwd <password>][-quick][-render <path-%%d.tga>] <filename>",
            path::GetBaseName(argList.At(0)));
        return 2;
    }

    ScopedMem<WCHAR> filePath;
    WCHAR *password = NULL;
    bool fullDump = true;
    WCHAR *renderPath = NULL;
    float renderZoom = 1.f;
    bool useAlternateHandlers = false;
    bool loadOnly = false, silent = false;
#ifdef DEBUG
    int breakAlloc = 0;
#endif

    for (size_t i = 1; i < argList.Count(); i++) {
        if (str::Eq(argList.At(i), L"-pwd") && i + 1 < argList.Count() && !password)
            password = argList.At(++i);
        else if (str::Eq(argList.At(i), L"-quick"))
            fullDump = false;
        else if (str::Eq(argList.At(i), L"-render") && i + 1 < argList.Count() && !renderPath) {
            // optional zoom argument (e.g. -render 50% file.pdf)
            float zoom;
            if (i + 2 < argList.Count() && str::Parse(argList.At(i + 1), L"%f%%%$", &zoom) && zoom > 0.f) {
                renderZoom = zoom / 100.f;
                i++;
            }
            renderPath = argList.At(++i);
        }
        // -alt is for debugging alternate rendering methods
        else if (str::Eq(argList.At(i), L"-alt"))
            useAlternateHandlers = true;
        // -loadonly and -silent are only meant for profiling
        else if (str::Eq(argList.At(i), L"-loadonly"))
            loadOnly = true;
        else if (str::Eq(argList.At(i), L"-silent"))
            silent = true;
        // -full is for backward compatibility
        else if (str::Eq(argList.At(i), L"-full"))
            fullDump = true;
#ifdef DEBUG
        else if (str::Eq(argList.At(i), L"-breakalloc") && i + 1 < argList.Count())
            breakAlloc = _wtoi(argList.At(++i));
#endif
        else if (!filePath)
            filePath.Set(str::Dup(argList.At(i)));
        else
            goto Usage;
    }
    if (!filePath)
        goto Usage;

#ifdef DEBUG
    if (breakAlloc) {
        _CrtSetBreakAlloc(breakAlloc);
        if (!IsDebuggerPresent())
            MessageBox(NULL, L"Keep your debugger ready for the allocation breakpoint...", L"EngineDump", MB_ICONINFORMATION);
    }
#endif
    if (silent) {
        FILE *nul;
        freopen_s(&nul, "NUL", "w", stdout);
        freopen_s(&nul, "NUL", "w", stderr);
    }

    // optionally use GDI+ rendering for PDF/XPS
    DebugGdiPlusDevice(useAlternateHandlers);

    ScopedGdiPlus gdiPlus;
    ScopedMiniMui miniMui;

    WIN32_FIND_DATA fdata;
    HANDLE hfind = FindFirstFile(filePath, &fdata);
    // embedded documents are referred to by an invalid path
    // containing more information after a colon (e.g. "C:\file.pdf:3:0")
    if (INVALID_HANDLE_VALUE != hfind) {
        ScopedMem<WCHAR> dir(path::GetDir(filePath));
        filePath.Set(path::Join(dir, fdata.cFileName));
        FindClose(hfind);
    }

    EngineType engineType;
    PasswordHolder pwdUI(password);
    BaseEngine *engine = EngineManager::CreateEngine(filePath, &pwdUI, &engineType);
    if (!engine) {
        ErrOut("Error: Couldn't create an engine for %s!", path::GetBaseName(filePath));
        return 1;
    }
    Vec<PageAnnotation> *userAnnots = LoadFileModifications(engine->FileName());
    engine->UpdateUserAnnotations(userAnnots);
    delete userAnnots;
    if (!loadOnly)
        DumpData(engine, fullDump);
    if (renderPath)
        RenderDocument(engine, renderPath, renderZoom, silent);
    delete engine;

#ifdef DEBUG
    // report memory leaks on stderr for engines that shouldn't leak
    if (engineType != Engine_DjVu) {
        _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
        _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
        _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
    }
#endif

    return 0;
}