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 = _stprintf (msg,_T("OPENSSL_Uplink(%p,%02X): "),table,index); 44 _tcscpy (msg+len,_T("unimplemented function")); 45 46 if ((h=apphandle)==NULL) 47 { if ((h=GetModuleHandle(NULL))==NULL) 48 { apphandle=(HMODULE)-1; 49 _tcscpy (msg+len,_T("no host application")); 50 break; 51 } 52 apphandle = h; 53 } 54 if ((h=apphandle)==(HMODULE)-1) /* revalidate */ 55 break; 56 57 if (applinktable==NULL) 58 { void**(*applink)(); 59 60 applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink"); 61 if (applink==NULL) 62 { apphandle=(HMODULE)-1; 63 _tcscpy (msg+len,_T("no OPENSSL_Applink")); 64 break; 65 } 66 p = (*applink)(); 67 if (p==NULL) 68 { apphandle=(HMODULE)-1; 69 _tcscpy (msg+len,_T("no ApplinkTable")); 70 break; 71 } 72 applinktable = p; 73 } 74 else 75 p = applinktable; 76 77 if (index > (int)p[0]) 78 break; 79 80 if (p[index]) func = p[index]; 81 } while (0); 82 83 table[index] = func; 84 } 85 86 #if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM) 87 #define LAZY(i) \ 88 __declspec(naked) static void lazy##i (void) { \ 89 _asm push i \ 90 _asm push OFFSET OPENSSL_UplinkTable \ 91 _asm call OPENSSL_Uplink \ 92 _asm add esp,8 \ 93 _asm jmp OPENSSL_UplinkTable+4*i } 94 95 #if APPLINK_MAX>25 96 #error "Add more stubs..." 97 #endif 98 /* make some in advance... */ 99 LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5) 100 LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10) 101 LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15) 102 LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20) 103 LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) 104 void *OPENSSL_UplinkTable[] = { 105 (void *)APPLINK_MAX, 106 lazy1, lazy2, lazy3, lazy4, lazy5, 107 lazy6, lazy7, lazy8, lazy9, lazy10, 108 lazy11,lazy12,lazy13,lazy14,lazy15, 109 lazy16,lazy17,lazy18,lazy19,lazy20, 110 lazy21,lazy22,lazy23,lazy24,lazy25, 111 }; 112 #endif 113 114 #ifdef SELFTEST 115 main() { UP_fprintf(UP_stdout,"hello, world!\n"); } 116 #endif 117