]> git.saurik.com Git - apple/security.git/blob - cdsa/cssm/module.cpp
Security-179.tar.gz
[apple/security.git] / cdsa / cssm / module.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // module - CSSM Module objects
21 //
22 #include "module.h"
23 #include "manager.h"
24 #include "attachment.h"
25
26
27 //
28 // Module object construction.
29 //
30 Module::Module(CssmManager *mgr, const MdsComponent &info, Plugin *plug)
31 : MdsComponent(info), cssm(*mgr), plugin(plug)
32 {
33 // invoke module's load entry (tell it it's being loaded)
34 if (CSSM_RETURN err = plugin->CSSM_SPI_ModuleLoad(&cssm.myGuid(), // CSSM's Guid
35 &myGuid(), // module's Guid
36 spiEventRelay, this)) {
37 plugin->unload();
38 CssmError::throwMe(err); // self-destruct this module
39 }
40 }
41
42
43 //
44 // Destroy the module object.
45 // The unload() method must have succeeded and returned true before
46 // you get to delete a Module. A destructor is too precarious a place
47 // to negotiate with a plugin...
48 //
49 Module::~Module()
50 {
51 }
52
53
54 bool Module::unload(const ModuleCallback &callback)
55 {
56 StLock<Mutex> _(mLock);
57 // locked module - no more attachment creations possible
58 if (callbackCount() == 1) {
59 // would be last callback if successful, check for actual unload
60 if (attachmentCount() > 0)
61 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED); // @# module is busy
62 // no attachments active - we are idle and ready to unload
63 if (CSSM_RETURN err = plugin->CSSM_SPI_ModuleUnload(&cssm.myGuid(), // CSSM's Guid
64 &myGuid(), // module's Guid
65 spiEventRelay, this)) // our callback
66 CssmError::throwMe(err); // tough...
67 // okay, commit
68 remove(callback);
69 plugin->unload();
70 return true;
71 } else {
72 // more callbacks - we're not going to unload
73 remove(callback);
74 return false;
75 }
76 }
77
78
79 //
80 // Create a new attachment for this module
81 //
82 CSSM_HANDLE Module::attach(const CSSM_VERSION &version,
83 uint32 subserviceId,
84 CSSM_SERVICE_TYPE subserviceType,
85 const CSSM_API_MEMORY_FUNCS &memoryOps,
86 CSSM_ATTACH_FLAGS attachFlags,
87 CSSM_KEY_HIERARCHY keyHierarchy,
88 CSSM_FUNC_NAME_ADDR *functionTable,
89 uint32 functionTableSize)
90 {
91 StLock<Mutex> _(mLock);
92
93 // check if the module can do this kind of service
94 if (!supportsService(subserviceType))
95 CssmError::throwMe(CSSMERR_CSSM_INVALID_SERVICE_MASK);
96
97 Attachment *attachment = cssm.attachmentMakerFor(subserviceType)->make(this,
98 version,
99 subserviceId, subserviceType,
100 memoryOps,
101 attachFlags,
102 keyHierarchy,
103 functionTable, functionTableSize);
104
105 try {
106 // add to module's attachment map
107 attachmentMap.insert(AttachmentMap::value_type(attachment->handle(), attachment));
108 } catch (...) {
109 delete attachment;
110 throw;
111 }
112
113 // all done
114 return attachment->handle();
115 }
116
117
118 //
119 // Detach an Attachment from this module.
120 // THREADS: Requires the attachment to be idled out, i.e. caller
121 // is responsible for keeping more users from entering it.
122 //
123 void Module::detach(Attachment *attachment)
124 {
125 StLock<Mutex> _(mLock);
126 attachmentMap.erase(attachment->handle());
127 }
128
129
130 //
131 // Handle events sent by the loaded module.
132 //
133 void Module::spiEvent(CSSM_MODULE_EVENT event,
134 const Guid &guid,
135 uint32 subserviceId,
136 CSSM_SERVICE_TYPE serviceType)
137 {
138 StLock<Mutex> _(mLock);
139 if (guid != myGuid())
140 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
141 callbackSet(event, guid, subserviceId, serviceType);
142 }
143
144 // static shim
145 CSSM_RETURN Module::spiEventRelay(const CSSM_GUID *ModuleGuid,
146 void *Context,
147 uint32 SubserviceId,
148 CSSM_SERVICE_TYPE ServiceType,
149 CSSM_MODULE_EVENT EventType)
150 {
151 BEGIN_API
152 static_cast<Module *>(Context)->spiEvent(EventType,
153 Guid::required(ModuleGuid),
154 SubserviceId,
155 ServiceType);
156 END_API(CSSM)
157 }