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

connect.c File Reference

#include "precomp.h"
#include "nddeagnt.h"

Go to the source code of this file.

Classes

struct  tagINIT_ENUM

Defines

#define ValidateConvList(h)
#define ValidateAllConvLists()
#define ORPATH(x)

Typedefs

typedef tagINIT_ENUM INIT_ENUM
typedef tagINIT_ENUMPINIT_ENUM

Functions

BOOL InitiateEnumerationProc (HWND hwndTarget, PINIT_ENUM pie)
VOID DisconnectConv (PCONV_INFO pcoi)
HCONV DdeConnect (DWORD idInst, HSZ hszService, HSZ hszTopic, PCONVCONTEXT pCC)
HCONVLIST DdeConnectList (DWORD idInst, HSZ hszService, HSZ hszTopic, HCONVLIST hConvList, PCONVCONTEXT pCC)
HCONV DdeReconnect (HCONV hConv)
BOOL ValidateConnectParameters (HANDLE hInst, PCL_INSTANCE_INFO *ppcii, HSZ *phszService, HSZ hszTopic, LATOM *plaNormalSvcName, PCONVCONTEXT *ppCC, HWND *phwndTarget, HCONVLIST hConvList)
PCL_CONV_INFO ConnectConv (PCL_INSTANCE_INFO pcii, LATOM laService, LATOM laTopic, HWND hwndTarget, HWND hwndSkip, PCONVCONTEXT pCC, HCONVLIST hConvList, DWORD clst)
VOID SetCommonStateFlags (HWND hwndUs, HWND hwndThem, PWORD pwFlags)
HCONV DdeQueryNextServer (HCONVLIST hConvList, HCONV hConvPrev)
BOOL DdeDisconnect (HCONV hConv)
BOOL DdeDisconnectList (HCONVLIST hConvList)
VOID ShutdownConversation (PCONV_INFO pcoi, BOOL fMakeCallback)
VOID UnlinkConvFromOthers (PCONV_INFO pcoi, BOOL gGoingZombie)
VOID FreeConversationResources (PCONV_INFO pcoi)
BOOL WaitForZombieTerminate (HANDLE hData)

Variables

CONVCONTEXT TempConvContext
CONVCONTEXT DefConvContext


Define Documentation

#define ORPATH  ) 
 

Referenced by UnlinkConvFromOthers().

 
#define ValidateAllConvLists  ) 
 

Definition at line 103 of file connect.c.

Referenced by UnlinkConvFromOthers().

#define ValidateConvList  ) 
 

Definition at line 102 of file connect.c.

Referenced by DdeConnectList(), DdeDisconnectList(), and UnlinkConvFromOthers().


Typedef Documentation

typedef struct tagINIT_ENUM INIT_ENUM
 

typedef struct tagINIT_ENUM * PINIT_ENUM
 


Function Documentation

PCL_CONV_INFO ConnectConv PCL_INSTANCE_INFO  pcii,
LATOM  laService,
LATOM  laTopic,
HWND  hwndTarget,
HWND  hwndSkip,
PCONVCONTEXT  pCC,
HCONVLIST  hConvList,
DWORD  clst
 

Definition at line 607 of file connect.c.

References tagSERVERINFO::atomSysClass, CheckDDECritIn, CheckDDECritOut, tagCL_CONV_INFO::ci, tagINIT_ENUM::clst, CLST_CONNECTED, DWORD, EnterDDECrit, EnumWindows(), Error, tagCL_INSTANCE_INFO::flags, GATOM, GetWindowLongPtr(), gpsi, GWL_CONVSTATE, GWLP_CHINST, GWLP_PCI, GWLP_SHINST, tagINIT_ENUM::hConvList, tagCL_INSTANCE_INFO::hInstClient, tagCL_INSTANCE_INFO::hInstServer, tagINIT_ENUM::hwndClient, tagCL_INSTANCE_INFO::hwndMother, tagCL_CONV_INFO::hwndReconnect, tagINIT_ENUM::hwndSkip, ICLS_DDEMLCLIENTA, ICLS_DDEMLCLIENTW, IIF_UNICODE, IncLocalAtomCount(), InitiateEnumerationProc(), L, tagINIT_ENUM::laServiceRequested, tagCONV_INFO::laServiceRequested, tagINIT_ENUM::laTopic, LeaveDDECrit, LocalToGlobalAtom(), tagINIT_ENUM::lParam, LPVOID, MONCONV, tagCL_INSTANCE_INFO::MonitorFlags, tagCONV_INFO::next, NtUserDdeSetQualityOfService(), NtUserDestroyWindow(), NULL, SendMessage(), SetConvContext(), SetLastDDEMLError(), SetWindowLongPtr(), and TRUE.

Referenced by DdeConnect(), DdeConnectList(), and DdeReconnect().

