Reply To: It appears that this version…has just been upgraded

Product Compare Forums Multi-Edit Support It appears that this version…has just been upgraded Reply To: It appears that this version…has just been upgraded

#5742
Michal Vodicka
Participant

Backup config directory is good idea in any case. Years before I wrote a macro which does it automatically during every MEW startup. Config directory is copied to numbered directories; last 10 copies are kept so in the case of failure is is easy to find the newest working configuration and copy it back. It saved me numerous times; mostly because I write device drivers and occassional BSODs are unavoidable. But there are also other situations. Running multiple MEW instances is one, reaching windows number limit (~250) is the next. In this case a macro which isn’t prepared for it can overwrite meconfig.db (the limit should be removed in MEW X).

Macro is started from MEW command line: E:\Mew91\Mew32.exe -SR -RMvUtils^BackupMEWConfig -NI and looks like this (it is necessary to write a file header and add some includes):

[code:1hc8t55b]// —- configuration saving —————

import Bool CopyFile(Asciiz ExistingFileName, Asciiz NewFileName, Bool FailIfExists)
kernel32 "CopyFileA";

import int CreateFile(Asciiz FileName, DWORD dwDesiredAccess, DWORD dwShareMode,
pointer lpSecurityAttributes, DWORD dwCreationDistribution,
DWORD dwFlagsAndAttributes, int hTemplateFile)
kernel32 "CreateFileA";

import Bool CloseHandle(int Handle)
kernel32 "CloseHandle";

import int GetFileAttributes(Asciiz FileName)
kernel32 "GetFileAttributesA";

import Bool SetFileAttributes(Asciiz lpFileName, DWORD FileAttributes)
kernel32 "SetFileAttributesA";

#define FILE_ATTRIBUTE_DIRECTORY 0x00000010

#define INVALID_FILE_ATTRIBUTES -1

#define FILE_ATTRIBUTE_READONLY 0x00000001

#define BACKUP_NUM 10 // number of last saved backups

#define _CfgBackup ( _ConfigDir + "BACKUP" )
#define _TimeStamp ( "TimeStamp" )

int FindOldestBackup() {
/* ==================
Tries to find the oldest backup dir to replace.
*/

int OldestTime = 0;
int OldestBackup = 0;

for ( int i = 0; i < BACKUP_NUM; i++ ) {
str TSName = _CfgBackup + str(i) + "\\" + _TimeStamp;

if (!File_Exists(TSName)) {
// timestamp doesn’t exist, directory can be used for backup
return(i);
}
else {
int ActTime = GetFileTime(TSName);

if ((OldestTime == 0) || (ActTime < OldestTime)) {
OldestTime = ActTime;
OldestBackup = i;
}
}
}
return(OldestBackup);
}

void BackupMEWConfig() {
/* =================
Backups all MEW configuration files. Should be run automaticaly
after MEW start.
*/
int BackupNum = FindOldestBackup();
str BackupPath = _CfgBackup + str(BackupNum) + "\\";
struct WIN32_FIND_DATA Win32Data;
struct DOS_FIND_DATA DosData;
int FindHandle;
int Number = 0;

if (!CreatePath(BackupPath)) {
RM("MessageBox /B=2/T=Backup/M=Error creating " + BackupPath + " directory");
return();
}

TTRACE("MvUtils", TDBG_WARN, "Starting config backup no.%d (%s)", BackupNum, BackupPath);

FindHandle = FindFirstFile(_ConfigDir + "*.*", &Win32Data, &DosData);

if (FindHandle != 0) {
do {
if (!(Win32Data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
str NewName = BackupPath + Win32Data.cFileName;

if (!CopyFile(_ConfigDir + Win32Data.cFileName, NewName, FALSE)) {
int DisplayError = TRUE;

if (GetLastError() == 5) {
int Attr = GetFileAttributes(NewName);

if (Attr != INVALID_FILE_ATTRIBUTES) {
if (Attr & FILE_ATTRIBUTE_READONLY) {
// destination is RO, remove this flag
Attr &= 0xfffffffe; // ~FILE_ATTRIBUTE_READONLY;

TTRACE("MvUtils", TDBG_DEBUG, "Copy destination %s is read-only, removing flag.", NewName);

if (!SetFileAttributes(NewName, Attr)) {
TTRACE("MvUtils", TDBG_ERROR, "Error %x setting attributes %x for file %s", GetLastError(), Attr, NewName);
}
}
}
// and retry original operation anyway (to restore last error in the worst case)
DisplayError = !CopyFile(_ConfigDir + Win32Data.cFileName, NewName, FALSE);
}
if (DisplayError) {
RM("MessageBox /B=2/T=Backup/M=Error [" + hex_str(GetLastError()) + "] copying " + NewName + " file");
}
}
else {
Number++;
}
}

} while (FindNextFile(FindHandle, &Win32Data, &DosData));
FindClose(FindHandle);
}

TTRACE("MvUtils", TDBG_WARN, "Config backup done, %d files saved.", Number);

Make_Message(str(Number) + " files was saved to " + BackupPath);

CloseHandle(CreateFile(BackupPath + _TimeStamp, 0, 0, 0, 2, 0, 0));
}
[/code:1hc8t55b]