]>
Commit | Line | Data |
---|---|---|
ea1b02db | 1 | #if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE) |
10621efd | 2 | # define UNICODE |
3fc378aa AP |
3 | #endif |
4 | #if defined(UNICODE) && !defined(_UNICODE) | |
10621efd | 5 | # define _UNICODE |
3fc378aa AP |
6 | #endif |
7 | #if defined(_UNICODE) && !defined(UNICODE) | |
10621efd | 8 | # define UNICODE |
3fc378aa | 9 | #endif |
3fc378aa AP |
10 | |
11 | #include <windows.h> | |
12 | #include <tchar.h> | |
13 | #include <stdio.h> | |
3fc378aa | 14 | #include "uplink.h" |
10621efd | 15 | void OPENSSL_showfatal(const char *, ...); |
3fc378aa AP |
16 | |
17 | static TCHAR msg[128]; | |
18 | ||
10621efd MC |
19 | static void unimplemented(void) |
20 | { | |
21 | OPENSSL_showfatal(sizeof(TCHAR) == sizeof(char) ? "%s\n" : "%S\n", msg); | |
22 | ExitProcess(1); | |
3fc378aa AP |
23 | } |
24 | ||
10621efd MC |
25 | void 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; | |
ea1b02db | 33 | |
10621efd MC |
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 | */ | |
ea1b02db | 48 | do { |
10621efd MC |
49 | len = _sntprintf(msg, sizeof(msg) / sizeof(TCHAR), |
50 | _T("OPENSSL_Uplink(%p,%02X): "), table, index); | |
51 | _tcscpy(msg + len, _T("unimplemented function")); | |
ea1b02db | 52 | |
10621efd MC |
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; | |
ea1b02db | 63 | |
10621efd MC |
64 | if (applinktable == NULL) { |
65 | void **(*applink) (); | |
ea1b02db | 66 | |
10621efd MC |
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; | |
3fc378aa | 82 | |
10621efd MC |
83 | if (index > (int)p[0]) |
84 | break; | |
ea1b02db | 85 | |
10621efd MC |
86 | if (p[index]) |
87 | func = p[index]; | |
ea1b02db | 88 | } while (0); |
3fc378aa | 89 | |
ea1b02db | 90 | table[index] = func; |
10621efd | 91 | } |
3fc378aa | 92 | |
ea1b02db | 93 | #if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM) |
10621efd MC |
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 } | |
3fc378aa | 101 | |
10621efd MC |
102 | # if APPLINK_MAX>25 |
103 | # error "Add more stubs..." | |
104 | # endif | |
3fc378aa | 105 | /* make some in advance... */ |
10621efd MC |
106 | LAZY(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) | |
3fc378aa | 111 | void *OPENSSL_UplinkTable[] = { |
10621efd MC |
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, | |
3fc378aa AP |
118 | }; |
119 | #endif | |
120 | ||
121 | #ifdef SELFTEST | |
10621efd MC |
122 | main() |
123 | { | |
124 | UP_fprintf(UP_stdout, "hello, world!\n"); | |
125 | } | |
3fc378aa | 126 | #endif |