]> git.saurik.com Git - apple/security.git/blob - cdsa/cssm/attachment.cpp
d2f2be4f79c3aa99940b52b0c86ed0779e77a466
[apple/security.git] / cdsa / cssm / attachment.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 // attachment - CSSM module attachment objects
21 //
22 #ifdef __MWERKS__
23 #define _CPP_ATTACHMENT
24 #endif
25 #include "attachment.h"
26 #include "module.h"
27 #include "manager.h"
28 #include "cssmcontext.h"
29
30
31 //
32 // Construct an Attachment object.
33 // This constructor does almost all the work: it initializes the Attachment
34 // object, calls the plugin's attach function, and initializes everything.
35 // The only job left for the subclass's constructor is to take the spiFunctionTable
36 // field and extract from it the plugin's dispatch table in suitable form.
37 //
38 Attachment::Attachment(Module *parent,
39 const CSSM_VERSION &version,
40 uint32 ssId,
41 CSSM_SERVICE_TYPE ssType,
42 const CSSM_API_MEMORY_FUNCS &memoryOps,
43 CSSM_ATTACH_FLAGS attachFlags,
44 CSSM_KEY_HIERARCHY keyHierarchy)
45 : CssmMemoryFunctionsAllocator(memoryOps), module(*parent)
46 {
47 // record our origins
48 mVersion = version;
49 mSubserviceId = ssId;
50 mSubserviceType = ssType;
51 mAttachFlags = attachFlags;
52 mKeyHierarchy = keyHierarchy;
53
54 // we are not (yet) attached to our plugin
55 mIsActive = false;
56
57 // build the upcalls table
58 // (we could do this once in a static, but then we'd have to lock on it)
59 upcalls.malloc_func = upcallMalloc;
60 upcalls.free_func = upcallFree;
61 upcalls.realloc_func = upcallRealloc;
62 upcalls.calloc_func = upcallCalloc;
63 upcalls.CcToHandle_func = upcallCcToHandle;
64 upcalls.GetModuleInfo_func = upcallGetModuleInfo;
65
66 // tell the module to create an attachment
67 spiFunctionTable = NULL; // preset invalid
68 if (CSSM_RETURN err = module.plugin->CSSM_SPI_ModuleAttach(&module.myGuid(),
69 &mVersion,
70 mSubserviceId,
71 mSubserviceType,
72 mAttachFlags,
73 handle(),
74 mKeyHierarchy,
75 &module.cssm.myGuid(), // CSSM's Guid
76 &module.cssm.myGuid(), // module manager Guid
77 &module.cssm.callerGuid(), // caller Guid
78 &upcalls,
79 &spiFunctionTable)) {
80 // attach rejected by module
81 CssmError::throwMe(err);
82 }
83 try {
84 if (spiFunctionTable == NULL || spiFunctionTable->ServiceType != subserviceType())
85 CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_FUNCTION_TABLE);
86 mIsActive = true; // now officially attached to plugin
87 // subclass is responsible for taking spiFunctionTable and build
88 // whatever dispatch is needed
89 } catch (...) {
90 module.plugin->CSSM_SPI_ModuleDetach(handle()); // with extreme prejudice
91 throw;
92 }
93 }
94
95
96 //
97 // Detach an attachment.
98 // This is the polite way to detach from the plugin. It may be refused safely
99 // (though perhaps not meaningfully).
100 // THREADS: mLock is locked on entry IFF isLocked, and will be unlocked on exit.
101 //
102 void Attachment::detach(bool isLocked)
103 {
104 StLock<Mutex> locker(*this, isLocked); // pre-state locker
105 locker.lock(); // make sure it's locked
106
107 if (mIsActive) {
108 if (!isIdle())
109 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_FAILED); //@#attachment busy
110 if (CSSM_RETURN error = module.plugin->CSSM_SPI_ModuleDetach(handle()))
111 CssmError::throwMe(error); // I'm sorry Dave, ...
112 mIsActive = false;
113 module.detach(this);
114 }
115 }
116
117
118 //
119 // Destroy the Attachment object
120 //
121 Attachment::~Attachment()
122 {
123 try {
124 detach(false);
125 } catch (...) {
126 // too bad - you're dead
127 }
128 }
129
130
131 //
132 // Upcall relays.
133 // These do not lock the attachment object. The attachment can't go away
134 // because we incremented the busy count on entry to the plugin; and these
135 // fields are quite constant for the life of the Attachment.
136 //
137 void *Attachment::upcallMalloc(CSSM_HANDLE handle, uint32 size)
138 {
139 BEGIN_API
140 return findHandle<Attachment>(handle).malloc(size);
141 END_API1(NULL)
142 }
143
144 void Attachment::upcallFree(CSSM_HANDLE handle, void *mem)
145 {
146 BEGIN_API
147 return findHandle<Attachment>(handle).free(mem);
148 END_API0
149 }
150
151 void *Attachment::upcallRealloc(CSSM_HANDLE handle, void *mem, uint32 size)
152 {
153 BEGIN_API
154 return findHandle<Attachment>(handle).realloc(mem, size);
155 END_API1(NULL)
156 }
157
158 void *Attachment::upcallCalloc(CSSM_HANDLE handle, uint32 num, uint32 size)
159 {
160 BEGIN_API
161 return findHandle<Attachment>(handle).calloc(num, size);
162 END_API1(NULL)
163 }
164
165 CSSM_RETURN Attachment::upcallCcToHandle(CSSM_CC_HANDLE handle,
166 CSSM_MODULE_HANDLE *modHandle)
167 {
168 BEGIN_API
169 Required(modHandle) = findHandle<HandleContext>(handle).attachment.handle();
170 END_API(CSP)
171 }
172
173 CSSM_RETURN Attachment::upcallGetModuleInfo(CSSM_MODULE_HANDLE handle,
174 CSSM_GUID_PTR guid,
175 CSSM_VERSION_PTR version,
176 uint32 *subserviceId,
177 CSSM_SERVICE_TYPE *subserviceType,
178 CSSM_ATTACH_FLAGS *attachFlags,
179 CSSM_KEY_HIERARCHY *keyHierarchy,
180 CSSM_API_MEMORY_FUNCS_PTR memoryOps,
181 CSSM_FUNC_NAME_ADDR_PTR FunctionTable,
182 uint32 NumFunctions)
183 {
184 BEGIN_API
185 Attachment &attachment = findHandle<Attachment>(handle);
186 Required(guid) = attachment.myGuid();
187 Required(version) = attachment.mVersion;
188 Required(subserviceId) = attachment.mSubserviceId;
189 Required(subserviceType) = attachment.mSubserviceType;
190 Required(attachFlags) = attachment.mAttachFlags;
191 Required(keyHierarchy) = attachment.mKeyHierarchy;
192 Required(memoryOps) = attachment;
193 if (FunctionTable)
194 attachment.resolveSymbols(FunctionTable, NumFunctions);
195 END_API(CSSM)
196 }