OpenSSL  1.0.1c
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
uplink.c
Go to the documentation of this file.
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 = _sntprintf (msg,sizeof(msg)/sizeof(TCHAR),
44  _T("OPENSSL_Uplink(%p,%02X): "),table,index);
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;
54  }
55  if ((h=apphandle)==(HMODULE)-1) /* revalidate */
56  break;
57 
58  if (applinktable==NULL)
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;
74  }
75  else
76  p = applinktable;
77 
78  if (index > (int)p[0])
79  break;
80 
81  if (p[index]) func = p[index];
82  } while (0);
83 
84  table[index] = func;
85 }
86 
87 #if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM)
88 #define LAZY(i) \
89 __declspec(naked) static void lazy##i (void) { \
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 
96 #if APPLINK_MAX>25
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)
104 LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25)
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,
111  lazy21,lazy22,lazy23,lazy24,lazy25,
112 };
113 #endif
114 
115 #ifdef SELFTEST
116 main() { UP_fprintf(UP_stdout,"hello, world!\n"); }
117 #endif