cryptlib.c: allow application to override OPENSSL_isservice [from HEAD].
[openssl.git] / crypto / cryptlib.c
index 12f24f6cc84ec990a78237534c36d29374d7a8d9..b4449b86d68fcfa3462ff616737bc4a426a6ae70 100644 (file)
@@ -174,7 +174,7 @@ static const char* const lock_names[CRYPTO_NUM_LOCKS] =
 
 /* This is for applications to allocate new type names in the non-dynamic
    array of lock names.  These are numbered with positive numbers.  */
-static STACK_OF(STRING) *app_locks=NULL;
+static STACK_OF(OPENSSL_STRING) *app_locks=NULL;
 
 /* For applications that want a more dynamic way of handling threads, the
    following stack is used.  These are externally numbered with negative
@@ -205,12 +205,12 @@ int CRYPTO_get_new_lockid(char *name)
 #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
        /* A hack to make Visual C++ 5.0 work correctly when linking as
         * a DLL using /MT. Without this, the application cannot use
-        * and floating point printf's.
+        * any floating point printf's.
         * It also seems to be needed for Visual C 1.5 (win16) */
        SSLeay_MSVC5_hack=(double)name[0]*(double)name[1];
 #endif
 
-       if ((app_locks == NULL) && ((app_locks=sk_STRING_new_null()) == NULL))
+       if ((app_locks == NULL) && ((app_locks=sk_OPENSSL_STRING_new_null()) == NULL))
                {
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
                return(0);
@@ -220,7 +220,7 @@ int CRYPTO_get_new_lockid(char *name)
                CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID,ERR_R_MALLOC_FAILURE);
                return(0);
                }
-       i=sk_STRING_push(app_locks,str);
+       i=sk_OPENSSL_STRING_push(app_locks,str);
        if (!i)
                OPENSSL_free(str);
        else
@@ -554,14 +554,6 @@ unsigned long CRYPTO_thread_id(void)
        }
 #endif
 
-static void (*do_dynlock_cb)(int mode, int type, const char *file, int line);
-
-void int_CRYPTO_set_do_dynlock_callback(
-       void (*dyn_cb)(int mode, int type, const char *file, int line))
-       {
-       do_dynlock_cb = dyn_cb;
-       }
-
 void CRYPTO_lock(int mode, int type, const char *file, int line)
        {
 #ifdef LOCK_DEBUG
@@ -591,8 +583,17 @@ void CRYPTO_lock(int mode, int type, const char *file, int line)
 #endif
        if (type < 0)
                {
-               if (do_dynlock_cb)
-                       do_dynlock_cb(mode, type, file, line);
+               if (dynlock_lock_callback != NULL)
+                       {
+                       struct CRYPTO_dynlock_value *pointer
+                               = CRYPTO_get_dynlock_value(type);
+
+                       OPENSSL_assert(pointer != NULL);
+
+                       dynlock_lock_callback(mode, pointer, file, line);
+
+                       CRYPTO_destroy_dynlockid(type);
+                       }
                }
        else
                if (locking_callback != NULL)
@@ -650,15 +651,15 @@ const char *CRYPTO_get_lock_name(int type)
                return("dynamic");
        else if (type < CRYPTO_NUM_LOCKS)
                return(lock_names[type]);
-       else if (type-CRYPTO_NUM_LOCKS > sk_STRING_num(app_locks))
+       else if (type-CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks))
                return("ERROR");
        else
-               return(sk_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS));
+               return(sk_OPENSSL_STRING_value(app_locks,type-CRYPTO_NUM_LOCKS));
        }
 
 #if    defined(__i386)   || defined(__i386__)   || defined(_M_IX86) || \
        defined(__INTEL__) || \
-       defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64)
+       defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)
 
 unsigned long  OPENSSL_ia32cap_P=0;
 unsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; }
@@ -694,65 +695,11 @@ void OPENSSL_cpuid_setup(void) {}
 #endif
 
 #if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL)
