Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

747 lines
20 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: hdata.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * DDE Manager data handle functions
  7. *
  8. * Created: 11/12/91 Sanford Staab
  9. *
  10. \***************************************************************************/
  11. #define DDEMLDB
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. /***************************************************************************\
  15. * DdeCreateDataHandle (DDEML API)
  16. *
  17. * Description
  18. *
  19. * History:
  20. * 11-1-91 sanfords Created.
  21. \***************************************************************************/
  22. FUNCLOG7(LOG_GENERAL, HDDEDATA, DUMMYCALLINGTYPE, DdeCreateDataHandle, DWORD, idInst, LPBYTE, pSrc, DWORD, cb, DWORD, cbOff, HSZ, hszItem, UINT, wFmt, UINT, afCmd)
  23. HDDEDATA DdeCreateDataHandle(
  24. DWORD idInst,
  25. LPBYTE pSrc,
  26. DWORD cb,
  27. DWORD cbOff,
  28. HSZ hszItem,
  29. UINT wFmt,
  30. UINT afCmd)
  31. {
  32. PCL_INSTANCE_INFO pcii;
  33. HDDEDATA hRet = 0;
  34. if (cb == -1) {
  35. RIPMSG0(RIP_WARNING, "DdeCreateDataHandle called with cb == -1");
  36. return NULL;
  37. }
  38. EnterDDECrit;
  39. pcii = ValidateInstance((HANDLE)LongToHandle( idInst ));
  40. if (pcii == NULL) {
  41. BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
  42. goto Exit;
  43. }
  44. if (afCmd & ~HDATA_APPOWNED) {
  45. SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
  46. goto Exit;
  47. }
  48. if (cb + cbOff < sizeof(DWORD) && pSrc == NULL &&
  49. (wFmt == CF_METAFILEPICT ||
  50. wFmt == CF_DSPMETAFILEPICT ||
  51. wFmt == CF_DIB ||
  52. wFmt == CF_BITMAP ||
  53. wFmt == CF_DSPBITMAP ||
  54. wFmt == CF_PALETTE ||
  55. wFmt == CF_ENHMETAFILE ||
  56. wFmt == CF_DSPENHMETAFILE)) {
  57. /*
  58. * We have the nasty possibility of blowing up in FreeDDEData if we
  59. * don't initialize the data for formats with indirect data to 0.
  60. * This is because GlobalLock/GlobalSize do not adequately validate
  61. * random numbers given to them.
  62. */
  63. cb += 4;
  64. }
  65. hRet = InternalCreateDataHandle(pcii, pSrc, cb, cbOff,
  66. hszItem ? afCmd : (afCmd | HDATA_EXECUTE),
  67. (WORD)((afCmd & HDATA_APPOWNED) ? 0 : DDE_FRELEASE), (WORD)wFmt);
  68. if (!hRet) {
  69. SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
  70. }
  71. Exit:
  72. LeaveDDECrit;
  73. return (hRet);
  74. }
  75. /***************************************************************************\
  76. * InternalCreateDataHandle
  77. *
  78. * Description:
  79. * Worker function for creating a data handle. If cb is -1, pSrc is
  80. * a GMEM_DDESHARE data handle. 0 is return ed on error.
  81. *
  82. * History:
  83. * 11-19-91 sanfords Created.
  84. \***************************************************************************/
  85. HDDEDATA InternalCreateDataHandle(
  86. PCL_INSTANCE_INFO pcii,
  87. LPBYTE pSrc,
  88. DWORD cb, // cb of actual data to initialize with
  89. DWORD cbOff, // offset from start of data
  90. DWORD flags,
  91. WORD wStatus,
  92. WORD wFmt)
  93. {
  94. PDDEMLDATA pdd;
  95. HDDEDATA hRet;
  96. LPBYTE p;
  97. DWORD cbOff2;
  98. CheckDDECritIn;
  99. pdd = (PDDEMLDATA)DDEMLAlloc(sizeof(DDEMLDATA));
  100. if (pdd == NULL) {
  101. return (0);
  102. }
  103. if (cb == -1) {
  104. pdd->hDDE = (HANDLE)pSrc;
  105. } else {
  106. if (flags & HDATA_EXECUTE) {
  107. cbOff2 = 0;
  108. } else {
  109. cbOff2 = sizeof(WORD) + sizeof(WORD); // skip wStatus, wFmt
  110. }
  111. pdd->hDDE = UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE | GMEM_ZEROINIT,
  112. cb + cbOff + cbOff2);
  113. if (pdd->hDDE == NULL) {
  114. DDEMLFree(pdd);
  115. return (0);
  116. }
  117. if (!(flags & HDATA_EXECUTE)) {
  118. PDDE_DATA pdde;
  119. USERGLOBALLOCK(pdd->hDDE, pdde);
  120. UserAssert(pdde);
  121. pdde->wStatus = wStatus;
  122. pdde->wFmt = wFmt;
  123. USERGLOBALUNLOCK(pdd->hDDE);
  124. }
  125. }
  126. pdd->flags = (WORD)flags;
  127. hRet = (HDDEDATA)CreateHandle((ULONG_PTR)pdd, HTYPE_DATA_HANDLE,
  128. InstFromHandle(pcii->hInstClient));
  129. if (!hRet) {
  130. WOWGLOBALFREE(pdd->hDDE);
  131. DDEMLFree(pdd);
  132. return (0);
  133. }
  134. if (cb != -1 && pSrc != NULL) {
  135. USERGLOBALLOCK(pdd->hDDE, p);
  136. UserAssert(p);
  137. RtlCopyMemory(p + cbOff + cbOff2, pSrc, cb);
  138. USERGLOBALUNLOCK(pdd->hDDE);
  139. pdd->flags |= HDATA_INITIALIZED;
  140. }
  141. return (hRet);
  142. }
  143. /***************************************************************************\
  144. * DdeAddData (DDEML API)
  145. *
  146. * Description:
  147. * Copys data from a user buffer to a data handles. Reallocates if needed.
  148. *
  149. * History:
  150. * 11-1-91 sanfords Created.
  151. \***************************************************************************/
  152. FUNCLOG4(LOG_GENERAL, HDDEDATA, DUMMYCALLINGTYPE, DdeAddData, HDDEDATA, hData, LPBYTE, pSrc, DWORD, cb, DWORD, cbOff)
  153. HDDEDATA DdeAddData(
  154. HDDEDATA hData,
  155. LPBYTE pSrc,
  156. DWORD cb,
  157. DWORD cbOff)
  158. {
  159. LPSTR pMem;
  160. PDDEMLDATA pdd;
  161. PCL_INSTANCE_INFO pcii;
  162. HDDEDATA hRet = 0;
  163. HANDLE hTempDDE;
  164. EnterDDECrit;
  165. pdd = (PDDEMLDATA)ValidateCHandle((HANDLE)hData, HTYPE_DATA_HANDLE, HINST_ANY);
  166. if (pdd == NULL) {
  167. goto Exit;
  168. }
  169. pcii = PciiFromHandle((HANDLE)hData);
  170. if (pcii == NULL) {
  171. BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
  172. goto Exit;
  173. }
  174. if (!(pdd->flags & HDATA_EXECUTE)) {
  175. cbOff += 4;
  176. }
  177. if (cb + cbOff > UserGlobalSize(pdd->hDDE)) {
  178. /*
  179. * If the realloc failed, free the old ptr. We continue
  180. * on in order to maintain compatibility with previous DDE code.
  181. */
  182. hTempDDE = UserGlobalReAlloc(pdd->hDDE, cb + cbOff,
  183. GMEM_MOVEABLE | GMEM_ZEROINIT);
  184. if ((hTempDDE == NULL) && ((pdd->hDDE) != NULL)) {
  185. UserGlobalFree(pdd->hDDE);
  186. }
  187. pdd->hDDE = hTempDDE;
  188. }
  189. USERGLOBALLOCK(pdd->hDDE, pMem);
  190. if (pMem == NULL) {
  191. SetLastDDEMLError(pcii, DMLERR_MEMORY_ERROR);
  192. goto Exit;
  193. }
  194. hRet = hData;
  195. if (pSrc != NULL) {
  196. try {
  197. RtlCopyMemory(pMem + cbOff, pSrc, cb);
  198. pdd->flags |= HDATA_INITIALIZED;
  199. } except(W32ExceptionHandler(FALSE, RIP_WARNING)) {
  200. SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
  201. hRet = 0;
  202. }
  203. }
  204. USERGLOBALUNLOCK(pdd->hDDE);
  205. Exit:
  206. LeaveDDECrit;
  207. return (hRet);
  208. }
  209. /***************************************************************************\
  210. * DdeGetData (DDEML API)
  211. *
  212. * Description:
  213. * Copys data from a data handle into a user buffer.
  214. *
  215. * History:
  216. * 11-1-91 sanfords Created.
  217. \***************************************************************************/
  218. FUNCLOG4(LOG_GENERAL, DWORD, DUMMYCALLINGTYPE, DdeGetData, HDDEDATA, hData, LPBYTE, pDst, DWORD, cbMax, DWORD, cbOff)
  219. DWORD DdeGetData(
  220. HDDEDATA hData,
  221. LPBYTE pDst,
  222. DWORD cbMax,
  223. DWORD cbOff)
  224. {
  225. DWORD cbCopied = 0;
  226. DWORD cbSize;
  227. PDDEMLDATA pdd;
  228. PCL_INSTANCE_INFO pcii;
  229. EnterDDECrit;
  230. pdd = (PDDEMLDATA)ValidateCHandle((HANDLE)hData,
  231. HTYPE_DATA_HANDLE, HINST_ANY);
  232. if (pdd == NULL) {
  233. BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
  234. goto Exit;
  235. }
  236. pcii = PciiFromHandle((HANDLE)hData);
  237. if (pcii == NULL) {
  238. BestSetLastDDEMLError(DMLERR_INVALIDPARAMETER);
  239. goto Exit;
  240. }
  241. if (!(pdd->flags & HDATA_EXECUTE)) {
  242. cbOff += 4;
  243. }
  244. cbSize = (DWORD)UserGlobalSize(pdd->hDDE);
  245. if (cbOff >= cbSize) {
  246. SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
  247. goto Exit;
  248. }
  249. if (pDst == NULL) {
  250. cbCopied = cbSize - cbOff;
  251. goto Exit;
  252. } else {
  253. LPSTR pMem;
  254. cbCopied = min(cbMax, cbSize - cbOff);
  255. USERGLOBALLOCK(pdd->hDDE, pMem);
  256. UserAssert(pMem);
  257. try {
  258. RtlCopyMemory(pDst, pMem + cbOff, cbCopied);
  259. } except(W32ExceptionHandler(FALSE, RIP_WARNING)) {
  260. SetLastDDEMLError(pcii, DMLERR_INVALIDPARAMETER);
  261. cbCopied = 0;
  262. }
  263. if (pMem != NULL) {
  264. USERGLOBALUNLOCK(pdd->hDDE);
  265. }
  266. }
  267. Exit:
  268. LeaveDDECrit;
  269. return (cbCopied);
  270. }
  271. /***************************************************************************\
  272. * DdeAccessData (DDEML API)
  273. *
  274. * Description:
  275. * Locks a data handle for access.
  276. *
  277. * History:
  278. * 11-1-91 sanfords Created.
  279. \***************************************************************************/
  280. FUNCLOG2(LOG_GENERAL, LPBYTE, DUMMYCALLINGTYPE, DdeAccessData, HDDEDATA, hData, LPDWORD, pcbDataSize)
  281. LPBYTE DdeAccessData(
  282. HDDEDATA hData,
  283. LPDWORD pcbDataSize)
  284. {
  285. PCL_INSTANCE_INFO pcii;
  286. PDDEMLDATA pdd;
  287. LPBYTE pRet = NULL;
  288. DWORD cbOff;
  289. EnterDDECrit;
  290. pdd = (PDDEMLDATA)ValidateCHandle((HANDLE)hData,
  291. HTYPE_DATA_HANDLE, HINST_ANY);
  292. if (pdd == NULL) {
  293. goto Exit;
  294. }
  295. pcii = PciiFromHandle((HANDLE)hData);
  296. cbOff = pdd->flags & HDATA_EXECUTE ? 0 : 4;
  297. if (pcbDataSize != NULL) {
  298. *pcbDataSize = (DWORD)UserGlobalSize(pdd->hDDE) - cbOff;
  299. }
  300. USERGLOBALLOCK(pdd->hDDE, pRet);
  301. UserAssert(pRet);
  302. pRet = (LPBYTE)pRet + cbOff;
  303. Exit:
  304. LeaveDDECrit;
  305. return (pRet);
  306. }
  307. /***************************************************************************\
  308. * DdeUnaccessData (DDEML API)
  309. *
  310. * Description:
  311. * Unlocks a data handle
  312. *
  313. * History:
  314. * 11-1-91 sanfords Created.
  315. \***************************************************************************/
  316. FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, DdeUnaccessData, HDDEDATA, hData)
  317. BOOL DdeUnaccessData(
  318. HDDEDATA hData)
  319. {
  320. PDDEMLDATA pdd;
  321. BOOL fSuccess = FALSE;
  322. EnterDDECrit;
  323. pdd = (PDDEMLDATA)ValidateCHandle((HANDLE)hData,
  324. HTYPE_DATA_HANDLE, HINST_ANY);
  325. if (pdd == NULL) {
  326. goto Exit;
  327. }
  328. USERGLOBALUNLOCK(pdd->hDDE);
  329. fSuccess = TRUE;
  330. Exit:
  331. LeaveDDECrit;
  332. return (fSuccess);
  333. }
  334. /***************************************************************************\
  335. * DdeFreeDataHandle (DDEML API)
  336. *
  337. * Description:
  338. * Releases application interest in a data handle.
  339. *
  340. * History:
  341. * 11-1-91 sanfords Created.
  342. \***************************************************************************/
  343. FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, DdeFreeDataHandle, HDDEDATA, hData)
  344. BOOL DdeFreeDataHandle(
  345. HDDEDATA hData)
  346. {
  347. PDDEMLDATA pdd;
  348. BOOL fSuccess = FALSE;
  349. EnterDDECrit;
  350. pdd = (PDDEMLDATA)ValidateCHandle((HANDLE)hData,
  351. HTYPE_DATA_HANDLE, HINST_ANY);
  352. if (pdd == NULL) {
  353. goto Exit;
  354. }
  355. if (pdd->flags & HDATA_NOAPPFREE) {
  356. fSuccess = TRUE;
  357. goto Exit;
  358. }
  359. fSuccess = InternalFreeDataHandle(hData, TRUE);
  360. Exit:
  361. LeaveDDECrit;
  362. return (fSuccess);
  363. }
  364. /***************************************************************************\
  365. * InternalFreeDataHandle
  366. *
  367. * Description:
  368. * Frees a data handle and its contents. The contents are NOT freed for
  369. * APPOWNED data handles unless fIgnorefRelease is set.
  370. *
  371. * History:
  372. * 11-19-91 sanfords Created.
  373. \***************************************************************************/
  374. BOOL InternalFreeDataHandle(
  375. HDDEDATA hData,
  376. BOOL fIgnorefRelease)
  377. {
  378. PDDEMLDATA pdd;
  379. CheckDDECritIn;
  380. pdd = (PDDEMLDATA)ValidateCHandle((HANDLE)hData,
  381. HTYPE_DATA_HANDLE, HINST_ANY);
  382. if (pdd == NULL) {
  383. return (FALSE);
  384. }
  385. if (pdd->flags & HDATA_EXECUTE) {
  386. if (!(pdd->flags & HDATA_APPOWNED) || fIgnorefRelease) {
  387. WOWGLOBALFREE(pdd->hDDE);
  388. }
  389. } else {
  390. FreeDDEData(pdd->hDDE, fIgnorefRelease, TRUE);
  391. }
  392. DDEMLFree(pdd);
  393. DestroyHandle((HANDLE)hData);
  394. return (TRUE);
  395. }
  396. /***************************************************************************\
  397. * ApplyFreeDataHandle
  398. *
  399. * Description:
  400. * Used during data handle cleanup.
  401. *
  402. * History:
  403. * 11-19-91 sanfords Created.
  404. \***************************************************************************/
  405. BOOL ApplyFreeDataHandle(
  406. HANDLE hData)
  407. {
  408. BOOL fRet;
  409. CheckDDECritOut;
  410. EnterDDECrit;
  411. fRet = InternalFreeDataHandle((HDDEDATA)hData, FALSE);
  412. LeaveDDECrit;
  413. return(fRet);
  414. }
  415. /***************************************************************************\
  416. * FreeDDEData
  417. *
  418. * Description:
  419. * Used for freeing DDE data including any special indirect objects
  420. * associated with the data depending on the format. This function
  421. * SHOULD NOT BE USED TO FREE EXECUTE DATA!
  422. *
  423. * The data is not freed if the fRelease bit is clear and fIgnoreRelease
  424. * is FALSE.
  425. *
  426. * The fFreeTruelyGlobalObjects parameter is used to distinguish tracking
  427. * layer frees from DDEML frees. Data in certain formats (CF_BITMAP,
  428. * CF_PALETTE) is maintained on the gdi CSR server side. When this is
  429. * passed between processes, gdi is not able to maintain multiple process
  430. * ownership on these objects so the objects must be made global. Thus
  431. * the tracking layer should NOT free these objects on behalf of another
  432. * process because they are truely global- however, DDEML can do this
  433. * because it is following the protocol which delclares who is in charge
  434. * of freeing global data. (YUCK!)
  435. *
  436. * History:
  437. * 11-19-91 sanfords Created.
  438. \***************************************************************************/
  439. /*
  440. * WARNING: This is exported for NetDDE use - DO NOT CHANGE THE PARAMETERS!
  441. */
  442. VOID FreeDDEData(
  443. HANDLE hDDE,
  444. BOOL fIgnorefRelease,
  445. BOOL fFreeTruelyGlobalObjects)
  446. {
  447. PDDE_DATA pdde;
  448. LPMETAFILEPICT pmfPict;
  449. DWORD cb;
  450. USERGLOBALLOCK(hDDE, pdde);
  451. if (pdde == NULL) {
  452. return ;
  453. }
  454. if ((pdde->wStatus & DDE_FRELEASE) || fIgnorefRelease) {
  455. cb = (DWORD)GlobalSize(hDDE);
  456. /*
  457. * Because there is the possibility that the data never got
  458. * initialized we need to do this in a try-except so we
  459. * behave nicely.
  460. */
  461. switch (pdde->wFmt) {
  462. case CF_BITMAP:
  463. case CF_DSPBITMAP:
  464. case CF_PALETTE:
  465. if (cb >= sizeof(HANDLE)) {
  466. if (fFreeTruelyGlobalObjects) {
  467. if (pdde->Data != 0) {
  468. DeleteObject((HANDLE)pdde->Data);
  469. }
  470. } else {
  471. /*
  472. * !fFreeTruelyGlobalObject implies we are only freeing
  473. * the Gdi proxy. (another process may still have this
  474. * object in use.)
  475. *
  476. * ChrisWil: removed this call. No longer
  477. * applicable in KMode.
  478. *
  479. * GdiDeleteLocalObject((ULONG)pdde->Data);
  480. *
  481. */
  482. }
  483. }
  484. break;
  485. case CF_DIB:
  486. if (cb >= sizeof(HANDLE)) {
  487. if (pdde->Data != 0) {
  488. WOWGLOBALFREE((HANDLE)pdde->Data);
  489. }
  490. }
  491. break;
  492. case CF_METAFILEPICT:
  493. case CF_DSPMETAFILEPICT:
  494. if (cb >= sizeof(HANDLE)) {
  495. if (pdde->Data != 0) {
  496. USERGLOBALLOCK(pdde->Data, pmfPict);
  497. if (pmfPict != NULL) {
  498. if (GlobalSize((HANDLE)pdde->Data) >= sizeof(METAFILEPICT)) {
  499. DeleteMetaFile(pmfPict->hMF);
  500. }
  501. USERGLOBALUNLOCK((HANDLE)pdde->Data);
  502. WOWGLOBALFREE((HANDLE)pdde->Data);
  503. }
  504. }
  505. }
  506. break;
  507. case CF_ENHMETAFILE:
  508. case CF_DSPENHMETAFILE:
  509. if (cb >= sizeof(HANDLE)) {
  510. if (pdde->Data != 0) {
  511. DeleteEnhMetaFile((HANDLE)pdde->Data);
  512. }
  513. }
  514. break;
  515. }
  516. USERGLOBALUNLOCK(hDDE);
  517. WOWGLOBALFREE(hDDE);
  518. } else {
  519. USERGLOBALUNLOCK(hDDE);
  520. }
  521. }
  522. HBITMAP CopyBitmap(
  523. HBITMAP hbm)
  524. {
  525. BITMAP bm;
  526. HBITMAP hbm2 = NULL, hbmOld1, hbmOld2;
  527. HDC hdc, hdcMem1, hdcMem2;
  528. if (!GetObject(hbm, sizeof(BITMAP), &bm)) {
  529. return(0);
  530. }
  531. hdc = NtUserGetDC(NULL); // screen DC
  532. if (!hdc) {
  533. return(0);
  534. }
  535. hdcMem1 = CreateCompatibleDC(hdc);
  536. if (!hdcMem1) {
  537. goto Cleanup3;
  538. }
  539. hdcMem2 = CreateCompatibleDC(hdc);
  540. if (!hdcMem2) {
  541. goto Cleanup2;
  542. }
  543. hbmOld1 = SelectObject(hdcMem1, hbm);
  544. hbm2 = CreateCompatibleBitmap(hdcMem1, bm.bmWidth, bm.bmHeight);
  545. if (!hbm2) {
  546. goto Cleanup1;
  547. }
  548. hbmOld2 = SelectObject(hdcMem2, hbm2);
  549. BitBlt(hdcMem2, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem1, 0, 0, SRCCOPY);
  550. SelectObject(hdcMem1, hbmOld1);
  551. SelectObject(hdcMem2, hbmOld2);
  552. Cleanup1:
  553. DeleteDC(hdcMem2);
  554. Cleanup2:
  555. DeleteDC(hdcMem1);
  556. Cleanup3:
  557. NtUserReleaseDC(NULL, hdc);
  558. return(hbm2);
  559. }
  560. HPALETTE CopyPalette(
  561. HPALETTE hpal)
  562. {
  563. int cPalEntries;
  564. LOGPALETTE *plp;
  565. if (!GetObject(hpal, sizeof(int), &cPalEntries)) {
  566. return(0);
  567. }
  568. plp = (LOGPALETTE *)DDEMLAlloc(sizeof(LOGPALETTE) +
  569. (cPalEntries - 1) * sizeof(PALETTEENTRY));
  570. if (!plp) {
  571. return(0);
  572. }
  573. if (!GetPaletteEntries(hpal, 0, cPalEntries, plp->palPalEntry)) {
  574. DDEMLFree(plp);
  575. return(0);
  576. }
  577. plp->palVersion = 0x300;
  578. plp->palNumEntries = (WORD)cPalEntries;
  579. hpal = CreatePalette(plp);
  580. if (hpal != NULL) {
  581. if (!SetPaletteEntries(hpal, 0, cPalEntries, plp->palPalEntry)) {
  582. DeleteObject(hpal);
  583. hpal = NULL;
  584. }
  585. }
  586. DDEMLFree(plp);
  587. return(hpal);
  588. }
  589. /***************************************************************************\
  590. * CopyDDEData
  591. *
  592. * Description:
  593. * Used to copy DDE data apropriately.
  594. *
  595. * History:
  596. * 11-19-91 sanfords Created.
  597. \***************************************************************************/
  598. HANDLE CopyDDEData(
  599. HANDLE hDDE,
  600. BOOL fIsExecute)
  601. {
  602. HANDLE hDDENew;
  603. PDDE_DATA pdde, pddeNew;
  604. LPMETAFILEPICT pmfPict;
  605. HANDLE hmfPict;
  606. hDDENew = UserGlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE,
  607. UserGlobalSize(hDDE));
  608. if (!hDDENew) {
  609. return (0);
  610. }
  611. USERGLOBALLOCK(hDDE, pdde);
  612. if (pdde == NULL) {
  613. UserGlobalFree(hDDENew);
  614. return (0);
  615. }
  616. USERGLOBALLOCK(hDDENew, pddeNew);
  617. UserAssert(pddeNew);
  618. RtlCopyMemory(pddeNew, pdde, UserGlobalSize(hDDE));
  619. if (!fIsExecute) {
  620. switch (pdde->wFmt) {
  621. case CF_BITMAP:
  622. case CF_DSPBITMAP:
  623. pddeNew->Data = (KERNEL_PVOID)CopyBitmap((HBITMAP)pdde->Data);
  624. break;
  625. case CF_PALETTE:
  626. pddeNew->Data = (KERNEL_PVOID)CopyPalette((HPALETTE)pdde->Data);
  627. break;
  628. case CF_DIB:
  629. pddeNew->Data = (KERNEL_PVOID)CopyDDEData((HANDLE)pdde->Data, TRUE);
  630. break;
  631. case CF_METAFILEPICT:
  632. case CF_DSPMETAFILEPICT:
  633. hmfPict = CopyDDEData((HANDLE)pdde->Data, TRUE);
  634. USERGLOBALLOCK(hmfPict, pmfPict);
  635. if (pmfPict == NULL) {
  636. WOWGLOBALFREE(hmfPict);
  637. USERGLOBALUNLOCK(hDDENew);
  638. WOWGLOBALFREE(hDDENew);
  639. USERGLOBALUNLOCK(hDDE);
  640. return (FALSE);
  641. }
  642. pmfPict->hMF = CopyMetaFile(pmfPict->hMF, NULL);
  643. USERGLOBALUNLOCK(hmfPict);
  644. pddeNew->Data = (KERNEL_PVOID)hmfPict;
  645. break;
  646. case CF_ENHMETAFILE:
  647. case CF_DSPENHMETAFILE:
  648. pddeNew->Data = (KERNEL_PVOID)CopyEnhMetaFile((HANDLE)pdde->Data, NULL);
  649. break;
  650. }
  651. }
  652. USERGLOBALUNLOCK(hDDENew);
  653. USERGLOBALUNLOCK(hDDE);
  654. return (hDDENew);
  655. }