Finished separation of comclt32 and comdlg32.
[wine/multimedia.git] / if1632 / relay.c
blobc2d770a269937c70ee214cfb6f4043ac40d9f9e4
1 /*
2 * Copyright 1993 Robert J. Amstadt
3 * Copyright 1995 Alexandre Julliard
4 */
6 #include <assert.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include "wine/winbase16.h"
10 #include "winnt.h"
11 #include "heap.h"
12 #include "module.h"
13 #include "stackframe.h"
14 #include "selectors.h"
15 #include "builtin16.h"
16 #include "task.h"
17 #include "syslevel.h"
18 #include "debugtools.h"
19 #include "main.h"
20 #include "callback.h"
22 DEFAULT_DEBUG_CHANNEL(relay);
24 /***********************************************************************
25 * RELAY_Init
27 BOOL RELAY_Init(void)
29 #ifdef __i386__
30 WORD codesel;
32 /* Allocate the code selector for CallTo16 routines */
34 extern void Call16_Ret_Start(), Call16_Ret_End();
35 extern void CallTo16_Ret();
36 extern void CALL32_CBClient_Ret();
37 extern void CALL32_CBClientEx_Ret();
38 extern SEGPTR CallTo16_RetAddr;
39 extern DWORD CallTo16_DataSelector;
40 extern SEGPTR CALL32_CBClient_RetAddr;
41 extern SEGPTR CALL32_CBClientEx_RetAddr;
43 codesel = SELECTOR_AllocBlock( (void *)Call16_Ret_Start,
44 (char *)Call16_Ret_End - (char *)Call16_Ret_Start,
45 WINE_LDT_FLAGS_CODE | WINE_LDT_FLAGS_32BIT );
46 if (!codesel) return FALSE;
48 /* Patch the return addresses for CallTo16 routines */
50 CallTo16_DataSelector = __get_ds();
51 CallTo16_RetAddr =
52 PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CallTo16_Ret - (char*)Call16_Ret_Start );
53 CALL32_CBClient_RetAddr =
54 PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CALL32_CBClient_Ret - (char*)Call16_Ret_Start );
55 CALL32_CBClientEx_RetAddr =
56 PTR_SEG_OFF_TO_SEGPTR( codesel, (char*)CALL32_CBClientEx_Ret - (char*)Call16_Ret_Start );
57 #endif
58 return TRUE;
62 * Stubs for the CallTo16/CallFrom16 routines on non-Intel architectures
63 * (these will never be called but need to be present to satisfy the linker ...)
65 #ifndef __i386__
66 /***********************************************************************
67 * wine_call_to_16_word
69 WORD WINAPI wine_call_to_16_word( FARPROC16 target, INT nArgs )
71 assert( FALSE );
74 /***********************************************************************
75 * wine_call_to_16_long
77 LONG WINAPI wine_call_to_16_long( FARPROC16 target, INT nArgs )
79 assert( FALSE );
82 /***********************************************************************
83 * wine_call_to_16_regs_short
85 void WINAPI wine_call_to_16_regs_short( CONTEXT86 *context, INT nArgs )
87 assert( FALSE );
90 /***********************************************************************
91 * wine_call_to_16_regs_long
93 void WINAPI wine_call_to_16_regs_long ( CONTEXT86 *context, INT nArgs )
95 assert( FALSE );
98 /***********************************************************************
99 * __wine_call_from_16_word
101 WORD __cdecl __wine_call_from_16_word(...)
103 assert( FALSE );
106 /***********************************************************************
107 * __wine_call_from_16_long
109 LONG __cdecl __wine_call_from_16_long(...)
111 assert( FALSE );
114 /***********************************************************************
115 * __wine_call_from_16_regs
117 void __cdecl __wine_call_from_16_regs(...)
119 assert( FALSE );
122 /***********************************************************************
123 * __wine_call_from_16_thunk
125 void __cdecl __wine_call_from_16_thunk(...)
127 assert( FALSE );
130 DWORD WINAPI CALL32_CBClient( FARPROC proc, LPWORD args, DWORD *esi )
131 { assert( FALSE ); }
133 DWORD WINAPI CALL32_CBClientEx( FARPROC proc, LPWORD args, DWORD *esi, INT *nArgs )
134 { assert( FALSE ); }
135 #endif
138 /* from relay32/relay386.c */
139 extern char **debug_relay_excludelist,**debug_relay_includelist;
141 /***********************************************************************
142 * RELAY_DebugCallFrom16
144 void RELAY_DebugCallFrom16( CONTEXT86 *context )
146 STACK16FRAME *frame;
147 WORD ordinal;
148 char *args16, funstr[80];
149 const char *args;
150 int i, usecdecl, reg_func;
152 if (!TRACE_ON(relay)) return;
154 frame = CURRENT_STACK16;
155 args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal );
156 if (!args) return; /* happens for the two snoop register relays */
157 if (!RELAY_ShowDebugmsgRelay(funstr)) return;
158 DPRINTF( "Call %s(",funstr);
159 VA_START16( args16 );
161 usecdecl = ( *args == 'c' );
162 args += 2;
163 reg_func = ( memcmp( args, "regs_", 5 ) == 0
164 || memcmp( args, "intr_", 5 ) == 0 );
165 args += 5;
167 if (usecdecl)
169 while (*args)
171 switch(*args)
173 case 'w':
174 case 's':
175 DPRINTF( "0x%04x", *(WORD *)args16 );
176 args16 += 2;
177 break;
178 case 'l':
179 DPRINTF( "0x%08x", *(int *)args16 );
180 args16 += 4;
181 break;
182 case 'p':
183 DPRINTF( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
184 args16 += 4;
185 break;
186 case 't':
187 case 'T':
188 DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16,
189 debugres_a( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 )) );
190 args16 += 4;
191 break;
193 args++;
194 if (*args) DPRINTF( "," );
197 else /* not cdecl */
199 /* Start with the last arg */
200 for (i = 0; args[i]; i++)
202 switch(args[i])
204 case 'w':
205 case 's':
206 args16 += 2;
207 break;
208 case 'l':
209 case 'p':
210 case 't':
211 case 'T':
212 args16 += 4;
213 break;
217 while (*args)
219 switch(*args)
221 case 'w':
222 case 's':
223 args16 -= 2;
224 DPRINTF( "0x%04x", *(WORD *)args16 );
225 break;
226 case 'l':
227 args16 -= 4;
228 DPRINTF( "0x%08x", *(int *)args16 );
229 break;
230 case 't':
231 args16 -= 4;
232 DPRINTF( "0x%08x %s", *(int *)args16,
233 debugres_a( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 )));
234 break;
235 case 'p':
236 args16 -= 4;
237 DPRINTF( "%04x:%04x", *(WORD *)(args16+2), *(WORD *)args16 );
238 break;
239 case 'T':
240 args16 -= 4;
241 DPRINTF( "%04x:%04x %s", *(WORD *)(args16+2), *(WORD *)args16,
242 debugres_a( (LPSTR)PTR_SEG_TO_LIN(*(SEGPTR *)args16 )));
243 break;
245 args++;
246 if (*args) DPRINTF( "," );
250 DPRINTF( ") ret=%04x:%04x ds=%04x\n", frame->cs, frame->ip, frame->ds );
251 VA_END16( args16 );
253 if (reg_func)
254 DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
255 AX_reg(context), BX_reg(context), CX_reg(context),
256 DX_reg(context), SI_reg(context), DI_reg(context),
257 (WORD)context->SegEs, context->EFlags );
259 SYSLEVEL_CheckNotLevel( 2 );
263 /***********************************************************************
264 * RELAY_DebugCallFrom16Ret
266 void RELAY_DebugCallFrom16Ret( CONTEXT86 *context, int ret_val )
268 STACK16FRAME *frame;
269 WORD ordinal;
270 char funstr[80];
271 const char *args;
273 if (!TRACE_ON(relay)) return;
274 frame = CURRENT_STACK16;
275 args = BUILTIN_GetEntryPoint16( frame, funstr, &ordinal );
276 if (!args) return;
277 if (!RELAY_ShowDebugmsgRelay(funstr)) return;
278 DPRINTF( "Ret %s() ",funstr);
280 if ( memcmp( args+2, "long_", 5 ) == 0 )
282 DPRINTF( "retval=0x%08x ret=%04x:%04x ds=%04x\n",
283 ret_val, frame->cs, frame->ip, frame->ds );
285 else if ( memcmp( args+2, "word_", 5 ) == 0 )
287 DPRINTF( "retval=0x%04x ret=%04x:%04x ds=%04x\n",
288 ret_val & 0xffff, frame->cs, frame->ip, frame->ds );
290 else if ( memcmp( args+2, "regs_", 5 ) == 0
291 || memcmp( args+2, "intr_", 5 ) == 0 )
293 DPRINTF("retval=none ret=%04x:%04x ds=%04x\n",
294 (WORD)context->SegCs, LOWORD(context->Eip), (WORD)context->SegDs);
295 DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x ES=%04x EFL=%08lx\n",
296 AX_reg(context), BX_reg(context), CX_reg(context),
297 DX_reg(context), SI_reg(context), DI_reg(context),
298 (WORD)context->SegEs, context->EFlags );
301 SYSLEVEL_CheckNotLevel( 2 );
305 /***********************************************************************
306 * RELAY_DebugCallTo16
308 * 'target' contains either the function to call (normal CallTo16)
309 * or a pointer to the CONTEXT86 struct (register CallTo16).
310 * 'nb_args' is the number of argument bytes on the 16-bit stack;
311 * 'reg_func' specifies whether we have a register CallTo16 or not.
313 void RELAY_DebugCallTo16( LPVOID target, int nb_args, BOOL reg_func )
315 WORD *stack16;
316 TEB *teb;
318 if (!TRACE_ON(relay)) return;
319 teb = NtCurrentTeb();
320 stack16 = (WORD *)THREAD_STACK16(teb);
322 nb_args /= sizeof(WORD);
324 if ( reg_func )
326 CONTEXT86 *context = (CONTEXT86 *)target;
328 DPRINTF("CallTo16(func=%04lx:%04x,ds=%04lx",
329 context->SegCs, LOWORD(context->Eip), context->SegDs );
330 while (nb_args--) DPRINTF( ",0x%04x", *--stack16 );
331 DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
332 OFFSETOF(teb->cur_stack) );
333 DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x SI=%04x DI=%04x BP=%04x ES=%04x FS=%04x\n",
334 AX_reg(context), BX_reg(context), CX_reg(context),
335 DX_reg(context), SI_reg(context), DI_reg(context),
336 BP_reg(context), (WORD)context->SegEs, (WORD)context->SegFs );
338 else
340 DPRINTF("CallTo16(func=%04x:%04x,ds=%04x",
341 HIWORD(target), LOWORD(target), SELECTOROF(teb->cur_stack) );
342 while (nb_args--) DPRINTF( ",0x%04x", *--stack16 );
343 DPRINTF(") ss:sp=%04x:%04x\n", SELECTOROF(teb->cur_stack),
344 OFFSETOF(teb->cur_stack) );
347 SYSLEVEL_CheckNotLevel( 2 );
351 /***********************************************************************
352 * RELAY_DebugCallTo16Ret
354 void RELAY_DebugCallTo16Ret( BOOL reg_func, int ret_val )
356 if (!TRACE_ON(relay)) return;
358 if (!reg_func)
360 DPRINTF("CallTo16() ss:sp=%04x:%04x retval=0x%08x\n",
361 SELECTOROF(NtCurrentTeb()->cur_stack),
362 OFFSETOF(NtCurrentTeb()->cur_stack), ret_val);
364 else
366 CONTEXT86 *context = (CONTEXT86 *)ret_val;
368 DPRINTF("CallTo16() ss:sp=%04x:%04x\n",
369 SELECTOROF(NtCurrentTeb()->cur_stack),
370 OFFSETOF(NtCurrentTeb()->cur_stack));
371 DPRINTF(" AX=%04x BX=%04x CX=%04x DX=%04x BP=%04x SP=%04x\n",
372 AX_reg(context), BX_reg(context), CX_reg(context),
373 DX_reg(context), BP_reg(context), LOWORD(context->Esp));
376 SYSLEVEL_CheckNotLevel( 2 );