From b7eadfd310bc61e7a982dc8bce4eb32038a6fa09 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 9 Jun 2015 23:29:33 +0200 Subject: Windows: solve installer issue on Windows 10 caused by failure to overwrite VeraCrypt driver file. --- src/Common/Dlgcode.c | 37 +++++++++++++++++++++++++++++++++---- src/Common/Dlgcode.h | 4 +++- src/Format/InPlace.c | 4 ++-- src/Setup/SelfExtract.c | 14 +++++++------- src/Setup/Setup.c | 37 ++++++++++++++++++++++++------------- src/Setup/Setup.h | 2 +- 6 files changed, 70 insertions(+), 28 deletions(-) diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 246f35a6..5e26ef0f 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -7520,18 +7520,47 @@ BOOL TCCopyFile (char *sourceFileName, char *destinationFile) // If bAppend is TRUE, the buffer is appended to an existing file. If bAppend is FALSE, any existing file // is replaced. If an error occurs, the incomplete file is deleted (provided that bAppend is FALSE). -BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend) +BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend, BOOL bRenameIfFailed) { HANDLE dst; DWORD bytesWritten; BOOL res = TRUE; + DWORD dwLastError = 0; dst = CreateFile (destinationFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL); + dwLastError = GetLastError(); + if (!bAppend && bRenameIfFailed && (dst == INVALID_HANDLE_VALUE) && (GetLastError () == ERROR_SHARING_VIOLATION)) + { + char renamedPath[TC_MAX_PATH + 1]; + StringCbCopyA (renamedPath, sizeof(renamedPath), destinationFile); + StringCbCatA (renamedPath, sizeof(renamedPath), VC_FILENAME_RENAMED_SUFFIX); + + /* rename the locked file in order to be able to create a new one */ + if (MoveFileEx (destinationFile, renamedPath, MOVEFILE_REPLACE_EXISTING)) + { + dst = CreateFile (destinationFile, + GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, bAppend ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL); + dwLastError = GetLastError(); + if (dst == INVALID_HANDLE_VALUE) + { + /* restore the original file name */ + MoveFileEx (renamedPath, destinationFile, MOVEFILE_REPLACE_EXISTING); + } + else + { + /* delete the renamed file when the machine reboots */ + MoveFileEx (renamedPath, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); + } + } + } + if (dst == INVALID_HANDLE_VALUE) { + SetLastError (dwLastError); handleWin32Error (MainDlg); return FALSE; } @@ -7603,14 +7632,14 @@ BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, size_t textByteLen) } // Write the Unicode signature - if (!SaveBufferToFile ("\xFF\xFE", path, 2, FALSE)) + if (!SaveBufferToFile ("\xFF\xFE", path, 2, FALSE, FALSE)) { remove (path); return FALSE; } // Write the actual text - if (!SaveBufferToFile ((char *) text, path, (DWORD) textByteLen, TRUE)) + if (!SaveBufferToFile ((char *) text, path, (DWORD) textByteLen, TRUE, FALSE)) { remove (path); return FALSE; @@ -10068,7 +10097,7 @@ BOOL CALLBACK SecurityTokenKeyfileDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam finally_do_arg (vector *, &keyfileData, { burn (&finally_arg->front(), finally_arg->size()); }); - if (!SaveBufferToFile ((char *) &keyfileData.front(), keyfilePath, (DWORD) keyfileData.size(), FALSE)) + if (!SaveBufferToFile ((char *) &keyfileData.front(), keyfilePath, (DWORD) keyfileData.size(), FALSE, FALSE)) throw SystemException (); } diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index a8d571dd..f6b285c4 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -77,6 +77,8 @@ enum #define TC_APPD_FILENAME_POST_INSTALL_TASK_TUTORIAL "Post-Install Task - Tutorial" #define TC_APPD_FILENAME_POST_INSTALL_TASK_RELEASE_NOTES "Post-Install Task - Release Notes" +#define VC_FILENAME_RENAMED_SUFFIX "_old" + #ifndef USER_DEFAULT_SCREEN_DPI #define USER_DEFAULT_SCREEN_DPI 96 #endif @@ -351,7 +353,7 @@ int64 FindString (const char *buf, const char *str, int64 bufLen, int64 strLen, BOOL FileExists (const char *filePathPtr); __int64 FindStringInFile (const char *filePath, const char *str, int strLen); BOOL TCCopyFile (char *sourceFileName, char *destinationFile); -BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend); +BOOL SaveBufferToFile (const char *inputBuffer, const char *destinationFile, DWORD inputLength, BOOL bAppend, BOOL bRenameIfFailed); BOOL TCFlushFile (FILE *f); BOOL PrintHardCopyTextUTF16 (wchar_t *text, char *title, size_t byteLen); void GetSpeedString (unsigned __int64 speed, wchar_t *str, size_t cbStr); diff --git a/src/Format/InPlace.c b/src/Format/InPlace.c index 043c1cd7..24303036 100644 --- a/src/Format/InPlace.c +++ b/src/Format/InPlace.c @@ -2007,7 +2007,7 @@ BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm, { StringCbPrintfA (str, sizeof(str), "%d", (int) newWipeAlgorithm); - SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE), (DWORD) strlen(str), FALSE); + SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE), (DWORD) strlen(str), FALSE, FALSE); } else if (FileExists (GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC_WIPE))) { @@ -2017,7 +2017,7 @@ BOOL SaveNonSysInPlaceEncSettings (int delta, WipeAlgorithmId newWipeAlgorithm, StringCbPrintfA (str, sizeof(str), "%d", count); - return SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), (DWORD) strlen(str), FALSE); + return SaveBufferToFile (str, GetConfigPath (TC_APPD_FILENAME_NONSYS_INPLACE_ENC), (DWORD) strlen(str), FALSE, FALSE); } diff --git a/src/Setup/SelfExtract.c b/src/Setup/SelfExtract.c index 7169c991..a4acde26 100644 --- a/src/Setup/SelfExtract.c +++ b/src/Setup/SelfExtract.c @@ -297,7 +297,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir) // Write the start marker - if (!SaveBufferToFile (MAG_START_MARKER, outputFile, strlen (MAG_START_MARKER), TRUE)) + if (!SaveBufferToFile (MAG_START_MARKER, outputFile, strlen (MAG_START_MARKER), TRUE, FALSE)) { if (remove (outputFile)) PkgError ("Cannot write the start marker\nFailed also to delete package file"); @@ -357,7 +357,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir) // Write total size of the uncompressed data szTmp32bitPtr = szTmp32bit; mputLong (szTmp32bitPtr, (unsigned __int32) uncompressedDataLen); - if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE)) + if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE, FALSE)) { if (remove (outputFile)) PkgError ("Cannot write the total size of the uncompressed data.\nFailed also to delete package file"); @@ -394,7 +394,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir) // Write the total size of the compressed data szTmp32bitPtr = szTmp32bit; mputLong (szTmp32bitPtr, (unsigned __int32) compressedDataLen); - if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE)) + if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE, FALSE)) { if (remove (outputFile)) PkgError ("Cannot write the total size of the compressed data.\nFailed also to delete package file"); @@ -404,7 +404,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir) } // Write the compressed data - if (!SaveBufferToFile (compressedBuffer, outputFile, compressedDataLen, TRUE)) + if (!SaveBufferToFile (compressedBuffer, outputFile, compressedDataLen, TRUE, FALSE)) { if (remove (outputFile)) PkgError ("Cannot write compressed data to the package.\nFailed also to delete package file"); @@ -414,7 +414,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir) } // Write the end marker - if (!SaveBufferToFile (MagEndMarker, outputFile, strlen (MagEndMarker), TRUE)) + if (!SaveBufferToFile (MagEndMarker, outputFile, strlen (MagEndMarker), TRUE, FALSE)) { if (remove (outputFile)) PkgError ("Cannot write the end marker.\nFailed also to delete package file"); @@ -450,7 +450,7 @@ BOOL MakeSelfExtractingPackage (HWND hwndDlg, char *szDestDir) mputLong (szTmp32bitPtr, GetCrc32 (tmpBuffer, tmpFileSize)); free (tmpBuffer); - if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE)) + if (!SaveBufferToFile (szTmp32bit, outputFile, sizeof (szTmp32bit), TRUE, FALSE)) { if (remove (outputFile)) PkgError ("Cannot write the total size of the compressed data.\nFailed also to delete package file"); @@ -745,7 +745,7 @@ void __cdecl ExtractAllFilesThread (void *hwndDlg) Decompressed_Files[fileNo].fileContent, filePath, Decompressed_Files[fileNo].fileLength, - FALSE)) + FALSE, FALSE)) { wchar_t szTmp[512]; diff --git a/src/Setup/Setup.c b/src/Setup/Setup.c index c52b311c..5f1c9300 100644 --- a/src/Setup/Setup.c +++ b/src/Setup/Setup.c @@ -86,10 +86,20 @@ void localcleanup (void) CloseAppSetupMutex (); } -BOOL StatDeleteFile (char *lpszFile) +BOOL StatDeleteFile (char *lpszFile, BOOL bCheckForOldFile) { struct __stat64 st; + if (bCheckForOldFile) + { + char szOldPath[MAX_PATH + 1]; + StringCbCopyA (szOldPath, sizeof(szOldPath), lpszFile); + StringCbCatA (szOldPath, sizeof(szOldPath), VC_FILENAME_RENAMED_SUFFIX); + + if (_stat64 (szOldPath, &st) == 0) + DeleteFile (szOldPath); + } + if (_stat64 (lpszFile, &st) == 0) return DeleteFile (lpszFile); else @@ -725,7 +735,8 @@ BOOL DoFilesInstall (HWND hwndDlg, char *szDestDir) (char *) Decompressed_Files[fileNo].fileContent, szTmp, Decompressed_Files[fileNo].fileLength, - FALSE); + FALSE, + TRUE); if (driver64) { @@ -769,7 +780,7 @@ BOOL DoFilesInstall (HWND hwndDlg, char *szDestDir) } else { - bResult = StatDeleteFile (szTmp); + bResult = StatDeleteFile (szTmp, TRUE); } err: @@ -1022,27 +1033,27 @@ BOOL DoApplicationDataUninstall (HWND hwndDlg) // Delete favorite volumes file StringCbPrintfA (path2, sizeof(path2), "%s%s", path, TC_APPD_FILENAME_FAVORITE_VOLUMES); RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2); + StatDeleteFile (path2, FALSE); // Delete keyfile defaults StringCbPrintfA (path2, sizeof(path2), "%s%s", path, TC_APPD_FILENAME_DEFAULT_KEYFILES); RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2); + StatDeleteFile (path2, FALSE); // Delete history file StringCbPrintfA (path2, sizeof(path2), "%s%s", path, TC_APPD_FILENAME_HISTORY); RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2); + StatDeleteFile (path2, FALSE); // Delete configuration file StringCbPrintfA (path2, sizeof(path2), "%s%s", path, TC_APPD_FILENAME_CONFIGURATION); RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2); + StatDeleteFile (path2, FALSE); // Delete system encryption configuration file StringCbPrintfA (path2, sizeof(path2), "%s%s", path, TC_APPD_FILENAME_SYSTEM_ENCRYPTION); RemoveMessage (hwndDlg, path2); - StatDeleteFile (path2); + StatDeleteFile (path2, FALSE); SHGetFolderPath (NULL, CSIDL_APPDATA, NULL, 0, path); StringCbCatA (path, sizeof(path), "\\VeraCrypt"); @@ -1491,22 +1502,22 @@ BOOL DoShortcutsUninstall (HWND hwndDlg, char *szDestDir) // Start menu entries StringCbPrintfA (szTmp2, sizeof(szTmp2), "%s%s", szLinkDir, "\\VeraCrypt.lnk"); RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2) == FALSE) + if (StatDeleteFile (szTmp2, FALSE) == FALSE) goto error; StringCbPrintfA (szTmp2, sizeof(szTmp2), "%s%s", szLinkDir, "\\VeraCryptExpander.lnk"); RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2) == FALSE) + if (StatDeleteFile (szTmp2, FALSE) == FALSE) goto error; StringCbPrintfA (szTmp2, sizeof(szTmp2), "%s%s", szLinkDir, "\\VeraCrypt Website.url"); RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2) == FALSE) + if (StatDeleteFile (szTmp2, FALSE) == FALSE) goto error; StringCbPrintfA (szTmp2, sizeof(szTmp2), "%s%s", szLinkDir, "\\Uninstall VeraCrypt.lnk"); RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2) == FALSE) + if (StatDeleteFile (szTmp2, FALSE) == FALSE) goto error; StringCbPrintfA (szTmp2, sizeof(szTmp2), "%s%s", szLinkDir, "\\VeraCrypt User's Guide.lnk"); @@ -1527,7 +1538,7 @@ BOOL DoShortcutsUninstall (HWND hwndDlg, char *szDestDir) StringCbPrintfA (szTmp2, sizeof(szTmp2), "%s%s", szLinkDir, "\\VeraCrypt.lnk"); RemoveMessage (hwndDlg, szTmp2); - if (StatDeleteFile (szTmp2) == FALSE) + if (StatDeleteFile (szTmp2, FALSE) == FALSE) goto error; bOK = TRUE; diff --git a/src/Setup/Setup.h b/src/Setup/Setup.h index 5852f058..0b4b68ee 100644 --- a/src/Setup/Setup.h +++ b/src/Setup/Setup.h @@ -123,7 +123,7 @@ static char *szCompressedFiles[]= #define NBR_COMPRESSED_FILES (sizeof(szCompressedFiles) / sizeof(szCompressedFiles[0])) void localcleanup (void); -BOOL StatDeleteFile ( char *lpszFile ); +BOOL StatDeleteFile ( char *lpszFile, BOOL bCheckForOldFile ); BOOL StatRemoveDirectory ( char *lpszDir ); HRESULT CreateLink ( char *lpszPathObj , char *lpszArguments , char *lpszPathLink ); void GetProgramPath ( HWND hwndDlg , char *path ); -- cgit v1.2.3