00001 /****************************** Module Header ******************************\ 00002 * Module Name: util.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * DDE Manager general utility functions 00007 * 00008 * Created: 11/3/91 Sanford Staab 00009 \***************************************************************************/ 00010 00011 #include "precomp.h" 00012 #pragma hdrstop 00013 00014 /***************************************************************************\ 00015 * AddLink 00016 * 00017 * Description: 00018 * Adds an advise link to the conversation's info. 00019 * 00020 * History: 00021 * 11-19-91 sanfords Created. 00022 \***************************************************************************/ 00023 BOOL AddLink( 00024 PCONV_INFO pcoi, 00025 GATOM gaItem, 00026 WORD wFmt, 00027 WORD wType) 00028 { 00029 PADVISE_LINK aLinkNew; 00030 int cLinks; 00031 LATOM la; 00032 PCL_INSTANCE_INFO pcii; 00033 00034 /* 00035 * if the link already exists, update its flags, otherwise create a 00036 * new one. 00037 */ 00038 00039 aLinkNew = pcoi->aLinks; 00040 cLinks = pcoi->cLinks; 00041 la = GlobalToLocalAtom(gaItem); // aLinkNew copy 00042 while (cLinks) { 00043 if (aLinkNew->laItem == la && aLinkNew->wFmt == wFmt) { 00044 aLinkNew->wType = wType; 00045 aLinkNew->state = 0; 00046 DeleteAtom(la); 00047 return TRUE; 00048 } 00049 aLinkNew++; 00050 cLinks--; 00051 } 00052 00053 if (pcoi->aLinks == NULL) { 00054 aLinkNew = (PADVISE_LINK)DDEMLAlloc(sizeof(ADVISE_LINK)); 00055 } else { 00056 aLinkNew = (PADVISE_LINK)DDEMLReAlloc(pcoi->aLinks, 00057 sizeof(ADVISE_LINK) * (pcoi->cLinks + 1)); 00058 } 00059 if (aLinkNew == NULL) { 00060 SetLastDDEMLError(pcoi->pcii, DMLERR_MEMORY_ERROR); 00061 DeleteAtom(la); 00062 return FALSE; 00063 } 00064 pcoi->aLinks = aLinkNew; 00065 aLinkNew += pcoi->cLinks; 00066 pcoi->cLinks++; 00067 00068 aLinkNew->laItem = la; 00069 aLinkNew->wFmt = wFmt; 00070 aLinkNew->wType = wType; 00071 aLinkNew->state = 0; 00072 00073 if (!(pcoi->state & ST_CLIENT)) { 00074 /* 00075 * Add count for this link 00076 */ 00077 pcii = pcoi->pcii; 00078 00079 for (aLinkNew->pLinkCount = pcii->pLinkCount; 00080 aLinkNew->pLinkCount; 00081 aLinkNew->pLinkCount = aLinkNew->pLinkCount->next) { 00082 if (aLinkNew->pLinkCount->laTopic == pcoi->laTopic && 00083 aLinkNew->pLinkCount->gaItem == gaItem && 00084 aLinkNew->pLinkCount->wFmt == wFmt) { 00085 aLinkNew->pLinkCount->Total++; 00086 return(TRUE); 00087 } 00088 } 00089 00090 /* 00091 * Not found - add an entry 00092 */ 00093 aLinkNew->pLinkCount = (PLINK_COUNT)DDEMLAlloc(sizeof(LINK_COUNT)); 00094 if (aLinkNew->pLinkCount == NULL) { 00095 SetLastDDEMLError(pcoi->pcii, DMLERR_MEMORY_ERROR); 00096 return FALSE; 00097 } 00098 aLinkNew->pLinkCount->next = pcii->pLinkCount; 00099 pcii->pLinkCount = aLinkNew->pLinkCount; 00100 00101 aLinkNew->pLinkCount->laTopic = IncLocalAtomCount(pcoi->laTopic); // LinkCount copy 00102 aLinkNew->pLinkCount->gaItem = IncGlobalAtomCount(gaItem); // LinkCount copy 00103 aLinkNew->pLinkCount->laItem = IncLocalAtomCount(la); // LinkCount copy 00104 00105 aLinkNew->pLinkCount->wFmt = wFmt; 00106 aLinkNew->pLinkCount->Total = 1; 00107 // doesn't matter: aLinkNew->pLinkCount->Count = 0; 00108 } 00109 00110 return TRUE; 00111 } 00112 00113 00114 00115 /* 00116 * The LinkCount array is a list of all active links grouped by topic 00117 * and item. The Total field is the number of active links total for 00118 * that particular topic/item pair for the entire instance. The count 00119 * field is used to properly set up the links to go field of the XTYP_ADVREQ 00120 * callback. Whenever links are added or removed, DeleteLinkCount or 00121 * AddLink need to be called to keep thses counts correct. 00122 */ 00123 VOID DeleteLinkCount( 00124 PCL_INSTANCE_INFO pcii, 00125 PLINK_COUNT pLinkCountDelete) 00126 { 00127 PLINK_COUNT pLinkCount, pLinkCountPrev; 00128 00129 if (--pLinkCountDelete->Total != 0) { 00130 return; 00131 } 00132 pLinkCountPrev = NULL; 00133 pLinkCount = pcii->pLinkCount; 00134 while (pLinkCount) { 00135 00136 if (pLinkCount == pLinkCountDelete) { 00137 GlobalDeleteAtom(pLinkCount->gaItem); 00138 DeleteAtom(pLinkCount->laItem); 00139 DeleteAtom(pLinkCount->laTopic); 00140 if (pLinkCountPrev == NULL) { 00141 pcii->pLinkCount = pLinkCount->next; 00142 } else { 00143 pLinkCountPrev->next = pLinkCount->next; 00144 } 00145 DDEMLFree(pLinkCount); 00146 return; 00147 } 00148 00149 pLinkCountPrev = pLinkCount; 00150 pLinkCount = pLinkCount->next; 00151 } 00152 }