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 = _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... */ 99LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5) 100LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10) 101LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15) 102LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20) 103LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) 104void *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 115main() { UP_fprintf(UP_stdout,"hello, world!\n"); } 116#endif 117