1 static char RCSId
[] = "$Id: wine.c,v 1.2 1993/07/04 04:04:21 root Exp root $";
2 static char Copyright
[] = "Copyright Robert J. Amstadt, 1993";
10 extern SEGDESC Segments
[];
11 extern unsigned short IF1632_Saved16_ss
;
12 extern unsigned long IF1632_Saved16_ebp
;
13 extern unsigned long IF1632_Saved16_esp
;
14 extern unsigned short IF1632_Saved32_ss
;
15 extern unsigned long IF1632_Saved32_ebp
;
16 extern unsigned long IF1632_Saved32_esp
;
18 extern struct segment_descriptor_s
*MakeProcThunks
;
23 unsigned char thunk
[10];
26 /**********************************************************************
30 PushOn16(int size
, unsigned int value
)
32 char *p
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
33 (IF1632_Saved16_esp
& 0xffff));
36 unsigned long *lp
= (unsigned long *) p
- 1;
39 IF1632_Saved16_esp
-= 4;
43 unsigned short *sp
= (unsigned short *) p
- 1;
46 IF1632_Saved16_esp
-= 2;
50 /**********************************************************************
51 * FindDataSegmentForCode
54 FindDataSegmentForCode(unsigned long csip
)
58 seg_idx
= (unsigned short) (csip
>> 19);
59 return Segments
[seg_idx
].owner
;
62 /**********************************************************************
66 CallBack16(void *func
, int n_args
, ...)
70 int arg_type
, arg_value
;
74 for (i
= 0; i
< n_args
; i
++)
76 arg_type
= va_arg(ap
, int);
77 arg_value
= va_arg(ap
, int);
78 PushOn16(arg_type
, arg_value
);
83 return CallTo16((unsigned int) func
,
84 FindDataSegmentForCode((unsigned long) func
));
87 /**********************************************************************
88 * CALLBACK_MakeProcInstance
91 CALLBACK_MakeProcInstance(void *func
, int instance
)
98 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
99 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
107 tp
->thunk
[1] = (unsigned char) instance
;
108 tp
->thunk
[2] = (unsigned char) (instance
>> 8);
112 memcpy(&tp
->thunk
[6], &func
, 4);
118 /**********************************************************************
119 * FreeProcInstance (KERNEL.52)
121 void FreeProcInstance(FARPROC func
)
128 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
129 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
131 if ((void *) tp
->thunk
== (void *) func
)
139 /**********************************************************************
140 * CallWindowProc (USER.122)
142 LONG
CallWindowProc( FARPROC func
, HWND hwnd
, WORD message
,
143 WORD wParam
, LONG lParam
)
145 SpyMessage(hwnd
, message
, wParam
, lParam
);
147 if (Is16bitAddress(func
))
149 PushOn16( CALLBACK_SIZE_WORD
, hwnd
);
150 PushOn16( CALLBACK_SIZE_WORD
, message
);
151 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
152 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
153 return CallTo16((unsigned int) func
,
154 FindDataSegmentForCode((unsigned long) func
));
158 return (*func
)(hwnd
, message
, wParam
, lParam
);
162 /**********************************************************************
165 void CallLineDDAProc(FARPROC func
, short xPos
, short yPos
, long lParam
)
167 if (Is16bitAddress(func
))
169 PushOn16( CALLBACK_SIZE_WORD
, xPos
);
170 PushOn16( CALLBACK_SIZE_WORD
, yPos
);
171 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
172 CallTo16((unsigned int) func
,
173 FindDataSegmentForCode((unsigned long) func
));
177 (*func
)(xPos
, yPos
, lParam
);
181 /**********************************************************************
184 DWORD
CallHookProc( HOOKPROC func
, short code
, WPARAM wParam
, LPARAM lParam
)
186 if (Is16bitAddress(func
))
188 PushOn16( CALLBACK_SIZE_WORD
, code
);
189 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
190 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
191 return CallTo16((unsigned int) func
,
192 FindDataSegmentForCode((unsigned long) func
));
196 return (*func
)( code
, wParam
, lParam
);
200 /**********************************************************************
203 BOOL
CallGrayStringProc(FARPROC func
, HDC hdc
, LPARAM lParam
, INT cch
)
205 if (Is16bitAddress(func
))
207 PushOn16( CALLBACK_SIZE_WORD
, hdc
);
208 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
209 PushOn16( CALLBACK_SIZE_WORD
, cch
);
210 return CallTo16((unsigned int) func
,
211 FindDataSegmentForCode((unsigned long) func
));
215 return (*func
)( hdc
, lParam
, cch
);
219 /* ------------------------------------------------------------------------ */
221 * The following functions realize the Catch/Throw functionality.
222 * My thought is to use the setjmp, longjmp combination to do the
223 * major part of this one. All I have to remember, in addition to
224 * whatever the jmp_buf contains, is the contents of the 16-bit
225 * sp, bp and ss. I do this by storing them in the structure passed
226 * to me by the 16-bit program (including my own jmp_buf...).
227 * Hopefully there isn't any program that modifies the contents!
228 * Bad thing: I have to save part of the stack, since this will
229 * get reused on the next call after my return, leaving it in an
232 #define STACK_DEPTH_16 28
234 struct special_buffer
{
237 char stack_part
[STACK_DEPTH_16
];
240 int Catch (LPCATCHBUF cbuf
)
244 char *stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
245 (IF1632_Saved16_esp
& 0xffff));
247 sb
= malloc (sizeof (struct special_buffer
));
249 sb
-> regs
[0] = IF1632_Saved16_esp
;
250 sb
-> regs
[1] = IF1632_Saved16_ebp
;
251 sb
-> regs
[2] = IF1632_Saved16_ss
& 0xffff;
252 sb
-> regs
[3] = IF1632_Saved32_esp
;
253 sb
-> regs
[4] = IF1632_Saved32_ebp
;
254 sb
-> regs
[5] = IF1632_Saved32_ss
& 0xffff;
255 memcpy (sb
-> stack_part
, stack16
, STACK_DEPTH_16
);
256 tmp_jmp
= &sb
-> buffer
;
257 *((struct special_buffer
**)cbuf
) = sb
;
259 if ((retval
= setjmp (*tmp_jmp
)))
261 IF1632_Saved16_esp
= sb
-> regs
[0];
262 IF1632_Saved16_ebp
= sb
-> regs
[1];
263 IF1632_Saved16_ss
= sb
-> regs
[2] & 0xffff;
264 IF1632_Saved32_esp
= sb
-> regs
[3];
265 IF1632_Saved32_ebp
= sb
-> regs
[4];
266 IF1632_Saved32_ss
= sb
-> regs
[5] & 0xffff;
267 stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
268 (IF1632_Saved16_esp
& 0xffff));
270 memcpy (stack16
, sb
-> stack_part
, STACK_DEPTH_16
);
272 printf ("Been thrown here: %d, retval = %d\n", sb
, retval
);
278 printf ("Will somtime get thrown here: %d\n", sb
);
284 void Throw (LPCATCHBUF cbuf
, int val
)
286 sb
= *((struct special_buffer
**)cbuf
);
288 printf ("Throwing to: %d\n", sb
);
290 longjmp (sb
-> buffer
, val
);