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