121
121
static double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */
124
DECLARE_STACK_OF(CRYPTO_dynlock)
125
IMPLEMENT_STACK_OF(CRYPTO_dynlock)
127
/* real #defines in crypto.h, keep these upto date */
128
static const char* const lock_names[CRYPTO_NUM_LOCKS] =
169
#if CRYPTO_NUM_LOCKS != 39
170
# error "Inconsistency between crypto.h and cryptlib.c"
174
/* This is for applications to allocate new type names in the non-dynamic
175
array of lock names. These are numbered with positive numbers. */
176
static STACK *app_locks=NULL;
178
/* For applications that want a more dynamic way of handling threads, the
179
following stack is used. These are externally numbered with negative
181
static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL;
184
124
static void (MS_FAR *locking_callback)(int mode,int type,
185
125
const char *file,int line)=NULL;
186
126
static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
187
127
int type,const char *file,int line)=NULL;
188
128
static unsigned long (MS_FAR *id_callback)(void)=NULL;
189
static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
190
(const char *file,int line)=NULL;
191
static void (MS_FAR *dynlock_lock_callback)(int mode,
192
struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL;
193
static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l,
194
const char *file,int line)=NULL;
196
int CRYPTO_get_new_lockid(char *name)
201
#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
202
/* A hack to make Visual C++ 5.0 work correctly when linking as
203
* a DLL using /MT. Without this, the application cannot use
204
* and floating point printf's.
205
* It also seems to be needed for Visual C 1.5 (win16) */
206
SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
209
if ((app_locks == NULL) && ((app_locks=sk_new_null()) == NULL))
211
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
214
if ((str=BUF_strdup(name)) == NULL)
216
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
219
i=sk_push(app_locks,str);
223
i+=CRYPTO_NUM_LOCKS; /* gap of one :-) */
227
130
int CRYPTO_num_locks(void)
229
132
return CRYPTO_NUM_LOCKS;
232
int CRYPTO_get_new_dynlockid(void)
235
CRYPTO_dynlock *pointer = NULL;
237
if (dynlock_create_callback == NULL)
239
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK);
242
CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
243
if ((dyn_locks == NULL)
244
&& ((dyn_locks=sk_CRYPTO_dynlock_new_null()) == NULL))
246
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
247
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
250
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
252
pointer = (CRYPTO_dynlock *)OPENSSL_malloc(sizeof(CRYPTO_dynlock));
255
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
258
pointer->references = 1;
259
pointer->data = dynlock_create_callback(__FILE__,__LINE__);
260
if (pointer->data == NULL)
262
OPENSSL_free(pointer);
263
CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID,ERR_R_MALLOC_FAILURE);
267
CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
268
/* First, try to find an existing empty slot */
269
i=sk_CRYPTO_dynlock_find(dyn_locks,NULL);
270
/* If there was none, push, thereby creating a new one */
272
/* Since sk_push() returns the number of items on the
273
stack, not the location of the pushed item, we need
274
to transform the returned number into a position,
276
i=sk_CRYPTO_dynlock_push(dyn_locks,pointer) - 1;
278
/* If we found a place with a NULL pointer, put our pointer
280
(void)sk_CRYPTO_dynlock_set(dyn_locks,i,pointer);
281
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
285
dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
286
OPENSSL_free(pointer);
289
i += 1; /* to avoid 0 */
293
void CRYPTO_destroy_dynlockid(int i)
295
CRYPTO_dynlock *pointer = NULL;
298
if (dynlock_destroy_callback == NULL)
301
CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
303
if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks))
305
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
308
pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
311
--pointer->references;
313
if (pointer->references < 0)
315
fprintf(stderr,"CRYPTO_destroy_dynlockid, bad reference count\n");
320
if (pointer->references <= 0)
322
(void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL);
327
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
331
dynlock_destroy_callback(pointer->data,__FILE__,__LINE__);
332
OPENSSL_free(pointer);
336
struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i)
338
CRYPTO_dynlock *pointer = NULL;
342
CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK);
344
if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks))
345
pointer = sk_CRYPTO_dynlock_value(dyn_locks, i);
347
pointer->references++;
349
CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK);
352
return pointer->data;
356
struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void))
357
(const char *file,int line)
359
return(dynlock_create_callback);
362
void (*CRYPTO_get_dynlock_lock_callback(void))(int mode,
363
struct CRYPTO_dynlock_value *l, const char *file,int line)
365
return(dynlock_lock_callback);
368
void (*CRYPTO_get_dynlock_destroy_callback(void))
369
(struct CRYPTO_dynlock_value *l, const char *file,int line)
371
return(dynlock_destroy_callback);
374
void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
375
(const char *file, int line))
377
dynlock_create_callback=func;
380
void CRYPTO_set_dynlock_lock_callback(void (*func)(int mode,
381
struct CRYPTO_dynlock_value *l, const char *file, int line))
383
dynlock_lock_callback=func;
386
void CRYPTO_set_dynlock_destroy_callback(void (*func)
387
(struct CRYPTO_dynlock_value *l, const char *file, int line))
389
dynlock_destroy_callback=func;
393
135
void (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file,
579
308
#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
312
#include <tlhelp32.h>
313
#if defined(__GNUC__) && __GNUC__>=2
314
static int DllInit(void) __attribute__((constructor));
315
#elif defined(_MSC_VER)
316
static int DllInit(void);
318
# pragma section(".CRT$XCU",read)
319
__declspec(allocate(".CRT$XCU"))
321
# pragma data_seg(".CRT$XCU")
323
static int (*p)(void) = DllInit;
327
static int DllInit(void)
329
#if defined(_WIN32_WINNT)
330
union { int(*f)(void); BYTE *p; } t = { DllInit };
331
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
332
IMAGE_DOS_HEADER *dos_header;
333
IMAGE_NT_HEADERS *nt_headers;
334
MODULEENTRY32 me32 = {sizeof(me32)};
336
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
337
if (hModuleSnap != INVALID_HANDLE_VALUE &&
338
Module32First(hModuleSnap,&me32)) do
340
if (t.p >= me32.modBaseAddr &&
341
t.p < me32.modBaseAddr+me32.modBaseSize)
343
dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr;
344
if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
346
nt_headers=(IMAGE_NT_HEADERS *)
347
((BYTE *)dos_header+dos_header->e_lfanew);
348
if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
349
me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase)
350
OPENSSL_NONPIC_relocated=1;
354
} while (Module32Next(hModuleSnap,&me32));
356
if (hModuleSnap != INVALID_HANDLE_VALUE)
357
CloseHandle(hModuleSnap);
359
OPENSSL_cpuid_setup();
580
365
#ifdef __CYGWIN__
581
366
/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
582
367
#include <windows.h>