openssl/ms/uplink.c

169 lines
4.4 KiB
C
Raw Normal View History

#if defined(_WIN64) && !defined(UNICODE)
#define UNICODE
#endif
#if defined(UNICODE) && !defined(_UNICODE)
#define _UNICODE
#endif
#if defined(_UNICODE) && !defined(UNICODE)
#define UNICODE
#endif
#if defined(_MSC_VER) && !defined(_WIN32_WINNT)
#define _WIN32_WINNT 0x0333 /* 3.51 */
#endif
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <malloc.h>
#include "uplink.h"
#ifdef _MSC_VER
#pragma comment(lib,"delayimp")
/*
* CL command line should also be complemented with following:
*
* /link /delayload:advapi32.dll /delayload:user32.dll
*
* This is required if/as we want to support Win9x. With delayloaded
* DLLs in question all we have to do is to make sure NT-specific
* functions are not actually called under Win9x.
*/
#endif
#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
int IsService()
{ HWINSTA h;
DWORD len;
WCHAR *name;
GetDesktopWindow(); /* return value is ignored */
h = GetProcessWindowStation();
if (h==NULL) return -1;
if (GetUserObjectInformationW (h,UOI_NAME,NULL,0,&len) ||
GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
if (len>512) return -1; /* paranoia */
len++,len&=~1; /* paranoia */
#ifdef _MSC_VER
name=(WCHAR *)_alloca(len+sizeof(WCHAR));
#else
name=(WCHAR *)alloca(len+sizeof(WCHAR));
#endif
if (!GetUserObjectInformationW (h,UOI_NAME,name,len,&len))
return -1;
len++,len&=~1; /* paranoia */
name[len/sizeof(WCHAR)]=L'\0'; /* paranoia */
#if 1
/* This doesn't cover "interactive" services [working with real
* WinSta0's] nor programs started non-interactively by Task
* Scheduler [those are working with SAWinSta]. */
if (wcsstr(name,L"Service-0x")) return 1;
#else
/* This covers all non-interactive programs such as services. */
if (!wcsstr(name,L"WinSta0")) return 1;
#endif
else return 0;
}
#endif
static TCHAR msg[128];
static void unimplemented ()
{
#if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333
/* this -------------v--- guards NT-specific calls */
if (GetVersion() < 0x80000000 && IsService())
{ HANDLE h = RegisterEventSource(0,_T("OPENSSL"));
TCHAR *pmsg=msg;
ReportEvent(h,EVENTLOG_ERROR_TYPE,0,0,0,1,0,&pmsg,0);
DeregisterEventSource(h);
}
else
#endif
{ MSGBOXPARAMS m;
m.cbSize = sizeof(m);
m.hwndOwner = NULL;
m.lpszCaption = _T("OpenSSL: FATAL");
m.dwStyle = MB_OK;
m.hInstance = NULL;
m.lpszIcon = IDI_ERROR;
m.dwContextHelpId = 0;
m.lpfnMsgBoxCallback = NULL;
m.dwLanguageId = MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US);
m.lpszText = msg;
MessageBoxIndirect (&m);
}
ExitProcess (1);
}
void OPENSSL_Uplink (void **table, int index)
{ static HMODULE app=NULL;
static void **applinktable=NULL;
int len;
len = _stprintf (msg,_T("OPENSSL_Uplink(%p,%02X): "),table,index);
_tcscpy (msg+len,_T("unimplemented function"));
table [index] = unimplemented;
if (app==NULL && (app=GetModuleHandle(NULL))==NULL)
{ app=(HMODULE)-1; _tcscpy (msg+len,_T("no host application"));
return;
}
else if (app==(HMODULE)-1) { return; }
if (applinktable==NULL)
{ void**(*applink)();
applink=(void**(*)())GetProcAddress(app,"OPENSSL_Applink");
if (applink==NULL)
{ app=(HMODULE)-1; _tcscpy (msg+len,_T("no OPENSSL_Applink"));
return;
}
applinktable = (*applink)();
if (applinktable==NULL)
{ app=(HMODULE)-1; _tcscpy (msg+len,_T("no ApplinkTable"));
return;
}
}
if (index > (int)applinktable[0]) { return; }
if (applinktable[index]) table[index] = applinktable[index];
}
#if defined(_MSC_VER) && defined(_M_IX86)
#define LAZY(i) \
__declspec(naked) static void lazy##i () { \
_asm push i \
_asm push OFFSET OPENSSL_UplinkTable \
_asm call OPENSSL_Uplink \
_asm add esp,8 \
_asm jmp OPENSSL_UplinkTable+4*i }
#if APPLINK_MAX>20
#error "Add more stubs..."
#endif
/* make some in advance... */
LAZY(1) LAZY(2) LAZY(3) LAZY(4) LAZY(5)
LAZY(6) LAZY(7) LAZY(8) LAZY(9) LAZY(10)
LAZY(11) LAZY(12) LAZY(13) LAZY(14) LAZY(15)
LAZY(16) LAZY(17) LAZY(18) LAZY(19) LAZY(20)
void *OPENSSL_UplinkTable[] = {
(void *)APPLINK_MAX,
lazy1, lazy2, lazy3, lazy4, lazy5,
lazy6, lazy7, lazy8, lazy9, lazy10,
lazy11,lazy12,lazy13,lazy14,lazy15,
lazy16,lazy17,lazy18,lazy19,lazy20,
};
#endif
#ifdef SELFTEST
main() { UP_fprintf(UP_stdout,"hello, world!\n"); }
#endif