3 static char RCSId[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
4 static char Copyright[] = "Copyright Robert J. Amstadt, 1993";
19 extern SEGDESC Segments
[];
20 extern unsigned short IF1632_Saved16_ss
;
21 extern unsigned long IF1632_Saved16_ebp
;
22 extern unsigned long IF1632_Saved16_esp
;
23 extern unsigned short IF1632_Saved32_ss
;
24 extern unsigned long IF1632_Saved32_ebp
;
25 extern unsigned long IF1632_Saved32_esp
;
27 extern struct segment_descriptor_s
*MakeProcThunks
;
32 unsigned char thunk
[10];
36 /**********************************************************************
40 PushOn16(int size
, unsigned int value
)
42 char *p
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
43 (IF1632_Saved16_esp
& 0xffff));
46 unsigned long *lp
= (unsigned long *) p
- 1;
49 IF1632_Saved16_esp
-= 4;
53 unsigned short *sp
= (unsigned short *) p
- 1;
56 IF1632_Saved16_esp
-= 2;
60 /**********************************************************************
61 * FindDataSegmentForCode
64 FindDataSegmentForCode(unsigned long csip
)
68 seg_idx
= (unsigned short) (csip
>> 19);
69 return Segments
[seg_idx
].owner
;
72 /**********************************************************************
76 CallBack16(void *func
, int n_args
, ...)
80 int arg_type
, arg_value
;
84 for (i
= 0; i
< n_args
; i
++)
86 arg_type
= va_arg(ap
, int);
87 arg_value
= va_arg(ap
, int);
88 PushOn16(arg_type
, arg_value
);
93 return CallTo16((unsigned int) func
,
94 FindDataSegmentForCode((unsigned long) func
));
97 /**********************************************************************
98 * CALLBACK_MakeProcInstance
101 CALLBACK_MakeProcInstance(void *func
, int instance
)
106 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
107 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
115 tp
->thunk
[1] = (unsigned char) instance
;
116 tp
->thunk
[2] = (unsigned char) (instance
>> 8);
120 memcpy(&tp
->thunk
[6], &func
, 4);
126 /**********************************************************************
127 * FreeProcInstance (KERNEL.52)
129 void FreeProcInstance(FARPROC func
)
134 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
135 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
137 if ((void *) tp
->thunk
== (void *) func
)
145 /**********************************************************************
146 * GetCodeHandle (KERNEL.93)
148 HANDLE
GetCodeHandle( FARPROC proc
)
150 struct thunk_s
*tp
= (struct thunk_s
*)proc
;
152 /* Return the code segment containing 'proc'. */
153 /* Not sure if this is really correct (shouldn't matter that much). */
154 printf( "STUB: GetCodeHandle(%p) returning %x\n",
155 proc
, tp
->thunk
[8] + (tp
->thunk
[9] << 8) );
156 return tp
->thunk
[8] + (tp
->thunk
[9] << 8);
160 /**********************************************************************
161 * CallWindowProc (USER.122)
163 LONG
CallWindowProc( WNDPROC func
, HWND hwnd
, WORD message
,
164 WORD wParam
, LONG lParam
)
166 SpyMessage(hwnd
, message
, wParam
, lParam
);
168 if (HIWORD((LONG
)func
) == WINE_CODE_SELECTOR
)
170 static struct dll_table_entry_s
*user_tab
= NULL
;
171 void *address
= (void *) ((LONG
) func
& 0xffff);
173 if (user_tab
== NULL
)
174 user_tab
= FindDLLTable("USER");
177 if (((LONG
)user_tab
[107].address
&0xffff) == (LONG
) address
)
178 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
181 else if (((LONG
)user_tab
[308].address
&0xffff) == (LONG
)address
)
182 return DefDlgProc(hwnd
, message
, wParam
, lParam
);
184 /* DefMDIChildProc */
185 else if (((LONG
)user_tab
[447].address
&0xffff) == (LONG
)address
)
186 return DefMDIChildProc(hwnd
, message
, wParam
, lParam
);
191 fprintf(stderr
, "wine: Unknown wine callback %08x\n",
192 (unsigned int) func
);
196 else if (IS_16_BIT_ADDRESS(func
))
198 dprintf_callback(stddeb
, "CallWindowProc // 16bit func=%08x !\n",
199 (unsigned int) func
);
200 PushOn16( CALLBACK_SIZE_WORD
, hwnd
);
201 PushOn16( CALLBACK_SIZE_WORD
, message
);
202 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
203 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
204 return CallTo16((unsigned int) func
,
205 FindDataSegmentForCode((unsigned long) func
));
209 dprintf_callback(stddeb
, "CallWindowProc // 32bit func=%08X !\n",
210 (unsigned int) func
);
211 return (*func
)(hwnd
, message
, wParam
, lParam
);
215 /**********************************************************************
218 void CallLineDDAProc(FARPROC func
, short xPos
, short yPos
, long lParam
)
220 if (IS_16_BIT_ADDRESS(func
))
222 PushOn16( CALLBACK_SIZE_WORD
, xPos
);
223 PushOn16( CALLBACK_SIZE_WORD
, yPos
);
224 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
225 CallTo16((unsigned int) func
,
226 FindDataSegmentForCode((unsigned long) func
));
230 (*func
)(xPos
, yPos
, lParam
);
234 /**********************************************************************
237 DWORD
CallHookProc( HOOKPROC func
, short code
, WPARAM wParam
, LPARAM lParam
)
239 if (IS_16_BIT_ADDRESS(func
))
241 PushOn16( CALLBACK_SIZE_WORD
, code
);
242 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
243 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
244 return CallTo16((unsigned int) func
,
245 FindDataSegmentForCode((unsigned long) func
));
249 return (*func
)( code
, wParam
, lParam
);
253 /**********************************************************************
256 BOOL
CallGrayStringProc(FARPROC func
, HDC hdc
, LPARAM lParam
, INT cch
)
258 if (IS_16_BIT_ADDRESS(func
))
260 PushOn16( CALLBACK_SIZE_WORD
, hdc
);
261 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
262 PushOn16( CALLBACK_SIZE_WORD
, cch
);
263 return CallTo16((unsigned int) func
,
264 FindDataSegmentForCode((unsigned long) func
));
268 return (*func
)( hdc
, lParam
, cch
);
272 /* ------------------------------------------------------------------------ */
274 * The following functions realize the Catch/Throw functionality.
275 * My thought is to use the setjmp, longjmp combination to do the
276 * major part of this one. All I have to remember, in addition to
277 * whatever the jmp_buf contains, is the contents of the 16-bit
278 * sp, bp and ss. I do this by storing them in the structure passed
279 * to me by the 16-bit program (including my own jmp_buf...).
280 * Hopefully there isn't any program that modifies the contents!
281 * Bad thing: I have to save part of the stack, since this will
282 * get reused on the next call after my return, leaving it in an
285 #define STACK_DEPTH_16 28
287 struct special_buffer
{
290 char stack_part
[STACK_DEPTH_16
];
293 int Catch (LPCATCHBUF cbuf
)
297 char *stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
298 (IF1632_Saved16_esp
& 0xffff));
300 sb
= malloc (sizeof (struct special_buffer
));
302 sb
-> regs
[0] = IF1632_Saved16_esp
;
303 sb
-> regs
[1] = IF1632_Saved16_ebp
;
304 sb
-> regs
[2] = IF1632_Saved16_ss
& 0xffff;
305 sb
-> regs
[3] = IF1632_Saved32_esp
;
306 sb
-> regs
[4] = IF1632_Saved32_ebp
;
307 sb
-> regs
[5] = IF1632_Saved32_ss
& 0xffff;
308 memcpy (sb
-> stack_part
, stack16
, STACK_DEPTH_16
);
309 tmp_jmp
= &sb
-> buffer
;
310 *((struct special_buffer
**)cbuf
) = sb
;
312 if ((retval
= setjmp (*tmp_jmp
)))
314 IF1632_Saved16_esp
= sb
-> regs
[0];
315 IF1632_Saved16_ebp
= sb
-> regs
[1];
316 IF1632_Saved16_ss
= sb
-> regs
[2] & 0xffff;
317 IF1632_Saved32_esp
= sb
-> regs
[3];
318 IF1632_Saved32_ebp
= sb
-> regs
[4];
319 IF1632_Saved32_ss
= sb
-> regs
[5] & 0xffff;
320 stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
321 (IF1632_Saved16_esp
& 0xffff));
323 memcpy (stack16
, sb
-> stack_part
, STACK_DEPTH_16
);
324 dprintf_catch (stddeb
, "Been thrown here: %d, retval = %d\n",
325 (int) sb
, (int) retval
);
329 dprintf_catch (stddeb
, "Will somtime get thrown here: %d\n",
335 void Throw (LPCATCHBUF cbuf
, int val
)
337 sb
= *((struct special_buffer
**)cbuf
);
338 dprintf_catch (stddeb
, "Throwing to: %d\n", (int) sb
);
339 longjmp (sb
-> buffer
, val
);
341 #endif /* !WINELIB */