1#if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE) 2#define UNICODE 3#endif 4#if defined(UNICODE) && !defined(_UNICODE) 5#define _UNICODE 6#endif 7#if defined(_UNICODE) && !defined(UNICODE) 8#define UNICODE 9#endif 10 11#include <windows.h> 12#include <tchar.h> 13#include <stdio.h> 14#include "uplink.h" 15void OPENSSL_showfatal(const char *,...); 16 17static TCHAR msg[128]; 18 19static void unimplemented (void) 20{ OPENSSL_showfatal (sizeof(TCHAR)==sizeof(char)?"%s\n":"%S\n",msg); 21 ExitProcess (1); 22} 23 24void OPENSSL_Uplink (volatile void **table, int index) 25{ static HMODULE volatile apphandle=NULL; 26 static void ** volatile applinktable=NULL; 27 int len; 28 void (*func)(void)=unimplemented; 29 HANDLE h; 30 void **p; 31 32 /* Note that the below code is not MT-safe in respect to msg 33 * buffer, but what's the worst thing that can happen? Error 34 * message might be misleading or corrupted. As error condition 35 * is fatal and should never be risen, I accept the risk... */ 36 /* One can argue that I should have used InterlockedExchangePointer 37 * or something to update static variables and table[]. Well, 38 * store instructions are as atomic as they can get and assigned 39 * values are effectively constant... So that volatile qualifier 40 * should be sufficient [it prohibits compiler to reorder memory 41 * access instructions]. */ 42 do { 43 len = _sntprintf (msg,sizeof(msg)/sizeof(TCHAR), 44 _T("OPENSSL_Uplink(%p,%02X): "),table,index); 45 _tcscpy (msg+len,_T("unimplemented function")); 46 47 if ((h=apphandle)==NULL) 48 { if ((h=GetModuleHandle(NULL))==NULL) 49 { apphandle=(HMODULE)-1; 50 _tcscpy (msg+len,_T("no host application")); 51 break; 52 } 53 apphandle = h; 54 } 55 if ((h=apphandle)==(HMODULE)-1) /* revalidate */ 56 break; 57 58 if (applinktable==NULL) 59 { void**(*applink)(); 60 61 applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink"); 62 if (applink==NULL) 63 { apphandle=(HMODULE)-1; 64 _tcscpy (msg+len,_T("no OPENSSL_Applink")); 65 break; 66 } 67 p = (*applink)(); 68 if (p==NULL) 69 { apphandle=(HMODULE)-1; 70 _tcscpy (msg+len,_T("no ApplinkTable")); 71 break; 72 } 73 applinktable = p; 74 } 75 else 76 p = applinktable; 77 78 if (index > (int)p[0]) 79 break; 80 81 if (p[index]) func = p[index]; 82 } while (0); 83 84 table[index] = func; 85} 86 87#if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM) 88#define LAZY(i) \ 89__declspec(naked) static void lazy##i (void) { \ 90 _asm push i \ 91 _asm push OFFSET OPENSSL_UplinkTable \ 92 _asm call OPENSSL_Uplink \ 93 _asm add esp,8 \ 94 _asm jmp OPENSSL_UplinkTable+4*i } 95 96#if APPLINK_MAX>25 97#error "Add more stubs..." 98#endif 99/* make some in advance... */ 100LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5) 101LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10) 102LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15) 103LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20) 104LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) 105void *OPENSSL_UplinkTable[] = { 106 (void *)APPLINK_MAX, 107 lazy1, lazy2, lazy3, lazy4, lazy5, 108 lazy6, lazy7, lazy8, lazy9, lazy10, 109 lazy11,lazy12,lazy13,lazy14,lazy15, 110 lazy16,lazy17,lazy18,lazy19,lazy20, 111 lazy21,lazy22,lazy23,lazy24,lazy25, 112}; 113#endif 114 115#ifdef SELFTEST 116main() { UP_fprintf(UP_stdout,"hello, world!\n"); } 117#endif 118