2 static char RCSId[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
15 #include <linux/unistd.h>
16 #include <linux/head.h>
17 #include <linux/ldt.h>
22 #include "prototypes.h"
26 /* #define DEBUG_RELAY /* */
27 /* #define DEBUG_STACK /* */
31 /* Make make_debug think these were really used */
37 #define WineLibSkip(x) 0
39 #define WineLibSkip(x) x
42 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
44 { "KERNEL", WineLibSkip(KERNEL_table
), 410, 1 },
45 { "USER", WineLibSkip(USER_table
), 540, 2 },
46 { "GDI", WineLibSkip(GDI_table
), 490, 3 },
47 { "UNIXLIB", WineLibSkip(UNIXLIB_table
), 10, 4 },
48 { "WIN87EM", WineLibSkip(WIN87EM_table
), 10, 5 },
49 { "SHELL", WineLibSkip(SHELL_table
), 103, 6 },
50 { "SOUND", WineLibSkip(SOUND_table
), 20, 7 },
51 { "KEYBOARD",WineLibSkip(KEYBOARD_table
),137, 8 },
52 { "WINSOCK", WineLibSkip(WINSOCK_table
), 155, 9 },
53 { "STRESS", WineLibSkip(STRESS_table
), 15, 10},
54 { "MMSYSTEM",WineLibSkip(MMSYSTEM_table
),1226,11},
55 { "SYSTEM", WineLibSkip(SYSTEM_table
), 20 ,12},
56 { "TOOLHELP",WineLibSkip(TOOLHELP_table
), 83, 13},
57 { "MOUSE", WineLibSkip(MOUSE_table
), 8, 14},
58 { "EMUCOMMDLG", WineLibSkip(COMMDLG_table
), 31, 15},
60 /* don't forget to increase N_BUILTINS in dll.h if you add a dll */
63 unsigned short *Stack16Frame
;
65 extern unsigned long IF1632_Saved16_esp
;
66 extern unsigned long IF1632_Saved16_ebp
;
67 extern unsigned short IF1632_Saved16_ss
;
69 /**********************************************************************
72 * We get a stack frame pointer to data that looks like this:
76 * +00 previous saved_16ss
77 * +02 previous saved_16ebp
78 * +06 previous saved_16esp
82 * +12 length of 16-bit arguments
88 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
90 struct dll_table_entry_s
*dll_p
;
91 unsigned short *saved_Stack16Frame
;
95 int arg_table
[DLL_MAX_ARGS
];
102 * Determine address of arguments.
104 saved_Stack16Frame
= Stack16Frame
;
105 Stack16Frame
= (unsigned short *) seg_off
;
106 arg_ptr
= (void *) (seg_off
+ 0x18);
109 * Extract the DLL number and ordinal number.
111 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
112 ordinal
= func_num
& 0xffff;
113 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
117 unsigned int *ret_addr
;
119 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
120 printf("Call %s (%s.%d), stack=%04x:%04x, ",
122 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
123 seg_off
>> 16, seg_off
& 0xffff);
124 printf("ret=%08x", *ret_addr
);
125 printf(" ESP=%08lx, EBP=%08lx, SS=%04x\n",
126 IF1632_Saved16_esp
, IF1632_Saved16_ebp
,
131 unsigned short *stack_p
= (unsigned short *) seg_off
;
132 for (i
= 0; i
< 24; i
++, stack_p
++)
134 printf("%04x ", *stack_p
);
143 * Make sure we have a handler defined for this call.
145 if (dll_p
->handler
== NULL
)
149 sprintf(buffer
, "No handler for routine %s.%d",
150 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
153 func_ptr
= dll_p
->handler
;
156 * OK, special case. If the handler is define as taking no arguments
157 * then pass the address of the arguments on the 16-bit stack to the
158 * handler. It will just ignore the pointer if it really takes no
159 * arguments. This allows us to write slightly faster library routines
162 if (dll_p
->n_args
== 0)
164 ret_val
= (*func_ptr
)(arg_ptr
);
165 Stack16Frame
= saved_Stack16Frame
;
170 * Getting this far means we need to convert the 16-bit argument stack.
172 for (i
= 0; i
< dll_p
->n_args
; i
++)
177 offset
= dll_p
->args
[i
].dst_arg
;
179 switch (dll_p
->args
[i
].src_type
)
181 case DLL_ARGTYPE_SIGNEDWORD
:
182 sp
= (short *) ((char *) arg_ptr
+ offset
);
186 case DLL_ARGTYPE_WORD
:
187 sp
= (short *) ((char *) arg_ptr
+ offset
);
188 arg_table
[i
] = (int) *sp
& 0xffff;
191 case DLL_ARGTYPE_LONG
:
192 ip
= (int *) ((char *) arg_ptr
+ offset
);
196 case DLL_ARGTYPE_FARPTR
:
197 ip
= (int *) ((char *) arg_ptr
+ offset
);
198 if (*ip
& 0xffff0000)
199 arg_table
[i
] = FIXPTR(*ip
);
209 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
210 arg_table
[3], arg_table
[4], arg_table
[5],
211 arg_table
[6], arg_table
[7], arg_table
[8],
212 arg_table
[9], arg_table
[10], arg_table
[11],
213 arg_table
[12], arg_table
[13], arg_table
[14],
218 printf("Returning %08x from %s (%s.%d)\n",
221 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
224 Stack16Frame
= saved_Stack16Frame
;
229 /**********************************************************************
232 struct dll_table_entry_s
*
233 FindDLLTable(char *dll_name
)
237 for (i
= 0; i
< N_BUILTINS
; i
++)
238 if (strcasecmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
240 return dll_builtin_table
[i
].dll_number
;
242 return dll_builtin_table
[i
].dll_table
;
247 /**********************************************************************
248 * FindOrdinalFromName
251 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
255 for (i
= 0; i
< N_BUILTINS
; i
++)
256 if (dll_table
== dll_builtin_table
[i
].dll_table
)
262 limit
= dll_builtin_table
[i
].dll_table_length
;
263 for (i
= 0; i
< limit
; i
++)
264 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
269 /**********************************************************************
283 int used
, implemented
;
284 int tused
, timplemented
;
285 struct dll_table_entry_s
*table
;
289 for (i
= 0; i
< N_BUILTINS
; i
++) {
290 table
= dll_builtin_table
[i
].dll_table
;
293 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
296 if (table
[j
].handler
) implemented
++;
298 printf("%s.%d not implemented\n",
299 dll_builtin_table
[i
].dll_name
,
304 timplemented
+= implemented
;
306 perc
= implemented
* 100.00 / used
;
310 printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
312 perc
= timplemented
* 100.00 / tused
;
313 printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented
, tused
, perc
);
315 #endif /* WINESTAT */
316 #endif /* !WINELIB */