Merge from Corel tree. Contributors are:

- Corel (Sean Langley, Michael Abd-El-Malek, Rick Mutzke, Bill Xing)
- Macadamian on behalf of Corel (Louis-Philippe Gagnon, Jean-Claude Batista)
Also added a few bits:
- Complete window model for several instances and conversations.
- Support for asynchronous transactions.
- Fixed some code (WM_DDE_REQUEST, WM_DDE_ADVISE, WM_DDE_REQUEST) handling.
- Support for wild connections.
This commit is contained in:
Eric Pouech 2001-06-22 23:02:48 +00:00 committed by Alexandre Julliard
parent f4b14106f7
commit 6a03ac0e96
11 changed files with 4824 additions and 2287 deletions

View file

@ -10,7 +10,10 @@ IMPORTS = gdi32 kernel32 ntdll
C_SRCS = \
bidi16.c \
cache.c \
ddeml.c \
dde/client.c \
dde/ddeml16.c \
dde/misc.c \
dde/server.c \
display.c \
exticon.c \
lstr.c \
@ -42,6 +45,7 @@ SUBDIRS = \
$(TOPOBJDIR)/windows
EXTRASUBDIRS = \
dde \
resources
@MAKE_DLL_RULES@

1113
dlls/user/dde/client.c Normal file

File diff suppressed because it is too large Load diff

208
dlls/user/dde/dde_private.h Normal file
View file

@ -0,0 +1,208 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* DDEML library
*
* Copyright 1997 Alexandre Julliard
* Copyright 1997 Len White
* Copyright 1999 Keith Matthews
* Copyright 2000 Corel
* Copyright 2001 Eric Pouech
*/
#ifndef __WINE_DDEML_PRIVATE_H
#define __WINE_DDEML_PRIVATE_H
/* defined in atom.c file.
*/
#define MAX_ATOM_LEN 255
/* Maximum buffer size ( including the '\0' ).
*/
#define MAX_BUFFER_LEN (MAX_ATOM_LEN + 1)
/* This is a simple list to keep track of the strings created
* by DdeCreateStringHandle. The list is used to free
* the strings whenever DdeUninitialize is called.
* This mechanism is not complete and does not handle multiple instances.
* Most of the DDE API use a DWORD parameter indicating which instance
* of a given program is calling them. The API are supposed to
* associate the data to the instance that created it.
*/
/* The internal structures (prefixed by WDML) are used as follows:
* + a WDML_INSTANCE is created for each instance creation (DdeInitialize)
* - a popup windows (InstanceClass) is created for each instance. It will be
* used to receive all the DDEML events (server registration, conversation
* confirmation...)
* + when registring a server (DdeNameService) a WDML_SERVER is created
* - a popup window (ServerNameClass) is created
* + a conversation is represented by two WDML_CONV structures:
* - one on the client side, the other one on the server side
* - this is needed because the address spaces may be different
* - therefore, two lists of links are kept for each instance
* - two windows are created for a conversation:
* o a popup window on client side (ClientConvClass)
* o a child window (of the ServerName) on the server side
* (ServerConvClass)
* - all the exchanges then take place between those two windows
* + a (warm or link) is represented by two WDML_LINK structures:
* - one on client side, the other one on server side
* - therefore, two lists of links are kept for each instance
*
* To help getting back to data, WDML windows store information:
* - offset 0: the DDE instance
* - offset 4: the current conversation (for ClientConv and ServerConv only)
*
*/
typedef struct tagHSZNode
{
struct tagHSZNode* next;
HSZ hsz;
HSZ hsz2;
} HSZNode;
typedef struct tagWDML_SERVER
{
struct tagWDML_SERVER* next;
HSZ hszService;
HSZ hszTopic;
BOOL filterOn;
HWND hwndServer;
} WDML_SERVER;
typedef struct tagWDML_XACT {
struct tagWDML_XACT* next;
DWORD xActID;
UINT ddeMsg;
HDDEDATA hDdeData;
DWORD dwTimeout;
DWORD hUser;
union {
struct {
UINT wType;
UINT wFmt;
HSZ hszItem;
HGLOBAL hDdeAdvise;
} advise;
struct {
UINT wFmt;
HSZ hszItem;
} unadvise;
struct {
HGLOBAL hMem;
} execute;
struct {
HGLOBAL hMem;
HSZ hszItem;
} poke;
struct {
HSZ hszItem;
} request;
} u;
} WDML_XACT;
typedef struct tagWDML_CONV
{
struct tagWDML_CONV* next; /* to link all the conversations */
struct tagWDML_INSTANCE* thisInstance;
HSZ hszService; /* pmt used for connection */
HSZ hszTopic; /* pmt used for connection */
UINT afCmd; /* service name flag */
CONVCONTEXT convContext;
HWND hwndClient; /* source of conversation (ClientConvClass) */
HWND hwndServer; /* destination of conversation (ServerConvClass) */
WDML_XACT* transactions; /* pending transactions (client only) */
DWORD hUser; /* user defined value */
} WDML_CONV;
/* DDE_LINK struct defines hot, warm, and cold links */
typedef struct tagWDML_LINK {
struct tagWDML_LINK* next; /* to link all the active links */
HCONV hConv; /* to get back to the converstaion */
UINT transactionType;/* 0 for no link */
HSZ hszItem; /* item targetted for (hot/warm) link */
UINT uFmt; /* format for data */
HDDEDATA hDdeData; /* data them selves */
} WDML_LINK;
typedef struct tagWDML_INSTANCE
{
struct tagWDML_INSTANCE* next;
DWORD instanceID; /* needed to track monitor usage */
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 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 */
PFNCALLBACK callback;
DWORD CBFflags;
DWORD monitorFlags;
UINT txnCount; /* count transactions open to simplify closure */
DWORD lastError;
HWND hwndEvent;
WDML_SERVER* servers; /* list of registered servers */
WDML_CONV* convs[2]; /* active conversations for this instance (client and server) */
WDML_LINK* links[2]; /* active links for this instance (client and server) */
} WDML_INSTANCE;
extern WDML_INSTANCE* WDML_InstanceList; /* list of created instances, a process can create many */
extern DWORD WDML_MaxInstanceID; /* FIXME: OK for present, may have to worry about wrap-around later */
extern HANDLE handle_mutex;
/* header for the DDE Data objects */
typedef struct tagDDE_DATAHANDLE_HEAD
{
short cfFormat;
} DDE_DATAHANDLE_HEAD;
typedef enum tagWDML_SIDE
{
WDML_CLIENT_SIDE = 0, WDML_SERVER_SIDE = 1
} WDML_SIDE;
/* server calls this. */
extern WDML_SERVER* WDML_AddServer(WDML_INSTANCE* thisInstance, HSZ hszService, HSZ hszTopic);
extern void WDML_RemoveServer(WDML_INSTANCE* thisInstance, HSZ hszService, HSZ hszTopic);
extern WDML_SERVER* WDML_FindServer(WDML_INSTANCE* thisInstance, HSZ hszService, HSZ hszTopic);
/* called both in DdeClientTransaction and server side. */
extern WDML_CONV* WDML_AddConv(WDML_INSTANCE* thisInstance, WDML_SIDE side,
HSZ hszService, HSZ hszTopic, HWND hwndClient, HWND hwndServer);
extern void WDML_RemoveConv(WDML_INSTANCE* thisInstance, WDML_SIDE side, HCONV hConv);
extern WDML_CONV* WDML_GetConv(HCONV hConv);
extern WDML_CONV* WDML_FindConv(WDML_INSTANCE* thisInstance, WDML_SIDE side,
HSZ hszService, HSZ hszTopic);
extern void WDML_AddLink(WDML_INSTANCE* thisInstance, HCONV hConv, WDML_SIDE side,
UINT wType, HSZ hszItem, UINT wFmt);
extern WDML_LINK* WDML_FindLink(WDML_INSTANCE* thisInstance, HCONV hConv, WDML_SIDE side,
HSZ hszItem, UINT uFmt);
extern void WDML_RemoveLink(WDML_INSTANCE* thisInstance, HCONV hConv, WDML_SIDE side,
HSZ hszItem, UINT wFmt);
extern void WDML_RemoveAllLinks(WDML_INSTANCE* thisInstance, HCONV hConv, WDML_SIDE side);
/* client calls these */
extern WDML_XACT* WDML_AllocTransaction(WDML_INSTANCE* thisInstance, UINT ddeMsg);
extern void WDML_QueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct);
extern BOOL WDML_UnQueueTransaction(WDML_CONV* pConv, WDML_XACT* pXAct);
extern void WDML_FreeTransaction(WDML_XACT* pXAct);
extern WDML_XACT* WDML_FindTransaction(WDML_CONV* pConv, DWORD tid);
extern HGLOBAL WDML_DataHandle2Global(HDDEDATA hDdeData, BOOL fResponse, BOOL fRelease,
BOOL fDeferUpd, BOOL dAckReq);
extern HDDEDATA WDML_Global2DataHandle(HGLOBAL hMem);
extern WDML_INSTANCE* WDML_FindInstance(DWORD InstId);
extern BOOL WDML_WaitForMutex(HANDLE mutex);
extern DWORD WDML_ReleaseMutex(HANDLE mutex, LPSTR mutex_name, BOOL release_handle_m);
extern void WDML_FreeAllHSZ(WDML_INSTANCE* thisInstance);
extern void WDML_ReleaseAtom(WDML_INSTANCE* thisInstance, HSZ hsz);
extern void WDML_ReserveAtom(WDML_INSTANCE* thisInstance, HSZ hsz);
/* broadcasting to DDE windows */
extern void WDML_BroadcastDDEWindows(const char* clsName, UINT uMsg,
WPARAM wParam, LPARAM lParam);
extern const char WDML_szEventClass[]; /* class of window for events (aka instance) */
#define WM_WDML_REGISTER (WM_USER + 0x200)
#define WM_WDML_UNREGISTER (WM_USER + 0x201)
#endif /* __WINE_DDEML_PRIVATE_H */

