3fc378aa0b
make it possible to produce for a unified binary build, which can be used with a variety of Win32 compilers.
168 lines
4.4 KiB
C
168 lines
4.4 KiB
C
#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
|