#ifdef __MWERKS__
#define _CPP_CSSMCONTEXT
#endif
#include "cssmcontext.h"
HandleContext::~HandleContext()
{
attachment.free(extent);
attachment.free(ContextAttributes);
}
void HandleContext::lock()
{ attachment.enter(); }
bool HandleContext::tryLock()
{ return attachment.tryEnter(); }
void HandleContext::mergeAttributes(const CSSM_CONTEXT_ATTRIBUTE *attributes, uint32 count)
{
if (count == 1) {
if (Attr *attr = find(attributes[0].AttributeType)) {
if (attr->baseType() == CSSM_ATTRIBUTE_DATA_UINT32) {
Attr oldAttr = *attr;
*attr = attributes[0];
if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
*attr = oldAttr;
CssmError::throwMe(err);
}
return; } else {
size_t oldSize = size(*attr);
size_t newSize = size(attributes[0]);
Attr oldAttr = *attr;
if (newSize <= oldSize) { *attr = attributes[0];
if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
*attr = oldAttr;
CssmError::throwMe(err);
}
CopyWalker copier(oldAttr.Attribute.String);
walk(copier, *attr);
return;
}
}
} else { if (Attr *slot = find(CSSM_ATTRIBUTE_NONE)) {
const Attr *attr = static_cast<const Attr *>(&attributes[0]);
if (attr->baseType() == CSSM_ATTRIBUTE_DATA_UINT32) { Attr oldSlot = *slot;
*slot = *attr;
if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
*slot = oldSlot;
CssmError::throwMe(err);
}
return;
} else if (extent == NULL) { void *data = attachment.malloc(size(*attr));
try {
Attr oldSlot = *slot;
*slot = attributes[0];
CopyWalker copier(data);
walk(copier, *slot);
if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
*slot = oldSlot;
CssmError::throwMe(err);
}
} catch (...) {
attachment.free(data);
throw;
}
extent = data;
return;
}
}
}
}
Context::Builder builder(attachment);
for (unsigned n = 0; n < count; n++)
builder.setup(attributes[n]);
for (unsigned n = 0; n < attributesInUse(); n++)
if (!find(ContextAttributes[n].AttributeType, attributes, count))
builder.setup(ContextAttributes[n]);
builder.make();
for (unsigned n = 0; n < count; n++)
builder.put(attributes[n]);
for (unsigned n = 0; n < attributesInUse(); n++)
if (!find(ContextAttributes[n].AttributeType, attributes, count))
builder.put(ContextAttributes[n]);
CSSM_CONTEXT_ATTRIBUTE *oldAttributes = ContextAttributes;
uint32 oldCount = NumberOfAttributes;
builder.done(ContextAttributes, NumberOfAttributes);
if (CSSM_RETURN err = validateChange(CSSM_CONTEXT_EVENT_UPDATE)) {
attachment.free(ContextAttributes);
ContextAttributes = oldAttributes;
NumberOfAttributes = oldCount;
CssmError::throwMe(err);
}
attachment.free(oldAttributes);
}
CSSM_RETURN HandleContext::validateChange(CSSM_CONTEXT_EVENT event)
{
StLock<Module, &Module::safeLock, &Module::safeUnlock> _(attachment.module);
return attachment.downcalls.EventNotify(attachment.handle(),
event, handle(), this);
}
CSSM_CC_HANDLE HandleContext::Maker::operator () (CSSM_CONTEXT_TYPE type,
CSSM_ALGORITHMS algorithm)
{
HandleContext &context = *new(attachment) HandleContext(attachment, type, algorithm);
context.CSPHandle = attachment.handle();
done(context.ContextAttributes, context.NumberOfAttributes);
if (CSSM_RETURN err = context.validateChange(CSSM_CONTEXT_EVENT_CREATE)) {
context.destroy(&context, context.attachment);
CssmError::throwMe(err);
}
return context.handle();
}