00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <os2win.h>
00018 #include <string.h>
00019 #include <win\winproc.h>
00020 #include <win\debugtools.h>
00021 #include <heapcode.h>
00022 #include "win32wbase.h"
00023
00024 #define DBG_LOCALLOG DBG_winproc
00025 #include "dbglocal.h"
00026
00027 DECLARE_DEBUG_CHANNEL(relay)
00028
00029
00030
00031 #pragma pack(1)
00032 typedef struct
00033 {
00034 BYTE jmp;
00035 WNDPROC proc WINE_PACKED;
00036 } WINPROC_JUMP;
00037 #pragma pack()
00038
00039 typedef struct tagWINDOWPROC
00040 {
00041 WINPROC_JUMP jmp;
00042 struct tagWINDOWPROC *next;
00043 UINT magic;
00044 WINDOWPROCTYPE type;
00045 WINDOWPROCUSER user;
00046 } WINDOWPROC;
00047
00048 #define WINPROC_MAGIC ('W' | ('P' << 8) | ('R' << 16) | ('C' << 24))
00049
00050 #define WINPROC_THUNKPROC(pproc) \
00051 (WNDPROC)((LONG)(pproc)->jmp.proc + (LONG)(&(pproc)->jmp.proc+1))
00052
00053
00054
00055
00056
00057
00058 static WINDOWPROC *WINPROC_GetPtr( WNDPROC handle )
00059 {
00060 BYTE *ptr;
00061 WINDOWPROC *proc;
00062
00063 ptr = (BYTE *)handle;
00064 if(ptr == NULL) {
00065 DebugInt3();
00066 return NULL;
00067 }
00068
00069
00070
00071
00072
00073
00074 if (((WINDOWPROC *)ptr)->magic == WINPROC_MAGIC)
00075 return (WINDOWPROC *)ptr;
00076
00077 return NULL;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086 static WINDOWPROC *WINPROC_AllocWinProc( WNDPROC func, WINDOWPROCTYPE type,
00087 WINDOWPROCUSER user )
00088 {
00089 WINDOWPROC *proc, *oldproc;
00090
00091
00092
00093 if (!(proc = (WINDOWPROC *)_cmalloc(sizeof(WINDOWPROC) ))) return 0;
00094
00095
00096
00097 oldproc = WINPROC_GetPtr( func );
00098 if (oldproc)
00099 {
00100 *proc = *oldproc;
00101 }
00102 else
00103 {
00104 switch(type)
00105 {
00106 case WIN_PROC_32A:
00107 case WIN_PROC_32W:
00108 proc->jmp.jmp = 0xe9;
00109
00110 proc->jmp.proc = (WNDPROC)((LONG)func - (LONG)(&proc->jmp.proc+1));
00111 break;
00112 default:
00113
00114 break;
00115 }
00116 proc->magic = WINPROC_MAGIC;
00117 proc->type = type;
00118 proc->user = user;
00119 }
00120 proc->next = NULL;
00121 return proc;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130 WNDPROC WINPROC_GetProc( HWINDOWPROC proc, WINDOWPROCTYPE type )
00131 {
00132 WINDOWPROC *lpProc = (WINDOWPROC *)proc;
00133
00134 if(!lpProc) {
00135 DebugInt3();
00136 return NULL;
00137 }
00138
00139 if(type != lpProc->type) {
00140
00141 return (WNDPROC)&lpProc->jmp;
00142 }
00143 else return WINPROC_THUNKPROC(lpProc);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168 BOOL WINPROC_SetProc( HWINDOWPROC *pFirst, WNDPROC func,
00169 WINDOWPROCTYPE type, WINDOWPROCUSER user )
00170 {
00171 BOOL bRecycle = FALSE;
00172 WINDOWPROC *proc, **ppPrev;
00173
00174 if(func == NULL) {
00175 *(WINDOWPROC **)pFirst = 0;
00176 return TRUE;
00177 }
00178
00179
00180
00181 ppPrev = (WINDOWPROC **)pFirst;
00182 proc = WINPROC_GetPtr( func );
00183 while (*ppPrev)
00184 {
00185 if (proc)
00186 {
00187 if (*ppPrev == proc)
00188 {
00189 if ((*ppPrev)->user != user)
00190 {
00191
00192
00193 WINPROC_FreeProc( *pFirst, (*ppPrev)->user );
00194 *(WINDOWPROC **)pFirst = *ppPrev;
00195 return TRUE;
00196 }
00197 bRecycle = TRUE;
00198 break;
00199 }
00200 }
00201 else
00202 {
00203 if (((*ppPrev)->type == type) &&
00204 (func == WINPROC_THUNKPROC(*ppPrev)))
00205 {
00206 bRecycle = TRUE;
00207 break;
00208 }
00209 }
00210
00211
00212 if ((*ppPrev)->user != user) break;
00213 ppPrev = &(*ppPrev)->next;
00214 }
00215
00216 if (bRecycle)
00217 {
00218
00219 proc = *ppPrev;
00220 *ppPrev = proc->next;
00221 }
00222 else
00223 {
00224 if (proc)
00225 {
00226 type = proc->type;
00227 func = WINPROC_THUNKPROC(proc);
00228 }
00229 proc = WINPROC_AllocWinProc( func, type, user );
00230 if (!proc) return FALSE;
00231 }
00232
00233
00234
00235 proc->next = *(WINDOWPROC **)pFirst;
00236 *(WINDOWPROC **)pFirst = proc;
00237 return TRUE;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246 void WINPROC_FreeProc( HWINDOWPROC proc, WINDOWPROCUSER user )
00247 {
00248 while (proc)
00249 {
00250 WINDOWPROC *next = ((WINDOWPROC *)proc)->next;
00251 if (((WINDOWPROC *)proc)->user != user) break;
00252 free( proc );
00253 proc = next;
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263 WINDOWPROCTYPE WINPROC_GetProcType( HWINDOWPROC proc )
00264 {
00265 if (!proc ||
00266 (((WINDOWPROC *)proc)->magic != WINPROC_MAGIC))
00267 return WIN_PROC_INVALID;
00268 return ((WINDOWPROC *)proc)->type;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 LRESULT WINAPI CallWindowProcA(
00296 WNDPROC func,
00297 HWND hwnd,
00298 UINT msg,
00299 WPARAM wParam,
00300 LPARAM lParam
00301 ) {
00302 WINDOWPROC *proc = WINPROC_GetPtr( func );
00303
00304 if(proc) {
00305 dprintf2(("CallWindowProcA %x %x %x %x %x -> proc %x, type %d, org func %x", func, hwnd, msg, wParam, lParam, proc, proc->type, WINPROC_THUNKPROC(proc)));
00306 }
00307 else dprintf2(("CallWindowProcA %x %x %x %x %x (unknown proc)", func, hwnd, msg, wParam, lParam));
00308
00309 if(!IsWindow(hwnd)) {
00310 dprintf(("CallWindowProcA, window %x not found", hwnd));
00311
00312 return 0;
00313 }
00314
00315 if (!proc) return func(hwnd, msg, wParam, lParam );
00316
00317 switch(proc->type)
00318 {
00319 case WIN_PROC_32A:
00320 return func(hwnd, msg, wParam, lParam );
00321 case WIN_PROC_32W:
00322 return WINPROC_CallProc32ATo32W( func, hwnd, msg, wParam, lParam );
00323 default:
00324 WARN_(relay)("Invalid proc %p\n", proc );
00325 return 0;
00326 }
00327 }
00328
00329
00330
00331
00332
00333 LRESULT WINAPI CallWindowProcW( WNDPROC func, HWND hwnd, UINT msg,
00334 WPARAM wParam, LPARAM lParam )
00335 {
00336 WINDOWPROC *proc = WINPROC_GetPtr( func );
00337
00338 if(proc) {
00339 dprintf2(("CallWindowProcW %x %x %x %x %x -> proc %x, type %d, org func %x", func, hwnd, msg, wParam, lParam, proc, proc->type, WINPROC_THUNKPROC(proc)));
00340 }
00341 else dprintf2(("CallWindowProcW %x %x %x %x %x (unknown proc)", func, hwnd, msg, wParam, lParam));
00342
00343 if(!IsWindow(hwnd)) {
00344 dprintf(("CallWindowProcW, window %x not found", hwnd));
00345
00346 return 0;
00347 }
00348
00349 if (!proc) return func( hwnd, msg, wParam, lParam );
00350
00351 switch(proc->type)
00352 {
00353 case WIN_PROC_32A:
00354 return WINPROC_CallProc32WTo32A( func, hwnd, msg, wParam, lParam );
00355 case WIN_PROC_32W:
00356 return func(hwnd, msg, wParam, lParam );
00357 default:
00358 WARN_(relay)("Invalid proc %p\n", proc );
00359 return 0;
00360 }
00361 }
00362