Source code of Windows XP (NT5)
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.

1143 lines
32 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WDDE.C
  8. * WOW32 DDE worker routines.
  9. *
  10. * History:
  11. * WOW DDE support designed and developed by ChandanC
  12. *
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. LPDDENODE DDEInitiateList = NULL;
  17. STATIC PHDDE phDDEFirst = NULL; // pointer to first hDDE entry
  18. STATIC PCPDATA pCPDataFirst = NULL; // pointer to first CopyData entry
  19. MODNAME(wdde.c);
  20. // This routine maintains a list of client windows that are in
  21. // Initiate mode. This is called from THUNKING of DDE_INITIATE
  22. // message (from both the WMDISP32.C and WMSG16.C).
  23. //
  24. VOID WI32DDEAddInitiator (HAND16 Initiator)
  25. {
  26. LPDDENODE Node;
  27. Node = (LPDDENODE) malloc_w(sizeof(DDENODE));
  28. if (Node) {
  29. //
  30. // Initialize Node with the Initiator's window handle
  31. //
  32. Node->Initiator = Initiator;
  33. //
  34. // Insert this Node into the linked list of DDE_Initiate message
  35. // in progress.
  36. //
  37. Node->Next = DDEInitiateList;
  38. DDEInitiateList = Node;
  39. LOGDEBUG(12, ("WOW::WI32DDEInitiator(): thunking -- adding an Initiator %04lX\n", Initiator));
  40. }
  41. else {
  42. //
  43. // We could not allocate memory.
  44. //
  45. LOGDEBUG(12, ("WOW::WI32DDEInitiator(): thunking -- Couldn't allocate memory\n"));
  46. WOW32ASSERT (FALSE);
  47. }
  48. }
  49. // This routine deletes the client window that was in Initiate mode. Because
  50. // the initiate message is completed now. This is called from UNTHUNKING
  51. // of DDE_INITIATE message (from both the WMDISP32.C and WMSG16.C).
  52. //
  53. VOID WI32DDEDeleteInitiator(HAND16 Initiator)
  54. {
  55. LPDDENODE Node, Temp1;
  56. Node = DDEInitiateList;
  57. if (Node) {
  58. while (Node) {
  59. if (Node->Initiator == Initiator) {
  60. if (Node == DDEInitiateList) {
  61. //
  62. // first guy in the list
  63. //
  64. DDEInitiateList = Node->Next;
  65. }
  66. else {
  67. //
  68. // update the list
  69. //
  70. Temp1->Next = Node->Next;
  71. }
  72. LOGDEBUG(12, ("WOW::WI32DDEDeleteInitiator(): unthunking -- deleting an Initiator %08lX\n", Initiator));
  73. //
  74. // free up the memory
  75. //
  76. free_w(Node);
  77. Node = NULL;
  78. }
  79. else {
  80. //
  81. // traverse the list
  82. //
  83. Temp1 = Node;
  84. Node = Node->Next;
  85. }
  86. }
  87. }
  88. else {
  89. // This is an ERROR condition, which should never occur. If it does
  90. // talk to CHANDANC as soon as possible.
  91. //
  92. LOGDEBUG(0, ("WOW::WI32DDEDeletInitiator(): unthunking -- no Initiator\n"));
  93. WOW32ASSERT (FALSE);
  94. }
  95. }
  96. // This routine is used by DDE_ACK thunk to figure out how to thunk the
  97. // DDE_ACK message, ie, whether lParam is a combination of 2 atoms or
  98. // its a pointer to 32 bit packed structure.
  99. //
  100. BOOL WI32DDEInitiate(HAND16 Initiator)
  101. {
  102. LPDDENODE Node;
  103. Node = DDEInitiateList;
  104. while (Node) {
  105. if (Node->Initiator == Initiator) {
  106. //
  107. // DDE_Initiate is in progress for this Window
  108. //
  109. LOGDEBUG(12, ("WOW::WI32DDEInitiate(): thunking -- found an Initiator %08lX\n", Initiator));
  110. return (TRUE);
  111. }
  112. else {
  113. Node = Node->Next;
  114. }
  115. }
  116. LOGDEBUG(12, ("WOW::WI32DDEInitiate(): thunking -- did not find an Initiator %08lX\n", Initiator));
  117. //
  118. // DDE_Initiate is not in progress for this Window
  119. //
  120. return (FALSE);
  121. }
  122. //
  123. // This routine determines if the current dde operation is a poke to MSDRAW
  124. // Pokes to MSDRAW for metafilepicts are special because the metafile pict
  125. // is part of the POKE block.
  126. //
  127. BOOL DDEIsTargetMSDraw(HAND16 To_hwnd)
  128. {
  129. BOOL fStatus = FALSE;
  130. HANDLE hInst;
  131. HAND16 hModuleName;
  132. LPSTR lpszModuleName16, lpszMsDraw = "MSDRAW.EXE";
  133. WORD cchModuleName = MAX_PATH, cchMsDraw = 10;
  134. VPVOID vp;
  135. LPSTR lpszNewMsDrawKey = "MSDRAW\\protocol\\StdFileEditing\\verb";
  136. HKEY hKey = NULL;
  137. LONG Status;
  138. //
  139. // To check if the target is msdraw, check the following.
  140. //
  141. // - That the destination window hInst is that of a 16 bit task (this is
  142. // checking to see if the LOWORD of the hInst is not 0.
  143. // - That the module name is MSDRAW.
  144. //
  145. // NOTE: THERE ARE THREE CALLBACK16 ROUTINES IN THIS CALL, MAKING IT AN
  146. // EXPENSIVE CALL. HOWEVER THIS CALL IS RARELY MADE.
  147. //
  148. if (
  149. (hInst = (HANDLE)GetWindowLong((HWND)HWND32(To_hwnd),GWL_HINSTANCE))
  150. && (LOWORD(hInst) != 0 )
  151. && (vp = GlobalAllocLock16(GMEM_MOVEABLE, cchModuleName, &hModuleName))
  152. ) {
  153. //
  154. // Callback 16 to get the module name of the current hInst
  155. //
  156. if (cchModuleName = GetModuleFileName16( LOWORD(hInst), vp, cchModuleName )) {
  157. GETMISCPTR(vp, lpszModuleName16);
  158. fStatus = (cchModuleName >= cchMsDraw)
  159. && !WOW32_stricmp( lpszModuleName16 + (cchModuleName - cchMsDraw), lpszMsDraw )
  160. && (Status = RegOpenKeyEx( HKEY_CLASSES_ROOT, lpszNewMsDrawKey, 0, KEY_READ, &hKey)) != ERROR_SUCCESS;
  161. if (hKey) {
  162. RegCloseKey( hKey );
  163. }
  164. FREEMISCPTR(lpszModuleName16);
  165. }
  166. //
  167. // Cleanup
  168. //
  169. GlobalUnlockFree16(vp);
  170. }
  171. return ( fStatus );
  172. }
  173. // This routine converts a 32 bit DDE memory object into a 16 bit DDE
  174. // memory object. It also, does the data conversion from 32 bit to 16 bit
  175. // for the type of data.
  176. //
  177. // WARNING: The Copyh32Toh16() calls may cause 16-bit memory movement
  178. //
  179. HAND16 DDECopyhData16(HAND16 To_hwnd, HAND16 From_hwnd, HANDLE h32, PDDEINFO pDdeInfo)
  180. {
  181. HAND16 h16 = 0;
  182. VPVOID vp1, vp2;
  183. DDEDATA *lpMem32;
  184. DDEDATA16 *lpMem16;
  185. int cb;
  186. //
  187. // NULL handle ?
  188. //
  189. if (!h32) {
  190. LOGDEBUG(12, ("WOW::DDECopyhData16(): h32 is %08x\n", h32));
  191. return 0;
  192. }
  193. cb = GlobalSize(h32);
  194. lpMem32 = GlobalLock(h32);
  195. LOGDEBUG(12, ("WOW::DDECopyhData16(): CF_FORMAT is %04x\n", lpMem32->cfFormat));
  196. switch (lpMem32->cfFormat) {
  197. default:
  198. // This is intentional to let it thru to "case statements".
  199. // ChandanC 5/11/92.
  200. case CF_TEXT:
  201. case CF_DSPTEXT:
  202. case CF_SYLK:
  203. case CF_DIF:
  204. case CF_TIFF:
  205. case CF_OEMTEXT:
  206. case CF_PENDATA:
  207. case CF_RIFF:
  208. case CF_WAVE:
  209. case CF_OWNERDISPLAY:
  210. h16 = Copyh32Toh16 (cb, (LPBYTE) lpMem32);
  211. pDdeInfo->Format = lpMem32->cfFormat;
  212. break;
  213. case CF_BITMAP:
  214. case CF_DSPBITMAP:
  215. vp1 = GlobalAllocLock16(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HAND16)), &h16);
  216. if (vp1) {
  217. pDdeInfo->Format = lpMem32->cfFormat;
  218. GETMISCPTR(vp1, lpMem16);
  219. RtlCopyMemory(lpMem16, lpMem32, 4);
  220. STOREWORD(lpMem16->Value, GETHBITMAP16(*((HANDLE *)lpMem32->Value)));
  221. FLUSHVDMPTR(vp1, (sizeof(DDEDATA)-1+sizeof(HAND16)), lpMem16);
  222. FREEMISCPTR(lpMem16);
  223. GlobalUnlock16(h16);
  224. }
  225. break;
  226. case CF_PALETTE:
  227. vp1 = GlobalAllocLock16(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HAND16)), &h16);
  228. if (vp1) {
  229. pDdeInfo->Format = lpMem32->cfFormat;
  230. GETMISCPTR(vp1, lpMem16);
  231. RtlCopyMemory(lpMem16, lpMem32, 4);
  232. STOREWORD(lpMem16->Value, GETHPALETTE16(*((HANDLE *)lpMem32->Value)));
  233. FLUSHVDMPTR(vp1, (sizeof(DDEDATA)-1+sizeof(HAND16)), lpMem16);
  234. FREEMISCPTR(lpMem16);
  235. GlobalUnlock16(h16);
  236. }
  237. break;
  238. case CF_DIB:
  239. {
  240. LPBYTE lpMemDib32;
  241. HAND16 hDib16 = 0;
  242. HANDLE hDib32;
  243. vp1 = GlobalAllocLock16(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HAND16)), &h16);
  244. if (vp1) {
  245. GETMISCPTR(vp1, lpMem16);
  246. RtlCopyMemory(lpMem16, lpMem32, 4);
  247. FREEMISCPTR(lpMem16);
  248. hDib32 = (*((HANDLE *)lpMem32->Value));
  249. if (hDib32) {
  250. lpMemDib32 = GlobalLock(hDib32);
  251. cb = GlobalSize(hDib32);
  252. hDib16 = Copyh32Toh16 (cb, (LPBYTE) lpMemDib32);
  253. GlobalUnlock(hDib32);
  254. pDdeInfo->Format = lpMem32->cfFormat;
  255. pDdeInfo->Flags = 0;
  256. pDdeInfo->h16 = 0;
  257. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hDib16, hDib32, pDdeInfo);
  258. }
  259. GETMISCPTR(vp1, lpMem16);
  260. STOREWORD(lpMem16->Value, hDib16);
  261. GlobalUnlock16(h16);
  262. FLUSHVDMPTR(vp1, (sizeof(DDEDATA)-1+sizeof(HAND16)), lpMem16);
  263. FREEMISCPTR(lpMem16);
  264. }
  265. }
  266. break;
  267. case CF_METAFILEPICT:
  268. case CF_DSPMETAFILEPICT:
  269. {
  270. HANDLE hMeta32, hMF32 = NULL;
  271. HAND16 hMeta16 = 0, hMF16 = 0;
  272. LPMETAFILEPICT lpMemMeta32;
  273. LPMETAFILEPICT16 lpMemMeta16;
  274. BOOL IsMSDRAWPoke;
  275. //
  276. // We need to find out if the to_handle is MSDRAW, in which case
  277. // we should copy the METAFILEPICT data to the DDEPOKE instead
  278. // of a handle to the METAFILEPICT.
  279. if( IsMSDRAWPoke = ((pDdeInfo->Msg == WM_DDE_POKE) && DDEIsTargetMSDraw(To_hwnd)) ) {
  280. cb = sizeof(DDEPOKE)-1+sizeof(METAFILEPICT16);
  281. }
  282. else {
  283. cb = sizeof(DDEDATA)-1+sizeof(HAND16);
  284. }
  285. vp1 = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16);
  286. if (vp1) {
  287. GETMISCPTR(vp1, lpMem16);
  288. RtlCopyMemory(lpMem16, lpMem32, 4);
  289. hMeta32 = (*((HANDLE *)lpMem32->Value));
  290. if ( IsMSDRAWPoke ) {
  291. lpMemMeta16 = (LPMETAFILEPICT16)((PBYTE)lpMem16 + sizeof(DDEPOKE) - 1);
  292. RtlZeroMemory( (PVOID)lpMemMeta16, sizeof (METAFILEPICT16) );
  293. if (hMeta32) {
  294. lpMemMeta32 = GlobalLock(hMeta32);
  295. FixMetafile32To16 (lpMemMeta32, lpMemMeta16);
  296. FREEMISCPTR(lpMem16);
  297. hMF32 = lpMemMeta32->hMF;
  298. if (hMF32) {
  299. hMF16 = WinMetaFileFromHMF(hMF32, FALSE);
  300. pDdeInfo->Format = lpMem32->cfFormat;
  301. pDdeInfo->h16 = 0;
  302. pDdeInfo->Flags = DDE_METAFILE;
  303. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo);
  304. }
  305. GETMISCPTR(vp1, lpMem16);
  306. lpMemMeta16 = (LPMETAFILEPICT16)((PBYTE)lpMem16 + sizeof(DDEPOKE) - 1);
  307. STOREWORD(lpMemMeta16->hMF, hMF16);
  308. GlobalUnlock(hMeta32);
  309. }
  310. }
  311. else {
  312. if (hMeta32) {
  313. lpMemMeta32 = GlobalLock(hMeta32);
  314. FREEMISCPTR(lpMem16);
  315. vp2 = GlobalAllocLock16(GMEM_DDESHARE, sizeof(METAFILEPICT16), &hMeta16);
  316. WOW32ASSERT(vp2);
  317. if (vp2) {
  318. GETMISCPTR(vp2, lpMemMeta16);
  319. FixMetafile32To16 (lpMemMeta32, lpMemMeta16);
  320. FREEMISCPTR(lpMemMeta16);
  321. pDdeInfo->Format = lpMem32->cfFormat;
  322. pDdeInfo->Flags = 0;
  323. pDdeInfo->h16 = 0;
  324. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMeta16, hMeta32, pDdeInfo);
  325. hMF32 = lpMemMeta32->hMF;
  326. if (hMF32) {
  327. hMF16 = WinMetaFileFromHMF(hMF32, FALSE);
  328. pDdeInfo->Flags = DDE_METAFILE;
  329. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo);
  330. }
  331. GETMISCPTR(vp2, lpMemMeta16);
  332. STOREWORD(lpMemMeta16->hMF, hMF16);
  333. GlobalUnlock16(hMeta16);
  334. FLUSHVDMPTR(vp2, 8, lpMemMeta16);
  335. FREEMISCPTR(lpMemMeta16);
  336. }
  337. GlobalUnlock(hMeta32);
  338. }
  339. GETMISCPTR(vp1, lpMem16);
  340. STOREWORD(lpMem16->Value, hMeta16);
  341. }
  342. GlobalUnlock16(h16);
  343. FLUSHVDMPTR(vp1, cb, lpMem16);
  344. FREEMISCPTR(lpMem16);
  345. }
  346. }
  347. break;
  348. }
  349. GlobalUnlock(h32);
  350. return (h16);
  351. }
  352. // This routine converts a 16 bit DDE memory object into a 32 bit DDE
  353. // memory object. It also, does the data conversion from 16 bit to 32 bit
  354. // for the type of data.
  355. //
  356. HANDLE DDECopyhData32(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 h16, PDDEINFO pDdeInfo)
  357. {
  358. HANDLE h32 = NULL;
  359. INT cb;
  360. VPVOID vp;
  361. DDEDATA *lpMem16;
  362. DDEDATA32 *lpMem32;
  363. //
  364. // AmiPro passes a NULL handle.
  365. //
  366. if (!h16) {
  367. LOGDEBUG(12, ("WOW::DDECopyhData16(): h16 is %04x\n", h16));
  368. return (HANDLE) NULL;
  369. }
  370. vp = GlobalLock16(h16, &cb);
  371. GETMISCPTR(vp, lpMem16);
  372. LOGDEBUG(12, ("WOW::DDECopyhData32(): CF_FORMAT is %04x\n", lpMem16->cfFormat));
  373. switch(lpMem16->cfFormat) {
  374. default:
  375. // This is intentional to let it thru to the "case statements".
  376. // ChandanC 5/11/92.
  377. case CF_TEXT:
  378. case CF_DSPTEXT:
  379. case CF_SYLK:
  380. case CF_DIF:
  381. case CF_TIFF:
  382. case CF_OEMTEXT:
  383. case CF_PENDATA:
  384. case CF_RIFF:
  385. case CF_WAVE:
  386. case CF_OWNERDISPLAY:
  387. h32 = Copyh16Toh32 (cb, (LPBYTE) lpMem16);
  388. pDdeInfo->Format = lpMem16->cfFormat;
  389. break;
  390. case CF_BITMAP:
  391. case CF_DSPBITMAP:
  392. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  393. if (h32) {
  394. pDdeInfo->Format = lpMem16->cfFormat;
  395. lpMem32 = GlobalLock(h32);
  396. RtlCopyMemory(lpMem32, lpMem16, 4);
  397. lpMem32->Value = HBITMAP32(FETCHWORD(*((WORD *)lpMem16->Value)));
  398. GlobalUnlock(h32);
  399. }
  400. break;
  401. case CF_PALETTE:
  402. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  403. if (h32) {
  404. pDdeInfo->Format = lpMem16->cfFormat;
  405. lpMem32 = GlobalLock(h32);
  406. RtlCopyMemory(lpMem32, lpMem16, 4);
  407. lpMem32->Value = HPALETTE32(FETCHWORD(*((WORD *)lpMem16->Value)));
  408. GlobalUnlock(h32);
  409. }
  410. break;
  411. case CF_DIB:
  412. {
  413. LPBYTE lpMemDib16;
  414. HAND16 hDib16;
  415. HANDLE hDib32 = NULL;
  416. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  417. if (h32) {
  418. lpMem32 = GlobalLock(h32);
  419. RtlCopyMemory(lpMem32, lpMem16, 4);
  420. hDib16 = FETCHWORD(*((WORD *)lpMem16->Value));
  421. if (hDib16) {
  422. vp = GlobalLock16(hDib16, &cb);
  423. GETMISCPTR(vp, lpMemDib16);
  424. hDib32 = Copyh16Toh32 (cb, (LPBYTE) lpMemDib16);
  425. pDdeInfo->Format = lpMem16->cfFormat;
  426. pDdeInfo->Flags = 0;
  427. pDdeInfo->h16 = 0;
  428. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hDib16, hDib32, pDdeInfo);
  429. GlobalUnlock16(hDib16);
  430. FREEMISCPTR(lpMemDib16);
  431. }
  432. lpMem32->Value = hDib32;
  433. GlobalUnlock(h32);
  434. }
  435. }
  436. break;
  437. case CF_METAFILEPICT:
  438. case CF_DSPMETAFILEPICT:
  439. {
  440. HANDLE hMeta32 = NULL, hMF32 = NULL;
  441. HAND16 hMeta16, hMF16 = 0;
  442. LPMETAFILEPICT lpMemMeta32;
  443. LPMETAFILEPICT16 lpMemMeta16;
  444. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  445. if (h32) {
  446. lpMem32 = GlobalLock(h32);
  447. RtlCopyMemory(lpMem32, lpMem16, 4);
  448. //
  449. // MSDRAW has the METAFILEPICT in the DDEPOKE block instead of
  450. // a handle to the METAFILEPICT. So we need to find out if the
  451. // to handle belongs to MSDRAW. Since MSDRAW is a 16 bit
  452. // server we needn't thunk the metafilepict at all, we will just
  453. // use NULL as the 32 bit handle to the metafilepict.
  454. //
  455. hMeta32 = NULL;
  456. if( !((pDdeInfo->Msg == WM_DDE_POKE) && DDEIsTargetMSDraw(To_hwnd)) ) {
  457. hMeta16 = FETCHWORD(*((WORD *)lpMem16->Value));
  458. //
  459. // Make sure that a valid metafile pict handle has been
  460. // passed in otherwise use NULL again as the hMeta32.
  461. //
  462. if (hMeta16 && (vp = GlobalLock16(hMeta16, &cb))) {
  463. GETMISCPTR(vp, lpMemMeta16);
  464. hMeta32 = WOWGLOBALALLOC(GMEM_DDESHARE, sizeof(METAFILEPICT));
  465. WOW32ASSERT(hMeta32);
  466. if (hMeta32) {
  467. lpMemMeta32 = GlobalLock(hMeta32);
  468. lpMemMeta32->mm = (LONG) FETCHSHORT(lpMemMeta16->mm);
  469. lpMemMeta32->xExt = (LONG) FETCHSHORT(lpMemMeta16->xExt);
  470. lpMemMeta32->yExt = (LONG) FETCHSHORT(lpMemMeta16->yExt);
  471. pDdeInfo->Format = lpMem16->cfFormat;
  472. pDdeInfo->Flags = 0;
  473. pDdeInfo->h16 = 0;
  474. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMeta16, hMeta32, pDdeInfo);
  475. hMF16 = FETCHWORD(lpMemMeta16->hMF);
  476. if (hMF16) {
  477. hMF32 = (HMETAFILE) HMFFromWinMetaFile(hMF16, FALSE);
  478. pDdeInfo->Flags = DDE_METAFILE;
  479. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo);
  480. }
  481. lpMemMeta32->hMF = (HMETAFILE) hMF32;
  482. GlobalUnlock(hMeta32);
  483. }
  484. GlobalUnlock16(hMeta16);
  485. FREEMISCPTR(lpMemMeta16);
  486. }
  487. }
  488. lpMem32->Value = hMeta32;
  489. GlobalUnlock(h32);
  490. }
  491. }
  492. break;
  493. }
  494. GlobalUnlock16(h16);
  495. FREEMISCPTR(lpMem16);
  496. return (h32);
  497. }
  498. /****** These routines maintain a linked list of dde handles, which
  499. ******* are the h16 and h32 pairs.
  500. ******/
  501. // This routine adds the given h16-h32 pair to the linked list, and updates
  502. // the list.
  503. //
  504. BOOL DDEAddhandle(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 hMem16, HANDLE hMem32, PDDEINFO pDdeInfo)
  505. {
  506. PHDDE phTemp;
  507. if (hMem16 && hMem32) {
  508. if (phTemp = malloc_w (sizeof(HDDE))) {
  509. phTemp->hMem16 = hMem16;
  510. phTemp->hMem32 = hMem32;
  511. phTemp->To_hwnd = To_hwnd;
  512. phTemp->From_hwnd = From_hwnd;
  513. phTemp->DdeMsg = pDdeInfo->Msg;
  514. phTemp->DdeFormat = pDdeInfo->Format;
  515. phTemp->DdeFlags = pDdeInfo->Flags;
  516. phTemp->h16 = pDdeInfo->h16;
  517. phTemp->pDDENext = phDDEFirst; // insert at the top
  518. phDDEFirst = phTemp; // update list head
  519. // Mark the GAH_WOWDDEFREEHANDLE (ie GAH_PAHTOM) bit in the global
  520. // arena of this handle.
  521. W32MarkDDEHandle (hMem16);
  522. return (TRUE);
  523. }
  524. else {
  525. LOGDEBUG(2, ("WOW::DDEAddhandle(): *** memory allocation failed *** \n"));
  526. return (FALSE);
  527. }
  528. }
  529. LOGDEBUG(2,("WOW::DDEAddhandle(): *** ERROR *** one of the handles is NULL \n"));
  530. return (FALSE);
  531. }
  532. // This routine deletes the given h16-h32 pair from the list and frees up
  533. // the memory.
  534. //
  535. BOOL DDEDeletehandle(HAND16 h16, HANDLE h32)
  536. {
  537. PHDDE phTemp1, phTemp2;
  538. phTemp1 = phDDEFirst;
  539. if ((phTemp1->hMem16 == h16) && (phTemp1->hMem32 == h32)) { // first node
  540. phDDEFirst = phTemp1->pDDENext;
  541. free_w(phTemp1);
  542. return (TRUE);
  543. }
  544. else { // rest of the list
  545. phTemp2 = phTemp1;
  546. phTemp1 = phTemp1->pDDENext;
  547. while (phTemp1) {
  548. if ((phTemp1->hMem16 == h16) && (phTemp1->hMem32 == h32)) {
  549. phTemp2->pDDENext = phTemp1->pDDENext;
  550. free_w(phTemp1);
  551. return (TRUE);
  552. }
  553. phTemp2 = phTemp1;
  554. phTemp1 = phTemp1->pDDENext;
  555. }
  556. LOGDEBUG (2, ("WOW::DDEDeleteHandle : Can't find a 16-32 memory pair\n"));
  557. // WOW32ASSERT (FALSE);
  558. return (FALSE);
  559. }
  560. }
  561. // This routine finds a hMem16 for a DDE conversation, if one exists.
  562. //
  563. HAND16 DDEFindPair16(HAND16 To_hwnd, HAND16 From_hwnd, HANDLE hMem32)
  564. {
  565. PHDDE phTemp;
  566. phTemp = phDDEFirst;
  567. while (phTemp) {
  568. if ((phTemp->To_hwnd == To_hwnd) &&
  569. (phTemp->From_hwnd == From_hwnd) &&
  570. (phTemp->hMem32 == hMem32)) {
  571. return (phTemp->hMem16);
  572. }
  573. else {
  574. phTemp = phTemp->pDDENext;
  575. }
  576. }
  577. return (HAND16) NULL;
  578. }
  579. // This routine finds a hMem32 for a DDE conversation, if one exists.
  580. //
  581. HANDLE DDEFindPair32(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 hMem16)
  582. {
  583. PHDDE phTemp;
  584. phTemp = phDDEFirst;
  585. while (phTemp) {
  586. if ((phTemp->To_hwnd == To_hwnd) &&
  587. (phTemp->From_hwnd == From_hwnd) &&
  588. (phTemp->hMem16 == hMem16)) {
  589. return (phTemp->hMem32);
  590. }
  591. else {
  592. phTemp = phTemp->pDDENext;
  593. }
  594. }
  595. return (HANDLE) NULL;
  596. }
  597. // This routine find the DDE node that is doing DDE conversation
  598. //
  599. PHDDE DDEFindNode16 (HAND16 h16)
  600. {
  601. PHDDE phTemp;
  602. phTemp = phDDEFirst;
  603. while (phTemp) {
  604. if (phTemp->hMem16 == h16) {
  605. return (phTemp);
  606. }
  607. phTemp = phTemp->pDDENext;
  608. }
  609. return (NULL);
  610. }
  611. // This routine find the DDE node that is doing DDE conversation
  612. //
  613. PHDDE DDEFindNode32 (HANDLE h32)
  614. {
  615. PHDDE phTemp;
  616. phTemp = phDDEFirst;
  617. while (phTemp) {
  618. if (phTemp->hMem32 == h32) {
  619. return (phTemp);
  620. }
  621. phTemp = phTemp->pDDENext;
  622. }
  623. return (NULL);
  624. }
  625. // This routine returns a pointer to the DDE node, if the conversation exists,
  626. // else it retunrs NULL
  627. PHDDE DDEFindAckNode (HAND16 To_hwnd, HAND16 From_hwnd, HANDLE hMem32)
  628. {
  629. PHDDE phTemp;
  630. phTemp = phDDEFirst;
  631. while (phTemp) {
  632. if ((phTemp->To_hwnd == To_hwnd) &&
  633. (phTemp->From_hwnd == From_hwnd) &&
  634. (phTemp->hMem32 == hMem32)) {
  635. return (phTemp);
  636. }
  637. else {
  638. phTemp = phTemp->pDDENext;
  639. }
  640. }
  641. return (PHDDE) NULL;
  642. }
  643. // This function marks GAH_WOWDDEFREEHANDLE bit in the global arena of the
  644. // hMem16.
  645. //
  646. VOID W32MarkDDEHandle (HAND16 hMem16)
  647. {
  648. PARM16 Parm16;
  649. VPVOID vp = 0;
  650. Parm16.WndProc.wParam = hMem16;
  651. Parm16.WndProc.wMsg = 1;
  652. CallBack16(RET_WOWDDEFREEHANDLE, &Parm16, 0, &vp);
  653. }
  654. VOID W32UnMarkDDEHandle (HAND16 hMem16)
  655. {
  656. PARM16 Parm16;
  657. VPVOID vp = 0;
  658. Parm16.WndProc.wParam = hMem16;
  659. Parm16.WndProc.wMsg = 0;
  660. CallBack16(RET_WOWDDEFREEHANDLE, &Parm16, 0, &vp);
  661. }
  662. // This function frees the 32 and 16 bit memory. It is called by 32 bit
  663. // BASE by GlobalFree.
  664. //
  665. BOOL W32DDEFreeGlobalMem32 (HANDLE h32)
  666. {
  667. HAND16 h16;
  668. PHDDE pDdeNode;
  669. BOOL fOkToFree = TRUE;
  670. if (h32) {
  671. if (pDdeNode = DDEFindNode32(h32)) {
  672. if (pDdeNode->DdeFlags & DDE_METAFILE) {
  673. LOGDEBUG (12, ("WOW32: W32DDEFreeGlobalMem32: Freeing MetaFile hMF32 %x\n", h32));
  674. DeleteMetaFile (h32);
  675. fOkToFree = FALSE;
  676. }
  677. while ((pDdeNode) && (h16 = pDdeNode->hMem16)) {
  678. W32UnMarkDDEHandle (h16);
  679. GlobalUnlockFree16(GlobalLock16(h16, NULL));
  680. DDEDeletehandle(h16, h32);
  681. pDdeNode = DDEFindNode32(h32);
  682. }
  683. }
  684. else {
  685. LOGDEBUG (2, ("WOW32: W32DDEFreeGlobalMem32: Can't find a 16-32 memory pair\n"));
  686. }
  687. }
  688. else {
  689. WOW32WARNMSG(FALSE, "WOW32: W32DDEFreeGlobalMem32: h32 is NULL to Win32 GlobalFree\n");
  690. /*
  691. * since in this case the Failure and Success return values from
  692. * GlobalFree are NULL, just return false so things are faster
  693. * in GlobalFree.
  694. */
  695. fOkToFree = FALSE;
  696. }
  697. return(fOkToFree);
  698. }
  699. // This function frees only the 32 bit memory because the 16 bit memory
  700. // is being free'd by the 16 bit app. We are just getting the
  701. // notification of this fact. So free the corresponding 32 bit memory.
  702. //
  703. ULONG FASTCALL WK32WowDdeFreeHandle (PVDMFRAME pFrame)
  704. {
  705. ULONG ul;
  706. HAND16 h16;
  707. PWOWDDEFREEHANDLE16 parg16;
  708. GETARGPTR(pFrame, sizeof(WOWDDEFREEHANDLE16), parg16);
  709. h16 = (HAND16) parg16->h16;
  710. ul = W32DdeFreeHandle16 (h16);
  711. FREEARGPTR(parg16);
  712. RETURN (ul);
  713. }
  714. BOOL W32DdeFreeHandle16 (HAND16 h16)
  715. {
  716. HANDLE h32;
  717. PHDDE pDdeNode;
  718. if (!(pDdeNode = DDEFindNode16(h16))) {
  719. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Not found h16 -> %04x\n", h16));
  720. // in this case look for a 16:32 pair in the list of hdrop handles
  721. // see file wshell.c for comments
  722. FindAndReleaseHDrop16(h16);
  723. return (TRUE);
  724. }
  725. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Entering... h16 -> %04x\n", h16));
  726. if (pDdeNode->DdeMsg == WM_DDE_EXECUTE) {
  727. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : App TRYING !!! to freeing EXECUTE h16 -> %04x\n", h16));
  728. pDdeNode->DdeFlags = pDdeNode->DdeFlags | DDE_EXECUTE_FREE_MEM;
  729. return (FALSE);
  730. }
  731. else {
  732. while ((pDdeNode) && (h32 = pDdeNode->hMem32)) {
  733. if (pDdeNode->DdeFlags & DDE_METAFILE) {
  734. DDEDeletehandle(h16, h32);
  735. DeleteMetaFile (h32);
  736. }
  737. else {
  738. /*
  739. * REMOVE THE PAIR FIRST!!!
  740. * Since GlobalFree will hook back to W32DDEFreeGlobalMem32
  741. * we want to remove the handle from our tables before
  742. * the call.
  743. */
  744. DDEDeletehandle(h16, h32);
  745. WOWGLOBALFREE(h32);
  746. }
  747. pDdeNode = DDEFindNode16(h16);
  748. }
  749. }
  750. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Leaving ...\n"));
  751. return (TRUE);
  752. }
  753. // This routine adds the given h16-h32 CopyData pair to the linked list,
  754. // and updates the list.
  755. //
  756. BOOL CopyDataAddNode (HAND16 To_hwnd, HAND16 From_hwnd, DWORD Mem16, DWORD Mem32, DWORD Flags)
  757. {
  758. PCPDATA pTemp;
  759. if (Mem16 && Mem32) {
  760. if (pTemp = malloc_w (sizeof(CPDATA))) {
  761. pTemp->Mem16 = Mem16;
  762. pTemp->Mem32 = Mem32;
  763. pTemp->To_hwnd = To_hwnd;
  764. pTemp->From_hwnd= From_hwnd;
  765. pTemp->Flags = Flags;
  766. pTemp->Next = pCPDataFirst; // insert at the top
  767. pCPDataFirst = pTemp; // update list head
  768. return (TRUE);
  769. }
  770. else {
  771. LOGDEBUG(2, ("WOW::CopyDataAddNode: *** memory allocation failed *** \n"));
  772. return (FALSE);
  773. }
  774. }
  775. LOGDEBUG(2,("WOW::CopyDataAddNode: *** ERROR *** one of the memory pointers is NULL \n"));
  776. return (FALSE);
  777. }
  778. VPVOID CopyDataFindData16 (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem)
  779. {
  780. PCPDATA pTemp;
  781. pTemp = pCPDataFirst;
  782. while (pTemp) {
  783. if ((pTemp->To_hwnd == To_hwnd) &&
  784. (pTemp->From_hwnd == From_hwnd) &&
  785. (pTemp->Mem32 == Mem)) {
  786. return (pTemp->Mem16);
  787. }
  788. else {
  789. pTemp = pTemp->Next;
  790. }
  791. }
  792. return 0;
  793. }
  794. PCPDATA CopyDataFindData32 (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem)
  795. {
  796. PCPDATA pTemp;
  797. pTemp = pCPDataFirst;
  798. while (pTemp) {
  799. if ((pTemp->To_hwnd == To_hwnd) &&
  800. (pTemp->From_hwnd == From_hwnd) &&
  801. (pTemp->Mem16 == Mem)) {
  802. return (pTemp);
  803. }
  804. else {
  805. pTemp = pTemp->Next;
  806. }
  807. }
  808. return 0;
  809. }
  810. // This routine deletes the given h16-h32 pair from the list.
  811. //
  812. //
  813. BOOL CopyDataDeleteNode (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem)
  814. {
  815. PCPDATA pTemp1;
  816. PCPDATA pTemp2;
  817. pTemp1 = pCPDataFirst;
  818. if ((pTemp1->To_hwnd == To_hwnd) &&
  819. (pTemp1->From_hwnd == From_hwnd) &&
  820. (pTemp1->Mem32 == Mem)) {
  821. pCPDataFirst = pTemp1->Next;
  822. free_w (pTemp1);
  823. return (TRUE);
  824. }
  825. else {
  826. pTemp2 = pTemp1;
  827. pTemp1 = pTemp1->Next;
  828. while (pTemp1) {
  829. if ((pTemp1->To_hwnd == To_hwnd) &&
  830. (pTemp1->From_hwnd == From_hwnd) &&
  831. (pTemp1->Mem32 == Mem)) {
  832. pTemp2->Next = pTemp1->Next;
  833. free_w (pTemp1);
  834. return (TRUE);
  835. }
  836. pTemp2 = pTemp1;
  837. pTemp1 = pTemp1->Next;
  838. }
  839. return (FALSE);
  840. }
  841. }
  842. // While allocating GMEM_DDESHARE memory object should we have GMEM_MOVEABLE
  843. // flag or not ???????????????????
  844. // ChandanC Sept 23rd 1993.
  845. //
  846. // WARNING: This function may cause 16-bit memory movement.
  847. //
  848. HAND16 Copyh32Toh16 (int cb, LPBYTE lpMem32)
  849. {
  850. HAND16 h16 = 0;
  851. LPBYTE lpMem16;
  852. VPVOID vp;
  853. vp = GlobalAllocLock16(GMEM_DDESHARE | GMEM_MOVEABLE, cb, &h16);
  854. WOW32ASSERT(vp);
  855. if (vp) {
  856. GETMISCPTR(vp, lpMem16);
  857. RtlCopyMemory(lpMem16, lpMem32, cb);
  858. GlobalUnlock16(h16);
  859. FLUSHVDMPTR(vp, cb, lpMem16);
  860. FREEMISCPTR(lpMem16);
  861. }
  862. return (h16);
  863. }
  864. HANDLE Copyh16Toh32 (int cb, LPBYTE lpMem16)
  865. {
  866. HANDLE hMem32;
  867. LPBYTE lpMem32;
  868. hMem32 = WOWGLOBALALLOC(GMEM_DDESHARE | GMEM_MOVEABLE, cb);
  869. WOW32ASSERT(hMem32);
  870. if (hMem32) {
  871. lpMem32 = GlobalLock(hMem32);
  872. RtlCopyMemory (lpMem32, lpMem16, cb);
  873. GlobalUnlock(hMem32);
  874. }
  875. return (hMem32);
  876. }
  877. VOID FixMetafile32To16 (LPMETAFILEPICT lpMemMeta32, LPMETAFILEPICT16 lpMemMeta16)
  878. {
  879. if (lpMemMeta32->mm == MM_ANISOTROPIC) {
  880. LONG xExt = lpMemMeta32->xExt;
  881. LONG yExt = lpMemMeta32->yExt;
  882. while (xExt < (LONG)(SHORT)MINSHORT
  883. || xExt > (LONG)(SHORT)MAXSHORT
  884. || yExt < (LONG)(SHORT)MINSHORT
  885. || yExt > (LONG)(SHORT)MAXSHORT) {
  886. xExt = xExt / 2;
  887. yExt = yExt / 2;
  888. }
  889. STORESHORT(lpMemMeta16->mm, MM_ANISOTROPIC);
  890. STORESHORT(lpMemMeta16->xExt, xExt);
  891. STORESHORT(lpMemMeta16->yExt, yExt);
  892. }
  893. else {
  894. STORESHORT(lpMemMeta16->mm, lpMemMeta32->mm);
  895. STORESHORT(lpMemMeta16->xExt, lpMemMeta32->xExt);
  896. STORESHORT(lpMemMeta16->yExt, lpMemMeta32->yExt);
  897. }
  898. }
  899. //
  900. // CHEESE ALERT: This function is exported for the OLE DDE code
  901. // to call so it can correctly free up metafile handle pairs in
  902. // a VDM. This function is NOT found in any header files. If you
  903. // change this, you need to find its use in the OLE project.
  904. // Probably best to just leave it alone.
  905. //
  906. BOOL WINAPI WOWFreeMetafile( HANDLE h32 )
  907. {
  908. return( W32DDEFreeGlobalMem32( h32 ) );
  909. }