cryptlib.c revision 237998
11590Srgrimes/* crypto/cryptlib.c */ 21590Srgrimes/* ==================================================================== 31590Srgrimes * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 91590Srgrimes * 1. Redistributions of source code must retain the above copyright 101590Srgrimes * notice, this list of conditions and the following disclaimer. 111590Srgrimes * 121590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131590Srgrimes * notice, this list of conditions and the following disclaimer in 141590Srgrimes * the documentation and/or other materials provided with the 151590Srgrimes * distribution. 161590Srgrimes * 171590Srgrimes * 3. All advertising materials mentioning features or use of this 181590Srgrimes * software must display the following acknowledgment: 191590Srgrimes * "This product includes software developed by the OpenSSL Project 201590Srgrimes * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 211590Srgrimes * 221590Srgrimes * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 231590Srgrimes * endorse or promote products derived from this software without 241590Srgrimes * prior written permission. For written permission, please contact 251590Srgrimes * openssl-core@openssl.org. 261590Srgrimes * 271590Srgrimes * 5. Products derived from this software may not be called "OpenSSL" 281590Srgrimes * nor may "OpenSSL" appear in their names without prior written 291590Srgrimes * permission of the OpenSSL Project. 301590Srgrimes * 311590Srgrimes * 6. Redistributions of any form whatsoever must retain the following 321590Srgrimes * acknowledgment: 331590Srgrimes * "This product includes software developed by the OpenSSL Project 341590Srgrimes * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 3574769Smikeh * 361590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 3774769Smikeh * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 381590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 3999112Sobrien * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 4099112Sobrien * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 411590Srgrimes * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 421590Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 431590Srgrimes * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 441590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 451590Srgrimes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 461590Srgrimes * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 471590Srgrimes * OF THE POSSIBILITY OF SUCH DAMAGE. 481590Srgrimes * ==================================================================== 491590Srgrimes * 501590Srgrimes * This product includes cryptographic software written by Eric Young 511590Srgrimes * (eay@cryptsoft.com). This product includes software written by Tim 521590Srgrimes * Hudson (tjh@cryptsoft.com). 531590Srgrimes * 541590Srgrimes */ 551590Srgrimes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 561590Srgrimes * All rights reserved. 571590Srgrimes * 581590Srgrimes * This package is an SSL implementation written 591590Srgrimes * by Eric Young (eay@cryptsoft.com). 601590Srgrimes * The implementation was written so as to conform with Netscapes SSL. 611590Srgrimes * 6277274Smikeh * This library is free for commercial and non-commercial use as long as 631590Srgrimes * the following conditions are aheared to. The following conditions 6477274Smikeh * apply to all code found in this distribution, be it the RC4, RSA, 6577274Smikeh * lhash, DES, etc., code; not just the SSL code. The SSL documentation 6677274Smikeh * included with this distribution is covered by the same copyright terms 671590Srgrimes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 681590Srgrimes * 6977274Smikeh * Copyright remains Eric Young's, and as such any Copyright notices in 701590Srgrimes * the code are not to be removed. 711590Srgrimes * If this package is used in a product, Eric Young should be given attribution 721590Srgrimes * as the author of the parts of the library used. 731590Srgrimes * This can be in the form of a textual message at program startup or 741590Srgrimes * in documentation (online or textual) provided with the package. 751590Srgrimes * 761590Srgrimes * Redistribution and use in source and binary forms, with or without 771590Srgrimes * modification, are permitted provided that the following conditions 781590Srgrimes * are met: 7977274Smikeh * 1. Redistributions of source code must retain the copyright 801590Srgrimes * notice, this list of conditions and the following disclaimer. 811590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 8277274Smikeh * notice, this list of conditions and the following disclaimer in the 8377274Smikeh * documentation and/or other materials provided with the distribution. 8477274Smikeh * 3. All advertising materials mentioning features or use of this software 851590Srgrimes * must display the following acknowledgement: 8677274Smikeh * "This product includes cryptographic software written by 871590Srgrimes * Eric Young (eay@cryptsoft.com)" 881590Srgrimes * The word 'cryptographic' can be left out if the rouines from the library 891590Srgrimes * being used are not cryptographic related :-). 901590Srgrimes * 4. If you include any Windows specific code (or a derivative thereof) from 911590Srgrimes * the apps directory (application code) you must include an acknowledgement: 9277274Smikeh * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 931590Srgrimes * 941590Srgrimes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 951590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 961590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 971590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 981590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 9977274Smikeh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 10077274Smikeh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1011590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 10277274Smikeh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 10377274Smikeh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 10477274Smikeh * SUCH DAMAGE. 10574769Smikeh * 10677274Smikeh * The licence and distribution terms for any publically available version or 10777274Smikeh * derivative of this code cannot be changed. i.e. this code cannot simply be 1081590Srgrimes * copied and put under another distribution licence 10977274Smikeh * [including the GNU Public Licence.] 1101590Srgrimes */ 11177274Smikeh/* ==================================================================== 1121590Srgrimes * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. 1131590Srgrimes * ECDH support in OpenSSL originally developed by 1141590Srgrimes * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. 1151590Srgrimes */ 1161590Srgrimes 1171590Srgrimes#include "cryptlib.h" 11877274Smikeh#include <openssl/safestack.h> 11977274Smikeh 1201590Srgrimes#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) 1211590Srgrimesstatic double SSLeay_MSVC5_hack=0.0; /* and for VC1.5 */ 1221590Srgrimes#endif 1231590Srgrimes 1241590Srgrimesstatic void (MS_FAR *locking_callback)(int mode,int type, 1251590Srgrimes const char *file,int line)=NULL; 1261590Srgrimesstatic int (MS_FAR *add_lock_callback)(int *pointer,int amount, 12777274Smikeh int type,const char *file,int line)=NULL; 1281590Srgrimesstatic unsigned long (MS_FAR *id_callback)(void)=NULL; 1291590Srgrimes 13077274Smikehint CRYPTO_num_locks(void) 13177274Smikeh { 13277274Smikeh return CRYPTO_NUM_LOCKS; 1331590Srgrimes } 1341590Srgrimes 13577274Smikehvoid (*CRYPTO_get_locking_callback(void))(int mode,int type,const char *file, 13677274Smikeh int line) 1371590Srgrimes { 1381590Srgrimes return(locking_callback); 1391590Srgrimes } 1401590Srgrimes 14177274Smikehint (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, 1421590Srgrimes const char *file,int line) 1431590Srgrimes { 1441590Srgrimes return(add_lock_callback); 1451590Srgrimes } 1461590Srgrimes 1471590Srgrimesvoid CRYPTO_set_locking_callback(void (*func)(int mode,int type, 1481590Srgrimes const char *file,int line)) 14977274Smikeh { 1501590Srgrimes locking_callback=func; 1511590Srgrimes } 1521590Srgrimes 15377274Smikehvoid CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, 1541590Srgrimes const char *file,int line)) 1551590Srgrimes { 15674769Smikeh add_lock_callback=func; 15777274Smikeh } 1581590Srgrimes 1591590Srgrimesunsigned long (*CRYPTO_get_id_callback(void))(void) 1601590Srgrimes { 16174769Smikeh return(id_callback); 1621590Srgrimes } 16374769Smikeh 16477274Smikehvoid CRYPTO_set_id_callback(unsigned long (*func)(void)) 1651590Srgrimes { 1661590Srgrimes id_callback=func; 1671590Srgrimes } 1681590Srgrimes 1691590Srgrimesunsigned long CRYPTO_thread_id(void) 1701590Srgrimes { 1711590Srgrimes unsigned long ret=0; 1721590Srgrimes 1731590Srgrimes if (id_callback == NULL) 1741590Srgrimes { 17577274Smikeh#ifdef OPENSSL_SYS_WIN16 1761590Srgrimes ret=(unsigned long)GetCurrentTask(); 1771590Srgrimes#elif defined(OPENSSL_SYS_WIN32) 1781590Srgrimes ret=(unsigned long)GetCurrentThreadId(); 1791590Srgrimes#elif defined(GETPID_IS_MEANINGLESS) 18077274Smikeh ret=1L; 1811590Srgrimes#else 18277274Smikeh ret=(unsigned long)getpid(); 1831590Srgrimes#endif 1841590Srgrimes } 1851590Srgrimes else 1861590Srgrimes ret=id_callback(); 1871590Srgrimes return(ret); 1881590Srgrimes } 1891590Srgrimes 1901590Srgrimesstatic void (*do_dynlock_cb)(int mode, int type, const char *file, int line); 1911590Srgrimes 1921590Srgrimesvoid int_CRYPTO_set_do_dynlock_callback( 1931590Srgrimes void (*dyn_cb)(int mode, int type, const char *file, int line)) 1941590Srgrimes { 1951590Srgrimes do_dynlock_cb = dyn_cb; 1961590Srgrimes } 1971590Srgrimes 1981590Srgrimesvoid CRYPTO_lock(int mode, int type, const char *file, int line) 1991590Srgrimes { 2001590Srgrimes#ifdef LOCK_DEBUG 2011590Srgrimes { 2021590Srgrimes char *rw_text,*operation_text; 2031590Srgrimes 2041590Srgrimes if (mode & CRYPTO_LOCK) 20577274Smikeh operation_text="lock "; 20677274Smikeh else if (mode & CRYPTO_UNLOCK) 2071590Srgrimes operation_text="unlock"; 2081590Srgrimes else 20977274Smikeh operation_text="ERROR "; 2101590Srgrimes 2111590Srgrimes if (mode & CRYPTO_READ) 2121590Srgrimes rw_text="r"; 213126415Smikeh else if (mode & CRYPTO_WRITE) 214126415Smikeh rw_text="w"; 215126415Smikeh else 216126415Smikeh rw_text="ERROR"; 217126415Smikeh 218126415Smikeh fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", 219126415Smikeh CRYPTO_thread_id(), rw_text, operation_text, 220126415Smikeh CRYPTO_get_lock_name(type), file, line); 221126415Smikeh } 222126415Smikeh#endif 223126415Smikeh if (type < 0) 224126415Smikeh { 225126415Smikeh if (do_dynlock_cb) 226126415Smikeh do_dynlock_cb(mode, type, file, line); 227126415Smikeh } 228126415Smikeh else 229126415Smikeh if (locking_callback != NULL) 230126415Smikeh locking_callback(mode,type,file,line); 231126415Smikeh } 232126415Smikeh 233126415Smikehint CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, 234126415Smikeh int line) 235126415Smikeh { 236126415Smikeh int ret = 0; 237126415Smikeh 238126415Smikeh if (add_lock_callback != NULL) 239126415Smikeh { 240126415Smikeh#ifdef LOCK_DEBUG 241126415Smikeh int before= *pointer; 242126415Smikeh#endif 243126415Smikeh 244126415Smikeh ret=add_lock_callback(pointer,amount,type,file,line); 245126415Smikeh#ifdef LOCK_DEBUG 246126415Smikeh fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 247126415Smikeh CRYPTO_thread_id(), 248126415Smikeh before,amount,ret, 249126415Smikeh CRYPTO_get_lock_name(type), 250126415Smikeh file,line); 251126415Smikeh#endif 252126415Smikeh } 253126415Smikeh else 254126415Smikeh { 255126415Smikeh CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line); 256126415Smikeh 257126415Smikeh ret= *pointer+amount; 258126415Smikeh#ifdef LOCK_DEBUG 259126415Smikeh fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", 260126415Smikeh CRYPTO_thread_id(), 261126415Smikeh *pointer,amount,ret, 262126415Smikeh CRYPTO_get_lock_name(type), 263126415Smikeh file,line); 264126415Smikeh#endif 265126415Smikeh *pointer=ret; 266126415Smikeh CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); 267126415Smikeh } 268126415Smikeh return(ret); 269126415Smikeh } 270126415Smikeh 271126415Smikeh#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ 272126415Smikeh defined(__INTEL__) || \ 273126415Smikeh defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) 274126415Smikeh 275126415Smikehunsigned long OPENSSL_ia32cap_P=0; 276126415Smikehunsigned long *OPENSSL_ia32cap_loc(void) { return &OPENSSL_ia32cap_P; } 277126415Smikeh 278126415Smikeh#if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) 279126415Smikeh#define OPENSSL_CPUID_SETUP 280126415Smikehvoid OPENSSL_cpuid_setup(void) 281126415Smikeh{ static int trigger=0; 282126415Smikeh unsigned long OPENSSL_ia32_cpuid(void); 283126415Smikeh char *env; 284126415Smikeh 285126415Smikeh if (trigger) return; 2861590Srgrimes 2871590Srgrimes trigger=1; 2881590Srgrimes if ((env=getenv("OPENSSL_ia32cap"))) 2891590Srgrimes OPENSSL_ia32cap_P = strtoul(env,NULL,0)|(1<<10); 2901590Srgrimes else 2911590Srgrimes OPENSSL_ia32cap_P = OPENSSL_ia32_cpuid()|(1<<10); 2921590Srgrimes /* 2931590Srgrimes * |(1<<10) sets a reserved bit to signal that variable 2941590Srgrimes * was initialized already... This is to avoid interference 2951590Srgrimes * with cpuid snippets in ELF .init segment. 2961590Srgrimes */ 2971590Srgrimes} 2981590Srgrimes#endif 29977274Smikeh 30077274Smikeh#else 30177274Smikehunsigned long *OPENSSL_ia32cap_loc(void) { return NULL; } 30277274Smikeh#endif 3031590Srgrimesint OPENSSL_NONPIC_relocated = 0; 3041590Srgrimes#if !defined(OPENSSL_CPUID_SETUP) 3051590Srgrimesvoid OPENSSL_cpuid_setup(void) {} 3061590Srgrimes#endif 30777274Smikeh 3081590Srgrimes#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) 30977274Smikeh 3101590Srgrimes#ifdef OPENSSL_FIPS 3111590Srgrimes 3121590Srgrimes#include <tlhelp32.h> 3131590Srgrimes#if defined(__GNUC__) && __GNUC__>=2 3141590Srgrimesstatic int DllInit(void) __attribute__((constructor)); 3151590Srgrimes#elif defined(_MSC_VER) 3161590Srgrimesstatic int DllInit(void); 3171590Srgrimes# ifdef _WIN64 3181590Srgrimes# pragma section(".CRT$XCU",read) 3191590Srgrimes __declspec(allocate(".CRT$XCU")) 3201590Srgrimes# else 3211590Srgrimes# pragma data_seg(".CRT$XCU") 3221590Srgrimes# endif 3231590Srgrimes static int (*p)(void) = DllInit; 3241590Srgrimes# pragma data_seg() 3251590Srgrimes#endif 32674769Smikeh 32774769Smikehstatic int DllInit(void) 32874769Smikeh{ 32977274Smikeh#if defined(_WIN32_WINNT) 33077274Smikeh union { int(*f)(void); BYTE *p; } t = { DllInit }; 33174769Smikeh HANDLE hModuleSnap = INVALID_HANDLE_VALUE; 33274769Smikeh IMAGE_DOS_HEADER *dos_header; 33374769Smikeh IMAGE_NT_HEADERS *nt_headers; 3341590Srgrimes MODULEENTRY32 me32 = {sizeof(me32)}; 3351590Srgrimes 3361590Srgrimes hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,0); 33774769Smikeh if (hModuleSnap != INVALID_HANDLE_VALUE && 33877274Smikeh Module32First(hModuleSnap,&me32)) do 3391590Srgrimes { 34074769Smikeh if (t.p >= me32.modBaseAddr && 3411590Srgrimes t.p < me32.modBaseAddr+me32.modBaseSize) 34277274Smikeh { 3431590Srgrimes dos_header=(IMAGE_DOS_HEADER *)me32.modBaseAddr; 3441590Srgrimes if (dos_header->e_magic==IMAGE_DOS_SIGNATURE) 34577274Smikeh { 3461590Srgrimes nt_headers=(IMAGE_NT_HEADERS *) 34732189Sjoerg ((BYTE *)dos_header+dos_header->e_lfanew); 34877274Smikeh if (nt_headers->Signature==IMAGE_NT_SIGNATURE && 3491590Srgrimes me32.modBaseAddr!=(BYTE*)nt_headers->OptionalHeader.ImageBase) 35077274Smikeh OPENSSL_NONPIC_relocated=1; 3511590Srgrimes } 35277274Smikeh break; 35377274Smikeh } 35474769Smikeh } while (Module32Next(hModuleSnap,&me32)); 35574769Smikeh 35674769Smikeh if (hModuleSnap != INVALID_HANDLE_VALUE) 35777274Smikeh CloseHandle(hModuleSnap); 35874769Smikeh#endif 35974769Smikeh OPENSSL_cpuid_setup(); 36077274Smikeh return 0; 3611590Srgrimes} 3621590Srgrimes 3631590Srgrimes#else 3641590Srgrimes 3651590Srgrimes#ifdef __CYGWIN__ 3661590Srgrimes/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ 3671590Srgrimes#include <windows.h> 3681590Srgrimes#endif 3691590Srgrimes 3701590Srgrimes/* All we really need to do is remove the 'error' state when a thread 37177274Smikeh * detaches */ 37288150Smikeh 3731590SrgrimesBOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, 3741590Srgrimes LPVOID lpvReserved) 3751590Srgrimes { 3761590Srgrimes switch(fdwReason) 3771590Srgrimes { 3781590Srgrimes case DLL_PROCESS_ATTACH: 3791590Srgrimes OPENSSL_cpuid_setup(); 3801590Srgrimes#if defined(_WIN32_WINNT) 38177274Smikeh { 38277274Smikeh IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *)hinstDLL; 38388150Smikeh IMAGE_NT_HEADERS *nt_headers; 38488150Smikeh 38588150Smikeh if (dos_header->e_magic==IMAGE_DOS_SIGNATURE) 38688150Smikeh { 38788150Smikeh nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header 38888150Smikeh + dos_header->e_lfanew); 3891590Srgrimes if (nt_headers->Signature==IMAGE_NT_SIGNATURE && 3901590Srgrimes hinstDLL!=(HINSTANCE)(nt_headers->OptionalHeader.ImageBase)) 3911590Srgrimes OPENSSL_NONPIC_relocated=1; 3921590Srgrimes } 3931590Srgrimes } 3941590Srgrimes#endif 3951590Srgrimes break; 3961590Srgrimes case DLL_THREAD_ATTACH: 39774769Smikeh break; 3981590Srgrimes case DLL_THREAD_DETACH: 3991590Srgrimes break; 4001590Srgrimes case DLL_PROCESS_DETACH: 4011590Srgrimes break; 40274769Smikeh } 4031590Srgrimes return(TRUE); 4041590Srgrimes } 4051590Srgrimes#endif 4061590Srgrimes 4071590Srgrimes#endif 40877274Smikeh 4091590Srgrimes#if defined(_WIN32) && !defined(__CYGWIN__) 4101590Srgrimes#include <tchar.h> 4111590Srgrimes 4121590Srgrimes#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 4131590Srgrimesint OPENSSL_isservice(void) 41477274Smikeh{ HWINSTA h; 41574769Smikeh DWORD len; 41674769Smikeh WCHAR *name; 41774769Smikeh 41877274Smikeh (void)GetDesktopWindow(); /* return value is ignored */ 41977274Smikeh 42074769Smikeh h = GetProcessWindowStation(); 42174769Smikeh if (h==NULL) return -1; 42277274Smikeh 42377274Smikeh if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) || 4241590Srgrimes GetLastError() != ERROR_INSUFFICIENT_BUFFER) 4251590Srgrimes return -1; 4261590Srgrimes 4271590Srgrimes if (len>512) return -1; /* paranoia */ 4281590Srgrimes len++,len&=~1; /* paranoia */ 4291590Srgrimes#ifdef _MSC_VER 4301590Srgrimes name=(WCHAR *)_alloca(len+sizeof(WCHAR)); 4311590Srgrimes#else 4321590Srgrimes name=(WCHAR *)alloca(len+sizeof(WCHAR)); 4331590Srgrimes#endif 4341590Srgrimes if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len)) 43577274Smikeh return -1; 4361590Srgrimes 4371590Srgrimes len++,len&=~1; /* paranoia */ 43877274Smikeh name[len/sizeof(WCHAR)]=L'\0'; /* paranoia */ 4391590Srgrimes#if 1 4401590Srgrimes /* This doesn't cover "interactive" services [working with real 4411590Srgrimes * WinSta0's] nor programs started non-interactively by Task 4421590Srgrimes * Scheduler [those are working with SAWinSta]. */ 4431590Srgrimes if (wcsstr(name,L"Service-0x")) return 1; 4441590Srgrimes#else 4451590Srgrimes /* This covers all non-interactive programs such as services. */ 4461590Srgrimes if (!wcsstr(name,L"WinSta0")) return 1; 4471590Srgrimes#endif 4481590Srgrimes else return 0; 4491590Srgrimes} 45077274Smikeh#else 4511590Srgrimesint OPENSSL_isservice(void) { return 0; } 4521590Srgrimes#endif 45377274Smikeh 45477274Smikehvoid OPENSSL_showfatal (const char *fmta,...) 4551590Srgrimes{ va_list ap; 45677274Smikeh TCHAR buf[256]; 4571590Srgrimes const TCHAR *fmt; 45877274Smikeh#ifdef STD_ERROR_HANDLE /* what a dirty trick! */ 4591590Srgrimes HANDLE h; 46077274Smikeh 4611590Srgrimes if ((h=GetStdHandle(STD_ERROR_HANDLE)) != NULL && 4621590Srgrimes GetFileType(h)!=FILE_TYPE_UNKNOWN) 4631590Srgrimes { /* must be console application */ 4641590Srgrimes va_start (ap,fmta); 4651590Srgrimes vfprintf (stderr,fmta,ap); 4661590Srgrimes va_end (ap); 4671590Srgrimes return; 4681590Srgrimes } 4691590Srgrimes#endif 4701590Srgrimes 4711590Srgrimes if (sizeof(TCHAR)==sizeof(char)) 4721590Srgrimes fmt=(const TCHAR *)fmta; 4731590Srgrimes else do 47477274Smikeh { int keepgoing; 4751590Srgrimes size_t len_0=strlen(fmta)+1,i; 47677274Smikeh WCHAR *fmtw; 4771590Srgrimes 47877274Smikeh#ifdef _MSC_VER 4791590Srgrimes fmtw = (WCHAR *)_alloca (len_0*sizeof(WCHAR)); 48077274Smikeh#else 48177274Smikeh fmtw = (WCHAR *)alloca (len_0*sizeof(WCHAR)); 4821590Srgrimes#endif 4831590Srgrimes if (fmtw == NULL) { fmt=(const TCHAR *)L"no stack?"; break; } 4841590Srgrimes 4851590Srgrimes#ifndef OPENSSL_NO_MULTIBYTE 4861590Srgrimes if (!MultiByteToWideChar(CP_ACP,0,fmta,len_0,fmtw,len_0)) 4871590Srgrimes#endif 4881590Srgrimes for (i=0;i<len_0;i++) fmtw[i]=(WCHAR)fmta[i]; 4891590Srgrimes 49077274Smikeh for (i=0;i<len_0;i++) 4911590Srgrimes { if (fmtw[i]==L'%') do 4921590Srgrimes { keepgoing=0; 4931590Srgrimes switch (fmtw[i+1]) 4941590Srgrimes { case L'0': case L'1': case L'2': case L'3': case L'4': 4951590Srgrimes case L'5': case L'6': case L'7': case L'8': case L'9': 49677274Smikeh case L'.': case L'*': 4971590Srgrimes case L'-': i++; keepgoing=1; break; 4981590Srgrimes case L's': fmtw[i+1]=L'S'; break; 4991590Srgrimes case L'S': fmtw[i+1]=L's'; break; 5001590Srgrimes case L'c': fmtw[i+1]=L'C'; break; 5011590Srgrimes case L'C': fmtw[i+1]=L'c'; break; 5021590Srgrimes } 5031590Srgrimes } while (keepgoing); 5041590Srgrimes } 5051590Srgrimes fmt = (const TCHAR *)fmtw; 5061590Srgrimes } while (0); 5071590Srgrimes 5081590Srgrimes va_start (ap,fmta); 5091590Srgrimes _vsntprintf (buf,sizeof(buf)/sizeof(TCHAR)-1,fmt,ap); 5101590Srgrimes buf [sizeof(buf)/sizeof(TCHAR)-1] = _T('\0'); 5111590Srgrimes va_end (ap); 5121590Srgrimes 5131590Srgrimes#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 5141590Srgrimes /* this -------------v--- guards NT-specific calls */ 5151590Srgrimes if (GetVersion() < 0x80000000 && OPENSSL_isservice() > 0) 5161590Srgrimes { HANDLE h = RegisterEventSource(0,_T("OPENSSL")); 5171590Srgrimes const TCHAR *pmsg=buf; 5181590Srgrimes ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0); 51977274Smikeh DeregisterEventSource(h); 5201590Srgrimes } 5211590Srgrimes else 52277274Smikeh#endif 5231590Srgrimes MessageBox (NULL,buf,_T("OpenSSL: FATAL"),MB_OK|MB_ICONSTOP); 5241590Srgrimes} 5251590Srgrimes#else 5261590Srgrimesvoid OPENSSL_showfatal (const char *fmta,...) 5271590Srgrimes{ va_list ap; 52877274Smikeh 5291590Srgrimes va_start (ap,fmta); 5301590Srgrimes vfprintf (stderr,fmta,ap); 5311590Srgrimes va_end (ap); 5321590Srgrimes} 5331590Srgrimesint OPENSSL_isservice (void) { return 0; } 5341590Srgrimes#endif 5351590Srgrimes 5361590Srgrimesvoid OpenSSLDie(const char *file,int line,const char *assertion) 5371590Srgrimes { 53877274Smikeh OPENSSL_showfatal( 5391590Srgrimes "%s(%d): OpenSSL internal error, assertion failed: %s\n", 5401590Srgrimes file,line,assertion); 5411590Srgrimes abort(); 5421590Srgrimes } 5431590Srgrimes 5441590Srgrimesvoid *OPENSSL_stderr(void) { return stderr; } 5451590Srgrimes