2 static char RCSId[] = "$Id: relay.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
15 #include <linux/unistd.h>
16 #include <linux/head.h>
17 #include <linux/ldt.h>
23 #include "prototypes.h"
26 #include "stackframe.h"
28 /* #define DEBUG_RELAY */
29 /* #define DEBUG_STACK */
33 /* Make make_debug think these were really used */
39 #define WineLibSkip(x) 0
41 #define WineLibSkip(x) x
44 struct dll_name_table_entry_s dll_builtin_table
[N_BUILTINS
] =
46 { "KERNEL", WineLibSkip(KERNEL_table
), 410, 1, 1 },
47 { "USER", WineLibSkip(USER_table
), 540, 2, 1 },
48 { "GDI", WineLibSkip(GDI_table
), 490, 3, 1 },
49 { "WIN87EM", WineLibSkip(WIN87EM_table
), 10, 4, 1 },
50 { "SHELL", WineLibSkip(SHELL_table
), 103, 5, 1 },
51 { "SOUND", WineLibSkip(SOUND_table
), 20, 6, 1 },
52 { "KEYBOARD",WineLibSkip(KEYBOARD_table
),137, 7, 1 },
53 { "WINSOCK", WineLibSkip(WINSOCK_table
), 155, 8, 1 },
54 { "STRESS", WineLibSkip(STRESS_table
), 15, 9, 1},
55 { "MMSYSTEM",WineLibSkip(MMSYSTEM_table
),1226,10, 1},
56 { "SYSTEM", WineLibSkip(SYSTEM_table
), 20 ,11, 1},
57 { "TOOLHELP",WineLibSkip(TOOLHELP_table
), 83, 12, 1},
58 { "MOUSE", WineLibSkip(MOUSE_table
), 8, 13, 1},
59 { "COMMDLG", WineLibSkip(COMMDLG_table
), 31, 14, 1},
60 { "OLE2", WineLibSkip(OLE2_table
), 31, 15, 1},
61 { "OLE2CONV",WineLibSkip(OLE2CONV_table
), 31, 16, 1},
62 { "OLE2DISP",WineLibSkip(OLE2DISP_table
), 31, 17, 1},
63 { "OLE2NLS", WineLibSkip(OLE2NLS_table
), 31, 18, 1},
64 { "OLE2PROX",WineLibSkip(OLE2PROX_table
), 31, 19, 1},
65 { "OLECLI", WineLibSkip(OLECLI_table
), 31, 20, 1},
66 { "OLESVR", WineLibSkip(OLESVR_table
), 31, 21, 1},
67 { "COMPOBJ", WineLibSkip(COMPOBJ_table
), 31, 22, 1},
68 { "STORAGE", WineLibSkip(STORAGE_table
), 31, 23, 1}
70 /* don't forget to increase N_BUILTINS in dll.h if you add a dll */
72 /* the argument conversion tables for each dll */
73 struct dll_conversions
{
74 unsigned short *dst_args
; /* Offsets to arguments on stack */
75 unsigned char *src_types
; /* Argument types */
76 } dll_conversion_table
[N_BUILTINS
]= {
77 { KERNEL_offsets
, KERNEL_types
}, /* KERNEL */
78 { USER_offsets
, USER_types
}, /* USER */
79 { GDI_offsets
, GDI_types
}, /* GDI */
80 { WIN87EM_offsets
, WIN87EM_types
}, /* WIN87EM */
81 { SHELL_offsets
, SHELL_types
}, /* SHELL */
82 { SOUND_offsets
, SOUND_types
}, /* SOUND */
83 { KEYBOARD_offsets
, KEYBOARD_types
}, /* KEYBOARD */
84 { WINSOCK_offsets
, WINSOCK_types
}, /* WINSOCK */
85 { STRESS_offsets
, STRESS_types
}, /* STRESS, */
86 { MMSYSTEM_offsets
, MMSYSTEM_types
}, /* MMSYSTEM */
87 { SYSTEM_offsets
, SYSTEM_types
}, /* SYSTEM */
88 { TOOLHELP_offsets
, TOOLHELP_types
}, /* TOOLHELP */
89 { MOUSE_offsets
, MOUSE_types
}, /* MOUSE */
90 { COMMDLG_offsets
, COMMDLG_types
}, /* EMUCOMMDLG */
91 { OLE2_offsets
, OLE2_types
}, /* OLE2 */
92 { OLE2CONV_offsets
, OLE2CONV_types
}, /* OLE2CONV */
93 { OLE2DISP_offsets
, OLE2DISP_types
}, /* OLE2DISP */
94 { OLE2NLS_offsets
, OLE2NLS_types
}, /* OLE2NLS */
95 { OLE2DISP_offsets
, OLE2DISP_types
}, /* OLE2PROX */
96 { OLECLI_offsets
, OLECLI_types
}, /* OLE2CLI */
97 { OLESVR_offsets
, OLESVR_types
}, /* OLE2CLI */
98 { COMPOBJ_offsets
, COMPOBJ_types
}, /* COMPOBJ */
99 { STORAGE_offsets
, STORAGE_types
} /* STORAGE */
105 extern unsigned short IF1632_Saved16_sp
;
106 extern unsigned short IF1632_Saved16_bp
;
107 extern unsigned short IF1632_Saved16_ss
;
109 void RelayDebug( unsigned int func_num
)
111 unsigned int dll_id
, ordinal
;
115 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
116 ordinal
= func_num
& 0xffff;
117 printf( "Calling %s.%d\n",
118 dll_builtin_table
[dll_id
].dll_table
[ordinal
].export_name
,
124 /**********************************************************************
127 * We get a stack frame pointer to data that looks like this:
129 * Hex Offset Contents
131 * +00 previous saved_16ss
132 * +02 previous saved_16ebp
133 * +06 previous saved_16esp
137 * +12 length of 16-bit arguments
143 DLLRelay(unsigned int func_num
, unsigned int seg_off
)
145 struct dll_table_entry_s
*dll_p
;
146 STACK16FRAME
*pStack16Frame
;
149 unsigned int ordinal
;
150 int arg_table
[DLL_MAX_ARGS
];
156 unsigned char *type_conv
;
157 unsigned short *offset_conv
;
158 STACK16FRAME stackFrameCopy
;
161 * Determine address of arguments.
163 pStack16Frame
= (STACK16FRAME
*) PTR_SEG_TO_LIN(seg_off
);
164 arg_ptr
= (void *)pStack16Frame
->args
;
167 * Extract the DLL number and ordinal number.
169 dll_id
= ((func_num
>> 16) & 0xffff) - 1;
170 ordinal
= func_num
& 0xffff;
171 dll_p
= &dll_builtin_table
[dll_id
].dll_table
[ordinal
];
173 dprintf_relay( stddeb
, "Call %s (%s.%d), stack=%04x:%04x ret=%04x:%04x ds=%04x bp=%04x args=%d\n",
175 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
176 seg_off
>> 16, seg_off
& 0xffff,
177 pStack16Frame
->cs
, pStack16Frame
->ip
,
178 pStack16Frame
->ds
, pStack16Frame
->bp
,
179 pStack16Frame
->arg_length
);
183 unsigned short *stack_p
= (unsigned short *) pStack16Frame
;
184 /* FIXME: Is there an end-of-stack-pointer somewhere ? */
185 int n
= min(24, (0x10000 - (seg_off
& 0xffff)) / sizeof(*stack_p
));
186 for (i
= 0; i
< n
; i
++, stack_p
++)
188 printf("%04x ", *stack_p
);
196 * Make sure we have a handler defined for this call.
198 if (dll_p
->handler
== NULL
)
202 sprintf(buffer
, "No handler for routine %s.%d",
203 dll_builtin_table
[dll_id
].dll_name
, ordinal
);
206 func_ptr
= dll_p
->handler
;
209 * OK, special case. If the handler is define as taking no arguments
210 * then pass the address of the arguments on the 16-bit stack to the
211 * handler. It will just ignore the pointer if it really takes no
212 * arguments. This allows us to write slightly faster library routines
215 if (dll_p
->n_args
== 0)
217 ret_val
= (*func_ptr
)(arg_ptr
);
218 dprintf_relay( stddeb
, "Returning %08x from %s (%s.%d) ds=%04x\n",
219 ret_val
, dll_p
->export_name
,
220 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
226 * Getting this far means we need to convert the 16-bit argument stack.
228 conv_ref
= dll_p
->conv_reference
;
229 type_conv
= dll_conversion_table
[dll_id
].src_types
+ conv_ref
;
230 offset_conv
= dll_conversion_table
[dll_id
].dst_args
+ conv_ref
;
231 for (i
= 0; i
< dll_p
->n_args
; i
++,type_conv
++,offset_conv
++)
236 offset
= *offset_conv
;
240 case DLL_ARGTYPE_SIGNEDWORD
:
241 sp
= (short *) ((char *) arg_ptr
+ offset
);
245 case DLL_ARGTYPE_WORD
:
246 sp
= (short *) ((char *) arg_ptr
+ offset
);
247 arg_table
[i
] = (int) *sp
& 0xffff;
250 case DLL_ARGTYPE_LONG
:
251 ip
= (int *) ((char *) arg_ptr
+ offset
);
255 case DLL_ARGTYPE_FARPTR
:
256 ip
= (int *) ((char *) arg_ptr
+ offset
);
257 arg_table
[i
] = (unsigned int) PTR_SEG_TO_LIN( *ip
);
263 memcpy( &stackFrameCopy
, pStack16Frame
, sizeof(stackFrameCopy
) );
268 ret_val
= (*func_ptr
)(arg_table
[0], arg_table
[1], arg_table
[2],
269 arg_table
[3], arg_table
[4], arg_table
[5],
270 arg_table
[6], arg_table
[7], arg_table
[8],
271 arg_table
[9], arg_table
[10], arg_table
[11],
272 arg_table
[12], arg_table
[13], arg_table
[14],
277 if (memcmp( &stackFrameCopy
, pStack16Frame
, sizeof(stackFrameCopy
) ))
279 printf( "**** 16-bit stack corrupted!\n" );
281 printf("Returning %08x from %s (%s.%d) ds=%04x\n",
284 dll_builtin_table
[dll_id
].dll_name
, ordinal
,
292 /**********************************************************************
295 struct dll_table_entry_s
*
296 FindDLLTable(char *dll_name
)
300 for (i
= 0; i
< N_BUILTINS
; i
++)
301 if (strcasecmp(dll_builtin_table
[i
].dll_name
, dll_name
) == 0
302 && dll_builtin_table
[i
].dll_is_used
)
304 return dll_builtin_table
[i
].dll_number
;
306 return dll_builtin_table
[i
].dll_table
;
311 /**********************************************************************
312 * FindOrdinalFromName
315 FindOrdinalFromName(struct dll_table_entry_s
*dll_table
, char *func_name
)
319 for (i
= 0; i
< N_BUILTINS
; i
++)
320 if (dll_table
== dll_builtin_table
[i
].dll_table
)
326 limit
= dll_builtin_table
[i
].dll_table_length
;
327 for (i
= 0; i
< limit
; i
++)
328 if (strcasecmp(dll_table
[i
].export_name
, func_name
) == 0)
333 /**********************************************************************
347 int used
, implemented
;
348 int tused
, timplemented
;
349 struct dll_table_entry_s
*table
;
353 for (i
= 0; i
< N_BUILTINS
; i
++) {
354 table
= dll_builtin_table
[i
].dll_table
;
357 for(j
=0; j
< dll_builtin_table
[i
].dll_table_length
; j
++) {
360 if (table
[j
].handler
) implemented
++;
362 printf("%s.%d not implemented\n",
363 dll_builtin_table
[i
].dll_name
,
368 timplemented
+= implemented
;
370 perc
= implemented
* 100.00 / used
;
374 printf("%s: %d of %d (%3.1f %%)\n", dll_builtin_table
[i
].dll_name
, implemented
, used
, perc
);
376 perc
= timplemented
* 100.00 / tused
;
377 printf("TOTAL: %d of %d winapi functions implemented (%3.1f %%)\n",timplemented
, tused
, perc
);
379 #endif /* WINESTAT */
380 #endif /* !WINELIB */