test: ddemlwp.c File Reference

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# ddemlwp.c File Reference

`#include "precomp.h"`

Go to the source code of this file.

## Functions

VOID | ProcessDDEMLInitiate (PCL_INSTANCE_INFO pcii, HWND hwndClient, GATOM aServer, GATOM aTopic)
LRESULT | DDEMLMotherWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT | DDEMLClientWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
LRESULT | DDEMLServerWndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
PCONV_INFO | ProcessTerminateMsg (PCONV_INFO pcoi, HWND hwndFrom)
VOID | ProcessAsyncDDEMsg (PCONV_INFO pcoi, UINT msg, HWND hwndFrom, LPARAM lParam)
BOOL | CheckForQueuedMessages (PCONV_INFO pcoi)
VOID | DumpDDEMessage (BOOL fFreeData, UINT msg, LPARAM lParam)
BOOL | ProcessSyncDDEMessage (PCONV_INFO pcoi, UINT msg, LPARAM lParam)

## Function Documentation

BOOL CheckForQueuedMessages | ( | PCONV_INFO | pcoi | ) |

Definition at line 664 of file ddemlwp.c.

References BOOL, CheckDDECritIn, _CLIENTINFO::CI_flags, CI_PROCESSING_QUEUE, _CLIENTINFO::cInDDEMLCallback, tagCONV_INFO::cLocks, DDEMLFree, tagCONV_INFO::dmqIn, tagCONV_INFO::dmqOut, FALSE, GetClientInfo, tagDDE_MESSAGE_QUEUE::lParam, tagDDE_MESSAGE_QUEUE::msg, tagDDE_MESSAGE_QUEUE::next, NULL, ProcessSyncDDEMessage(), tagCONV_INFO::state, and TRUE.

Referenced by DdeEnableCallback(), ProcessAsyncDDEMsg(), and SetEnableState().

    00666 {
    00667     PDDE_MESSAGE_QUEUE pdmq;
    00668     BOOL fRet = FALSE;
    00669     PCLIENTINFO pci;
    00670
    00671     CheckDDECritIn;
    00672
    00673     if (pcoi->state & ST_PROCESSING) {      // recursion prevention
    00674         return(FALSE);
    00675     }
    00676
    00677     UserAssert(pcoi->cLocks);
    00678
    00679     pci = GetClientInfo();
    00680
    00681     pcoi->state |= ST_PROCESSING;
    00682     while (!(pcoi->state & ST_BLOCKED) &&
    00683                 pcoi->dmqOut != NULL &&
    00684                 !pci->cInDDEMLCallback) {
    00685         pci->CI_flags |= CI_PROCESSING_QUEUE;
    00686         if (ProcessSyncDDEMessage(pcoi, pcoi->dmqOut->msg, pcoi->dmqOut->lParam)) {
    00687             fRet = TRUE;
    00688             pdmq = pcoi->dmqOut;
    00689             pcoi->dmqOut = pcoi->dmqOut->next;
    00690             if (pcoi->dmqOut == NULL) {
    00691                 pcoi->dmqIn = NULL;
    00692             }
    00693             DDEMLFree(pdmq);
    00694         }
    00695         pci->CI_flags &= ~CI_PROCESSING_QUEUE;
    00696     }
    00697     pcoi->state &= ~ST_PROCESSING;
    00698     return(fRet);
    00699 }

LRESULT DDEMLClientWndProc | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 376 of file ddemlwp.c.

References tagCLS::atomClassName, tagSERVERINFO::atomSysClass, tagCL_CONV_INFO::ci, CLST_CONNECTED, CLST_SINGLE_INITIALIZING, CreateHandle(), DDEMLAlloc, DDEMLFree, DefWindowProc(), EnterDDECrit, GetWindowLongPtr(), GlobalToLocalAtom(), gpsi, GWL_CONVSTATE, GWLP_CHINST, GWLP_PCI, HTYPE_CLIENT_CONVERSATION, tagCONV_INFO::hwndConv, ICLS_DDEMLSERVERA, ICLS_DDEMLSERVERW, InstFromHandle, LeaveDDECrit, tagCONV_INFO::next, NULL, tagCONV_INFO::pcii, PostMessage(), ProcessAsyncDDEMsg(), ProcessTerminateMsg(), REBASEALWAYS, SetCommonStateFlags(), SetWindowLongPtr(), TestWF, ValidateHwnd, ValidateInstance(), and WFANSIPROC.

