Commit 3c3ba771 authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

user32: Clearly separate the 16bit code out of user32.

parent a91a97d8
...@@ -341,7 +341,7 @@ static LRESULT CALLBACK WDML_EventProc(HWND hwndEvent, UINT uMsg, WPARAM wParam, ...@@ -341,7 +341,7 @@ static LRESULT CALLBACK WDML_EventProc(HWND hwndEvent, UINT uMsg, WPARAM wParam,
* *
*/ */
UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes, BOOL bUnicode, BOOL b16) DWORD afCmd, DWORD ulRes, BOOL bUnicode)
{ {
WDML_INSTANCE* pInstance; WDML_INSTANCE* pInstance;
WDML_INSTANCE* reference_inst; WDML_INSTANCE* reference_inst;
...@@ -377,7 +377,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, ...@@ -377,7 +377,6 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
pInstance->threadID = GetCurrentThreadId(); pInstance->threadID = GetCurrentThreadId();
pInstance->callback = *pfnCallback; pInstance->callback = *pfnCallback;
pInstance->unicode = bUnicode; pInstance->unicode = bUnicode;
pInstance->win16 = b16;
pInstance->nodeList = NULL; /* node will be added later */ pInstance->nodeList = NULL; /* node will be added later */
pInstance->monitorFlags = afCmd & MF_MASK; pInstance->monitorFlags = afCmd & MF_MASK;
pInstance->wStatus = 0; pInstance->wStatus = 0;
...@@ -591,7 +590,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, ...@@ -591,7 +590,7 @@ UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback, UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes) DWORD afCmd, DWORD ulRes)
{ {
return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, FALSE, FALSE); return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, FALSE);
} }
/****************************************************************************** /******************************************************************************
...@@ -611,7 +610,7 @@ UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback, ...@@ -611,7 +610,7 @@ UINT WINAPI DdeInitializeA(LPDWORD pidInst, PFNCALLBACK pfnCallback,
UINT WINAPI DdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback, UINT WINAPI DdeInitializeW(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes) DWORD afCmd, DWORD ulRes)
{ {
return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, TRUE, FALSE); return WDML_Initialize(pidInst, pfnCallback, afCmd, ulRes, TRUE);
} }
/***************************************************************** /*****************************************************************
...@@ -728,18 +727,10 @@ HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInstance, UINT uType, UINT uFmt, H ...@@ -728,18 +727,10 @@ HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInstance, UINT uType, UINT uFmt, H
if (pInstance == NULL) if (pInstance == NULL)
return NULL; return NULL;
TRACE("invoking CB%d[%p] (%x %x %p %p %p %p %lx %lx)\n", TRACE("invoking CB[%p] (%x %x %p %p %p %p %lx %lx)\n",
pInstance->win16 ? 16 : 32, pInstance->callback, uType, uFmt, pInstance->callback, uType, uFmt,
hConv, hsz1, hsz2, hdata, dwData1, dwData2); hConv, hsz1, hsz2, hdata, dwData1, dwData2);
if (pInstance->win16) ret = pInstance->callback(uType, uFmt, hConv, hsz1, hsz2, hdata, dwData1, dwData2);
{
ret = WDML_InvokeCallback16(pInstance->callback, uType, uFmt, hConv,
hsz1, hsz2, hdata, dwData1, dwData2);
}
else
{
ret = pInstance->callback(uType, uFmt, hConv, hsz1, hsz2, hdata, dwData1, dwData2);
}
TRACE("done => %p\n", ret); TRACE("done => %p\n", ret);
return ret; return ret;
} }
......
...@@ -157,7 +157,6 @@ typedef struct tagWDML_INSTANCE ...@@ -157,7 +157,6 @@ typedef struct tagWDML_INSTANCE
BOOL monitor; /* have these two as full Booleans cos they'll be tested frequently */ BOOL monitor; /* have these two as full Booleans cos they'll be tested frequently */
BOOL clientOnly; /* bit wasteful of space but it will be faster */ BOOL clientOnly; /* bit wasteful of space but it will be faster */
BOOL unicode; /* Flag to indicate Win32 API used to initialise */ BOOL unicode; /* Flag to indicate Win32 API used to initialise */
BOOL win16; /* flag to indicate Win16 API used to initialize */
HSZNode* nodeList; /* for cleaning upon exit */ HSZNode* nodeList; /* for cleaning upon exit */
PFNCALLBACK callback; PFNCALLBACK callback;
DWORD CBFflags; DWORD CBFflags;
...@@ -189,9 +188,6 @@ typedef enum { ...@@ -189,9 +188,6 @@ typedef enum {
extern HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInst, UINT uType, UINT uFmt, HCONV hConv, extern HDDEDATA WDML_InvokeCallback(WDML_INSTANCE* pInst, UINT uType, UINT uFmt, HCONV hConv,
HSZ hsz1, HSZ hsz2, HDDEDATA hdata, HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
ULONG_PTR dwData1, ULONG_PTR dwData2) DECLSPEC_HIDDEN; ULONG_PTR dwData1, ULONG_PTR dwData2) DECLSPEC_HIDDEN;
extern HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt, HCONV hConv,
HSZ hsz1, HSZ hsz2, HDDEDATA hdata,
DWORD dwData1, DWORD dwData2) DECLSPEC_HIDDEN;
extern WDML_SERVER* WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN; extern WDML_SERVER* WDML_AddServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
extern void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN; extern void WDML_RemoveServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN; extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* pInstance, HSZ hszService, HSZ hszTopic) DECLSPEC_HIDDEN;
...@@ -201,7 +197,7 @@ extern WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct) DE ...@@ -201,7 +197,7 @@ extern WDML_QUEUE_STATE WDML_ServerHandle(WDML_CONV* pConv, WDML_XACT* pXAct) DE
HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, LPDWORD pdwResult) DECLSPEC_HIDDEN; HDDEDATA WDML_ClientHandle(WDML_CONV *pConv, WDML_XACT *pXAct, DWORD dwTimeout, LPDWORD pdwResult) DECLSPEC_HIDDEN;
/* called both in DdeClientTransaction and server side. */ /* called both in DdeClientTransaction and server side. */
extern UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback, extern UINT WDML_Initialize(LPDWORD pidInst, PFNCALLBACK pfnCallback,
DWORD afCmd, DWORD ulRes, BOOL bUnicode, BOOL b16) DECLSPEC_HIDDEN; DWORD afCmd, DWORD ulRes, BOOL bUnicode) DECLSPEC_HIDDEN;
extern WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side, extern WDML_CONV* WDML_AddConv(WDML_INSTANCE* pInstance, WDML_SIDE side,
HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer) DECLSPEC_HIDDEN; HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer) DECLSPEC_HIDDEN;
extern void WDML_RemoveConv(WDML_CONV* pConv, WDML_SIDE side) DECLSPEC_HIDDEN; extern void WDML_RemoveConv(WDML_CONV* pConv, WDML_SIDE side) DECLSPEC_HIDDEN;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Copyright 1997 Len White * Copyright 1997 Len White
* Copyright 1999 Keith Matthews * Copyright 1999 Keith Matthews
* Copyright 2000 Corel * Copyright 2000 Corel
* Copyright 2001,2002 Eric Pouech * Copyright 2001,2002,2009 Eric Pouech
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -22,6 +22,9 @@ ...@@ -22,6 +22,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#include "config.h"
#include "wine/port.h"
#include <stdarg.h> #include <stdarg.h>
#include <string.h> #include <string.h>
#include "windef.h" #include "windef.h"
...@@ -30,7 +33,6 @@ ...@@ -30,7 +33,6 @@
#include "wownt32.h" #include "wownt32.h"
#include "dde.h" #include "dde.h"
#include "ddeml.h" #include "ddeml.h"
#include "dde_private.h"
#include "wine/debug.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ddeml); WINE_DEFAULT_DEBUG_CHANNEL(ddeml);
...@@ -87,15 +89,14 @@ static void map3216_conv_context(CONVCONTEXT16* cc16, const CONVCONTEXT* cc32) ...@@ -87,15 +89,14 @@ static void map3216_conv_context(CONVCONTEXT16* cc16, const CONVCONTEXT* cc32)
cc16->dwSecurity = cc32->dwSecurity; cc16->dwSecurity = cc32->dwSecurity;
} }
/****************************************************************** /******************************************************************
* WDML_InvokeCallback16 * WDML_InvokeCallback16
* *
* *
*/ */
HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt, static HDDEDATA CALLBACK WDML_InvokeCallback16(DWORD pfn16, UINT uType, UINT uFmt,
HCONV hConv, HSZ hsz1, HSZ hsz2, HCONV hConv, HSZ hsz1, HSZ hsz2,
HDDEDATA hdata, DWORD dwData1, DWORD dwData2) HDDEDATA hdata, ULONG_PTR dwData1, ULONG_PTR dwData2)
{ {
DWORD d1 = 0; DWORD d1 = 0;
HDDEDATA ret; HDDEDATA ret;
...@@ -133,7 +134,7 @@ HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt, ...@@ -133,7 +134,7 @@ HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt,
args[2] = LOWORD(d1); args[2] = LOWORD(d1);
args[1] = HIWORD(dwData2); args[1] = HIWORD(dwData2);
args[0] = LOWORD(dwData2); args[0] = LOWORD(dwData2);
WOWCallback16Ex( (DWORD)pfn, WCB16_PASCAL, sizeof(args), args, (DWORD *)&ret ); WOWCallback16Ex(pfn16, WCB16_PASCAL, sizeof(args), args, (DWORD *)&ret);
switch (uType) switch (uType)
{ {
...@@ -145,14 +146,89 @@ HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt, ...@@ -145,14 +146,89 @@ HDDEDATA WDML_InvokeCallback16(PFNCALLBACK pfn, UINT uType, UINT uFmt,
return ret; return ret;
} }
#define MAX_THUNKS 32
/* As DDEML doesn't provide a way to get back to an InstanceID when
* a callback is run, we use thunk in order to implement simply the
* 32bit->16bit callback mechanism.
* For each 16bit instance, we create a thunk, which will be passed as
* a 32bit callback. This thunk also stores (in the code!) the 16bit
* address of the 16bit callback, and passes it back to
* WDML_InvokeCallback16.
* The code below is mainly to create the thunks themselved
*/
static struct ddeml_thunk
{
BYTE popl_eax; /* popl %eax (return address) */
BYTE pushl_func; /* pushl $pfn16 (16bit callback function) */
SEGPTR pfn16;
BYTE pushl_eax; /* pushl %eax */
BYTE jmp; /* ljmp WDML_InvokeCallback16 */
DWORD callback;
DWORD instId; /* instance ID */
} *DDEML16_Thunks;
static CRITICAL_SECTION ddeml_cs;
static CRITICAL_SECTION_DEBUG critsect_debug =
{
0, 0, &ddeml_cs,
{ &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
0, 0, { (DWORD_PTR)(__FILE__ ": ddeml_cs") }
};
static CRITICAL_SECTION ddeml_cs = { &critsect_debug, -1, 0, 0, 0, 0 };
static struct ddeml_thunk* DDEML_AddThunk(DWORD instId, DWORD pfn16)
{
struct ddeml_thunk* thunk;
if (!DDEML16_Thunks)
{
DDEML16_Thunks = VirtualAlloc(NULL, MAX_THUNKS * sizeof(*DDEML16_Thunks), MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!DDEML16_Thunks) return NULL;
for (thunk = DDEML16_Thunks; thunk < &DDEML16_Thunks[MAX_THUNKS]; thunk++)
{
thunk->popl_eax = 0x58; /* popl %eax */
thunk->pushl_func = 0x68; /* pushl $pfn16 */
thunk->pfn16 = 0;
thunk->pushl_eax = 0x50; /* pushl %eax */
thunk->jmp = 0xe9; /* jmp WDML_InvokeCallback16 */
thunk->callback = (char *)WDML_InvokeCallback16 - (char *)(&thunk->callback + 1);
thunk->instId = 0;
}
}
for (thunk = DDEML16_Thunks; thunk < &DDEML16_Thunks[MAX_THUNKS]; thunk++)
{
/* either instId is 0, and we're looking for an empty slot, or
* instId is an already existing instance, and we should find its thunk
*/
if (thunk->instId == instId)
{
thunk->pfn16 = pfn16;
return thunk;
}
}
FIXME("Out of ddeml-thunks. Bump MAX_THUNKS\n");
return NULL;
}
/****************************************************************************** /******************************************************************************
* DdeInitialize (DDEML.2) * DdeInitialize (DDEML.2)
*/ */
UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback, UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
DWORD afCmd, DWORD ulRes) DWORD afCmd, DWORD ulRes)
{ {
return WDML_Initialize(pidInst, (PFNCALLBACK)pfnCallback, afCmd, ulRes, UINT16 ret;
FALSE, TRUE); struct ddeml_thunk* thunk;
EnterCriticalSection(&ddeml_cs);
if ((thunk = DDEML_AddThunk(*pidInst, (DWORD)pfnCallback)))
{
ret = DdeInitializeA(pidInst, (PFNCALLBACK)thunk, afCmd, ulRes);
if (ret == DMLERR_NO_ERROR) thunk->instId = *pidInst;
}
else ret = DMLERR_SYS_ERROR;
LeaveCriticalSection(&ddeml_cs);
return ret;
} }
/***************************************************************** /*****************************************************************
...@@ -160,7 +236,23 @@ UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback, ...@@ -160,7 +236,23 @@ UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
*/ */
BOOL16 WINAPI DdeUninitialize16(DWORD idInst) BOOL16 WINAPI DdeUninitialize16(DWORD idInst)
{ {
return (BOOL16)DdeUninitialize(idInst); struct ddeml_thunk* thunk;
BOOL16 ret = FALSE;
if (!DdeUninitialize(idInst)) return FALSE;
EnterCriticalSection(&ddeml_cs);
for (thunk = DDEML16_Thunks; thunk < &DDEML16_Thunks[MAX_THUNKS]; thunk++)
{
if (thunk->instId == idInst)
{
thunk->instId = 0;
ret = TRUE;
break;
}
}
LeaveCriticalSection(&ddeml_cs);
if (!ret) FIXME("Should never happen\n");
return ret;
} }
/***************************************************************** /*****************************************************************
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment