/***************************************************************************\ * DdeImpersonateClient() * * Description: * Does security impersonation for DDEML server apps. * This API should only be called with server side hConvs; * * History: * 5-4-92 sanfords Created. \***************************************************************************/ BOOL DdeImpersonateClient( HCONV hConv) { PCONV_INFO pcoi; PCL_INSTANCE_INFO pcii; BOOL fRet = FALSE; EnterDDECrit; pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv, HTYPE_SERVER_CONVERSATION, HINST_ANY); if (pcoi == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } pcii = PciiFromHandle((HANDLE)hConv); if (pcii == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } fRet = NtUserImpersonateDdeClientWindow(pcoi->hwndPartner, pcoi->hwndConv); Exit: LeaveDDECrit; return (fRet); }
/***************************************************************************\ * DdeDisconnect (DDEML API) * * Description: * Terminates a conversation. * * History: * 11-12-91 sanfords Created. \***************************************************************************/ BOOL DdeDisconnect( HCONV hConv) { BOOL fRet = FALSE; PCONV_INFO pcoi; PCL_INSTANCE_INFO pcii; CheckDDECritOut; EnterDDECrit; pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv, HTYPE_CLIENT_CONVERSATION, HINST_ANY); if (pcoi == NULL) { pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv, HTYPE_SERVER_CONVERSATION, HINST_ANY); } if (pcoi == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } pcii = PciiFromHandle((HANDLE)hConv); if (pcii == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } if (pcoi->state & ST_CONNECTED) { ShutdownConversation(pcoi, FALSE); } fRet = TRUE; Exit: LeaveDDECrit; return (fRet); }
/***************************************************************************\ * DdeDisconnectList (DDEML API) * * Description: * Terminates all conversations in a conversation list and frees the list. * * History: * 11-12-91 sanfords Created. \***************************************************************************/ BOOL DdeDisconnectList( HCONVLIST hConvList) { BOOL fRet = FALSE; PCL_INSTANCE_INFO pcii; PCONVLIST pcl; PCONV_INFO pcoi, pcoiNext; int i; CheckDDECritOut; EnterDDECrit; pcl = (PCONVLIST)ValidateCHandle((HANDLE)hConvList, HTYPE_CONVERSATION_LIST, HINST_ANY); if (pcl == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } ValidateConvList(hConvList); pcii = PciiFromHandle((HANDLE)hConvList); if (pcii == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } for(i = pcl->chwnd - 1; i >= 0; i--) { pcoi = (PCONV_INFO)GetWindowLong(pcl->ahwnd[i], GWL_PCI); while (pcoi != NULL && pcoi->state & ST_CONNECTED) { pcoiNext = pcoi->next; ShutdownConversation(pcoi, FALSE); // may unlink pcoi! pcoi = pcoiNext; } } DestroyHandle((HANDLE)hConvList); DDEMLFree(pcl); fRet = TRUE; Exit: LeaveDDECrit; return (fRet); }
/***************************************************************************\ * DdeQueryNextServer (DDEML API) * * Description: * Enumerates conversations within a list. * * History: * 11-12-91 sanfords Created. \***************************************************************************/ HCONV DdeQueryNextServer( HCONVLIST hConvList, HCONV hConvPrev) { HCONV hConvRet = 0; PCONVLIST pcl; HWND *phwnd; int i; PCL_CONV_INFO pci; PCL_INSTANCE_INFO pcii; EnterDDECrit; pcl = (PCONVLIST)ValidateCHandle((HANDLE)hConvList, HTYPE_CONVERSATION_LIST, HINST_ANY); if (pcl == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } if (!pcl->chwnd) { // empty list goto Exit; } pcii = PciiFromHandle((HANDLE)hConvList); if (pcii == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } pcii->LastError = DMLERR_NO_ERROR; do { hConvRet = 0; if (hConvPrev == 0) { pci = (PCL_CONV_INFO)GetWindowLong(pcl->ahwnd[0], GWL_PCI); if (pci == NULL) { goto Exit; // Must have all conversations zombied. } hConvPrev = hConvRet = pci->ci.hConv; continue; } pci = (PCL_CONV_INFO)ValidateCHandle((HANDLE)hConvPrev, HTYPE_CLIENT_CONVERSATION, InstFromHandle(hConvList)); if (pci == NULL) { pci = (PCL_CONV_INFO)ValidateCHandle((HANDLE)hConvPrev, HTYPE_ZOMBIE_CONVERSATION, InstFromHandle(hConvList)); if (pci == NULL) { SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); break; } else { goto ZombieSkip; } } if (pci->hConvList != hConvList) { SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); break; } ZombieSkip: if (pci->ci.next == NULL) { /* * end of list for this window, go to next window */ for (phwnd = pcl->ahwnd, i = 0; (i + 1) < pcl->chwnd; i++) { if (phwnd[i] == pci->ci.hwndConv) { pci = (PCL_CONV_INFO)GetWindowLong(phwnd[i + 1], GWL_PCI); if (pci == NULL) { break; } hConvPrev = hConvRet = pci->ci.hConv; break; } } } else { hConvPrev = hConvRet = pci->ci.next->hConv; // next conv for this window. } } while (hConvRet && TypeFromHandle(hConvRet) == HTYPE_ZOMBIE_CONVERSATION); Exit: LeaveDDECrit; return (hConvRet); }
/***************************************************************************\ * DdeReconnect (DDEML API) * * Description: * Attempts to reconnect an externally (from the server) terminated * client side conversation. * * History: * 11-12-91 sanfords Created. \***************************************************************************/ HCONV DdeReconnect( HCONV hConv) { PCL_INSTANCE_INFO pcii; PCL_CONV_INFO pci, pciNew; HCONV hConvRet = 0; CONVCONTEXT cc; EnterDDECrit; pcii = PciiFromHandle((HANDLE)hConv); if (pcii == NULL) { BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER); goto Exit; } pci = (PCL_CONV_INFO)ValidateCHandle((HANDLE)hConv, HTYPE_CLIENT_CONVERSATION, HINST_ANY); if (pci == NULL) { SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER); goto Exit; } if (pci->ci.state & ST_CONNECTED) { goto Exit; } GetConvContext(pci->ci.hwndConv, (LONG *)&cc); pciNew = ConnectConv(pcii, pci->ci.laService, pci->ci.laTopic, pci->hwndReconnect, 0, &cc, 0, CLST_SINGLE_INITIALIZING); if (pciNew == NULL) { SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED); goto Exit; } else { hConvRet = pciNew->ci.hConv; if (pci->ci.cLinks) { PXACT_INFO pxi; int iLink; PADVISE_LINK paLink; /* * reestablish advise links */ for (paLink = pci->ci.aLinks, iLink = pci->ci.cLinks; iLink; paLink++, iLink--) { pxi = (PXACT_INFO)DDEMLAlloc(sizeof(XACT_INFO)); if (pxi == NULL) { break; // abort relinking } pxi->pcoi = (PCONV_INFO)pciNew; pxi->gaItem = LocalToGlobalAtom(paLink->laItem); // pxi copy pxi->wFmt = paLink->wFmt; pxi->wType = (WORD)((paLink->wType >> 12) | XTYP_ADVSTART); if (ClStartAdvise(pxi)) { pxi->flags |= XIF_ABANDONED; } else { GlobalDeleteAtom(pxi->gaItem); DDEMLFree(pxi); } } } }