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";
10 #include <linux/unistd.h>
11 #include <linux/head.h>
12 #include <linux/ldt.h>
13 #include <linux/segment.h>
17 #include "prototypes.h"
22 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
24 { "KERNEL", KERNEL_table
, 410, 1 },
25 { "USER", USER_table
, 540, 2 },
26 { "GDI", GDI_table
, 490, 3 },
27 { "UNIXLIB", UNIXLIB_table
, 10, 4 },
28 { "WIN87EM", WIN87EM_table
, 10, 5 },
29 { "SHELL", SHELL_table
, 256, 6 },
32 unsigned short *Stack16Frame
;
34 extern unsigned long IF1632_Saved16_esp
;
35 extern unsigned long IF1632_Saved16_ebp
;
36 extern unsigned short IF1632_Saved16_ss
;
38 /**********************************************************************
41 * We get a stack frame pointer to data that looks like this:
45 * +00 previous saved_16ss
46 * +02 previous saved_16ebp
47 * +06 previous saved_16esp
51 * +12 length of 16-bit arguments
57 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
59 struct dll_table_entry_s
*dll_p
;
64 int arg_table
[DLL_MAX_ARGS
];
71 * Determine address of arguments.
73 Stack16Frame
= (unsigned short *) seg_off
;
74 arg_ptr
= (void *) (seg_off
+ 0x18);
77 * Extract the DLL number and ordinal number.
79 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
80 ordinal
= func_num
& 0xffff;
81 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
85 unsigned int *ret_addr
;
86 unsigned short *stack_p
;
88 ret_addr
= (unsigned int *) ((char *) seg_off
+ 0x14);
89 printf("Calling %s (%s.%d), 16-bit stack at %04x:%04x, ",
91 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
92 seg_off
>> 16, seg_off
& 0xffff);
93 printf("return to %08x\n", *ret_addr
);
94 printf(" ESP %08x, EBP %08x, SS %04x\n",
95 IF1632_Saved16_esp
, IF1632_Saved16_ebp
,
98 if (strcmp("GetMessage", dll_p
->export_name
) == 0 &&
99 seg_off
== 0x00972526 &&
100 *ret_addr
== 0x004700cd &&
101 IF1632_Saved16_esp
== 0x2526 &&
102 IF1632_Saved16_ebp
== 0x2534 &&
103 IF1632_Saved16_ss
== 0x0097)
107 IF1632_Saved16_esp
&= 0x0000ffff;
108 IF1632_Saved16_ebp
&= 0x0000ffff;
112 stack_p
= (unsigned short *) seg_off
;
113 for (i
= 0; i
< 24; i
++, stack_p
++)
115 printf("%04x ", *stack_p
);
120 #endif /* DEBUG_STACK */
122 #endif /* DEBUG_RELAY */
125 * Make sure we have a handler defined for this call.
127 if (dll_p
->handler
== NULL
)
131 sprintf(buffer
, "No handler for routine %s.%d",
132 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
135 func_ptr
= dll_p
->handler
;
138 * OK, special case. If the handler is define as taking no arguments
139 * then pass the address of the arguments on the 16-bit stack to the
140 * handler. It will just ignore the pointer if it really takes no
141 * arguments. This allows us to write slightly faster library routines
144 if (dll_p
->n_args
== 0)
145 return (*func_ptr
)(arg_ptr
);
148 * Getting this far means we need to convert the 16-bit argument stack.
150 for (i
= 0; i
< dll_p
->n_args
; i
++)
155 offset
= dll_p
->args
[i
].dst_arg
;
157 switch (dll_p
->args
[i
].src_type
)
159 case DLL_ARGTYPE_SIGNEDWORD
:
160 sp
= (short *) ((char *) arg_ptr
+ offset
);
164 case DLL_ARGTYPE_WORD
:
165 sp
= (short *) ((char *) arg_ptr
+ offset
);
166 arg_table
[i
] = (int) *sp
& 0xffff;
169 case DLL_ARGTYPE_LONG
:
170 case DLL_ARGTYPE_FARPTR
:
171 ip
= (int *) ((char *) arg_ptr
+ offset
);
180 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
181 arg_table
[3], arg_table
[4], arg_table
[5],
182 arg_table
[6], arg_table
[7], arg_table
[8],
183 arg_table
[9], arg_table
[10], arg_table
[11],
184 arg_table
[12], arg_table
[13], arg_table
[14],
188 printf("Returning %08.8x from %s (%s.%d)\n",
191 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
197 /**********************************************************************
200 struct dll_table_entry_s
*
201 FindDLLTable(char *dll_name
)
205 for (i
= 0; i
< N_BUILTINS
; i
++)
206 if (strcmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0)
207 return dll_builtin_table
[i
].dll_table
;
212 /**********************************************************************
213 * FindOrdinalFromName
216 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
220 for (i
= 0; i
< N_BUILTINS
; i
++)
221 if (dll_table
== dll_builtin_table
[i
].dll_table
)
227 limit
= dll_builtin_table
[i
].dll_table_length
;
228 for (i
= 0; i
< limit
; i
++)
229 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
234 /**********************************************************************