00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #define DDEMLDB
00013
#include "precomp.h"
00014
#pragma hdrstop
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 HDDEDATA
DdeCreateDataHandle(
00026 DWORD idInst,
00027 LPBYTE pSrc,
00028 DWORD cb,
00029 DWORD cbOff,
00030 HSZ hszItem,
00031 UINT wFmt,
00032 UINT afCmd)
00033 {
00034
PCL_INSTANCE_INFO pcii;
00035 HDDEDATA hRet = 0;
00036
00037
if (cb == -1) {
00038 RIPMSG0(RIP_ERROR,
"DdeCreateDataHandle called with cb == -1\n");
00039
return NULL;
00040 }
00041
00042
EnterDDECrit;
00043
00044 pcii =
ValidateInstance((HANDLE)LongToHandle( idInst ));
00045
if (pcii ==
NULL) {
00046
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00047
goto Exit;
00048 }
00049
if (afCmd & ~HDATA_APPOWNED) {
00050
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00051
goto Exit;
00052 }
00053
00054
if (cb + cbOff <
sizeof(
DWORD) && pSrc ==
NULL &&
00055 (wFmt == CF_METAFILEPICT ||
00056 wFmt == CF_DSPMETAFILEPICT ||
00057 wFmt == CF_DIB ||
00058 wFmt == CF_BITMAP ||
00059 wFmt == CF_DSPBITMAP ||
00060 wFmt == CF_PALETTE ||
00061 wFmt == CF_ENHMETAFILE ||
00062 wFmt == CF_DSPENHMETAFILE)) {
00063
00064
00065
00066
00067
00068
00069 cb += 4;
00070 }
00071 hRet =
InternalCreateDataHandle(pcii, pSrc, cb, cbOff,
00072 hszItem ? afCmd : (afCmd | HDATA_EXECUTE),
00073 (WORD)((afCmd & HDATA_APPOWNED) ? 0 : DDE_FRELEASE), (WORD)wFmt);
00074
00075
if (!hRet) {
00076
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00077 }
00078 Exit:
00079
LeaveDDECrit;
00080
return (hRet);
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 HDDEDATA
InternalCreateDataHandle(
00095
PCL_INSTANCE_INFO pcii,
00096 LPBYTE pSrc,
00097 DWORD cb,
00098 DWORD cbOff,
00099 DWORD flags,
00100 WORD wStatus,
00101 WORD wFmt)
00102 {
00103
PDDEMLDATA pdd;
00104 HDDEDATA hRet;
00105 LPBYTE p;
00106
DWORD cbOff2;
00107
00108
CheckDDECritIn;
00109
00110 pdd = (
PDDEMLDATA)
DDEMLAlloc(
sizeof(
DDEMLDATA));
00111
if (pdd ==
NULL) {
00112
return (0);
00113 }
00114
if (cb == -1) {
00115 pdd->
hDDE = (HANDLE)pSrc;
00116 }
else {
00117
if (flags & HDATA_EXECUTE) {
00118 cbOff2 = 0;
00119 }
else {
00120 cbOff2 =
sizeof(WORD) +
sizeof(WORD);
00121 }
00122 pdd->
hDDE =
UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
00123 cb + cbOff + cbOff2);
00124
if (pdd->
hDDE ==
NULL) {
00125
DDEMLFree(pdd);
00126
return (0);
00127 }
00128
00129
if (!(flags & HDATA_EXECUTE)) {
00130
PDDE_DATA pdde;
00131
00132
USERGLOBALLOCK(pdd->
hDDE, pdde);
00133 UserAssert(pdde);
00134 pdde->
wStatus = wStatus;
00135 pdde->
wFmt = wFmt;
00136
USERGLOBALUNLOCK(pdd->
hDDE);
00137 }
00138 }
00139 pdd->
flags = (WORD)flags;
00140 hRet = (HDDEDATA)
CreateHandle((ULONG_PTR)pdd,
HTYPE_DATA_HANDLE,
00141
InstFromHandle(pcii->
hInstClient));
00142
if (!hRet) {
00143
WOWGLOBALFREE(pdd->hDDE);
00144
DDEMLFree(pdd);
00145
return (0);
00146 }
00147
if (cb != -1 && pSrc !=
NULL) {
00148
USERGLOBALLOCK(pdd->hDDE, p);
00149 UserAssert(p);
00150 RtlCopyMemory(p + cbOff + cbOff2, pSrc, cb);
00151
USERGLOBALUNLOCK(pdd->hDDE);
00152 pdd->flags |= HDATA_INITIALIZED;
00153 }
00154
return (hRet);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 HDDEDATA
DdeAddData(
00167 HDDEDATA hData,
00168 LPBYTE pSrc,
00169 DWORD cb,
00170 DWORD cbOff)
00171 {
00172 LPSTR pMem;
00173
PDDEMLDATA pdd;
00174
PCL_INSTANCE_INFO pcii;
00175 HDDEDATA hRet = 0;
00176
00177
EnterDDECrit;
00178
00179 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
HTYPE_DATA_HANDLE,
HINST_ANY);
00180
if (pdd ==
NULL) {
00181
goto Exit;
00182 }
00183 pcii =
PciiFromHandle((HANDLE)hData);
00184
if (pcii ==
NULL) {
00185
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00186
goto Exit;
00187 }
00188
if (!(pdd->
flags & HDATA_EXECUTE)) {
00189 cbOff += 4;
00190 }
00191
if (cb + cbOff >
UserGlobalSize(pdd->
hDDE)) {
00192 pdd->
hDDE =
UserGlobalReAlloc(pdd->
hDDE, cb + cbOff,
00193 GMEM_MOVEABLE | GMEM_ZEROINIT);
00194 }
00195
00196
USERGLOBALLOCK(pdd->
hDDE, pMem);
00197
00198
if (pMem ==
NULL) {
00199
SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
00200
goto Exit;
00201 }
00202
00203 hRet = hData;
00204
00205
if (pSrc !=
NULL) {
00206
try {
00207 RtlCopyMemory(pMem + cbOff, pSrc, cb);
00208 pdd->
flags |= HDATA_INITIALIZED;
00209 } except(W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00210
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00211 hRet = 0;
00212 }
00213 }
00214
00215
USERGLOBALUNLOCK(pdd->
hDDE);
00216
00217 Exit:
00218
LeaveDDECrit;
00219
return (hRet);
00220 }
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 DWORD DdeGetData(
00235 HDDEDATA hData,
00236 LPBYTE pDst,
00237 DWORD cbMax,
00238 DWORD cbOff)
00239 {
00240
DWORD cbCopied = 0;
00241
DWORD cbSize;
00242
PDDEMLDATA pdd;
00243
PCL_INSTANCE_INFO pcii;
00244
00245
EnterDDECrit;
00246
00247 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
00248
HTYPE_DATA_HANDLE,
HINST_ANY);
00249
if (pdd ==
NULL) {
00250
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00251
goto Exit;
00252 }
00253 pcii =
PciiFromHandle((HANDLE)hData);
00254
if (pcii ==
NULL) {
00255
BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
00256
goto Exit;
00257 }
00258
if (!(pdd->
flags & HDATA_EXECUTE)) {
00259 cbOff += 4;
00260 }
00261 cbSize = (
DWORD)
UserGlobalSize(pdd->
hDDE);
00262
if (cbOff >= cbSize) {
00263
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00264
goto Exit;
00265 }
00266
if (pDst ==
NULL) {
00267 cbCopied = cbSize - cbOff;
00268
goto Exit;
00269 }
else {
00270 LPSTR pMem;
00271
00272 cbCopied =
min(cbMax, cbSize - cbOff);
00273
USERGLOBALLOCK(pdd->
hDDE, pMem);
00274 UserAssert(pMem);
00275
try {
00276 RtlCopyMemory(pDst, pMem + cbOff, cbCopied);
00277 } except(W32ExceptionHandler(
FALSE, RIP_WARNING)) {
00278
SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
00279 cbCopied = 0;
00280 }
00281
if (pMem !=
NULL) {
00282
USERGLOBALUNLOCK(pdd->
hDDE);
00283 }
00284 }
00285
00286 Exit:
00287
LeaveDDECrit;
00288
return (cbCopied);
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 LPBYTE
DdeAccessData(
00305 HDDEDATA hData,
00306 LPDWORD pcbDataSize)
00307 {
00308
PCL_INSTANCE_INFO pcii;
00309
PDDEMLDATA pdd;
00310 LPBYTE pRet =
NULL;
00311
DWORD cbOff;
00312
00313
EnterDDECrit;
00314
00315 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
00316
HTYPE_DATA_HANDLE,
HINST_ANY);
00317
if (pdd ==
NULL) {
00318
goto Exit;
00319 }
00320 pcii =
PciiFromHandle((HANDLE)hData);
00321 cbOff = pdd->
flags & HDATA_EXECUTE ? 0 : 4;
00322
if (pcbDataSize !=
NULL) {
00323 *pcbDataSize = (
DWORD)
UserGlobalSize(pdd->
hDDE) - cbOff;
00324 }
00325
USERGLOBALLOCK(pdd->
hDDE, pRet);
00326 UserAssert(pRet);
00327 pRet = (LPBYTE)pRet + cbOff;
00328
00329 Exit:
00330
LeaveDDECrit;
00331
return (pRet);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 BOOL DdeUnaccessData(
00347 HDDEDATA hData)
00348 {
00349
PDDEMLDATA pdd;
00350
BOOL fSuccess =
FALSE;
00351
00352
EnterDDECrit;
00353
00354 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
00355
HTYPE_DATA_HANDLE,
HINST_ANY);
00356
if (pdd ==
NULL) {
00357
goto Exit;
00358 }
00359
USERGLOBALUNLOCK(pdd->
hDDE);
00360 fSuccess =
TRUE;
00361
00362 Exit:
00363
LeaveDDECrit;
00364
return (fSuccess);
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378 BOOL DdeFreeDataHandle(
00379 HDDEDATA hData)
00380 {
00381
PDDEMLDATA pdd;
00382
BOOL fSuccess =
FALSE;
00383
00384
EnterDDECrit;
00385
00386 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
00387
HTYPE_DATA_HANDLE,
HINST_ANY);
00388
if (pdd ==
NULL) {
00389
goto Exit;
00390 }
00391
if (pdd->
flags & HDATA_NOAPPFREE) {
00392 fSuccess =
TRUE;
00393
goto Exit;
00394 }
00395
00396 fSuccess =
InternalFreeDataHandle(hData,
TRUE);
00397
00398 Exit:
00399
LeaveDDECrit;
00400
return (fSuccess);
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 BOOL InternalFreeDataHandle(
00417 HDDEDATA hData,
00418 BOOL fIgnorefRelease)
00419 {
00420
PDDEMLDATA pdd;
00421
00422
CheckDDECritIn;
00423
00424 pdd = (
PDDEMLDATA)
ValidateCHandle((HANDLE)hData,
00425
HTYPE_DATA_HANDLE,
HINST_ANY);
00426
if (pdd ==
NULL) {
00427
return (
FALSE);
00428 }
00429
if (pdd->
flags & HDATA_EXECUTE) {
00430
if (!(pdd->
flags & HDATA_APPOWNED) || fIgnorefRelease) {
00431
WOWGLOBALFREE(pdd->
hDDE);
00432 }
00433 }
else {
00434
FreeDDEData(pdd->
hDDE, fIgnorefRelease,
TRUE);
00435 }
00436
DDEMLFree(pdd);
00437
DestroyHandle((HANDLE)hData);
00438
return (
TRUE);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 BOOL ApplyFreeDataHandle(
00452 HANDLE hData)
00453 {
00454
BOOL fRet;
00455
00456
CheckDDECritOut;
00457
EnterDDECrit;
00458 fRet =
InternalFreeDataHandle((HDDEDATA)hData,
FALSE);
00459
LeaveDDECrit;
00460
return(fRet);
00461 }
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491 VOID FreeDDEData(
00492 HANDLE hDDE,
00493 BOOL fIgnorefRelease,
00494 BOOL fFreeTruelyGlobalObjects)
00495 {
00496
PDDE_DATA pdde;
00497 LPMETAFILEPICT pmfPict;
00498
DWORD cb;
00499
00500
USERGLOBALLOCK(hDDE, pdde);
00501
if (pdde ==
NULL) {
00502
return ;
00503 }
00504
00505
if ((pdde->
wStatus & DDE_FRELEASE) || fIgnorefRelease) {
00506 cb = (
DWORD)GlobalSize(hDDE);
00507
00508
00509
00510
00511
00512
switch (pdde->
wFmt) {
00513
case CF_BITMAP:
00514
case CF_DSPBITMAP:
00515
case CF_PALETTE:
00516
if (cb >=
sizeof(HANDLE)) {
00517
if (fFreeTruelyGlobalObjects) {
00518
if (pdde->
Data != 0) {
00519 DeleteObject((HANDLE)pdde->
Data);
00520 }
00521 }
else {
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 }
00534 }
00535
break;
00536
00537
case CF_DIB:
00538
if (cb >=
sizeof(HANDLE)) {
00539
if (pdde->
Data != 0) {
00540
WOWGLOBALFREE((HANDLE)pdde->
Data);
00541 }
00542 }
00543
break;
00544
00545
case CF_METAFILEPICT:
00546
case CF_DSPMETAFILEPICT:
00547
if (cb >=
sizeof(HANDLE)) {
00548
if (pdde->
Data != 0) {
00549
USERGLOBALLOCK(pdde->
Data, pmfPict);
00550
if (pmfPict !=
NULL) {
00551
if (GlobalSize((HANDLE)pdde->
Data) >=
sizeof(METAFILEPICT)) {
00552 DeleteMetaFile(pmfPict->hMF);
00553 }
00554
USERGLOBALUNLOCK((HANDLE)pdde->
Data);
00555
WOWGLOBALFREE((HANDLE)pdde->
Data);
00556 }
00557 }
00558 }
00559
break;
00560
00561
case CF_ENHMETAFILE:
00562
case CF_DSPENHMETAFILE:
00563
if (cb >=
sizeof(HANDLE)) {
00564
if (pdde->
Data != 0) {
00565 DeleteEnhMetaFile((HANDLE)pdde->
Data);
00566 }
00567 }
00568
break;
00569 }
00570
USERGLOBALUNLOCK(hDDE);
00571
WOWGLOBALFREE(hDDE);
00572 }
else {
00573
USERGLOBALUNLOCK(hDDE);
00574 }
00575 }
00576
00577
00578
00579 HBITMAP
CopyBitmap(
00580 HBITMAP hbm)
00581 {
00582 BITMAP bm;
00583 HBITMAP hbm2, hbmOld1, hbmOld2;
00584 HDC hdc, hdcMem1, hdcMem2;
00585
00586
if (!GetObject(hbm,
sizeof(BITMAP), &bm)) {
00587
return(0);
00588 }
00589 hdc =
NtUserGetDC(
NULL);
00590
if (!hdc) {
00591
return(0);
00592 }
00593 hdcMem1 = CreateCompatibleDC(hdc);
00594
if (!hdcMem1) {
00595
goto Cleanup3;
00596 }
00597 hdcMem2 = CreateCompatibleDC(hdc);
00598
if (!hdcMem2) {
00599
goto Cleanup2;
00600 }
00601 hbmOld1 = SelectObject(hdcMem1, hbm);
00602 hbm2 = CreateCompatibleBitmap(hdcMem1, bm.bmWidth, bm.bmHeight);
00603
if (!hbm2) {
00604
goto Cleanup1;
00605 }
00606 hbmOld2 = SelectObject(hdcMem2, hbm2);
00607 BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY);
00608 SelectObject(hdcMem1, hbmOld1);
00609 SelectObject(hdcMem2, hbmOld2);
00610 Cleanup1:
00611 DeleteDC(hdcMem2);
00612 Cleanup2:
00613 DeleteDC(hdcMem1);
00614 Cleanup3:
00615
NtUserReleaseDC(
NULL, hdc);
00616
return(hbm2);
00617 }
00618
00619
00620 HPALETTE
CopyPalette(
00621 HPALETTE hpal)
00622 {
00623
int cPalEntries;
00624 LOGPALETTE *plp;
00625
00626
if (!GetObject(hpal,
sizeof(
int), &cPalEntries)) {
00627
return(0);
00628 }
00629 plp = (LOGPALETTE *)
DDEMLAlloc(
sizeof(LOGPALETTE) +
00630 (cPalEntries - 1) *
sizeof(PALETTEENTRY));
00631
if (!plp) {
00632
return(0);
00633 }
00634
if (!GetPaletteEntries(hpal, 0, cPalEntries, plp->palPalEntry)) {
00635
DDEMLFree(plp);
00636
return(0);
00637 }
00638 plp->palVersion = 0x300;
00639 plp->palNumEntries = (WORD)cPalEntries;
00640 hpal = CreatePalette(plp);
00641
if (hpal &&
00642 !SetPaletteEntries(hpal, 0, cPalEntries, plp->palPalEntry)) {
00643 hpal = 0;
00644 }
00645
DDEMLFree(plp);
00646
return(hpal);
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660 HANDLE
CopyDDEData(
00661 HANDLE hDDE,
00662 BOOL fIsExecute)
00663 {
00664 HANDLE hDDENew;
00665
PDDE_DATA pdde, pddeNew;
00666 LPMETAFILEPICT pmfPict;
00667 HANDLE hmfPict;
00668
00669 hDDENew =
UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,
00670
UserGlobalSize(hDDE));
00671
if (!hDDENew) {
00672
return (0);
00673 }
00674
USERGLOBALLOCK(hDDE, pdde);
00675
if (pdde ==
NULL) {
00676
UserGlobalFree(hDDENew);
00677
return (0);
00678 }
00679
USERGLOBALLOCK(hDDENew, pddeNew);
00680 UserAssert(pddeNew);
00681 RtlCopyMemory(pddeNew, pdde,
UserGlobalSize(hDDE));
00682
00683
if (!fIsExecute) {
00684
switch (pdde->
wFmt) {
00685
case CF_BITMAP:
00686
case CF_DSPBITMAP:
00687 pddeNew->
Data = (ULONG_PTR)
CopyBitmap((HBITMAP)pdde->
Data);
00688
break;
00689
00690
case CF_PALETTE:
00691 pddeNew->
Data = (ULONG_PTR)
CopyPalette((HPALETTE)pdde->
Data);
00692
break;
00693
00694
case CF_DIB:
00695 pddeNew->
Data = (ULONG_PTR)
CopyDDEData((HANDLE)pdde->
Data,
TRUE);
00696
break;
00697
00698
case CF_METAFILEPICT:
00699
case CF_DSPMETAFILEPICT:
00700 hmfPict =
CopyDDEData((HANDLE)pdde->
Data,
TRUE);
00701
USERGLOBALLOCK(hmfPict, pmfPict);
00702
if (pmfPict ==
NULL) {
00703
WOWGLOBALFREE(hmfPict);
00704
USERGLOBALUNLOCK(hDDENew);
00705
WOWGLOBALFREE(hDDENew);
00706
USERGLOBALUNLOCK(hDDE);
00707
return (
FALSE);
00708 }
00709 pmfPict->hMF = CopyMetaFile(pmfPict->hMF,
NULL);
00710
USERGLOBALUNLOCK(hmfPict);
00711 pddeNew->
Data = (ULONG_PTR)hmfPict;
00712
break;
00713
00714
case CF_ENHMETAFILE:
00715
case CF_DSPENHMETAFILE:
00716 pddeNew->
Data = (ULONG_PTR)CopyEnhMetaFile((HANDLE)pdde->
Data,
NULL);
00717
break;
00718 }
00719 }
00720
USERGLOBALUNLOCK(hDDENew);
00721
USERGLOBALUNLOCK(hDDE);
00722
return (hDDENew);
00723 }