Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

ddetrack.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define TRACE_DDE(str)   TAGMSG0(DBGTAG_DDE, str)
#define TRACE_DDE1(s, a)   TAGMSG1(DBGTAG_DDE, (s), (a))
#define TRACE_DDE2(s, a, b)   TAGMSG2(DBGTAG_DDE, (s), (a), (b))
#define TRACE_DDE3(s, a, b, c)   TAGMSG3(DBGTAG_DDE, (s), (a), (b), (c))
#define ValidatePublicObjectList()
#define TraceDdeMsg(m, h1, h2, c)

Functions

BOOL NewConversation (PDDECONV *ppdcNewClient, PDDECONV *ppdcNewServer, PWND pwndClient, PWND pwndServer)
PDDECONV FindDdeConv (PWND pwndProp, PWND pwndPartner)
BOOL AddConvProp (PWND pwndUs, PWND pwndThem, DWORD flags, PDDECONV pdcNew, PDDECONV pdcPartner)
DWORD Unadvise (PDDECONV pDdeConv)
DWORD Request (PDDECONV pDdeConv)
DWORD SpontaneousTerminate (PDWORD pmessage, PDDECONV pDdeConv)
HANDLE AnticipatePost (PDDECONV pDdeConv, FNDDERESPONSE fnResponse, HANDLE hClient, HANDLE hServer, PINTDDEINFO pIntDdeInfo, DWORD flags)
PXSTATE Createpxs (FNDDERESPONSE fnResponse, HANDLE hClient, HANDLE hServer, PINTDDEINFO pIntDdeInfo, DWORD flags)
DWORD AbnormalDDEPost (PDDECONV pDdeConv, DWORD message)
DWORD xxxCopyDdeIn (HANDLE hSrc, PDWORD pflags, PHANDLE phDirect, PINTDDEINFO *ppi)
DWORD xxxCopyAckIn (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv, PINTDDEINFO *ppIntDdeInfo)
HANDLE xxxCopyDDEOut (PINTDDEINFO pIntDdeInfo, PHANDLE phDirect)
BOOL FreeListAdd (PDDECONV pDdeConv, HANDLE hClient, DWORD flags)
VOID xxxFreeListFree (PFREELIST pfl)
VOID PopState (PDDECONV pDdeConv)
PDDECONV UnlinkConv (PDDECONV pDdeConv)
VOID FreeDDEHandle (PDDECONV pDdeConv, HANDLE hClient, DWORD flags)
DWORD ClientFreeDDEHandle (HANDLE hClient, DWORD flags)
DWORD ClientGetDDEFlags (HANDLE hClient, DWORD flags)
DWORD xxxClientCopyDDEIn1 (HANDLE hClient, DWORD flags, PINTDDEINFO *ppi)
HANDLE xxxClientCopyDDEOut1 (PINTDDEINFO pIntDdeInfo)
DWORD xxxClientCopyDDEOut2 (PINTDDEINFO pIntDdeInfo)
PPUBOBJ IsObjectPublic (HANDLE hObj)
BOOL AddPublicObject (UINT format, HANDLE hObj, W32PID pid)
BOOL RemovePublicObject (UINT format, HANDLE hObj)
BOOL GiveObject (UINT format, HANDLE hObj, W32PID pid)
BOOL xxxDDETrackSendHook (PWND pwndTo, DWORD message, WPARAM wParam, LPARAM lParam)
DWORD xxxDDETrackPostHook (PUINT pmessage, PWND pwndTo, WPARAM wParam, LPARAM *plParam, BOOL fSent)
void xxxCleanupDdeConv (PWND pwndProp)
VOID xxxDDETrackGetMessageHook (PMSG pmsg)
VOID xxxDDETrackWindowDying (PWND pwnd, PDDECONV pDdeConv)
DWORD xxxUnexpectedServerPost (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxUnexpectedClientPost (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxAdvise (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxAdviseAck (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxAdviseData (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxAdviseDataAck (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxUnadviseAck (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxRequestAck (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxPoke (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxPokeAck (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxExecute (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxExecuteAck (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD DupConvTerminate (PDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv)
DWORD xxxCopyAckIn (LPDWORD pmessage, LPARAM *plParam, PDDECONV pDdeConv, PINTDDEINFO *ppIntDdeInfo)
VOID FreeListFree (PFREELIST pfl)
VOID FreeDdeConv (PDDECONV pDdeConv)
BOOL _DdeSetQualityOfService (PWND pwndClient, CONST PSECURITY_QUALITY_OF_SERVICE pqosNew, PSECURITY_QUALITY_OF_SERVICE pqosOld)
BOOL _DdeGetQualityOfService (PWND pwndClient, PWND pwndServer, PSECURITY_QUALITY_OF_SERVICE pqos)
BOOL _ImpersonateDdeClientWindow (PWND pwndClient, PWND pwndServer)
VOID FreeDdeXact (PXSTATE pxs)

Variables

PPUBOBJ gpPublicObjectList
FNDDERESPONSE xxxUnexpectedServerPost
FNDDERESPONSE xxxUnexpectedClientPost
FNDDERESPONSE xxxAdvise
FNDDERESPONSE xxxAdviseAck
FNDDERESPONSE xxxAdviseData
FNDDERESPONSE xxxAdviseDataAck
FNDDERESPONSE xxxUnadviseAck
FNDDERESPONSE xxxRequestAck
FNDDERESPONSE xxxPoke
FNDDERESPONSE xxxPokeAck
FNDDERESPONSE xxxExecute
FNDDERESPONSE xxxExecuteAck
FNDDERESPONSE DupConvTerminate


Define Documentation

#define TRACE_DDE str   )     TAGMSG0(DBGTAG_DDE, str)
 

Definition at line 19 of file kernel/ddetrack.c.

Referenced by DupConvTerminate(), Request(), SpontaneousTerminate(), Unadvise(), xxxAdvise(), xxxAdviseAck(), xxxAdviseData(), xxxAdviseDataAck(), xxxDDETrackGetMessageHook(), xxxDDETrackPostHook(), xxxExecute(), xxxExecuteAck(), xxxPoke(), xxxPokeAck(), xxxRequestAck(), xxxUnadviseAck(), xxxUnexpectedClientPost(), and xxxUnexpectedServerPost().

#define TRACE_DDE1 s,
 )     TAGMSG1(DBGTAG_DDE, (s), (a))
 

Definition at line 20 of file kernel/ddetrack.c.

Referenced by FreeDdeConv(), FreeDDEHandle(), UnlinkConv(), xxxAdviseData(), xxxAdviseDataAck(), xxxCopyDDEOut(), xxxDDETrackGetMessageHook(), and xxxFreeListFree().

#define TRACE_DDE2 s,
a,
 )     TAGMSG2(DBGTAG_DDE, (s), (a), (b))
 

Definition at line 21 of file kernel/ddetrack.c.

Referenced by FreeListAdd(), xxxCopyDdeIn(), xxxDDETrackGetMessageHook(), xxxDDETrackSendHook(), and xxxDDETrackWindowDying().

#define TRACE_DDE3 s,
a,
b,
c   )     TAGMSG3(DBGTAG_DDE, (s), (a), (b), (c))
 

Definition at line 22 of file kernel/ddetrack.c.

Referenced by xxxAdviseDataAck(), xxxCopyDdeIn(), and xxxCopyDDEOut().

#define TraceDdeMsg m,
h1,
h2,
c   ) 
 

Definition at line 79 of file kernel/ddetrack.c.

Referenced by xxxDDETrackGetMessageHook(), xxxDDETrackPostHook(), and xxxReadPostMessage().

 
#define ValidatePublicObjectList  ) 
 

Definition at line 78 of file kernel/ddetrack.c.

Referenced by Createpxs(), and FreeDdeXact().


Function Documentation

BOOL _DdeGetQualityOfService PWND  pwndClient,
PWND  pwndServer,
PSECURITY_QUALITY_OF_SERVICE  pqos
 

Definition at line 2218 of file kernel/ddetrack.c.

References _GetProp(), BOOL, FALSE, FindDdeConv(), GETPWNDPPI, gqosDefault, NULL, tagDDECONV::pddei, PROP_QOS, PROPF_INTERNAL, tagDDEIMP::qos, and TRUE.

Referenced by NtUserDdeGetQualityOfService().

02222 { 02223 PDDECONV pDdeConv; 02224 PSECURITY_QUALITY_OF_SERVICE pqosClient; 02225 02226 if (pwndServer == NULL) { 02227 /* 02228 * Special case to support DDEML-RAW conversations that need to get 02229 * the QOS prior to initiation completion. 02230 */ 02231 pqosClient = _GetProp(pwndClient, PROP_QOS, PROPF_INTERNAL); 02232 if (pqosClient == NULL) { 02233 *pqos = gqosDefault; 02234 } else { 02235 *pqos = *pqosClient; 02236 } 02237 return(TRUE); 02238 } 02239 if (GETPWNDPPI(pwndClient) == GETPWNDPPI(pwndServer)) { 02240 *pqos = gqosDefault; 02241 return(TRUE); 02242 } 02243 pDdeConv = FindDdeConv(pwndClient, pwndServer); 02244 if (pDdeConv == NULL) { 02245 return(FALSE); 02246 } 02247 if (pDdeConv->pddei == NULL) { 02248 return(FALSE); 02249 } 02250 *pqos = pDdeConv->pddei->qos; 02251 return(TRUE); 02252 }

BOOL _DdeSetQualityOfService PWND  pwndClient,
CONST PSECURITY_QUALITY_OF_SERVICE  pqosNew,
PSECURITY_QUALITY_OF_SERVICE  pqosOld
 

Definition at line 2176 of file kernel/ddetrack.c.

References BOOL, FALSE, gqosDefault, InternalRemoveProp(), InternalSetProp(), NULL, PROP_QOS, PROPF_INTERNAL, and TRUE.

Referenced by NtUserDdeSetQualityOfService().

02180 { 02181 PSECURITY_QUALITY_OF_SERVICE pqosUser; 02182 PSECURITY_QUALITY_OF_SERVICE pqosAlloc = NULL; 02183 BOOL fRet; 02184 02185 /* 02186 * ASSUME: calling process is owner of pwndClient - ensured in thunk. 02187 */ 02188 pqosUser = (PSECURITY_QUALITY_OF_SERVICE)InternalRemoveProp(pwndClient, 02189 PROP_QOS, PROPF_INTERNAL); 02190 if (pqosUser == NULL) { 02191 if (RtlEqualMemory(pqosNew, &gqosDefault, sizeof(SECURITY_QUALITY_OF_SERVICE))) { 02192 return(TRUE); // no PROP_QOS property implies default QOS 02193 } 02194 pqosAlloc = (PSECURITY_QUALITY_OF_SERVICE)UserAllocPoolZInit( 02195 sizeof(SECURITY_QUALITY_OF_SERVICE), TAG_DDE2); 02196 if (pqosAlloc == NULL) { 02197 return(FALSE); // memory allocation failure - can't change from default 02198 } 02199 pqosUser = pqosAlloc; 02200 } 02201 *pqosOld = *pqosUser; 02202 *pqosUser = *pqosNew; 02203 02204 fRet = InternalSetProp(pwndClient, PROP_QOS, pqosUser, PROPF_INTERNAL); 02205 if ((fRet == FALSE) && (pqosAlloc != NULL)) { 02206 UserFreePool(pqosAlloc); 02207 } 02208 02209 return fRet; 02210 }

BOOL _ImpersonateDdeClientWindow PWND  pwndClient,
PWND  pwndServer
 

Definition at line 2256 of file kernel/ddetrack.c.

References BOOL, tagDDEIMP::ClientContext, FALSE, FindDdeConv(), NT_SUCCESS, NTSTATUS(), NULL, tagDDECONV::pddei, PsGetCurrentThread, SeImpersonateClientEx(), Status, and TRUE.

Referenced by NtUserImpersonateDdeClientWindow().

02259 { 02260 PDDECONV pDdeConv; 02261 NTSTATUS Status; 02262 02263 /* 02264 * Locate token used in the conversation 02265 */ 02266 pDdeConv = FindDdeConv(pwndClient, pwndServer); 02267 if (pDdeConv == NULL || pDdeConv->pddei == NULL) 02268 return(FALSE); 02269 02270 /* 02271 * Stick the token into the dde server thread 02272 */ 02273 Status = SeImpersonateClientEx(&pDdeConv->pddei->ClientContext, 02274 PsGetCurrentThread()); 02275 if (!NT_SUCCESS(Status)) { 02276 RIPNTERR0(Status, RIP_VERBOSE, ""); 02277 return FALSE; 02278 } 02279 return TRUE; 02280 }

DWORD AbnormalDDEPost PDDECONV  pDdeConv,
DWORD  message
 

Definition at line 1729 of file kernel/ddetrack.c.

References _PostMessage(), CXF_TERMINATE_POSTED, DWORD, FAIL_POST, FAKE_POST, tagDDECONV::flags, PtoH, tagDDECONV::spwnd, and tagDDECONV::spwndPartner.

Referenced by xxxUnexpectedClientPost(), and xxxUnexpectedServerPost().

01732 { 01733 01734 #if DBG 01735 if (message != WM_DDE_TERMINATE) { 01736 RIPMSG2(RIP_WARNING, 01737 "DDE Post failed (%#p:%#p) - protocol violation.", 01738 PtoH(pDdeConv->spwnd), PtoH(pDdeConv->spwndPartner)); 01739 } 01740 #endif // DBG 01741 01742 // shutdown this conversation by posting a terminate on 01743 // behalf of this guy, then fail all future posts but 01744 // fake a successful terminate. 01745 01746 if (!(pDdeConv->flags & CXF_TERMINATE_POSTED)) { 01747 _PostMessage(pDdeConv->spwndPartner, WM_DDE_TERMINATE, 01748 (WPARAM)PtoH(pDdeConv->spwnd), 0); 01749 // pDdeConv->flags |= CXF_TERMINATE_POSTED; Set by post hook proc 01750 } 01751 return(message == WM_DDE_TERMINATE ? FAKE_POST : FAIL_POST); 01752 }

BOOL AddConvProp PWND  pwndUs,
PWND  pwndThem,
DWORD  flags,
PDDECONV  pdcNew,
PDDECONV  pdcPartner
 

Definition at line 217 of file kernel/ddetrack.c.

References _GetProp(), BOOL, tagDDEIMP::cRefConv, CXF_IS_SERVER, tagDDECONV::flags, HMLockObject, InternalSetProp(), Lock, NULL, tagDDECONV::pddei, PROP_DDEIMP, PROP_DDETRACK, PROPF_INTERNAL, tagDDECONV::snext, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, tagDDECONV::spxsIn, tagDDECONV::spxsOut, and TRUE.

Referenced by NewConversation().

00223 { 00224 PDDECONV pDdeConv; 00225 PDDEIMP pddei; 00226 00227 pDdeConv = (PDDECONV)_GetProp(pwndUs, PROP_DDETRACK, PROPF_INTERNAL); 00228 Lock(&(pdcNew->snext), pDdeConv); 00229 Lock(&(pdcNew->spwnd), pwndUs); 00230 Lock(&(pdcNew->spwndPartner), pwndThem); 00231 00232 /* 00233 * Assert to catch stress bug. 00234 */ 00235 UserAssert(pdcPartner != (PDDECONV)(-1)); 00236 00237 Lock(&(pdcNew->spartnerConv), pdcPartner); 00238 pdcNew->spxsIn = NULL; 00239 pdcNew->spxsOut = NULL; 00240 pdcNew->flags = flags; 00241 pddei = (PDDEIMP)_GetProp((flags & CXF_IS_SERVER) ? 00242 pwndThem : pwndUs, PROP_DDEIMP, PROPF_INTERNAL); 00243 if (pddei != NULL) { // This can be NULL if a bad WOW app has been 00244 pddei->cRefConv++; // allowed through for compatability. 00245 } 00246 pdcNew->pddei = pddei; 00247 00248 HMLockObject(pdcNew); // lock for property 00249 InternalSetProp(pwndUs, PROP_DDETRACK, pdcNew, PROPF_INTERNAL); 00250 return(TRUE); 00251 }

BOOL AddPublicObject UINT  format,
HANDLE  hObj,
W32PID  pid
 

Definition at line 2348 of file kernel/ddetrack.c.

References BOOL, tagPUBOBJ::count, FALSE, format, GiveObject(), gpPublicObjectList, tagPUBOBJ::hObj, IsObjectPublic(), tagPUBOBJ::next, NULL, tagPUBOBJ::pid, PUBOBJ, and TRUE.

Referenced by xxxAdviseData(), xxxPoke(), and xxxRequestAck().

02352 { 02353 PPUBOBJ ppo; 02354 02355 switch (format) { 02356 case CF_BITMAP: 02357 case CF_DSPBITMAP: 02358 case CF_PALETTE: 02359 break; 02360 02361 default: 02362 return(FALSE); 02363 } 02364 02365 ppo = IsObjectPublic(hObj); 02366 if (ppo == NULL) { 02367 ppo = UserAllocPool(sizeof(PUBOBJ), TAG_DDE4); 02368 if (ppo == NULL) { 02369 return(FALSE); 02370 } 02371 ppo->count = 1; 02372 ppo->hObj = hObj; 02373 ppo->pid = pid; 02374 ppo->next = gpPublicObjectList; 02375 gpPublicObjectList = ppo; 02376 GiveObject(format, hObj, OBJECT_OWNER_PUBLIC); 02377 } else { 02378 ppo->count++; 02379 } 02380 return(TRUE); 02381 }

HANDLE AnticipatePost PDDECONV  pDdeConv,
FNDDERESPONSE  fnResponse,
HANDLE  hClient,
HANDLE  hServer,
PINTDDEINFO  pIntDdeInfo,
DWORD  flags
 

Definition at line 1634 of file kernel/ddetrack.c.

References tagSHAREDINFO::aheList, Createpxs(), giheLast, gSharedInfo, HANDLEENTRY, tagDDECONV::head, tagXSTATE::head, Lock, NULL, _THROBJHEAD::pti, PtoH, tagXSTATE::snext, tagDDECONV::spxsIn, tagDDECONV::spxsOut, TYPE_DDECONV, and TYPE_DDEXACT.

Referenced by Request(), Unadvise(), xxxAdvise(), xxxAdviseData(), xxxDDETrackSendHook(), xxxExecute(), xxxPoke(), and xxxRequestAck().

01641 { 01642 PXSTATE pxs; 01643 01644 pxs = Createpxs(fnResponse, hClient, hServer, pIntDdeInfo, flags); 01645 if (pxs != NULL) { 01646 pxs->head.pti = pDdeConv->head.pti; 01647 if (pDdeConv->spxsOut == NULL) { 01648 UserAssert(pDdeConv->spxsIn == NULL); 01649 Lock(&(pDdeConv->spxsOut), pxs); 01650 Lock(&(pDdeConv->spxsIn), pxs); 01651 } else { 01652 UserAssert(pDdeConv->spxsIn != NULL); 01653 Lock(&(pDdeConv->spxsIn->snext), pxs); 01654 Lock(&(pDdeConv->spxsIn), pxs); 01655 } 01656 #if 0 01657 { 01658 int i; 01659 HANDLEENTRY *phe; 01660 01661 for (i = 0, phe = gSharedInfo.aheList; 01662 i <= (int)giheLast; 01663 i++) { 01664 if (phe[i].bType == TYPE_DDEXACT) { 01665 UserAssert(((PXSTATE)(phe[i].phead))->snext != pDdeConv->spxsOut); 01666 } 01667 if (phe[i].bType == TYPE_DDECONV && 01668 (PDDECONV)phe[i].phead != pDdeConv) { 01669 UserAssert(((PDDECONV)(phe[i].phead))->spxsOut != pDdeConv->spxsOut); 01670 UserAssert(((PDDECONV)(phe[i].phead))->spxsIn != pDdeConv->spxsOut); 01671 } 01672 } 01673 } 01674 #endif 01675 } 01676 return(PtoH(pxs)); 01677 }

DWORD ClientFreeDDEHandle HANDLE  hClient,
DWORD  flags
 

Referenced by FreeDDEHandle(), and xxxFreeListFree().

DWORD ClientGetDDEFlags HANDLE  hClient,
DWORD  flags
 

Referenced by xxxRequestAck().

PXSTATE Createpxs FNDDERESPONSE  fnResponse,
HANDLE  hClient,
HANDLE  hServer,
PINTDDEINFO  pIntDdeInfo,
DWORD  flags
 

Definition at line 1689 of file kernel/ddetrack.c.

References tagXSTATE::flags, tagXSTATE::fnResponse, tagXSTATE::hClient, tagXSTATE::head, HMAllocObject(), tagXSTATE::hServer, NULL, tagXSTATE::pIntDdeInfo, PtiCurrent, tagXSTATE::snext, TYPE_DDEXACT, ValidatePublicObjectList, and XSTATE.

Referenced by AnticipatePost(), xxxAdviseData(), xxxCopyAckIn(), xxxExecuteAck(), and xxxRequestAck().

01695 { 01696 PXSTATE pxs; 01697 01698 pxs = HMAllocObject(PtiCurrent(), NULL, TYPE_DDEXACT, sizeof(XSTATE)); 01699 if (pxs == NULL) { 01700 #if DBG 01701 RIPMSG0(RIP_WARNING, "Unable to alloc DDEXACT"); 01702 #endif 01703 return(NULL); 01704 } 01705 pxs->snext = NULL; 01706 pxs->fnResponse = fnResponse; 01707 pxs->hClient = hClient; 01708 pxs->hServer = hServer; 01709 pxs->pIntDdeInfo = pIntDdeInfo; 01710 pxs->flags = flags; 01711 ValidatePublicObjectList(); 01712 UserAssert(pxs->head.cLockObj == 0); 01713 return(pxs); 01714 }

DWORD DupConvTerminate PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1601 of file kernel/ddetrack.c.

References CheckLock, DWORD, FAKE_POST, PopState(), TRACE_DDE, and xxxUnexpectedServerPost().

01605 { 01606 CheckLock(pDdeConv); 01607 01608 TRACE_DDE("DupConvTerminate"); 01609 01610 if (*pmessage != WM_DDE_TERMINATE) { 01611 return(xxxUnexpectedServerPost(pmessage, plParam, pDdeConv)); 01612 } 01613 01614 PopState(pDdeConv); 01615 return(FAKE_POST); 01616 }

PDDECONV FindDdeConv PWND  pwndProp,
PWND  pwndPartner
 

Definition at line 1811 of file kernel/ddetrack.c.

References _GetProp(), NULL, PROP_DDETRACK, PROPF_INTERNAL, tagDDECONV::snext, and tagDDECONV::spwndPartner.

Referenced by _DdeGetQualityOfService(), _ImpersonateDdeClientWindow(), xxxDDETrackGetMessageHook(), xxxDDETrackPostHook(), and xxxDDETrackSendHook().

01814 { 01815 PDDECONV pDdeConv; 01816 01817 pDdeConv = (PDDECONV)_GetProp(pwndProp, PROP_DDETRACK, PROPF_INTERNAL); 01818 while (pDdeConv != NULL && pDdeConv->spwndPartner != pwndPartner) { 01819 pDdeConv = pDdeConv->snext; 01820 } 01821 01822 return(pDdeConv); 01823 }

VOID FreeDdeConv PDDECONV  pDdeConv  ) 
 

Definition at line 2042 of file kernel/ddetrack.c.

References _PostMessage(), tagDDEIMP::ClientContext, tagDDEIMP::cRefConv, tagDDEIMP::cRefInit, CXF_TERMINATE_POSTED, tagDDECONV::flags, GETPTI, HMFreeObject(), HMIsMarkDestroy, HMMarkObjectDestroy(), NULL, tagDDECONV::pddei, PopState(), PtoH, SeDeleteClientSecurity, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, TIF_INCLEANUP, TRACE_DDE1, UnlinkConv(), Unlock, and VOID().

Referenced by xxxCleanupDdeConv(), xxxDDETrackGetMessageHook(), and xxxDDETrackWindowDying().

02044 { 02045 02046 TRACE_DDE1("FreeDdeConv(%#p)", pDdeConv); 02047 02048 if (!(pDdeConv->flags & CXF_TERMINATE_POSTED) && 02049 !HMIsMarkDestroy(pDdeConv->spwndPartner)) { 02050 _PostMessage(pDdeConv->spwndPartner, WM_DDE_TERMINATE, 02051 (WPARAM)PtoH(pDdeConv->spwnd), 0); 02052 // pDdeConv->flags |= CXF_TERMINATE_POSTED; set by PostHookProc 02053 } 02054 02055 if (pDdeConv->spartnerConv != NULL && 02056 GETPTI(pDdeConv)->TIF_flags & TIF_INCLEANUP) { 02057 /* 02058 * Fake that the other side already posted a terminate. 02059 * This prevents vestigal dde structures from hanging 02060 * around after thread cleanup if the conversation structure 02061 * is destroyed before the associated window. 02062 */ 02063 pDdeConv->spartnerConv->flags |= CXF_TERMINATE_POSTED; 02064 } 02065 02066 UnlinkConv(pDdeConv); 02067 02068 if (pDdeConv->pddei != NULL) { 02069 pDdeConv->pddei->cRefConv--; 02070 if (pDdeConv->pddei->cRefConv == 0 && pDdeConv->pddei->cRefInit == 0) { 02071 SeDeleteClientSecurity(&pDdeConv->pddei->ClientContext); 02072 UserFreePool(pDdeConv->pddei); 02073 } 02074 pDdeConv->pddei = NULL; 02075 } 02076 02077 Unlock(&(pDdeConv->spartnerConv)); 02078 Unlock(&(pDdeConv->spwndPartner)); 02079 Unlock(&(pDdeConv->spwnd)); 02080 02081 if (!HMMarkObjectDestroy((PHEAD)pDdeConv)) 02082 return; 02083 02084 while (pDdeConv->spxsOut) { 02085 PopState(pDdeConv); 02086 } 02087 02088 HMFreeObject(pDdeConv); 02089 }

VOID FreeDDEHandle PDDECONV  pDdeConv,
HANDLE  hClient,
DWORD  flags
 

Definition at line 1919 of file kernel/ddetrack.c.

References ClientFreeDDEHandle(), FreeListAdd(), PtiCurrent, TIF_16BIT, TRACE_DDE1, and VOID().

Referenced by xxxAdviseData(), xxxAdviseDataAck(), xxxDDETrackPostHook(), xxxPokeAck(), xxxUnexpectedClientPost(), and xxxUnexpectedServerPost().

01923 { 01924 if (PtiCurrent()->TIF_flags & TIF_16BIT) { 01925 TRACE_DDE1("FreeDDEHandle: (WOW hack) delayed Freeing %#p.", hClient); 01926 FreeListAdd(pDdeConv, hClient, flags); 01927 } else { 01928 TRACE_DDE1("FreeDDEHandle: Freeing %#p.", hClient); 01929 ClientFreeDDEHandle(hClient, flags); 01930 } 01931 }

VOID FreeDdeXact PXSTATE  pxs  ) 
 

Definition at line 2285 of file kernel/ddetrack.c.

References tagSHAREDINFO::aheList, tagINTDDEINFO::flags, tagXSTATE::flags, giheLast, gSharedInfo, tagXSTATE::head, tagINTDDEINFO::hIndirect, HMFreeObject(), HMMarkObjectDestroy(), NULL, tagXSTATE::pIntDdeInfo, RemovePublicObject(), tagXSTATE::snext, TYPE_DDECONV, TYPE_DDEXACT, ValidatePublicObjectList, VOID(), XS_ENHMETAFILE, XS_METAFILEPICT, and XS_PUBLICOBJ.

Referenced by FindQMsg(), PopState(), and xxxDDETrackGetMessageHook().

02287 { 02288 if (!HMMarkObjectDestroy(pxs)) 02289 return; 02290 02291 #if 0 02292 { 02293 int i; 02294 HANDLEENTRY *phe; 02295 02296 for (i = 0, phe = gSharedInfo.aheList; 02297 i <= giheLast; 02298 i++) { 02299 if (phe[i].bType == TYPE_DDEXACT) { 02300 UserAssert(((PXSTATE)(phe[i].phead))->snext != pxs); 02301 } 02302 if (phe[i].bType == TYPE_DDECONV) { 02303 UserAssert(((PDDECONV)(phe[i].phead))->spxsOut != pxs); 02304 UserAssert(((PDDECONV)(phe[i].phead))->spxsIn != pxs); 02305 } 02306 } 02307 } 02308 UserAssert(pxs->head.cLockObj == 0); 02309 UserAssert(pxs->snext == NULL); 02310 #endif 02311 02312 if (pxs->pIntDdeInfo != NULL) { 02313 /* 02314 * free any server-side GDI objects 02315 */ 02316 if (pxs->pIntDdeInfo->flags & (XS_METAFILEPICT | XS_ENHMETAFILE)) { 02317 GreDeleteServerMetaFile(pxs->pIntDdeInfo->hIndirect); 02318 } 02319 if (pxs->flags & XS_PUBLICOBJ) { 02320 RemovePublicObject(((PDDE_DATA)(pxs->pIntDdeInfo + 1))->wFmt, 02321 pxs->pIntDdeInfo->hIndirect); 02322 pxs->flags &= ~XS_PUBLICOBJ; 02323 } 02324 UserFreePool(pxs->pIntDdeInfo); 02325 } 02326 02327 HMFreeObject(pxs); 02328 ValidatePublicObjectList(); 02329 }

BOOL FreeListAdd PDDECONV  pDdeConv,
HANDLE  hClient,
DWORD  flags
 

Definition at line 1890 of file kernel/ddetrack.c.

References BOOL, FALSE, tagFREELIST::flags, FREELIST, tagFREELIST::h, tagDDECONV::head, tagFREELIST::next, tagDDECONV::pfl, _THROBJHEAD::pti, TRACE_DDE2, and TRUE.

Referenced by FreeDDEHandle(), xxxAdviseAck(), xxxAdviseDataAck(), xxxPokeAck(), and xxxRequestAck().

01894 { 01895 PFREELIST pfl; 01896 01897 pfl = (PFREELIST)UserAllocPool(sizeof(FREELIST), TAG_DDE1); 01898 if (!pfl) { 01899 return(FALSE); 01900 } 01901 TRACE_DDE2("FreeListAdd: %x for thread %x.", hClient, 01902 pDdeConv->head.pti->pEThread->Cid.UniqueThread); 01903 pfl->h = hClient; 01904 pfl->flags = flags; 01905 pfl->next = pDdeConv->pfl; 01906 pDdeConv->pfl = pfl; 01907 return(TRUE); 01908 }

VOID FreeListFree PFREELIST  pfl  ) 
 

Definition at line 1943 of file kernel/ddetrack.c.

References CheckCritIn, tagFREELIST::next, NULL, and VOID().

Referenced by xxxFreeListFree().

01945 { 01946 PFREELIST pflPrev; 01947 01948 CheckCritIn(); 01949 01950 UserAssert(pfl != NULL); 01951 01952 while (pfl != NULL) { 01953 pflPrev = pfl; 01954 pfl = pfl->next; 01955 UserFreePool(pflPrev); 01956 } 01957 }

BOOL GiveObject UINT  format,
HANDLE  hObj,
W32PID  pid
 

Definition at line 2427 of file kernel/ddetrack.c.

References FALSE, format, and TRUE.

Referenced by AddPublicObject(), RemovePublicObject(), xxxAdviseData(), xxxCopyAckIn(), xxxPoke(), and xxxRequestAck().

02431 { 02432 switch (format) { 02433 case CF_BITMAP: 02434 case CF_DSPBITMAP: 02435 GreSetBitmapOwner(hObj, pid); 02436 return(TRUE); 02437 02438 case CF_PALETTE: 02439 GreSetPaletteOwner(hObj, pid); 02440 return(TRUE); 02441 02442 default: 02443 return(FALSE); 02444 } 02445 }

PPUBOBJ IsObjectPublic HANDLE  hObj  ) 
 

Definition at line 2333 of file kernel/ddetrack.c.

References gpPublicObjectList, tagPUBOBJ::hObj, tagPUBOBJ::next, and NULL.

Referenced by AddPublicObject(), xxxAdviseData(), xxxPoke(), and xxxRequestAck().

02335 { 02336 PPUBOBJ ppo; 02337 02338 for (ppo = gpPublicObjectList; ppo != NULL; ppo = ppo->next) { 02339 if (ppo->hObj == hObj) { 02340 break; 02341 } 02342 } 02343 return(ppo); 02344 }

BOOL NewConversation PDDECONV ppdcNewClient,
PDDECONV ppdcNewServer,
PWND  pwndClient,
PWND  pwndServer
 

Definition at line 1766 of file kernel/ddetrack.c.

References AddConvProp(), BOOL, CXF_IS_SERVER, DDECONV, FALSE, GETPTI, HMAllocObject(), HMFreeObject(), NULL, TRUE, and TYPE_DDECONV.

Referenced by xxxDDETrackPostHook(), and xxxDDETrackSendHook().

01771 { 01772 PDDECONV pdcNewClient; 01773 PDDECONV pdcNewServer; 01774 01775 pdcNewClient = HMAllocObject(GETPTI(pwndClient), NULL, 01776 TYPE_DDECONV, sizeof(DDECONV)); 01777 if (pdcNewClient == NULL) { 01778 return(FALSE); 01779 } 01780 01781 pdcNewServer = HMAllocObject(GETPTI(pwndServer), NULL, 01782 TYPE_DDECONV, sizeof(DDECONV)); 01783 if (pdcNewServer == NULL) { 01784 HMFreeObject(pdcNewClient); // we know it's not locked. 01785 return(FALSE); 01786 } 01787 01788 AddConvProp(pwndClient, pwndServer, 0, pdcNewClient, pdcNewServer); 01789 AddConvProp(pwndServer, pwndClient, CXF_IS_SERVER, pdcNewServer, 01790 pdcNewClient); 01791 01792 if (ppdcNewClient != NULL) { 01793 *ppdcNewClient = pdcNewClient; 01794 } 01795 if (ppdcNewServer != NULL) { 01796 *ppdcNewServer = pdcNewServer; 01797 } 01798 return(TRUE); 01799 }

VOID PopState PDDECONV  pDdeConv  ) 
 

Definition at line 2001 of file kernel/ddetrack.c.

References tagSHAREDINFO::aheList, tagXSTATE::flags, FreeDdeXact(), giheLast, gSharedInfo, Lock, NULL, tagXSTATE::snext, tagDDECONV::spxsIn, tagDDECONV::spxsOut, ThreadLockAlways, ThreadUnlock, TYPE_DDEXACT, Unlock, VOID(), and XS_FREEPXS.

Referenced by DupConvTerminate(), FreeDdeConv(), xxxAdviseAck(), xxxAdviseDataAck(), xxxExecuteAck(), xxxPokeAck(), xxxRequestAck(), and xxxUnadviseAck().

02003 { 02004 PXSTATE pxsNext, pxsFree; 02005 TL tlpxs; 02006 02007 UserAssert(pDdeConv->spxsOut != NULL); 02008 #if 0 02009 { 02010 int i; 02011 HANDLEENTRY *phe; 02012 02013 for (i = 0, phe = gSharedInfo.aheList; 02014 i <= giheLast; 02015 i++) { 02016 if (phe[i].bType == TYPE_DDEXACT) { 02017 UserAssert(((PXSTATE)(phe[i].phead))->snext != pDdeConv->spxsOut); 02018 } 02019 } 02020 } 02021 #endif 02022 UserAssert(!(pDdeConv->spxsOut->flags & XS_FREEPXS)); 02023 UserAssert(pDdeConv->spxsIn != NULL); 02024 UserAssert(pDdeConv->spxsIn->snext == NULL); 02025 02026 ThreadLockAlways(pDdeConv->spxsOut, &tlpxs); // hold it fast 02027 pxsNext = pDdeConv->spxsOut->snext; 02028 pxsFree = Lock(&(pDdeConv->spxsOut), pxsNext); // lock next into head 02029 if (pxsNext == NULL) { 02030 UserAssert(pDdeConv->spxsIn == pxsFree); 02031 Unlock(&(pDdeConv->spxsIn)); // queue is empty. 02032 } else { 02033 Unlock(&(pxsFree->snext)); // clear next ptr 02034 } 02035 pxsFree = ThreadUnlock(&tlpxs); // undo our lock 02036 if (pxsFree != NULL) { 02037 FreeDdeXact(pxsFree); // cleanup. 02038 } 02039 }

BOOL RemovePublicObject UINT  format,
HANDLE  hObj
 

Definition at line 2385 of file kernel/ddetrack.c.

References BOOL, FALSE, format, GiveObject(), gpPublicObjectList, tagPUBOBJ::next, NULL, and TRUE.

Referenced by FreeDdeXact(), and xxxCopyAckIn().

02388 { 02389 PPUBOBJ ppo, ppoPrev; 02390 02391 switch (format) { 02392 case CF_BITMAP: 02393 case CF_DSPBITMAP: 02394 case CF_PALETTE: 02395 break; 02396 02397 default: 02398 return(FALSE); 02399 } 02400 02401 for (ppoPrev = NULL, ppo = gpPublicObjectList; 02402 ppo != NULL; 02403 ppoPrev = ppo, ppo = ppo->next) { 02404 if (ppo->hObj == hObj) { 02405 break; 02406 } 02407 } 02408 if (ppo == NULL) { 02409 UserAssert(FALSE); 02410 return(FALSE); 02411 } 02412 ppo->count--; 02413 if (ppo->count == 0) { 02414 GiveObject(format, hObj, ppo->pid); 02415 if (ppoPrev != NULL) { 02416 ppoPrev->next = ppo->next; 02417 } else { 02418 gpPublicObjectList = ppo->next; 02419 } 02420 UserFreePool(ppo); 02421 } 02422 return(TRUE); 02423 }

DWORD Request PDDECONV  pDdeConv  ) 
 

Definition at line 1221 of file kernel/ddetrack.c.

References AnticipatePost(), DO_POST, DWORD, FAIL_POST, NULL, tagDDECONV::spartnerConv, TRACE_DDE, and xxxRequestAck.

Referenced by IopQueryReconfiguration(), IopSendMessageToTrackService(), LpcpCreatePort(), RtlCallbackLpcClient(), SendRequest(), and xxxUnexpectedClientPost().

01223 { 01224 TRACE_DDE("Request"); 01225 if (AnticipatePost(pDdeConv->spartnerConv, xxxRequestAck, NULL, NULL, NULL, 0)) { 01226 return(DO_POST); 01227 } else { 01228 return(FAIL_POST); 01229 } 01230 }

DWORD SpontaneousTerminate PDWORD  pmessage,
PDDECONV  pDdeConv
 

Definition at line 1565 of file kernel/ddetrack.c.

References CXF_TERMINATE_POSTED, DO_POST, DWORD, FAKE_POST, tagDDECONV::flags, MSGFLAG_DDE_MID_THUNK, and TRACE_DDE.

Referenced by xxxUnexpectedClientPost(), and xxxUnexpectedServerPost().

01568 { 01569 TRACE_DDE("SpontaneousTerminate"); 01570 if (pDdeConv->flags & CXF_TERMINATE_POSTED) { 01571 return(FAKE_POST); 01572 } else { 01573 pDdeConv->flags |= CXF_TERMINATE_POSTED; 01574 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01575 return(DO_POST); 01576 } 01577 }

DWORD Unadvise PDDECONV  pDdeConv  ) 
 

Definition at line 1180 of file kernel/ddetrack.c.

References AnticipatePost(), DO_POST, DWORD, FAIL_POST, NULL, tagDDECONV::spartnerConv, TRACE_DDE, and xxxUnadviseAck.

Referenced by xxxUnexpectedClientPost().

01182 { 01183 TRACE_DDE("Unadvise"); 01184 if (AnticipatePost(pDdeConv->spartnerConv, xxxUnadviseAck, NULL, NULL, NULL, 0)) { 01185 return(DO_POST); 01186 } else { 01187 return(FAIL_POST); 01188 } 01189 }

PDDECONV UnlinkConv PDDECONV  pDdeConv  ) 
 

Definition at line 264 of file kernel/ddetrack.c.

References _GetProp(), HMUnlockObject, InternalRemoveProp(), InternalSetProp(), Lock, NULL, PROP_DDETRACK, PROPF_INTERNAL, tagDDECONV::snext, tagDDECONV::spwnd, TRACE_DDE1, and Unlock.

Referenced by FreeDdeConv(), and xxxDDETrackWindowDying().

00266 { 00267 PDDECONV pdcPrev, pdcT, pDdeConvNext; 00268 00269 /* 00270 * Already unlinked 00271 */ 00272 if (pDdeConv->spwnd == NULL) { 00273 return(NULL); 00274 } 00275 TRACE_DDE1("UnlinkConv(%#p)", pDdeConv); 00276 00277 pdcT = (PDDECONV)_GetProp(pDdeConv->spwnd, 00278 PROP_DDETRACK, PROPF_INTERNAL); 00279 if (pdcT == NULL) { 00280 return(NULL); // already unlinked 00281 } 00282 00283 pdcPrev = NULL; 00284 while (pdcT != pDdeConv) { 00285 pdcPrev = pdcT; 00286 pdcT = pdcT->snext; 00287 if (pdcT == NULL) { 00288 return(NULL); // already unlinked 00289 } 00290 } 00291 00292 if (pdcPrev == NULL) { 00293 if (pDdeConv->snext == NULL) { 00294 // last one out removes the property 00295 InternalRemoveProp(pDdeConv->spwnd, PROP_DDETRACK, PROPF_INTERNAL); 00296 } else { 00297 // head conv unlinked - update prop 00298 InternalSetProp(pDdeConv->spwnd, PROP_DDETRACK, pDdeConv->snext, 00299 PROPF_INTERNAL); 00300 } 00301 } else { 00302 Lock(&(pdcPrev->snext), pDdeConv->snext); 00303 } 00304 pDdeConvNext = Unlock(&(pDdeConv->snext)); 00305 HMUnlockObject(pDdeConv); // unlock for property detachment 00306 return(pDdeConvNext); 00307 }

DWORD xxxAdvise PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 942 of file kernel/ddetrack.c.

References AnticipatePost(), CheckLock, DO_POST, DWORD, FAILNOFREE_POST, MSGFLAG_DDE_MID_THUNK, NULL, tagDDECONV::spartnerConv, TRACE_DDE, XS_LOHANDLE, XS_PACKED, xxxAdviseAck, and xxxCopyDdeIn().

Referenced by xxxUnexpectedClientPost().

00946 { 00947 PINTDDEINFO pIntDdeInfo; 00948 HANDLE hDirect; 00949 DWORD flags, dwRet; 00950 00951 CheckLock(pDdeConv); 00952 00953 TRACE_DDE("xxxAdvise"); 00954 flags = XS_PACKED | XS_LOHANDLE; 00955 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, &hDirect, &pIntDdeInfo); 00956 if (dwRet == DO_POST) { 00957 UserAssert(pIntDdeInfo != NULL); 00958 *pmessage |= MSGFLAG_DDE_MID_THUNK; 00959 *plParam = (LPARAM)AnticipatePost(pDdeConv->spartnerConv, xxxAdviseAck, 00960 hDirect, NULL, pIntDdeInfo, flags); 00961 if (*plParam == 0) { 00962 dwRet = FAILNOFREE_POST; 00963 } 00964 } 00965 return dwRet; 00966 }

DWORD xxxAdviseAck PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 978 of file kernel/ddetrack.c.

References CheckLock, tagINTDDEINFO::DdePack, DO_POST, DWORD, tagXSTATE::flags, FreeListAdd(), tagXSTATE::hClient, tagXSTATE::hServer, NULL, PopState(), tagDDECONV::spartnerConv, tagDDECONV::spxsOut, TRACE_DDE, tagDDEPACK::uiLo, XS_PACKED, xxxCopyAckIn(), and xxxUnexpectedServerPost().

00982 { 00983 PXSTATE pxsFree; 00984 PINTDDEINFO pIntDdeInfo; 00985 DWORD dwRet; 00986 00987 CheckLock(pDdeConv); 00988 00989 if (*pmessage != WM_DDE_ACK) { 00990 return(xxxUnexpectedServerPost(pmessage, plParam, pDdeConv)); 00991 } 00992 00993 TRACE_DDE("xxxAdviseAck"); 00994 00995 dwRet = xxxCopyAckIn(pmessage, plParam, pDdeConv, &pIntDdeInfo); 00996 if (dwRet != DO_POST) { 00997 return dwRet; 00998 } 00999 UserAssert(pIntDdeInfo != NULL); 01000 01001 pxsFree = pDdeConv->spxsOut; 01002 if (pIntDdeInfo->DdePack.uiLo & DDE_FACK) { 01003 01004 /* 01005 * positive ack implies server accepted the hOptions data - free from 01006 * client at postmessage time. 01007 */ 01008 TRACE_DDE("xxxAdviseAck: +ACK delayed freeing data from client"); 01009 FreeListAdd(pDdeConv->spartnerConv, pxsFree->hClient, pxsFree->flags & ~XS_PACKED); 01010 } else { 01011 // Shouldn't this be freed directly? 01012 TRACE_DDE("xxxAdviseAck: -ACK delayed freeing data from server"); 01013 FreeListAdd(pDdeConv, pxsFree->hServer, pxsFree->flags & ~XS_PACKED); 01014 } 01015 01016 PopState(pDdeConv); 01017 return(DO_POST); 01018 }

DWORD xxxAdviseData PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1028 of file kernel/ddetrack.c.

References AddPublicObject(), AnticipatePost(), CheckLock, Createpxs(), DO_POST, DWORD, FAILNOFREE_POST, FreeDDEHandle(), GETPTI, GiveObject(), tagXSTATE::head, IsObjectPublic(), MSGFLAG_DDE_MID_THUNK, NULL, _THROBJHEAD::pti, PtoH, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, TRACE_DDE, TRACE_DDE1, XS_DATA, XS_FREEPXS, XS_FRELEASE, XS_GIVEBACKONNACK, XS_LOHANDLE, XS_PACKED, XS_PUBLICOBJ, xxxAdviseDataAck, and xxxCopyDdeIn().

Referenced by xxxRequestAck(), and xxxUnexpectedServerPost().

01032 { 01033 DWORD flags, dwRet; 01034 PINTDDEINFO pIntDdeInfo; 01035 HANDLE hDirect; 01036 PXSTATE pxs; 01037 01038 CheckLock(pDdeConv); 01039 01040 TRACE_DDE("xxxAdviseData"); 01041 01042 flags = XS_PACKED | XS_LOHANDLE | XS_DATA; 01043 01044 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, &hDirect, &pIntDdeInfo); 01045 if (dwRet == DO_POST) { 01046 UserAssert(pIntDdeInfo != NULL); 01047 TRACE_DDE1("xxxAdviseData: wStatus = %x", 01048 ((PDDE_DATA)(pIntDdeInfo + 1))->wStatus); 01049 if (!(((PDDE_DATA)(pIntDdeInfo + 1))->wStatus & (DDE_FACK | DDE_FRELEASE))) { 01050 RIPMSG0(RIP_ERROR, "DDE protocol violation - no RELEASE or ACK bit set - setting RELEASE."); 01051 ((PDDE_DATA)(pIntDdeInfo + 1))->wStatus |= DDE_FRELEASE; 01052 } 01053 if (((PDDE_DATA)(pIntDdeInfo + 1))->wStatus & DDE_FRELEASE) { 01054 /* 01055 * giving it away 01056 */ 01057 if (IsObjectPublic(pIntDdeInfo->hIndirect) != NULL) { 01058 RIPMSG0(RIP_ERROR, "DDE Protocol violation - giving away a public GDI object."); 01059 UserFreePool(pIntDdeInfo); 01060 return(FAILNOFREE_POST); 01061 } 01062 if (GiveObject(((PDDE_DATA)(pIntDdeInfo + 1))->wFmt, 01063 pIntDdeInfo->hIndirect, 01064 (W32PID)(GETPTI(pDdeConv->spwndPartner)->ppi->W32Pid))) { 01065 flags |= XS_GIVEBACKONNACK; 01066 } 01067 flags |= XS_FRELEASE; 01068 } else { 01069 /* 01070 * on loan 01071 */ 01072 if (AddPublicObject(((PDDE_DATA)(pIntDdeInfo + 1))->wFmt, 01073 pIntDdeInfo->hIndirect, 01074 (W32PID)(GETPTI(pDdeConv->spwnd)->ppi->W32Pid))) { 01075 flags |= XS_PUBLICOBJ; 01076 } 01077 } 01078 01079 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01080 if (((PDDE_DATA)(pIntDdeInfo + 1))->wStatus & DDE_FACK) { 01081 *plParam = (LPARAM)AnticipatePost(pDdeConv->spartnerConv, 01082 xxxAdviseDataAck, NULL, hDirect, pIntDdeInfo, flags); 01083 } else { 01084 TRACE_DDE("xxxAdviseData: dumping non Ackable data..."); 01085 UserAssert(hDirect != (HANDLE)*plParam); 01086 FreeDDEHandle(pDdeConv, hDirect, flags & ~XS_PACKED); 01087 pxs = Createpxs(NULL, NULL, NULL, pIntDdeInfo, flags | XS_FREEPXS); 01088 if (pxs != NULL) { 01089 pxs->head.pti = GETPTI(pDdeConv->spwndPartner); 01090 } 01091 *plParam = (LPARAM)PtoH(pxs); 01092 } 01093 if (*plParam == 0) { 01094 dwRet = FAILNOFREE_POST; 01095 } 01096 } 01097 return dwRet; 01098 }

DWORD xxxAdviseDataAck PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1113 of file kernel/ddetrack.c.

References CheckLock, tagINTDDEINFO::DdePack, DO_POST, DWORD, tagXSTATE::flags, FreeDDEHandle(), FreeListAdd(), tagXSTATE::hClient, tagXSTATE::hServer, NULL, PopState(), tagDDECONV::spartnerConv, tagDDECONV::spxsOut, TRACE_DDE, TRACE_DDE1, TRACE_DDE3, tagDDEPACK::uiLo, XS_FRELEASE, XS_PACKED, xxxCopyAckIn(), and xxxUnexpectedClientPost().

01117 { 01118 PXSTATE pxsFree; 01119 PINTDDEINFO pIntDdeInfo; 01120 DWORD dwRet; 01121 01122 CheckLock(pDdeConv); 01123 01124 /* 01125 * This is also used for request data ack processing. 01126 */ 01127 if (*pmessage != WM_DDE_ACK) { 01128 return(xxxUnexpectedClientPost(pmessage, plParam, pDdeConv)); 01129 } 01130 01131 TRACE_DDE("xxxAdviseDataAck"); 01132 01133 dwRet = xxxCopyAckIn(pmessage, plParam, pDdeConv, &pIntDdeInfo); 01134 if (dwRet != DO_POST) { 01135 return dwRet; 01136 } 01137 UserAssert(pIntDdeInfo != NULL); 01138 01139 pxsFree = pDdeConv->spxsOut; 01140 TRACE_DDE3("xxxAdviseDataAck:pxs.hClient(%#p), hServer(%#p), wStatus(%x)", 01141 pxsFree->hClient, pxsFree->hServer, pIntDdeInfo->DdePack.uiLo); 01142 if (pIntDdeInfo->DdePack.uiLo & DDE_FACK) { 01143 01144 /* 01145 * positive ack implies client accepted the data - free from 01146 * server at postmessage time iff FRELEASE was set in data msg. 01147 */ 01148 if (pxsFree->flags & XS_FRELEASE) { 01149 TRACE_DDE("xxxAdviseDataAck: +ACK delayed server data free"); 01150 FreeListAdd(pDdeConv->spartnerConv, pxsFree->hServer, 01151 pxsFree->flags & ~XS_PACKED); 01152 } else { 01153 /* 01154 * Ack w/out fRelease bit means client is done with data. 01155 */ 01156 TRACE_DDE1("xxxAdviseDataAck: Freeing %#p. (+ACK)", 01157 pxsFree->hClient); 01158 UserAssert(pxsFree->hClient != (HANDLE)*plParam); 01159 FreeDDEHandle(pDdeConv, pxsFree->hClient, pxsFree->flags & ~XS_PACKED); 01160 } 01161 01162 } else { 01163 TRACE_DDE1("xxxAdviseDataAck: Freeing %#p. (-ACK)", 01164 pxsFree->hClient); 01165 FreeDDEHandle(pDdeConv, pxsFree->hClient, pxsFree->flags & ~XS_PACKED); 01166 UserAssert(pxsFree->hClient != (HANDLE)*plParam); 01167 } 01168 PopState(pDdeConv); 01169 return(DO_POST); 01170 }

void xxxCleanupDdeConv PWND  pwndProp  ) 
 

Definition at line 548 of file kernel/ddetrack.c.

References _GetProp(), BOOL, CheckCritIn, CXF_IS_SERVER, CXF_PARTNER_WINDOW_DIED, CXF_TERMINATE_POSTED, tagDDECONV::flags, FreeDdeConv(), NULL, tagDDECONV::pfl, PROP_DDETRACK, PROPF_INTERNAL, tagDDECONV::snext, tagDDECONV::spartnerConv, ThreadLockAlways, ThreadUnlock, and xxxFreeListFree().

Referenced by xxxDDETrackGetMessageHook().

00550 { 00551 PDDECONV pDdeConv; 00552 00553 Restart: 00554 00555 CheckCritIn(); 00556 00557 pDdeConv = (PDDECONV)_GetProp(pwndProp, PROP_DDETRACK, PROPF_INTERNAL); 00558 00559 while (pDdeConv != NULL) { 00560 if ((pDdeConv->flags & (CXF_IS_SERVER | CXF_TERMINATE_POSTED | CXF_PARTNER_WINDOW_DIED)) 00561 == (CXF_IS_SERVER | CXF_TERMINATE_POSTED | CXF_PARTNER_WINDOW_DIED) && 00562 00563 (pDdeConv->spartnerConv->flags & CXF_TERMINATE_POSTED)) { 00564 00565 /* 00566 * clean up client side objects on this side 00567 */ 00568 BOOL fUnlockDdeConv; 00569 TL tlpDdeConv; 00570 00571 RIPMSG1(RIP_VERBOSE, "xxxCleanupDdeConv %p", pDdeConv); 00572 00573 fUnlockDdeConv = (pDdeConv->pfl != NULL); 00574 if (fUnlockDdeConv) { 00575 PFREELIST pfl; 00576 00577 ThreadLockAlways(pDdeConv, &tlpDdeConv); 00578 00579 pfl = pDdeConv->pfl; 00580 pDdeConv->pfl = NULL; 00581 xxxFreeListFree(pfl); 00582 } 00583 00584 FreeDdeConv(pDdeConv->spartnerConv); 00585 FreeDdeConv(pDdeConv); 00586 00587 if (fUnlockDdeConv) { 00588 ThreadUnlock(&tlpDdeConv); 00589 } 00590 00591 /* 00592 * Take it back from the top. The list might have changed 00593 * if we left the critical section 00594 */ 00595 goto Restart; 00596 } 00597 00598 pDdeConv = pDdeConv->snext; 00599 } 00600 }

DWORD xxxClientCopyDDEIn1 HANDLE  hClient,
DWORD  flags,
PINTDDEINFO ppi
 

Referenced by xxxCopyDdeIn().

HANDLE xxxClientCopyDDEOut1 PINTDDEINFO  pIntDdeInfo  ) 
 

Referenced by xxxCopyDDEOut().

DWORD xxxClientCopyDDEOut2 PINTDDEINFO  pIntDdeInfo  ) 
 

DWORD xxxCopyAckIn LPDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv,
PINTDDEINFO ppIntDdeInfo
 

Definition at line 1835 of file kernel/ddetrack.c.

References CheckLock, Createpxs(), DO_POST, DWORD, FAILNOFREE_POST, tagXSTATE::flags, GETPTI, GiveObject(), tagXSTATE::head, tagINTDDEINFO::hIndirect, MSGFLAG_DDE_MID_THUNK, NULL, tagXSTATE::pIntDdeInfo, _THROBJHEAD::pti, PtoH, RemovePublicObject(), tagDDECONV::spwndPartner, tagDDECONV::spxsOut, XS_FREEPXS, XS_FREESRC, XS_GIVEBACKONNACK, XS_PACKED, XS_PUBLICOBJ, and xxxCopyDdeIn().

Referenced by xxxAdviseAck(), xxxAdviseDataAck(), xxxPokeAck(), xxxRequestAck(), and xxxUnadviseAck().

01840 { 01841 PINTDDEINFO pIntDdeInfo; 01842 DWORD flags, dwRet; 01843 PXSTATE pxs; 01844 01845 CheckLock(pDdeConv); 01846 01847 flags = XS_PACKED | XS_FREESRC; 01848 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, NULL, ppIntDdeInfo); 01849 if (dwRet == DO_POST) { 01850 UserAssert(*ppIntDdeInfo != NULL); 01851 pIntDdeInfo = *ppIntDdeInfo; 01852 if (pDdeConv->spxsOut->flags & XS_GIVEBACKONNACK && 01853 !(((PDDE_DATA)(pIntDdeInfo + 1))->wStatus & DDE_FACK)) { 01854 GiveObject(((PDDE_DATA)(pDdeConv->spxsOut->pIntDdeInfo + 1))->wFmt, 01855 pDdeConv->spxsOut->pIntDdeInfo->hIndirect, 01856 (W32PID)GETPTI(pDdeConv->spwndPartner)->ppi->W32Pid); 01857 } 01858 if (pDdeConv->spxsOut->flags & XS_PUBLICOBJ) { 01859 RemovePublicObject(((PDDE_DATA)(pDdeConv->spxsOut->pIntDdeInfo + 1))->wFmt, 01860 pDdeConv->spxsOut->pIntDdeInfo->hIndirect); 01861 pDdeConv->spxsOut->flags &= ~XS_PUBLICOBJ; 01862 } 01863 pxs = Createpxs(NULL, NULL, NULL, pIntDdeInfo, flags | XS_FREEPXS); 01864 if (pxs != NULL) { 01865 pxs->head.pti = GETPTI(pDdeConv->spwndPartner); 01866 } 01867 *plParam = (LPARAM)PtoH(pxs); 01868 if (*plParam == 0) { 01869 return FAILNOFREE_POST; 01870 } 01871 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01872 } 01873 return dwRet; 01874 }

DWORD xxxCopyAckIn PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv,
PINTDDEINFO ppIntDdeInfo
 

DWORD xxxCopyDdeIn HANDLE  hSrc,
PDWORD  pflags,
PHANDLE  phDirect,
PINTDDEINFO ppi
 

Definition at line 2104 of file kernel/ddetrack.c.

References tagINTDDEINFO::DdePack, DO_POST, DWORD, tagINTDDEINFO::flags, tagINTDDEINFO::hDirect, NULL, TRACE_DDE2, TRACE_DDE3, tagDDEPACK::uiHi, tagDDEPACK::uiLo, XS_FREESRC, and xxxClientCopyDDEIn1().

Referenced by xxxAdvise(), xxxAdviseData(), xxxCopyAckIn(), xxxExecute(), xxxExecuteAck(), xxxPoke(), and xxxRequestAck().

02109 { 02110 DWORD dwRet; 02111 PINTDDEINFO pi; 02112 02113 dwRet = xxxClientCopyDDEIn1(hSrc, *pflags, ppi); 02114 pi = *ppi; 02115 TRACE_DDE2(*pflags & XS_FREESRC ? 02116 "Copying in and freeing %#p(%#p)" : 02117 "Copying in %#p(%#p)", 02118 hSrc, pi ? pi->hDirect : 0); 02119 02120 if (dwRet == DO_POST) { 02121 UserAssert(*ppi != NULL); 02122 *pflags = pi->flags; 02123 TRACE_DDE3("xxxCopyDdeIn: uiLo=%x, uiHi=%x, hDirect=%#p", 02124 pi->DdePack.uiLo, pi->DdePack.uiHi, pi->hDirect); 02125 if (phDirect != NULL) { 02126 *phDirect = pi->hDirect; 02127 } 02128 } 02129 #if DBG 02130 else { 02131 RIPMSG0(RIP_WARNING, "Unable to alloc DDE INTDDEINFO"); 02132 } 02133 #endif 02134 02135 return(dwRet); 02136 }

HANDLE xxxCopyDDEOut PINTDDEINFO  pIntDdeInfo,
PHANDLE  phDirect
 

Definition at line 2149 of file kernel/ddetrack.c.

References tagINTDDEINFO::cbDirect, tagINTDDEINFO::cbIndirect, tagINTDDEINFO::DdePack, tagINTDDEINFO::flags, tagINTDDEINFO::hDirect, NULL, TRACE_DDE1, TRACE_DDE3, tagDDEPACK::uiHi, tagDDEPACK::uiLo, and xxxClientCopyDDEOut1().

Referenced by xxxDDETrackGetMessageHook().

02152 { 02153 HANDLE hDst; 02154 02155 TRACE_DDE3("xxxCopyDDEOut: cbDirect=%x, cbIndirect=%x, flags=%x", 02156 pi->cbDirect, pi->cbIndirect, pi->flags); 02157 hDst = xxxClientCopyDDEOut1(pi); 02158 TRACE_DDE3("xxxCopyDDEOut: uiLo=%x, uiHi=%x, hResult=%#p", 02159 pi->DdePack.uiLo, pi->DdePack.uiHi, hDst); 02160 if (hDst != NULL) { 02161 if (phDirect != NULL) { 02162 TRACE_DDE1("xxxCopyDDEOut: *phDirect=%#p", pi->hDirect); 02163 *phDirect = pi->hDirect; 02164 } 02165 } 02166 return(hDst); 02167 }

VOID xxxDDETrackGetMessageHook PMSG  pmsg  ) 
 

Definition at line 618 of file kernel/ddetrack.c.

References BOOL, CXF_IS_SERVER, CXF_TERMINATE_POSTED, DWORD, FALSE, FindDdeConv(), tagDDECONV::flags, tagXSTATE::flags, FreeDdeConv(), FreeDdeXact(), GetAppCompatFlags2(), tagXSTATE::hClient, HMValidateHandleNoRip(), tagXSTATE::hServer, NULL, tagDDECONV::pfl, tagXSTATE::pIntDdeInfo, RevalidateCatHwnd, tagDDECONV::spartnerConv, ThreadLockAlways, ThreadUnlock, TRACE_DDE, TRACE_DDE1, TRACE_DDE2, TraceDdeMsg, TRUE, TYPE_DDEXACT, ValidateHwnd, VOID(), XS_FREEPXS, xxxCleanupDdeConv(), xxxCopyDDEOut(), and xxxFreeListFree().

Referenced by xxxReadPostMessage().

00620 { 00621 PXSTATE pxs; 00622 HANDLE hDirect; 00623 DWORD flags; 00624 BOOL fUnlockDdeConv; 00625 TL tlpDdeConv, tlpxs; 00626 00627 TraceDdeMsg(pmsg->message, (HWND)pmsg->wParam, pmsg->hwnd, MSG_RECV); 00628 00629 if (pmsg->message == WM_DDE_TERMINATE) { 00630 PWND pwndFrom, pwndTo; 00631 PDDECONV pDdeConv; 00632 00633 pwndTo = ValidateHwnd(pmsg->hwnd); 00634 00635 /* 00636 * We should get the pwnd even if the partner is destroyed in order 00637 * to clean up the DDE objects now. Exiting now would work, but would 00638 * leave the conversation objects locked and present until the To window 00639 * gets destroyed, which seems excessive. 00640 */ 00641 pwndFrom = RevalidateCatHwnd((HWND)pmsg->wParam); 00642 00643 if (pwndTo == NULL) { 00644 TRACE_DDE("TERMINATE ignored, invalid window(s)."); 00645 return; 00646 00647 } else if (pwndFrom == NULL) { 00648 00649 CleanupAndExit: 00650 /* 00651 * Do this only for appcompat 00652 */ 00653 if (GetAppCompatFlags2(VERMAX) & GACF2_DDE) { 00654 xxxCleanupDdeConv(pwndTo); 00655 } else { 00656 TRACE_DDE("TERMINATE ignored, invalid window(s)."); 00657 } 00658 return; 00659 } 00660 00661 /* 00662 * locate conversation info. 00663 */ 00664 pDdeConv = FindDdeConv(pwndTo, pwndFrom); 00665 if (pDdeConv == NULL) { 00666 /* 00667 * Must be a harmless extra terminate. 00668 */ 00669 TRACE_DDE("TERMINATE ignored, conversation not found."); 00670 return; 00671 } 00672 00673 if (pDdeConv->flags & CXF_TERMINATE_POSTED && 00674 pDdeConv->spartnerConv->flags & CXF_TERMINATE_POSTED) { 00675 00676 /* 00677 * clean up client side objects on this side 00678 */ 00679 fUnlockDdeConv = FALSE; 00680 if (pDdeConv->pfl != NULL) { 00681 PFREELIST pfl; 00682 00683 fUnlockDdeConv = TRUE; 00684 ThreadLockAlways(pDdeConv, &tlpDdeConv); 00685 pfl = pDdeConv->pfl; 00686 pDdeConv->pfl = NULL; 00687 xxxFreeListFree(pfl); 00688 } 00689 00690 TRACE_DDE2("DDE conversation (%#p:%#p) closed", 00691 (pDdeConv->flags & CXF_IS_SERVER) ? pmsg->wParam : (ULONG_PTR)pmsg->hwnd, 00692 (pDdeConv->flags & CXF_IS_SERVER) ? (ULONG_PTR)pmsg->hwnd : pmsg->wParam); 00693 00694 FreeDdeConv(pDdeConv->spartnerConv); 00695 FreeDdeConv(pDdeConv); 00696 00697 if (fUnlockDdeConv) { 00698 ThreadUnlock(&tlpDdeConv); 00699 } 00700 } 00701 00702 goto CleanupAndExit; 00703 } 00704 00705 pxs = (PXSTATE)HMValidateHandleNoRip((HANDLE)pmsg->lParam, TYPE_DDEXACT); 00706 if (pxs == NULL) { 00707 /* 00708 * The posting window has died and the pxs was freed so this 00709 * message shouldn't be bothered with...map to WM_NULL. 00710 */ 00711 pmsg->lParam = 0; 00712 pmsg->message = WM_NULL; 00713 return; 00714 } 00715 flags = pxs->flags; 00716 00717 ThreadLockAlways(pxs, &tlpxs); 00718 pmsg->lParam = (LPARAM)xxxCopyDDEOut(pxs->pIntDdeInfo, &hDirect); 00719 if (pmsg->lParam == (LPARAM)NULL) { 00720 /* 00721 * Turn this message into a terminate - we failed to copy the 00722 * message data out which implies we are too low on memory 00723 * to continue the conversation. Shut it down now before 00724 * other problems pop up that this failure will cause. 00725 */ 00726 pmsg->message = WM_DDE_TERMINATE; 00727 RIPMSG0(RIP_WARNING, "DDETrack: couldn't copy data out, terminate faked."); 00728 } 00729 if (ThreadUnlock(&tlpxs) == NULL) { 00730 return; 00731 } 00732 00733 if (flags & XS_FREEPXS) { 00734 FreeDdeXact(pxs); 00735 return; 00736 } 00737 00738 /* 00739 * The only reason XS_FREEPXS isn't set is because we don't know which 00740 * side frees the data till an ACK comes back, thus one of the client 00741 * handles in pxs is already set via xxxDDETrackPostHook(). The one thats 00742 * not yet set gets set here. 00743 */ 00744 00745 if (pxs->hClient == NULL) { 00746 TRACE_DDE1("Saving %#p into hClient", hDirect); 00747 pxs->hClient = hDirect; 00748 } else { 00749 TRACE_DDE1("Saving %#p into hServer.", hDirect); 00750 pxs->hServer = hDirect; 00751 } 00752 return; 00753 }

DWORD xxxDDETrackPostHook PUINT  pmessage,
PWND  pwndTo,
WPARAM  wParam,
LPARAM *  plParam,
BOOL  fSent
 

Definition at line 320 of file kernel/ddetrack.c.

References CheckLock, ClientGetDDEHookData(), CXF_IS_SERVER, CXF_PARTNER_WINDOW_DIED, CXF_TERMINATE_POSTED, DO_POST, DWORD, FAIL_POST, FAILNOFREE_POST, FAKE_POST, FindDdeConv(), tagDDECONV::flags, tagXSTATE::fnResponse, FreeDDEHandle(), GETPTI, GETPWNDPPI, tagWND::head, MonitorFlags, NewConversation(), tagFREELIST::next, NULL, tagDDECONV::pfl, PtiCurrent, PtoH, tagDDECONV::spartnerConv, tagDDECONV::spxsOut, ThreadLockAlways, ThreadUnlock, TIF_16BIT, TIF_INCLEANUP, TRACE_DDE, TraceDdeMsg, ValidateHwnd, VER40, XS_DATA, XS_DUMPMSG, XS_EXECUTE, XS_HIHANDLE, XS_LOHANDLE, XS_PACKED, xxxFreeListFree(), xxxMessageEvent(), xxxUnexpectedClientPost(), and xxxUnexpectedServerPost().

Referenced by _PostMessage(), and MESSAGECALL().

00326 { 00327 PWND pwndFrom; 00328 PDDECONV pDdeConv = NULL; 00329 DWORD dwRet; 00330 TL tlpDdeConv; 00331 PFREELIST pfl, *ppfl; 00332 DWORD MFlag; 00333 00334 CheckLock(pwndTo); 00335 00336 MFlag = fSent ? MF_SENDMSGS : MF_POSTMSGS; 00337 if (MonitorFlags & MFlag) { 00338 DDEML_MSG_HOOK_DATA dmhd; 00339 00340 switch (*pmessage ) { 00341 case WM_DDE_DATA: 00342 case WM_DDE_POKE: 00343 case WM_DDE_ADVISE: 00344 case WM_DDE_EXECUTE: 00345 case WM_DDE_ACK: 00346 ClientGetDDEHookData(*pmessage, *plParam, &dmhd); 00347 break; 00348 00349 default: 00350 // WM_DDE_REQUEST 00351 // WM_DDE_TERMINATE 00352 // WM_DDE_UNADVISE 00353 dmhd.cbData = 0; 00354 dmhd.uiLo = LOWORD(*plParam); 00355 dmhd.uiHi = HIWORD(*plParam); 00356 } 00357 xxxMessageEvent(pwndTo, *pmessage, wParam, *plParam, MFlag, 00358 &dmhd); 00359 } 00360 00361 if (PtiCurrent()->ppi == GETPWNDPPI(pwndTo)) { 00362 /* 00363 * skip all intra-process conversation tracking. 00364 */ 00365 dwRet = DO_POST; 00366 goto Exit; 00367 } 00368 00369 if (*pmessage == WM_DDE_INITIATE) { 00370 RIPMSG2(RIP_WARNING, 00371 "DDE Post failed (%#p:%#p) - WM_DDE_INITIATE posted", 00372 wParam, PtoH(pwndTo)); 00373 dwRet = FAIL_POST; 00374 goto Exit; 00375 } 00376 00377 pwndFrom = ValidateHwnd((HWND)wParam); 00378 if (pwndFrom == NULL) { 00379 /* 00380 * This is a post AFTER a window has been destroyed. This is not 00381 * expected except in the case where xxxDdeTrackWindowDying() 00382 * is posting a cleanup terminate. 00383 */ 00384 dwRet = *pmessage == WM_DDE_TERMINATE ? DO_POST : FAKE_POST; 00385 goto Exit; 00386 } 00387 00388 /* 00389 * locate conversation info. 00390 */ 00391 pDdeConv = FindDdeConv(pwndFrom, pwndTo); 00392 if (pDdeConv == NULL) { 00393 if (*pmessage != WM_DDE_TERMINATE && 00394 (GETPTI(pwndFrom)->TIF_flags & TIF_16BIT) && 00395 (pwndTo->head.rpdesk == pwndFrom->head.rpdesk)) { 00396 /* 00397 * If a WOW app bypasses initiates and posts directly to 00398 * a window on the same desktop, let it sneak by here. 00399 * 00400 * This allows some evil apps such as OpenEngine and CA-Cricket 00401 * to get away with murder. 00402 * 00403 * TERMINATES out of the blue however may be due to an app 00404 * posting its WM_DDE_TERMINATE after it has destroyed its 00405 * window. Since window destruction would have generated the 00406 * TERMINATE already, don't let it through here. 00407 */ 00408 NewConversation(&pDdeConv, NULL, pwndFrom, pwndTo); 00409 } 00410 if (pDdeConv == NULL) { 00411 RIPMSG2(RIP_VERBOSE, "Can't find DDE conversation for (%#p:%#p).", 00412 wParam, PtoH(pwndTo)); 00413 dwRet = *pmessage == WM_DDE_TERMINATE ? FAKE_POST : FAIL_POST; 00414 goto Exit; 00415 } 00416 } 00417 00418 if (fSent && pDdeConv->spartnerConv->spxsOut != NULL) { 00419 /* 00420 * Sent DDE messages will not work if any posted DDE messages are 00421 * in the queue because this will violate the message ordering rule. 00422 */ 00423 RIPMSG0(RIP_VERBOSE, 00424 "Sent DDE message failed - queue contains a previous post."); 00425 dwRet = FAIL_POST; 00426 goto Exit; 00427 } 00428 00429 /* 00430 * The tracking layer never did allow multiple threads to handle 00431 * the same DDE conversation but win95 shipped and some apps 00432 * got out there that did just this. We will let it slide for 00433 * 4.0 apps only so that when they rev their app, they will see 00434 * that they were wrong. 00435 */ 00436 if (PtiCurrent() != GETPTI(pDdeConv) && 00437 PtiCurrent()->dwExpWinVer != VER40) { 00438 RIPERR0(ERROR_WINDOW_OF_OTHER_THREAD, 00439 RIP_ERROR, 00440 "Posting DDE message from wrong thread!"); 00441 00442 dwRet = FAIL_POST; 00443 goto Exit; 00444 } 00445 00446 ThreadLockAlways(pDdeConv, &tlpDdeConv); 00447 00448 /* 00449 * If the handle we're using is in the free list, remove it 00450 */ 00451 ppfl = &pDdeConv->pfl; 00452 while (*ppfl != NULL) { 00453 if ((*ppfl)->h == (HANDLE)*plParam) { 00454 /* Let's stop to check this out */ 00455 UserAssert((*ppfl)->h == (HANDLE)*plParam); 00456 *ppfl = (*ppfl)->next; 00457 } else { 00458 ppfl = &(*ppfl)->next; 00459 } 00460 } 00461 pfl = pDdeConv->pfl; 00462 pDdeConv->pfl = NULL; 00463 xxxFreeListFree(pfl); 00464 00465 if (*pmessage != WM_DDE_TERMINATE && 00466 (pDdeConv->flags & (CXF_TERMINATE_POSTED | CXF_PARTNER_WINDOW_DIED))) { 00467 dwRet = FAKE_POST; 00468 goto UnlockExit; 00469 } 00470 00471 if (pDdeConv->spxsOut == NULL) { 00472 if (pDdeConv->flags & CXF_IS_SERVER) { 00473 dwRet = xxxUnexpectedServerPost((PDWORD)pmessage, plParam, pDdeConv); 00474 } else { 00475 dwRet = xxxUnexpectedClientPost((PDWORD)pmessage, plParam, pDdeConv); 00476 } 00477 } else { 00478 dwRet = (pDdeConv->spxsOut->fnResponse)(pmessage, plParam, pDdeConv); 00479 } 00480 00481 UnlockExit: 00482 00483 ThreadUnlock(&tlpDdeConv); 00484 00485 Exit: 00486 00487 if (dwRet == FAKE_POST && !((PtiCurrent())->TIF_flags & TIF_INCLEANUP)) { 00488 /* 00489 * We faked the post so do a client side cleanup here so that we 00490 * don't make it appear there is a leak in the client app. 00491 */ 00492 DWORD flags = XS_DUMPMSG; 00493 /* 00494 * The XS_DUMPMSG tells FreeDDEHandle to also free the atoms 00495 * associated with the data - since a faked post would make the app 00496 * think that the receiver was going to cleanup the atoms. 00497 * It also tells FreeDDEHandle to pay attention to the 00498 * fRelease bit when freeing the data - this way, loaned data 00499 * won't be destroyed. 00500 */ 00501 00502 switch (*pmessage & 0xFFFF) { 00503 case WM_DDE_UNADVISE: 00504 case WM_DDE_REQUEST: 00505 goto DumpMsg; 00506 00507 case WM_DDE_ACK: 00508 flags |= XS_PACKED; 00509 goto DumpMsg; 00510 00511 case WM_DDE_ADVISE: 00512 flags |= XS_PACKED | XS_HIHANDLE; 00513 goto DumpMsg; 00514 00515 case WM_DDE_DATA: 00516 case WM_DDE_POKE: 00517 flags |= XS_DATA | XS_LOHANDLE | XS_PACKED; 00518 goto DumpMsg; 00519 00520 case WM_DDE_EXECUTE: 00521 flags |= XS_EXECUTE; 00522 // fall through 00523 DumpMsg: 00524 if (pDdeConv != NULL) { 00525 TRACE_DDE("xxxDdeTrackPostHook: dumping message..."); 00526 FreeDDEHandle(pDdeConv, (HANDLE)*plParam, flags); 00527 dwRet = FAILNOFREE_POST; 00528 } 00529 } 00530 } 00531 #if DBG 00532 if (fSent) { 00533 TraceDdeMsg(*pmessage, (HWND)wParam, PtoH(pwndTo), MSG_SENT); 00534 } else { 00535 TraceDdeMsg(*pmessage, (HWND)wParam, PtoH(pwndTo), MSG_POST); 00536 } 00537 if (dwRet == FAKE_POST) { 00538 TRACE_DDE("...FAKED!"); 00539 } else if (dwRet == FAIL_POST) { 00540 TRACE_DDE("...FAILED!"); 00541 } else if (dwRet == FAILNOFREE_POST) { 00542 TRACE_DDE("...FAILED, DATA FREED!"); 00543 } 00544 #endif // DBG 00545 return(dwRet); 00546 }

BOOL xxxDDETrackSendHook PWND  pwndTo,
DWORD  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 147 of file kernel/ddetrack.c.

References _PostMessage(), AnticipatePost(), BOOL, DupConvTerminate, FALSE, FindDdeConv(), GETPWNDPPI, MonitorFlags, NewConversation(), NULL, PtiCurrent, PtoH, TRACE_DDE2, TRUE, ValidateHwnd, and xxxMessageEvent().

Referenced by xxxSendMessageTimeout().

00152 { 00153 PWND pwndServer; 00154 PDDECONV pdcNewClient, pdcNewServer; 00155 00156 if (MonitorFlags & MF_SENDMSGS) { 00157 DDEML_MSG_HOOK_DATA dmhd; 00158 00159 dmhd.cbData = 0; // Initiate and Ack sent messages have no data. 00160 dmhd.uiLo = LOWORD(lParam); // they arn't packed either. 00161 dmhd.uiHi = HIWORD(lParam); 00162 xxxMessageEvent(pwndTo, message, wParam, lParam, MF_SENDMSGS, &dmhd); 00163 } 00164 00165 if (PtiCurrent()->ppi == GETPWNDPPI(pwndTo)) { 00166 /* 00167 * Skip monitoring of all intra-process conversations. 00168 */ 00169 return(TRUE); 00170 } 00171 00172 if (message != WM_DDE_ACK) { 00173 if (message == WM_DDE_INITIATE) { 00174 return TRUE; // this is cool 00175 } 00176 return(FALSE); 00177 } 00178 00179 pwndServer = ValidateHwnd((HWND)wParam); 00180 if (pwndServer == NULL) { 00181 return(FALSE); 00182 } 00183 00184 pdcNewServer = FindDdeConv(pwndServer, pwndTo); 00185 if (pdcNewServer != NULL) { 00186 RIPMSG2(RIP_WARNING, 00187 "DDE protocol violation - non-unique window pair (%#p:%#p)", 00188 PtoH(pwndTo), PtoH(pwndServer)); 00189 /* 00190 * Duplicate Conversation case: 00191 * Don't allow the ACK to pass, post a terminate to the server 00192 * to shut down the duplicate on his end. 00193 */ 00194 AnticipatePost(pdcNewServer, DupConvTerminate, NULL, NULL, NULL, 0); 00195 _PostMessage(pwndServer, WM_DDE_TERMINATE, (WPARAM)PtoH(pwndTo), 0); 00196 return(FALSE); 00197 } 00198 00199 if (!NewConversation(&pdcNewClient, &pdcNewServer, pwndTo, pwndServer)) { 00200 return(FALSE); 00201 } 00202 00203 TRACE_DDE2("%#p->%#p DDE Conversation started", PtoH(pwndTo), wParam); 00204 return(TRUE); 00205 }

VOID xxxDDETrackWindowDying PWND  pwnd,
PDDECONV  pDdeConv
 

Definition at line 768 of file kernel/ddetrack.c.

References _PostMessage(), CheckLock, CXF_PARTNER_WINDOW_DIED, CXF_TERMINATE_POSTED, tagDDECONV::flags, FreeDdeConv(), GetAppCompatFlags2(), GetAppCompatFlags2ForPti(), GETPTI, NULL, tagDDECONV::pfl, PtoH, tagDDECONV::snext, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, ThreadLock, ThreadLockAlways, ThreadUnlock, TRACE_DDE2, UnlinkConv(), VER40, VOID(), and xxxFreeListFree().

Referenced by xxxFreeWindow().

00771 { 00772 TL tlpDdeConv, tlpDdeConvNext; 00773 00774 UNREFERENCED_PARAMETER(pwnd); 00775 00776 CheckLock(pwnd); 00777 CheckLock(pDdeConv); 00778 00779 TRACE_DDE2("xxxDDETrackWindowDying(%#p, %#p)", PtoH(pwnd), pDdeConv); 00780 00781 while (pDdeConv != NULL) { 00782 00783 PFREELIST pfl; 00784 00785 /* 00786 * If there are any active conversations for this window 00787 * start termination if not already started. 00788 */ 00789 if (!(pDdeConv->flags & CXF_TERMINATE_POSTED)) { 00790 /* 00791 * Win9x doesn't do any tracking. This breaks some apps that 00792 * destroy the window first and then post the terminate. The 00793 * other side gets two terminates. 00794 */ 00795 if (!(GACF2_NODDETRKDYING & GetAppCompatFlags2(VER40)) 00796 || (pDdeConv->spwndPartner == NULL) 00797 || !(GACF2_NODDETRKDYING 00798 & GetAppCompatFlags2ForPti(GETPTI(pDdeConv->spwndPartner), VER40))) { 00799 00800 /* 00801 * CXF_TERMINATE_POSTED would have been set if the window had died. 00802 */ 00803 _PostMessage(pDdeConv->spwndPartner, WM_DDE_TERMINATE, 00804 (WPARAM)PtoH(pDdeConv->spwnd), 0); 00805 // pDdeConv->flags |= CXF_TERMINATE_POSTED; set by PostHookProc 00806 } else { 00807 RIPMSG2(RIP_WARNING, "xxxDDETrackWindowDying(GACF2_NODDETRKDYING) not posting terminate from %#p to %#p\r\n", 00808 pwnd, pDdeConv->spwndPartner); 00809 } 00810 } 00811 00812 /* 00813 * now fake that the other side already posted a terminate since 00814 * we will be gone. 00815 */ 00816 pDdeConv->spartnerConv->flags |= 00817 CXF_TERMINATE_POSTED | CXF_PARTNER_WINDOW_DIED; 00818 00819 ThreadLock(pDdeConv->snext, &tlpDdeConvNext); 00820 ThreadLockAlways(pDdeConv, &tlpDdeConv); 00821 00822 pfl = pDdeConv->pfl; 00823 pDdeConv->pfl = NULL; 00824 00825 if (pDdeConv->flags & CXF_PARTNER_WINDOW_DIED) { 00826 00827 ThreadUnlock(&tlpDdeConv); 00828 /* 00829 * he's already gone, free up conversation tracking data 00830 */ 00831 FreeDdeConv(pDdeConv->spartnerConv); 00832 FreeDdeConv(pDdeConv); 00833 } else { 00834 UnlinkConv(pDdeConv); 00835 ThreadUnlock(&tlpDdeConv); 00836 } 00837 xxxFreeListFree(pfl); 00838 00839 pDdeConv = ThreadUnlock(&tlpDdeConvNext); 00840 } 00841 }

DWORD xxxExecute PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1460 of file kernel/ddetrack.c.

References AnticipatePost(), CheckLock, DO_POST, DWORD, FAILNOFREE_POST, GETPTI, MSGFLAG_DDE_MID_THUNK, NULL, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, TestWF, TIF_ALLOWFOREGROUNDACTIVATE, TRACE_DDE, WFANSIPROC, XS_EXECUTE, XS_UNICODE, xxxCopyDdeIn(), and xxxExecuteAck.

Referenced by xxxUnexpectedClientPost().

01464 { 01465 DWORD flags, dwRet; 01466 PINTDDEINFO pIntDdeInfo; 01467 HANDLE hDirect; 01468 01469 CheckLock(pDdeConv); 01470 01471 TRACE_DDE("xxxExecute"); 01472 01473 flags = XS_EXECUTE; 01474 if (!TestWF(pDdeConv->spwnd, WFANSIPROC) && 01475 !TestWF(pDdeConv->spwndPartner, WFANSIPROC)) { 01476 flags |= XS_UNICODE; 01477 } 01478 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, &hDirect, &pIntDdeInfo); 01479 if (dwRet == DO_POST) { 01480 UserAssert(pIntDdeInfo != NULL); 01481 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01482 *plParam = (LPARAM)AnticipatePost(pDdeConv->spartnerConv, xxxExecuteAck, 01483 hDirect, NULL, pIntDdeInfo, flags); 01484 /* 01485 * Check for != 0 to make sure the AnticipatePost() succeeded. 01486 */ 01487 if (*plParam != 0) { 01488 01489 /* 01490 * In the execute case it is likely that the postee will want to activate 01491 * itself and come on top (OLE 1.0 is an example). In this case, allow 01492 * both the postee and the poster to foreground activate for the next 01493 * activate (poster because it will want to activate itself again 01494 * probably, once the postee is done.) 01495 */ 01496 GETPTI(pDdeConv->spwnd)->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; 01497 TAGMSG1(DBGTAG_FOREGROUND, "xxxExecute set TIF %#p", GETPTI(pDdeConv->spwnd)); 01498 GETPTI(pDdeConv->spwndPartner)->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; 01499 TAGMSG1(DBGTAG_FOREGROUND, "xxxExecute set TIF %#p", GETPTI(pDdeConv->spwndPartner)); 01500 } else { 01501 dwRet = FAILNOFREE_POST; 01502 } 01503 01504 } 01505 return dwRet; 01506 }

DWORD xxxExecuteAck PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1515 of file kernel/ddetrack.c.

References tagINTDDEINFO::cbDirect, CheckLock, Createpxs(), tagINTDDEINFO::DdePack, DO_POST, DWORD, FAILNOFREE_POST, GETPTI, tagXSTATE::hClient, tagINTDDEINFO::hDirect, tagXSTATE::head, MSGFLAG_DDE_MID_THUNK, NULL, PopState(), _THROBJHEAD::pti, PtoH, tagDDECONV::spwndPartner, tagDDECONV::spxsOut, TRACE_DDE, tagDDEPACK::uiHi, XS_EXECUTE, XS_FREEPXS, XS_FREESRC, XS_PACKED, xxxCopyDdeIn(), and xxxUnexpectedServerPost().

01519 { 01520 PXSTATE pxsFree; 01521 PINTDDEINFO pi; 01522 DWORD flags = XS_PACKED | XS_FREESRC | XS_EXECUTE; 01523 DWORD dwRet; 01524 01525 CheckLock(pDdeConv); 01526 01527 if (*pmessage != WM_DDE_ACK) { 01528 return(xxxUnexpectedServerPost(pmessage, plParam, pDdeConv)); 01529 } 01530 01531 TRACE_DDE("xxxExecuteAck"); 01532 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, NULL, &pi); 01533 if (dwRet == DO_POST) { 01534 UserAssert(pi != NULL); 01535 /* 01536 * the server must respond to the execute with an ack containing the 01537 * same handle it was given. 01538 */ 01539 pi->DdePack.uiHi = (ULONG_PTR)pDdeConv->spxsOut->hClient; 01540 pi->hDirect = NULL; 01541 pi->cbDirect = 0; 01542 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01543 pxsFree = Createpxs(NULL, NULL, NULL, pi, XS_PACKED | XS_FREEPXS); 01544 if (pxsFree != NULL) { 01545 pxsFree->head.pti = GETPTI(pDdeConv->spwndPartner); 01546 } 01547 *plParam = (LPARAM)PtoH(pxsFree); 01548 if (*plParam != 0) { 01549 PopState(pDdeConv); 01550 } else { 01551 dwRet = FAILNOFREE_POST; 01552 } 01553 } 01554 return dwRet; 01555 }

VOID xxxFreeListFree PFREELIST  pfl  ) 
 

Definition at line 1960 of file kernel/ddetrack.c.

References BOOL, CheckCritIn, ClientFreeDDEHandle(), tagFREELIST::flags, FreeListFree(), tagFREELIST::h, tagFREELIST::next, NULL, PtiCurrent, ThreadLockPoolCleanup, ThreadUnlockPoolCleanup, TIF_INCLEANUP, TRACE_DDE1, and VOID().

Referenced by xxxCleanupDdeConv(), xxxDDETrackGetMessageHook(), xxxDDETrackPostHook(), and xxxDDETrackWindowDying().

01962 { 01963 PFREELIST pflPrev; 01964 BOOL fInCleanup; 01965 TL tlPool; 01966 01967 CheckCritIn(); 01968 01969 if (pfl == NULL) { 01970 return; 01971 } 01972 01973 fInCleanup = (PtiCurrent())->TIF_flags & TIF_INCLEANUP; 01974 01975 while (pfl != NULL) { 01976 01977 ThreadLockPoolCleanup(PtiCurrent(), pfl, &tlPool, FreeListFree); 01978 01979 if (!fInCleanup) { 01980 TRACE_DDE1("Freeing %#p from free list.\n", pfl->h); 01981 ClientFreeDDEHandle(pfl->h, pfl->flags); 01982 } 01983 01984 ThreadUnlockPoolCleanup(PtiCurrent(), &tlPool); 01985 01986 pflPrev = pfl; 01987 pfl = pfl->next; 01988 UserFreePool(pflPrev); 01989 } 01990 }

DWORD xxxPoke PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1344 of file kernel/ddetrack.c.

References AddPublicObject(), AnticipatePost(), CheckLock, DO_POST, DWORD, FAILNOFREE_POST, GETPTI, GiveObject(), tagINTDDEINFO::hIndirect, IsObjectPublic(), MSGFLAG_DDE_MID_THUNK, NULL, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, TRACE_DDE, XS_DATA, XS_FRELEASE, XS_GIVEBACKONNACK, XS_LOHANDLE, XS_PACKED, XS_PUBLICOBJ, xxxCopyDdeIn(), and xxxPokeAck.

Referenced by xxxUnexpectedClientPost().

01348 { 01349 DWORD flags, dwRet; 01350 PINTDDEINFO pIntDdeInfo; 01351 HANDLE hDirect; 01352 01353 CheckLock(pDdeConv); 01354 01355 TRACE_DDE("xxxPoke"); 01356 flags = XS_PACKED | XS_LOHANDLE | XS_DATA; 01357 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, &hDirect, &pIntDdeInfo); 01358 if (dwRet == DO_POST) { 01359 UserAssert(pIntDdeInfo != NULL); 01360 if (((PDDE_DATA)(pIntDdeInfo + 1))->wStatus & DDE_FRELEASE) { 01361 /* 01362 * giving it away 01363 */ 01364 if (IsObjectPublic(pIntDdeInfo->hIndirect) != NULL) { 01365 RIPMSG0(RIP_ERROR, "DDE Protocol violation - giving away a public GDI object."); 01366 UserFreePool(pIntDdeInfo); 01367 return FAILNOFREE_POST; 01368 } 01369 if (GiveObject(((PDDE_DATA)(pIntDdeInfo + 1))->wFmt, 01370 pIntDdeInfo->hIndirect, 01371 (W32PID)GETPTI(pDdeConv->spwndPartner)->ppi->W32Pid)) { 01372 flags |= XS_GIVEBACKONNACK; 01373 } 01374 flags |= XS_FRELEASE; 01375 } else { 01376 /* 01377 * on loan 01378 */ 01379 /* 01380 * fAck bit is ignored and assumed on. 01381 */ 01382 if (AddPublicObject(((PDDE_DATA)(pIntDdeInfo + 1))->wFmt, 01383 pIntDdeInfo->hIndirect, 01384 (W32PID)GETPTI(pDdeConv->spwnd)->ppi->W32Pid)) { 01385 flags |= XS_PUBLICOBJ; 01386 } 01387 } 01388 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01389 *plParam = (LPARAM)AnticipatePost(pDdeConv->spartnerConv, xxxPokeAck, 01390 hDirect, NULL, pIntDdeInfo, flags); 01391 if (*plParam == 0) { 01392 dwRet = FAILNOFREE_POST; 01393 } 01394 } 01395 return dwRet; 01396 }

DWORD xxxPokeAck PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1411 of file kernel/ddetrack.c.

References CheckLock, tagINTDDEINFO::DdePack, DO_POST, DWORD, tagXSTATE::flags, FreeDDEHandle(), FreeListAdd(), tagXSTATE::hClient, tagXSTATE::hServer, NULL, PopState(), tagDDECONV::spartnerConv, tagDDECONV::spxsOut, TRACE_DDE, tagDDEPACK::uiLo, XS_FRELEASE, XS_PACKED, xxxCopyAckIn(), and xxxUnexpectedServerPost().

01415 { 01416 PXSTATE pxsFree; 01417 PINTDDEINFO pIntDdeInfo; 01418 DWORD dwRet; 01419 01420 CheckLock(pDdeConv); 01421 01422 if (*pmessage != WM_DDE_ACK) { 01423 return(xxxUnexpectedServerPost(pmessage, plParam, pDdeConv)); 01424 } 01425 01426 TRACE_DDE("xxxPokeAck"); 01427 01428 dwRet = xxxCopyAckIn(pmessage, plParam, pDdeConv, &pIntDdeInfo); 01429 if (dwRet != DO_POST) { 01430 return dwRet; 01431 } 01432 UserAssert(pIntDdeInfo != NULL); 01433 01434 pxsFree = pDdeConv->spxsOut; 01435 if (pIntDdeInfo->DdePack.uiLo & DDE_FACK) { 01436 // positive ack implies server accepted the data - free from 01437 // client at postmessage time iff fRelease was set in poke message. 01438 if (pxsFree->flags & XS_FRELEASE) { 01439 TRACE_DDE("xxxPokeAck: delayed freeing client data"); 01440 FreeListAdd(pDdeConv->spartnerConv, pxsFree->hClient, 01441 pxsFree->flags & ~XS_PACKED); 01442 } 01443 } else { 01444 // Nack means that sender is responsible for freeing it. 01445 // We must free it in the receiver's context for him. 01446 TRACE_DDE("xxxPokeAck: freeing Nacked data"); 01447 UserAssert(pxsFree->hServer != (HANDLE)*plParam); 01448 FreeDDEHandle(pDdeConv, pxsFree->hServer, pxsFree->flags & ~XS_PACKED); 01449 } 01450 PopState(pDdeConv); 01451 return(DO_POST); 01452 }

DWORD xxxRequestAck PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1234 of file kernel/ddetrack.c.

References AddPublicObject(), AnticipatePost(), CheckLock, ClientGetDDEFlags(), Createpxs(), DO_POST, DWORD, FAILNOFREE_POST, FreeListAdd(), GETPTI, GiveObject(), tagXSTATE::head, tagINTDDEINFO::hIndirect, IsObjectPublic(), MSGFLAG_DDE_MID_THUNK, NULL, PopState(), _THROBJHEAD::pti, PtoH, tagDDECONV::spartnerConv, tagDDECONV::spwnd, tagDDECONV::spwndPartner, tagDDECONV::spxsOut, TRACE_DDE, XS_DATA, XS_FREEPXS, XS_FRELEASE, XS_GIVEBACKONNACK, XS_LOHANDLE, XS_PACKED, XS_PUBLICOBJ, xxxAdviseData(), xxxAdviseDataAck, xxxCopyAckIn(), xxxCopyDdeIn(), and xxxUnexpectedServerPost().

01238 { 01239 PXSTATE pxsFree; 01240 DWORD flags; 01241 PINTDDEINFO pIntDdeInfo; 01242 HANDLE hDirect; 01243 DWORD dwStatus, dwRet; 01244 01245 CheckLock(pDdeConv); 01246 01247 TRACE_DDE("xxxRequestAck or xxxAdviseData"); 01248 switch (*pmessage) { 01249 case WM_DDE_DATA: 01250 01251 /* 01252 * This is very close to advise data handling - the only catch 01253 * is that if the fRequest bit is clear this IS advise data. 01254 */ 01255 flags = XS_PACKED | XS_LOHANDLE | XS_DATA; 01256 01257 dwStatus = ClientGetDDEFlags((HANDLE)*plParam, flags); 01258 01259 if (!(dwStatus & DDE_FREQUESTED)) { 01260 01261 /* 01262 * Its NOT a request Ack - it must be advise data 01263 */ 01264 return(xxxAdviseData(pmessage, plParam, pDdeConv)); 01265 } 01266 01267 pxsFree = pDdeConv->spxsOut; 01268 dwRet = xxxCopyDdeIn((HANDLE)*plParam, &flags, &hDirect, &pIntDdeInfo); 01269 if (dwRet == DO_POST) { 01270 UserAssert(pIntDdeInfo != NULL); 01271 if (!(((PDDE_DATA)(pIntDdeInfo + 1))->wStatus & (DDE_FACK | DDE_FRELEASE))) { 01272 RIPMSG0(RIP_ERROR, "DDE protocol violation - no RELEASE or ACK bit set - setting RELEASE."); 01273 ((PDDE_DATA)(pIntDdeInfo + 1))->wStatus |= DDE_FRELEASE; 01274 } 01275 if (dwStatus & DDE_FRELEASE) { 01276 /* 01277 * giving it away 01278 */ 01279 if (IsObjectPublic(pIntDdeInfo->hIndirect) != NULL) { 01280 RIPMSG0(RIP_ERROR, "DDE Protocol violation - giving away a public GDI object."); 01281 UserFreePool(pIntDdeInfo); 01282 return FAILNOFREE_POST; 01283 } 01284 if (GiveObject(((PDDE_DATA)(pIntDdeInfo + 1))->wFmt, 01285 pIntDdeInfo->hIndirect, 01286 (W32PID)GETPTI(pDdeConv->spwndPartner)->ppi->W32Pid)) { 01287 flags |= XS_GIVEBACKONNACK; 01288 } 01289 flags |= XS_FRELEASE; 01290 } else { 01291 /* 01292 * on loan 01293 */ 01294 if (AddPublicObject(((PDDE_DATA)(pIntDdeInfo + 1))->wFmt, 01295 pIntDdeInfo->hIndirect, 01296 (W32PID)GETPTI(pDdeConv->spwnd)->ppi->W32Pid)) { 01297 flags |= XS_PUBLICOBJ; 01298 } 01299 } 01300 *pmessage |= MSGFLAG_DDE_MID_THUNK; 01301 if (dwStatus & DDE_FACK) { 01302 *plParam = (LPARAM)AnticipatePost(pDdeConv->spartnerConv, 01303 xxxAdviseDataAck, NULL, hDirect, pIntDdeInfo, flags); 01304 } else { 01305 TRACE_DDE("xxxRequestAck: Delayed freeing non-ackable request data"); 01306 FreeListAdd(pDdeConv, hDirect, flags & ~XS_PACKED); 01307 pxsFree = Createpxs(NULL, NULL, NULL, pIntDdeInfo, flags | XS_FREEPXS); 01308 if (pxsFree != NULL) { 01309 pxsFree->head.pti = GETPTI(pDdeConv->spwndPartner); 01310 } 01311 *plParam = (LPARAM)PtoH(pxsFree); 01312 } 01313 01314 if (*plParam != 0) { 01315 PopState(pDdeConv); 01316 } else { 01317 dwRet = FAILNOFREE_POST; 01318 } 01319 } 01320 return dwRet; 01321 01322 case WM_DDE_ACK: // server NACKs request 01323 dwRet = xxxCopyAckIn(pmessage, plParam, pDdeConv, &pIntDdeInfo); 01324 if (dwRet != DO_POST) { 01325 return dwRet; 01326 } 01327 UserAssert(pIntDdeInfo != NULL); 01328 PopState(pDdeConv); 01329 return(DO_POST); 01330 01331 default: 01332 return(xxxUnexpectedServerPost(pmessage, plParam, pDdeConv)); 01333 } 01334 }

DWORD xxxUnadviseAck PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 1193 of file kernel/ddetrack.c.

References CheckLock, DO_POST, DWORD, NULL, PopState(), TRACE_DDE, xxxCopyAckIn(), and xxxUnexpectedServerPost().

01197 { 01198 DWORD dwRet; 01199 PINTDDEINFO pIntDdeInfo; 01200 CheckLock(pDdeConv); 01201 01202 if (*pmessage != WM_DDE_ACK) { 01203 return(xxxUnexpectedServerPost(pmessage, plParam, pDdeConv)); 01204 } 01205 TRACE_DDE("xxxUnadviseAck"); 01206 dwRet = xxxCopyAckIn(pmessage, plParam, pDdeConv, &pIntDdeInfo); 01207 if (dwRet != DO_POST) { 01208 return dwRet; 01209 } 01210 UserAssert(pIntDdeInfo != NULL); 01211 PopState(pDdeConv); 01212 return(DO_POST); 01213 }

DWORD xxxUnexpectedClientPost PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 895 of file kernel/ddetrack.c.

References AbnormalDDEPost(), DWORD, FAILNOFREE_POST, FreeDDEHandle(), Request(), SpontaneousTerminate(), TRACE_DDE, Unadvise(), XS_PACKED, xxxAdvise(), xxxExecute(), and xxxPoke().

Referenced by xxxAdviseDataAck(), and xxxDDETrackPostHook().

00899 { 00900 switch (*pmessage) { 00901 case WM_DDE_TERMINATE: 00902 return(SpontaneousTerminate(pmessage, pDdeConv)); 00903 00904 case WM_DDE_ACK: 00905 00906 /* 00907 * Could be an extra NACK due to timeout problems, just fake it. 00908 */ 00909 TRACE_DDE("xxxUnexpectedClientPost: dumping ACK data..."); 00910 FreeDDEHandle(pDdeConv, (HANDLE)*plParam, XS_PACKED); 00911 return(FAILNOFREE_POST); 00912 00913 case WM_DDE_DATA: 00914 return(AbnormalDDEPost(pDdeConv, *pmessage)); 00915 00916 case WM_DDE_ADVISE: 00917 return(xxxAdvise(pmessage, plParam, pDdeConv)); 00918 00919 case WM_DDE_UNADVISE: 00920 return(Unadvise(pDdeConv)); 00921 00922 case WM_DDE_REQUEST: 00923 return(Request(pDdeConv)); 00924 00925 case WM_DDE_POKE: 00926 return(xxxPoke(pmessage, plParam, pDdeConv)); 00927 00928 case WM_DDE_EXECUTE: 00929 return(xxxExecute(pmessage, plParam, pDdeConv)); 00930 } 00931 return 0; 00932 }

DWORD xxxUnexpectedServerPost PDWORD  pmessage,
LPARAM *  plParam,
PDDECONV  pDdeConv
 

Definition at line 853 of file kernel/ddetrack.c.

References AbnormalDDEPost(), DWORD, FAILNOFREE_POST, FreeDDEHandle(), SpontaneousTerminate(), TRACE_DDE, XS_PACKED, and xxxAdviseData().

Referenced by DupConvTerminate(), xxxAdviseAck(), xxxDDETrackPostHook(), xxxExecuteAck(), xxxPokeAck(), xxxRequestAck(), and xxxUnadviseAck().

00857 { 00858 switch (*pmessage) { 00859 case WM_DDE_TERMINATE: 00860 return(SpontaneousTerminate(pmessage, pDdeConv)); 00861 00862 case WM_DDE_DATA: 00863 return(xxxAdviseData(pmessage, plParam, pDdeConv)); 00864 00865 case WM_DDE_ACK: 00866 00867 /* 00868 * Could be an extra NACK due to timeout problems, just fake it. 00869 */ 00870 TRACE_DDE("xxxUnexpectedServerPost: dumping ACK data..."); 00871 FreeDDEHandle(pDdeConv, (HANDLE)*plParam, XS_PACKED); 00872 return(FAILNOFREE_POST); 00873 00874 case WM_DDE_ADVISE: 00875 case WM_DDE_UNADVISE: 00876 case WM_DDE_REQUEST: 00877 case WM_DDE_POKE: 00878 case WM_DDE_EXECUTE: 00879 return(AbnormalDDEPost(pDdeConv, *pmessage)); 00880 } 00881 return 0; 00882 }


Variable Documentation

FNDDERESPONSE DupConvTerminate
 

Definition at line 44 of file kernel/ddetrack.c.

Referenced by xxxDDETrackSendHook().

PPUBOBJ gpPublicObjectList
 

Definition at line 17 of file kernel/ddetrack.c.

Referenced by AddPublicObject(), DestroyProcessInfo(), IsObjectPublic(), and RemovePublicObject().

FNDDERESPONSE xxxAdvise
 

Definition at line 31 of file kernel/ddetrack.c.

FNDDERESPONSE xxxAdviseAck
 

Definition at line 32 of file kernel/ddetrack.c.

Referenced by xxxAdvise().

FNDDERESPONSE xxxAdviseData
 

Definition at line 33 of file kernel/ddetrack.c.

FNDDERESPONSE xxxAdviseDataAck
 

Definition at line 34 of file kernel/ddetrack.c.

Referenced by xxxAdviseData(), and xxxRequestAck().

FNDDERESPONSE xxxExecute
 

Definition at line 41 of file kernel/ddetrack.c.

FNDDERESPONSE xxxExecuteAck
 

Definition at line 42 of file kernel/ddetrack.c.

Referenced by xxxExecute().

FNDDERESPONSE xxxPoke
 

Definition at line 39 of file kernel/ddetrack.c.

FNDDERESPONSE xxxPokeAck
 

Definition at line 40 of file kernel/ddetrack.c.

Referenced by xxxPoke().

FNDDERESPONSE xxxRequestAck
 

Definition at line 38 of file kernel/ddetrack.c.

Referenced by Request().

FNDDERESPONSE xxxUnadviseAck
 

Definition at line 36 of file kernel/ddetrack.c.

Referenced by Unadvise().

FNDDERESPONSE xxxUnexpectedClientPost
 

Definition at line 30 of file kernel/ddetrack.c.

FNDDERESPONSE xxxUnexpectedServerPost
 

Definition at line 29 of file kernel/ddetrack.c.


Generated on Sat May 15 19:43:25 2004 for test by doxygen 1.3.7