00616 { 00617 INIT_ENUM ie; 00618 PCL_CONV_INFO pci; 00619 PCONV_INFO pcoi; 00620 GATOM gaService, gaTopic; 00621 00622 CheckDDECritIn; 00623 00624 if (hwndTarget && hwndTarget == hwndSkip) { 00625 return(NULL); 00626 } 00627 00628 LeaveDDECrit; 00629 CheckDDECritOut; 00630 00631 if (pcii->flags & IIF_UNICODE) { 00632 ie.hwndClient = CreateWindowW((LPWSTR)(gpsi->atomSysClass[ICLS_DDEMLCLIENTW]), 00633 L"", 00634 WS_CHILD, 00635 0, 0, 0, 0, 00636 pcii->hwndMother, 00637 (HMENU)0, 00638 (HANDLE)0, 00639 (LPVOID)NULL); 00640 } else { 00641 ie.hwndClient = CreateWindowA((LPSTR)(gpsi->atomSysClass[ICLS_DDEMLCLIENTA]), 00642 "", 00643 WS_CHILD, 00644 0, 0, 0, 0, 00645 pcii->hwndMother, 00646 (HMENU)0, 00647 (HANDLE)0, 00648 (LPVOID)NULL); 00649 } 00650 00651 EnterDDECrit; 00652 00653 if (ie.hwndClient == 0) { 00654 return (NULL); 00655 } 00656 00657 if (pCC != NULL) { 00658 if (!NtUserDdeSetQualityOfService(ie.hwndClient, &(pCC->qos), NULL)) { 00659 SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR); 00660 goto Error; 00661 } 00662 } 00663 /* 00664 * Note that a pci will be created and allocated for each ACK recieved. 00665 */ 00666 SetConvContext(ie.hwndClient, (LONG *)pCC); 00667 SetWindowLong(ie.hwndClient, GWL_CONVSTATE, clst); 00668 SetWindowLongPtr(ie.hwndClient, GWLP_SHINST, (LONG_PTR)pcii->hInstServer); 00669 SetWindowLongPtr(ie.hwndClient, GWLP_CHINST, (LONG_PTR)pcii->hInstClient); 00670 00671 gaService = LocalToGlobalAtom(laService); 00672 gaTopic = LocalToGlobalAtom(laTopic); 00673 ie.lParam = MAKELONG(gaService, gaTopic); 00674 if (!hwndTarget) { 00675 ie.hwndSkip = hwndSkip; 00676 ie.laServiceRequested = laService; 00677 ie.laTopic = laTopic; 00678 ie.hConvList = hConvList; 00679 ie.clst = clst; 00680 } 00681 00682 LeaveDDECrit; 00683 00684 if (hwndTarget) { 00685 SendMessage(hwndTarget, WM_DDE_INITIATE, (WPARAM)ie.hwndClient, 00686 ie.lParam); 00687 } else { 00688 /* 00689 * Send this message to the nddeagnt app first so it can start 00690 * the netdde services BEFORE we do an enumeration of windows. 00691 * This lets things work the first time. NetDDEAgent caches 00692 * service status so this is the fastest way to do this. 00693 */ 00694 HWND hwndAgent = FindWindowW(SZ_NDDEAGNT_CLASS, SZ_NDDEAGNT_TITLE); 00695 if (hwndAgent) { 00696 SendMessage(hwndAgent, 00697 WM_DDE_INITIATE, (WPARAM)ie.hwndClient, ie.lParam); 00698 } 00699 EnumWindows((WNDENUMPROC)InitiateEnumerationProc, (LPARAM)&ie); 00700 } 00701 00702 EnterDDECrit; 00703 /* 00704 * hConvList may have been destroyed during the enumeration but we are 00705 * done with it now so no need to revalidate. 00706 */ 00707 00708 #if DBG 00709 { 00710 WCHAR sz[10]; 00711 00712 if (gaService && GlobalGetAtomName(gaService, sz, 10) == 0) { 00713 RIPMSG1(RIP_ERROR, "Bad Service Atom after Initiate phase: %lX", (DWORD)gaService); 00714 } 00715 if (gaTopic && GlobalGetAtomName(gaTopic, sz, 10) == 0) { 00716 RIPMSG1(RIP_ERROR, "Bad Topic Atom after Initiate phase: %lX", (DWORD)gaTopic); 00717 } 00718 } 00719 #endif // DBG 00720 00721 GlobalDeleteAtom(gaService); 00722 GlobalDeleteAtom(gaTopic); 00723 00724 // 00725 // Get the first pci allocated when a WM_DDE_ACK was recieved. 00726 // 00727 pci = (PCL_CONV_INFO)GetWindowLongPtr(ie.hwndClient, GWLP_PCI); 00728 if (pci == NULL) { 00729 Error: 00730 LeaveDDECrit; 00731 NtUserDestroyWindow(ie.hwndClient); 00732 EnterDDECrit; 00733 return (NULL); 00734 } 00735 00736 SetWindowLong(ie.hwndClient, GWL_CONVSTATE, CLST_CONNECTED); 00737 if (hwndTarget) { 00738 /* 00739 * If hwndTarget was NULL, the enumeration proc took care of this. 00740 */ 00741 pci->hwndReconnect = hwndTarget; 00742 UserAssert(pci->ci.next == NULL); 00743 pci->ci.laServiceRequested = laService; 00744 IncLocalAtomCount(laService); // pci copy 00745 } 00746 00747 if (pcii->MonitorFlags & MF_CONV) { 00748 for (pcoi = (PCONV_INFO)pci; pcoi; pcoi = pcoi->next) { 00749 MONCONV(pcoi, TRUE); 00750 } 00751 } 00752 return (pci); 00753 }

HCONV DdeConnect DWORD  idInst,
HSZ  hszService,
HSZ  hszTopic,
PCONVCONTEXT  pCC
 

Definition at line 146 of file connect.c.

References tagCL_INSTANCE_INFO::afCmd, tagCL_CONV_INFO::ci, CLST_SINGLE_INITIALIZING, ConnectConv(), EnterDDECrit, tagCONV_INFO::hConv, tagCL_INSTANCE_INFO::hwndMother, LATOM, LATOM_FROM_HSZ, LeaveDDECrit, NULL, SetLastDDEMLError(), and ValidateConnectParameters().

00151 { 00152 PCL_INSTANCE_INFO pcii; 00153 PCL_CONV_INFO pci; 00154 HCONV hConvRet = 0; 00155 HWND hwndTarget = 0; 00156 LATOM aNormalSvcName = 0; 00157 00158 EnterDDECrit; 00159 00160 if (!ValidateConnectParameters((HANDLE)LongToHandle( idInst ), &pcii, &hszService, hszTopic, 00161 &aNormalSvcName, &pCC, &hwndTarget, 0)) { 00162 goto Exit; 00163 } 00164 pci = ConnectConv(pcii, LATOM_FROM_HSZ(hszService), LATOM_FROM_HSZ(hszTopic), 00165 hwndTarget, 00166 (pcii->afCmd & CBF_FAIL_SELFCONNECTIONS) ? pcii->hwndMother : 0, 00167 pCC, 0, CLST_SINGLE_INITIALIZING); 00168 if (pci == NULL) { 00169 SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED); 00170 goto Exit; 00171 } else { 00172 hConvRet = pci->ci.hConv; 00173 } 00174 00175 Exit: 00176 if (aNormalSvcName) { 00177 GlobalDeleteAtom(aNormalSvcName); 00178 } 00179 LeaveDDECrit; 00180 return (hConvRet); 00181 }

HCONVLIST DdeConnectList DWORD  idInst,
HSZ  hszService,
HSZ  hszTopic,
HCONVLIST  hConvList,
PCONVCONTEXT  pCC
 

Definition at line 195 of file connect.c.

References tagCL_INSTANCE_INFO::afCmd, tagCONVLIST::ahwnd, CheckDDECritOut, tagCONVLIST::chwnd, CLST_MULT_INITIALIZING, ConnectConv(), CONVLIST, CreateHandle(), DDEMLAlloc, DDEMLFree, DDEMLReAlloc, DestroyHandle(), DisconnectConv(), EnterDDECrit, FALSE, GetHandleData(), GetWindowLongPtr(), GWLP_PCI, tagCL_INSTANCE_INFO::hInstClient, HTYPE_CONVERSATION_LIST, tagCONV_INFO::hwndConv, tagCL_INSTANCE_INFO::hwndMother, InstFromHandle, LATOM, LATOM_FROM_HSZ, LeaveDDECrit, tagCONV_INFO::next, NULL, SetHandleData(), SetLastDDEMLError(), ShutdownConversation(), tagCONV_INFO::state, ValidateConnectParameters(), and ValidateConvList.

