OPENSSL_Applink update.
This commit is contained in:
parent
2c4b354d32
commit
ea1b02db6a
11 changed files with 257 additions and 150 deletions
|
@ -79,7 +79,6 @@
|
|||
#include <openssl/x509v3.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/pem.h>
|
||||
#include "../crypto/cryptlib.h"
|
||||
|
||||
#define SECTION "req"
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/bio.h>
|
||||
#include "bio_lcl.h"
|
||||
|
||||
#define TRUNCATE
|
||||
#define DUMP_WIDTH 16
|
||||
|
@ -160,7 +160,7 @@ int BIO_dump_indent_cb(int (*cb)(const void *data, size_t len, void *u),
|
|||
#ifndef OPENSSL_NO_FP_API
|
||||
static int write_fp(const void *data, size_t len, void *fp)
|
||||
{
|
||||
return fwrite(data, len, 1, (FILE *)fp);
|
||||
return UP_fwrite(data, len, 1, fp);
|
||||
}
|
||||
int BIO_dump_fp(FILE *fp, const char *s, int len)
|
||||
{
|
||||
|
|
|
@ -169,6 +169,11 @@ extern "C" {
|
|||
#define BIO_FLAGS_IO_SPECIAL 0x04
|
||||
#define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL)
|
||||
#define BIO_FLAGS_SHOULD_RETRY 0x08
|
||||
#ifndef BIO_FLAGS_UPLINK
|
||||
/* "UPLINK" flag denotes file descriptors provided by application.
|
||||
It defaults to 0, as most platforms don't require UPLINK interface. */
|
||||
#define BIO_FLAGS_UPLINK 0
|
||||
#endif
|
||||
|
||||
/* Used in BIO_gethostbyname() */
|
||||
#define BIO_GHBN_CTRL_HITS 1
|
||||
|
|
28
crypto/bio/bio_lcl.h
Normal file
28
crypto/bio/bio_lcl.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <openssl/bio.h>
|
||||
|
||||
#if BIO_FLAGS_UPLINK==0
|
||||
/* Shortcut UPLINK calls on most platforms... */
|
||||
#define UP_stdin stdin
|
||||
#define UP_stdout stdout
|
||||
#define UP_stderr stderr
|
||||
#define UP_fprintf fprintf
|
||||
#define UP_fgets fgets
|
||||
#define UP_fread fread
|
||||
#define UP_fwrite fwrite
|
||||
#undef UP_fsetmod
|
||||
#define UP_feof feof
|
||||
#define UP_fclose fclose
|
||||
|
||||
#define UP_fopen fopen
|
||||
#define UP_fseek fseek
|
||||
#define UP_ftell ftell
|
||||
#define UP_fflush fflush
|
||||
#define UP_ferror ferror
|
||||
#define UP_fileno fileno
|
||||
|
||||
#define UP_open open
|
||||
#define UP_read read
|
||||
#define UP_write write
|
||||
#define UP_lseek lseek
|
||||
#define UP_close close
|
||||
#endif
|
|
@ -60,7 +60,19 @@
|
|||
#include <errno.h>
|
||||
#define USE_SOCKETS
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/bio.h>
|
||||
/*
|
||||
* As for unconditional usage of "UPLINK" interface in this module.
|
||||
* Trouble is that unlike Unix file descriptors [which are indexes
|
||||
* in kernel-side per-process table], corresponding descriptors on
|
||||
* platforms which require "UPLINK" interface seem to be indexes
|
||||
* in a user-land, non-global table. Well, in fact they are indexes
|
||||
* in stdio _iob[], and recall that _iob[] was the very reason why
|
||||
* "UPLINK" interface was introduced in first place. But one way on
|
||||
* another. Neither libcrypto or libssl use this BIO meaning that
|
||||
* file descriptors can only be provided by application. Therefore
|
||||
* "UPLINK" calls are due...
|
||||
*/
|
||||
#include "bio_lcl.h"
|
||||
|
||||
static int fd_write(BIO *h, const char *buf, int num);
|
||||
static int fd_read(BIO *h, char *buf, int size);
|
||||
|
@ -100,9 +112,9 @@ BIO *BIO_new_fd(int fd,int close_flag)
|
|||
static int fd_new(BIO *bi)
|
||||
{
|
||||
bi->init=0;
|
||||
bi->num=0;
|
||||
bi->num=-1;
|
||||
bi->ptr=NULL;
|
||||
bi->flags=0;
|
||||
bi->flags=BIO_FLAGS_UPLINK; /* essentially redundant */
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -113,10 +125,10 @@ static int fd_free(BIO *a)
|
|||
{
|
||||
if (a->init)
|
||||
{
|
||||
close(a->num);
|
||||
UP_close(a->num);
|
||||
}
|
||||
a->init=0;
|
||||
a->flags=0;
|
||||
a->flags=BIO_FLAGS_UPLINK;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
@ -128,7 +140,7 @@ static int fd_read(BIO *b, char *out,int outl)
|
|||
if (out != NULL)
|
||||
{
|
||||
clear_sys_error();
|
||||
ret=read(b->num,out,outl);
|
||||
ret=UP_read(b->num,out,outl);
|
||||
BIO_clear_retry_flags(b);
|
||||
if (ret <= 0)
|
||||
{
|
||||
|
@ -143,7 +155,7 @@ static int fd_write(BIO *b, const char *in, int inl)
|
|||
{
|
||||
int ret;
|
||||
clear_sys_error();
|
||||
ret=write(b->num,in,inl);
|
||||
ret=UP_write(b->num,in,inl);
|
||||
BIO_clear_retry_flags(b);
|
||||
if (ret <= 0)
|
||||
{
|
||||
|
@ -163,11 +175,11 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||
case BIO_CTRL_RESET:
|
||||
num=0;
|
||||
case BIO_C_FILE_SEEK:
|
||||
ret=(long)lseek(b->num,num,0);
|
||||
ret=(long)UP_lseek(b->num,num,0);
|
||||
break;
|
||||
case BIO_C_FILE_TELL:
|
||||
case BIO_CTRL_INFO:
|
||||
ret=(long)lseek(b->num,0,1);
|
||||
ret=(long)UP_lseek(b->num,0,1);
|
||||
break;
|
||||
case BIO_C_SET_FD:
|
||||
fd_free(b);
|
||||
|
|
|
@ -68,7 +68,7 @@
|
|||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/bio.h>
|
||||
#include "bio_lcl.h"
|
||||
#include <openssl/err.h>
|
||||
|
||||
#if !defined(OPENSSL_NO_STDIO)
|
||||
|
@ -112,6 +112,7 @@ BIO *BIO_new_file(const char *filename, const char *mode)
|
|||
if ((ret=BIO_new(BIO_s_file_internal())) == NULL)
|
||||
return(NULL);
|
||||
|
||||
BIO_clear_flags(ret,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
|
||||
BIO_set_fp(ret,file,BIO_CLOSE);
|
||||
return(ret);
|
||||
}
|
||||
|
@ -123,6 +124,7 @@ BIO *BIO_new_fp(FILE *stream, int close_flag)
|
|||
if ((ret=BIO_new(BIO_s_file())) == NULL)
|
||||
return(NULL);
|
||||
|
||||
BIO_set_flags(ret,BIO_FLAGS_UPLINK); /* redundant, left for documentation puposes */
|
||||
BIO_set_fp(ret,stream,close_flag);
|
||||
return(ret);
|
||||
}
|
||||
|
@ -137,6 +139,7 @@ static int MS_CALLBACK file_new(BIO *bi)
|
|||
bi->init=0;
|
||||
bi->num=0;
|
||||
bi->ptr=NULL;
|
||||
bi->flags=BIO_FLAGS_UPLINK; /* default to UPLINK */
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -147,8 +150,12 @@ static int MS_CALLBACK file_free(BIO *a)
|
|||
{
|
||||
if ((a->init) && (a->ptr != NULL))
|
||||
{
|
||||
fclose((FILE *)a->ptr);
|
||||
if (a->flags&BIO_FLAGS_UPLINK)
|
||||
UP_fclose (a->ptr);
|
||||
else
|
||||
fclose (a->ptr);
|
||||
a->ptr=NULL;
|
||||
a->flags=BIO_FLAGS_UPLINK;
|
||||
}
|
||||
a->init=0;
|
||||
}
|
||||
|
@ -161,8 +168,11 @@ static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
|
|||
|
||||
if (b->init && (out != NULL))
|
||||
{
|
||||
ret=fread(out,1,(int)outl,(FILE *)b->ptr);
|
||||
if(ret == 0 && ferror((FILE *)b->ptr))
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
ret=UP_fread(out,1,(int)outl,b->ptr);
|
||||
else
|
||||
ret=fread(out,1,(int)outl,(FILE *)b->ptr);
|
||||
if(ret == 0 && (b->flags&BIO_FLAGS_UPLINK)?UP_ferror((FILE *)b->ptr):ferror((FILE *)b->ptr))
|
||||
{
|
||||
SYSerr(SYS_F_FREAD,get_last_sys_error());
|
||||
BIOerr(BIO_F_FILE_READ,ERR_R_SYS_LIB);
|
||||
|
@ -178,7 +188,11 @@ static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
|
|||
|
||||
if (b->init && (in != NULL))
|
||||
{
|
||||
if (fwrite(in,(int)inl,1,(FILE *)b->ptr))
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
ret=UP_fwrite(in,(int)inl,1,b->ptr);
|
||||
else
|
||||
ret=fwrite(in,(int)inl,1,(FILE *)b->ptr);
|
||||
if (ret)
|
||||
ret=inl;
|
||||
/* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
|
||||
/* according to Tim Hudson <tjh@cryptsoft.com>, the commented
|
||||
|
@ -199,20 +213,40 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||
{
|
||||
case BIO_C_FILE_SEEK:
|
||||
case BIO_CTRL_RESET:
|
||||
ret=(long)fseek(fp,num,0);
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
ret=(long)UP_fseek(b->ptr,num,0);
|
||||
else
|
||||
ret=(long)fseek(fp,num,0);
|
||||
break;
|
||||
case BIO_CTRL_EOF:
|
||||
ret=(long)feof(fp);
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
ret=(long)UP_feof(fp);
|
||||
else
|
||||
ret=(long)feof(fp);
|
||||
break;
|
||||
case BIO_C_FILE_TELL:
|
||||
case BIO_CTRL_INFO:
|
||||
ret=ftell(fp);
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
ret=UP_ftell(b->ptr);
|
||||
else
|
||||
ret=ftell(fp);
|
||||
break;
|
||||
case BIO_C_SET_FILE_PTR:
|
||||
file_free(b);
|
||||
b->shutdown=(int)num&BIO_CLOSE;
|
||||
b->ptr=(char *)ptr;
|
||||
b->ptr=ptr;
|
||||
b->init=1;
|
||||
#if BIO_FLAGS_UPLINK!=0 && defined(_IOB_ENTRIES)
|
||||
/* Safety net to catch purely internal BIO_set_fp calls */
|
||||
if ((size_t)ptr >= (size_t)stdin &&
|
||||
(size_t)ptr < (size_t)(stdin+_IOB_ENTRIES))
|
||||
BIO_clear_flags(b,BIO_FLAGS_UPLINK);
|
||||
#endif
|
||||
#ifdef UP_fsetmode
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
UP_fsetmode(b->ptr,num&BIO_FP_TEXT?'t':'b');
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if defined(OPENSSL_SYS_WINDOWS)
|
||||
int fd = fileno((FILE*)ptr);
|
||||
|
@ -286,7 +320,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||
else
|
||||
strcat(p,"t");
|
||||
#endif
|
||||
fp=fopen(ptr,p);
|
||||
fp=fopen(ptr,p);
|
||||
if (fp == NULL)
|
||||
{
|
||||
SYSerr(SYS_F_FOPEN,get_last_sys_error());
|
||||
|
@ -295,8 +329,9 @@ fp=fopen(ptr,p);
|
|||
ret=0;
|
||||
break;
|
||||
}
|
||||
b->ptr=(char *)fp;
|
||||
b->ptr=fp;
|
||||
b->init=1;
|
||||
BIO_clear_flags(b,BIO_FLAGS_UPLINK); /* we did fopen -> we disengage UPLINK */
|
||||
break;
|
||||
case BIO_C_GET_FILE_PTR:
|
||||
/* the ptr parameter is actually a FILE ** in this case. */
|
||||
|
@ -313,7 +348,10 @@ fp=fopen(ptr,p);
|
|||
b->shutdown=(int)num;
|
||||
break;
|
||||
case BIO_CTRL_FLUSH:
|
||||
fflush((FILE *)b->ptr);
|
||||
if (b->flags&BIO_FLAGS_UPLINK)
|
||||
UP_fflush(b->ptr);
|
||||
else
|
||||
fflush((FILE *)b->ptr);
|
||||
break;
|
||||
case BIO_CTRL_DUP:
|
||||
ret=1;
|
||||
|
|
|
@ -64,6 +64,11 @@
|
|||
|
||||
#include "e_os.h"
|
||||
|
||||
#ifdef OPENSSL_USE_APPLINK
|
||||
#define BIO_FLAGS_UPLINK 0x8000
|
||||
#include "uplink.h"
|
||||
#endif
|
||||
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/bio.h>
|
||||
|
|
44
ms/applink.c
44
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 <stdio.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
172
ms/uplink.c
172
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 <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
|
||||
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;
|
||||
void (*func)(void)=unimplemented;
|
||||
HANDLE h;
|
||||
void **p;
|
||||
|
||||
len = _stprintf (msg,_T("OPENSSL_Uplink(%p,%02X): "),table,index);
|
||||
_tcscpy (msg+len,_T("unimplemented function"));
|
||||
table [index] = unimplemented;
|
||||
/* 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 (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;
|
||||
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 (applinktable[index]) table[index] = applinktable[index];
|
||||
if (p[index]) func = p[index];
|
||||
} while (0);
|
||||
|
||||
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
|
||||
|
||||
|
|
25
ms/uplink.h
25
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])
|
||||
|
|
31
ms/uplink.pl
31
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
|
||||
|
|
Loading…
Reference in a new issue