Release 950403
[wine/multimedia.git] / if1632 / callback.c
bloba941b16045db27c0826e4af50304b5d3f374fd6a
1 #ifndef WINELIB
2 /*
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";
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <strings.h>
10 #include <setjmp.h>
11 #include "windows.h"
12 #include "callback.h"
13 #include "wine.h"
14 #include "global.h"
15 #include "stackframe.h"
16 #include "dlls.h"
17 #include "stddebug.h"
18 #include "debug.h"
19 #include "if1632.h"
21 extern unsigned long IF1632_Saved32_ebp;
22 extern unsigned long IF1632_Saved32_esp;
24 static WORD ThunkSelector = 0;
26 struct thunk_s
28 int used;
29 unsigned char thunk[8];
33 /**********************************************************************
34 * MakeProcInstance
36 FARPROC MakeProcInstance( FARPROC func, WORD instance )
38 char *thunks;
39 struct thunk_s *tp;
40 int i;
42 if (!ThunkSelector)
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++)
51 if (!tp->used)
52 break;
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;
61 tp->used = 1;
63 return (FARPROC)MAKELONG( (char *)tp->thunk - thunks, ThunkSelector );
66 /**********************************************************************
67 * FreeProcInstance (KERNEL.52)
69 void FreeProcInstance(FARPROC func)
71 struct thunk_s *tp;
72 int i;
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)
79 tp->used = 0;
80 break;
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
122 * undefined state.
124 #define STACK_DEPTH_16 28
126 struct special_buffer {
127 jmp_buf buffer;
128 long regs [5];
129 char stack_part [STACK_DEPTH_16];
130 } *sb;
132 int Catch (LPCATCHBUF cbuf)
134 WORD retval;
135 jmp_buf *tmp_jmp;
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);
159 free ((void *) sb);
160 return (retval);
161 } else {
162 dprintf_catch (stddeb, "Will somtime get thrown here: %d\n",
163 (int) sb);
164 return (retval);
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 */