00201 { 00202 PCL_INSTANCE_INFO pcii; 00203 PCONV_INFO pcoi, pcoiNew, pcoiExisting, pcoiNext; 00204 HCONVLIST hConvListRet = 0; 00205 HWND hwndTarget = 0; 00206 LATOM aNormalSvcName = 0; 00207 PCONVLIST pcl = NULL; 00208 HCONVLIST hConvListOld; 00209 int i; 00210 00211 CheckDDECritOut; 00212 00213 EnterDDECrit; 00214 00215 if (!ValidateConnectParameters((HANDLE)LongToHandle( idInst ), &pcii, &hszService, hszTopic, 00216 &aNormalSvcName, &pCC, &hwndTarget, hConvList)) { 00217 goto Exit; 00218 } 00219 00220 ValidateConvList(hConvList); 00221 00222 hConvListOld = hConvList; 00223 pcoi = (PCONV_INFO)ConnectConv(pcii, 00224 LATOM_FROM_HSZ(hszService), 00225 LATOM_FROM_HSZ(hszTopic), 00226 hwndTarget, 00227 (pcii->afCmd & (CBF_FAIL_SELFCONNECTIONS | CBF_FAIL_CONNECTIONS)) ? 00228 pcii->hwndMother : 0, 00229 pCC, 00230 hConvListOld, 00231 CLST_MULT_INITIALIZING); 00232 00233 if (pcoi == NULL) { 00234 /* 00235 * no new connections made 00236 */ 00237 SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED); 00238 hConvListRet = hConvListOld; 00239 goto Exit; 00240 } 00241 00242 /* 00243 * allocate or reallocate the hConvList hwnd list for later addition 00244 * If we already have a valid list, reuse the handle so we don't have 00245 * to alter the preexisting pcoi->hConvList values. 00246 */ 00247 if (hConvListOld == 0) { 00248 pcl = (PCONVLIST)DDEMLAlloc(sizeof(CONVLIST)); 00249 if (pcl == NULL) { 00250 SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR); 00251 DisconnectConv(pcoi); 00252 goto Exit; 00253 } 00254 // pcl->chwnd = 0; LPTR zero inits. 00255 00256 hConvList = (HCONVLIST)CreateHandle((ULONG_PTR)pcl, 00257 HTYPE_CONVERSATION_LIST, InstFromHandle(pcii->hInstClient)); 00258 if (hConvList == 0) { 00259 DDEMLFree(pcl); 00260 SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR); 00261 DisconnectConv(pcoi); 00262 goto Exit; 00263 } 00264 } else { 00265 pcl = (PCONVLIST)GetHandleData((HANDLE)hConvList); 00266 pcl = DDEMLReAlloc(pcl, sizeof(CONVLIST) + sizeof(HWND) * pcl->chwnd); 00267 if (pcl == NULL) { 00268 SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR); 00269 hConvListRet = hConvListOld; 00270 DisconnectConv(pcoi); 00271 goto Exit; 00272 } 00273 SetHandleData((HANDLE)hConvList, (ULONG_PTR)pcl); 00274 } 00275 00276 ValidateConvList(hConvListOld); 00277 00278 if (hConvListOld) { 00279 /* 00280 * remove duplicates from new conversations 00281 * 00282 * Although we tried to prevent duplicates from happening 00283 * within the initiate enumeration code, wild initiates or 00284 * servers responding with different service names than 00285 * requested could cause duplicates. 00286 */ 00287 00288 /* For each client window... */ 00289 00290 for (i = 0; i < pcl->chwnd; i++) { 00291 00292 /* For each existing conversation in that window... */ 00293 00294 for (pcoiExisting = (PCONV_INFO) 00295 GetWindowLongPtr(pcl->ahwnd[i], GWLP_PCI); 00296 pcoi != NULL && pcoiExisting != NULL; 00297 pcoiExisting = pcoiExisting->next) { 00298 00299 if (!(pcoiExisting->state & ST_CONNECTED)) 00300 continue; 00301 00302 /* For each new conversation... */ 00303 00304 for (pcoiNew = pcoi; pcoiNew != NULL; pcoiNew = pcoiNext) { 00305 00306 pcoiNext = pcoiNew->next; 00307 00308 /* see if the new conversation duplicates the existing one */ 00309 00310 if (!(pcoiNew->state & ST_CONNECTED)) 00311 continue; 00312 00313 UserAssert(((PCL_CONV_INFO)pcoiExisting)->hwndReconnect); 00314 UserAssert(((PCL_CONV_INFO)pcoiNew)->hwndReconnect); 00315 00316 if (((PCL_CONV_INFO)pcoiExisting)->hwndReconnect == 00317 ((PCL_CONV_INFO)pcoiNew)->hwndReconnect && 00318 pcoiExisting->laTopic == pcoiNew->laTopic && 00319 pcoiExisting->laService == pcoiNew->laService) { 00320 /* 00321 * duplicate conversation - disconnection causes an unlink 00322 */ 00323 if (pcoiNew == pcoi) { 00324 /* 00325 * We are freeing up the head of the list, 00326 * Reset the head to the next guy. 00327 */ 00328 pcoi = pcoiNext; 00329 } 00330 ValidateConvList(hConvList); 00331 ShutdownConversation(pcoiNew, FALSE); 00332 ValidateConvList(hConvList); 00333 break; 00334 } 00335 } 00336 } 00337 } 00338 00339 for (pcoiExisting = pcoi; pcoiExisting != NULL; pcoiExisting = pcoiExisting->next) { 00340 /* 00341 * if these are all zombies - we DONT want to link it in! 00342 * This is possible because ShutdownConversation() leaves the critical section 00343 * and could allow responding terminates to come through. 00344 */ 00345 if (pcoiExisting->state & ST_CONNECTED) { 00346 goto FoundOne; 00347 } 00348 } 00349 pcoi = NULL; // abandon this guy - he will clean up in time. 00350 FoundOne: 00351 /* 00352 * add new pcoi (if any are left) hwnd to ConvList hwnd list. 00353 */ 00354 if (pcoi != NULL) { 00355 UserAssert(pcoi->hwndConv); 00356 pcl->ahwnd[pcl->chwnd] = pcoi->hwndConv; 00357 pcl->chwnd++; 00358 hConvListRet = hConvList; 00359 } else { 00360 hConvListRet = hConvListOld; 00361 if (!hConvListOld) { 00362 DestroyHandle((HANDLE)hConvList); 00363 } 00364 } 00365 00366 00367 } else { // no hConvListOld 00368 00369 UserAssert(pcoi->hwndConv); 00370 pcl->ahwnd[0] = pcoi->hwndConv; 00371 pcl->chwnd = 1; 00372 hConvListRet = hConvList; 00373 } 00374 00375 if (pcoi != NULL) { 00376 /* 00377 * set hConvList field for all remaining new conversations. 00378 */ 00379 UserAssert(hConvListRet); 00380 for (pcoiNew = pcoi; pcoiNew != NULL; pcoiNew = pcoiNew->next) { 00381 if (pcoiNew->state & ST_CONNECTED) { 00382 ((PCL_CONV_INFO)pcoiNew)->hConvList = hConvListRet; 00383 } 00384 } 00385 } 00386 00387 Exit: 00388 if (aNormalSvcName) { 00389 DeleteAtom(aNormalSvcName); 00390 } 00391 ValidateConvList(hConvListRet); 00392 LeaveDDECrit; 00393 return (hConvListRet); 00394 }

BOOL DdeDisconnect HCONV  hConv  ) 
 

Definition at line 1008 of file connect.c.

References BestSetLastDDEMLError(), BOOL, CheckDDECritOut, EnterDDECrit, FALSE, HINST_ANY, HTYPE_CLIENT_CONVERSATION, HTYPE_SERVER_CONVERSATION, LeaveDDECrit, NULL, PciiFromHandle(), ShutdownConversation(), tagCONV_INFO::state, TRUE, and ValidateCHandle().

Referenced by DdeUninitialize().

01010 { 01011 BOOL fRet = FALSE; 01012 PCONV_INFO pcoi; 01013 PCL_INSTANCE_INFO pcii; 01014 01015 CheckDDECritOut; 01016 EnterDDECrit; 01017 01018 pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv, 01019 HTYPE_CLIENT_CONVERSATION, HINST_ANY); 01020 if (pcoi == NULL) { 01021 pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv, 01022 HTYPE_SERVER_CONVERSATION, HINST_ANY); 01023 } 01024 if (pcoi == NULL) { 01025 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 01026 goto Exit; 01027 } 01028 pcii = PciiFromHandle((HANDLE)hConv); 01029 if (pcii == NULL) { 01030 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 01031 goto Exit; 01032 } 01033 if (pcoi->state & ST_CONNECTED) { 01034 ShutdownConversation(pcoi, FALSE); 01035 } 01036 fRet = TRUE; 01037 01038 Exit: 01039 LeaveDDECrit; 01040 return (fRet); 01041 }

