From 2b64c1847019c8cf05aad15f616e949fa6c9f935 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 5 Jun 2014 22:46:43 +0530 Subject: [PATCH] Portable installer: Fix a crash if the user selects a destination for the portable install that does not have enough disk space. Fixes #1324575 [Portable install crashes on low disk space](https://bugs.launchpad.net/calibre/+bug/1324575) --- .../installer/windows/portable-installer.cpp | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/setup/installer/windows/portable-installer.cpp b/setup/installer/windows/portable-installer.cpp index ff4e5e8036..87f444c6ac 100644 --- a/setup/installer/windows/portable-installer.cpp +++ b/setup/installer/windows/portable-installer.cpp @@ -45,13 +45,17 @@ static void show_detailed_error(LPCWSTR preamble, LPCWSTR msg, int code) { static void show_zip_error(LPCWSTR preamble, LPCWSTR msg, ZRESULT code) { LPWSTR buf; + char msgbuf[1024] = {0}; + + FormatZipMessage(code, msgbuf, 1024); + buf = (LPWSTR)LocalAlloc(LMEM_ZEROINIT, sizeof(WCHAR)* - (wcslen(preamble) + wcslen(msg) + 80)); + (wcslen(preamble) + wcslen(msg) + 1100)); _snwprintf_s(buf, LocalSize(buf) / sizeof(WCHAR), _TRUNCATE, - L"%s\r\n %s %s (Error Code: %X)\r\n", - preamble, msg, code); + L"%s\r\n %s (Error: %S)\r\n", + preamble, msg, msgbuf); show_error(buf); LocalFree(buf); @@ -116,7 +120,7 @@ static BOOL unzip(HZIP zipf, int nitems, IProgressDialog *pd) { if (res != ZR_OK) { show_zip_error(L"Failed to get zip item", L"", res); return false;} res = UnzipItem(zipf, i, ze.name, 0, ZIP_FILENAME); - if (res != ZR_OK) { show_zip_error(L"Failed to extract zip item:", ze.name, res); return false;} + if (res != ZR_OK) { CloseZip(zipf); show_zip_error(L"Failed to extract zip item (is your disk full?):", ze.name, res); return false;} pd->SetLine(2, ze.name, true, NULL); pd->SetProgress(i, nitems); @@ -168,7 +172,9 @@ input_callback(void *ctx, void *buf, size_t * size) return 0; } - + +static int output_error_shown = 0; + static size_t output_callback(void *ctx, const void *buf, size_t size) { @@ -178,6 +184,7 @@ output_callback(void *ctx, const void *buf, size_t size) if (size > 0) { if (!WriteFile(ds->out, buf, size, &written, NULL)) { show_last_error(L"Failed to write uncompressed data to temp file"); + output_error_shown = 1; return 0; } written = SetFilePointer(ds->out, 0, NULL, FILE_CURRENT); @@ -205,8 +212,8 @@ static BOOL decompress(LPVOID src, DWORD src_sz, HANDLE out, IProgressDialog *pd (void *) &ds, ELZMA_lzip); if (rc != ELZMA_E_OK) { + if (!output_error_shown) show_detailed_error(L"Failed to decompress portable data", L"", rc); elzma_decompress_free(&h); - show_zip_error(L"Failed to decompress portable data", L"", rc); return false; } @@ -238,6 +245,8 @@ static BOOL extract(LPVOID cdata, DWORD csz) { pd->StartProgressDialog(NULL, NULL, PROGDLG_NORMAL | PROGDLG_AUTOTIME | PROGDLG_NOCANCEL, NULL); if (!decompress(cdata, csz, h, pd)) { ret = false; goto end; } + pd->SetLine(1, L"Reading manifest", true, NULL); + pd->SetProgress(1, 1000); SetFilePointer(h, 0, NULL, FILE_BEGIN); zipf = OpenZip(h, 0, ZIP_HANDLE); if (zipf == 0) { show_last_error(L"Failed to open zipped portable data"); ret = false; goto end; } @@ -571,8 +580,6 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine // Move files from temp dir to the install dir if (!move_program()) goto end; - SetCurrentDirectoryW(L".."); - _snwprintf_s(mb_msg, 4*MAX_PATH, _TRUNCATE, L"Calibre Portable successfully installed to %s. Launch calibre?", fdest); @@ -580,7 +587,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine L"Success", MB_ICONINFORMATION | MB_YESNO | MB_TOPMOST) == IDYES; end: - if (unpack_dir != NULL) { rmtree(unpack_dir); free(unpack_dir); } + if (unpack_dir != NULL) { SetCurrentDirectoryW(L".."); rmtree(unpack_dir); free(unpack_dir); } CoUninitialize(); if (launch) launch_calibre(); return 0;