00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
#include "precomp.h"
00012
#pragma hdrstop
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 HDDEDATA
DdeClientTransaction(
00025 LPBYTE pData,
00026 DWORD cbData,
00027 HCONV hConv,
00028 HSZ hszItem,
00029 UINT wFmt,
00030 UINT wType,
00031 DWORD ulTimeout,
00032 LPDWORD pulResult)
00033 {
00034 MSG
msg;
00035
PCL_INSTANCE_INFO pcii =
NULL;
00036 HDDEDATA hRet = 0;
00037
PCL_CONV_INFO pci;
00038
PDDEMLDATA pdd =
NULL;
00039
PXACT_INFO pxi;
00040
BOOL fStarted;
00041
PDDE_DATA pdde;
00042
00043
EnterDDECrit;
00044
00045 pci = (
PCL_CONV_INFO)
ValidateCHandle((HANDLE)hConv,
00046
HTYPE_CLIENT_CONVERSATION,
HINST_ANY);
00047
if (pci ==
NULL) {
00048
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00049
goto Exit;
00050 }
00051 pcii = pci->
ci.
pcii;
00052
if (ulTimeout != TIMEOUT_ASYNC &&
GetClientInfo()->CI_flags &
CI_IN_SYNC_TRANSACTION) {
00053
SetLastDDEMLError(pcii, DMLERR_REENTRANCY);
00054
goto Exit;
00055 }
00056
if (!(pci->
ci.
state & ST_CONNECTED)) {
00057
SetLastDDEMLError(pcii, DMLERR_NO_CONV_ESTABLISHED);
00058
goto Exit;
00059 }
00060
00061
switch (wType) {
00062
case XTYP_POKE:
00063
case XTYP_ADVSTART:
00064
case XTYP_ADVSTART | XTYPF_NODATA:
00065
case XTYP_ADVSTART | XTYPF_ACKREQ:
00066
case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
00067
case XTYP_REQUEST:
00068
case XTYP_ADVSTOP:
00069
if (hszItem == 0) {
00070
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00071
goto Exit;
00072 }
00073
break;
00074
00075
case XTYP_EXECUTE:
00076
break;
00077
00078
default:
00079
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00080
goto Exit;
00081 }
00082
00083 pxi =
DDEMLAlloc(
sizeof(
XACT_INFO));
00084
if (pxi ==
NULL) {
00085
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00086
goto Exit;
00087 }
00088
00089
switch (wType) {
00090
case XTYP_EXECUTE:
00091
case XTYP_POKE:
00092
if ((LONG)cbData == -1
L) {
00093
00094
00095
00096
00097 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)pData,
00098
HTYPE_DATA_HANDLE,
HINST_ANY);
00099
if (pdd ==
NULL) {
00100 InvParam:
00101
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00102
DDEMLFree(pxi);
00103
goto Exit;
00104 }
00105
00106
00107
00108
if ((pdd->
flags & HDATA_EXECUTE && wType != XTYP_EXECUTE) ||
00109 (!(pdd->
flags & HDATA_EXECUTE) && wType == XTYP_EXECUTE)) {
00110
goto InvParam;
00111 }
00112
00113
00114
00115
00116
if (pdd->
flags & (HDATA_APPOWNED | HDATA_NOAPPFREE)) {
00117 pxi->
hDDESent =
CopyDDEData(pdd->
hDDE, wType == XTYP_EXECUTE);
00118
if (!pxi->
hDDESent) {
00119 MemErr:
00120
DDEMLFree(pxi);
00121
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00122
goto Exit;
00123 }
00124
USERGLOBALLOCK(pxi->
hDDESent, pdde);
00125
if (pdde ==
NULL) {
00126
FreeDDEData(pxi->
hDDESent,
TRUE,
TRUE);
00127
goto MemErr;
00128 }
00129 pdde->
wStatus = DDE_FRELEASE;
00130
USERGLOBALUNLOCK(pxi->
hDDESent);
00131 }
else {
00132 pxi->
hDDESent = pdd->
hDDE;
00133 }
00134
00135
00136
00137
if (wType == XTYP_POKE) {
00138
USERGLOBALLOCK(pxi->
hDDESent, pdde);
00139
if (pdde ==
NULL) {
00140
goto InvParam;
00141 }
00142 pdde->
wFmt = (WORD)wFmt;
00143
USERGLOBALUNLOCK(pxi->
hDDESent);
00144 }
00145
00146 }
else {
00147
00148
if (wType == XTYP_POKE) {
00149 pxi->
hDDESent =
AllocAndSetDDEData(pData, cbData,
00150 DDE_FRELEASE, (WORD)wFmt);
00151 }
else {
00152 pxi->
hDDESent =
AllocAndSetDDEData(pData, cbData, 0, 0);
00153 }
00154
if (!pxi->
hDDESent) {
00155
goto MemErr;
00156 }
00157 }
00158 }
00159
00160
00161
00162 pxi->
pcoi = (
PCONV_INFO)pci;
00163 pxi->
gaItem =
LocalToGlobalAtom(
LATOM_FROM_HSZ(hszItem));
00164 pxi->
wFmt = (WORD)wFmt;
00165 pxi->
wType = (WORD)wType;
00166
00167
switch (wType) {
00168
case XTYP_ADVSTART:
00169
case XTYP_ADVSTART | XTYPF_NODATA:
00170
case XTYP_ADVSTART | XTYPF_ACKREQ:
00171
case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
00172 fStarted =
ClStartAdvise(pxi);
00173
break;
00174
00175
case XTYP_ADVSTOP:
00176 fStarted =
ClStartUnadvise(pxi);
00177
break;
00178
00179
case XTYP_EXECUTE:
00180 fStarted =
ClStartExecute(pxi);
00181
break;
00182
00183
case XTYP_POKE:
00184 fStarted =
ClStartPoke(pxi);
00185
break;
00186
00187
case XTYP_REQUEST:
00188 fStarted =
ClStartRequest(pxi);
00189 }
00190
00191
if (!fStarted) {
00192
00193
if (pxi->
hDDESent && (pdd ==
NULL || pxi->
hDDESent != pdd->
hDDE)) {
00194
FreeDDEData(pxi->
hDDESent,
FALSE,
TRUE);
00195 }
00196 GlobalDeleteAtom(pxi->
gaItem);
00197
DDEMLFree(pxi);
00198
goto Exit;
00199 }
00200
00201
if (pdd !=
NULL && !(pdd->
flags & (HDATA_NOAPPFREE | HDATA_APPOWNED))) {
00202
00203
00204
00205
00206
00207
DDEMLFree(pdd);
00208
DestroyHandle((HANDLE)pData);
00209 }
00210
00211
if (ulTimeout == TIMEOUT_ASYNC) {
00212
00213
00214
00215
if (pulResult !=
NULL) {
00216 pxi->
hXact =
CreateHandle((ULONG_PTR)pxi,
HTYPE_TRANSACTION,
00217
InstFromHandle(pcii->
hInstClient));
00218 *pulResult = HandleToUlong(pxi->hXact);
00219 }
00220 hRet = (HDDEDATA)
TRUE;
00221
00222 }
else {
00223
00224
00225
00226
GetClientInfo()->CI_flags |=
CI_IN_SYNC_TRANSACTION;
00227 pcii->
flags |=
IIF_IN_SYNC_XACT;
00228
00229 pxi->
flags |=
XIF_SYNCHRONOUS;
00230
NtUserSetTimer(pci->
ci.
hwndConv,
TID_TIMEOUT, ulTimeout,
NULL);
00231
00232
LeaveDDECrit;
00233
CheckDDECritOut;
00234
00235
GetMessage(&
msg, (HWND)
NULL, 0, 0);
00236
00237
00238
00239
00240
while (
msg.hwnd != pci->
ci.
hwndConv ||
msg.message != WM_TIMER ||
00241 (
msg.wParam !=
TID_TIMEOUT)) {
00242
00243
if (!
CallMsgFilter(&
msg, MSGF_DDEMGR))
00244
DispatchMessage(&
msg);
00245
00246
GetMessage(&
msg, (HWND)
NULL, 0, 0);
00247 }
00248
00249
EnterDDECrit;
00250
00251
NtUserKillTimer(pci->
ci.
hwndConv,
TID_TIMEOUT);
00252
GetClientInfo()->CI_flags &= ~
CI_IN_SYNC_TRANSACTION;
00253 pcii->
flags &= ~
IIF_IN_SYNC_XACT;
00254
00255
if (pxi->
flags &
XIF_COMPLETE) {
00256
if (pulResult !=
NULL) {
00257 *pulResult = pxi->
wStatus;
00258 }
00259
switch (wType) {
00260
case XTYP_ADVSTART:
00261
case XTYP_ADVSTART | XTYPF_NODATA:
00262
case XTYP_ADVSTART | XTYPF_ACKREQ:
00263
case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
00264
case XTYP_ADVSTOP:
00265
case XTYP_EXECUTE:
00266
case XTYP_POKE:
00267 hRet = (HDDEDATA)((pxi->
wStatus & DDE_FACK) ?
TRUE :
FALSE);
00268
if (!hRet) {
00269
if (pxi->
wStatus & DDE_FBUSY) {
00270
SetLastDDEMLError(pcii, DMLERR_BUSY);
00271 }
else {
00272
SetLastDDEMLError(pcii, DMLERR_NOTPROCESSED);
00273 }
00274 }
00275
break;
00276
00277
case XTYP_REQUEST:
00278
if (pxi->
hDDEResult == 0) {
00279 hRet = (HDDEDATA)((pxi->
wStatus & DDE_FACK) ?
TRUE :
FALSE);
00280
if (!hRet) {
00281
if (pxi->
wStatus & DDE_FBUSY) {
00282
SetLastDDEMLError(pcii, DMLERR_BUSY);
00283 }
else {
00284
SetLastDDEMLError(pcii, DMLERR_NOTPROCESSED);
00285 }
00286 }
00287
break;
00288 }
00289
00290
00291
00292
00293 hRet =
InternalCreateDataHandle(pcii, (LPBYTE)pxi->
hDDEResult, (
DWORD)-1, 0,
00294 HDATA_READONLY, 0, 0);
00295 pxi->
hDDEResult = 0;
00296 }
00297
00298 (pxi->
pfnResponse)((
struct tagXACT_INFO *)pxi, 0, 0);
00299
00300 }
else {
00301
00302
00303
00304
00305 pxi->
flags &= ~
XIF_SYNCHRONOUS;
00306 pxi->
flags |=
XIF_ABANDONED;
00307
00308
switch (wType) {
00309
case XTYP_ADVSTART:
00310
case XTYP_ADVSTART | XTYPF_NODATA:
00311
case XTYP_ADVSTART | XTYPF_ACKREQ:
00312
case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
00313
SetLastDDEMLError(pcii, DMLERR_ADVACKTIMEOUT);
00314
break;
00315
case XTYP_ADVSTOP:
00316
SetLastDDEMLError(pcii, DMLERR_UNADVACKTIMEOUT);
00317
break;
00318
case XTYP_EXECUTE:
00319
SetLastDDEMLError(pcii, DMLERR_EXECACKTIMEOUT);
00320
break;
00321
case XTYP_POKE:
00322
SetLastDDEMLError(pcii, DMLERR_POKEACKTIMEOUT);
00323
break;
00324
case XTYP_REQUEST:
00325
SetLastDDEMLError(pcii, DMLERR_DATAACKTIMEOUT);
00326
break;
00327 }
00328
00329 }
00330 }
00331
if (pci->
ci.
state & ST_FREE_CONV_RES_NOW) {
00332
00333
00334
00335
00336
FreeConversationResources((
PCONV_INFO)pci);
00337 }
00338
00339 Exit:
00340
00341
00342
00343
00344
if (pcii !=
NULL &&
00345 (pcii->
afCmd & APPCMD_UNINIT_ASAP) &&
00346
00347 !pcii->
cInDDEMLCallback) {
00348
DdeUninitialize(HandleToUlong(pcii->
hInstClient));
00349 hRet = 0;
00350 }
00351
LeaveDDECrit;
00352
return (hRet);
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368 VOID GetConvContext(
00369 HWND hwnd,
00370 LONG *pl)
00371 {
00372
int i;
00373
00374
for (i = 0; i <
sizeof(CONVCONTEXT); i += 4) {
00375 *pl++ = GetWindowLong(hwnd,
GWL_CONVCONTEXT + i);
00376 }
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 VOID SetConvContext(
00388 HWND hwnd,
00389 LONG *pl)
00390 {
00391
int i;
00392
00393
for (i = 0; i <
sizeof(CONVCONTEXT); i += 4) {
00394 SetWindowLong(hwnd,
GWL_CONVCONTEXT + i, *pl++);
00395 }
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 UINT DdeQueryConvInfo(
00412 HCONV hConv,
00413 DWORD idTransaction,
00414 PCONVINFO pConvInfo)
00415 {
00416
PCONV_INFO pcoi;
00417
PXACT_INFO pxi;
00418 CONVINFO ci;
00419
UINT uiRet = 0;
00420
00421
EnterDDECrit;
00422
00423
if (!
ValidateTransaction(hConv, (HANDLE)LongToHandle( idTransaction ), &pcoi, &pxi)) {
00424
goto Exit;
00425 }
00426
00427
try {
00428
if (pConvInfo->cb >
sizeof(CONVINFO)) {
00429
SetLastDDEMLError(pcoi->
pcii, DMLERR_INVALIDPARAMETER);
00430
goto Exit;
00431 }
00432 ci.cb = pConvInfo->cb;
00433 ci.hConvPartner = 0;
00434 ci.hszSvcPartner =
NORMAL_HSZ_FROM_LATOM(pcoi->
laService);
00435 ci.hszServiceReq =
NORMAL_HSZ_FROM_LATOM(pcoi->
laServiceRequested);
00436 ci.hszTopic =
NORMAL_HSZ_FROM_LATOM(pcoi->
laTopic);
00437 ci.wStatus = pcoi->
state;
00438 ci.wLastError = (WORD)pcoi->
pcii->
LastError;
00439
if (pcoi->
state & ST_CLIENT) {
00440 ci.hConvList = ((
PCL_CONV_INFO)pcoi)->hConvList;
00441
GetConvContext(pcoi->
hwndConv, (LONG *)&ci.ConvCtxt);
00442 }
else {
00443 ci.hConvList = 0;
00444
if (pcoi->
state & ST_ISLOCAL) {
00445
GetConvContext(pcoi->
hwndPartner, (LONG *)&ci.ConvCtxt);
00446 }
else {
00447 ci.ConvCtxt =
DefConvContext;
00448 }
00449 }
00450
if (pxi ==
NULL) {
00451 ci.hUser = pcoi->
hUser;
00452 ci.hszItem = 0;
00453 ci.wFmt = 0;
00454 ci.wType = 0;
00455 ci.wConvst = XST_CONNECTED;
00456 }
else {
00457 ci.hUser = pxi->
hUser;
00458
00459
00460 ci.hszItem =
NORMAL_HSZ_FROM_LATOM(
GlobalToLocalAtom(pxi->
gaItem));
00461 ci.wFmt = pxi->
wFmt;
00462 ci.wType = pxi->
wType;
00463 ci.wConvst = pxi->
state;
00464 }
00465 ci.hwnd = pcoi->
hwndConv;
00466 ci.hwndPartner = pcoi->
hwndPartner;
00467 RtlCopyMemory((LPSTR)pConvInfo, (LPSTR)&ci, pConvInfo->cb);
00468 } except(W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00469
SetLastDDEMLError(pcoi->
pcii, DMLERR_INVALIDPARAMETER);
00470
goto Exit;
00471 }
00472 uiRet =
TRUE;
00473
00474 Exit:
00475
LeaveDDECrit;
00476
return (uiRet);
00477 }
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489 BOOL DdeSetUserHandle(
00490 HCONV hConv,
00491 DWORD
id,
00492 DWORD_PTR hUser)
00493 {
00494
PCONV_INFO pcoi;
00495
PXACT_INFO pxi;
00496
BOOL fRet =
FALSE;
00497
00498
EnterDDECrit;
00499
00500
if (!
ValidateTransaction(hConv, (HANDLE)LongToHandle(
id ), &pcoi, &pxi)) {
00501
goto Exit;
00502 }
00503
if (pxi ==
NULL) {
00504 pcoi->
hUser = hUser;
00505 }
else {
00506 pxi->
hUser = hUser;
00507 }
00508 fRet =
TRUE;
00509
00510 Exit:
00511
LeaveDDECrit;
00512
return (fRet);
00513 }
00514
00515
00516
00517 VOID AbandonTransaction(
00518
PCONV_INFO pcoi,
00519
PXACT_INFO pxi)
00520 {
00521
if (pxi !=
NULL) {
00522 pxi->
flags |=
XIF_ABANDONED;
00523 }
else {
00524
for (pxi = pcoi->
pxiIn; pxi !=
NULL; pxi = pxi->
next) {
00525 pxi->
flags |=
XIF_ABANDONED;
00526 }
00527 }
00528 }
00529
00530
00531
00532 BOOL AbandonEnumerateProc(
00533 HWND hwnd,
00534 LPARAM idTransaction)
00535 {
00536
PCONV_INFO pcoi;
00537
00538 pcoi = (
PCONV_INFO)
GetWindowLongPtr(hwnd,
GWLP_PCI);
00539
if (!pcoi || !(pcoi->
state & ST_CLIENT)) {
00540
return(
TRUE);
00541 }
00542
while (pcoi) {
00543
AbandonTransaction(pcoi, (
PXACT_INFO)idTransaction);
00544 pcoi = pcoi->
next;
00545 }
00546
return(
TRUE);
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 BOOL DdeAbandonTransaction(
00561 DWORD idInst,
00562 HCONV hConv,
00563 DWORD idTransaction)
00564 {
00565
PCONV_INFO pcoi;
00566
PXACT_INFO pxi;
00567
PCL_INSTANCE_INFO pcii;
00568
BOOL fRet =
FALSE;
00569
00570
EnterDDECrit;
00571
00572 pcii =
ValidateInstance((HANDLE)LongToHandle( idInst ));
00573
00574
if (hConv == 0 && idTransaction == 0) {
00575
EnumChildWindows(pcii->
hwndMother,
AbandonEnumerateProc, 0);
00576
goto Exit;
00577 }
00578
if (idTransaction == 0) {
00579 idTransaction = QID_SYNC;
00580 }
00581
if (!
ValidateTransaction(hConv, (HANDLE)LongToHandle( idTransaction ), &pcoi, &pxi)) {
00582
goto Exit;
00583 }
00584
if (pcii ==
NULL || pcoi->
pcii != pcii) {
00585
SetLastDDEMLError(pcoi->
pcii, DMLERR_INVALIDPARAMETER);
00586
goto Exit;
00587 }
00588
AbandonTransaction(pcoi, pxi);
00589 fRet =
TRUE;
00590
00591 Exit:
00592
LeaveDDECrit;
00593
return (fRet);
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611 BOOL UpdateLinkIfChanged(
00612
PADVISE_LINK paLink,
00613
PXACT_INFO pxi,
00614
PCONV_INFO pcoi,
00615
PADVISE_LINK paLinkLast,
00616 PBOOL pfSwapped,
00617 DWORD cLinksToGo)
00618 {
00619
ADVISE_LINK aLinkT;
00620
00621
CheckDDECritIn;
00622
00623 *pfSwapped =
FALSE;
00624
if (paLink->
state &
ADVST_CHANGED && !(paLink->
state &
ADVST_WAITING)) {
00625 pxi->
pfnResponse =
SvRespAdviseDataAck;
00626 pxi->
pcoi = pcoi;
00627 pxi->
gaItem =
LocalToGlobalAtom(paLink->
laItem);
00628 pxi->
wFmt = paLink->
wFmt;
00629 pxi->
wType = paLink->
wType;
00630 paLink->
state &= ~
ADVST_CHANGED;
00631
if (
SvStartAdviseUpdate(pxi, cLinksToGo)) {
00632
if (pxi->
wType & DDE_FACKREQ) {
00633 paLink->
state |=
ADVST_WAITING;
00634
00635
00636
00637
00638
if (paLink != paLinkLast) {
00639 aLinkT = *paLink;
00640 RtlMoveMemory(paLink, paLink + 1,
00641 (
PBYTE)paLinkLast - (
PBYTE)paLink);
00642 *paLinkLast = aLinkT;
00643 *pfSwapped =
TRUE;
00644 }
00645 }
00646
return(
TRUE);
00647 }
else {
00648 GlobalDeleteAtom(pxi->
gaItem);
00649
return(
FALSE);
00650 }
00651 }
00652
return(
FALSE);
00653 }
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665 BOOL DdePostAdvise(
00666 DWORD idInst,
00667 HSZ hszTopic,
00668 HSZ hszItem)
00669 {
00670
PCL_INSTANCE_INFO pcii;
00671
PSVR_CONV_INFO psi;
00672
PXACT_INFO pxi;
00673
PADVISE_LINK paLink;
00674
BOOL fRet =
FALSE, fSwapped, fFound;
00675
int iServer, iLink;
00676
PLINK_COUNT pLinkCount;
00677
#if DBG
00678
int cLinks;
00679
#endif
00680
00681
EnterDDECrit;
00682
00683 pcii =
ValidateInstance((HANDLE)LongToHandle( idInst ));
00684
if (pcii ==
NULL) {
00685
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00686
goto Exit;
00687 }
00688
if ((
ValidateHSZ(hszTopic) ==
HSZT_INVALID) ||
00689 (
ValidateHSZ(hszItem) ==
HSZT_INVALID)) {
00690
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00691
goto Exit;
00692 }
00693
00694
00695
00696
00697 fFound =
FALSE;
00698
for (pLinkCount = pcii->
pLinkCount;
00699 pLinkCount; pLinkCount = pLinkCount->
next) {
00700 pLinkCount->
Count = pLinkCount->
Total;
00701 fFound |= pLinkCount->
laTopic ==
LATOM_FROM_HSZ(hszTopic) &&
00702 pLinkCount->
laItem ==
LATOM_FROM_HSZ(hszItem);
00703 }
00704
if (!fFound && hszTopic && hszItem) {
00705 fRet =
TRUE;
00706
goto Exit;
00707 }
00708
00709
00710
00711
00712 pxi =
DDEMLAlloc(
sizeof(
XACT_INFO));
00713
if (pxi ==
NULL) {
00714
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00715 fRet =
FALSE;
00716
goto Exit;
00717 }
00718
00719
00720
00721
00722
for (iServer = 0; iServer < pcii->
cServerLookupAlloc; iServer++) {
00723
if (hszTopic == 0 ||
00724 pcii->
aServerLookup[iServer].
laTopic ==
LATOM_FROM_HSZ(hszTopic)) {
00725
00726
00727
00728
00729 psi = (
PSVR_CONV_INFO)
GetWindowLongPtr(
00730 pcii->
aServerLookup[iServer].
hwndServer,
GWLP_PSI);
00731 UserAssert(psi !=
NULL && psi->
ci.
pcii == pcii);
00732
while (psi !=
NULL) {
00733
00734
00735
00736
00737
00738 psi->
ci.
cLocks++;
00739
00740
#if DBG
00741
00742
00743
00744 cLinks = psi->
ci.
cLinks;
00745
#endif
00746
00747
00748
00749
for (paLink = psi->
ci.
aLinks, iLink = 0;
00750 iLink < psi->
ci.
cLinks; paLink++, iLink++) {
00751
if (hszItem == 0 ||
00752 paLink->
laItem ==
LATOM_FROM_HSZ(hszItem)) {
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765 paLink->
state |=
ADVST_CHANGED;
00766
if (
UpdateLinkIfChanged(paLink, pxi, &psi->
ci,
00767 &psi->
ci.
aLinks[psi->
ci.
cLinks - 1],
00768 &fSwapped, --paLink->
pLinkCount->
Count)) {
00769
if (fSwapped) {
00770 paLink--;
00771 }
00772
00773
00774
00775 pxi =
DDEMLAlloc(
sizeof(
XACT_INFO));
00776
if (pxi ==
NULL) {
00777
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00778
00779
00780
00781 psi->
ci.
cLocks--;
00782
if ((psi->
ci.
cLocks == 0) && (psi->
ci.
state & ST_FREE_CONV_RES_NOW)) {
00783 RIPMSG1(RIP_ERROR,
"DdePostAdvise: Conversation terminated. psi:%#p", psi);
00784
FreeConversationResources((
PCONV_INFO)psi);
00785 }
00786
goto Exit;
00787 }
00788 }
00789
00790
00791
00792 UserAssert(pcii ==
ValidateInstance((HANDLE)LongToHandle( idInst )));
00793 }
00794 }
00795
#if DBG
00796
if (cLinks != psi->
ci.
cLinks) {
00797 RIPMSG1(RIP_ERROR,
"DdePostAdvise: cLinks changed. psi:%#p", psi);
00798 }
00799
#endif
00800
00801
00802
00803
00804 psi->
ci.
cLocks--;
00805
if ((psi->
ci.
cLocks == 0) && (psi->
ci.
state & ST_FREE_CONV_RES_NOW)) {
00806 RIPMSG1(RIP_ERROR,
"DdePostAdvise: Conversation terminated. psi:%#p", psi);
00807
FreeConversationResources((
PCONV_INFO)psi);
00808
break;
00809 }
00810
00811 psi = (
PSVR_CONV_INFO)psi->
ci.
next;
00812 }
00813 }
00814 }
00815
DDEMLFree(pxi);
00816 fRet =
TRUE;
00817
00818 Exit:
00819
00820
00821
00822
00823 UserAssert(pcii ==
ValidateInstance((HANDLE)LongToHandle( idInst )));
00824
if (pcii !=
NULL &&
00825 pcii->
afCmd & APPCMD_UNINIT_ASAP &&
00826 !(pcii->
flags &
IIF_IN_SYNC_XACT) &&
00827 !pcii->
cInDDEMLCallback) {
00828
DdeUninitialize(HandleToUlong(pcii->
hInstClient));
00829 fRet =
TRUE;
00830 }
00831
LeaveDDECrit;
00832
return (fRet);
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846 VOID LinkTransaction(
00847
PXACT_INFO pxi)
00848 {
00849
CheckDDECritIn;
00850
00851 pxi->
next =
NULL;
00852
if (pxi->
pcoi->
pxiOut ==
NULL) {
00853 pxi->
pcoi->
pxiIn = pxi->
pcoi->
pxiOut = pxi;
00854 }
else {
00855 pxi->
pcoi->
pxiIn->
next = pxi;
00856 pxi->
pcoi->
pxiIn = pxi;
00857 }
00858
#if DBG
00859
00860
00861
00862
00863
00864 {
00865
PXACT_INFO pxiT;
00866
00867
for (pxiT = pxi->
pcoi->
pxiOut; pxiT !=
NULL; pxiT = pxiT->
next) {
00868 ;
00869 }
00870 }
00871
#endif // DBG
00872
}
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 VOID UnlinkTransaction(
00886
PXACT_INFO pxi)
00887 {
00888
CheckDDECritIn;
00889
if (pxi == pxi->
pcoi->
pxiOut) {
00890 pxi->
pcoi->
pxiOut = pxi->
next;
00891
if (pxi->
next ==
NULL) {
00892 pxi->
pcoi->
pxiIn =
NULL;
00893 }
00894 }
00895 }
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 BOOL ValidateTransaction(
00910 HCONV hConv,
00911 HANDLE hXact,
00912
PCONV_INFO *ppcoi,
00913
PXACT_INFO *ppxi)
00914 {
00915
PCL_INSTANCE_INFO pcii;
00916
00917 *ppcoi = (
PCONV_INFO)
ValidateCHandle((HANDLE)hConv,
00918
HTYPE_CLIENT_CONVERSATION,
HINST_ANY);
00919
if (*ppcoi ==
NULL) {
00920 *ppcoi = (
PCONV_INFO)
ValidateCHandle((HANDLE)hConv,
00921
HTYPE_SERVER_CONVERSATION,
HINST_ANY);
00922 }
00923
if (*ppcoi ==
NULL) {
00924
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00925
return (
FALSE);
00926 }
00927 pcii =
ValidateInstance((*ppcoi)->pcii->hInstClient);
00928
if (pcii != (*ppcoi)->pcii) {
00929
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00930
return (
FALSE);
00931 }
00932
00933
if (hXact == (HANDLE)IntToPtr( QID_SYNC )) {
00934 *ppxi =
NULL;
00935 }
else {
00936 *ppxi = (
PXACT_INFO)
ValidateCHandle(hXact,
HTYPE_TRANSACTION,
00937
InstFromHandle((*ppcoi)->pcii->hInstClient));
00938
if (*ppxi ==
NULL) {
00939
SetLastDDEMLError((*ppcoi)->pcii, DMLERR_INVALIDPARAMETER);
00940
return (
FALSE);
00941 }
00942 }
00943
return (
TRUE);
00944 }