BOOL DdeDisconnectList HCONVLIST  hConvList  ) 
 

Definition at line 1053 of file connect.c.

References tagCONVLIST::ahwnd, BestSetLastDDEMLError(), BOOL, CheckDDECritOut, tagCONVLIST::chwnd, DDEMLFree, DestroyHandle(), EnterDDECrit, FALSE, GetWindowLongPtr(), GWLP_PCI, HINST_ANY, HTYPE_CONVERSATION_LIST, LeaveDDECrit, tagCONV_INFO::next, NULL, PciiFromHandle(), ShutdownConversation(), tagCONV_INFO::state, TRUE, ValidateCHandle(), and ValidateConvList.

Referenced by DdeUninitialize().

01055 { 01056 BOOL fRet = FALSE; 01057 PCL_INSTANCE_INFO pcii; 01058 PCONVLIST pcl; 01059 PCONV_INFO pcoi, pcoiNext; 01060 int i; 01061 01062 CheckDDECritOut; 01063 EnterDDECrit; 01064 01065 pcl = (PCONVLIST)ValidateCHandle((HANDLE)hConvList, 01066 HTYPE_CONVERSATION_LIST, HINST_ANY); 01067 if (pcl == NULL) { 01068 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 01069 goto Exit; 01070 } 01071 ValidateConvList(hConvList); 01072 pcii = PciiFromHandle((HANDLE)hConvList); 01073 if (pcii == NULL) { 01074 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 01075 goto Exit; 01076 } 01077 01078 for(i = pcl->chwnd - 1; i >= 0; i--) { 01079 pcoi = (PCONV_INFO)GetWindowLongPtr(pcl->ahwnd[i], GWLP_PCI); 01080 while (pcoi != NULL && pcoi->state & ST_CONNECTED) { 01081 pcoiNext = pcoi->next; 01082 ShutdownConversation(pcoi, FALSE); // may unlink pcoi! 01083 pcoi = pcoiNext; 01084 } 01085 } 01086 01087 DestroyHandle((HANDLE)hConvList); 01088 DDEMLFree(pcl); 01089 fRet = TRUE; 01090 01091 Exit: 01092 LeaveDDECrit; 01093 return (fRet); 01094 }

HCONV DdeQueryNextServer HCONVLIST  hConvList,
HCONV  hConvPrev
 

Definition at line 906 of file connect.c.

References tagCONVLIST::ahwnd, BestSetLastDDEMLError(), tagCONVLIST::chwnd, tagCL_CONV_INFO::ci, EnterDDECrit, GetWindowLongPtr(), GWLP_PCI, tagCONV_INFO::hConv, tagCL_CONV_INFO::hConvList, HINST_ANY, HTYPE_CLIENT_CONVERSATION, HTYPE_CONVERSATION_LIST, HTYPE_ZOMBIE_CONVERSATION, tagCONV_INFO::hwndConv, InstFromHandle, tagCL_INSTANCE_INFO::LastError, LeaveDDECrit, tagCONV_INFO::next, NULL, PciiFromHandle(), SetLastDDEMLError(), TypeFromHandle, and ValidateCHandle().

00909 { 00910 HCONV hConvRet = 0; 00911 PCONVLIST pcl; 00912 HWND *phwnd; 00913 int i; 00914 PCL_CONV_INFO pci; 00915 PCL_INSTANCE_INFO pcii; 00916 00917 EnterDDECrit; 00918 00919 pcl = (PCONVLIST)ValidateCHandle((HANDLE)hConvList, 00920 HTYPE_CONVERSATION_LIST, HINST_ANY); 00921 if (pcl == NULL) { 00922 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 00923 goto Exit; 00924 } 00925 if (!pcl->chwnd) { // empty list 00926 goto Exit; 00927 } 00928 pcii = PciiFromHandle((HANDLE)hConvList); 00929 if (pcii == NULL) { 00930 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 00931 goto Exit; 00932 } 00933 00934 pcii->LastError = DMLERR_NO_ERROR; 00935 00936 do { 00937 00938 hConvRet = 0; 00939 00940 if (hConvPrev == 0) { 00941 pci = (PCL_CONV_INFO)GetWindowLongPtr(pcl->ahwnd[0], GWLP_PCI); 00942 if (pci == NULL) { 00943 goto Exit; // Must have all conversations zombied. 00944 } 00945 hConvPrev = hConvRet = pci->ci.hConv; 00946 continue; 00947 } 00948 00949 pci = (PCL_CONV_INFO)ValidateCHandle((HANDLE)hConvPrev, 00950 HTYPE_CLIENT_CONVERSATION, InstFromHandle(hConvList)); 00951 if (pci == NULL) { 00952 pci = (PCL_CONV_INFO)ValidateCHandle((HANDLE)hConvPrev, 00953 HTYPE_ZOMBIE_CONVERSATION, InstFromHandle(hConvList)); 00954 if (pci == NULL) { 00955 SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); 00956 break; 00957 } else { 00958 goto ZombieSkip; 00959 } 00960 } 00961 00962 if (pci->hConvList != hConvList) { 00963 SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); 00964 break; 00965 } 00966 00967 ZombieSkip: 00968 00969 if (pci->ci.next == NULL) { 00970 00971 /* 00972 * end of list for this window, go to next window 00973 */ 00974 for (phwnd = pcl->ahwnd, i = 0; (i + 1) < pcl->chwnd; i++) { 00975 if (phwnd[i] == pci->ci.hwndConv) { 00976 pci = (PCL_CONV_INFO)GetWindowLongPtr(phwnd[i + 1], GWLP_PCI); 00977 if (pci == NULL) { 00978 break; 00979 } 00980 hConvPrev = hConvRet = pci->ci.hConv; 00981 break; 00982 } 00983 } 00984 } else { 00985 00986 hConvPrev = hConvRet = pci->ci.next->hConv; // next conv for this window. 00987 } 00988 00989 } while (hConvRet && TypeFromHandle(hConvRet) == HTYPE_ZOMBIE_CONVERSATION); 00990 Exit: 00991 LeaveDDECrit; 00992 return (hConvRet); 00993 }

HCONV DdeReconnect HCONV  hConv  ) 
 

Definition at line 409 of file connect.c.

References tagCONV_INFO::aLinks, BestSetLastDDEMLError(), tagCL_CONV_INFO::ci, tagCONV_INFO::cLinks, CLST_SINGLE_INITIALIZING, ClStartAdvise(), ConnectConv(), DDEMLAlloc, DDEMLFree, EnterDDECrit, tagXACT_INFO::flags, tagXACT_INFO::gaItem, GetConvContext(), tagCONV_INFO::hConv, HINST_ANY, HTYPE_CLIENT_CONVERSATION, tagCONV_INFO::hwndConv, tagCL_CONV_INFO::hwndReconnect, tagADVISE_LINK::laItem, tagCONV_INFO::laService, tagCONV_INFO::laTopic, LeaveDDECrit, LocalToGlobalAtom(), NULL, PADVISE_LINK, PciiFromHandle(), tagXACT_INFO::pcoi, SetLastDDEMLError(), tagCONV_INFO::state, ValidateCHandle(), tagADVISE_LINK::wFmt, tagXACT_INFO::wFmt, tagADVISE_LINK::wType, tagXACT_INFO::wType, XACT_INFO, and XIF_ABANDONED.

00411 { 00412 PCL_INSTANCE_INFO pcii; 00413 PCL_CONV_INFO pci, pciNew; 00414 HCONV hConvRet = 0; 00415 CONVCONTEXT cc; 00416 00417 EnterDDECrit; 00418 00419 pcii = PciiFromHandle((HANDLE)hConv); 00420 if (pcii == NULL) { 00421 BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); 00422 goto Exit; 00423 } 00424 pci = (PCL_CONV_INFO)ValidateCHandle((HANDLE)hConv, 00425 HTYPE_CLIENT_CONVERSATION, HINST_ANY); 00426 if (pci == NULL) { 00427 SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); 00428 goto Exit; 00429 } 00430 00431 if (pci->ci.state & ST_CONNECTED) { 00432 goto Exit; 00433 } 00434 00435 GetConvContext(pci->ci.hwndConv, (LONG *)&cc); 00436 pciNew = ConnectConv(pcii, pci->ci.laService, pci->ci.laTopic, 00437 pci->hwndReconnect, 0, &cc, 0, CLST_SINGLE_INITIALIZING); 00438 if (pciNew == NULL) { 00439 SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED); 00440 goto Exit; 00441 } else { 00442 hConvRet = pciNew->ci.hConv; 00443 if (pci->ci.cLinks) { 00444 PXACT_INFO pxi; 00445 int iLink; 00446 PADVISE_LINK paLink; 00447 00448 /* 00449 * reestablish advise links 00450 */ 00451 00452 for (paLink = pci->ci.aLinks, iLink = pci->ci.cLinks; 00453 iLink; paLink++, iLink--) { 00454 00455 pxi = (PXACT_INFO)DDEMLAlloc(sizeof(XACT_INFO)); 00456 if (pxi == NULL) { 00457 break; // abort relinking 00458 } 00459 pxi->pcoi = (PCONV_INFO)pciNew; 00460 pxi->gaItem = LocalToGlobalAtom(paLink->laItem); // pxi copy 00461 pxi->wFmt = paLink->wFmt; 00462 pxi->wType = (WORD)((paLink->wType >> 12) | XTYP_ADVSTART); 00463 if (ClStartAdvise(pxi)) { 00464 pxi->flags |= XIF_ABANDONED; 00465 } else { 00466 GlobalDeleteAtom(pxi->gaItem); 00467 DDEMLFree(pxi); 00468 } 00469 } 00470 } 00471 } 00472 00473 Exit: 00474 LeaveDDECrit; 00475 return (hConvRet); 00476 }

VOID DisconnectConv PCONV_INFO  pcoi  ) 
 

Definition at line 759 of file connect.c.

References FALSE, tagCONV_INFO::next, ShutdownConversation(), and VOID().

Referenced by DdeConnectList().

00761 { 00762 PCONV_INFO pcoiNext; 00763 00764 for (; pcoi; pcoi = pcoiNext) { 00765 pcoiNext = pcoi->next; 00766 ShutdownConversation(pcoi, FALSE); 00767 } 00768 }

VOID FreeConversationResources PCONV_INFO  pcoi  ) 
 

Definition at line 1354 of file connect.c.

References tagCONV_INFO::aLinks, CheckDDECritIn, tagCONV_INFO::cLinks, tagCONV_INFO::cLocks, CreateHandle(), DDEMLFree, DeleteLinkCount(), DestroyHandle(), tagCONV_INFO::dmqIn, tagCONV_INFO::dmqOut, DumpDDEMessage(), FALSE, tagXACT_INFO::flags, tagCONV_INFO::hConv, HTYPE_ZOMBIE_CONVERSATION, tagCONV_INFO::hwndConv, tagCONV_INFO::hwndPartner, InstFromHandle, tagADVISE_LINK::laItem, tagCONV_INFO::laService, tagCONV_INFO::laServiceRequested, tagCONV_INFO::laTopic, LocalToGlobalAtom(), tagDDE_MESSAGE_QUEUE::lParam, MONLINK, tagDDE_MESSAGE_QUEUE::msg, tagXACT_INFO::next, tagDDE_MESSAGE_QUEUE::next, NULL, tagCONV_INFO::pcii, tagXACT_INFO::pfnResponse, tagADVISE_LINK::pLinkCount, PostMessage(), tagCONV_INFO::pxiOut, tagCONV_INFO::state, TID_TIMEOUT, TRUE, UnlinkConvFromOthers(), VOID(), tagADVISE_LINK::wFmt, tagADVISE_LINK::wType, and XIF_SYNCHRONOUS.

Referenced by DdeClientTransaction(), DdeEnableCallback(), DdePostAdvise(), EnableEnumProc(), ProcessAsyncDDEMsg(), ProcessSyncDDEMessage(), and ShutdownConversation().

01356 { 01357 PADVISE_LINK paLink; 01358 PDDE_MESSAGE_QUEUE pdmq; 01359 PXACT_INFO pxi; 01360 01361 CheckDDECritIn; 01362 01363 /* 01364 * Don't free resources on locked conversations. 01365 */ 01366 if (pcoi->cLocks > 0) { 01367 pcoi->state |= ST_FREE_CONV_RES_NOW; 01368 return; 01369 } 01370 01371 /* 01372 * Don't free resources if a synchronous transaction is in effect! 01373 */ 01374 pxi = pcoi->pxiOut; 01375 while (pxi != NULL) { 01376 if (pxi->flags & XIF_SYNCHRONOUS) { 01377 /* 01378 * This conversation is in a synchronous transaction. 01379 * Shutdown the modal loop FIRST, then call this when 01380 * the loop exits. 01381 */ 01382 PostMessage(pcoi->hwndConv, WM_TIMER, TID_TIMEOUT, 0); 01383 pcoi->state |= ST_FREE_CONV_RES_NOW; 01384 return; 01385 } 01386 pxi = pxi->next; 01387 } 01388 01389 /* 01390 * If this is an Intra-Process conversation that hasn't yet received 01391 * a terminate message, make it a zombie. We will call this routine 01392 * again once the terminate arrives or when WaitForZombieTerminate() has 01393 * timed out waiting. 01394 */ 01395 if (pcoi->state & ST_INTRA_PROCESS && !(pcoi->state & ST_TERMINATE_RECEIVED)) { 01396 DestroyHandle((HANDLE)pcoi->hConv); 01397 pcoi->hConv = (HCONV)CreateHandle((ULONG_PTR)pcoi, HTYPE_ZOMBIE_CONVERSATION, 01398 InstFromHandle(pcoi->hConv)); 01399 UnlinkConvFromOthers(pcoi, TRUE); 01400 return; 01401 } 01402 01403 /* 01404 * remove any transactions left in progress 01405 */ 01406 while (pcoi->pxiOut != NULL) { 01407 (pcoi->pxiOut->pfnResponse)(pcoi->pxiOut, 0, 0); 01408 } 01409 01410 /* 01411 * Throw away any incoming queued DDE messages. 01412 */ 01413 while (pcoi->dmqOut != NULL) { 01414 01415 pdmq = pcoi->dmqOut; 01416 DumpDDEMessage(!(pcoi->state & ST_INTRA_PROCESS), pdmq->msg, pdmq->lParam); 01417 pcoi->dmqOut = pcoi->dmqOut->next; 01418 if (pcoi->dmqOut == NULL) { 01419 pcoi->dmqIn = NULL; 01420 } 01421 DDEMLFree(pdmq); 01422 } 01423 01424 // 01425 // Remove all link info 01426 // 01427 paLink = pcoi->aLinks; 01428 while (pcoi->cLinks) { 01429 if (pcoi->state & ST_CLIENT) { 01430 MONLINK(pcoi->pcii, FALSE, paLink->wType & XTYPF_NODATA, 01431 pcoi->laService, pcoi->laTopic, 01432 LocalToGlobalAtom(paLink->laItem), 01433 paLink->wFmt, FALSE, 01434 (HCONV)pcoi->hwndPartner, (HCONV)pcoi->hwndConv); 01435 } else { 01436 MONLINK(pcoi->pcii, FALSE, paLink->wType & XTYPF_NODATA, 01437 pcoi->laService, pcoi->laTopic, 01438 LocalToGlobalAtom(paLink->laItem), 01439 paLink->wFmt, TRUE, 01440 (HCONV)pcoi->hwndConv, (HCONV)pcoi->hwndPartner); 01441 } 01442 if (!(pcoi->state & ST_CLIENT)) { 01443 DeleteLinkCount(pcoi->pcii, paLink->pLinkCount); 01444 } 01445 DeleteAtom(paLink->laItem); // link structure copy 01446 paLink++; 01447 pcoi->cLinks--; 01448 } 01449 if (pcoi->aLinks) { 01450 DDEMLFree(pcoi->aLinks); 01451 } 01452 01453 // 01454 // free atoms associated with this conv 01455 // 01456 DeleteAtom(pcoi->laService); 01457 DeleteAtom(pcoi->laTopic); 01458 if (pcoi->laServiceRequested) { 01459 DeleteAtom(pcoi->laServiceRequested); 01460 } 01461 01462 UnlinkConvFromOthers(pcoi, FALSE); 01463 01464 /* 01465 * invalidate app's conversation handle 01466 */ 01467 DestroyHandle((HANDLE)pcoi->hConv); 01468 01469 DDEMLFree(pcoi); 01470 }

BOOL InitiateEnumerationProc HWND  hwndTarget,
PINIT_ENUM  pie
 

Definition at line 784 of file connect.c.

References tagCONVLIST::ahwnd, BOOL, CheckDDECritOut, tagCONVLIST::chwnd, tagCL_CONV_INFO::ci, tagINIT_ENUM::clst, CLST_MULT_INITIALIZING, CLST_SINGLE_INITIALIZING, EnterDDECrit, GetWindowLongPtr(), GWLP_PCI, tagINIT_ENUM::hConvList, HINST_ANY, HTYPE_CONVERSATION_LIST, tagINIT_ENUM::hwndClient, tagCL_CONV_INFO::hwndReconnect, tagINIT_ENUM::hwndSkip, IncLocalAtomCount(), tagCONV_INFO::laService, tagCONV_INFO::laServiceRequested, tagINIT_ENUM::laServiceRequested, tagCONV_INFO::laTopic, tagINIT_ENUM::laTopic, LeaveDDECrit, tagINIT_ENUM::lParam, tagCONV_INFO::next, NULL, SendMessage(), tagCONV_INFO::state, TRUE, and ValidateCHandle().

Referenced by ConnectConv().

00787 { 00788 PCL_CONV_INFO pci; 00789 00790 CheckDDECritOut; 00791 00792 if (hwndTarget == pie->hwndSkip) { 00793 return (TRUE); 00794 } 00795 00796 if (pie->hConvList && pie->laTopic && pie->laServiceRequested) { 00797 /* 00798 * Head off duplicates BEFORE we send the WM_DDE_INITIATE messages! 00799 */ 00800 PCONVLIST pcl; 00801 PCONV_INFO pcoiExisting; 00802 int i; 00803 00804 EnterDDECrit; 00805 /* 00806 * We revalidate hConvList here because we left the critical section. 00807 */ 00808 pcl = (PCONVLIST)ValidateCHandle((HANDLE)pie->hConvList, 00809 HTYPE_CONVERSATION_LIST, HINST_ANY); 00810 if (pcl != NULL) { 00811 for (i = 0; i < pcl->chwnd; i++) { 00812 for (pcoiExisting = (PCONV_INFO)GetWindowLongPtr(pcl->ahwnd[i], GWLP_PCI); 00813 pcoiExisting != NULL; 00814 pcoiExisting = pcoiExisting->next) { 00815 if (pcoiExisting->state & ST_CONNECTED && 00816 ((PCL_CONV_INFO)pcoiExisting)->hwndReconnect == hwndTarget && 00817 pcoiExisting->laTopic == pie->laTopic && 00818 pcoiExisting->laService == pie->laServiceRequested) { 00819 LeaveDDECrit; 00820 return(TRUE); 00821 } 00822 } 00823 } 00824 } 00825 LeaveDDECrit; 00826 } 00827 00828 CheckDDECritOut; 00829 00830 SendMessage(hwndTarget, WM_DDE_INITIATE, (WPARAM)pie->hwndClient, 00831 pie->lParam); 00832 00833 EnterDDECrit; 00834 00835 // 00836 // During the initiate process, any acks received cause more pci's 00837 // to become linked together under the same hwndClient. Once 00838 // the SendMessage() returns, we set the parts of the new pci's 00839 // that hold initiate context information. 00840 // 00841 pci = (PCL_CONV_INFO)GetWindowLongPtr(pie->hwndClient, GWLP_PCI); 00842 if (pci == NULL) { 00843 LeaveDDECrit; 00844 return (TRUE); 00845 } 00846 00847 while (pci != NULL) { 00848 if (pci->hwndReconnect == 0) { // this one needs updating 00849 pci->hwndReconnect = hwndTarget; 00850 if (pie->laServiceRequested) { 00851 pci->ci.laServiceRequested = pie->laServiceRequested; 00852 IncLocalAtomCount(pie->laServiceRequested); // pci copy 00853 } 00854 } 00855 if (pie->clst == CLST_SINGLE_INITIALIZING) { 00856 break; 00857 } 00858 pci = (PCL_CONV_INFO)pci->ci.next; 00859 } 00860 LeaveDDECrit; 00861 return (pie->clst == CLST_MULT_INITIALIZING); 00862 }

VOID SetCommonStateFlags HWND  hwndUs,
HWND  hwndThem,
PWORD  pwFlags
 

Definition at line 876 of file connect.c.

References DWORD, GetWindowThreadProcessId(), IsWindowUnicode(), and VOID().

Referenced by DDEMLClientWndProc(), and ProcessDDEMLInitiate().

00880 { 00881 DWORD pidUs, pidThem; 00882 00883 GetWindowThreadProcessId(hwndUs, &pidUs); 00884 GetWindowThreadProcessId(hwndThem, &pidThem); 00885 if (pidUs == pidThem) { 00886 *pwFlags |= ST_INTRA_PROCESS; 00887 } 00888 00889 if (IsWindowUnicode(hwndUs) && IsWindowUnicode(hwndThem)) { 00890 *pwFlags |= ST_UNICODE_EXECUTE; 00891 } 00892 }

VOID ShutdownConversation PCONV_INFO  pcoi,
BOOL  fMakeCallback
 

Definition at line 1109 of file connect.c.

References tagCL_INSTANCE_INFO::afCmd, CheckDDECritIn, DoCallback(), FALSE, FreeConversationResources(), tagCONV_INFO::hConv, tagCONV_INFO::hwndConv, tagCONV_INFO::hwndPartner, IsWindow(), L, MONCONV, tagCONV_INFO::pcii, PostMessage(), tagCONV_INFO::state, and VOID().

Referenced by DdeConnectList(), DdeDisconnect(), DdeDisconnectList(), DisconnectConv(), ProcessTerminateMsg(), and SpontaneousClientMessage().

01112 { 01113 CheckDDECritIn; 01114 01115 if (pcoi->state & ST_CONNECTED) { 01116 pcoi->state &= ~ST_CONNECTED; 01117 01118 if (IsWindow(pcoi->hwndPartner)) { 01119 PostMessage(pcoi->hwndPartner, WM_DDE_TERMINATE, 01120 (WPARAM)pcoi->hwndConv, 0); 01121 } 01122 if (fMakeCallback && !(pcoi->pcii->afCmd & CBF_SKIP_DISCONNECTS)) { 01123 DoCallback(pcoi->pcii, (WORD)XTYP_DISCONNECT, 0, pcoi->hConv, 01124 0, 0, 0, 0, (pcoi->state & ST_ISSELF) ? 1L : 0L); 01125 } 01126 MONCONV(pcoi, FALSE); 01127 } 01128 01129 FreeConversationResources(pcoi); 01130 }

VOID UnlinkConvFromOthers PCONV_INFO  pcoi,
BOOL  gGoingZombie
 

Definition at line 1153 of file connect.c.

References tagCONVLIST::ahwnd, tagCL_INSTANCE_INFO::aServerLookup, BOOL, CheckDDECritIn, tagCONVLIST::chwnd, tagCL_INSTANCE_INFO::cServerLookupAlloc, DDEMLFree, DWORD, EnterDDECrit, FALSE, GetAppCompatFlags2(), GetHandleData(), GetWindowLongPtr(), GWLP_PCI, tagCONV_INFO::hConv, HTYPE_ZOMBIE_CONVERSATION, tagCONV_INFO::hwndConv, tagSERVER_LOOKUP::hwndServer, tagSERVER_LOOKUP::laService, tagSERVER_LOOKUP::laTopic, LeaveDDECrit, tagCONV_INFO::next, NtUserDestroyWindow(), NULL, ORPATH, path, tagCONV_INFO::pcii, PCL_CONV_INFO, SetWindowLongPtr(), tagCONV_INFO::state, TRUE, TypeFromHandle, ValidateAllConvLists, ValidateConvList, and VOID().

Referenced by FreeConversationResources().

01156 { 01157 PCONV_INFO pcoiPrev, pcoiFirst, pcoiNow; 01158 PCONVLIST pcl; 01159 int i, cActiveInList = 0; 01160 #ifdef TESTING 01161 DWORD path = 0; 01162 #define ORPATH(x) path |= x; 01163 #else 01164 #define ORPATH(x) 01165 #endif // TESTING 01166 01167 CheckDDECritIn; 01168 01169 /* 01170 * Scan pcoi linked list to get key pointers. 01171 */ 01172 pcoiPrev = NULL; 01173 pcoiFirst = pcoiNow = (PCONV_INFO)GetWindowLongPtr(pcoi->hwndConv, GWLP_PCI); 01174 01175 #ifdef TESTING 01176 /* 01177 * verify that pcoi is in the conv list for this window. 01178 */ 01179 while (pcoiNow != NULL) { 01180 if (pcoiNow == pcoi) { 01181 goto FoundIt; 01182 } 01183 pcoiNow = pcoiNow->next; 01184 } 01185 DebugBreak(); 01186 FoundIt: 01187 pcoiNow = pcoiFirst; 01188 #endif // TESTING 01189 01190 UserAssert(pcoiFirst); 01191 while (pcoiNow != NULL) { 01192 if (TypeFromHandle(pcoiNow->hConv) != HTYPE_ZOMBIE_CONVERSATION) { 01193 ORPATH(1); 01194 cActiveInList++; 01195 } 01196 if (pcoiNow->next == pcoi) { 01197 pcoiPrev = pcoiNow; 01198 } 01199 pcoiNow = pcoiNow->next; 01200 } 01201 01202 ValidateAllConvLists(); 01203 01204 /* 01205 * Unlink conversation unless its going Zombie. 01206 */ 01207 if (!gGoingZombie) { 01208 ORPATH(2); 01209 if (TypeFromHandle(pcoi->hConv) != HTYPE_ZOMBIE_CONVERSATION) { 01210 ORPATH(4); 01211 cActiveInList--; 01212 } 01213 01214 if (pcoiPrev == NULL) { 01215 ORPATH(8); 01216 pcoiFirst = pcoi->next; 01217 SetWindowLongPtr(pcoi->hwndConv, GWLP_PCI, (LONG_PTR)pcoiFirst); 01218 } else { 01219 pcoiPrev->next = pcoi->next; 01220 } 01221 } 01222 01223 UserAssert(pcoiFirst != NULL || !cActiveInList); 01224 01225 if (cActiveInList == 0) { 01226 ORPATH(0x10); 01227 if (pcoi->state & ST_CLIENT) { 01228 ORPATH(0x20); 01229 if (((PCL_CONV_INFO)pcoi)->hConvList) { 01230 /* 01231 * Remove pcoi's hwnd from its hConvList. 01232 */ 01233 pcl = (PCONVLIST)GetHandleData((HANDLE)((PCL_CONV_INFO)pcoi)->hConvList); 01234 for (i = 0; i < pcl->chwnd; i++) { 01235 if (pcl->ahwnd[i] == pcoi->hwndConv) { 01236 ORPATH(0x40); 01237 pcl->chwnd--; 01238 UserAssert(pcl->ahwnd[pcl->chwnd]); 01239 pcl->ahwnd[i] = pcl->ahwnd[pcl->chwnd]; 01240 ValidateConvList(((PCL_CONV_INFO)pcoi)->hConvList); 01241 break; 01242 } 01243 } 01244 ORPATH(0x80); 01245 } 01246 } else { // SERVER 01247 /* 01248 * remove server window from the service/topic lookup table. 01249 */ 01250 ORPATH(0x100); 01251 for (i = 0; i < pcoi->pcii->cServerLookupAlloc; i++) { 01252 if (pcoi->pcii->aServerLookup[i].hwndServer == pcoi->hwndConv) { 01253 ORPATH(0x200); 01254 01255 /* 01256 * Check for appcompat hack 01257 */ 01258 if (GetAppCompatFlags2(VERMAX) & GACF2_DDE) { 01259 DeleteAtom(pcoi->pcii->aServerLookup[i].laService); // delete laService 01260 DeleteAtom(pcoi->pcii->aServerLookup[i].laTopic); // delete laTopic 01261 } 01262 01263 if (--(pcoi->pcii->cServerLookupAlloc)) { 01264 ORPATH(0x400); 01265 pcoi->pcii->aServerLookup[i] = 01266 pcoi->pcii->aServerLookup[pcoi->pcii->cServerLookupAlloc]; 01267 } else { 01268 DDEMLFree(pcoi->pcii->aServerLookup); 01269 pcoi->pcii->aServerLookup = NULL; 01270 } 01271 break; 01272 } 01273 } 01274 } 01275 } 01276 #ifdef TESTING 01277 else { 01278 /* 01279 * make sure at this point we have at least one non-zombie 01280 */ 01281 pcoiNow = pcoiFirst; 01282 while (pcoiNow != NULL) { 01283 if (TypeFromHandle(pcoiNow->hConv) != HTYPE_ZOMBIE_CONVERSATION) { 01284 goto Out; 01285 } 01286 pcoiNow = pcoiNow->next; 01287 } 01288 DebugBreak(); 01289 Out: 01290 ; 01291 } 01292 #endif // TESTING 01293 01294 ValidateAllConvLists(); 01295 ORPATH(0x800); 01296 01297 /* 01298 * In any case remove hConvList references from client conversation. 01299 */ 01300 if (pcoi->state & ST_CLIENT) { 01301 #ifdef TESTING 01302 /* 01303 * Verify that the hConvList that is being removed, doesn't reference 01304 * this window. 01305 */ 01306 if (((PCL_CONV_INFO)pcoi)->hConvList && !cActiveInList) { 01307 BOOL fFound = FALSE; 01308 01309 pcl = (PCONVLIST)GetHandleData((HANDLE)((PCL_CONV_INFO)pcoi)->hConvList); 01310 for (i = 0; i < pcl->chwnd; i++) { 01311 if (pcl->ahwnd[i] == pcoi->hwndConv) { 01312 fFound = TRUE; 01313 break; 01314 } 01315 } 01316 UserAssert(!fFound); 01317 } 01318 #endif // TESTING 01319 ((PCL_CONV_INFO)pcoi)->hConvList = 0; 01320 pcoi->state &= ~ST_INLIST; 01321 } 01322 01323 /* 01324 * last one out turns out the lights. 01325 */ 01326 if (pcoiFirst == NULL) { 01327 /* 01328 * If the pcoi list is empty, this window can go away. 01329 */ 01330 LeaveDDECrit; 01331 NtUserDestroyWindow(pcoi->hwndConv); 01332 EnterDDECrit; 01333 } 01334 }

BOOL ValidateConnectParameters HANDLE  hInst,
PCL_INSTANCE_INFO ppcii,
HSZ *  phszService,
HSZ  hszTopic,
LATOM plaNormalSvcName,
PCONVCONTEXT *  ppCC,
HWND *  phwndTarget,
HCONVLIST  hConvList
 

Definition at line 491 of file connect.c.

References BOOL, DefConvContext, DWORD, FALSE, hInst, HSZT_INST_SPECIFIC, HSZT_INVALID, HTYPE_CONVERSATION_LIST, IIF_UNICODE, InstFromHandle, LATOM_FROM_HSZ, NORMAL_HSZ_FROM_LATOM, NULL, ParseInstSpecificAtom(), SetLastDDEMLError(), TempConvContext, TRUE, ValidateCHandle(), ValidateHSZ(), and ValidateInstance().

Referenced by DdeConnect(), and DdeConnectList().

00500 { 00501 DWORD hszType; 00502 BOOL fError = FALSE; 00503 00504 *ppcii = ValidateInstance(hInst); 00505 if (*ppcii == NULL) { 00506 return (FALSE); 00507 } 00508 hszType = ValidateHSZ(*phszService); 00509 if (hszType == HSZT_INVALID || ValidateHSZ(hszTopic) == HSZT_INVALID) { 00510 SetLastDDEMLError(*ppcii, DMLERR_INVALIDPARAMETER); 00511 return (FALSE); 00512 } 00513 if (hszType == HSZT_INST_SPECIFIC) { 00514 *phwndTarget = ParseInstSpecificAtom(LATOM_FROM_HSZ(*phszService), 00515 plaNormalSvcName); 00516 if (*plaNormalSvcName == 0) { 00517 SetLastDDEMLError(*ppcii, DMLERR_SYS_ERROR); 00518 return (FALSE); 00519 } 00520 *phszService = NORMAL_HSZ_FROM_LATOM(*plaNormalSvcName); 00521 } 00522 if (*ppCC == NULL) { 00523 *ppCC = &DefConvContext; 00524 if ((*ppcii)->flags & IIF_UNICODE) { 00525 (*ppCC)->iCodePage = CP_WINUNICODE; 00526 } else { 00527 (*ppCC)->iCodePage = CP_WINANSI; 00528 } 00529 } else try { 00530 if ((*ppCC)->cb > sizeof(CONVCONTEXT)) { 00531 SetLastDDEMLError(*ppcii, DMLERR_INVALIDPARAMETER); 00532 fError = TRUE; 00533 } else if ((*ppCC)->cb < sizeof(CONVCONTEXT)) { 00534 TempConvContext = DefConvContext; 00535 /* 00536 * we can use this static temp because we are synchronized. 00537 */ 00538 RtlCopyMemory(&TempConvContext, *ppCC, (*ppCC)->cb); 00539 *ppCC = &TempConvContext; 00540 } 00541 } except(W32ExceptionHandler(FALSE, RIP_WARNING)) { 00542 SetLastDDEMLError(*ppcii, DMLERR_INVALIDPARAMETER); 00543 fError = TRUE; 00544 } 00545 if (fError) { 00546 return(FALSE); 00547 } 00548 if (hConvList != 0 && 00549 !ValidateCHandle((HANDLE)hConvList, HTYPE_CONVERSATION_LIST, 00550 (DWORD)InstFromHandle((*ppcii)->hInstClient))) { 00551 return (FALSE); 00552 } 00553 return (TRUE); 00554 }

BOOL WaitForZombieTerminate HANDLE  hData  ) 
 

Definition at line 1474 of file connect.c.

References BOOL, CheckDDECritOut, DispatchMessage(), DWORD, EnterDDECrit, FALSE, HTYPE_ZOMBIE_CONVERSATION, tagCONV_INFO::hwndConv, tagCONV_INFO::hwndPartner, InstFromHandle, LeaveDDECrit, msg, MsgWaitForMultipleObjectsEx(), NULL, PeekMessage(), ProcessTerminateMsg(), tagCONV_INFO::state, TRUE, and ValidateCHandle().

Referenced by DdeUninitialize().

01476 { 01477 PCONV_INFO pcoi; 01478 MSG msg; 01479 HWND hwnd; 01480 BOOL fTerminated; 01481 DWORD fRet = 0; 01482 01483 CheckDDECritOut; 01484 EnterDDECrit; 01485 01486 fTerminated = FALSE; 01487 while ((pcoi = (PCONV_INFO)ValidateCHandle(hData, 01488 HTYPE_ZOMBIE_CONVERSATION, InstFromHandle(hData))) != NULL && 01489 !(pcoi->state & ST_TERMINATE_RECEIVED)) { 01490 hwnd = pcoi->hwndConv; 01491 LeaveDDECrit; 01492 while (PeekMessage(&msg, hwnd, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE)) { 01493 DispatchMessage(&msg); 01494 if (msg.message == WM_DDE_TERMINATE) { 01495 fTerminated = TRUE; 01496 } 01497 } 01498 if (!fTerminated) { 01499 fRet = MsgWaitForMultipleObjectsEx(0, NULL, 100, QS_POSTMESSAGE, 0); 01500 if (fRet == 0xFFFFFFFF) { 01501 RIPMSG0(RIP_WARNING, "WaitForZombieTerminate: I give up - faking terminate."); 01502 ProcessTerminateMsg(pcoi, pcoi->hwndPartner); 01503 EnterDDECrit; 01504 return(FALSE); 01505 } 01506 } 01507 EnterDDECrit; 01508 } 01509 LeaveDDECrit; 01510 return(TRUE); 01511 }


Variable Documentation

CONVCONTEXT DefConvContext
 

Initial value:

{ sizeof(CONVCONTEXT), 0, 0, CP_WINANSI, 0L, 0L, { sizeof(SECURITY_QUALITY_OF_SERVICE), SecurityImpersonation, SECURITY_STATIC_TRACKING, TRUE } }

Definition at line 107 of file connect.c.

Referenced by DdeQueryConvInfo(), and ValidateConnectParameters().

CONVCONTEXT TempConvContext
 

Definition at line 106 of file connect.c.

Referenced by ValidateConnectParameters().


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