2 static char RCSId
[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
3 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
13 extern SEGDESC Segments
[];
14 extern unsigned short IF1632_Saved16_ss
;
15 extern unsigned long IF1632_Saved16_ebp
;
16 extern unsigned long IF1632_Saved16_esp
;
17 extern unsigned short IF1632_Saved32_ss
;
18 extern unsigned long IF1632_Saved32_ebp
;
19 extern unsigned long IF1632_Saved32_esp
;
21 extern struct segment_descriptor_s
*MakeProcThunks
;
26 unsigned char thunk
[10];
29 /**********************************************************************
33 PushOn16(int size
, unsigned int value
)
35 char *p
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
36 (IF1632_Saved16_esp
& 0xffff));
39 unsigned long *lp
= (unsigned long *) p
- 1;
42 IF1632_Saved16_esp
-= 4;
46 unsigned short *sp
= (unsigned short *) p
- 1;
49 IF1632_Saved16_esp
-= 2;
53 /**********************************************************************
54 * FindDataSegmentForCode
57 FindDataSegmentForCode(unsigned long csip
)
61 seg_idx
= (unsigned short) (csip
>> 19);
62 return Segments
[seg_idx
].owner
;
65 /**********************************************************************
69 CallBack16(void *func
, int n_args
, ...)
73 int arg_type
, arg_value
;
77 for (i
= 0; i
< n_args
; i
++)
79 arg_type
= va_arg(ap
, int);
80 arg_value
= va_arg(ap
, int);
81 PushOn16(arg_type
, arg_value
);
86 return CallTo16((unsigned int) func
,
87 FindDataSegmentForCode((unsigned long) func
));
90 /**********************************************************************
91 * CALLBACK_MakeProcInstance
94 CALLBACK_MakeProcInstance(void *func
, int instance
)
101 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
102 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
110 tp
->thunk
[1] = (unsigned char) instance
;
111 tp
->thunk
[2] = (unsigned char) (instance
>> 8);
115 memcpy(&tp
->thunk
[6], &func
, 4);
121 /**********************************************************************
122 * FreeProcInstance (KERNEL.52)
124 void FreeProcInstance(FARPROC func
)
131 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
132 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
134 if ((void *) tp
->thunk
== (void *) func
)
142 /**********************************************************************
143 * CallWindowProc (USER.122)
145 LONG
CallWindowProc( FARPROC func
, HWND hwnd
, WORD message
,
146 WORD wParam
, LONG lParam
)
148 SpyMessage(hwnd
, message
, wParam
, lParam
);
150 if (HIWORD((LONG
)func
) == WINE_CODE_SELECTOR
)
152 static struct dll_table_entry_s
*user_tab
= NULL
;
153 void *address
= (void *) ((LONG
) func
& 0xffff);
155 if (user_tab
== NULL
)
156 user_tab
= FindDLLTable("USER");
159 if (user_tab
[107].address
== address
)
160 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
163 else if (user_tab
[308].address
== address
)
164 return DefDlgProc(hwnd
, message
, wParam
, lParam
);
166 /* DefMDIChildProc */
167 else if (user_tab
[447].address
== address
)
168 return DefMDIChildProc(hwnd
, message
, wParam
, lParam
);
173 fprintf(stderr
, "wine: Unknown wine callback %08x\n", func
);
177 else if (Is16bitAddress(func
))
179 #ifdef DEBUG_CALLBACK
180 printf("CallWindowProc // 16bit func=%08X !\n", func
);
182 PushOn16( CALLBACK_SIZE_WORD
, hwnd
);
183 PushOn16( CALLBACK_SIZE_WORD
, message
);
184 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
185 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
186 return CallTo16((unsigned int) func
,
187 FindDataSegmentForCode((unsigned long) func
));
191 #ifdef DEBUG_CALLBACK
192 printf("CallWindowProc // 32bit func=%08X !\n", func
);
194 return (*func
)(hwnd
, message
, wParam
, lParam
);
198 /**********************************************************************
201 void CallLineDDAProc(FARPROC func
, short xPos
, short yPos
, long lParam
)
203 if (Is16bitAddress(func
))
205 PushOn16( CALLBACK_SIZE_WORD
, xPos
);
206 PushOn16( CALLBACK_SIZE_WORD
, yPos
);
207 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
208 CallTo16((unsigned int) func
,
209 FindDataSegmentForCode((unsigned long) func
));
213 (*func
)(xPos
, yPos
, lParam
);
217 /**********************************************************************
220 DWORD
CallHookProc( HOOKPROC func
, short code
, WPARAM wParam
, LPARAM lParam
)
222 if (Is16bitAddress(func
))
224 PushOn16( CALLBACK_SIZE_WORD
, code
);
225 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
226 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
227 return CallTo16((unsigned int) func
,
228 FindDataSegmentForCode((unsigned long) func
));
232 return (*func
)( code
, wParam
, lParam
);
236 /**********************************************************************
239 BOOL
CallGrayStringProc(FARPROC func
, HDC hdc
, LPARAM lParam
, INT cch
)
241 if (Is16bitAddress(func
))
243 PushOn16( CALLBACK_SIZE_WORD
, hdc
);
244 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
245 PushOn16( CALLBACK_SIZE_WORD
, cch
);
246 return CallTo16((unsigned int) func
,
247 FindDataSegmentForCode((unsigned long) func
));
251 return (*func
)( hdc
, lParam
, cch
);
255 /* ------------------------------------------------------------------------ */
257 * The following functions realize the Catch/Throw functionality.
258 * My thought is to use the setjmp, longjmp combination to do the
259 * major part of this one. All I have to remember, in addition to
260 * whatever the jmp_buf contains, is the contents of the 16-bit
261 * sp, bp and ss. I do this by storing them in the structure passed
262 * to me by the 16-bit program (including my own jmp_buf...).
263 * Hopefully there isn't any program that modifies the contents!
264 * Bad thing: I have to save part of the stack, since this will
265 * get reused on the next call after my return, leaving it in an
268 #define STACK_DEPTH_16 28
270 struct special_buffer
{
273 char stack_part
[STACK_DEPTH_16
];
276 int Catch (LPCATCHBUF cbuf
)
280 char *stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
281 (IF1632_Saved16_esp
& 0xffff));
283 sb
= malloc (sizeof (struct special_buffer
));
285 sb
-> regs
[0] = IF1632_Saved16_esp
;
286 sb
-> regs
[1] = IF1632_Saved16_ebp
;
287 sb
-> regs
[2] = IF1632_Saved16_ss
& 0xffff;
288 sb
-> regs
[3] = IF1632_Saved32_esp
;
289 sb
-> regs
[4] = IF1632_Saved32_ebp
;
290 sb
-> regs
[5] = IF1632_Saved32_ss
& 0xffff;
291 memcpy (sb
-> stack_part
, stack16
, STACK_DEPTH_16
);
292 tmp_jmp
= &sb
-> buffer
;
293 *((struct special_buffer
**)cbuf
) = sb
;
295 if ((retval
= setjmp (*tmp_jmp
)))
297 IF1632_Saved16_esp
= sb
-> regs
[0];
298 IF1632_Saved16_ebp
= sb
-> regs
[1];
299 IF1632_Saved16_ss
= sb
-> regs
[2] & 0xffff;
300 IF1632_Saved32_esp
= sb
-> regs
[3];
301 IF1632_Saved32_ebp
= sb
-> regs
[4];
302 IF1632_Saved32_ss
= sb
-> regs
[5] & 0xffff;
303 stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
304 (IF1632_Saved16_esp
& 0xffff));
306 memcpy (stack16
, sb
-> stack_part
, STACK_DEPTH_16
);
308 printf ("Been thrown here: %d, retval = %d\n", sb
, retval
);
314 printf ("Will somtime get thrown here: %d\n", sb
);
320 void Throw (LPCATCHBUF cbuf
, int val
)
322 sb
= *((struct special_buffer
**)cbuf
);
324 printf ("Throwing to: %d\n", sb
);
326 longjmp (sb
-> buffer
, val
);
328 #endif /* !WINELIB */