home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
xwplascr.zip
/
XWPL0208.ZIP
/
src
/
startshut
/
archives.c
< prev
next >
Wrap
C/C++ Source or Header
|
2002-06-02
|
48KB
|
1,311 lines
/*
*@@sourcefile archives.c:
* the purpose of this code is to examine the WPS's status
* by evaluating dates, directory and system INI file contents.
* We can then draw the conclusion (depending on user settings)
* whether the WPS backup functionality should be enabled.
*
* These checks are performed in arcCheckIfBackupNeeded, which
* gets called during Desktop startup.
*
* This file is ALL new with V0.9.0.
*
* This is based on ideas in the WPSArcO code which has kindly
* been provided by Stefan Milcke (Stefan.Milcke@t-online.de).
*
* All funtions in this file have the arc* prefix.
*
* Note that the ARCHIVINGSETTINGS are only manipulated by the
* new Desktop "Archives" notebook page, whose code is
* in xfdesk.c. For the archiving settings, we do not use
* the global settings (as the rest of XWorkplace does), but
* this separate structure instead. See arcQuerySettings.
*
*@@added V0.9.0 [umoeller]
*@@header "startshut\archives.h"
*/
/*
* Copyright (C) 1999-2002 Ulrich Möller.
* This file is part of the XWorkplace source package.
* XWorkplace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published
* by the Free Software Foundation, in version 2 as it comes in the
* "COPYING" file of the XWorkplace main distribution.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
/*
*@@todo:
* csm:
Ok, no guarantee, but this is what I found out:
Offset 0x00: (int32) "Nummer des Archives nach Restore"
(Ist immer 0, wenn ein Backup gemacht wurde.
Nach einem Restore ist hier die Nummer des Archives zu finden)
Offset 0xCF: (int32) "Dateien bei jedem Systemstart aktivieren"
(0 = off, 1 = on/selected)
Offset 0xD7: (int32) "Anzahl der zu sichernden Archive"
Offset 0xD9: (int32) "Anzeige der Optionen bei jedem Neustart"
(0 = off, 2 = on/selected)
Offset 0xDD: (int32) "Zeitsperre fuer Anzeigen der Optionen"
(0 to 999)
The rest of the file I don't know (besides the path
beginning at offset 0x06, 200 bytes long)
*/
#pragma strings(readonly)
/*
* Suggested #include order:
* 1) os2.h
* 2) C library headers
* 3) setup.h (code generation and debugging options)
* 4) headers in helpers\
* 5) at least one SOM implementation header (*.ih)
* 6) dlgids.h, headers in shared\ (as needed)
* 7) headers in implementation dirs (e.g. filesys\, as needed)
* 8) #pragma hdrstop and then more SOM headers which crash with precompiled headers
*/
#define INCL_DOSDATETIME
#define INCL_DOSERRORS
#define INCL_WINDIALOGS
#define INCL_WINBUTTONS
#define INCL_WINSTATICS
#define INCL_WINSTDSPIN
#define INCL_WINSHELLDATA // Prf* functions
#include <os2.h>
#include <string.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <time.h>
#include <process.h>
#include <math.h>
// generic headers
#include "setup.h" // code generation and debugging options
// headers in /helpers
#include "helpers\datetime.h" // date/time helpers
#include "helpers\dialog.h" // dialog helpers
#include "helpers\dosh.h"
#include "helpers\prfh.h"
#include "helpers\standards.h" // some standard macros
#include "helpers\stringh.h"
#include "helpers\winh.h" // PM helper routines
#include "helpers\wphandle.h" // file-system object handles
#include "helpers\xstring.h" // extended string helpers
// SOM headers which don't crash with prec. header files
#include "xfdesk.ih"
// XWorkplace implementation headers
#include "dlgids.h" // all the IDs that are shared with NLS
#include "shared\common.h" // the majestic XWorkplace include file
#include "shared\notebook.h" // generic XWorkplace notebook handling
#include "startshut\archives.h" // archiving declarations
// other SOM headers
#pragma hdrstop // VAC++ keeps crashing otherwise
/********************************************************************
*
* Global variables
*
********************************************************************/
static ARCHIVINGSETTINGS G_ArcSettings;
static DATETIME G_dtLastArchived;
static BOOL G_fSettingsLoaded = FALSE;
static CHAR G_szArcBaseFilename[CCHMAXPATH] = "";
#define ARCOFS_JUSTRESTORED 0x00000
#define ARCOFS_ARCHIVINGENABLED 0x000CF
#define ARCOFS_MAXARCHIVES 0x000D7
/********************************************************************
*
* "Archives" page replacement in WPDesktop
*
********************************************************************/
// PSZ's for percentage spinbutton
static PCSZ G_apcszPercentages[] =
{
"0.010",
"0.025",
"0.050",
"0.075",
"0.100",
"0.250",
"0.500",
"0.750",
"1.000",
"2.500",
"5.000"
};
#define SPIN_WIDTH 40
#define SPIN_HEIGHT STD_SPIN_HEIGHT
static const CONTROLDEF
ArcCriteriaGroup = LOADDEF_GROUP(ID_XSDI_ARC_CRITERIA_GROUP, DEFAULT_TABLE_WIDTH),
EnableArchiveCB = LOADDEF_AUTOCHECKBOX(ID_XSDI_ARC_ENABLE),
ArcAlwaysCB = LOADDEF_AUTOCHECKBOX(ID_XSDI_ARC_ALWAYS),
ArcNextCB = LOADDEF_AUTOCHECKBOX(ID_XSDI_ARC_NEXT),
ArcINICB = LOADDEF_AUTOCHECKBOX(ID_XSDI_ARC_INI),
ArcINISpin =
{
WC_SPINBUTTON,
NULL,
WS_VISIBLE | WS_TABSTOP
| SPBS_MASTER | SPBS_JUSTLEFT | SPBS_JUSTRIGHT | SPBS_JUSTCENTER
| SPBS_FASTSPIN,
ID_XSDI_ARC_INI_SPIN,
CTL_COMMON_FONT,
0,
{ SPIN_WIDTH, SPIN_HEIGHT }, // size
COMMON_SPACING,
},
ArcINITxt2 = LOADDEF_TEXT(ID_XSDI_ARC_INI_SPINTXT1),
ArcDaysCB = LOADDEF_AUTOCHECKBOX(ID_XSDI_ARC_DAYS),
ArcDaysSpin =
{
WC_SPINBUTTON,
NULL,
WS_VISIBLE | WS_TABSTOP
| SPBS_MASTER | SPBS_JUSTLEFT | SPBS_JUSTRIGHT | SPBS_JUSTCENTER
| SPBS_FASTSPIN,
ID_XSDI_ARC_DAYS_SPIN,
CTL_COMMON_FONT,
0,
{ SPIN_WIDTH, SPIN_HEIGHT }, // size
COMMON_SPACING,
},
ArcDaysTxt2 = LOADDEF_TEXT(ID_XSDI_ARC_DAYS_SPINTXT1),
ArcShowStatusCB = LOADDEF_AUTOCHECKBOX(ID_XSDI_ARC_SHOWSTATUS),
Arc2Group = LOADDEF_GROUP(ID_XSDI_ARC_ARCHIVES_GROUP, DEFAULT_TABLE_WIDTH),
ArcNoTxt1 = LOADDEF_TEXT(ID_XSDI_ARC_ARCHIVES_NO_TXT1),
ArcNoSpin =
{
WC_SPINBUTTON,
NULL,
WS_VISIBLE | WS_TABSTOP
| SPBS_MASTER | SPBS_JUSTLEFT | SPBS_JUSTRIGHT | SPBS_JUSTCENTER,
ID_XSDI_ARC_ARCHIVES_NO_SPIN,
CTL_COMMON_FONT,
0,
{ SPIN_WIDTH, SPIN_HEIGHT }, // size
COMMON_SPACING,
},
ArcNoTxt2 = LOADDEF_TEXT(ID_XSDI_ARC_ARCHIVES_NO_TXT2);
static const DLGHITEM dlgArchives[] =
{
START_TABLE, // root table, required
START_ROW(0), // row 1 in the root table, required
// create group on top
START_GROUP_TABLE(&ArcCriteriaGroup),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&EnableArchiveCB),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&G_Spacing), // notebook.c
CONTROL_DEF(&ArcAlwaysCB),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&G_Spacing), // notebook.c
CONTROL_DEF(&ArcNextCB),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&G_Spacing), // notebook.c
CONTROL_DEF(&ArcINICB),
CONTROL_DEF(&ArcINISpin),
CONTROL_DEF(&ArcINITxt2),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&G_Spacing), // notebook.c
CONTROL_DEF(&ArcDaysCB),
CONTROL_DEF(&ArcDaysSpin),
CONTROL_DEF(&ArcDaysTxt2),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&ArcShowStatusCB),
END_TABLE,
START_ROW(0), // row 2 in the root table
START_GROUP_TABLE(&Arc2Group),
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&ArcNoTxt1),
CONTROL_DEF(&ArcNoSpin),
CONTROL_DEF(&ArcNoTxt2),
END_TABLE,
START_ROW(0), // notebook buttons (will be moved)
CONTROL_DEF(&G_UndoButton), // common.c
CONTROL_DEF(&G_DefaultButton), // common.c
CONTROL_DEF(&G_HelpButton), // common.c
END_TABLE
};
/*
* arcArchivesInitPage:
* notebook callback function (notebook.c) for the
* "Archives" page replacement in the Desktop's settings
* notebook.
* Sets the controls on the page according to the
* Global Settings.
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.9 (2001-04-07) [pr]: fixed Undo/Default
*@@changed V0.9.16 (2001-11-22) [umoeller]: now using dlg formatter
*/
VOID arcArchivesInitPage(PNOTEBOOKPAGE pnbp, // notebook info struct
ULONG flFlags) // CBI_* flags (notebook.h)
{
PARCHIVINGSETTINGS pArcSettings = arcQuerySettings();
if (flFlags & CBI_INIT)
{
// first call: backup archive settings for "Undo" button;
// this memory will be freed automatically by the
// common notebook window function (notebook.c) when
// the notebook page is destroyed
if (pnbp->pUser = malloc(sizeof(ARCHIVINGSETTINGS)))
memcpy(pnbp->pUser, pArcSettings, sizeof(ARCHIVINGSETTINGS));
// insert the controls using the dialog formatter
// V0.9.16 (2001-11-22) [umoeller]
ntbFormatPage(pnbp->hwndDlgPage,
dlgArchives,
ARRAYITEMCOUNT(dlgArchives));
WinSendDlgItemMsg(pnbp->hwndDlgPage, ID_XSDI_ARC_INI_SPIN,
SPBM_SETARRAY,
(MPARAM)&G_apcszPercentages,
(MPARAM)ARRAYITEMCOUNT(G_apcszPercentages));
}
if (flFlags & CBI_SET)
{
ULONG ul = 0;
winhSetDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_ENABLE,
(pArcSettings->ulArcFlags & ARCF_ENABLED) != 0);
winhSetDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_ALWAYS,
(pArcSettings->ulArcFlags & ARCF_ALWAYS) != 0);
winhSetDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_NEXT,
(pArcSettings->ulArcFlags & ARCF_NEXT) != 0);
winhSetDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_INI,
(pArcSettings->ulArcFlags & ARCF_INI) != 0);
// INI files percentage:
// go thru the spin button array and find
// percentage that matches
for (ul = 0; ul < ARRAYITEMCOUNT(G_apcszPercentages); ul++)
{
float dTemp;
// CHAR szTempx[100];
// convert current array item to float
sscanf(G_apcszPercentages[ul], "%f", &dTemp);
// same?
if (fabs(dTemp - pArcSettings->dIniFilesPercent) < 0.00001)
// prevent rounding errors
{
// yes: set this spin button array item
WinSendDlgItemMsg(pnbp->hwndDlgPage, ID_XSDI_ARC_INI_SPIN,
SPBM_SETCURRENTVALUE,
(MPARAM)ul,
(MPARAM)NULL);
break;
}
}
// every xxx days
winhSetDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_DAYS,
(pArcSettings->ulArcFlags & ARCF_DAYS) != 0);
winhSetDlgItemSpinData(pnbp->hwndDlgPage, ID_XSDI_ARC_DAYS_SPIN,
1, 50, // spin button limits
pArcSettings->ulEveryDays);
// status
winhSetDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_SHOWSTATUS,
pArcSettings->fShowStatus);
// no. of archives
arcSetNumArchives(&pArcSettings->cArchivesCount,
FALSE); // query
winhSetDlgItemSpinData(pnbp->hwndDlgPage, ID_XSDI_ARC_ARCHIVES_NO_SPIN,
1, 9, // spin button limits
pArcSettings->cArchivesCount);
}
if (flFlags & CBI_ENABLE)
{
BOOL fEnabled = ((pArcSettings->ulArcFlags & ARCF_ENABLED) != 0),
fAlways = ((pArcSettings->ulArcFlags & ARCF_ALWAYS) != 0),
fINI = winhIsDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_INI),
fDays = winhIsDlgItemChecked(pnbp->hwndDlgPage, ID_XSDI_ARC_DAYS);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_ALWAYS,
fEnabled);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_NEXT,
fEnabled && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_INI,
fEnabled && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_INI_SPIN,
( (fEnabled) && (fINI) ) && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_INI_SPINTXT1,
( (fEnabled) && (fINI) ) && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_DAYS,
fEnabled && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_DAYS_SPIN,
( (fEnabled) && (fDays) ) && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_DAYS_SPINTXT1,
( (fEnabled) && (fDays) ) && !fAlways);
WinEnableControl(pnbp->hwndDlgPage, ID_XSDI_ARC_SHOWSTATUS,
fEnabled);
}
}
/*
* arcArchivesItemChanged:
* notebook callback function (notebook.c) for the
* "Archives" page replacement in the Desktop's settings
* notebook.
* Reacts to changes of any of the dialog controls.
*
*@@added V0.9.0 [umoeller]
*@@changed V0.9.9 (2001-04-07) [pr]: fixed Undo/Default
*/
MRESULT arcArchivesItemChanged(PNOTEBOOKPAGE pnbp,
ULONG ulItemID,
USHORT usNotifyCode,
ULONG ulExtra) // for checkboxes: contains new state
{
PARCHIVINGSETTINGS pArcSettings = arcQuerySettings();
ULONG ulSetFlags = 0;
BOOL fSave = TRUE;
switch (ulItemID)
{
case ID_XSDI_ARC_ENABLE:
ulSetFlags |= ARCF_ENABLED;
break;
case ID_XSDI_ARC_ALWAYS:
ulSetFlags |= ARCF_ALWAYS;
break;
case ID_XSDI_ARC_NEXT:
ulSetFlags |= ARCF_NEXT;
break;
case ID_XSDI_ARC_INI:
ulSetFlags |= ARCF_INI;
break;
case ID_XSDI_ARC_INI_SPIN:
if ( (pnbp->flPage & NBFL_PAGE_INITED) // skip this during initialization
&& (usNotifyCode == SPBN_CHANGE)
)
{
CHAR szTemp[100];
float flTemp = 0;
// query current spin button array
// item as a string
WinSendDlgItemMsg(pnbp->hwndDlgPage, ulItemID,
SPBM_QUERYVALUE,
(MPARAM)szTemp,
MPFROM2SHORT(sizeof(szTemp),
SPBQ_ALWAYSUPDATE));
sscanf(szTemp, "%f", &flTemp);
pArcSettings->dIniFilesPercent = (double)flTemp;
}
break;
case ID_XSDI_ARC_DAYS:
ulSetFlags |= ARCF_DAYS;
break;
case ID_XSDI_ARC_DAYS_SPIN:
pArcSettings->ulEveryDays = winhAdjustDlgItemSpinData(pnbp->hwndDlgPage,
ulItemID,
0, // no grid
usNotifyCode);
break;
case ID_XSDI_ARC_SHOWSTATUS:
pArcSettings->fShowStatus = ulExtra;
break;
case ID_XSDI_ARC_ARCHIVES_NO_SPIN:
pArcSettings->cArchivesCount = (CHAR)winhAdjustDlgItemSpinData(pnbp->hwndDlgPage,
ulItemID,
0, // no grid
usNotifyCode);
arcSetNumArchives(&pArcSettings->cArchivesCount,
TRUE); // set
fSave = FALSE;
break;
case DID_UNDO:
{
// "Undo" button: get pointer to backed-up archive settings
PARCHIVINGSETTINGS pWASBackup = (PARCHIVINGSETTINGS)(pnbp->pUser);
// and restore the settings for this page
pArcSettings->ulArcFlags = pWASBackup->ulArcFlags;
pArcSettings->dIniFilesPercent = pWASBackup->dIniFilesPercent;
pArcSettings->ulEveryDays = pWASBackup->ulEveryDays;
pArcSettings->fShowStatus = pWASBackup->fShowStatus;
pArcSettings->cArchivesCount = pWASBackup->cArchivesCount;
arcSetNumArchives(&pArcSettings->cArchivesCount,
TRUE); // set
// update the display by calling the INIT callback
pnbp->inbp.pfncbInitPage(pnbp, CBI_SET | CBI_ENABLE);
}
break;
case DID_DEFAULT:
// set the default settings for this settings page
arcSetDefaultSettings();
arcSetNumArchives(&pArcSettings->cArchivesCount,
TRUE); // set
// update the display by calling the INIT callback
pnbp->inbp.pfncbInitPage(pnbp, CBI_SET | CBI_ENABLE);
break;
default:
fSave = FALSE;
}
if (ulSetFlags)
{
if (ulExtra) // checkbox checked
pArcSettings->ulArcFlags |= ulSetFlags;
else // checkbox unchecked
pArcSettings->ulArcFlags &= ~ulSetFlags;
// re-enable dlg items by calling the INIT callback
pnbp->inbp.pfncbInitPage(pnbp, CBI_ENABLE);
}
if (fSave)
// enable/disable items
arcSaveSettings();
return ((MPARAM)0);
}
/********************************************************************
*
* Archiving settings
*
********************************************************************/
/*
*@@ arcSetDefaultSettings:
* this initializes the global ARCHIVINGSETTINGS
* structure with default values.
*
*@@changed V0.9.9 (2001-04-07) [pr]: fixed Undo/Default
*/
VOID arcSetDefaultSettings(VOID)
{
#ifdef DEBUG_STARTUP
_Pmpf(("**** Settings defaults"));
#endif
G_ArcSettings.ulArcFlags = 0;
G_ArcSettings.dIniFilesPercent = .1;
G_ArcSettings.ulEveryDays = 1;
G_ArcSettings.fShowStatus = TRUE;
G_ArcSettings.cArchivesCount = 3;
}
/*
*@@ arcQuerySettings:
* this returns the global ARCHIVINGSETTINGS
* structure, which is filled with the data
* from OS2.INI if this is queried for the
* first time.
*
*@@changed V0.9.9 (2001-04-07) [pr]: fixed Undo/Default
*/
PARCHIVINGSETTINGS arcQuerySettings(VOID)
{
if (!G_fSettingsLoaded)
{
ULONG cbData = sizeof(G_ArcSettings);
BOOL brc = FALSE;
// first call:
G_fSettingsLoaded = TRUE;
// load settings
brc = PrfQueryProfileData(HINI_USER,
(PSZ)INIAPP_XWORKPLACE,
(PSZ)INIKEY_ARCHIVE_SETTINGS,
&G_ArcSettings,
&cbData);
if ((!brc) || cbData != sizeof(G_ArcSettings))
// data not found:
{
G_ArcSettings.dAppsSizeLast = 0;
G_ArcSettings.dKeysSizeLast = 0;
G_ArcSettings.dDataSumLast = 0;
arcSetDefaultSettings();
}
cbData = sizeof(G_dtLastArchived);
brc = PrfQueryProfileData(HINI_USER,
(PSZ)INIAPP_XWORKPLACE,
(PSZ)INIKEY_ARCHIVE_LASTBACKUP,
&G_dtLastArchived,
&cbData);
if ((!brc) || cbData != sizeof(G_dtLastArchived))
{
// data not found:
DosGetDateTime(&G_dtLastArchived);
G_dtLastArchived.year = 1990; // enfore backup then
}
// initialize szArcBaseFilename
sprintf(G_szArcBaseFilename,
"%c:\\OS2\\BOOT\\ARCHBASE.$$$",
doshQueryBootDrive());
}
return (&G_ArcSettings);
}
/*
*@@ arcSaveSettings:
* this writes the ARCHIVINGSETTINGS structure
* back to OS2.INI.
*/
BOOL arcSaveSettings(VOID)
{
return (PrfWriteProfileData(HINI_USER,
(PSZ)INIAPP_XWORKPLACE,
(PSZ)INIKEY_ARCHIVE_SETTINGS,
&G_ArcSettings,
sizeof(G_ArcSettings)));
}
/********************************************************************
*
* Archiving Enabling
*
********************************************************************/
/*
*@@ arcSetArchiveByte:
* writes byte "byte" to offset "offset" in ARCHBASE.$$$.
*
*@@added V0.9.13 (2001-06-14) [umoeller]
*/
APIRET arcSetArchiveByte(UCHAR byte, // in: byte to write
LONG offset)
{
APIRET arc = NO_ERROR;
// ULONG ulAttr;
// file is always write protected, so disable this
// before writing
if (!(arc = doshSetPathAttr(G_szArcBaseFilename,
FILE_ARCHIVED)))
{
// open the file for write access then
PXFILE pFile = NULL;
ULONG cb = 0;
if (!(arc = doshOpen(G_szArcBaseFilename,
XOPEN_READWRITE_EXISTING,
&cb,
&pFile)))
{
arc = doshWriteAt(pFile,
offset,
1,
&byte);
doshClose(&pFile);
}
doshSetPathAttr(G_szArcBaseFilename,
FILE_ARCHIVED | FILE_READONLY);
}
if (arc)
cmnLog(__FILE__, __LINE__, __FUNCTION__,
"Got error %d");
return arc;
}
/*
*@@ arcQueryArchiveByte:
* gets byte pointed to by "pByte" from offset "offset"
* in ARCHBASE.$$$.
*
*@@added V0.9.13 (2001-06-14) [umoeller]
*/
APIRET arcQueryArchiveByte(UCHAR *pByte, // out: read byte
LONG offset)
{
APIRET arc = NO_ERROR;
// open the file then
PXFILE pFile;
ULONG cbFile = 0;
if (!(arc = doshOpen(G_szArcBaseFilename,
XOPEN_READ_EXISTING,
&cbFile,
&pFile)))
{
ULONG cb = 1;
arc = doshReadAt(pFile,
offset,
&cb,
pByte,
0);
doshClose(&pFile);
}
if (arc)
cmnLog(__FILE__, __LINE__, __FUNCTION__,
"Got error %d");
return arc;
}
/*
*@@ arcForceNoArchiving:
* enforces that all archiving is disabled, both in
* XWP and the WPS.
*
*@@added V0.9.16 (2001-10-25) [umoeller]
*/
VOID arcForceNoArchiving(VOID)
{
// force loading of settings
arcQuerySettings();
arcSwitchArchivingOn(FALSE);
G_ArcSettings.ulArcFlags &= ~ARCF_ENABLED;
arcSaveSettings();
}
#define ID_XFDI_GENERICDLGTEXT 221
static CONTROLDEF
ArcStatusIcon = CONTROLDEF_ICON(
NULLHANDLE, // replaced below
ID_ICONDLG),
ArcStatusText = CONTROLDEF_TEXT_WORDBREAK(
"1\n2\n3", // room for three lines, replaced below
ID_XFDI_GENERICDLGTEXT,
200);
static const DLGHITEM dlgArcStatus[] =
{
START_TABLE, // root table, required
START_ROW(ROW_VALIGN_CENTER),
CONTROL_DEF(&ArcStatusIcon),
CONTROL_DEF(&ArcStatusText),
END_TABLE
};
/*
*@@ ShowStatus:
*
*@@added V0.9.16 (2001-11-25) [umoeller]
*/
static VOID ShowStatus(HWND hwndStatus,
PCSZ pcszText)
{
WinSetDlgItemText(hwndStatus, ID_XFDI_GENERICDLGTEXT,
pcszText);
WinSetWindowPos(hwndStatus,
HWND_TOP,
50,
50,
0,
0,
SWP_MOVE | SWP_ZORDER | SWP_SHOW);
// but no activate
}
/*
*@@ arcCheckIfBackupNeeded:
* this checks the system according to the settings
* in ARCHIVINGSETTINGS (i.e. always, next bootup,
* date, INI changes -- see arcCheckINIFiles),
* and calls arcSwitchArchivingOn according to the
* result of these checks.
*
* This gets called from initMain
* while the WPS is booting up (see remarks there).
* If we enable Desktop archiving here, the WPS will
* archive the Desktop soon afterwards.
*
* If (ARCHIVINGSETTINGS.fShowStatus == TRUE), hwndNotify
* will receive a msg with the value ulMsg and the
* HWND of the notification window in mp1 to be able
* to destroy it later.
*
* initMain sets this to the XWorkplace
* Thread-1 object window (krn_fnwpThread1Object), which in
* turn starts a timer to destroy the window later.
*
*@@changed V0.9.4 (2000-07-22) [umoeller]: archiving wasn't always disabled if turned off completely; fixed
*@@changed V0.9.13 (2001-06-14) [umoeller]: no longer using archive marker file, thanks Stefan Milcke
*@@changed V0.9.16 (2001-11-19) [umoeller]: now using dialog formatter for status window
*/
BOOL arcCheckIfBackupNeeded(HWND hwndNotify, // in: window to notify
ULONG ulMsg) // in: msg to post to hwndNotify
{
BOOL fBackup = FALSE,
fDisableArchiving = FALSE;
CHAR szTemp[300];
// force loading of settings
arcQuerySettings();
if (G_ArcSettings.ulArcFlags & ARCF_ENABLED)
{
HWND hwndStatus = NULLHANDLE;
XSTRING strMsg;
CHAR lRestoredArchiveNumber = 0;
xstrInit(&strMsg, 300);
if (G_ArcSettings.fShowStatus)
{
ArcStatusIcon.pcszText = (PCSZ)cmnQueryDlgIcon();
// format the status window
// V0.9.16 (2001-11-19) [umoeller]
dlghCreateDlg(&hwndStatus,
NULLHANDLE,
FCF_TITLEBAR | /* FCF_SYSMENU | */ FCF_DLGBORDER | FCF_NOBYTEALIGN,
WinDefDlgProc,
cmnGetString(ID_XFD_ARCHIVINGSTATUS),
dlgArcStatus,
ARRAYITEMCOUNT(dlgArcStatus),
NULL,
cmnQueryDefaultFont());
}
// changed V0.9.13 (2001-06-14) [umoeller]:
// get the "restored archive" byte
arcQueryArchiveByte(&lRestoredArchiveNumber,
ARCOFS_JUSTRESTORED);
if (lRestoredArchiveNumber)
{
// archive was just restored:
// disable archiving then
sprintf(szTemp,
cmnGetString(ID_XSSI_ARCRESTORED), // archive %d was restored
lRestoredArchiveNumber);
xstrcpy(&strMsg, szTemp, 0);
fBackup = FALSE;
fDisableArchiving = TRUE;
arcSetArchiveByte(0, ARCOFS_JUSTRESTORED);
} // end V0.9.13 (2001-06-14) [umoeller]
else
{
// no archive was just restored:
if (G_ArcSettings.ulArcFlags & ARCF_ALWAYS)
{
fBackup = TRUE;
if (G_ArcSettings.fShowStatus)
ShowStatus(hwndStatus,
cmnGetString(ID_XSSI_ARCENABLED));
}
else
{
BOOL fCheckINIs = (G_ArcSettings.ulArcFlags & ARCF_INI);
if (G_ArcSettings.ulArcFlags & ARCF_NEXT)
{
if (G_ArcSettings.fShowStatus)
ShowStatus(hwndStatus,
cmnGetString(ID_XSSI_ARCENABLEDONCE));
fBackup = TRUE;
fCheckINIs = FALSE; // not necessary
// unset this settings flag for next time
G_ArcSettings.ulArcFlags &= ~ARCF_NEXT;
arcSaveSettings();
}
else if (G_ArcSettings.ulArcFlags & ARCF_DAYS)
{
// days-based:
DATETIME dtNow;
LONG lDaysNow,
lDaysLast,
lDaysPassed;
DosGetDateTime(&dtNow);
lDaysNow = dtDate2Scalar(dtNow.year,
dtNow.month,
dtNow.day);
lDaysLast= dtDate2Scalar(G_dtLastArchived.year,
G_dtLastArchived.month,
G_dtLastArchived.day);
lDaysPassed = lDaysNow - lDaysLast;
if (lDaysPassed >= G_ArcSettings.ulEveryDays)
{
fBackup = TRUE;
fCheckINIs = FALSE; // not necessary
}
if (G_ArcSettings.fShowStatus)
{
sprintf(szTemp,
cmnGetString(ID_XSSI_ARCDAYSPASSED), // "%d days passed since last backup." // pszArcDaysPassed
lDaysPassed);
xstrcpy(&strMsg, szTemp, 0);
xstrcatc(&strMsg, '\n');
sprintf(szTemp,
cmnGetString(ID_XSSI_ARCDAYSLIMIT), // "Limit: %d days." // pszArcDaysLimit
G_ArcSettings.ulEveryDays);
xstrcat(&strMsg, szTemp, 0);
xstrcatc(&strMsg, '\n');
}
}
if (fCheckINIs)
{
// INI-based:
double dMaxDifferencePercent = 0;
if (G_ArcSettings.fShowStatus)
{
sprintf(szTemp,
"%s\n",
cmnGetString(ID_XSSI_ARCINICHECKING)) ; // pszArcINIChecking
ShowStatus(hwndStatus,
szTemp);
}
fBackup = arcCheckINIFiles(&G_ArcSettings.dIniFilesPercent,
(PSZ)INIAPP_XWORKPLACE, // ignore this
&G_ArcSettings.dAppsSizeLast,
&G_ArcSettings.dKeysSizeLast,
&G_ArcSettings.dDataSumLast,
&dMaxDifferencePercent);
if (G_ArcSettings.fShowStatus)
{
sprintf(szTemp,
cmnGetString(ID_XSSI_ARCINICHANGED), // "INI files changed %f %%", // pszArcINIChanged
dMaxDifferencePercent);
xstrcpy(&strMsg, szTemp, 0);
xstrcatc(&strMsg, '\n');
sprintf(szTemp,
cmnGetString(ID_XSSI_ARCINILIMIT), // "Limit: %f %%." // pszArcINILimit
G_ArcSettings.dIniFilesPercent);
xstrcat(&strMsg, szTemp, 0);
xstrcatc(&strMsg, '\n');
}
} // end if (fCheckINIs)
} // end else if (G_ArcSettings.ulArcFlags & ARCF_ALWAYS)
} // else if (fWasJustRestored)
if (strMsg.ulLength)
{
if (G_ArcSettings.fShowStatus)
{
if (fBackup)
{
// archiving to be turned on:
// save "last app" etc. data so we won't get this twice
arcSaveSettings();
xstrcat(&strMsg,
cmnGetString(ID_XSSI_ARCENABLED), // "Desktop archiving enabled"
0);
}
else
xstrcat(&strMsg,
cmnGetString(ID_XSSI_ARCNOTNECC), // "Desktop archiving not necessary"
0);
ShowStatus(hwndStatus,
strMsg.psz);
}
}
xstrClear(&strMsg);
if (G_ArcSettings.fShowStatus)
WinPostMsg(hwndNotify, ulMsg, (MPARAM)hwndStatus, (MPARAM)NULL);
}
arcSwitchArchivingOn(fBackup); // moved V0.9.4 (2000-07-22) [umoeller]
if (fDisableArchiving)
{
G_ArcSettings.ulArcFlags &= ~ARCF_ENABLED;
arcSaveSettings();
cmnMessageBoxExt(NULLHANDLE,
116,
NULL, 0,
188,
MB_OK);
}
return (fBackup);
}
/*
*@@ arcSwitchArchivingOn:
* depending on fSwitchOn, this switches Desktop archiving on or off
* by manipulating the \OS2\BOOT\ARCHBASE.$$$ file.
*
* In addition, this stores the date of the last archive in OS2.INI
* and creates a file on the desktop to mark this as an archive.
*
* This should only be called by arcCheckIfBackupNeeded.
*
*@@changed V0.9.13 (2001-06-14) [umoeller]: optimized
*@@changed V0.9.13 (2001-06-14) [smilcke]: when archiving is switched on we have to clear the restore flag
*/
APIRET arcSwitchArchivingOn(BOOL fSwitchOn)
{
APIRET arc = NO_ERROR;
if (fSwitchOn)
{
if (!(arc = arcSetArchiveByte(1, ARCOFS_ARCHIVINGENABLED)))
{
// reset the restore flag V0.9.13 (2001-06-14) [smilcke]
arc = arcSetArchiveByte(0, ARCOFS_JUSTRESTORED);
#ifdef DEBUG_STARTUP
_Pmpf(("WPS Archiving activated"));
#endif
// store date of backup in OS2.INI
DosGetDateTime(&G_dtLastArchived);
PrfWriteProfileData(HINI_USER,
(PSZ)INIAPP_XWORKPLACE,
(PSZ)INIKEY_ARCHIVE_LASTBACKUP,
&G_dtLastArchived,
sizeof(G_dtLastArchived));
}
}
else
{
arc = arcSetArchiveByte(0, ARCOFS_ARCHIVINGENABLED);
#ifdef DEBUG_STARTUP
_Pmpf(("WPS Archiving deactivated"));
#endif
}
if (arc)
cmnLog(__FILE__, __LINE__, __FUNCTION__,
"Got error %d");
return arc;
}
/*
*@@ arcSetNumArchives:
* queries or sets the maximum no. of archives
* which are maintained by the WPS.
*
* If (fSet == TRUE), the number of archives is set
* to *pcArchives. This must be > 0 and < 10, otherwise
* FALSE is returned.
*
* If (fSet == FALSE), the current number of archives
* is queried and written into *pcArchives, but not
* changed.
*
*@@changed V0.9.12 (2001-05-24) [smilcke]: code optimized to use arcSetByte/arcGetByte
*/
BOOL arcSetNumArchives(PCHAR pcArchives, // in/out: number of archives
BOOL fSet) // if TRUE, archive number is set
{
BOOL brc = FALSE;
if (pcArchives)
if ( (fSet)
&& ( (*pcArchives < 0)
|| (*pcArchives > 9)
)
)
{
brc = FALSE;
}
else
{
CHAR cArchives = 0;
arcQueryArchiveByte(&cArchives,
ARCOFS_MAXARCHIVES);
if (fSet)
arcSetArchiveByte(*pcArchives,
ARCOFS_MAXARCHIVES);
*pcArchives = cArchives;
}
return brc;
}
/*
*@@ arcCheckINIFiles:
* this function goes thru both OS2.INI and OS2SYS.INI and
* checks for changes. This gets called from arcCheckIfBackupNeeded.
*
* To find this out, we check the following data:
* -- the size of the applications list;
* -- the size of the keys list;
* -- the actual profile data, for which all values are summed up.
*
* If any of these values differs more than cPercent from the old
* data passed to this function, we update that data and return TRUE,
* which means that Desktop archiving should be turned on.
*
* Otherwise FALSE is returned, and the data is not changed.
*
* In any case, *pcMaxDifferencePercent is set to the maximum
* percentage of difference which was computed.
*
* If (cPercent == 0), all data is checked for, and TRUE is always
* returned. This might be useful for retrieving the "last app" etc.
* data once.
*
* NOTE: It is the responsibility of the caller to save the
* old data somewhere. This function does _not_ check the
* INI files.
*
* Set pszIgnoreApp to any INI application which should be ignored
* when checking for changes. This is useful if the "last app" etc.
* data is stored in the profiles too. If (pszIgnoreApp == NULL),
* all applications are checked for.
*/
BOOL arcCheckINIFiles(double* pdPercent,
PSZ pszIgnoreApp, // in: this application will not be checked
double* pdAppsSizeLast,
double* pdKeysSizeLast,
double* pdDataSumLast,
double* pdMaxDifferencePercent) // out: maximum difference found
{
BOOL brc = FALSE; // return value
double dDataSum = 0,
dTotalAppsSize = 0,
dTotalKeysSize = 0;
double dMaxDifferencePercent = 0;
// 1) Applications loop
APIRET arc;
PSZ pszAppsList = NULL;
#ifdef DEBUG_STARTUP
_Pmpf(("Checking INI files"));
#endif
if (!(arc = prfhQueryKeysForApp(HINI_PROFILE, // both OS2.INI and OS2SYS.INI
NULL, // return applications
&pszAppsList)))
{
PSZ pApp2 = pszAppsList;
while (*pApp2 != 0)
{
BOOL fIgnore = FALSE;
// pApp2 has the current app now
// ignore this app?
if (pszIgnoreApp)
if (!strcmp(pszIgnoreApp, pApp2))
fIgnore = TRUE;
if (!fIgnore)
{
// 2) keys loop for this app
PSZ pszKeysList = NULL;
if (!(arc = prfhQueryKeysForApp(HINI_PROFILE, // both OS2.INI and OS2SYS.INI
pApp2, // return keys
&pszKeysList)))
{
PSZ pKey2 = pszKeysList;
while (*pKey2 != 0)
{
// pKey2 has the current key now
// 3) get key data
ULONG cbData = 0;
PSZ pszData = prfhQueryProfileData(HINI_PROFILE,
pApp2,
pKey2,
&cbData);
if (pszData)
{
// sum up all values
PSZ p = pszData;
ULONG ul = 0;
for (ul = 0;
ul < cbData;
ul++, p++)
dDataSum += (double)*p;
free(pszData);
}
pKey2 += strlen(pKey2)+1; // next key
} // end while (*pKey2 != 0)
// add size of keys list to total size
dTotalKeysSize += (pKey2 - pszKeysList);
free(pszKeysList);
} // end if (pszKeysList)
} // end if (!fIgnore)
pApp2 += strlen(pApp2)+1; // next app
} // end while (*pApp2 != 0)
// add size of apps list to total size
dTotalAppsSize += (pApp2 - pszAppsList);
free(pszAppsList);
} // end if (pszAppsList)
if (*pdPercent != 0)
{
#ifdef DEBUG_STARTUP
CHAR szTemp[1000];
_Pmpf(("Last, now"));
sprintf(szTemp, "Apps size: %f, %f", *pdAppsSizeLast, dTotalAppsSize);
_Pmpf(("%s", szTemp));
sprintf(szTemp, "Keys size: %f, %f", *pdKeysSizeLast, dTotalKeysSize);
_Pmpf(("%s", szTemp));
sprintf(szTemp, "Data sum: %f, %f", *pdDataSumLast, dDataSum);
_Pmpf(("%s", szTemp));
#endif
if ((*pdAppsSizeLast) && (dTotalAppsSize))
{
// if so, check if more than the given percentage of application strings
// where modified
double dPercentThis =
fabs(dTotalAppsSize - *pdAppsSizeLast) // difference (we need fabs, abs returns 0 always)
* 100 // in percent
/ *pdAppsSizeLast;
#ifdef DEBUG_STARTUP
sprintf(szTemp, "%f", dPercentThis);
_Pmpf(("dPercent Apps: %s", szTemp));
#endif
if (dPercentThis > *pdPercent)
{
// yes: store new value (for later writing to log-file)
// and switch archiving on
*pdAppsSizeLast = dTotalAppsSize;
brc = TRUE;
}
if (dPercentThis > dMaxDifferencePercent)
dMaxDifferencePercent = dPercentThis;
}
// same logic for keys size
if ((*pdKeysSizeLast) && (dTotalKeysSize))
{
double dPercentThis =
fabs(dTotalKeysSize - *pdKeysSizeLast) // difference (we need fabs, abs returns 0 always)
* 100 // in percent
/ *pdKeysSizeLast;
#ifdef DEBUG_STARTUP
sprintf(szTemp, "%f", dPercentThis);
_Pmpf(("dPercent Keys: %s", szTemp));
#endif
if (dPercentThis > *pdPercent)
{
// yes: store new value (for later writing to log-file)
// and switch archiving on
*pdKeysSizeLast = dTotalKeysSize;
brc = TRUE;
}
if (dPercentThis > dMaxDifferencePercent)
dMaxDifferencePercent = dPercentThis;
}
// same logic for profile data
if ((*pdDataSumLast) && (dDataSum))
{
double dPercentThis =
fabs(dDataSum - *pdDataSumLast) // difference (we need fabs, abs returns 0 always)
* 100 // in percent
/ *pdDataSumLast;
#ifdef DEBUG_STARTUP
sprintf(szTemp, "%f", dPercentThis);
_Pmpf(("dPercent Data: %s", szTemp));
#endif
if (dPercentThis > *pdPercent)
{
// yes: store new value (for later writing to log-file)
// and switch archiving on
*pdDataSumLast = dDataSum;
brc = TRUE;
}
if (dPercentThis > dMaxDifferencePercent)
dMaxDifferencePercent = dPercentThis;
}
if (pdMaxDifferencePercent)
*pdMaxDifferencePercent = dMaxDifferencePercent;
} // end if (cPercent)
// check if any size is 0 so the values MUST be written and archiving MUST
// be switched on
if (!*pdAppsSizeLast || !*pdKeysSizeLast || !*pdDataSumLast)
{
*pdAppsSizeLast = dTotalAppsSize;
*pdKeysSizeLast = dTotalKeysSize;
*pdDataSumLast = dDataSum;
brc = TRUE;
}
#ifdef DEBUG_STARTUP
_Pmpf((" Done checking INI files, returning %d", brc));
#endif
return brc;
}