Referenced by RW_RegisterDDEML().

    00381 {
    00382     PCL_CONV_INFO pci, pciNew;
    00383     LONG lState;
    00384     LRESULT lRet = 0;
    00385     PWND pwnd;
    00386     PCLS pcls;
    00387
    00388     EnterDDECrit;
    00389
    00390     pci = (PCL_CONV_INFO)GetWindowLongPtr(hwnd, GWLP_PCI);
    00391     UserAssert(pci == NULL || pci->ci.hwndConv == hwnd);
    00392
    00393     switch (message) {
    00394     case WM_DDE_ACK:
    00395         lState = GetWindowLong(hwnd, GWL_CONVSTATE);
    00396         if (lState != CLST_CONNECTED) {
    00397
    00398             // Initiation mode
    00399
    00400             pciNew = (PCL_CONV_INFO)DDEMLAlloc(sizeof(CL_CONV_INFO));
    00401             if (pciNew == NULL ||
    00402                     (pci != NULL && lState == CLST_SINGLE_INITIALIZING)) {
    00403                 PostMessage((HWND)wParam, WM_DDE_TERMINATE, (WPARAM)hwnd, 0);
    00404                 goto Exit;
    00405             }
    00406
    00407             // PCL_CONV_INFO initialization
    00408
    00409             pciNew->ci.pcii = ValidateInstance((HANDLE)GetWindowLongPtr(hwnd, GWLP_CHINST));
    00410
    00411             if (pciNew->ci.pcii == NULL) {
    00412                 DDEMLFree(pciNew);
    00413                 goto Exit;
    00414             }
    00415
    00416             pciNew->ci.next = (PCONV_INFO)pci; // pci may be NULL
    00417             //
    00418             // Seting GWLP_PCI gives feedback to ConnectConv() which issued
    00419             // the WM_DDE_INITIATE message.
    00420             //
    00421             SetWindowLongPtr(hwnd, GWLP_PCI, (LONG_PTR)pciNew);
    00422             // pciNew->hUser = 0; // Zero init.
    00423
    00424             // BUG: If this fails we can have some nasty problems
    00425             pciNew->ci.hConv = (HCONV)CreateHandle((ULONG_PTR)pciNew,
    00426                     HTYPE_CLIENT_CONVERSATION, InstFromHandle(pciNew->ci.pcii->hInstClient));
    00427
    00428             pciNew->ci.laService = GlobalToLocalAtom(LOWORD(lParam)); // pci copy
    00429             GlobalDeleteAtom(LOWORD(lParam));
    00430             pciNew->ci.laTopic = GlobalToLocalAtom(HIWORD(lParam)); // pci copy
    00431             GlobalDeleteAtom(HIWORD(lParam));
    00432             pciNew->ci.hwndPartner = (HWND)wParam;
    00433             pciNew->ci.hwndConv = hwnd;
    00434             pciNew->ci.state = (WORD)(ST_CONNECTED | ST_CLIENT |
    00435                     pciNew->ci.pcii->ConvStartupState);
    00436             SetCommonStateFlags(hwnd, (HWND)wParam, &pciNew->ci.state);
    00437
    00438             pwnd = ValidateHwnd((HWND)wParam);
    00439
    00440             if (pwnd == NULL) goto Exit;
    00441             pcls = (PCLS)REBASEALWAYS(pwnd, pcls);
    00442
    00443             if (!TestWF(pwnd, WFANSIPROC)) {
    00444                 if (pcls->atomClassName == gpsi->atomSysClass[ICLS_DDEMLSERVERW]) {
    00445                     pciNew->ci.state |= ST_ISLOCAL;
    00446                 }
    00447             } else {
    00448                 if (pcls->atomClassName == gpsi->atomSysClass[ICLS_DDEMLSERVERA]) {
    00449                     pciNew->ci.state |= ST_ISLOCAL;
    00450                 }
    00451             }
    00452
    00453             // pciNew->ci.laServiceRequested = 0; // Set by InitiateEnumerationProc()
    00454             // pciNew->ci.pxiIn = 0;
    00455             // pciNew->ci.pxiOut = 0;
    00456             // pciNew->ci.dmqIn = 0;
    00457             // pciNew->ci.dmqOut = 0;
    00458             // pciNew->ci.aLinks = NULL;
    00459             // pciNew->ci.cLinks = 0;
    00460             // pciNew->ci.cLocks = 0;
    00461             goto Exit;
    00462         }
    00463         // fall through to handle posted messages here.
    00464
    00465     case WM_DDE_DATA:
    00466         ProcessAsyncDDEMsg((PCONV_INFO)pci, message, (HWND)wParam, lParam);
    00467         goto Exit;
    00468
    00469     case WM_DDE_TERMINATE:
    00470     case WM_DESTROY:
    00471         {
    00472             ProcessTerminateMsg((PCONV_INFO)pci, (HWND)wParam);
    00473             break;
    00474         }
    00475     }
    00476
    00477     lRet = DefWindowProc(hwnd, message, wParam, lParam);
    00478
    00479 Exit:
    00480     LeaveDDECrit;
    00481     return (lRet);
    00482 }

LRESULT DDEMLMotherWndProc | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 27 of file ddemlwp.c.

References DefWindowProc(), GetWindowLongPtr(), GWLP_PCI, ProcessDDEMLInitiate(), and ProcessRegistrationMessage().

