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