c839f9b0874e5c8eb64bbe935949e157c39db890
[openssl.git] / ms / uplink.c
1 #if defined(_WIN64) && !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 #if defined(_MSC_VER) && !defined(_WIN32_WINNT)
11 #define _WIN32_WINNT 0x0333     /* 3.51 */
12 #endif
13
14 #include <windows.h>
15 #include <tchar.h>
16 #include <stdio.h>
17 #include <malloc.h>
18 #include "uplink.h"
19
20 #ifdef _MSC_VER
21 #pragma comment(lib,"delayimp")
22 /*
23  * CL command line should also be complemented with following:
24  *
25  *      /link /delayload:advapi32.dll /delayload:user32.dll
26  *
27  * This is required if/as we want to support Win9x. With delayloaded
28  * DLLs in question all we have to do is to make sure NT-specific
29  * functions are not actually called under Win9x.
30  */
31 #endif
32
33 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
34 int IsService()
35 { HWINSTA h;
36   DWORD len;
37   WCHAR *name;
38
39     GetDesktopWindow(); /* return value is ignored */
40
41     h = GetProcessWindowStation();
42     if (h==NULL) return -1;
43
44     if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
45         GetLastError() != ERROR_INSUFFICIENT_BUFFER)
46         return -1;
47
48     if (len>512) return -1;             /* paranoia */
49     len++,len&=~1;                      /* paranoia */
50 #ifdef _MSC_VER
51     name=(WCHAR *)_alloca(len+sizeof(WCHAR));
52 #else
53     name=(WCHAR *)alloca(len+sizeof(WCHAR));
54 #endif
55     if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
56         return -1;
57
58     len++,len&=~1;                      /* paranoia */
59     name[len/sizeof(WCHAR)]=L'\0';      /* paranoia */
60 #if 1
61     /* This doesn't cover "interactive" services [working with real
62      * WinSta0's] nor programs started non-interactively by Task
63      * Scheduler [those are working with SAWinSta]. */
64     if (wcsstr(name,L"Service-0x"))     return 1;
65 #else
66     /* This covers all non-interactive programs such as services. */
67     if (!wcsstr(name,L"WinSta0"))       return 1;
68 #endif
69     else                                return 0;
70 }
71 #endif
72
73 static TCHAR msg[128];
74
75 static void unimplemented ()
76 {
77 #if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
78     /* this -------------v--- guards NT-specific calls */
79     if (GetVersion() < 0x80000000 && IsService())
80     {   HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
81         TCHAR *pmsg=msg;
82         ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
83         DeregisterEventSource(h);
84     }
85     else
86 #endif
87     {   MSGBOXPARAMS         m;
88
89         m.cbSize             = sizeof(m);
90         m.hwndOwner          = NULL;
91         m.lpszCaption        = _T("OpenSSL: FATAL");
92         m.dwStyle            = MB_OK;
93         m.hInstance          = NULL;
94         m.lpszIcon           = IDI_ERROR;
95         m.dwContextHelpId    = 0;
96         m.lpfnMsgBoxCallback = NULL;
97         m.dwLanguageId       = MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
98         m.lpszText           = msg;
99
100         MessageBoxIndirect (&m);
101     }
102     ExitProcess (1);
103 }
104
105 void OPENSSL_Uplink (void **table, int index)
106 { static HMODULE app=NULL;
107   static void **applinktable=NULL;
108   int len;
109
110     len = _stprintf (msg,_T("OPENSSL_Uplink(%p,%02X): "),table,index);
111     _tcscpy (msg+len,_T("unimplemented function"));
112     table [index] = unimplemented;
113
114     if (app==NULL && (app=GetModuleHandle(NULL))==NULL)
115     {   app=(HMODULE)-1; _tcscpy (msg+len,_T("no host application"));
116         return;
117     }
118     else if (app==(HMODULE)-1)  { return; }
119
120     if (applinktable==NULL)
121     { void**(*applink)();
122
123         applink=(void**(*)())GetProcAddress(app,"OPENSSL_Applink");
124         if (applink==NULL)
125         {   app=(HMODULE)-1; _tcscpy (msg+len,_T("no OPENSSL_Applink"));
126             return;
127         }
128         applinktable = (*applink)();
129         if (applinktable==NULL)
130         {   app=(HMODULE)-1; _tcscpy (msg+len,_T("no ApplinkTable"));
131             return;
132         }
133     }
134
135     if (index > (int)applinktable[0])   { return; }
136
137     if (applinktable[index]) table[index] = applinktable[index];
138 }    
139
140 #if defined(_MSC_VER) && defined(_M_IX86)
141 #define LAZY(i)         \
142 __declspec(naked) static void lazy##i () {      \
143         _asm    push i                          \
144         _asm    push OFFSET OPENSSL_UplinkTable \
145         _asm    call OPENSSL_Uplink             \
146         _asm    add  esp,8                      \
147         _asm    jmp  OPENSSL_UplinkTable+4*i    }
148
149 #if APPLINK_MAX>20
150 #error "Add more stubs..."
151 #endif
152 /* make some in advance... */
153 LAZY(1)  LAZY(2)  LAZY(3)  LAZY(4)  LAZY(5)
154 LAZY(6)  LAZY(7)  LAZY(8)  LAZY(9)  LAZY(10)
155 LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15)
156 LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20)
157 void *OPENSSL_UplinkTable[] = {
158         (void *)APPLINK_MAX,
159         lazy1, lazy2, lazy3, lazy4, lazy5,
160         lazy6, lazy7, lazy8, lazy9, lazy10,
161         lazy11,lazy12,lazy13,lazy14,lazy15,
162         lazy16,lazy17,lazy18,lazy19,lazy20,
163 };
164 #endif
165
166 #ifdef SELFTEST
167 main() {  UP_fprintf(UP_stdout,"hello, world!\n"); }
168 #endif