1 | /*
|
---|
2 | * Copyright 2004-2019 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the OpenSSL license (the "License"). You may not use
|
---|
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 |
|
---|
10 | #if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE)
|
---|
11 | # define UNICODE
|
---|
12 | #endif
|
---|
13 | #if defined(UNICODE) && !defined(_UNICODE)
|
---|
14 | # define _UNICODE
|
---|
15 | #endif
|
---|
16 | #if defined(_UNICODE) && !defined(UNICODE)
|
---|
17 | # define UNICODE
|
---|
18 | #endif
|
---|
19 |
|
---|
20 | #include <windows.h>
|
---|
21 | #include <tchar.h>
|
---|
22 | #include <stdio.h>
|
---|
23 | #include "uplink.h"
|
---|
24 | void OPENSSL_showfatal(const char *, ...);
|
---|
25 |
|
---|
26 | static TCHAR msg[128];
|
---|
27 |
|
---|
28 | static void unimplemented(void)
|
---|
29 | {
|
---|
30 | OPENSSL_showfatal(sizeof(TCHAR) == sizeof(char) ? "%s\n" : "%S\n", msg);
|
---|
31 | TerminateProcess(GetCurrentProcess(), 1);
|
---|
32 | }
|
---|
33 |
|
---|
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;
|
---|
42 |
|
---|
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 | */
|
---|
57 | do {
|
---|
58 | len = _sntprintf(msg, sizeof(msg) / sizeof(TCHAR),
|
---|
59 | _T("OPENSSL_Uplink(%p,%02X): "), table, index);
|
---|
60 | _tcscpy(msg + len, _T("unimplemented function"));
|
---|
61 |
|
---|
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;
|
---|
72 |
|
---|
73 | if (applinktable == NULL) {
|
---|
74 | void **(*applink) ();
|
---|
75 |
|
---|
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;
|
---|
91 |
|
---|
92 | if (index > (int)p[0])
|
---|
93 | break;
|
---|
94 |
|
---|
95 | if (p[index])
|
---|
96 | func = p[index];
|
---|
97 | } while (0);
|
---|
98 |
|
---|
99 | table[index] = func;
|
---|
100 | }
|
---|
101 |
|
---|
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 |
|
---|
130 | #ifdef SELFTEST
|
---|
131 | main()
|
---|
132 | {
|
---|
133 | UP_fprintf(UP_stdout, "hello, world!\n");
|
---|
134 | }
|
---|
135 | #endif
|
---|