mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 00:25:23 +00:00
fa68b75bad
Sun Apr 2 18:31:12 1995 Alexandre Julliard (julliard@sunsite.unc.edu) * [Configure] [if1632/Imakefile] Removed new build and short names options. * [if1632/*.c] [tools/build.c] Implemented compiled call-back functions for better performance; all the relay code is now done in assembly code generated by the build program. Relay code is no longer dependent on being loaded below 64K. * [loader/resource.c] Fixed memory leak in LoadString(). A fix will also be needed for other resources. * [memory/global.c] Implemented global heap arenas, so we can store informations about global blocks, like lock counts or owner handle. Implemented FarGetOwner() and FarSetOwner(). Implemented global heap TOOLHELP functions. * [memory/selector.c] Bug fix: it was not possible to re-use a free selector. Sun Apr 2 01:34:52 1995 Constantine Sapuntzakis (csapuntz@mit.edu) * [controls/listbox.c] Major work on listbox code - Many bugs fixed (still many bugs) - More messages supported - Code simplified Fri Mar 31 03:27:16 EST 1995 William Magro (wmagro@tc.cornell.edu) * [controls/edit.c] Lots of bug fixes related to diappearing text, lost carets, highlighting, segmentation faults, occurance of random characters, insertion of characters over selection, misplaced caret location, display corruption, end of line behavior, etc. * [controls/widgets.c] EDIT class doesn't want to use CS_PARENTDC flag. Thu Mar 30 20:58:25 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [loader/selector.c] FixupFunctionPrologs() should also handle multiple data modules. (this bug only became visible because MakeProcInstance() was fixed in 950319) * [misc/dosfs.c] Simplified DOS_SimplifyPath. Small fix to DOS_opendir to reuse an entry if an open directory is opened again, to prevent "too many open directories" messages. Thu Mar 30 12:05:05 1995 Martin von Loewis <loewis@informatik.hu-berlin.de> * [if1632/compobj.spec][include/compobj.h][misc/compobj.c] CoDisconnectObject: new stub function * [include/msdos.h] fix DOSVERSION * [loader/ne_image.c] NE_FixupSegment: Be more generous on additive fixups * [if1632/user.spec][misc/network.c] Add more WNet* stubs Wed Mar 29 11:47:22 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [controls/listbox.c] DlgDirList(): send segptr instead of linear pointer in message to static control * [controls/menu.c] Tried to implement ownerdrawn menuitems. Doesn't work. * [if1632/gdi.spec] [include/windows.h] [objects/font.c] Provide a stub for GetRasterizerCaps() * [loader/selector.c] Pass end address instead of length to LocalInit() in CreateSelectors() * [memory/local.c] LocalInit(): If there's already a local heap in the segment, do nothing and return TRUE * [objects/linedda.c] Replaced buggy LineDDA() with a Bresenham algorithm. Should work now. * [windows/cursor.c] LoadCursor()/CreateCursor(): Cleaned up the mess. Needs some more work still. Tue Mar 21 17:54:43 1995 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de> * [if1632/relay.c] [if1632/callback.c] [include/dlls.h] [if1632/winprocs.spec] [if1632/winprocs.c] [include/winprocs.h] [controls/widgets.c] [misc/shell.c] [misc/commdlg.c] [windows/nonclient.c] [misc/message.c] Added a new builtin DLL that provides 16 bit entry points for all the Def*Procs (DefDlgProc, ButtonProc etc.). OWL programs work again. * [misc/shell.c] RegOpenKey()/RegCreateKey() bugs fixed. * [loader/ne_image.c] Skipping the initialization of a DLL when CS == 0 was broken.
323 lines
8.8 KiB
C
323 lines
8.8 KiB
C
/*
|
|
static char RCSId[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
|
|
static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
#ifdef linux
|
|
#include <linux/unistd.h>
|
|
#include <linux/head.h>
|
|
#include <linux/ldt.h>
|
|
#endif
|
|
|
|
#include "ldt.h"
|
|
|
|
#include "neexe.h"
|
|
#include "prototypes.h"
|
|
#include "dlls.h"
|
|
#include "options.h"
|
|
#include "selectors.h"
|
|
#include "stackframe.h"
|
|
#include "wine.h"
|
|
#include "stddebug.h"
|
|
/* #define DEBUG_RELAY */
|
|
#include "debug.h"
|
|
|
|
#if 0
|
|
/* Make make_debug think these were really used */
|
|
dprintf_relay
|
|
#endif
|
|
|
|
#ifdef WINELIB
|
|
#define WineLibSkip(x) 0
|
|
#else
|
|
#define WineLibSkip(x) x
|
|
#endif
|
|
|
|
struct dll_name_table_entry_s dll_builtin_table[N_BUILTINS] =
|
|
{
|
|
{ "KERNEL", WineLibSkip(&KERNEL_table), 1 },
|
|
{ "USER", WineLibSkip(&USER_table), 1 },
|
|
{ "GDI", WineLibSkip(&GDI_table), 1 },
|
|
{ "WIN87EM", WineLibSkip(&WIN87EM_table), 1 },
|
|
{ "SHELL", WineLibSkip(&SHELL_table), 1 },
|
|
{ "SOUND", WineLibSkip(&SOUND_table), 1 },
|
|
{ "KEYBOARD", WineLibSkip(&KEYBOARD_table), 1 },
|
|
{ "WINSOCK", WineLibSkip(&WINSOCK_table), 1 },
|
|
{ "STRESS", WineLibSkip(&STRESS_table), 1 },
|
|
{ "MMSYSTEM", WineLibSkip(&MMSYSTEM_table), 1 },
|
|
{ "SYSTEM", WineLibSkip(&SYSTEM_table), 1 },
|
|
{ "TOOLHELP", WineLibSkip(&TOOLHELP_table), 1 },
|
|
{ "MOUSE", WineLibSkip(&MOUSE_table), 1 },
|
|
{ "COMMDLG", WineLibSkip(&COMMDLG_table), 1 },
|
|
{ "OLE2", WineLibSkip(&OLE2_table), 1 },
|
|
{ "OLE2CONV", WineLibSkip(&OLE2CONV_table), 1 },
|
|
{ "OLE2DISP", WineLibSkip(&OLE2DISP_table), 1 },
|
|
{ "OLE2NLS", WineLibSkip(&OLE2NLS_table), 1 },
|
|
{ "OLE2PROX", WineLibSkip(&OLE2PROX_table), 1 },
|
|
{ "OLECLI", WineLibSkip(&OLECLI_table), 1 },
|
|
{ "OLESVR", WineLibSkip(&OLESVR_table), 1 },
|
|
{ "COMPOBJ", WineLibSkip(&COMPOBJ_table), 1 },
|
|
{ "STORAGE", WineLibSkip(&STORAGE_table), 1 },
|
|
{ "WINPROCS", WineLibSkip(&WINPROCS_table), 1 },
|
|
};
|
|
/* don't forget to increase N_BUILTINS in dlls.h if you add a dll */
|
|
|
|
/* Saved 16-bit stack */
|
|
WORD IF1632_Saved16_ss = 0;
|
|
WORD IF1632_Saved16_sp = 0;
|
|
WORD IF1632_Saved16_bp = 0;
|
|
|
|
/* Saved 32-bit stack */
|
|
DWORD IF1632_Saved32_esp = 0;
|
|
DWORD IF1632_Saved32_ebp = 0;
|
|
|
|
/***********************************************************************
|
|
* RELAY_Init
|
|
*/
|
|
BOOL RELAY_Init(void)
|
|
{
|
|
WORD codesel, datasel;
|
|
struct dll_table_s *table;
|
|
struct dll_table_entry_s *entry;
|
|
int i, j;
|
|
|
|
/* Allocate the code selector for CallTo16 routines */
|
|
|
|
extern void CALL16_Start(), CALL16_End();
|
|
extern void CALL16_Ret_word(), CALL16_Ret_long();
|
|
extern DWORD CALL16_RetAddr_word, CALL16_RetAddr_long;
|
|
|
|
codesel = SELECTOR_AllocBlock( (void *)CALL16_Start,
|
|
(int)CALL16_End - (int)CALL16_Start,
|
|
SEGMENT_CODE, TRUE, FALSE );
|
|
if (!codesel) return FALSE;
|
|
|
|
/* Patch the return addresses for CallTo16 routines */
|
|
|
|
CALL16_RetAddr_word = MAKELONG( (int)CALL16_Ret_word - (int)CALL16_Start,
|
|
codesel );
|
|
CALL16_RetAddr_long = MAKELONG( (int)CALL16_Ret_long - (int)CALL16_Start,
|
|
codesel );
|
|
|
|
/* Allocate the selectors for built-in dlls */
|
|
|
|
for (i = 0; i < N_BUILTINS; i++)
|
|
{
|
|
table = dll_builtin_table[i].table;
|
|
codesel = SELECTOR_AllocBlock( table->code_start,
|
|
(int)table->code_end-(int)table->code_start,
|
|
SEGMENT_CODE, TRUE, FALSE );
|
|
if (!codesel) return FALSE;
|
|
if (table->data_start != table->data_end)
|
|
datasel = SELECTOR_AllocBlock( table->data_start,
|
|
(int)table->data_end-(int)table->data_start,
|
|
SEGMENT_DATA, TRUE, FALSE );
|
|
else datasel = 0;
|
|
entry = table->dll_table;
|
|
for (j = 0; j < table->dll_table_length; j++, entry++)
|
|
{
|
|
if (entry->selector == 1) /* code selector */
|
|
entry->selector = codesel;
|
|
else if (entry->selector == 2) /* data selector */
|
|
entry->selector = datasel;
|
|
else entry->selector = 0; /* constant selector */
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
#ifndef WINELIB
|
|
|
|
void RELAY_DebugCall32( char *args )
|
|
{
|
|
STACK16FRAME *frame;
|
|
char *args16;
|
|
int i;
|
|
|
|
if (!debugging_relay) return;
|
|
|
|
frame = CURRENT_STACK16;
|
|
printf( "Call %s.%d: %s(",
|
|
dll_builtin_table[frame->dll_id-1].dll_name,
|
|
frame->ordinal_number,
|
|
dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name );
|
|
args16 = (char *)frame->args;
|
|
for (i = 0; i < strlen(args); i++)
|
|
{
|
|
switch(args[i])
|
|
{
|
|
case 'w':
|
|
case 's':
|
|
args16 += 2;
|
|
break;
|
|
case 'l':
|
|
case 'p':
|
|
args16 += 4;
|
|
break;
|
|
}
|
|
}
|
|
|
|
while (*args)
|
|
{
|
|
switch(*args)
|
|
{
|
|
case 'w':
|
|
case 's':
|
|
args16 -= 2;
|
|
printf( "0x%04x", *(WORD *)args16 );
|
|
break;
|
|
case 'l':
|
|
args16 -= 4;
|
|
printf( "0x%08x", *(int *)args16 );
|
|
break;
|
|
case 'p':
|
|
args16 -= 4;
|
|
printf( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
|
|
break;
|
|
}
|
|
args++;
|
|
if (*args) printf( "," );
|
|
}
|
|
printf( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
|
|
}
|
|
|
|
|
|
void RELAY_DebugReturn( int short_ret, int ret_val )
|
|
{
|
|
STACK16FRAME *frame;
|
|
|
|
if (!debugging_relay) return;
|
|
|
|
frame = CURRENT_STACK16;
|
|
printf( "Ret %s.%d: %s() ",
|
|
dll_builtin_table[frame->dll_id-1].dll_name,
|
|
frame->ordinal_number,
|
|
dll_builtin_table[frame->dll_id-1].table->dll_table[frame->ordinal_number].export_name );
|
|
if (short_ret) printf( "retval=0x%04x\n", ret_val & 0xffff );
|
|
else printf( "retval=0x%08x\n", ret_val );
|
|
}
|
|
|
|
|
|
void RELAY_Unimplemented(void)
|
|
{
|
|
STACK16FRAME *frame = CURRENT_STACK16;
|
|
|
|
fprintf( stderr, "No handler for routine %s.%d\n",
|
|
dll_builtin_table[frame->dll_id-1].dll_name,
|
|
frame->ordinal_number );
|
|
exit(1);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* RELAY_DebugCall16
|
|
*
|
|
* 'stack' points to the called function address on the 32-bit stack.
|
|
* Stack layout:
|
|
* ... ...
|
|
* (stack+12) arg2
|
|
* (stack+8) arg1
|
|
* (stack+4) 16-bit ds
|
|
* (stack) func to call
|
|
*/
|
|
void RELAY_DebugCall16( int* stack, int nbargs )
|
|
{
|
|
if (!debugging_relay) return;
|
|
|
|
printf( "CallTo16(func=%04x:%04x,ds=%04x",
|
|
HIWORD(stack[0]), LOWORD(stack[0]), LOWORD(stack[1]) );
|
|
stack += 2;
|
|
while (nbargs--) printf( ",0x%x", *stack++ );
|
|
printf( ")\n" );
|
|
}
|
|
|
|
#endif /* WINELIB */
|
|
|
|
/**********************************************************************
|
|
* FindDLLTable
|
|
*/
|
|
struct dll_table_s *
|
|
FindDLLTable(char *dll_name)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < N_BUILTINS; i++)
|
|
if (strcasecmp(dll_builtin_table[i].dll_name, dll_name) == 0
|
|
&& dll_builtin_table[i].dll_is_used)
|
|
return dll_builtin_table[i].table;
|
|
return NULL;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* FindOrdinalFromName
|
|
*/
|
|
int
|
|
FindOrdinalFromName(struct dll_table_entry_s *dll_table, char *func_name)
|
|
{
|
|
int i, limit;
|
|
|
|
for (i = 0; i < N_BUILTINS; i++)
|
|
if (dll_table == dll_builtin_table[i].table->dll_table)
|
|
break;
|
|
|
|
if (i == N_BUILTINS)
|
|
return 0;
|
|
|
|
limit = dll_builtin_table[i].table->dll_table_length;
|
|
for (i = 0; i < limit; i++)
|
|
if (strcasecmp(dll_table[i].export_name, func_name) == 0)
|
|
return i;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#ifndef WINELIB
|
|
#ifdef WINESTAT
|
|
void winestat(){
|
|
int i, j;
|
|
double perc;
|
|
int used, implemented;
|
|
int tused, timplemented;
|
|
struct dll_table_entry_s *table;
|
|
|
|
tused = 0;
|
|
timplemented = 0;
|
|
for (i = 0; i < N_BUILTINS; i++) {
|
|
table = dll_builtin_table[i].table->dll_table;
|
|
used = 0;
|
|
implemented = 0;
|
|
for(j=0; j < dll_builtin_table[i].table->dll_table_length; j++) {
|
|
if(table[j].used){
|
|
used++;
|
|
if (table[j].export_name[0]) implemented++;
|
|
else
|
|
printf("%s.%d not implemented\n",
|
|
dll_builtin_table[i].dll_name,
|
|
j);
|
|
};
|
|
};
|
|
tused += used;
|
|
timplemented += implemented;
|
|
if(used)
|
|
perc = implemented * 100.00 / used;
|
|
else
|
|
perc = 0.0;
|
|
if (used)
|
|
printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table[i].dll_name, implemented, used, perc);
|
|
};
|
|
perc = timplemented * 100.00 / tused;
|
|
printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented, tused, perc);
|
|
}
|
|
#endif /* WINESTAT */
|
|
#endif /* !WINELIB */
|