コード例 #1
0
ファイル: ddemlcli.c プロジェクト: conioh/os-design
UINT InternalDdeInitialize(
LPDWORD pidInst,
PFNCALLBACK pfnCallback,
DWORD afCmd,
BOOL fUnicode)
{
    UINT uiRet = DMLERR_MEMORY_ERROR;
    register PCL_INSTANCE_INFO pcii;

    if (afCmd & APPCLASS_MONITOR) {
        afCmd |= CBF_MONMASK;
    }

    if (afCmd & APPCMD_CLIENTONLY) {
        afCmd |= CBF_FAIL_CONNECTIONS;
    }

    EnterDDECrit;

    if (*pidInst != 0) {
        pcii = ValidateInstance((HANDLE)LongToHandle( *pidInst ));
        if (pcii == NULL) {
            uiRet = DMLERR_INVALIDPARAMETER;
            goto Exit;
        }

        // only allow certain bits to be changed on reinitialize call

        pcii->afCmd = (pcii->afCmd & ~(CBF_MASK | MF_MASK)) |
                (afCmd & (CBF_MASK | MF_MASK));

        LeaveDDECrit;
        NtUserUpdateInstance(pcii->hInstServer, &pcii->MonitorFlags, afCmd);
        return (DMLERR_NO_ERROR);
    }

    pcii = (PCL_INSTANCE_INFO)DDEMLAlloc(sizeof(CL_INSTANCE_INFO));
    if (pcii == NULL) {
        uiRet = DMLERR_MEMORY_ERROR;
        goto Exit;
    }

    pcii->plaNameService = (LATOM *)DDEMLAlloc(sizeof(LATOM));
    if (pcii->plaNameService == NULL) {
        uiRet = DMLERR_MEMORY_ERROR;
        goto Backout3;
    }
    // *pcii->plaNameService = 0; // zero init takes care of this
    pcii->cNameServiceAlloc = 1;


    /*
     * Flag this window as being create from a diff hmod as the app so
     * hotkeys don't take it as the first window created in the app and
     * assign it as the hotkey.
     */
    pcii->hwndMother =  _CreateWindowEx(0, (LPTSTR)(gpsi->atomSysClass[ICLS_DDEMLMOTHER]), L"",
            WS_POPUP, 0, 0, 0, 0, (HWND)0,
            (HMENU)0, 0, (LPVOID)NULL, CW_FLAGS_DIFFHMOD);

    if (pcii->hwndMother == 0) {
        uiRet = DMLERR_SYS_ERROR;
        goto Backout2;
    }
    SetWindowLongPtr(pcii->hwndMother, GWLP_INSTANCE_INFO, (LONG_PTR)pcii);

    pcii->afCmd = afCmd | APPCMD_FILTERINITS;
    pcii->pfnCallback = pfnCallback;
    // pcii->LastError = DMLERR_NO_ERROR; // zero init
    pcii->tid = GetCurrentThreadId();
    // pcii->aServerLookup = NULL;          // zero init
    // pcii->cServerLookupAlloc = 0;        // zero init
    // pcii->ConvStartupState = 0;          // zero init - Not blocked.
    // pcii->flags = 0;                     // zero init
    // pcii->cInDDEMLCallback = 0;          // zero init
    // pcii->pLinkCounts = NULL;            // zero init

    // Do this last when the client side is ready for whatever events
    // flying around may come charging in.

    LeaveDDECrit;
    uiRet = NtUserDdeInitialize(&pcii->hInstServer,
                            &pcii->hwndEvent,
                            &pcii->MonitorFlags,
                            pcii->afCmd,
                            pcii);
    EnterDDECrit;

    if (uiRet != DMLERR_NO_ERROR) {
Backout:
        NtUserDestroyWindow(pcii->hwndMother);
Backout2:
        DDEMLFree(pcii->plaNameService);
Backout3:
        DDEMLFree(pcii);
        goto Exit;
    }
    pcii->hInstClient = AddInstance(pcii->hInstServer);
    *pidInst = HandleToUlong(pcii->hInstClient);
    if (pcii->hInstClient == 0) {
        LeaveDDECrit;
        NtUserCallOneParam((ULONG_PTR)pcii->hInstServer, SFI__CSDDEUNINITIALIZE);
        EnterDDECrit;
        uiRet = DMLERR_MEMORY_ERROR;
        goto Backout;
    }
    SetHandleData(pcii->hInstClient, (ULONG_PTR)pcii);

    pcii->next = pciiList;
    pciiList = pcii;
    if (fUnicode) {
        pcii->flags |= IIF_UNICODE;
    }
    uiRet = DMLERR_NO_ERROR;

Exit:
    LeaveDDECrit;
    return (uiRet);
}
コード例 #2
0
ファイル: connect.c プロジェクト: Gaikokujin/WinNT4
/***************************************************************************\
* DdeConnectList (DDEML API)
*
* Description:
* Initiates DDE conversations with multiple servers or adds unique servers
* to an existing conversation list.
*
* History:
* 11-12-91 sanfords Created.
\***************************************************************************/
HCONVLIST DdeConnectList(
    DWORD idInst,
    HSZ hszService,
    HSZ hszTopic,
    HCONVLIST hConvList,
    PCONVCONTEXT pCC)
{
    PCL_INSTANCE_INFO pcii;
    PCONV_INFO pcoi, pcoiNew, pcoiExisting, pcoiNext;
    HCONVLIST hConvListRet = 0;
    HWND hwndTarget = 0;
    LATOM aNormalSvcName = 0;
    PCONVLIST pcl = NULL;
    HCONVLIST hConvListOld;
    int i;

    CheckDDECritOut;

    EnterDDECrit;

    if (!ValidateConnectParameters((HANDLE)idInst, &pcii, &hszService, hszTopic,
            &aNormalSvcName, &pCC, &hwndTarget, hConvList)) {
        goto Exit;
    }

    ValidateConvList(hConvList);

    hConvListOld = hConvList;
    pcoi = (PCONV_INFO)ConnectConv(pcii,
            LATOM_FROM_HSZ(hszService),
            LATOM_FROM_HSZ(hszTopic),
            hwndTarget,
            (pcii->afCmd & (CBF_FAIL_SELFCONNECTIONS | CBF_FAIL_CONNECTIONS)) ?
                pcii->hwndMother : 0,
            pCC,
            hConvListOld,
            CLST_MULT_INITIALIZING);

    if (pcoi == NULL) {
        /*
         * no new connections made
         */
        SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED);
        hConvListRet = hConvListOld;
        goto Exit;
    }

    /*
     * allocate or reallocate the hConvList hwnd list for later addition
     * If we already have a valid list, reuse the handle so we don't have
     * to alter the preexisting pcoi->hConvList values.
     */
    if (hConvListOld == 0) {
        pcl = (PCONVLIST)DDEMLAlloc(sizeof(CONVLIST));
        if (pcl == NULL) {
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            DisconnectConv(pcoi);
            goto Exit;
        }
        // pcl->chwnd = 0; LPTR zero inits.

        hConvList = (HCONVLIST)CreateHandle((DWORD)pcl,
                HTYPE_CONVERSATION_LIST, InstFromHandle(pcii->hInstClient));
        if (hConvList == 0) {
            DDEMLFree(pcl);
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            DisconnectConv(pcoi);
            goto Exit;
        }
    } else {
        pcl = (PCONVLIST)GetHandleData((HANDLE)hConvList);
        pcl = DDEMLReAlloc(pcl, sizeof(CONVLIST) + sizeof(HWND) * pcl->chwnd);
        if (pcl == NULL) {
            SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
            hConvListRet = hConvListOld;
            DisconnectConv(pcoi);
            goto Exit;
        }
        SetHandleData((HANDLE)hConvList, (DWORD)pcl);
    }

    ValidateConvList(hConvListOld);

    if (hConvListOld) {
        /*
         * remove duplicates from new conversations
         *
         * Although we tried to prevent duplicates from happening
         * within the initiate enumeration code, wild initiates or
         * servers responding with different service names than
         * requested could cause duplicates.
         */

        /* For each client window... */

        for (i = 0; i < pcl->chwnd; i++) {

        /* For each existing conversation in that window... */

            for (pcoiExisting = (PCONV_INFO)
                        GetWindowLong(pcl->ahwnd[i], GWL_PCI);
                    pcoi != NULL && pcoiExisting != NULL;
                    pcoiExisting = pcoiExisting->next) {

                if (!(pcoiExisting->state & ST_CONNECTED))
                    continue;

        /* For each new conversation... */

                for (pcoiNew = pcoi; pcoiNew != NULL; pcoiNew = pcoiNext) {

                    pcoiNext = pcoiNew->next;

        /* see if the new conversation duplicates the existing one */

                    if (!(pcoiNew->state & ST_CONNECTED))
                        continue;

                    UserAssert(((PCL_CONV_INFO)pcoiExisting)->hwndReconnect);
                    UserAssert(((PCL_CONV_INFO)pcoiNew)->hwndReconnect);

                    if (((PCL_CONV_INFO)pcoiExisting)->hwndReconnect ==
                                ((PCL_CONV_INFO)pcoiNew)->hwndReconnect &&
                            pcoiExisting->laTopic == pcoiNew->laTopic &&
                            pcoiExisting->laService == pcoiNew->laService) {
                        /*
                         * duplicate conversation - disconnection causes an unlink
                         */
                        if (pcoiNew == pcoi) {
                            /*
                             * We are freeing up the head of the list,
                             * Reset the head to the next guy.
                             */
                            pcoi = pcoiNext;
                        }
                        ValidateConvList(hConvList);
                        ShutdownConversation(pcoiNew, FALSE);
                        ValidateConvList(hConvList);
                        break;
                    }
                }
            }
        }

        for (pcoiExisting = pcoi; pcoiExisting != NULL; pcoiExisting = pcoiExisting->next) {
            /*
             * if these are all zombies - we DONT want to link it in!
             * This is possible because ShutdownConversation() leaves the critical section
             * and could allow responding terminates to come through.
             */
            if (pcoiExisting->state & ST_CONNECTED) {
                goto FoundOne;
            }
        }
        pcoi = NULL;    // abandon this guy - he will clean up in time.
FoundOne:
        /*
         * add new pcoi (if any are left) hwnd to ConvList hwnd list.
         */
        if (pcoi != NULL) {
            UserAssert(pcoi->hwndConv);
            pcl->ahwnd[pcl->chwnd] = pcoi->hwndConv;
            pcl->chwnd++;
            hConvListRet = hConvList;
        } else {
            hConvListRet = hConvListOld;
            if (!hConvListOld) {
                DestroyHandle((HANDLE)hConvList);
            }
        }


    } else {    // no hConvListOld

        UserAssert(pcoi->hwndConv);
        pcl->ahwnd[0] = pcoi->hwndConv;
        pcl->chwnd = 1;
        hConvListRet = hConvList;
    }

    if (pcoi != NULL) {
        /*
         * set hConvList field for all remaining new conversations.
         */
        UserAssert(hConvListRet);
        for (pcoiNew = pcoi; pcoiNew != NULL; pcoiNew = pcoiNew->next) {
            if (pcoiNew->state & ST_CONNECTED) {
                ((PCL_CONV_INFO)pcoiNew)->hConvList = hConvListRet;
            }
        }
    }

Exit:
    if (aNormalSvcName) {
        DeleteAtom(aNormalSvcName);
    }
    ValidateConvList(hConvListRet);
    LeaveDDECrit;
    return (hConvListRet);
}