311
dlls/user/dde/ddeml16.c Normal file
View file

@ -0,0 +1,311 @@
/* -*- tab-width: 8; c-basic-offset: 8 -*- */
/*
* DDEML library
*
* Copyright 1997 Alexandre Julliard
* Copyright 1997 Len White
* Copyright 1999 Keith Matthews
* Copyright 2000 Corel
* Copyright 2001 Eric Pouech
*/
#include <string.h>
#include "winbase.h"
#include "windef.h"
#include "wine/windef16.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "dde.h"
#include "ddeml.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(ddeml);
typedef HDDEDATA CALLBACK (*PFNCALLBACK16)(UINT16,UINT16,HCONV,HSZ,HSZ,HDDEDATA,DWORD,DWORD);
typedef struct
{
UINT16 cb;
UINT16 wFlags;
UINT16 wCountryID;
INT16 iCodePage;
DWORD dwLangID;
DWORD dwSecurity;
} CONVCONTEXT16, *LPCONVCONTEXT16;
typedef struct
{
DWORD cb;
DWORD hUser;
HCONV hConvPartner;
HSZ hszSvcPartner;
HSZ hszServiceReq;
HSZ hszTopic;
HSZ hszItem;
UINT16 wFmt;
UINT16 wType;
UINT16 wStatus;
UINT16 wConvst;
UINT16 wLastError;
HCONVLIST hConvList;
CONVCONTEXT16 ConvCtxt;
} CONVINFO16, *LPCONVINFO16;
/******************************************************************************
* DdeInitialize16 (DDEML.2)
*/
UINT16 WINAPI DdeInitialize16(LPDWORD pidInst, PFNCALLBACK16 pfnCallback,
DWORD afCmd, DWORD ulRes)
{
return (UINT16)DdeInitializeA(pidInst,(PFNCALLBACK)pfnCallback,
afCmd, ulRes);
}
/*****************************************************************
* DdeUninitialize16 (DDEML.3)
*/
BOOL16 WINAPI DdeUninitialize16(DWORD idInst)
{
FIXME(" stub calling DdeUninitialize\n");
return (BOOL16)DdeUninitialize(idInst);
}
/*****************************************************************
* DdeConnectList16 [DDEML.4]
*/
HCONVLIST WINAPI DdeConnectList16(DWORD idInst, HSZ hszService, HSZ hszTopic,
HCONVLIST hConvList, LPCONVCONTEXT16 pCC)
{
return DdeConnectList(idInst, hszService, hszTopic, hConvList,
(LPCONVCONTEXT)pCC);
}
/*****************************************************************
* DdeQueryNextServer16 [DDEML.5]
*/
HCONV WINAPI DdeQueryNextServer16(HCONVLIST hConvList, HCONV hConvPrev)
{
return DdeQueryNextServer(hConvList, hConvPrev);
}
/*****************************************************************
* DdeDisconnectList (DDEML.6)
*/
BOOL16 WINAPI DdeDisconnectList16(HCONVLIST hConvList)
{
return (BOOL16)DdeDisconnectList(hConvList);
}
/*****************************************************************
* DdeQueryString16 (DDEML.23)
*/
DWORD WINAPI DdeQueryString16(DWORD idInst, HSZ hsz, LPSTR lpsz, DWORD cchMax, INT16 codepage)
{
FIXME("(%ld, 0x%x, %p, %ld, %d): stub \n",
idInst, hsz, lpsz, cchMax, codepage);
return 0;
}
/*****************************************************************
* DdeConnect16 (DDEML.7)
*/
HCONV WINAPI DdeConnect16(DWORD idInst, HSZ hszService, HSZ hszTopic,
LPCONVCONTEXT16 pCC16)
{
CONVCONTEXT cc;
CONVCONTEXT* pCC = NULL;
if (pCC16) {
pCC = &cc;
cc.cb = sizeof(cc);
cc.wFlags = pCC16->wFlags;
cc.iCodePage = pCC16->iCodePage;
cc.dwLangID = pCC16->dwLangID;
cc.dwSecurity = pCC16->dwSecurity;
}
return DdeConnect(idInst, hszService, hszTopic, pCC);
}
/*****************************************************************
* DdeDisconnect16 (DDEML.8)
*/
BOOL16 WINAPI DdeDisconnect16(HCONV hConv)
{
return (BOOL16)DdeDisconnect(hConv);
}
/*****************************************************************
* DdeSetUserHandle16 (DDEML.10)
*/
BOOL16 WINAPI DdeSetUserHandle16(HCONV hConv, DWORD id, DWORD hUser)
{
FIXME("(%d,%ld,%ld): stub\n",hConv,id, hUser);
return 0;
}
/*****************************************************************
* DdeCreateDataHandle16 (DDEML.14)
*/
HDDEDATA WINAPI DdeCreateDataHandle16(DWORD idInst, LPBYTE pSrc, DWORD cb,
DWORD cbOff, HSZ hszItem, UINT16 wFmt,
UINT16 afCmd)
{
return DdeCreateDataHandle(idInst, pSrc, cb, cbOff, hszItem, wFmt, afCmd);
}
/*****************************************************************
* DdeCreateStringHandle16 (DDEML.21)
*/
HSZ WINAPI DdeCreateStringHandle16(DWORD idInst, LPCSTR str, INT16 codepage)
{
if (codepage)
{
return DdeCreateStringHandleA(idInst, str, codepage);
} else {
TRACE("Default codepage supplied\n");
return DdeCreateStringHandleA(idInst, str, CP_WINANSI);
}
}
/*****************************************************************
* DdeFreeStringHandle16 (DDEML.22)
*/
BOOL16 WINAPI DdeFreeStringHandle16(DWORD idInst, HSZ hsz)
{
FIXME("idInst %ld hsz 0x%x\n",idInst,hsz);
return (BOOL)DdeFreeStringHandle(idInst, hsz);
}
/*****************************************************************
* DdeFreeDataHandle16 (DDEML.19)
*/
BOOL16 WINAPI DdeFreeDataHandle16(HDDEDATA hData)
{
return (BOOL)DdeFreeDataHandle(hData);
}
/*****************************************************************
* DdeKeepStringHandle16 (DDEML.24)
*/
BOOL16 WINAPI DdeKeepStringHandle16(DWORD idInst, HSZ hsz)
{
return (BOOL)DdeKeepStringHandle(idInst, hsz);
}
/*****************************************************************
* DdeClientTransaction16 (DDEML.11)
*/
HDDEDATA WINAPI DdeClientTransaction16(LPVOID pData, DWORD cbData,
HCONV hConv, HSZ hszItem, UINT16 wFmt,
UINT16 wType, DWORD dwTimeout,
LPDWORD pdwResult)
{
return DdeClientTransaction((LPBYTE)pData, cbData, hConv, hszItem,
wFmt, wType, dwTimeout, pdwResult);
}
/*****************************************************************
*
* DdeAbandonTransaction16 (DDEML.12)
*
*/
BOOL16 WINAPI DdeAbandonTransaction16(DWORD idInst, HCONV hConv,
DWORD idTransaction)
{
FIXME("empty stub\n");
return TRUE;
}
/*****************************************************************
* DdePostAdvise16 [DDEML.13]
*/
BOOL16 WINAPI DdePostAdvise16(DWORD idInst, HSZ hszTopic, HSZ hszItem)
{
return (BOOL16)DdePostAdvise(idInst, hszTopic, hszItem);
}
/*****************************************************************
* DdeAddData16 (DDEML.15)
*/
HDDEDATA WINAPI DdeAddData16(HDDEDATA hData, LPBYTE pSrc, DWORD cb,
DWORD cbOff)
{
return DdeAddData(hData, pSrc, cb, cbOff);
}
/*****************************************************************
* DdeGetData16 [DDEML.16]
*/
DWORD WINAPI DdeGetData16(
HDDEDATA hData,
LPBYTE pDst,
DWORD cbMax,
DWORD cbOff)
{
return DdeGetData(hData, pDst, cbMax, cbOff);
}
/*****************************************************************
* DdeAccessData16 (DDEML.17)
*/
LPBYTE WINAPI DdeAccessData16(HDDEDATA hData, LPDWORD pcbDataSize)
{
return DdeAccessData(hData, pcbDataSize);
}
/*****************************************************************
* DdeUnaccessData16 (DDEML.18)
*/
BOOL16 WINAPI DdeUnaccessData16(HDDEDATA hData)
{
return DdeUnaccessData(hData);
}
/*****************************************************************
* DdeEnableCallback16 (DDEML.26)
*/
BOOL16 WINAPI DdeEnableCallback16(DWORD idInst, HCONV hConv, UINT16 wCmd)
{
return DdeEnableCallback(idInst, hConv, wCmd);
}
/*****************************************************************
* DdeNameService16 (DDEML.27)
*/
HDDEDATA WINAPI DdeNameService16(DWORD idInst, HSZ hsz1, HSZ hsz2,
UINT16 afCmd)
{
return DdeNameService(idInst, hsz1, hsz2, afCmd);
}
/*****************************************************************
* DdeGetLastError16 (DDEML.20)
*/
UINT16 WINAPI DdeGetLastError16(DWORD idInst)
{
return (UINT16)DdeGetLastError(idInst);
}
/*****************************************************************
* DdeCmpStringHandles16 (DDEML.36)
*/
INT16 WINAPI DdeCmpStringHandles16(HSZ hsz1, HSZ hsz2)
{
return DdeCmpStringHandles(hsz1, hsz2);
}
/******************************************************************
* DdeQueryConvInfo16 (DDEML.9)
*
*/
UINT16 WINAPI DdeQueryConvInfo16(HCONV hconv, DWORD idTransaction, LPCONVINFO16 lpConvInfo)
{
FIXME("stub.\n");
return 0;
}

