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