#ifndef _H_CSSMPLUGIN
#define _H_CSSMPLUGIN
#include <Security/c++plugin.h>
#include <Security/globalizer.h>
#include <Security/callback.h>
#include <set>
#if __GNUC__ > 2
#include <ext/hash_map>
using __gnu_cxx::hash_map;
#else
#include <hash_map>
#endif
namespace Security
{
class CssmPlugin {
NOCOPY(CssmPlugin)
public:
CssmPlugin();
virtual ~CssmPlugin();
void moduleLoad(const Guid &cssmGuid,
const Guid &moduleGuid,
const ModuleCallback &callback);
void moduleUnload(const Guid &cssmGuid,
const Guid &moduleGuid,
const ModuleCallback &callback);
void moduleAttach(CSSM_MODULE_HANDLE theHandle,
const Guid &cssmGuid,
const Guid &moduleGuid,
const Guid &moduleManagerGuid,
const Guid &callerGuid,
const CSSM_VERSION &Version,
uint32 SubserviceID,
CSSM_SERVICE_TYPE SubServiceType,
CSSM_ATTACH_FLAGS AttachFlags,
CSSM_KEY_HIERARCHY KeyHierarchy,
const CSSM_UPCALLS &Upcalls,
CSSM_MODULE_FUNCS_PTR &FuncTbl);
void moduleDetach(CSSM_MODULE_HANDLE handle);
const Guid &myGuid() const { return mMyGuid; }
void sendCallback(CSSM_MODULE_EVENT event,
uint32 subId,
CSSM_SERVICE_TYPE serviceType) const;
void sendInsertion(uint32 subId, CSSM_SERVICE_TYPE serviceType) const
{ sendCallback(CSSM_NOTIFY_INSERT, subId, serviceType); }
void sendRemoval(uint32 subId, CSSM_SERVICE_TYPE serviceType) const
{ sendCallback(CSSM_NOTIFY_REMOVE, subId, serviceType); }
void sendFault(uint32 subId, CSSM_SERVICE_TYPE serviceType) const
{ sendCallback(CSSM_NOTIFY_FAULT, subId, serviceType); }
protected:
virtual void load();
virtual void unload();
virtual PluginSession *makeSession(CSSM_MODULE_HANDLE handle,
const CSSM_VERSION &version,
uint32 subserviceId,
CSSM_SERVICE_TYPE subserviceType,
CSSM_ATTACH_FLAGS attachFlags,
const CSSM_UPCALLS &upcalls) = 0;
private:
struct SessionMap :
public hash_map<CSSM_MODULE_HANDLE, PluginSession *>,
public Mutex { };
static ModuleNexus<SessionMap> sessionMap;
Guid mMyGuid;
ModuleCallback callback;
bool haveCallback;
public:
static PluginSession *find(CSSM_MODULE_HANDLE h)
{
StLock<Mutex> _(sessionMap());
SessionMap::iterator it = sessionMap().find(h);
if (it == sessionMap().end())
CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
return it->second;
}
};
template <class SessionClass>
inline SessionClass &findSession(CSSM_MODULE_HANDLE h)
{
SessionClass *session = dynamic_cast<SessionClass *>(CssmPlugin::find(h));
if (session == NULL)
CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
assert(session->handle() == h);
return *session;
}
}
#endif //_H_CSSMPLUGIN