diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/wow32/wdde.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/mvdm/wow32/wdde.c')
-rw-r--r-- | private/mvdm/wow32/wdde.c | 1138 |
1 files changed, 1138 insertions, 0 deletions
diff --git a/private/mvdm/wow32/wdde.c b/private/mvdm/wow32/wdde.c new file mode 100644 index 000000000..1fbdbf5bb --- /dev/null +++ b/private/mvdm/wow32/wdde.c @@ -0,0 +1,1138 @@ +/*++ + * + * WOW v1.0 + * + * Copyright (c) 1991, Microsoft Corporation + * + * WDDE.C + * WOW32 DDE worker routines. + * + * History: + * WOW DDE support designed and developed by ChandanC + * +--*/ + + +#include "precomp.h" +#pragma hdrstop + +LPDDENODE DDEInitiateList = NULL; +STATIC PHDDE phDDEFirst = NULL; // pointer to first hDDE entry +STATIC PCPDATA pCPDataFirst = NULL; // pointer to first CopyData entry + +MODNAME(wdde.c); + + +// This routine maintains a list of client windows that are in +// Initiate mode. This is called from THUNKING of DDE_INITIATE +// message (from both the WMDISP32.C and WMSG16.C). +// + +VOID WI32DDEAddInitiator (HAND16 Initiator) +{ + LPDDENODE Node; + + Node = (LPDDENODE) malloc_w(sizeof(DDENODE)); + + if (Node) { + + // + // Initialize Node with the Initiator's window handle + // + + Node->Initiator = Initiator; + + // + // Insert this Node into the linked list of DDE_Initiate message + // in progress. + // + + Node->Next = DDEInitiateList; + DDEInitiateList = Node; + + LOGDEBUG(12, ("WOW::WI32DDEInitiator(): thunking -- adding an Initiator %04lX\n", Initiator)); + } + else { + + // + // We could not allocate memory. + // + + LOGDEBUG(12, ("WOW::WI32DDEInitiator(): thunking -- Couldn't allocate memory\n")); + WOW32ASSERT (FALSE); + } +} + + +// This routine deletes the client window that was in Initiate mode. Because +// the initiate message is completed now. This is called from UNTHUNKING +// of DDE_INITIATE message (from both the WMDISP32.C and WMSG16.C). +// + +VOID WI32DDEDeleteInitiator(HAND16 Initiator) +{ + LPDDENODE Node, Temp1; + + Node = DDEInitiateList; + + if (Node) { + + while (Node) { + if (Node->Initiator == Initiator) { + + if (Node == DDEInitiateList) { + + // + // first guy in the list + // + + DDEInitiateList = Node->Next; + } + else { + + // + // update the list + // + + Temp1->Next = Node->Next; + } + + LOGDEBUG(12, ("WOW::WI32DDEDeleteInitiator(): unthunking -- deleting an Initiator %08lX\n", Initiator)); + + // + // free up the memory + // + + free_w(Node); + Node = NULL; + } + else { + + // + // traverse the list + // + + Temp1 = Node; + Node = Node->Next; + } + } + + } + else { + + // This is an ERROR condition, which should never occur. If it does + // talk to CHANDANC as soon as possible. + // + + LOGDEBUG(0, ("WOW::WI32DDEDeletInitiator(): unthunking -- no Initiator\n")); + WOW32ASSERT (FALSE); + } +} + + +// This routine is used by DDE_ACK thunk to figure out how to thunk the +// DDE_ACK message, ie, whether lParam is a combination of 2 atoms or +// its a pointer to 32 bit packed structure. +// + +BOOL WI32DDEInitiate(HAND16 Initiator) +{ + LPDDENODE Node; + + Node = DDEInitiateList; + + while (Node) { + if (Node->Initiator == Initiator) { + // + // DDE_Initiate is in progress for this Window + // + + LOGDEBUG(12, ("WOW::WI32DDEInitiate(): thunking -- found an Initiator %08lX\n", Initiator)); + return (TRUE); + } + else { + Node = Node->Next; + } + } + LOGDEBUG(12, ("WOW::WI32DDEInitiate(): thunking -- did not find an Initiator %08lX\n", Initiator)); + + // + // DDE_Initiate is not in progress for this Window + // + + return (FALSE); +} + + +// +// This routine determines if the current dde operation is a poke to MSDRAW +// Pokes to MSDRAW for metafilepicts are special because the metafile pict +// is part of the POKE block. +// + +BOOL DDEIsTargetMSDraw(HAND16 To_hwnd) +{ + BOOL fStatus = FALSE; + HANDLE hInst; + HAND16 hModuleName; + LPSTR lpszModuleName16, lpszMsDraw = "MSDRAW.EXE"; + WORD cchModuleName = MAX_PATH, cchMsDraw = 10; + VPVOID vp; + LPSTR lpszNewMsDrawKey = "MSDRAW\\protocol\\StdFileEditing\\verb"; + HKEY hKey = NULL; + LONG Status; + + // + // To check if the target is msdraw, check the following. + // + // - That the destination window hInst is that of a 16 bit task (this is + // checking to see if the LOWORD of the hInst is not 0. + // - That the module name is MSDRAW. + // + // NOTE: THERE ARE THREE CALLBACK16 ROUTINES IN THIS CALL, MAKING IT AN + // EXPENSIVE CALL. HOWEVER THIS CALL IS RARELY MADE. + // + + if ( + (hInst = (HANDLE)GetWindowLong((HWND)HWND32(To_hwnd),GWL_HINSTANCE)) + && (LOWORD(hInst) != 0 ) + && (vp = GlobalAllocLock16(GMEM_MOVEABLE, cchModuleName, &hModuleName)) + ) { + + // + // Callback 16 to get the module name of the current hInst + // + + if (cchModuleName = GetModuleFileName16( LOWORD(hInst), vp, cchModuleName )) { + GETMISCPTR(vp, lpszModuleName16); + fStatus = (cchModuleName >= cchMsDraw) + && !_stricmp( lpszModuleName16 + (cchModuleName - cchMsDraw), lpszMsDraw ) + && (Status = RegOpenKeyEx( HKEY_CLASSES_ROOT, lpszNewMsDrawKey, 0, KEY_READ, &hKey)) != ERROR_SUCCESS; + + if (hKey) { + RegCloseKey( hKey ); + } + FREEMISCPTR(lpszModuleName16); + } + + // + // Cleanup + // + + GlobalUnlockFree16(vp); + } + return ( fStatus ); +} + + + +// This routine converts a 32 bit DDE memory object into a 16 bit DDE +// memory object. It also, does the data conversion from 32 bit to 16 bit +// for the type of data. +// +// WARNING: The Copyh32Toh16() calls may cause 16-bit memory movement +// + +HAND16 DDECopyhData16(HAND16 To_hwnd, HAND16 From_hwnd, HANDLE h32, PDDEINFO pDdeInfo) +{ + HAND16 h16 = 0; + VPVOID vp1, vp2; + DDEDATA *lpMem32; + DDEDATA16 *lpMem16; + int cb; + + // + // NULL handle ? + // + + if (!h32) { + LOGDEBUG(12, ("WOW::DDECopyhData16(): h32 is %08x\n", h32)); + return 0; + } + + cb = GlobalSize(h32); + lpMem32 = GlobalLock(h32); + LOGDEBUG(12, ("WOW::DDECopyhData16(): CF_FORMAT is %04x\n", lpMem32->cfFormat)); + + switch (lpMem32->cfFormat) { + + default: + + // This is intentional to let it thru to "case statements". + // ChandanC 5/11/92. + + case CF_TEXT: + case CF_DSPTEXT: + case CF_SYLK: + case CF_DIF: + case CF_TIFF: + case CF_OEMTEXT: + case CF_PENDATA: + case CF_RIFF: + case CF_WAVE: + case CF_OWNERDISPLAY: + h16 = Copyh32Toh16 (cb, (LPBYTE) lpMem32); + + pDdeInfo->Format = lpMem32->cfFormat; + break; + + case CF_BITMAP: + case CF_DSPBITMAP: + vp1 = GlobalAllocLock16(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HAND16)), &h16); + if (vp1) { + pDdeInfo->Format = lpMem32->cfFormat; + GETMISCPTR(vp1, lpMem16); + RtlCopyMemory(lpMem16, lpMem32, 4); + STOREWORD(lpMem16->Value, GETHBITMAP16(*((HANDLE *)lpMem32->Value))); + FLUSHVDMPTR(vp1, (sizeof(DDEDATA)-1+sizeof(HAND16)), lpMem16); + FREEMISCPTR(lpMem16); + GlobalUnlock16(h16); + } + break; + + case CF_PALETTE: + vp1 = GlobalAllocLock16(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HAND16)), &h16); + if (vp1) { + pDdeInfo->Format = lpMem32->cfFormat; + GETMISCPTR(vp1, lpMem16); + RtlCopyMemory(lpMem16, lpMem32, 4); + STOREWORD(lpMem16->Value, GETHPALETTE16(*((HANDLE *)lpMem32->Value))); + FLUSHVDMPTR(vp1, (sizeof(DDEDATA)-1+sizeof(HAND16)), lpMem16); + FREEMISCPTR(lpMem16); + GlobalUnlock16(h16); + } + break; + + case CF_DIB: + { + LPBYTE lpMemDib32; + HAND16 hDib16 = 0; + HANDLE hDib32; + + vp1 = GlobalAllocLock16(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HAND16)), &h16); + if (vp1) { + + GETMISCPTR(vp1, lpMem16); + RtlCopyMemory(lpMem16, lpMem32, 4); + FREEMISCPTR(lpMem16); + + hDib32 = (*((HANDLE *)lpMem32->Value)); + if (hDib32) { + lpMemDib32 = GlobalLock(hDib32); + cb = GlobalSize(hDib32); + hDib16 = Copyh32Toh16 (cb, (LPBYTE) lpMemDib32); + GlobalUnlock(hDib32); + pDdeInfo->Format = lpMem32->cfFormat; + pDdeInfo->Flags = 0; + pDdeInfo->h16 = 0; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hDib16, hDib32, pDdeInfo); + + } + + GETMISCPTR(vp1, lpMem16); + STOREWORD(lpMem16->Value, hDib16); + GlobalUnlock16(h16); + FLUSHVDMPTR(vp1, (sizeof(DDEDATA)-1+sizeof(HAND16)), lpMem16); + FREEMISCPTR(lpMem16); + } + } + break; + + case CF_METAFILEPICT: + case CF_DSPMETAFILEPICT: + { + HANDLE hMeta32, hMF32 = NULL; + HAND16 hMeta16 = 0, hMF16 = 0; + LPMETAFILEPICT lpMemMeta32; + LPMETAFILEPICT16 lpMemMeta16; + BOOL IsMSDRAWPoke; + + // + // We need to find out if the to_handle is MSDRAW, in which case + // we should copy the METAFILEPICT data to the DDEPOKE instead + // of a handle to the METAFILEPICT. + + if( IsMSDRAWPoke = ((pDdeInfo->Msg == WM_DDE_POKE) && DDEIsTargetMSDraw(To_hwnd)) ) { + cb = sizeof(DDEPOKE)-1+sizeof(METAFILEPICT16); + } + else { + cb = sizeof(DDEDATA)-1+sizeof(HAND16); + } + vp1 = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16); + + + if (vp1) { + GETMISCPTR(vp1, lpMem16); + RtlCopyMemory(lpMem16, lpMem32, 4); + hMeta32 = (*((HANDLE *)lpMem32->Value)); + + if ( IsMSDRAWPoke ) { + + lpMemMeta16 = (LPMETAFILEPICT16)((PBYTE)lpMem16 + sizeof(DDEPOKE) - 1); + RtlZeroMemory( (PVOID)lpMemMeta16, sizeof (METAFILEPICT16) ); + if (hMeta32) { + lpMemMeta32 = GlobalLock(hMeta32); + FixMetafile32To16 (lpMemMeta32, lpMemMeta16); + FREEMISCPTR(lpMem16); + + hMF32 = lpMemMeta32->hMF; + if (hMF32) { + hMF16 = WinMetaFileFromHMF(hMF32, FALSE); + pDdeInfo->Format = lpMem32->cfFormat; + pDdeInfo->h16 = 0; + pDdeInfo->Flags = DDE_METAFILE; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo); + } + + GETMISCPTR(vp1, lpMem16); + lpMemMeta16 = (LPMETAFILEPICT16)((PBYTE)lpMem16 + sizeof(DDEPOKE) - 1); + STOREWORD(lpMemMeta16->hMF, hMF16); + GlobalUnlock(hMeta32); + } + + } + else { + if (hMeta32) { + lpMemMeta32 = GlobalLock(hMeta32); + FREEMISCPTR(lpMem16); + vp2 = GlobalAllocLock16(GMEM_DDESHARE, sizeof(METAFILEPICT16), &hMeta16); + WOW32ASSERT(vp2); + if (vp2) { + GETMISCPTR(vp2, lpMemMeta16); + FixMetafile32To16 (lpMemMeta32, lpMemMeta16); + FREEMISCPTR(lpMemMeta16); + + pDdeInfo->Format = lpMem32->cfFormat; + pDdeInfo->Flags = 0; + pDdeInfo->h16 = 0; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMeta16, hMeta32, pDdeInfo); + hMF32 = lpMemMeta32->hMF; + if (hMF32) { + hMF16 = WinMetaFileFromHMF(hMF32, FALSE); + pDdeInfo->Flags = DDE_METAFILE; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo); + } + + GETMISCPTR(vp2, lpMemMeta16); + STOREWORD(lpMemMeta16->hMF, hMF16); + GlobalUnlock16(hMeta16); + FLUSHVDMPTR(vp2, 8, lpMemMeta16); + FREEMISCPTR(lpMemMeta16); + } + GlobalUnlock(hMeta32); + } + GETMISCPTR(vp1, lpMem16); + STOREWORD(lpMem16->Value, hMeta16); + } + + GlobalUnlock16(h16); + FLUSHVDMPTR(vp1, cb, lpMem16); + FREEMISCPTR(lpMem16); + } + } + break; + } + + GlobalUnlock(h32); + + return (h16); +} + + + + +// This routine converts a 16 bit DDE memory object into a 32 bit DDE +// memory object. It also, does the data conversion from 16 bit to 32 bit +// for the type of data. +// + +HANDLE DDECopyhData32(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 h16, PDDEINFO pDdeInfo) +{ + HANDLE h32 = NULL; + INT cb; + VPVOID vp; + DDEDATA *lpMem16; + DDEDATA32 *lpMem32; + + // + // AmiPro passes a NULL handle. + // + + if (!h16) { + LOGDEBUG(12, ("WOW::DDECopyhData16(): h16 is %04x\n", h16)); + return (HANDLE) NULL; + } + + vp = GlobalLock16(h16, &cb); + GETMISCPTR(vp, lpMem16); + LOGDEBUG(12, ("WOW::DDECopyhData32(): CF_FORMAT is %04x\n", lpMem16->cfFormat)); + + switch(lpMem16->cfFormat) { + + default: + + // This is intentional to let it thru to the "case statements". + // ChandanC 5/11/92. + + case CF_TEXT: + case CF_DSPTEXT: + case CF_SYLK: + case CF_DIF: + case CF_TIFF: + case CF_OEMTEXT: + case CF_PENDATA: + case CF_RIFF: + case CF_WAVE: + case CF_OWNERDISPLAY: + h32 = Copyh16Toh32 (cb, (LPBYTE) lpMem16); + + pDdeInfo->Format = lpMem16->cfFormat; + break; + + case CF_BITMAP: + case CF_DSPBITMAP: + h32 = GlobalAlloc(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE))); + if (h32) { + pDdeInfo->Format = lpMem16->cfFormat; + lpMem32 = GlobalLock(h32); + RtlCopyMemory(lpMem32, lpMem16, 4); + lpMem32->Value = HBITMAP32(FETCHWORD(*((WORD *)lpMem16->Value))); + GlobalUnlock(h32); + } + break; + + case CF_PALETTE: + h32 = GlobalAlloc(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE))); + if (h32) { + pDdeInfo->Format = lpMem16->cfFormat; + lpMem32 = GlobalLock(h32); + RtlCopyMemory(lpMem32, lpMem16, 4); + lpMem32->Value = HPALETTE32(FETCHWORD(*((WORD *)lpMem16->Value))); + GlobalUnlock(h32); + } + break; + + case CF_DIB: + { + LPBYTE lpMemDib16; + HAND16 hDib16; + HANDLE hDib32 = NULL; + + h32 = GlobalAlloc(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE))); + if (h32) { + lpMem32 = GlobalLock(h32); + RtlCopyMemory(lpMem32, lpMem16, 4); + + hDib16 = FETCHWORD(*((WORD *)lpMem16->Value)); + if (hDib16) { + vp = GlobalLock16(hDib16, &cb); + GETMISCPTR(vp, lpMemDib16); + hDib32 = Copyh16Toh32 (cb, (LPBYTE) lpMemDib16); + + pDdeInfo->Format = lpMem16->cfFormat; + pDdeInfo->Flags = 0; + pDdeInfo->h16 = 0; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hDib16, hDib32, pDdeInfo); + + GlobalUnlock16(hDib16); + FREEMISCPTR(lpMemDib16); + } + lpMem32->Value = hDib32; + GlobalUnlock(h32); + } + } + break; + + case CF_METAFILEPICT: + case CF_DSPMETAFILEPICT: + { + HANDLE hMeta32 = NULL, hMF32 = NULL; + HAND16 hMeta16, hMF16 = 0; + LPMETAFILEPICT lpMemMeta32; + LPMETAFILEPICT16 lpMemMeta16; + + h32 = GlobalAlloc(GMEM_DDESHARE, (sizeof(DDEDATA)-1+sizeof(HANDLE))); + if (h32) { + lpMem32 = GlobalLock(h32); + RtlCopyMemory(lpMem32, lpMem16, 4); + + // + // MSDRAW has the METAFILEPICT in the DDEPOKE block instead of + // a handle to the METAFILEPICT. So we need to find out if the + // to handle belongs to MSDRAW. Since MSDRAW is a 16 bit + // server we needn't thunk the metafilepict at all, we will just + // use NULL as the 32 bit handle to the metafilepict. + // + + hMeta32 = NULL; + if( !((pDdeInfo->Msg == WM_DDE_POKE) && DDEIsTargetMSDraw(To_hwnd)) ) { + + hMeta16 = FETCHWORD(*((WORD *)lpMem16->Value)); + + // + // Make sure that a valid metafile pict handle has been + // passed in otherwise use NULL again as the hMeta32. + // + + if (hMeta16 && (vp = GlobalLock16(hMeta16, &cb))) { + GETMISCPTR(vp, lpMemMeta16); + hMeta32 = GlobalAlloc(GMEM_DDESHARE, sizeof(METAFILEPICT)); + WOW32ASSERT(hMeta32); + if (hMeta32) { + lpMemMeta32 = GlobalLock(hMeta32); + lpMemMeta32->mm = (LONG) FETCHSHORT(lpMemMeta16->mm); + lpMemMeta32->xExt = (LONG) FETCHSHORT(lpMemMeta16->xExt); + lpMemMeta32->yExt = (LONG) FETCHSHORT(lpMemMeta16->yExt); + pDdeInfo->Format = lpMem16->cfFormat; + pDdeInfo->Flags = 0; + pDdeInfo->h16 = 0; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMeta16, hMeta32, pDdeInfo); + + hMF16 = FETCHWORD(lpMemMeta16->hMF); + + if (hMF16) { + hMF32 = (HMETAFILE) HMFFromWinMetaFile(hMF16, FALSE); + pDdeInfo->Flags = DDE_METAFILE; + DDEAddhandle(To_hwnd, From_hwnd, (HAND16) hMF16, hMF32, pDdeInfo); + } + + lpMemMeta32->hMF = (HMETAFILE) hMF32; + GlobalUnlock(hMeta32); + } + GlobalUnlock16(hMeta16); + FREEMISCPTR(lpMemMeta16); + } + } + lpMem32->Value = hMeta32; + GlobalUnlock(h32); + } + } + break; + } + + GlobalUnlock16(h16); + + FREEMISCPTR(lpMem16); + return (h32); +} + + +/****** These routines maintain a linked list of dde handles, which +******* are the h16 and h32 pairs. +******/ + + + +// This routine adds the given h16-h32 pair to the linked list, and updates +// the list. +// + +BOOL DDEAddhandle(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 hMem16, HANDLE hMem32, PDDEINFO pDdeInfo) +{ + PHDDE phTemp; + + if (hMem16 && hMem32) { + if (phTemp = malloc_w (sizeof(HDDE))) { + phTemp->hMem16 = hMem16; + phTemp->hMem32 = hMem32; + phTemp->To_hwnd = To_hwnd; + phTemp->From_hwnd = From_hwnd; + + phTemp->DdeMsg = pDdeInfo->Msg; + phTemp->DdeFormat = pDdeInfo->Format; + phTemp->DdeFlags = pDdeInfo->Flags; + + phTemp->h16 = pDdeInfo->h16; + + phTemp->pDDENext = phDDEFirst; // insert at the top + phDDEFirst = phTemp; // update list head + + // Mark the GAH_WOWDDEFREEHANDLE (ie GAH_PAHTOM) bit in the global + // arena of this handle. + + W32MarkDDEHandle (hMem16); + + return (TRUE); + } + else { + LOGDEBUG(2, ("WOW::DDEAddhandle(): *** memory allocation failed *** \n")); + return (FALSE); + } + } + + LOGDEBUG(2,("WOW::DDEAddhandle(): *** ERROR *** one of the handles is NULL \n")); + return (FALSE); +} + + +// This routine deletes the given h16-h32 pair from the list and frees up +// the memory. +// + +BOOL DDEDeletehandle(HAND16 h16, HANDLE h32) +{ + PHDDE phTemp1, phTemp2; + + phTemp1 = phDDEFirst; + + if ((phTemp1->hMem16 == h16) && (phTemp1->hMem32 == h32)) { // first node + phDDEFirst = phTemp1->pDDENext; + free_w(phTemp1); + return (TRUE); + } + else { // rest of the list + phTemp2 = phTemp1; + phTemp1 = phTemp1->pDDENext; + + while (phTemp1) { + if ((phTemp1->hMem16 == h16) && (phTemp1->hMem32 == h32)) { + phTemp2->pDDENext = phTemp1->pDDENext; + free_w(phTemp1); + return (TRUE); + } + phTemp2 = phTemp1; + phTemp1 = phTemp1->pDDENext; + } + + LOGDEBUG (2, ("WOW::DDEDeleteHandle : Can't find a 16-32 memory pair\n")); +// WOW32ASSERT (FALSE); + + return (FALSE); + } +} + + +// This routine finds a hMem16 for a DDE conversation, if one exists. +// + +HAND16 DDEFindPair16(HAND16 To_hwnd, HAND16 From_hwnd, HANDLE hMem32) +{ + PHDDE phTemp; + + phTemp = phDDEFirst; + + while (phTemp) { + if ((phTemp->To_hwnd == To_hwnd) && + (phTemp->From_hwnd == From_hwnd) && + (phTemp->hMem32 == hMem32)) { + return (phTemp->hMem16); + } + else { + phTemp = phTemp->pDDENext; + } + } + return (HAND16) NULL; +} + + +// This routine finds a hMem32 for a DDE conversation, if one exists. +// + +HANDLE DDEFindPair32(HAND16 To_hwnd, HAND16 From_hwnd, HAND16 hMem16) +{ + PHDDE phTemp; + + phTemp = phDDEFirst; + + while (phTemp) { + if ((phTemp->To_hwnd == To_hwnd) && + (phTemp->From_hwnd == From_hwnd) && + (phTemp->hMem16 == hMem16)) { + return (phTemp->hMem32); + } + else { + phTemp = phTemp->pDDENext; + } + } + return (HANDLE) NULL; +} + + +// This routine find the DDE node that is doing DDE conversation +// + +PHDDE DDEFindNode16 (HAND16 h16) +{ + PHDDE phTemp; + + phTemp = phDDEFirst; + + while (phTemp) { + if (phTemp->hMem16 == h16) { + return (phTemp); + } + phTemp = phTemp->pDDENext; + } + + return (NULL); +} + + +// This routine find the DDE node that is doing DDE conversation +// + +PHDDE DDEFindNode32 (HANDLE h32) +{ + PHDDE phTemp; + + phTemp = phDDEFirst; + + while (phTemp) { + if (phTemp->hMem32 == h32) { + return (phTemp); + } + phTemp = phTemp->pDDENext; + } + + return (NULL); +} + + +// This routine returns a pointer to the DDE node, if the conversation exists, +// else it retunrs NULL + +PHDDE DDEFindAckNode (HAND16 To_hwnd, HAND16 From_hwnd, HANDLE hMem32) +{ + PHDDE phTemp; + + phTemp = phDDEFirst; + + while (phTemp) { + if ((phTemp->To_hwnd == To_hwnd) && + (phTemp->From_hwnd == From_hwnd) && + (phTemp->hMem32 == hMem32)) { + return (phTemp); + } + else { + phTemp = phTemp->pDDENext; + } + } + return (PHDDE) NULL; +} + + +// This function marks GAH_WOWDDEFREEHANDLE bit in the global arena of the +// hMem16. +// + +VOID W32MarkDDEHandle (HAND16 hMem16) +{ + PARM16 Parm16; + VPVOID vp = 0; + + Parm16.WndProc.wParam = hMem16; + Parm16.WndProc.wMsg = 1; + CallBack16(RET_WOWDDEFREEHANDLE, &Parm16, 0, &vp); +} + +VOID W32UnMarkDDEHandle (HAND16 hMem16) +{ + PARM16 Parm16; + VPVOID vp = 0; + + Parm16.WndProc.wParam = hMem16; + Parm16.WndProc.wMsg = 0; + CallBack16(RET_WOWDDEFREEHANDLE, &Parm16, 0, &vp); +} + +// This function frees the 32 and 16 bit memory. It is called by 32 bit +// BASE by GlobalFree. +// + +BOOL W32DDEFreeGlobalMem32 (HANDLE h32) +{ + HAND16 h16; + PHDDE pDdeNode; + BOOL fOkToFree = TRUE; + + if (h32) { + if (pDdeNode = DDEFindNode32(h32)) { + + if (pDdeNode->DdeFlags & DDE_METAFILE) { + LOGDEBUG (12, ("WOW32: W32DDEFreeGlobalMem32: Freeing MetaFile hMF32 %x\n", h32)); + DeleteMetaFile (h32); + fOkToFree = FALSE; + } + + while ((pDdeNode) && (h16 = pDdeNode->hMem16)) { + W32UnMarkDDEHandle (h16); + GlobalUnlockFree16(GlobalLock16(h16, NULL)); + DDEDeletehandle(h16, h32); + pDdeNode = DDEFindNode32(h32); + } + } + else { + + LOGDEBUG (2, ("WOW32: W32DDEFreeGlobalMem32: Can't find a 16-32 memory pair\n")); + } + } + else { + WOW32ASSERTMSG(FALSE, "WOW32: W32DDEFreeGlobalMem32: h32 is NULL to Win32 GlobalFree\n"); + /* + * since in this case the Failure and Success return values from + * GlobalFree are NULL, just return false so things are faster + * in GlobalFree. + */ + fOkToFree = FALSE; + } + + return(fOkToFree); +} + + +// This function frees only the 32 bit memory because the 16 bit memory +// is being free'd by the 16 bit app. We are just getting the +// notification of this fact. So free the corresponding 32 bit memory. +// + +BOOL FASTCALL W32WowDdeFreeHandle (PVDMFRAME pFrame) +{ + ULONG ul; + HAND16 h16; + PWOWDDEFREEHANDLE16 parg16; + + GETARGPTR(pFrame, sizeof(WOWDDEFREEHANDLE16), parg16); + + h16 = (HAND16) parg16->h16; + + ul = W32DdeFreeHandle16 (h16); + + FREEARGPTR(parg16); + RETURN (ul); +} + + +BOOL W32DdeFreeHandle16 (HAND16 h16) +{ + HANDLE h32; + PHDDE pDdeNode; + + if (!(pDdeNode = DDEFindNode16(h16))) { + LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Not found h16 -> %04x\n", h16)); + return (TRUE); + } + + LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Entering... h16 -> %04x\n", h16)); + + if (pDdeNode->DdeMsg == WM_DDE_EXECUTE) { + LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : App TRYING !!! to freeing EXECUTE h16 -> %04x\n", h16)); + pDdeNode->DdeFlags = pDdeNode->DdeFlags | DDE_EXECUTE_FREE_MEM; + return (FALSE); + } + else { + while ((pDdeNode) && (h32 = pDdeNode->hMem32)) { + if (pDdeNode->DdeFlags & DDE_METAFILE) { + DDEDeletehandle(h16, h32); + DeleteMetaFile (h32); + } + else { + /* + * REMOVE THE PAIR FIRST!!! + * Since GlobalFree will hook back to W32DDEFreeGlobalMem32 + * we want to remove the handle from our tables before + * the call. + */ + DDEDeletehandle(h16, h32); + GlobalFree(h32); + } + + pDdeNode = DDEFindNode16(h16); + } + } + + LOGDEBUG (12, ("WOW::W32DdeFreeHandle16 : Leaving ...\n")); + return (TRUE); +} + + +// This routine adds the given h16-h32 CopyData pair to the linked list, +// and updates the list. +// + +BOOL CopyDataAddNode (HAND16 To_hwnd, HAND16 From_hwnd, DWORD Mem16, DWORD Mem32, DWORD Flags) +{ + PCPDATA pTemp; + + if (Mem16 && Mem32) { + if (pTemp = malloc_w (sizeof(CPDATA))) { + pTemp->Mem16 = Mem16; + pTemp->Mem32 = Mem32; + pTemp->To_hwnd = To_hwnd; + pTemp->From_hwnd= From_hwnd; + pTemp->Flags = Flags; + pTemp->Next = pCPDataFirst; // insert at the top + pCPDataFirst = pTemp; // update list head + + return (TRUE); + } + else { + LOGDEBUG(2, ("WOW::CopyDataAddNode: *** memory allocation failed *** \n")); + return (FALSE); + } + } + + LOGDEBUG(2,("WOW::CopyDataAddNode: *** ERROR *** one of the memory pointers is NULL \n")); + return (FALSE); +} + + +VPVOID CopyDataFindData16 (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem) +{ + PCPDATA pTemp; + + pTemp = pCPDataFirst; + + while (pTemp) { + if ((pTemp->To_hwnd == To_hwnd) && + (pTemp->From_hwnd == From_hwnd) && + (pTemp->Mem32 == Mem)) { + return (pTemp->Mem16); + } + else { + pTemp = pTemp->Next; + } + } + return 0; +} + + +PCPDATA CopyDataFindData32 (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem) +{ + PCPDATA pTemp; + + pTemp = pCPDataFirst; + + while (pTemp) { + if ((pTemp->To_hwnd == To_hwnd) && + (pTemp->From_hwnd == From_hwnd) && + (pTemp->Mem16 == Mem)) { + return (pTemp); + } + else { + pTemp = pTemp->Next; + } + } + return 0; +} + + +// This routine deletes the given h16-h32 pair from the list. +// +// + +BOOL CopyDataDeleteNode (HWND16 To_hwnd, HWND16 From_hwnd, DWORD Mem) +{ + PCPDATA pTemp1; + PCPDATA pTemp2; + + pTemp1 = pCPDataFirst; + + if ((pTemp1->To_hwnd == To_hwnd) && + (pTemp1->From_hwnd == From_hwnd) && + (pTemp1->Mem32 == Mem)) { + pCPDataFirst = pTemp1->Next; + free_w (pTemp1); + return (TRUE); + } + else { + pTemp2 = pTemp1; + pTemp1 = pTemp1->Next; + + while (pTemp1) { + if ((pTemp1->To_hwnd == To_hwnd) && + (pTemp1->From_hwnd == From_hwnd) && + (pTemp1->Mem32 == Mem)) { + pTemp2->Next = pTemp1->Next; + free_w (pTemp1); + return (TRUE); + } + + pTemp2 = pTemp1; + pTemp1 = pTemp1->Next; + } + return (FALSE); + } + +} + + +// While allocating GMEM_DDESHARE memory object should we have GMEM_MOVEABLE +// flag or not ??????????????????? +// ChandanC Sept 23rd 1993. +// +// WARNING: This function may cause 16-bit memory movement. +// + +HAND16 Copyh32Toh16 (int cb, LPBYTE lpMem32) +{ + HAND16 h16 = 0; + LPBYTE lpMem16; + VPVOID vp; + + vp = GlobalAllocLock16(GMEM_DDESHARE | GMEM_MOVEABLE, cb, &h16); + WOW32ASSERT(vp); + if (vp) { + GETMISCPTR(vp, lpMem16); + RtlCopyMemory(lpMem16, lpMem32, cb); + GlobalUnlock16(h16); + FLUSHVDMPTR(vp, cb, lpMem16); + FREEMISCPTR(lpMem16); + } + + return (h16); +} + + +HANDLE Copyh16Toh32 (int cb, LPBYTE lpMem16) +{ + HANDLE hMem32; + LPBYTE lpMem32; + + hMem32 = GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, cb); + WOW32ASSERT(hMem32); + if (hMem32) { + lpMem32 = GlobalLock(hMem32); + RtlCopyMemory (lpMem32, lpMem16, cb); + GlobalUnlock(hMem32); + } + + return (hMem32); +} + + +VOID FixMetafile32To16 (LPMETAFILEPICT lpMemMeta32, LPMETAFILEPICT16 lpMemMeta16) +{ + + if (lpMemMeta32->mm == MM_ANISOTROPIC) { + LONG xExt = lpMemMeta32->xExt; + LONG yExt = lpMemMeta32->yExt; + + while (xExt < (LONG)(SHORT)MINSHORT + || xExt > (LONG)(SHORT)MAXSHORT + || yExt < (LONG)(SHORT)MINSHORT + || yExt > (LONG)(SHORT)MAXSHORT) { + xExt = xExt / 2; + yExt = yExt / 2; + } + STORESHORT(lpMemMeta16->mm, MM_ANISOTROPIC); + STORESHORT(lpMemMeta16->xExt, xExt); + STORESHORT(lpMemMeta16->yExt, yExt); + } + else { + STORESHORT(lpMemMeta16->mm, lpMemMeta32->mm); + STORESHORT(lpMemMeta16->xExt, lpMemMeta32->xExt); + STORESHORT(lpMemMeta16->yExt, lpMemMeta32->yExt); + } +} + +// +// CHEESE ALERT: This function is exported for the OLE DDE code +// to call so it can correctly free up metafile handle pairs in +// a VDM. This function is NOT found in any header files. If you +// change this, you need to find its use in the OLE project. +// Probably best to just leave it alone. +// +BOOL WINAPI WOWFreeMetafile( HANDLE h32 ) +{ + return( W32DDEFreeGlobalMem32( h32 ) ); +} |