Ejemplo n.º 1
0
/***************************************************************************\
* 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);
}
Ejemplo n.º 2
0
/***************************************************************************\
* 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);
}
Ejemplo n.º 3
0
/***************************************************************************\
* ValidateInstance
*
* Description:
* Verifies the current validity of an instance handle - which is a server
* side handle that also references a client side data structure (pcii).
*
* History:
* 11-19-91 sanfords Created.
\***************************************************************************/
PCL_INSTANCE_INFO ValidateInstance(
HANDLE hInstClient)
{
    PCL_INSTANCE_INFO pcii;

    pcii = (PCL_INSTANCE_INFO)ValidateCHandle(hInstClient, HTYPE_INSTANCE, HINST_ANY);

    if (pcii != NULL) {
        if (pcii->tid != GetCurrentThreadId() ||
                pcii->hInstClient != hInstClient) {
            return (NULL);
        }
    }
    return (pcii);
}
Ejemplo n.º 4
0
/***************************************************************************\
* 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);
}
Ejemplo n.º 5
0
BOOL WaitForZombieTerminate(
HANDLE hData)
{
    PCONV_INFO pcoi;
    MSG msg;
    HWND hwnd;
    BOOL fTerminated;
    DWORD fRet = 0;

    CheckDDECritOut;
    EnterDDECrit;

    fTerminated = FALSE;
    while ((pcoi = (PCONV_INFO)ValidateCHandle(hData,
            HTYPE_ZOMBIE_CONVERSATION, InstFromHandle(hData))) != NULL &&
            !(pcoi->state & ST_TERMINATE_RECEIVED)) {
        hwnd = pcoi->hwndConv;
        LeaveDDECrit;
        while (PeekMessage(&msg, hwnd, WM_DDE_FIRST, WM_DDE_LAST, PM_REMOVE)) {
            DispatchMessage(&msg);
            if (msg.message == WM_DDE_TERMINATE) {
                fTerminated = TRUE;
            }
        }
        if (!fTerminated) {
            fRet = MsgWaitForMultipleObjectsEx(0, NULL, 100, QS_POSTMESSAGE, 0);
            if (fRet == 0xFFFFFFFF) {
                RIPMSG0(RIP_WARNING, "WaitForZombieTerminate: I give up - faking terminate.");
                ProcessTerminateMsg(pcoi, pcoi->hwndPartner);
                EnterDDECrit;
                return(FALSE);
            }
        }
        EnterDDECrit;
    }
    LeaveDDECrit;
    return(TRUE);
}
Ejemplo n.º 6
0
/***************************************************************************\
* DdeEnableCallback (DDEML API)
*
* Description:
* Turns on and off asynchronous callbacks (BLOCKABLE).
*
* History:
* 11-12-91 sanfords Created.
\***************************************************************************/
BOOL DdeEnableCallback(
DWORD idInst,
HCONV hConv,
UINT wCmd)
{
    BOOL fRet = FALSE;
    PCL_INSTANCE_INFO pcii;
    PCONV_INFO pcoi;
    ENABLE_ENUM_STRUCT ees;

    EnterDDECrit;

    pcii = (PCL_INSTANCE_INFO)ValidateInstance((HANDLE)idInst);
    if (pcii == NULL) {
        BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
        goto Exit;
    }

    switch (wCmd) {
    case EC_QUERYWAITING:
    case EC_DISABLE:
    case EC_ENABLEONE:
    case EC_ENABLEALL:
        break;

    default:
        SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
        goto Exit;
    }

    if (hConv) {
        pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv,
                HTYPE_CLIENT_CONVERSATION, InstFromHandle(idInst));
        if (pcoi == NULL) {
            pcoi = (PCONV_INFO)ValidateCHandle((HANDLE)hConv,
                    HTYPE_SERVER_CONVERSATION, InstFromHandle(idInst));
        }
        if (pcoi == NULL) {
            SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
            goto Exit;
        }
        pcoi->cLocks++;
        fRet = SetEnableState(pcoi, wCmd);
        switch (wCmd) {
        case EC_ENABLEALL:
        case EC_ENABLEONE:
            CheckForQueuedMessages(pcoi);
        }
        pcoi->cLocks--;
        if (pcoi->cLocks == 0 && pcoi->state & ST_FREE_CONV_RES_NOW) {
            FreeConversationResources(pcoi);
        }
    } else {
        if (wCmd == EC_ENABLEONE) {
            wCmd = EC_ENABLEONEOFALL;
        }
        switch (wCmd) {
        case EC_ENABLEONEOFALL:
            pcii->ConvStartupState = ST_BLOCKNEXT | ST_BLOCKALLNEXT;
            break;

        case EC_DISABLE:
            pcii->ConvStartupState = ST_BLOCKED;
            break;

        case EC_ENABLEALL:
            pcii->ConvStartupState = 0;
            break;
        }
        ees.pfRet = &fRet;
        ees.wCmd = wCmd;
        switch (wCmd) {
        case EC_ENABLEALL:
            ees.wCmd2 = EC_CHECKQUEUE;
            break;

        case EC_ENABLEONEOFALL:
            ees.wCmd2 = EC_CHECKQUEUEONCE;
            break;

        default:
            ees.wCmd2 = 0;
        }
        EnumChildWindows(pcii->hwndMother, (WNDENUMPROC)EnableEnumProc,
                (LONG)&ees);
    }

