From 84528ce316803a0fc4f893fc4e8c606d0063122d Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 19 May 2016 22:01:56 +0200 Subject: [PATCH] Check all files are writeable before applying update. Closes #264 --- renderdoccmd/renderdoccmd_win32.cpp | 61 ++++++++++++++++++++++++++++- renderdocui/Code/AppMain.cs | 12 +++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/renderdoccmd/renderdoccmd_win32.cpp b/renderdoccmd/renderdoccmd_win32.cpp index 9c0364fdb..a3637ae77 100644 --- a/renderdoccmd/renderdoccmd_win32.cpp +++ b/renderdoccmd/renderdoccmd_win32.cpp @@ -333,6 +333,9 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, mz_zip_archive zip; ZeroMemory(&zip, sizeof(zip)); + bool successful = false; + wstring failReason; + mz_bool b = mz_zip_reader_init_file(&zip, "./update.zip", 0); if(b) @@ -373,7 +376,53 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, } } - for(mz_uint i=0; i < numfiles; i++) + // next make sure we can get read+write access to every file. If not + // one might be in use, but we definitely can't update it + successful = true; + + for(mz_uint i=0; successful && i < numfiles; i++) + { + if(!mz_zip_reader_is_file_a_directory(&zip, i)) + { + mz_zip_archive_file_stat zstat; + mz_zip_reader_file_stat(&zip, i, &zstat); + + const char *fn = zstat.m_filename; + // skip first directory because it's RenderDoc_Version_Bitness/ + fn = strchr(fn, '/'); + if(fn) fn++; + + if(fn && *fn) + { + wchar_t conv[MAX_PATH] = {0}; + wchar_t *wfn = conv; + + // I know the zip only contains ASCII chars, just upcast + while(*fn) *(wfn++) = wchar_t(*(fn++)); + + wstring target = wide_path + conv; + + wfn = &target[0]; + + // convert slashes just to be consistent + while(*(wfn++)) { if(*wfn == L'/') *wfn = L'\\'; } + + FILE *f = NULL; + _wfopen_s(&f, target.c_str(), L"a+"); + if(!f) + { + failReason = L"\"Couldn't modify an install file - likely file is in use.\""; + successful = false; + } + else + { + fclose(f); + } + } + } + } + + for(mz_uint i=0; successful && i < numfiles; i++) { if(!mz_zip_reader_is_file_a_directory(&zip, i)) { @@ -405,11 +454,19 @@ int WINAPI wWinMain(_In_ HINSTANCE hInst, } } } + else + { + failReason = L"\"Failed to open update .zip file - possibly corrupted.\""; + } // run original UI exe and tell it an update succeeded wstring cmdline = L"\""; cmdline += wide_path; - cmdline += L"/renderdocui.exe\" --updatedone"; + cmdline += L"/renderdocui.exe\" "; + if(successful) + cmdline += L"--updatedone"; + else + cmdline += L"--updatefailed " + failReason; wchar_t *paramsAlloc = new wchar_t[512]; diff --git a/renderdocui/Code/AppMain.cs b/renderdocui/Code/AppMain.cs index c31e6cde5..e3d1f3a2a 100644 --- a/renderdocui/Code/AppMain.cs +++ b/renderdocui/Code/AppMain.cs @@ -156,8 +156,10 @@ namespace renderdocui.Code var core = new Core(filename, remoteHost, remoteIdent, temp, cfg); - foreach (var a in args) + for(int i=0; i < args.Length; i++) { + var a = args[i]; + if (a.ToUpperInvariant() == "--UPDATEDONE") { cfg.CheckUpdate_UpdateAvailable = false; @@ -178,6 +180,14 @@ namespace renderdocui.Code Helpers.UpdateInstalledVersionNumber(); } + + if (a.ToUpperInvariant() == "--UPDATEFAILED") + { + if(i < args.Length-1) + MessageBox.Show(String.Format("Error applying update: {0}", args[i+1]), "Error updating", MessageBoxButtons.OK, MessageBoxIcon.Error); + else + MessageBox.Show("Unknown error applying update", "Error updating", MessageBoxButtons.OK, MessageBoxIcon.Error); + } } try