|
|
/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
certnotf.hxx
Abstract:
Definitions and data structures needed to deal with cert store change notifications
Author:
Alex Mallet (amallet) 17-Dec-1997
--*/
#ifndef _CERTNOTF_HXX_
#define _CERTNOTF_HXX_
#if !defined( dllexp)
#define dllexp __declspec( dllexport)
#endif // !defined( dllexp)
typedef VOID (*NOTIFFNCPTR) ( LPVOID pvParam ) ; #define INVALID_FNC_PTR (-1)
//
// Define signatures "backwards" so they read the right way around in debugger
//
#define NOTIFIER_GOOD_SIG (DWORD) 'FTON'
#define NOTIFIER_BAD_SIG (DWORD) 'fton'
#define STORE_ENTRY_GOOD_SIG (DWORD) 'EHCS'
#define STORE_ENTRY_BAD_SIG (DWORD) 'ehcs'
class STORE_CHANGE_NOTIFIER;
//
// Link in linked list containing notification functions to be called
//
typedef struct _NotifFncChainEntry { NOTIFFNCPTR pNotifFnc; //pointer to function
LPVOID pvParam; //parameter for function
LIST_ENTRY ListEntry; } NOTIF_FNC_CHAIN_ENTRY, *PNOTIF_FNC_CHAIN_ENTRY;
//
// Class containing data for each store being watched
//
class STORE_CHANGE_ENTRY {
public:
STORE_CHANGE_ENTRY( STORE_CHANGE_NOTIFIER *pNotifier, LPSTR pszStoreName, HCERTSTORE hStore, NOTIFFNCPTR pFncPtr, PVOID pvParam );
~STORE_CHANGE_ENTRY();
//
// For functions that return variables that can't be changed after the initial construction
// of the object, there are no calls to Lock()/Unlock() because all callers will
// get the same [valid] value
//
DWORD GetLastError() { DWORD dwError = 0; Lock(); dwError = m_dwError; Unlock(); return dwError; }
BOOL CheckSignature() { DWORD dwSig = 0; Lock(); dwSig = m_dwSignature; Unlock(); return ( dwSig == STORE_ENTRY_GOOD_SIG ? TRUE : FALSE ); }
BOOL ContainsNotifFnc( NOTIFFNCPTR pFncPtr, LPVOID pvParam );
BOOL AddNotifFnc( NOTIFFNCPTR pFncPtr, LPVOID pvParam );
BOOL RemoveNotifFnc( NOTIFFNCPTR pFncPtr, LPVOID pvParam );
BOOL HasNotifFncs() { BOOL fEmpty = FALSE; Lock(); fEmpty = IsListEmpty( &m_NotifFncChain ); Unlock(); return !fEmpty; }
LPSTR QueryStoreName() { return m_strStoreName.QueryStr() ; }
LIST_ENTRY* QueryNotifFncChain() { return &(m_NotifFncChain) ; }
HCERTSTORE QueryStoreHandle() { return m_hCertStore; }
HANDLE QueryStoreEvent() { return m_hStoreEvent; }
HANDLE* QueryEventHandleAddr() { return &m_hStoreEvent; } HANDLE QueryWaitHandle() { HANDLE hHandle; Lock(); hHandle = m_hWaitHandle; Unlock(); return hHandle; }
STORE_CHANGE_NOTIFIER* QueryNotifier() { return m_pNotifier; }
BOOL Matches( IN LPSTR pszStoreName, IN NOTIFFNCPTR pFncPtr, IN PVOID pvParam );
//
// Synchronization functions
//
VOID Lock() { EnterCriticalSection( &m_CS ); }
VOID Unlock() { LeaveCriticalSection( &m_CS ); }
//
// Public Member variable needed so this object can be included in a LIST_ENTRY
// structure
//
LIST_ENTRY m_StoreListEntry;
friend class STORE_CHANGE_NOTIFIER;
static DWORD m_dwNumEntries;
static DWORD QueryStoreEntryCount() { return m_dwNumEntries ; }
private:
VOID MarkInvalid() { Lock(); m_fInvalid = TRUE; Unlock(); }
BOOL IsInvalid() { BOOL fInvalid = FALSE; Lock(); fInvalid = m_fInvalid; Unlock(); return fInvalid; }
VOID MarkForDelete() { Lock(); m_fDeleteMe = TRUE; Unlock(); }
BOOL IsMarkedForDelete() { BOOL fMarked = FALSE; Lock(); fMarked = m_fDeleteMe; Unlock(); return fMarked; }
DWORD m_dwSignature; //signature, used for debugging
STORE_CHANGE_NOTIFIER *m_pNotifier; //pointer to "parent" object
HCERTSTORE m_hCertStore; //handle to cert store being watched
STR m_strStoreName; //Store name
HANDLE m_hStoreEvent; //event that is signalled when store changes
HANDLE m_hWaitHandle; //handle returned from call to RegisterWaitForSingleObject()
LIST_ENTRY m_NotifFncChain; //Functions to be called for changes to this store
DWORD m_dwRefCount; //ref count for this object
DWORD m_dwError; //internal error state
//
// Variables used to aid cleanup
//
BOOL m_fDeleteMe; BOOL m_fInvalid; static VOID IncrementStoreEntryCount() { InterlockedIncrement((LPLONG) &(STORE_CHANGE_ENTRY::m_dwNumEntries) ); }
static VOID DecrementStoreEntryCount() { InterlockedDecrement((LPLONG) &(STORE_CHANGE_ENTRY::m_dwNumEntries) ); }
CRITICAL_SECTION m_CS; };
typedef STORE_CHANGE_ENTRY *PSTORE_CHANGE_ENTRY;
class STORE_CHANGE_NOTIFIER { public: dllexp STORE_CHANGE_NOTIFIER(); dllexp ~STORE_CHANGE_NOTIFIER();
dllexp BOOL IsStoreRegisteredForChange( IN LPTSTR pszStoreName, IN NOTIFFNCPTR pFncPtr, IN LPVOID pvParam );
dllexp BOOL RegisterStoreForChange( IN LPTSTR pszStoreName, IN HCERTSTORE hStore, IN NOTIFFNCPTR pFncPtr, IN LPVOID pvParam );
dllexp VOID UnregisterStore( IN LPTSTR pszStoreName, NOTIFFNCPTR pFncPtr, IN LPVOID pvParam );
#if DBG
dllexp VOID DumpRegisteredStores(); #endif
dllexp VOID ReleaseRegisteredStores();
dllexp static VOID NTAPI NotifFncCaller( LPVOID pv, BOOLEAN fBoolean );
static VOID Lock() { EnterCriticalSection( STORE_CHANGE_NOTIFIER::m_pStoreListCS ) ; }
static VOID Unlock() { LeaveCriticalSection( STORE_CHANGE_NOTIFIER::m_pStoreListCS ) ; }
private:
PSTORE_CHANGE_ENTRY InternalIsStoreRegisteredForChange( IN LPTSTR pszStoreName, IN NOTIFFNCPTR pFncPtr, IN LPVOID pvParam );
BOOL CheckSignature() { return ( m_dwSignature == NOTIFIER_GOOD_SIG ? TRUE : FALSE ); }
VOID StartCleanup( PSTORE_CHANGE_ENTRY pEntry );
DWORD m_dwSignature;
LIST_ENTRY m_StoreList; //list of STORE_CHANGE_ENTRY entries for stores being watched
static CRITICAL_SECTION *m_pStoreListCS;
};
BOOL CopyString( LPTSTR *ppszDest, LPTSTR pszSrc );
LIST_ENTRY* CopyNotifFncChain( LIST_ENTRY *pNotifFncChain );
VOID DeallocateNotifFncChain( LIST_ENTRY *pNotifFncChain );
#endif // _CERTNOTF_HXX_
|