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";
11 #include <linux/unistd.h>
12 #include <linux/head.h>
13 #include <linux/ldt.h>
14 #include <linux/segment.h>
19 #include "prototypes.h"
24 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
26 { "KERNEL", KERNEL_table
, 410, 1 },
27 { "USER", USER_table
, 540, 2 },
28 { "GDI", GDI_table
, 490, 3 },
29 { "UNIXLIB", UNIXLIB_table
, 10, 4 },
30 { "WIN87EM", WIN87EM_table
, 10, 5 },
31 { "SHELL", SHELL_table
, 256, 6 },
32 { "SOUND", SOUND_table
, 20, 7 },
33 { "KEYBOARD",KEYBOARD_table
,137, 8 },
36 unsigned short *Stack16Frame
;
38 extern unsigned long IF1632_Saved16_esp
;
39 extern unsigned long IF1632_Saved16_ebp
;
40 extern unsigned short IF1632_Saved16_ss
;
42 /**********************************************************************
45 * We get a stack frame pointer to data that looks like this:
49 * +00 previous saved_16ss
50 * +02 previous saved_16ebp
51 * +06 previous saved_16esp
55 * +12 length of 16-bit arguments
61 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
63 struct dll_table_entry_s
*dll_p
;
68 int arg_table
[DLL_MAX_ARGS
];
75 * Determine address of arguments.
77 Stack16Frame
= (unsigned short *) seg_off
;
78 arg_ptr
= (void *) (seg_off
+ 0x18);
81 * Extract the DLL number and ordinal number.
83 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
84 ordinal
= func_num
& 0xffff;
85 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
89 unsigned int *ret_addr
;
90 unsigned short *stack_p
;
92 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
93 printf("Calling %s (%s.%d), 16-bit stack at %04x:%04x, ",
95 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
96 seg_off
>> 16, seg_off
& 0xffff);
97 printf("return to %08x\n", *ret_addr
);
98 printf(" ESP %08x, EBP %08x, SS %04x\n",
99 IF1632_Saved16_esp
, IF1632_Saved16_ebp
,
102 if (strcmp("GetMessage", dll_p
->export_name
) == 0 &&
103 seg_off
== 0x00972526 &&
104 *ret_addr
== 0x004700cd &&
105 IF1632_Saved16_esp
== 0x2526 &&
106 IF1632_Saved16_ebp
== 0x2534 &&
107 IF1632_Saved16_ss
== 0x0097)
111 stack_p
= (unsigned short *) seg_off
;
112 for (i
= 0; i
< 24; i
++, stack_p
++)
114 printf("%04x ", *stack_p
);
119 #endif /* DEBUG_STACK */
121 #endif /* DEBUG_RELAY */
124 * Make sure we have a handler defined for this call.
126 if (dll_p
->handler
== NULL
)
130 sprintf(buffer
, "No handler for routine %s.%d",
131 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
134 func_ptr
= dll_p
->handler
;
137 * OK, special case. If the handler is define as taking no arguments
138 * then pass the address of the arguments on the 16-bit stack to the
139 * handler. It will just ignore the pointer if it really takes no
140 * arguments. This allows us to write slightly faster library routines
143 if (dll_p
->n_args
== 0)
144 return (*func_ptr
)(arg_ptr
);
147 * Getting this far means we need to convert the 16-bit argument stack.
149 for (i
= 0; i
< dll_p
->n_args
; i
++)
154 offset
= dll_p
->args
[i
].dst_arg
;
156 switch (dll_p
->args
[i
].src_type
)
158 case DLL_ARGTYPE_SIGNEDWORD
:
159 sp
= (short *) ((char *) arg_ptr
+ offset
);
163 case DLL_ARGTYPE_WORD
:
164 sp
= (short *) ((char *) arg_ptr
+ offset
);
165 arg_table
[i
] = (int) *sp
& 0xffff;
168 case DLL_ARGTYPE_LONG
:
169 ip
= (int *) ((char *) arg_ptr
+ offset
);
173 case DLL_ARGTYPE_FARPTR
:
174 ip
= (int *) ((char *) arg_ptr
+ offset
);
175 if (*ip
& 0xffff0000)
176 arg_table
[i
] = FIXPTR(*ip
);
186 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
187 arg_table
[3], arg_table
[4], arg_table
[5],
188 arg_table
[6], arg_table
[7], arg_table
[8],
189 arg_table
[9], arg_table
[10], arg_table
[11],
190 arg_table
[12], arg_table
[13], arg_table
[14],
194 printf("Returning %08.8x from %s (%s.%d)\n",
197 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
203 /**********************************************************************
206 struct dll_table_entry_s
*
207 FindDLLTable(char *dll_name
)
211 for (i
= 0; i
< N_BUILTINS
; i
++)
212 if (strcmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
213 return dll_builtin_table
[i
].dll_table
;
218 /**********************************************************************
219 * FindOrdinalFromName
222 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
226 for (i
= 0; i
< N_BUILTINS
; i
++)
227 if (dll_table
== dll_builtin_table
[i
].dll_table
)
233 limit
= dll_builtin_table
[i
].dll_table_length
;
234 for (i
= 0; i
< limit
; i
++)
235 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
240 /**********************************************************************
253 int used
, implemented
;
254 int tused
, timplemented
;
255 struct dll_table_entry_s
*table
;
259 for (i
= 0; i
< N_BUILTINS
; i
++) {
260 table
= dll_builtin_table
[i
].dll_table
;
263 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
266 if (table
[j
].handler
) implemented
++;
269 dll_builtin_table
[i
].dll_name
,
274 timplemented
+= implemented
;
276 perc
= implemented
* 100.00 / used
;
279 printf("%s: %d %d %3.1f\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
281 perc
= timplemented
* 100.00 / tused
;
282 printf("TOTAL: %d %d %3.1f\n",timplemented
, tused
, perc
);
284 #endif /* WINESTAT */