00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 BOOL ClStartAdvise(
00068
PXACT_INFO pxi)
00069 {
00070
DWORD dwError;
00071
00072
00073
00074
00075
00076
00077 pxi->
hDDESent =
AllocAndSetDDEData(
NULL,
sizeof(
DDE_DATA),
00078 (WORD)(((pxi->
wType << 12) & (DDE_FDEFERUPD | DDE_FACKREQ)) | DDE_FRELEASE),
00079 pxi->
wFmt);
00080
if (!pxi->
hDDESent) {
00081
SetLastDDEMLError(pxi->
pcoi->
pcii, DMLERR_MEMORY_ERROR);
00082
return (
FALSE);
00083 }
00084
00085
IncGlobalAtomCount(pxi->
gaItem);
00086 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner, 0, WM_DDE_ADVISE,
00087 pxi->
pcoi->
hwndConv, 0, HandleToUlong(pxi->
hDDESent), pxi->
gaItem);
00088
if (dwError) {
00089
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
00090
WOWGLOBALFREE(pxi->
hDDESent);
00091 pxi->
hDDESent = 0;
00092 GlobalDeleteAtom(pxi->
gaItem);
00093
return (
FALSE);
00094 }
00095
00096 pxi->
state = XST_ADVSENT;
00097 pxi->
pfnResponse = (
FNRESPONSE)
ClRespAdviseAck;
00098
LinkTransaction(pxi);
00099
return (
TRUE);
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 BOOL SvSpontAdvise(
00113
PSVR_CONV_INFO psi,
00114 LPARAM lParam)
00115 {
00116 UINT_PTR uiHi;
00117 HANDLE hDDE;
00118 WORD wFmt, wStatus;
00119 ULONG_PTR dwRet = 0;
00120
DWORD dwError;
00121
LATOM la;
00122
00123
UnpackDDElParam(WM_DDE_ADVISE, lParam, (PUINT_PTR)&hDDE, &uiHi);
00124
if (psi->
ci.
pcii->
afCmd & CBF_FAIL_ADVISES) {
00125
goto Ack;
00126 }
00127
00128
if (!
ExtractDDEDataInfo(hDDE, &wStatus, &wFmt)) {
00129
goto Ack;
00130 }
00131
00132
if (wStatus & DDE_FDEFERUPD) {
00133 wStatus &= ~DDE_FACKREQ;
00134 }
00135
00136 la =
GlobalToLocalAtom((
GATOM)uiHi);
00137 dwRet = (ULONG_PTR)
DoCallback(psi->
ci.
pcii,
00138 XTYP_ADVSTART,
00139 wFmt, psi->
ci.
hConv,
00140
NORMAL_HSZ_FROM_LATOM(psi->
ci.
laTopic),
00141
NORMAL_HSZ_FROM_LATOM(la),
00142 (HDDEDATA)0, 0, 0);
00143 DeleteAtom(la);
00144
00145
00146
00147
if (dwRet == (ULONG_PTR)CBR_BLOCK) {
00148
return (
FALSE);
00149 }
00150
00151
if (dwRet) {
00152
00153
00154
00155 dwRet =
AddLink((
PCONV_INFO)psi, (
GATOM)uiHi, wFmt,
00156 (WORD)(wStatus & (WORD)(DDE_FDEFERUPD | DDE_FACKREQ)));
00157
if (dwRet) {
00158
MONLINK(psi->ci.
pcii,
TRUE, wStatus & DDE_FDEFERUPD, psi->ci.
laService,
00159 psi->ci.
laTopic, (
GATOM)uiHi, wFmt,
TRUE,
00160 (HCONV)psi->ci.
hwndConv, (HCONV)psi->ci.
hwndPartner);
00161 }
00162 }
00163
00164 Ack:
00165
if (dwRet) {
00166
WOWGLOBALFREE(hDDE);
00167 }
00168
00169 dwError =
PackAndPostMessage(psi->
ci.
hwndPartner, WM_DDE_ADVISE, WM_DDE_ACK,
00170 psi->
ci.
hwndConv, lParam, dwRet ? DDE_FACK : 0, uiHi);
00171
if (dwError) {
00172
SetLastDDEMLError(psi->
ci.
pcii, dwError);
00173 GlobalDeleteAtom((ATOM)uiHi);
00174 }
00175
00176
return (
TRUE);
00177 }
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190 BOOL ClRespAdviseAck(
00191
PXACT_INFO pxi,
00192 UINT msg,
00193 LPARAM lParam)
00194 {
00195 UINT_PTR uiLo, uiHi;
00196
00197
if (
msg) {
00198
if (
msg != WM_DDE_ACK) {
00199
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
00200 }
00201
00202
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi);
00203
#if DBG
00204
if ((
GATOM)uiHi != pxi->
gaItem) {
00205
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
00206 }
00207
#endif
00208
00209 GlobalDeleteAtom((ATOM)uiHi);
00210
00211 pxi->
state = XST_ADVACKRCVD;
00212 pxi->
wStatus = (WORD)uiLo;
00213
00214
if (pxi->
wStatus & DDE_FACK) {
00215
if (
AddLink(pxi->
pcoi, pxi->
gaItem, pxi->
wFmt,
00216 (WORD)((pxi->
wType << 12) & (DDE_FACKREQ | DDE_FDEFERUPD)))) {
00217
00218
00219
00220
if (!(pxi->
pcoi->
state & ST_ISLOCAL)) {
00221
MONLINK(pxi->
pcoi->
pcii,
TRUE, (WORD)uiLo & DDE_FDEFERUPD,
00222 pxi->
pcoi->
laService, pxi->
pcoi->
laTopic, pxi->
gaItem,
00223 pxi->
wFmt,
FALSE, (HCONV)pxi->
pcoi->
hwndPartner,
00224 (HCONV)pxi->
pcoi->
hwndConv);
00225 }
00226 }
else {
00227 pxi->
wStatus = 0;
00228 }
00229 }
else {
00230
WOWGLOBALFREE(pxi->
hDDESent);
00231 }
00232
00233
if (
TransactionComplete(pxi,
00234 (pxi->
wStatus & DDE_FACK) ? (HDDEDATA)1
L : (HDDEDATA)0
L)) {
00235
goto Cleanup;
00236 }
00237 }
else {
00238 Cleanup:
00239 GlobalDeleteAtom(pxi->
gaItem);
00240
UnlinkTransaction(pxi);
00241
DDEMLFree(pxi);
00242 }
00243
if (
msg) {
00244
FreeDDElParam(
msg, lParam);
00245 }
00246
return (
TRUE);
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263 BOOL SvStartAdviseUpdate(
00264
PXACT_INFO pxi,
00265 DWORD cLinksToGo)
00266 {
00267 HDDEDATA hData =
NULL;
00268
PDDE_DATA pdde;
00269
DWORD dwError;
00270 HANDLE hDDE;
00271
LATOM al;
00272
00273
CheckDDECritIn;
00274
00275
if (pxi->
wType & DDE_FDEFERUPD) {
00276 hDDE = 0;
00277 }
else {
00278 al =
GlobalToLocalAtom(pxi->
gaItem);
00279 hData =
DoCallback(pxi->
pcoi->
pcii,
00280 XTYP_ADVREQ,
00281 pxi->
wFmt,
00282 pxi->
pcoi->
hConv,
00283
NORMAL_HSZ_FROM_LATOM(pxi->
pcoi->
laTopic),
00284
NORMAL_HSZ_FROM_LATOM(al),
00285 (HDDEDATA)0,
00286 MAKELONG(cLinksToGo, 0),
00287 0);
00288 DeleteAtom(al);
00289
if (!hData) {
00290
00291
return (
FALSE);
00292 }
00293 hDDE =
UnpackAndFreeDDEMLDataHandle(hData,
FALSE);
00294
if (!hDDE) {
00295
00296
00297
00298
00299
InternalFreeDataHandle(hData,
FALSE);
00300
SetLastDDEMLError(pxi->
pcoi->
pcii, DMLERR_DLL_USAGE);
00301
return (
FALSE);
00302 }
00303
00304
00305
00306
00307
USERGLOBALLOCK(hDDE, pdde);
00308
if (pdde ==
NULL) {
00309
return (
FALSE);
00310 }
00311
if (pdde->
wFmt != pxi->
wFmt) {
00312
00313
00314
00315
00316
USERGLOBALUNLOCK(hDDE);
00317
InternalFreeDataHandle(hData,
FALSE);
00318
SetLastDDEMLError(pxi->
pcoi->
pcii, DMLERR_DLL_USAGE);
00319
return (
FALSE);
00320 }
00321
if (!(pdde->
wStatus & DDE_FRELEASE)) {
00322 pxi->
wType |= DDE_FACKREQ;
00323 }
00324 pdde->
wStatus |= (pxi->
wType & DDE_FACKREQ);
00325
USERGLOBALUNLOCK(hDDE);
00326 }
00327
00328
IncGlobalAtomCount(pxi->
gaItem);
00329 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner, 0, WM_DDE_DATA,
00330 pxi->
pcoi->
hwndConv, 0, HandleToUlong(hDDE), pxi->
gaItem);
00331
if (dwError) {
00332
if (hData) {
00333
InternalFreeDataHandle(hData,
FALSE);
00334 }
00335
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
00336 GlobalDeleteAtom(pxi->
gaItem);
00337
return (
FALSE);
00338 }
00339
00340 pxi->
state = XST_ADVDATASENT;
00341
if (pxi->
wType & DDE_FACKREQ) {
00342 pxi->
hDDESent = hDDE;
00343 pxi->
pfnResponse = (
FNRESPONSE)
SvRespAdviseDataAck;
00344
LinkTransaction(pxi);
00345
return (
TRUE);
00346 }
else {
00347
return (
FALSE);
00348 }
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 BOOL ClSpontAdviseData(
00363
PCL_CONV_INFO pci,
00364 LPARAM lParam)
00365 {
00366 UINT_PTR uiHi;
00367
DWORD dwError;
00368 HANDLE hDDE = 0;
00369 HDDEDATA hData, hDataReturn;
00370
PDDE_DATA pdde;
00371 WORD wFmt;
00372 WORD wStatus;
00373
LATOM la;
00374
PADVISE_LINK paLink;
00375
int iLink;
00376
00377
UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT_PTR)&hDDE, &uiHi);
00378 UserAssert(!hDDE || GlobalSize(hDDE));
00379 wFmt = 0;
00380 wStatus = 0;
00381 hDataReturn = 0;
00382 la =
GlobalToLocalAtom((
GATOM)uiHi);
00383
if (hDDE) {
00384
USERGLOBALLOCK(hDDE, pdde);
00385
if (pdde ==
NULL) {
00386 hData = 0;
00387 }
else {
00388 wFmt = pdde->
wFmt;
00389 wStatus = pdde->
wStatus;
00390
USERGLOBALUNLOCK(hDDE);
00391
00392
00393
00394
00395 hData =
InternalCreateDataHandle(pci->
ci.
pcii, (LPBYTE)hDDE,
00396 (
DWORD)-1, 0, HDATA_NOAPPFREE | HDATA_READONLY, 0, 0);
00397 }
00398
if (hData) {
00399 hDataReturn =
DoCallback(pci->
ci.
pcii, XTYP_ADVDATA,
00400 wFmt, pci->
ci.
hConv,
00401
NORMAL_HSZ_FROM_LATOM(pci->
ci.
laTopic),
00402
NORMAL_HSZ_FROM_LATOM(la),
00403 hData, 0, 0);
00404
if (hDataReturn != CBR_BLOCK) {
00405
UnpackAndFreeDDEMLDataHandle(hData,
FALSE);
00406
if (((ULONG_PTR)hDataReturn & DDE_FACK) || !(wStatus & DDE_FACKREQ)) {
00407
00408
00409
00410
00411
FreeDDEData(hDDE,
FALSE,
TRUE);
00412 }
00413 }
00414 }
00415 }
else {
00416
00417
00418
00419
00420
00421
00422
00423
00424
for (paLink = pci->
ci.
aLinks, iLink = 0; iLink < pci->
ci.
cLinks; iLink++, paLink++) {
00425
if ((paLink->
laItem == la) && (paLink->
wType & DDE_FDEFERUPD)) {
00426 hDataReturn =
DoCallback(pci->
ci.
pcii, XTYP_ADVDATA,
00427 paLink->
wFmt, pci->
ci.
hConv,
00428
NORMAL_HSZ_FROM_LATOM(pci->
ci.
laTopic),
00429
NORMAL_HSZ_FROM_LATOM(la),
00430 0, 0, 0);
00431
if (hDataReturn == CBR_BLOCK) {
00432 DeleteAtom(la);
00433
return (
FALSE);
00434 }
00435 }
00436 }
00437 }
00438 DeleteAtom(la);
00439
if (hDataReturn == CBR_BLOCK) {
00440
return (
FALSE);
00441 }
00442
00443
if (wStatus & DDE_FACKREQ) {
00444
00445 (ULONG_PTR)hDataReturn &= ~DDE_FACKRESERVED;
00446
00447
if (dwError =
PackAndPostMessage(pci->
ci.
hwndPartner, WM_DDE_DATA,
00448 WM_DDE_ACK, pci->
ci.
hwndConv, lParam, (UINT_PTR)hDataReturn, uiHi)) {
00449
SetLastDDEMLError(pci->
ci.
pcii, dwError);
00450 }
00451 }
else {
00452 GlobalDeleteAtom((ATOM)uiHi);
00453
FreeDDElParam(WM_DDE_DATA, lParam);
00454 }
00455
return (
TRUE);
00456 }
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470 BOOL SvRespAdviseDataAck(
00471
PXACT_INFO pxi,
00472 UINT msg,
00473 LPARAM lParam)
00474 {
00475 UINT_PTR uiLo, uiHi;
00476
int iLink;
00477
PADVISE_LINK paLink;
00478
PXACT_INFO pxiNew;
00479
LATOM la;
00480
BOOL fSwapped;
00481
#if DBG
00482
int cLinks;
00483
#endif
00484
00485
if (
msg) {
00486
if (
msg != WM_DDE_ACK) {
00487
return (
SpontaneousServerMessage((
PSVR_CONV_INFO)pxi->
pcoi,
msg, lParam));
00488 }
00489
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi);
00490
if ((
GATOM)uiHi != pxi->
gaItem) {
00491 RIPMSG0(RIP_ERROR,
"DDE Protocol violation: Data ACK had wrong item");
00492
return (
SpontaneousServerMessage((
PSVR_CONV_INFO)pxi->
pcoi,
msg, lParam));
00493 }
00494
00495 GlobalDeleteAtom((ATOM)uiHi);
00496
FreeDDElParam(WM_DDE_ACK, lParam);
00497
00498
if (!((uiLo & DDE_FACK) && pxi->
hDDESent)) {
00499
FreeDDEData(pxi->
hDDESent,
FALSE,
TRUE);
00500 }
00501
00502
#if DBG
00503
00504
00505
00506 cLinks = pxi->
pcoi->
cLinks;
00507
#endif
00508
00509
00510
00511 la =
GlobalToLocalAtom((
GATOM)uiHi);
00512 paLink = pxi->
pcoi->
aLinks;
00513
for (iLink = 0; iLink < pxi->
pcoi->
cLinks; iLink++, paLink++) {
00514
if (paLink->
laItem == la &&
00515 paLink->
state &
ADVST_WAITING) {
00516 paLink->
state &= ~
ADVST_WAITING;
00517
00518
00519
00520
00521 pxiNew = (
PXACT_INFO)
DDEMLAlloc(
sizeof(
XACT_INFO));
00522
00523
if (pxiNew && !
UpdateLinkIfChanged(paLink, pxiNew, pxi->
pcoi,
00524 &pxi->
pcoi->
aLinks[pxi->
pcoi->
cLinks - 1], &fSwapped,
00525 CADV_LATEACK)) {
00526
00527
00528
00529
DDEMLFree(pxiNew);
00530 }
00531
break;
00532 }
00533 }
00534
#if DBG
00535
if (cLinks != pxi->
pcoi->
cLinks) {
00536 RIPMSG1(RIP_ERROR,
"SvRespAdviseDataAck: cLinks changed. pxi:%#p", pxi);
00537 }
00538
#endif
00539
00540 DeleteAtom(la);
00541 }
00542 GlobalDeleteAtom(pxi->
gaItem);
00543
UnlinkTransaction(pxi);
00544
DDEMLFree(pxi);
00545
return (
TRUE);
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 BOOL ClStartUnadvise(
00562
PXACT_INFO pxi)
00563 {
00564
DWORD dwError;
00565
00566
IncGlobalAtomCount(pxi->
gaItem);
00567 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner, 0, WM_DDE_UNADVISE,
00568 pxi->
pcoi->
hwndConv, 0, pxi->
wFmt, pxi->
gaItem);
00569
if (dwError) {
00570
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
00571 GlobalDeleteAtom(pxi->
gaItem);
00572
return (
FALSE);
00573 }
00574
00575
00576
00577
00578
if (!(pxi->
pcoi->
state & ST_ISLOCAL)) {
00579
MONLINK(pxi->
pcoi->
pcii,
FALSE, 0,
00580 pxi->
pcoi->
laService, pxi->
pcoi->
laTopic, pxi->
gaItem,
00581 pxi->
wFmt,
FALSE, (HCONV)pxi->
pcoi->
hwndPartner,
00582 (HCONV)pxi->
pcoi->
hwndConv);
00583 }
00584 pxi->
state = XST_UNADVSENT;
00585 pxi->
pfnResponse = (
FNRESPONSE)
ClRespUnadviseAck;
00586
LinkTransaction(pxi);
00587
return (
TRUE);
00588 }
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 void CloseTransaction(
00600
PCONV_INFO pci,
00601 ATOM atom)
00602 {
00603
PXACT_INFO pxi;
00604
PXACT_INFO pxiD;
00605
00606 pxi = pci->
pxiOut;
00607
00608
while (pxi && (pxi->
gaItem == atom)) {
00609 pxiD = pxi;
00610 pxi = pxi->
next;
00611
DDEMLFree(pxiD);
00612 }
00613 pci->
pxiOut = pxi;
00614
00615
if (pxi ==
NULL) {
00616 pci->
pxiIn =
NULL;
00617
return;
00618 }
00619
00620
while (pxi->
next) {
00621
if (pxi->
next->
gaItem == atom) {
00622 pxiD = pxi->
next;
00623 pxi->
next = pxiD->
next;
00624
DDEMLFree(pxiD);
00625 }
else
00626 pxi = pxi->
next;
00627 }
00628 pci->
pxiIn = pxi;
00629 }
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 BOOL SvSpontUnadvise(
00641
PSVR_CONV_INFO psi,
00642 LPARAM lParam)
00643 {
00644 ULONG_PTR dwRet = 0;
00645
DWORD dwError;
00646
INT iLink;
00647
PADVISE_LINK aLink;
00648
LATOM la;
00649
00650 la =
GlobalToLocalAtom((
GATOM)HIWORD(lParam));
00651
00652
CloseTransaction(&psi->
ci, HIWORD(lParam));
00653
00654
for (aLink = psi->
ci.
aLinks, iLink = 0; iLink < psi->
ci.
cLinks;) {
00655
00656
if (la == 0 || aLink->
laItem == la &&
00657 (LOWORD(lParam) == 0 || LOWORD(lParam) == aLink->
wFmt)) {
00658
00659
if (!(psi->
ci.
pcii->
afCmd & CBF_FAIL_ADVISES)) {
00660
00661
00662
00663 dwRet = (ULONG_PTR)
DoCallback(psi->
ci.
pcii,
00664 (WORD)XTYP_ADVSTOP, aLink->
wFmt, psi->
ci.
hConv,
00665
NORMAL_HSZ_FROM_LATOM(psi->
ci.
laTopic),
00666
NORMAL_HSZ_FROM_LATOM(la),
00667 (HDDEDATA)0, 0
L, 0
L);
00668
if (dwRet == (ULONG_PTR)CBR_BLOCK) {
00669 DeleteAtom(la);
00670
return(
FALSE);
00671 }
00672 }
00673
00674
00675
00676
MONLINK(psi->
ci.
pcii,
TRUE, 0, psi->
ci.
laService,
00677 psi->
ci.
laTopic, HIWORD(lParam), aLink->
wFmt,
TRUE,
00678 (HCONV)psi->
ci.
hwndConv, (HCONV)psi->
ci.
hwndPartner);
00679
00680
00681
00682 DeleteAtom(aLink->
laItem);
00683
DeleteLinkCount(psi->
ci.
pcii, aLink->
pLinkCount);
00684
if (--psi->
ci.
cLinks) {
00685 memmove((LPSTR)aLink, (LPSTR)(aLink + 1),
00686
sizeof(
ADVISE_LINK) * (psi->
ci.
cLinks - iLink));
00687 }
00688 }
else {
00689 aLink++;
00690 iLink++;
00691 }
00692 }
00693
00694 DeleteAtom(la);
00695
00696
00697
00698
00699 dwError =
PackAndPostMessage(psi->
ci.
hwndPartner, 0,
00700 WM_DDE_ACK, psi->
ci.
hwndConv, 0, DDE_FACK, HIWORD(lParam));
00701
if (dwError) {
00702
SetLastDDEMLError(psi->
ci.
pcii, dwError);
00703 GlobalDeleteAtom((ATOM)HIWORD(lParam));
00704
00705 }
00706
00707
return (
TRUE);
00708 }
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719 BOOL ClRespUnadviseAck(
00720
PXACT_INFO pxi,
00721 UINT msg,
00722 LPARAM lParam)
00723 {
00724 UINT_PTR uiLo, uiHi;
00725
LATOM al;
00726
PADVISE_LINK aLink;
00727
int iLink;
00728
00729
if (
msg) {
00730
if (
msg != WM_DDE_ACK) {
00731
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
00732 }
00733
00734
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi);
00735
if ((
GATOM)uiHi != pxi->
gaItem) {
00736
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
00737 }
00738
00739 al =
GlobalToLocalAtom((ATOM)uiHi);
00740
for (aLink = pxi->
pcoi->
aLinks, iLink = 0;
00741 iLink < pxi->
pcoi->
cLinks;
00742 ) {
00743
if (aLink->
laItem == al &&
00744 (pxi->
wFmt == 0 || aLink->
wFmt == pxi->
wFmt)) {
00745 DeleteAtom(al);
00746
if (--pxi->
pcoi->
cLinks) {
00747 memmove((LPSTR)aLink, (LPSTR)(aLink + 1),
00748
sizeof(
ADVISE_LINK) * (pxi->
pcoi->
cLinks - iLink));
00749 }
00750 }
else {
00751 aLink++;
00752 iLink++;
00753 }
00754 }
00755 DeleteAtom(al);
00756 GlobalDeleteAtom((ATOM)uiHi);
00757
00758 pxi->
state = XST_UNADVACKRCVD;
00759 pxi->
wStatus = (WORD)uiLo;
00760
if (
TransactionComplete(pxi, (HDDEDATA)1)) {
00761
goto Cleanup;
00762 }
00763 }
else {
00764 Cleanup:
00765 GlobalDeleteAtom(pxi->
gaItem);
00766
UnlinkTransaction(pxi);
00767
if (pxi->
hXact) {
00768
DestroyHandle(pxi->
hXact);
00769 }
00770
DDEMLFree(pxi);
00771 }
00772
if (
msg) {
00773
FreeDDElParam(
msg, lParam);
00774 }
00775
return (
TRUE);
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791 HANDLE
MaybeTranslateExecuteData(
00792 HANDLE hDDE,
00793 BOOL fUnicodeFrom,
00794 BOOL fUnicodeTo,
00795 BOOL fFreeSource)
00796 {
00797 PSTR pstr;
00798 PWSTR pwstr;
00799
DWORD cb;
00800 HANDLE hDDEnew;
00801
00802
if (fUnicodeFrom && !fUnicodeTo) {
00803
00804 cb = (
DWORD)(GlobalSize(hDDE) >> 1);
00805 hDDEnew =
UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cb);
00806
USERGLOBALLOCK(hDDEnew, pstr);
00807
USERGLOBALLOCK(hDDE, pwstr);
00808
if (pstr !=
NULL && pwstr !=
NULL) {
00809 WCSToMB(pwstr, -1, &pstr, cb,
FALSE);
00810 }
00811
if (pwstr) {
00812
USERGLOBALUNLOCK(hDDE);
00813 }
00814
if (pstr) {
00815
USERGLOBALUNLOCK(hDDEnew);
00816 }
00817 }
else if (!fUnicodeFrom && fUnicodeTo) {
00818
00819 cb = (
DWORD)(GlobalSize(hDDE) << 1);
00820 hDDEnew =
UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cb);
00821
USERGLOBALLOCK(hDDEnew, pwstr);
00822
USERGLOBALLOCK(hDDE, pstr);
00823
if (pwstr !=
NULL && pstr !=
NULL) {
00824 MBToWCS(pstr, -1, &pwstr, cb,
FALSE);
00825 }
00826
if (pstr) {
00827
USERGLOBALUNLOCK(hDDE);
00828 }
00829
if (pwstr) {
00830
USERGLOBALUNLOCK(hDDEnew);
00831 }
00832 }
else {
00833
return (hDDE);
00834 }
00835
if (fFreeSource) {
00836
WOWGLOBALFREE(hDDE);
00837 }
00838
return (hDDEnew);
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852 BOOL ClStartExecute(
00853
PXACT_INFO pxi)
00854 {
00855
DWORD dwError;
00856
00857 pxi->
hDDESent =
MaybeTranslateExecuteData(pxi->
hDDESent,
00858 pxi->
pcoi->
pcii->
flags &
IIF_UNICODE,
00859 pxi->
pcoi->
state & ST_UNICODE_EXECUTE,
00860
TRUE);
00861
00862 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner, 0, WM_DDE_EXECUTE,
00863 pxi->
pcoi->
hwndConv, 0, 0, HandleToUlong(pxi->
hDDESent));
00864
if (dwError) {
00865
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
00866
return (
FALSE);
00867 }
00868 pxi->
state = XST_EXECSENT;
00869 pxi->
pfnResponse = (
FNRESPONSE)
ClRespExecuteAck;
00870
LinkTransaction(pxi);
00871
return (
TRUE);
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 BOOL SvSpontExecute(
00886
PSVR_CONV_INFO psi,
00887 LPARAM lParam)
00888 {
00889 HANDLE hDDE, hDDEx;
00890 ULONG_PTR dwRet = 0;
00891
DWORD dwError;
00892 HDDEDATA hData = 0;
00893
00894 hDDEx = hDDE = (HANDLE)lParam;
00895
if (psi->
ci.
pcii->
afCmd & CBF_FAIL_EXECUTES) {
00896
goto Ack;
00897 }
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908 hDDEx =
MaybeTranslateExecuteData(hDDE,
00909 psi->
ci.
state & ST_UNICODE_EXECUTE,
00910 psi->
ci.
pcii->
flags &
IIF_UNICODE,
00911
FALSE);
00912
00913 hData =
InternalCreateDataHandle(psi->
ci.
pcii, (LPBYTE)hDDEx, (
DWORD)-1, 0,
00914 HDATA_EXECUTE | HDATA_READONLY | HDATA_NOAPPFREE, 0, 0);
00915
if (!hData) {
00916
SetLastDDEMLError(psi->
ci.
pcii, DMLERR_MEMORY_ERROR);
00917
goto Ack;
00918 }
00919
00920 dwRet = (ULONG_PTR)
DoCallback(psi->
ci.
pcii,
00921 XTYP_EXECUTE, 0, psi->
ci.
hConv,
00922
NORMAL_HSZ_FROM_LATOM(psi->
ci.
laTopic), 0, hData, 0, 0);
00923
UnpackAndFreeDDEMLDataHandle(hData,
TRUE);
00924
00925
if (dwRet == (ULONG_PTR)CBR_BLOCK) {
00926
if (hDDEx != hDDE) {
00927
WOWGLOBALFREE(hDDEx);
00928 }
00929
return (
FALSE);
00930 }
00931
00932 Ack:
00933 dwRet &= ~DDE_FACKRESERVED;
00934 dwError =
PackAndPostMessage(psi->
ci.
hwndPartner, WM_DDE_EXECUTE,
00935 WM_DDE_ACK, psi->
ci.
hwndConv, lParam, (
DWORD)dwRet, HandleToUlong(hDDE));
00936
if (dwError) {
00937
SetLastDDEMLError(psi->
ci.
pcii, dwError);
00938 }
00939
00940
if (hDDEx != hDDE) {
00941
WOWGLOBALFREE(hDDEx);
00942 }
00943
00944
return (
TRUE);
00945 }
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 BOOL ClRespExecuteAck(
00959
PXACT_INFO pxi,
00960 UINT msg,
00961 LPARAM lParam)
00962 {
00963 UINT_PTR uiLo, uiHi;
00964
00965
if (
msg) {
00966
if (
msg != WM_DDE_ACK) {
00967
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
00968 }
00969
00970
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi);
00971
if (uiHi != HandleToUlong(pxi->
hDDESent)) {
00972
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
00973 }
00974
00975
WOWGLOBALFREE((HANDLE)uiHi);
00976
00977 pxi->
state = XST_EXECACKRCVD;
00978 pxi->
wStatus = (WORD)uiLo;
00979
00980
if (
TransactionComplete(pxi, (HDDEDATA)(pxi->
wStatus & DDE_FACK ? 1 : 0))) {
00981
goto Cleanup;
00982 }
00983 }
else {
00984 Cleanup:
00985 GlobalDeleteAtom(pxi->
gaItem);
00986
UnlinkTransaction(pxi);
00987
if (pxi->
hXact) {
00988
DestroyHandle(pxi->
hXact);
00989 }
00990
DDEMLFree(pxi);
00991 }
00992
if (
msg) {
00993
FreeDDElParam(
msg, lParam);
00994 }
00995
return (
TRUE);
00996 }
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 BOOL ClStartPoke(
01013
PXACT_INFO pxi)
01014 {
01015
DWORD dwError;
01016
01017
IncGlobalAtomCount(pxi->
gaItem);
01018 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner, 0, WM_DDE_POKE,
01019 pxi->
pcoi->
hwndConv, 0, HandleToUlong(pxi->
hDDESent), pxi->
gaItem);
01020
if (dwError) {
01021
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
01022 GlobalDeleteAtom(pxi->
gaItem);
01023
return (
FALSE);
01024 }
01025
01026 pxi->
state = XST_POKESENT;
01027 pxi->
pfnResponse = (
FNRESPONSE)
ClRespPokeAck;
01028
LinkTransaction(pxi);
01029
return (
TRUE);
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 BOOL SvSpontPoke(
01043
PSVR_CONV_INFO psi,
01044 LPARAM lParam)
01045 {
01046 UINT_PTR uiHi;
01047 HANDLE hDDE = 0;
01048 HDDEDATA hData;
01049 ULONG_PTR dwRet = 0;
01050
DWORD dwError;
01051 WORD wFmt, wStatus;
01052
LATOM al;
01053
01054
01055
01056
UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT_PTR)&hDDE, &uiHi);
01057
01058
if (!(psi->
ci.
pcii->
afCmd & CBF_FAIL_POKES)) {
01059
if (!hDDE) {
01060
goto Ack;
01061 }
01062
if (!
ExtractDDEDataInfo(hDDE, &wStatus, &wFmt)) {
01063
FreeDDEData(hDDE,
FALSE,
TRUE);
01064
goto Ack;
01065 }
01066
01067 hData =
InternalCreateDataHandle(psi->
ci.
pcii, (LPBYTE)hDDE, (
DWORD)-1, 0,
01068 HDATA_NOAPPFREE | HDATA_READONLY, 0, 0);
01069
if (!hData) {
01070
SetLastDDEMLError(psi->
ci.
pcii, DMLERR_MEMORY_ERROR);
01071
FreeDDEData(hDDE,
FALSE,
TRUE);
01072
goto Ack;
01073
return(
TRUE);
01074 }
01075
01076 al =
GlobalToLocalAtom((
GATOM)uiHi);
01077 dwRet = (ULONG_PTR)
DoCallback(psi->
ci.
pcii, XTYP_POKE,
01078 wFmt, psi->
ci.
hConv,
01079
NORMAL_HSZ_FROM_LATOM(psi->
ci.
laTopic),
01080
NORMAL_HSZ_FROM_LATOM(al),
01081 hData, 0, 0);
01082 DeleteAtom(al);
01083
UnpackAndFreeDDEMLDataHandle(hData,
FALSE);
01084 }
01085
if (dwRet == (ULONG_PTR)CBR_BLOCK) {
01086
01087
01088
01089
01090
return (
FALSE);
01091 }
01092
if (dwRet & DDE_FACK) {
01093
FreeDDEData(hDDE,
FALSE,
TRUE);
01094 }
01095
01096 Ack:
01097 dwRet &= ~DDE_FACKRESERVED;
01098 dwError =
PackAndPostMessage(psi->
ci.
hwndPartner, WM_DDE_POKE, WM_DDE_ACK,
01099 psi->
ci.
hwndConv, lParam, dwRet, uiHi);
01100
if (dwError) {
01101
SetLastDDEMLError(psi->
ci.
pcii, dwError);
01102 }
01103
return (
TRUE);
01104 }
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116 BOOL ClRespPokeAck(
01117
PXACT_INFO pxi,
01118 UINT msg,
01119 LPARAM lParam)
01120 {
01121 UINT_PTR uiLo, uiHi;
01122
01123
if (
msg) {
01124
if (
msg != WM_DDE_ACK) {
01125
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
01126 }
01127
01128
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi);
01129
if ((
GATOM)uiHi != pxi->
gaItem) {
01130
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
01131 }
01132
01133 GlobalDeleteAtom((ATOM)uiHi);
01134
01135 pxi->
state = XST_POKEACKRCVD;
01136 pxi->
wStatus = (WORD)uiLo;
01137
01138
if (!((WORD)uiLo & DDE_FACK)) {
01139
01140
01141
01142
FreeDDEData(pxi->
hDDESent,
FALSE,
TRUE);
01143 }
01144
01145
if (
TransactionComplete(pxi,
01146 (HDDEDATA)(pxi->
wStatus & DDE_FACK ? 1 : 0))) {
01147
goto Cleanup;
01148 }
01149 }
else {
01150 Cleanup:
01151 GlobalDeleteAtom(pxi->
gaItem);
01152
UnlinkTransaction(pxi);
01153
if (pxi->
hXact) {
01154
DestroyHandle(pxi->
hXact);
01155 }
01156
DDEMLFree(pxi);
01157 }
01158
if (
msg) {
01159
FreeDDElParam(
msg, lParam);
01160 }
01161
return (
TRUE);
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176 BOOL ClStartRequest(
01177
PXACT_INFO pxi)
01178 {
01179
DWORD dwError;
01180
01181
IncGlobalAtomCount(pxi->
gaItem);
01182 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner, 0, WM_DDE_REQUEST,
01183 pxi->
pcoi->
hwndConv, 0, pxi->
wFmt, pxi->
gaItem);
01184
if (dwError) {
01185
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
01186 GlobalDeleteAtom(pxi->
gaItem);
01187
return (
FALSE);
01188 }
01189
01190 pxi->
state = XST_REQSENT;
01191 pxi->
pfnResponse = (
FNRESPONSE)
ClRespRequestData;
01192
LinkTransaction(pxi);
01193
return (
TRUE);
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207 BOOL SvSpontRequest(
01208
PSVR_CONV_INFO psi,
01209 LPARAM lParam)
01210 {
01211 HANDLE hDDE = 0;
01212 HDDEDATA hDataRet;
01213 WORD wFmt, wStatus;
01214
DWORD dwError;
01215
LATOM la;
01216
01217
if (psi->
ci.
pcii->
afCmd & CBF_FAIL_REQUESTS) {
01218
goto Nack;
01219 }
01220
01221
01222
01223 wFmt = LOWORD(lParam);
01224 la =
GlobalToLocalAtom((
GATOM)HIWORD(lParam));
01225 hDataRet =
DoCallback(psi->
ci.
pcii, XTYP_REQUEST,
01226 wFmt, psi->
ci.
hConv,
01227
NORMAL_HSZ_FROM_LATOM(psi->
ci.
laTopic),
01228
NORMAL_HSZ_FROM_LATOM(la),
01229 (HDDEDATA)0, 0, 0);
01230 DeleteAtom(la);
01231
01232
if (hDataRet == CBR_BLOCK) {
01233
return (
FALSE);
01234 }
01235
01236
if (hDataRet) {
01237
01238 hDDE =
UnpackAndFreeDDEMLDataHandle(hDataRet,
FALSE);
01239
if (!hDDE) {
01240
SetLastDDEMLError(psi->
ci.
pcii, DMLERR_DLL_USAGE);
01241
goto Nack;
01242 }
01243
if (!
ExtractDDEDataInfo(hDDE, &wStatus, &wFmt)) {
01244
SetLastDDEMLError(psi->
ci.
pcii, DMLERR_DLL_USAGE);
01245
goto Nack;
01246 }
01247
if (!(wStatus & DDE_FRELEASE)) {
01248
01249
01250 hDDE =
CopyDDEData(hDDE,
FALSE);
01251
if (!hDDE) {
01252
SetLastDDEMLError(psi->
ci.
pcii, DMLERR_MEMORY_ERROR);
01253
goto Nack;
01254 }
01255 }
01256
01257
01258
01259 wStatus = DDE_FRELEASE | DDE_FREQUESTED;
01260
AllocAndSetDDEData((LPBYTE)hDDE, (
DWORD)-1, wStatus, wFmt);
01261
01262
01263
if (dwError =
PackAndPostMessage(psi->
ci.
hwndPartner, WM_DDE_REQUEST,
01264 WM_DDE_DATA, psi->
ci.
hwndConv, 0, HandleToUlong(hDDE), HIWORD(lParam))) {
01265
SetLastDDEMLError(psi->
ci.
pcii, dwError);
01266 GlobalDeleteAtom(HIWORD(lParam));
01267 }
01268
01269 }
else {
01270 Nack:
01271
01272 dwError =
PackAndPostMessage(psi->
ci.
hwndPartner, WM_DDE_REQUEST,
01273 WM_DDE_ACK, psi->
ci.
hwndConv, 0, 0, HIWORD(lParam));
01274
if (dwError) {
01275
SetLastDDEMLError(psi->
ci.
pcii, dwError);
01276 GlobalDeleteAtom(HIWORD(lParam));
01277 }
01278 }
01279
01280
return (
TRUE);
01281 }
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294 BOOL ClRespRequestData(
01295
PXACT_INFO pxi,
01296 UINT msg,
01297 LPARAM lParam)
01298 {
01299 UINT_PTR uiLo, uiHi;
01300 WORD wFmt, wStatus;
01301
DWORD dwError;
01302
01303
if (
msg) {
01304
switch (
msg) {
01305
case WM_DDE_DATA:
01306
UnpackDDElParam(WM_DDE_DATA, lParam, (PUINT_PTR)&pxi->
hDDEResult, &uiHi);
01307
if (!pxi->
hDDEResult) {
01308
01309
return (
ClSpontAdviseData((
PCL_CONV_INFO)pxi->
pcoi, lParam));
01310 }
01311
if (!
ExtractDDEDataInfo(pxi->
hDDEResult, &wStatus, &wFmt)) {
01312
return (
ClSpontAdviseData((
PCL_CONV_INFO)pxi->
pcoi, lParam));
01313 }
01314
if (!(wStatus & DDE_FREQUESTED)) {
01315
01316
return (
ClSpontAdviseData((
PCL_CONV_INFO)pxi->
pcoi, lParam));
01317 }
01318
if (wStatus & DDE_FACKREQ) {
01319
01320
01321
01322
01323
01324
01325 dwError =
PackAndPostMessage(pxi->
pcoi->
hwndPartner,
01326 WM_DDE_DATA, WM_DDE_ACK, pxi->
pcoi->
hwndConv, 0,
01327 pxi->
wFmt == wFmt && pxi->
gaItem == (
GATOM)uiHi ?
01328 DDE_FACK : 0, uiHi);
01329
if (dwError) {
01330
SetLastDDEMLError(pxi->
pcoi->
pcii, dwError);
01331 }
01332 }
else {
01333 GlobalDeleteAtom((
GATOM)uiHi);
01334 }
01335
if (wFmt != pxi->
wFmt || (
GATOM)uiHi != pxi->
gaItem) {
01336
01337
01338
01339
01340
FreeDDEData(pxi->
hDDEResult,
FALSE,
TRUE);
01341 pxi->
hDDEResult = 0;
01342
if (
TransactionComplete(pxi, 0)) {
01343
goto Cleanup;
01344 }
01345 }
else {
01346
if (
TransactionComplete(pxi, (HDDEDATA)-1)) {
01347
goto Cleanup;
01348 }
01349 }
01350
break;
01351
01352
case WM_DDE_ACK:
01353
UnpackDDElParam(WM_DDE_ACK, lParam, &uiLo, &uiHi);
01354
if ((
GATOM)uiHi != pxi->
gaItem) {
01355
return(
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
01356 }
01357 pxi->
state = XST_DATARCVD;
01358 pxi->
wStatus = (WORD)uiLo;
01359 GlobalDeleteAtom((
GATOM)uiHi);
01360
if (
TransactionComplete(pxi, 0)) {
01361
goto Cleanup;
01362 }
01363
break;
01364
01365
default:
01366
return (
SpontaneousClientMessage((
PCL_CONV_INFO)pxi->
pcoi,
msg, lParam));
01367 }
01368
01369 }
else {
01370
01371 Cleanup:
01372 GlobalDeleteAtom(pxi->
gaItem);
01373
if (pxi->
hDDEResult) {
01374
FreeDDEData(pxi->
hDDEResult,
FALSE,
TRUE);
01375 }
01376
UnlinkTransaction(pxi);
01377
DDEMLFree(pxi);
01378 }
01379
if (
msg) {
01380
FreeDDElParam(
msg, lParam);
01381 }
01382
return (
TRUE);
01383 }
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 BOOL SpontaneousClientMessage(
01397
PCL_CONV_INFO pci,
01398 UINT msg,
01399 LPARAM lParam)
01400 {
01401
switch (
msg) {
01402
case WM_DDE_DATA:
01403
return (
ClSpontAdviseData(pci, lParam));
01404
break;
01405
01406
default:
01407
DumpDDEMessage(!(pci->
ci.
state & ST_INTRA_PROCESS),
msg, lParam);
01408
ShutdownConversation((
PCONV_INFO)pci,
TRUE);
01409
return (
TRUE);
01410 }
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424 BOOL SpontaneousServerMessage(
01425
PSVR_CONV_INFO psi,
01426 UINT msg,
01427 LPARAM lParam)
01428 {
01429
switch (
msg) {
01430
case WM_DDE_ADVISE:
01431
return (
SvSpontAdvise(psi, lParam));
01432
break;
01433
01434
case WM_DDE_UNADVISE:
01435
return (
SvSpontUnadvise(psi, lParam));
01436
break;
01437
01438
case WM_DDE_EXECUTE:
01439
return (
SvSpontExecute(psi, lParam));
01440
break;
01441
01442
case WM_DDE_POKE:
01443
return (
SvSpontPoke(psi, lParam));
01444
break;
01445
01446
case WM_DDE_REQUEST:
01447
return (
SvSpontRequest(psi, lParam));
01448
break;
01449
01450
default:
01451
DumpDDEMessage(!(psi->
ci.
state & ST_INTRA_PROCESS),
msg, lParam);
01452
01453
01454
01455
01456
01457
01458
return (
TRUE);
01459 }
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479 HANDLE
AllocAndSetDDEData(
01480 LPBYTE pSrc,
01481 DWORD cb,
01482 WORD wStatus,
01483 WORD wFmt)
01484 {
01485 HANDLE hDDE;
01486
DWORD cbOff;
01487
PDDE_DATA pdde;
01488
DWORD fCopyIt;
01489
01490
if (cb == -1) {
01491 hDDE = (HANDLE)pSrc;
01492 cb = (
DWORD)GlobalSize(hDDE);
01493 fCopyIt =
FALSE;
01494 }
else {
01495 hDDE =
UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
01496 (wFmt ? (cb + 4) : cb));
01497 fCopyIt = (pSrc !=
NULL);
01498 }
01499
if (hDDE ==
NULL) {
01500
return(0);
01501 }
01502
USERGLOBALLOCK(hDDE, pdde);
01503
if (pdde ==
NULL) {
01504
WOWGLOBALFREE(hDDE);
01505
return (0);
01506 }
01507
if (wFmt) {
01508 pdde->
wStatus = wStatus;
01509 pdde->
wFmt = wFmt;
01510 cbOff = 4;
01511 }
else {
01512 cbOff = 0;
01513 }
01514
if (fCopyIt) {
01515 RtlCopyMemory((
PBYTE)pdde + cbOff, pSrc, cb);
01516 }
01517
USERGLOBALUNLOCK(hDDE);
01518
01519
return (hDDE);
01520 }
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534 DWORD PackAndPostMessage(
01535 HWND hwndTo,
01536 UINT msgIn,
01537 UINT msgOut,
01538 HWND hwndFrom,
01539 LPARAM lParam,
01540 UINT_PTR uiLo,
01541 UINT_PTR uiHi)
01542 {
01543
DWORD retval;
01544
01545 lParam =
ReuseDDElParam(lParam, msgIn, msgOut, uiLo, uiHi);
01546
if (!lParam) {
01547
return (DMLERR_MEMORY_ERROR);
01548 }
01549
CheckDDECritIn;
01550
LeaveDDECrit;
01551
CheckDDECritOut;
01552
01553 retval = (
DWORD)
PostMessage(hwndTo, msgOut, (WPARAM)hwndFrom, lParam);
01554
switch (retval) {
01555
case FAIL_POST:
01556
#if (FAIL_POST != FALSE)
01557
#error FAIL_POST must be defined as PostMessage's failure return value.
01558
#endif
01559
FreeDDElParam(msgOut, lParam);
01560 RIPMSG0(RIP_WARNING,
"PostMessage failed.");
01561
01562
01563
case FAILNOFREE_POST:
01564 retval = DMLERR_POSTMSG_FAILED;
01565
break;
01566
01567
default:
01568
#if (FAKE_POST != TRUE)
01569
#error FAKE_POST must be defined as PostMessage's success return value.
01570
#endif
01571
UserAssert(retval ==
TRUE);
01572 retval = 0;
01573 }
01574
01575
EnterDDECrit;
01576
return (retval);
01577 }
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 BOOL ExtractDDEDataInfo(
01592 HANDLE hDDE,
01593 LPWORD pwStatus,
01594 LPWORD pwFmt)
01595 {
01596
PDDE_DATA pdde;
01597
01598
USERGLOBALLOCK(hDDE, pdde);
01599
if (pdde ==
NULL) {
01600
return (
FALSE);
01601 }
01602 *pwStatus = pdde->
wStatus;
01603 *pwFmt = pdde->
wFmt;
01604
USERGLOBALUNLOCK(hDDE);
01605
return (
TRUE);
01606 }
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624 BOOL TransactionComplete(
01625
PXACT_INFO pxi,
01626 HDDEDATA hData)
01627 {
01628
LATOM al;
01629
BOOL fMustFree;
01630
01631
if (pxi->
flags &
XIF_ABANDONED) {
01632 UserAssert(!(pxi->
flags &
XIF_SYNCHRONOUS));
01633
return (
TRUE);
01634 }
01635 pxi->
flags |=
XIF_COMPLETE;
01636
if (pxi->
flags &
XIF_SYNCHRONOUS) {
01637
PostMessage(pxi->
pcoi->
hwndConv, WM_TIMER,
TID_TIMEOUT, 0);
01638
return (
FALSE);
01639 }
else {
01640
if (hData == (HDDEDATA)(-1)) {
01641 fMustFree =
TRUE;
01642 hData =
InternalCreateDataHandle(pxi->
pcoi->
pcii,
01643 (LPBYTE)pxi->
hDDEResult, (
DWORD)-1, 0,
01644 HDATA_NOAPPFREE | HDATA_READONLY, 0, 0);
01645 }
else {
01646 fMustFree =
FALSE;
01647 }
01648 al =
GlobalToLocalAtom(pxi->
gaItem);
01649
01650
if (!(pxi->
wStatus & DDE_FACK)) {
01651
if (pxi->
wStatus & DDE_FBUSY) {
01652
SetLastDDEMLError(pxi->
pcoi->
pcii, DMLERR_BUSY);
01653 }
else {
01654
SetLastDDEMLError(pxi->
pcoi->
pcii, DMLERR_NOTPROCESSED);
01655 }
01656 }
01657
01658
01659
01660
01661
01662
01663
UnlinkTransaction(pxi);
01664
01665
DoCallback(
01666 pxi->
pcoi->
pcii,
01667 (WORD)XTYP_XACT_COMPLETE,
01668 pxi->
wFmt,
01669 pxi->
pcoi->
hConv,
01670
NORMAL_HSZ_FROM_LATOM(pxi->
pcoi->
laTopic),
01671 (HSZ)al,
01672 hData,
01673 HandleToUlong(pxi->
hXact),
01674 (
DWORD)pxi->
wStatus);
01675 DeleteAtom(al);
01676
if (fMustFree) {
01677
InternalFreeDataHandle(hData,
FALSE);
01678 pxi->
hDDEResult = 0;
01679 }
01680
01681
01682
01683
01684
01685
01686
if (pxi->
hXact) {
01687
DestroyHandle(pxi->
hXact);
01688 pxi->
hXact = 0;
01689 }
01690
return (
TRUE);
01691 }
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708 HANDLE
UnpackAndFreeDDEMLDataHandle(
01709 HDDEDATA hData,
01710 BOOL fExec)
01711 {
01712
PDDEMLDATA pdd;
01713 HANDLE hDDE;
01714
01715
CheckDDECritIn;
01716
01717
if (hData == 0) {
01718
return (0);
01719 }
01720 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
HTYPE_DATA_HANDLE,
01721
HINST_ANY);
01722
if (pdd ==
NULL) {
01723
return (0);
01724 }
01725
if (!fExec && pdd->
flags & HDATA_EXECUTE) {
01726
return (0);
01727 }
01728
01729 hDDE = pdd->
hDDE;
01730
if (pdd->
flags & HDATA_APPOWNED) {
01731
return (hDDE);
01732 }
01733
DDEMLFree(pdd);
01734
DestroyHandle((HANDLE)hData);
01735
return (hDDE);
01736 }