Exit:
    LeaveDDECrit;
    return (fRet);
}
Ejemplo n.º 7
0
/***************************************************************************\
* 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);
}
Ejemplo n.º 8
0
/***************************************************************************\
* InitiateEnumerationProc (FILE LOCAL)
*
* Description:
* Function used via EnumWindows to enumerate all server window candidates
* during DDE initiation. The enumeration allows DDEML to know what
* window WM_DDE_INITIATE was sent to so that it can be remembered for
* possible reconnection later. (The window that receives the WM_DDE_INITIATE
* message is not necessarily going to be the server window.)
*
* History:
* 11-1-91 sanfords Created.
\***************************************************************************/
BOOL InitiateEnumerationProc(
    HWND hwndTarget,
    PINIT_ENUM pie)
{
    PCL_CONV_INFO pci;

    CheckDDECritOut;

    if (hwndTarget == pie->hwndSkip) {
        return (TRUE);
    }

    if (pie->hConvList && pie->laTopic && pie->laServiceRequested) {
        /*
         * Head off duplicates BEFORE we send the WM_DDE_INITIATE messages!
         */
        PCONVLIST pcl;
        PCONV_INFO pcoiExisting;
        int i;

        EnterDDECrit;
        /*
         * We revalidate hConvList here because we left the critical section.
         */
        pcl = (PCONVLIST)ValidateCHandle((HANDLE)pie->hConvList,
                HTYPE_CONVERSATION_LIST, HINST_ANY);
        if (pcl != NULL) {
            for (i = 0; i < pcl->chwnd; i++) {
                for (pcoiExisting = (PCONV_INFO)GetWindowLong(pcl->ahwnd[i], GWL_PCI);
                        pcoiExisting != NULL;
                        pcoiExisting = pcoiExisting->next) {
                    if (pcoiExisting->state & ST_CONNECTED &&
                            ((PCL_CONV_INFO)pcoiExisting)->hwndReconnect == hwndTarget &&
                            pcoiExisting->laTopic == pie->laTopic &&
                            pcoiExisting->laService == pie->laServiceRequested) {
                        LeaveDDECrit;
                        return(TRUE);
                    }
                }
            }
        }
        LeaveDDECrit;
    }

    CheckDDECritOut;

    SendMessage(hwndTarget, WM_DDE_INITIATE, (DWORD)pie->hwndClient,
            pie->lParam);

    EnterDDECrit;

    //
    // During the initiate process, any acks received cause more pci's
    // to become linked together under the same hwndClient. Once
    // the SendMessage() returns, we set the parts of the new pci's
    // that hold initiate context information.
    //
    pci = (PCL_CONV_INFO)GetWindowLong(pie->hwndClient, GWL_PCI);
    if (pci == NULL) {
        LeaveDDECrit;
        return (TRUE);
    }

    while (pci != NULL) {
        if (pci->hwndReconnect == 0) {  // this one needs updating
            pci->hwndReconnect = hwndTarget;
            if (pie->laServiceRequested) {
                pci->ci.laServiceRequested = pie->laServiceRequested;
                IncLocalAtomCount(pie->laServiceRequested); // pci copy
            }
        }
        if (pie->clst == CLST_SINGLE_INITIALIZING) {
            break;
        }
        pci = (PCL_CONV_INFO)pci->ci.next;
    }
    LeaveDDECrit;
    return (pie->clst == CLST_MULT_INITIALIZING);
}
Ejemplo n.º 9
0
/***************************************************************************\
* ValidateConnectParameters
*
* Description:
* worker function to handle common validation code.
*
* Note that paNormalSvcName is set to the atom value created upon extracting
* a normal HSZ from an InstanceSpecific HSZ.
*
* History:
* 11-12-91 sanfords Created.
\***************************************************************************/
BOOL ValidateConnectParameters(
    HANDLE hInst,
    PCL_INSTANCE_INFO *ppcii, // set if valid hInst
    HSZ *phszService, // altered if InstSpecific HSZ
    HSZ hszTopic,
    LATOM *plaNormalSvcName, // set to atom that needs freeing when done
    PCONVCONTEXT *ppCC, // set to point to DefConvContext if NULL
    HWND *phwndTarget, // set if hszService is InstSpecific
    HCONVLIST hConvList)
{
    DWORD hszType;
    BOOL fError = FALSE;

    *ppcii = ValidateInstance(hInst);
    if (*ppcii == NULL) {
        return (FALSE);
    }
    hszType = ValidateHSZ(*phszService);
    if (hszType == HSZT_INVALID || ValidateHSZ(hszTopic) == HSZT_INVALID) {
        SetLastDDEMLError(*ppcii, DMLERR_INVALIDPARAMETER);
        return (FALSE);
    }
    if (hszType == HSZT_INST_SPECIFIC) {
        *phwndTarget = ParseInstSpecificAtom(LATOM_FROM_HSZ(*phszService),
            plaNormalSvcName);
        if (*plaNormalSvcName == 0) {
            SetLastDDEMLError(*ppcii, DMLERR_SYS_ERROR);
            return (FALSE);
        }
        *phszService = NORMAL_HSZ_FROM_LATOM(*plaNormalSvcName);
    }
    if (*ppCC == NULL) {
        *ppCC = &DefConvContext;
        if ((*ppcii)->flags & IIF_UNICODE) {
            (*ppCC)->iCodePage = CP_WINUNICODE;
        } else {
            (*ppCC)->iCodePage = CP_WINANSI;
        }
    } else try {
        if ((*ppCC)->cb > sizeof(CONVCONTEXT)) {
            SetLastDDEMLError(*ppcii, DMLERR_INVALIDPARAMETER);
            fError = TRUE;
        } else if ((*ppCC)->cb < sizeof(CONVCONTEXT)) {
            TempConvContext = DefConvContext;
            /*
             * we can use this static temp because we are synchronized.
             */
            RtlCopyMemory(&TempConvContext, *ppCC, (*ppCC)->cb);
            *ppCC = &TempConvContext;
        }
    } except(EXCEPTION_EXECUTE_HANDLER) {
        SetLastDDEMLError(*ppcii, DMLERR_INVALIDPARAMETER);
        fError = TRUE;
    }
    if (fError) {
        return(FALSE);
    }
    if (hConvList != 0 &&
            !ValidateCHandle((HANDLE)hConvList, HTYPE_CONVERSATION_LIST,
            (DWORD)InstFromHandle((*ppcii)->hInstClient))) {
        return (FALSE);
    }
    return (TRUE);
}
Ejemplo n.º 10
0
/***************************************************************************\
* 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);
                }
            }
        }
    }
Ejemplo n.º 11
0
BOOL ValidateConvList(
HCONVLIST hConvList)
{
    PCONVLIST pcl;
    PCL_CONV_INFO pci;
    PXACT_INFO pxi;
    int i;
    BOOL fMatch;

    if (hConvList == 0) {
        return(TRUE);
    }
    pcl = (PCONVLIST)ValidateCHandle((HANDLE)hConvList,
                                     HTYPE_CONVERSATION_LIST,
                                     HINST_ANY);
    for (i = 0; i < pcl->chwnd; i++) {
        /*
         * all windows in the list are valid
         */
        if (!IsWindow(pcl->ahwnd[i])) {
            DebugBreak();
        }
        pci = (PCL_CONV_INFO)GetWindowLong(pcl->ahwnd[i], GWL_PCI);
       /*
        * All windows have at least one convinfo associated with them.
        */
        if (pci == NULL) {
            DebugBreak();
        }
        fMatch = FALSE;
        while (pci != NULL) {
            /*
             * All non-zombie conversations have hConvList set correctly.
             */
            if (pci->hConvList != hConvList &&
                    TypeFromHandle(pci->ci.hConv) != HTYPE_ZOMBIE_CONVERSATION) {
                DebugBreak();
            }
            /*
             * All conversations have hConvList clear or set correctly.
             */
            if (pci->hConvList != 0 && pci->hConvList != hConvList) {
                DebugBreak();
            }
            /*
             * At least 1 of the conversations references the list
             */
            if (pci->hConvList == hConvList) {
                fMatch = TRUE;
            }
            for (pxi = pci->ci.pxiOut; pxi; pxi = pxi->next) {
                if ((PCL_CONV_INFO)pxi->pcoi != pci) {
                    DebugBreak();
                }
            }
            pci = (PCL_CONV_INFO)pci->ci.next;
        }
        if (!fMatch) {
            /*
             * At least 1 of the conversations references the list
             */
            DebugBreak;
        }
    }
    return(TRUE);
}