Example #1
0
/***************************************************************************\
* AddInstance
*
* Description:
* Adds a server side instance handle to the instance handle array.
* The array index becomes the client-side unique instance index used for
* identifying other client side handles.
*
* Returns:
* client side instance handle or 0 on error.
*
* History:
* 11-1-91 sanfords Created.
\***************************************************************************/
DWORD AddInstance(
HANDLE hInstServer)
{
    int i, iNextFree;
    PHANDLE ph;

    if (iFirstFreeInst >= cInstAllocated) {
        if (cInstAllocated == 0) {
           aInstance = (PHANDLE)DDEMLAlloc(sizeof(HANDLE) * INST_GROW_COUNT);
        } else {
           aInstance = (PHANDLE)DDEMLReAlloc((PVOID)aInstance,
                 sizeof(HANDLE) * (cInstAllocated + INST_GROW_COUNT));
        }
        if (aInstance == 0) {
            return (0);
        }
        ph = &aInstance[cInstAllocated];
        i = cInstAllocated + 1;
        while (i <= cInstAllocated + INST_GROW_COUNT) {
           *ph++ = (HANDLE)i++;
        }
        cInstAllocated += INST_GROW_COUNT;
    }
    iNextFree = (int)aInstance[iFirstFreeInst];
    if (iNextFree > MAX_INST) {
        /*
         * Instance limit for this process exceeded!
         */
        return(0);
    }
    aInstance[iFirstFreeInst] = hInstServer;
    i = iFirstFreeInst;
    iFirstFreeInst = iNextFree;
    return ((DWORD)CreateHandle(0, HTYPE_INSTANCE, i));
}
Example #2
0
/***************************************************************************\
* DdeNameService (DDEML API)
*
* Description:
* Registers, and Unregisters service names and sets the Initiate filter
* state for an instance.
*
* History:
* 11-1-91 sanfords Created.
\***************************************************************************/
HDDEDATA DdeNameService(
DWORD idInst,
HSZ hsz1, // service name
HSZ hsz2, // reserved for future enhancements
UINT afCmd) // DNS_ flags.
{
    BOOL fRet = TRUE;
    LATOM *plaNameService;
    PCL_INSTANCE_INFO pcii;

    EnterDDECrit;

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

    if ((hsz1 && ValidateHSZ(hsz1) == HSZT_INVALID) || hsz2 != 0) {
        SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
        fRet = FALSE;
        goto Exit;
    }

    if (afCmd & DNS_FILTERON && !(pcii->afCmd & APPCMD_FILTERINITS)) {
        pcii->afCmd |= APPCMD_FILTERINITS;
        NtUserUpdateInstance(pcii->hInstServer, &pcii->MonitorFlags, pcii->afCmd);
    }
    if (afCmd & DNS_FILTEROFF && (pcii->afCmd & APPCMD_FILTERINITS)) {
        pcii->afCmd &= ~APPCMD_FILTERINITS;
        NtUserUpdateInstance(pcii->hInstServer, &pcii->MonitorFlags, pcii->afCmd);
    }

    if (afCmd & (DNS_REGISTER | DNS_UNREGISTER)) {
        GATOM ga;

        if (pcii->afCmd & APPCMD_CLIENTONLY) {
            SetLastDDEMLError(pcii, DMLERR_DLL_USAGE);
            fRet = FALSE;
            goto Exit;
        }

        if (hsz1 == 0) {
            if (afCmd & DNS_REGISTER) {

                /*
                 * registering NULL is not allowed!
                 */
                SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
                fRet = FALSE;
                goto Exit;
            }

            /*
             * unregistering NULL is just like unregistering each
             * registered name.
             *
             * 10/19/90 - made this a synchronous event so that hsz
             * can be freed by calling app after this call completes
             * without us having to keep a copy around forever.
             */
            plaNameService = pcii->plaNameService;
            while (*plaNameService != 0) {
                ga = LocalToGlobalAtom(*plaNameService);
                DeleteAtom(*plaNameService);
                LeaveDDECrit;
                RegisterService(FALSE, ga, pcii->hwndMother);
                EnterDDECrit;
                GlobalDeleteAtom(ga);
                plaNameService++;
            }
            pcii->cNameServiceAlloc = 1;
            *pcii->plaNameService = 0;
            goto Exit;
        }

        if (afCmd & DNS_REGISTER) {
            plaNameService = (LATOM *)DDEMLReAlloc(pcii->plaNameService,
                    sizeof(LATOM) * ++pcii->cNameServiceAlloc);
            if (plaNameService == NULL) {
                SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
                pcii->cNameServiceAlloc--;
                fRet = FALSE;
                goto Exit;
            } else {
                pcii->plaNameService = plaNameService;
            }
            IncLocalAtomCount(LATOM_FROM_HSZ(hsz1)); // NameService copy
            plaNameService[pcii->cNameServiceAlloc - 2] = LATOM_FROM_HSZ(hsz1);
            plaNameService[pcii->cNameServiceAlloc - 1] = 0;

        } else { // DNS_UNREGISTER
            plaNameService = pcii->plaNameService;
            while (*plaNameService != 0 && *plaNameService != LATOM_FROM_HSZ(hsz1)) {
                plaNameService++;
            }
            if (*plaNameService == 0) {
                goto Exit; // not found just exit
            }
            //
            // fill empty slot with last entry and fill last entry with 0
            //
            pcii->cNameServiceAlloc--;
            *plaNameService = pcii->plaNameService[pcii->cNameServiceAlloc - 1];
            pcii->plaNameService[pcii->cNameServiceAlloc - 1] = 0;
        }

        ga = LocalToGlobalAtom(LATOM_FROM_HSZ(hsz1));
        LeaveDDECrit;
        RegisterService((afCmd & DNS_REGISTER) ? TRUE : FALSE, ga,
            pcii->hwndMother);
        EnterDDECrit;
        GlobalDeleteAtom(ga);
    }

Exit:
    LeaveDDECrit;
    return ((HDDEDATA)IntToPtr( fRet ));
}
Example #3
0
/***************************************************************************\
* 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);
}