From ea1b02db6ab4864befde88ed03099f075cf7db76 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 17 May 2005 00:08:28 +0000 Subject: OPENSSL_Applink update. --- ms/applink.c | 44 +++++++++++++-- ms/uplink.c | 176 +++++++++++++++++++++-------------------------------------- ms/uplink.h | 25 +++++++-- ms/uplink.pl | 31 ++++++++++- 4 files changed, 148 insertions(+), 128 deletions(-) (limited to 'ms') diff --git a/ms/applink.c b/ms/applink.c index 4333d2639d..e2d066bc1e 100644 --- a/ms/applink.c +++ b/ms/applink.c @@ -8,21 +8,38 @@ #define APPLINK_FSETMOD 8 #define APPLINK_FEOF 9 #define APPLINK_FCLOSE 10 /* should not be used */ -#define APPLINK_MAX 10 /* always same as last macro */ + +#define APPLINK_FOPEN 11 /* solely for completeness */ +#define APPLINK_FSEEK 12 +#define APPLINK_FTELL 13 +#define APPLINK_FFLUSH 14 +#define APPLINK_FERROR 15 +#define APPLINK_CLEARERR 16 +#define APPLINK_FILENO 17 /* to be used with below */ + +#define APPLINK_OPEN 18 /* formally can't be used, as flags can vary */ +#define APPLINK_READ 19 +#define APPLINK_WRITE 20 +#define APPLINK_LSEEK 21 +#define APPLINK_CLOSE 22 +#define APPLINK_MAX 22 /* always same as last macro */ #ifndef APPMACROS_ONLY #include #include #include -static void *app_stdin() { return stdin; } -static void *app_stdout() { return stdout; } -static void *app_stderr() { return stderr; } -static int app_feof(FILE *fp) { return feof(fp); } +static void *app_stdin(void) { return stdin; } +static void *app_stdout(void) { return stdout; } +static void *app_stderr(void) { return stderr; } +static int app_feof(FILE *fp) { return feof(fp); } +static int app_ferror(FILE *fp) { return ferror(fp); } +static void app_clearerr(FILE *fp) { clearerr(fp); } +static int app_fileno(FILE *fp) { return _fileno(fp); } static int app_fsetmod(FILE *fp,char mod) { return _setmode (_fileno(fp),mod=='b'?_O_BINARY:_O_TEXT); } -__declspec(dllexport) void **OPENSSL_Applink() +__declspec(dllexport) void **OPENSSL_Applink(void) { static int once=1; static void *OPENSSL_ApplinkTable[APPLINK_MAX+1]={(void *)APPLINK_MAX}; @@ -37,6 +54,21 @@ __declspec(dllexport) void **OPENSSL_Applink() OPENSSL_ApplinkTable[APPLINK_FSETMOD] = app_fsetmod; OPENSSL_ApplinkTable[APPLINK_FEOF] = app_feof; OPENSSL_ApplinkTable[APPLINK_FCLOSE] = fclose; + + OPENSSL_ApplinkTable[APPLINK_FOPEN] = fopen; + OPENSSL_ApplinkTable[APPLINK_FSEEK] = fseek; + OPENSSL_ApplinkTable[APPLINK_FTELL] = ftell; + OPENSSL_ApplinkTable[APPLINK_FFLUSH] = fflush; + OPENSSL_ApplinkTable[APPLINK_FERROR] = app_ferror; + OPENSSL_ApplinkTable[APPLINK_CLEARERR] = app_clearerr; + OPENSSL_ApplinkTable[APPLINK_FILENO] = app_fileno; + + OPENSSL_ApplinkTable[APPLINK_OPEN] = _open; + OPENSSL_ApplinkTable[APPLINK_READ] = _read; + OPENSSL_ApplinkTable[APPLINK_WRITE] = _write; + OPENSSL_ApplinkTable[APPLINK_LSEEK] = _lseek; + OPENSSL_ApplinkTable[APPLINK_CLOSE] = _close; + once = 0; } diff --git a/ms/uplink.c b/ms/uplink.c index c839f9b087..8e2eaa8ffd 100644 --- a/ms/uplink.c +++ b/ms/uplink.c @@ -1,4 +1,4 @@ -#if defined(_WIN64) && !defined(UNICODE) +#if (defined(_WIN64) || defined(_WIN32_WCE)) && !defined(UNICODE) #define UNICODE #endif #if defined(UNICODE) && !defined(_UNICODE) @@ -7,146 +7,90 @@ #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 +void OPENSSL_showfatal(const char *,...); 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); - } +static void unimplemented (void) +{ OPENSSL_showfatal (sizeof(TCHAR)==sizeof(char)?"%s\n":"%S\n",msg); ExitProcess (1); } -void OPENSSL_Uplink (void **table, int index) -{ static HMODULE app=NULL; - static void **applinktable=NULL; +void OPENSSL_Uplink (volatile void **table, int index) +{ static HMODULE volatile apphandle=NULL; + static void ** volatile 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; + void (*func)(void)=unimplemented; + HANDLE h; + void **p; + + /* Note that the below code is not MT-safe in respect to msg + * buffer, but what's the worst thing that can happen? Error + * message might be misleading or corrupted. As error condition + * is fatal and should never be risen, I accept the risk... */ + /* One can argue that I should have used InterlockedExchangePointer + * or something to update static variables and table[]. Well, + * store instructions are as atomic as they can get and assigned + * values are effectively constant... So that volatile qualifier + * should be sufficient [it prohibits compiler to reorder memory + * access instructions]. */ + do { + len = _stprintf (msg,_T("OPENSSL_Uplink(%p,%02X): "),table,index); + _tcscpy (msg+len,_T("unimplemented function")); + + if ((h=apphandle)==NULL) + { if ((h=GetModuleHandle(NULL))==NULL) + { apphandle=(HMODULE)-1; + _tcscpy (msg+len,_T("no host application")); + break; + } + apphandle = h; } - applinktable = (*applink)(); + if ((h=apphandle)==(HMODULE)-1) /* revalidate */ + break; + if (applinktable==NULL) - { app=(HMODULE)-1; _tcscpy (msg+len,_T("no ApplinkTable")); - return; + { void**(*applink)(); + + applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink"); + if (applink==NULL) + { apphandle=(HMODULE)-1; + _tcscpy (msg+len,_T("no OPENSSL_Applink")); + break; + } + p = (*applink)(); + if (p==NULL) + { apphandle=(HMODULE)-1; + _tcscpy (msg+len,_T("no ApplinkTable")); + break; + } + applinktable = p; } - } - if (index > (int)applinktable[0]) { return; } + if (index > (int)p[0]) + break; + + if (p[index]) func = p[index]; + } while (0); - if (applinktable[index]) table[index] = applinktable[index]; + table[index] = func; } -#if defined(_MSC_VER) && defined(_M_IX86) +#if defined(_MSC_VER) && defined(_M_IX86) && !defined(OPENSSL_NO_INLINE_ASM) #define LAZY(i) \ -__declspec(naked) static void lazy##i () { \ +__declspec(naked) static void lazy##i (void) { \ _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 +#if APPLINK_MAX>25 #error "Add more stubs..." #endif /* make some in advance... */ @@ -154,12 +98,14 @@ 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) +LAZY(21) LAZY(22) LAZY(23) LAZY(24) LAZY(25) 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, + lazy21,lazy22,lazy23,lazy24,lazy25, }; #endif diff --git a/ms/uplink.h b/ms/uplink.h index 3e9911ab93..a4a67d3c14 100644 --- a/ms/uplink.h +++ b/ms/uplink.h @@ -2,13 +2,28 @@ #include "applink.c" extern void *OPENSSL_UplinkTable[]; -#define UP_stdin (*(void *(*)())OPENSSL_UplinkTable[APPLINK_STDIN])() -#define UP_stdout (*(void *(*)())OPENSSL_UplinkTable[APPLINK_STDOUT])() -#define UP_stderr (*(void *(*)())OPENSSL_UplinkTable[APPLINK_STDERR])() + +#define UP_stdin (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDIN])() +#define UP_stdout (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDOUT])() +#define UP_stderr (*(void *(*)(void))OPENSSL_UplinkTable[APPLINK_STDERR])() #define UP_fprintf (*(int (*)(void *,const char *,...))OPENSSL_UplinkTable[APPLINK_FPRINTF]) #define UP_fgets (*(char *(*)(char *,int,void *))OPENSSL_UplinkTable[APPLINK_FGETS]) #define UP_fread (*(size_t (*)(void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FREAD]) -#define UP_fwrite (*(size_t (*)(void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FWRITE]) +#define UP_fwrite (*(size_t (*)(const void *,size_t,size_t,void *))OPENSSL_UplinkTable[APPLINK_FWRITE]) #define UP_fsetmod (*(int (*)(void *,char))OPENSSL_UplinkTable[APPLINK_FSETMOD]) #define UP_feof (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FEOF]) -#define UP_fclose (*(int (*)(void *))OPENSSL_Uplink[APPLINK_FCLOSE]) +#define UP_fclose (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FCLOSE]) + +#define UP_fopen (*(void *(*)(const char *,const char *))OPENSSL_UplinkTable[APPLINK_FOPEN]) +#define UP_fseek (*(int (*)(void *,long,int))OPENSSL_UplinkTable[APPLINK_FSEEK]) +#define UP_ftell (*(long (*)(void *))OPENSSL_UplinkTable[APPLINK_FTELL]) +#define UP_fflush (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FFLUSH]) +#define UP_ferror (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FERROR]) +#define UP_clearerr (*(void (*)(void *))OPENSSL_UplinkTable[APPLINK_CLEARERR]) +#define UP_fileno (*(int (*)(void *))OPENSSL_UplinkTable[APPLINK_FILENO]) + +#define UP_open (*(int (*)(const char *,int,...))OPENSSL_UplinkTable[APPLINK_OPEN]) +#define UP_read (*(ssize_t (*)(int,void *,size_t))OPENSSL_UplinkTable[APPLINK_READ]) +#define UP_write (*(ssize_t (*)(int,const void *,size_t))OPENSSL_UplinkTable[APPLINK_WRITE]) +#define UP_lseek (*(long (*)(int,long,int))OPENSSL_UplinkTable[APPLINK_LSEEK]) +#define UP_close (*(int (*)(int))OPENSSL_UplinkTable[APPLINK_CLOSE]) diff --git a/ms/uplink.pl b/ms/uplink.pl index 801f6e01fa..cd9d37f56f 100755 --- a/ms/uplink.pl +++ b/ms/uplink.pl @@ -29,10 +29,37 @@ $arg = shift; if ($arg =~ /win32n/) { ia32nasm(); } elsif ($arg =~ /win32/) { ia32masm(); } -elsif ($arg =~ /ia64/) { ia64ias(); } -elsif ($arg =~ /amd64/) { amd64masm(); } +elsif ($arg =~ /coff/) { ia32gas(); } +elsif ($arg =~ /win64i/ or $arg =~ /ia64/) { ia64ias(); } +elsif ($arg =~ /win64a/ or $arg =~ /amd64/) { amd64masm(); } else { die "nonsense $arg"; } +sub ia32gas() { +print <<___; +.text +___ +for ($i=1;$i<=$N;$i++) { +print <<___; +.def .Lazy$i; .scl 3; .type 32; .endef +.align 4 +.Lazy$i: + pushl \$$i + pushl _OPENSSL_UplinkTable + call _OPENSSL_Uplink + addl \$8,%esp + jmp *(_OPENSSL_UplinkTable+4*$i) +___ +} +print <<___; +.data +.align 4 +.globl _OPENSSL_UplinkTable +_OPENSSL_UplinkTable: + .long $N +___ +for ($i=1;$i<=$N;$i++) { print " .long .Lazy$i\n"; } +} + sub ia32masm() { print <<___; .386P -- cgit v1.2.3