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 /* FIXME: Is there an end-of-stack-pointer somewhere ? */
133 int n
= min(24, (0x10000 - (seg_off
& 0xffff)) / sizeof(*stack_p
));
134 for (i
= 0; i
< n
; i
++, stack_p
++)
136 printf("%04x ", *stack_p
);
145 * Make sure we have a handler defined for this call.
147 if (dll_p
->handler
== NULL
)
151 sprintf(buffer
, "No handler for routine %s.%d",
152 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
155 func_ptr
= dll_p
->handler
;
158 * OK, special case. If the handler is define as taking no arguments
159 * then pass the address of the arguments on the 16-bit stack to the
160 * handler. It will just ignore the pointer if it really takes no
161 * arguments. This allows us to write slightly faster library routines
164 if (dll_p
->n_args
== 0)
166 ret_val
= (*func_ptr
)(arg_ptr
);
167 Stack16Frame
= saved_Stack16Frame
;
172 * Getting this far means we need to convert the 16-bit argument stack.
174 for (i
= 0; i
< dll_p
->n_args
; i
++)
179 offset
= dll_p
->args
[i
].dst_arg
;
181 switch (dll_p
->args
[i
].src_type
)
183 case DLL_ARGTYPE_SIGNEDWORD
:
184 sp
= (short *) ((char *) arg_ptr
+ offset
);
188 case DLL_ARGTYPE_WORD
:
189 sp
= (short *) ((char *) arg_ptr
+ offset
);
190 arg_table
[i
] = (int) *sp
& 0xffff;
193 case DLL_ARGTYPE_LONG
:
194 ip
= (int *) ((char *) arg_ptr
+ offset
);
198 case DLL_ARGTYPE_FARPTR
:
199 ip
= (int *) ((char *) arg_ptr
+ offset
);
200 if (*ip
& 0xffff0000)
201 arg_table
[i
] = FIXPTR(*ip
);
211 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
212 arg_table
[3], arg_table
[4], arg_table
[5],
213 arg_table
[6], arg_table
[7], arg_table
[8],
214 arg_table
[9], arg_table
[10], arg_table
[11],
215 arg_table
[12], arg_table
[13], arg_table
[14],
220 printf("Returning %08x from %s (%s.%d)\n",
223 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
226 Stack16Frame
= saved_Stack16Frame
;
231 /**********************************************************************
234 struct dll_table_entry_s
*
235 FindDLLTable(char *dll_name
)
239 for (i
= 0; i
< N_BUILTINS
; i
++)
240 if (strcasecmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
242 return dll_builtin_table
[i
].dll_number
;
244 return dll_builtin_table
[i
].dll_table
;
249 /**********************************************************************
250 * FindOrdinalFromName
253 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
257 for (i
= 0; i
< N_BUILTINS
; i
++)
258 if (dll_table
== dll_builtin_table
[i
].dll_table
)
264 limit
= dll_builtin_table
[i
].dll_table_length
;
265 for (i
= 0; i
< limit
; i
++)
266 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
271 /**********************************************************************
285 int used
, implemented
;
286 int tused
, timplemented
;
287 struct dll_table_entry_s
*table
;
291 for (i
= 0; i
< N_BUILTINS
; i
++) {
292 table
= dll_builtin_table
[i
].dll_table
;
295 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
298 if (table
[j
].handler
) implemented
++;
300 printf("%s.%d not implemented\n",
301 dll_builtin_table
[i
].dll_name
,
306 timplemented
+= implemented
;
308 perc
= implemented
* 100.00 / used
;
312 printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
314 perc
= timplemented
* 100.00 / tused
;
315 printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented
, tused
, perc
);
317 #endif /* WINESTAT */
318 #endif /* !WINELIB */