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";
12 extern SEGDESC Segments
[];
13 extern unsigned short IF1632_Saved16_ss
;
14 extern unsigned long IF1632_Saved16_ebp
;
15 extern unsigned long IF1632_Saved16_esp
;
16 extern unsigned short IF1632_Saved32_ss
;
17 extern unsigned long IF1632_Saved32_ebp
;
18 extern unsigned long IF1632_Saved32_esp
;
20 extern struct segment_descriptor_s
*MakeProcThunks
;
25 unsigned char thunk
[10];
28 /**********************************************************************
32 PushOn16(int size
, unsigned int value
)
34 char *p
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
35 (IF1632_Saved16_esp
& 0xffff));
38 unsigned long *lp
= (unsigned long *) p
- 1;
41 IF1632_Saved16_esp
-= 4;
45 unsigned short *sp
= (unsigned short *) p
- 1;
48 IF1632_Saved16_esp
-= 2;
52 /**********************************************************************
53 * FindDataSegmentForCode
56 FindDataSegmentForCode(unsigned long csip
)
60 seg_idx
= (unsigned short) (csip
>> 19);
61 return Segments
[seg_idx
].owner
;
64 /**********************************************************************
68 CallBack16(void *func
, int n_args
, ...)
72 int arg_type
, arg_value
;
76 for (i
= 0; i
< n_args
; i
++)
78 arg_type
= va_arg(ap
, int);
79 arg_value
= va_arg(ap
, int);
80 PushOn16(arg_type
, arg_value
);
85 return CallTo16((unsigned int) func
,
86 FindDataSegmentForCode((unsigned long) func
));
89 /**********************************************************************
90 * CALLBACK_MakeProcInstance
93 CALLBACK_MakeProcInstance(void *func
, int instance
)
100 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
101 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
109 tp
->thunk
[1] = (unsigned char) instance
;
110 tp
->thunk
[2] = (unsigned char) (instance
>> 8);
114 memcpy(&tp
->thunk
[6], &func
, 4);
120 /**********************************************************************
121 * FreeProcInstance (KERNEL.52)
123 void FreeProcInstance(FARPROC func
)
130 tp
= (struct thunk_s
*) MakeProcThunks
->base_addr
;
131 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
133 if ((void *) tp
->thunk
== (void *) func
)
141 /**********************************************************************
142 * CallWindowProc (USER.122)
144 LONG
CallWindowProc( FARPROC func
, HWND hwnd
, WORD message
,
145 WORD wParam
, LONG lParam
)
147 SpyMessage(hwnd
, message
, wParam
, lParam
);
149 if (HIWORD((LONG
)func
) == WINE_CODE_SELECTOR
)
151 static struct dll_table_entry_s
*user_tab
= NULL
;
152 void *address
= (void *) ((LONG
) func
& 0xffff);
154 if (user_tab
== NULL
)
155 user_tab
= FindDLLTable("USER");
158 if (user_tab
[104].address
== address
)
159 return DefWindowProc(hwnd
, message
, wParam
, lParam
);
162 else if (user_tab
[308].address
== address
)
163 return DefDlgProc(hwnd
, message
, wParam
, lParam
);
165 /* DefMDIChildProc */
166 else if (user_tab
[447].address
== address
)
167 return DefMDIChildProc(hwnd
, message
, wParam
, lParam
);
172 fprintf(stderr
, "wine: Unknown wine callback %08x\n", func
);
176 else if (Is16bitAddress(func
))
178 #ifdef DEBUG_CALLBACK
179 printf("CallWindowProc // 16bit func=%08X !\n", func
);
181 PushOn16( CALLBACK_SIZE_WORD
, hwnd
);
182 PushOn16( CALLBACK_SIZE_WORD
, message
);
183 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
184 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
185 return CallTo16((unsigned int) func
,
186 FindDataSegmentForCode((unsigned long) func
));
190 #ifdef DEBUG_CALLBACK
191 printf("CallWindowProc // 32bit func=%08X !\n", func
);
193 return (*func
)(hwnd
, message
, wParam
, lParam
);
197 /**********************************************************************
200 void CallLineDDAProc(FARPROC func
, short xPos
, short yPos
, long lParam
)
202 if (Is16bitAddress(func
))
204 PushOn16( CALLBACK_SIZE_WORD
, xPos
);
205 PushOn16( CALLBACK_SIZE_WORD
, yPos
);
206 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
207 CallTo16((unsigned int) func
,
208 FindDataSegmentForCode((unsigned long) func
));
212 (*func
)(xPos
, yPos
, lParam
);
216 /**********************************************************************
219 DWORD
CallHookProc( HOOKPROC func
, short code
, WPARAM wParam
, LPARAM lParam
)
221 if (Is16bitAddress(func
))
223 PushOn16( CALLBACK_SIZE_WORD
, code
);
224 PushOn16( CALLBACK_SIZE_WORD
, wParam
);
225 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
226 return CallTo16((unsigned int) func
,
227 FindDataSegmentForCode((unsigned long) func
));
231 return (*func
)( code
, wParam
, lParam
);
235 /**********************************************************************
238 BOOL
CallGrayStringProc(FARPROC func
, HDC hdc
, LPARAM lParam
, INT cch
)
240 if (Is16bitAddress(func
))
242 PushOn16( CALLBACK_SIZE_WORD
, hdc
);
243 PushOn16( CALLBACK_SIZE_LONG
, lParam
);
244 PushOn16( CALLBACK_SIZE_WORD
, cch
);
245 return CallTo16((unsigned int) func
,
246 FindDataSegmentForCode((unsigned long) func
));
250 return (*func
)( hdc
, lParam
, cch
);
254 /* ------------------------------------------------------------------------ */
256 * The following functions realize the Catch/Throw functionality.
257 * My thought is to use the setjmp, longjmp combination to do the
258 * major part of this one. All I have to remember, in addition to
259 * whatever the jmp_buf contains, is the contents of the 16-bit
260 * sp, bp and ss. I do this by storing them in the structure passed
261 * to me by the 16-bit program (including my own jmp_buf...).
262 * Hopefully there isn't any program that modifies the contents!
263 * Bad thing: I have to save part of the stack, since this will
264 * get reused on the next call after my return, leaving it in an
267 #define STACK_DEPTH_16 28
269 struct special_buffer
{
272 char stack_part
[STACK_DEPTH_16
];
275 int Catch (LPCATCHBUF cbuf
)
279 char *stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
280 (IF1632_Saved16_esp
& 0xffff));
282 sb
= malloc (sizeof (struct special_buffer
));
284 sb
-> regs
[0] = IF1632_Saved16_esp
;
285 sb
-> regs
[1] = IF1632_Saved16_ebp
;
286 sb
-> regs
[2] = IF1632_Saved16_ss
& 0xffff;
287 sb
-> regs
[3] = IF1632_Saved32_esp
;
288 sb
-> regs
[4] = IF1632_Saved32_ebp
;
289 sb
-> regs
[5] = IF1632_Saved32_ss
& 0xffff;
290 memcpy (sb
-> stack_part
, stack16
, STACK_DEPTH_16
);
291 tmp_jmp
= &sb
-> buffer
;
292 *((struct special_buffer
**)cbuf
) = sb
;
294 if ((retval
= setjmp (*tmp_jmp
)))
296 IF1632_Saved16_esp
= sb
-> regs
[0];
297 IF1632_Saved16_ebp
= sb
-> regs
[1];
298 IF1632_Saved16_ss
= sb
-> regs
[2] & 0xffff;
299 IF1632_Saved32_esp
= sb
-> regs
[3];
300 IF1632_Saved32_ebp
= sb
-> regs
[4];
301 IF1632_Saved32_ss
= sb
-> regs
[5] & 0xffff;
302 stack16
= (char *) (((unsigned int)IF1632_Saved16_ss
<< 16) +
303 (IF1632_Saved16_esp
& 0xffff));
305 memcpy (stack16
, sb
-> stack_part
, STACK_DEPTH_16
);
307 printf ("Been thrown here: %d, retval = %d\n", sb
, retval
);
313 printf ("Will somtime get thrown here: %d\n", sb
);
319 void Throw (LPCATCHBUF cbuf
, int val
)
321 sb
= *((struct special_buffer
**)cbuf
);
323 printf ("Throwing to: %d\n", sb
);
325 longjmp (sb
-> buffer
, val
);