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";
15 #include "stackframe.h"
21 extern unsigned long IF1632_Saved32_ebp
;
22 extern unsigned long IF1632_Saved32_esp
;
24 static WORD ThunkSelector
= 0;
29 unsigned char thunk
[8];
33 /**********************************************************************
36 FARPROC
MakeProcInstance( FARPROC func
, WORD instance
)
44 HGLOBAL handle
= GLOBAL_Alloc( GMEM_ZEROINIT
, 0x10000, 0, TRUE
, FALSE
);
45 ThunkSelector
= GlobalHandleToSel(handle
);
48 thunks
= (char *)PTR_SEG_OFF_TO_LIN( ThunkSelector
, 0 );
49 tp
= (struct thunk_s
*) thunks
;
50 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
54 if (tp
->used
) return (FARPROC
)0;
56 tp
->thunk
[0] = 0xb8; /* movw instance, %ax */
57 tp
->thunk
[1] = (unsigned char) instance
;
58 tp
->thunk
[2] = (unsigned char) (instance
>> 8);
59 tp
->thunk
[3] = 0xea; /* ljmp func */
60 *(LONG
*)&tp
->thunk
[4] = (LONG
)func
;
63 return (FARPROC
)MAKELONG( (char *)tp
->thunk
- thunks
, ThunkSelector
);
66 /**********************************************************************
67 * FreeProcInstance (KERNEL.52)
69 void FreeProcInstance(FARPROC func
)
74 tp
= (struct thunk_s
*) PTR_SEG_OFF_TO_LIN( ThunkSelector
, 0 );
75 for (i
= 0; i
< 0x10000 / sizeof(*tp
); i
++, tp
++)
77 if ((void *) tp
->thunk
== (void *) func
)
85 /**********************************************************************
86 * GetCodeHandle (KERNEL.93)
88 HANDLE
GetCodeHandle( FARPROC proc
)
90 struct thunk_s
*tp
= (struct thunk_s
*)proc
;
92 /* Return the code segment containing 'proc'. */
93 /* Not sure if this is really correct (shouldn't matter that much). */
94 printf( "STUB: GetCodeHandle(%p) returning %x\n",
95 proc
, tp
->thunk
[8] + (tp
->thunk
[9] << 8) );
96 return tp
->thunk
[8] + (tp
->thunk
[9] << 8);
100 /**********************************************************************
101 * CallWindowProc (USER.122)
103 LONG
CallWindowProc( WNDPROC func
, HWND hwnd
, WORD message
,
104 WORD wParam
, LONG lParam
)
106 SpyMessage(hwnd
, message
, wParam
, lParam
);
107 return CallWndProc( (FARPROC
)func
, hwnd
, message
, wParam
, lParam
);
111 /* ------------------------------------------------------------------------ */
113 * The following functions realize the Catch/Throw functionality.
114 * My thought is to use the setjmp, longjmp combination to do the
115 * major part of this one. All I have to remember, in addition to
116 * whatever the jmp_buf contains, is the contents of the 16-bit
117 * sp, bp and ss. I do this by storing them in the structure passed
118 * to me by the 16-bit program (including my own jmp_buf...).
119 * Hopefully there isn't any program that modifies the contents!
120 * Bad thing: I have to save part of the stack, since this will
121 * get reused on the next call after my return, leaving it in an
124 #define STACK_DEPTH_16 28
126 struct special_buffer
{
129 char stack_part
[STACK_DEPTH_16
];
132 int Catch (LPCATCHBUF cbuf
)
137 sb
= malloc (sizeof (struct special_buffer
));
139 sb
-> regs
[0] = IF1632_Saved16_sp
& 0xffff;
140 sb
-> regs
[1] = IF1632_Saved16_bp
& 0xffff;
141 sb
-> regs
[2] = IF1632_Saved16_ss
& 0xffff;
142 sb
-> regs
[3] = IF1632_Saved32_esp
;
143 sb
-> regs
[4] = IF1632_Saved32_ebp
;
144 memcpy (sb
-> stack_part
, CURRENT_STACK16
, STACK_DEPTH_16
);
145 tmp_jmp
= &sb
-> buffer
;
146 *((struct special_buffer
**)cbuf
) = sb
;
148 if ((retval
= setjmp (*tmp_jmp
)))
150 IF1632_Saved16_sp
= sb
-> regs
[0] & 0xffff;
151 IF1632_Saved16_bp
= sb
-> regs
[1] & 0xffff;
152 IF1632_Saved16_ss
= sb
-> regs
[2] & 0xffff;
153 IF1632_Saved32_esp
= sb
-> regs
[3];
154 IF1632_Saved32_ebp
= sb
-> regs
[4];
156 memcpy (CURRENT_STACK16
, sb
-> stack_part
, STACK_DEPTH_16
);
157 dprintf_catch (stddeb
, "Been thrown here: %d, retval = %d\n",
158 (int) sb
, (int) retval
);
162 dprintf_catch (stddeb
, "Will somtime get thrown here: %d\n",
168 void Throw (LPCATCHBUF cbuf
, int val
)
170 sb
= *((struct special_buffer
**)cbuf
);
171 dprintf_catch (stddeb
, "Throwing to: %d\n", (int) sb
);
172 longjmp (sb
-> buffer
, val
);
174 #endif /* !WINELIB */