summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/ddeml/stdinit.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow16/ddeml/stdinit.c')
-rw-r--r--private/mvdm/wow16/ddeml/stdinit.c464
1 files changed, 464 insertions, 0 deletions
diff --git a/private/mvdm/wow16/ddeml/stdinit.c b/private/mvdm/wow16/ddeml/stdinit.c
new file mode 100644
index 000000000..a4d2f0066
--- /dev/null
+++ b/private/mvdm/wow16/ddeml/stdinit.c
@@ -0,0 +1,464 @@
+/****************************** Module Header ******************************\
+* Module Name: STDINIT.C
+*
+* This module contains functions used in the involved initiate sequence.
+*
+* Created: 3/21/91 Sanfords
+*
+* Copyright (c) 1991 Microsoft Corporation
+\***************************************************************************/
+
+#include "ddemlp.h"
+
+/*
+ * WM_CREATE ClientWndProc processing
+ */
+long ClientCreate(
+HWND hwnd,
+PAPPINFO pai)
+{
+ PCLIENTINFO pci;
+
+ static DWORD defid = (DWORD)QID_SYNC;
+ static XFERINFO defXferInfo = {
+ &defid,
+ 1L,
+ XTYP_CONNECT,
+ DDEFMT_TEXT,
+ 0L,
+ 0L,
+ };
+
+ /*
+ * allocate and initialize the client window info.
+ */
+ SEMENTER();
+
+ if(!(pci = (PCLIENTINFO)FarAllocMem(pai->hheapApp, sizeof(CLIENTINFO)))) {
+ SEMLEAVE();
+ SETLASTERROR(pai, DMLERR_MEMORY_ERROR);
+ return(1); /* aboart creation - low memory */
+ }
+
+ SetWindowLong(hwnd, GWL_PCI, (DWORD)pci);
+ SetWindowWord(hwnd, GWW_CHECKVAL, ++hwInst);
+ pci->ci.pai = pai;
+ // pci->ci.xad.hUser = 0L;
+ pci->ci.xad.state = XST_NULL;
+ pci->ci.xad.pXferInfo = &defXferInfo; //???
+ pci->ci.fs = ST_CLIENT | (pai->wFlags & AWF_DEFCREATESTATE ? ST_BLOCKED : 0);
+ if (GetWindowLong(GetParent(hwnd), GWL_WNDPROC) == (LONG)ConvListWndProc)
+ pci->ci.fs |= ST_INLIST;
+ // pci->ci.hConvPartner = NULL;
+ // pci->ci.hszServerApp = NULL;
+ // pci->ci.hszTopic = NULL;
+ pci->pQ = NULL; /* don't create until we need one */
+ pci->pClientAdvList = CreateLst(pai->hheapApp, sizeof(ADVLI));
+ SEMLEAVE();
+
+}
+
+
+
+
+/***************************** Private Function ****************************\
+* This routine returns the hwnd of a newly created and connected DDE
+* client or NULL if failure.
+*
+* History: created 1/6/89 sanfords
+\***************************************************************************/
+HWND GetDDEClientWindow(
+PAPPINFO pai,
+HWND hwndParent,
+HWND hwndSend, // NULL -> broadcast
+HSZ hszSvc,
+ATOM aTopic,
+PCONVCONTEXT pCC)
+{
+ HWND hwnd;
+ PCLIENTINFO pci;
+
+ SEMCHECKOUT();
+ if(!(hwnd = CreateWindow(SZCLIENTCLASS, szNull, WS_CHILD, 0, 0, 0, 0, hwndParent,
+ NULL, hInstance, &pai))) {
+ return(NULL);
+ }
+
+ pci = (PCLIENTINFO)GetWindowLong(hwnd, GWL_PCI);
+
+ SEMENTER();
+ /*
+ * we need to set this info BEFORE we do the synchronous initiate
+ * so the INITIATEACK msg is done correctly.
+ */
+ pci->ci.xad.state = XST_INIT1;
+ pci->ci.xad.LastError = DMLERR_NO_ERROR;
+ pci->ci.hszSvcReq = hszSvc;
+ pci->ci.aServerApp = LOWORD(hszSvc);
+ pci->ci.aTopic = aTopic;
+ pci->ci.CC = pCC ? *pCC : CCDef;
+ SEMLEAVE();
+
+ if (hwndSend) {
+ pci->hwndInit = hwndSend;
+ SendMessage(hwndSend, WM_DDE_INITIATE, hwnd,
+ MAKELONG((ATOM)hszSvc, aTopic));
+ } else {
+ IE ie = {
+ hwnd, pci, aTopic
+ };
+
+ EnumWindows(InitEnum, (LONG)(IE FAR *)&ie);
+ }
+
+
+ if (pci->ci.xad.state == XST_INIT1) { // no connections?
+ DestroyWindow(hwnd);
+ return(NULL);
+ }
+
+ pci->ci.xad.state = XST_CONNECTED; // fully ready now.
+ pci->ci.fs |= ST_CONNECTED;
+
+ return(hwnd);
+}
+
+
+
+BOOL FAR PASCAL InitEnum(
+HWND hwnd,
+IE FAR *pie)
+{
+ pie->pci->hwndInit = hwnd;
+ SendMessage(hwnd, WM_DDE_INITIATE, pie->hwnd,
+ MAKELONG((ATOM)pie->pci->ci.hszSvcReq, pie->aTopic));
+ return((pie->pci->ci.fs & ST_INLIST) || pie->pci->ci.xad.state == XST_INIT1);
+}
+
+
+
+
+void ServerFrameInitConv(
+PAPPINFO pai,
+HWND hwndFrame,
+HWND hwndClient,
+ATOM aApp,
+ATOM aTopic)
+{
+ HSZPAIR hp[2];
+ PHSZPAIR php;
+ DWORD dwRet;
+ LPBYTE pdata;
+ HWND hwndServer;
+ BOOL fWild, fIsLocal, fIsSelf = FALSE;
+ PCLIENTINFO pci;
+
+ SEMCHECKOUT();
+
+ if (pai->afCmd & CBF_FAIL_CONNECTIONS) {
+ return;
+ }
+
+ /*
+ * If we are filtering and no app names are registered, quit.
+ */
+ if ((pai->afCmd & APPCMD_FILTERINITS) &&
+ QPileItemCount(pai->pAppNamePile) == 0) {
+ return;
+ }
+ fIsLocal = ((FARPROC)GetWindowLong(hwndClient,GWL_WNDPROC) == (FARPROC)ClientWndProc);
+ if (fIsLocal) {
+ pci = (PCLIENTINFO)GetWindowLong(hwndClient, GWL_PCI);
+ fIsSelf = (pci->ci.pai == pai);
+
+ /*
+ * filter out inits from ourselves
+ */
+ if (pai->afCmd & CBF_FAIL_SELFCONNECTIONS && fIsSelf) {
+ return;
+ }
+ }
+
+ hp[0].hszSvc = (HSZ)aApp;
+
+ /*
+ * filter out unwanted app names.
+ */
+ if (aApp && (pai->afCmd & APPCMD_FILTERINITS) &&
+ !FindPileItem(pai->pAppNamePile, CmpWORD, (LPBYTE)&aApp, 0))
+ return;
+
+ hp[0].hszTopic = aTopic;
+ hp[1].hszSvc = hp[1].hszTopic = 0L;
+ fWild = (hp[0].hszSvc == 0L || hp[0].hszTopic == 0L);
+
+ dwRet = DoCallback(pai, NULL, hp[0].hszTopic,
+ hp[0].hszSvc, 0, (fWild ? XTYP_WILDCONNECT : XTYP_CONNECT),
+ 0L, fIsLocal ? (DWORD)&pci->ci.CC : 0L, fIsSelf ? 1 : 0);
+
+ if (dwRet == NULL)
+ return;
+
+ if (fWild) {
+ pdata = GLOBALLOCK(HIWORD(dwRet));
+ php = (PHSZPAIR)pdata;
+ } else {
+ php = &hp[0];
+ pdata = NULL;
+ }
+
+ /*
+ * now php points to a 0 terminated list of hszpairs to respond to.
+ */
+ SEMENTER();
+ while (QueryHszLength(php->hszSvc) && QueryHszLength(php->hszTopic)) {
+ PSERVERINFO psi;
+
+ SEMLEAVE();
+ if ((hwndServer = CreateServerWindow(pai, (ATOM)php->hszTopic,
+ fIsLocal ? &pci->ci.CC : &CCDef)) == 0)
+ return;
+ SEMENTER();
+
+ /*
+ * have the server respond
+ */
+ psi = (PSERVERINFO)GetWindowLong(hwndServer, GWL_PCI);
+ psi->ci.hConvPartner = fIsLocal ? MAKEHCONV(hwndClient) : (HCONV)hwndClient;
+ psi->ci.hwndFrame = hwndFrame;
+ psi->ci.fs |= ST_CONNECTED;
+ if (fIsSelf) {
+ psi->ci.fs |= ST_ISSELF;
+ pci->ci.fs |= ST_ISSELF;
+ }
+ psi->ci.xad.state = XST_CONNECTED;
+ psi->ci.hszSvcReq = (HSZ)aApp;
+ psi->ci.aServerApp = (ATOM)php->hszSvc;
+ psi->ci.aTopic = (ATOM)php->hszTopic;
+
+ MONCONN(psi->ci.pai, psi->ci.aServerApp, psi->ci.aTopic,
+ hwndClient, hwndServer, TRUE);
+
+ IncHszCount(aApp); // for server window to keep
+ IncHszCount(LOWORD(php->hszSvc));
+ IncHszCount(LOWORD(php->hszTopic));
+
+ IncHszCount(LOWORD(php->hszSvc)); // for client to remove on ack
+ IncHszCount(LOWORD(php->hszTopic));
+
+#ifdef DEBUG
+ cAtoms -= 2; // we are giving these away
+#endif
+
+ SEMLEAVE();
+ SendMessage(hwndClient, WM_DDE_ACK, hwndServer,
+ MAKELONG(LOWORD(php->hszSvc), LOWORD(php->hszTopic)));
+ /*
+ * confirm initialization to server app - synchronously
+ */
+ DoCallback(pai, MAKEHCONV(hwndServer), php->hszTopic, php->hszSvc,
+ 0, XTYP_CONNECT_CONFIRM, 0L, 0L, fIsSelf ? 1 : 0);
+
+ SEMENTER();
+ php++;
+ }
+ if (pdata) {
+ GLOBALUNLOCK(HIWORD(dwRet));
+ FreeDataHandle(pai, dwRet, TRUE);
+ }
+ SEMLEAVE();
+ SEMCHECKOUT();
+}
+
+
+
+
+
+
+HWND CreateServerWindow(
+PAPPINFO pai,
+ATOM aTopic,
+PCONVCONTEXT pCC)
+{
+ HWND hwndServer;
+
+ SEMCHECKOUT();
+
+ /*
+ * make a server root window if needed....
+ */
+ if (pai->hwndSvrRoot == 0) {
+ /*
+ * NO - make one.
+ */
+ if ((pai->hwndSvrRoot = CreateWindow(SZCONVLISTCLASS, szNull, WS_CHILD,
+ 0, 0, 0, 0, pai->hwndDmg, NULL, hInstance, 0L)) == NULL) {
+ SETLASTERROR(pai, DMLERR_SYS_ERROR);
+ return(NULL);
+ }
+ }
+
+ /*
+ * Create the server window
+ */
+ if ((hwndServer = CreateWindow(SZSERVERCLASS, szNull, WS_CHILD,
+ 0, 0, 0, 0, pai->hwndSvrRoot, NULL, hInstance, &pai)) == NULL) {
+ SETLASTERROR(pai, DMLERR_SYS_ERROR);
+ return(NULL);
+ }
+ ((PSERVERINFO)GetWindowLong(hwndServer, GWL_PCI))->ci.CC = *pCC;
+ return(hwndServer);
+}
+
+
+
+
+
+
+/*
+ * WM_CREATE ServerWndProc processing
+ */
+long ServerCreate(
+HWND hwnd,
+PAPPINFO pai)
+{
+ PSERVERINFO psi;
+
+ /*
+ * allocate and initialize the server window info.
+ */
+
+ SEMENTER();
+
+ if (!(psi = (PSERVERINFO)FarAllocMem(pai->hheapApp, sizeof(SERVERINFO)))) {
+ SETLASTERROR(pai, DMLERR_MEMORY_ERROR);
+ return(1);
+ }
+
+ SEMLEAVE();
+ psi->ci.pai = pai;
+ // psi->ci.xad.hUser = 0L;
+ psi->ci.xad.state = XST_NULL;
+ psi->ci.fs = pai->wFlags & AWF_DEFCREATESTATE ? ST_BLOCKED : 0;
+ SetWindowLong(hwnd, GWL_PCI, (DWORD)psi);
+ SetWindowWord(hwnd, GWW_CHECKVAL, ++hwInst);
+ return(0);
+}
+
+
+
+
+
+/*
+ * Client response to a WM_DDE_ACK message when ACK to INITIATE expected.
+ */
+BOOL ClientInitAck(hwnd, pci, hwndServer, aApp, aTopic)
+HWND hwnd;
+PCLIENTINFO pci;
+HWND hwndServer;
+ATOM aApp;
+ATOM aTopic;
+{
+ HWND hwndClient;
+ PCLIENTINFO pciNew;
+
+#ifdef DEBUG
+ cAtoms += 2; // the incomming atoms need to be accounted for.
+#endif
+ SEMCHECKOUT();
+
+ switch (pci->ci.xad.state) {
+
+ case XST_INIT1:
+
+ /*
+ * first one back... lock in!
+ */
+ pci->ci.xad.state = XST_INIT2;
+ MONCONN(pci->ci.pai, aApp, aTopic, hwnd, hwndServer, TRUE);
+ if (GetWindowLong(hwndServer, GWL_WNDPROC) == (LONG)ServerWndProc) {
+ pci->ci.fs |= ST_ISLOCAL;
+ pci->ci.hConvPartner = MAKEHCONV(hwndServer);
+ } else {
+ pci->ci.hConvPartner = (HCONV)hwndServer;
+ if (aApp == aProgmanHack) {
+ // PROGMAN HACK!!!!
+ IncHszCount(aApp);
+ IncHszCount(aTopic);
+#ifdef DEBUG
+ cAtoms -= 2;
+#endif
+ }
+ }
+
+ pci->ci.aServerApp = aApp;
+ pci->ci.aTopic = aTopic;
+ if (!pci->ci.hwndFrame) // remember the frame this was sent to.
+ pci->ci.hwndFrame = pci->hwndInit;
+ IncHszCount(LOWORD(pci->ci.hszSvcReq)); // keep this for ourselves
+ break;
+
+
+ case XST_INIT2:
+
+ // Extra ack...
+
+ // throw away if from our partner or if we are not in a list.
+ if (hwndServer == (HWND)pci->ci.hConvPartner ||
+ GetParent(hwnd) == pci->ci.pai->hwndDmg) {
+Abort:
+ TRACETERM((szT, "ClientInitAck: Extra ack terminate: %x->%x\n", hwndServer, hwnd));
+ PostMessage(hwndServer, WM_DDE_TERMINATE, hwnd, 0L);
+ FreeHsz(aApp);
+ FreeHsz(aTopic);
+ break;
+ }
+
+ if (GetWindowLong(hwndServer, GWL_WNDPROC) != (LONG)ServerWndProc) {
+
+ // Non Local Extra Ack... terminate and attempt reconnection.
+
+ TRACETERM((szT, "ClientInitAck: Extra ack terminate and reconnect: %x->%x\n", hwndServer, hwnd));
+ PostMessage(hwndServer, WM_DDE_TERMINATE, hwnd, 0L);
+ GetDDEClientWindow(pci->ci.pai, GetParent(hwnd),
+ pci->hwndInit, aApp, aTopic, &pci->ci.CC);
+
+ // PROGMAN HACK!!!!
+ if (aApp != aProgmanHack) {
+ FreeHsz(aApp);
+ FreeHsz(aTopic);
+ }
+ break;
+ }
+ // Local Extra Ack... create a client window, set it up to be talking
+ // to the server window and tell the server window to change
+ // partners.
+
+
+ hwndClient = CreateWindow(SZCLIENTCLASS, szNull, WS_CHILD,
+ 0, 0, 0, 0, GetParent(hwnd), NULL, hInstance, &(pci->ci.pai));
+
+ if (!hwndClient) {
+ SETLASTERROR(pci->ci.pai, DMLERR_SYS_ERROR);
+ goto Abort;
+ }
+
+ pciNew = (PCLIENTINFO)GetWindowLong(hwndClient, GWL_PCI);
+ pciNew->ci.xad.state = XST_CONNECTED;
+ pciNew->ci.xad.LastError = DMLERR_NO_ERROR;
+ pciNew->ci.aServerApp = aApp;
+ pciNew->ci.hszSvcReq = pci->ci.hszSvcReq;
+ IncHszCount(LOWORD(pciNew->ci.hszSvcReq));
+ pciNew->ci.aTopic = aTopic;
+ pciNew->ci.hConvPartner = MAKEHCONV(hwndServer);
+ pciNew->ci.hwndFrame = pci->hwndInit;
+ pciNew->ci.fs |= ST_CONNECTED | ST_ISLOCAL;
+ MONCONN(pciNew->ci.pai, aApp, aTopic, hwnd, hwndServer, TRUE);
+ SendMessage(hwndServer, UMSR_CHGPARTNER, hwndClient, 0L);
+
+ break;
+ }
+
+ return(TRUE);
+}
+