Referenced by RW_RegisterDDEML().

    00032 {
    00033     switch (message) {
    00034     case UM_REGISTER:
    00035     case UM_UNREGISTER:
    00036         return(ProcessRegistrationMessage(hwnd, message, wParam, lParam));
    00037
    00038     case WM_DDE_INITIATE:
    00039         ProcessDDEMLInitiate((PCL_INSTANCE_INFO)GetWindowLongPtr(hwnd, GWLP_PCI),
    00040                 (HWND)wParam, (ATOM)LOWORD(lParam), (ATOM)HIWORD(lParam));
    00041         return(0);
    00042
    00043     }
    00044     return(DefWindowProc(hwnd, message, wParam, lParam));
    00045 }

LRESULT DDEMLServerWndProc | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wParam,
|  | LPARAM | lParam
| ) |

Definition at line 496 of file ddemlwp.c.

References tagSVR_CONV_INFO::ci, DefWindowProc(), EnterDDECrit, GetWindowLongPtr(), GWLP_PSI, tagCONV_INFO::hwndConv, LeaveDDECrit, NULL, ProcessAsyncDDEMsg(), and ProcessTerminateMsg().

Referenced by RW_RegisterDDEML().

    00501 {
    00502     PSVR_CONV_INFO psi;
    00503     LRESULT lRet = 0;
    00504
    00505     EnterDDECrit;
    00506
    00507     psi = (PSVR_CONV_INFO)GetWindowLongPtr(hwnd, GWLP_PSI);
    00508     UserAssert(psi == NULL || psi->ci.hwndConv == hwnd);
    00509
    00510     switch (message) {
    00511     case WM_DDE_REQUEST:
    00512     case WM_DDE_POKE:
    00513     case WM_DDE_ADVISE:
    00514     case WM_DDE_EXECUTE:
    00515     case WM_DDE_ACK:
    00516     case WM_DDE_UNADVISE:
    00517         ProcessAsyncDDEMsg((PCONV_INFO)psi, message, (HWND)wParam, lParam);
    00518         goto Exit;
    00519
    00520     case WM_DDE_TERMINATE:
    00521     case WM_DESTROY:
    00522         ProcessTerminateMsg((PCONV_INFO)psi, (HWND)wParam);
    00523         break;
    00524     }
    00525     lRet = DefWindowProc(hwnd, message, wParam, lParam);
    00526 Exit:
    00527     LeaveDDECrit;
    00528     return (lRet);
    00529 }

VOID DumpDDEMessage | ( | BOOL | fFreeData,
|  | UINT | msg,
|  | LPARAM | lParam
| ) |

Definition at line 714 of file ddemlwp.c.

References FALSE, FreeDDEData(), FreeDDElParam(), msg, TRUE, UnpackDDElParam(), VOID(), and WOWGLOBALFREE.

Referenced by FreeConversationResources(), ProcessAsyncDDEMsg(), ProcessSyncDDEMessage(), SpontaneousClientMessage(), and SpontaneousServerMessage().

    00718 {
    00719     UINT_PTR uiLo, uiHi;
    00720
    00721     RIPMSG2(RIP_WARNING, "Dump DDE msg %x lParam %x", msg, lParam);
    00722
    00723     switch (msg) {
    00724     case WM_DDE_ACK:
    00725     case WM_DDE_DATA:
    00726     case WM_DDE_POKE:
    00727     case WM_DDE_ADVISE:
    00728         UnpackDDElParam(msg, lParam, &uiLo, &uiHi);
    00729         switch (msg) {
    00730         case WM_DDE_DATA:
    00731         case WM_DDE_POKE:
    00732             if (uiLo) {
    00733                 if (fFreeData) {
    00734                     FreeDDEData((HANDLE)uiLo, FALSE, TRUE);
    00735                 }
    00736                 GlobalDeleteAtom((ATOM)uiHi);
    00737             }
    00738             break;
    00739
    00740         case WM_DDE_ADVISE:
    00741             if (uiLo) {
    00742                 if (fFreeData) {
    00743                     FreeDDEData((HANDLE)uiLo, FALSE, TRUE);
    00744                 }
    00745                 GlobalDeleteAtom((ATOM)uiHi);
    00746             }
    00747             break;
    00748
    00749         case WM_DDE_ACK:
    00750             // could be EXEC Ack - cant know what to do exactly.
    00751             break;
    00752         }
    00753         FreeDDElParam(msg, lParam);
    00754         break;
    00755
    00756     case WM_DDE_EXECUTE:
    00757         if (fFreeData) {
    00758             WOWGLOBALFREE((HANDLE)lParam);
    00759         }
    00760         break;
    00761
    00762     case WM_DDE_REQUEST:
    00763     case WM_DDE_UNADVISE:
    00764         GlobalDeleteAtom((ATOM)HIWORD(lParam));
    00765         break;
    00766     }
    00767 }

VOID ProcessAsyncDDEMsg | ( | PCONV_INFO | pcoi,
|  | UINT | msg,
|  | HWND | hwndFrom,
|  | LPARAM | lParam
| ) |

Definition at line 572 of file ddemlwp.c.

