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},
50 /* don't forget to increase N_BUILTINS in dll.h if you add a dll */
53 unsigned short *Stack16Frame
;
55 extern unsigned long IF1632_Saved16_esp
;
56 extern unsigned long IF1632_Saved16_ebp
;
57 extern unsigned short IF1632_Saved16_ss
;
59 /**********************************************************************
62 * We get a stack frame pointer to data that looks like this:
66 * +00 previous saved_16ss
67 * +02 previous saved_16ebp
68 * +06 previous saved_16esp
72 * +12 length of 16-bit arguments
78 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
80 struct dll_table_entry_s
*dll_p
;
81 unsigned short *saved_Stack16Frame
;
86 int arg_table
[DLL_MAX_ARGS
];
93 * Determine address of arguments.
95 saved_Stack16Frame
= Stack16Frame
;
96 Stack16Frame
= (unsigned short *) seg_off
;
97 arg_ptr
= (void *) (seg_off
+ 0x18);
100 * Extract the DLL number and ordinal number.
102 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
103 ordinal
= func_num
& 0xffff;
104 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
107 if (Options
.relay_debug
)
109 unsigned int *ret_addr
;
110 unsigned short *stack_p
;
112 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
113 printf("Calling %s (%s.%d), 16-bit stack at %04x:%04x, ",
115 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
116 seg_off
>> 16, seg_off
& 0xffff);
117 printf("return to %08x\n", *ret_addr
);
118 printf(" ESP %08x, EBP %08x, SS %04x\n",
119 IF1632_Saved16_esp
, IF1632_Saved16_ebp
,
123 stack_p
= (unsigned short *) seg_off
;
124 for (i
= 0; i
< 24; i
++, stack_p
++)
126 printf("%04x ", *stack_p
);
131 #endif /* DEBUG_STACK */
133 #endif /* DEBUG_RELAY */
136 * Make sure we have a handler defined for this call.
138 if (dll_p
->handler
== NULL
)
142 sprintf(buffer
, "No handler for routine %s.%d",
143 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
146 func_ptr
= dll_p
->handler
;
149 * OK, special case. If the handler is define as taking no arguments
150 * then pass the address of the arguments on the 16-bit stack to the
151 * handler. It will just ignore the pointer if it really takes no
152 * arguments. This allows us to write slightly faster library routines
155 if (dll_p
->n_args
== 0)
157 ret_val
= (*func_ptr
)(arg_ptr
);
158 Stack16Frame
= saved_Stack16Frame
;
163 * Getting this far means we need to convert the 16-bit argument stack.
165 for (i
= 0; i
< dll_p
->n_args
; i
++)
170 offset
= dll_p
->args
[i
].dst_arg
;
172 switch (dll_p
->args
[i
].src_type
)
174 case DLL_ARGTYPE_SIGNEDWORD
:
175 sp
= (short *) ((char *) arg_ptr
+ offset
);
179 case DLL_ARGTYPE_WORD
:
180 sp
= (short *) ((char *) arg_ptr
+ offset
);
181 arg_table
[i
] = (int) *sp
& 0xffff;
184 case DLL_ARGTYPE_LONG
:
185 ip
= (int *) ((char *) arg_ptr
+ offset
);
189 case DLL_ARGTYPE_FARPTR
:
190 ip
= (int *) ((char *) arg_ptr
+ offset
);
191 if (*ip
& 0xffff0000)
192 arg_table
[i
] = FIXPTR(*ip
);
202 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
203 arg_table
[3], arg_table
[4], arg_table
[5],
204 arg_table
[6], arg_table
[7], arg_table
[8],
205 arg_table
[9], arg_table
[10], arg_table
[11],
206 arg_table
[12], arg_table
[13], arg_table
[14],
210 if (Options
.relay_debug
)
212 printf("Returning %08.8x from %s (%s.%d)\n",
215 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
219 Stack16Frame
= saved_Stack16Frame
;
224 /**********************************************************************
227 struct dll_table_entry_s
*
228 FindDLLTable(char *dll_name
)
232 for (i
= 0; i
< N_BUILTINS
; i
++)
233 if (strcasecmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
235 return dll_builtin_table
[i
].dll_number
;
237 return dll_builtin_table
[i
].dll_table
;
242 /**********************************************************************
243 * FindOrdinalFromName
246 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
250 for (i
= 0; i
< N_BUILTINS
; i
++)
251 if (dll_table
== dll_builtin_table
[i
].dll_table
)
257 limit
= dll_builtin_table
[i
].dll_table_length
;
258 for (i
= 0; i
< limit
; i
++)
259 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
264 /**********************************************************************
278 int used
, implemented
;
279 int tused
, timplemented
;
280 struct dll_table_entry_s
*table
;
284 for (i
= 0; i
< N_BUILTINS
; i
++) {
285 table
= dll_builtin_table
[i
].dll_table
;
288 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
291 if (table
[j
].handler
) implemented
++;
294 dll_builtin_table
[i
].dll_name
,
299 timplemented
+= implemented
;
301 perc
= implemented
* 100.00 / used
;
304 printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
306 perc
= timplemented
* 100.00 / tused
;
307 printf("TOTAL: %d of %d implemented (%3.1f %%)\n",timplemented
, tused
, perc
);
309 #endif /* WINESTAT */
310 #endif /* !WINELIB */