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 }


Generated on Sat May 15 19:43:24 2004 for test by doxygen 1.3.7