|
|
/*
** wcsutil.h ** Sean P. Nolan ** ** server-side utils */
#ifndef _WCSUTIL_H_
#define _WCSUTIL_H_
#include <windows.h>
#include <ole2.h>
#include <winsock.h>
#include <httpext.h>
#include "wcguids.h"
/*--------------------------------------------------------------------------+
| Utilities Provided by the Framework | +--------------------------------------------------------------------------*/
extern LPSTR g_szSSOProgID;
// Logging to application event log -- see ReportEvent() in win32 sdk
// documentation for information on wType and dwEventID.
void LogEvent(WORD wType, DWORD dwEventID, char *sz);
// Asserts
#ifdef DEBUG
extern void AssertProc(PCSTR szFile, DWORD dwLine, PCSTR szMsg, DWORD dwFlags); #define AssertSzFlg(f, sz, dwFlag) ( (f) ? 0 : AssertProc(__FILE__, __LINE__, sz, dwFlag))
#else // !DEBUG
#define AssertSzFlg(f, sz, dwFlg)
#endif // !DEBUG
#define AP_GETLASTERROR 0x00000001
// under non-debug, AssertSzFlg is defined away, so these #defines don't
// have to be #ifdef DEBUG
#define AssertSz(f, sz) AssertSzFlg(f, sz, 0)
#define AssertEx(f) AssertSz((f), "!(" #f ")")
#define Assert(f) AssertEx(f)
#define AssertSzGLE(f, sz) AssertSzFlg(f, sz, AP_GETLASTERROR)
#define AssertExGLE(f) AssertSzGLE((f), "!(" #f ")")
// Debug Printing
#ifdef DEBUG
int dbgprintf(PCSTR pFormat, ...); #else
#define dbgprintf()
#endif
// Memory Mgmt
LPVOID _MsnAlloc(DWORD cb); LPVOID _MsnRealloc(LPVOID pv, DWORD cb); void _MsnFree(LPVOID pv);
// Data Munging
LPSTR _SzFromVariant(VARIANT *pvar); BSTR _BstrFromVariant(VARIANT *pvar, BOOL *pfFree); BOOL _FIntFromVariant(VARIANT *pvar, int *pi);
BSTR BstrQuoteHtml(WCHAR *wsz); BSTR BstrQuoteForUrl(WCHAR *wsz); void UnquoteHtml(WCHAR *wszSrc, WCHAR *rgchDst, int cchDst);
// String Manipulation / Parsing
void _AnsiStringFromGuid(REFGUID rguid, LPSTR sz); LPSTR _SkipWhiteSpace(LPSTR sz); LPSTR _FindEndOfLine(LPSTR sz); DWORD _atoi(LPSTR sz);
// URL Fiddling
int UrlType(char *szUrl); #define URL_TYPE_ABSOLUTE 0 // e.g. http://foo/bar or just //foo.com/bar.htm
#define URL_TYPE_LOCAL_ABSOLUTE 1 // e.g. /foo/bar/baz.htm
#define URL_TYPE_RELATIVE 2 // e.g. xyzzy/plugh.html
// IIS Hacks
#ifdef _HTTPEXT_H_
BOOL _FTranslateVirtualRoot(EXTENSION_CONTROL_BLOCK *pecb, LPSTR szPathIn, LPSTR szPathTranslated, DWORD cbPathTranslated); #endif // _HTTPEXT_H_
// Critical Sections
class CCritSec { private: CRITICAL_SECTION m_cs;
public: CCritSec(void) { ::InitializeCriticalSection(&m_cs); } ~CCritSec(void) { ::DeleteCriticalSection(&m_cs); } void Lock(void) { ::EnterCriticalSection(&m_cs); } void Unlock(void) { ::LeaveCriticalSection(&m_cs); } };
/*--------------------------------------------------------------------------+
| CThingWatcher/CFileWatcher/CRegKeyWatcher | +--------------------------------------------------------------------------*/
typedef void (*PFNFILECHANGED)(LPSTR szFile, LONG lUser); typedef void (*PFNREGKEYCHANGED)(HKEY hkey, LONG lUser);
typedef int (__stdcall *PFNCLOSEHEVTNOTIFY)(HANDLE hevtNotify);
class CThingWatcher { friend DWORD ThingWatcherThread(CThingWatcher *pfw);
public: CThingWatcher(PFNCLOSEHEVTNOTIFY pfnCloseHevtNotify); ~CThingWatcher(); BOOL FWatchHandle(HANDLE hevtNotify);
private: virtual BOOL FireChange(DWORD dwWait) = 0;
HANDLE m_rghWait[2]; HINSTANCE m_hModule; PFNCLOSEHEVTNOTIFY m_pfnCloseHevtNotify; };
class CFileWatcher : public CThingWatcher { private: char m_szPath[MAX_PATH]; FILETIME m_ftLastWrite; LONG m_lUser; PFNFILECHANGED m_pfnChanged; BOOL m_fDirectory; HANDLE m_hevtNotify;
public: CFileWatcher(void); ~CFileWatcher(void);
BOOL FStartWatching(LPSTR szPath, LONG lUser, PFNFILECHANGED pfnChanged);
private: virtual BOOL FireChange(DWORD dwWait); }; class CRegKeyWatcher : public CThingWatcher { public: CRegKeyWatcher(); ~CRegKeyWatcher();
BOOL FStartWatching(HKEY hkey, BOOL fSubTree, DWORD dwNotifyFilter, LONG lUser, PFNREGKEYCHANGED pfnChanged);
private: virtual BOOL FireChange(DWORD dwWait); HKEY m_hkey; LONG m_lUser; PFNREGKEYCHANGED m_pfnChanged; HANDLE m_hevtNotify; };
/*--------------------------------------------------------------------------+
| CDataFile | +--------------------------------------------------------------------------*/
class CDataFile { friend class CDataFileGroup; friend void DataFileChanged(LPSTR szFile, LONG lUser);
private: ULONG m_cRef;
CDataFile *m_pdfNext; CDataFile *m_pdfPrev; CDataFileGroup *m_pfg;
protected: CCritSec m_cs; char m_szDataPath[MAX_PATH]; CFileWatcher m_fw;
public: CDataFile(LPSTR szDataPath, CDataFileGroup *pfg); ~CDataFile(void);
ULONG AddRef(void); ULONG Release(void);
BOOL FWatchFile(PFNFILECHANGED pfnChanged = NULL);
virtual void FreeDataFile(void) { delete this; }
private: ULONG GetRefCount(void); BOOL FMatch(LPSTR szDataPath);
CDataFile *GetNext(void) { return(m_pdfNext); } CDataFile *GetPrev(void) { return(m_pdfPrev); } void SetNext(CDataFile *pdf) { m_pdfNext = pdf; } void SetPrev(CDataFile *pdf) { m_pdfPrev = pdf; } };
/*--------------------------------------------------------------------------+
| CDataFileGroup | +--------------------------------------------------------------------------*/
#define NUM_GROUP_BUCKETS (1024)
typedef struct _HashBucket { CDataFile *pdfHead; CDataFile *pdfTail; } HB;
class CDataFileGroup { private: CCritSec m_cs; HB m_rghb[NUM_GROUP_BUCKETS]; public: CDataFileGroup(void); ~CDataFileGroup(void);
CDataFile *GetDataFile(LPSTR szDataPath); void ForgetDataFile(CDataFile *pdf);
virtual CDataFile *CreateDataFile(LPSTR szDataPath) = 0;
private: void RememberDataFile(CDataFile *pdf, HB *phb = NULL); HB *GetHashBucket(LPSTR szDataPath); }; /*--------------------------------------------------------------------------+
| CGenericHash | +--------------------------------------------------------------------------*/
typedef struct _HashItem { BSTR bstrName; LPVOID pvData; struct _HashItem *phiNext; struct _HashItem *phiPrev; } HITEM;
class CGenericHash { protected: DWORD m_chi; HITEM **m_rgphi; CCritSec m_cs;
public: CGenericHash(DWORD cBuckets); ~CGenericHash(void);
LPVOID PvFind(OLECHAR *wszName);
BOOL FAdd(OLECHAR *wszName, LPVOID pv); void Remove(OLECHAR *wszName); void RemoveAll(void);
void Lock(void) { m_cs.Lock(); } void Unlock(void) { m_cs.Unlock(); }
virtual DWORD GetHashValue(OLECHAR *wsz); virtual void FreeHashData(LPVOID pv);
private: HITEM *FindItem(OLECHAR *wszName, HITEM ***ppphiHead); void RemoveItem(HITEM **pphiHead, HITEM *phi); BOOL FEnsureBuckets(void); };
/*--------------------------------------------------------------------------+
| CResourceCollection | +--------------------------------------------------------------------------*/
typedef struct _resource { BOOL fInUse; BOOL fValid; PVOID pv; } RS, *PRS;
typedef PRS HRS; #define hrsNil NULL
class CResourceCollection { public: CResourceCollection(); ~CResourceCollection(); BOOL FInit(int cRsrc); BOOL FTerm(); HRS HrsGetResource(); void ReleaseResource(BOOL fReset, HRS hrs);
void CleanupAll(PVOID pvNil); BOOL FValid(HRS hrs);
private: PRS PrsFree(); void WaitForRs();
CCritSec m_cs; HANDLE m_hsem; int m_crs; PRS m_rgrs;
virtual BOOL FInitResource(PRS prs) = 0; virtual void CleanupResource(PRS prs) = 0; };
/*--------------------------------------------------------------------------+
| CSocketCollection | +--------------------------------------------------------------------------*/
class CSocketCollection : public CResourceCollection { public: CSocketCollection() : CResourceCollection() {}; ~CSocketCollection() {}; BOOL FInit(int cRsrc, char *szServer, USHORT usPort); // usPort should be in host byte order
BOOL FReinit(char *szServer, USHORT usPort); SOCKET ScFromHrs(HRS hrs); private: char m_szServer[MAX_PATH]; int m_usPort; SOCKADDR_IN m_sin;
virtual BOOL FInitResource(PRS prs); virtual void CleanupResource(PRS prs); };
#endif // _WCSUTIL_H_
|