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" 15 void OPENSSL_showfatal(const char *,...); 16 17 static TCHAR msg[128]; 18 19 static void unimplemented (void) 20 { OPENSSL_showfatal (sizeof(TCHAR)==sizeof(char)?"%s\n":"%S\n",msg); 21 ExitProcess (1); 22 } 23 24 void 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... */ 100 LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5) 101 LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10) 102 LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15) 103 LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20) 104 LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) 105 void *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 116 main() { UP_fprintf(UP_stdout,"hello, world!\n"); } 117 #endif 118