diff options
Diffstat (limited to 'src/lib/libssl/src/ms/uplink.c')
-rw-r--r-- | src/lib/libssl/src/ms/uplink.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/lib/libssl/src/ms/uplink.c b/src/lib/libssl/src/ms/uplink.c new file mode 100644 index 0000000000..7b7da08d47 --- /dev/null +++ b/src/lib/libssl/src/ms/uplink.c | |||
@@ -0,0 +1,116 @@ | |||
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 = _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... */ | ||
99 | LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5) | ||
100 | LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10) | ||
101 | LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15) | ||
102 | LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20) | ||
103 | LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) | ||
104 | void *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 | ||
115 | main() { UP_fprintf(UP_stdout,"hello, world!\n"); } | ||
116 | #endif | ||