]>
Commit | Line | Data |
---|---|---|
ea1b02db | 1 | #if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE) |
3fc378aa AP |
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 | |
3fc378aa AP |
10 | |
11 | #include <windows.h> | |
12 | #include <tchar.h> | |
13 | #include <stdio.h> | |
3fc378aa | 14 | #include "uplink.h" |
ea1b02db | 15 | void OPENSSL_showfatal(const char *,...); |
3fc378aa AP |
16 | |
17 | static TCHAR msg[128]; | |
18 | ||
ea1b02db AP |
19 | static void unimplemented (void) |
20 | { OPENSSL_showfatal (sizeof(TCHAR)==sizeof(char)?"%s\n":"%S\n",msg); | |
3fc378aa AP |
21 | ExitProcess (1); |
22 | } | |
23 | ||
ea1b02db AP |
24 | void OPENSSL_Uplink (volatile void **table, int index) |
25 | { static HMODULE volatile apphandle=NULL; | |
26 | static void ** volatile applinktable=NULL; | |
3fc378aa | 27 | int len; |
ea1b02db AP |
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 { | |
b429c4cb AP |
43 | len = _sntprintf (msg,sizeof(msg)/sizeof(TCHAR), |
44 | _T("OPENSSL_Uplink(%p,%02X): "),table,index); | |
ea1b02db AP |
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; | |
3fc378aa | 54 | } |
ea1b02db AP |
55 | if ((h=apphandle)==(HMODULE)-1) /* revalidate */ |
56 | break; | |
57 | ||
3fc378aa | 58 | if (applinktable==NULL) |
ea1b02db AP |
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; | |
3fc378aa | 74 | } |
b7741110 AP |
75 | else |
76 | p = applinktable; | |
3fc378aa | 77 | |
ea1b02db AP |
78 | if (index > (int)p[0]) |
79 | break; | |
80 | ||
81 | if (p[index]) func = p[index]; | |
82 | } while (0); | |
3fc378aa | 83 | |
ea1b02db | 84 | table[index] = func; |
3fc378aa AP |
85 | } |
86 | ||
ea1b02db | 87 | #if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM) |
3fc378aa | 88 | #define LAZY(i) \ |
ea1b02db | 89 | __declspec(naked) static void lazy##i (void) { \ |
3fc378aa AP |
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 | ||
ea1b02db | 96 | #if APPLINK_MAX>25 |
3fc378aa AP |
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) | |
ea1b02db | 104 | LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) |
3fc378aa AP |
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, | |
ea1b02db | 111 | lazy21,lazy22,lazy23,lazy24,lazy25, |
3fc378aa AP |
112 | }; |
113 | #endif | |
114 | ||
115 | #ifdef SELFTEST | |
116 | main() { UP_fprintf(UP_stdout,"hello, world!\n"); } | |
117 | #endif |