References CheckForQueuedMessages(), tagCONV_INFO::cLocks, DDEMLAlloc, tagCONV_INFO::dmqIn, tagCONV_INFO::dmqOut, DumpDDEMessage(), FALSE, FreeConversationResources(), tagCONV_INFO::hwndConv, tagCONV_INFO::hwndPartner, tagDDE_MESSAGE_QUEUE::lParam, tagDDE_MESSAGE_QUEUE::msg, msg, tagDDE_MESSAGE_QUEUE::next, tagCONV_INFO::next, NULL, tagDDE_MESSAGE_QUEUE::pcoi, PostMessage(), ProcessSyncDDEMessage(), tagCONV_INFO::state, and VOID().

Referenced by DDEMLClientWndProc(), and DDEMLServerWndProc().

    00577 {
    00578     PDDE_MESSAGE_QUEUE pdmq;
    00579 #if DBG
    00580     HWND hwndT = pcoi->hwndConv;
    00581 #endif // DBG
    00582
    00583     while (pcoi != NULL && pcoi->hwndPartner != hwndFrom) {
    00584         pcoi = pcoi->next;
    00585     }
    00586     if (pcoi == NULL) {
    00587         RIPMSG3(RIP_WARNING,
    00588                 "Bogus DDE message %x received from %x by %x. Dumping.",
    00589                 msg, hwndFrom, hwndT);
    00590         DumpDDEMessage(FALSE, msg, lParam);
    00591         return ;
    00592     }
    00593     if (pcoi->state & ST_CONNECTED) {
    00594
    00595         if (pcoi->dmqOut == NULL &&
    00596                 !(pcoi->state & ST_BLOCKED)
    00597 //                && !PctiCurrent()->cInDDEMLCallback
    00598                 ) {
    00599
    00600             if (ProcessSyncDDEMessage(pcoi, msg, lParam)) {
    00601                 return; // not blocked, ok to return.
    00602             }
    00603         }
    00604
    00605         // enter into queue
    00606
    00607         pdmq = DDEMLAlloc(sizeof(DDE_MESSAGE_QUEUE));
    00608         if (pdmq == NULL) {
    00609
    00610             // insufficient memory - we can't process this msg - we MUST
    00611             // terminate.
    00612
    00613             if (pcoi->state & ST_CONNECTED) {
    00614                 PostMessage(pcoi->hwndPartner, WM_DDE_TERMINATE,
    00615                         (WPARAM)pcoi->hwndConv, 0);
    00616                 pcoi->state &= ~ST_CONNECTED;
    00617             }
    00618             DumpDDEMessage(!(pcoi->state & ST_INTRA_PROCESS), msg, lParam);
    00619             return ;
    00620         }
    00621         pdmq->pcoi = pcoi;
    00622         pdmq->msg = msg;
    00623         pdmq->lParam = lParam;
    00624         pdmq->next = NULL;
    00625
    00626         // dmqOut->next->next->next->dmqIn->NULL
    00627
    00628         if (pcoi->dmqIn != NULL) {
    00629             pcoi->dmqIn->next = pdmq;
    00630         }
    00631         pcoi->dmqIn = pdmq;
    00632         if (pcoi->dmqOut == NULL) {
    00633             pcoi->dmqOut = pcoi->dmqIn;
    00634         }
    00635         pcoi->cLocks++;
    00636         CheckForQueuedMessages(pcoi);
    00637         pcoi->cLocks--;
    00638         if (pcoi->cLocks == 0 && pcoi->state & ST_FREE_CONV_RES_NOW) {
    00639             FreeConversationResources(pcoi);
    00640         }
    00641     } else {
    00642         DumpDDEMessage(!(pcoi->state & ST_INTRA_PROCESS), msg, lParam);
    00643     }
    00644 }

VOID ProcessDDEMLInitiate | ( | PCL_INSTANCE_INFO | pcii,
|  | HWND | hwndClient,
|  | GATOM | aServer,
|  | GATOM | aTopic
| ) |

Definition at line 59 of file ddemlwp.c.

References tagCL_INSTANCE_INFO::afCmd, tagCL_INSTANCE_INFO::aServerLookup, tagCLS::atomClassName, tagSERVERINFO::atomSysClass, BOOL, CheckDDECritOut, tagSVR_CONV_INFO::ci, CLST_SINGLE_INITIALIZING, tagCL_INSTANCE_INFO::ConvStartupState, CreateHandle(), tagCL_INSTANCE_INFO::cServerLookupAlloc, DdeAccessData(), DDEMLAlloc, DDEMLFree, DDEMLReAlloc, DdeUnaccessData(), DoCallback(), DWORD, EnterDDECrit, FALSE, tagCL_INSTANCE_INFO::flags, GetConvContext(), GetWindowLongPtr(), GlobalToLocalAtom(), gpsi, GWL_CONVSTATE, GWLP_PSI, GWLP_SHINST, tagCL_INSTANCE_INFO::hInstClient, tagCL_INSTANCE_INFO::hInstServer, HTYPE_SERVER_CONVERSATION, tagCL_INSTANCE_INFO::hwndMother, tagCONV_INFO::hwndPartner, tagSERVER_LOOKUP::hwndServer, ICLS_DDEMLCLIENTA, ICLS_DDEMLCLIENTW, ICLS_DDEMLSERVERA, ICLS_DDEMLSERVERW, IIF_UNICODE, IncLocalAtomCount(), InstFromHandle, InternalFreeDataHandle(), IsWindow(), L, tagSERVER_LOOKUP::laService, LATOM, LATOM_FROM_HSZ, tagSERVER_LOOKUP::laTopic, LeaveDDECrit, LocalToGlobalAtom(), LPVOID, MONCONV, tagCONV_INFO::next, NORMAL_HSZ_FROM_LATOM, NtUserDdeGetQualityOfService(), NtUserDestroyWindow(), NULL, tagCL_INSTANCE_INFO::plaNameService, REBASEALWAYS, SendMessage(), SetCommonStateFlags(), SetWindowLongPtr(), TestWF, TRUE, ValidateHwnd, VOID(), and WFANSIPROC.