-
-#ifdef OPENSSL_FIPS
-
-#include <tlhelp32.h>
-#if defined(__GNUC__) && __GNUC__>=2
-static int DllInit(void) __attribute__((constructor));
-#elif defined(_MSC_VER)
-static int DllInit(void);
-# ifdef _WIN64
-# pragma section(".CRT$XCU",read)
-  __declspec(allocate(".CRT$XCU"))
-# else
-# pragma data_seg(".CRT$XCU")
-# endif
-  static int (*p)(void) = DllInit;
-# pragma data_seg()
-#endif
-
-static int DllInit(void)
-{
-#if defined(_WIN32_WINNT)
-       union   { int(*f)(void); BYTE *p; } t = { DllInit };
-        HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
-       IMAGE_DOS_HEADER *dos_header;
-       IMAGE_NT_HEADERS *nt_headers;
-       MODULEENTRY32 me32 = {sizeof(me32)};
-
-       hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0);
-       if (hModuleSnap != INVALID_HANDLE_VALUE &&
-           Module32First(hModuleSnap,&me32)) do
-               {
-               if (t.p >= me32.modBaseAddr &&
-                   t.p <  me32.modBaseAddr+me32.modBaseSize)
-                       {
-                       dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr;
-                       if (dos_header->e_magic==IMAGE_DOS_SIGNATURE)
-                               {
-                               nt_headers=(IMAGE_NT_HEADERS *)
-                                       ((BYTE *)dos_header+dos_header->e_lfanew);
-                               if (nt_headers->Signature==IMAGE_NT_SIGNATURE &&
-                                   me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase)
-                                       OPENSSL_NONPIC_relocated=1;
-                               }
-                       break;
-                       }
-               } while (Module32Next(hModuleSnap,&me32));
-
-       if (hModuleSnap != INVALID_HANDLE_VALUE)
-               CloseHandle(hModuleSnap);
-#endif
-       OPENSSL_cpuid_setup();
-       return 0;
-}
-
-#else
-
 #ifdef __CYGWIN__
 /* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */
 #include <windows.h>
+/* this has side-effect of _WIN32 getting defined, which otherwise
+ * is mutually exclusive with __CYGWIN__... */
 #endif
 
 /* All we really need to do is remove the 'error' state when a thread
@@ -793,16 +740,27 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason,
        }
 #endif
 
-#endif
-
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #include <tchar.h>
+#include <signal.h>
 
 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
 int OPENSSL_isservice(void)
 { HWINSTA h;
   DWORD len;
   WCHAR *name;
+  static union { void *p; int (*f)(void); } _OPENSSL_isservice = { NULL };
+
+    if (_OPENSSL_isservice.p == NULL) {
+       HANDLE h = GetModuleHandle(NULL);
+       if (h != NULL)
+           _OPENSSL_isservice.p = GetProcAddress(h,"_OPENSSL_isservice");
+       if (_OPENSSL_isservice.p == NULL)
+           _OPENSSL_isservice.p = (void *)-1;
+    }
+
+    if (_OPENSSL_isservice.p != (void *)-1)
+       return (*_OPENSSL_isservice.f)();
 
     (void)GetDesktopWindow(); /* return value is ignored */
 
@@ -901,7 +859,7 @@ void OPENSSL_showfatal (const char *fmta,...)
 
 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
     /* this -------------v--- guards NT-specific calls */
-    if (GetVersion() < 0x80000000 && OPENSSL_isservice())
+    if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0)
     {  HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
        const TCHAR *pmsg=buf;
        ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
@@ -927,7 +885,13 @@ void OpenSSLDie(const char *file,int line,const char *assertion)
        OPENSSL_showfatal(
                "%s(%d): OpenSSL internal error, assertion failed: %s\n",
                file,line,assertion);
+#if !defined(_WIN32) || defined(__CYGWIN__)
        abort();
+#else
+       /* Win32 abort() customarily shows a dialog, but we just did that... */
+       raise(SIGABRT);
+       _exit(3);
+#endif
        }
 
 void *OPENSSL_stderr(void)     { return stderr; }