182 lines
5.3 KiB
C
182 lines
5.3 KiB
C
|
//*** CUACount -- user-assistance counter w/ decay
|
||
|
//
|
||
|
#define XXX_DELETE 1
|
||
|
#define XXX_VERSIONED 0
|
||
|
|
||
|
//*** NRW -- named i/o
|
||
|
// DESCRIPTION
|
||
|
// i/o to a 'named' location (e.g. registry)
|
||
|
typedef struct {
|
||
|
void *self;
|
||
|
LPCTSTR pszName;
|
||
|
} NRWINFO, *PNRWINFO;
|
||
|
|
||
|
typedef HRESULT (*PFNNRW)(void *pvBuf, DWORD cbBuf, PNRWINFO prwi);
|
||
|
typedef struct {
|
||
|
PFNNRW _pfnRead;
|
||
|
PFNNRW _pfnWrite;
|
||
|
PFNNRW _pfnDelete;
|
||
|
} FNNRW3, *PFNNRW3;
|
||
|
|
||
|
//*** UAQ_* -- quantum
|
||
|
// NOTES
|
||
|
// todo: for now everything is flat
|
||
|
typedef enum {
|
||
|
UAQ_TASK=0,
|
||
|
UAQ_DOC=0,
|
||
|
UAQ_APP=0,
|
||
|
UAQ_SESSION=0
|
||
|
} UAQUANTUM;
|
||
|
#define UAQ_DEFAULT UAQ_SESSION // currently implemented quanta
|
||
|
#define UAQ_COUNT (UAQ_SESSION + 1)
|
||
|
|
||
|
typedef DWORD UATIME; // 1 minute (approx)
|
||
|
|
||
|
#define UAT_MINUTE1 ((UATIME)1) // 1 minute
|
||
|
#define UAT_HOUR12 ((UATIME)(12 * 60)) // 12 hours (see FTToUATime)
|
||
|
|
||
|
extern UATIME GetUaTime(LPSYSTEMTIME pst);
|
||
|
|
||
|
//*** UATTOMSEC -- convert UATIME to mSec's
|
||
|
// NOTES
|
||
|
// ISSUE: we should be more accurate. currently we just assume a UATIME
|
||
|
// is exactly 1 minute, which it's not... easy enough to do, but we'll
|
||
|
// wait until i have time to do the math.
|
||
|
#define UATTOMSEC(uat) ((uat) * 60 * 1000)
|
||
|
|
||
|
class IUASession
|
||
|
{
|
||
|
public:
|
||
|
virtual void SetSession(UAQUANTUM uaq, BOOL fForce) PURE;
|
||
|
virtual int GetSessionId() PURE;
|
||
|
};
|
||
|
|
||
|
class CUASession : public IUASession
|
||
|
{
|
||
|
struct SUASession {
|
||
|
#if XXX_VERSIONED
|
||
|
UINT _cbSize;
|
||
|
#endif
|
||
|
UATIME _qtMru;
|
||
|
int _cCnt;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
void SetSession(UAQUANTUM uaq, BOOL fForce);
|
||
|
int GetSessionId();
|
||
|
|
||
|
CUASession(); // n.b. public so can stack-alloc
|
||
|
HRESULT Initialize();
|
||
|
HRESULT LoadFrom(PFNNRW3 pfnIO, PNRWINFO pRwi);
|
||
|
HRESULT SaveTo(BOOL fForce, PFNNRW3 pfnIO, PNRWINFO pRwi);
|
||
|
|
||
|
protected:
|
||
|
// for xfers directly into me w/o an extra copy-ctor
|
||
|
// e.g. p->QueryValue(pszName, aUac.GetRawData(), &cb);
|
||
|
// e.g. p->SetValue (pszName, aUac.GetRawData(), aUac.GetRawCount());
|
||
|
_inline BYTE * _GetRawData() { return (BYTE *)&_qtMru; };
|
||
|
_inline DWORD _GetRawCount() { return SIZEOF(SUASession); };
|
||
|
|
||
|
//struct SUASession {
|
||
|
#if XXX_VERSIONED
|
||
|
UINT _cbSize;
|
||
|
#endif
|
||
|
UATIME _qtMru;
|
||
|
int _cCnt;
|
||
|
//};
|
||
|
|
||
|
BITBOOL _fInited : 1; // 1:we've been initialized
|
||
|
BITBOOL _fDirty : 1; // 1:save me (e.g. _sidMru was xformed)
|
||
|
};
|
||
|
|
||
|
// all special values are < 0 for easy check
|
||
|
#define SID_SNOWREAD (-1) // like SID_SNOWINIT, but no auto-save
|
||
|
#define SID_SNOWINIT (-2) // convert to 'now' on 1st read
|
||
|
#define SID_SNOWALWAYS (-3) // always 'now'
|
||
|
|
||
|
#define ISSID_SSPECIAL(s) ((int)(s) < 0)
|
||
|
|
||
|
// tunable values for IncCount (talk to your neighborhood PM)
|
||
|
#define UAC_NEWCOUNT 2 // brand-new count starts from here
|
||
|
#define UAC_MINCOUNT 6 // incr to a minimum of this
|
||
|
|
||
|
class CUACount
|
||
|
{
|
||
|
// must match CUACount semi-embedded struct
|
||
|
struct SUACount
|
||
|
{
|
||
|
#define UAC_d0 _sidMruDisk
|
||
|
#if XXX_VERSIONED
|
||
|
#undef UAC_d0
|
||
|
#define UAC_d0 _cbSize
|
||
|
UINT _cbSize;
|
||
|
#endif
|
||
|
UINT _sidMruDisk; // MRU for this entry
|
||
|
// todo: eventually we'll want task,doc,app,session
|
||
|
// so this will be _cCnt[UAQ_COUNT], and we'll index by _cCnt[quanta]
|
||
|
int _cCnt; // use count (lazily decayed)
|
||
|
FILETIME _ftExecuteTime;
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
CUACount(); // n.b. public so can stack-alloc
|
||
|
HRESULT Initialize(IUASession *puas);
|
||
|
HRESULT LoadFrom(PFNNRW3 pfnIO, PNRWINFO pRwi);
|
||
|
HRESULT SaveTo(BOOL fForce, PFNNRW3 pfnIO, PNRWINFO pRwi);
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
BOOL DBIsInit();
|
||
|
#endif
|
||
|
int GetCount();
|
||
|
void IncCount();
|
||
|
void AddCount(int i);
|
||
|
void SetCount(int cCnt);
|
||
|
void UpdateFileTime();
|
||
|
FILETIME GetFileTime();
|
||
|
void SetFileTime(const FILETIME *pft);
|
||
|
|
||
|
// most people should *not* call these
|
||
|
void _SetMru(UINT sidMru) { _sidMruDisk = sidMru; Initialize(_puas); };
|
||
|
int _GetCount() { return _cCnt; };
|
||
|
#if XXX_DELETE
|
||
|
DWORD _SetFlags(DWORD dwMask, DWORD dwValue);
|
||
|
#define UACF_INHERITED 0x01
|
||
|
#define UACF_NODECAY 0x02
|
||
|
#endif
|
||
|
|
||
|
protected:
|
||
|
int _DecayCount(BOOL fWrite);
|
||
|
UINT _ExpandSpecial(UINT sidMru);
|
||
|
|
||
|
// for xfers directly into me w/o an extra copy-ctor
|
||
|
// e.g. p->QueryValue(pszName, aUac.GetRawData(), &cb);
|
||
|
// e.g. p->SetValue (pszName, aUac.GetRawData(), aUac.GetRawCount());
|
||
|
_inline BYTE * _GetRawData() { return (BYTE *)&UAC_d0; };
|
||
|
_inline DWORD _GetRawCount() { return SIZEOF(SUACount); };
|
||
|
|
||
|
// struct SUACount {
|
||
|
#if XXX_VERSIONED
|
||
|
UINT _cbSize; // SIZEOF
|
||
|
#endif
|
||
|
UINT _sidMruDisk; // MRU for this entry
|
||
|
// todo: eventually we'll want task,doc,app,session
|
||
|
// so this will be cCnt[UAQ_COUNT], and we'll index by cCnt[quanta]
|
||
|
int _cCnt; // use count (lazily decayed)
|
||
|
FILETIME _ftExecuteTime;
|
||
|
// }
|
||
|
UINT _sidMru; // MRU for this entry
|
||
|
|
||
|
IUASession * _puas; // session callback
|
||
|
BITBOOL _fInited : 1; // 1:we've been initialized
|
||
|
BITBOOL _fDirty : 1; // 1:save me (e.g. _sidMru was xformed)
|
||
|
#if XXX_DELETE
|
||
|
BITBOOL _fInherited : 1; // 1:we didn't exist
|
||
|
#else
|
||
|
BITBOOL _fUnused : 1;
|
||
|
#endif
|
||
|
BITBOOL _fNoDecay : 1; // 1:don't decay me
|
||
|
BITBOOL _fNoPurge : 1; // 1:don't auto-delete me (debug)
|
||
|
|
||
|
private:
|
||
|
};
|