Referenced by DDEMLMotherWndProc().

    00064 {
    00065     CONVCONTEXT cc = {
    00066         sizeof(CONVCONTEXT),
    00067         0,
    00068         0,
    00069         CP_WINANSI,
    00070         0L,
    00071         0L,
    00072         {
    00073             sizeof(SECURITY_QUALITY_OF_SERVICE),
    00074             SecurityImpersonation,
    00075             SECURITY_STATIC_TRACKING,
    00076             TRUE
    00077         }
    00078     };
    00079     BOOL flags = ST_INLIST;
    00080     BOOL fWild;
    00081     HDDEDATA hData;
    00082     HWND hwndServer;
    00083     PSERVER_LOOKUP psl;
    00084     PHSZPAIR php;
    00085     HSZPAIR hp[2];
    00086     LATOM laService, laFree1 = 0;
    00087     LATOM laTopic, laFree2 = 0;
    00088     PSVR_CONV_INFO psi;
    00089     LATOM *plaNameService;
    00090     PWND pwndClient;
    00091     PCLS pcls;
    00092
    00093     if (pcii == NULL) {
    00094         return;     // we aren't done being initiated yet.
    00095     }
    00096
    00097     EnterDDECrit;
    00098
    00099     if (pcii->afCmd & CBF_FAIL_CONNECTIONS || !IsWindow(hwndClient)) {
    00100         goto Exit;
    00101     }
    00102
    00103     pwndClient = ValidateHwnd(hwndClient);
    00104     if (pwndClient == NULL) goto Exit;
    00105
    00106     pcls = (PCLS)REBASEALWAYS(pwndClient, pcls);
    00107     if (!TestWF(pwndClient, WFANSIPROC)) {
    00108         if (pcls->atomClassName == gpsi->atomSysClass[ICLS_DDEMLCLIENTW]) {
    00109             flags |= ST_ISLOCAL;
    00110         }
    00111     } else {
    00112         if (pcls->atomClassName == gpsi->atomSysClass[ICLS_DDEMLCLIENTA]) {
    00113             flags |= ST_ISLOCAL;
    00114         }
    00115     }
    00116
    00117     if (flags & ST_ISLOCAL) {
    00118         /*
    00119          * Make sure other guy allows self-connections if that's what this is.
    00120          */
    00121         if (pcii->hInstServer == (HANDLE)GetWindowLongPtr(hwndClient, GWLP_SHINST)) {
    00122             if (pcii->afCmd & CBF_FAIL_SELFCONNECTIONS) {
    00123                 goto Exit;
    00124             }
    00125             flags |= ST_ISSELF;
    00126         }
    00127
    00128         GetConvContext(hwndClient, (LONG *)&cc);
    00129         if (GetWindowLong(hwndClient, GWL_CONVSTATE) & CLST_SINGLE_INITIALIZING) {
    00130             flags &= ~ST_INLIST;
    00131         }
    00132     } else {
    00133         NtUserDdeGetQualityOfService(hwndClient, NULL, &cc.qos);
    00134     }
    00135
    00136 /***************************************************************************\
    00137 *
    00138 * Server window creation is minimized by only creating one window per
    00139 * Instance/Service/Topic set. This should be all that is needed and
    00140 * duplicate connections (ie where the server/client window pair is identical
    00141 * to another conversation) should not happen. However, if some dumb
    00142 * server app attempts to create a duplicate conversation by having
    00143 * duplicate service/topic pairs passed back from a XTYP_WILD_CONNECT
    00144 * callback we will not honor the request.
    00145 *
    00146 * The INSTANCE_INFO structure holds a pointer to an array of SERVERLOOKUP
    00147 * structures each entry of which references the hwndServer that supports
    00148 * all conversations on that service/topic pair. The hwndServer windows
    00149 * in turn have window words that reference the first member in a linked
    00150 * list of SVR_CONV_INFO structures, one for each conversation on that
    00151 * service/topic pair.
    00152 *
    00153 \***************************************************************************/
    00154
    00155     laFree1 = laService = GlobalToLocalAtom(aServer);
    00156     laFree2 = laTopic = GlobalToLocalAtom(aTopic);
    00157
    00158     plaNameService = pcii->plaNameService;
    00159     if (!laService && pcii->afCmd & APPCMD_FILTERINITS && *plaNameService == 0) {
    00160         /*
    00161          * no WILDCONNECTS to servers with no registered names while filtering.
    00162          */
    00163         goto Exit;
    00164     }
    00165     if ((pcii->afCmd & APPCMD_FILTERINITS) && laService) {
    00166         /*
    00167          * if we can't find the aServer in this instance's service name
    00168          * list, don't bother the server.
    00169          */
    00170         while (*plaNameService != 0 && *plaNameService != laService) {
    00171             plaNameService++;
    00172         }
    00173         if (*plaNameService == 0) {
    00174             goto Exit;
    00175         }
    00176     }
    00177     hp[0].hszSvc = NORMAL_HSZ_FROM_LATOM(laService);
    00178     hp[0].hszTopic = NORMAL_HSZ_FROM_LATOM(laTopic);
    00179     hp[1].hszSvc = 0;
    00180     hp[1].hszTopic = 0;
    00181     fWild = !laService || !laTopic;
    00182
    00183     hData = DoCallback(pcii,
    00184         (WORD)(fWild ? XTYP_WILDCONNECT : XTYP_CONNECT),
    00185         0,
    00186         (HCONV)0,
    00187         hp[0].hszTopic,
    00188         hp[0].hszSvc,
    00189         (HDDEDATA)0,
    00190         flags & ST_ISLOCAL ? (ULONG_PTR)&cc : 0,
    00191         (DWORD)(flags & ST_ISSELF) ? 1 : 0);
    00192
    00193     if (!hData) {
    00194         goto Exit;
    00195     }
    00196
    00197     if (fWild) {
    00198         php = (PHSZPAIR)DdeAccessData(hData, NULL);
    00199         if (php == NULL) {
    00200             goto Exit;
    00201         }
    00202     } else {
    00203         php = hp;
    00204     }
    00205
    00206     while (php->hszSvc && php->hszTopic) {
    00207
    00208         psi = (PSVR_CONV_INFO)DDEMLAlloc(sizeof(SVR_CONV_INFO));
    00209         if (psi == NULL) {
    00210             break;
    00211         }
    00212
    00213         laService = LATOM_FROM_HSZ(php->hszSvc);
    00214         laTopic = LATOM_FROM_HSZ(php->hszTopic);
    00215
    00216         hwndServer = 0;
    00217         if (pcii->cServerLookupAlloc) {
    00218             int i;
    00219             /*
    00220              * See if there already exists a server window for this
    00221              * aServer/aTopic pair
    00222              */
    00223             for (i = pcii->cServerLookupAlloc; i; i--) {
    00224                 if (pcii->aServerLookup[i - 1].laService == laService &&
    00225                         pcii->aServerLookup[i - 1].laTopic == laTopic) {
    00226                     PSVR_CONV_INFO psiT;
    00227                     PCONV_INFO pcoi;
    00228
    00229                     hwndServer = pcii->aServerLookup[i - 1].hwndServer;
    00230                     /*
    00231                      * Now make sure this window isn't some bogus idiot
    00232                      * trying to create a second conversation from the
    00233                      * same client window that is already talking to
    00234                      * our existing server window.
    00235                      */
    00236                     psiT = (PSVR_CONV_INFO)GetWindowLongPtr(hwndServer, GWLP_PSI);
    00237                     for (pcoi = &psiT->ci; pcoi != NULL; pcoi = pcoi->next) {
    00238                         if (pcoi->hwndPartner == hwndClient) {
    00239                             hwndServer = NULL;
    00240                             break;
    00241                         }
    00242                     }
    00243                     break;
    00244                 }
    00245             }
    00246         }
    00247
    00248         if (hwndServer == 0) {
    00249
    00250             // no server window exists - make one.
    00251
    00252             LeaveDDECrit;
    00253             if (pcii->flags & IIF_UNICODE) {
    00254                 hwndServer = CreateWindowW((LPWSTR)(gpsi->atomSysClass[ICLS_DDEMLSERVERW]),
    00255                                           L"",
    00256                                           WS_CHILD,
    00257                                           0, 0, 0, 0,
    00258                                           pcii->hwndMother,
    00259                                           (HMENU)0,
    00260                                           0,
    00261                                           (LPVOID)NULL);
    00262             } else {
    00263                 hwndServer = CreateWindowA((LPSTR)(gpsi->atomSysClass[ICLS_DDEMLSERVERA]),
    00264                                           "",
    00265                                           WS_CHILD,
    00266                                           0, 0, 0, 0,
    00267                                           pcii->hwndMother,
    00268                                           (HMENU)0,
    00269                                           0,
    00270                                           (LPVOID)NULL);
    00271             }
    00272             EnterDDECrit;
    00273
    00274             if (hwndServer == 0) {
    00275                 DDEMLFree(psi);
    00276                 break;
    00277             }
    00278             // SetWindowLongPtr(hwndServer, GWLP_PSI, (LONG)NULL); // Zero init.
    00279
    00280             // put the window into the lookup list
    00281
    00282             if (pcii->aServerLookup == NULL) {
    00283                 psl = (PSERVER_LOOKUP)DDEMLAlloc(sizeof(SERVER_LOOKUP));
    00284             } else {
    00285                 psl = (PSERVER_LOOKUP)DDEMLReAlloc(pcii->aServerLookup,
    00286                         sizeof(SERVER_LOOKUP) * (pcii->cServerLookupAlloc + 1));
    00287             }
    00288             if (psl == NULL) {
    00289                 RIPMSG1(RIP_WARNING, "ProcessDDEMLInitiate:hwndServer (%x) destroyed due to low memory.", hwndServer);
    00290                 NtUserDestroyWindow(hwndServer);
    00291                 DDEMLFree(psi);
    00292                 break;
    00293             }
    00294
    00295             IncLocalAtomCount(laService); // for SERVER_LOOKUP
    00296             psl[pcii->cServerLookupAlloc].laService = laService;
    00297             IncLocalAtomCount(laTopic); // for SERVER_LOOKUP
    00298             psl[pcii->cServerLookupAlloc].laTopic = laTopic;
    00299             psl[pcii->cServerLookupAlloc].hwndServer = hwndServer;
    00300             pcii->aServerLookup = psl;
    00301             pcii->cServerLookupAlloc++;
    00302             // DumpServerLookupTable("After addition:", hwndServer, psl, pcii->cServerLookupAlloc);
    00303         }
    00304
    00305         psi->ci.next = (PCONV_INFO)GetWindowLongPtr(hwndServer, GWLP_PSI);
    00306         SetWindowLongPtr(hwndServer, GWLP_PSI, (LONG_PTR)psi);
    00307         psi->ci.pcii = pcii;
    00308         // psi->ci.hUser = 0;
    00309         psi->ci.hConv = (HCONV)CreateHandle((ULONG_PTR)psi,
    00310                 HTYPE_SERVER_CONVERSATION, InstFromHandle(pcii->hInstClient));
    00311         psi->ci.laService = laService;
    00312         IncLocalAtomCount(laService); // for server window
    00313         psi->ci.laTopic = laTopic;
    00314         IncLocalAtomCount(laTopic); // for server window
    00315         psi->ci.hwndPartner = hwndClient;
    00316         psi->ci.hwndConv = hwndServer;
    00317         psi->ci.state = (WORD)(flags | ST_CONNECTED | pcii->ConvStartupState);
    00318         SetCommonStateFlags(hwndClient, hwndServer, &psi->ci.state);
    00319         psi->ci.laServiceRequested = laFree1;
    00320         IncLocalAtomCount(psi->ci.laServiceRequested); // for server window
    00321         // psi->ci.pxiIn = NULL;
    00322         // psi->ci.pxiOut = NULL;
    00323         // psi->ci.dmqIn = NULL;
    00324         // psi->ci.dmqOut = NULL;
    00325         // psi->ci.aLinks = NULL;
    00326         // psi->ci.cLinks = 0;
    00327         // psi->ci.cLocks = 0;
    00328
    00329         LeaveDDECrit;
    00330         CheckDDECritOut;
    00331         SendMessage(hwndClient, WM_DDE_ACK, (WPARAM)hwndServer,
    00332                 MAKELONG(LocalToGlobalAtom(laService), LocalToGlobalAtom(laTopic)));
    00333         EnterDDECrit;
    00334
    00335         if (!(pcii->afCmd & CBF_SKIP_CONNECT_CONFIRMS)) {
    00336             DoCallback(pcii,
    00337                     (WORD)XTYP_CONNECT_CONFIRM,
    00338                     0,
    00339                     psi->ci.hConv,
    00340                     (HSZ)laTopic,
    00341                     (HSZ)laService,
    00342                     (HDDEDATA)0,
    00343                     0,
    00344                     (flags & ST_ISSELF) ? 1L : 0L);
    00345         }
    00346
    00347         MONCONV((PCONV_INFO)psi, TRUE);
    00348
    00349         if (!(flags & ST_INLIST)) {
    00350             break;      // our partner's only gonna take the first one anyway.
    00351         }
    00352         php++;
    00353     }
    00354
    00355     if (fWild) {
    00356         DdeUnaccessData(hData);
    00357         InternalFreeDataHandle(hData, FALSE);
    00358     }
    00359
    00360 Exit:
    00361     DeleteAtom(laFree1);
    00362     DeleteAtom(laFree2);
    00363     LeaveDDECrit;
    00364     return;
    00365 }

