@@ -1044,18 +1044,23 @@ Friend Function FileReadData(ByVal srcHandle As Long, ByVal ptrToDestinationObje
10441044
10451045End Function
10461046
1047- 'Replace an arbitrary file with another arbitrary file, with optional backup file of the original created during the process.
1047+ 'Replace an arbitrary file with another arbitrary file, with an optional backup file of the original
1048+ ' created during the process.
10481049'
1049- 'All files must reside on the same volume. The target file should exist, but to be safe, I have added some custom code to address instances
1050- ' where the target file does not exist (this function will silently fall back to a "Move file" action instead).
1050+ 'All files must reside on the same volume. The target file should exist, but to be safe, I have added
1051+ ' some custom code to address instances where the target file does not exist (this function will silently
1052+ ' fall back to a "Move file" action instead).
10511053'
1052- 'IMPORTANT NOTE: the ReplaceFileW function has rare-but-not-impossible failure outcomes where the original file is deleted, but the new file is
1053- ' not renamed. Because this failure could be catastrophic during an update process, PD will forcibly create backups of any files
1054- ' patched via this function, and restore them as necessary. The "customBackupFile" parameter only exists if you want to specify
1055- ' a CUSTOM backup filename + location; it does not affect whether or not a backup IS created. (TL;DR - backups are always created.)
1054+ 'IMPORTANT NOTE: the ReplaceFileW function has rare-but-not-impossible failure outcomes where the original
1055+ ' file is deleted, but the new file is not renamed. Because this failure could be
1056+ ' catastrophic during an update process, PD will forcibly create backups of any files patched
1057+ ' via this function and restore them as necessary. The "customBackupFile" parameter only exists
1058+ ' if you want to specify a CUSTOM backup filename + location; it does not affect whether or not
1059+ ' a backup IS created. (TL;DR - backups are always created.)
10561060Friend Function FileReplace (ByVal oldFile As String , ByVal newFile As String , Optional ByVal customBackupFile As String = vbNullString) As PD_FILE_PATCH_RESULT
10571061
1058- 'Because this function is capable of botching an existing PD install if catastrophic failure occurs, error handling must be comprehensive.
1062+ 'Because this function is capable of botching an existing PD install if catastrophic failure occurs,
1063+ ' error handling must be comprehensive.
10591064 On Error GoTo ReplaceFailure
10601065
10611066 Dim backupFile As String
@@ -1067,8 +1072,9 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
10671072 'Consider forcibly specifying a backup path if the user didn't provide their own
10681073 If (LenB(customBackupFile) = 0 ) Then
10691074
1070- 'IMPORTANT NOTE! If the files you're patching are critical, I STRONGLY recommend forcibly creating a backup here.
1071- ' Otherwise, you risk a scenario where something goes wrong during the replace step, and the original file is gone forever.
1075+ 'IMPORTANT NOTE! If the files you're patching are critical, I STRONGLY recommend forcibly creating
1076+ ' a backup here. Otherwise, you risk a scenario where something goes wrong during the replace step,
1077+ ' and the original file is lost forever.
10721078
10731079 'For example, in PhotoDemon I use the standard Data/Updates folder for backups when patching, like this:
10741080 'backupFile = UserPrefs.GetUpdatePath & FileGetName(oldFile)
@@ -1079,8 +1085,9 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
10791085 backupFile = customBackupFile
10801086 End If
10811087
1082- 'ReplaceFileW returns a non-zero value if successful, or zero if it fails. Because this function is used to patch PhotoDemon.exe,
1083- ' there is no margin for failure, so detailed handling of every possible outcome is required.
1088+ 'ReplaceFileW returns a non-zero value if successful, or zero if it fails. Because this function is used
1089+ ' to patch PhotoDemon.exe, there is no margin for failure, so detailed handling of every possible outcome
1090+ ' is necessary.
10841091 rfReturn = ReplaceFileW(StrPtr(oldFile), StrPtr(newFile), StrPtr(backupFile), REPLACEFILE_IGNORE_MERGE_ERRORS, 0 &, 0 &)
10851092
10861093 'Success means we can exit immediately
@@ -1096,15 +1103,17 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
10961103
10971104 Select Case Err.LastDllError
10981105
1099- 'The replacement file could not be renamed. If lpBackupFileName was specified, the replaced and replacement files retain their original
1100- ' file names. Otherwise, the replaced file no longer exists and the replacement file exists under its original name.
1106+ 'The replacement file could not be renamed. If lpBackupFileName was specified, the replaced and
1107+ ' replacement files retain their original file names. Otherwise, the replaced file no longer exists
1108+ ' and the replacement file exists under its original name.
11011109 Case ERROR_UNABLE_TO_MOVE_REPLACEMENT
11021110
11031111 'See if the old file exists
11041112 If Me.FileExists(oldFile) Then
11051113
1106- 'The old file exists. Remove the backup file (if any), then exit. Because the system is in an identical place as it was prior
1107- ' to this function being invoked, the caller is free to try again.
1114+ 'The old file exists. Remove the backup file (if any), then exit. Because the system is in
1115+ ' an identical place as it was prior to this function being invoked, the caller is free to
1116+ ' try again.
11081117 Me.FileDelete customBackupFile
11091118 FileReplace = FPR_FAIL_NOTHING_CHANGED
11101119 Exit Function
@@ -1117,8 +1126,8 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
11171126 'The backup file exists. Try to restore it to the location of the original file.
11181127 mfReturn = MoveFileExW(StrPtr(backupFile), StrPtr(oldFile), MOVEFILE_REPLACE_EXISTING Or MOVEFILE_COPY_ALLOWED)
11191128
1120- 'The move succeeded! Perform a failsafe deletion of the backup file, then notify the caller that the system has been
1121- ' restored to its original state.
1129+ 'The move succeeded! Perform a failsafe deletion of the backup file, then notify the
1130+ ' caller that the system has been restored to its original state.
11221131 If (mfReturn <> 0 ) Then
11231132 Me.FileDelete backupFile
11241133 FileReplace = FPR_FAIL_NOTHING_CHANGED
@@ -1140,16 +1149,18 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
11401149
11411150 End If
11421151
1143- 'The replacement file could not be moved. The replacement file still exists under its original name; however, it has inherited the file streams
1144- ' and attributes from the file it is replacing. The file to be replaced still exists with a different name. If lpBackupFileName is specified,
1152+ 'The replacement file could not be moved. The replacement file still exists under its original name;
1153+ ' however, it has inherited the file streams and attributes from the file it is replacing.
1154+ ' The file to be replaced still exists with a different name. If lpBackupFileName is specified,
11451155 ' it will be the name of the replaced file.
11461156 Case ERROR_UNABLE_TO_MOVE_REPLACEMENT_2
11471157
11481158 'See if the old file exists; this should never happen.
11491159 If Me.FileExists(oldFile) Then
11501160
1151- 'The old file exists. Remove the backup file (if any), then exit. Because the system is in an identical place as it was prior
1152- ' to this function being invoked, the caller is free to try again.
1161+ 'The old file exists. Remove the backup file (if any), then exit. Because the system is in
1162+ ' an identical place as it was prior to this function being invoked, the caller is free to
1163+ ' try again.
11531164 Me.FileDelete customBackupFile
11541165
11551166 FSOError "FileReplace" , "Impossible outcome 3 occurred in FileReplace. Please investigate."
@@ -1158,14 +1169,15 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
11581169
11591170 Else
11601171
1161- 'The old file no longer exists. Restore the backup file. (The backup file is supposedly guaranteed to exist with this error code.)
1172+ 'The old file no longer exists. Restore the backup file.
1173+ ' (The backup file is supposedly guaranteed to exist with this error code.)
11621174 If Me.FileExists(backupFile) Then
11631175
11641176 'The backup file exists. Try to restore it to the location of the original file.
11651177 mfReturn = MoveFileExW(StrPtr(backupFile), StrPtr(oldFile), MOVEFILE_REPLACE_EXISTING Or MOVEFILE_COPY_ALLOWED)
11661178
1167- 'The move succeeded! Perform a failsafe deletion of the backup file, then notify the caller that the system has been
1168- ' restored to its original state.
1179+ 'The move succeeded! Perform a failsafe deletion of the backup file, then notify
1180+ ' the caller that the system has been restored to its original state.
11691181 If (mfReturn <> 0 ) Then
11701182 Me.FileDelete backupFile
11711183 FileReplace = FPR_FAIL_NOTHING_CHANGED
@@ -1195,8 +1207,8 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
11951207 FileReplace = FPR_FAIL_NOTHING_CHANGED
11961208 Exit Function
11971209
1198- 'Other failure states are more problematic. Defer to the primary error handler, which will try to restore the
1199- ' original file setup as best as it can.
1210+ 'Other failure states are more problematic. Defer to the primary error handler,
1211+ ' which will try to restore the original file setup as best as it can.
12001212 Case Else
12011213 PDDebug.LogAction "pdFSO.ReplaceFile last DLL error: " & Err.LastDllError
12021214 GoTo ReplaceFailure
@@ -1230,15 +1242,16 @@ Friend Function FileReplace(ByVal oldFile As String, ByVal newFile As String, Op
12301242 Exit Function
12311243
12321244
1233- 'Arbitrary failure states are problematic. Basically, our goal is to restore the original file setup as best as we can. We do this by attempting
1234- ' to restore the backup file (if it exists), and applying any renames or moves required to get everything back to the way it was.
1245+ 'Arbitrary failure states are problematic. Basically, our goal is to restore the original file setup
1246+ ' as best as we can. We do this by attempting to restore the backup file (if it exists), and applying
1247+ ' any renames or moves required to get everything back to the way it was.
12351248ReplaceFailure:
12361249
12371250 'See if the old file exists
12381251 If Me.FileExists(oldFile) Then
12391252
1240- 'The old file exists. Remove the backup file (if any), then exit. Because the system is in an identical place as it was prior
1241- ' to this function being invoked, the caller is free to try again.
1253+ 'The old file exists. Remove the backup file (if any), then exit. Because the system is in an
1254+ ' identical place as it was prior to this function being invoked, the caller is free to try again.
12421255 Me.FileDelete customBackupFile
12431256
12441257 If Me.FileExists(newFile) Then
@@ -1258,8 +1271,8 @@ ReplaceFailure:
12581271 'The backup file exists. Try to restore it to the location of the original file.
12591272 mfReturn = MoveFileExW(StrPtr(backupFile), StrPtr(oldFile), MOVEFILE_REPLACE_EXISTING Or MOVEFILE_COPY_ALLOWED)
12601273
1261- 'The move succeeded! Perform a failsafe deletion of the backup file, then notify the caller that the system has been
1262- ' restored to its original state.
1274+ 'The move succeeded! Perform a failsafe deletion of the backup file, then notify the caller
1275+ ' that the system has been restored to its original state.
12631276 If (mfReturn <> 0 ) Then
12641277
12651278 Me.FileDelete backupFile
0 commit comments