2195
dlls/user/dde/misc.c Normal file

File diff suppressed because it is too large Load diff

925
dlls/user/dde/server.c Normal file
View file

@ -0,0 +1,925 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* DDEML library
*
* Copyright 1997 Alexandre Julliard
* Copyright 1997 Len White
* Copyright 1999 Keith Matthews
* Copyright 2000 Corel
* Copyright 2001 Eric Pouech
*/
#include <string.h>
#include "winbase.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "winerror.h"
#include "dde.h"
#include "ddeml.h"
#include "debugtools.h"
#include "dde_private.h"
DEFAULT_DEBUG_CHANNEL(ddeml);
static const char szServerNameClassA[] = "DdeServerNameAnsi";
static const char szServerConvClassA[] = "DdeServerConvAnsi";
static LRESULT CALLBACK WDML_ServerNameProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK WDML_ServerConvProc(HWND, UINT, WPARAM, LPARAM);
/******************************************************************************
* DdePostAdvise [USER32.@] Send transaction to DDE callback function.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI DdePostAdvise(
DWORD idInst, /* [in] Instance identifier */
HSZ hszTopic, /* [in] Handle to topic name string */
HSZ hszItem) /* [in] Handle to item name string */
{
WDML_INSTANCE* thisInstance = NULL;
WDML_LINK* pLink = NULL;
HDDEDATA hDdeData = 0, hItemData = 0;
WDML_CONV* pConv = NULL;
CHAR pszTopic[MAX_BUFFER_LEN];
CHAR pszItem[MAX_BUFFER_LEN];
TRACE("(%ld,%ld,%ld)\n",idInst,(DWORD)hszTopic,(DWORD)hszItem);
if (idInst == 0)
{
return FALSE;
}
thisInstance = WDML_FindInstance(idInst);
if (thisInstance == NULL || thisInstance->links == NULL)
{
return FALSE;
}
GlobalGetAtomNameA(hszTopic, (LPSTR)pszTopic, MAX_BUFFER_LEN);
GlobalGetAtomNameA(hszItem, (LPSTR)pszItem, MAX_BUFFER_LEN);
for (pLink = thisInstance->links[WDML_SERVER_SIDE]; pLink != NULL; pLink = pLink->next)
{
if (DdeCmpStringHandles(hszItem, pLink->hszItem) == 0)
{
hDdeData = 0;
if (thisInstance->callback != NULL /* && thisInstance->Process_id == GetCurrentProcessId()*/)
{
TRACE("Calling the callback, type=XTYP_ADVREQ, CB=0x%lx, hConv=0x%lx, Topic=%s, Item=%s\n",
(DWORD)thisInstance->callback, (DWORD)pLink->hConv, pszTopic, pszItem);
hDdeData = (thisInstance->callback)(XTYP_ADVREQ,
pLink->uFmt,
pLink->hConv,
hszTopic,
hszItem,
0, 0, 0);
TRACE("Callback was called\n");
}
if (hDdeData)
{
if (pLink->transactionType & XTYPF_NODATA)
{
TRACE("no data\n");
hItemData = 0;
}
else
{
TRACE("with data\n");
hItemData = WDML_DataHandle2Global(hDdeData, FALSE, FALSE, FALSE, FALSE);
}
pConv = WDML_GetConv(pLink->hConv);
if (pConv == NULL ||
!PostMessageA(pConv->hwndClient, WM_DDE_DATA, (WPARAM)pConv->hwndServer,
PackDDElParam(WM_DDE_DATA, (UINT)hItemData, (DWORD)hszItem)))
{
ERR("post message failed\n");
DdeFreeDataHandle(hDdeData);
return FALSE;
}
}
}
}
return TRUE;
}
/******************************************************************************
* DdeNameService [USER32.@] {Un}registers service name of DDE server
*
* PARAMS
* idInst [I] Instance identifier
* hsz1 [I] Handle to service name string
* hsz2 [I] Reserved
* afCmd [I] Service name flags
*
* RETURNS
* Success: Non-zero
* Failure: 0
*/
HDDEDATA WINAPI DdeNameService(DWORD idInst, HSZ hsz1, HSZ hsz2, UINT afCmd)
{
WDML_SERVER* pServer;
WDML_SERVER* pServerTmp;
WDML_INSTANCE* thisInstance;
HDDEDATA hDdeData;
HSZ hsz2nd = 0;
HWND hwndServer;
WNDCLASSEXA wndclass;
hDdeData = (HDDEDATA)NULL;
TRACE("(%ld,%d,%d,%d): stub\n",idInst,hsz1,hsz2,afCmd);
if (WDML_MaxInstanceID == 0)
{
/* Nothing has been initialised - exit now !
* needs something for DdeGetLastError */
return 0;
}
if (!WDML_WaitForMutex(handle_mutex))
{
/* FIXME: setError DMLERR_SYS_ERROR; */
return 0;
}
/* First check instance
*/
thisInstance = WDML_FindInstance(idInst);
if (thisInstance == NULL)
{
TRACE("Instance not found as initialised\n");
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
/* Nothing has been initialised - exit now ! can return TRUE since effect is the same */
return FALSE;
}
if (hsz2 != 0L)
{
/* Illegal, reserved parameter
*/
thisInstance->lastError = DMLERR_INVALIDPARAMETER;
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
FIXME("Reserved parameter no-zero !!\n");
return FALSE;
}
if (hsz1 == 0L)
{
/*
* General unregister situation
*/
if (afCmd != DNS_UNREGISTER)
{
/* don't know if we should check this but it makes sense
* why supply REGISTER or filter flags if de-registering all
*/
TRACE("General unregister unexpected flags\n");
thisInstance->lastError = DMLERR_DLL_USAGE;
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return FALSE;
}
/* Loop to find all registered service and de-register them
*/
if (thisInstance->servers == NULL)
{
/* None to unregister !!
*/
TRACE("General de-register - nothing registered\n");
thisInstance->lastError = DMLERR_DLL_USAGE;
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return FALSE;
}
else
{
pServer = thisInstance->servers;
while (pServer != NULL)
{
TRACE("general deregister - iteration\n");
pServerTmp = pServer;
pServer = pServer->next;
WDML_ReleaseAtom(thisInstance, pServerTmp->hszService);
/* finished - release heap space used as work store */
HeapFree(GetProcessHeap(), 0, pServerTmp);
}
thisInstance->servers = NULL;
TRACE("General de-register - finished\n");
}
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return (HDDEDATA)TRUE;
}
TRACE("Specific name action detected\n");
if (afCmd & DNS_REGISTER)
{
/* Register new service name
*/
pServer = WDML_FindServer(thisInstance, hsz1, 0);
if (pServer)
ERR("Trying to register already registered service!\n");
else
{
TRACE("Adding service name\n");
WDML_ReserveAtom(thisInstance, hsz1);
pServer = WDML_AddServer(thisInstance, hsz1, 0);
WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_REGISTER, hsz1, hsz2nd);
}
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = WDML_ServerNameProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 2 * sizeof(DWORD);
wndclass.hInstance = 0;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szServerNameClassA;
wndclass.hIconSm = 0;
RegisterClassExA(&wndclass);
hwndServer = CreateWindowA(szServerNameClassA, NULL,
WS_POPUP, 0, 0, 0, 0,
0, 0, 0, 0);
SetWindowLongA(hwndServer, 0, (DWORD)thisInstance);
TRACE("Created nameServer=%04x for instance=%08lx\n", hwndServer, idInst);
pServer->hwndServer = hwndServer;
}
if (afCmd & DNS_UNREGISTER)
{
TRACE("Broadcasting WM_DDE_TERMINATE message\n");
SendMessageA(HWND_BROADCAST, WM_DDE_TERMINATE, (WPARAM)NULL,
PackDDElParam(WM_DDE_TERMINATE, (UINT)hsz1, (UINT)hsz2));
WDML_RemoveServer(thisInstance, hsz1, hsz2);
}
if (afCmd & DNS_FILTERON)
{
/* Set filter flags on to hold notifications of connection
*
* test coded this way as this is the default setting
*/
pServer = WDML_FindServer(thisInstance, hsz1, 0);
if (!pServer)
{
/* trying to filter where no service names !!
*/
thisInstance->lastError = DMLERR_DLL_USAGE;
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return FALSE;
}
else
{
pServer->filterOn = TRUE;
}
}
if (afCmd & DNS_FILTEROFF)
{
/* Set filter flags on to hold notifications of connection
*/
pServer = WDML_FindServer(thisInstance, hsz1, 0);
if (!pServer)
{
/* trying to filter where no service names !!
*/
thisInstance->lastError = DMLERR_DLL_USAGE;
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return FALSE;
}
else
{
pServer->filterOn = FALSE;
}
}
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return (HDDEDATA)TRUE;
}
/******************************************************************
* WDML_CreateServerConv
*
*
*/
static BOOL WDML_CreateServerConv(WDML_INSTANCE* thisInstance, HWND hwndClient, HWND hwndServerName,
HSZ hszApp, HSZ hszTopic)
{
WNDCLASSEXA wndclass;
HWND hwndServerConv;
WDML_CONV* pConv;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = 0;
wndclass.lpfnWndProc = WDML_ServerConvProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 2 * sizeof(DWORD);
wndclass.hInstance = 0;
wndclass.hIcon = 0;
wndclass.hCursor = 0;
wndclass.hbrBackground = 0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szServerConvClassA;
wndclass.hIconSm = 0;
RegisterClassExA(&wndclass);
hwndServerConv = CreateWindowA(szServerConvClassA, 0,
WS_CHILD, 0, 0, 0, 0,
hwndServerName, 0, 0, 0);
TRACE("Created convServer=%04x (nameServer=%04x) for instance=%08lx\n",
hwndServerConv, hwndServerName, thisInstance->instanceID);
pConv = WDML_AddConv(thisInstance, WDML_SERVER_SIDE, hszApp, hszTopic, hwndClient, hwndServerConv);
SetWindowLongA(hwndServerConv, 0, (DWORD)thisInstance);
SetWindowLongA(hwndServerConv, 4, (DWORD)pConv);
/* this should be the only place using SendMessage for WM_DDE_ACK */
SendMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServerConv,
PackDDElParam(WM_DDE_ACK, (UINT)hszApp, (UINT)hszTopic));
#if 0
if (thisInstance && thisInstance->callback != NULL /*&& thisInstance->Process_id == GetCurrentProcessId()*/)
{
/* confirm connection...
* FIXME: a better way would be to check for any incoming message if the conversation
* exists (and/or) has been confirmed...
* Anyway, always pretend we use a connection from a different instance...
*/
(thisInstance->callback)(XTYP_CONNECT_CONFIRM, 0, (HCONV)pConv, hszApp, hszTopic, 0, 0, 0);
}
#endif
return TRUE;
}
/******************************************************************
* WDML_ServerNameProc
*
*
*/
static LRESULT CALLBACK WDML_ServerNameProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
HWND hwndClient;
HSZ hszApp, hszTop;
HDDEDATA hDdeData = 0;
WDML_INSTANCE* thisInstance;
UINT uiLow, uiHi;
switch (iMsg)
{
case WM_DDE_INITIATE:
/* wParam -- sending window handle
LOWORD(lParam) -- application atom
HIWORD(lParam) -- topic atom */
TRACE("WM_DDE_INITIATE message received in the Server Proc!\n");
hwndClient = (HWND)wParam;
/* don't free DDEParams, since this is a broadcast */
UnpackDDElParam(WM_DDE_INITIATE, lParam, &uiLow, &uiHi);
hszApp = (HSZ)uiLow;
hszTop = (HSZ)uiHi;
thisInstance = (WDML_INSTANCE*)GetWindowLongA(hwndServer, 0);
TRACE("idInst=%ld, ProcessID=0x%lx\n", thisInstance->instanceID, GetCurrentProcessId());
if (hszApp && hszTop)
{
/* pass on to the callback */
if (thisInstance && thisInstance->callback != NULL /*&& thisInstance->Process_id == GetCurrentProcessId()*/)
{
TRACE("calling the Callback, type = XTYP_CONNECT, CB=0x%lx\n",
(DWORD)thisInstance->callback);
hDdeData = (thisInstance->callback)(XTYP_CONNECT,
0, 0,
hszTop,
hszApp,
0, 0, 0);
if ((UINT)hDdeData)
{
WDML_CreateServerConv(thisInstance, hwndClient, hwndServer, hszApp, hszTop);
}
}
}
else
{
/* pass on to the callback */
if (thisInstance && thisInstance->callback != NULL /*&& thisInstance->Process_id == GetCurrentProcessId()*/)
{
TRACE("calling the Callback, type=XTYP_WILDCONNECT, CB=0x%lx\n",
(DWORD)thisInstance->callback);
hDdeData = (thisInstance->callback)(XTYP_WILDCONNECT,
0, 0,
hszTop,
hszApp,
0, 0, 0);
if ((UINT)hDdeData)
{
HSZPAIR* hszp;
hszp = (HSZPAIR*)DdeAccessData(hDdeData, NULL);
if (hszp)
{
int i;
for (i = 0; hszp[i].hszSvc && hszp[i].hszTopic; i++)
{
WDML_CreateServerConv(thisInstance, hwndClient, hwndServer,
hszp[i].hszSvc, hszp[i].hszTopic);
}
DdeUnaccessData(hDdeData);
}
}
}
}
/*
billx: make a conv and add it to the server list -
this can be delayed when link is created for the conv. NO NEED !!!
*/
return 0;
case WM_DDE_REQUEST:
FIXME("WM_DDE_REQUEST message received!\n");
return 0;
case WM_DDE_ADVISE:
FIXME("WM_DDE_ADVISE message received!\n");
return 0;
case WM_DDE_UNADVISE:
FIXME("WM_DDE_UNADVISE message received!\n");
return 0;
case WM_DDE_EXECUTE:
FIXME("WM_DDE_EXECUTE message received!\n");
return 0;
case WM_DDE_POKE:
FIXME("WM_DDE_POKE message received!\n");
return 0;
case WM_DDE_TERMINATE:
FIXME("WM_DDE_TERMINATE message received!\n");
return 0;
}
return DefWindowProcA(hwndServer, iMsg, wParam, lParam);
}
/******************************************************************
* WDML_ServerHandleRequest
*
*
*/
static LRESULT WDML_ServerHandleRequest(WDML_INSTANCE* thisInstance, WDML_CONV* pConv,
HWND hwndServer, HWND hwndClient, LPARAM lParam)
{
UINT uiLow, uiHi;
HSZ hszItem;
HDDEDATA hDdeData;
TRACE("(%04x %04x %08lx)!\n", hwndServer, hwndClient, lParam);
UnpackDDElParam(WM_DDE_REQUEST, lParam, &uiLow, &uiHi);
hszItem = (HSZ)uiHi;
hDdeData = 0;
if (thisInstance && thisInstance->callback != NULL /* && thisInstance->Process_id == GetCurrentProcessId() */)
{
TRACE("calling the Callback, idInst=%ld, CB=0x%lx, uType=0x%x\n",
thisInstance->instanceID, (DWORD)thisInstance->callback, XTYP_REQUEST);
hDdeData = (thisInstance->callback)(XTYP_REQUEST, uiLow, (HCONV)pConv,
pConv->hszTopic, hszItem, 0, 0, 0);
}
if (hDdeData)
{
HGLOBAL hMem = WDML_DataHandle2Global(hDdeData, FALSE, FALSE, FALSE, FALSE);
if (!PostMessageA(hwndClient, WM_DDE_DATA, (WPARAM)hwndServer,
ReuseDDElParam(lParam, WM_DDE_REQUEST, WM_DDE_DATA, (UINT)hMem, (UINT)hszItem)))
{
DdeFreeDataHandle(hDdeData);
GlobalFree(hMem);
}
}
else
{
DDEACK ddeAck;
ddeAck.bAppReturnCode = 0;
ddeAck.reserved = 0;
ddeAck.fBusy = FALSE;
ddeAck.fAck = FALSE;
TRACE("Posting a %s ack\n", ddeAck.fAck ? "positive" : "negative");
PostMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer,
ReuseDDElParam(lParam, WM_DDE_REQUEST, WM_DDE_ACK, *((WORD*)&ddeAck), (UINT)hszItem));
}
return 0;
}
/******************************************************************
* WDML_ServerHandleAdvise
*
*
*/
static LRESULT WDML_ServerHandleAdvise(WDML_INSTANCE* thisInstance, WDML_CONV* pConv,
HWND hwndServer, HWND hwndClient, LPARAM lParam)
{
UINT uiLo, uiHi, uType;
HGLOBAL hDdeAdvise;
HSZ hszItem;
WDML_LINK* pLink;
DDEADVISE* pDdeAdvise;
HDDEDATA hDdeData;
DDEACK ddeAck;
/* XTYP_ADVSTART transaction:
establish link and save link info to InstanceInfoTable */
TRACE("(%04x %04x %08lx)!\n", hwndServer, hwndClient, lParam);
UnpackDDElParam(WM_DDE_ADVISE, lParam, &uiLo, &uiHi);
hDdeAdvise = (HGLOBAL)uiLo;
hszItem = (HSZ)uiHi; /* FIXME: it should be a global atom */
if (!pConv)
{
ERR("Got an advise on a not known conversation, dropping request\n");
FreeDDElParam(WM_DDE_ADVISE, lParam);
return 0;
}
pDdeAdvise = (DDEADVISE*)GlobalLock(hDdeAdvise);
uType = XTYP_ADVSTART |
(pDdeAdvise->fDeferUpd ? XTYPF_NODATA : 0) |
(pDdeAdvise->fAckReq ? XTYPF_ACKREQ : 0);
hDdeData = 0;
if (thisInstance && thisInstance->callback != NULL /* && thisInstance->Process_id == GetCurrentProcessId() */)
{
TRACE("calling the Callback, idInst=%ld, CB=0x%lx, uType=0x%x, uFmt=%x\n",
thisInstance->instanceID, (DWORD)thisInstance->callback,
uType, pDdeAdvise->cfFormat);
hDdeData = (thisInstance->callback)(XTYP_ADVSTART, pDdeAdvise->cfFormat, (HCONV)pConv,
pConv->hszTopic, hszItem, 0, 0, 0);
}
ddeAck.bAppReturnCode = 0;
ddeAck.reserved = 0;
ddeAck.fBusy = FALSE;
if ((UINT)hDdeData || TRUE) /* FIXME (from Corel ?) some apps don't return this value */
{
ddeAck.fAck = TRUE;
/* billx: first to see if the link is already created. */
pLink = WDML_FindLink(thisInstance, (HCONV)pConv, WDML_SERVER_SIDE,
hszItem, pDdeAdvise->cfFormat);
if (pLink != NULL)
{
/* we found a link, and only need to modify it in case it changes */
pLink->transactionType = uType;
}
else
{
TRACE("Adding Link with hConv=0x%lx\n", (DWORD)pConv);
WDML_AddLink(thisInstance, (HCONV)pConv, WDML_SERVER_SIDE,
uType, hszItem, pDdeAdvise->cfFormat);
}
}
else
{
TRACE("No data returned from the Callback\n");
ddeAck.fAck = FALSE;
}
GlobalUnlock(hDdeAdvise);
if (ddeAck.fAck)
GlobalFree(hDdeAdvise);
TRACE("Posting a %s ack\n", ddeAck.fAck ? "positive" : "negative");
PostMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer,
ReuseDDElParam(lParam, WM_DDE_ADVISE, WM_DDE_ACK, *((WORD*)&ddeAck), (UINT)hszItem));
return 0L;
}
/******************************************************************
* WDML_ServerHandleUnadvise
*
*
*/
static LRESULT WDML_ServerHandleUnadvise(WDML_INSTANCE* thisInstance, WDML_CONV* pConv,
HWND hwndServer, HWND hwndClient, LPARAM lParam)
{
UINT uiLo, uiHi;
HSZ hszItem;
WDML_LINK* pLink;
DDEACK ddeAck;
TRACE("(%04x %04x %08lx)!\n", hwndServer, hwndClient, lParam);
/* billx: XTYP_ADVSTOP transaction */
UnpackDDElParam(WM_DDE_UNADVISE, lParam, &uiLo, &uiHi);
/* uiLow: wFmt */
hszItem = (HSZ)uiHi; /* FIXME: it should be a global atom */
if (hszItem == (HSZ)0 || uiLo == 0)
{
ERR("Unsupported yet options (null item or clipboard format\n");
}
pLink = WDML_FindLink(thisInstance, (HCONV)pConv, WDML_SERVER_SIDE, hszItem, uiLo);
if (pLink == NULL)
{
ERR("Couln'd find link for %08lx, dropping request\n", (DWORD)hszItem);
FreeDDElParam(WM_DDE_UNADVISE, lParam);
return 0;
}
/* callback shouldn't be invoked if CBF_FAIL_ADVISES is on. */
if (thisInstance && thisInstance->callback != NULL &&
!(thisInstance->CBFflags & CBF_SKIP_DISCONNECTS) /* && thisInstance->Process_id == GetCurrentProcessId() */)
{
TRACE("calling the Callback, idInst=%ld, CB=0x%lx, uType=0x%x\n",
thisInstance->instanceID, (DWORD)thisInstance->callback, XTYP_ADVSTOP);
(thisInstance->callback)(XTYP_ADVSTOP, uiLo, (HCONV)pConv, pConv->hszTopic,
hszItem, 0, 0, 0);
}
WDML_RemoveLink(thisInstance, (HCONV)pConv, WDML_SERVER_SIDE, hszItem, uiLo);
/* send back ack */
ddeAck.bAppReturnCode = 0;
ddeAck.reserved = 0;
ddeAck.fBusy = FALSE;
ddeAck.fAck = TRUE;
PostMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer,
ReuseDDElParam(lParam, WM_DDE_UNADVISE, WM_DDE_ACK, *((WORD*)&ddeAck), (UINT)hszItem));
return 0;
}
/******************************************************************
* WDML_ServerHandleExecute
*
*
*/
static LRESULT WDML_ServerHandleExecute(WDML_INSTANCE* thisInstance, WDML_CONV* pConv,
HWND hwndServer, HWND hwndClient, LPARAM lParam)
{
DDEACK ddeAck;
HDDEDATA hDdeData;
TRACE("(%04x %04x %08lx)!\n", hwndServer, hwndClient, lParam);
if (hwndClient != pConv->hwndClient)
WARN("hmmm source window (%04x)\n", hwndClient);
hDdeData = 0;
if (thisInstance && thisInstance->callback != NULL /* && thisInstance->Process_id == GetCurrentProcessId() */)
{
LPVOID ptr = GlobalLock((HGLOBAL)lParam);
if (ptr)
{
hDdeData = DdeCreateDataHandle(0, ptr, GlobalSize((HGLOBAL)lParam),
0, 0, CF_TEXT, 0);
GlobalUnlock((HGLOBAL)lParam);
}
TRACE("calling the Callback, idInst=%ld, CB=0x%lx, uType=0x%x\n",
thisInstance->instanceID, (DWORD)thisInstance->callback, XTYP_EXECUTE);
hDdeData = (thisInstance->callback)(XTYP_EXECUTE, 0, (HCONV)pConv, pConv->hszTopic, 0,
hDdeData, 0L, 0L);
}
ddeAck.bAppReturnCode = 0;
ddeAck.reserved = 0;
ddeAck.fBusy = FALSE;
ddeAck.fAck = FALSE;
switch ((UINT)hDdeData)
{
case DDE_FACK:
ddeAck.fAck = TRUE;
break;
case DDE_FBUSY:
ddeAck.fBusy = TRUE;
break;
default:
WARN("Bad result code\n");
/* fall thru */
case DDE_FNOTPROCESSED:
break;
}
PostMessageA(pConv->hwndClient, WM_DDE_ACK, (WPARAM)hwndServer,
PackDDElParam(WM_DDE_ACK, *((WORD*)&ddeAck), lParam));
return 0;
}
/******************************************************************
* WDML_ServerHandlePoke
*
*
*/
static LRESULT WDML_ServerHandlePoke(WDML_INSTANCE* thisInstance, WDML_CONV* pConv,
HWND hwndServer, HWND hwndClient, LPARAM lParam)
{
UINT uiLo, uiHi;
HSZ hszItem;
DDEACK ddeAck;
DDEPOKE* pDdePoke;
HDDEDATA hDdeData;
TRACE("(%04x %04x %08lx)!\n", hwndServer, hwndClient, lParam);
UnpackDDElParam(WM_DDE_UNADVISE, lParam, &uiLo, &uiHi);
hszItem = (HSZ)uiHi;
pDdePoke = (DDEPOKE*)GlobalLock((HGLOBAL)uiLo);
if (!pDdePoke)
{
return 0;
}
ddeAck.bAppReturnCode = 0;
ddeAck.reserved = 0;
ddeAck.fBusy = FALSE;
ddeAck.fAck = FALSE;
if (thisInstance && thisInstance->callback != NULL)
{
hDdeData = DdeCreateDataHandle(thisInstance->instanceID, pDdePoke->Value,
GlobalSize((HGLOBAL)uiLo) - sizeof(DDEPOKE) + 1,
0, 0, pDdePoke->cfFormat, 0);
if (hDdeData)
{
HDDEDATA hDdeDataOut;
TRACE("calling callback XTYP_POKE, idInst=%ld\n",
thisInstance->instanceID);
hDdeDataOut = (thisInstance->callback)(XTYP_POKE,
pDdePoke->cfFormat, (HCONV)pConv,
pConv->hszTopic, (HSZ)uiHi,
hDdeData, 0, 0);
switch ((UINT)hDdeDataOut)
{
case DDE_FACK:
ddeAck.fAck = TRUE;
break;
case DDE_FBUSY:
ddeAck.fBusy = TRUE;
break;
default:
FIXME("Unsupported returned value %08lx\n", (DWORD)hDdeDataOut);
/* fal thru */
case DDE_FNOTPROCESSED:
break;
}
DdeFreeDataHandle(hDdeData);
}
}
GlobalUnlock((HGLOBAL)uiLo);
if (!ddeAck.fAck)
GlobalFree((HGLOBAL)uiHi);
PostMessageA(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer,
ReuseDDElParam(lParam, WM_DDE_POKE, WM_DDE_ACK, *((WORD*)&ddeAck), (UINT)hszItem));
return 0L;
}
/******************************************************************
* WDML_ServerHandleTerminate
*
*
*/
static LRESULT WDML_ServerHandleTerminate(WDML_INSTANCE* thisInstance, WDML_CONV* pConv,
HWND hwndServer, HWND hwndClient, LPARAM lParam)
{
UINT uiLo, uiHi;
HSZ hszApp, hszTop;
TRACE("(%04x %04x %08lx)!\n", hwndServer, hwndClient, lParam);
TRACE("WM_DDE_TERMINATE!\n");
/* XTYP_DISCONNECT transaction */
/* billx: two things to remove: the conv, and associated links.
callback shouldn't be called if CBF_SKIP_DISCONNECTS is on.
Respond with another WM_DDE_TERMINATE iMsg.*/
/* don't free DDEParams, since this is a broadcast */
UnpackDDElParam(WM_DDE_TERMINATE, lParam, &uiLo, &uiHi);
hszApp = (HSZ)uiLo;
hszTop = (HSZ)uiHi;
WDML_BroadcastDDEWindows(WDML_szEventClass, WM_WDML_UNREGISTER, hszApp, hszTop);
/* PostMessageA(hwndClient, WM_DDE_TERMINATE, (WPARAM)hwndServer, (LPARAM)hConv); */
WDML_RemoveAllLinks(thisInstance, (HCONV)pConv, WDML_SERVER_SIDE);
WDML_RemoveConv(thisInstance, WDML_SERVER_SIDE, (HCONV)pConv);
/* DestroyWindow(hwnd); don't destroy it now, we may still need it. */
return 0;
}
/******************************************************************
* WDML_ServerConvProc
*
*
*/
static LRESULT CALLBACK WDML_ServerConvProc(HWND hwndServer, UINT iMsg, WPARAM wParam, LPARAM lParam)
{
WDML_INSTANCE* thisInstance;
WDML_CONV* pConv;
if (iMsg < WM_DDE_FIRST || iMsg > WM_DDE_LAST)
{
return DefWindowProcA(hwndServer, iMsg, wParam, lParam);
}
TRACE("About to wait... \n");
if (!WDML_WaitForMutex(handle_mutex))
{
return 0;
}
thisInstance = (WDML_INSTANCE*)GetWindowLongA(hwndServer, 0);
pConv = (WDML_CONV*)GetWindowLongA(hwndServer, 4);
switch (iMsg)
{
case WM_DDE_INITIATE:
FIXME("WM_DDE_INITIATE message received in the ServerConv Proc!\n");
break;
case WM_DDE_REQUEST:
WDML_ServerHandleRequest(thisInstance, pConv, hwndServer, (HWND)wParam, lParam);
break;
case WM_DDE_ADVISE:
WDML_ServerHandleAdvise(thisInstance, pConv, hwndServer, (HWND)wParam, lParam);
break;
case WM_DDE_UNADVISE:
WDML_ServerHandleUnadvise(thisInstance, pConv, hwndServer, (HWND)wParam, lParam);
break;
case WM_DDE_EXECUTE:
WDML_ServerHandleExecute(thisInstance, pConv, hwndServer, (HWND)wParam, lParam);
break;
case WM_DDE_POKE:
WDML_ServerHandlePoke(thisInstance, pConv, hwndServer, (HWND)wParam, lParam);
break;
case WM_DDE_TERMINATE:
WDML_ServerHandleTerminate(thisInstance, pConv, hwndServer, (HWND)wParam, lParam);
break;
case WM_DDE_ACK:
WARN("Shouldn't receive a ACK message (never requests them). Ignoring it\n");
break;
default:
FIXME("Unsupported message %d\n", iMsg);
}
WDML_ReleaseMutex(handle_mutex, "handle_mutex", FALSE);
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,79 +0,0 @@
/*
* DDEML 16-bit library definitions
*
* Copyright 1997 Alexandre Julliard
* Copyright 1997 Len White
*/
#ifndef __WINE_WINE_DDEML16_H
#define __WINE_WINE_DDEML16_H
#include "windef.h"
#include "wine/windef16.h"
#define QID_SYNC16 -1L
typedef HDDEDATA CALLBACK (*PFNCALLBACK16)(UINT16,UINT16,HCONV,HSZ,HSZ,HDDEDATA,DWORD,DWORD);
/***************************************************
Externally visible data structures
***************************************************/
typedef struct
{
UINT16 cb;
UINT16 wFlags;
UINT16 wCountryID;
INT16 iCodePage;
DWORD dwLangID;
DWORD dwSecurity;
} CONVCONTEXT16, *LPCONVCONTEXT16;
typedef struct
{
DWORD cb;
DWORD hUser;
HCONV hConvPartner;
HSZ hszSvcPartner;
HSZ hszServiceReq;
HSZ hszTopic;
HSZ hszItem;
UINT16 wFmt;
UINT16 wType;
UINT16 wStatus;
UINT16 wConvst;
UINT16 wLastError;
HCONVLIST hConvList;
CONVCONTEXT16 ConvCtxt;
} CONVINFO16, *LPCONVINFO16;
/* Interface Definitions */
UINT16 WINAPI DdeInitialize16(LPDWORD,PFNCALLBACK16,DWORD,DWORD);
BOOL16 WINAPI DdeUninitialize16(DWORD);
HCONVLIST WINAPI DdeConnectList16(DWORD,HSZ,HSZ,HCONVLIST,LPCONVCONTEXT16);
HCONV WINAPI DdeQueryNextServer16(HCONVLIST, HCONV);
BOOL16 WINAPI DdeDisconnectList16(HCONVLIST);
HCONV WINAPI DdeConnect16(DWORD,HSZ,HSZ,LPCONVCONTEXT16);
BOOL16 WINAPI DdeDisconnect16(HCONV);
BOOL16 WINAPI DdeSetUserHandle16(HCONV,DWORD,DWORD);
HDDEDATA WINAPI DdeCreateDataHandle16(DWORD,LPBYTE,DWORD,DWORD,HSZ,UINT16,UINT16);
HSZ WINAPI DdeCreateStringHandle16(DWORD,LPCSTR,INT16);
BOOL16 WINAPI DdeFreeStringHandle16(DWORD,HSZ);
BOOL16 WINAPI DdeFreeDataHandle16(HDDEDATA);
BOOL16 WINAPI DdeKeepStringHandle16(DWORD,HSZ);
HDDEDATA WINAPI DdeClientTransaction16(LPVOID,DWORD,HCONV,HSZ,UINT16,UINT16,DWORD,LPDWORD);
BOOL16 WINAPI DdeAbandonTransaction16(DWORD,HCONV,DWORD);
BOOL16 WINAPI DdePostAdvise16(DWORD,HSZ,HSZ);
HDDEDATA WINAPI DdeAddData16(HDDEDATA,LPBYTE,DWORD,DWORD);
LPBYTE WINAPI DdeAccessData16(HDDEDATA,LPDWORD);
BOOL16 WINAPI DdeUnaccessData16(HDDEDATA);
BOOL16 WINAPI DdeEnableCallback16(DWORD,HCONV,UINT16);
INT16 WINAPI DdeCmpStringHandles16(HSZ,HSZ);
HDDEDATA WINAPI DdeNameService16(DWORD,HSZ,HSZ,UINT16);
UINT16 WINAPI DdeGetLastError16(DWORD);
UINT16 WINAPI DdeQueryConvInfo16(HCONV,DWORD,LPCONVINFO16);
#endif /* __WINE_WINE_DDEML16_H */

View file

@ -8,7 +8,7 @@ import advapi32.dll
import kernel32.dll
import ntdll.dll
debug_channels (accel caret class clipboard combo cursor dc ddeml dialog driver
debug_channels (accel caret class clipboard combo cursor dc dde ddeml dialog driver
edit event graphics hook icon key keyboard listbox local mdi
menu message msg nonclient prop relay resource scroll sendmsg
shell static string syscolor system text timer win win32 wnet)
@ -331,7 +331,7 @@ debug_channels (accel caret class clipboard combo cursor dc ddeml dialog driver
@ stdcall GrayStringW(long long ptr long long long long long long) GrayStringW
@ stdcall HideCaret(long) HideCaret
@ stdcall HiliteMenuItem(long long long long) HiliteMenuItem
@ stub ImpersonateDdeClientWindow
@ stdcall ImpersonateDdeClientWindow(long long) ImpersonateDdeClientWindow
@ stdcall InSendMessage() InSendMessage
@ stdcall InSendMessageEx(ptr) InSendMessageEx
@ stdcall InflateRect(ptr long long) InflateRect

View file

@ -32,7 +32,7 @@ extern "C" {
/* DDEACK: wStatus in WM_DDE_ACK message */
struct tagDDEACK
{
unsigned bAppReturnCode:8, reserved:6, fBusy:1, fAck:1;
unsigned short bAppReturnCode:8, reserved:6, fBusy:1, fAck:1;
};
typedef struct tagDDEACK DDEACK;
@ -61,6 +61,11 @@ struct tagDDEPOKE
};
typedef struct tagDDEPOKE DDEPOKE;
BOOL WINAPI DdeSetQualityOfService(HWND hwndClient,
CONST SECURITY_QUALITY_OF_SERVICE *pqosNew,
PSECURITY_QUALITY_OF_SERVICE pqosPrev);
BOOL WINAPI ImpersonateDdeClientWindow(HWND hWndClient, HWND hWndServer);
/* lParam packing/unpacking API */

View file

@ -32,12 +32,49 @@ extern "C" {
#define EXPENTRY CALLBACK
#define SZDDESYS_TOPIC TEXT("System")
#define SZDDESYS_ITEM_TOPICS TEXT("Topics")
#define SZDDESYS_ITEM_SYSITEMS TEXT("SysItems")
#define SZDDESYS_ITEM_RTNMSG TEXT("ReturnMessage")
#define SZDDESYS_ITEM_STATUS TEXT("Status")
#define SZDDESYS_ITEM_FORMATS TEXT("Formats")
#define SZDDESYS_ITEM_HELP TEXT("Help")
#define SZDDE_ITEM_ITEMLIST TEXT("TopicItemList")
/***************************************************
FLAGS Section - copied from Microsoft SDK as must be standard, probably Copyright Microsoft Corporation
***************************************************/
#define XST_NULL 0
#define XST_INCOMPLETE 1
#define XST_CONNECTED 2
#define XST_INIT1 3
#define XST_INIT2 4
#define XST_REQSENT 5
#define XST_DATARCVD 6
#define XST_POKESENT 7
#define XST_POKEACKRCVD 8
#define XST_EXECSENT 9
#define XST_EXECACKRCVD 10
#define XST_ADVSENT 11
#define XST_UNADVSENT 12
#define XST_ADVACKRCVD 13
#define XST_UNADVACKRCVD 14
#define XST_ADVDATASENT 15
#define XST_ADVDATAACKRCVD 16
#define ST_CONNECTED 0x0001
#define ST_ADVISE 0x0002
#define ST_ISLOCAL 0x0004
#define ST_BLOCKED 0x0008
#define ST_CLIENT 0x0010
#define ST_TERMINATED 0x0020
#define ST_INLIST 0x0040
#define ST_BLOCKNEXT 0x0080
#define ST_ISSELF 0x0100
/*
* Callback filter flags for use with standard apps.
*/
@ -138,6 +175,8 @@ extern "C" {
#define XTYP_MASK 0x00F0
#define XTYP_SHIFT 4
#define TIMEOUT_ASYNC 0xFFFFFFFF
/**************************************************
End of Message Types Section
@ -159,6 +198,10 @@ extern "C" {
#define DDE_FAPPSTATUS 0x00FF
#define DDE_FNOTPROCESSED 0x0000
#define DDE_FACKRESERVED (~(DDE_FACK | DDE_FBUSY | DDE_FAPPSTATUS))
#define DDE_FADVRESERVED (~(DDE_FACKREQ | DDE_FDEFERUPD))
#define DDE_FDATRESERVED (~(DDE_FACKREQ | DDE_FRELEASE | DDE_FREQUESTED))
#define DDE_FPOKRESERVED (~(DDE_FRELEASE))
/*****************************************************
@ -197,6 +240,8 @@ extern "C" {
#define DMLERR_LAST 0x4011
#define HDATA_APPOWNED 0x0001
/*****************************************************
End of Return Codes and Microsoft section
@ -205,10 +250,10 @@ extern "C" {
DECLARE_OLD_HANDLE(HCONVLIST);
DECLARE_OLD_HANDLE(HCONV);
DECLARE_OLD_HANDLE(HSZ);
DECLARE_OLD_HANDLE(HDDEDATA);
DECLARE_HANDLE(HCONVLIST);
DECLARE_HANDLE(HCONV);
DECLARE_HANDLE(HSZ);
DECLARE_HANDLE(HDDEDATA);
@ -218,8 +263,8 @@ DECLARE_OLD_HANDLE(HDDEDATA);
*******************************************************/
typedef HDDEDATA CALLBACK (*PFNCALLBACK)(UINT,UINT,HCONV,HSZ,HSZ,
HDDEDATA,DWORD,DWORD);
typedef HDDEDATA CALLBACK (*PFNCALLBACK)(UINT, UINT, HCONV, HSZ, HSZ,
HDDEDATA, DWORD, DWORD);
/***************************************************
@ -227,7 +272,13 @@ typedef HDDEDATA CALLBACK (*PFNCALLBACK)(UINT,UINT,HCONV,HSZ,HSZ,
***************************************************/
typedef struct
typedef struct tagHSZPAIR
{
HSZ hszSvc;
HSZ hszTopic;
} HSZPAIR, *PHSZPAIR, *LPHSZPAIR;
typedef struct tagCONVCONTEXT
{
UINT cb;
UINT wFlags;
@ -237,7 +288,7 @@ typedef struct
DWORD dwSecurity;
} CONVCONTEXT, *LPCONVCONTEXT;
typedef struct
typedef struct tagCONVINFO
{
DWORD cb;
DWORD hUser;