xref: /minix/crypto/external/bsd/openssl/dist/ms/uplink.c (revision ebfedea0)
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