#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 #include #include #include #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