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.

1164 lines
35 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 ((hInst = (HANDLE)GetWindowLong((HWND)HWND32(To_hwnd),GWL_HINSTANCE))
  149. && (LOWORD(hInst) != 0 )) {
  150. if(vp = GlobalAllocLock16(GMEM_MOVEABLE, cchModuleName, &hModuleName)) {
  151. //
  152. // Callback 16 to get the module name of the current hInst
  153. //
  154. if (cchModuleName = GetModuleFileName16( LOWORD(hInst),
  155. vp,
  156. cchModuleName )) {
  157. GETMISCPTR(vp, lpszModuleName16);
  158. fStatus = (cchModuleName >= cchMsDraw) && !WOW32_stricmp( lpszModuleName16 + (cchModuleName - cchMsDraw), lpszMsDraw ) && (Status = RegOpenKeyEx( HKEY_CLASSES_ROOT, lpszNewMsDrawKey, 0, KEY_READ, &hKey)) != ERROR_SUCCESS;
  159. if (hKey) {
  160. RegCloseKey( hKey );
  161. }
  162. FREEMISCPTR(lpszModuleName16);
  163. }
  164. // Cleanup
  165. GlobalUnlockFree16(vp);
  166. }
  167. }
  168. return ( fStatus );
  169. }
  170. // This routine converts a 32 bit DDE memory object into a 16 bit DDE
  171. // memory object. It also, does the data conversion from 32 bit to 16 bit
  172. // for the type of data.
  173. //
  174. // WARNING: The Copyh32Toh16() calls may cause 16-bit memory movement
  175. //
  176. HAND16 DDECopyhData16(HAND16 To_hwnd, HAND16 From_hwnd, HANDLE h32, PDDEINFO pDdeInfo)
  177. {
  178. HAND16 h16 = 0;
  179. VPVOID vp1, vp2;
  180. DDEDATA *lpMem32;
  181. DDEDATA16 *lpMem16;
  182. int cb;
  183. //
  184. // NULL handle ?
  185. //
  186. if (!h32) {
  187. LOGDEBUG(12, ("WOW::DDECopyhData16(): h32 is %08x\n", h32));
  188. return 0;
  189. }
  190. cb = GlobalSize(h32);
  191. lpMem32 = GlobalLock(h32);
  192. if(lpMem32) {
  193. LOGDEBUG(12,
  194. ("WOW::DDECopyhData16(): CF_FORMAT is %04x\n",
  195. 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. if(lpMemDib32) {
  252. cb = GlobalSize(hDib32);
  253. hDib16 = Copyh32Toh16 (cb, (LPBYTE) lpMemDib32);
  254. GlobalUnlock(hDib32);
  255. pDdeInfo->Format = lpMem32->cfFormat;
  256. pDdeInfo->Flags = 0;
  257. pDdeInfo->h16 = 0;
  258. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hDib16, hDib32, pDdeInfo);
  259. }
  260. }
  261. GETMISCPTR(vp1, lpMem16);
  262. STOREWORD(lpMem16->Value, hDib16);
  263. GlobalUnlock16(h16);
  264. FLUSHVDMPTR(vp1,(sizeof(DDEDATA)-1+sizeof(HAND16)),lpMem16);
  265. FREEMISCPTR(lpMem16);
  266. }
  267. }
  268. break;
  269. case CF_METAFILEPICT:
  270. case CF_DSPMETAFILEPICT:
  271. {
  272. HANDLE hMeta32, hMF32 = NULL;
  273. HAND16 hMeta16 = 0, hMF16 = 0;
  274. LPMETAFILEPICT lpMemMeta32;
  275. LPMETAFILEPICT16 lpMemMeta16;
  276. BOOL IsMSDRAWPoke;
  277. //
  278. // We need to find out if the to_handle is MSDRAW, in which case
  279. // we should copy the METAFILEPICT data to the DDEPOKE instead
  280. // of a handle to the METAFILEPICT.
  281. if( IsMSDRAWPoke = ((pDdeInfo->Msg == WM_DDE_POKE) && DDEIsTargetMSDraw(To_hwnd)) ) {
  282. cb = sizeof(DDEPOKE)-1+sizeof(METAFILEPICT16);
  283. }
  284. else {
  285. cb = sizeof(DDEDATA)-1+sizeof(HAND16);
  286. }
  287. vp1 = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16);
  288. if (vp1) {
  289. GETMISCPTR(vp1, lpMem16);
  290. RtlCopyMemory(lpMem16, lpMem32, 4);
  291. hMeta32 = (*((HANDLE *)lpMem32->Value));
  292. if ( IsMSDRAWPoke ) {
  293. lpMemMeta16 = (LPMETAFILEPICT16)((PBYTE)lpMem16 + sizeof(DDEPOKE) - 1);
  294. RtlZeroMemory( (PVOID)lpMemMeta16, sizeof (METAFILEPICT16) );
  295. if (hMeta32) {
  296. lpMemMeta32 = GlobalLock(hMeta32);
  297. if(lpMemMeta32) {
  298. FixMetafile32To16 (lpMemMeta32, lpMemMeta16);
  299. FREEMISCPTR(lpMem16);
  300. hMF32 = lpMemMeta32->hMF;
  301. if (hMF32) {
  302. hMF16 = WinMetaFileFromHMF(hMF32, FALSE);
  303. pDdeInfo->Format = lpMem32->cfFormat;
  304. pDdeInfo->h16 = 0;
  305. pDdeInfo->Flags = DDE_METAFILE;
  306. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo);
  307. }
  308. }
  309. GETMISCPTR(vp1, lpMem16);
  310. lpMemMeta16 = (LPMETAFILEPICT16)((PBYTE)lpMem16 + sizeof(DDEPOKE) - 1);
  311. STOREWORD(lpMemMeta16->hMF, hMF16);
  312. GlobalUnlock(hMeta32);
  313. }
  314. }
  315. else {
  316. if (hMeta32) {
  317. lpMemMeta32 = GlobalLock(hMeta32);
  318. if(lpMemMeta32) {
  319. // 16-bit memory may move -- invalidate ptr
  320. FREEMISCPTR(lpMem16);
  321. vp2 = GlobalAllocLock16(GMEM_DDESHARE, sizeof(METAFILEPICT16), &hMeta16);
  322. WOW32ASSERT(vp2);
  323. if (vp2) {
  324. GETMISCPTR(vp2, lpMemMeta16);
  325. FixMetafile32To16(lpMemMeta32, lpMemMeta16);
  326. FREEMISCPTR(lpMemMeta16);
  327. pDdeInfo->Format = lpMem32->cfFormat;
  328. pDdeInfo->Flags = 0;
  329. pDdeInfo->h16 = 0;
  330. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMeta16, hMeta32, pDdeInfo);
  331. hMF32 = lpMemMeta32->hMF;
  332. if (hMF32) {
  333. hMF16 = WinMetaFileFromHMF(hMF32,FALSE);
  334. pDdeInfo->Flags = DDE_METAFILE;
  335. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo);
  336. }
  337. GETMISCPTR(vp2, lpMemMeta16);
  338. STOREWORD(lpMemMeta16->hMF, hMF16);
  339. GlobalUnlock16(hMeta16);
  340. FLUSHVDMPTR(vp2, 8, lpMemMeta16);
  341. FREEMISCPTR(lpMemMeta16);
  342. }
  343. GlobalUnlock(hMeta32);
  344. }
  345. }
  346. GETMISCPTR(vp1, lpMem16);
  347. STOREWORD(lpMem16->Value, hMeta16);
  348. }
  349. GlobalUnlock16(h16);
  350. FLUSHVDMPTR(vp1, cb, lpMem16);
  351. FREEMISCPTR(lpMem16);
  352. }
  353. }
  354. break;
  355. }
  356. GlobalUnlock(h32);
  357. }
  358. return (h16);
  359. }
  360. // This routine converts a 16 bit DDE memory object into a 32 bit DDE
  361. // memory object. It also, does the data conversion from 16 bit to 32 bit
  362. // for the type of data.
  363. //
  364. HANDLE DDECopyhData32(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 h16, PDDEINFO pDdeInfo)
  365. {
  366. HANDLE h32 = NULL;
  367. INT cb;
  368. VPVOID vp;
  369. DDEDATA *lpMem16;
  370. DDEDATA32 *lpMem32;
  371. //
  372. // AmiPro passes a NULL handle.
  373. //
  374. if (!h16) {
  375. LOGDEBUG(12, ("WOW::DDECopyhData32(): h16 is %04x\n", h16));
  376. return (HANDLE) NULL;
  377. }
  378. vp = GlobalLock16(h16, &cb);
  379. GETMISCPTR(vp, lpMem16);
  380. LOGDEBUG(12, ("WOW::DDECopyhData32(): CF_FORMAT is %04x\n", lpMem16->cfFormat));
  381. switch(lpMem16->cfFormat) {
  382. default:
  383. // This is intentional to let it thru to the "case statements".
  384. // ChandanC 5/11/92.
  385. case CF_TEXT:
  386. case CF_DSPTEXT:
  387. case CF_SYLK:
  388. case CF_DIF:
  389. case CF_TIFF:
  390. case CF_OEMTEXT:
  391. case CF_PENDATA:
  392. case CF_RIFF:
  393. case CF_WAVE:
  394. case CF_OWNERDISPLAY:
  395. h32 = Copyh16Toh32 (cb, (LPBYTE) lpMem16);
  396. pDdeInfo->Format = lpMem16->cfFormat;
  397. break;
  398. case CF_BITMAP:
  399. case CF_DSPBITMAP:
  400. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  401. if (h32) {
  402. pDdeInfo->Format = lpMem16->cfFormat;
  403. lpMem32 = GlobalLock(h32);
  404. if(lpMem32) {
  405. RtlCopyMemory(lpMem32, lpMem16, 4);
  406. lpMem32->Value = HBITMAP32(FETCHWORD(*((WORD *)lpMem16->Value)));
  407. GlobalUnlock(h32);
  408. }
  409. }
  410. break;
  411. case CF_PALETTE:
  412. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  413. if (h32) {
  414. pDdeInfo->Format = lpMem16->cfFormat;
  415. lpMem32 = GlobalLock(h32);
  416. if(lpMem32) {
  417. RtlCopyMemory(lpMem32, lpMem16, 4);
  418. lpMem32->Value = HPALETTE32(FETCHWORD(*((WORD *)lpMem16->Value)));
  419. GlobalUnlock(h32);
  420. }
  421. }
  422. break;
  423. case CF_DIB:
  424. {
  425. LPBYTE lpMemDib16;
  426. HAND16 hDib16;
  427. HANDLE hDib32 = NULL;
  428. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  429. if (h32) {
  430. lpMem32 = GlobalLock(h32);
  431. if(lpMem32) {
  432. RtlCopyMemory(lpMem32, lpMem16, 4);
  433. hDib16 = FETCHWORD(*((WORD *)lpMem16->Value));
  434. if (hDib16) {
  435. vp = GlobalLock16(hDib16, &cb);
  436. GETMISCPTR(vp, lpMemDib16);
  437. hDib32 = Copyh16Toh32 (cb, (LPBYTE) lpMemDib16);
  438. pDdeInfo->Format = lpMem16->cfFormat;
  439. pDdeInfo->Flags = 0;
  440. pDdeInfo->h16 = 0;
  441. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hDib16, hDib32, pDdeInfo);
  442. GlobalUnlock16(hDib16);
  443. FREEMISCPTR(lpMemDib16);
  444. }
  445. lpMem32->Value = hDib32;
  446. GlobalUnlock(h32);
  447. }
  448. }
  449. }
  450. break;
  451. case CF_METAFILEPICT:
  452. case CF_DSPMETAFILEPICT:
  453. {
  454. HANDLE hMeta32 = NULL, hMF32 = NULL;
  455. HAND16 hMeta16, hMF16 = 0;
  456. LPMETAFILEPICT lpMemMeta32;
  457. LPMETAFILEPICT16 lpMemMeta16;
  458. h32 = WOWGLOBALALLOC(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE)));
  459. if (h32) {
  460. lpMem32 = GlobalLock(h32);
  461. if(lpMem32) {
  462. RtlCopyMemory(lpMem32, lpMem16, 4);
  463. //
  464. // MSDRAW has the METAFILEPICT in the DDEPOKE block instead
  465. // of a handle to the METAFILEPICT. So we need to find out
  466. // if the to handle belongs to MSDRAW. Since MSDRAW is a 16
  467. // bit server we needn't thunk the metafilepict at all, we
  468. // just use NULL as the 32 bit handle to the metafilepict.
  469. //
  470. hMeta32 = NULL;
  471. if( !((pDdeInfo->Msg == WM_DDE_POKE) && DDEIsTargetMSDraw(To_hwnd)) ) {
  472. hMeta16 = FETCHWORD(*((WORD *)lpMem16->Value));
  473. //
  474. // Make sure that a valid metafile pict handle has been
  475. // passed in otherwise use NULL again as the hMeta32.
  476. //
  477. if (hMeta16 && (vp = GlobalLock16(hMeta16, &cb))) {
  478. GETMISCPTR(vp, lpMemMeta16);
  479. hMeta32 = WOWGLOBALALLOC(GMEM_DDESHARE, sizeof(METAFILEPICT));
  480. WOW32ASSERT(hMeta32);
  481. if (hMeta32) {
  482. lpMemMeta32 = GlobalLock(hMeta32);
  483. if(lpMemMeta32) {
  484. lpMemMeta32->mm = (LONG) FETCHSHORT(lpMemMeta16->mm);
  485. lpMemMeta32->xExt = (LONG) FETCHSHORT(lpMemMeta16->xExt);
  486. lpMemMeta32->yExt = (LONG) FETCHSHORT(lpMemMeta16->yExt);
  487. pDdeInfo->Format = lpMem16->cfFormat;
  488. pDdeInfo->Flags = 0;
  489. pDdeInfo->h16 = 0;
  490. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMeta16, hMeta32, pDdeInfo);
  491. hMF16 = FETCHWORD(lpMemMeta16->hMF);
  492. if (hMF16) {
  493. hMF32 = (HMETAFILE) HMFFromWinMetaFile(hMF16, FALSE);
  494. pDdeInfo->Flags = DDE_METAFILE;
  495. DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo);
  496. }
  497. lpMemMeta32->hMF = (HMETAFILE) hMF32;
  498. GlobalUnlock(hMeta32);
  499. }
  500. }
  501. GlobalUnlock16(hMeta16);
  502. FREEMISCPTR(lpMemMeta16);
  503. }
  504. }
  505. lpMem32->Value = hMeta32;
  506. GlobalUnlock(h32);
  507. }
  508. }
  509. }
  510. break;
  511. }
  512. GlobalUnlock16(h16);
  513. FREEMISCPTR(lpMem16);
  514. return (h32);
  515. }
  516. /****** These routines maintain a linked list of dde handles, which
  517. ******* are the h16 and h32 pairs.
  518. ******/
  519. // This routine adds the given h16-h32 pair to the linked list, and updates
  520. // the list.
  521. //
  522. BOOL DDEAddhandle(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 hMem16, HANDLE hMem32, PDDEINFO pDdeInfo)
  523. {
  524. PHDDE phTemp;
  525. if (hMem16 && hMem32) {
  526. if (phTemp = malloc_w (sizeof(HDDE))) {
  527. phTemp->hMem16 = hMem16;
  528. phTemp->hMem32 = hMem32;
  529. phTemp->To_hwnd = To_hwnd;
  530. phTemp->From_hwnd = From_hwnd;
  531. phTemp->DdeMsg = pDdeInfo->Msg;
  532. phTemp->DdeFormat = pDdeInfo->Format;
  533. phTemp->DdeFlags = pDdeInfo->Flags;
  534. phTemp->h16 = pDdeInfo->h16;
  535. phTemp->pDDENext = phDDEFirst; // insert at the top
  536. phDDEFirst = phTemp; // update list head
  537. // Mark the GAH_WOWDDEFREEHANDLE (ie GAH_PAHTOM) bit in the global
  538. // arena of this handle.
  539. W32MarkDDEHandle (hMem16);
  540. return (TRUE);
  541. }
  542. else {
  543. LOGDEBUG(2, ("WOW::DDEAddhandle(): *** memory allocation failed *** \n"));
  544. return (FALSE);
  545. }
  546. }
  547. LOGDEBUG(2,("WOW::DDEAddhandle(): *** ERROR *** one of the handles is NULL \n"));
  548. return (FALSE);
  549. }
  550. // This routine deletes the given h16-h32 pair from the list and frees up
  551. // the memory.
  552. //
  553. BOOL DDEDeletehandle(HAND16 h16, HANDLE h32)
  554. {
  555. PHDDE phTemp1, phTemp2;
  556. phTemp1 = phDDEFirst;
  557. if ((phTemp1->hMem16 == h16) && (phTemp1->hMem32 == h32)) { // first node
  558. phDDEFirst = phTemp1->pDDENext;
  559. free_w(phTemp1);
  560. return (TRUE);
  561. }
  562. else { // rest of the list
  563. phTemp2 = phTemp1;
  564. phTemp1 = phTemp1->pDDENext;
  565. while (phTemp1) {
  566. if ((phTemp1->hMem16 == h16) && (phTemp1->hMem32 == h32)) {
  567. phTemp2->pDDENext = phTemp1->pDDENext;
  568. free_w(phTemp1);
  569. return (TRUE);
  570. }
  571. phTemp2 = phTemp1;
  572. phTemp1 = phTemp1->pDDENext;
  573. }
  574. LOGDEBUG(2,("WOW::DDEDeleteHandle : Can't find a 16-32 memory pair\n"));
  575. return (FALSE);
  576. }
  577. }
  578. // This routine finds a hMem16 for a DDE conversation, if one exists.
  579. //
  580. HAND16 DDEFindPair16(HAND16 To_hwnd, HAND16 From_hwnd, HANDLE hMem32)
  581. {
  582. PHDDE phTemp;
  583. phTemp = phDDEFirst;
  584. while (phTemp) {
  585. if ((phTemp->To_hwnd == To_hwnd) &&
  586. (phTemp->From_hwnd == From_hwnd) &&
  587. (phTemp->hMem32 == hMem32)) {
  588. return (phTemp->hMem16);
  589. }
  590. else {
  591. phTemp = phTemp->pDDENext;
  592. }
  593. }
  594. return (HAND16) NULL;
  595. }
  596. // This routine finds a hMem32 for a DDE conversation, if one exists.
  597. //
  598. HANDLE DDEFindPair32(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 hMem16)
  599. {
  600. PHDDE phTemp;
  601. phTemp = phDDEFirst;
  602. while (phTemp) {
  603. if ((phTemp->To_hwnd == To_hwnd) &&
  604. (phTemp->From_hwnd == From_hwnd) &&
  605. (phTemp->hMem16 == hMem16)) {
  606. return (phTemp->hMem32);
  607. }
  608. else {
  609. phTemp = phTemp->pDDENext;
  610. }
  611. }
  612. return (HANDLE) NULL;
  613. }
  614. // This routine find the DDE node that is doing DDE conversation
  615. //
  616. PHDDE DDEFindNode16 (HAND16 h16)
  617. {
  618. PHDDE phTemp;
  619. phTemp = phDDEFirst;
  620. while (phTemp) {
  621. if (phTemp->hMem16 == h16) {
  622. return (phTemp);
  623. }
  624. phTemp = phTemp->pDDENext;
  625. }
  626. return (NULL);
  627. }
  628. // This routine find the DDE node that is doing DDE conversation
  629. //
  630. PHDDE DDEFindNode32 (HANDLE h32)
  631. {
  632. PHDDE phTemp;
  633. phTemp = phDDEFirst;
  634. while (phTemp) {
  635. if (phTemp->hMem32 == h32) {
  636. return (phTemp);
  637. }
  638. phTemp = phTemp->pDDENext;
  639. }
  640. return (NULL);
  641. }
  642. // This routine returns a pointer to the DDE node, if the conversation exists,
  643. // else it retunrs NULL
  644. PHDDE DDEFindAckNode (HAND16 To_hwnd, HAND16 From_hwnd, HANDLE hMem32)
  645. {
  646. PHDDE phTemp;
  647. phTemp = phDDEFirst;
  648. while (phTemp) {
  649. if ((phTemp->To_hwnd == To_hwnd) &&
  650. (phTemp->From_hwnd == From_hwnd) &&
  651. (phTemp->hMem32 == hMem32)) {
  652. return (phTemp);
  653. }
  654. else {
  655. phTemp = phTemp->pDDENext;
  656. }
  657. }
  658. return (PHDDE) NULL;
  659. }
  660. // This function marks GAH_WOWDDEFREEHANDLE bit in the global arena of the
  661. // hMem16.
  662. //
  663. VOID W32MarkDDEHandle (HAND16 hMem16)
  664. {
  665. PARM16 Parm16;
  666. VPVOID vp = 0;
  667. Parm16.WndProc.wParam = hMem16;
  668. Parm16.WndProc.wMsg = 1;
  669. CallBack16(RET_WOWDDEFREEHANDLE, &Parm16, 0, &vp);
  670. }
  671. VOID W32UnMarkDDEHandle (HAND16 hMem16)
  672. {
  673. PARM16 Parm16;
  674. VPVOID vp = 0;
  675. Parm16.WndProc.wParam = hMem16;
  676. Parm16.WndProc.wMsg = 0;
  677. CallBack16(RET_WOWDDEFREEHANDLE, &Parm16, 0, &vp);
  678. }
  679. // This function frees the 32 and 16 bit memory. It is called by 32 bit
  680. // BASE by GlobalFree.
  681. //
  682. BOOL W32DDEFreeGlobalMem32 (HANDLE h32)
  683. {
  684. HAND16 h16;
  685. PHDDE pDdeNode;
  686. BOOL fOkToFree = TRUE;
  687. if (h32) {
  688. if (pDdeNode = DDEFindNode32(h32)) {
  689. if (pDdeNode->DdeFlags & DDE_METAFILE) {
  690. LOGDEBUG (12, ("WOW32: W32DDEFreeGlobalMem32: Freeing MetaFile hMF32 %x\n", h32));
  691. DeleteMetaFile (h32);
  692. fOkToFree = FALSE;
  693. }
  694. while ((pDdeNode) && (h16 = pDdeNode->hMem16)) {
  695. W32UnMarkDDEHandle (h16);
  696. GlobalUnlockFree16(GlobalLock16(h16, NULL));
  697. DDEDeletehandle(h16, h32);
  698. pDdeNode = DDEFindNode32(h32);
  699. }
  700. }
  701. else {
  702. LOGDEBUG (2, ("WOW32: W32DDEFreeGlobalMem32: Can't find a 16-32 memory pair\n"));
  703. }
  704. }
  705. else {
  706. WOW32WARNMSG(FALSE, "WOW32: W32DDEFreeGlobalMem32: h32 is NULL to Win32 GlobalFree\n");
  707. /*
  708. * since in this case the Failure and Success return values from
  709. * GlobalFree are NULL, just return false so things are faster
  710. * in GlobalFree.
  711. */
  712. fOkToFree = FALSE;
  713. }
  714. return(fOkToFree);
  715. }
  716. // This function frees only the 32 bit memory because the 16 bit memory
  717. // is being free'd by the 16 bit app. We are just getting the
  718. // notification of this fact. So free the corresponding 32 bit memory.
  719. //
  720. ULONG FASTCALL WK32WowDdeFreeHandle (PVDMFRAME pFrame)
  721. {
  722. ULONG ul;
  723. HAND16 h16;
  724. PWOWDDEFREEHANDLE16 parg16;
  725. GETARGPTR(pFrame, sizeof(WOWDDEFREEHANDLE16), parg16);
  726. h16 = (HAND16) parg16->h16;
  727. ul = W32DdeFreeHandle16 (h16);
  728. FREEARGPTR(parg16);
  729. RETURN (ul);
  730. }
  731. BOOL W32DdeFreeHandle16 (HAND16 h16)
  732. {
  733. HANDLE h32;
  734. PHDDE pDdeNode;
  735. if (!(pDdeNode = DDEFindNode16(h16))) {
  736. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Not found h16 -> %04x\n", h16));
  737. // in this case look for a 16:32 pair in the list of hdrop handles
  738. // see file wshell.c for comments
  739. FindAndReleaseHDrop16(h16);
  740. return (TRUE);
  741. }
  742. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Entering... h16 -> %04x\n", h16));
  743. if (pDdeNode->DdeMsg == WM_DDE_EXECUTE) {
  744. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : App TRYING !!! to freeing EXECUTE h16 -> %04x\n", h16));
  745. pDdeNode->DdeFlags = pDdeNode->DdeFlags | DDE_EXECUTE_FREE_MEM;
  746. return (FALSE);
  747. }
  748. else {
  749. while ((pDdeNode) && (h32 = pDdeNode->hMem32)) {
  750. if (pDdeNode->DdeFlags & DDE_METAFILE) {
  751. DDEDeletehandle(h16, h32);
  752. DeleteMetaFile (h32);
  753. }
  754. else {
  755. /*
  756. * REMOVE THE PAIR FIRST!!!
  757. * Since GlobalFree will hook back to W32DDEFreeGlobalMem32
  758. * we want to remove the handle from our tables before
  759. * the call.
  760. */
  761. DDEDeletehandle(h16, h32);
  762. WOWGLOBALFREE(h32);
  763. }
  764. pDdeNode = DDEFindNode16(h16);
  765. }
  766. }
  767. LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Leaving ...\n"));
  768. return (TRUE);
  769. }
  770. // This routine adds the given h16-h32 CopyData pair to the linked list,
  771. // and updates the list.
  772. //
  773. BOOL CopyDataAddNode (HAND16 To_hwnd, HAND16 From_hwnd, DWORD Mem16, DWORD Mem32, DWORD Flags)
  774. {
  775. PCPDATA pTemp;
  776. if (Mem16 && Mem32) {
  777. if (pTemp = malloc_w (sizeof(CPDATA))) {
  778. pTemp->Mem16 = Mem16;
  779. pTemp->Mem32 = Mem32;
  780. pTemp->To_hwnd = To_hwnd;
  781. pTemp->From_hwnd= From_hwnd;
  782. pTemp->Flags = Flags;
  783. pTemp->Next = pCPDataFirst; // insert at the top
  784. pCPDataFirst = pTemp; // update list head
  785. return (TRUE);
  786. }
  787. else {
  788. LOGDEBUG(2, ("WOW::CopyDataAddNode: *** memory allocation failed *** \n"));
  789. return (FALSE);
  790. }
  791. }
  792. LOGDEBUG(2,("WOW::CopyDataAddNode: *** ERROR *** one of the memory pointers is NULL \n"));
  793. return (FALSE);
  794. }
  795. VPVOID CopyDataFindData16 (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem)
  796. {
  797. PCPDATA pTemp;
  798. pTemp = pCPDataFirst;
  799. while (pTemp) {
  800. if ((pTemp->To_hwnd == To_hwnd) &&
  801. (pTemp->From_hwnd == From_hwnd) &&
  802. (pTemp->Mem32 == Mem)) {
  803. return (pTemp->Mem16);
  804. }
  805. else {
  806. pTemp = pTemp->Next;
  807. }
  808. }
  809. return 0;
  810. }
  811. PCPDATA CopyDataFindData32 (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem)
  812. {
  813. PCPDATA pTemp;
  814. pTemp = pCPDataFirst;
  815. while (pTemp) {
  816. if ((pTemp->To_hwnd == To_hwnd) &&
  817. (pTemp->From_hwnd == From_hwnd) &&
  818. (pTemp->Mem16 == Mem)) {
  819. return (pTemp);
  820. }
  821. else {
  822. pTemp = pTemp->Next;
  823. }
  824. }
  825. return 0;
  826. }
  827. // This routine deletes the given h16-h32 pair from the list.
  828. //
  829. //
  830. BOOL CopyDataDeleteNode (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem)
  831. {
  832. PCPDATA pTemp1;
  833. PCPDATA pTemp2;
  834. pTemp1 = pCPDataFirst;
  835. if ((pTemp1->To_hwnd == To_hwnd) &&
  836. (pTemp1->From_hwnd == From_hwnd) &&
  837. (pTemp1->Mem32 == Mem)) {
  838. pCPDataFirst = pTemp1->Next;
  839. free_w (pTemp1);
  840. return (TRUE);
  841. }
  842. else {
  843. pTemp2 = pTemp1;
  844. pTemp1 = pTemp1->Next;
  845. while (pTemp1) {
  846. if ((pTemp1->To_hwnd == To_hwnd) &&
  847. (pTemp1->From_hwnd == From_hwnd) &&
  848. (pTemp1->Mem32 == Mem)) {
  849. pTemp2->Next = pTemp1->Next;
  850. free_w (pTemp1);
  851. return (TRUE);
  852. }
  853. pTemp2 = pTemp1;
  854. pTemp1 = pTemp1->Next;
  855. }
  856. return (FALSE);
  857. }
  858. }
  859. // While allocating GMEM_DDESHARE memory object should we have GMEM_MOVEABLE
  860. // flag or not ???????????????????
  861. // ChandanC Sept 23rd 1993.
  862. //
  863. // WARNING: This function may cause 16-bit memory movement.
  864. //
  865. HAND16 Copyh32Toh16 (int cb, LPBYTE lpMem32)
  866. {
  867. HAND16 h16 = 0;
  868. LPBYTE lpMem16;
  869. VPVOID vp;
  870. vp = GlobalAllocLock16(GMEM_DDESHARE | GMEM_MOVEABLE, cb, &h16);
  871. WOW32ASSERT(vp);
  872. if (vp) {
  873. GETMISCPTR(vp, lpMem16);
  874. RtlCopyMemory(lpMem16, lpMem32, cb);
  875. GlobalUnlock16(h16);
  876. FLUSHVDMPTR(vp, cb, lpMem16);
  877. FREEMISCPTR(lpMem16);
  878. }
  879. return (h16);
  880. }
  881. HANDLE Copyh16Toh32 (int cb, LPBYTE lpMem16)
  882. {
  883. HANDLE hMem32;
  884. LPBYTE lpMem32;
  885. hMem32 = WOWGLOBALALLOC(GMEM_DDESHARE | GMEM_MOVEABLE, cb);
  886. WOW32ASSERT(hMem32);
  887. if (hMem32) {
  888. lpMem32 = GlobalLock(hMem32);
  889. if(lpMem32) {
  890. RtlCopyMemory (lpMem32, lpMem16, cb);
  891. GlobalUnlock(hMem32);
  892. }
  893. }
  894. return (hMem32);
  895. }
  896. VOID FixMetafile32To16 (LPMETAFILEPICT lpMemMeta32, LPMETAFILEPICT16 lpMemMeta16)
  897. {
  898. if (lpMemMeta32->mm == MM_ANISOTROPIC) {
  899. LONG xExt = lpMemMeta32->xExt;
  900. LONG yExt = lpMemMeta32->yExt;
  901. while (xExt < (LONG)(SHORT)MINSHORT
  902. || xExt > (LONG)(SHORT)MAXSHORT
  903. || yExt < (LONG)(SHORT)MINSHORT
  904. || yExt > (LONG)(SHORT)MAXSHORT) {
  905. xExt = xExt / 2;
  906. yExt = yExt / 2;
  907. }
  908. STORESHORT(lpMemMeta16->mm, MM_ANISOTROPIC);
  909. STORESHORT(lpMemMeta16->xExt, xExt);
  910. STORESHORT(lpMemMeta16->yExt, yExt);
  911. }
  912. else {
  913. STORESHORT(lpMemMeta16->mm, lpMemMeta32->mm);
  914. STORESHORT(lpMemMeta16->xExt, lpMemMeta32->xExt);
  915. STORESHORT(lpMemMeta16->yExt, lpMemMeta32->yExt);
  916. }
  917. }
  918. //
  919. // CHEESE ALERT: This function is exported for the OLE DDE code
  920. // to call so it can correctly free up metafile handle pairs in
  921. // a VDM. This function is NOT found in any header files. If you
  922. // change this, you need to find its use in the OLE project.
  923. // Probably best to just leave it alone.
  924. //
  925. BOOL WINAPI WOWFreeMetafile( HANDLE h32 )
  926. {
  927. return( W32DDEFreeGlobalMem32( h32 ) );
  928. }