BOOL ProcessSyncDDEMessage | ( | PCONV_INFO | pcoi,
|  | UINT | msg,
|  | LPARAM | lParam
| ) |

Definition at line 782 of file ddemlwp.c.

References tagCL_INSTANCE_INFO::afCmd, BOOL, CheckDDECritIn, tagCL_INSTANCE_INFO::cInDDEMLCallback, tagCONV_INFO::cLocks, DdeUninitialize(), DumpDDEMessage(), EnableEnumProc(), EnumChildWindows(), FALSE, tagCL_INSTANCE_INFO::flags, FreeConversationResources(), HINST_ANY, tagCL_INSTANCE_INFO::hInstClient, HTYPE_TRANSACTION, tagCL_INSTANCE_INFO::hwndMother, tagXACT_INFO::hXact, IIF_IN_SYNC_XACT, msg, NULL, tagCONV_INFO::pcii, tagXACT_INFO::pfnResponse, tagENABLE_ENUM_STRUCT::pfRet, tagCONV_INFO::pxiOut, SpontaneousClientMessage(), SpontaneousServerMessage(), tagCONV_INFO::state, TRUE, ValidateCHandle(), tagENABLE_ENUM_STRUCT::wCmd, and tagENABLE_ENUM_STRUCT::wCmd2.

