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 /* */
29 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
31 { "KERNEL", KERNEL_table
, 410, 1 },
32 { "USER", USER_table
, 540, 2 },
33 { "GDI", GDI_table
, 490, 3 },
34 { "UNIXLIB", UNIXLIB_table
, 10, 4 },
35 { "WIN87EM", WIN87EM_table
, 10, 5 },
36 { "SHELL", SHELL_table
, 256, 6 },
37 { "SOUND", SOUND_table
, 20, 7 },
38 { "KEYBOARD",KEYBOARD_table
,137, 8 },
39 { "WINSOCK", WINSOCK_table
, 155, 9 },
40 { "STRESS", STRESS_table
, 15,10 },
43 unsigned short *Stack16Frame
;
45 extern unsigned long IF1632_Saved16_esp
;
46 extern unsigned long IF1632_Saved16_ebp
;
47 extern unsigned short IF1632_Saved16_ss
;
49 /**********************************************************************
52 * We get a stack frame pointer to data that looks like this:
56 * +00 previous saved_16ss
57 * +02 previous saved_16ebp
58 * +06 previous saved_16esp
62 * +12 length of 16-bit arguments
68 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
70 struct dll_table_entry_s
*dll_p
;
71 unsigned short *saved_Stack16Frame
;
76 int arg_table
[DLL_MAX_ARGS
];
83 * Determine address of arguments.
85 saved_Stack16Frame
= Stack16Frame
;
86 Stack16Frame
= (unsigned short *) seg_off
;
87 arg_ptr
= (void *) (seg_off
+ 0x18);
90 * Extract the DLL number and ordinal number.
92 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
93 ordinal
= func_num
& 0xffff;
94 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
97 if (Options
.relay_debug
)
99 unsigned int *ret_addr
;
100 unsigned short *stack_p
;
102 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
103 printf("Calling %s (%s.%d), 16-bit stack at %04x:%04x, ",
105 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
106 seg_off
>> 16, seg_off
& 0xffff);
107 printf("return to %08x\n", *ret_addr
);
108 printf(" ESP %08x, EBP %08x, SS %04x\n",
109 IF1632_Saved16_esp
, IF1632_Saved16_ebp
,
113 stack_p
= (unsigned short *) seg_off
;
114 for (i
= 0; i
< 24; i
++, stack_p
++)
116 printf("%04x ", *stack_p
);
121 #endif /* DEBUG_STACK */
123 #endif /* DEBUG_RELAY */
126 * Make sure we have a handler defined for this call.
128 if (dll_p
->handler
== NULL
)
132 sprintf(buffer
, "No handler for routine %s.%d",
133 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
136 func_ptr
= dll_p
->handler
;
139 * OK, special case. If the handler is define as taking no arguments
140 * then pass the address of the arguments on the 16-bit stack to the
141 * handler. It will just ignore the pointer if it really takes no
142 * arguments. This allows us to write slightly faster library routines
145 if (dll_p
->n_args
== 0)
147 ret_val
= (*func_ptr
)(arg_ptr
);
148 Stack16Frame
= saved_Stack16Frame
;
153 * Getting this far means we need to convert the 16-bit argument stack.
155 for (i
= 0; i
< dll_p
->n_args
; i
++)
160 offset
= dll_p
->args
[i
].dst_arg
;
162 switch (dll_p
->args
[i
].src_type
)
164 case DLL_ARGTYPE_SIGNEDWORD
:
165 sp
= (short *) ((char *) arg_ptr
+ offset
);
169 case DLL_ARGTYPE_WORD
:
170 sp
= (short *) ((char *) arg_ptr
+ offset
);
171 arg_table
[i
] = (int) *sp
& 0xffff;
174 case DLL_ARGTYPE_LONG
:
175 ip
= (int *) ((char *) arg_ptr
+ offset
);
179 case DLL_ARGTYPE_FARPTR
:
180 ip
= (int *) ((char *) arg_ptr
+ offset
);
181 if (*ip
& 0xffff0000)
182 arg_table
[i
] = FIXPTR(*ip
);
192 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
193 arg_table
[3], arg_table
[4], arg_table
[5],
194 arg_table
[6], arg_table
[7], arg_table
[8],
195 arg_table
[9], arg_table
[10], arg_table
[11],
196 arg_table
[12], arg_table
[13], arg_table
[14],
200 if (Options
.relay_debug
)
202 printf("Returning %08.8x from %s (%s.%d)\n",
205 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
209 Stack16Frame
= saved_Stack16Frame
;
213 /**********************************************************************
216 struct dll_table_entry_s
*
217 FindDLLTable(char *dll_name
)
221 for (i
= 0; i
< N_BUILTINS
; i
++)
222 if (strcmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
223 return dll_builtin_table
[i
].dll_table
;
228 /**********************************************************************
229 * FindOrdinalFromName
232 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
236 for (i
= 0; i
< N_BUILTINS
; i
++)
237 if (dll_table
== dll_builtin_table
[i
].dll_table
)
243 limit
= dll_builtin_table
[i
].dll_table_length
;
244 for (i
= 0; i
< limit
; i
++)
245 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
250 /**********************************************************************
263 int used
, implemented
;
264 int tused
, timplemented
;
265 struct dll_table_entry_s
*table
;
269 for (i
= 0; i
< N_BUILTINS
; i
++) {
270 table
= dll_builtin_table
[i
].dll_table
;
273 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
276 if (table
[j
].handler
) implemented
++;
279 dll_builtin_table
[i
].dll_name
,
284 timplemented
+= implemented
;
286 perc
= implemented
* 100.00 / used
;
289 printf("%s: %d %d %3.1f\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
291 perc
= timplemented
* 100.00 / tused
;
292 printf("TOTAL: %d %d %3.1f\n",timplemented
, tused
, perc
);
294 #endif /* WINESTAT */