00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
#include "precomp.h"
00015
#pragma hdrstop
00016
00017 PPUBOBJ gpPublicObjectList;
00018
00019 #define TRACE_DDE(str) TAGMSG0(DBGTAG_DDE, str)
00020 #define TRACE_DDE1(s, a) TAGMSG1(DBGTAG_DDE, (s), (a))
00021 #define TRACE_DDE2(s, a, b) TAGMSG2(DBGTAG_DDE, (s), (a), (b))
00022 #define TRACE_DDE3(s, a, b, c) TAGMSG3(DBGTAG_DDE, (s), (a), (b), (c))
00023
00024
BOOL NewConversation(
PDDECONV *ppdcNewClient,
PDDECONV *ppdcNewServer,
00025
PWND pwndClient,
PWND pwndServer);
00026
PDDECONV FindDdeConv(
PWND pwndProp,
PWND pwndPartner);
00027
BOOL AddConvProp(
PWND pwndUs,
PWND pwndThem, DWORD flags,
PDDECONV pdcNew,
00028
PDDECONV pdcPartner);
00029 FNDDERESPONSE xxxUnexpectedServerPost;
00030 FNDDERESPONSE xxxUnexpectedClientPost;
00031 FNDDERESPONSE xxxAdvise;
00032 FNDDERESPONSE xxxAdviseAck;
00033 FNDDERESPONSE xxxAdviseData;
00034 FNDDERESPONSE xxxAdviseDataAck;
00035
DWORD Unadvise(
PDDECONV pDdeConv);
00036 FNDDERESPONSE xxxUnadviseAck;
00037
DWORD Request(
PDDECONV pDdeConv);
00038 FNDDERESPONSE xxxRequestAck;
00039 FNDDERESPONSE xxxPoke;
00040 FNDDERESPONSE xxxPokeAck;
00041 FNDDERESPONSE xxxExecute;
00042 FNDDERESPONSE xxxExecuteAck;
00043
DWORD SpontaneousTerminate(PDWORD pmessage,
PDDECONV pDdeConv);
00044 FNDDERESPONSE DupConvTerminate;
00045
00046 HANDLE
AnticipatePost(
PDDECONV pDdeConv, FNDDERESPONSE fnResponse,
00047 HANDLE hClient, HANDLE hServer,
PINTDDEINFO pIntDdeInfo, DWORD flags);
00048
PXSTATE Createpxs(FNDDERESPONSE fnResponse, HANDLE hClient, HANDLE hServer,
00049
PINTDDEINFO pIntDdeInfo, DWORD flags);
00050
DWORD AbnormalDDEPost(
PDDECONV pDdeConv, DWORD message);
00051
DWORD xxxCopyDdeIn(HANDLE hSrc, PDWORD pflags, PHANDLE phDirect,
PINTDDEINFO *ppi);
00052
DWORD xxxCopyAckIn(PDWORD pmessage, LPARAM *plParam,
PDDECONV pDdeConv,
PINTDDEINFO *ppIntDdeInfo);
00053 HANDLE
xxxCopyDDEOut(
PINTDDEINFO pIntDdeInfo, PHANDLE phDirect);
00054
BOOL FreeListAdd(
PDDECONV pDdeConv, HANDLE hClient, DWORD flags);
00055
VOID xxxFreeListFree(
PFREELIST pfl);
00056
VOID PopState(
PDDECONV pDdeConv);
00057
PDDECONV UnlinkConv(
PDDECONV pDdeConv);
00058
00059
VOID FreeDDEHandle(
PDDECONV pDdeConv, HANDLE hClient, DWORD flags);
00060
DWORD ClientFreeDDEHandle(HANDLE hClient, DWORD flags);
00061
DWORD ClientGetDDEFlags(HANDLE hClient, DWORD flags);
00062
DWORD xxxClientCopyDDEIn1(HANDLE hClient, DWORD flags,
PINTDDEINFO *ppi);
00063 HANDLE
xxxClientCopyDDEOut1(
PINTDDEINFO pIntDdeInfo);
00064
DWORD xxxClientCopyDDEOut2(
PINTDDEINFO pIntDdeInfo);
00065
00066
PPUBOBJ IsObjectPublic(HANDLE hObj);
00067
BOOL AddPublicObject(UINT format, HANDLE hObj, W32PID pid);
00068
BOOL RemovePublicObject(UINT format, HANDLE hObj);
00069
BOOL GiveObject(UINT format, HANDLE hObj, W32PID pid);
00070
#if DBG
00071
VOID ValidatePublicObjectList(VOID);
00072
#define MSG_SENT 0
00073
#define MSG_POST 1
00074
#define MSG_RECV 2
00075
#define MSG_PEEK 3
00076
VOID TraceDdeMsg(UINT msg, HWND hwndFrom, HWND hwndTo, UINT code);
00077
#else
00078 #define ValidatePublicObjectList()
00079 #define TraceDdeMsg(m, h1, h2, c)
00080
#endif // DBG
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 BOOL xxxDDETrackSendHook(
00148
PWND pwndTo,
00149 DWORD message,
00150 WPARAM wParam,
00151 LPARAM lParam)
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;
00160 dmhd.uiLo = LOWORD(lParam);
00161 dmhd.uiHi = HIWORD(lParam);
00162
xxxMessageEvent(pwndTo, message, wParam, lParam, MF_SENDMSGS, &dmhd);
00163 }
00164
00165
if (
PtiCurrent()->ppi ==
GETPWNDPPI(pwndTo)) {
00166
00167
00168
00169
return(
TRUE);
00170 }
00171
00172
if (message != WM_DDE_ACK) {
00173
if (message == WM_DDE_INITIATE) {
00174
return TRUE;
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
00191
00192
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 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 BOOL AddConvProp(
00218
PWND pwndUs,
00219
PWND pwndThem,
00220 DWORD flags,
00221
PDDECONV pdcNew,
00222
PDDECONV pdcPartner)
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
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) {
00244 pddei->
cRefConv++;
00245 }
00246 pdcNew->
pddei = pddei;
00247
00248
HMLockObject(pdcNew);
00249
InternalSetProp(pwndUs,
PROP_DDETRACK, pdcNew,
PROPF_INTERNAL);
00250
return(
TRUE);
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 PDDECONV UnlinkConv(
00265
PDDECONV pDdeConv)
00266 {
00267
PDDECONV pdcPrev, pdcT, pDdeConvNext;
00268
00269
00270
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);
00281 }
00282
00283 pdcPrev =
NULL;
00284
while (pdcT != pDdeConv) {
00285 pdcPrev = pdcT;
00286 pdcT = pdcT->
snext;
00287
if (pdcT ==
NULL) {
00288
return(
NULL);
00289 }
00290 }
00291
00292
if (pdcPrev ==
NULL) {
00293
if (pDdeConv->
snext ==
NULL) {
00294
00295
InternalRemoveProp(pDdeConv->
spwnd,
PROP_DDETRACK,
PROPF_INTERNAL);
00296 }
else {
00297
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);
00306
return(pDdeConvNext);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320 DWORD xxxDDETrackPostHook(
00321 PUINT pmessage,
00322
PWND pwndTo,
00323 WPARAM wParam,
00324 LPARAM *plParam,
00325 BOOL fSent)
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
00351
00352
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
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
00381
00382
00383
00384 dwRet = *pmessage == WM_DDE_TERMINATE ?
DO_POST :
FAKE_POST;
00385
goto Exit;
00386 }
00387
00388
00389
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
00398
00399
00400
00401
00402
00403
00404
00405
00406
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
00421
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
00431
00432
00433
00434
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
00450
00451 ppfl = &pDdeConv->
pfl;
00452
while (*ppfl !=
NULL) {
00453
if ((*ppfl)->h == (HANDLE)*plParam) {
00454
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
00490
00491
00492
DWORD flags =
XS_DUMPMSG;
00493
00494
00495
00496
00497
00498
00499
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
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 }
00547
00548 void xxxCleanupDdeConv(
00549
PWND pwndProp)
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
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
00593
00594
00595
goto Restart;
00596 }
00597
00598 pDdeConv = pDdeConv->
snext;
00599 }
00600 }
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618 VOID xxxDDETrackGetMessageHook(
00619 PMSG pmsg)
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
00637
00638
00639
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
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
00663
00664 pDdeConv =
FindDdeConv(pwndTo, pwndFrom);
00665
if (pDdeConv ==
NULL) {
00666
00667
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
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
00709
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
00722
00723
00724
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
00740
00741
00742
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 }
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 VOID xxxDDETrackWindowDying(
00769
PWND pwnd,
00770
PDDECONV pDdeConv)
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
00787
00788
00789
if (!(pDdeConv->
flags &
CXF_TERMINATE_POSTED)) {
00790
00791
00792
00793
00794
00795
if (!(GACF2_NODDETRKDYING &
GetAppCompatFlags2(
VER40))
00796 || (pDdeConv->
spwndPartner ==
NULL)
00797 || !(GACF2_NODDETRKDYING
00798 &
GetAppCompatFlags2ForPti(
GETPTI(pDdeConv->
spwndPartner),
VER40))) {
00799
00800
00801
00802
00803
_PostMessage(pDdeConv->
spwndPartner, WM_DDE_TERMINATE,
00804 (WPARAM)
PtoH(pDdeConv->
spwnd), 0);
00805
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
00814
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
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 }
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 DWORD xxxUnexpectedServerPost(
00854 PDWORD pmessage,
00855 LPARAM *plParam,
00856
PDDECONV pDdeConv)
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
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 }
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 DWORD xxxUnexpectedClientPost(
00896 PDWORD pmessage,
00897 LPARAM *plParam,
00898
PDDECONV pDdeConv)
00899 {
00900
switch (*pmessage) {
00901
case WM_DDE_TERMINATE:
00902
return(
SpontaneousTerminate(pmessage, pDdeConv));
00903
00904
case WM_DDE_ACK:
00905
00906
00907
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 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 DWORD xxxAdvise(
00943 PDWORD pmessage,
00944 LPARAM *plParam,
00945
PDDECONV pDdeConv)
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 }
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978 DWORD xxxAdviseAck(
00979 PDWORD pmessage,
00980 LPARAM *plParam,
00981
PDDECONV pDdeConv)
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
01006
01007
01008
TRACE_DDE(
"xxxAdviseAck: +ACK delayed freeing data from client");
01009
FreeListAdd(pDdeConv->
spartnerConv, pxsFree->
hClient, pxsFree->
flags & ~
XS_PACKED);
01010 }
else {
01011
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 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028 DWORD xxxAdviseData(
01029 PDWORD pmessage,
01030 LPARAM *plParam,
01031
PDDECONV pDdeConv)
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
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
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 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113 DWORD xxxAdviseDataAck(
01114 PDWORD pmessage,
01115 LPARAM *plParam,
01116
PDDECONV pDdeConv)
01117 {
01118
PXSTATE pxsFree;
01119
PINTDDEINFO pIntDdeInfo;
01120
DWORD dwRet;
01121
01122
CheckLock(pDdeConv);
01123
01124
01125
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
01146
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
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 }
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 DWORD Unadvise(
01181
PDDECONV pDdeConv)
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 }
01190
01191
01192
01193 DWORD xxxUnadviseAck(
01194 PDWORD pmessage,
01195 LPARAM *plParam,
01196
PDDECONV pDdeConv)
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 }
01214
01215
01216
01217
01218
01219
01220
01221 DWORD Request(
01222
PDDECONV pDdeConv)
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 }
01231
01232
01233
01234 DWORD xxxRequestAck(
01235 PDWORD pmessage,
01236 LPARAM *plParam,
01237
PDDECONV pDdeConv)
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
01253
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
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
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
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:
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 }
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344 DWORD xxxPoke(
01345 PDWORD pmessage,
01346 LPARAM *plParam,
01347
PDDECONV pDdeConv)
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
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
01378
01379
01380
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 }
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411 DWORD xxxPokeAck(
01412 PDWORD pmessage,
01413 LPARAM *plParam,
01414
PDDECONV pDdeConv)
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
01437
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
01445
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 }
01453
01454
01455
01456
01457
01458
01459
01460 DWORD xxxExecute(
01461 PDWORD pmessage,
01462 LPARAM *plParam,
01463
PDDECONV pDdeConv)
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
01486
01487
if (*plParam != 0) {
01488
01489
01490
01491
01492
01493
01494
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 }
01507
01508
01509
01510
01511
01512
01513
01514
01515 DWORD xxxExecuteAck(
01516 PDWORD pmessage,
01517 LPARAM *plParam,
01518
PDDECONV pDdeConv)
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
01537
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 }
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565 DWORD SpontaneousTerminate(
01566 PDWORD pmessage,
01567
PDDECONV pDdeConv)
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 }
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601 DWORD DupConvTerminate(
01602 PDWORD pmessage,
01603 LPARAM *plParam,
01604
PDDECONV pDdeConv)
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 }
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 HANDLE
AnticipatePost(
01635
PDDECONV pDdeConv,
01636 FNDDERESPONSE fnResponse,
01637 HANDLE hClient,
01638 HANDLE hServer,
01639
PINTDDEINFO pIntDdeInfo,
01640 DWORD flags)
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 }
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 PXSTATE Createpxs(
01690 FNDDERESPONSE fnResponse,
01691 HANDLE hClient,
01692 HANDLE hServer,
01693
PINTDDEINFO pIntDdeInfo,
01694 DWORD flags)
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 }
01715
01716
01717
01718
01719
01720
01721
01722
01723
01724
01725
01726
01727
01728
01729 DWORD AbnormalDDEPost(
01730
PDDECONV pDdeConv,
01731 DWORD message)
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
01743
01744
01745
01746
if (!(pDdeConv->
flags &
CXF_TERMINATE_POSTED)) {
01747
_PostMessage(pDdeConv->
spwndPartner, WM_DDE_TERMINATE,
01748 (WPARAM)
PtoH(pDdeConv->
spwnd), 0);
01749
01750 }
01751
return(message == WM_DDE_TERMINATE ?
FAKE_POST :
FAIL_POST);
01752 }
01753
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766 BOOL NewConversation(
01767
PDDECONV *ppdcNewClient,
01768
PDDECONV *ppdcNewServer,
01769
PWND pwndClient,
01770
PWND pwndServer)
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);
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 }
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811 PDDECONV FindDdeConv(
01812
PWND pwndProp,
01813
PWND pwndPartner)
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 }
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833
01834
01835 DWORD xxxCopyAckIn(
01836 LPDWORD pmessage,
01837 LPARAM *plParam,
01838
PDDECONV pDdeConv,
01839
PINTDDEINFO * ppIntDdeInfo)
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 }
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890 BOOL FreeListAdd(
01891
PDDECONV pDdeConv,
01892 HANDLE hClient,
01893 DWORD flags)
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 }
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919 VOID FreeDDEHandle(
01920
PDDECONV pDdeConv,
01921 HANDLE hClient,
01922 DWORD flags)
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 }
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943 VOID FreeListFree(
01944
PFREELIST pfl)
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 }
01958
01959
01960 VOID xxxFreeListFree(
01961
PFREELIST pfl)
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 }
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001 VOID PopState(
02002
PDDECONV pDdeConv)
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);
02027 pxsNext = pDdeConv->
spxsOut->
snext;
02028 pxsFree =
Lock(&(pDdeConv->
spxsOut), pxsNext);
02029
if (pxsNext ==
NULL) {
02030 UserAssert(pDdeConv->
spxsIn == pxsFree);
02031
Unlock(&(pDdeConv->
spxsIn));
02032 }
else {
02033
Unlock(&(pxsFree->
snext));
02034 }
02035 pxsFree =
ThreadUnlock(&tlpxs);
02036
if (pxsFree !=
NULL) {
02037
FreeDdeXact(pxsFree);
02038 }
02039 }
02040
02041
02042 VOID FreeDdeConv(
02043
PDDECONV pDdeConv)
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
02053 }
02054
02055
if (pDdeConv->
spartnerConv !=
NULL &&
02056
GETPTI(pDdeConv)->TIF_flags &
TIF_INCLEANUP) {
02057
02058
02059
02060
02061
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 }
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104 DWORD xxxCopyDdeIn(
02105 HANDLE hSrc,
02106 PDWORD pflags,
02107 PHANDLE phDirect,
02108
PINTDDEINFO *ppi)
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 }
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149 HANDLE
xxxCopyDDEOut(
02150
PINTDDEINFO pi,
02151 PHANDLE phDirect)
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 }
02168
02169
02170
02171
02172
02173
02174
02175
02176 BOOL _DdeSetQualityOfService(
02177
PWND pwndClient,
02178 CONST PSECURITY_QUALITY_OF_SERVICE pqosNew,
02179 PSECURITY_QUALITY_OF_SERVICE pqosOld)
02180 {
02181 PSECURITY_QUALITY_OF_SERVICE pqosUser;
02182 PSECURITY_QUALITY_OF_SERVICE pqosAlloc =
NULL;
02183
BOOL fRet;
02184
02185
02186
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);
02193 }
02194 pqosAlloc = (PSECURITY_QUALITY_OF_SERVICE)UserAllocPoolZInit(
02195
sizeof(SECURITY_QUALITY_OF_SERVICE), TAG_DDE2);
02196
if (pqosAlloc ==
NULL) {
02197
return(
FALSE);
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 }
02211
02212
02213
02214
02215
02216
02217
02218 BOOL _DdeGetQualityOfService(
02219
PWND pwndClient,
02220
PWND pwndServer,
02221 PSECURITY_QUALITY_OF_SERVICE pqos)
02222 {
02223
PDDECONV pDdeConv;
02224 PSECURITY_QUALITY_OF_SERVICE pqosClient;
02225
02226
if (pwndServer ==
NULL) {
02227
02228
02229
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 }
02253
02254
02255
02256 BOOL _ImpersonateDdeClientWindow(
02257
PWND pwndClient,
02258
PWND pwndServer)
02259 {
02260
PDDECONV pDdeConv;
02261
NTSTATUS Status;
02262
02263
02264
02265
02266 pDdeConv =
FindDdeConv(pwndClient, pwndServer);
02267
if (pDdeConv ==
NULL || pDdeConv->
pddei ==
NULL)
02268
return(
FALSE);
02269
02270
02271
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 }
02281
02282
02283
02284
02285 VOID FreeDdeXact(
02286
PXSTATE pxs)
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
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 }
02330
02331
02332
02333 PPUBOBJ IsObjectPublic(
02334 HANDLE hObj)
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 }
02345
02346
02347
02348 BOOL AddPublicObject(
02349 UINT format,
02350 HANDLE hObj,
02351 W32PID pid)
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 }
02382
02383
02384
02385 BOOL RemovePublicObject(
02386 UINT format,
02387 HANDLE hObj)
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 }
02424
02425
02426
BOOL
02427 GiveObject(
02428 UINT format,
02429 HANDLE hObj,
02430 W32PID pid)
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 }
02446
02447
#if DBG
02448
VOID ValidatePublicObjectList()
02449 {
02450
PPUBOBJ ppo;
02451
int i, count;
02452
HANDLEENTRY *phe;
02453
02454
for (count = 0, ppo =
gpPublicObjectList;
02455 ppo !=
NULL;
02456 ppo = ppo->next) {
02457 count += ppo->count;
02458 }
02459
for (i = 0, phe =
gSharedInfo.
aheList;
02460 i <= (
int)
giheLast;
02461 i++) {
02462
if (phe[i].bType ==
TYPE_DDEXACT) {
02463
if (((
PXSTATE)(phe[i].phead))->flags &
XS_PUBLICOBJ) {
02464 UserAssert(((
PXSTATE)(phe[i].phead))->pIntDdeInfo != NULL);
02465 UserAssert(
IsObjectPublic(((
PXSTATE)
02466 (phe[i].phead))->pIntDdeInfo->hIndirect) != NULL);
02467 count--;
02468 }
02469 }
02470 }
02471 UserAssert(count == 0);
02472 }
02473
02474
02475
VOID TraceDdeMsg(
02476 UINT msg,
02477 HWND hwndFrom,
02478 HWND hwndTo,
02479 UINT code)
02480 {
02481 LPSTR szMsg, szType;
02482
02483
msg =
msg & 0xFFFF;
02484
02485
switch (
msg) {
02486
case WM_DDE_INITIATE:
02487 szMsg =
"INITIATE";
02488
break;
02489
02490
case WM_DDE_TERMINATE:
02491 szMsg =
"TERMINATE";
02492
break;
02493
02494
case WM_DDE_ADVISE:
02495 szMsg =
"ADVISE";
02496
break;
02497
02498
case WM_DDE_UNADVISE:
02499 szMsg =
"UNADVISE";
02500
break;
02501
02502
case WM_DDE_ACK:
02503 szMsg =
"ACK";
02504
break;
02505
02506
case WM_DDE_DATA:
02507 szMsg =
"DATA";
02508
break;
02509
02510
case WM_DDE_REQUEST:
02511 szMsg =
"REQUEST";
02512
break;
02513
02514
case WM_DDE_POKE:
02515 szMsg =
"POKE";
02516
break;
02517
02518
case WM_DDE_EXECUTE:
02519 szMsg =
"EXECUTE";
02520
break;
02521
02522
default:
02523 szMsg =
"BOGUS";
02524 UserAssert(msg >= WM_DDE_FIRST && msg <= WM_DDE_LAST);
02525
break;
02526 }
02527
02528
switch (code) {
02529
case MSG_SENT:
02530 szType =
"[sent]";
02531
break;
02532
02533
case MSG_POST:
02534 szType =
"[posted]";
02535
break;
02536
02537
case MSG_RECV:
02538 szType =
"[received]";
02539
break;
02540
02541
case MSG_PEEK:
02542 szType =
"[peeked]";
02543
break;
02544
02545
default:
02546 szType =
"[bogus]";
02547 UserAssert(FALSE);
02548
break;
02549 }
02550
02551 RIPMSG4(RIP_VERBOSE,
02552
"%#p->%#p WM_DDE_%s %s",
02553 hwndFrom, hwndTo, szMsg, szType);
02554 }
02555
#endif //DBG