Referenced by CheckForQueuedMessages(), and ProcessAsyncDDEMsg().

    00786 {
    00787     BOOL fNotBlocked = TRUE;
    00788     PCL_INSTANCE_INFO pcii;
    00789     ENABLE_ENUM_STRUCT ees;
    00790     BOOL fRet;
    00791
    00792     CheckDDECritIn;
    00793
    00794     /*
    00795      * lock the conversation so its resources don't go away till we are
    00796      * done with them.  This function could generate a callback which could
    00797      * disconnect the conversation.
    00798      */
    00799     pcoi->cLocks++;
    00800
    00801     if (pcoi->state & ST_BLOCKNEXT) {
    00802         pcoi->state ^= ST_BLOCKNEXT | ST_BLOCKED;
    00803     }
    00804     if (pcoi->state & ST_BLOCKALLNEXT) {
    00805         ees.pfRet = &fRet;
    00806         ees.wCmd = EC_DISABLE;
    00807         ees.wCmd2 = 0;
    00808         EnumChildWindows(pcoi->pcii->hwndMother, (WNDENUMPROC)EnableEnumProc,
    00809                 (LPARAM)&ees);
    00810     }
    00811
    00812     if (pcoi->state & ST_CONNECTED) {
    00813         if (pcoi->pxiOut == NULL) {
    00814             if (pcoi->state & ST_CLIENT) {
    00815                 fNotBlocked = SpontaneousClientMessage((PCL_CONV_INFO)pcoi, msg, lParam);
    00816             } else {
    00817                 fNotBlocked = SpontaneousServerMessage((PSVR_CONV_INFO)pcoi, msg, lParam);
    00818             }
    00819         } else {
    00820             UserAssert(pcoi->pxiOut->hXact == (HANDLE)0 ||
    00821                     ValidateCHandle(pcoi->pxiOut->hXact, HTYPE_TRANSACTION,
    00822                     HINST_ANY)
    00823                     == (ULONG_PTR)pcoi->pxiOut);
    00824             fNotBlocked = (pcoi->pxiOut->pfnResponse)(pcoi->pxiOut, msg, lParam);
    00825         }
    00826     } else {
    00827         DumpDDEMessage(!(pcoi->state & ST_INTRA_PROCESS), msg, lParam);
    00828     }
    00829     if (!fNotBlocked) {
    00830         pcoi->state |= ST_BLOCKED;
    00831         pcoi->state &= ~ST_BLOCKNEXT;
    00832     }
    00833
    00834     pcii = pcoi->pcii;  // save this incase unlocking makes pcoi go away.
    00835
    00836     pcoi->cLocks--;
    00837     if (pcoi->cLocks == 0 && pcoi->state & ST_FREE_CONV_RES_NOW) {
    00838         FreeConversationResources(pcoi);
    00839     }
    00840
    00841     /*
    00842      * Because callbacks are capable of blocking DdeUninitialize(), we check
    00843      * before exit to see if it needs to be called.
    00844      */
    00845     if (pcii->afCmd & APPCMD_UNINIT_ASAP &&
    00846             !(pcii->flags & IIF_IN_SYNC_XACT) &&
    00847             !pcii->cInDDEMLCallback) {
    00848         DdeUninitialize(HandleToUlong(pcii->hInstClient));
    00849         return(FALSE);
    00850     }
    00851     return (fNotBlocked);
    00852 }

PCONV_INFO ProcessTerminateMsg | ( | PCONV_INFO | pcoi,
|  | HWND | hwndFrom
| ) |

Definition at line 543 of file ddemlwp.c.

References tagCONV_INFO::hwndPartner, tagCONV_INFO::next, NULL, ShutdownConversation(), tagCONV_INFO::state, and TRUE.

Referenced by DDEMLClientWndProc(), DDEMLServerWndProc(), and WaitForZombieTerminate().

    00546 {
    00547     while (pcoi != NULL && pcoi->hwndPartner != hwndFrom) {
    00548         pcoi = pcoi->next;
    00549     }
    00550     if (pcoi != NULL) {
    00551         pcoi->state |= ST_TERMINATE_RECEIVED;
    00552         ShutdownConversation(pcoi, TRUE);
    00553     }
    00554     return (pcoi);
    00555 }