1 static char RCSId
[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
12 #include <linux/unistd.h>
13 #include <linux/head.h>
14 #include <linux/ldt.h>
15 #include <linux/segment.h>
21 #include "prototypes.h"
25 #define DEBUG_RELAY /* */
28 #define WineLibSkip(x) 0
30 #define WineLibSkip(x) x
33 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
35 { "KERNEL", WineLibSkip(KERNEL_table
), 410, 1 },
36 { "USER", WineLibSkip(USER_table
), 540, 2 },
37 { "GDI", WineLibSkip(GDI_table
), 490, 3 },
38 { "UNIXLIB", WineLibSkip(UNIXLIB_table
), 10, 4 },
39 { "WIN87EM", WineLibSkip(WIN87EM_table
), 10, 5 },
40 { "SHELL", WineLibSkip(SHELL_table
), 103, 6 },
41 { "SOUND", WineLibSkip(SOUND_table
), 20, 7 },
42 { "KEYBOARD",WineLibSkip(KEYBOARD_table
),137, 8 },
43 { "WINSOCK", WineLibSkip(WINSOCK_table
), 155, 9 },
44 { "STRESS", WineLibSkip(STRESS_table
), 15, 10},
45 { "MMSYSTEM",WineLibSkip(MMSYSTEM_table
),1226,11},
46 { "SYSTEM", WineLibSkip(SYSTEM_table
), 20 ,12},
47 { "TOOLHELP",WineLibSkip(TOOLHELP_table
), 83, 13},
48 { "MOUSE", WineLibSkip(MOUSE_table
), 8, 14},
49 { "EMUCOMMDLG", WineLibSkip(COMMDLG_table
), 31, 15},
51 /* don't forget to increase N_BUILTINS in dll.h if you add a dll */
54 unsigned short *Stack16Frame
;
56 extern unsigned long IF1632_Saved16_esp
;
57 extern unsigned long IF1632_Saved16_ebp
;
58 extern unsigned short IF1632_Saved16_ss
;
60 /**********************************************************************
63 * We get a stack frame pointer to data that looks like this:
67 * +00 previous saved_16ss
68 * +02 previous saved_16ebp
69 * +06 previous saved_16esp
73 * +12 length of 16-bit arguments
79 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
81 struct dll_table_entry_s
*dll_p
;
82 unsigned short *saved_Stack16Frame
;
87 int arg_table
[DLL_MAX_ARGS
];
94 * Determine address of arguments.
96 saved_Stack16Frame
= Stack16Frame
;
97 Stack16Frame
= (unsigned short *) seg_off
;
98 arg_ptr
= (void *) (seg_off
+ 0x18);
101 * Extract the DLL number and ordinal number.
103 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
104 ordinal
= func_num
& 0xffff;
105 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
108 if (Options
.relay_debug
)
110 unsigned int *ret_addr
;
111 unsigned short *stack_p
;
113 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
114 printf("Call %s (%s.%d), stack=%04x:%04x, ",
116 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
117 seg_off
>> 16, seg_off
& 0xffff);
118 printf("ret=%08x", *ret_addr
);
119 printf(" ESP=%08x, EBP=%08x, SS=%04x\n",
120 IF1632_Saved16_esp
, IF1632_Saved16_ebp
,
124 stack_p
= (unsigned short *) seg_off
;
125 for (i
= 0; i
< 24; i
++, stack_p
++)
127 printf("%04x ", *stack_p
);
132 #endif /* DEBUG_STACK */
134 #endif /* DEBUG_RELAY */
137 * Make sure we have a handler defined for this call.
139 if (dll_p
->handler
== NULL
)
143 sprintf(buffer
, "No handler for routine %s.%d",
144 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
147 func_ptr
= dll_p
->handler
;
150 * OK, special case. If the handler is define as taking no arguments
151 * then pass the address of the arguments on the 16-bit stack to the
152 * handler. It will just ignore the pointer if it really takes no
153 * arguments. This allows us to write slightly faster library routines
156 if (dll_p
->n_args
== 0)
158 ret_val
= (*func_ptr
)(arg_ptr
);
159 Stack16Frame
= saved_Stack16Frame
;
164 * Getting this far means we need to convert the 16-bit argument stack.
166 for (i
= 0; i
< dll_p
->n_args
; i
++)
171 offset
= dll_p
->args
[i
].dst_arg
;
173 switch (dll_p
->args
[i
].src_type
)
175 case DLL_ARGTYPE_SIGNEDWORD
:
176 sp
= (short *) ((char *) arg_ptr
+ offset
);
180 case DLL_ARGTYPE_WORD
:
181 sp
= (short *) ((char *) arg_ptr
+ offset
);
182 arg_table
[i
] = (int) *sp
& 0xffff;
185 case DLL_ARGTYPE_LONG
:
186 ip
= (int *) ((char *) arg_ptr
+ offset
);
190 case DLL_ARGTYPE_FARPTR
:
191 ip
= (int *) ((char *) arg_ptr
+ offset
);
192 if (*ip
& 0xffff0000)
193 arg_table
[i
] = FIXPTR(*ip
);
203 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
204 arg_table
[3], arg_table
[4], arg_table
[5],
205 arg_table
[6], arg_table
[7], arg_table
[8],
206 arg_table
[9], arg_table
[10], arg_table
[11],
207 arg_table
[12], arg_table
[13], arg_table
[14],
211 if (Options
.relay_debug
)
213 printf("Returning %08.8x from %s (%s.%d)\n",
216 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
220 Stack16Frame
= saved_Stack16Frame
;
225 /**********************************************************************
228 struct dll_table_entry_s
*
229 FindDLLTable(char *dll_name
)
233 for (i
= 0; i
< N_BUILTINS
; i
++)
234 if (strcasecmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
236 return dll_builtin_table
[i
].dll_number
;
238 return dll_builtin_table
[i
].dll_table
;
243 /**********************************************************************
244 * FindOrdinalFromName
247 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
251 for (i
= 0; i
< N_BUILTINS
; i
++)
252 if (dll_table
== dll_builtin_table
[i
].dll_table
)
258 limit
= dll_builtin_table
[i
].dll_table_length
;
259 for (i
= 0; i
< limit
; i
++)
260 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
265 /**********************************************************************
279 int used
, implemented
;
280 int tused
, timplemented
;
281 struct dll_table_entry_s
*table
;
285 for (i
= 0; i
< N_BUILTINS
; i
++) {
286 table
= dll_builtin_table
[i
].dll_table
;
289 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
292 if (table
[j
].handler
) implemented
++;
294 printf("%s.%d not implemented\n",
295 dll_builtin_table
[i
].dll_name
,
300 timplemented
+= implemented
;
302 perc
= implemented
* 100.00 / used
;
306 printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
308 perc
= timplemented
* 100.00 / tused
;
309 printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented
, tused
, perc
);
311 #endif /* WINESTAT */
312 #endif /* !WINELIB */