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