diff options
Diffstat (limited to 'private/mvdm/wow16/ole')
42 files changed, 23109 insertions, 0 deletions
diff --git a/private/mvdm/wow16/ole/client/amabaabo b/private/mvdm/wow16/ole/client/amabaabo new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/private/mvdm/wow16/ole/client/amabaabo diff --git a/private/mvdm/wow16/ole/client/amabaace b/private/mvdm/wow16/ole/client/amabaace new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/private/mvdm/wow16/ole/client/amabaace diff --git a/private/mvdm/wow16/ole/client/bm.c b/private/mvdm/wow16/ole/client/bm.c new file mode 100644 index 000000000..8753086d4 --- /dev/null +++ b/private/mvdm/wow16/ole/client/bm.c @@ -0,0 +1,605 @@ +/****************************** Module Header ******************************\ +* Module Name: BM.C +* +* Handles all API routines for the bitmap sub-dll of the ole dll. +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor,Srinik (../../1990,91) Designed, coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" +#include "pict.h" + +extern int maxPixelsX, maxPixelsY; +void INTERNAL GetHimetricUnits(HBITMAP, LPPOINT); + +#pragma alloc_text(_TEXT, BmSaveToStream, BmStreamWrite, BmLoadFromStream, BmStreamRead, GetBytes, PutBytes, PutStrWithLen, BmQueryBounds, BmChangeData, BmCopy, BmDuplicate, BmUpdateStruct, GetHimetricUnits) + + +OLEOBJECTVTBL vtblBM = { + + ErrQueryProtocol, // check whether the speced protocol is supported + + BmRelease, // Release + ErrShow, // Show + ErrPlay, // play + BmGetData, // Get the object data + ErrSetData, // Set the object data + ErrSetTargetDevice,// + + ErrSetBounds, // set viewport bounds + BmEnumFormat, // enumerate supported formats + ErrSetColorScheme, // + BmRelease, // delete + ErrSetHostNames, // + + BmSaveToStream, // write to file + BmClone, // clone object + ErrCopyFromLink, // Create embedded from Link + + BmEqual, // compares the given objects for data equality + + BmCopy, // copy to clip + + BmDraw, // draw the object + + ErrActivate, // open + ErrExecute, // excute + ErrClose, // Stop + ErrUpdate, // Update + ErrReconnect, // Reconnect + + ErrObjectConvert, // convert object to specified type + + ErrGetUpdateOptions,// update options + ErrSetUpdateOptions,// update options + + ObjRename, // Change Object name + ObjQueryName, // Get current object name + + ObjQueryType, // Object type + BmQueryBounds, // QueryBounds + ObjQuerySize, // Find the size of the object + ErrQueryOpen, // Query open + ErrQueryOutOfDate, // query whether object is current + + ErrQueryRelease, // release related stuff + ErrQueryRelease, + ErrQueryRelease, + + ErrRequestData, // requestdata + ErrObjectLong, // objectLong + BmChangeData // change data of the existing object +}; + + + +OLESTATUS FARINTERNAL BmRelease (lpobj) +LPOBJECT_BM lpobj; +{ + HOBJECT hobj; + + if (lpobj->hBitmap) { + DeleteObject (lpobj->hBitmap); + lpobj->hBitmap = NULL; + } + + if (lpobj->head.lhclientdoc) + DocDeleteObject ((LPOLEOBJECT) lpobj); + + if (hobj = lpobj->head.hobj){ + lpobj->head.hobj = NULL; + GlobalUnlock (hobj); + GlobalFree (hobj); + } + + return OLE_OK; +} + + + +OLESTATUS FARINTERNAL BmSaveToStream (lpobj, lpstream) +LPOBJECT_BM lpobj; +LPOLESTREAM lpstream; +{ + if (!lpobj->hBitmap || !lpobj->sizeBytes) + return OLE_ERROR_BLANK; + + if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutStrWithLen(lpstream, (LPSTR)"BITMAP")) + return OLE_ERROR_STREAM; + + if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) { + if (!PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) + if (!PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD))) + return BmStreamWrite (lpstream, lpobj); + } + return OLE_ERROR_STREAM; +} + + +OLESTATUS FARINTERNAL BmClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_BM lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_BM FAR * lplpobj; +{ + if (!CheckClientDoc ((LPCLIENTDOC)lhclientdoc)) + return OLE_ERROR_HANDLE; + + if (!(*lplpobj = BmCreateObject (lpobjsrc->hBitmap, lpclient, FALSE, + lhclientdoc, lpobjname, lpobjsrc->head.ctype))) + return OLE_ERROR_MEMORY; + else + return OLE_OK; +} + + +OLESTATUS FARINTERNAL BmEqual (lpobj1, lpobj2) +LPOBJECT_BM lpobj1; +LPOBJECT_BM lpobj2; +{ + HANDLE hBits1 = NULL, hBits2 = NULL; + LPSTR lpBits1 = NULL, lpBits2 = NULL; + OLESTATUS retVal; + DWORD dwBytes1, dwBytes2; + + if (lpobj1->sizeBytes != lpobj2->sizeBytes) + return OLE_ERROR_NOT_EQUAL; + + retVal = OLE_ERROR_MEMORY; + + if (!(hBits1 = GlobalAlloc (GMEM_MOVEABLE, lpobj1->sizeBytes))) + goto errEqual; + + if (!(lpBits1 = GlobalLock (hBits1))) + goto errEqual; + + if (!(hBits2 = GlobalAlloc (GMEM_MOVEABLE, lpobj2->sizeBytes))) + goto errEqual; + + if (!(lpBits2 = GlobalLock (hBits2))) + goto errEqual; + + dwBytes1 = GetBitmapBits (lpobj1->hBitmap, lpobj1->sizeBytes, lpBits1); + dwBytes2 = GetBitmapBits (lpobj2->hBitmap, lpobj2->sizeBytes, lpBits2); + + if (dwBytes1 != dwBytes2) { + retVal = OLE_ERROR_NOT_EQUAL; + goto errEqual; + } + + // !!! UtilMemCmp has to be redone for >64k bitmaps + if (UtilMemCmp (lpBits1, lpBits2, dwBytes1)) + retVal = OLE_ERROR_NOT_EQUAL; + else + retVal = OLE_OK; + +errEqual: + if (lpBits1) + GlobalUnlock (hBits1); + + if (lpBits2) + GlobalUnlock (hBits2); + + if (hBits1) + GlobalFree (hBits1); + + if (hBits2) + GlobalFree (hBits2); + + return retVal; +} + + + +OLESTATUS FARINTERNAL BmCopy (lpobj) +LPOBJECT_BM lpobj; +{ + HBITMAP hBitmap; + DWORD size; + + if (!lpobj->hBitmap) + return OLE_ERROR_BLANK; + + if(!(hBitmap = BmDuplicate (lpobj->hBitmap, &size, NULL))) + return OLE_ERROR_MEMORY; + + SetClipboardData(CF_BITMAP, hBitmap); + return OLE_OK; +} + + +OLESTATUS FARINTERNAL BmQueryBounds (lpobj, lpRc) +LPOBJECT_BM lpobj; +LPRECT lpRc; +{ + Puts("BmQueryBounds"); + + if (!lpobj->hBitmap) + return OLE_ERROR_BLANK; + + lpRc->left = 0; + lpRc->top = 0; + lpRc->right = (int) lpobj->head.cx; + lpRc->bottom = (int) lpobj->head.cy; + return OLE_OK; +} + + + +OLECLIPFORMAT FARINTERNAL BmEnumFormat (lpobj, cfFormat) +LPOBJECT_BM lpobj; +OLECLIPFORMAT cfFormat; +{ + if (!cfFormat) + return CF_BITMAP; + + return NULL; +} + + + +OLESTATUS FARINTERNAL BmGetData (lpobj, cfFormat, lphandle) +LPOBJECT_BM lpobj; +OLECLIPFORMAT cfFormat; +LPHANDLE lphandle; +{ + if (cfFormat != CF_BITMAP) + return OLE_ERROR_FORMAT; + + if (!(*lphandle = lpobj->hBitmap)) + return OLE_ERROR_BLANK; + return OLE_OK; + +} + + + + +OLESTATUS FARINTERNAL BmLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) +LPOLESTREAM lpstream; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +LONG objType; +{ + LPOBJECT_BM lpobj = NULL; + + *lplpoleobject = NULL; + + if (!(lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType))) + return OLE_ERROR_MEMORY; + + lpobj->head.lpclient = lpclient; + + if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) { + if (!GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) + if (!GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD))) + if (BmStreamRead (lpstream, lpobj)) { + *lplpoleobject = (LPOLEOBJECT)lpobj; + return OLE_OK; + } + } + + OleDelete ((LPOLEOBJECT)lpobj); + return OLE_ERROR_STREAM;; +} + + + +OLESTATUS INTERNAL BmStreamWrite (lpstream, lpobj) +LPOLESTREAM lpstream; +LPOBJECT_BM lpobj; +{ + HANDLE hBits; + LPSTR lpBits; + int retVal = OLE_ERROR_STREAM; + BITMAP bm; + DWORD dwSize; // size of bit array + + dwSize = lpobj->sizeBytes - sizeof(BITMAP); + + if (hBits = GlobalAlloc (GMEM_MOVEABLE, dwSize)) { + if (lpBits = (LPSTR) GlobalLock (hBits)) { + if (GetBitmapBits (lpobj->hBitmap, dwSize, lpBits)) { + GetObject (lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm); + if (!PutBytes (lpstream, (LPSTR) &bm, sizeof(BITMAP))) + if (!PutBytes (lpstream, (LPSTR) lpBits, dwSize)) + retVal = OLE_OK; + } + GlobalUnlock(hBits); + } else + retVal = OLE_ERROR_MEMORY; + GlobalFree(hBits); + } else + retVal = OLE_ERROR_MEMORY; + + return retVal; +} + + + +BOOL INTERNAL BmStreamRead (lpstream, lpobj) +LPOLESTREAM lpstream; +LPOBJECT_BM lpobj; +{ + HANDLE hBits; + LPSTR lpBits; + BOOL retVal = FALSE; + BITMAP bm; + POINT point; + + if (GetBytes (lpstream, (LPSTR)&bm, sizeof(BITMAP))) + return FALSE; + + lpobj->sizeBytes = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * + ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel); + + if (hBits = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)) { + if (lpBits = (LPSTR) GlobalLock (hBits)) { + if (!GetBytes(lpstream, lpBits, lpobj->sizeBytes)) { + if (lpobj->hBitmap = CreateBitmap (bm.bmWidth, + bm.bmHeight, + bm.bmPlanes, + bm.bmBitsPixel, + lpBits)) { + retVal = TRUE; + lpobj->xSize = point.x = bm.bmWidth; + lpobj->ySize = point.y = bm.bmHeight; + + // size of (bitmap header + bits) + lpobj->sizeBytes += sizeof(BITMAP); +#ifdef OLD + // !!! We shouldn't do the conversion. The info should be + // part of the stream. + if (!lpobj->head.cx) { + ConvertToHimetric (&point); + lpobj->head.cx = (LONG) point.x; + lpobj->head.cy = (LONG) point.y; + } +#endif + } + } + GlobalUnlock(hBits); + } + GlobalFree(hBits); + } + return retVal; +} + + +OLESTATUS FARINTERNAL BmPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +LONG objType; +{ + HBITMAP hBitmap; + + *lplpoleobject = NULL; + + if ((hBitmap = (HBITMAP) GetClipboardData(CF_BITMAP)) == NULL) + return OLE_ERROR_MEMORY; + + if (!(*lplpoleobject = (LPOLEOBJECT) BmCreateObject (hBitmap, + lpclient, FALSE, lhclientdoc, + lpobjname, objType))) + return OLE_ERROR_MEMORY; + + return OLE_OK; + +} + + +LPOBJECT_BM INTERNAL BmCreateObject (hBitmap, lpclient, fDelete, lhclientdoc, lpobjname, objType) +HBITMAP hBitmap; +LPOLECLIENT lpclient; +BOOL fDelete; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + LPOBJECT_BM lpobj; + + if (lpobj = BmCreateBlank (lhclientdoc, lpobjname, objType)) { + if (BmChangeData (lpobj, hBitmap, lpclient, fDelete) != OLE_OK) { + BmRelease (lpobj); + lpobj = NULL; + } + } + + return lpobj; +} + + +// If the routine fails then the object will be left with it's old data. +// If fDelete is TRUE, then hNewBitmap will be deleted whether the routine +// is successful or not. + +OLESTATUS FARINTERNAL BmChangeData (lpobj, hNewBitmap, lpclient, fDelete) +LPOBJECT_BM lpobj; +HBITMAP hNewBitmap; +LPOLECLIENT lpclient; +BOOL fDelete; +{ + BITMAP bm; + DWORD dwSize; + HBITMAP hOldBitmap; + + hOldBitmap = lpobj->hBitmap; + + if (!fDelete) { + if (!(hNewBitmap = BmDuplicate (hNewBitmap, &dwSize, &bm))) + return OLE_ERROR_MEMORY; + } + else { + if (!GetObject (hNewBitmap, sizeof(BITMAP), (LPSTR) &bm)) { + DeleteObject (hNewBitmap); + return OLE_ERROR_MEMORY; + } + + dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * + ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel); + } + + BmUpdateStruct (lpobj, lpclient, hNewBitmap, &bm, dwSize); + if (hOldBitmap) + DeleteObject (hOldBitmap); + + return OLE_OK; +} + + +void INTERNAL BmUpdateStruct (lpobj, lpclient, hBitmap, lpBm, dwBytes) +LPOBJECT_BM lpobj; +LPOLECLIENT lpclient; +HBITMAP hBitmap; +LPBITMAP lpBm; +DWORD dwBytes; +{ + POINT point; + + lpobj->head.lpclient = lpclient; + lpobj->xSize = point.x = lpBm->bmWidth; + lpobj->ySize = point.y = lpBm->bmHeight; + GetHimetricUnits (hBitmap, &point); + lpobj->head.cx = (LONG) point.x; + lpobj->head.cy = (LONG) point.y; + lpobj->sizeBytes = dwBytes + sizeof(BITMAP); + lpobj->hBitmap = hBitmap; +} + + + +LPOBJECT_BM FARINTERNAL BmCreateBlank (lhclientdoc, lpobjname, objType) +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + HOBJECT hobj; + LPOBJECT_BM lpobj; + + if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_BM))) + == NULL) + return NULL; + + if (!(lpobj = (LPOBJECT_BM) GlobalLock (hobj))){ + GlobalFree (hobj); + return NULL; + } + + lpobj->head.objId[0] = 'L'; + lpobj->head.objId[1] = 'E'; + lpobj->head.mm = MM_TEXT; + lpobj->head.ctype = objType; + lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblBM; + lpobj->head.iTable = INVALID_INDEX; + lpobj->head.hobj = hobj; + + if (objType == CT_STATIC) + DocAddObject ((LPCLIENTDOC) lhclientdoc, + (LPOLEOBJECT) lpobj, lpobjname); + + return lpobj; +} + + + +HBITMAP FARINTERNAL BmDuplicate (hold, lpdwSize, lpBm) +HBITMAP hold; +DWORD FAR * lpdwSize; +LPBITMAP lpBm; +{ + HBITMAP hnew; + HANDLE hMem; + LPSTR lpMem; + LONG retVal = TRUE; + DWORD dwSize; + BITMAP bm; + DWORD dwExtents = NULL; + + // !!! another way to duplicate the bitmap + + GetObject (hold, sizeof(BITMAP), (LPSTR) &bm); + dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * + ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel); + + if (!(hMem = GlobalAlloc (GMEM_MOVEABLE, dwSize))) + return NULL; + + if (!(lpMem = GlobalLock (hMem))){ + GlobalFree (hMem); + return NULL; + } + + GetBitmapBits (hold, dwSize, lpMem); + if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight, + bm.bmPlanes, bm.bmBitsPixel, NULL)) + retVal = SetBitmapBits (hnew, dwSize, lpMem); + + GlobalUnlock (hMem); + GlobalFree (hMem); + + if (hnew && (!retVal)) { + DeleteObject (hnew); + hnew = NULL; + } + *lpdwSize = dwSize; + if (lpBm) + *lpBm = bm; + + if (dwExtents = GetBitmapDimension (hold)) + SetBitmapDimension (hnew, LOWORD(dwExtents), HIWORD(dwExtents)); + + return hnew; +} + + +void INTERNAL GetHimetricUnits(HBITMAP hBitmap, LPPOINT lpPoint) +{ + HDC hdc; + DWORD dwDim; + + if (dwDim = GetBitmapDimension (hBitmap)) { + lpPoint->x = 10 * LOWORD(dwDim); + lpPoint->y = - (10 * HIWORD(dwDim)); + return; + } + + // clip if it exceeds maxPixels. Note that we have a limitation of + // 0x8FFF HIMETRIC units in OLE1.0 + + if (lpPoint->x > maxPixelsX) + lpPoint->x = maxPixelsX; + + if (lpPoint->y > maxPixelsY) + lpPoint->y = maxPixelsY; + + if (hdc = GetDC (NULL)) { + lpPoint->x = MulDiv (lpPoint->x, 2540, + GetDeviceCaps (hdc, LOGPIXELSX)); + lpPoint->y = - MulDiv (lpPoint->y, 2540, + GetDeviceCaps (hdc, LOGPIXELSY)); + ReleaseDC (NULL, hdc); + } + else { + lpPoint->x = 0; + lpPoint->y = 0; + } +} + diff --git a/private/mvdm/wow16/ole/client/cmacs.h b/private/mvdm/wow16/ole/client/cmacs.h new file mode 100644 index 000000000..ca531d9f1 --- /dev/null +++ b/private/mvdm/wow16/ole/client/cmacs.h @@ -0,0 +1,61 @@ +/****************************** Module Header ******************************\ +* Module Name: CMACS.H +* +* This module contains common macros used by C routines. +* +* Created: 9-Feb-1989 +* +* Copyright (c) 1985 - 1989 Microsoft Corporation +* +* History: +* Created by Raor +* +\***************************************************************************/ + +#define _WINDOWS +#define DLL_USE + +#define INTERNAL PASCAL NEAR +#define FARINTERNAL PASCAL FAR + +#ifdef FIREWALLS +extern short ole_flags; + +#define DEBUG_PUTS 0x01 +#define DEBUG_DEBUG_OUT 0x02 +#define DEBUG_MESSAGEBOX 0x04 + +extern char szDebugBuffer[]; + +#define DEBUG_OUT(parm1,parm2){\ + if(ole_flags & DEBUG_DEBUG_OUT){\ + wsprintf(szDebugBuffer,parm1,parm2);\ + OutputDebugString(szDebugBuffer);\ + OutputDebugString ("^^^ ");\ + }\ + } + +#define ASSERT(x,y) {\ + if (!(x)) { \ + wsprintf (szDebugBuffer, "Assert Failure file %s, line %d\r\n ", \ + (LPSTR) __FILE__, __LINE__);\ + OutputDebugString (szDebugBuffer);\ + OutputDebugString ((LPSTR) (y));\ + OutputDebugString ("@@@ ");\ + } \ +} + +#define Puts(msg) {\ + if(ole_flags & DEBUG_PUTS){\ + OutputDebugString ((LPSTR)(msg));\ + OutputDebugString ("** ");\ + }\ + } + +#else + +#define DEBUG_OUT(err, val) ; +#define ASSERT(cond, msg) +#define Puts(msg) + +#endif /* FIREWALLS */ diff --git a/private/mvdm/wow16/ole/client/dde.c b/private/mvdm/wow16/ole/client/dde.c new file mode 100644 index 000000000..6559c3eac --- /dev/null +++ b/private/mvdm/wow16/ole/client/dde.c @@ -0,0 +1,1327 @@ + +/****************************** Module Header ******************************\ +* Module Name: DDE.C (Extensible Compound Documents -DDE) +* +* Copyright (c) 1985 - 1991 Microsoft Corporation +* +* PURPOSE: Handles all API routines for the dde sub-dll of the ole dll. +* +* History: +* Raor,Srinik (../../90,91) Designed and coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dde.h" +#include "dll.h" + +#define WIN32S + +/* #define GRAPHBUG */ + + +// ### may not need seperate wndproc for system topic! +HANDLE GetDDEDataHandle (DDEDATA FAR *, WORD, HANDLE); + +extern ATOM aSystem; +extern ATOM aOle; +extern HANDLE hInstDLL; + + +// DocWndProc: Window procedure used to document DDE conversations +long FAR PASCAL DocWndProc(hwnd, message, wParam, lParam) +HWND hwnd; +unsigned message; +WORD wParam; +LONG lParam; + +{ + PEDIT_DDE pedit = NULL; + LPOBJECT_LE lpobj = NULL; + + + + Puts("DocWndProc"); + + if (lpobj = (LPOBJECT_LE) GetWindowLong (hwnd, 0)) + pedit = lpobj->pDocEdit; + + switch (message){ + + case WM_DDE_ACK: +#ifdef FIREWALLS + ASSERT (pedit, "Doc conv channel missing"); +#endif + DEBUG_OUT ("WM_DDE_ACK ", 0); + if (pedit->bTerminating){ + // ### this error recovery may not be correct. + DEBUG_OUT ("No action due to termination process",0) + break; + } + + switch(pedit->awaitAck){ + + case AA_INITIATE: + HandleAckInitMsg (pedit, (HWND)wParam); + if (LOWORD(lParam)) + GlobalDeleteAtom (LOWORD(lParam)); + if (HIWORD(lParam)) + GlobalDeleteAtom (HIWORD(lParam)); + break; + + case AA_REQUEST: + case AA_UNADVISE: + case AA_EXECUTE: + case AA_ADVISE: + HandleAck (lpobj, pedit, lParam); + break; + + case AA_POKE: + + // freeing pokedata is done in handleack + HandleAck (lpobj, pedit, lParam); + break; + + default: + DEBUG_OUT ("received ACK We don't know how to handle ",0) + break; + + } // end of switch + break; + + case WM_TIMER: + HandleTimerMsg (lpobj, pedit); + break; + + case WM_DDE_DATA: +#ifdef FIREWALLS + ASSERT (pedit, "Doc conv channel missing"); +#endif + DEBUG_OUT ("WM_DDE_DATA",0); + HandleDataMsg (lpobj, LOWORD(lParam), HIWORD(lParam)); + break; + + case WM_DDE_TERMINATE: + +#ifdef FIREWALLS + ASSERT (pedit, "Doc conv channel missing"); +#endif + DEBUG_OUT ("WM_DDE_TERMINATE",0); + HandleTermMsg (lpobj, pedit, (HWND)wParam, TRUE); + break; + + case WM_DESTROY: + +#ifdef FIREWALLS + ASSERT (pedit, "Doc conv channel missing"); +#endif + DEBUG_OUT ("Client window being destroyed", 0) + pedit->hClient = NULL; + break; + + default: + return DefWindowProc (hwnd, message, wParam, lParam); + + } + return 0L; +} + + + +// SrvrWndProc: Window Procedure for System Topic DDE conversations +// wndproc for system topic + +long FAR PASCAL SrvrWndProc(hwnd, message, wParam, lParam) +HWND hwnd; +unsigned message; +WORD wParam; +LONG lParam; + +{ + PEDIT_DDE pedit = NULL; + LPOBJECT_LE lpobj = NULL; + + Puts("SysWndProc"); + + if (lpobj = (LPOBJECT_LE) GetWindowLong (hwnd, 0)) + pedit = lpobj->pSysEdit; + + switch (message){ + + case WM_DDE_ACK: + +#ifdef FIREWALLS + ASSERT (pedit, "sys conv edit block missing"); +#endif + + DEBUG_OUT ("SYS: WM_DDE_ACK",0); + + if(pedit->bTerminating){ + //### Error recovery may not be OK. + DEBUG_OUT ("No action due to termination process",0) + break; + } + + switch (pedit->awaitAck) { + + + case AA_INITIATE: + +#ifdef HISTORY + if (GetWindowWord ((HWND)wParam, GWW_HINSTANCE) == pedit->hInst || + IsSrvrDLLwnd ((HWND)wParam, pedit->hInst)) { + // For exact instance match or for + // DLL instance match, keep the new one +#ifdef FIREWALLS + ASSERT (!pedit->hServer, "Two instances are matching"); +#endif + + pedit->hServer = (HWND)wParam; + } else { + + ++pedit->extraTerm; + // This post directly is alright since we are + // terminating extra initiates. + + PostMessage ((HWND)wParam, + WM_DDE_TERMINATE, hwnd, 0); + } +#else + + HandleAckInitMsg (pedit, (HWND)wParam); +#endif + if (LOWORD(lParam)) + GlobalDeleteAtom (LOWORD(lParam)); + if (HIWORD(lParam)) + GlobalDeleteAtom (HIWORD(lParam)); + + break; + + case AA_EXECUTE: + HandleAck(lpobj, pedit, lParam); + break; + + + default: + DEBUG_OUT ("received ACK We don't know how to handle ",0) + break; + + + } + + break; + + case WM_TIMER: + HandleTimerMsg (lpobj, pedit); + break; + + case WM_DDE_TERMINATE: + +#ifdef FIREWALLS + ASSERT (pedit, "sys conv edit block missing"); +#endif + HandleTermMsg (lpobj, pedit, (HWND)wParam, FALSE); + break; + + case WM_DESTROY: +#ifdef FIREWALLS + ASSERT (pedit, "sys conv edit block missing"); +#endif + DEBUG_OUT ("destroy window for the sys connection", 0); + pedit->hClient = NULL; + break; + + + default: + return DefWindowProc (hwnd, message, wParam, lParam); + + } + return 0L; +} + +void INTERNAL HandleTimerMsg (lpobj, pedit) +PEDIT_DDE pedit; +LPOBJECT_LE lpobj; +{ + + + // Since there is only one timer for each client, just + // repost the message and delete the timer. + + KillTimer (pedit->hClient, 1); + pedit->wTimer = 0; + + if (PostMessageToServer(pedit, pedit->msg, pedit->lParam)) + return ; // return something. + + // Postmessage failed. We need to getback to the main stream of + // commands for the object. + HandleAck (lpobj, pedit, pedit->lParam); + return ; +} + + +void INTERNAL HandleTermMsg (lpobj, pedit, hwndPost, bDoc) +LPOBJECT_LE lpobj; +PEDIT_DDE pedit; +HWND hwndPost; +BOOL bDoc; +{ + WORD asyncCmd; + BOOL bBusy; + + if (pedit->hServer != hwndPost){ + DEBUG_OUT ("Got terminate for extra conversation",0) + if (--pedit->extraTerm == 0 && pedit->bTerminating) + ScheduleAsyncCmd (lpobj); + return; + + } + + if (!pedit->bTerminating){ + + // If we are waiting for any ack, then goto next step with error + + // delete any data if we were in busy mode. + bBusy = DeleteBusyData (lpobj, pedit); + + asyncCmd = lpobj->asyncCmd; + PostMessageToServer(pedit, WM_DDE_TERMINATE, NULL); + pedit->hServer = NULL; + if (pedit->awaitAck || bBusy) { + // Set error and goto next step. + lpobj->subErr = OLE_ERROR_COMM; + pedit->awaitAck = NULL; + ScheduleAsyncCmd (lpobj); + } + + // If the command is delete, do not delete + // the edit blocks. It will be deleted + // in the OleLnkDelete routine and for delete it is + // possible that by the time we come here, the object + // may not exist at all. + + if (asyncCmd != OLE_DELETE){ + // QueryOpen() is done because excel is sending WM_DDE_TERMINATE + // for system without sending for doc in case of failure. + + if (bDoc || QueryOpen (lpobj)) { + // if the termination is for document and no async command + // terminate the server conversation also. + if ((asyncCmd == OLE_NONE) || (asyncCmd == OLE_REQUESTDATA) + || (asyncCmd == OLE_OTHER) || (asyncCmd == OLE_SETDATA) + || (asyncCmd == OLE_RUN) || (asyncCmd == OLE_SHOW) + || (asyncCmd == OLE_SETUPDATEOPTIONS)) { + if (lpobj->pDocEdit->awaitAck) + // we are waiting for an ack on Doc channel. So start + // the unlaunch process after we get the ack. + lpobj->bUnlaunchLater = TRUE; + else + CallEmbLnkDelete (lpobj); + } else { + if (bDoc) + DeleteDocEdit (lpobj); + + } + }else + DeleteSrvrEdit (lpobj); + + } + } else { + pedit->hServer = NULL; + if (pedit->extraTerm == 0) + ScheduleAsyncCmd (lpobj); + } +} + +#ifdef FIREWALLS +BOOL INTERNAL CheckAtomValid (ATOM aItem) +{ + char buffer[MAX_ATOM]; + int len, val; + + + Puts("CheckAtomValid"); + + if (aItem == NULL) + return TRUE; + + val = GlobalGetAtomName (aItem, buffer, MAX_ATOM); + len = lstrlen (buffer); + return ((val != 0) && (val == len)); +} +#endif + + + + +// HandleAckInitMsg: Handles WM_DDE_ACKs received while in initiate state. If +// this is the first reply, save its window handle. If multiple replies +// are received, take the one with the prefered instance, if there is +// one. Keep a count of WM_DDE_TERMINATEs we send so that we don't shut +// the window until we get all of the responses for WM_DDE_TERMINATEs. + +void INTERNAL HandleAckInitMsg (pedit, hserver) +PEDIT_DDE pedit; +HWND hserver; +{ + + Puts("HandleAckInitMsg"); + + if (pedit->hServer){ + // just take the very first one. Direct post is OK + PostMessage (hserver, WM_DDE_TERMINATE, pedit->hClient, 0); + ++pedit->extraTerm; + } else + pedit->hServer = hserver; + +} + + +// HandleAck: returns 0 if <ack> is not positive, else non-0. Should probably be +// a macro. + +BOOL INTERNAL HandleAck (lpobj, pedit, lParam) +LPOBJECT_LE lpobj; +PEDIT_DDE pedit; +DWORD lParam; +{ + + BOOL retval = TRUE; + + + // check for busy bit + if ((LOWORD (lParam) & 0x4000) && ContextCallBack (lpobj, OLE_QUERY_RETRY)){ + // we got busy from the server. create a timer and wait for time out. + + // We do not need makeprocinstance since, DLLs are single insance, all + // we need to do is export for this function. + + if (pedit->wTimer = SetTimer (pedit->hClient, 1, 3000, NULL)) + return TRUE; + } + + // even if the client got terminate we have to go thru this path. + + if (pedit->wTimer) { + KillTimer (pedit->hClient, 1); + pedit->wTimer = 0; + } + + if (pedit->awaitAck == AA_POKE) + // We have to free the data first. Handleack can trigger + // another Poke (like pokehostnames) + FreePokeData (lpobj, pedit); + + if (pedit->awaitAck == AA_EXECUTE) + GlobalFree (HIWORD (lParam)); + else { + ASSERT (CheckAtomValid(HIWORD(lParam)),"Invalid atom in ACK") + if (HIWORD (lParam)) + GlobalDeleteAtom (HIWORD (lParam)); + } + + if (!(LOWORD (lParam) & 0x8000)) { + // error case. set the error + DEBUG_OUT ("DDE ACK with failure", 0) + + if (lpobj->errHint){ + lpobj->subErr = lpobj->errHint; + lpobj->errHint = OLE_OK; + } else + lpobj->subErr = OLE_ERROR_COMM; + + retval = FALSE; + + if (pedit->awaitAck == AA_ADVISE) { + +#ifdef ASSERT + ASSERT (pedit->hopt, "failed advise, options block missing"); +#endif + GlobalFree (pedit->hopt); + } + } + + pedit->hopt = NULL; + pedit->awaitAck = NULL; + ScheduleAsyncCmd (lpobj); + return retval; +} + +// HandleDataMsg: Called for WM_DDE_DATA message. If data is from an +// ADVISE-ON-CLOSE and this is there are no more outstanding +// ADVISE-ON-CLOSE requests, close the document and end the +// conversation. + +void INTERNAL HandleDataMsg (lpobj, hdata, aItem) +LPOBJECT_LE lpobj; +HANDLE hdata; +ATOM aItem; +{ + DDEDATA far *lpdata = NULL; + BOOL fAck; + BOOL fRelease; + int options; + PEDIT_DDE pedit; + + Puts("HandleDataMsg"); + + if (ScanItemOptions (aItem, (int far *)&options) != OLE_OK) { + DEBUG_OUT (FALSE, "Improper item options"); + return; + } + + pedit = lpobj->pDocEdit; + + if (hdata) { + if (!(lpdata = (DDEDATA FAR *) GlobalLock(hdata))) + return; + + fAck = lpdata->fAckReq; + fRelease = lpdata->fRelease; + + if (pedit->bTerminating) { + DEBUG_OUT ("Got DDE_DATA in terminate sequence",0) + fRelease = TRUE; + } + else { + if (lpdata->cfFormat == (int)cfBinary && aItem == aStdDocName) { + ChangeDocName (lpobj, (LPSTR)lpdata->Value); + } + else + SetData (lpobj, hdata, options); + + #ifdef FIREWALLS + ASSERT (IsWindowValid(pedit->hServer), + "Server window missing in HandleDataMsg") + ASSERT (CheckAtomValid(aItem),"HandleDataMsg invalid atom") + #endif + + // important that we post the acknowledge first. Otherwist the + // messages are not in sync. + + if (fAck) + PostMessageToServer (pedit, WM_DDE_ACK, + MAKELONG(POSITIVE_ACK,aItem)); + else if (aItem) + GlobalDeleteAtom (aItem); + + if ((lpdata->fResponse) && (pedit->awaitAck == AA_REQUEST)) { + // we sent the request. So, schedule next step. + pedit->awaitAck = NULL; + ScheduleAsyncCmd (lpobj); + } + } + + GlobalUnlock (hdata); + if (fRelease) + GlobalFree (hdata); + } + else { + if (CanCallback (lpobj, options)) { + if (options != OLE_CLOSED) + ContextCallBack (lpobj, options); + else + lpobj->bSvrClosing = FALSE; + + } + } + + if (options == OLE_CLOSED && (lpobj->pDocEdit->nAdviseClose <= 2) + && (lpobj->asyncCmd == OLE_NONE)) { + InitAsyncCmd (lpobj, OLE_SERVERUNLAUNCH, EMBLNKDELETE); + EmbLnkDelete (lpobj); + } +} + + +HANDLE GetDDEDataHandle (lpdata, cfFormat, hdata) +DDEDATA far *lpdata; +WORD cfFormat; +HANDLE hdata; +{ + if (cfFormat == CF_BITMAP || cfFormat == CF_METAFILEPICT) + return *(LPHANDLE)lpdata->Value; + + if (cfFormat == CF_DIB) + return GlobalReAlloc (*(LPHANDLE)lpdata->Value, 0L, + GMEM_MODIFY|GMEM_SHARE); + + return CopyData (((LPSTR)lpdata)+4, GlobalSize (hdata) - 4); +} + +// SetData: Given the DDEDATA structure from a WM_DDE_DATA message, set up the +// appropriate data in lpobj. If the native is in native format, add +// that field, otherwise, if it is in picture format, ask the picture +// to add it itself. + +void INTERNAL SetData (lpobj, hdata, options) +LPOBJECT_LE lpobj; +HANDLE hdata; +int options; +{ + DDEDATA far *lpdata = NULL; + OLESTATUS retVal = OLE_ERROR_MEMORY; + HANDLE hdataDDE; + + Puts("SetData"); + + if (!(lpdata = (DDEDATA far *) (GlobalLock (hdata)))) + goto errrtn; + + + if (!(hdataDDE = GetDDEDataHandle (lpdata, lpdata->cfFormat, hdata))) { + lpobj->subErr = OLE_ERROR_MEMORY; + goto errrtn; + } + + if (lpdata->cfFormat == (int)cfNative) { + retVal = (*lpobj->head.lpvtbl->ChangeData) ( lpobj, + hdataDDE, + lpobj->head.lpclient, + TRUE); // use this data, don't copy + + } + else if (lpdata->cfFormat && (lpdata->cfFormat == GetPictType (lpobj))) { + + retVal = (*lpobj->lpobjPict->lpvtbl->ChangeData) (lpobj->lpobjPict, + hdataDDE, + lpobj->head.lpclient, + lpdata->fRelease); + + } else { + // case of extra data in the object. + DeleteExtraData (lpobj); + lpobj->cfExtra = lpdata->cfFormat; + lpobj->hextraData = hdataDDE; + goto end; + } + + if (retVal == OLE_OK) { + SetExtents (lpobj); + if (CanCallback (lpobj, options)) { + if (options == OLE_CLOSED) { + ContextCallBack (lpobj, OLE_CHANGED); + ContextCallBack (lpobj, OLE_CLOSED); + lpobj->bSvrClosing = FALSE; + } + else + ContextCallBack (lpobj, options); + } + } + +end: +errrtn: + if (lpdata) + GlobalUnlock (hdata); + + return; +} + + +// SysStartConvDDE: Starts a system conversation. Returns a handle to that +// conversation, or NULL. + +BOOL INTERNAL InitSrvrConv (lpobj, hInst) +LPOBJECT_LE lpobj; +HANDLE hInst; +{ + HANDLE hedit = NULL; + PEDIT_DDE pedit = NULL; + + Puts("InitSrvrConv"); + + if (!lpobj->hSysEdit) { + hedit = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (EDIT_DDE)); + + if (hedit == NULL || ((pedit = (PEDIT_DDE) LocalLock (hedit)) == NULL)) + goto errRtn; + + } else { +#ifdef FIREWALLS + ASSERT (!lpobj->pSysEdit->hClient, "Sys conv lptr is present"); +#endif + hedit = lpobj->hSysEdit; + pedit = lpobj->pSysEdit; + UtilMemClr ((PSTR) pedit, sizeof (EDIT_DDE)); + } + + if((pedit->hClient = CreateWindow ("OleSrvrWndClass", "", + WS_OVERLAPPED,0,0,0,0,NULL,NULL, hInstDLL, NULL)) == NULL) + goto errRtn; + + + lpobj->hSysEdit = hedit; + lpobj->pSysEdit = pedit; + pedit->hInst = hInst; + pedit->awaitAck = AA_INITIATE; + + SetWindowLong (pedit->hClient, 0, (LONG)lpobj); + SendMessage (-1, WM_DDE_INITIATE, pedit->hClient, + MAKELONG (lpobj->app, aOle)); + + ASSERT (CheckAtomValid(aOle),"systopic invalid atom") + + pedit->awaitAck = NULL; + if (pedit->hServer == NULL) { + pedit->awaitAck = AA_INITIATE; + // Now try the System topic + SendMessage (-1, WM_DDE_INITIATE, pedit->hClient, + MAKELONG (lpobj->app, aSystem)); + + ASSERT (CheckAtomValid(aSystem),"systopic invalid atom") + + pedit->awaitAck = NULL; + if (pedit->hServer == NULL) { + DEBUG_OUT ("Srver connection failed", 0); + goto errRtn; + } + } + + // Put the long ptr handle in the object. + return TRUE; + +errRtn: + if (pedit->hClient) + DestroyWindow (pedit->hClient); + + if (pedit) + LocalUnlock (hedit); + + if (hedit) + LocalFree (hedit); + + lpobj->hSysEdit = NULL; + lpobj->pSysEdit = NULL; + + return FALSE; +} + + +// TermSrvrConv: Ends conversation indicated by hedit. +void INTERNAL TermSrvrConv (lpobj) +LPOBJECT_LE lpobj; +{ + PEDIT_DDE pedit; + + Puts("TermSrvrConv"); + + + if (!(pedit = lpobj->pSysEdit)) + return; + + if (PostMessageToServer (pedit, WM_DDE_TERMINATE, 0)){ + lpobj->bAsync = TRUE; + pedit->bTerminating = TRUE; + } else { + pedit->bTerminating = FALSE; + lpobj->subErr = OLE_ERROR_TERMINATE; + } + return; +} + + +void INTERNAL DeleteAbortData (lpobj, pedit) +LPOBJECT_LE lpobj; +PEDIT_DDE pedit; +{ + + // kill if any timer active. + if (pedit->wTimer) { + KillTimer (pedit->hClient, 1); + pedit->wTimer = 0; + } + return; + + +} + +BOOL INTERNAL DeleteBusyData (lpobj, pedit) +LPOBJECT_LE lpobj; +PEDIT_DDE pedit; +{ + + // kill if any timer active. + if (pedit->wTimer) { + KillTimer (pedit->hClient, 1); + pedit->wTimer = 0; + + if (pedit->hData) { + GlobalFree (pedit->hData); + pedit->hData = NULL; + } + + if (pedit->hopt) { + GlobalFree (pedit->hopt); + pedit->hopt = NULL; + } + + if (pedit->awaitAck && (HIWORD(pedit->lParam))) { + if (pedit->awaitAck == AA_EXECUTE) + GlobalFree (HIWORD (pedit->lParam)); + else { + ASSERT (CheckAtomValid(HIWORD(pedit->lParam)), + "Invalid atom in ACK") + if (HIWORD(pedit->lParam)) + GlobalDeleteAtom (HIWORD(pedit->lParam)); + } + + // we want to wipe out the HIWORD of lParam + pedit->lParam &= 0x0000FFFF; + } + + return TRUE; + } + + return FALSE; +} + +void INTERNAL DeleteSrvrEdit (lpobj) +LPOBJECT_LE lpobj; +{ + + PEDIT_DDE pedit; + + Puts("deleteSrvrEdit"); + + if (!(pedit = lpobj->pSysEdit)) + return; + + + // delete any data if we were in busy mode. + DeleteBusyData (lpobj, pedit); + + if (pedit->hClient) + DestroyWindow (pedit->hClient); + + if (lpobj->pSysEdit) + LocalUnlock (lpobj->hSysEdit); + + if (lpobj->hSysEdit) + LocalFree (lpobj->hSysEdit); + + lpobj->hSysEdit = NULL; + lpobj->pSysEdit = NULL; + + return; +} + + +void INTERNAL SendStdExit (lpobj) +LPOBJECT_LE lpobj; +{ + + + Puts("SendSrvrExit"); + + if (!lpobj->pSysEdit) + return; + + SrvrExecute (lpobj, MapStrToH ("[StdExit]")); + +} + +void INTERNAL SendStdClose (lpobj) +LPOBJECT_LE lpobj; +{ + + + Puts("SendDocClose"); + + if (!lpobj->pDocEdit) + return; + + DocExecute (lpobj, MapStrToH ("[StdCloseDocument]")); + +} + + +// SrvrExecute: Sends execute command to system conversation. +BOOL INTERNAL SrvrExecute (lpobj, hdata) +LPOBJECT_LE lpobj; +HANDLE hdata; +{ + PEDIT_DDE pedit = NULL; + int retval = FALSE; + + Puts("SrvrExecute"); + +#ifdef FIREWALLS + + ASSERT (lpobj->hSysEdit, "Sys conv handle missing"); + ASSERT (lpobj->pSysEdit, "sys conv lptr is missing"); + +#endif + pedit = lpobj->pSysEdit; + + if (hdata == NULL || pedit == NULL) { + lpobj->subErr = OLE_ERROR_MEMORY; + return FALSE; + } + +#ifdef FIREWALLS + ASSERT (!pedit->bTerminating, "In terminate state") + ASSERT (pedit->awaitAck == NULL, "trying to Post msg while waiting for ack") +#endif + + if (lpobj->bOldLink) { + GlobalFree (hdata); + return TRUE; + } + + + if (PostMessageToServer (pedit, WM_DDE_EXECUTE, MAKELONG (0, hdata))) { + // data is being freed in the acknowledge + lpobj->bAsync = TRUE; + pedit->awaitAck = AA_EXECUTE; + return TRUE; + } else { + lpobj->subErr = OLE_ERROR_COMMAND; + GlobalFree (hdata); + return FALSE; + } +} + +// StartConvDDE: Starts the document conversation for an object based on +// .app and .topic atoms. +BOOL FARINTERNAL InitDocConv (lpobj, fNetDlg) +LPOBJECT_LE lpobj; +BOOL fNetDlg; +{ + + // ### This routine looks very similar to IitSrvrConv + // combine with the it + + HANDLE hedit = NULL; + PEDIT_DDE pedit = NULL; + char buf[MAX_NET_NAME]; + int nDrive = 2; // drive C + char cOldDrive; + + Puts("InitDocConv"); + + if (QueryOpen (lpobj)){ + DEBUG_OUT ("Attempt to start already existing conversation",0); + return FALSE; + } + + cOldDrive = lpobj->cDrive; + if (CheckNetDrive (lpobj, fNetDlg) != OLE_OK) + return FALSE; + + if (!lpobj->pDocEdit) { + hedit = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (EDIT_DDE)); + + if (hedit == NULL || ((pedit = (PEDIT_DDE) LocalLock (hedit)) == NULL)){ + lpobj->subErr = OLE_ERROR_MEMORY; + goto errRtn; + } + } else { +#ifdef FIREWALLS + ASSERT (!lpobj->pDocEdit->hClient, "Doc conv lptr is present"); +#endif + hedit = lpobj->hDocEdit; + pedit = lpobj->pDocEdit; + UtilMemClr ((PSTR) pedit, sizeof (EDIT_DDE)); + } + + if ((pedit->hClient = CreateWindow ("OleDocWndClass", "Window Name", + WS_OVERLAPPED,0,0,0,0,NULL,NULL, hInstDLL, NULL)) == NULL) { + lpobj->subErr = OLE_ERROR_MEMORY; + goto errRtn; + } + lpobj->hDocEdit = hedit; + lpobj->pDocEdit = pedit; + SetWindowLong (pedit->hClient, 0, (LONG)lpobj); + + // buf will filled by netname in the first call to SetNextNetDrive() + buf[0] = '\0'; + do { + pedit->awaitAck = AA_INITIATE; + + // !!! Where are the atom counts bumped? + + SendMessage (-1, WM_DDE_INITIATE, pedit->hClient, + MAKELONG (lpobj->app, lpobj->topic)); + + pedit->awaitAck = NULL; + + if (pedit->hServer) { + if ((cOldDrive != lpobj->cDrive) + && (lpobj->asyncCmd != OLE_CREATEFROMFILE)) + ContextCallBack (lpobj, OLE_RENAMED); + return TRUE; + } + + } while ((lpobj->head.ctype == CT_LINK) && (lpobj->aNetName) + && SetNextNetDrive (lpobj, &nDrive, buf)) ; + +errRtn: + if (cOldDrive != lpobj->cDrive) { + // put back the old drive + lpobj->cDrive = cOldDrive; + ChangeTopic (lpobj); + } + + if (pedit->hClient) + DestroyWindow (pedit->hClient); + + if (pedit) + LocalUnlock (hedit); + + if (hedit) + LocalFree (hedit); + + lpobj->hDocEdit = NULL; + lpobj->pDocEdit = NULL; + return FALSE; +} + + +// Execute: Sends an execute string WM_DDE_EXECUTE to the document conversation. +BOOL INTERNAL DocExecute (lpobj, hdata) +LPOBJECT_LE lpobj; +HANDLE hdata; +{ + PEDIT_DDE pedit; + + Puts("DocExecute"); + pedit = lpobj->pDocEdit; + + if (hdata == NULL || pedit == NULL) + return FALSE; + + +#ifdef FIREWALLS + ASSERT (!pedit->bTerminating, "Execute: terminating") + ASSERT (pedit->hClient, "Client null") + ASSERT (IsWindowValid(pedit->hClient),"Invalid client") + ASSERT (pedit->awaitAck == NULL, "trying to Post msg while waiting for ack") +#endif + + if (lpobj->bOldLink) { + GlobalFree (hdata); + return TRUE; + } + + if (PostMessageToServer (pedit, WM_DDE_EXECUTE, MAKELONG (0, hdata))) { + // data is being freed in the execute command + pedit->awaitAck = AA_EXECUTE; + lpobj->bAsync = TRUE; + return TRUE; + } else { + lpobj->subErr = OLE_ERROR_COMMAND; + GlobalFree (hdata); + return FALSE; + } +} + + +// EndConvDDE: terminates the doc level conversation. +void INTERNAL TermDocConv (lpobj) +LPOBJECT_LE lpobj; +{ + PEDIT_DDE pedit; + + Puts ("TermDocConv"); + + DEBUG_OUT ("About to terminate convs from destroy",0) + + if (!(pedit = lpobj->pDocEdit)) + return; + + if (PostMessageToServer (pedit, WM_DDE_TERMINATE, 0)) { + pedit->bTerminating = TRUE; + lpobj->bAsync = TRUE; + } else + lpobj->subErr = OLE_ERROR_TERMINATE; + + return; + +} + +// Deletes the document conversdation memory. +void INTERNAL DeleteDocEdit (lpobj) +LPOBJECT_LE lpobj; +{ + + PEDIT_DDE pedit; + + Puts ("DeleteDocEdit"); + + if (!(pedit = lpobj->pDocEdit)) + return; + + // delete any data if we were in busy mode. + DeleteBusyData (lpobj, pedit); + + // Delete if any data blocks. + if (pedit->hClient) + DestroyWindow (pedit->hClient); + + if (lpobj->pDocEdit) + LocalUnlock (lpobj->hDocEdit); + + if (lpobj->hDocEdit) + LocalFree (lpobj->hDocEdit); + + lpobj->hDocEdit = NULL; + lpobj->pDocEdit = NULL; + + return; +} + + +// LeLauchApp: Launches app based on the ClassName in lpobj. +HANDLE INTERNAL LeLaunchApp (lpobj) +LPOBJECT_LE lpobj; +{ + struct CMDSHOW + { + WORD first; + WORD second; + } cmdShow = {2, SW_SHOWNORMAL}; + + struct + { + WORD wEnvSeg; + LPSTR lpcmdline; + struct CMDSHOW FAR *lpCmdShow; + DWORD dwReserved; + } paramBlock; + + char cmdline[MAX_STR]; + char exeName[MAX_STR]; +#ifdef WIN32S + char execCmdLine[MAX_STR]; +#endif + HANDLE hInst; + + #define EMB_STR " -Embedding " + + Puts("LeLaunchApp"); + + GlobalGetAtomName (lpobj->aServer, exeName, MAX_STR); + + if (lpobj->bOldLink) { + cmdShow.second = SW_SHOWMINIMIZED; + cmdline[0] = ' '; + GlobalGetAtomName (lpobj->topic, cmdline + 1, MAX_STR); + } else { + lstrcpy ((LPSTR)cmdline, (LPSTR) EMB_STR); + + // For all link servers we want to give the filename on the command + // line. But Excel is not registering the document before returning + // from WinMain, if it has auto load macros. So, we want send StdOpen + // for the old servers, instead of giving the file name on the command + // line. + + if (lpobj->bOleServer && (lpobj->fCmd & LN_MASK) == LN_LNKACT) + GlobalGetAtomName (lpobj->topic, cmdline+sizeof(EMB_STR)-1, + MAX_STR-sizeof(EMB_STR)); + if (lpobj->fCmd & ACT_MINIMIZE) + cmdShow.second = SW_SHOWMINIMIZED; + else if (!(lpobj->fCmd & (ACT_SHOW | ACT_DOVERB)) + // we want to launch with show in create invisible case + // even though ACT_SHOW flag will be false + && ((lpobj->fCmd & LN_MASK) != LN_NEW)) + cmdShow.second = SW_HIDE; + } + + paramBlock.wEnvSeg = NULL; + paramBlock.lpcmdline = (LPSTR)cmdline; + paramBlock.lpCmdShow = &cmdShow; + paramBlock.dwReserved = NULL; + +#ifdef WIN32S + if (wWinVer != 0x0003) { + lstrcpy( (LPSTR)execCmdLine, (LPSTR)exeName); + lstrcat( (LPSTR)execCmdLine, (LPSTR)" "); + lstrcat( (LPSTR)execCmdLine, (LPSTR)paramBlock.lpcmdline); + if ((hInst = WinExec ((LPSTR)execCmdLine, cmdShow.second)) <= 32) + hInst = NULL; + } else +#endif + if ((hInst = LoadModule ((LPSTR)exeName, ¶mBlock)) <= 32) + hInst = NULL; + + if (!hInst) { + LPSTR lptmp; + char ch; + + // strip off the path and try again + lptmp = (LPSTR)exeName; + lptmp += lstrlen ((LPSTR) exeName); + ch = *lptmp; + while (ch != '\\' && ch != ':') { + if (lptmp == (LPSTR) exeName) { + // exe did not have path in it's name. we already tried + // loading and it failed, no point trying again. + return NULL; + } + else + ch = *--lptmp; + } + +#ifdef WIN32S + if (wWinVer != 0x0003) { + lstrcpy( (LPSTR)execCmdLine, (LPSTR)++lptmp); + lstrcat( (LPSTR)execCmdLine, (LPSTR)" "); + lstrcat( (LPSTR)execCmdLine, (LPSTR)paramBlock.lpcmdline); + if ((hInst = WinExec ((LPSTR)execCmdLine, cmdShow.second)) <= 32) + hInst = NULL; + } else +#endif + if ((hInst = LoadModule (++lptmp, ¶mBlock)) <= 32) + hInst = NULL; + } + + return hInst; +} + + + +//ScanItemOptions: Scan for the item options like Close/Save etc. + +int INTERNAL ScanItemOptions (aItem, lpoptions) +ATOM aItem; +int far *lpoptions; +{ + + ATOM aModifier; + + LPSTR lpbuf; + char buf[MAX_STR]; + + *lpoptions = OLE_CHANGED; + + if (!aItem) { + // NULL item with no modifier means OLE_CHANGED for NULL item + return OLE_OK; + } + + GlobalGetAtomName (aItem, (LPSTR)buf, MAX_STR); + lpbuf = (LPSTR)buf; + + while ( *lpbuf && *lpbuf != '/') + lpbuf++; + + // no modifier same as /change + + if (*lpbuf == NULL) + return OLE_OK; + + *lpbuf++ = NULL; // seperate out the item string + // We are using this in the caller. + + if (!(aModifier = GlobalFindAtom (lpbuf))) + return OLE_ERROR_SYNTAX; + + if (aModifier == aChange) + return OLE_OK; + + // Is it a save? + if (aModifier == aSave){ + *lpoptions = OLE_SAVED; + return OLE_OK; + } + // Is it a Close? + if (aModifier == aClose){ + *lpoptions = OLE_CLOSED; + return OLE_OK; + } + + // unknown modifier + return OLE_ERROR_SYNTAX; + +} + +void INTERNAL ChangeDocName (lpobj, lpdata) +LPOBJECT_LE lpobj; +LPSTR lpdata; +{ + ATOM aOldTopic; + OLESTATUS retVal; + + aOldTopic = lpobj->topic; + lpobj->topic = GlobalAddAtom (lpdata); + if ((retVal = SetNetName (lpobj)) != OLE_OK) { + if (lpobj->topic) + GlobalDeleteAtom (lpobj->topic); + lpobj->topic = aOldTopic; + return; + // !!! what should we do in case of error? Currently, we will not + // change the topic if SetNetName fails. + } + + if (aOldTopic) + GlobalDeleteAtom (aOldTopic); + + // Delete the link data block + if (lpobj->hLink) { + GlobalFree (lpobj->hLink); + lpobj->hLink = NULL; + } + + ContextCallBack (lpobj, OLE_RENAMED); + +} + + +BOOL INTERNAL CanCallback (lpobj, options) +LPOBJECT_LE lpobj; +int options; +{ + LPINT lpCount; + + if (options == OLE_CLOSED) { + lpobj->bSvrClosing = TRUE; + lpCount = &(lpobj->pDocEdit->nAdviseClose); + } + else if (options == OLE_SAVED) { + if (lpobj->head.ctype == CT_LINK) + return TRUE; + lpCount = &(lpobj->pDocEdit->nAdviseSave); + } + else { + // it must be due to request + if ((lpobj->pDocEdit->awaitAck == AA_REQUEST) + && lpobj->pDocEdit->bCallLater) + return FALSE; + + return TRUE; + } + + switch (*lpCount) { + case 1: + break; + + case 2: + ++(*lpCount); + return FALSE; + + case 3: + --(*lpCount); + break; + + default: + return FALSE; + } + + return TRUE; +} + + +void FARINTERNAL CallEmbLnkDelete (lpobj) +LPOBJECT_LE lpobj; +{ + InitAsyncCmd (lpobj, OLE_SERVERUNLAUNCH,EMBLNKDELETE); + EmbLnkDelete (lpobj); + + if (lpobj->head.ctype == CT_EMBEDDED) { + lpobj->bSvrClosing = TRUE; + ContextCallBack (lpobj, OLE_CLOSED); + if (FarCheckObject ((LPOLEOBJECT)lpobj)) + lpobj->bSvrClosing = FALSE; + } +} diff --git a/private/mvdm/wow16/ole/client/defcreat.c b/private/mvdm/wow16/ole/client/defcreat.c new file mode 100644 index 000000000..a941abd0f --- /dev/null +++ b/private/mvdm/wow16/ole/client/defcreat.c @@ -0,0 +1,215 @@ +/****************************** Module Header ******************************\ +* Module Name: defcreat.c +* +* Purpose: Handles the various object creation routines, which are exported +* to the DLL writers. +* +* Created: November 1990 +* +* Copyright (c) 1985, 1986, 1987, 1988, 1989 Microsoft Corporation +* +* History: +* Srinik (11/12/90) Original +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" + +extern OLECLIPFORMAT cfOwnerLink; +extern OLECLIPFORMAT cfObjectLink; +extern OLECLIPFORMAT cfNative; + + +RENDER_ENTRY stdRender[NUM_RENDER] = { + { "METAFILEPICT", 0, MfLoadFromStream}, + { "DIB", 0, DibLoadFromStream}, + { "BITMAP", 0, BmLoadFromStream} +}; + + +OLESTATUS FARINTERNAL DefLoadFromStream (lpstream, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfFormat) +LPOLESTREAM lpstream; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +LONG objType; +ATOM aClass; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + int i; + + *lplpobj = NULL; + + if ((objType == CT_PICTURE) || (objType == CT_STATIC)) { + for (i = 0; i < NUM_RENDER; i++) { + if (stdRender[i].aClass == aClass) { + retVal = (*stdRender[i].Load) (lpstream, lpclient, + lhclientdoc, lpobjname, lplpobj, objType); + if (aClass) + GlobalDeleteAtom (aClass); + return retVal; + } + } + + return GenLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, + lplpobj, objType, aClass, cfFormat); + } + else { + return LeLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, + lplpobj, objType, aClass, cfFormat); + } +} + + +OLESTATUS FAR PASCAL DefCreateFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, objType) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LONG objType; +{ + if (objType == CT_EMBEDDED) + return EmbPaste (lpclient, lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat); + + if (objType == CT_LINK) + return LnkPaste (lpclient, lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat, cfOwnerLink); + + return OLE_ERROR_CLIPBOARD; +} + + + + +OLESTATUS FAR PASCAL DefCreateLinkFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + return LnkPaste (lpclient, lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat, cfObjectLink); +} + + +OLESTATUS FAR PASCAL DefCreateFromTemplate (lpprotocol, lpclient, lptemplate, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lptemplate; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + return LeCreateFromTemplate (lpclient, + lptemplate, + lhclientdoc, + lpobjname, + lplpoleobject, + optRender, + cfFormat); +} + + +OLESTATUS FAR PASCAL DefCreate (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + return LeCreate (lpclient, + lpclass, + lhclientdoc, + lpobjname, + lplpoleobject, + optRender, + cfFormat); +} + + + +OLESTATUS FAR PASCAL DefCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + return CreateEmbLnkFromFile (lpclient, + lpclass, + lpfile, + NULL, + lhclientdoc, + lpobjname, + lplpoleobject, + optRender, + cfFormat, + CT_EMBEDDED); +} + + +OLESTATUS FAR PASCAL DefCreateLinkFromFile (lpprotocol, lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LPSTR lpitem; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + return CreateEmbLnkFromFile (lpclient, + lpclass, + lpfile, + lpitem, + lhclientdoc, + lpobjname, + lplpoleobject, + optRender, + cfFormat, + CT_LINK); +} + + +OLESTATUS FAR PASCAL DefCreateInvisible (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, fActivate) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +BOOL fActivate; +{ + return LeCreateInvisible (lpclient, + lpclass, + lhclientdoc, + lpobjname, + lplpoleobject, + optRender, + cfFormat, + fActivate); +} diff --git a/private/mvdm/wow16/ole/client/dib.c b/private/mvdm/wow16/ole/client/dib.c new file mode 100644 index 000000000..80d434a9f --- /dev/null +++ b/private/mvdm/wow16/ole/client/dib.c @@ -0,0 +1,495 @@ +/****************************** Module Header ******************************\ +* Module Name: DIB.C +* +* Handles all API routines for the device independent bitmap sub-dll of +* the ole dll. +* +* Created: Oct-1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Srinik, Raor (../../1990,91) Designed, coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" +#include "pict.h" + +void FARINTERNAL DibGetExtents (LPSTR, LPPOINT); + +#pragma alloc_text(_TEXT, DibSaveToStream, DibLoadFromStream, DibStreamRead, GetBytes, PutBytes, PutStrWithLen, DibGetExtents) + +OLEOBJECTVTBL vtblDIB = { + + ErrQueryProtocol, // check whether the speced protocol is supported + + DibRelease, // Release + ErrShow, // Show + ErrPlay, // show + DibGetData, // Get the object data + ErrSetData, // Set the object data + ErrSetTargetDevice, // + + ErrSetBounds, // set viewport bounds + DibEnumFormat, // enumerate supported formats + ErrSetColorScheme, // + DibRelease, // delete + ErrSetHostNames, // + + DibSaveToStream, // write to file + DibClone, // clone object + ErrCopyFromLink, // Create embedded from Lnk + + DibEqual, // compares the given objects for data equality + + DibCopy, // copy to clip + + DibDraw, // draw the object + + ErrActivate, // open + ErrExecute, // excute + ErrClose, // Stop + ErrUpdate, // Update + ErrReconnect, // Reconnect + + ErrObjectConvert, // convert object to specified type + + ErrGetUpdateOptions, // update options + ErrSetUpdateOptions, // update options + + ObjRename, // Change Object name + ObjQueryName, // Get current object name + + ObjQueryType, // Object type + DibQueryBounds, // QueryBounds + ObjQuerySize, // Find the size of the object + ErrQueryOpen, // Query open + ErrQueryOutOfDate, // query whether object is current + + ErrQueryRelease, // release related stuff + ErrQueryRelease, + ErrQueryRelease, + + ErrRequestData, // requestdata + ErrObjectLong, // objectLong + DibChangeData // change data of the existing object +}; + + + +OLESTATUS FARINTERNAL DibRelease (lpobj) +LPOBJECT_DIB lpobj; +{ + HOBJECT hobj; + + if (lpobj->hDIB){ + GlobalFree (lpobj->hDIB); + lpobj->hDIB = NULL; + } + + if (lpobj->head.lhclientdoc) + DocDeleteObject ((LPOLEOBJECT) lpobj); + + if (hobj = lpobj->head.hobj){ + lpobj->head.hobj = NULL; + GlobalUnlock (hobj); + GlobalFree (hobj); + } + + return OLE_OK; +} + + + +OLESTATUS FARINTERNAL DibSaveToStream (lpobj, lpstream) +LPOBJECT_DIB lpobj; +LPOLESTREAM lpstream; +{ + LPSTR lpDIBbuf; + + if (!lpobj->hDIB) + return OLE_ERROR_BLANK; + + if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutStrWithLen (lpstream, (LPSTR)"DIB")) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) + return OLE_ERROR_STREAM; + + lpobj->sizeBytes = GlobalSize (lpobj->hDIB); + if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (!(lpDIBbuf = GlobalLock (lpobj->hDIB))) + return OLE_ERROR_MEMORY; + + if (PutBytes (lpstream, lpDIBbuf, lpobj->sizeBytes)) + return OLE_ERROR_STREAM; + + GlobalUnlock (lpobj->hDIB); + return OLE_OK; +} + + + +OLESTATUS FARINTERNAL DibClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_DIB lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_DIB FAR * lplpobj; +{ + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + if (!(*lplpobj = DibCreateObject (lpobjsrc->hDIB, lpclient, FALSE, + lhclientdoc, lpobjname, lpobjsrc->head.ctype))) + return OLE_ERROR_MEMORY; + else + return OLE_OK; +} + + + +OLESTATUS FARINTERNAL DibEqual (lpobj1, lpobj2) +LPOBJECT_DIB lpobj1; +LPOBJECT_DIB lpobj2; +{ + if (CmpGlobals (lpobj1->hDIB, lpobj1->hDIB)) + return OLE_OK; + + return OLE_ERROR_NOT_EQUAL; +} + + +OLESTATUS FARINTERNAL DibCopy (lpobj) +LPOBJECT_DIB lpobj; +{ + HANDLE hDIB; + + if (!lpobj->hDIB) + return OLE_ERROR_BLANK; + + if (!(hDIB = DuplicateGlobal (lpobj->hDIB, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + + SetClipboardData (CF_DIB, hDIB); + return OLE_OK; +} + + +OLESTATUS FARINTERNAL DibQueryBounds (lpobj, lpRc) +LPOBJECT_DIB lpobj; +LPRECT lpRc; +{ + Puts("DibQueryBounds"); + + if (!lpobj->hDIB) + return OLE_ERROR_BLANK; + + lpRc->left = 0; + lpRc->top = 0; + lpRc->right = (int) lpobj->head.cx; + lpRc->bottom = (int) lpobj->head.cy; + return OLE_OK; +} + + + +OLECLIPFORMAT FARINTERNAL DibEnumFormat (lpobj, cfFormat) +LPOBJECT_DIB lpobj; +OLECLIPFORMAT cfFormat; +{ + if (!cfFormat) + return CF_DIB; + + return NULL; +} + + +OLESTATUS FARINTERNAL DibGetData (lpobj, cfFormat, lphandle) +LPOBJECT_DIB lpobj; +OLECLIPFORMAT cfFormat; +LPHANDLE lphandle; +{ + if (cfFormat != CF_DIB) + return OLE_ERROR_FORMAT; + + if (!(*lphandle = lpobj->hDIB)) + return OLE_ERROR_BLANK; + + return OLE_OK; +} + + + +LPOBJECT_DIB FARINTERNAL DibCreateObject (hDIB, lpclient, fDelete, lhclientdoc, lpobjname, objType) +HANDLE hDIB; +LPOLECLIENT lpclient; +BOOL fDelete; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + LPOBJECT_DIB lpobj; + + if (lpobj = DibCreateBlank (lhclientdoc, lpobjname, objType)) { + if (DibChangeData (lpobj, hDIB, lpclient, fDelete) != OLE_OK) { + DibRelease (lpobj); + lpobj = NULL; + } + } + + return lpobj; +} + + + +// If the routine fails then the object will be left with it's old data. +// If fDelete is TRUE, then hNewDIB will be deleted whether the routine +// is successful or not. + +OLESTATUS FARINTERNAL DibChangeData (lpobj, hNewDIB, lpclient, fDelete) +LPOBJECT_DIB lpobj; +HANDLE hNewDIB; +LPOLECLIENT lpclient; +BOOL fDelete; +{ + BITMAPINFOHEADER bi; + DWORD dwSize; + LPBITMAPINFOHEADER lpBi; + + if (!hNewDIB) + return OLE_ERROR_BLANK; + + lpBi = (LPBITMAPINFOHEADER) &bi; + if (!fDelete) { + if (!(hNewDIB = DuplicateGlobal (hNewDIB, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + } + else { + // change the ownership to yourself + + HANDLE htmp; + + if (!(htmp = GlobalReAlloc (hNewDIB, 0L, GMEM_MODIFY|GMEM_SHARE))) { + htmp = DuplicateGlobal (hNewDIB, GMEM_MOVEABLE); + GlobalFree (hNewDIB); + if (!htmp) + return OLE_ERROR_MEMORY; + } + + hNewDIB = htmp; + } + + if (!(lpBi = (LPBITMAPINFOHEADER) GlobalLock (hNewDIB))) { + GlobalFree (hNewDIB); + return OLE_ERROR_MEMORY; + } + + dwSize = GlobalSize (hNewDIB); + if (lpobj->hDIB) + GlobalFree (lpobj->hDIB); + DibUpdateStruct (lpobj, lpclient, hNewDIB, lpBi, dwSize); + return OLE_OK; +} + + +void INTERNAL DibUpdateStruct (lpobj, lpclient, hDIB, lpBi, dwBytes) +LPOBJECT_DIB lpobj; +LPOLECLIENT lpclient; +HANDLE hDIB; +LPBITMAPINFOHEADER lpBi; +DWORD dwBytes; +{ + POINT point; + + lpobj->head.lpclient = lpclient; + lpobj->sizeBytes = dwBytes; + +#ifdef OLD + lpobj->xSize = point.x = (int) lpBi->biWidth; + lpobj->ySize = point.y = (int) lpBi->biHeight; + ConvertToHimetric (&point); +#else + DibGetExtents ((LPSTR) lpBi, &point); +#endif + + lpobj->head.cx = (LONG) point.x; + lpobj->head.cy = (LONG) point.y; + lpobj->hDIB = hDIB; +} + + + +OLESTATUS FARINTERNAL DibLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) +LPOLESTREAM lpstream; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +LONG objType; +{ + LPOBJECT_DIB lpobj = NULL; + + *lplpoleobject = NULL; + + if (!(lpobj = DibCreateBlank (lhclientdoc, lpobjname, objType))) + return OLE_ERROR_MEMORY; + + lpobj->head.lpclient = lpclient; + if (GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) + goto errLoad; + + if (GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) + goto errLoad; + + if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(LONG))) + goto errLoad; + + if (DibStreamRead (lpstream, lpobj)) { + *lplpoleobject = (LPOLEOBJECT) lpobj; + return OLE_OK; + } + +errLoad: + OleDelete ((LPOLEOBJECT) lpobj); + return OLE_ERROR_STREAM; +} + + + +LPOBJECT_DIB FARINTERNAL DibCreateBlank (lhclientdoc, lpobjname, objType) +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + HOBJECT hobj; + LPOBJECT_DIB lpobj; + + if((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_DIB))) + == NULL) + return NULL; + + if (!(lpobj = (LPOBJECT_DIB) GlobalLock (hobj))){ + GlobalFree (hobj); + return NULL; + } + + // The structure is ZERO initialized at allocation time. So only the + // fields that need to be filled with values other than ZEROS are + // initialized below + + lpobj->head.objId[0] = 'L'; + lpobj->head.objId[1] = 'E'; + lpobj->head.mm = MM_TEXT; + lpobj->head.ctype = objType; + lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblDIB; + lpobj->head.iTable = INVALID_INDEX; + lpobj->head.hobj = hobj; + + if (objType == CT_STATIC) + DocAddObject ((LPCLIENTDOC) lhclientdoc, + (LPOLEOBJECT) lpobj, lpobjname); + return lpobj; +} + + + + +BOOL INTERNAL DibStreamRead (lpstream, lpobj) +LPOLESTREAM lpstream; +LPOBJECT_DIB lpobj; +{ + HANDLE hDIBbuf; + LPSTR lpDIBbuf; + BOOL retVal = FALSE; + BITMAPINFOHEADER bi; + + if (GetBytes (lpstream, (LPSTR) &bi, sizeof(bi))) + return FALSE; + + if (hDIBbuf = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes)) { + if (lpDIBbuf = (LPSTR)GlobalLock (hDIBbuf)){ + *((LPBITMAPINFOHEADER) lpDIBbuf) = bi; + if (!GetBytes (lpstream, lpDIBbuf+sizeof(bi), + (lpobj->sizeBytes - sizeof(bi)))) { + + lpobj->hDIB = hDIBbuf; +#ifdef OLD + //!!! this info should be part of the stream + if (!lpobj->head.cx) { + DibGetExtents ((LPSTR) lpDIBbuf, &point); + lpobj->head.cx = (LONG) point.x; + lpobj->head.cy = (LONG) point.y; + } +#endif + retVal = TRUE; + } + GlobalUnlock(hDIBbuf); + } + //* Hang on to the memory allocated for the DIB + } + return retVal; +} + + +OLESTATUS FARINTERNAL DibPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +LONG objType; +{ + HANDLE hDIB; + + if ((hDIB = GetClipboardData (CF_DIB)) == NULL) + return OLE_ERROR_MEMORY; + + *lplpoleobject = (LPOLEOBJECT) DibCreateObject (hDIB, lpclient, FALSE, + lhclientdoc, lpobjname, objType); + + return OLE_OK; + +} + + +void FARINTERNAL DibGetExtents (lpData, lpPoint) +LPSTR lpData; +LPPOINT lpPoint; +{ + #define HIMET_PER_METER 100000L // number of HIMETRIC units / meter + + LPBITMAPINFOHEADER lpbmi; + + lpbmi = (LPBITMAPINFOHEADER)lpData; + + if (!(lpbmi->biXPelsPerMeter && lpbmi->biYPelsPerMeter)) { + HDC hdc; + + hdc = GetDC (NULL); + lpbmi->biXPelsPerMeter = MulDiv (GetDeviceCaps (hdc, LOGPIXELSX), + 10000, 254); + lpbmi->biYPelsPerMeter = MulDiv (GetDeviceCaps (hdc, LOGPIXELSY), + 10000, 254); + + ReleaseDC (NULL, hdc); + } + + lpPoint->x = (int) (lpbmi->biWidth * HIMET_PER_METER + / lpbmi->biXPelsPerMeter); + lpPoint->y = -(int) (lpbmi->biHeight * HIMET_PER_METER + / lpbmi->biYPelsPerMeter); +} + diff --git a/private/mvdm/wow16/ole/client/dll.h b/private/mvdm/wow16/ole/client/dll.h new file mode 100644 index 000000000..355126a74 --- /dev/null +++ b/private/mvdm/wow16/ole/client/dll.h @@ -0,0 +1,958 @@ +/****************************** Module Header ******************************\ +* Module Name: dll.h +* +* PURPOSE: Private definitions file for ole.c +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, Srinik (../../90,91) Original +* +\***************************************************************************/ + +#define OLE_INTERNAL + +#include "cmacs.h" +#include "ole.h" + +///////////////////////////////////////////////////////////////////////////// +// // +// Defines, Object methods table and Structures. // +// // +///////////////////////////////////////////////////////////////////////////// + + +#ifndef HUGE +#define HUGE huge +#endif + +// Different OS version numbers. One of these values will be in the HIWORD +// of the OLE version field + +#define OS_WIN16 0x0000 +#define OS_MAC 0x0001 +#define OS_WIN32 0x0002 + + +// Characteristics Type Field +#define CT_NULL 0L +#define CT_LINK 1L +#define CT_EMBEDDED 2L +#define CT_STATIC 3L +#define CT_OLDLINK 4L +#define CT_PICTURE 5L + +#define OLE_NO 0 // for boolean query functions +#define OLE_YES 1 // for boolean query functions + +#define MAX_STR 256 +#define MAX_NET_NAME MAX_STR +#define INVALID_INDEX -1 +#define MAX_ATOM 256 + +#define NUM_RENDER 3 + +#define PROTOCOL_EDIT ((LPSTR)"StdFileEditing") +#define PROTOCOL_STATIC ((LPSTR)"Static") +#define PROTOCOL_EXECUTE ((LPSTR)"StdExecute") + +#define READ_ACCESS 0 +#define WRITE_ACCESS 1 + +#define POPUP_NETDLG 1 + +extern WORD CheckPointer (LPVOID, int); +WORD FARINTERNAL FarCheckPointer (LPVOID, int); + +#define PROBE_OLDLINK(lpobj){\ + if (lpobj->bOldLink)\ + return OLE_ERROR_OBJECT;\ +} + + +#define PROBE_READ(lp){\ + if (!CheckPointer(lp, READ_ACCESS))\ + return OLE_ERROR_ADDRESS; \ +} + +#define PROBE_WRITE(lp){\ + if (!CheckPointer(lp, WRITE_ACCESS))\ + return OLE_ERROR_ADDRESS; \ +} + + +#define FARPROBE_READ(lp){\ + if (!FarCheckPointer(lp, READ_ACCESS))\ + return OLE_ERROR_ADDRESS; \ +} + +#define FARPROBE_WRITE(lp){\ + if (!FarCheckPointer(lp, WRITE_ACCESS))\ + return OLE_ERROR_ADDRESS; \ +} + +#define PROBE_MODE(bProtMode) {\ + if (!bProtMode) \ + return OLE_ERROR_PROTECT_ONLY; \ +} + +extern OLECLIPFORMAT cfBinary; +extern OLECLIPFORMAT cfOwnerLink; +extern OLECLIPFORMAT cfObjectLink; +extern OLECLIPFORMAT cfLink; +extern OLECLIPFORMAT cfNative; + +extern ATOM aStdHostNames; +extern ATOM aStdTargetDevice ; +extern ATOM aStdDocDimensions; +extern ATOM aStdDocName; +extern ATOM aStdColorScheme; +extern ATOM aNullArg; +extern ATOM aSave; +extern ATOM aChange; +extern ATOM aClose; +extern ATOM aPackage; + +extern HANDLE hInstDLL; +extern DWORD dwVerToFile; +extern DWORD dwVerFromFile; +extern WORD wWinVer; +extern BOOL bProtMode; + +// Used by QuerySize() API; +extern DWORD dwObjSize; + +extern OLESTREAM dllStream; +extern BOOL bWLO; + +//////////////////////////////////////////////////////////////////////////// +// +// Note: Whenever this table is changed, then we need to update the +// method table in ole.h. Otherwise we are in trouble. +// +//////////////////////////////////////////////////////////////////////////// + +typedef struct _OLEOBJECTVTBL{ + LPVOID (FAR PASCAL *QueryProtocol) (LPVOID, LPSTR); + OLESTATUS (FAR PASCAL *Release) (LPVOID); + OLESTATUS (FAR PASCAL *Show) (LPVOID, BOOL); + OLESTATUS (FAR PASCAL *DoVerb) (LPVOID, WORD, BOOL, BOOL); + OLESTATUS (FAR PASCAL *GetData) (LPVOID, OLECLIPFORMAT, LPHANDLE); + OLESTATUS (FAR PASCAL *SetData) (LPVOID, OLECLIPFORMAT, HANDLE); + OLESTATUS (FAR PASCAL *SetTargetDevice) (LPVOID, HANDLE); + OLESTATUS (FAR PASCAL *SetBounds) (LPVOID, LPRECT); + OLECLIPFORMAT (FAR PASCAL *EnumFormats) (LPVOID, OLECLIPFORMAT); + + OLESTATUS (FAR PASCAL *SetColorScheme) (LPVOID, LPLOGPALETTE); + OLESTATUS (FAR PASCAL *Delete) (LPVOID); + OLESTATUS (FAR PASCAL *SetHostNames) (LPVOID, LPSTR, LPSTR); + + OLESTATUS (FAR PASCAL *SaveToStream) (LPVOID, LPOLESTREAM); + OLESTATUS (FAR PASCAL *Clone) (LPVOID, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPVOID); + OLESTATUS (FAR PASCAL *CopyFromLink) (LPVOID, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPVOID); + OLESTATUS (FAR PASCAL *Equal) (LPVOID, LPVOID); + OLESTATUS (FAR PASCAL *CopyToClipboard) (LPVOID); + OLESTATUS (FAR PASCAL *Draw) (LPVOID, HDC, LPRECT, LPRECT, HDC); + OLESTATUS (FAR PASCAL *Activate) (LPVOID, WORD, BOOL, BOOL, HWND, LPRECT); + OLESTATUS (FAR PASCAL *Execute) (LPVOID, HANDLE, WORD); + OLESTATUS (FAR PASCAL *Close) (LPVOID); + OLESTATUS (FAR PASCAL *Update) (LPVOID); + OLESTATUS (FAR PASCAL *Reconnect) (LPVOID); + + OLESTATUS (FAR PASCAL *ObjectConvert) (LPVOID, LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *); + + OLESTATUS (FAR PASCAL *GetLinkUpdateOptions) (LPVOID, OLEOPT_UPDATE FAR *); + OLESTATUS (FAR PASCAL *SetLinkUpdateOptions) (LPVOID, OLEOPT_UPDATE); + OLESTATUS (FAR PASCAL *Rename) (LPVOID, LPSTR); + OLESTATUS (FAR PASCAL *QueryName) (LPVOID, LPSTR, WORD FAR *); + OLESTATUS (FAR PASCAL *QueryType) (LPVOID, LPLONG); + OLESTATUS (FAR PASCAL *QueryBounds) (LPVOID, LPRECT); + OLESTATUS (FAR PASCAL *QuerySize) (LPVOID, DWORD FAR *); + OLESTATUS (FAR PASCAL *QueryOpen) (LPVOID); + OLESTATUS (FAR PASCAL *QueryOutOfDate) (LPVOID); + + OLESTATUS (FAR PASCAL *QueryReleaseStatus) (LPVOID); + OLESTATUS (FAR PASCAL *QueryReleaseError) (LPVOID); + OLE_RELEASE_METHOD (FAR PASCAL *QueryReleaseMethod) (LPVOID); + + OLESTATUS (FAR PASCAL *RequestData) (LPVOID, OLECLIPFORMAT); + OLESTATUS (FAR PASCAL *ObjectLong) (LPVOID, WORD, LPLONG); + OLESTATUS (FAR PASCAL *ChangeData) (LPVOID, HANDLE, LPOLECLIENT, BOOL); + +} OLEOBJECTVTBL; + +typedef OLEOBJECTVTBL FAR *LPOLEOBJECTVTBL; + + +typedef struct _OLEOBJECT { /*object */ + LPOLEOBJECTVTBL lpvtbl; + char objId[2]; + HOBJECT hobj; + LPOLECLIENT lpclient; + LONG ctype; + LONG cx; + LONG cy; + LONG mm; + int iTable; // Index into the dll table + ATOM aObjName; //** Client + LHCLIENTDOC lhclientdoc; // Document + LPOLEOBJECT lpPrevObj; // related + LPOLEOBJECT lpNextObj; //** fileds + LPOLEOBJECT lpParent; // NULL for LE or Static objects. +} OBJECT; + + + +typedef struct _CF_NAME_ATOM { + char * cfName; + ATOM cfAtom; +} CF_NAME_ATOM; + +extern CF_NAME_ATOM cfNameAtom[]; + + +typedef struct _METADC { + int xMwo; + int yMwo; + int xMwe; + int yMwe; + int xre; + int yre; + struct _METADC * pNext; +} METADC, *PMETADC; + +typedef struct _METAINFO { + METADC headDc; + int xwo; + int ywo; + int xwe; + int ywe; + int xro; + int yro; +} METAINFO, *PMETAINFO; + +typedef struct OBJECT_MF { /* object_mf */ + OBJECT head; + DWORD sizeBytes; + METAFILEPICT mfp; + HANDLE hmfp; + BOOL fMetaDC; + OLESTATUS error; + int nRecord; + PMETAINFO pMetaInfo; + PMETADC pCurMdc; +} OBJECT_MF; + +typedef OBJECT_MF FAR * LPOBJECT_MF; + + + +typedef struct +{ + OBJECT head; + DWORD sizeBytes; + int xSize; // width in pixels + int ySize; // height in pixels + HBITMAP hBitmap; +} OBJECT_BM; + +typedef OBJECT_BM FAR * LPOBJECT_BM; + + + +typedef struct _OBJECT_DIB { + OBJECT head; + DWORD sizeBytes; + int xSize; + int ySize; + HANDLE hDIB; +} OBJECT_DIB; + +typedef OBJECT_DIB FAR * LPOBJECT_DIB; + + + +typedef struct +{ + OBJECT head; + OLECLIPFORMAT cfFormat; + ATOM aClass; + DWORD sizeBytes; + HANDLE hData; +} OBJECT_GEN; + +typedef OBJECT_GEN FAR * LPOBJECT_GEN; + + + +typedef struct _RENDER_ENTRY { /* dll_entry */ + LPSTR lpClass; + ATOM aClass; + OLESTATUS (FARINTERNAL *Load) (LPOLESTREAM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); +} RENDER_ENTRY; + + +typedef struct _DLL_ENTRY { + ATOM aDll; /* global atom for dll name with full path */ + HANDLE hDll; /* handle to the dll module */ + int cObj; /* count of objects, unload dll when this is 0 */ + OLESTATUS (FAR PASCAL *Load) (LPOLESTREAM, LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG, ATOM, OLECLIPFORMAT); + + OLESTATUS (FAR PASCAL *Clip) (LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, LONG); + + OLESTATUS (FAR PASCAL *Link) (LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + + OLESTATUS (FAR PASCAL *CreateFromTemplate) (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + + OLESTATUS (FAR PASCAL *Create) (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + + OLESTATUS (FAR PASCAL *CreateFromFile) (LPSTR, LPOLECLIENT, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + + OLESTATUS (FAR PASCAL *CreateLinkFromFile) (LPSTR, LPOLECLIENT, LPSTR, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + OLESTATUS (FAR PASCAL *CreateInvisible) (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, BOOL); + +} DLL_ENTRY; + + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in OLE.C // +// // +///////////////////////////////////////////////////////////////////////////// + +BOOL INTERNAL CheckObject(LPOLEOBJECT); +BOOL FARINTERNAL FarCheckObject(LPOLEOBJECT); +OLESTATUS INTERNAL LeQueryCreateFromClip (LPSTR, OLEOPT_RENDER, OLECLIPFORMAT, LONG); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in DEFCREAT.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FAR PASCAL DefLoadFromStream (LPOLESTREAM, LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG, ATOM, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL DefCreateFromClip (LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, LONG); + +OLESTATUS FAR PASCAL DefCreateLinkFromClip (LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL DefCreateFromTemplate (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL DefCreate (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL DefCreateFromFile (LPSTR, LPOLECLIENT, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL DefCreateLinkFromFile (LPSTR, LPOLECLIENT, LPSTR, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL DefCreateInvisible (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, BOOL); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in PBHANDLR.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FAR PASCAL PbLoadFromStream (LPOLESTREAM, LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG, ATOM, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL PbCreateFromClip (LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, LONG); + +OLESTATUS FAR PASCAL PbCreateLinkFromClip (LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL PbCreateFromTemplate (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL PbCreate (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL PbCreateFromFile (LPSTR, LPOLECLIENT, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL PbCreateLinkFromFile (LPSTR, LPOLECLIENT, LPSTR, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FAR PASCAL PbCreateInvisible (LPSTR, LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, BOOL); + + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Defines common for le.c, ledde.c, dde.c, doc.c // +// // +///////////////////////////////////////////////////////////////////////////// + + +// Constants for chekcing whether the instance is SrvrDLL instance. + +#define WW_LPTR 0 // ptr tosrvr/doc/item +#define WW_LE 4 // signature +#define WW_HANDLE 6 // instance handle + +#define WC_LE 0x4c45 // LE chars + + +// command flags +#define ACT_SHOW 0x0001 // show the window +#define ACT_ACTIVATE 0x0002 // activate +#define ACT_DOVERB 0x0004 // Run the item +#define ACT_ADVISE 0x0008 // advise for data +#define ACT_REQUEST 0x0010 // request for data +#define ACT_CLOSE 0x0020 // request for advise only on close +#define ACT_UNLAUNCH 0x0040 // unload the server after all the +#define ACT_TERMSRVR 0x0080 // terminate server +#define ACT_TERMDOC 0x0100 // terminate document + +#define ACT_NATIVE 0x0200 // only for LNKed objects, if we + // need native data. + +#define ACT_MINIMIZE 0x0400 // launch the app minimized + +#define ACT_NOLAUNCH 0x0800 // don't launch the server + + +#define LN_TEMPLATE 0x0000 // create from template +#define LN_NEW 0x1000 // create new +#define LN_EMBACT 0x2000 // activate emb +#define LN_LNKACT 0x3000 // activate link +#define LN_MASK 0xf000 // launch mask +#define LN_SHIFT 12 // shift count for LN_MASK + +typedef struct _EDIT_DDE { /* edit_dde */ + HANDLE hInst; + int extraTerm; + HWND hClient; + HWND hServer; + BOOL bTerminating; + BOOL bAbort; + BOOL bCallLater; // used in request cases. if this is FALSE + // then OLE_CHANGED is sent to client + int awaitAck; + HANDLE hopt; // Memory block I may have to free + int nAdviseClose; // count of outstanding advises on closes + int nAdviseSave; // count of outstanding advises on save + HANDLE hData; // Poked data/ temp for holding the + // handle in DDE messages + + // busy parameters + LONG lParam; // lparam value in case we need to + // repost the message + WORD msg; // busy repost message + + WORD wTimer; // timer id. +} EDIT_DDE; + +typedef EDIT_DDE NEAR *PEDIT_DDE; +typedef EDIT_DDE FAR *LPEDIT_DDE; + +typedef struct _OBJECT_LE { /* object_le */ + OBJECT head; + ATOM app; + ATOM topic; + ATOM item; + ATOM aServer; + BOOL bOldLink; // whether a linked object for old link + BOOL bOleServer; // server which supports the verbs + WORD verb; // verb nuymber; + WORD fCmd; // Command flags; + OLEOPT_UPDATE optUpdate; + OLEOPT_UPDATE optNew; // new update options + LPSTR lptemplate; // ptr to the template string, if + // create from template + + ATOM aNetName; // network name on which the doc is + char cDrive; // local drive for that network + DWORD dwNetInfo; // LOW WORD = Net type + // HIGH WORD = Driver version + + LPOLEOBJECT lpobjPict; + + LONG lAppData; // apps data + LONG lHandlerData; // handler data + + HANDLE hnative; + HANDLE hLink; + HANDLE hhostNames; // host name block + HANDLE htargetDevice; // target device info + HANDLE hdocDimensions; // document dimensions + HANDLE hextraData; // reqestdata handle + WORD cfExtra; // extra format data + HANDLE hlogpal; // logiccal palette + + + WORD oldasyncCmd; // previous asynchronous command + WORD asyncCmd; // asynchronous command + BOOL endAsync; // true if we need to send END_RELEASE. + BOOL bAsync; // true if async command on. + WORD mainRtn; // main async routine + WORD subRtn; // step within the main async routine + WORD mainErr; // failure error + WORD subErr; // step error + WORD errHint; // ;error hint + + BOOL bSvrClosing; // TRUE - server in the process of + // closing down + BOOL bUnlaunchLater; // Call EmbLnkDelete from EndAsyncCmd + // if this flag is TRUE + + HANDLE hSysEdit; // handle to system edit. + PEDIT_DDE pSysEdit; // near ptr to system edit. + HANDLE hDocEdit; // handle to doc level channel + PEDIT_DDE pDocEdit; // near ptr to the doc level channel + +} OBJECT_LE; +typedef OBJECT_LE FAR * LPOBJECT_LE; + + +typedef struct _CLIENTDOC { /* object_le */ + char docId[2]; + LPOLEOBJECT lpHeadObj; + LPOLEOBJECT lpTailObj; + ATOM aClass; + ATOM aDoc; + HANDLE hdoc; + struct _CLIENTDOC FAR * lpPrevDoc; + struct _CLIENTDOC FAR * lpNextDoc; +} CLIENTDOC; +typedef CLIENTDOC FAR * LPCLIENTDOC; + + +typedef struct _HOSTNAMES { + WORD clientNameOffset; + WORD documentNameOffset; + BYTE data[]; +} HOSTNAMES; + +typedef HOSTNAMES FAR * LPHOSTNAMES; + +typedef struct _BOUNDSRECT { + WORD defaultWidth; + WORD defaultHeight; + WORD maxWidth; + WORD maxHeight; +} BOUNDSRECT; + +typedef BOUNDSRECT FAR *LPBOUNDSRECT; + + +// AwaitAck values +#define AA_REQUEST 1 +#define AA_ADVISE 2 +#define AA_POKE 3 +#define AA_EXECUTE 4 +#define AA_UNADVISE 5 +#define AA_INITIATE 6 + +// Bits for Positive WM_DDE_ACK +#define POSITIVE_ACK 0x8000 + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in LE.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +LPVOID FARINTERNAL LeQueryProtocol (LPOBJECT_LE, LPSTR); +OLESTATUS FARINTERNAL LeRelease (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeClone (LPOBJECT_LE, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOBJECT_LE FAR *); +OLESTATUS FARINTERNAL LeCopyFromLink (LPOBJECT_LE, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOBJECT_LE FAR *); +OLESTATUS FARINTERNAL LeEqual (LPOBJECT_LE, LPOBJECT_LE); +OLESTATUS FARINTERNAL LeCopy (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeQueryBounds (LPOBJECT_LE, LPRECT); +OLESTATUS FARINTERNAL LeDraw (LPOBJECT_LE, HDC, LPRECT, LPRECT, HDC); +OLECLIPFORMAT FARINTERNAL LeEnumFormat (LPOBJECT_LE, OLECLIPFORMAT); +OLESTATUS FARINTERNAL LeGetData (LPOBJECT_LE, OLECLIPFORMAT, HANDLE FAR *); +OLESTATUS FARINTERNAL LeRequestData (LPOBJECT_LE, OLECLIPFORMAT); +OLESTATUS FARINTERNAL LeQueryOutOfDate (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeObjectConvert (LPOBJECT_LE, LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *); +OLESTATUS FARINTERNAL LeChangeData (LPOBJECT_LE, HANDLE, LPOLECLIENT, BOOL); +LPOBJECT_LE FARINTERNAL LeCreateBlank(LHCLIENTDOC, LPSTR, LONG); +void FARINTERNAL SetExtents (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeSaveToStream (LPOBJECT_LE, LPOLESTREAM); +OLESTATUS FARINTERNAL LeLoadFromStream (LPOLESTREAM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG, ATOM, OLECLIPFORMAT); +OLESTATUS INTERNAL LeStreamRead (LPOLESTREAM, LPOBJECT_LE); +OLESTATUS INTERNAL LeStreamWrite (LPOLESTREAM, LPOBJECT_LE); +int FARINTERNAL ContextCallBack (LPVOID, OLE_NOTIFICATION); +void INTERNAL DeleteObjectAtoms (LPOBJECT_LE); +void FARINTERNAL DeleteExtraData (LPOBJECT_LE); + +OLESTATUS FARINTERNAL LeGetUpdateOptions (LPOBJECT_LE, OLEOPT_UPDATE FAR *); +OLESTATUS FARINTERNAL LnkPaste (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, OLECLIPFORMAT); +OLESTATUS FARINTERNAL EmbPaste (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); +BOOL INTERNAL SetLink (LPOBJECT_LE, HANDLE, LPSTR FAR *); +HANDLE INTERNAL GetLink (LPOBJECT_LE); +void FARINTERNAL SetEmbeddedTopic (LPOBJECT_LE); + +OLESTATUS FAR PASCAL LeQueryReleaseStatus (LPOBJECT_LE); +OLESTATUS FAR PASCAL LeQueryReleaseError (LPOBJECT_LE); +OLE_RELEASE_METHOD FAR PASCAL LeQueryReleaseMethod (LPOBJECT_LE); + +OLESTATUS FARINTERNAL LeQueryType (LPOBJECT_LE, LPLONG); +OLESTATUS FARINTERNAL LeObjectLong (LPOBJECT_LE, WORD, LPLONG); + + +void SetNetDrive (LPOBJECT_LE); + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in LEDDE.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FARINTERNAL LeDoVerb (LPOBJECT_LE, WORD, BOOL, BOOL); +OLESTATUS FARINTERNAL LeShow (LPOBJECT_LE, BOOL); +OLESTATUS FARINTERNAL LeQueryOpen (LPOBJECT_LE); +BOOL INTERNAL QueryOpen (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeActivate (LPOBJECT_LE, WORD, BOOL, BOOL, HWND, LPRECT); +OLESTATUS FARINTERNAL LeUpdate (LPOBJECT_LE); +OLESTATUS FARINTERNAL EmbOpen (LPOBJECT_LE, BOOL, BOOL, HWND, LPRECT); +OLESTATUS FARINTERNAL EmbUpdate (LPOBJECT_LE); +OLESTATUS FARINTERNAL EmbOpenUpdate (LPOBJECT_LE); +OLESTATUS FARINTERNAL LnkOpen (LPOBJECT_LE, BOOL, BOOL, HWND, LPRECT); +OLESTATUS FARINTERNAL LnkUpdate (LPOBJECT_LE); +OLESTATUS FARINTERNAL LnkOpenUpdate (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeClose (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeReconnect (LPOBJECT_LE); +OLESTATUS INTERNAL PokeNativeData (LPOBJECT_LE); +BOOL INTERNAL PostMessageToServer (PEDIT_DDE, WORD, LONG); + +OLESTATUS FARINTERNAL LeCreateFromTemplate (LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FARINTERNAL LeCreate (LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT); + +OLESTATUS FARINTERNAL LeCreateInvisible (LPOLECLIENT, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, BOOL); + +OLESTATUS FARINTERNAL CreateFromClassOrTemplate (LPOLECLIENT, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, WORD, LPSTR, LHCLIENTDOC, LPSTR); + +OLESTATUS FARINTERNAL CreateEmbLnkFromFile (LPOLECLIENT, LPSTR, LPSTR, LPSTR, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, LONG); + +OLESTATUS FARINTERNAL LeSetUpdateOptions (LPOBJECT_LE, OLEOPT_UPDATE); + +void INTERNAL AdvisePict (LPOBJECT_LE, ATOM); +void INTERNAL UnAdvisePict (LPOBJECT_LE); +int INTERNAL GetPictType (LPOBJECT_LE); +void INTERNAL AdviseOn (LPOBJECT_LE, int, ATOM); +void INTERNAL UnAdviseOn (LPOBJECT_LE, int); +void INTERNAL RequestOn (LPOBJECT_LE, int); +void INTERNAL RequestPict (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeSetHostNames (LPOBJECT_LE, LPSTR, LPSTR); +OLESTATUS INTERNAL PokeHostNames (LPOBJECT_LE); +OLESTATUS INTERNAL SetHostNamesHandle (LPOBJECT_LE, LPSTR, LPSTR); +void INTERNAL FreePokeData (LPOBJECT_LE, PEDIT_DDE); +OLESTATUS INTERNAL SendPokeData (LPOBJECT_LE, ATOM, HANDLE, OLECLIPFORMAT); +OLESTATUS FARINTERNAL LeSetTargetDevice (LPOBJECT_LE, HANDLE); +OLESTATUS INTERNAL PokeTargetDeviceInfo (LPOBJECT_LE); +OLESTATUS INTERNAL PokeDocDimensions (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeSetBounds (LPOBJECT_LE, LPRECT); +OLESTATUS FARINTERNAL LeSetData (LPOBJECT_LE, OLECLIPFORMAT, HANDLE); +BOOL INTERNAL SendSrvrMainCmd (LPOBJECT_LE, LPSTR); +ATOM INTERNAL ExtendAtom (LPOBJECT_LE, ATOM); +BOOL INTERNAL CreatePictObject (LHCLIENTDOC, LPSTR, LPOBJECT_LE, OLEOPT_RENDER, OLECLIPFORMAT, LPSTR); +BOOL INTERNAL IsSrvrDLLwnd (HWND, HANDLE); +OLESTATUS INTERNAL ChangeDocAndItem (LPOBJECT_LE, HANDLE); +BOOL QueryUnlaunch (LPOBJECT_LE); +BOOL QueryClose (LPOBJECT_LE); +OLESTATUS FARINTERNAL LeSetColorScheme (LPOBJECT_LE, LPLOGPALETTE); +OLESTATUS INTERNAL PokeColorScheme (LPOBJECT_LE); +OLESTATUS FARINTERNAL ProbeAsync (LPOBJECT_LE); +BOOL INTERNAL IsServerValid (LPOBJECT_LE); +BOOL INTERNAL IsWindowValid (HWND); +OLESTATUS FARINTERNAL LeExecute (LPOBJECT_LE, HANDLE, WORD); +void INTERNAL FreeGDIdata (HANDLE, OLECLIPFORMAT); +BOOL INTERNAL CanPutHandleInPokeBlock (LPOBJECT_LE, OLECLIPFORMAT); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in DDE.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +long FARINTERNAL DocWndProc(HWND, unsigned, WORD, LONG ); +long FARINTERNAL SrvrWndProc(HWND, unsigned, WORD, LONG ); +BOOL INTERNAL CheckAtomValid (ATOM); +void INTERNAL HandleAckInitMsg (PEDIT_DDE, HWND); +BOOL INTERNAL HandleAck (LPOBJECT_LE, PEDIT_DDE, DWORD); +void INTERNAL HandleDataMsg (LPOBJECT_LE, HANDLE, ATOM); +void INTERNAL HandleTermMsg (LPOBJECT_LE, PEDIT_DDE, HWND, BOOL); +void INTERNAL HandleTimerMsg (LPOBJECT_LE, PEDIT_DDE); +void INTERNAL SetData (LPOBJECT_LE, HANDLE, int); +BOOL INTERNAL DeleteBusyData (LPOBJECT_LE, PEDIT_DDE); +void INTERNAL DeleteAbortData (LPOBJECT_LE, PEDIT_DDE); + +BOOL INTERNAL WaitDDE (HWND, BOOL); +BOOL INTERNAL WaitDDEAck (PEDIT_DDE); + +BOOL INTERNAL InitSrvrConv (LPOBJECT_LE, HANDLE); +void INTERNAL TermSrvrConv (LPOBJECT_LE); +void INTERNAL DeleteSrvrEdit (LPOBJECT_LE); +BOOL INTERNAL SrvrExecute (LPOBJECT_LE, HANDLE); +void INTERNAL SendStdExit (LPOBJECT_LE); +void INTERNAL SendStdClose (LPOBJECT_LE); +void INTERNAL SendStdExit (LPOBJECT_LE); + +BOOL FARINTERNAL InitDocConv (LPOBJECT_LE, BOOL); +BOOL INTERNAL DocExecute (LPOBJECT_LE, HANDLE); +void INTERNAL TermDocConv (LPOBJECT_LE); +void INTERNAL DeleteDocEdit (LPOBJECT_LE); + +HANDLE INTERNAL LeLaunchApp (LPOBJECT_LE); +HANDLE INTERNAL LoadApp (LPSTR, WORD); + +int INTERNAL ScanItemOptions (ATOM, int FAR *); +void INTERNAL ChangeDocName (LPOBJECT_LE, LPSTR); +BOOL INTERNAL CanCallback (LPOBJECT_LE, int); + +void FARINTERNAL CallEmbLnkDelete (LPOBJECT_LE); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Picture Object routines used by routines in other modules // +// // +///////////////////////////////////////////////////////////////////////////// + + +LPOBJECT_BM FARINTERNAL BmCreateBlank (LHCLIENTDOC, LPSTR, LONG); +OLESTATUS FARINTERNAL BmLoadFromStream (LPOLESTREAM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); +OLESTATUS FARINTERNAL BmPaste (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); + + +LPOBJECT_DIB FARINTERNAL DibCreateBlank (LHCLIENTDOC, LPSTR, LONG); +LPOBJECT_DIB FARINTERNAL DibCreateObject (HANDLE, LPOLECLIENT, BOOL, LHCLIENTDOC, LPSTR, LONG); +OLESTATUS FARINTERNAL DibLoadFromStream (LPOLESTREAM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); +OLESTATUS FARINTERNAL DibPaste (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); + + +LPOBJECT_MF FARINTERNAL MfCreateBlank (LHCLIENTDOC, LPSTR, LONG); +LPOBJECT_MF FARINTERNAL MfCreateObject (HANDLE, LPOLECLIENT, BOOL, LHCLIENTDOC, LPSTR, LONG); + +OLESTATUS FARINTERNAL MfLoadFromStream (LPOLESTREAM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); +OLESTATUS FARINTERNAL MfPaste (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG); + + +LPOBJECT_GEN FARINTERNAL GenCreateBlank (LHCLIENTDOC, LPSTR, LONG, ATOM); +OLESTATUS FARINTERNAL GenLoadFromStream (LPOLESTREAM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LONG, ATOM, OLECLIPFORMAT); +OLESTATUS FARINTERNAL GenPaste (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, LPSTR, OLECLIPFORMAT, LONG); + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in MAIN.C // +// // +///////////////////////////////////////////////////////////////////////////// + +void FARINTERNAL UnloadDll (void); +int FARINTERNAL LoadDll (LPSTR); +void FARINTERNAL DecreaseHandlerObjCount (int); + +void FARINTERNAL RemoveLinkStringFromTopic (LPOBJECT_LE); + +OLESTATUS FARINTERNAL CreatePictFromClip (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, LPSTR, LONG); + +OLESTATUS FARINTERNAL CreatePackageFromClip (LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *, OLEOPT_RENDER, OLECLIPFORMAT, LONG); + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in UTILS.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +BOOL PutStrWithLen (LPOLESTREAM, LPSTR); +BOOL GetStrWithLen (LPOLESTREAM, LPSTR); +ATOM GetAtomFromStream (LPOLESTREAM); +BOOL PutAtomIntoStream (LPOLESTREAM, ATOM); +BOOL GetBytes (LPOLESTREAM, LPSTR, LONG); +BOOL PutBytes (LPOLESTREAM, LPSTR, LONG); +BOOL QueryApp (LPSTR, LPSTR, LPSTR); +HANDLE MapStrToH (LPSTR); +void UtilMemClr (PSTR, WORD); +BOOL QueryHandler (WORD); + +OLESTATUS INTERNAL FileExists (LPOBJECT_LE); +ATOM FARINTERNAL GetAppAtom (LPSTR); +HANDLE FARINTERNAL DuplicateGlobal (HANDLE, WORD); +HANDLE FARINTERNAL CopyData (LPSTR, DWORD); +ATOM FARINTERNAL DuplicateAtom (ATOM); +BOOL FARINTERNAL UtilQueryProtocol (LPOBJECT_LE, LPSTR); +BOOL FARINTERNAL CmpGlobals (HANDLE, HANDLE); +void FARINTERNAL ConvertToHimetric(LPPOINT); +BOOL FARINTERNAL QueryVerb (LPOBJECT_LE, WORD, LPSTR, LONG); +BOOL FARINTERNAL MapExtToClass (LPSTR, LPSTR, int); +int FARINTERNAL GlobalGetAtomLen (ATOM); +void FARINTERNAL UtilMemCpy (LPSTR, LPSTR, DWORD); +BOOL FARINTERNAL UtilMemCmp (LPSTR, LPSTR, DWORD); +BOOL FARINTERNAL IsObjectBlank (LPOBJECT_LE); + +OLESTATUS FARINTERNAL ObjQueryName (LPOLEOBJECT, LPSTR, WORD FAR *); +OLESTATUS FARINTERNAL ObjRename (LPOLEOBJECT, LPSTR); +void INTERNAL SetExeAtom (LPOBJECT_LE); + + +// !!!make a routine and let the macro call the routine +// definitions related to the asynchronous operations. +#define WAIT_FOR_ASYNC_MSG(lpobj) { \ + lpobj->subRtn++; \ + if (lpobj->bAsync){ \ + lpobj->endAsync = TRUE; \ + return OLE_WAIT_FOR_RELEASE; \ + } \ +} + +#define STEP_NOP(lpobj) lpobj->subRtn++; + +// !!! Assumes all the creates are in order +#define PROBE_CREATE_ASYNC(lpobj) \ + if (lpobj->asyncCmd >= OLE_CREATE && \ + lpobj->asyncCmd <= OLE_CREATEINVISIBLE) {\ + if(ProbeAsync(lpobj) == OLE_BUSY)\ + return OLE_BUSY;\ + } + +#define PROBE_OBJECT_BLANK(lpobj) \ + if (lpobj->asyncCmd >= OLE_CREATE && \ + lpobj->asyncCmd <= OLE_CREATEFROMFILE) { \ + if ((ProbeAsync(lpobj) == OLE_BUSY) && IsObjectBlank(lpobj)) \ + return OLE_ERROR_BLANK;\ + } + +#define PROBE_ASYNC(lpobj)\ + if(ProbeAsync(lpobj) == OLE_BUSY)\ + return OLE_BUSY; + +#define IS_SVRCLOSING(lpobj)\ + ((lpobj->bUnlaunchLater || lpobj->bSvrClosing) ? TRUE : FALSE) + +#define PROBE_SVRCLOSING(lpobj)\ + if (IS_SVRCLOSING(lpobj)) \ + return OLE_ERROR_NOT_OPEN; \ + + +#define CLEAR_STEP_ERROR(lpobj) lpobj->subErr = OLE_OK; + + +#define SKIP_TO(a, b) if (a) goto b; +#define RESETERR(lpobj) lpobj->mainErr = OLE_OK +#define SETSTEP(lpobj, no) lpobj->subRtn = no +#define SETERRHINT(lpobj, no) lpobj->errHint = no +#define CLEARASYNCCMD(lpobj) lpobj->asyncCmd = OLE_NONE + +// routines. +BOOL ProcessErr (LPOBJECT_LE); +void InitAsyncCmd (LPOBJECT_LE, WORD, WORD); +void NextAsyncCmd (LPOBJECT_LE, WORD); +void ScheduleAsyncCmd (LPOBJECT_LE); +OLESTATUS EndAsyncCmd (LPOBJECT_LE); +OLESTATUS DocShow (LPOBJECT_LE); +OLESTATUS DocRun (LPOBJECT_LE); +void SendStdShow (LPOBJECT_LE); +OLESTATUS EmbLnkClose (LPOBJECT_LE); +OLESTATUS LnkSetUpdateOptions (LPOBJECT_LE); +OLESTATUS EmbSrvrUnlaunch (LPOBJECT_LE); +OLESTATUS LnkChangeLnk (LPOBJECT_LE); +OLESTATUS RequestData (LPOBJECT_LE, OLECLIPFORMAT); + +OLESTATUS FARINTERNAL EmbLnkDelete(LPOBJECT_LE); + +void FARINTERNAL FarInitAsyncCmd(LPOBJECT_LE, WORD, WORD); + +// async command routines. +#define EMBLNKDELETE 1 +#define LNKOPENUPDATE 2 +#define DOCSHOW 3 +#define EMBOPENUPDATE 4 +#define EMBLNKCLOSE 5 +#define LNKSETUPDATEOPTIONS 6 +#define LNKCHANGELNK 7 +#define REQUESTDATA 8 +#define DOCRUN 9 + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in DOC.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +BOOL FARINTERNAL CheckClientDoc (LPCLIENTDOC); +void FARINTERNAL DocAddObject (LPCLIENTDOC, LPOLEOBJECT, LPSTR); +void FARINTERNAL DocDeleteObject (LPOLEOBJECT); +LPOLEOBJECT INTERNAL DocGetNextObject (LPCLIENTDOC, LPOLEOBJECT); + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in NET.C // +// // +///////////////////////////////////////////////////////////////////////////// + +#define IDD_DRIVE 500 +#define IDD_PASSWORD 501 +#define IDD_PATH 502 + +#define IDS_NETERR 600 +#define IDS_NETCONERRMSG 601 +#define IDS_FILENOTFOUNDMSG 602 +#define IDS_BADPATHMSG 603 + +OLESTATUS FARINTERNAL SetNetName (LPOBJECT_LE); +BOOL FARINTERNAL SetNextNetDrive (LPOBJECT_LE, int FAR *, LPSTR); +OLESTATUS FARINTERNAL CheckNetDrive (LPOBJECT_LE, BOOL); +OLESTATUS INTERNAL FixNet (LPOBJECT_LE, LPSTR, BOOL); +OLESTATUS INTERNAL ConnectNet (LPOBJECT_LE, LPSTR); +BOOL FARINTERNAL ChangeTopic (LPOBJECT_LE); +VOID INTERNAL FillDrives (HWND); +int FAR PASCAL ConnectDlgProc(HWND, WORD, WORD, DWORD); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in OLE.ASM // +// // +///////////////////////////////////////////////////////////////////////////// + +WORD GetGDIds (DWORD); +WORD IsMetaDC (HDC, WORD); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in ERROR.C // +// // +///////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL ObjQueryType (LPOLEOBJECT, LPLONG); +OLESTATUS FARINTERNAL ObjQuerySize (LPOLEOBJECT, DWORD FAR *); +DWORD PASCAL FAR DllPut (LPOLESTREAM, LPSTR, DWORD); +HANDLE FARINTERNAL DuplicateGDIdata (HANDLE, OLECLIPFORMAT); + + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in BM.C // +// // +///////////////////////////////////////////////////////////////////////////// + +HBITMAP FARINTERNAL BmDuplicate (HBITMAP, DWORD FAR *, LPBITMAP); diff --git a/private/mvdm/wow16/ole/client/doc.c b/private/mvdm/wow16/ole/client/doc.c new file mode 100644 index 000000000..c4ae63c02 --- /dev/null +++ b/private/mvdm/wow16/ole/client/doc.c @@ -0,0 +1,316 @@ +/****************************** Module Header ******************************\ +* Module Name: doc.c +* +* PURPOSE: Contains client document maipulation routines. +* +* Created: Jan 1991 +* +* Copyright (c) 1991 Microsoft Corporation +* +* History: +* Srinik 01/11/1191 Orginal +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" + +#ifdef FIREWALLS +extern BOOL bShowed; +extern void FARINTERNAL ShowVersion (void); +#endif + +LPCLIENTDOC lpHeadDoc = NULL; +LPCLIENTDOC lpTailDoc = NULL; + +extern ATOM aClipDoc; +extern int iUnloadableDll; + +#pragma alloc_text(_TEXT, CheckClientDoc, CheckPointer) + + +OLESTATUS FAR PASCAL OleRegisterClientDoc (lpClassName, lpDocName, future, lplhclientdoc) +LPSTR lpClassName; +LPSTR lpDocName; +LONG future; +LHCLIENTDOC FAR * lplhclientdoc; +{ + HANDLE hdoc = NULL; + LPCLIENTDOC lpdoc; + OLESTATUS retVal; + ATOM aClass, aDoc; + + +#ifdef FIREWALLS + if (!bShowed && (ole_flags & DEBUG_MESSAGEBOX)) + ShowVersion (); +#endif + + Puts ("OleRegisterClientDoc"); + + PROBE_MODE(bProtMode); + FARPROBE_WRITE(lplhclientdoc); + *lplhclientdoc = NULL; + FARPROBE_READ(lpClassName); + FARPROBE_READ(lpDocName); + if (!lpDocName[0]) + return OLE_ERROR_NAME; + + aDoc = GlobalAddAtom (lpDocName); + aClass = GlobalAddAtom (lpClassName); + + if (!(hdoc = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE, + sizeof(CLIENTDOC))) + || !(lpdoc = (LPCLIENTDOC) GlobalLock (hdoc))) { + retVal = OLE_ERROR_MEMORY; + goto err; + } + + lpdoc->docId[0] = 'C'; + lpdoc->docId[1] = 'D'; + lpdoc->aClass = aClass; + lpdoc->aDoc = aDoc; + lpdoc->hdoc = hdoc; + + // Documents are doubly linked + + if (!lpHeadDoc) { +#ifdef FIREWALLS + ASSERT(!lpTailDoc, "lpTailDoc is not NULL"); +#endif + lpHeadDoc = lpTailDoc = lpdoc; + } + else { + lpTailDoc->lpNextDoc = lpdoc; + lpdoc->lpPrevDoc = lpTailDoc; + lpTailDoc = lpdoc; + } + + *lplhclientdoc = (LHCLIENTDOC) lpdoc; + + // inform the link manager; + return OLE_OK; + +err: + if (aClass) + GlobalDeleteAtom (aClass); + + if (aDoc) + GlobalDeleteAtom (aDoc); + + if (hdoc) + GlobalFree (hdoc); + + return retVal; +} + + +OLESTATUS FAR PASCAL OleRevokeClientDoc (lhclientdoc) +LHCLIENTDOC lhclientdoc; +{ + LPCLIENTDOC lpdoc; + + Puts ("OleRevokeClientDoc"); + + // if there is any handler dll that can be freed up, free it now. + // Otherwise it might become too late if the app quits. + if (iUnloadableDll) + UnloadDll (); + + if (!CheckClientDoc (lpdoc = (LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + if (lpdoc->lpHeadObj) { + ASSERT (0, "OleRevokeClientDoc() called without freeing all objects"); + return OLE_ERROR_NOT_EMPTY; + } + + if (lpdoc->aClass) + GlobalDeleteAtom (lpdoc->aClass); + + if (lpdoc->aDoc) + GlobalDeleteAtom (lpdoc->aDoc); + + // if only one doc is in the list then it's prev and next docs are NULL + + if (lpdoc == lpHeadDoc) + lpHeadDoc = lpdoc->lpNextDoc; + + if (lpdoc == lpTailDoc) + lpTailDoc = lpdoc->lpPrevDoc; + + if (lpdoc->lpPrevDoc) + lpdoc->lpPrevDoc->lpNextDoc = lpdoc->lpNextDoc; + + if (lpdoc->lpNextDoc) + lpdoc->lpNextDoc->lpPrevDoc = lpdoc->lpPrevDoc; + + GlobalUnlock (lpdoc->hdoc); + GlobalFree (lpdoc->hdoc); + + // inform link manager + return OLE_OK; +} + + +OLESTATUS FAR PASCAL OleRenameClientDoc (lhclientdoc, lpNewDocName) +LHCLIENTDOC lhclientdoc; +LPSTR lpNewDocName; +{ + LPCLIENTDOC lpdoc; + ATOM aNewDoc; + LPOLEOBJECT lpobj = NULL; + + if (!CheckClientDoc (lpdoc = (LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + FARPROBE_READ(lpNewDocName); + + aNewDoc = GlobalAddAtom (lpNewDocName); + if (aNewDoc == lpdoc->aDoc) { + if (aNewDoc) + GlobalDeleteAtom (aNewDoc); + return OLE_OK; + } + + // Document name has changed. So, change the topic of all embedded objects + if (lpdoc->aDoc) + GlobalDeleteAtom (lpdoc->aDoc); + lpdoc->aDoc = aNewDoc; + + while (lpobj = DocGetNextObject (lpdoc, lpobj)) { + if (lpobj->ctype == CT_EMBEDDED) + if (OleQueryReleaseStatus (lpobj) != OLE_BUSY) + SetEmbeddedTopic ((LPOBJECT_LE) lpobj); + } + + return OLE_OK; +} + + +OLESTATUS FAR PASCAL OleRevertClientDoc (lhclientdoc) +LHCLIENTDOC lhclientdoc; +{ + // if there is any handler dll that can be freed up, free it now. + // Otherwise it might become too late if the app quits. + if (iUnloadableDll) + UnloadDll (); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + return OLE_OK; +} + + +OLESTATUS FAR PASCAL OleSavedClientDoc (lhclientdoc) +LHCLIENTDOC lhclientdoc; +{ + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + return OLE_OK; +} + +OLESTATUS FAR PASCAL OleEnumObjects (lhclientdoc, lplpobj) +LHCLIENTDOC lhclientdoc; +LPOLEOBJECT FAR * lplpobj; +{ + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + FARPROBE_WRITE(lplpobj); + + if (*lplpobj) { + // we are making lhclientdoc field of the object NULL at deletion + // time. The check (*lpobj->lhclientdoc != lhclientdoc) will take care + // of the case where same chunk of memory is allocated again for the + // same pointer and old contents are not erased yet. + if (!FarCheckObject (*lplpobj) + || ((*lplpobj)->lhclientdoc != lhclientdoc)) + return OLE_ERROR_OBJECT; + } + + *lplpobj = DocGetNextObject ((LPCLIENTDOC) lhclientdoc, *lplpobj); + return OLE_OK; +} + + + +LPOLEOBJECT INTERNAL DocGetNextObject (lpdoc, lpobj) +LPCLIENTDOC lpdoc; +LPOLEOBJECT lpobj; +{ + if (!lpobj) + return lpdoc->lpHeadObj; + + return lpobj->lpNextObj; +} + + +BOOL FARINTERNAL CheckClientDoc (lpdoc) +LPCLIENTDOC lpdoc; +{ + if (!CheckPointer(lpdoc, WRITE_ACCESS)) + return FALSE; + + if ((lpdoc->docId[0] == 'C') && (lpdoc->docId[1] == 'D')) + return TRUE; + return FALSE; +} + + +void FARINTERNAL DocAddObject (lpdoc, lpobj, lpobjname) +LPCLIENTDOC lpdoc; +LPOLEOBJECT lpobj; +LPSTR lpobjname; +{ + if (lpobjname) + lpobj->aObjName = GlobalAddAtom (lpobjname); + else + lpobj->aObjName = NULL; + + // Objects of a doc are doubly linked + + if (!lpdoc->lpHeadObj) + lpdoc->lpHeadObj = lpdoc->lpTailObj = lpobj; + else { + lpdoc->lpTailObj->lpNextObj = lpobj; + lpobj->lpPrevObj = lpdoc->lpTailObj; + lpdoc->lpTailObj = lpobj; + } + lpobj->lhclientdoc = (LHCLIENTDOC)lpdoc; +} + + +void FARINTERNAL DocDeleteObject (lpobj) +LPOLEOBJECT lpobj; +{ + LPCLIENTDOC lpdoc; + + if (!(lpdoc = (LPCLIENTDOC) lpobj->lhclientdoc)) + return; + + if (lpobj->aObjName) { + GlobalDeleteAtom (lpobj->aObjName); + lpobj->aObjName = NULL; + } + + // Remove this obj from object chain of the relevant client doc. + // The objects of a doc are doubly linked. + + if (lpdoc->lpHeadObj == lpobj) + lpdoc->lpHeadObj = lpobj->lpNextObj; + + if (lpdoc->lpTailObj == lpobj) + lpdoc->lpTailObj = lpobj->lpPrevObj; + + if (lpobj->lpPrevObj) + lpobj->lpPrevObj->lpNextObj = lpobj->lpNextObj; + + if (lpobj->lpNextObj) + lpobj->lpNextObj->lpPrevObj = lpobj->lpPrevObj; + + lpobj->lhclientdoc = NULL; +} + diff --git a/private/mvdm/wow16/ole/client/draw.c b/private/mvdm/wow16/ole/client/draw.c new file mode 100644 index 000000000..aee6e28b4 --- /dev/null +++ b/private/mvdm/wow16/ole/client/draw.c @@ -0,0 +1,1023 @@ +/****************************** Module Header ******************************\ +* Module Name: DRAW.C +* +* PURPOSE: Contains all the drawing related routines +* +* Created: March 1991 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* (03/21/91) Srinik Original +* (03/22/91) Srinik Added support for drawing metafile in a metafile +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" +#include "pict.h" + +#define RECORD_COUNT 16 + +int INTERNAL PaletteSize (int); +HANDLE INTERNAL DibMakeLogPalette(LPSTR, WORD, LPLOGPALETTE FAR *); +OLESTATUS FARINTERNAL wDibDraw (HANDLE, HDC, LPRECT, LPRECT, HDC, BOOL); +OLESTATUS INTERNAL wDrawBitmap (LPOBJECT_BM, HDC, HDC, LPRECT); +OLESTATUS INTERNAL wDrawBitmapUsingDib (LPOBJECT_BM, HDC, HDC, HDC, LPRECT, LPRECT); + +void SetPictOrg (LPOBJECT_MF, HDC, int, int, BOOL); +void SetPictExt (LPOBJECT_MF, HDC, int, int); +void ScalePictExt (LPOBJECT_MF, HDC, int, int, int, int); +void ScaleRectExt (LPOBJECT_MF, HDC, int, int, int, int); + +void CleanStack(LPOBJECT_MF, HANDLE); +BOOL PopDc (LPOBJECT_MF); +BOOL PushDc (LPOBJECT_MF); + +#ifdef META_DEBUG +void PutMetaFuncName (WORD); +#endif + +OLESTATUS FARINTERNAL BmDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOBJECT_BM lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + HDC hMemDC, hScreenDC; + int iScreenDevCaps; + OLESTATUS ret = OLE_OK; + + if (!lpobj->hBitmap) + return OLE_ERROR_BLANK; + + hScreenDC = GetDC (NULL); + + iScreenDevCaps = GetDeviceCaps (hScreenDC, TECHNOLOGY); + if (!OleIsDcMeta (hdc) + && (iScreenDevCaps != GetDeviceCaps (hdc, TECHNOLOGY))) { + ret = wDrawBitmapUsingDib (lpobj, hdc, hScreenDC, + hdcTarget, lprc, lpWrc); + } + else { + hMemDC = CreateCompatibleDC (hdc); + ret = wDrawBitmap (lpobj, hdc, hMemDC, lprc); + DeleteDC (hMemDC); + } + + ReleaseDC (NULL, hScreenDC); + return ret; +} + + +OLESTATUS INTERNAL wDrawBitmap (lpobj, hdc, hMemDC, lprc) +LPOBJECT_BM lpobj; +HDC hdc; +HDC hMemDC; +LPRECT lprc; +{ + HBITMAP hOldBitmap; + OLESTATUS ret = OLE_OK; + + if (!hMemDC) + return OLE_ERROR_MEMORY; + + if (!(hOldBitmap = SelectObject(hMemDC, lpobj->hBitmap))) + return OLE_ERROR_DRAW; + + if (!StretchBlt(hdc, + lprc->left, lprc->top, + (lprc->right - lprc->left), (lprc->bottom - lprc->top), + hMemDC, 0, 0, lpobj->xSize, lpobj->ySize, SRCCOPY)) { + ret = OLE_ERROR_DRAW; + } + + SelectObject (hMemDC, hOldBitmap); + return ret; +} + + +OLESTATUS INTERNAL wDrawBitmapUsingDib ( +LPOBJECT_BM lpobj, +HDC hdc, +HDC hScreenDC, +HDC hTargetDC, +LPRECT lprc, +LPRECT lpWrc) +{ + BITMAP bm; + LPBITMAPINFOHEADER lpBmi; + HANDLE hBmi, hDib = NULL; + WORD wBmiSize; + OLESTATUS retVal = OLE_ERROR_MEMORY; + + if (!GetObject(lpobj->hBitmap, sizeof(BITMAP), (LPSTR) &bm)) + return OLE_ERROR_HANDLE; + + wBmiSize = sizeof(BITMAPINFOHEADER) + + PaletteSize(bm.bmPlanes * bm.bmBitsPixel); + + if (!(hBmi = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT, (DWORD) wBmiSize))) + return OLE_ERROR_MEMORY; + + if (!(lpBmi = (LPBITMAPINFOHEADER) GlobalLock (hBmi))) { + GlobalFree (hBmi); + return OLE_ERROR_MEMORY; + } + + GlobalUnlock (hBmi); + + lpBmi->biSize = (LONG) sizeof(BITMAPINFOHEADER); + lpBmi->biWidth = (LONG) bm.bmWidth; + lpBmi->biHeight = (LONG) bm.bmHeight; + lpBmi->biPlanes = 1; + lpBmi->biBitCount = bm.bmPlanes * bm.bmBitsPixel; + lpBmi->biCompression = BI_RGB; + lpBmi->biSizeImage = 0L; + lpBmi->biXPelsPerMeter = 0L; + lpBmi->biYPelsPerMeter = 0L; + lpBmi->biClrUsed = 0L; + lpBmi->biClrImportant = 0L; + + // Call GetDIBits with a NULL lpBits parm, so that it will calculate + // the biSizeImage field for us + if (!GetDIBits(hScreenDC, lpobj->hBitmap, 0, bm.bmHeight, NULL, + (LPBITMAPINFO)lpBmi, DIB_RGB_COLORS)) + return OLE_ERROR_HANDLE; + + // Realloc the buffer to provide space for the bits + if (!(hDib = GlobalReAlloc (hBmi, (wBmiSize + lpBmi->biSizeImage), + GMEM_MOVEABLE))) { + GlobalFree (hBmi); + return OLE_ERROR_MEMORY; + } + + // If reallocation gave a new handle then lock that handle and get the + // long pointer to it. + if (hDib != hBmi) { + if (!(lpBmi = (LPBITMAPINFOHEADER) GlobalLock (hDib))) + goto errRtn; + GlobalUnlock (hDib); + } + + // Call GetDIBits with a NON-NULL lpBits parm, and get the actual bits + + if (!GetDIBits(hScreenDC, lpobj->hBitmap, 0, (WORD) lpBmi->biHeight, + ((LPSTR)lpBmi)+wBmiSize, + (LPBITMAPINFO) lpBmi, + DIB_RGB_COLORS)) { + retVal = OLE_ERROR_HANDLE; + goto errRtn; + } + + retVal = wDibDraw (hDib, hdc, lprc, lpWrc, hTargetDC, FALSE); + +errRtn: + if (hDib) + GlobalFree (hDib); + return retVal; +} + + +OLESTATUS FARINTERNAL DibDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOBJECT_DIB lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + return wDibDraw (lpobj->hDIB, hdc, lprc, lpWrc, hdcTarget, FALSE); +} + + + +OLESTATUS FARINTERNAL wDibDraw (hData, hdc, lprc, lpWrc, hdcTarget, bPbrushData) +HANDLE hData; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +BOOL bPbrushData; +{ + // !!! current implementation is not using hdcTarget + OLESTATUS ret = OLE_ERROR_DRAW; + LPSTR lpData; + HANDLE hPalette = NULL; + HPALETTE hLogPalette = NULL, hOldPalette = NULL; + LPLOGPALETTE lpLogPalette; + WORD wPalSize; + int iOffBits; + + if (!hData) + return OLE_ERROR_BLANK; + + if (!(lpData = GlobalLock (hData))) + return OLE_ERROR_MEMORY; + + if (bPbrushData) + lpData += sizeof(BITMAPFILEHEADER); + + wPalSize = PaletteSize (((LPBITMAPINFOHEADER)lpData)->biBitCount); + iOffBits = sizeof(BITMAPINFOHEADER) + wPalSize; + + // if color palette exits do the following + if (wPalSize) { + if (!(hLogPalette = DibMakeLogPalette(lpData+sizeof(BITMAPINFOHEADER), + wPalSize, &lpLogPalette))) { + ret = OLE_ERROR_MEMORY; + goto end; + } + + if (!(hPalette = CreatePalette (lpLogPalette))) + goto end; + + // select as a background palette + if (!(hOldPalette = SelectPalette (hdc, hPalette, TRUE))) + goto end; + + RealizePalette(hdc); + } + + if (!StretchDIBits(hdc, + lprc->left, lprc->top, + (lprc->right - lprc->left), (lprc->bottom - lprc->top), + 0, 0, + (WORD) ((LPBITMAPINFOHEADER)lpData)->biWidth, + (WORD) ((LPBITMAPINFOHEADER)lpData)->biHeight, + lpData + iOffBits, + ((LPBITMAPINFO) lpData), + DIB_RGB_COLORS, + SRCCOPY)) { + ret = OLE_ERROR_DRAW; + } + else + ret = OLE_OK; + +end: + // if color palette exists do the following + if (wPalSize) { + hOldPalette = (OleIsDcMeta (hdc) ? GetStockObject(DEFAULT_PALETTE) + : hOldPalette); + if (hOldPalette) { + // select as a background palette + SelectPalette (hdc, hOldPalette, TRUE); + RealizePalette (hdc); + } + + if (hPalette) + DeleteObject (hPalette); + + if (hLogPalette) + GlobalFree (hLogPalette); + } + + GlobalUnlock (hData); + return ret; +} + + + + + +HANDLE INTERNAL DibMakeLogPalette (lpColorData, wDataSize, lplpLogPalette) +LPSTR lpColorData; +WORD wDataSize; +LPLOGPALETTE FAR * lplpLogPalette; +{ + HANDLE hLogPalette=NULL; + LPLOGPALETTE lpLogPalette; + DWORD dwLogPalSize = wDataSize + 2 * sizeof(WORD); + LPPALETTEENTRY lpPE; + RGBQUAD FAR * lpQuad; + + if (!(hLogPalette = GlobalAlloc(GMEM_MOVEABLE,dwLogPalSize))) + return NULL; + + if (!(lpLogPalette = (LPLOGPALETTE) GlobalLock (hLogPalette))) { + GlobalFree (hLogPalette); + return NULL; + } + + GlobalUnlock (hLogPalette); + *lplpLogPalette = lpLogPalette; + + lpLogPalette->palVersion = 0x300; + lpLogPalette->palNumEntries = wDataSize / sizeof(PALETTEENTRY); + + /* now convert RGBQUAD to PALETTEENTRY as we copy color info */ + for (lpQuad = (RGBQUAD far *)lpColorData, + lpPE = (LPPALETTEENTRY)lpLogPalette->palPalEntry, + wDataSize /= sizeof(RGBQUAD); + wDataSize--; + ++lpQuad,++lpPE) { + lpPE->peFlags=0; + lpPE->peRed = lpQuad->rgbRed; + lpPE->peBlue = lpQuad->rgbBlue; + lpPE->peGreen = lpQuad->rgbGreen; + } + + return hLogPalette; +} + + +int INTERNAL PaletteSize (int iBitCount) +{ + switch (iBitCount) { + case 1: + return (2*sizeof(RGBQUAD)); + + case 4: + return (16*sizeof(RGBQUAD)); + + case 8: + return (256*sizeof(RGBQUAD)); + + default: + return 0; /* A 24 bitcount DIB has no color table */ + } +} + + +OLESTATUS FARINTERNAL GenDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOBJECT_GEN lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + return OLE_ERROR_GENERIC; +} + + + + + + + +//*** All the following routines are relevant for metafile drawing only + + +OLESTATUS FARINTERNAL MfDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOBJECT_MF lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + HANDLE hInfo; + int iOldDc; + RECT rect; + LPRECT lpRrc = (LPRECT) ▭ + + rect.left = lprc->left; + rect.right = lprc->right; + rect.top = lprc->top; + rect.bottom = lprc->bottom; + + if (!lpobj->mfp.hMF) + return OLE_ERROR_BLANK; + + lpobj->nRecord = RECORD_COUNT; + lpobj->fMetaDC = OleIsDcMeta (hdc); + + if (!(iOldDc = SaveDC (hdc))) + return OLE_ERROR_MEMORY; + + IntersectClipRect (hdc, lpRrc->left, lpRrc->top, + lpRrc->right, lpRrc->bottom); + + if (!lpobj->fMetaDC) { + LPtoDP (hdc, (LPPOINT) lpRrc, 2); + SetMapMode (hdc, MM_ANISOTROPIC); + SetViewportOrg (hdc, lpRrc->left, lpRrc->top); + SetViewportExt (hdc, lpRrc->right - lpRrc->left, + lpRrc->bottom - lpRrc->top); + } + else { + + iOldDc = -1; + + if (!lpWrc) { +#ifdef FIREWALLS + ASSERT(0, "Pointer to rect is null") +#endif + return OLE_ERROR_DRAW; + } + + if (!(hInfo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, + sizeof(METAINFO)))) + return OLE_ERROR_MEMORY; + + if (!(lpobj->pMetaInfo = (PMETAINFO) LocalLock (hInfo))) { + LocalFree (hInfo); + return OLE_ERROR_MEMORY; + } + + LocalUnlock (hInfo); + + lpobj->pCurMdc = (PMETADC) (lpobj->pMetaInfo); + + lpobj->pMetaInfo->xwo = lpWrc->left; + lpobj->pMetaInfo->ywo = lpWrc->top; + lpobj->pMetaInfo->xwe = lpWrc->right; + lpobj->pMetaInfo->ywe = lpWrc->bottom; + + lpobj->pMetaInfo->xro = lpRrc->left - lpWrc->left; + lpobj->pMetaInfo->yro = lpRrc->top - lpWrc->top; + + lpobj->pCurMdc->xre = lpRrc->right - lpRrc->left; + lpobj->pCurMdc->yre = lpRrc->bottom - lpRrc->top; + + } + + lpobj->error = OLE_OK; + MfInterruptiblePaint(lpobj, hdc); + + if (lpobj->fMetaDC) + CleanStack (lpobj, hInfo); + + RestoreDC (hdc, iOldDc); + return lpobj->error; +} + + +void INTERNAL MfInterruptiblePaint (lpobj, hdc) +LPOBJECT_MF lpobj; +HDC hdc; +{ + FARPROC lpCallbackFunc; + + if (!(lpCallbackFunc = MakeProcInstance (MfCallbackFunc, hInstDLL))) + PlayMetaFile (hdc, lpobj->mfp.hMF); + else { + EnumMetaFile (hdc,lpobj->mfp.hMF, lpCallbackFunc, (LPARAM) lpobj); + FreeProcInstance (lpCallbackFunc); + } +} + + + +int FARINTERNAL MfCallbackFunc (hdc, lpHTable, lpMFR, nObj, lpobj) +HDC hdc; +LPHANDLETABLE lpHTable; +LPMETARECORD lpMFR; +int nObj; +BYTE FAR * lpobj; +{ + LPOBJECT_MF lpobjMf; + + lpobjMf = (LPOBJECT_MF) lpobj; + if (!--lpobjMf->nRecord) { + lpobjMf->nRecord = RECORD_COUNT; + if (!ContextCallBack ((lpobjMf->head.lpParent + ? lpobjMf->head.lpParent + : (LPOLEOBJECT) lpobjMf), + OLE_QUERY_PAINT)) { + lpobjMf->error = OLE_ERROR_ABORT; + return FALSE; + } + } + + if (lpobjMf->fMetaDC) { + +#ifdef META_DEBUG + PutMetaFuncName (lpMFR->rdFunction); +#endif + + switch (lpMFR->rdFunction) { + case META_SETWINDOWORG: + SetPictOrg (lpobjMf, hdc, lpMFR->rdParm[1], + lpMFR->rdParm[0], FALSE); + return TRUE; + + case META_OFFSETWINDOWORG: + SetPictOrg (lpobjMf, hdc, lpMFR->rdParm[1], + lpMFR->rdParm[0], TRUE); + return TRUE; + + case META_SETWINDOWEXT: + SetPictExt (lpobjMf, hdc, lpMFR->rdParm[1], lpMFR->rdParm[0]); + return TRUE; + + case META_SCALEWINDOWEXT: + ScalePictExt (lpobjMf, hdc, + lpMFR->rdParm[3], lpMFR->rdParm[2], + lpMFR->rdParm[1], lpMFR->rdParm[0]); + return TRUE; + + case META_SAVEDC: + if (!PushDc (lpobjMf)) + return FALSE; + break; + + case META_RESTOREDC: + PopDc (lpobjMf); + break; + + case META_SCALEVIEWPORTEXT: + ScaleRectExt (lpobjMf, hdc, + lpMFR->rdParm[3], lpMFR->rdParm[2], + lpMFR->rdParm[1], lpMFR->rdParm[0]); + return TRUE; + + case META_OFFSETVIEWPORTORG: +#ifdef FIREWALLS + ASSERT(0, "OffsetViewportOrg() in metafile"); +#endif + return TRUE; + + case META_SETVIEWPORTORG: +#ifdef FIREWALLS + ASSERT(0, "SetViewportOrg() in metafile"); +#endif + return TRUE; + + case META_SETVIEWPORTEXT: +#ifdef FIREWALLS + ASSERT(0, "SetViewportExt() in metafile"); +#endif + return TRUE; + + case META_SETMAPMODE: +#ifdef FIREWALLS + ASSERT(lpMFR->rdParm[0] == MM_ANISOTROPIC, + "SetmapMode() in metafile with invalid mapping mode"); +#endif + return TRUE; + + default: + break; + } + } + else { + switch (lpMFR->rdFunction) { + DWORD exts; + + case META_SCALEWINDOWEXT: + exts = GetWindowExt (hdc); + SetWindowExt (hdc, + MulDiv(LOWORD(exts), lpMFR->rdParm[3], lpMFR->rdParm[2]), + MulDiv(HIWORD(exts), lpMFR->rdParm[1], lpMFR->rdParm[0])); + return TRUE; + + case META_SCALEVIEWPORTEXT: + exts = GetViewportExt (hdc); + SetViewportExt (hdc, + MulDiv(LOWORD(exts), lpMFR->rdParm[3], lpMFR->rdParm[2]), + MulDiv(HIWORD(exts), lpMFR->rdParm[1], lpMFR->rdParm[0])); + return TRUE; + + default: + break; + } + } + + PlayMetaFileRecord (hdc, lpHTable, lpMFR, nObj); + return TRUE; +} + + +void SetPictOrg (lpobj, hdc, xOrg, yOrg, fOffset) +LPOBJECT_MF lpobj; +HDC hdc; +int xOrg; +int yOrg; +BOOL fOffset; +{ + if (fOffset) { + // it's OffsetWindowOrg() call + lpobj->pCurMdc->xMwo += xOrg; + lpobj->pCurMdc->yMwo += yOrg; + } + else { + // it's SetWindowOrg() + lpobj->pCurMdc->xMwo = xOrg; + lpobj->pCurMdc->yMwo = yOrg; + } + + if (lpobj->pCurMdc->xMwe && lpobj->pCurMdc->yMwe) { + SetWindowOrg (hdc, + (lpobj->pCurMdc->xMwo - MulDiv (lpobj->pMetaInfo->xro, + lpobj->pCurMdc->xMwe, + lpobj->pCurMdc->xre)), + (lpobj->pCurMdc->yMwo - MulDiv (lpobj->pMetaInfo->yro, + lpobj->pCurMdc->yMwe, + lpobj->pCurMdc->yre))); + } +} + + +void SetPictExt (lpobj, hdc, xExt, yExt) +LPOBJECT_MF lpobj; +HDC hdc; +int xExt; +int yExt; +{ + lpobj->pCurMdc->xMwe = xExt; + lpobj->pCurMdc->yMwe = yExt; + + SetWindowExt (hdc, + MulDiv (lpobj->pMetaInfo->xwe, xExt, lpobj->pCurMdc->xre), + MulDiv (lpobj->pMetaInfo->ywe, yExt, lpobj->pCurMdc->yre)); + + SetWindowOrg (hdc, + (lpobj->pCurMdc->xMwo + - MulDiv (lpobj->pMetaInfo->xro, xExt, lpobj->pCurMdc->xre)), + (lpobj->pCurMdc->yMwo + - MulDiv (lpobj->pMetaInfo->yro, yExt, lpobj->pCurMdc->yre))); +} + + +void ScalePictExt (lpobj, hdc, xNum, xDenom, yNum, yDenom) +LPOBJECT_MF lpobj; +HDC hdc; +int xNum; +int xDenom; +int yNum; +int yDenom; +{ + SetPictExt (lpobj, hdc, MulDiv (lpobj->pCurMdc->xMwe, xNum, xDenom), + MulDiv (lpobj->pCurMdc->yMwe, yNum, yDenom)); +} + + +void ScaleRectExt (lpobj, hdc, xNum, xDenom, yNum, yDenom) +LPOBJECT_MF lpobj; +HDC hdc; +int xNum; +int xDenom; +int yNum; +int yDenom; +{ + lpobj->pCurMdc->xre = MulDiv (lpobj->pCurMdc->xre, xNum, xDenom); + lpobj->pCurMdc->yre = MulDiv (lpobj->pCurMdc->yre, yNum, yDenom); + + SetPictExt (lpobj, hdc, lpobj->pCurMdc->xMwe, lpobj->pCurMdc->yMwe); +} + + + +BOOL PushDc (lpobj) +LPOBJECT_MF lpobj; +{ + HANDLE hNode = NULL; + PMETADC pNode = NULL; + + if ((hNode = LocalAlloc (LMEM_MOVEABLE, sizeof (METADC))) + && (pNode = (PMETADC) LocalLock (hNode))) { + *pNode = *lpobj->pCurMdc; + lpobj->pCurMdc->pNext = pNode; + pNode->pNext = NULL; + lpobj->pCurMdc = pNode; + LocalUnlock (hNode); + return TRUE; + } + + if (pNode) + LocalFree (hNode); + + lpobj->error = OLE_ERROR_MEMORY; + return FALSE; +} + + +BOOL PopDc (lpobj) +LPOBJECT_MF lpobj; +{ + PMETADC pPrev = (PMETADC) (lpobj->pMetaInfo); + PMETADC pCur = ((PMETADC) (lpobj->pMetaInfo))->pNext; + HANDLE hCur; + + if (!pCur) + // more Pops than Pushes + return FALSE; + + while (pCur->pNext) { + pPrev = pCur; + pCur = pCur->pNext; + } + + if (hCur = LocalHandle ((WORD) pCur)) + LocalFree (hCur); + pPrev->pNext = NULL; + lpobj->pCurMdc = pPrev; +} + + +void CleanStack(lpobj, hMetaInfo) +LPOBJECT_MF lpobj; +HANDLE hMetaInfo; +{ + PMETADC pCur = ((PMETADC) (lpobj->pMetaInfo))->pNext; + HANDLE hCur; + + while (pCur) { + hCur = LocalHandle ((WORD) pCur); + ((PMETADC) (lpobj->pMetaInfo))->pNext = pCur = pCur->pNext; + if (hCur) + LocalFree (hCur); + } + + LocalFree (hMetaInfo); + lpobj->fMetaDC = FALSE; + lpobj->pCurMdc = NULL; + lpobj->pMetaInfo = NULL; +} + +#ifdef META_DEBUG +void PutMetaFuncName (value) +WORD value; +{ + switch (value) { + case META_SETBKCOLOR: + OutputDebugString ("SetBkColor "); + break; + + case META_SETBKMODE: + OutputDebugString ("SetBkMode "); + break; + + case META_SETMAPMODE: + OutputDebugString ("SetMapMode "); + break; + + case META_SETROP2: + OutputDebugString ("SetRop2 "); + break; + + case META_SETRELABS: + OutputDebugString ("SetRelabs "); + break; + + case META_SETPOLYFILLMODE: + OutputDebugString ("SetPolyfillMode "); + break; + + case META_SETSTRETCHBLTMODE: + OutputDebugString ("SetStretchBltMode "); + break; + + case META_SETTEXTCHAREXTRA: + OutputDebugString ("SetTextCharExtra "); + break; + + case META_SETTEXTCOLOR: + OutputDebugString ("SetTextColor "); + break; + + case META_SETTEXTJUSTIFICATION: + OutputDebugString ("SetTextJustification "); + break; + + case META_SETWINDOWORG: + OutputDebugString ("SetWindowOrg "); + break; + + case META_SETWINDOWEXT: + OutputDebugString ("SetWindowExt "); + break; + + case META_SETVIEWPORTORG: + OutputDebugString ("SetViewportOrg "); + break; + + case META_SETVIEWPORTEXT: + OutputDebugString ("SetViewportExt "); + break; + + case META_OFFSETWINDOWORG: + OutputDebugString ("OffsetWindowOrg "); + break; + + case META_SCALEWINDOWEXT: + OutputDebugString ("ScaleWindowExt "); + break; + + case META_OFFSETVIEWPORTORG: + OutputDebugString ("OffsetViewportOrg "); + break; + + case META_SCALEVIEWPORTEXT: + OutputDebugString ("ScaleViewportExt "); + break; + + case META_LINETO: + OutputDebugString ("LineTo "); + break; + + case META_MOVETO: + OutputDebugString ("MoveTo "); + break; + + case META_EXCLUDECLIPRECT: + OutputDebugString ("ExcludeCliprect "); + break; + + case META_INTERSECTCLIPRECT: + OutputDebugString ("IntersectCliprect "); + break; + + case META_ARC: + OutputDebugString ("Arc "); + break; + + case META_ELLIPSE: + OutputDebugString ("Ellipse "); + break; + + case META_FLOODFILL: + OutputDebugString ("FloodFill "); + break; + + case META_PIE: + OutputDebugString ("Pie "); + break; + + case META_RECTANGLE: + OutputDebugString ("Rectangle "); + break; + + case META_ROUNDRECT: + OutputDebugString ("RoundRect "); + break; + + case META_PATBLT: + OutputDebugString ("PatBlt "); + break; + + case META_SAVEDC: + OutputDebugString ("SaveDC "); + break; + + case META_SETPIXEL: + OutputDebugString ("SetPixel "); + break; + + case META_OFFSETCLIPRGN: + OutputDebugString ("OffsetClipRegion "); + break; + + case META_TEXTOUT: + OutputDebugString ("TextOut "); + break; + + case META_BITBLT: + OutputDebugString ("BitBlt "); + break; + + case META_STRETCHBLT: + OutputDebugString ("StrechBlt "); + break; + + case META_POLYGON: + OutputDebugString ("Polygon "); + break; + + case META_POLYLINE: + OutputDebugString ("PolyLine "); + break; + + case META_ESCAPE: + OutputDebugString ("Escape "); + break; + + case META_RESTOREDC: + OutputDebugString ("RestoreDC "); + break; + + case META_FILLREGION: + OutputDebugString ("FillRegion "); + break; + + case META_FRAMEREGION: + OutputDebugString ("FrameRegion "); + break; + + case META_INVERTREGION: + OutputDebugString ("InvertRegion "); + break; + + case META_PAINTREGION: + OutputDebugString ("PaintRegion "); + break; + + case META_SELECTCLIPREGION: + OutputDebugString ("SelectClipRegion "); + break; + + case META_SELECTOBJECT: + OutputDebugString ("SelectObject "); + break; + + case META_SETTEXTALIGN: + OutputDebugString ("SetTextAlign "); + break; + + case META_DRAWTEXT: + OutputDebugString ("DrawText"); + break; + + case META_CHORD: + OutputDebugString ("Chord "); + break; + + case META_SETMAPPERFLAGS: + OutputDebugString ("SetMapperFlags "); + break; + + case META_EXTTEXTOUT: + OutputDebugString ("ExtTextOut "); + break; + + case META_SETDIBTODEV: + OutputDebugString ("SetDIBitsToDevice "); + break; + + case META_SELECTPALETTE: + OutputDebugString ("SelectPalette "); + break; + + case META_REALIZEPALETTE: + OutputDebugString ("RealizePalette "); + break; + + case META_ANIMATEPALETTE: + OutputDebugString ("AnimatePalette "); + break; + + case META_SETPALENTRIES: + OutputDebugString ("SetPaletteEntries "); + break; + + case META_POLYPOLYGON: + OutputDebugString ("PolyPolygon "); + break; + + case META_RESIZEPALETTE: + OutputDebugString ("ResizePalette "); + break; + + case META_DIBBITBLT: + OutputDebugString ("DibBitBlt "); + break; + + case META_DIBSTRETCHBLT: + OutputDebugString ("DibStrechBlt "); + break; + + case META_DIBCREATEPATTERNBRUSH: + OutputDebugString ("DibCreatePatternBrush "); + break; + + case META_STRETCHDIB: + OutputDebugString ("StretchDIBits "); + break; + + case META_DELETEOBJECT: + OutputDebugString ("DeleteObject "); + break; + + case META_CREATEPALETTE: + OutputDebugString ("CreatePalette "); + break; + + case META_CREATEBRUSH: + OutputDebugString ("CreateBrush "); + break; + + case META_CREATEPATTERNBRUSH: + OutputDebugString ("CreatePatternBrush "); + break; + + case META_CREATEPENINDIRECT: + OutputDebugString ("CreatePenIndirect "); + break; + + case META_CREATEFONTINDIRECT: + OutputDebugString ("CreateFontIndirect "); + break; + + case META_CREATEBRUSHINDIRECT: + OutputDebugString ("CreateBrushIndirect "); + break; + + case META_CREATEBITMAPINDIRECT: + OutputDebugString ("CreateBitmapIndirect "); + break; + + case META_CREATEBITMAP: + OutputDebugString ("CreateBitmap "); + break; + + case META_CREATEREGION: + OutputDebugString ("CreateRegion "); + break; + + default: + OutputDebugString ("Invalid+Function+encountered "); + break; + + } +} +#endif diff --git a/private/mvdm/wow16/ole/client/error.c b/private/mvdm/wow16/ole/client/error.c new file mode 100644 index 000000000..a32b18ab2 --- /dev/null +++ b/private/mvdm/wow16/ole/client/error.c @@ -0,0 +1,281 @@ +/****************************** Module Header ******************************\ +* Module Name: ERROR.C +* +* PURPOSE: Contains routines which are commonly used, as method functions, by +* bm.c, mf.c and dib.c. These routines do nothing more than +* returning an error code. +* +* Created: November 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, Srinik (11/20/90) Original +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" +#include "pict.h" + +OLESTATUS FARINTERNAL ErrQueryRelease (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_ERROR_STATIC; +} + +OLESTATUS FARINTERNAL ErrPlay (lpobj, verb, fShow, fAct) +WORD verb; +LPOLEOBJECT lpobj; +BOOL fAct; +BOOL fShow; +{ + return OLE_ERROR_STATIC; +} + + +OLESTATUS FARINTERNAL ErrShow (lpobj, fAct) +LPOLEOBJECT lpobj; +BOOL fAct; +{ + return OLE_ERROR_STATIC; +} + +OLESTATUS FARINTERNAL ErrAbort (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_ERROR_STATIC; +} + +OLESTATUS FARINTERNAL ErrCopyFromLink(lpobj, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOLEOBJECT lpobj; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + return OLE_ERROR_STATIC; +} + + +OLESTATUS FARINTERNAL ErrSetHostNames (lpobj, lpclientName, lpdocName) +LPOLEOBJECT lpobj; +LPSTR lpclientName; +LPSTR lpdocName; +{ + return OLE_ERROR_STATIC; +} + + +OLESTATUS FARINTERNAL ErrSetTargetDevice (lpobj, hDevInfo) +LPOLEOBJECT lpobj; +HANDLE hDevInfo; +{ + return OLE_ERROR_STATIC; +} + + +OLESTATUS FARINTERNAL ErrSetColorScheme (lpobj, lplogpal) +LPOLEOBJECT lpobj; +LPLOGPALETTE lplogpal; +{ + return OLE_ERROR_STATIC; +} + + +OLESTATUS FARINTERNAL ErrSetBounds(lpobj, lprc) +LPOLEOBJECT lpobj; +LPRECT lprc; +{ + return OLE_ERROR_MEMORY; +} + + +OLESTATUS FARINTERNAL ErrQueryOpen (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_ERROR_STATIC; // static object +} + + +OLESTATUS FARINTERNAL ErrActivate (lpobj, verb, fShow, fAct, hWnd, lprc) +LPOLEOBJECT lpobj; +WORD verb; +BOOL fShow; +BOOL fAct; +HWND hWnd; +LPRECT lprc; +{ + return OLE_ERROR_STATIC; // static object +} + +OLESTATUS FARINTERNAL ErrEdit (lpobj, fShow, hWnd, lprc) +LPOLEOBJECT lpobj; +BOOL fShow; +HWND hWnd; +LPRECT lprc; +{ + return OLE_ERROR_STATIC; // static object +} + +OLESTATUS FARINTERNAL ErrClose (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_ERROR_STATIC; // static object +} + + +OLESTATUS FARINTERNAL ErrUpdate (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_ERROR_STATIC; // static object +} + + +OLESTATUS FARINTERNAL ErrReconnect (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_ERROR_STATIC; // static object + +} + + +OLESTATUS FARINTERNAL ErrSetData (lpobj, cfFormat, hData) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +HANDLE hData; +{ + return OLE_ERROR_MEMORY; +} + + +OLESTATUS FARINTERNAL ErrReadFromStream (lpobj, cfFormat, lpstream) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +LPOLESTREAM lpstream; +{ + return OLE_ERROR_STREAM; +} + + + +OLESTATUS FARINTERNAL ErrQueryOutOfDate (lpobj) +LPOLEOBJECT lpobj; +{ + return OLE_OK; +} + + +OLESTATUS FARINTERNAL ErrObjectConvert (lpobj, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOLEOBJECT lpobj; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + return OLE_ERROR_STATIC; +} + + +OLESTATUS FARINTERNAL ErrGetUpdateOptions (lpobj, lpoptions) +LPOLEOBJECT lpobj; +OLEOPT_UPDATE FAR *lpoptions; +{ + return OLE_ERROR_STATIC; + +} + +OLESTATUS FARINTERNAL ErrSetUpdateOptions (lpobj, options) +LPOLEOBJECT lpobj; +OLEOPT_UPDATE options; +{ + return OLE_ERROR_STATIC; + +} + +LPVOID FARINTERNAL ErrQueryProtocol (lpobj, lpprotocol) +LPOLEOBJECT lpobj; +LPSTR lpprotocol; +{ + return NULL; +} + +OLESTATUS FARINTERNAL ErrRequestData (lpobj, cfFormat) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +{ + return OLE_ERROR_STATIC; + +} + +OLESTATUS FARINTERNAL ErrExecute (lpobj, hData, wReserved) +LPOLEOBJECT lpobj; +HANDLE hData; +WORD wReserved; +{ + return OLE_ERROR_STATIC; +} + + + +OLESTATUS FARINTERNAL ErrObjectLong (lpobj, wFlags, lplong) +LPOLEOBJECT lpobj; +WORD wFlags; +LPLONG lplong; +{ + return OLE_ERROR_STATIC; +} + + +HANDLE FARINTERNAL DuplicateGDIdata (hSrcData, cfFormat) +HANDLE hSrcData; +OLECLIPFORMAT cfFormat; +{ + if (cfFormat == CF_METAFILEPICT) { + LPMETAFILEPICT lpSrcMfp; + LPMETAFILEPICT lpDstMfp = NULL; + HANDLE hMF = NULL; + HANDLE hDstMfp = NULL; + + if (!(lpSrcMfp = (LPMETAFILEPICT) GlobalLock(hSrcData))) + return NULL; + + GlobalUnlock (hSrcData); + + if (!(hMF = CopyMetaFile (lpSrcMfp->hMF, NULL))) + return NULL; + + if (!(hDstMfp = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT)))) + goto errMfp; + + if (!(lpDstMfp = (LPMETAFILEPICT) GlobalLock (hDstMfp))) + goto errMfp; + + GlobalUnlock (hDstMfp); + + *lpDstMfp = *lpSrcMfp; + lpDstMfp->hMF = hMF; + return hDstMfp; +errMfp: + if (hMF) + DeleteMetaFile (hMF); + + if (hDstMfp) + GlobalFree (hDstMfp); + + return NULL; + } + + if (cfFormat == CF_BITMAP) { + DWORD dwSize; + + return BmDuplicate (hSrcData, &dwSize, NULL); + } + + if (cfFormat == CF_DIB) + return DuplicateGlobal (hSrcData, GMEM_MOVEABLE); + + return NULL; +} + diff --git a/private/mvdm/wow16/ole/client/funchead.c b/private/mvdm/wow16/ole/client/funchead.c new file mode 100644 index 000000000..d76977875 --- /dev/null +++ b/private/mvdm/wow16/ole/client/funchead.c @@ -0,0 +1,21 @@ + +////////////////////////////////////////////////////////////////////////////// +// +// int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine) +// +// The main library entry point. This routine is called when the library +// is loaded. +// +// Arguments: +// +// hInst - +// wDataSeg - +// cbHeapSize - +// lpszCmdLine - +// +// Returns: +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + diff --git a/private/mvdm/wow16/ole/client/generic.c b/private/mvdm/wow16/ole/client/generic.c new file mode 100644 index 000000000..ccf6e84d6 --- /dev/null +++ b/private/mvdm/wow16/ole/client/generic.c @@ -0,0 +1,531 @@ +/****************************** Module Header ******************************\ +* Module Name: GENERIC.C +* +* Handles all API routines for the generic sub-dll of the ole dll. +* Since the data format is unknown, all the routines are written with the +* assumption that all the relevant data is placed in a single global data +* segment. Note that this assumption is not valid for metafiles, bitmaps, and +* and there can always be some other formats with such idiosyncracies. To +* accommodate those cases the rendering dll writer should replace the relevant +* routines after the creation of the generic object. If for a given class this +* assumption (about data format) is valid then the dll writer need to replace +* only the Draw and QueryBounds functions. +* +* Created: November-1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* +* Srinik, Raor (11/05/90) Designed, coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" +#include "pict.h" + +char aMacText[4] = {'T', 'E', 'X', 'T'}; +char aMacRtf[4] = "RTF"; + +extern OLESTATUS FARINTERNAL wCreateDummyMetaFile (LPOBJECT_MF, int, int); + +#pragma alloc_text(_TEXT, GenSaveToStream, GenLoadFromStream, GetBytes, PutBytes, PutStrWithLen, PutAtomIntoStream, GenQueryBounds) + + +OLEOBJECTVTBL vtblGEN = { + + ErrQueryProtocol, // check whether the speced protocol is supported + + GenRelease, // Release + ErrShow, // Show + ErrPlay, // plat + GenGetData, // Get the object data + GenSetData, // Set the object data + ErrSetTargetDevice, // + + ErrSetBounds, // set viewport bounds + GenEnumFormat, // enumerate supported formats + ErrSetColorScheme, // + GenRelease, // delete + ErrSetHostNames, // + + GenSaveToStream, // write to file + GenClone, // clone object + ErrCopyFromLink, // Create embedded from Link + + GenEqual, // compares the given objects for data equality + + GenCopy, // copy to clip + + GenDraw, // draw the object + + ErrActivate, // open + ErrExecute, // excute + ErrClose, // Stop + ErrUpdate, // Update + ErrReconnect, // Reconnect + + ErrObjectConvert, // convert object to specified type + + ErrGetUpdateOptions, // update options + ErrSetUpdateOptions, // update options + + ObjRename, // Change Object name + ObjQueryName, // Get current object name + + GenQueryType, // Object type + GenQueryBounds, // QueryBounds + ObjQuerySize, // Find the size of the object + ErrQueryOpen, // Query open + ErrQueryOutOfDate, // query whether object is current + + ErrQueryRelease, // release related stuff + ErrQueryRelease, + ErrQueryRelease, + + ErrRequestData, // requestdata + ErrObjectLong, // objectLong + GenChangeData // change data of the existing object +}; + + +OLESTATUS FARINTERNAL GenRelease (lpobj) +LPOBJECT_GEN lpobj; +{ + HOBJECT hobj; + + if (lpobj->hData) { + GlobalFree (lpobj->hData); + lpobj->hData = NULL; + } + + if (lpobj->aClass) + GlobalDeleteAtom (lpobj->aClass); + + if (lpobj->head.lhclientdoc) + DocDeleteObject ((LPOLEOBJECT) lpobj); + + if (hobj = lpobj->head.hobj){ + lpobj->head.hobj = NULL; + GlobalUnlock (hobj); + GlobalFree (hobj); + } + + return OLE_OK; +} + + + +OLESTATUS FARINTERNAL GenSaveToStream (lpobj, lpstream) +LPOBJECT_GEN lpobj; +LPOLESTREAM lpstream; +{ + LPSTR lpData; + OLESTATUS retVal = OLE_OK; + DWORD dwClipFormat = NULL; + char formatName[MAX_STR]; + + if (!lpobj->hData) + return OLE_ERROR_BLANK; + + if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutAtomIntoStream (lpstream, lpobj->aClass)) + return OLE_ERROR_STREAM; + + if (lpobj->cfFormat < 0xC000) + // then it is a predefined format + dwClipFormat = lpobj->cfFormat; + + if (PutBytes (lpstream, (LPSTR) &dwClipFormat, sizeof(DWORD))) + return OLE_ERROR_STREAM; + + if (!dwClipFormat) { + if (!GetClipboardFormatName (lpobj->cfFormat, (LPSTR) formatName, + sizeof(formatName))) + return OLE_ERROR_FORMAT; + + if (PutStrWithLen (lpstream, formatName)) + return OLE_ERROR_STREAM; + } + + if (!lpobj->sizeBytes) + return OLE_ERROR_BLANK; + + if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(DWORD))) + return OLE_ERROR_STREAM; + + if (!(lpData = GlobalLock (lpobj->hData))) + return OLE_ERROR_MEMORY; + + if (PutBytes (lpstream, lpData, lpobj->sizeBytes)) + retVal = OLE_ERROR_STREAM; + + GlobalUnlock (lpobj->hData); + return retVal; +} + + +OLESTATUS FARINTERNAL GenClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_GEN lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_GEN FAR * lplpobj; +{ + if (!lpobjsrc->hData) + return OLE_ERROR_BLANK; + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + if (!(*lplpobj = GenCreateObject (lpobjsrc->hData, lpclient, + FALSE, lhclientdoc, + lpobjname, lpobjsrc->head.ctype))) + return OLE_ERROR_MEMORY; + else { + (*lplpobj)->cfFormat = lpobjsrc->cfFormat; + (*lplpobj)->aClass = DuplicateAtom (lpobjsrc->aClass); + return OLE_OK; + } +} + + + +OLESTATUS FARINTERNAL GenEqual (lpobj1, lpobj2) +LPOBJECT_GEN lpobj1; +LPOBJECT_GEN lpobj2; +{ + if (CmpGlobals (lpobj1->hData, lpobj2->hData)) + return OLE_OK; + + return OLE_ERROR_NOT_EQUAL; +} + + + +OLESTATUS FARINTERNAL GenCopy (lpobj) +LPOBJECT_GEN lpobj; +{ + HANDLE hData; + + if (!lpobj->hData) + return OLE_ERROR_BLANK; + + if (!(hData = DuplicateGlobal (lpobj->hData, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + + SetClipboardData (lpobj->cfFormat, hData); + return OLE_OK; +} + + +OLESTATUS FARINTERNAL GenLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfFormat) +LPOLESTREAM lpstream; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +LONG objType; +ATOM aClass; +OLECLIPFORMAT cfFormat; +{ + LPOBJECT_GEN lpobj = NULL; + OLESTATUS retVal = OLE_ERROR_STREAM; + HANDLE hData; + LPSTR lpData; + DWORD dwClipFormat; + char formatName[MAX_STR]; + LONG length; + + if (!(*lplpobj = (LPOLEOBJECT) (lpobj = GenCreateBlank(lhclientdoc, + lpobjname, objType, + aClass)))) { + if (aClass) + GlobalDeleteAtom(aClass); + return OLE_ERROR_MEMORY; + } + + if (GetBytes (lpstream, (LPSTR) &dwClipFormat, sizeof (DWORD))) + goto errLoad; + + // If object is from MAC then we will keep the data intact if the data + // format is either TEXT or RTF + if (HIWORD(dwVerFromFile) == OS_MAC) { + if (dwClipFormat == *((DWORD *) aMacText)) + lpobj->cfFormat = CF_TEXT; + else if (dwClipFormat == *((DWORD *) aMacRtf)) + lpobj->cfFormat = RegisterClipboardFormat ((LPSTR) "Rich Text Format"); + else + lpobj->cfFormat = NULL; + } + else { + // object is created on windows + if (!dwClipFormat) { + // this is new file format. format name string follows + if (GetBytes (lpstream, (LPSTR) &length, sizeof (LONG)) + || GetBytes (lpstream, (LPSTR)formatName, length) + || (!(lpobj->cfFormat = RegisterClipboardFormat ((LPSTR) formatName)))) + goto errLoad; + } + else if ((lpobj->cfFormat = (WORD) dwClipFormat) >= 0xc000) { + // if format is not predefined and file format is old, then use + // what value is passed to you through "cfFormat" argument + lpobj->cfFormat = cfFormat; + } + } + + if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof (DWORD))) + goto errLoad; + + lpobj->head.lpclient = lpclient; + + retVal = OLE_ERROR_MEMORY; + if (!(hData = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes))) + goto errLoad; + + if (!(lpData = GlobalLock (hData))) + goto errMem; + + if (GetBytes (lpstream, lpData, lpobj->sizeBytes)) { + retVal = OLE_ERROR_STREAM; + GlobalUnlock (hData); + goto errMem; + } + + lpobj->hData = hData; + GlobalUnlock (hData); + + // if the object is from MAC then we want delete this and create blank + // metafile object, which draws a rectangle + if ((HIWORD(dwVerFromFile) == OS_MAC) && !lpobj->cfFormat) { + LPOBJECT_MF lpobjMf; + + OleDelete ((LPOLEOBJECT)lpobj); // delete generic object + + // Now create a dummy metafile object which draws a rectangle of size + // 1" x 1". Note that 1" = 2540 HIMETRIC units + lpobjMf = MfCreateBlank (lhclientdoc, lpobjname, objType); + lpobjMf->head.cx = lpobjMf->mfp.xExt = 2540; + lpobjMf->head.cy = - (lpobjMf->mfp.yExt = 2540); + if ((retVal = wCreateDummyMetaFile (lpobjMf, lpobjMf->mfp.xExt, + lpobjMf->mfp.yExt)) != OLE_OK) { + OleDelete ((LPOLEOBJECT) lpobjMf); + return retVal; + } + + *lplpobj = (LPOLEOBJECT) lpobjMf; + } + + return OLE_OK; + +errMem: + GlobalFree (hData); + +errLoad: + OleDelete ((LPOLEOBJECT)lpobj); + *lplpobj = NULL; + return OLE_ERROR_STREAM; +} + + + + +LPOBJECT_GEN INTERNAL GenCreateObject (hData, lpclient, fDelete, lhclientdoc, lpobjname, objType) +HANDLE hData; +LPOLECLIENT lpclient; +BOOL fDelete; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + LPOBJECT_GEN lpobj; + + if (!hData) + return NULL; + + if (lpobj = GenCreateBlank (lhclientdoc, lpobjname, objType, NULL)) { + if (GenChangeData (lpobj, hData, lpclient, fDelete) != OLE_OK) { + GenRelease (lpobj); + lpobj = NULL; + } + } + + return lpobj; +} + + +// If the routine fails then the object will be left with it's old data. +// If fDelete is TRUE, then hNewData will be deleted whether the routine +// is successful or not. + +OLESTATUS FARINTERNAL GenChangeData (lpobj, hSrcData, lpclient, fDelete) +LPOBJECT_GEN lpobj; +HANDLE hSrcData; +LPOLECLIENT lpclient; +BOOL fDelete; +{ + HANDLE hDestData; + + if (!fDelete) { + if (!(hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + } + else { + // change the ownership to yourself + if (!(hDestData = GlobalReAlloc(hSrcData,0L,GMEM_MODIFY|GMEM_SHARE))){ + hDestData = DuplicateGlobal (hSrcData, GMEM_MOVEABLE); + GlobalFree (hSrcData); + if (!hDestData) + return OLE_ERROR_MEMORY; + } + } + + lpobj->head.lpclient = lpclient; + if (lpobj->hData) + GlobalFree (lpobj->hData); + lpobj->hData = hDestData; + lpobj->sizeBytes = GlobalSize (hDestData); + + return OLE_OK; +} + + + +LPOBJECT_GEN FARINTERNAL GenCreateBlank(lhclientdoc, lpobjname, objType, aClass) +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +ATOM aClass; +{ + HOBJECT hobj; + LPOBJECT_GEN lpobj; + + if ((hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_GEN))) + == NULL) + return NULL; + + if (!(lpobj = (LPOBJECT_GEN) GlobalLock (hobj))){ + GlobalFree (hobj); + return NULL; + } + + lpobj->head.objId[0] = 'L'; + lpobj->head.objId[1] = 'E'; + lpobj->head.mm = MM_TEXT; + lpobj->head.ctype = objType; + lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblGEN; + lpobj->head.iTable = INVALID_INDEX; + lpobj->head.hobj = hobj; + lpobj->aClass = aClass; + + if (objType == CT_STATIC) + DocAddObject ((LPCLIENTDOC) lhclientdoc, + (LPOLEOBJECT) lpobj, lpobjname); + + return lpobj; +} + + +OLESTATUS FARINTERNAL GenPaste (lpclient, lhclientdoc, lpobjname, lplpobj, lpClass, cfFormat, objType) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +LPSTR lpClass; +OLECLIPFORMAT cfFormat; +LONG objType; +{ + HANDLE hData = NULL; + + *lplpobj = NULL; + if (!cfFormat) + return OLE_ERROR_FORMAT; + + if (!(hData = GetClipboardData(cfFormat))) + return OLE_ERROR_MEMORY; + + if (!(*lplpobj = (LPOLEOBJECT) GenCreateObject (hData, lpclient, + FALSE, lhclientdoc, + lpobjname, objType))) + return OLE_ERROR_MEMORY; + + ((LPOBJECT_GEN)(*lplpobj))->cfFormat = cfFormat; + ((LPOBJECT_GEN)(*lplpobj))->aClass = GlobalAddAtom (lpClass); + return OLE_OK; + +} + + + +OLESTATUS FARINTERNAL GenQueryType (lpobj, lptype) +LPOLEOBJECT lpobj; +LPLONG lptype; +{ + return OLE_ERROR_GENERIC;; +} + + + +OLESTATUS FARINTERNAL GenSetData (lpobj, cfFormat, hData) +LPOBJECT_GEN lpobj; +OLECLIPFORMAT cfFormat; +HANDLE hData; +{ + + if (lpobj->cfFormat != cfFormat) + return OLE_ERROR_FORMAT; + + if (!hData) + return OLE_ERROR_BLANK; + + GlobalFree (lpobj->hData); + lpobj->hData = hData; + lpobj->sizeBytes = GlobalSize (hData); + return OLE_OK; +} + + +OLESTATUS FARINTERNAL GenGetData (lpobj, cfFormat, lphandle) +LPOBJECT_GEN lpobj; +OLECLIPFORMAT cfFormat; +LPHANDLE lphandle; +{ + if (cfFormat != lpobj->cfFormat) + return OLE_ERROR_FORMAT; + + if (!(*lphandle = lpobj->hData)) + return OLE_ERROR_BLANK; + + return OLE_OK; + +} + + +OLECLIPFORMAT FARINTERNAL GenEnumFormat (lpobj, cfFormat) +LPOBJECT_GEN lpobj; +OLECLIPFORMAT cfFormat; +{ + if (!cfFormat) + return lpobj->cfFormat; + + return NULL; +} + + +OLESTATUS FARINTERNAL GenQueryBounds (lpobj, lpRc) +LPOBJECT_GEN lpobj; +LPRECT lpRc; +{ + lpRc->right = 0; + lpRc->left = 0; + lpRc->top = 0; + lpRc->bottom = 0; + return OLE_ERROR_GENERIC; +} + diff --git a/private/mvdm/wow16/ole/client/le.c b/private/mvdm/wow16/ole/client/le.c new file mode 100644 index 000000000..14f12c403 --- /dev/null +++ b/private/mvdm/wow16/ole/client/le.c @@ -0,0 +1,2324 @@ + +/****************************** Module Header ******************************\ +* Module Name: le.c +* +* Purpose: Handles all API routines for the dde L&E sub-dll of the ole dll. +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, srinik (../../1990,91) Designed and coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" + +#define EMB_ID_INDEX 3 // index of ones digit in #000 +char embStr[] = "#000"; + +extern HANDLE hInfo; +extern OLECLIPFORMAT cfNetworkName; + +HANDLE GetNetNameHandle (LPOBJECT_LE); +BOOL AreTopicsEqual (LPOBJECT_LE, LPOBJECT_LE); + +ATOM FARINTERNAL wAtomCat (ATOM, ATOM); + +#pragma alloc_text(_RARETEXT, LeObjectLong, LeQueryProtocol, LeEqual, AreTopicsEqual, LeObjectConvert, wAtomCat) + +#pragma alloc_text(_DDETEXT, LeRequestData, RequestData, LeChangeData, ContextCallBack, DeleteExtraData, NextAsyncCmd, InitAsyncCmd, FarInitAsyncCmd, EndAsyncCmd, ProcessErr, ScheduleAsyncCmd, LeQueryReleaseStatus, EmbLnkDelete, LeRelease, DeleteObjectAtoms, QueryClose, SendStdClose, TermDocConv, DeleteDocEdit, QueryUnlaunch, SendStdExit, QueryOpen, GetPictType, RequestOn, DocShow, EmbLnkClose, LnkSetUpdateOptions, LnkChangeLnk, TermSrvrConv, DeleteSrvrEdit, LeCopyFromLink) + +OLEOBJECTVTBL vtblLE = { + + LeQueryProtocol, // check whether the speced protocol is supported + + LeRelease, // release + LeShow, // Show + LeDoVerb, // run + LeGetData, + LeSetData, + LeSetTargetDevice, // + + LeSetBounds, // set viewport bounds + LeEnumFormat, // returns format + LeSetColorScheme, // set color scheme + LeRelease, // delete + LeSetHostNames, // + LeSaveToStream, // write to file + LeClone, // clone object + LeCopyFromLink, // Create embedded from Link + + LeEqual, // test whether the object data is similar + + LeCopy, // copy to clip + + LeDraw, // draw the object + + LeActivate, // activate + LeExecute, // excute the given commands + LeClose, // stop + LeUpdate, // Update + LeReconnect, // Reconnect + + LeObjectConvert, // convert object to specified type + + LeGetUpdateOptions, // Get Link Update options + LeSetUpdateOptions, // Set Link Update options + + ObjRename, // Change Object name + ObjQueryName, // Get current object name + + LeQueryType, // object Type + LeQueryBounds, // QueryBounds + ObjQuerySize, // Find the size of the object + LeQueryOpen, // Query open + LeQueryOutOfDate, // query whether object is current + + LeQueryReleaseStatus, // returns release status + LeQueryReleaseError, // assynchronusrelease error + LeQueryReleaseMethod, // the method/proc which is in assynchronus + // operation. + LeRequestData, // requestdata + LeObjectLong, // objectLong + LeChangeData // change native data of existing object +}; + + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FAR PASCAL LeObjectLong (lpobj, wFlags, lpData) +// +// +// Returns whether a given object is still processing a previous +// asynchronous command. returns OLE_BUSY if the object is still +// processing the previous command +// +// Arguments: +// +// lpobj - object handle +// wFlags - get, set flags +// lpData - long pointer to data +// +// Returns: +// +// OLE_OK +// OLE_ERROR_OBJECT +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FARINTERNAL LeObjectLong (lpobj, wFlags, lpData) +LPOBJECT_LE lpobj; +WORD wFlags; +LPLONG lpData; +{ + LONG lData; + + Puts("LeObjectLong"); + + if (!FarCheckObject((LPOLEOBJECT) lpobj)) + return OLE_ERROR_OBJECT; + + if ((lpobj->head.ctype != CT_EMBEDDED) && (lpobj->head.ctype != CT_LINK)) + return OLE_ERROR_OBJECT; + + if (wFlags & OF_HANDLER) { + lData = lpobj->lHandlerData; + if (wFlags & OF_SET) + lpobj->lHandlerData = *lpData; + + if (wFlags & OF_GET) + *lpData = lData; + } + else { + lData = lpobj->lAppData; + if (wFlags & OF_SET) + lpobj->lAppData = *lpData; + + if (wFlags & OF_GET) + *lpData = lData; + } + + return OLE_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FAR PASCAL LeQueryReleaseStatus (lpobj) +// +// +// Returns whether a given object is still processing a previous +// asynchronous command. returns OLE_BUSY if the object is still +// processing the previous command +// +// Arguments: +// +// lpobj - object handle +// +// Returns: +// +// OLE_BUSY - object is busy +// OLE_OK - not busy +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FAR PASCAL LeQueryReleaseStatus (lpobj) +LPOBJECT_LE lpobj; +{ + + // probe async will clean up the channels + // if the server died. + + + PROBE_ASYNC (lpobj); + return OLE_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FAR PASCAL LeQueryReleaseError (lpobj) +// +// returns the errors of an asynchronous command. +// +// Arguments: +// +// lpobj - object handle +// +// Returns: +// +// OLE_ERROR_.. - if there is any error +// OLE_OK - no error +// +// Note: This api is typically valid only during the callback of +// OLE_RELEASE. +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FAR PASCAL LeQueryReleaseError (lpobj) +LPOBJECT_LE lpobj; +{ + return lpobj->mainErr; +} + +////////////////////////////////////////////////////////////////////////////// +// +// OLE_RELEASE_METHOD FAR PASCAL LeQueryReleaseMethod (lpobj) +// +// returns the method/command of the asynchronous command which +// resulted in the OLE_RELEASE call back. +// +// Arguments: +// +// lpobj - object handle +// +// Returns: +// OLE_RELEASE_METHOD +// +// Note: This api is typically valid only during the callback of +// OLE_RELEASE. Using this api, clients can decide which previous +// asynchronous command resulted in OLE_RELEASE. +// +////////////////////////////////////////////////////////////////////////////// +OLE_RELEASE_METHOD FAR PASCAL LeQueryReleaseMethod (lpobj) +LPOBJECT_LE lpobj; +{ + return lpobj->oldasyncCmd; +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// LPVOID FARINTERNAL LeQueryProtocol (lpobj, lpprotocol) +// +// Given an oject, returns the new object handle for the new protocol. +// Does the conversion of objects from one protocol to another one. +// +// Arguments: +// +// lpobj - object handle +// lpprotocol - ptr to new protocol string +// +// Returns: +// lpobj - New object handle +// null - if the protocol is not supported. +// +// +////////////////////////////////////////////////////////////////////////////// + +LPVOID FARINTERNAL LeQueryProtocol (lpobj, lpprotocol) +LPOBJECT_LE lpobj; +LPSTR lpprotocol; +{ + if (lpobj->bOldLink) + return NULL; + + if (!lstrcmp (lpprotocol, PROTOCOL_EDIT)) + return lpobj; + + if (!lstrcmp (lpprotocol, PROTOCOL_EXECUTE)) { + if (UtilQueryProtocol (lpobj, lpprotocol)) + return lpobj; + + return NULL; + } + + return NULL; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS EmbLnkDelete (lpobj) +// +// Routine for the object termination/deletion. Schedules differnt +// asynchronous commands depending on different conditions. +// Arguments: +// +// Sends "StdClose" only if it is Ok to close the document. Sends +// "StdExit" only if the server has to be unlaunched. Deletes the object +// only if the original command is OLE_DELETE. No need to call back the +// client if the deletion is internal. +// +// While delete, this routine is entered several times. EAIT_FOR_ASYNC_MSG +// results in going back to from where it is called and the next DDE message +// brings back the control to this routine. +// +// Arguments: +// +// lpobj - object handle +// +// Returns: +// +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL EmbLnkDelete (lpobj) +LPOBJECT_LE lpobj; +{ + HOBJECT hobj; + + switch (lpobj->subRtn) { + + case 0: + + SKIP_TO (!QueryClose (lpobj), step1); + // Send "StdCloseDocument" + SendStdClose (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + + step1: + SETSTEP (lpobj, 1); + + // End the doc conversation + TermDocConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + + case 2: + + + // delete the doc edit block. It is Ok even if the object + // is not actually getting deleted. + DeleteDocEdit (lpobj); + + // if need to unluanch the app, send stdexit. + SKIP_TO (!QueryUnlaunch (lpobj), step3); + SendStdExit (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 3: + + step3: + SETSTEP (lpobj, 3); + + // Do not set any errors. + // Terminate the server conversation. + TermSrvrConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 4: + + // delete the server edit block + DeleteSrvrEdit (lpobj); + if (lpobj->asyncCmd != OLE_DELETE) { + + // if this delete is called because of unlauncinh of + // object because of some error, no need to + // call end asynchronous. It should have been already + // called from somewhere else. + + if (lpobj->asyncCmd == OLE_SERVERUNLAUNCH){ + // send the async cmd; + CLEARASYNCCMD (lpobj); + } else + EndAsyncCmd (lpobj); + return OLE_OK; + } + + + + // for real delete delete the atoms and space. + DeleteObjectAtoms (lpobj); + + if (lpobj->lpobjPict) + (*lpobj->lpobjPict->lpvtbl->Delete) (lpobj->lpobjPict); + + if (lpobj->hnative) + GlobalFree (lpobj->hnative); + + if (lpobj->hLink) + GlobalFree (lpobj->hLink); + + if (lpobj->hhostNames) + GlobalFree (lpobj->hhostNames); + + if (lpobj->htargetDevice) + GlobalFree (lpobj->htargetDevice); + + if (lpobj->hdocDimensions) + GlobalFree (lpobj->hdocDimensions); + + DeleteExtraData (lpobj); + + DocDeleteObject ((LPOLEOBJECT) lpobj); + // send the async cmd; + EndAsyncCmd (lpobj); + + if (lpobj->head.iTable != INVALID_INDEX) + DecreaseHandlerObjCount (lpobj->head.iTable); + + hobj = lpobj->head.hobj; + ASSERT (hobj, "Object handle NULL in delete") + + GlobalUnlock (hobj); + GlobalFree (hobj); + + return OLE_OK; + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeRelease (lpobj) +// +// Deletes the given object. This is can be asynchronous operation. +// +// Arguments: +// +// lpobj - object handle +// +// Returns: +// +// OLE_WAIT_FOR_RELASE: If any DDE_TRANSACTIONS have been queued +// OLE_OK : If deletion successfully +// OLE_ERROR_... : If any error +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeRelease (lpobj) +LPOBJECT_LE lpobj; +{ + + + // For delete allow if the object has been aborted. + + PROBE_ASYNC (lpobj); + + // reset the flags so that we do not delete the object based on the old + // flags + lpobj->fCmd = 0; + InitAsyncCmd (lpobj, OLE_DELETE, EMBLNKDELETE); + return EmbLnkDelete (lpobj); +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +// +// Clones a given object. +// +// Arguments: +// +// lpobjsrc: ptr to the src object. +// lpclient: client callback handle +// lhclientdoc: doc handle +// lpobjname: object name +// lplpobj: holder for returning object. +// +// Returns: +// OLE_OK : successful +// OLE_ERROR_... : error +// +// Note: If the object being cloned is connected to the server, then +// the cloned object is not connected to the server. For linked +// objects, OleConnect has to be called. +// +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_LE lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_LE FAR * lplpobj; +{ + + LPOBJECT_LE lpobj = NULL; + int retval = OLE_ERROR_MEMORY; + + // Assumes all the creates are in order +// PROBE_OBJECT_BLANK(lpobjsrc); + + PROBE_CREATE_ASYNC(lpobjsrc); + + if (!(lpobj = LeCreateBlank(lhclientdoc, lpobjname, + lpobjsrc->head.ctype))) + goto errRtn; + + lpobj->head.lpclient = lpclient; + lpobj->head.iTable = lpobjsrc->head.iTable; //!!! dll loading + lpobj->head.lpvtbl = lpobjsrc->head.lpvtbl; + + // set the atoms. + lpobj->app = DuplicateAtom (lpobjsrc->app); + lpobj->topic = DuplicateAtom (lpobjsrc->topic); + lpobj->item = DuplicateAtom (lpobjsrc->item); + lpobj->aServer = DuplicateAtom (lpobjsrc->aServer); + + lpobj->bOleServer = lpobjsrc->bOleServer; + lpobj->verb = lpobjsrc->verb; + lpobj->fCmd = lpobjsrc->fCmd; + + lpobj->aNetName = DuplicateAtom (lpobjsrc->aNetName); + lpobj->cDrive = lpobjsrc->cDrive; + lpobj->dwNetInfo = lpobjsrc->dwNetInfo; + + if (lpobjsrc->htargetDevice) + lpobj->htargetDevice = DuplicateGlobal (lpobjsrc->htargetDevice, + GMEM_MOVEABLE); + + if (lpobjsrc->head.ctype == CT_EMBEDDED) { + if (lpobjsrc->hnative) { + if (!(lpobj->hnative = DuplicateGlobal (lpobjsrc->hnative, + GMEM_MOVEABLE))) + goto errRtn; + } + + if (lpobjsrc->hdocDimensions) + lpobj->hdocDimensions = DuplicateGlobal (lpobjsrc->hdocDimensions, + GMEM_MOVEABLE); + if (lpobjsrc->hlogpal) + lpobj->hlogpal = DuplicateGlobal (lpobjsrc->hlogpal, + GMEM_MOVEABLE); + SetEmbeddedTopic (lpobj); + } + else { + lpobj->bOldLink = lpobjsrc->bOldLink; + lpobj->optUpdate = lpobjsrc->optUpdate; + } + + retval = OLE_OK; + // if picture is needed clone the picture object. + if ((!lpobjsrc->lpobjPict) || + ((retval = (*lpobjsrc->lpobjPict->lpvtbl->Clone)(lpobjsrc->lpobjPict, + lpclient, lhclientdoc, lpobjname, + (LPOLEOBJECT FAR *)&lpobj->lpobjPict)) + == OLE_OK)) { + SetExtents (lpobj); + *lplpobj = lpobj; + if (lpobj->lpobjPict) + lpobj->lpobjPict->lpParent = (LPOLEOBJECT) lpobj; + } + + return retval; + +errRtn: + + // This oledelete should not result in any async communication. + if (lpobj) + OleDelete ((LPOLEOBJECT)lpobj); + + return retval; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeCopyFromLink (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +// +// Creates an embedded object from a lonked object. If the linked object +// is not activated, then launches the server, gets the native data and +// unlaunches the server. All these operations are done silently. +// +// Arguments: +// +// lpobjsrc: ptr to the src object. +// lpclient: client callback handle +// lhclientdoc: doc handle +// lpobjname: object name +// lplpobj: holder for returning object. +// +// Returns: +// OLE_OK : successful +// OLE_ERROR_... : error +// OLE_WAITF_FOR_RELEASE : if DDE transcation is queued +// +// Note: Could result in asynchronous operation if there is any +// DDE operaion involved in getting any data from the server. +// +// Also, If there is any error in getting the native data, the +// client is expected delete the object after the OLE_RELEASE +// call back +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeCopyFromLink (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_LE lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_LE FAR * lplpobj; +{ + + LPOBJECT_LE lpobj; + int retval; + + + *lplpobj = NULL; + PROBE_OLDLINK (lpobjsrc); + if (lpobjsrc->head.ctype != CT_LINK) + return OLE_ERROR_NOT_LINK; + + PROBE_ASYNC (lpobjsrc); + PROBE_SVRCLOSING(lpobjsrc); + + if ((retval = LeClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, + (LPOBJECT_LE FAR *)&lpobj)) != OLE_OK) + return retval; + + + // we successfully cloned the object. if picture object has native data + // then grab it and put it in LE object. otherwise activate and get native + // data also. + + if (lpobj->lpobjPict + && (*lpobj->lpobjPict->lpvtbl->EnumFormats) + (lpobj->lpobjPict, NULL) == cfNative){ + // Now we know that the picture object is of native format, and it + // means that it is a generic object. So grab the handle to native + // data and put it in LE object. + + lpobj->hnative = ((LPOBJECT_GEN) (lpobj->lpobjPict))->hData; + ((LPOBJECT_GEN) (lpobj->lpobjPict))->hData = NULL; + (*lpobj->lpobjPict->lpvtbl->Delete) (lpobj->lpobjPict); + lpobj->lpobjPict = NULL; + SetEmbeddedTopic (lpobj); + *lplpobj = lpobj; + return OLE_OK; + } else { + + // if necessary launch, get native data and unlaunch the app. + lpobj->fCmd = LN_LNKACT | ACT_REQUEST | ACT_NATIVE | (QueryOpen(lpobjsrc) ? ACT_TERMDOC : ACT_UNLAUNCH); + InitAsyncCmd (lpobj, OLE_COPYFROMLNK, LNKOPENUPDATE); + if ((retval = LnkOpenUpdate (lpobj)) > OLE_WAIT_FOR_RELEASE) + LeRelease (lpobj); + else + *lplpobj = lpobj; + + return retval; + + // we will be changing the topic in end conversation. + } +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeEqual (lpobj1, lpobj2) +// +// Checks whethere two objects are equal. Checks for equality +// of links, native data and picture data. +// +// Arguments: +// +// lpobj1: first object +// lpobj2: second object +// +// Returns: +// OLE_OK : equal +// OLE_ERROR_NOT_EQUAL : if not equal +// OLE_ERROR_..... : any errors +// +// Note: If any of the objects are connectd to the servers, leequal operaion +// may not make much sense because the data might be changing from the +// the server +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeEqual (lpobj1, lpobj2) +LPOBJECT_LE lpobj1; +LPOBJECT_LE lpobj2; +{ + + if (lpobj1->app != lpobj2->app) + return OLE_ERROR_NOT_EQUAL; + + // type of the objects is same. Otherwise this routine won't be called + if (lpobj1->head.ctype == CT_LINK) { + if (AreTopicsEqual (lpobj1, lpobj2) && (lpobj1->item == lpobj2->item)) + return OLE_OK; + + return OLE_ERROR_NOT_EQUAL; + } + else { + ASSERT (lpobj1->head.ctype == CT_EMBEDDED, "Invalid ctype in LeEqual") + + if (lpobj1->item != lpobj2->item) + return OLE_ERROR_NOT_EQUAL; + + if (CmpGlobals (lpobj1->hnative, lpobj2->hnative)) + return OLE_OK; + else + return OLE_ERROR_NOT_EQUAL; + } + + //### we may have to compare the picture data also +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeCopy (lpobj) +// +// Copies the object to the clipboard. Even for linked objects +// we do not render the objectlink. It is up to the client app +// to render object link +// +// Arguments: +// +// lpobj: object handle +// +// Returns: +// OLE_OK : successful +// OLE_ERROR_..... : any errors +// +// Note: Library does not open the clipboard. Client is supposed to +// open the librray before this call is made +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeCopy (lpobj) +LPOBJECT_LE lpobj; +{ + HANDLE hlink = NULL; + HANDLE hnative = NULL; + + PROBE_OLDLINK (lpobj); + // Assumes all the creates are in order +// PROBE_OBJECT_BLANK(lpobj); + + PROBE_CREATE_ASYNC(lpobj); + + if (lpobj->head.ctype == CT_EMBEDDED){ + if (!(hnative = DuplicateGlobal (lpobj->hnative, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + SetClipboardData (cfNative, hnative); + } + + hlink = GetLink (lpobj); + if (!(hlink = DuplicateGlobal (hlink, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + SetClipboardData (cfOwnerLink, hlink); + + // copy network name if it exists + if (lpobj->head.ctype == CT_LINK && lpobj->aNetName) { + HANDLE hNetName; + + if (hNetName = GetNetNameHandle (lpobj)) + SetClipboardData (cfNetworkName, hNetName); + } + + if (lpobj->lpobjPict) + return (*lpobj->lpobjPict->lpvtbl->CopyToClipboard)(lpobj->lpobjPict); + + return OLE_OK; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeQueryBounds (lpobj, lpRc) +// +// Returns the bounding rectangle of the object. Returns topleft +// as zero always and the units are himetric units. +// +// Arguments: +// +// lpobj: object handle +// +// Returns: +// OLE_OK : successful +// OLE_ERROR_..... : any errors +// +// Note: Library does not open the clipboard. Client is supposed to +// open the librray before this call is made +// +////////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FARINTERNAL LeQueryBounds (lpobj, lpRc) +LPOBJECT_LE lpobj; +LPRECT lpRc; +{ + Puts("LeQueryBounds"); + + // MM_HIMETRIC units + + lpRc->left = 0; + lpRc->top = 0; + lpRc->right = (int) lpobj->head.cx; + lpRc->bottom = (int) lpobj->head.cy; + + if (lpRc->right || lpRc->bottom) + return OLE_OK; + + if (!lpobj->lpobjPict) + return OLE_ERROR_BLANK; + + return (*lpobj->lpobjPict->lpvtbl->QueryBounds) (lpobj->lpobjPict, lpRc); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +// +// Draws the object. Calls the picture object for drawing the object +// +// +// Arguments: +// +// lpobj: source object +// hdc: handle to dest dc. Could be metafile dc +// lprc: rectangle into which the object should be drawn +// should be in himetric units and topleft +// could be nonzero. +// hdctarget: Target dc for which the object should be drawn +// (Ex: Draw metafile on the dest dc using the attributes +// of traget dc). +// +// Returns: +// OLE_OK : successful +// OLE_ERROR_BLANK : no picture +// +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOBJECT_LE lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + if (lpobj->lpobjPict) + return (*lpobj->lpobjPict->lpvtbl->Draw) (lpobj->lpobjPict, + hdc, lprc, lpWrc, hdcTarget); + return OLE_ERROR_BLANK; +} + + +////////////////////////////////////////////////////////////////////////////// +// +// OLECLIPFORMAT FARINTERNAL LeEnumFormat (lpobj, cfFormat) +// +// Enumerates the object formats. +// +// +// Arguments: +// +// lpobj : source object +// cfFormat : ref fprmat +// +// Returns: +// NULL : no more formats or if we do not understand the +// given format. +// +// Note: Even if the object is connected, we do not enumerate all the formats +// the server can render. Server protocol can render the format list +// only on system channel. Object can be connected only on the doc +// channel +// +////////////////////////////////////////////////////////////////////////////// + +OLECLIPFORMAT FARINTERNAL LeEnumFormat (lpobj, cfFormat) +LPOBJECT_LE lpobj; +OLECLIPFORMAT cfFormat; +{ + Puts("LeEnumFormat"); + + ASSERT((lpobj->head.ctype == CT_LINK)||(lpobj->head.ctype == CT_EMBEDDED), + "Invalid Object Type"); + + // switch is not used because case won't take variable argument + if (cfFormat == NULL) { + if (lpobj->head.ctype == CT_EMBEDDED) + return cfNative; + else + return (lpobj->bOldLink ? cfLink : cfObjectLink); + } + + if (cfFormat == cfNative) { + if (lpobj->head.ctype == CT_EMBEDDED) + return cfOwnerLink; + else + return NULL; + } + + if (cfFormat == cfObjectLink) { + if (lpobj->aNetName) + return cfNetworkName; + else + cfFormat = NULL; + } + else if (cfFormat == cfOwnerLink || cfFormat == cfLink + || cfFormat == cfNetworkName) + cfFormat = NULL; + + if (lpobj->lpobjPict) + return (*lpobj->lpobjPict->lpvtbl->EnumFormats) (lpobj->lpobjPict, cfFormat); + + return NULL; +} + +//////////////////////////////////////////////////////////////////////////////// +// +// +// OLESTATUS FARINTERNAL LeRequestData (lpobj, cfFormat) +// +// Requests data from the server for a given format, if the server +// is connected. If the server is not connected returns error. +// +// +// Arguments: +// +// lpobj: source object +// cfFormat: ref fprmat +// +// Returns: +// OLE_WAIT_FOR_RELEASE : If the data request data is sent to +// the server. +// OLE_ERROR_NOT_OPEN : Server is not open for data +// +// Note: If the server is ready, sends request to the server. When the +// the data comes back from the server OLE_DATA_READY is sent in +// the callback and the client can use Getdata to get the data. +// +// +////////////////////////////////////////////////////////////////////////////// + + + +OLESTATUS FARINTERNAL LeRequestData (lpobj, cfFormat) +LPOBJECT_LE lpobj; +OLECLIPFORMAT cfFormat; +{ + + // Assumes all the creates are in order + PROBE_ASYNC(lpobj); + PROBE_SVRCLOSING(lpobj); + + if (!QueryOpen (lpobj)) + return OLE_ERROR_NOT_OPEN; + + if (cfFormat == cfOwnerLink || cfFormat == cfObjectLink) + return OLE_ERROR_FORMAT; + + if (!(cfFormat == cfNative && lpobj->head.ctype == CT_EMBEDDED) + && (cfFormat != (OLECLIPFORMAT) GetPictType (lpobj))) { + DeleteExtraData (lpobj); + lpobj->cfExtra = cfFormat; + } + + InitAsyncCmd (lpobj, OLE_REQUESTDATA, REQUESTDATA); + lpobj->pDocEdit->bCallLater = FALSE; + return RequestData(lpobj, cfFormat); +} + + +OLESTATUS RequestData (lpobj, cfFormat) +LPOBJECT_LE lpobj; +OLECLIPFORMAT cfFormat; +{ + switch (lpobj->subRtn) { + + case 0: + RequestOn (lpobj, cfFormat); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + ProcessErr (lpobj); + return EndAsyncCmd (lpobj); + + default: + ASSERT (TRUE, "unexpected step in Requestdata"); + return OLE_ERROR_GENERIC; + } +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// +// OLESTATUS FARINTERNAL LeGetData (lpobj, cfFormat, lphandle) +// +// Returns the data handle for a given format +// +// Arguments: +// +// lpobj: source object +// cfFormat: ref fprmat +// lphandle: handle return +// +// Returns: +// NULL : no more formats or if we do not understand the +// given format. +// +// Note: Even if the object is connected, we do not get the data from the +// server. Getdata can not be used for getting data in any other +// format other than the formats available with the object on +// the client side. +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeGetData (lpobj, cfFormat, lphandle) +LPOBJECT_LE lpobj; +OLECLIPFORMAT cfFormat; +LPHANDLE lphandle; +{ + + // Assumes all the creates are in order +// PROBE_OBJECT_BLANK(lpobj); + + PROBE_CREATE_ASYNC(lpobj); + + *lphandle = NULL; + + // The assumption made here is that the native data can be in either + // LE object or picture object. + if ((cfFormat == cfNative) && (lpobj->hnative)) { + ASSERT ((lpobj->head.ctype == CT_EMBEDDED) || (!lpobj->lpobjPict) || + ((*lpobj->lpobjPict->lpvtbl->EnumFormats) (lpobj->lpobjPict, NULL) + != cfNative), "Native data at wrong Place"); + *lphandle = lpobj->hnative; + return OLE_OK; + } + + if (cfFormat == cfOwnerLink && lpobj->head.ctype == CT_EMBEDDED) { + if (*lphandle = GetLink (lpobj)) + return OLE_OK; + + return OLE_ERROR_BLANK; + } + + if ((cfFormat == cfObjectLink || cfFormat == cfLink) && + lpobj->head.ctype == CT_LINK) { + if (*lphandle = GetLink (lpobj)) + return OLE_OK; + + return OLE_ERROR_BLANK; + } + + if (cfFormat == cfNetworkName) { + if (lpobj->aNetName && (*lphandle = GetNetNameHandle (lpobj))) + return OLE_WARN_DELETE_DATA; + + return OLE_ERROR_BLANK; + } + + if (cfFormat == lpobj->cfExtra) { + if (*lphandle = lpobj->hextraData) + return OLE_OK; + + return OLE_ERROR_BLANK; + } + + if (!lpobj->lpobjPict && cfFormat) + return OLE_ERROR_FORMAT; + + return (*lpobj->lpobjPict->lpvtbl->GetData) (lpobj->lpobjPict, cfFormat, lphandle); +} + + + + +OLESTATUS FARINTERNAL LeQueryOutOfDate (lpobj) +LPOBJECT_LE lpobj; +{ + return OLE_OK; +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeObjectConvert (lpobj, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj) +// +// Converts a given linked/embedded object to static object. +// +// Arguments: +// lpobj : source object +// lpprotocol : protocol +// lpclient : client callback for the new object +// lhclientdoc: client doc +// lpobjname : object name +// lplpobj : object return +// +// +// Returns: +// OLE_OK : successful +// OLE_ERROR_.... : any errors +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeObjectConvert (lpobj, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_LE lpobj; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + OLESTATUS retVal; + + PROBE_ASYNC (lpobj); + + *lplpobj = NULL; + + if (lstrcmp (lpprotocol, PROTOCOL_STATIC)) + return OLE_ERROR_PROTOCOL; + + if (!lpobj->lpobjPict || + ((*lpobj->lpobjPict->lpvtbl->QueryType) (lpobj->lpobjPict, NULL) + == OLE_ERROR_GENERIC)) { + // Either no picture object or non-standard picture object. + // Create a metafile Object. + + HDC hMetaDC; + RECT rc; + HANDLE hMF = NULL, hmfp = NULL; + LPMETAFILEPICT lpmfp; + + OleQueryBounds ((LPOLEOBJECT) lpobj, &rc); + if (!(hMetaDC = CreateMetaFile (NULL))) + goto Cleanup; + + SetWindowOrg (hMetaDC, rc.left, rc.top); + SetWindowExt (hMetaDC, rc.right - rc.left, rc.bottom - rc.top); + retVal = OleDraw ((LPOLEOBJECT) lpobj, hMetaDC, &rc, &rc, NULL); + hMF = CloseMetaFile (hMetaDC); + if ((retVal != OLE_OK) || !hMF) + goto Cleanup; + + if (!(hmfp = GlobalAlloc (GMEM_MOVEABLE, sizeof (METAFILEPICT)))) + goto Cleanup; + + if (!(lpmfp = (LPMETAFILEPICT) GlobalLock (hmfp))) + goto Cleanup; + + lpmfp->hMF = hMF; + lpmfp->mm = MM_ANISOTROPIC; + lpmfp->xExt = rc.right - rc.left; + lpmfp->yExt = rc.top - rc.bottom; + GlobalUnlock (hmfp); + + if (*lplpobj = (LPOLEOBJECT) MfCreateObject (hmfp, lpclient, TRUE, + lhclientdoc, lpobjname, CT_STATIC)) + return OLE_OK; + +Cleanup: + if (hMF) + DeleteMetaFile (hMF); + + if (hmfp) + GlobalFree (hmfp); + + return OLE_ERROR_MEMORY; + } + + + // Picture object is one of the standard objects + if ((retVal = (*lpobj->lpobjPict->lpvtbl->Clone) (lpobj->lpobjPict, + lpclient, lhclientdoc, + lpobjname, lplpobj)) == OLE_OK) { + (*lplpobj)->ctype = CT_STATIC; + DocAddObject ((LPCLIENTDOC) lhclientdoc, *lplpobj, lpobjname); + } + + return retVal; +} + + + +// internal method used for changing picture/native data +OLESTATUS FARINTERNAL LeChangeData (lpobj, hnative, lpoleclient, fDelete) +LPOBJECT_LE lpobj; +HANDLE hnative; +LPOLECLIENT lpoleclient; +BOOL fDelete; +{ + if (!fDelete) { + if (!(hnative = DuplicateGlobal (hnative, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + } + + // In case of a CopyFromLink, eventhough the object type is CT_LINK, the + // native data should go to LE object rather than the picture object, as + // we are going to change the object type to embedded after the required + // data is recieved. + + if ((lpobj->head.ctype == CT_LINK) + && (lpobj->asyncCmd != OLE_COPYFROMLNK) + && (lpobj->asyncCmd != OLE_CREATEFROMFILE)) { + if (lpobj->lpobjPict) + return (*lpobj->lpobjPict->lpvtbl->SetData) + (lpobj->lpobjPict, cfNative, hnative); + } + else { // It must be embedded. + if (lpobj->hnative) + GlobalFree (lpobj->hnative); + lpobj->hnative = hnative; + return OLE_OK; + } + + return OLE_ERROR_BLANK; +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// LPOBJECT_LE FARINTERNAL LeCreateBlank (lhclientdoc, lpobjname, ctype) +// +// Create a blank object. Global block is used for the object and it is +// locked once sucessful. Unlocking is done only while deletion. Object +// is added to the corresponding doc. +// +// 'LE' signature is used for object validation. +// +// Arguments: +// lhclientdoc : client doc handle +// lpobjname : object name +// ctype : type of object to be created +// +// Returns: +// LPOBJECT : successful +// NULL : any errors +// +////////////////////////////////////////////////////////////////////////////// + +LPOBJECT_LE FARINTERNAL LeCreateBlank (lhclientdoc, lpobjname, ctype) +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG ctype; +{ + HOBJECT hobj; + LPOBJECT_LE lpobj; + + if (!(ctype == CT_LINK || ctype == CT_EMBEDDED || ctype == CT_OLDLINK)) + return NULL; + + if (!(hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT, + sizeof (OBJECT_LE)))) + return NULL; + + if (!(lpobj = (LPOBJECT_LE) GlobalLock (hobj))) { + GlobalFree (hobj); + return NULL; + } + + if (ctype == CT_OLDLINK) { + ctype = CT_LINK; + lpobj->bOldLink = TRUE; + } + + lpobj->head.objId[0] = 'L'; + lpobj->head.objId[1] = 'E'; + lpobj->head.ctype = ctype; + lpobj->head.iTable = INVALID_INDEX; + + lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblLE; + + if (ctype == CT_LINK){ + lpobj->optUpdate = oleupdate_always; + + }else { + lpobj->optUpdate = oleupdate_onclose; + } + lpobj->head.hobj = hobj; + DocAddObject ((LPCLIENTDOC) lhclientdoc, (LPOLEOBJECT) lpobj, lpobjname); + return lpobj; +} + + +void FARINTERNAL SetExtents (LPOBJECT_LE lpobj) +{ + RECT rc = {0, 0, 0, 0}; + + if (lpobj->lpobjPict) { + if ((*lpobj->lpobjPict->lpvtbl->QueryBounds) (lpobj->lpobjPict, + (LPRECT)&rc) == OLE_OK) { + // Bounds are in MM_HIMETRIC units + lpobj->head.cx = (LONG) (rc.right - rc.left); + lpobj->head.cy = (LONG) (rc.bottom - rc.top); + } + return; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeSaveToStream (lpobj, lpstream) +// +// Save the object to the stream. Uses the stream functions provided +// in the lpclient. +// +// Format: (!!! Document the fomrat here). +// +// +// +// Arguments: +// lhclientdoc : client doc handle +// lpobjname : object name +// ctype : type of object to be created +// +// Returns: +// LPOBJECT : successful +// NULL : any errors +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeSaveToStream (lpobj, lpstream) +LPOBJECT_LE lpobj; +LPOLESTREAM lpstream; +{ + +// PROBE_OBJECT_BLANK(lpobj); + + PROBE_CREATE_ASYNC(lpobj); + + if (lpobj->head.ctype == CT_LINK && lpobj->bOldLink) + lpobj->head.ctype = CT_OLDLINK; + + if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (lpobj->bOldLink) + lpobj->head.ctype = CT_OLDLINK; + + return LeStreamWrite (lpstream, lpobj); +} + + + +//////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpoleobject, ctype, aClass, cfFormat) +// +// Create an object, loading the object from the stream. +// +// Arguments: +// lpstream : stream table +// lpclient : client callback table +// lhclientdoc : Doc handle foe which the object should be created +// lpobjname : Object name +// lplpoleobject : object return +// ctype : Type of object +// aClass : class atom +// cfFormat : render format +// +// Returns: +// LPOBJECT : successful +// NULL : any errors +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpoleobject, ctype, aClass, cfFormat) +LPOLESTREAM lpstream; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +LONG ctype; +ATOM aClass; +OLECLIPFORMAT cfFormat; +{ + LPOBJECT_LE lpobj = NULL; + OLESTATUS retval = OLE_ERROR_STREAM; + LONG type; // this not same as ctype + LONG ver; + char chVerb [2]; + + *lplpoleobject = NULL; + + if (!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, ctype))) + return OLE_ERROR_MEMORY; + + lpobj->head.lpclient = lpclient; + lpobj->app = aClass; + // if the entry is present, then it is + lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2); + + if (LeStreamRead (lpstream, lpobj) == OLE_OK) { + + // Get exe name from aClass and set it as aServer + SetExeAtom (lpobj); + if (!GetBytes (lpstream, (LPSTR) &ver, sizeof(LONG))) { + if (!GetBytes (lpstream, (LPSTR) &type, sizeof(LONG))) { + if (type == CT_NULL) + retval = OLE_OK; + else if (aClass = GetAtomFromStream (lpstream)) { + retval = DefLoadFromStream (lpstream, NULL, lpclient, + lhclientdoc, lpobjname, + (LPOLEOBJECT FAR *)&lpobj->lpobjPict, + CT_PICTURE, aClass, cfFormat); + } + } + } + + if (retval == OLE_OK) { + SetExtents (lpobj); + *lplpoleobject = (LPOLEOBJECT) lpobj; + if (lpobj->lpobjPict) + lpobj->lpobjPict->lpParent = (LPOLEOBJECT) lpobj; + + if ((lpobj->head.ctype != CT_LINK) + || (!InitDocConv (lpobj, !POPUP_NETDLG)) + || (lpobj->optUpdate >= oleupdate_oncall)) + return OLE_OK; + + lpobj->fCmd = ACT_ADVISE; + + // If it's auto update, then get the latest data. + if (lpobj->optUpdate == oleupdate_always) + lpobj->fCmd |= ACT_REQUEST; + + FarInitAsyncCmd (lpobj, OLE_LOADFROMSTREAM, LNKOPENUPDATE); + return LnkOpenUpdate (lpobj); + } + } + + // This delete will not run into async command. We did not even + // even connect. + OleDelete ((LPOLEOBJECT) lpobj); + return OLE_ERROR_STREAM; +} + + + +// + +OLESTATUS INTERNAL LeStreamRead (lpstream, lpobj) +LPOLESTREAM lpstream; +LPOBJECT_LE lpobj; +{ + DWORD dwBytes; + LPSTR lpstr; + OLESTATUS retval = OLE_OK; + + if (!(lpobj->topic = GetAtomFromStream(lpstream)) + && (lpobj->head.ctype != CT_EMBEDDED)) + return OLE_ERROR_STREAM; + + // !!! This atom could be NULL. How do we distinguish the + // error case + + lpobj->item = GetAtomFromStream(lpstream); + + if (lpobj->head.ctype == CT_EMBEDDED) { + if (GetBytes (lpstream, (LPSTR) &dwBytes, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (!(lpobj->hnative = GlobalAlloc (GMEM_MOVEABLE, dwBytes))) + return OLE_ERROR_MEMORY; + else if (!(lpstr = GlobalLock (lpobj->hnative))) { + GlobalFree (lpobj->hnative); + return OLE_ERROR_MEMORY; + } + else { + if (GetBytes(lpstream, lpstr, dwBytes)) + retval = OLE_ERROR_STREAM; + GlobalUnlock (lpobj->hnative); + } + + if (retval == OLE_OK) + SetEmbeddedTopic (lpobj); + } + else { + if (lpobj->aNetName = GetAtomFromStream (lpstream)) { + if (HIWORD(dwVerFromFile) == OS_MAC) { + // if it is a mac file this field will have "ZONE:MACHINE:" + // string. Lets prepend this to the topic, so that server + // app or user can fix the string + + ATOM aTemp; + + aTemp = wAtomCat (lpobj->aNetName, lpobj->topic); + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = NULL; + GlobalDeleteAtom (lpobj->topic); + lpobj->topic = aTemp; + } + else + SetNetDrive (lpobj); + } + + if (HIWORD(dwVerFromFile) != OS_MAC) { + if (GetBytes (lpstream, (LPSTR) &lpobj->dwNetInfo, sizeof(LONG))) + return OLE_ERROR_STREAM; + } + + if (GetBytes (lpstream, (LPSTR) &lpobj->optUpdate, sizeof(LONG))) + return OLE_ERROR_STREAM; + } + return retval; +} + + + +OLESTATUS INTERNAL LeStreamWrite (lpstream, lpobj) +LPOLESTREAM lpstream; +LPOBJECT_LE lpobj; +{ + LPSTR lpstr; + DWORD dwBytes = 0L; + LONG nullType = CT_NULL; + int error; + + if (PutAtomIntoStream(lpstream, lpobj->app)) + return OLE_ERROR_STREAM; + + if (lpobj->head.ctype == CT_EMBEDDED) { + // we set the topic at load time, no point in saving it + if (PutBytes (lpstream, (LPSTR) &dwBytes, sizeof(LONG))) + return OLE_ERROR_STREAM; + } + else { + if (PutAtomIntoStream(lpstream, lpobj->topic)) + return OLE_ERROR_STREAM; + } + +#ifdef OLD + if (PutAtomIntoStream(lpstream, lpobj->topic)) + return OLE_ERROR_STREAM; +#endif + + if (PutAtomIntoStream(lpstream, lpobj->item)) + return OLE_ERROR_STREAM; + + // !!! deal with objects > 64k + + if (lpobj->head.ctype == CT_EMBEDDED) { + + if (!lpobj->hnative) + return OLE_ERROR_BLANK; + + // assumption low bytes are first + dwBytes = GlobalSize (lpobj->hnative); + + if (PutBytes (lpstream, (LPSTR)&dwBytes, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (!(lpstr = GlobalLock (lpobj->hnative))) + return OLE_ERROR_MEMORY; + + error = PutBytes (lpstream, lpstr, dwBytes); + GlobalUnlock (lpobj->hnative); + + if (error) + return OLE_ERROR_STREAM; + } + else { + if (PutAtomIntoStream(lpstream, lpobj->aNetName)) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->dwNetInfo, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->optUpdate, sizeof(LONG))) + return OLE_ERROR_STREAM; + } + + if (lpobj->lpobjPict) + return (*lpobj->lpobjPict->lpvtbl->SaveToStream) (lpobj->lpobjPict, + lpstream); + + if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &nullType, sizeof(LONG))) + return OLE_ERROR_STREAM; + + return OLE_OK; +} + + +/***************************** Public Function ****************************\ +* OLESTATUS FARINTERNAL LeQueryType (lpobj, lptype) +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FARINTERNAL LeQueryType (lpobj, lptype) +LPOBJECT_LE lpobj; +LPLONG lptype; +{ + Puts("LeQueryType"); + + if ((lpobj->head.ctype == CT_EMBEDDED) + || (lpobj->asyncCmd == OLE_COPYFROMLNK) + || (lpobj->asyncCmd == OLE_CREATEFROMFILE)) + *lptype = CT_EMBEDDED; + else if ((lpobj->head.ctype == CT_LINK) + || (lpobj->head.ctype == CT_OLDLINK)) + *lptype = CT_LINK; + else + return OLE_ERROR_OBJECT; + + return OLE_OK; +} + + + +// ContextCallBack: internal function. Calls callback function of <hobj> +// with flags. + +int FARINTERNAL ContextCallBack (lpobj, flags) +LPOLEOBJECT lpobj; +OLE_NOTIFICATION flags; +{ + LPOLECLIENT lpclient; + + Puts("ContextCallBack"); + + if (!FarCheckObject(lpobj)) + return FALSE; + + if (!(lpclient = lpobj->lpclient)) + return FALSE; + + ASSERT (lpclient->lpvtbl->CallBack, "Client Callback ptr is NULL"); + + return ((*lpclient->lpvtbl->CallBack) (lpclient, flags, lpobj)); +} + + +void FARINTERNAL DeleteExtraData (lpobj) +LPOBJECT_LE lpobj; +{ + if (lpobj->hextraData == NULL) + return; + + switch (lpobj->cfExtra) { + case CF_BITMAP: + DeleteObject (lpobj->hextraData); + break; + + case CF_METAFILEPICT: + { + LPMETAFILEPICT lpmfp; + + if (!(lpmfp = (LPMETAFILEPICT) GlobalLock (lpobj->hextraData))) + break; + + DeleteMetaFile (lpmfp->hMF); + GlobalUnlock (lpobj->hextraData); + GlobalFree (lpobj->hextraData); + break; + } + + default: + GlobalFree (lpobj->hextraData); + } + + lpobj->hextraData = NULL; +} + + +void INTERNAL DeleteObjectAtoms(lpobj) +LPOBJECT_LE lpobj; +{ + if (lpobj->app) { + GlobalDeleteAtom (lpobj->app); + lpobj->app = NULL; + } + + if (lpobj->topic) { + GlobalDeleteAtom (lpobj->topic); + lpobj->topic = NULL; + } + + if (lpobj->item) { + GlobalDeleteAtom (lpobj->item); + lpobj->item = NULL; + } + + if (lpobj->aServer) { + GlobalDeleteAtom (lpobj->aServer); + lpobj->aServer = NULL; + } + + if (lpobj->aNetName) { + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = NULL; + } +} + + +// LeGetUpdateOptions: Gets the update options. + +OLESTATUS FARINTERNAL LeGetUpdateOptions (lpobj, lpOptions) +LPOBJECT_LE lpobj; +OLEOPT_UPDATE FAR *lpOptions; +{ + if (lpobj->head.ctype != CT_LINK) + return OLE_ERROR_OBJECT; + + *lpOptions = lpobj->optUpdate; + return OLE_OK; +} + + + + +OLESTATUS FARINTERNAL LnkPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, sfFormat) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +OLECLIPFORMAT sfFormat; +{ + LPOBJECT_LE lpobj = NULL; + OLESTATUS retval = OLE_ERROR_MEMORY; + LPSTR lpClass = NULL; + + if (!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_LINK))) + goto errRtn; + + lpobj->head.lpclient = lpclient; + +#ifdef OLD + if (!bWLO) { + // we are not running under WLO + if (!(hInfo = GetClipboardData (sfFormat))) { + if (hInfo = GetClipboardData (cfLink)) + lpobj->bOldLink = TRUE; + } + } +#endif + + if (!hInfo) + goto errRtn; + + if (!IsClipboardFormatAvailable (sfFormat)) + lpobj->bOldLink = TRUE; + + if (!SetLink (lpobj, hInfo, &lpClass)) + goto errRtn; + + if ((retval = SetNetName(lpobj)) != OLE_OK) { + // see whether network name is on the clipboard and try to use it + HANDLE hNetName; + LPSTR lpNetName; + + if (!IsClipboardFormatAvailable (cfNetworkName)) + goto errRtn; + + if (!(hNetName = GetClipboardData (cfNetworkName))) + goto errRtn; + + if (!(lpNetName = GlobalLock (hNetName))) + goto errRtn; + + GlobalUnlock (hNetName); + if (!(lpobj->aNetName = GlobalAddAtom (lpNetName))) + goto errRtn; + + SetNetDrive (lpobj); + } + + retval = CreatePictFromClip (lpclient, lhclientdoc, lpobjname, + (LPOLEOBJECT FAR *)&lpobj->lpobjPict, optRender, + cfFormat, lpClass, CT_PICTURE); + + if (retval == OLE_OK) { + SetExtents (lpobj); + // why do we have to update the link, do we show it? + + // Reconnect if we could and advise for updates + *lplpoleobject = (LPOLEOBJECT)lpobj; + if (lpobj->lpobjPict) + lpobj->lpobjPict->lpParent = (LPOLEOBJECT) lpobj; + + if (!InitDocConv (lpobj, !POPUP_NETDLG)) + return OLE_OK; // document is not loaded , it is OK. + + lpobj->fCmd = ACT_ADVISE | ACT_REQUEST; + FarInitAsyncCmd (lpobj, OLE_LNKPASTE, LNKOPENUPDATE); + return LnkOpenUpdate (lpobj); + + } + else { +errRtn: + if (lpobj) + OleDelete ((LPOLEOBJECT)lpobj); + } + + return retval; +} + + + +// !!! EmbPaste and LnkPaste Can be combined +OLESTATUS FARINTERNAL EmbPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + LPOBJECT_LE lpobj = NULL; + HANDLE hnative; + OLESTATUS retval = OLE_ERROR_MEMORY; + LPSTR lpClass = NULL; + + if (!IsClipboardFormatAvailable (cfOwnerLink)) + return OLE_ERROR_CLIPBOARD; + + if (!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_EMBEDDED))) + goto errRtn; + + lpobj->head.lpclient = lpclient; + +#ifdef OLD + if (!bWLO) { + // we are not running under WLO + hInfo = GetClipboardData (cfOwnerLink); + } +#endif + + if (!hInfo) + goto errRtn; + + if (!SetLink (lpobj, hInfo, &lpClass)) + goto errRtn; + + SetEmbeddedTopic (lpobj); + + hnative = GetClipboardData (cfNative); + if (!(lpobj->hnative = DuplicateGlobal (hnative, GMEM_MOVEABLE))) + goto errRtn; + + retval = CreatePictFromClip (lpclient, lhclientdoc, lpobjname, + (LPOLEOBJECT FAR *)&lpobj->lpobjPict, optRender, + cfFormat, lpClass, CT_PICTURE); + + if (retval == OLE_OK) { + SetExtents (lpobj); + *lplpoleobject = (LPOLEOBJECT) lpobj; + if (lpobj->lpobjPict) + lpobj->lpobjPict->lpParent = (LPOLEOBJECT) lpobj; + } + else { +errRtn: + // Note: This oledelete should not result in any async commands. + if (lpobj) + OleDelete ((LPOLEOBJECT)lpobj); + } + +#ifdef EXCEL_BUG + // Some server apps (ex: Excel) copy picture (to clipboard) which is + // formatted for printer DC. So, we want to update the picture if the + // server app is running, and the it's a old server + + if ((retval == OLE_OK) && (!lpobj->bOleServer)) { + lpobj->fCmd = LN_EMBACT | ACT_NOLAUNCH | ACT_REQUEST | ACT_UNLAUNCH; + FarInitAsyncCmd (lpobj, OLE_EMBPASTE, EMBOPENUPDATE); + if ((retval = EmbOpenUpdate (lpobj)) > OLE_WAIT_FOR_RELEASE) + return OLE_OK; + } +#endif + + return retval; +} + + + +BOOL INTERNAL SetLink (lpobj, hinfo, lpLpClass) +LPOBJECT_LE lpobj; +HANDLE hinfo; +LPSTR FAR * lpLpClass; +{ + LPSTR lpinfo; + char chVerb[2]; + // If there exits a conversation, then terminate it. + + if (!(lpinfo = GlobalLock (hinfo))) + return FALSE; + + *lpLpClass = lpinfo; + +#if FIREWALLS + if (lpobj->pDocEdit) + ASSERT (!lpobj->pDocEdit->hClient, "unexpected client conv exists"); +#endif + + lpobj->app = GlobalAddAtom (lpinfo); + SetExeAtom (lpobj); + lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2); + +// lpobj->aServer = GetAppAtom (lpinfo); + + lpinfo += lstrlen (lpinfo) + 1; + lpobj->topic = GlobalAddAtom (lpinfo); + lpinfo += lstrlen (lpinfo) + 1; + if (*lpinfo) + lpobj->item = GlobalAddAtom (lpinfo); + else + lpobj->item = NULL; + + if (lpobj->hLink) { // As the atoms have already changed, + GlobalFree (lpobj->hLink); // lpobj->hLink becomes irrelevant. + lpobj->hLink = NULL; + } + + if (lpinfo) + GlobalUnlock(hinfo); + + if (!lpobj->app) + return FALSE; + + if (!lpobj->topic && (lpobj->head.ctype == CT_LINK)) + return FALSE; + + lpobj->hLink = DuplicateGlobal (hinfo, GMEM_MOVEABLE); + return TRUE; +} + + + +HANDLE INTERNAL GetLink (lpobj) +LPOBJECT_LE lpobj; +{ + HANDLE hLink = NULL; + LPSTR lpLink; + int len; + WORD size; + + if (lpobj->hLink) + return lpobj->hLink; + + size = 4; // three nulls and one null at the end + size += GlobalGetAtomLen (lpobj->app); + size += GlobalGetAtomLen (lpobj->topic); + size += GlobalGetAtomLen (lpobj->item); + + if (!(hLink = GlobalAlloc (GMEM_MOVEABLE, (DWORD) size))) + return NULL; + + if (!(lpLink = GlobalLock (hLink))) { + GlobalFree (hLink); + return NULL; + } + + len = (int) GlobalGetAtomName (lpobj->app, lpLink, size); + lpLink += ++len; + + len = (int) GlobalGetAtomName (lpobj->topic, lpLink, (size -= len)); + lpLink += ++len; + + if (!lpobj->item) + *lpLink = NULL; + else { + len = (int) GlobalGetAtomName (lpobj->item, lpLink, size - len); + lpLink += len; + } + + *++lpLink = NULL; // put another null the end + GlobalUnlock (hLink); + return (lpobj->hLink = hLink); + +} + + +void FARINTERNAL SetEmbeddedTopic (lpobj) +LPOBJECT_LE lpobj; +{ + LPCLIENTDOC lpdoc; + char buf[MAX_STR]; + char buf1[MAX_STR]; + LPSTR lpstr, lptmp; + int len; + + if (lpobj->topic) + GlobalDeleteAtom (lpobj->topic); + + if (lpobj->aNetName) { + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = NULL; + } + + lpobj->cDrive = NULL; + lpobj->dwNetInfo = NULL; + lpobj->head.ctype = CT_EMBEDDED; + + lpdoc = (LPCLIENTDOC) lpobj->head.lhclientdoc; + lpstr = (LPSTR) buf; + lptmp = (LPSTR) buf1; + ASSERT(lpdoc->aDoc, "lpdoc->aDoc is null"); + GlobalGetAtomName (lpdoc->aDoc, lpstr, sizeof(buf)); + + // strip the path + lpstr += (len = lstrlen(lpstr)); + while (--lpstr != (LPSTR) buf) { + if ((*lpstr == '\\') || (*lpstr == ':')) { + lpstr++; + break; + } + } + + GlobalGetAtomName (lpdoc->aClass, lptmp, sizeof(buf1)); + lstrcat (lptmp, "%"); + lstrcat (lptmp, lpstr); + lstrcat (lptmp, "%"); + lpstr = lptmp; + lptmp += lstrlen (lptmp); + + if (lpobj->head.aObjName) { + GlobalGetAtomName (lpobj->head.aObjName, lptmp, sizeof(buf)-(len+1)); + } + + if ((embStr[EMB_ID_INDEX] += 1) > '9') { + embStr[EMB_ID_INDEX] = '0'; + if ((embStr[EMB_ID_INDEX - 1] += 1) > '9') { + embStr[EMB_ID_INDEX - 1] = '0'; + if ((embStr[EMB_ID_INDEX - 2] += 1) > '9') + embStr[EMB_ID_INDEX - 2] = '0'; + } + } + + lstrcat (lptmp, embStr); + + lpobj->topic = GlobalAddAtom (lpstr); + + // Topic, item have changed, lpobj->hLink is out of date. + if (lpobj->hLink) { + GlobalFree (lpobj->hLink); + lpobj->hLink = NULL; + } +} + + +///////////////////////////////////////////////////////////////////// +// // +// Routines related to the asynchronous processing. // +// // +///////////////////////////////////////////////////////////////////// + +void NextAsyncCmd (lpobj, mainRtn) +LPOBJECT_LE lpobj; +WORD mainRtn; +{ + lpobj->mainRtn = mainRtn; + lpobj->subRtn = 0; + +} + +void InitAsyncCmd (lpobj, cmd, mainRtn) +LPOBJECT_LE lpobj; +WORD cmd; +WORD mainRtn; +{ + lpobj->asyncCmd = cmd; + lpobj->mainErr = OLE_OK; + lpobj->mainRtn = mainRtn; + lpobj->subRtn = 0; + lpobj->subErr = 0; + lpobj->bAsync = 0; + lpobj->endAsync = 0; + lpobj->errHint = 0; +} + +void FARINTERNAL FarInitAsyncCmd (lpobj, cmd, mainRtn) +LPOBJECT_LE lpobj; +WORD cmd; +WORD mainRtn; +{ + return (InitAsyncCmd(lpobj, cmd, mainRtn)); +} + + +OLESTATUS EndAsyncCmd (lpobj) +LPOBJECT_LE lpobj; +{ + + OLESTATUS olderr; + + + if (!lpobj->endAsync) { + lpobj->asyncCmd = OLE_NONE; + return OLE_OK; + } + + + // this is an asynchronous operation. Send callback with or without + // error. + + switch (lpobj->asyncCmd) { + + case OLE_DELETE: + break; + + case OLE_COPYFROMLNK: + case OLE_CREATEFROMFILE: + // change the topic name to embedded. + SetEmbeddedTopic (lpobj); + break; + + case OLE_LOADFROMSTREAM: + case OLE_LNKPASTE: + case OLE_RUN: + case OLE_SHOW: + case OLE_ACTIVATE: + case OLE_UPDATE: + case OLE_CLOSE: + case OLE_RECONNECT: + case OLE_CREATELINKFROMFILE: + case OLE_CREATEINVISIBLE: + case OLE_CREATE: + case OLE_CREATEFROMTEMPLATE: + case OLE_SETUPDATEOPTIONS: + case OLE_SERVERUNLAUNCH: + case OLE_SETDATA: + case OLE_REQUESTDATA: + case OLE_OTHER: + break; + + case OLE_EMBPASTE: + lpobj->mainErr = OLE_OK; + break; + + default: + DEBUG_OUT ("unexpected maincmd", 0); + break; + + } + + lpobj->bAsync = FALSE; + lpobj->endAsync = FALSE; + lpobj->oldasyncCmd = lpobj->asyncCmd; + olderr = lpobj->mainErr; + lpobj->asyncCmd = OLE_NONE; // no async command in progress. + + if (lpobj->head.lpclient) + ContextCallBack (lpobj, OLE_RELEASE); + + lpobj->mainErr = OLE_OK; + return olderr; +} + + +BOOL ProcessErr (lpobj) +LPOBJECT_LE lpobj; +{ + + if (lpobj->subErr == OLE_OK) + return FALSE; + + if (lpobj->mainErr == OLE_OK) + lpobj->mainErr = lpobj->subErr; + + lpobj->subErr = OLE_OK; + return TRUE; +} + + +void ScheduleAsyncCmd (lpobj) +LPOBJECT_LE lpobj; +{ + + // replacs this with direct proc jump later on. +#ifdef FIREWALLS + ASSERT (lpobj->bAsync, "Not an asynchronous command"); +#endif + lpobj->bAsync = FALSE; + + // if the object is active and we do pokes we go thru this path + // !!! We may have to go thru the endasynccmd. + + if ((lpobj->asyncCmd == OLE_OTHER) + || ((lpobj->asyncCmd == OLE_SETDATA) && !lpobj->mainRtn)) { + lpobj->endAsync = TRUE; + lpobj->mainErr = lpobj->subErr; + EndAsyncCmd (lpobj); + if (lpobj->bUnlaunchLater) { + lpobj->bUnlaunchLater = FALSE; + CallEmbLnkDelete(lpobj); + } + + return; + } + + switch (lpobj->mainRtn) { + + case EMBLNKDELETE: + EmbLnkDelete (lpobj); + break; + + case LNKOPENUPDATE: + LnkOpenUpdate (lpobj); + break; + + case DOCSHOW: + DocShow (lpobj); + break; + + + case EMBOPENUPDATE: + EmbOpenUpdate (lpobj); + break; + + + case EMBLNKCLOSE: + EmbLnkClose (lpobj); + break; + + case LNKSETUPDATEOPTIONS: + LnkSetUpdateOptions (lpobj); + break; + + case LNKCHANGELNK: + LnkChangeLnk (lpobj); + break; + + case REQUESTDATA: + RequestData (lpobj, NULL); + break; + + default: + DEBUG_OUT ("Unexpected asyn command", 0); + break; + } + + return; +} + +void SetNetDrive (lpobj) +LPOBJECT_LE lpobj; +{ + char buf[MAX_STR]; + + if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf)) + && (buf[1] == ':')) { + AnsiUpperBuff ((LPSTR) buf, 1); + lpobj->cDrive = buf[0]; + } +} + +HANDLE GetNetNameHandle (lpobj) +LPOBJECT_LE lpobj; +{ + HANDLE hNetName; + LPSTR lpNetName; + WORD size; + + if (!(size = GlobalGetAtomLen (lpobj->aNetName))) + return NULL; + + size++; + if (!(hNetName = GlobalAlloc (GMEM_MOVEABLE, (DWORD) size))) + return NULL; + + if (lpNetName = GlobalLock (hNetName)) { + GlobalUnlock (hNetName); + if (GlobalGetAtomName(lpobj->aNetName, lpNetName, size)) + return hNetName; + } + + // error case + GlobalFree (hNetName); + return NULL; +} + +BOOL AreTopicsEqual (lpobj1, lpobj2) +LPOBJECT_LE lpobj1; +LPOBJECT_LE lpobj2; +{ + char buf1[MAX_STR]; + char buf2[MAX_STR]; + + if (lpobj1->aNetName != lpobj2->aNetName) + return FALSE; + + if (!lpobj1->aNetName) { + if (lpobj1->topic == lpobj2->topic) + return TRUE; + + return FALSE; + } + + if (!GlobalGetAtomName (lpobj1->topic, buf1, MAX_STR)) + return FALSE; + + if (!GlobalGetAtomName (lpobj2->topic, buf2, MAX_STR)) + return FALSE; + + if (!lstrcmpi (&buf1[1], &buf2[1])) + return TRUE; + + return FALSE; +} + + +ATOM FARINTERNAL wAtomCat ( +ATOM a1, +ATOM a2) +{ + char buf[MAX_STR+MAX_STR]; + LPSTR lpBuf = (LPSTR)buf; + + if (!GlobalGetAtomName (a1, lpBuf, MAX_STR+MAX_STR)) + return NULL; + + lpBuf += lstrlen(lpBuf); + + if (!GlobalGetAtomName(a2, lpBuf, MAX_STR)) + return NULL; + + return GlobalAddAtom ((LPSTR) buf); +} diff --git a/private/mvdm/wow16/ole/client/ledde.c b/private/mvdm/wow16/ole/client/ledde.c new file mode 100644 index 000000000..648d92c82 --- /dev/null +++ b/private/mvdm/wow16/ole/client/ledde.c @@ -0,0 +1,2594 @@ +/****************************** Module Header ******************************\ +* Module Name: LEDDE.C +* +* Purpose: ????? +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, Srinik (../../1990,91) Designed and coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dde.h" +#include "dll.h" + +#define LN_FUDGE 16 // [],(), 3 * 3 (2 double quotes and comma) +#define RUNITEM + +#define OLEVERB_CONNECT 0xFFFF + +// Definitions for sending the server sys command. +char *srvrSysCmd[] = {"StdNewFromTemplate", + "StdNewDocument", + "StdEditDocument", + "StdOpenDocument" + }; + +#define EMB_ID_INDEX 11 // index of ones digit in #00 +extern char embStr[]; +extern BOOL gbCreateInvisible; +extern BOOL gbLaunchServer; + +extern ATOM aMSDraw; + +extern BOOL (FAR PASCAL *lpfnIsTask) (HANDLE); + +// !!! set error hints + +OLESTATUS FARINTERNAL LeDoVerb (lpobj, verb, fShow, fActivate) +LPOBJECT_LE lpobj; +WORD verb; +BOOL fShow; +BOOL fActivate; +{ + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + if (!QueryOpen(lpobj)) + return OLE_OK; + + lpobj->verb = verb; + lpobj->fCmd = ACT_DOVERB; + + if (fActivate) + lpobj->fCmd |= ACT_ACTIVATE; + + if (fShow) + lpobj->fCmd |= ACT_SHOW; + + InitAsyncCmd (lpobj, OLE_RUN, DOCSHOW); + return DocShow (lpobj); +} + + + +OLESTATUS FARINTERNAL LeShow (lpobj, fActivate) +LPOBJECT_LE lpobj; +BOOL fActivate; +{ + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + if (!QueryOpen(lpobj)) + return OLE_OK; + + lpobj->fCmd = ACT_SHOW; + InitAsyncCmd (lpobj, OLE_SHOW, DOCSHOW); + return DocShow (lpobj); +} + + +// DocShow : If the server is connected, show the item +// for editing. For embedded objects us NULL Item. +OLESTATUS DocShow (lpobj) +LPOBJECT_LE lpobj; +{ + switch (lpobj->subRtn) { + + case 0: + SendStdShow (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + ProcessErr (lpobj); + return EndAsyncCmd (lpobj); + + default: + DEBUG_OUT ("Unexpected subroutine", 0); + return OLE_ERROR_GENERIC; + } +} + + +void SendStdShow (lpobj) +LPOBJECT_LE lpobj; +{ + + WORD len; + WORD size; + LPSTR lpdata = NULL; + HANDLE hdata = NULL; + BOOL bShow; + + lpobj->subErr = OLE_OK; + + if (lpobj->verb == OLEVERB_CONNECT) { + lpobj->verb = NULL; + return; + } + + if (!(lpobj->fCmd & (ACT_SHOW | ACT_DOVERB))) + return; + + if (bShow = (!lpobj->bOleServer || !(lpobj->fCmd & ACT_DOVERB))) { + + // show is off, do not show the server. + if (!(lpobj->fCmd & ACT_SHOW)) + return; + + SETERRHINT(lpobj, OLE_ERROR_SHOW); + // and 18 "[StdShowItem(\"")for 5 extra for ",FALSE + len = 18 + 7; + } else { + // 19 for the string [StdDoVerbItem(\"") and + // 18 extra is for ",000,FALSE,FALSE + SETERRHINT(lpobj, OLE_ERROR_DOVERB); + len = 19 + 18; + } + + len += GlobalGetAtomLen (lpobj->item); + + len += 4; // ")]" + NULL + + hdata = GlobalAlloc (GMEM_DDESHARE, size = len); + if (hdata == NULL || (lpdata = (LPSTR)GlobalLock (hdata)) == NULL) + goto errRtn; + + if (bShow) + lstrcpy (lpdata, "[StdShowItem(\""); + else + lstrcpy (lpdata, "[StdDoVerbItem(\""); + + len = lstrlen (lpdata); + + if (lpobj->item) + GlobalGetAtomName (lpobj->item , lpdata + len, size - len); + + if (!bShow) { + + lstrcat (lpdata, (LPSTR)"\","); + // assume that the number of verbs are < 10 + + len = lstrlen (lpdata); +#ifdef FIREWALLS + ASSERT ( (lpobj->verb & 0x000f) < 9 , "Verb value more than 9"); +#endif + lpdata += len; + *lpdata++ = (char)((lpobj->verb & 0x000f) + '0'); + *lpdata = 0; + + if (lpobj->fCmd & ACT_SHOW) + lstrcat (lpdata, (LPSTR) ",TRUE"); + else + lstrcat (lpdata, (LPSTR) ",FALSE"); + // StdVerbItem (item, verb, TRUE + // add TRUE/FALSE constant for the activate + if (!(lpobj->fCmd & ACT_ACTIVATE)) + lstrcat (lpdata, (LPSTR) ",TRUE)]"); + else + lstrcat (lpdata, (LPSTR) ",FALSE)]"); + // [StdDoVerb ("item", verb, FALSE, FALSE)] + } else + lstrcat (lpdata, (LPSTR)"\")]"); + // apps like excel and wingraph do not suuport activate at + // item level. + + + GlobalUnlock (hdata); + DocExecute (lpobj, hdata); + return; + +errRtn: + if (lpdata) + GlobalUnlock (hdata); + + if (hdata) + GlobalFree (hdata); + + lpobj->subErr = OLE_ERROR_MEMORY; + return; +} + + + +OLESTATUS FARINTERNAL LeQueryOpen (LPOBJECT_LE lpobj) +{ + + if (QueryOpen(lpobj)) + return OLE_OK; + else + return OLE_ERROR_NOT_OPEN; + +} + + +BOOL INTERNAL QueryOpen (LPOBJECT_LE lpobj) +{ + + if (lpobj->pDocEdit && lpobj->pDocEdit->hClient) { + if (IsServerValid (lpobj)) + return TRUE; + // destroy the windows and pretend as if the server was never + // connected. + + DestroyWindow (lpobj->pDocEdit->hClient); + if (lpobj->pSysEdit && lpobj->pSysEdit->hClient) + DestroyWindow (lpobj->pSysEdit->hClient); + + } + return FALSE; +} + + + +OLESTATUS FARINTERNAL LeActivate (lpobj, verb, fShow, fActivate, hWnd, lprc) +LPOBJECT_LE lpobj; +WORD verb; +BOOL fShow; +BOOL fActivate; +HWND hWnd; +LPRECT lprc; +{ + + lpobj->verb = verb; + if (lpobj->head.ctype == CT_EMBEDDED) + return EmbOpen (lpobj, fShow, fActivate, hWnd, lprc); + +#ifdef FIREWALLS + ASSERT (lpobj->head.ctype == CT_LINK, "unknown object"); +#endif + return LnkOpen (lpobj, fShow, fActivate, hWnd, lprc); + +} + + +OLESTATUS FARINTERNAL LeUpdate (lpobj) +LPOBJECT_LE lpobj; +{ + if (lpobj->head.ctype == CT_EMBEDDED) + return EmbUpdate (lpobj); + +#ifdef FIREWALLS + ASSERT (lpobj->head.ctype == CT_LINK, "unknown object"); +#endif + return LnkUpdate (lpobj); +} + + + +OLESTATUS FARINTERNAL EmbOpen (lpobj, fShow, fActivate, hWnd, lprc) +LPOBJECT_LE lpobj; +BOOL fShow; +BOOL fActivate; +HWND hWnd; +LPRECT lprc; +{ + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + if(QueryOpen (lpobj)) + return LeDoVerb (lpobj, lpobj->verb, fShow, fActivate); + + // show the window + // advise for data only on close + // and shut down the conv after the advises. + + lpobj->fCmd = LN_EMBACT | ACT_DOVERB | ACT_ADVISE | ACT_CLOSE; + if (fActivate) + lpobj->fCmd |= ACT_ACTIVATE; + + if (fShow) + lpobj->fCmd |= ACT_SHOW; + + InitAsyncCmd (lpobj, OLE_ACTIVATE, EMBOPENUPDATE); + return EmbOpenUpdate (lpobj); + +} + + + +/***************************** Public Function ****************************\ +* OLESTATUS FARINTERNAL EmbUpdate (lpobj) +* +* This function updates an EMB object. If the server is connected +* simply send a request for the native as well as the display formats. +* If the server is connected, then tries to start the conversationa and +* get the data. If the conversation fails, then load the server and +* start the conversation. The embeded objects may have links in it. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + + +OLESTATUS FARINTERNAL EmbUpdate (lpobj) +LPOBJECT_LE lpobj; +{ + + // if we are loading the server, then definitly unload. + // if the connection is established, then unload if it is + // to be unloaded, when all the previous requests are satisfied. + + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + lpobj->fCmd = LN_EMBACT | ACT_REQUEST | (QueryOpen(lpobj) ? 0 : ACT_UNLAUNCH); + InitAsyncCmd (lpobj, OLE_UPDATE, EMBOPENUPDATE); + return EmbOpenUpdate (lpobj); + +} + + + +OLESTATUS FARINTERNAL EmbOpenUpdate (lpobj) +LPOBJECT_LE lpobj; +{ + + switch (lpobj->subRtn) { + + case 0: + + SKIP_TO (QueryOpen(lpobj), step6); + SendSrvrMainCmd (lpobj, lpobj->lptemplate); + lpobj->lptemplate = NULL; + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + + if (ProcessErr (lpobj)) + goto errRtn; + + // Init doc conversation should set the failure error + if (!InitDocConv (lpobj, !POPUP_NETDLG)) + goto errRtn; + + // If there is no native data, do not do any poke. + // creates will not have any poke data to start with + + SKIP_TO (!(lpobj->hnative), step6); + PokeNativeData (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 2: + if (ProcessErr (lpobj)) + goto errRtn; + // Now poke the hostnames etc stuff. + PokeHostNames (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 3: + + // do not worry about the poke hostname errors + PokeTargetDeviceInfo (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 4: + + PokeDocDimensions (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 5: + + PokeColorScheme (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + + case 6: + + step6: + + // wingraph does not accept the doc dimensions + // after sttedit. + CLEAR_STEP_ERROR (lpobj); + SETSTEP (lpobj, 6); + STEP_NOP (lpobj); + // step_nop simply increments the step numebr + // merge the steps later on + + + + case 7: + + if (ProcessErr (lpobj)) + goto errRtn; + + SKIP_TO (!(lpobj->fCmd & ACT_ADVISE), step11); + lpobj->optUpdate = oleupdate_onsave; + lpobj->pDocEdit->nAdviseSave = 0; + AdviseOn (lpobj, cfNative, aSave); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 8: + + // do not go for errors on /save. Some servers may not support + // this. + + CLEAR_STEP_ERROR (lpobj); + AdvisePict (lpobj, aSave); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 9: + + // do not worry about the error case for save. Ignore them + + CLEAR_STEP_ERROR (lpobj); + lpobj->optUpdate = oleupdate_onclose; + lpobj->pDocEdit->nAdviseClose = 0; + AdviseOn (lpobj, cfNative, aClose); + WAIT_FOR_ASYNC_MSG (lpobj); + + + case 10: + if (ProcessErr(lpobj)) + goto errRtn; + + AdvisePict (lpobj, aClose); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 11: + + step11: + SETSTEP (lpobj, 11); + if (ProcessErr(lpobj)) + goto errRtn; + + SKIP_TO (!(lpobj->fCmd & ACT_REQUEST), step13); + + // we don't want to send OLE_CHANGED when we get this data, if we + // are going to request for picture data also. + lpobj->pDocEdit->bCallLater = ((lpobj->lpobjPict) ? TRUE: FALSE); + RequestOn (lpobj, cfNative); + WAIT_FOR_ASYNC_MSG (lpobj); + + // If request pict fails, then native and pict are + // not in sync. + + case 12: + if (ProcessErr(lpobj)) + goto errRtn; + + lpobj->pDocEdit->bCallLater = FALSE; + RequestPict (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + + case 13: + + step13: + SETSTEP(lpobj, 13); + + if (ProcessErr(lpobj)) + goto errRtn; + + SendStdShow (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 14: + + + if (ProcessErr(lpobj)) + goto errRtn; + + SKIP_TO ((lpobj->fCmd & ACT_UNLAUNCH), step15); + return EndAsyncCmd (lpobj); + + + case 15: + +errRtn: + step15: + ProcessErr (lpobj); + + if ((lpobj->asyncCmd == OLE_UPDATE) + && (!(lpobj->fCmd & ACT_UNLAUNCH))) + return EndAsyncCmd (lpobj); + + // if we launched and error, unlaunch (send stdexit) + NextAsyncCmd (lpobj, EMBLNKDELETE); + lpobj->fCmd |= ACT_UNLAUNCH; + EmbLnkDelete (lpobj); + return lpobj->mainErr; + + + default: + DEBUG_OUT ("Unexpected subroutine", 0); + return OLE_ERROR_GENERIC; + } +} + + + + +OLESTATUS FARINTERNAL LnkOpen (lpobj, fShow, fActivate, hWnd, lprc) +LPOBJECT_LE lpobj; +BOOL fShow; +BOOL fActivate; +HWND hWnd; +LPRECT lprc; +{ + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + if(QueryOpen (lpobj)) + return LeDoVerb (lpobj, lpobj->verb, fShow, fActivate); + + // Just end the system conversation. we are not unloading + // this instance at all. + + lpobj->fCmd = LN_LNKACT | ACT_DOVERB; + + if (lpobj->optUpdate == oleupdate_always) + lpobj->fCmd |= ACT_ADVISE | ACT_REQUEST; + else if (lpobj->optUpdate == oleupdate_onsave) + lpobj->fCmd |= ACT_ADVISE; + + if (fActivate) + lpobj->fCmd |= ACT_ACTIVATE; + + if (fShow) + lpobj->fCmd |= ACT_SHOW; + + InitAsyncCmd (lpobj, OLE_ACTIVATE, LNKOPENUPDATE); + return LnkOpenUpdate (lpobj); + +} + + +OLESTATUS FARINTERNAL LnkUpdate (lpobj) +LPOBJECT_LE lpobj; +{ + // if we are loading the server, then definitly unload. + // if the connection is established, then unload if it is + // to be unloaded, when all the previous requests are satisfied. + + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + lpobj->fCmd = LN_LNKACT | ACT_REQUEST | (QueryOpen (lpobj) ? 0 : ACT_UNLAUNCH); + InitAsyncCmd (lpobj, OLE_UPDATE, LNKOPENUPDATE); + return LnkOpenUpdate (lpobj); +} + + + +OLESTATUS FARINTERNAL LnkOpenUpdate (lpobj) +LPOBJECT_LE lpobj; +{ + switch (lpobj->subRtn) { + + case 0: + + SKIP_TO (QueryOpen(lpobj), step2); + InitDocConv (lpobj, !POPUP_NETDLG); + if (QueryOpen(lpobj)) { + if (lpobj->app == aPackage) + RemoveLinkStringFromTopic (lpobj); + goto step2; + } + + SendSrvrMainCmd (lpobj, NULL); + WAIT_FOR_ASYNC_MSG (lpobj); + + + case 1: + + if (ProcessErr (lpobj)) + goto errRtn; + + if (lpobj->app == aPackage) + RemoveLinkStringFromTopic (lpobj); + + if (!InitDocConv (lpobj, POPUP_NETDLG)) { + lpobj->subErr = OLE_ERROR_OPEN; + goto errRtn; + } + + case 2: + + step2: + + SETSTEP (lpobj, 2); + PokeTargetDeviceInfo (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 3: + + if (ProcessErr (lpobj)) + goto errRtn; + + SKIP_TO (!(lpobj->fCmd & ACT_ADVISE), step6); + SKIP_TO (!(lpobj->fCmd & ACT_NATIVE), step4); + AdviseOn (lpobj, cfNative, NULL); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 4: + step4: + SETSTEP (lpobj, 4); + if (ProcessErr (lpobj)) + goto errRtn; + + AdvisePict (lpobj, NULL); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 5: + + if (ProcessErr (lpobj)) + goto errRtn; + + // Now send advise for renaming the documnet. + AdviseOn (lpobj, cfBinary, aStdDocName); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 6: + + step6: + // if name advise fails ignore it + SETSTEP (lpobj, 6); + + CLEAR_STEP_ERROR (lpobj); + SKIP_TO (!(lpobj->fCmd & ACT_REQUEST), step8); + SKIP_TO (!(lpobj->fCmd & ACT_NATIVE), step7); + + // we don't want to send OLE_CHANGED when we get this data, if we + // are going to request for picture data also. + lpobj->pDocEdit->bCallLater = ((lpobj->lpobjPict) ? TRUE: FALSE); + RequestOn (lpobj, cfNative); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 7: + step7: + + SETSTEP (lpobj, 7); + if (ProcessErr (lpobj)) + goto errRtn; + + lpobj->pDocEdit->bCallLater = FALSE; + RequestPict (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 8: + + step8: + + SETSTEP (lpobj, 8); + if (ProcessErr (lpobj)) + goto errRtn; + + SKIP_TO (!(lpobj->fCmd & ACT_TERMDOC), step10); + // terminate the document conversataion. + TermDocConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 9: + + if (ProcessErr (lpobj)) + goto errRtn; + + // delete the server edit block + DeleteDocEdit (lpobj); + + SKIP_TO ((lpobj->fCmd & ACT_UNLAUNCH), step14); + return EndAsyncCmd (lpobj); + + case 10: + + step10: + SETSTEP (lpobj, 10); + + if (ProcessErr (lpobj)) + goto errRtn; + + SKIP_TO (!(lpobj->fCmd & ACT_TERMSRVR), step12); + + // terminate the server conversataion. + TermSrvrConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 11: + + if (ProcessErr (lpobj)) + goto errRtn; + + // delete the server edit block + DeleteSrvrEdit (lpobj); + return EndAsyncCmd (lpobj); + + + case 12: + + step12: + SETSTEP (lpobj, 12); + if (ProcessErr (lpobj)) + goto errRtn; + + SendStdShow (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 13: + + if (ProcessErr (lpobj)) + goto errRtn; + SKIP_TO ((lpobj->fCmd & ACT_UNLAUNCH), step14); + return EndAsyncCmd (lpobj); + + + case 14: + + errRtn: + step14: + ProcessErr (lpobj); + + if ((lpobj->asyncCmd == OLE_UPDATE) + && (!(lpobj->fCmd & ACT_UNLAUNCH))) + return EndAsyncCmd (lpobj); + + // if we launched and error, unlaunch (send stdexit) + NextAsyncCmd (lpobj, EMBLNKDELETE); + lpobj->fCmd |= ACT_UNLAUNCH; + EmbLnkDelete (lpobj); + return lpobj->mainErr; + + default: + DEBUG_OUT ("Unexpected subroutine", 0); + return OLE_ERROR_GENERIC; + } +} + + + +OLESTATUS EmbLnkClose (lpobj) +LPOBJECT_LE lpobj; +{ + switch (lpobj->subRtn) { + + case 0: + TermDocConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + + // delete the edit block + DeleteDocEdit (lpobj); + TermSrvrConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 2: + + // Do not set any errors, just delete the object. + // delete the server edit block + DeleteSrvrEdit (lpobj); + return EndAsyncCmd (lpobj); + + + default: + DEBUG_OUT ("Unexpected subroutine", 0); + return OLE_ERROR_GENERIC; + } +} + + +OLESTATUS FARINTERNAL LeClose (lpobj) +LPOBJECT_LE lpobj; +{ + PROBE_ASYNC (lpobj); + if (IS_SVRCLOSING(lpobj)) + return OLE_OK; + + + lpobj->fCmd = 0; + + if (lpobj->head.ctype == CT_EMBEDDED) { + InitAsyncCmd (lpobj, OLE_CLOSE, EMBLNKDELETE); + return EmbLnkDelete (lpobj); + } + else { + InitAsyncCmd (lpobj, OLE_CLOSE, EMBLNKCLOSE); + return EmbLnkClose (lpobj); + } +} + + + +OLESTATUS FARINTERNAL LeReconnect (lpobj) +LPOBJECT_LE lpobj; +{ + // check for the existing conversation. + // if the client window is non-null, then + // connection exits. + + if (lpobj->head.ctype != CT_LINK) + return OLE_ERROR_NOT_LINK; // allow only for linked + + PROBE_ASYNC (lpobj); + PROBE_SVRCLOSING(lpobj); + + if (QueryOpen (lpobj)) + return OLE_OK; + + // start just the conversation. Do not load + // the app. + + if (!InitDocConv (lpobj, !POPUP_NETDLG)) + return OLE_OK; // document is not loaded , it is OK. + + lpobj->fCmd = LN_LNKACT; + if (lpobj->optUpdate == oleupdate_always) + lpobj->fCmd |= ACT_ADVISE | ACT_REQUEST; + + InitAsyncCmd (lpobj, OLE_RECONNECT, LNKOPENUPDATE); + return LnkOpenUpdate (lpobj); +} + + + + +OLESTATUS INTERNAL PokeNativeData (lpobj) +LPOBJECT_LE lpobj; +{ + SETERRHINT(lpobj, OLE_ERROR_POKE_NATIVE); + return SendPokeData (lpobj, + lpobj->item, + lpobj->hnative, + cfNative); +} + + + + +BOOL INTERNAL PostMessageToServer (pedit, msg, lparam) +PEDIT_DDE pedit; +WORD msg; +LONG lparam; +{ + +#ifdef FIREWALLS + ASSERT (pedit, "Dde edit block is NULL"); +#endif + // save the lparam and msg fpr possible reposting incase of error. + + // we are in abort state. no messages except for terminate. + + if (pedit->bAbort && msg != WM_DDE_TERMINATE) + return FALSE; + + pedit->lParam = lparam; + pedit->msg = msg; + + if (pedit->hClient && pedit->hServer) { + while (TRUE){ + if (!IsWindowValid (pedit->hServer)) + return FALSE; + if (PostMessage (pedit->hServer, msg, pedit->hClient, lparam) == FALSE) + Yield (); + else + return TRUE; + } + } + return FALSE; +} + + +OLESTATUS FARINTERNAL LeCreateFromTemplate (lpclient, lptemplate, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPOLECLIENT lpclient; +LPSTR lptemplate; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + char buf[MAX_STR]; + + if (!MapExtToClass (lptemplate, (LPSTR)buf, MAX_STR)) + return OLE_ERROR_CLASS; + + return CreateFromClassOrTemplate (lpclient, (LPSTR) buf, lplpoleobject, + optRender, cfFormat, LN_TEMPLATE, lptemplate, + lhclientdoc, lpobjname); +} + + +OLESTATUS FARINTERNAL LeCreate (lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPSTR lpclass; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + if (gbCreateInvisible) { + // this is in fact a call for invisible create + return LeCreateInvisible (lpclient, lpclass, lhclientdoc, lpobjname, + lplpoleobject, optRender, cfFormat, gbLaunchServer); + } + + return CreateFromClassOrTemplate (lpclient, lpclass, lplpoleobject, + optRender, cfFormat, LN_NEW, NULL, + lhclientdoc, lpobjname); +} + + + +OLESTATUS FARINTERNAL CreateFromClassOrTemplate (lpclient, lpclass, lplpoleobject, optRender, cfFormat, lnType, lptemplate, lhclientdoc, lpobjname) +LPOLECLIENT lpclient; +LPSTR lpclass; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +WORD lnType; +LPSTR lptemplate; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + LPOBJECT_LE lpobj = NULL; + ATOM aServer; + char chVerb [2]; + + if (!(aServer = GetAppAtom (lpclass))) + return OLE_ERROR_CLASS; + + if(!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_EMBEDDED))) { + GlobalDeleteAtom (aServer); + goto errRtn; + } + + // Now set the server. + + lpobj->head.lpclient = lpclient; + lpobj->app = GlobalAddAtom (lpclass); + SetEmbeddedTopic (lpobj); + lpobj->item = NULL; + lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2); + lpobj->aServer = aServer; + + // launch the app and start the system conversation. + + if (!CreatePictObject (lhclientdoc, lpobjname, lpobj, + optRender, cfFormat, lpclass)) + goto errRtn; + + + // show the window. Advise for data and close on receiving data + lpobj->fCmd = lnType | ACT_SHOW | ACT_ADVISE | ACT_CLOSE; + InitAsyncCmd (lpobj, lptemplate? OLE_CREATEFROMTEMPLATE : OLE_CREATE, EMBOPENUPDATE); + *lplpoleobject = (LPOLEOBJECT)lpobj; + + lpobj->lptemplate = lptemplate; + + if ((retval = EmbOpenUpdate (lpobj)) <= OLE_WAIT_FOR_RELEASE) + return retval; + + // If there is error afterwards, then the client app should call + // to delete the object. + +errRtn: + + // for error termination OleDelete will terminate any conversation + // in action. + + if (lpobj) { + // This oledelete will not result in asynchronous command. + OleDelete ((LPOLEOBJECT)lpobj); + *lplpoleobject = NULL; + } + + return retval; +} + + + +OLESTATUS FARINTERNAL CreateEmbLnkFromFile (lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, objType) +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LPSTR lpitem; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LONG objType; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + LPOBJECT_LE lpobj = NULL; + ATOM aServer; + char buf[MAX_STR]; + OLE_RELEASE_METHOD releaseMethod; + WORD wFlags = NULL; + char chVerb[2]; + + if (!lpclass && (lpclass = (LPSTR) buf) + && !MapExtToClass (lpfile, (LPSTR)buf, MAX_STR)) + return OLE_ERROR_CLASS; + + if (!(aServer = GetAppAtom (lpclass))) + return OLE_ERROR_CLASS; + + if (!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_LINK))) { + GlobalDeleteAtom (aServer); + goto errFileCreate; + } + + lpobj->head.lpclient = lpclient; + lpobj->app = GlobalAddAtom (lpclass); + lpobj->topic = GlobalAddAtom (lpfile); + lpobj->aServer = aServer; + lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2); + if ((retval = SetNetName (lpobj)) != OLE_OK) + goto errFileCreate; + + if (lpitem) + lpobj->item = GlobalAddAtom (lpitem); + + if (!CreatePictObject (lhclientdoc, lpobjname, lpobj, + optRender, cfFormat, lpclass)) { + retval = OLE_ERROR_MEMORY; + goto errFileCreate; + } + + *lplpoleobject = (LPOLEOBJECT) lpobj; + + if (objType == CT_EMBEDDED) { + releaseMethod = OLE_CREATEFROMFILE; + if ((optRender == olerender_format) && (cfFormat == cfNative)) + wFlags = 0; + else + wFlags = ACT_NATIVE; + } + else { + // caller wants linked object to be created + + // if no presentation data is requested and the link is to the whole + // file, then there is no need to launch the server. + + if ((optRender == olerender_none) && !lpobj->item) + return FileExists (lpobj); + + // we want to establish hot link + wFlags = ACT_ADVISE; + releaseMethod = OLE_CREATELINKFROMFILE; + } + + lpobj->fCmd = LN_LNKACT | ACT_REQUEST | ACT_UNLAUNCH | wFlags; + InitAsyncCmd (lpobj, releaseMethod , LNKOPENUPDATE); + + if ((retval = LnkOpenUpdate (lpobj)) <= OLE_WAIT_FOR_RELEASE) + return retval; + + // If there is error afterwards, then the client app should call + // to delete the object. + + +errFileCreate: + + if (lpobj) { + // This oledelete will not result in asynchronous command. + OleDelete ((LPOLEOBJECT)lpobj); + *lplpoleobject = NULL; + } + + return retval; +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FARINTERNAL LeCreateInvisible (lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, bActivate) +// +// Arguments: +// +// lpclient - +// lpclass - +// lhclientdoc - +// lpobjname - +// lplpoleobject - +// optRender - +// cfFormat - +// fActivate - +// +// Returns: +// +// OLE_ERROR_CLASS - +// OLE_OK - +// EmbOpenUpdate (lpobj) - +// retval - +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL LeCreateInvisible (lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, fActivate) +LPSTR lpclass; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +BOOL fActivate; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + LPOBJECT_LE lpobj = NULL; + ATOM aServer; + char chVerb [2]; + + if (!(aServer = GetAppAtom (lpclass))) + return OLE_ERROR_CLASS; + + if(!(lpobj = LeCreateBlank (lhclientdoc, lpobjname, CT_EMBEDDED))) { + GlobalDeleteAtom (aServer); + goto errRtn; + } + + // Now set the server. + + lpobj->head.lpclient = lpclient; + lpobj->app = GlobalAddAtom (lpclass); + lpobj->item = NULL; + lpobj->bOleServer = QueryVerb (lpobj, 0, (LPSTR)&chVerb, 2); + lpobj->aServer = aServer; + lpobj->lptemplate = NULL; + SetEmbeddedTopic (lpobj); + + if (!CreatePictObject (lhclientdoc, lpobjname, lpobj, + optRender, cfFormat, lpclass)) + goto errRtn; + + *lplpoleobject = (LPOLEOBJECT)lpobj; + + if (!fActivate) + return OLE_OK; + + // show the window. Advise for data and close on receiving data + lpobj->fCmd = LN_NEW | ACT_ADVISE | ACT_CLOSE; + InitAsyncCmd (lpobj, OLE_CREATEINVISIBLE, EMBOPENUPDATE); + + // launch the app and start the system conversation. + if ((retval = EmbOpenUpdate (lpobj)) <= OLE_WAIT_FOR_RELEASE) + return retval; + + // If there is error afterwards, then the client app should call + // to delete the object. + +errRtn: + + // for error termination OleDelete will terminate any conversation + // in action. + + if (lpobj) { + // This oledelete will not result in asynchronous command. + OleDelete ((LPOLEOBJECT)lpobj); + *lplpoleobject = NULL; + } + + return retval; +} + + + +// LeSetUpdateOptions: sets the update options. If the server +// is connectd then it unadvises for the current options and +// advises for the new options. + +OLESTATUS FARINTERNAL LeSetUpdateOptions (lpobj, options) +LPOBJECT_LE lpobj; +OLEOPT_UPDATE options; +{ + + PROBE_OLDLINK (lpobj); + PROBE_ASYNC (lpobj); + + //!!! make sure the options are within range. + + if (lpobj->head.ctype != CT_LINK) + return (OLE_ERROR_OBJECT); + + if (options > oleupdate_oncall) + return OLE_ERROR_OPTION; + + if (lpobj->optUpdate == options) + return OLE_OK; + + if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) { + lpobj->optUpdate = options; + return OLE_OK; + } + + lpobj->optNew = options; + lpobj->fCmd = 0; + InitAsyncCmd (lpobj, OLE_SETUPDATEOPTIONS, LNKSETUPDATEOPTIONS); + return LnkSetUpdateOptions (lpobj); + +} + +OLESTATUS LnkSetUpdateOptions (lpobj) +LPOBJECT_LE lpobj; +{ + + switch (lpobj->subRtn) { + + case 0: + + if (lpobj->optUpdate == oleupdate_oncall) + goto step1; + + // If the server is active then unadvise for old + // options. + + UnAdvisePict (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + step1: + + SETSTEP (lpobj, 1); + ProcessErr (lpobj); + + lpobj->optUpdate = lpobj->optNew; + if (lpobj->optUpdate == oleupdate_oncall) + goto step3; + + AdvisePict (lpobj, NULL); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 2: + SETSTEP (lpobj, 2); + if (ProcessErr (lpobj)) + goto errRtn; + + if (lpobj->optUpdate == oleupdate_onsave) + goto step3; + + RequestPict (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 3: + errRtn: + step3: + ProcessErr (lpobj); + return EndAsyncCmd (lpobj); + + default: + DEBUG_OUT ("Unexpected subroutine", 0); + return OLE_ERROR_GENERIC; + } +} + + + +//AdvisePict: Sends advise for pict data + +void INTERNAL AdvisePict (lpobj, aAdvItem) +LPOBJECT_LE lpobj; +ATOM aAdvItem; +{ + int cftype; + + if (cftype = GetPictType (lpobj)) + AdviseOn (lpobj, cftype, aAdvItem); +} + + +//UnAdvisePict: Sends unadvise for pict data + +void INTERNAL UnAdvisePict (lpobj) +LPOBJECT_LE lpobj; +{ + int cftype; + SETERRHINT (lpobj, OLE_ERROR_ADVISE_PICT); + if (cftype = GetPictType (lpobj)) + UnAdviseOn (lpobj, cftype); +} + +// GetPictType: Given the object, returns the pict type. + +int INTERNAL GetPictType (lpobj) +LPOBJECT_LE lpobj; +{ + if (lpobj->lpobjPict) + return (int)(*lpobj->lpobjPict->lpvtbl->EnumFormats) + (lpobj->lpobjPict, NULL); + return NULL; +} + + +// AdviseOn : Sends advise for a given picture type +// Send advise only if the advise options is not on call. + +void INTERNAL AdviseOn (lpobj, cftype, advItem) +LPOBJECT_LE lpobj; +int cftype; +ATOM advItem; +{ + HANDLE hopt = NULL; + DDEADVISE FAR *lpopt = NULL; + ATOM item = NULL; + PEDIT_DDE pedit; + OLESTATUS retval; + + if (cftype == (int)cfNative) + SETERRHINT (lpobj, OLE_ERROR_ADVISE_NATIVE); + else { + if (cftype == (int)cfBinary) + SETERRHINT (lpobj, OLE_ERROR_ADVISE_RENAME); + else + SETERRHINT (lpobj, OLE_ERROR_ADVISE_PICT); + + } + + if (lpobj->optUpdate == oleupdate_oncall) + return; + + if(!(hopt = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, sizeof(DDEADVISE)))) + goto errRtn; + + retval = OLE_ERROR_MEMORY; + if(!(lpopt = (DDEADVISE FAR *) GlobalLock (hopt))) + goto errRtn; + + pedit = lpobj->pDocEdit; + lpopt->fAckReq = TRUE; + + // get data always. Currently there is no way for the + // deferred updates. + + lpopt->fDeferUpd = 0; + lpopt->cfFormat = cftype; + GlobalUnlock (hopt); + + pedit->hopt = hopt; + + if (advItem == aStdDocName) + item = DuplicateAtom (advItem); + else + item = ExtendAtom (lpobj, lpobj->item); + + retval = OLE_ERROR_COMM; + if (!PostMessageToServer(pedit, WM_DDE_ADVISE, MAKELONG (hopt, item))) + goto errRtn; + +#ifdef FIREWALLS + ASSERT (!pedit->bTerminating, "trying to post while termination") + ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack") +#endif + pedit->awaitAck = AA_ADVISE; + lpobj->bAsync = TRUE; + + if (advItem == aClose) + lpobj->pDocEdit->nAdviseClose++; + else if (advItem == aSave) + lpobj->pDocEdit->nAdviseSave++; + + return; + +errRtn: + + if (item) + GlobalDeleteAtom (item); + + if (lpopt) + GlobalUnlock (hopt); + + if (hopt) + GlobalFree (hopt); + lpobj->subErr = retval; + + return ; + + +} + + + +//UnAdviseOn: Sends unadvise for an item. +void INTERNAL UnAdviseOn (lpobj, cftype) +LPOBJECT_LE lpobj; +int cftype; +{ + ATOM item; + PEDIT_DDE pedit; + + pedit = lpobj->pDocEdit; + item = ExtendAtom (lpobj, lpobj->item); + + if (!PostMessageToServer(pedit, WM_DDE_UNADVISE, MAKELONG (NULL, item))) + lpobj->subErr = OLE_ERROR_COMM; + else { +#ifdef FIREWALLS + ASSERT (!pedit->bTerminating, "trying to post while termination") + ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack") +#endif + lpobj->bAsync = TRUE; + pedit->awaitAck = AA_UNADVISE; + } +} + +// RequestOn: Semd WM_DDE_REQUEST for the item of the +// for a given type; + +void INTERNAL RequestOn (lpobj, cftype) +LPOBJECT_LE lpobj; +int cftype; +{ + ATOM item = NULL; + PEDIT_DDE pedit; + OLESTATUS retval = OLE_ERROR_COMM; + + if (cftype == (int)cfNative) + SETERRHINT (lpobj, OLE_ERROR_REQUEST_NATIVE); + else + SETERRHINT (lpobj, OLE_ERROR_REQUEST_PICT); + + pedit = lpobj->pDocEdit; + + item = DuplicateAtom (lpobj->item); + if (!PostMessageToServer (pedit, WM_DDE_REQUEST, MAKELONG (cftype, item))) + goto errRtn; + +#ifdef FIREWALLS + ASSERT (!pedit->bTerminating, "trying to post while termination") + ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack") +#endif + + lpobj->bAsync = TRUE; + pedit->awaitAck = AA_REQUEST; + return; + +errRtn: + + if (item) + GlobalDeleteAtom (item); + return ; + +} + + +//RequestPict: Sends request for apicture type. +void INTERNAL RequestPict (lpobj) +LPOBJECT_LE lpobj; +{ + int cftype; + + if (cftype = GetPictType (lpobj)) + RequestOn (lpobj, cftype); +} + + + +// LeSetHostNames: Sets the host names. If the server is connected +// send the host names to the server. +OLESTATUS FARINTERNAL LeSetHostNames (lpobj, lpclientName, lpdocName) +LPOBJECT_LE lpobj; +LPSTR lpclientName; +LPSTR lpdocName; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + + if (lpobj->head.ctype != CT_EMBEDDED) + return OLE_ERROR_OBJECT; + + PROBE_ASYNC (lpobj); + if ((retval = SetHostNamesHandle (lpobj, lpclientName, lpdocName)) + != OLE_OK) + return retval; + + + // If the server is connected poke the hostnames + InitAsyncCmd (lpobj, OLE_OTHER, NULL); + if ((retval = PokeHostNames (lpobj)) != OLE_WAIT_FOR_RELEASE) + CLEARASYNCCMD(lpobj); + + return retval; +} + + + +OLESTATUS FARINTERNAL LeSetTargetDevice (lpobj, hdata) +LPOBJECT_LE lpobj; +HANDLE hdata; +{ + HANDLE hdup = NULL; + OLESTATUS retval; + + PROBE_ASYNC (lpobj); + + if (!hdata) { + // hdata == NULL means we should not make the target device sticky. + // This will give the flexibility to the client app. Note that this + // will not be effective till the next activation. + if (lpobj->htargetDevice) { + GlobalFree (lpobj->htargetDevice); + lpobj->htargetDevice = NULL; + } + + return OLE_OK; + } + + if(!(hdup = DuplicateGlobal (hdata, GMEM_MOVEABLE))) + return OLE_ERROR_MEMORY; + + if (lpobj->htargetDevice) + GlobalFree (lpobj->htargetDevice); + + lpobj->htargetDevice = hdup; + InitAsyncCmd (lpobj, OLE_OTHER, NULL); + if ((retval = PokeTargetDeviceInfo (lpobj)) != OLE_WAIT_FOR_RELEASE) + CLEARASYNCCMD(lpobj); + + return retval; +} + + + +OLESTATUS FARINTERNAL LeSetBounds(lpobj, lprcBounds) +LPOBJECT_LE lpobj; +LPRECT lprcBounds; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + HANDLE hdata = NULL; + LPBOUNDSRECT lprc = NULL; + + PROBE_ASYNC (lpobj); + + if (lpobj->head.ctype != CT_EMBEDDED) + return OLE_ERROR_OBJECT; + + if(!(hdata = GlobalAlloc (GMEM_MOVEABLE, (WORD)sizeof (BOUNDSRECT)))) + return OLE_ERROR_MEMORY; + + if (!(lprc = (LPBOUNDSRECT)GlobalLock (hdata))) + goto errrtn; + + // Now set the data + + lprc->defaultWidth = lprcBounds->right - lprcBounds->left;; + lprc->defaultHeight = -(lprcBounds->bottom - lprcBounds->top); + lprc->maxWidth = lprcBounds->right - lprcBounds->left;; + lprc->maxHeight = -(lprcBounds->bottom - lprcBounds->top); + + GlobalUnlock (hdata); + + if (lpobj->hdocDimensions) + GlobalFree (lpobj->hdocDimensions); + + lpobj->hdocDimensions = hdata; + InitAsyncCmd (lpobj, OLE_OTHER, NULL); + if ((retval = PokeDocDimensions (lpobj)) != OLE_WAIT_FOR_RELEASE) + CLEARASYNCCMD(lpobj); + + return retval; + +errrtn: + if (lprc) + GlobalUnlock (hdata); + if (hdata) + GlobalFree (hdata); + + return retval; +} + + +OLESTATUS FARINTERNAL LeSetData (lpobj, cfFormat, hData) +LPOBJECT_LE lpobj; +OLECLIPFORMAT cfFormat; +HANDLE hData; +{ + OLESTATUS retVal = OLE_OK; + BOOL fKnown = FALSE; + + PROBE_ASYNC (lpobj); + + if ((cfFormat == cfObjectLink) || (cfFormat == cfOwnerLink)) + return ChangeDocAndItem (lpobj, hData); + + if (fKnown = (cfFormat && (cfFormat == ((WORD) GetPictType (lpobj))))) { + retVal = (*lpobj->lpobjPict->lpvtbl->ChangeData) (lpobj->lpobjPict, + hData, lpobj->head.lpclient, FALSE); + + (*lpobj->lpobjPict->lpvtbl->GetData) (lpobj->lpobjPict, + cfFormat, &hData); + } + else if (fKnown = (cfFormat == cfNative)) { + retVal = LeChangeData (lpobj, hData, lpobj->head.lpclient, FALSE); + hData = lpobj->hnative; + } + + if (retVal != OLE_OK) + return retVal; + + if (fKnown) + ContextCallBack (lpobj, OLE_CHANGED); + + if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) { + if (!fKnown) + return OLE_ERROR_NOT_OPEN; + return OLE_OK; + } + + // except for the following formats all the other data will be copied + // into DDEPOKE block. So there is no need to duplicate the data of the + // other formats + if ((cfFormat == CF_METAFILEPICT) || (cfFormat == CF_BITMAP) + || (cfFormat == CF_DIB)) { + + if (!(hData = DuplicateGDIdata (hData, cfFormat))) + return OLE_ERROR_MEMORY; + } + + // *** The last parameter must be NULL, don't change it *** + InitAsyncCmd (lpobj, OLE_SETDATA, NULL); + if ((retVal = SendPokeData (lpobj, lpobj->item, hData, cfFormat)) + != OLE_WAIT_FOR_RELEASE) + CLEARASYNCCMD(lpobj); + + return retVal; +} + + + +OLESTATUS FARINTERNAL LeSetColorScheme (lpobj, lplogpal) +LPOBJECT_LE lpobj; +LPLOGPALETTE lplogpal; +{ + HANDLE hdup = NULL; + DWORD cblogpal; + OLESTATUS retval; + LPBYTE lptemp; + + lptemp = (LPBYTE) lplogpal; + + if (lpobj->head.ctype != CT_EMBEDDED) + return OLE_ERROR_OBJECT; + + PROBE_ASYNC (lpobj); + + if (!lplogpal) { + // lplogpal == NULL means we should not make color scheme sticky. + // This will give the flexibility to the client app. Note that this + // will not be effective till next activation. + if (lpobj->hlogpal) { + GlobalFree (lpobj->hlogpal); + lpobj->hlogpal = NULL; + } + + return OLE_OK; + } + + + FARPROBE_READ(lptemp + (cblogpal = 2*sizeof(WORD))); + cblogpal += ((sizeof(PALETTEENTRY) * lplogpal->palNumEntries) -1); + if (!FarCheckPointer (lptemp + cblogpal, READ_ACCESS)) + return OLE_ERROR_PALETTE; + + if (!(hdup = CopyData ((LPSTR) lplogpal, cblogpal))) + return OLE_ERROR_MEMORY; + + if (lpobj->hlogpal) + GlobalFree (lpobj->hlogpal); + + lpobj->hlogpal = hdup; + InitAsyncCmd (lpobj, OLE_OTHER, NULL); + if ((retval = PokeColorScheme (lpobj)) != OLE_WAIT_FOR_RELEASE) + CLEARASYNCCMD(lpobj); + + return retval; +} + + + +//PokeHostNames: Pokes hostname data to the server +OLESTATUS INTERNAL PokeHostNames (lpobj) +LPOBJECT_LE lpobj; +{ + OLESTATUS retVal = OLE_ERROR_MEMORY; + + // if the server is connectd then poke the host names + if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) + return OLE_OK; + + if (!lpobj->hhostNames) + return OLE_OK; + + aStdHostNames = GlobalAddAtom ("StdHostNames"); + return SendPokeData (lpobj,aStdHostNames,lpobj->hhostNames,cfBinary); +} + + +OLESTATUS INTERNAL PokeTargetDeviceInfo (lpobj) +LPOBJECT_LE lpobj; +{ + + // if the server is connectd then poke the host names + if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) + return OLE_OK; + + if (!lpobj->htargetDevice) + return OLE_OK; + + aStdTargetDevice = GlobalAddAtom ("StdTargetDevice"); + return SendPokeData (lpobj, aStdTargetDevice, + lpobj->htargetDevice, + cfBinary); +} + + +OLESTATUS INTERNAL PokeDocDimensions (lpobj) +LPOBJECT_LE lpobj; +{ + + // if the server is connectd then poke the host names + if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) + return OLE_OK; + + if (!lpobj->hdocDimensions) + return OLE_OK; + + aStdDocDimensions = GlobalAddAtom ("StdDocDimensions"); + return SendPokeData (lpobj, aStdDocDimensions, + lpobj->hdocDimensions, + cfBinary); +} + + +OLESTATUS INTERNAL PokeColorScheme (lpobj) +LPOBJECT_LE lpobj; +{ + // if the server is connected then poke the palette info + if (!QueryOpen (lpobj) || IS_SVRCLOSING(lpobj)) + return OLE_OK; + + if (!lpobj->hlogpal) + return OLE_OK; + + aStdColorScheme = GlobalAddAtom ("StdColorScheme"); + return SendPokeData (lpobj, aStdColorScheme, + lpobj->hlogpal, + cfBinary); +} + + +OLESTATUS INTERNAL SendPokeData (lpobj, aItem, hdata, cfFormat) +LPOBJECT_LE lpobj; +ATOM aItem; +HANDLE hdata; +OLECLIPFORMAT cfFormat; +{ + HANDLE hdde = NULL; + DDEPOKE FAR * lpdde = NULL; + LPSTR lpdst = NULL; + LPSTR lpsrc = NULL; + OLESTATUS retval = OLE_ERROR_MEMORY; + DWORD dwSize = NULL; + PEDIT_DDE pedit; + BOOL bGDIdata = FALSE; + + pedit = lpobj->pDocEdit; + + // If it is GDI data then we can stuff the handle into POKE block. + // Otherwise we have to copy the data into DDE data block. There + // is a special case with old MSDraw, that will be handled by + // the routine CanPutHandleInPokeBlock() + + if (!(bGDIdata = CanPutHandleInPokeBlock (lpobj, cfFormat))) { + if (!(dwSize = GlobalSize (hdata))) + return OLE_ERROR_MEMORY; + + if (!(lpsrc = (LPSTR) GlobalLock (hdata))) + return OLE_ERROR_MEMORY; + + GlobalUnlock (hdata); + } + + // Now allocate the DDE data block + + if (!(hdde = GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, + (dwSize + sizeof(DDEPOKE) - sizeof(BYTE) + sizeof(HANDLE))))) + goto errRtn; + + if (!(lpdde = (DDEPOKE FAR *)GlobalLock (hdde))) + goto errRtn; + + GlobalUnlock (hdde); + + // !!! We may want to set it TRUE, for performance reasons. But it + // will require some rework on the server side + lpdde->fRelease = 0; + lpdde->cfFormat = cfFormat; + + if (bGDIdata) + *(LPHANDLE)lpdde->Value = hdata; + else { + lpdst = (LPSTR)lpdde->Value; + UtilMemCpy (lpdst, lpsrc, dwSize); + + // For the CF_METAFILEPICT format, we would come here only if we are + // dealing with the old version of MSDraw. In that case we want to + // free the handle to METAFILEPICT strcuture, because we've already + // copied its contents to DDEPOKE structure. + + // Note that that the old MSDraw expects the contents of METAFILEPICT + // structure to be part of DDEPOKE, rather than the handle to it. + + if (cfFormat == CF_METAFILEPICT) { + GlobalFree (hdata); + hdata = NULL; + } + } + + // *** From here onwards if there is an error call FreePokeData(), don't + // jump to errRtn + + aItem = DuplicateAtom (aItem); + + ASSERT(pedit->hData == NULL, "Poke data is not null"); + + pedit->hData = hdde; + if (!PostMessageToServer (pedit, WM_DDE_POKE, MAKELONG (hdde, aItem))) { + if (aItem) + GlobalDeleteAtom (aItem); + FreePokeData (lpobj, pedit); + return (lpobj->subErr = OLE_ERROR_COMM); + } + +#ifdef FIREWALLS + ASSERT (!pedit->bTerminating, "trying to post while termination") + ASSERT (pedit->awaitAck == NULL, "Trying to Post msg while waiting for ack") +#endif + if (lpobj->asyncCmd == OLE_NONE) + lpobj->asyncCmd = OLE_OTHER; + + lpobj->bAsync = TRUE; + pedit->awaitAck = AA_POKE; + // !!! after poke of the hostnames etc. we are not processing error., + + // Data is freed after the Poke is acknowledged. OLE_RELEASE will be sent + // to when ACK comes. + + return OLE_WAIT_FOR_RELEASE; + +errRtn: + if (hdata) + FreeGDIdata (hdata, cfFormat); + + if (hdde) + GlobalFree (hdde); + + pedit->hData = NULL; + + return (lpobj->subErr = retval); +} + + + +// FreePokeData: Frees the poked data. +void INTERNAL FreePokeData (lpobj, pedit) +LPOBJECT_LE lpobj; +PEDIT_DDE pedit; +{ + DDEPOKE FAR * lpdde; + +#ifdef FIREWALLS + ASSERT (pedit->hData, "Poke data handle is null"); + +#endif + + if (lpdde = (DDEPOKE FAR *) GlobalLock (pedit->hData)) { + GlobalUnlock (pedit->hData); + + // The old version of MSDraw expects the contents of METAFILEPICT + // structure to be part of DDEPOKE, rather than the handle to it. + + if (!lpobj->bOleServer && (lpobj->app == aMSDraw) + && (lpdde->cfFormat == CF_METAFILEPICT)) { + DeleteMetaFile (((LPMETAFILEPICT) ((LPSTR) &lpdde->Value))->hMF); + } + else { + FreeGDIdata (*(LPHANDLE)lpdde->Value, lpdde->cfFormat); + } + } + + GlobalFree (pedit->hData); + pedit->hData = NULL; +} + + + +BOOL INTERNAL SendSrvrMainCmd (lpobj, lptemplate) +LPOBJECT_LE lpobj; +LPSTR lptemplate; +{ + WORD size; + WORD len; + OLESTATUS retval; + int cmd; + HANDLE hInst = NULL; + LPSTR lpdata= NULL; + HANDLE hdata = NULL; + BOOL bLaunch = TRUE; + + Puts("Launch App and Send Sys command"); + +#ifdef FIREWALLS + ASSERT (lpobj->aServer, "Serevr is NULL"); +#endif + + if (!lpobj->aServer) { + retval = OLE_ERROR_REGISTRATION; + goto errRtn; + } + + if (!lpobj->bOldLink) { + bLaunch = !(lpobj->fCmd & ACT_NOLAUNCH); + cmd = lpobj->fCmd & LN_MASK; + } + + if (cmd == LN_LNKACT) { + // take care of network based document + char cDrive = lpobj->cDrive; + + if ((retval = CheckNetDrive (lpobj, POPUP_NETDLG)) != OLE_OK) { + lpobj->cDrive = cDrive; + goto errRtn; + } + + if (cDrive != lpobj->cDrive) + ContextCallBack (lpobj, OLE_RENAMED); + } + + if (!InitSrvrConv (lpobj, hInst)) { + + if (!bLaunch) + goto errRtn; + + if (!(hInst = LeLaunchApp (lpobj))) { + // We failed to launch the app. If it is a linked object, see + // whether the docname is valid for new servers. We wouldn't + // have given the doc name on the command line for the old + // servers. So, there is no point in checking for file existance + // in that case. + if (lpobj->bOleServer && (lpobj->bOldLink || (cmd == LN_LNKACT))){ + if ((retval = FileExists (lpobj)) != OLE_OK) + goto errRtn; + } + + retval = OLE_ERROR_LAUNCH; + goto errRtn; + } + + if (lpobj->bOldLink) + return TRUE; + + if (lpobj->bOleServer && (cmd == LN_LNKACT)) { + // We are not using any data blocks if the object is old link. + // we launched with docname, and don't have to establish system + // level and also we don't have to send exec strings. + + // for non-ole servers like excel, we do want to connect at + // the system level, so that we can send "StdOpen". We also + // have to send "StdExit" for the server to exit in the + // invisible launch case. + + return TRUE; + } + + retval = OLE_ERROR_COMM; + if(!InitSrvrConv (lpobj, hInst)) + goto errRtn; +#ifdef OLD + if (!lpobj->bOleServer && (cmd == LN_LNKACT)) + return TRUE; +#endif + } + + if (!lpobj->bOldLink) { + cmd = lpobj->fCmd & LN_MASK; + len = lstrlen (srvrSysCmd[cmd >> LN_SHIFT]); + + // for template and new, add the class name also + if (cmd == LN_NEW || cmd == LN_TEMPLATE) + len += GlobalGetAtomLen (lpobj->app); + + // Now add the document length. + len += GlobalGetAtomLen (lpobj->topic); + + // add the length of the template name + if (lptemplate) + len += lstrlen (lptemplate); + + // now add the fudge factor for the Quotes etc. + len += LN_FUDGE; + + // allocate the buffer and set the command. + hdata = GlobalAlloc (GMEM_DDESHARE, size = len); + + retval = OLE_ERROR_MEMORY; + SETERRHINT(lpobj, OLE_ERROR_MEMORY); + + if (hdata == NULL || (lpdata = (LPSTR)GlobalLock (hdata)) == NULL) + goto errRtn; + } + + lstrcpy (lpdata, (LPSTR)"["); // [ + lstrcat (lpdata, srvrSysCmd[cmd >> LN_SHIFT]); // [Std.... + lstrcat (lpdata, "(\""); // [std...(" + + if (cmd == LN_NEW || cmd == LN_TEMPLATE) { + len = lstrlen (lpdata); + GlobalGetAtomName (lpobj->app, (LPSTR)lpdata + len, size - len); + // [std...("class + lstrcat (lpdata, "\",\""); // [std...("class", " + } + len = lstrlen (lpdata); + // now get the topic name. + GlobalGetAtomName (lpobj->topic, lpdata + len, (WORD)size - len); + // [std...("class","doc + if (lptemplate) { + lstrcat (lpdata, "\",\""); // [std...("class","doc"," + lstrcat (lpdata, lptemplate); // [std...("class","doc","temp + } + + lstrcat (lpdata, "\")]"); // [std...("class","doc","temp")] + + GlobalUnlock (hdata); + + // !!!optimize with mapping. + SETERRHINT(lpobj, (OLE_ERROR_TEMPLATE + (cmd >> LN_SHIFT))); + + return SrvrExecute (lpobj, hdata); + +errRtn: + if (lpdata) + GlobalUnlock (hdata); + + if (hdata) + GlobalFree (hdata); + lpobj->subErr = retval; + return FALSE; +} + + + + +// ExtendAtom: Create a new atom, which is the old one plus extension + +ATOM INTERNAL ExtendAtom (lpobj, item) +LPOBJECT_LE lpobj; +ATOM item; +{ + char buffer[MAX_ATOM+1]; + LPSTR lpext; + + Puts("ExtendAtom"); + + buffer[0] = 0; + if (item) + GlobalGetAtomName (item, buffer, MAX_ATOM); + + switch (lpobj->optUpdate) { + + + case oleupdate_always: + lpext = (LPSTR)""; + break; + + case oleupdate_onsave: + lpext = (LPSTR)"/Save"; + break; + + case oleupdate_onclose: + lpext = (LPSTR)"/Close"; + break; + + default: + ASSERT (FALSE, "on call options not expected here"); + break; + + } + + lstrcat (buffer, lpext); + if (buffer[0]) + return GlobalAddAtom (buffer); + else + return NULL; +} + + +BOOL INTERNAL CreatePictObject (lhclientdoc, lpobjname, lpobj, optRender, cfFormat, lpclass) +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_LE lpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LPSTR lpclass; +{ + LPOLEOBJECT lpPictObj = NULL; + ATOM aClass; + + lpobj->lpobjPict = NULL; + if (optRender == olerender_format) { + switch (cfFormat) { + case NULL: + return FALSE; + + case CF_METAFILEPICT: + if (!(lpPictObj = (LPOLEOBJECT) MfCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE))) + return FALSE; + break; + + case CF_DIB: + if (!(lpPictObj = (LPOLEOBJECT) DibCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE))) + return FALSE; + break; + + case CF_BITMAP: + if (!(lpPictObj = (LPOLEOBJECT) BmCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE))) + return FALSE; + break; + + default: + aClass = GlobalAddAtom (lpclass); + if (!(lpPictObj = (LPOLEOBJECT) GenCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE, aClass))) + return FALSE; + + ((LPOBJECT_GEN)lpPictObj)->cfFormat = cfFormat; + break; + } + } + else if (optRender == olerender_draw) { + if (!(lpPictObj = (LPOLEOBJECT) MfCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE))) + return FALSE; +#ifdef LATER + if (AdviseOn (lpobj, (cfFormat = CF_METAFILEPICT), NULL)) + lpPictObj = (LPOLEOBJECT) MfCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE); + // !!! for the time being take assume we need to get metafile. + else if (AdviseOn (lpobj, (cfFormat = CF_DIB), NULL)) + lpPictObj = (LPOLEOBJECT) DibCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE); + else if (AdviseOn (lpobj, (cfFormat = CF_BITMAP), NULL)) + lpPictObj = (LPOLEOBJECT) BmCreateBlank (lhclientdoc, + lpobjname, CT_PICTURE); + else + goto errPict; +#endif + + } + else + return (optRender == olerender_none); + + if (lpobj->lpobjPict = lpPictObj) + lpobj->lpobjPict->lpParent = (LPOLEOBJECT) lpobj; + return TRUE; +} + + +OLESTATUS LnkChangeLnk (lpobj) +LPOBJECT_LE lpobj; +{ + + switch (lpobj->subRtn) { + + case 0: + TermDocConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 1: + + // delete the edit block + DeleteDocEdit (lpobj); + TermSrvrConv (lpobj); + WAIT_FOR_ASYNC_MSG (lpobj); + + case 2: + + // Do not set any errors, just delete the object. + // delete the server edit block + DeleteSrvrEdit (lpobj); + + // now try to activate the new link. + SKIP_TO (!InitDocConv (lpobj, !POPUP_NETDLG), step3); + lpobj->fCmd = LN_LNKACT | ACT_ADVISE | ACT_REQUEST; + InitAsyncCmd (lpobj, OLE_SETDATA, LNKOPENUPDATE); + return LnkOpenUpdate (lpobj); + + case 3: + step3: + return EndAsyncCmd (lpobj); + + default: + DEBUG_OUT ("Unexpected subroutine", 0); + return OLE_ERROR_GENERIC; + } +} + + +OLESTATUS INTERNAL ChangeDocAndItem (lpobj, hinfo) +LPOBJECT_LE lpobj; +HANDLE hinfo; +{ + LPSTR lpinfo; + ATOM aNewTopic, aNewItem = NULL, aOldTopic; + OLESTATUS retVal = OLE_ERROR_BLANK; + + PROBE_SVRCLOSING(lpobj); + + if (!(lpinfo = GlobalLock (hinfo))) + return OLE_ERROR_MEMORY; + + lpinfo += lstrlen (lpinfo) + 1; + aNewTopic = GlobalAddAtom (lpinfo); + lpinfo += lstrlen (lpinfo) + 1; + if (*lpinfo) + aNewItem = GlobalAddAtom (lpinfo); + + if (!aNewTopic && (lpobj->head.ctype == CT_LINK)) + goto errRtn; + + aOldTopic = lpobj->topic; + lpobj->topic = aNewTopic; + if ((retVal = SetNetName (lpobj)) != OLE_OK) { + if (lpobj->topic) + GlobalDeleteAtom (lpobj->topic); + lpobj->topic = aOldTopic; + goto errRtn; + } + + if (aOldTopic) + GlobalDeleteAtom (aOldTopic); + + if (lpobj->item) + GlobalDeleteAtom (lpobj->item); + + lpobj->item = aNewItem; + + // As the atoms have already changed, lpobj->hLink becomes irrelevant. + if (lpobj->hLink) { + GlobalFree (lpobj->hLink); + lpobj->hLink = NULL; + } + + GlobalUnlock(hinfo); + + // Now disconnect the old link and try to connect to the new one. + lpobj->fCmd = 0; + InitAsyncCmd (lpobj, OLE_SETDATA, LNKCHANGELNK); + return LnkChangeLnk (lpobj); + +errRtn: + + if (aNewItem) + GlobalDeleteAtom (aNewItem); + + GlobalUnlock (hinfo); + return retVal; +} + + +BOOL QueryUnlaunch (lpobj) +LPOBJECT_LE lpobj; +{ + if (!(lpobj->fCmd & ACT_UNLAUNCH)) + return FALSE; + + // only if we loaded the app + if (lpobj->pSysEdit && lpobj->pSysEdit->hClient && lpobj->pSysEdit->hInst) + return TRUE; + + return FALSE; +} + + +BOOL QueryClose (lpobj) +LPOBJECT_LE lpobj; +{ + if (!((lpobj->fCmd & ACT_UNLAUNCH) || + (lpobj->head.ctype == CT_EMBEDDED))) + return FALSE; + + // only if we loaded the documnet + if (lpobj->pSysEdit && lpobj->pSysEdit->hClient) + return TRUE; + + return FALSE; +} + + +OLESTATUS INTERNAL SetHostNamesHandle (lpobj, lpclientName, lpdocName) +LPOBJECT_LE lpobj; +LPSTR lpclientName; +LPSTR lpdocName; +{ + WORD cbClient; + WORD size; + HANDLE hhostNames = NULL; + LPHOSTNAMES lphostNames = NULL; + LPSTR lpdata; + + // 4 bytes is for the two offsets + size = (cbClient = lstrlen(lpclientName)+1) + (lstrlen(lpdocName)+1) + 4; + + if ((hhostNames = GlobalAlloc (GMEM_MOVEABLE, (DWORD) size)) + == NULL) + goto errRtn; + + if ((lphostNames = (LPHOSTNAMES)GlobalLock (hhostNames)) == NULL) + goto errRtn; + + lphostNames->clientNameOffset = 0; + lphostNames->documentNameOffset = cbClient; + + lpdata = (LPSTR)lphostNames->data; + lstrcpy (lpdata, lpclientName); + lstrcpy (lpdata + cbClient, lpdocName); + if (lpobj->hhostNames) + GlobalFree ( lpobj->hhostNames); + GlobalUnlock (hhostNames); + lpobj->hhostNames = hhostNames; + return OLE_OK; + +errRtn: + if (lphostNames) + GlobalUnlock (hhostNames); + + if (hhostNames) + GlobalFree (hhostNames); + + return OLE_ERROR_MEMORY; +} + + +#if 0 +OLESTATUS FARINTERNAL LeAbort (lpobj) +LPOBJECT_LE lpobj; +{ + + + BOOL bAbort = FALSE; + PEDIT_DDE pedit; + + + // check whether the any transaction pending for + // the document level. + + // channel open + // any transaction pending. + // and we are not in terminate mode. + + + if ((pedit = lpobj->pDocEdit) && pedit->hServer && + pedit->awaitAck && !pedit->bTerminating) { + pedit->bAbort = bAbort = TRUE; + // delete any data we need to delete. Ricght now + // we kill only the timer. We can not delete any + // since the server could potentially look at the data. + + DeleteAbortData (lpobj, pedit); + } + + if ((pedit = lpobj->pSysEdit) && pedit->hServer && + pedit->awaitAck && !pedit->bTerminating) { + pedit->bAbort = bAbort = TRUE; + DeleteAbortData (lpobj, pedit); + + } + + if (!bAbort) + return OLE_OK; + + // Now send the EndAsync + lpobj->mainErr = OLE_ERROR_ABORT; + EndAsyncCmd (lpobj); + return OLE_OK; + +} +#endif + + +OLESTATUS FARINTERNAL ProbeAsync(lpobj) +LPOBJECT_LE lpobj; +{ + + if (lpobj->asyncCmd == OLE_NONE) + return OLE_OK; + + if (!IsServerValid (lpobj)) { + + // Now send the EndAsync + lpobj->mainErr = OLE_ERROR_TASK; + EndAsyncCmd (lpobj); + return OLE_OK; + } + + return OLE_BUSY; +} + + +BOOL INTERNAL IsWindowValid (hwnd) +HWND hwnd; +{ + +#define TASK_OFFSET 0x00FA + + LPSTR lptask; + HANDLE htask; + + if (!IsWindow (hwnd)) + return FALSE; + + if (bWLO) + return TRUE; + + // now get the task handle and find out it is valid. + htask = GetWindowTask (hwnd); + + if ((wWinVer == 0x0003) || !lpfnIsTask) { + lptask = (LPSTR)(MAKELONG (TASK_OFFSET, htask)); + + if (!FarCheckPointer(lptask, READ_ACCESS)) + return FALSE; + + // now check for the signature bytes of task block in kernel + if (*lptask++ == 'T' && *lptask == 'D') + return TRUE; + } + else { + // From win31 onwards the API IsTask can be used for task validation + if ((*lpfnIsTask)(htask)) + return TRUE; + } + + return FALSE; +} + + + +BOOL INTERNAL IsServerValid (lpobj) +LPOBJECT_LE lpobj; +{ + + MSG msg; + BOOL retval = FALSE; + + + if (lpobj->pDocEdit && lpobj->pDocEdit->hServer) { + + retval = TRUE; + + if (!IsWindowValid (lpobj->pDocEdit->hServer)) { + if (!PeekMessage ((LPMSG)&msg, lpobj->pDocEdit->hClient, WM_DDE_TERMINATE, WM_DDE_TERMINATE, + PM_NOREMOVE | PM_NOYIELD)){ +#ifdef FIREWALLS + ASSERT (FALSE, "Server truely died"); +#endif + return FALSE; + } + + } + + } + + if (lpobj->pSysEdit && lpobj->pSysEdit->hServer) { + retval = TRUE; + + if (!IsWindowValid (lpobj->pSysEdit->hServer)) { + + if (!PeekMessage ((LPMSG)&msg, lpobj->pSysEdit->hClient, WM_DDE_TERMINATE, WM_DDE_TERMINATE, + PM_NOREMOVE | PM_NOYIELD)){ +#ifdef FIREWALLS + ASSERT (FALSE, "Server truely died"); +#endif + return FALSE; + + } + + + } + } + + return retval; +} + + +OLESTATUS FARINTERNAL LeExecute (lpobj, hCmds, wReserve) +LPOBJECT_LE lpobj; +HANDLE hCmds; +WORD wReserve; +{ + // Assumes all the creates are in order + PROBE_CREATE_ASYNC(lpobj); + PROBE_SVRCLOSING(lpobj); + + if (!(lpobj = (*lpobj->head.lpvtbl->QueryProtocol) (lpobj, + PROTOCOL_EXECUTE))) + return OLE_ERROR_PROTOCOL; + + if (!QueryOpen (lpobj)) + return OLE_ERROR_NOT_OPEN; + + if (!(hCmds = DuplicateGlobal (hCmds, GMEM_MOVEABLE|GMEM_DDESHARE))) + return OLE_ERROR_MEMORY; + + InitAsyncCmd (lpobj, OLE_OTHER, NULL); + SETERRHINT(lpobj, OLE_ERROR_COMMAND); + if (DocExecute(lpobj, hCmds)) + return OLE_WAIT_FOR_RELEASE; + else + return OLE_ERROR_COMMAND; +} + + +void INTERNAL FreeGDIdata (hData, cfFormat) +HANDLE hData; +OLECLIPFORMAT cfFormat; +{ + if (cfFormat == CF_METAFILEPICT) { + LPMETAFILEPICT lpMfp; + + if (lpMfp = (LPMETAFILEPICT) GlobalLock (hData)) { + GlobalUnlock (hData); + DeleteMetaFile (lpMfp->hMF); + } + + GlobalFree (hData); + } + + else if (cfFormat == CF_BITMAP) + DeleteObject (hData); + + else if (cfFormat == CF_DIB) + GlobalFree (hData); +} + + +// This routine figures out whether the handle to data block can be copied +// to DDEPOKE block rather than the contents of the handle + +BOOL INTERNAL CanPutHandleInPokeBlock (lpobj, cfFormat) +LPOBJECT_LE lpobj; +OLECLIPFORMAT cfFormat; +{ + if (cfFormat == CF_BITMAP || cfFormat == CF_DIB) + return TRUE; + + if (cfFormat == CF_METAFILEPICT) { + // The old version of MSDraw expects the contents of METAFILEPICT + // structure to be part of DDEPOKE, rather than the handle to it. + + if (!lpobj->bOleServer && lpobj->app == aMSDraw) + return FALSE; + + return TRUE; + } + + return FALSE; +} diff --git a/private/mvdm/wow16/ole/client/main.c b/private/mvdm/wow16/ole/client/main.c new file mode 100644 index 000000000..d64c5743f --- /dev/null +++ b/private/mvdm/wow16/ole/client/main.c @@ -0,0 +1,781 @@ + +/****************************** Module Header ******************************\ +* Module Name: MAIN.C +* +* PURPOSE: WinMain, WEP and some other misc routines +* +* Created: 1991 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Srinik (04/01/91) Pulled some routines, into this, from ole.c. +* +\***************************************************************************/ + +#include <windows.h> +#include <shellapi.h> + +#include "dll.h" + +#ifndef WF_WLO +#define WF_WLO 0x8000 +#endif + +// ordinal number new win31 API IsTask +#define ORD_IsTask 320 + +#define NUM_DLL 30 /* space for this many DLL_ENTRYs is created on */ + /* each alloc/realloc */ + +OLECLIPFORMAT cfOwnerLink = 0; // global variables for clip frmats +OLECLIPFORMAT cfObjectLink = 0; +OLECLIPFORMAT cfLink = 0; +OLECLIPFORMAT cfNative = 0; +OLECLIPFORMAT cfBinary = 0; +OLECLIPFORMAT cfFileName = 0; +OLECLIPFORMAT cfNetworkName = 0; + +ATOM aStdHostNames; +ATOM aStdTargetDevice ; +ATOM aStdDocDimensions; +ATOM aStdDocName; +ATOM aStdColorScheme; +ATOM aNullArg = 0; +ATOM aSave; +ATOM aChange; +ATOM aClose; +ATOM aSystem; +ATOM aOle; +ATOM aClipDoc; +ATOM aPackage; + +// Used in work around for MSDraw bug +ATOM aMSDraw; + +extern LPCLIENTDOC lpHeadDoc; +extern LPCLIENTDOC lpTailDoc; + +extern RENDER_ENTRY stdRender[]; + +HANDLE hInstDLL; +BOOL bProtMode; +BOOL bWLO = FALSE; + +/* HANDLE hDllTable; !!! Add this when bug in WEP is fixed */ +DLL_ENTRY lpDllTable[NUM_DLL]; //!!! change this when WEP bug is fixed +DWORD dllTableSize; +int iLast = 0; +int iMax = NUM_DLL -1; +int iUnloadableDll = NULL; // index to handler than can be freed up + +char packageClass[] = "Package"; + +// For QuerySize() API & methods. +extern OLESTREAMVTBL dllStreamVtbl; +extern CLIENTDOC lockDoc; + +#ifdef FIREWALLS +BOOL bShowed = FALSE; +char szDebugBuffer[80]; +short ole_flags; + +void FARINTERNAL ShowVersion (void); +void FARINTERNAL SetOleFlags(void); +#endif + +// LOWWORD - BYTE 0 major verision, BYTE1 minor version, +// HIWORD reserved + +DWORD dwOleVer = 0x2001L; // change this when we want to update dll version + // number + + +DWORD dwVerToFile = 0x0501L; // This is used while object is being saved to + // file. There is no need to change this value + // whenever we change ole dll version number + + + +static BOOL bLibInit = FALSE; + + +WORD wWinVer; + +HANDLE hModule; + +#define MAX_HIMETRIC 0x7FFF + +int maxPixelsX = MAX_HIMETRIC; +int maxPixelsY = MAX_HIMETRIC; +void SetMaxPixel (void); + +VOID FAR PASCAL WEP (int); + +#pragma alloc_text(WEP_TEXT, WEP) + + +FARPROC lpfnIsTask = NULL; // the API IsTask() became available from + // win31 onwards, hence we are trying to + // get it's address through GetProcAddress + + + +////////////////////////////////////////////////////////////////////////////// +// +// int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine) +// +// The main library entry point. This routine is called when the library +// is loaded. +// +// Arguments: +// +// hInst - dll's instance handle +// wDataSeg - DS register value +// cbHeapSize - heap size defined def file +// lpszCmdLine - command line info +// +// Returns: +// +// 0 - failure +// 1 - success +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + + +int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine) +HANDLE hInst; +WORD wDataSeg; +WORD cbHeapSize; +LPSTR lpszCmdLine; +{ + WNDCLASS wc; + int i; + + Puts("LibMain"); + +#ifdef FIREWALLS + SetOleFlags(); +#endif + + bLibInit = TRUE; + hInstDLL = hInst; + hModule = GetModuleHandle ("OLECLI"); + + bProtMode = (BOOL) (GetWinFlags() & WF_PMODE); + bWLO = (BOOL) (GetWinFlags() & WF_WLO); + wWinVer = (WORD) GetVersion(); + + // REGISTER LINK FORMAT + + cfObjectLink = RegisterClipboardFormat("ObjectLink"); + cfLink = RegisterClipboardFormat("Link"); + cfOwnerLink = RegisterClipboardFormat("OwnerLink"); + cfNative = RegisterClipboardFormat("Native"); + cfBinary = RegisterClipboardFormat("Binary"); + cfFileName = RegisterClipboardFormat("FileName"); + cfNetworkName = RegisterClipboardFormat("NetworkName"); + + if (!(cfObjectLink && cfOwnerLink && cfNative && cfLink)) + return 0; + + // SET UP OLEWNDCLASS + wc.style = NULL; + wc.lpfnWndProc = DocWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(LONG); //we are storing longs + wc.hInstance = hInst; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground= NULL; + wc.lpszMenuName = NULL; + wc.lpszClassName= "OleDocWndClass"; + if (!RegisterClass(&wc)) + return 0; + + wc.lpfnWndProc = SrvrWndProc; + wc.lpszClassName = "OleSrvrWndClass"; + + if (!RegisterClass(&wc)) + return 0; +/* + // !!! Add this when bug in WEP is fixed. + // Allocate memory for DLL table + dllTableSize = NUM_DLL * sizeof(DLL_ENTRY); + if (!(hDllTable = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, + dllTableSize))) + return 0; + + if (!(lpDllTable = (DLL_ENTRY FAR *) GlobalLock (hDllTable))) + return 0; +*/ + + // !!! remove the following when WEP bug is fixed + for (i = 0; i < NUM_DLL; i++) + lpDllTable[i].aDll = 0; + + // !!! BEGIN hack for Pbrush. + + lpDllTable[0].hDll = NULL; + lpDllTable[0].aDll = GlobalAddAtom ((LPSTR) "ole"); + lpDllTable[0].Load = PbLoadFromStream; + lpDllTable[0].Clip = PbCreateFromClip; + lpDllTable[0].Link = PbCreateLinkFromClip; + lpDllTable[0].Create = PbCreate; + lpDllTable[0].CreateFromTemplate = PbCreateFromTemplate; + lpDllTable[0].CreateFromFile = PbCreateFromFile; + lpDllTable[0].CreateLinkFromFile = PbCreateLinkFromFile; + lpDllTable[0].CreateInvisible = PbCreateInvisible; + + + // !!! END hack for pbrush + + // For ObjectSize API + dllStream.lpstbl = (LPOLESTREAMVTBL) &dllStreamVtbl; + dllStream.lpstbl->Put = DllPut; + + // add the atoms required. + aStdDocName = GlobalAddAtom ((LPSTR)"StdDocumentName"); + aSave = GlobalAddAtom ((LPSTR)"Save"); + aChange = GlobalAddAtom ((LPSTR)"Change"); + aClose = GlobalAddAtom ((LPSTR)"Close"); + aSystem = GlobalAddAtom ((LPSTR)"System"); + aOle = GlobalAddAtom ((LPSTR)"OLEsystem"); + aPackage = GlobalAddAtom ((LPSTR) packageClass); + + // Used in work around for MSDraw bug + aMSDraw = GlobalAddAtom ((LPSTR) "MSDraw"); + + // clipboard document name atom + aClipDoc = GlobalAddAtom ((LPSTR)"Clipboard"); + + stdRender[0].aClass = GlobalAddAtom ("METAFILEPICT"); + stdRender[1].aClass = GlobalAddAtom ("DIB"); + stdRender[2].aClass = GlobalAddAtom ("BITMAP"); + + SetMaxPixel(); + + if (wWinVer != 0x0003) { + HANDLE hModule; + + if (hModule = GetModuleHandle ("KERNEL")) + lpfnIsTask = GetProcAddress (hModule, + (LPSTR) MAKELONG (ORD_IsTask, 0)); + } + + if (cbHeapSize != 0) + UnlockData(0); + + return 1; +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// VOID FAR PASCAL WEP (nParameter) +// +// Called just before the library is being unloaded. Delete all the atoms +// added by this dll and also frees up all unloaded handler dlls. +// +// Arguments: +// +// nParameter - Termination code +// +// Returns: +// +// none +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + + +VOID FAR PASCAL WEP (nParameter) +int nParameter; +{ + int i; + + + Puts("LibExit"); + + // case when the DLLs are missing + if (!bLibInit) + return; + + if (nParameter == WEP_SYSTEM_EXIT) + DEBUG_OUT ("---L&E DLL EXIT on system exit---",0) + else if (nParameter == WEP_FREE_DLL) + DEBUG_OUT ("---L&E DLL EXIT---\n",0) + else + return; + + // Delete atoms added by us + + for (i = 0; i < NUM_RENDER; i++) { + if (stdRender[i].aClass) + GlobalDeleteAtom (stdRender[i].aClass); + } + + if (aStdDocName) + GlobalDeleteAtom (aStdDocName); + if (aSave) + GlobalDeleteAtom (aSave); + if (aChange) + GlobalDeleteAtom (aChange); + if (aClose) + GlobalDeleteAtom (aClose); + if (aSystem) + GlobalDeleteAtom (aSystem); + if (aOle) + GlobalDeleteAtom (aOle); + if (aPackage) + GlobalDeleteAtom (aPackage); + if (aClipDoc) + GlobalDeleteAtom (aClipDoc); + if (aMSDraw) + GlobalDeleteAtom (aMSDraw); + + // Free handler dlls if there are any still loaded. Entry 0 is used for + // Pbrush handler which is part of this dll. + + + for (i = 0; i <= iLast; i++) { + if (lpDllTable[i].aDll) + GlobalDeleteAtom (lpDllTable[i].aDll); + + if (lpDllTable[i].hDll) + FreeLibrary (lpDllTable[i].hDll); + } + + +#ifdef FIREWALLS + ASSERT(!lpHeadDoc, "Some client doc structures are not deleted"); + ASSERT(!lockDoc.lpHeadObj, "Some servers are left in a locked state"); +#endif + +/* !!! Add this when bug in WEP is fixed + + if (lpDllTable) + GlobalUnlock (hDllTable); + + if (hDllTable) + GlobalFree (hDllTable); +*/ +} + + +////////////////////////////////////////////////////////////////////////////// +// +// void FARINTERNAL SetOleFlags() +// +// Sets the debug level flags for controlling the level of debug information +// on the comm terminal. This will be included only in the debug version. +// +// Arguments: +// +// none +// +// Returns: +// +// none +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + +#ifdef FIREWALLS + +void FARINTERNAL SetOleFlags() +{ + + char buffer[80]; + + if(GetProfileString ("OLE", + "Puts","", (LPSTR)buffer, 80)) + ole_flags = DEBUG_PUTS; + else + ole_flags = 0; + + + if(GetProfileString ("OLE", + "DEBUG_OUT","", (LPSTR)buffer, 80)) + ole_flags |= DEBUG_DEBUG_OUT; + + + if(GetProfileString ("OLE", + "MESSAGEBOX","", (LPSTR)buffer, 80)) + ole_flags |= DEBUG_MESSAGEBOX; + +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// void FARINTERNAL ShowVersion (void) +// +// Displays version, date, time and copyright info in client app's window. +// Called by all the object create functions after checking the flag bShowed. +// This will be included only in the debug version. +// +// Arguments: +// +// none +// +// Returns: +// +// none +// +// Effects: +// +// sets bShowed +// +////////////////////////////////////////////////////////////////////////////// + +void FARINTERNAL ShowVersion () +{ + + if (!bShowed && (ole_flags & DEBUG_MESSAGEBOX)) { + MessageBox (NULL, "\ + VER: 1.09.000\n\ + TIME: 16:00:00\n\ + DATE: 01/31/1992\n\ + Copyright (c) 1990, 1991 Microsoft Corp.\n\ + All Rights Reserved.", + "Ole Client Library", + MB_OK | MB_TASKMODAL); + bShowed = TRUE; + } +} + +#endif + + + + +int FARINTERNAL LoadDll (lpClass) +LPSTR lpClass; +{ + char str[MAX_STR]; + char str1[MAX_STR]; + ATOM aDll = NULL; + int index; + int iEmpty; + BOOL found = FALSE; + HANDLE hDll; + int refcnt; + LONG cb = MAX_STR; + + if (!lstrcmpi (lpClass, "Pbrush")) + return 0; + + lstrcpy (str, lpClass); + lstrcat (str, "\\protocol\\StdFileEditing\\handler"); + if (RegQueryValue (HKEY_CLASSES_ROOT, str, str1, &cb)) + return INVALID_INDEX; + + if (aDll = GlobalFindAtom (str1)) { + for (index = 1; index <= iLast; index++) { + if (lpDllTable[index].aDll == aDll) { // Dll already loaded + lpDllTable[index].cObj ++; + + if (index == iUnloadableDll) { + // since the object count is not zero anymore, this + // handler can not be freed up. + iUnloadableDll = NULL; + } + + return index; + } + } + } + + aDll = GlobalAddAtom (str1); + + // Look for an empty entry + for (iEmpty = 1; iEmpty <= iLast; iEmpty++) { + if (!lpDllTable[iEmpty].aDll) { + found = TRUE; + break; + } + } + + if (iEmpty > iMax) + goto errLoad; +/* + if (!found) {// no empty entry exists create a new one if necessary. + if (iEmpty > iMax) { + dllTableSize += (blockSize = NUM_DLL * sizeof(DLL_ENTRY)); + hTable = GlobalReAlloc (hDllTable, dllTableSize, + GMEM_MOVEABLE | GMEM_ZEROINIT); + if (hTable == hDllTable) + iMax += NUM_DLL; + else { + dllTableSize -= blockSize; + iEmpty = INVALID_INDEX; + } + } + } +*/ + + // !!! reference count of OLECLI is increasing by 2 when the handlers are + // are loaded, looks like windows bug. Following is a temporary fix. + + refcnt = GetModuleUsage (hModule); + hDll = LoadLibrary ((LPSTR) str1); + refcnt = (GetModuleUsage (hModule) - refcnt); + + while (refcnt > 1) { + FreeModule (hModule); + refcnt--; + } + + if (hDll < 32) + goto errLoad; + + if (!(lpDllTable[iEmpty].Load = GetProcAddress (hDll, + "DllLoadFromStream"))) + goto errLoad; + + if (!(lpDllTable[iEmpty].Clip = GetProcAddress (hDll, + "DllCreateFromClip"))) + goto errLoad; + + if (!(lpDllTable[iEmpty].Link = GetProcAddress (hDll, + "DllCreateLinkFromClip"))) + goto errLoad; + + if (!(lpDllTable[iEmpty].CreateFromTemplate = GetProcAddress (hDll, + "DllCreateFromTemplate"))) + goto errLoad; + + if (!(lpDllTable[iEmpty].Create = GetProcAddress (hDll, "DllCreate"))) + goto errLoad; + + if (!(lpDllTable[iEmpty].CreateFromFile = GetProcAddress (hDll, + "DllCreateFromFile"))) + goto errLoad; + + if (!(lpDllTable[iEmpty].CreateLinkFromFile = GetProcAddress (hDll, + "DllCreateLinkFromFile"))) + goto errLoad; + + lpDllTable[iEmpty].CreateInvisible = GetProcAddress (hDll, + "DllCreateInvisible"); + + lpDllTable[iEmpty].aDll = aDll; + lpDllTable[iEmpty].cObj = 1; + lpDllTable[iEmpty].hDll = hDll; + if (iEmpty > iLast) + iLast++; + return iEmpty; + +errLoad: + if (aDll) + GlobalDeleteAtom (aDll); + if (hDll >= 32) + FreeLibrary (hDll); + return INVALID_INDEX; +} + + +// unload the the handler that can be free up (whose object count is NULL) + +void FARINTERNAL UnloadDll () +{ + if (!iUnloadableDll) + return; + + if (iUnloadableDll == iLast) + iLast--; + + if (lpDllTable[iUnloadableDll].aDll) + GlobalDeleteAtom (lpDllTable[iUnloadableDll].aDll); + lpDllTable[iUnloadableDll].aDll = NULL; + FreeLibrary (lpDllTable[iUnloadableDll].hDll); + lpDllTable[iUnloadableDll].hDll = NULL; + + iUnloadableDll = NULL; +} + + +// +// Reduce the object count of the handler, refered to by the index, by one. +// If the object count becomes NULL, free up the handler that is ready to be +// freed (refered to by index iUnloadableDll), and then make this handler the +// freeable one. +// +// As you can see we are trying to implement a simple mechanism of caching. +// + +void FARINTERNAL DecreaseHandlerObjCount (iTable) +int iTable; +{ + if (!iTable) + return; + + if (iTable != INVALID_INDEX) { + ASSERT (lpDllTable[iTable].cObj, "Handler Obj count is already NULL"); + if (!--lpDllTable[iTable].cObj) { + UnloadDll (); + iUnloadableDll = iTable; + } + } +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FARINTERNAL CreatePictFromClip (lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, lpClass, ctype) +* +* CreatePictFromClip: This function creates the LP to an object +* from the clipboard. It will try to create a static picture object if +* it understands any rendering formats on the clipboard. Currently, it +* understands only bitmaps and metafiles. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FARINTERNAL CreatePictFromClip (lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, lpClass, objType) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LPSTR lpClass; +LONG objType; +{ + OLESTATUS retVal = OLE_ERROR_OPTION; + + *lplpobj = NULL; + + if (optRender == olerender_none) + return OLE_OK; + else if (optRender == olerender_format) { + switch (cfFormat) { + case NULL: + return OLE_ERROR_FORMAT; + + case CF_METAFILEPICT: + return MfPaste (lpclient, lhclientdoc, lpobjname, + lplpobj, objType); + + case CF_DIB: + return DibPaste (lpclient, lhclientdoc, lpobjname, + lplpobj, objType); + + case CF_BITMAP: + return BmPaste (lpclient, lhclientdoc, lpobjname, + lplpobj, objType); + + default: + return GenPaste (lpclient, lhclientdoc, lpobjname, lplpobj, + lpClass, cfFormat, objType); + } + } + else if (optRender == olerender_draw) { + cfFormat = EnumClipboardFormats (NULL); + while ((cfFormat) && (retVal > OLE_WAIT_FOR_RELEASE)) { + switch (cfFormat) { + case CF_METAFILEPICT: + retVal = MfPaste (lpclient, lhclientdoc, + lpobjname, lplpobj, objType); + break; + + case CF_DIB: + retVal = DibPaste (lpclient, lhclientdoc, + lpobjname, lplpobj, objType); + break; + + case CF_BITMAP: + retVal = BmPaste (lpclient, lhclientdoc, + lpobjname, lplpobj, objType); + break; + } + + cfFormat = EnumClipboardFormats (cfFormat); + } + } + + return retVal; +} + + + +OLESTATUS FARINTERNAL CreatePackageFromClip (lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, objType) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LONG objType; +{ + char file[MAX_STR+6]; + HANDLE hData; + LPSTR lpFileName; + + if (!(hData = GetClipboardData (cfFileName)) + || !(lpFileName = GlobalLock (hData))) + return OLE_ERROR_CLIPBOARD; + + + if (objType == OT_LINK) { + lstrcpy (file, lpFileName); + lstrcat (file, "/Link"); + lpFileName = (LPSTR) file; + } + + GlobalUnlock (hData); + + return CreateEmbLnkFromFile (lpclient, packageClass, lpFileName, + NULL, lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat, OT_EMBEDDED); +} + + + +void FARINTERNAL RemoveLinkStringFromTopic (lpobj) +LPOBJECT_LE lpobj; +{ + char buf[MAX_STR+6]; + int i = 0; + + if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf))) { + // scan the topic for "/Link" + while (buf[i] != '/') { + if (!buf[i]) + return; + i++; + } + + buf[i] = '\0'; + if (lpobj->topic) + GlobalDeleteAtom (lpobj->topic); + lpobj->topic = GlobalAddAtom (buf); + } +} + +void SetMaxPixel () +{ + HDC hdc; + // find out the pixel equivalent of MAX_HIMETRIC in X and Y directions + + if (hdc = GetDC (NULL)) { + maxPixelsX = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSX), + 2540); + maxPixelsY = MulDiv (MAX_HIMETRIC, GetDeviceCaps(hdc, LOGPIXELSY), + 2540); + ReleaseDC (NULL, hdc); + } +} + + diff --git a/private/mvdm/wow16/ole/client/makefile b/private/mvdm/wow16/ole/client/makefile new file mode 100644 index 000000000..cdb658f3e --- /dev/null +++ b/private/mvdm/wow16/ole/client/makefile @@ -0,0 +1,169 @@ +# +# Make file for ole library routines +# +# International mods +# NOTE: INTL_SRC, INTL_EXE and LANG are macros set by international +!IFNDEF LANG +RES_DIR=.\messages\usa +!ELSE +RES_DIR=$(INTL_SRC)\$(LANG)\sdk\ole\client +EXE_DIR=$(INTL_EXE) +!ENDIF + + +# Flags set assuming small model + +LIBS= sdllcew libw shell +LIBENTRY_OBJ=libentry.obj + +########## Path definition so we find 16 bit tools ########## +# Also works around stupid bug in RC 3.1 that doesn't allow rcpp.err to be +# in a directory that is greater than 128 chars down the path, even if +# rc 3.1 is running as an OS/2 app. + +PATH = $(_NTBINDIR)\private\mvdm\tools16;$(PATH) + +!if "$(NTDEBUG)"!="" && "$(NTDEBUG)"!="retail" && "$(NTDEBUG)" != "ntsdnodbg" +DEBUG=1 +CDEBUG = /Od /Oi /Zd +ADEBUG = -Zd +LDEBUG = /LI +!endif + +!ifdef DEBUG +BLD=debug +CFLAGS= -c -ASw -G2sw -Od -Zipe -W3 -DFIREWALLS $(CDEBUG) +LFLAGS=/NOD /NOE /M $(LDEBUG) +AFLAGS= -D?PLM=0 -D?WIN=1 -ZI -W2 $(ADEBUG) +!else +BLD=retail +CFLAGS=-c -ASw -G2sw -Zpe -W3 -Ox +LFLAGS=/NOD /NOE /M +AFLAGS=-D?PLM=0 -D?WIN=1 -W2 +!endif + + +LE_OBJ= $(BLD)\main.obj $(BLD)\ole.obj $(BLD)\defcreat.obj $(BLD)\le.obj $(BLD)\dde.obj $(BLD)\ledde.obj $(BLD)\utils.obj $(BLD)\pbhandlr.obj $(BLD)\doc.obj $(BLD)\oleasm.obj $(BLD)\net.obj + +PICT_OBJ= $(BLD)\mf.obj $(BLD)\generic.obj $(BLD)\bm.obj $(BLD)\dib.obj $(BLD)\error.obj $(BLD)\draw.obj + + +#International mods +!IFNDEF LANG +ALL: $(BLD)\olecli.dll $(BLD)\olecli.lib +!ELSE +all: retail\olecli.$(LANG) +!ENDIF + + +!IFNDEF LANG +ole.rc: $(RES_DIR)\$@ + copy $(RES_DIR)\$@ + +olecli.rcv: $(RES_DIR)\$@ + copy $(RES_DIR)\$@ + +ole.res: ole.rc olecli.rcv + rc16 -r ole.rc $@ +!ELSE +ole.res: $(RES_DIR)\$@ + copy $(RES_DIR)\$@ +!ENDIF + + +$(BLD)\olecli.lib: olecli.def + mkpublic olecli.def stripped.def + implib $@ stripped.def + del stripped.def + +$(BLD)\oleasm.obj: ole.asm + masm $(AFLAGS) ole.asm, $@; + +$(BLD)\main.obj: main.c + cl16 $(CFLAGS) -NT _MAIN -Fo$@ $** + +$(BLD)\doc.obj: doc.c + cl16 $(CFLAGS) -NT _MAIN -Fo$@ $** + +$(BLD)\error.obj: error.c + cl16 $(CFLAGS) -NT _MISC -Fo$@ $** + +$(BLD)\dde.obj: dde.c + cl16 $(CFLAGS) -NT _DDETEXT -Fo$@ $** + +$(BLD)\ledde.obj: ledde.c + cl16 $(CFLAGS) -NT _DDETEXT -Fo$@ $** + +$(BLD)\defcreat.obj: defcreat.c + cl16 $(CFLAGS) -NT _DEFTEXT -Fo$@ $** + +$(BLD)\draw.obj: draw.c + cl16 $(CFLAGS) -NT _DRAW -Fo$@ $** + +$(BLD)\mf.obj: mf.c + cl16 $(CFLAGS) -NT _MF -Fo$@ $** + +$(BLD)\bm.obj: bm.c + cl16 $(CFLAGS) -NT _BM -Fo$@ $** + +$(BLD)\dib.obj: dib.c + cl16 $(CFLAGS) -NT _DIB -Fo$@ $** + +$(BLD)\generic.obj: generic.c + cl16 $(CFLAGS) -NT _GEN -Fo$@ $** + +$(BLD)\net.obj: net.c + cl16 $(CFLAGS) -NT _NET -Fo$@ $** + +$(BLD)\pbhandlr.obj: pbhandlr.c + cl16 $(CFLAGS) -NT _PBRUSH -Fo$@ $** + +{}.c{$(BLD)}.obj: + cl16 $(CFLAGS) -Fo$@ $< + + +$(BLD)\olecli.dll: $(LE_OBJ) $(PICT_OBJ) ole.res olecli.def + link $(LFLAGS) @<< +$(LE_OBJ) + +$(PICT_OBJ) + +$(LIBENTRY_OBJ) +$(BLD)\olecli.dll +$(BLD)\olecli.map +$(LIBS) +olecli.def; +<< + -@ cd $(BLD) + rc16 -30 ..\ole.res olecli.dll + mapsym olecli + convdll olecli.dll + -@ cd.. + +ole.c: dll.h +defcreat.c: dll.h +utils.c: dll.h +dde.c: dll.h +le.c: dll.h +ledde.c: dll.h +pbhandlr.c: dll.h +doc.c: dll.h +net.c: dll.h +bm.c: dll.h pict.h +mf.c: dll.h pict.h +dib.c: dll.h pict.h +generic.c: dll.h pict.h +error.c: dll.h pict.h +draw.c: dll.h pict.h + +dll.h: ole.h + + +iclean: + del *.rc + del *.rcv + del *.res + +retail\olecli.$(LANG): iclean ole.res + copy $(EXE_DIR)\olecli.dll retail\olecli.$(LANG) + -@ cd retail + rc16 -t -30 ..\ole.res olecli.$(LANG) + -@ cd.. diff --git a/private/mvdm/wow16/ole/client/mf.c b/private/mvdm/wow16/ole/client/mf.c new file mode 100644 index 000000000..9aaf4fc9b --- /dev/null +++ b/private/mvdm/wow16/ole/client/mf.c @@ -0,0 +1,645 @@ +/****************************** Module Header ******************************\ +* Module Name:MF.C (Extensible Compound Documents - Metafile) +* +* PURPOSE:Handles all API routines for the metafile sub-dll of the ole dll. +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* +* Raor, Srinik (../../1990,91) Designed, coded +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" +#include "pict.h" + +WORD wGDIds = NULL; + +OLESTATUS FARINTERNAL wCreateDummyMetaFile (LPOBJECT_MF, int, int); + +#pragma alloc_text(_TEXT, MfSaveToStream, MfLoadFromStream, GetBytes, PutBytes, PutStrWithLen, MfQueryBounds, OleIsDcMeta, GetGDIds, IsMetaDC) + +OLEOBJECTVTBL vtblMF = { + + ErrQueryProtocol, // check whether the speced protocol is supported + + MfRelease, // Release + ErrShow, // show + ErrPlay, // play + MfGetData, // Get the object data + ErrSetData, // Set the object data + ErrSetTargetDevice,// + ErrSetBounds, // set viewport bounds + MfEnumFormat, // enumerate supported formats + ErrSetColorScheme, // + MfRelease, // delete + ErrSetHostNames, // + + MfSaveToStream, // write to file + MfClone, // clone object + ErrCopyFromLink, // Create embedded from Lnk + + MfEqual, // compares the given objects for data equality + + MfCopy, // copy to clip + + MfDraw, // draw the object + + ErrActivate, // open + ErrExecute, // excute + ErrClose, // stop + ErrUpdate, // Update + ErrReconnect, // Reconnect + + ErrObjectConvert, // convert object to specified type + + ErrGetUpdateOptions, // update options + ErrSetUpdateOptions, // update options + + ObjRename, // Change Object name + ObjQueryName, // Get current object name + ObjQueryType, // Object type + MfQueryBounds, // QueryBounds + ObjQuerySize, // Find the size of the object + ErrQueryOpen, // Query open + ErrQueryOutOfDate, // query whether object is current + + ErrQueryRelease, // release related stuff + ErrQueryRelease, + ErrQueryRelease, + + ErrRequestData, // requestdata + ErrObjectLong, // objectLong + MfChangeData // change data of the existing object +}; + + + + +OLESTATUS FARINTERNAL MfRelease (lpobj) +LPOBJECT_MF lpobj; +{ + HOBJECT hobj; + + if (lpobj->mfp.hMF) { + DeleteMetaFile (lpobj->mfp.hMF); + lpobj->mfp.hMF = NULL; + } + + if (lpobj->hmfp) + GlobalFree (lpobj->hmfp); + + if (lpobj->head.lhclientdoc) + DocDeleteObject ((LPOLEOBJECT)lpobj); + + if (hobj = lpobj->head.hobj) { + lpobj->head.hobj = NULL; + GlobalUnlock (hobj); + GlobalFree (hobj); + } + + return OLE_OK; +} + + +OLESTATUS FARINTERNAL MfSaveToStream (lpobj, lpstream) +LPOBJECT_MF lpobj; +LPOLESTREAM lpstream; +{ + OLESTATUS retVal = OLE_ERROR_STREAM; + HANDLE hBits; + LPSTR lpBits; + + if (!lpobj->mfp.hMF) + return OLE_ERROR_BLANK; + + if (PutBytes (lpstream, (LPSTR) &dwVerToFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.ctype, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutStrWithLen(lpstream, (LPSTR)"METAFILEPICT")) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (PutBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (!(hBits = GetMetaFileBits (lpobj->mfp.hMF))) + return OLE_ERROR_MEMORY; + + if (lpBits = (LPSTR) GlobalLock (hBits)) { + if (!PutBytes (lpstream, (LPSTR)&lpobj->mfp, sizeof(METAFILEPICT))) + if (!PutBytes (lpstream, (LPSTR)lpBits, + lpobj->sizeBytes - sizeof(METAFILEPICT))) + retVal = OLE_OK; + + GlobalUnlock(hBits); + } + else + retVal = OLE_ERROR_MEMORY; + + lpobj->mfp.hMF = SetMetaFileBits (hBits); + return retVal; +} + + + + +OLESTATUS FARINTERNAL MfClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOBJECT_MF lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOBJECT_MF FAR * lplpobj; +{ + LPOBJECT_MF lpobjMf; + HANDLE hmf; + + *lplpobj = NULL; + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + if (!(hmf = CopyMetaFile (lpobjsrc->mfp.hMF, NULL))) + return OLE_ERROR_MEMORY; + + if (lpobjMf = MfCreateBlank (lhclientdoc, lpobjname, + lpobjsrc->head.ctype)) { + lpobjMf->mfp = lpobjsrc->mfp; + lpobjMf->sizeBytes = lpobjsrc->sizeBytes; + lpobjMf->mfp.hMF = hmf; + lpobjMf->head.lpclient = lpclient; + lpobjMf->head.mm = lpobjMf->mfp.mm; + MfSetExtents (lpobjMf); + + *lplpobj = lpobjMf; + return OLE_OK; + } + + return OLE_ERROR_MEMORY; +} + + + +OLESTATUS FARINTERNAL MfEqual (lpobj1, lpobj2) +LPOBJECT_MF lpobj1; +LPOBJECT_MF lpobj2; +{ + HANDLE hBits1 = NULL, hBits2 = NULL; + OLESTATUS retval = OLE_ERROR_NOT_EQUAL; + + if (!(hBits1 = GetMetaFileBits (lpobj1->mfp.hMF))) + goto errEqual; + + if (!(hBits2 = GetMetaFileBits (lpobj2->mfp.hMF))) + goto errEqual; + + if (CmpGlobals (hBits1, hBits2)) + retval = OLE_OK; + +errEqual: + if (hBits1) + lpobj1->mfp.hMF = SetMetaFileBits (hBits1); + + if (hBits2) + lpobj2->mfp.hMF = SetMetaFileBits (hBits2); + + return retval; +} + + +OLESTATUS FARINTERNAL MfCopy (LPOBJECT_MF lpobj) +{ + HANDLE hMF; + + if (!(hMF = CopyMetaFile (lpobj->mfp.hMF, NULL))) + return OLE_ERROR_MEMORY; + + return (MfCopyToClip (lpobj, hMF)); +} + + + +OLESTATUS FARINTERNAL MfQueryBounds (lpobj, lpRc) +LPOBJECT_MF lpobj; +LPRECT lpRc; +{ + Puts("MfQueryBounds"); + + if (!lpobj->mfp.hMF) + return OLE_ERROR_BLANK; + + // Bounds are given in MM_HIMETRIC mode. + + lpRc->left = 0; + lpRc->top = 0; + lpRc->right = (int) lpobj->head.cx; + lpRc->bottom = (int) lpobj->head.cy; + return OLE_OK; +} + + + +OLECLIPFORMAT FARINTERNAL MfEnumFormat (lpobj, cfFormat) +LPOBJECT_MF lpobj; +OLECLIPFORMAT cfFormat; +{ + if (!cfFormat) + return CF_METAFILEPICT; + + return NULL; +} + + +OLESTATUS FARINTERNAL MfGetData (lpobj, cfFormat, lphandle) +LPOBJECT_MF lpobj; +OLECLIPFORMAT cfFormat; +LPHANDLE lphandle; +{ + if (cfFormat != CF_METAFILEPICT) + return OLE_ERROR_FORMAT; + + if (!(*lphandle = GetHmfp (lpobj))) + return OLE_ERROR_BLANK; + + return OLE_OK; +} + + +LPOBJECT_MF FARINTERNAL MfCreateObject (hMeta, lpclient, fDelete, lhclientdoc, lpobjname, objType) +HANDLE hMeta; +LPOLECLIENT lpclient; +BOOL fDelete; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + LPOBJECT_MF lpobj; + + if (lpobj = MfCreateBlank (lhclientdoc, lpobjname, objType)) { + if (MfChangeData (lpobj, hMeta, lpclient, fDelete) != OLE_OK) { + MfRelease (lpobj); + lpobj = NULL; + } + } + + return lpobj; +} + +// If the routine fails then the object will be left with it's old data. +// If fDelete is TRUE, then hMeta, and the hMF it contains will be deleted +// whether the routine is successful or not. + +OLESTATUS FARINTERNAL MfChangeData (lpobj, hMeta, lpclient, fDelete) +LPOBJECT_MF lpobj; +HANDLE hMeta; +LPOLECLIENT lpclient; +BOOL fDelete; +{ + HANDLE hNewMF; + LPMETAFILEPICT lpMetaPict; + + if ((lpMetaPict = (LPMETAFILEPICT) GlobalLock (hMeta)) == NULL) { + if (fDelete) + GlobalFree (hMeta); + return OLE_ERROR_MEMORY; + } + + GlobalUnlock (hMeta); + + if (!fDelete) { + if (!(hNewMF = CopyMetaFile (lpMetaPict->hMF, NULL))) + return OLE_ERROR_MEMORY; + } + else { + hNewMF = lpMetaPict->hMF; + } + + return MfUpdateStruct (lpobj, lpclient, hMeta, lpMetaPict, hNewMF, fDelete); +} + + +OLESTATUS INTERNAL MfUpdateStruct (lpobj, lpclient, hMeta, lpMetaPict, hMF, fDelete) +LPOBJECT_MF lpobj; +LPOLECLIENT lpclient; +HANDLE hMeta; +LPMETAFILEPICT lpMetaPict; +HANDLE hMF; +BOOL fDelete; +{ + OLESTATUS retVal; + DWORD size; + HANDLE hOldMF; + + hOldMF = lpobj->mfp.hMF; + + ASSERT(lpMetaPict->mm == MM_ANISOTROPIC, "Wrong mapping mode") + if (lpMetaPict->mm != MM_ANISOTROPIC) + retVal = OLE_ERROR_METAFILE; + else if (!(size = MfGetSize (&hMF))) + retVal = OLE_ERROR_BLANK; + else { + lpobj->mfp = *lpMetaPict; + lpobj->mfp.hMF = hMF; + lpobj->sizeBytes = size + sizeof(METAFILEPICT); + lpobj->head.lpclient = lpclient; + lpobj->head.mm = lpobj->mfp.mm; + if (lpobj->hmfp) { + GlobalFree (lpobj->hmfp); + lpobj->hmfp = NULL; + } + MfSetExtents (lpobj); + if (hOldMF) + DeleteMetaFile (hOldMF); + retVal = OLE_OK; + } + + if (retVal != OLE_OK) + DeleteMetaFile (hMF); + + if (fDelete) + GlobalFree (hMeta); + return retVal; +} + + +LPOBJECT_MF FARINTERNAL MfCreateBlank(lhclientdoc, lpobjname, objType) +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LONG objType; +{ + HOBJECT hobj; + LPOBJECT_MF lpobj; + + if(!(hobj = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT,sizeof (OBJECT_MF)))) + return NULL; + + if (!(lpobj = (LPOBJECT_MF) GlobalLock (hobj))){ + GlobalFree (hobj); + return NULL; + } + + lpobj->head.objId[0] = 'L'; + lpobj->head.objId[1] = 'E'; + lpobj->head.ctype = objType; + lpobj->head.lpvtbl = (LPOLEOBJECTVTBL)&vtblMF; + lpobj->head.iTable = INVALID_INDEX; + lpobj->head.mm = MM_TEXT; + lpobj->head.hobj = hobj; + + if (objType == CT_STATIC) + DocAddObject ((LPCLIENTDOC) lhclientdoc, + (LPOLEOBJECT) lpobj, lpobjname); + + // Unlock will be done at object deletion time. + return lpobj; +} + + +OLESTATUS FARINTERNAL MfLoadFromStream (lpstream, lpclient, lhclientdoc, lpobjname, lplpobj, objType) +LPOLESTREAM lpstream; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +LONG objType; +{ + LPOBJECT_MF lpobj = NULL; + OLESTATUS retVal = OLE_ERROR_STREAM; + HANDLE hBits; + LPSTR lpBits; + DWORD dwSizeMfp = NULL; + + // Class name would've been read by this time. + + *lplpobj = NULL; + + if (!(lpobj = MfCreateBlank (lhclientdoc, lpobjname, objType))) + return OLE_ERROR_MEMORY; + + lpobj->head.lpclient = lpclient; + + if (GetBytes (lpstream, (LPSTR) &lpobj->head.cx, sizeof(LONG))) + goto errLoad; + + if (GetBytes (lpstream, (LPSTR) &lpobj->head.cy, sizeof(LONG))) + goto errLoad; + + if (GetBytes (lpstream, (LPSTR) &lpobj->sizeBytes, sizeof(LONG))) + goto errLoad; + + if (!lpobj->sizeBytes) { + retVal = OLE_ERROR_BLANK; + goto errLoad; + } + + // if we are reading a MAC object we want to skip this + if (HIWORD(dwVerFromFile) == OS_WIN16) { + if (GetBytes (lpstream, (LPSTR) &lpobj->mfp, sizeof(METAFILEPICT))) + goto errLoad; + + dwSizeMfp = sizeof(METAFILEPICT); + } + + retVal = OLE_ERROR_MEMORY; + if (!(hBits = GlobalAlloc (GMEM_MOVEABLE, lpobj->sizeBytes - dwSizeMfp))) + goto errLoad; + + if (!(lpBits = (LPSTR)GlobalLock (hBits))) + goto errMem; + + if (GetBytes (lpstream, (LPSTR)lpBits, lpobj->sizeBytes - dwSizeMfp)) { + retVal = OLE_ERROR_MEMORY; + GlobalUnlock (hBits); + goto errMem; + } + + lpobj->head.mm = lpobj->mfp.mm; + GlobalUnlock (hBits); + + if (HIWORD(dwVerFromFile) == OS_WIN16) { + if (!(lpobj->mfp.hMF = SetMetaFileBits (hBits))) + goto errMem; + } + else { + // if we are reading a MAC object we want to delete the original + // presentation data and show some rectangle + + GlobalFree (hBits); + lpobj->mfp.xExt = (int) lpobj->head.cx; + lpobj->mfp.yExt = (int) lpobj->head.cy; + + if ((retVal = wCreateDummyMetaFile (lpobj, lpobj->mfp.xExt, + lpobj->mfp.yExt)) != OLE_OK) + goto errLoad; + } + + MfSetExtents (lpobj); + + *lplpobj = (LPOLEOBJECT) lpobj; + return OLE_OK; + +errMem: + GlobalFree (hBits); + +errLoad: + OleDelete ((LPOLEOBJECT)lpobj); + return retVal; +} + + + + +OLESTATUS FARINTERNAL MfPaste (lpclient, lhclientdoc, lpobjname, lplpoleobject, objType) +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +LONG objType; +{ + HANDLE hMeta; + + *lplpoleobject = NULL; + + if((hMeta = GetClipboardData (CF_METAFILEPICT)) == NULL) + return OLE_ERROR_MEMORY; + + if (!(*lplpoleobject = (LPOLEOBJECT) MfCreateObject (hMeta, lpclient, + FALSE, lhclientdoc, + lpobjname, objType))) + return OLE_ERROR_MEMORY; + + return OLE_OK; +} + + + + +OLESTATUS INTERNAL MfCopyToClip (lpobj, hMF) +LPOBJECT_MF lpobj; +HANDLE hMF; +{ + LPMETAFILEPICT lpMeta; + HANDLE hMeta; + + if (!(hMeta = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT)))) + return OLE_ERROR_MEMORY; + + if (lpMeta = (LPMETAFILEPICT) GlobalLock(hMeta)){ + *lpMeta = lpobj->mfp; + if (hMF) + lpMeta->hMF = hMF; + else + lpobj->mfp.hMF = NULL; + GlobalUnlock (hMeta); + SetClipboardData(CF_METAFILEPICT, hMeta); + return OLE_OK; + } + + GlobalFree(hMeta); + return OLE_ERROR_MEMORY; +} + + + +void FARINTERNAL MfSetExtents (LPOBJECT_MF lpobj) +{ + if (lpobj->mfp.xExt > 0) { + // The extents are assumed to be in MM_HIMETIRC units + lpobj->head.cx = (LONG) lpobj->mfp.xExt; + lpobj->head.cy = (LONG) - lpobj->mfp.yExt; + } +} + + +DWORD INTERNAL MfGetSize (lphmf) +LPHANDLE lphmf; +{ + HANDLE hBits; + DWORD size; + + if ((hBits = GetMetaFileBits (*lphmf)) == NULL) + return NULL; + + size = GlobalSize(hBits); + *lphmf = SetMetaFileBits (hBits); + return size; +} + + + +HANDLE INTERNAL GetHmfp (lpobj) +LPOBJECT_MF lpobj; +{ + HANDLE hmfp; + LPMETAFILEPICT lpmfp = NULL; + + if (lpobj->hmfp) + return lpobj->hmfp; + + if (!(hmfp = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT)))) + return NULL; + + if (!(lpmfp = (LPMETAFILEPICT) GlobalLock (hmfp))) { + GlobalFree (hmfp); + return NULL; + } + + *lpmfp = lpobj->mfp; + GlobalUnlock (hmfp); + return (lpobj->hmfp = hmfp); +} + + +BOOL FAR PASCAL OleIsDcMeta (hdc) +HDC hdc; +{ + if (!bWLO && (wWinVer == 0x0003)) { + + WORD wDsAlias, wGDIcs = HIWORD(SaveDC); + WORD wOffset = LOWORD(((DWORD)SaveDC)); + WORD FAR PASCAL AllocCStoDSAlias (WORD); + WORD FAR PASCAL FreeSelector (WORD); + + if (!wGDIds) { + wDsAlias = AllocCStoDSAlias (wGDIcs); + wGDIds = GetGDIds (MAKELONG(wOffset, wDsAlias)); + FreeSelector (wDsAlias); + } + + return IsMetaDC (hdc, wGDIds); + } + else + return (GetDeviceCaps (hdc, TECHNOLOGY) == DT_METAFILE); +} + +OLESTATUS FARINTERNAL wCreateDummyMetaFile ( +LPOBJECT_MF lpobj, +int xExt, +int yExt) +{ + HDC hMetaDC; + + if (!(hMetaDC = CreateMetaFile (NULL))) + return OLE_ERROR_MEMORY; + + SetWindowOrg (hMetaDC, 0, 0); + SetWindowExt (hMetaDC, xExt, yExt); + Rectangle (hMetaDC, 0, 0, xExt, yExt); + if (!(lpobj->mfp.hMF = CloseMetaFile (hMetaDC))) + return OLE_ERROR_MEMORY; + lpobj->mfp.mm = MM_ANISOTROPIC; + lpobj->sizeBytes = MfGetSize (&lpobj->mfp.hMF) + sizeof(METAFILEPICT); + return OLE_OK; +} diff --git a/private/mvdm/wow16/ole/client/mk.cmd b/private/mvdm/wow16/ole/client/mk.cmd new file mode 100644 index 000000000..484f0121d --- /dev/null +++ b/private/mvdm/wow16/ole/client/mk.cmd @@ -0,0 +1,55 @@ +@Echo off + +REM Cmd file building DEBUG, RETAIL, and RELEASE versions of DLL + +SET DEBUG= +SET RETAIL= +REM set path2=%path% +REM set include2=%include% +REM set lib2=%lib% +REM set path=\ole\bin;\ole\bin\os2 +REM set include=\ole\inc +REM set lib=\ole\lib + +if %1x==x goto debug + +if %1==debug goto debug + +if %1==retail goto retail + +if %1==release goto retail +goto end + +:retail +SET RETAIL=TRUE +if NOT EXIST retail md retail +goto make + +:debug +SET DEBUG=TRUE +if NOT EXIST debug md debug +goto make + +:make +nmake >z.msg +goto end + +:release +if NOT EXIST retail md retail +SET RETAIL=TRUE +nmake >z.msg +if NOT EXIST release md release +copy retail\*.dll release > nul 2>&1 +copy retail\*.exe release > nul 2>&1 +copy retail\*.map release > nul 2>&1 +goto end + +:end +REM set path=%path2% +REM set path2= +REM set include=%include2% +REM set include2= +REM set lib=%lib2% +REM set lib2= +SET DEBUG= +SET RETAIL= diff --git a/private/mvdm/wow16/ole/client/net.asv b/private/mvdm/wow16/ole/client/net.asv new file mode 100644 index 000000000..6b4c0c4d4 --- /dev/null +++ b/private/mvdm/wow16/ole/client/net.asv @@ -0,0 +1,371 @@ +/****************************** Module Header ******************************\ +* Module Name: net.c +* +* PURPOSE: Contains routines network support +* +* Created: Feb 1991 +* +* Copyright (c) 1991 Microsoft Corporation +* +* History: +* Srinik 02\12\1190 Orginal +* +\***************************************************************************/ + +#include <windows.h> +#include <winnet.h> + +#include "dll.h" + +#define MAX_DRIVE 26 + +char szNULL[] = ""; +char szSS[] = "SS"; +char szOffset[] = "OFFSET"; + + +BOOL FAR PASCAL GetTaskVisibleWindow (HWND, DWORD); +void INTERNAL RemoveNetName (LPOBJECT_LE); + +// Gets the drive letter from topic (if one exists) and then gets the remote +// name for that drive and then saves it in the object. + +OLESTATUS FARINTERNAL SetNetName (lpobj) +LPOBJECT_LE lpobj; +{ + char buf[MAX_STR]; + WORD cbBuf = sizeof(buf); + WORD driveType; + char szDrive[3]; + + if (lpobj->head.ctype == CT_EMBEDDED) + return OLE_OK; + + if (!GlobalGetAtomName (lpobj->topic, buf, cbBuf)) + return OLE_ERROR_BLANK; + + if (buf[1] != ':') { + RemoveNetName (lpobj); + return OLE_OK; + } + + szDrive[2] = NULL; + szDrive[1] = ':'; + szDrive[0] = buf[0]; + AnsiUpperBuff ((LPSTR) szDrive, 1); + + if (!(driveType = GetDriveType (szDrive[0] - 'A'))) { + // drive is non existent + return OLE_ERROR_DRIVE; + } + + if (driveType == DRIVE_REMOTE) { + if (WNetGetConnection (szDrive, buf, (WORD FAR *) &cbBuf) + != WN_SUCCESS) + return OLE_ERROR_DRIVE; + + lpobj->cDrive = szDrive[0]; + if (lpobj->aNetName) + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = GlobalAddAtom(buf); + lpobj->dwNetInfo = MAKELONG((WNetGetCaps (WNNC_NET_TYPE)), + (WNetGetCaps (WNNC_DRIVER_VERSION))); + } + else { + RemoveNetName (lpobj); + } + + return OLE_OK; +} + + +// If netname exists for the given object, then it makes sure that drive +// in topic corresponds to the netname. If it's not the drive letter will +// be fixed by calling FixNet() + +OLESTATUS FARINTERNAL CheckNetDrive (lpobj, fNetDlg) +LPOBJECT_LE lpobj; +BOOL fNetDlg; +{ + char buf[MAX_NET_NAME]; + char netName[MAX_NET_NAME]; + WORD cbBuf = sizeof(buf); + char szDrive[3]; + + if (lpobj->head.ctype == CT_EMBEDDED) + return OLE_OK; + + if (!lpobj->aNetName) + return OLE_OK; + + if (!GlobalGetAtomName (lpobj->aNetName, netName, sizeof(netName))) + return OLE_ERROR_MEMORY; + + szDrive[2] = NULL; + szDrive[1] = ':'; + if (!(szDrive[0] = lpobj->cDrive)) { + if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf))) + szDrive[0] = lpobj->cDrive = buf[0]; + } + + if ((WNetGetConnection (szDrive, buf, (WORD FAR *) &cbBuf) + == WN_SUCCESS) && (!lstrcmp(netName, buf))) + return OLE_OK; + + return FixNet (lpobj, netName, fNetDlg); +} + + +// Find if there is a drive connected to the given server. If so, get the +// drive letter and set it in topic. If not try to make connection, and if +// that attempt is successful the set the drive letter in topic. + +OLESTATUS INTERNAL FixNet (lpobj, lpNetName, fNetDlg) +LPOBJECT_LE lpobj; +LPSTR lpNetName; +BOOL fNetDlg; +{ + int nDrive = 2; // drive 'C' + OLESTATUS retVal; + + if (SetNextNetDrive(lpobj, &nDrive, lpNetName)) + return OLE_OK; + + if (fNetDlg != POPUP_NETDLG) + return OLE_ERROR_NETWORK; + + if ((retVal = ConnectNet (lpobj, lpNetName)) == OLE_OK) { + if (!ChangeTopic (lpobj)) + return OLE_ERROR_BLANK; + } + + return retVal; +} + + + +BOOL FARINTERNAL SetNextNetDrive (lpobj, lpnDrive, lpNetName) +LPOBJECT_LE lpobj; +int FAR * lpnDrive; +LPSTR lpNetName; +{ + char buf[MAX_STR]; + WORD cbBuf = sizeof(buf); + char szDrive[3]; + + if (!lpNetName[0]) { + if (!GlobalGetAtomName(lpobj->aNetName, lpNetName, MAX_STR)) + return FALSE; + } + + szDrive[2] = NULL; + szDrive[1] = ':'; + while (*lpnDrive < MAX_DRIVE) { + if (GetDriveType (++*lpnDrive) == DRIVE_REMOTE) { + szDrive[0] = (char) ('A' + *lpnDrive); + cbBuf = sizeof(buf); + if ((WNetGetConnection (szDrive, buf, (WORD FAR *) &cbBuf) + == WN_SUCCESS) && (!lstrcmp(lpNetName, buf))) { + lpobj->cDrive = szDrive[0]; + return ChangeTopic (lpobj); + } + } + } + + return FALSE; +} + + +BOOL FARINTERNAL ChangeTopic (lpobj) +LPOBJECT_LE lpobj; +{ + char buf[MAX_STR]; + + if (!GlobalGetAtomName(lpobj->topic, buf, sizeof(buf))) + return FALSE; + if (lpobj->topic) + GlobalDeleteAtom(lpobj->topic); + buf[0] = lpobj->cDrive; + lpobj->topic = GlobalAddAtom (buf); + if (lpobj->hLink) { + GlobalFree (lpobj->hLink); + lpobj->hLink = NULL; + } + + return TRUE; +} + + + +OLESTATUS INTERNAL ConnectNet (lpobj, lpNetName) +LPOBJECT_LE lpobj; +LPSTR lpNetName; +{ + FARPROC lpConnectDlg; + FARPROC lpGetTaskVisWnd; + OLESTATUS retVal = OLE_ERROR_MEMORY; + HWND hCurTask; + HWND hwndParent = NULL; + + if (!(lpConnectDlg = MakeProcInstance ((FARPROC) ConnectDlgProc, + hInstDLL))) + return OLE_ERROR_MEMORY; + + + hCurTask = GetCurrentTask(); + ASSERT (hCurTask, "Current task handle in NULL"); + + if (!(lpGetTaskVisWnd = MakeProcInstance (GetTaskVisibleWindow,hInstDLL))) + goto errRtn; + + // Get the container task's main window, and use that as parent for + // the dlg box. + EnumTaskWindows (hCurTask, lpGetTaskVisWnd, + (DWORD) ((WORD FAR *) &hwndParent)); + + if (lpobj->cDrive = (char) DialogBoxParam (hInstDLL, "CONNECTDLG", + hwndParent, lpConnectDlg, + (DWORD) lpNetName)) + retVal = OLE_OK; + else + retVal = OLE_ERROR_NETWORK; + + FreeProcInstance (lpGetTaskVisWnd); + +errRtn: + FreeProcInstance (lpConnectDlg); + return retVal; +} + + + +int FAR PASCAL ConnectDlgProc(HWND hDlg, WORD wMsg, WORD wParam, DWORD lParam) +{ + char szPassword[32]; + char szTitle[64]; + + switch (wMsg) { + case WM_INITDIALOG: + SetProp (hDlg, szSS, HIWORD (lParam)); + SetProp (hDlg, szOffset, LOWORD (lParam)); + FillDrives (hDlg); + SetDlgItemText (hDlg, IDD_PATH, (LPSTR) lParam); + break; + + case WM_COMMAND: + switch (wParam) { + + case IDOK: + { + WORD cch = 128; + char szMessage[128]; + char szDrive[3]; + LPSTR lpNetName; + + GetDlgItemText(hDlg, IDD_DRIVE, szDrive, sizeof(szDrive)); + GetDlgItemText(hDlg, IDD_PASSWORD, szPassword, + sizeof(szPassword)); + lpNetName = (LPSTR) MAKELONG(((WORD) GetProp (hDlg, szOffset)), ((WORD) GetProp (hDlg, szSS))); + wParam = WNetAddConnection (lpNetName, + (LPSTR) szPassword, szDrive); + + if (wParam == WN_SUCCESS) { + RemoveProp (hDlg, szSS); + RemoveProp (hDlg, szOffset); + EndDialog (hDlg, szDrive[0]); + return TRUE; + } + + LoadString (hInstDLL, IDS_NETERR, szTitle, + sizeof(szTitle)); + if (WNetGetErrorText (wParam, szMessage, &cch) + != WN_SUCCESS) + LoadString (hInstDLL, IDS_NETCONERRMSG, + szMessage, sizeof(szMessage)); + + if (MessageBox (hDlg, szMessage, szTitle, + MB_RETRYCANCEL | MB_SYSTEMMODAL) == IDCANCEL) + goto error; + + if (wParam == WN_ALREADY_CONNECTED) + FillDrives (hDlg); + SetDlgItemText (hDlg, IDD_PASSWORD, szNULL); + break; + } + + case IDCANCEL: +error: + RemoveProp (hDlg, szSS); + RemoveProp (hDlg, szOffset); + EndDialog(hDlg, NULL); + return TRUE; + + case IDD_DRIVE: + break; + + case IDD_PATH: + if (HIWORD(lParam) == EN_KILLFOCUS) { + LPSTR lpNetName; + + lpNetName = (LPSTR) MAKELONG(((WORD)GetProp (hDlg, szOffset)), ((WORD) GetProp (hDlg, szSS))); + + SendDlgItemMessage (hDlg, IDD_PATH, WM_SETTEXT, 0, + (DWORD) lpNetName); + } + break; + + default: + break; + } + break; + + default: + break; + } + + return FALSE; +} + + +VOID INTERNAL FillDrives (hDlg) +HWND hDlg; +{ + HWND hwndCB; + int nDrive = 3; + char szDrive[3]; + + hwndCB = GetDlgItem(hDlg, IDD_DRIVE); + SendMessage(hwndCB, CB_RESETCONTENT, 0, 0L); + szDrive[2] = NULL; + szDrive[1] = ':'; + while (nDrive < MAX_DRIVE) { + szDrive[0] = (char) ('A' + nDrive); + if (!GetDriveType (nDrive)) + SendMessage(hwndCB, CB_ADDSTRING, 0, (DWORD)(LPSTR)szDrive); + nDrive++; + } + SendMessage(hwndCB, CB_SETCURSEL, 0, 0L); +} + + +BOOL FAR PASCAL GetTaskVisibleWindow (hWnd, lpTaskVisWnd) +HWND hWnd; +DWORD lpTaskVisWnd; +{ + if (IsWindowVisible (hWnd)) { + *(WORD FAR *) lpTaskVisWnd = hWnd; + return FALSE; + } + + return TRUE; +} + +void INTERNAL RemoveNetName (LPOBJECT_LE lpobj) +{ + if (lpobj->aNetName) { + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = NULL; + } + + lpobj->cDrive = NULL; +} diff --git a/private/mvdm/wow16/ole/client/net.c b/private/mvdm/wow16/ole/client/net.c new file mode 100644 index 000000000..6b4c0c4d4 --- /dev/null +++ b/private/mvdm/wow16/ole/client/net.c @@ -0,0 +1,371 @@ +/****************************** Module Header ******************************\ +* Module Name: net.c +* +* PURPOSE: Contains routines network support +* +* Created: Feb 1991 +* +* Copyright (c) 1991 Microsoft Corporation +* +* History: +* Srinik 02\12\1190 Orginal +* +\***************************************************************************/ + +#include <windows.h> +#include <winnet.h> + +#include "dll.h" + +#define MAX_DRIVE 26 + +char szNULL[] = ""; +char szSS[] = "SS"; +char szOffset[] = "OFFSET"; + + +BOOL FAR PASCAL GetTaskVisibleWindow (HWND, DWORD); +void INTERNAL RemoveNetName (LPOBJECT_LE); + +// Gets the drive letter from topic (if one exists) and then gets the remote +// name for that drive and then saves it in the object. + +OLESTATUS FARINTERNAL SetNetName (lpobj) +LPOBJECT_LE lpobj; +{ + char buf[MAX_STR]; + WORD cbBuf = sizeof(buf); + WORD driveType; + char szDrive[3]; + + if (lpobj->head.ctype == CT_EMBEDDED) + return OLE_OK; + + if (!GlobalGetAtomName (lpobj->topic, buf, cbBuf)) + return OLE_ERROR_BLANK; + + if (buf[1] != ':') { + RemoveNetName (lpobj); + return OLE_OK; + } + + szDrive[2] = NULL; + szDrive[1] = ':'; + szDrive[0] = buf[0]; + AnsiUpperBuff ((LPSTR) szDrive, 1); + + if (!(driveType = GetDriveType (szDrive[0] - 'A'))) { + // drive is non existent + return OLE_ERROR_DRIVE; + } + + if (driveType == DRIVE_REMOTE) { + if (WNetGetConnection (szDrive, buf, (WORD FAR *) &cbBuf) + != WN_SUCCESS) + return OLE_ERROR_DRIVE; + + lpobj->cDrive = szDrive[0]; + if (lpobj->aNetName) + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = GlobalAddAtom(buf); + lpobj->dwNetInfo = MAKELONG((WNetGetCaps (WNNC_NET_TYPE)), + (WNetGetCaps (WNNC_DRIVER_VERSION))); + } + else { + RemoveNetName (lpobj); + } + + return OLE_OK; +} + + +// If netname exists for the given object, then it makes sure that drive +// in topic corresponds to the netname. If it's not the drive letter will +// be fixed by calling FixNet() + +OLESTATUS FARINTERNAL CheckNetDrive (lpobj, fNetDlg) +LPOBJECT_LE lpobj; +BOOL fNetDlg; +{ + char buf[MAX_NET_NAME]; + char netName[MAX_NET_NAME]; + WORD cbBuf = sizeof(buf); + char szDrive[3]; + + if (lpobj->head.ctype == CT_EMBEDDED) + return OLE_OK; + + if (!lpobj->aNetName) + return OLE_OK; + + if (!GlobalGetAtomName (lpobj->aNetName, netName, sizeof(netName))) + return OLE_ERROR_MEMORY; + + szDrive[2] = NULL; + szDrive[1] = ':'; + if (!(szDrive[0] = lpobj->cDrive)) { + if (GlobalGetAtomName (lpobj->topic, buf, sizeof(buf))) + szDrive[0] = lpobj->cDrive = buf[0]; + } + + if ((WNetGetConnection (szDrive, buf, (WORD FAR *) &cbBuf) + == WN_SUCCESS) && (!lstrcmp(netName, buf))) + return OLE_OK; + + return FixNet (lpobj, netName, fNetDlg); +} + + +// Find if there is a drive connected to the given server. If so, get the +// drive letter and set it in topic. If not try to make connection, and if +// that attempt is successful the set the drive letter in topic. + +OLESTATUS INTERNAL FixNet (lpobj, lpNetName, fNetDlg) +LPOBJECT_LE lpobj; +LPSTR lpNetName; +BOOL fNetDlg; +{ + int nDrive = 2; // drive 'C' + OLESTATUS retVal; + + if (SetNextNetDrive(lpobj, &nDrive, lpNetName)) + return OLE_OK; + + if (fNetDlg != POPUP_NETDLG) + return OLE_ERROR_NETWORK; + + if ((retVal = ConnectNet (lpobj, lpNetName)) == OLE_OK) { + if (!ChangeTopic (lpobj)) + return OLE_ERROR_BLANK; + } + + return retVal; +} + + + +BOOL FARINTERNAL SetNextNetDrive (lpobj, lpnDrive, lpNetName) +LPOBJECT_LE lpobj; +int FAR * lpnDrive; +LPSTR lpNetName; +{ + char buf[MAX_STR]; + WORD cbBuf = sizeof(buf); + char szDrive[3]; + + if (!lpNetName[0]) { + if (!GlobalGetAtomName(lpobj->aNetName, lpNetName, MAX_STR)) + return FALSE; + } + + szDrive[2] = NULL; + szDrive[1] = ':'; + while (*lpnDrive < MAX_DRIVE) { + if (GetDriveType (++*lpnDrive) == DRIVE_REMOTE) { + szDrive[0] = (char) ('A' + *lpnDrive); + cbBuf = sizeof(buf); + if ((WNetGetConnection (szDrive, buf, (WORD FAR *) &cbBuf) + == WN_SUCCESS) && (!lstrcmp(lpNetName, buf))) { + lpobj->cDrive = szDrive[0]; + return ChangeTopic (lpobj); + } + } + } + + return FALSE; +} + + +BOOL FARINTERNAL ChangeTopic (lpobj) +LPOBJECT_LE lpobj; +{ + char buf[MAX_STR]; + + if (!GlobalGetAtomName(lpobj->topic, buf, sizeof(buf))) + return FALSE; + if (lpobj->topic) + GlobalDeleteAtom(lpobj->topic); + buf[0] = lpobj->cDrive; + lpobj->topic = GlobalAddAtom (buf); + if (lpobj->hLink) { + GlobalFree (lpobj->hLink); + lpobj->hLink = NULL; + } + + return TRUE; +} + + + +OLESTATUS INTERNAL ConnectNet (lpobj, lpNetName) +LPOBJECT_LE lpobj; +LPSTR lpNetName; +{ + FARPROC lpConnectDlg; + FARPROC lpGetTaskVisWnd; + OLESTATUS retVal = OLE_ERROR_MEMORY; + HWND hCurTask; + HWND hwndParent = NULL; + + if (!(lpConnectDlg = MakeProcInstance ((FARPROC) ConnectDlgProc, + hInstDLL))) + return OLE_ERROR_MEMORY; + + + hCurTask = GetCurrentTask(); + ASSERT (hCurTask, "Current task handle in NULL"); + + if (!(lpGetTaskVisWnd = MakeProcInstance (GetTaskVisibleWindow,hInstDLL))) + goto errRtn; + + // Get the container task's main window, and use that as parent for + // the dlg box. + EnumTaskWindows (hCurTask, lpGetTaskVisWnd, + (DWORD) ((WORD FAR *) &hwndParent)); + + if (lpobj->cDrive = (char) DialogBoxParam (hInstDLL, "CONNECTDLG", + hwndParent, lpConnectDlg, + (DWORD) lpNetName)) + retVal = OLE_OK; + else + retVal = OLE_ERROR_NETWORK; + + FreeProcInstance (lpGetTaskVisWnd); + +errRtn: + FreeProcInstance (lpConnectDlg); + return retVal; +} + + + +int FAR PASCAL ConnectDlgProc(HWND hDlg, WORD wMsg, WORD wParam, DWORD lParam) +{ + char szPassword[32]; + char szTitle[64]; + + switch (wMsg) { + case WM_INITDIALOG: + SetProp (hDlg, szSS, HIWORD (lParam)); + SetProp (hDlg, szOffset, LOWORD (lParam)); + FillDrives (hDlg); + SetDlgItemText (hDlg, IDD_PATH, (LPSTR) lParam); + break; + + case WM_COMMAND: + switch (wParam) { + + case IDOK: + { + WORD cch = 128; + char szMessage[128]; + char szDrive[3]; + LPSTR lpNetName; + + GetDlgItemText(hDlg, IDD_DRIVE, szDrive, sizeof(szDrive)); + GetDlgItemText(hDlg, IDD_PASSWORD, szPassword, + sizeof(szPassword)); + lpNetName = (LPSTR) MAKELONG(((WORD) GetProp (hDlg, szOffset)), ((WORD) GetProp (hDlg, szSS))); + wParam = WNetAddConnection (lpNetName, + (LPSTR) szPassword, szDrive); + + if (wParam == WN_SUCCESS) { + RemoveProp (hDlg, szSS); + RemoveProp (hDlg, szOffset); + EndDialog (hDlg, szDrive[0]); + return TRUE; + } + + LoadString (hInstDLL, IDS_NETERR, szTitle, + sizeof(szTitle)); + if (WNetGetErrorText (wParam, szMessage, &cch) + != WN_SUCCESS) + LoadString (hInstDLL, IDS_NETCONERRMSG, + szMessage, sizeof(szMessage)); + + if (MessageBox (hDlg, szMessage, szTitle, + MB_RETRYCANCEL | MB_SYSTEMMODAL) == IDCANCEL) + goto error; + + if (wParam == WN_ALREADY_CONNECTED) + FillDrives (hDlg); + SetDlgItemText (hDlg, IDD_PASSWORD, szNULL); + break; + } + + case IDCANCEL: +error: + RemoveProp (hDlg, szSS); + RemoveProp (hDlg, szOffset); + EndDialog(hDlg, NULL); + return TRUE; + + case IDD_DRIVE: + break; + + case IDD_PATH: + if (HIWORD(lParam) == EN_KILLFOCUS) { + LPSTR lpNetName; + + lpNetName = (LPSTR) MAKELONG(((WORD)GetProp (hDlg, szOffset)), ((WORD) GetProp (hDlg, szSS))); + + SendDlgItemMessage (hDlg, IDD_PATH, WM_SETTEXT, 0, + (DWORD) lpNetName); + } + break; + + default: + break; + } + break; + + default: + break; + } + + return FALSE; +} + + +VOID INTERNAL FillDrives (hDlg) +HWND hDlg; +{ + HWND hwndCB; + int nDrive = 3; + char szDrive[3]; + + hwndCB = GetDlgItem(hDlg, IDD_DRIVE); + SendMessage(hwndCB, CB_RESETCONTENT, 0, 0L); + szDrive[2] = NULL; + szDrive[1] = ':'; + while (nDrive < MAX_DRIVE) { + szDrive[0] = (char) ('A' + nDrive); + if (!GetDriveType (nDrive)) + SendMessage(hwndCB, CB_ADDSTRING, 0, (DWORD)(LPSTR)szDrive); + nDrive++; + } + SendMessage(hwndCB, CB_SETCURSEL, 0, 0L); +} + + +BOOL FAR PASCAL GetTaskVisibleWindow (hWnd, lpTaskVisWnd) +HWND hWnd; +DWORD lpTaskVisWnd; +{ + if (IsWindowVisible (hWnd)) { + *(WORD FAR *) lpTaskVisWnd = hWnd; + return FALSE; + } + + return TRUE; +} + +void INTERNAL RemoveNetName (LPOBJECT_LE lpobj) +{ + if (lpobj->aNetName) { + GlobalDeleteAtom (lpobj->aNetName); + lpobj->aNetName = NULL; + } + + lpobj->cDrive = NULL; +} diff --git a/private/mvdm/wow16/ole/client/ole.asm b/private/mvdm/wow16/ole/client/ole.asm new file mode 100644 index 000000000..f90aed7f5 --- /dev/null +++ b/private/mvdm/wow16/ole/client/ole.asm @@ -0,0 +1,139 @@ + ;\ + ; ole.asm + ; + ; Copyright (C) 1991, MicroSoft Corporation + ; + ; Contains pointer vaildation routine + ; + ; History: sriniK 02/01/1991 original + ; srinik 02/21/1991 added GetGDIds, IsMetaDC + ;/ + +.286p +.MODEL SMALL +.CODE + +;**************************** _CheckPointer **************************** +; +; WORD CheckPointer (lp, access) +; +; Args: +; lp pointer to be verified +; access 0 test the pointer for read access +; 1 test the pointer for write access +; returns: +; FALSE invalid pointer +; TRUE valid pointer +; +; +; + public _CheckPointer + +_CheckPointer proc + + push bp + mov bp, sp + + xor ax, ax + and word ptr [bp+8], -1 + jnz check_write_access + + verr word ptr [bp+6] ; check selector for read access + jnz error + jmp short check_offset + +check_write_access: + verw word ptr [bp+6] ; check selector for write access + jnz error + +check_offset: + lsl bx, word ptr [bp+6] ; segment limit gets copied into BX + jnz error + cmp [bp+4], bx + ja error + or ax, -1 +error: + pop bp + ret + +_CheckPointer endp + + + +;**************************** _GetGdiDS **************************** +; +; WORD GetGDIds (lpGdiFunc) +; +; Args: +; lpGdiFunc long pointer to one of the GDI functions, with selector +; part being aliased to a data selector +; returns: +; GDI DS value +; + public _GetGDIds + +_GetGDIds proc + + push bp + mov bp, sp + + mov ax, word ptr [bp+6] ; data selector + push ds + mov ds, ax + mov bx, word ptr [bp+4] + mov ax, word ptr ds:[bx+1] + pop ds + + pop bp + ret + +_GetGDIds endp + + + + +;**************************** _IsMetaDC **************************** +; +; WORD IsMetaDC (hdc, wGDIds) +; +; Args: +; hdc handle device context +; wGDIds GDI's data segment selector +; +; returns: +; TRUE if hdc is metafile dc +; FALSE otherwise +; +; ilObjHead struc +; dw ? ; pointer to next obj in chain +; ilObjType dw ? ; defines type of object +; ilObjCount dd ? ; the count of the object +; ilObjMetaList dw ? ; handle to the list of metafile +; ilObjHead ends +; + + public _IsMetaDC + +OBJ_METAFILE equ 10 + +_IsMetaDC proc + + push bp + mov bp, sp + + mov ax, [bp+6] ; data selector + push ds + mov ds, ax + mov di, [bp+4] ; hdc + mov di, [di] + cmp word ptr [di+2], OBJ_METAFILE + jz metafile + xor ax, ax +metafile: + pop ds + pop bp + ret + +_IsMetaDC endp + + end diff --git a/private/mvdm/wow16/ole/client/ole.c b/private/mvdm/wow16/ole/client/ole.c new file mode 100644 index 000000000..06564fcb8 --- /dev/null +++ b/private/mvdm/wow16/ole/client/ole.c @@ -0,0 +1,1812 @@ +/******************************* Module Header ******************************* +* Module Name: OLE.C +* +* Purpose: Handles all API routines for the dde L&E sub-dll of the ole dll. +* +* PURPOSE: API routines for handling generic objects (which may be static, +* linked, or embedded). These routines will be made into a DLL. +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, Srinik (../../90, 91) Designed/coded. +* +*****************************************************************************/ + +#include <windows.h> +#include <shellapi.h> + +#include "dll.h" + +extern DLL_ENTRY lpDllTable[]; +extern char packageClass[]; +extern OLECLIPFORMAT cfFileName; +extern DWORD dwOleVer; + +DWORD dwVerFromFile; +HANDLE hInfo = NULL; +CLIENTDOC lockDoc = {{'C', 'D'}, 0L, 0L, 0, 0, 0, 0L, 0L}; +LHCLIENTDOC lhLockDoc = (LHCLIENTDOC) ((LPCLIENTDOC) &lockDoc); +BOOL gbCreateInvisible = FALSE; +BOOL gbLaunchServer; + + +OLESTATUS INTERNAL LockServer (LPOBJECT_LE); + +#pragma alloc_text(_DDETEXT, OleLockServer, OleUnlockServer, LockServer, IsServerValid, DeleteSrvrEdit, InitSrvrConv, LeLaunchApp) + + +////////////////////////////////////////////////////////////////////////////// +// +// LPVOID FAR PASCAL OleQueryProtocol (lpobj, lpprotocol) +// +// Tells whether the object supports the specified protocol. +// +// Arguments: +// +// lpobj - object pointer +// lpprotocol - protocol string +// +// Returns: +// +// long ptr to object if the protocol is supported +// NULL if not. +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + + +LPVOID FAR PASCAL OleQueryProtocol (lpobj, lpprotocol) +LPOLEOBJECT lpobj; +LPSTR lpprotocol; +{ + if (!CheckObject(lpobj)) + return NULL; + + return (*lpobj->lpvtbl->QueryProtocol) (lpobj, lpprotocol); +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FAR PASCAL OleDelete (lpobj) +// +// Deletes the given object and all memory associated with its sub-parts. +// The calling function should cease to use 'lpobj', as it is now invalid. +// If handler dll is used reference count is reduced by one, and if it +// reaches zero the hanlder dll will be freed up. +// +// Arguments: +// +// lpobj - object pointer +// +// Returns: +// +// OLE_OK +// OLE_ERROR_OBJECT +// OLE_WAIT_FOR_RELEASE +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FAR PASCAL OleDelete (lpobj) +LPOLEOBJECT lpobj; +{ + Puts("OleDelete"); + + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + return (*lpobj->lpvtbl->Delete) (lpobj); +} + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleRelease (lpobj) +* +* OleRelease: +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRelease (lpobj) +LPOLEOBJECT lpobj; +{ + Puts("OleRelease"); + + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + return (*lpobj->lpvtbl->Release) (lpobj); +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleSaveToStream (lpobj, lpstream) +* +* oleSaveToStream: This will read <hobj> to the stream based on the <hfile> +* structure. It will return TRUE on success. This is the only object +* function for which it is not an error to pass a NULL <hobj>. In the case +* of NULL, this function will simply put a placemarker for an object. +* See oleLoadFromStream. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleSaveToStream (lpobj, lpstream) +LPOLEOBJECT lpobj; +LPOLESTREAM lpstream; +{ + Puts("OleSaveToStream"); + + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + PROBE_READ(lpstream); + + return ((*lpobj->lpvtbl->SaveToStream) (lpobj, lpstream)); +} + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleLoadFromStream (lpstream, lpprotcol, lpclient, lhclientdoc, lpobjname, lplpobj) +* +* oleLoadFromStream: This will read an object out of the stream based on the +* <hfile> structure. It will return a HANDLE to the object it creates. +* On error, the return value is NULL, but since NULL is also a valid object +* in the file, the <error> parameter should be checked as well. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleLoadFromStream (lpstream, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOLESTREAM lpstream; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + LONG len; + OLESTATUS retVal = OLE_ERROR_STREAM; + char class[100]; + ATOM aClass; + BOOL bEdit = FALSE, bStatic = FALSE; + LONG ctype; + int objCount; + int iTable = INVALID_INDEX; + + Puts("OleLoadFromStream"); + + *lplpobj = NULL; + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpstream); + PROBE_WRITE(lplpobj); + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleLoadFromStream\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + if (!(bEdit = !lstrcmpi (lpprotocol, PROTOCOL_EDIT))) + if (!(bStatic = !lstrcmpi (lpprotocol, PROTOCOL_STATIC))) + return OLE_ERROR_PROTOCOL; + + if (GetBytes (lpstream, (LPSTR) &dwVerFromFile, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (GetBytes (lpstream, (LPSTR)&ctype, sizeof(LONG))) + return OLE_ERROR_STREAM; + + if (ctype == CT_NULL) + return (bStatic ? OLE_OK: OLE_ERROR_PROTOCOL); + + if (((ctype != CT_PICTURE) && (ctype != CT_STATIC) && bStatic) || + ((ctype != CT_LINK) && (ctype != CT_OLDLINK) + && (ctype != CT_EMBEDDED) && bEdit)) + return OLE_ERROR_PROTOCOL; + + if ((ctype == CT_STATIC) && ((HIWORD(dwVerFromFile)) != OS_WIN16)) + return OLE_ERROR_STATIC_FROM_OTHER_OS; + + //** Get Class + if (GetBytes(lpstream, (LPSTR)&len, sizeof(len))) + return OLE_ERROR_STREAM; + + if (len == 0) + return OLE_ERROR_STREAM; + + if (GetBytes(lpstream, (LPSTR)&class, len)) + return OLE_ERROR_STREAM; + + aClass = GlobalAddAtom (class); + + if ((ctype == CT_PICTURE) || (ctype == CT_STATIC)) + retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, ctype, aClass, NULL); + + //!!! It's the DLL's responsibility to delete the atom. But in case of + // failure we delete the atom if our DefLoadFromStream(). + + else if ((iTable = LoadDll (class)) == INVALID_INDEX) { + retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, ctype, aClass, NULL); + } + else { + objCount = lpDllTable[iTable].cObj; + retVal = (*lpDllTable[iTable].Load) (lpstream, lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, ctype, aClass, NULL); + if (retVal > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpobj)->iTable = iTable; + } + + return retVal; +} + + + +OLESTATUS FAR PASCAL OleClone (lpobjsrc, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOLEOBJECT lpobjsrc; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + OLESTATUS retVal; + + Puts("OleClone"); + + if (!CheckObject(lpobjsrc)) + return OLE_ERROR_OBJECT; + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpclient); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleClone\n"); +#endif + + PROBE_READ(lpobjname); + + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + PROBE_WRITE(lplpobj); + + *lplpobj = NULL; + + retVal = (*lpobjsrc->lpvtbl->Clone) (lpobjsrc, lpclient, + lhclientdoc, lpobjname, lplpobj); + + if ((lpobjsrc->iTable != INVALID_INDEX) && (retVal <= OLE_WAIT_FOR_RELEASE)) + lpDllTable[lpobjsrc->iTable].cObj++; + + return retVal; +} + + +OLESTATUS FAR PASCAL OleCopyFromLink (lpobjsrc, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOLEOBJECT lpobjsrc; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + OLESTATUS retVal; + + Puts("OleCopyFromLnk"); + + if (!CheckObject(lpobjsrc)) + return(OLE_ERROR_OBJECT); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_WRITE(lplpobj); + PROBE_READ(lpclient); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCopyFromLink\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + *lplpobj = NULL; + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + retVal = (*lpobjsrc->lpvtbl->CopyFromLink) (lpobjsrc, lpclient, + lhclientdoc, lpobjname, lplpobj); + + if ((lpobjsrc->iTable != INVALID_INDEX) && (retVal <= OLE_WAIT_FOR_RELEASE)) + lpDllTable[lpobjsrc->iTable].cObj++; + + + return retVal; + +} + + + +OLESTATUS FAR PASCAL OleEqual (lpobj1, lpobj2) +LPOLEOBJECT lpobj1; +LPOLEOBJECT lpobj2; +{ + if (!CheckObject(lpobj1)) + return OLE_ERROR_OBJECT; + + if (!CheckObject(lpobj2)) + return OLE_ERROR_OBJECT; + + if (lpobj1->ctype != lpobj2->ctype) + return OLE_ERROR_NOT_EQUAL; + + return ((*lpobj1->lpvtbl->Equal) (lpobj1, lpobj2)); +} + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleQueryLinkFromClip (lpprotcol, optRender, cfFormat) +* +* oleQueryFromClip: Returns OLE_OK if a linked object can be created. +* +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + + +OLESTATUS FAR PASCAL OleQueryLinkFromClip (lpprotocol, optRender, cfFormat) +LPSTR lpprotocol; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + Puts("OleQueryLinkFromClip"); + return LeQueryCreateFromClip (lpprotocol, optRender, cfFormat, CT_LINK); +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleQueryCreateFromClip (lpprotcol, optRender, cfFormat) +* +* oleQueryCreateFromClip: Returns true if a non-linked object can be +* created. +* +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + + +OLESTATUS FAR PASCAL OleQueryCreateFromClip (lpprotocol, optRender, cfFormat) +LPSTR lpprotocol; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + Puts("OleQueryCreateFromClip"); + return (LeQueryCreateFromClip (lpprotocol, optRender, + cfFormat, CT_EMBEDDED)); +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleCreateLinkFromClip (lpprotcol, lpclient, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +* +* +* oleCreateLinkFromClip: This function creates the LP to an object from the +* clipboard. It will try to create a linked object. Return value is OLE_OK +* is the object is successfully created it +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleCreateLinkFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + int objCount; + int iTable = INVALID_INDEX; + OLESTATUS retVal; + LPSTR lpInfo; + + Puts("OleCreateLinkFromClip"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_WRITE(lplpobj); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreateLinkFromClip\n"); +#endif + + PROBE_READ(lpobjname); + + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + *lplpobj = NULL; + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + if (IsClipboardFormatAvailable (cfFileName)) + return CreatePackageFromClip (lpclient, lhclientdoc, lpobjname, + lplpobj, optRender, cfFormat, CT_LINK); + + if (!(hInfo = GetClipboardData (cfObjectLink))) + return OLE_ERROR_CLIPBOARD; + + if (!(lpInfo = GlobalLock(hInfo))) + return OLE_ERROR_CLIPBOARD; + + iTable = LoadDll (lpInfo); + GlobalUnlock (hInfo); + + + if (iTable == INVALID_INDEX) + retVal = DefCreateLinkFromClip (lpprotocol, lpclient, lhclientdoc, + lpobjname, lplpobj, optRender, cfFormat); + else { + objCount = lpDllTable[iTable].cObj; + retVal = (*lpDllTable[iTable].Link) (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, optRender, cfFormat); + if (retVal > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpobj)->iTable = iTable; + } + + hInfo = NULL; + return retVal; +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleCreateFromClip (lpprotcol, lpclient, lplpoleobject, optRender, cfFormat) +* +* +* oleCreateFromClip: This function creates the LP to an object +* from the clipboard. It will try to create an embedded object if +* OwnerLink and Native are available, otherwise it will create a static +* picture. Return value is OLE_OK if the object is successfully +* created it. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleCreateFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + LONG ctype; + int iTable = INVALID_INDEX; + LPSTR lpInfo; + LPSTR lpClass = NULL; + int objCount; + OLECLIPFORMAT cfEnum = NULL; + + Puts("OleCreateFromClip"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_WRITE(lplpobj); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreateFromClip\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + *lplpobj = NULL; + + if (!lstrcmpi (lpprotocol, PROTOCOL_STATIC)) { + if (optRender == olerender_none) + return OLE_ERROR_OPTION; + + if ((optRender == olerender_format) && (cfFormat != CF_METAFILEPICT) + && (cfFormat != CF_DIB) && (cfFormat != CF_BITMAP)) + return OLE_ERROR_FORMAT; + + if (!IsClipboardFormatAvailable (CF_METAFILEPICT) + && !IsClipboardFormatAvailable (CF_DIB) + && !IsClipboardFormatAvailable (CF_BITMAP)) + return OLE_ERROR_FORMAT; + + return CreatePictFromClip (lpclient, lhclientdoc, + lpobjname, lplpobj, optRender, + cfFormat, NULL, CT_STATIC); + } + else if (!lstrcmpi (lpprotocol, PROTOCOL_EDIT)) { + if (IsClipboardFormatAvailable (cfFileName)) + return CreatePackageFromClip (lpclient, lhclientdoc, lpobjname, + lplpobj, optRender, cfFormat, CT_EMBEDDED); + + if (!(hInfo = GetClipboardData (cfOwnerLink))) + return OLE_ERROR_CLIPBOARD; + + while (TRUE) { + cfEnum = EnumClipboardFormats (cfEnum); + if (cfEnum == cfNative) { + ctype = CT_EMBEDDED; + break; + } + else if (cfEnum == cfOwnerLink) { + ctype = CT_LINK; + break; + } + } + + if (!(lpInfo = GlobalLock(hInfo))) + return OLE_ERROR_CLIPBOARD; + + iTable = LoadDll (lpInfo); + GlobalUnlock (hInfo); + } + else { + return OLE_ERROR_PROTOCOL; + } + + if (iTable == INVALID_INDEX) + retVal = DefCreateFromClip (lpprotocol, lpclient, lhclientdoc, + lpobjname, lplpobj, optRender, cfFormat, ctype); + else { + objCount = lpDllTable[iTable].cObj; + retVal = (*lpDllTable[iTable].Clip) (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat, ctype); + + if (retVal > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpobj)->iTable = iTable; + } + + hInfo = NULL; + return retVal; +} + + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleCopyToClipboard (lpobj) +* +* +* oleCopyToClipboard: This routine executes the standard "Copy" menu item +* on the typical "Edit" menu. Returns TRUE if successful. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleCopyToClipboard (lpobj) +LPOLEOBJECT lpobj; +{ + Puts("OleCopyToClipboard"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return ((*lpobj->lpvtbl->CopyToClipboard) (lpobj)); +} + + +OLESTATUS FAR PASCAL OleSetHostNames (lpobj, lpclientName, lpdocName) +LPOLEOBJECT lpobj; +LPSTR lpclientName; +LPSTR lpdocName; +{ + Puts ("OleSetHostNames"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + PROBE_READ(lpclientName); + PROBE_READ(lpdocName); + + return ((*lpobj->lpvtbl->SetHostNames) (lpobj, lpclientName, lpdocName)); +} + + + +OLESTATUS FAR PASCAL OleSetTargetDevice (lpobj, hDevInfo) +LPOLEOBJECT lpobj; +HANDLE hDevInfo; +{ + Puts("OleSetTargetDevice"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return ((*lpobj->lpvtbl->SetTargetDevice) (lpobj, hDevInfo)); +} + + + +OLESTATUS FAR PASCAL OleSetColorScheme (lpobj, lplogpal) +LPOLEOBJECT lpobj; +LPLOGPALETTE lplogpal; +{ + Puts("OleSetColorScheme"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return ((*lpobj->lpvtbl->SetColorScheme) (lpobj, lplogpal)); +} + + + +OLESTATUS FAR PASCAL OleSetBounds(lpobj, lprc) +LPOLEOBJECT lpobj; +LPRECT lprc; +{ + Puts("OleSetBounds"); + + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + PROBE_READ(lprc); + + return ((*lpobj->lpvtbl->SetBounds) (lpobj, lprc)); + +} + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleQueryBounds (lpobj, lpRc) +* +* Returns the bounds of the object in question in MM_HIMETRIC mode. +* width = lprc->right - lprc->left; in HIMETRIC units +* height = lprc->top - lprc->bottom; in HIMETRIC units +* +* Returns OLE_OK or OLE_ERROR_MEMORY. +* +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleQueryBounds (lpobj, lprc) +LPOLEOBJECT lpobj; +LPRECT lprc; +{ + + Puts("OleQueryBounds"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + PROBE_WRITE(lprc); + + return (*lpobj->lpvtbl->QueryBounds) (lpobj, lprc); +} + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleQuerySize (lpobj, lpsize) +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleQuerySize (lpobj, lpdwSize) +LPOLEOBJECT lpobj; +DWORD FAR * lpdwSize; +{ + Puts("OleQuerySize"); + + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + PROBE_WRITE(lpdwSize); + + *lpdwSize = NULL; + return (*lpobj->lpvtbl->QuerySize) (lpobj, lpdwSize); +} + + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleDraw (lpobj, hdc, lprc, lpWrc, lphdcTarget) +* +* oleObjectDraw: This displays the given object on the device context <hcd>. +* The <htargetdc> parameter is not currently used. Returns same as Draw(). +* +* Expects rectangle coordinates in MM_HIMETRIC units. +* +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOLEOBJECT lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + + Puts("OleObjectDraw"); + + if (!FarCheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + PROBE_READ(lprc); + if (lpWrc) + PROBE_READ(lpWrc); + + return ((*lpobj->lpvtbl->Draw) (lpobj, hdc, lprc, lpWrc, hdcTarget)); +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleQueryOpen (lpobj) +* +* returns TRUE is an object has been activated. +* +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleQueryOpen (lpobj) +LPOLEOBJECT lpobj; +{ + Puts("OleQueryOpen"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->QueryOpen) (lpobj); +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleActivate (lpobj) +* +* Activates an object. For embeded objects always a new instance is +* loaded and the instance is destroyed once the data is transferred +* at close time. For linked objects, an instance of the render is created +* only if one does not exist. +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleActivate (lpobj, verb, fShow, fActivate, hWnd, lprc) +LPOLEOBJECT lpobj; +WORD verb; +BOOL fShow; +BOOL fActivate; +HWND hWnd; +LPRECT lprc; +{ + + Puts("OleActivate"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + /* PROBE_READ(lprc); */ + + return (*lpobj->lpvtbl->Activate) (lpobj, verb, fShow, fActivate, hWnd, lprc); +} + + + + +OLESTATUS FAR PASCAL OleClose (lpobj) +LPOLEOBJECT lpobj; +{ + + Puts("OleClose"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->Close) (lpobj); +} + + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleUpdate (lpobj) +* +* If there exists a link, sends advise for getting the latest rendering +* infromation. If there is no link, loads an instance, advises for the +* render information and closes the instance once the data is available. +* (If possible should not show the window). +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleUpdate (lpobj) +LPOLEOBJECT lpobj; +{ + + Puts("OleUpdate"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->Update) (lpobj); + +} + + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleReconnect (lpobj) +* +* Reconnects to the renderer if one does not exist already. +* +* History: +* Wrote it. +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleReconnect (lpobj) +LPOLEOBJECT lpobj; +{ + Puts("OleReconnect"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->Reconnect) (lpobj); +} + + +OLESTATUS FAR PASCAL OleGetLinkUpdateOptions (lpobj, lpOptions) +LPOLEOBJECT lpobj; +OLEOPT_UPDATE FAR * lpOptions; +{ + Puts("OleGetLinkUpdateOptions"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + PROBE_WRITE(lpOptions); + + return (*lpobj->lpvtbl->GetLinkUpdateOptions) (lpobj, lpOptions); +} + + + +OLESTATUS FAR PASCAL OleSetLinkUpdateOptions (lpobj, options) +LPOLEOBJECT lpobj; +OLEOPT_UPDATE options; +{ + Puts("OleSetLinkUpdateOptions"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->SetLinkUpdateOptions) (lpobj, options); + +} + + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleEnumFormats (lpobj, cfFormat) +* +* Returns OLE_YES if the object is of type LINK or EMBEDDED. +* +* Effects: +* +* History: +* Wrote it. +\***************************************************************************/ + +OLECLIPFORMAT FAR PASCAL OleEnumFormats (lpobj, cfFormat) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +{ + Puts("OleEnumFormats"); + + if (!CheckObject(lpobj)) + return NULL; + + return (*lpobj->lpvtbl->EnumFormats) (lpobj, cfFormat); +} + +OLESTATUS FAR PASCAL OleRequestData (lpobj, cfFormat) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +{ + Puts("OleGetData"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + if (!cfFormat) + return OLE_ERROR_FORMAT; + + return (*lpobj->lpvtbl->RequestData) (lpobj, cfFormat); +} + + +OLESTATUS FAR PASCAL OleGetData (lpobj, cfFormat, lphandle) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +LPHANDLE lphandle; +{ + Puts("OleGetData"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + PROBE_WRITE(lphandle); + + return (*lpobj->lpvtbl->GetData) (lpobj, cfFormat, lphandle); +} + + +OLESTATUS FAR PASCAL OleSetData (lpobj, cfFormat, hData) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +HANDLE hData; +{ + Puts("OleSetData"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->SetData) (lpobj, cfFormat, hData); +} + + + +OLESTATUS FAR PASCAL OleQueryOutOfDate (lpobj) +LPOLEOBJECT lpobj; +{ + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->QueryOutOfDate) (lpobj); +} + + +OLESTATUS FAR PASCAL OleLockServer (lpobjsrc, lplhsrvr) +LPOLEOBJECT lpobjsrc; +LHSERVER FAR * lplhsrvr; +{ + LPOBJECT_LE lpobj; + OLESTATUS retVal = OLE_OK; + ATOM aCliClass, aSvrClass; + + Puts ("OleLockServer"); + + if (!FarCheckObject(lpobjsrc)) + return OLE_ERROR_OBJECT; + + if (lpobjsrc->ctype == CT_STATIC) + return OLE_ERROR_STATIC; + + // Assumes all the creates are in order + PROBE_CREATE_ASYNC(((LPOBJECT_LE)lpobjsrc)); + FARPROBE_WRITE(lplhsrvr); + + aCliClass = ((LPCLIENTDOC)(lpobjsrc->lhclientdoc))->aClass; + aSvrClass = ((LPOBJECT_LE)lpobjsrc)->app; + + // See whether the server is already locked + lpobj = (LPOBJECT_LE) (lockDoc.lpHeadObj); + while (lpobj) { + if ((lpobj->app == aSvrClass) && (lpobj->topic == aCliClass)) { + if (!lpobj->head.cx) { + // The unlocking process of server handle has started. This + // is an asynchronous process. We want to let it complete. + // Let's try the next handle + + ; + } + else { + if (!IsServerValid (lpobj)) { + DeleteSrvrEdit (lpobj); + retVal = LockServer (lpobj); + } + else { + // Lock count + lpobj->head.cx++; + } + + if (retVal == OLE_OK) + *lplhsrvr = (LHSERVER) lpobj; + + return retVal; + } + } + + lpobj = (LPOBJECT_LE) (lpobj->head.lpNextObj); + } + + + if (!(lpobj = LeCreateBlank(lhLockDoc, NULL, OT_EMBEDDED))) + return OLE_ERROR_MEMORY; + + lpobj->head.lpclient = NULL; + lpobj->head.lpvtbl = lpobjsrc->lpvtbl; + lpobj->app = DuplicateAtom (aSvrClass); + lpobj->topic = DuplicateAtom (aCliClass); + lpobj->aServer = DuplicateAtom(((LPOBJECT_LE)lpobjsrc)->aServer); + lpobj->bOleServer = ((LPOBJECT_LE)lpobjsrc)->bOleServer; + + if ((retVal = LockServer (lpobj)) == OLE_OK) { + // Change signature + lpobj->head.objId[0] = 'S'; + lpobj->head.objId[1] = 'L'; + *lplhsrvr = (LHSERVER) lpobj; + } + else { + LeRelease (lpobj); + } + + return retVal; +} + + +OLESTATUS INTERNAL LockServer (lpobj) +LPOBJECT_LE lpobj; +{ + HANDLE hInst; + + if (!InitSrvrConv (lpobj, NULL)) { + if (!lpobj->bOleServer) + lpobj->fCmd = ACT_MINIMIZE; + else + lpobj->fCmd = NULL; + + if (!(hInst = LeLaunchApp (lpobj))) + return OLE_ERROR_LAUNCH; + + if (!InitSrvrConv (lpobj, hInst)) + return OLE_ERROR_COMM; + + } + + // lock count + lpobj->head.cx++; + return OLE_OK; +} + + +OLESTATUS FAR PASCAL OleUnlockServer (lhsrvr) +LHSERVER lhsrvr; +{ + LPOBJECT_LE lpobj; + OLESTATUS retval; + + Puts ("OleUnlockServer"); + + if (!FarCheckPointer ((lpobj = (LPOBJECT_LE)lhsrvr), WRITE_ACCESS)) + return OLE_ERROR_HANDLE; + + if (lpobj->head.objId[0] != 'S' || lpobj->head.objId[1] != 'L') + return OLE_ERROR_HANDLE; + + if (!lpobj->head.cx) + return OLE_OK; + + if (--lpobj->head.cx) + return OLE_OK; + + //change signature + lpobj->head.objId[0] = 'L'; + lpobj->head.objId[1] = 'E'; + + if ((retval = LeRelease (lpobj)) == OLE_WAIT_FOR_RELEASE) + DocDeleteObject ((LPOLEOBJECT)lpobj); + + return retval; +} + + +OLESTATUS FAR PASCAL OleObjectConvert (lpobj, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj) +LPOLEOBJECT lpobj; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +{ + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_WRITE(lplpobj); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleObjectConvert\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + + return (*lpobj->lpvtbl->ObjectConvert) (lpobj, lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj); +} + + +//OleCreateFromTemplate: Creates an embedded object from Template + +OLESTATUS FAR PASCAL OleCreateFromTemplate (lpprotocol, lpclient, lptemplate, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat ) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lptemplate; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + char buf[MAX_STR]; + int objCount; + int iTable = INVALID_INDEX; + + Puts("OleCreateFromTemplate"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_READ(lptemplate); + PROBE_WRITE(lplpoleobject); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreateFromTemplate\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + if (!MapExtToClass (lptemplate, (LPSTR)buf, MAX_STR)) + return OLE_ERROR_CLASS; + + + // !!! we found the class name. At this point, we need to load + // the right library and call the right entry point; + + iTable = LoadDll ((LPSTR)buf); + if (iTable == INVALID_INDEX) + retval = DefCreateFromTemplate (lpprotocol, lpclient, lptemplate, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + else { + objCount = lpDllTable[iTable].cObj; + retval = (*lpDllTable[iTable].CreateFromTemplate) (lpprotocol, + lpclient, lptemplate, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + if (retval > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpoleobject)->iTable = iTable; + } + + return retval; +} + + +//OleCreate: Creates an embedded object from the class. + +OLESTATUS FAR PASCAL OleCreate (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + int objCount; + int iTable = INVALID_INDEX; + + + Puts("OleCreate"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_READ(lpclass); + PROBE_WRITE(lplpoleobject); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreate\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + iTable = LoadDll (lpclass); + if (iTable == INVALID_INDEX) + retval = DefCreate (lpprotocol, lpclient, lpclass, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + else { + objCount = lpDllTable[iTable].cObj; + retval = (*lpDllTable[iTable].Create) (lpprotocol, + lpclient, lpclass, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + if (retval > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpoleobject)->iTable = iTable; + } + + return retval; +} + + + +////////////////////////////////////////////////////////////////////////////// +// +// OLESTATUS FAR PASCAL OleCreateInvisible (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, bLaunchServer) +// +// Creates an embedded object from the class. +// +// Arguments: +// +// lpprotocol - +// lpclient - +// lpclass - +// lhclientdoc - +// lpobjname - +// lplpoleobject - +// optRender - +// cfFormat - +// bLaunchServer - +// +// Returns: +// +// OLE_ERROR_HANDLE - +// OLE_ERROR_NAME - +// OLE_ERROR_PROTOCOL - +// +// Effects: +// +////////////////////////////////////////////////////////////////////////////// + +OLESTATUS FAR PASCAL OleCreateInvisible (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat, bLaunchServer) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +BOOL bLaunchServer; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + int objCount; + int iTable = INVALID_INDEX; + + + Puts("OleCreateInvisible"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_READ(lpclass); + PROBE_WRITE(lplpoleobject); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreate\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + iTable = LoadDll (lpclass); + if (iTable == INVALID_INDEX) { + retval = DefCreateInvisible (lpprotocol, lpclient, lpclass, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat, bLaunchServer); + } + else { + objCount = lpDllTable[iTable].cObj; + + if (!(lpDllTable[iTable].CreateInvisible)) { + // dll didn't export this function. Lets call DllCreate, so that + // handler will get a chance to replace the methods. The flag is + // used to tell the internal functions that this call infact wants + // to achieve the effect of CreateInvisble. + gbCreateInvisible = TRUE; + gbLaunchServer = bLaunchServer; + retval = (*lpDllTable[iTable].Create) (lpprotocol, + lpclient, lpclass, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + gbCreateInvisible = FALSE; + } + else { + retval = (*lpDllTable[iTable].CreateInvisible) (lpprotocol, + lpclient, lpclass, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat, bLaunchServer); + } + + if (retval > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpoleobject)->iTable = iTable; + } + + return retval; +} + + +//OleCreateFromFile: Creates an embedded object from file + +OLESTATUS FAR PASCAL OleCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat ) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + char buf[MAX_STR]; + int objCount; + int iTable = INVALID_INDEX; + + Puts("OleCreateFromFile"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_READ(lpfile); + PROBE_WRITE(lplpoleobject); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreateFromFile\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + if (lpclass) + PROBE_READ(lpclass); + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + if (lpclass) { + if (!QueryApp (lpclass, lpprotocol, buf)) + return OLE_ERROR_CLASS; + + if (!lstrcmp (lpclass, packageClass)) + iTable = INVALID_INDEX; + else + iTable = LoadDll (lpclass); + } + else if (MapExtToClass (lpfile, (LPSTR)buf, MAX_STR)) + iTable = LoadDll (buf); + else + return OLE_ERROR_CLASS; + + if (iTable == INVALID_INDEX) + retval = DefCreateFromFile (lpprotocol, + lpclient, lpclass, lpfile, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + else { + objCount = lpDllTable[iTable].cObj; + retval = (*lpDllTable[iTable].CreateFromFile) (lpprotocol, + lpclient, lpclass, lpfile, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + if (retval > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpoleobject)->iTable = iTable; + } + + return retval; +} + + +//OleCreateLinkFromFile: Creates a linked object from file + +OLESTATUS FAR PASCAL OleCreateLinkFromFile (lpprotocol, lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpoleobject, optRender, cfFormat ) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LPSTR lpitem; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpoleobject; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retval = OLE_ERROR_MEMORY; + char buf[MAX_STR+6]; + int objCount; + int iTable = INVALID_INDEX; + + Puts("OleCreateLinkFromFile"); + + PROBE_MODE(bProtMode); + + if (!CheckClientDoc ((LPCLIENTDOC) lhclientdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpprotocol); + PROBE_READ(lpclient); + PROBE_READ(lpfile); + PROBE_WRITE(lplpoleobject); + +#ifdef FIREWALLS + ASSERT (lpobjname, "NULL lpobjname passed to OleCreateLinkFromFile\n"); +#endif + + PROBE_READ(lpobjname); + if (!lpobjname[0]) + return OLE_ERROR_NAME; + if (lpclass) + PROBE_READ(lpclass); + if (lpitem) + PROBE_READ(lpitem); + + if (lstrcmpi (lpprotocol, PROTOCOL_EDIT)) + return OLE_ERROR_PROTOCOL; + + if (lpclass) { + if (!QueryApp (lpclass, lpprotocol, buf)) + return OLE_ERROR_CLASS; + + if (!lstrcmp (lpclass, packageClass)) { + lstrcpy (buf, lpfile); + lstrcat (buf, "/Link"); + return CreateEmbLnkFromFile (lpclient, packageClass, buf, + NULL, lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat, OT_EMBEDDED); + } + else + iTable = LoadDll (lpclass); + } + else if (MapExtToClass (lpfile, (LPSTR)buf, MAX_STR)) + iTable = LoadDll (buf); + else + return OLE_ERROR_CLASS; + + if (iTable == INVALID_INDEX) + retval = DefCreateLinkFromFile (lpprotocol, + lpclient, lpclass, lpfile, lpitem, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + + else { + objCount = lpDllTable[iTable].cObj; + retval = (*lpDllTable[iTable].CreateLinkFromFile) (lpprotocol, + lpclient, lpclass, lpfile, lpitem, + lhclientdoc, lpobjname, lplpoleobject, + optRender, cfFormat); + if (retval > OLE_WAIT_FOR_RELEASE) + lpDllTable[iTable].cObj = objCount - 1; + else + (*lplpoleobject)->iTable = iTable; + } + + return retval; +} + + + +// Routines related to asynchronous operations. +OLESTATUS FAR PASCAL OleQueryReleaseStatus (lpobj) +LPOLEOBJECT lpobj; +{ + if (!CheckPointer (lpobj, WRITE_ACCESS)) + return OLE_ERROR_OBJECT; + + // make sure that it is a long pointer to L&E object or a lock handle + if (!(lpobj->objId[0] == 'L' && lpobj->objId[1] == 'E') + && !(lpobj->objId[0] == 'S' && lpobj->objId[1] == 'L')) + return OLE_ERROR_OBJECT; + + return (*lpobj->lpvtbl->QueryReleaseStatus) (lpobj); +} + + +OLESTATUS FAR PASCAL OleQueryReleaseError (lpobj) +LPOLEOBJECT lpobj; +{ + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->QueryReleaseError) (lpobj); +} + +OLE_RELEASE_METHOD FAR PASCAL OleQueryReleaseMethod (lpobj) +LPOLEOBJECT lpobj; +{ + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + return (*lpobj->lpvtbl->QueryReleaseMethod) (lpobj); +} + + +OLESTATUS FAR PASCAL OleRename (lpobj, lpNewName) +LPOLEOBJECT lpobj; +LPSTR lpNewName; +{ + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + return (*lpobj->lpvtbl->Rename) (lpobj, lpNewName); +} + + +OLESTATUS FAR PASCAL OleExecute (lpobj, hCmds, wReserved) +LPOLEOBJECT lpobj; +HANDLE hCmds; +WORD wReserved; +{ + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + return (*lpobj->lpvtbl->Execute) (lpobj, hCmds, wReserved); +} + + +OLESTATUS FAR PASCAL OleQueryName (lpobj, lpBuf, lpcbBuf) +LPOLEOBJECT lpobj; +LPSTR lpBuf; +WORD FAR * lpcbBuf; +{ + if (!CheckObject(lpobj)) + return OLE_ERROR_OBJECT; + + return (*lpobj->lpvtbl->QueryName) (lpobj, lpBuf, lpcbBuf); +} + +OLESTATUS FAR PASCAL OleQueryType (lpobj, lptype) +LPOLEOBJECT lpobj; +LPLONG lptype; +{ + Puts("OleQueryType"); + + if (!CheckObject(lpobj)) + return(OLE_ERROR_OBJECT); + + PROBE_WRITE(lptype); + + return (*lpobj->lpvtbl->QueryType) (lpobj, lptype); +} + + + +DWORD FAR PASCAL OleQueryClientVersion () +{ + return dwOleVer; +} + + +OLESTATUS INTERNAL LeQueryCreateFromClip (lpprotocol, optRender, cfFormat, cType) +LPSTR lpprotocol; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LONG cType; +{ + OLESTATUS retVal = TRUE; + BOOL bEdit = FALSE, bStatic = FALSE; + + PROBE_MODE(bProtMode); + PROBE_READ(lpprotocol); + + if (bEdit = !lstrcmpi (lpprotocol, PROTOCOL_EDIT)) { + if (IsClipboardFormatAvailable (cfFileName)) + return OLE_OK; + + if (cType == CT_LINK) + retVal = IsClipboardFormatAvailable (cfObjectLink); +#ifdef OLD + || IsClipboardFormatAvailable (cfLink) ; +#endif + else if (cType == CT_EMBEDDED) + retVal = IsClipboardFormatAvailable (cfOwnerLink); + + if (!retVal) + return OLE_ERROR_FORMAT; + + if (optRender == olerender_none) + return OLE_OK; + } + else if (bStatic = !lstrcmpi (lpprotocol, PROTOCOL_STATIC)) { + if (cType == CT_LINK) + return OLE_ERROR_PROTOCOL; + + if (optRender == olerender_none) + return OLE_ERROR_FORMAT; + } + else { + return OLE_ERROR_PROTOCOL; + } + + if (optRender == olerender_draw) { + if (!IsClipboardFormatAvailable (CF_METAFILEPICT) && + !IsClipboardFormatAvailable (CF_DIB) && + !IsClipboardFormatAvailable (CF_BITMAP) && + !(bEdit && QueryHandler((cType == CT_LINK) ? cfObjectLink : cfOwnerLink))) + return OLE_ERROR_FORMAT; + } + else if (optRender == olerender_format) { + if (!IsClipboardFormatAvailable (cfFormat)) + return OLE_ERROR_FORMAT; + + if (bStatic && (cfFormat != CF_METAFILEPICT) + && (cfFormat != CF_DIB) && (cfFormat != CF_BITMAP)) + return OLE_ERROR_FORMAT; + + } + else { + return OLE_ERROR_FORMAT; + } + + return OLE_OK; +} + + + +BOOL INTERNAL CheckObject(lpobj) +LPOLEOBJECT lpobj; +{ + if (!CheckPointer(lpobj, WRITE_ACCESS)) + return FALSE; + + if (lpobj->objId[0] == 'L' && lpobj->objId[1] == 'E') + return TRUE; + + return FALSE; +} + +BOOL FARINTERNAL FarCheckObject(lpobj) +LPOLEOBJECT lpobj; +{ + return (CheckObject (lpobj)); +} + diff --git a/private/mvdm/wow16/ole/client/ole.h b/private/mvdm/wow16/ole/client/ole.h new file mode 100644 index 000000000..37bcf9cad --- /dev/null +++ b/private/mvdm/wow16/ole/client/ole.h @@ -0,0 +1,504 @@ +/*****************************************************************************\ +* * +* ole.h - Object Linking and Embedding functions, types, and definitions* +* * +* Version 1.0 * +* * +* NOTE: windows.h must be #included first * +* * +* Copyright (c) 1990-1992, Microsoft Corp. All rights reserved.* +* * +\*****************************************************************************/ + +#ifndef _INC_OLE +#define _INC_OLE + +#ifndef RC_INVOKED +#pragma pack(1) /* Assume byte packing throughout */ +#endif /* !RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +#ifndef WINAPI /* If not included with 3.1 headers... */ +#define WINAPI FAR PASCAL +#define CALLBACK FAR PASCAL +#define LPCSTR LPSTR +#define UINT WORD +#define LPARAM LONG +#define WPARAM WORD +#define LRESULT LONG +#define HMODULE HANDLE +#define HINSTANCE HANDLE +#define HLOCAL HANDLE +#define HGLOBAL HANDLE +#endif /* _INC_WINDOWS */ + +#ifdef STRICT +#define OLE_LPCSTR LPCSTR +#define OLE_CONST const +#else /* STRICT */ +#define OLE_LPCSTR LPSTR +#define OLE_CONST +#endif /* !STRICT */ + + +/* Object types */ +#define OT_LINK 1L +#define OT_EMBEDDED 2L +#define OT_STATIC 3L + +/* activate verbs */ +#define OLEVERB_PRIMARY 0 + +/* target device info structure */ +typedef struct _OLETARGETDEVICE +{ + UINT otdDeviceNameOffset; + UINT otdDriverNameOffset; + UINT otdPortNameOffset; + UINT otdExtDevmodeOffset; + UINT otdExtDevmodeSize; + UINT otdEnvironmentOffset; + UINT otdEnvironmentSize; + BYTE otdData[1]; +} OLETARGETDEVICE; +typedef OLETARGETDEVICE FAR* LPOLETARGETDEVICE; + +/* flags used in some methods */ +#define OF_SET 0x0001 +#define OF_GET 0x0002 +#define OF_HANDLER 0x0004 + +/* return codes for OLE functions */ +typedef enum +{ + OLE_OK, /* 0 Function operated correctly */ + + OLE_WAIT_FOR_RELEASE, /* 1 Command has been initiated, client */ + /* must wait for release. keep dispatching */ + /* messages till OLE_RELESE in callback */ + + OLE_BUSY, /* 2 Tried to execute a method while another */ + /* method is in progress. */ + + OLE_ERROR_PROTECT_ONLY, /* 3 Ole APIs are called in real mode */ + OLE_ERROR_MEMORY, /* 4 Could not alloc or lock memory */ + OLE_ERROR_STREAM, /* 5 (OLESTREAM) stream error */ + OLE_ERROR_STATIC, /* 6 Non static object expected */ + OLE_ERROR_BLANK, /* 7 Critical data missing */ + OLE_ERROR_DRAW, /* 8 Error while drawing */ + OLE_ERROR_METAFILE, /* 9 Invalid metafile */ + OLE_ERROR_ABORT, /* 10 Client chose to abort metafile drawing */ + OLE_ERROR_CLIPBOARD, /* 11 Failed to get/set clipboard data */ + OLE_ERROR_FORMAT, /* 12 Requested format is not available */ + OLE_ERROR_OBJECT, /* 13 Not a valid object */ + OLE_ERROR_OPTION, /* 14 Invalid option(link update / render) */ + OLE_ERROR_PROTOCOL, /* 15 Invalid protocol */ + OLE_ERROR_ADDRESS, /* 16 One of the pointers is invalid */ + OLE_ERROR_NOT_EQUAL, /* 17 Objects are not equal */ + OLE_ERROR_HANDLE, /* 18 Invalid handle encountered */ + OLE_ERROR_GENERIC, /* 19 Some general error */ + OLE_ERROR_CLASS, /* 20 Invalid class */ + OLE_ERROR_SYNTAX, /* 21 Command syntax is invalid */ + OLE_ERROR_DATATYPE, /* 22 Data format is not supported */ + OLE_ERROR_PALETTE, /* 23 Invalid color palette */ + OLE_ERROR_NOT_LINK, /* 24 Not a linked object */ + OLE_ERROR_NOT_EMPTY, /* 25 Client doc contains objects. */ + OLE_ERROR_SIZE, /* 26 Incorrect buffer size passed to the api */ + /* that places some string in caller's */ + /* buffer */ + + OLE_ERROR_DRIVE, /* 27 Drive letter in doc name is invalid */ + OLE_ERROR_NETWORK, /* 28 Failed to establish connection to a */ + /* network share on which the document */ + /* is located */ + + OLE_ERROR_NAME, /* 29 Invalid name(doc name, object name), */ + /* etc.. passed to the APIs */ + + OLE_ERROR_TEMPLATE, /* 30 Server failed to load template */ + OLE_ERROR_NEW, /* 31 Server failed to create new doc */ + OLE_ERROR_EDIT, /* 32 Server failed to create embedded */ + /* instance */ + OLE_ERROR_OPEN, /* 33 Server failed to open document, */ + /* possible invalid link */ + + OLE_ERROR_NOT_OPEN, /* 34 Object is not open for editing */ + OLE_ERROR_LAUNCH, /* 35 Failed to launch server */ + OLE_ERROR_COMM, /* 36 Failed to communicate with server */ + OLE_ERROR_TERMINATE, /* 37 Error in termination */ + OLE_ERROR_COMMAND, /* 38 Error in execute */ + OLE_ERROR_SHOW, /* 39 Error in show */ + OLE_ERROR_DOVERB, /* 40 Error in sending do verb, or invalid */ + /* verb */ + OLE_ERROR_ADVISE_NATIVE, /* 41 Item could be missing */ + OLE_ERROR_ADVISE_PICT, /* 42 Item could be missing or server doesn't */ + /* this format. */ + + OLE_ERROR_ADVISE_RENAME, /* 43 Server doesn't support rename */ + OLE_ERROR_POKE_NATIVE, /* 44 Failure of poking native data to server */ + OLE_ERROR_REQUEST_NATIVE, /* 45 Server failed to render native data */ + OLE_ERROR_REQUEST_PICT, /* 46 Server failed to render presentation */ + /* data */ + OLE_ERROR_SERVER_BLOCKED, /* 47 Trying to block a blocked server or */ + /* trying to revoke a blocked server */ + /* or document */ + + OLE_ERROR_REGISTRATION, /* 48 Server is not registered in regestation */ + /* data base */ + OLE_ERROR_ALREADY_REGISTERED,/*49 Trying to register same doc multiple */ + /* times */ + OLE_ERROR_TASK, /* 50 Server or client task is invalid */ + OLE_ERROR_OUTOFDATE, /* 51 Object is out of date */ + OLE_ERROR_CANT_UPDATE_CLIENT,/* 52 Embed doc's client doesn't accept */ + /* updates */ + OLE_ERROR_UPDATE, /* 53 erorr while trying to update */ + OLE_ERROR_SETDATA_FORMAT, /* 54 Server app doesn't understand the */ + /* format given to its SetData method */ + OLE_ERROR_STATIC_FROM_OTHER_OS,/* 55 trying to load a static object created */ + /* on another Operating System */ + + /* Following are warnings */ + OLE_WARN_DELETE_DATA = 1000 /* Caller must delete the data when he is */ + /* done with it. */ +} OLESTATUS; + + + +/* Codes for CallBack events */ +typedef enum +{ + OLE_CHANGED, /* 0 */ + OLE_SAVED, /* 1 */ + OLE_CLOSED, /* 2 */ + OLE_RENAMED, /* 3 */ + OLE_QUERY_PAINT, /* 4 Interruptible paint support */ + OLE_RELEASE, /* 5 Object is released(asynchronous operation */ + /* is completed) */ + OLE_QUERY_RETRY /* 6 Query for retry when server sends busy ACK */ +} OLE_NOTIFICATION; + +typedef enum +{ + OLE_NONE, /* 0 no method active */ + OLE_DELETE, /* 1 object delete */ + OLE_LNKPASTE, /* 2 PasteLink(auto reconnect) */ + OLE_EMBPASTE, /* 3 paste(and update) */ + OLE_SHOW, /* 4 Show */ + OLE_RUN, /* 5 Run */ + OLE_ACTIVATE, /* 6 Activate */ + OLE_UPDATE, /* 7 Update */ + OLE_CLOSE, /* 8 Close */ + OLE_RECONNECT, /* 9 Reconnect */ + OLE_SETUPDATEOPTIONS, /* 10 setting update options */ + OLE_SERVERUNLAUNCH, /* 11 server is being unlaunched */ + OLE_LOADFROMSTREAM, /* 12 LoadFromStream(auto reconnect) */ + OLE_SETDATA, /* 13 OleSetData */ + OLE_REQUESTDATA, /* 14 OleRequestData */ + OLE_OTHER, /* 15 other misc async operations */ + OLE_CREATE, /* 16 create */ + OLE_CREATEFROMTEMPLATE, /* 17 CreatefromTemplate */ + OLE_CREATELINKFROMFILE, /* 18 CreateLinkFromFile */ + OLE_COPYFROMLNK, /* 19 CopyFromLink(auto reconnect) */ + OLE_CREATEFROMFILE, /* 20 CreateFromFile */ + OLE_CREATEINVISIBLE /* 21 CreateInvisible */ +} OLE_RELEASE_METHOD; + +/* rendering options */ +typedef enum +{ + olerender_none, + olerender_draw, + olerender_format +} OLEOPT_RENDER; + +/* standard clipboard format type */ +typedef WORD OLECLIPFORMAT; + +/* Link update options */ +typedef enum +{ + oleupdate_always, + oleupdate_onsave, +#ifndef OLE_INTERNAL + oleupdate_oncall +#else + oleupdate_oncall, + oleupdate_onclose +#endif /* OLE_INTERNAL */ +} OLEOPT_UPDATE; + +typedef HANDLE HOBJECT; +typedef LONG LHSERVER; +typedef LONG LHCLIENTDOC; +typedef LONG LHSERVERDOC; + +typedef struct _OLEOBJECT FAR* LPOLEOBJECT; +typedef struct _OLESTREAM FAR* LPOLESTREAM; +typedef struct _OLECLIENT FAR* LPOLECLIENT; + + +#ifndef OLE_INTERNAL +/* object method table definitions. */ +typedef struct _OLEOBJECTVTBL +{ + void FAR* (CALLBACK* QueryProtocol) (LPOLEOBJECT, OLE_LPCSTR); + OLESTATUS (CALLBACK* Release) (LPOLEOBJECT); + OLESTATUS (CALLBACK* Show) (LPOLEOBJECT, BOOL); + OLESTATUS (CALLBACK* DoVerb) (LPOLEOBJECT, UINT, BOOL, BOOL); + OLESTATUS (CALLBACK* GetData) (LPOLEOBJECT, OLECLIPFORMAT, HANDLE FAR*); + OLESTATUS (CALLBACK* SetData) (LPOLEOBJECT, OLECLIPFORMAT, HANDLE); + OLESTATUS (CALLBACK* SetTargetDevice) (LPOLEOBJECT, HGLOBAL); + OLESTATUS (CALLBACK* SetBounds) (LPOLEOBJECT, OLE_CONST RECT FAR*); + OLECLIPFORMAT (CALLBACK* EnumFormats) (LPOLEOBJECT, OLECLIPFORMAT); + OLESTATUS (CALLBACK* SetColorScheme) (LPOLEOBJECT, OLE_CONST LOGPALETTE FAR*); + /* Server has to implement only the above methods. */ + +#ifndef SERVERONLY + /* Extra methods required for client. */ + OLESTATUS (CALLBACK* Delete) (LPOLEOBJECT); + OLESTATUS (CALLBACK* SetHostNames) (LPOLEOBJECT, OLE_LPCSTR, OLE_LPCSTR); + OLESTATUS (CALLBACK* SaveToStream) (LPOLEOBJECT, LPOLESTREAM); + OLESTATUS (CALLBACK* Clone) (LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, OLE_LPCSTR, LPOLEOBJECT FAR*); + OLESTATUS (CALLBACK* CopyFromLink) (LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, OLE_LPCSTR, LPOLEOBJECT FAR*); + OLESTATUS (CALLBACK* Equal) (LPOLEOBJECT, LPOLEOBJECT); + OLESTATUS (CALLBACK* CopyToClipboard) (LPOLEOBJECT); + OLESTATUS (CALLBACK* Draw) (LPOLEOBJECT, HDC, OLE_CONST RECT FAR*, OLE_CONST RECT FAR*, HDC); + OLESTATUS (CALLBACK* Activate) (LPOLEOBJECT, UINT, BOOL, BOOL, HWND, OLE_CONST RECT FAR*); + OLESTATUS (CALLBACK* Execute) (LPOLEOBJECT, HGLOBAL, UINT); + OLESTATUS (CALLBACK* Close) (LPOLEOBJECT); + OLESTATUS (CALLBACK* Update) (LPOLEOBJECT); + OLESTATUS (CALLBACK* Reconnect) (LPOLEOBJECT); + + OLESTATUS (CALLBACK* ObjectConvert) (LPOLEOBJECT, OLE_LPCSTR, LPOLECLIENT, LHCLIENTDOC, OLE_LPCSTR, LPOLEOBJECT FAR*); + OLESTATUS (CALLBACK* GetLinkUpdateOptions) (LPOLEOBJECT, OLEOPT_UPDATE FAR*); + OLESTATUS (CALLBACK* SetLinkUpdateOptions) (LPOLEOBJECT, OLEOPT_UPDATE); + + OLESTATUS (CALLBACK* Rename) (LPOLEOBJECT, OLE_LPCSTR); + OLESTATUS (CALLBACK* QueryName) (LPOLEOBJECT, LPSTR, UINT FAR*); + + OLESTATUS (CALLBACK* QueryType) (LPOLEOBJECT, LONG FAR*); + OLESTATUS (CALLBACK* QueryBounds) (LPOLEOBJECT, RECT FAR*); + OLESTATUS (CALLBACK* QuerySize) (LPOLEOBJECT, DWORD FAR*); + OLESTATUS (CALLBACK* QueryOpen) (LPOLEOBJECT); + OLESTATUS (CALLBACK* QueryOutOfDate) (LPOLEOBJECT); + + OLESTATUS (CALLBACK* QueryReleaseStatus) (LPOLEOBJECT); + OLESTATUS (CALLBACK* QueryReleaseError) (LPOLEOBJECT); + OLE_RELEASE_METHOD (CALLBACK* QueryReleaseMethod)(LPOLEOBJECT); + + OLESTATUS (CALLBACK* RequestData) (LPOLEOBJECT, OLECLIPFORMAT); + OLESTATUS (CALLBACK* ObjectLong) (LPOLEOBJECT, UINT, LONG FAR*); + +/* This method is internal only */ + OLESTATUS (CALLBACK* ChangeData) (LPOLEOBJECT, HANDLE, LPOLECLIENT, BOOL); +#endif /* !SERVERONLY */ +} OLEOBJECTVTBL; +typedef OLEOBJECTVTBL FAR* LPOLEOBJECTVTBL; + +typedef struct _OLEOBJECT +{ + LPOLEOBJECTVTBL lpvtbl; +} OLEOBJECT; +#endif /* !OLE_NTERNAL */ + +/* ole client definitions */ +typedef struct _OLECLIENTVTBL +{ + int (CALLBACK* CallBack)(LPOLECLIENT, OLE_NOTIFICATION, LPOLEOBJECT); +} OLECLIENTVTBL; + +typedef OLECLIENTVTBL FAR* LPOLECLIENTVTBL; + +typedef struct _OLECLIENT +{ + LPOLECLIENTVTBL lpvtbl; +} OLECLIENT; + +/* Stream definitions */ +typedef struct _OLESTREAMVTBL +{ + DWORD (CALLBACK* Get)(LPOLESTREAM, void FAR*, DWORD); + DWORD (CALLBACK* Put)(LPOLESTREAM, OLE_CONST void FAR*, DWORD); +} OLESTREAMVTBL; +typedef OLESTREAMVTBL FAR* LPOLESTREAMVTBL; + +typedef struct _OLESTREAM +{ + LPOLESTREAMVTBL lpstbl; +} OLESTREAM; + +/* Public Function Prototypes */ +OLESTATUS WINAPI OleDelete(LPOLEOBJECT); +OLESTATUS WINAPI OleRelease(LPOLEOBJECT); +OLESTATUS WINAPI OleSaveToStream(LPOLEOBJECT, LPOLESTREAM); +OLESTATUS WINAPI OleEqual(LPOLEOBJECT, LPOLEOBJECT ); +OLESTATUS WINAPI OleCopyToClipboard(LPOLEOBJECT); +OLESTATUS WINAPI OleSetHostNames(LPOLEOBJECT, LPCSTR, LPCSTR); +OLESTATUS WINAPI OleSetTargetDevice(LPOLEOBJECT, HGLOBAL); +OLESTATUS WINAPI OleSetBounds(LPOLEOBJECT, const RECT FAR*); +OLESTATUS WINAPI OleSetColorScheme(LPOLEOBJECT, const LOGPALETTE FAR*); +OLESTATUS WINAPI OleQueryBounds(LPOLEOBJECT, RECT FAR*); +OLESTATUS WINAPI OleQuerySize(LPOLEOBJECT, DWORD FAR*); +OLESTATUS WINAPI OleDraw(LPOLEOBJECT, HDC, const RECT FAR*, const RECT FAR*, HDC); +OLESTATUS WINAPI OleQueryOpen(LPOLEOBJECT); +OLESTATUS WINAPI OleActivate(LPOLEOBJECT, UINT, BOOL, BOOL, HWND, const RECT FAR*); +OLESTATUS WINAPI OleExecute(LPOLEOBJECT, HGLOBAL, UINT); +OLESTATUS WINAPI OleClose(LPOLEOBJECT); +OLESTATUS WINAPI OleUpdate(LPOLEOBJECT); +OLESTATUS WINAPI OleReconnect(LPOLEOBJECT); +OLESTATUS WINAPI OleGetLinkUpdateOptions(LPOLEOBJECT, OLEOPT_UPDATE FAR*); +OLESTATUS WINAPI OleSetLinkUpdateOptions(LPOLEOBJECT, OLEOPT_UPDATE); +void FAR* WINAPI OleQueryProtocol(LPOLEOBJECT, LPCSTR); + +/* Routines related to asynchronous operations. */ +OLESTATUS WINAPI OleQueryReleaseStatus(LPOLEOBJECT); +OLESTATUS WINAPI OleQueryReleaseError(LPOLEOBJECT); +OLE_RELEASE_METHOD WINAPI OleQueryReleaseMethod(LPOLEOBJECT); + +OLESTATUS WINAPI OleQueryType(LPOLEOBJECT, LONG FAR*); + +/* LOWORD is major version, HIWORD is minor version */ +DWORD WINAPI OleQueryClientVersion(void); +DWORD WINAPI OleQueryServerVersion(void); + +/* Converting to format (as in clipboard): */ +OLECLIPFORMAT WINAPI OleEnumFormats(LPOLEOBJECT, OLECLIPFORMAT); +OLESTATUS WINAPI OleGetData(LPOLEOBJECT, OLECLIPFORMAT, HANDLE FAR*); +OLESTATUS WINAPI OleSetData(LPOLEOBJECT, OLECLIPFORMAT, HANDLE); +OLESTATUS WINAPI OleQueryOutOfDate(LPOLEOBJECT); +OLESTATUS WINAPI OleRequestData(LPOLEOBJECT, OLECLIPFORMAT); + +/* Query apis for creation from clipboard */ +OLESTATUS WINAPI OleQueryLinkFromClip(LPCSTR, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleQueryCreateFromClip(LPCSTR, OLEOPT_RENDER, OLECLIPFORMAT); + +/* Object creation functions */ +OLESTATUS WINAPI OleCreateFromClip(LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleCreateLinkFromClip(LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleCreateFromFile(LPCSTR, LPOLECLIENT, LPCSTR, LPCSTR, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleCreateLinkFromFile(LPCSTR, LPOLECLIENT, LPCSTR, LPCSTR, LPCSTR, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleLoadFromStream(LPOLESTREAM, LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*); +OLESTATUS WINAPI OleCreate(LPCSTR, LPOLECLIENT, LPCSTR, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleCreateInvisible(LPCSTR, LPOLECLIENT, LPCSTR, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT, BOOL); +OLESTATUS WINAPI OleCreateFromTemplate(LPCSTR, LPOLECLIENT, LPCSTR, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*, OLEOPT_RENDER, OLECLIPFORMAT); +OLESTATUS WINAPI OleClone(LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*); +OLESTATUS WINAPI OleCopyFromLink(LPOLEOBJECT, LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*); +OLESTATUS WINAPI OleObjectConvert(LPOLEOBJECT, LPCSTR, LPOLECLIENT, LHCLIENTDOC, LPCSTR, LPOLEOBJECT FAR*); +OLESTATUS WINAPI OleRename(LPOLEOBJECT, LPCSTR); +OLESTATUS WINAPI OleQueryName(LPOLEOBJECT, LPSTR, UINT FAR*); +OLESTATUS WINAPI OleRevokeObject(LPOLECLIENT); +BOOL WINAPI OleIsDcMeta(HDC); + +/* client document API */ +OLESTATUS WINAPI OleRegisterClientDoc(LPCSTR, LPCSTR, LONG, LHCLIENTDOC FAR*); +OLESTATUS WINAPI OleRevokeClientDoc(LHCLIENTDOC); +OLESTATUS WINAPI OleRenameClientDoc(LHCLIENTDOC, LPCSTR); +OLESTATUS WINAPI OleRevertClientDoc(LHCLIENTDOC); +OLESTATUS WINAPI OleSavedClientDoc(LHCLIENTDOC); +OLESTATUS WINAPI OleEnumObjects(LHCLIENTDOC, LPOLEOBJECT FAR*); + +/* server usage definitions */ +typedef enum { + OLE_SERVER_MULTI, /* multiple instances */ + OLE_SERVER_SINGLE /* single instance(multiple document) */ +} OLE_SERVER_USE; + +/* Server API */ +typedef struct _OLESERVER FAR* LPOLESERVER; + +OLESTATUS WINAPI OleRegisterServer(LPCSTR, LPOLESERVER, LHSERVER FAR*, HINSTANCE, OLE_SERVER_USE); +OLESTATUS WINAPI OleRevokeServer(LHSERVER); +OLESTATUS WINAPI OleBlockServer(LHSERVER); +OLESTATUS WINAPI OleUnblockServer(LHSERVER, BOOL FAR*); + +/* APIs to keep server open */ +OLESTATUS WINAPI OleLockServer(LPOLEOBJECT, LHSERVER FAR*); +OLESTATUS WINAPI OleUnlockServer(LHSERVER); + +/* Server document API */ + +typedef struct _OLESERVERDOC FAR* LPOLESERVERDOC; + +OLESTATUS WINAPI OleRegisterServerDoc(LHSERVER, LPCSTR, LPOLESERVERDOC, LHSERVERDOC FAR*); +OLESTATUS WINAPI OleRevokeServerDoc(LHSERVERDOC); +OLESTATUS WINAPI OleRenameServerDoc(LHSERVERDOC, LPCSTR); +OLESTATUS WINAPI OleRevertServerDoc(LHSERVERDOC); +OLESTATUS WINAPI OleSavedServerDoc(LHSERVERDOC); + +typedef struct _OLESERVERVTBL +{ + OLESTATUS (CALLBACK* Open) (LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, LPOLESERVERDOC FAR*); + /* long handle to doc(privtate to DLL) */ + /* lp to OLESERVER */ + /* document name */ + /* place holder for returning oledoc. */ + + OLESTATUS (CALLBACK* Create)(LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, OLE_LPCSTR, LPOLESERVERDOC FAR*); + /* long handle to doc(privtate to DLL) */ + /* lp to OLESERVER */ + /* lp class name */ + /* lp doc name */ + /* place holder for returning oledoc. */ + + OLESTATUS (CALLBACK* CreateFromTemplate)(LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, OLE_LPCSTR, OLE_LPCSTR, LPOLESERVERDOC FAR*); + /* long handle to doc(privtate to DLL) */ + /* lp to OLESERVER */ + /* lp class name */ + /* lp doc name */ + /* lp template name */ + /* place holder for returning oledoc. */ + + OLESTATUS (CALLBACK* Edit) (LPOLESERVER, LHSERVERDOC, OLE_LPCSTR, OLE_LPCSTR, LPOLESERVERDOC FAR*); + /* long handle to doc(privtate to DLL) */ + /* lp to OLESERVER */ + /* lp class name */ + /* lp doc name */ + /* place holder for returning oledoc. */ + + OLESTATUS (CALLBACK* Exit) (LPOLESERVER); + /* lp OLESERVER */ + + OLESTATUS (CALLBACK* Release) (LPOLESERVER); + /* lp OLESERVER */ + + OLESTATUS (CALLBACK* Execute)(LPOLESERVER, HGLOBAL); + /* lp OLESERVER */ + /* handle to command strings */ +} OLESERVERVTBL; +typedef OLESERVERVTBL FAR* LPOLESERVERVTBL; + +typedef struct _OLESERVER +{ + LPOLESERVERVTBL lpvtbl; +} OLESERVER; + +typedef struct _OLESERVERDOCVTBL +{ + OLESTATUS (CALLBACK* Save) (LPOLESERVERDOC); + OLESTATUS (CALLBACK* Close) (LPOLESERVERDOC); + OLESTATUS (CALLBACK* SetHostNames)(LPOLESERVERDOC, OLE_LPCSTR, OLE_LPCSTR); + OLESTATUS (CALLBACK* SetDocDimensions)(LPOLESERVERDOC, OLE_CONST RECT FAR*); + OLESTATUS (CALLBACK* GetObject) (LPOLESERVERDOC, OLE_LPCSTR, LPOLEOBJECT FAR*, LPOLECLIENT); + OLESTATUS (CALLBACK* Release) (LPOLESERVERDOC); + OLESTATUS (CALLBACK* SetColorScheme)(LPOLESERVERDOC, OLE_CONST LOGPALETTE FAR*); + OLESTATUS (CALLBACK* Execute) (LPOLESERVERDOC, HGLOBAL); +} OLESERVERDOCVTBL; +typedef OLESERVERDOCVTBL FAR* LPOLESERVERDOCVTBL; + +typedef struct _OLESERVERDOC +{ + LPOLESERVERDOCVTBL lpvtbl; +} OLESERVERDOC; + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#ifndef RC_INVOKED +#pragma pack() +#endif /* !RC_INVOKED */ + +#endif /* !_INC_OLE */ diff --git a/private/mvdm/wow16/ole/client/olecli.def b/private/mvdm/wow16/ole/client/olecli.def new file mode 100644 index 000000000..cb161aa47 --- /dev/null +++ b/private/mvdm/wow16/ole/client/olecli.def @@ -0,0 +1,233 @@ +LIBRARY OLECLI INITINSTANCE + +DESCRIPTION "OLE Client. support (c) Copyright Microsoft Corp. 1990 - All Rights Reserved";" + +EXETYPE WINDOWS + +STUB 'WINSTUB.EXE' + +CODE MOVABLE DISCARDABLE +DATA MOVABLE SINGLE + +SEGMENTS + WEP_TEXT CLASS 'CODE' FIXED + +HEAPSIZE 2048 + +EXPORTS + WEP @1 RESIDENTNAME ;Internal + OLEDELETE @2 + + OLESAVETOSTREAM @3 + OLELOADFROMSTREAM @4 + OLECLONE @6 + OLECOPYFROMLINK @7 + + OLEEQUAL @8 + + OLEQUERYLINKFROMCLIP @9 + OLEQUERYCREATEFROMCLIP @10 + + OLECREATELINKFROMCLIP @11 + OLECREATEFROMCLIP @12 + + OLECOPYTOCLIPBOARD @13 + + OLEQUERYTYPE @14 + OLESETHOSTNAMES @15 + OLESETTARGETDEVICE @16 + OLESETBOUNDS @17 + + OLEQUERYBOUNDS @18 + OLEDRAW @19 + + OLEQUERYOPEN @20 + OLEACTIVATE @21 + OLEUPDATE @22 + OLERECONNECT @23 + + OLEGETLINKUPDATEOPTIONS @24 + OLESETLINKUPDATEOPTIONS @25 + + OLEENUMFORMATS @26 + OLECLOSE @27 + + OLEGETDATA @28 + OLESETDATA @29 + + OLEQUERYPROTOCOL @30 + + OLEQUERYOUTOFDATE @31 + + OLEOBJECTCONVERT @32 + OLECREATEFROMTEMPLATE @33 + OLECREATE @34 + OLEQUERYRELEASESTATUS @35 + OLEQUERYRELEASEERROR @36 + OLEQUERYRELEASEMETHOD @37 + + OLECREATEFROMFILE @38 + OLECREATELINKFROMFILE @39 + + OLERELEASE @40 + + OLEREGISTERCLIENTDOC @41 + OLEREVOKECLIENTDOC @42 + OLERENAMECLIENTDOC @43 + OLEREVERTCLIENTDOC @44 + OLESAVEDCLIENTDOC @45 + + OLERENAME @46 + OLEENUMOBJECTS @47 + OLEQUERYNAME @48 + + OLESETCOLORSCHEME @49 + OLEREQUESTDATA @50 + + OLELOCKSERVER @54 + OLEUNLOCKSERVER @55 + + OLEQUERYSIZE @56 + + OLEEXECUTE @57 + OLECREATEINVISIBLE @58 + OLEQUERYCLIENTVERSION @59 + + OLEISDCMETA @60 + + DocWndProc @100 ;Internal + SrvrWndProc @101 ;Internal + MfCallbackFunc @102 ;Internal + + DEFLOADFROMSTREAM @110 + DEFCREATEFROMCLIP @111 + DEFCREATELINKFROMCLIP @112 + DEFCREATEFROMTEMPLATE @113 + DEFCREATE @114 + DEFCREATEFROMFILE @115 + DEFCREATELINKFROMFILE @116 + DEFCREATEINVISIBLE @117 + + LeRelease @200 ;Internal + LeShow @201 ;Internal + LeGetData @202 ;Internal + LeSetData @203 ;Internal + LeSetHostNames @204 ;Internal + LeSetTargetDevice @205 ;Internal + LeSetBounds @206 ;Internal + LeSaveToStream @207 ;Internal + LeClone @208 ;Internal + LeCopyFromLink @209 ;Internal + LeEqual @210 ;Internal + LeCopy @211 ;Internal + LeQueryType @212 ;Internal + LeQueryBounds @213 ;Internal + LeDraw @214 ;Internal + LeQueryOpen @215 ;Internal + LeActivate @216 ;Internal + LeUpdate @218 ;Internal + LeReconnect @219 ;Internal + LeEnumFormat @220 ;Internal + LeQueryProtocol @221 ;Internal + LeQueryOutOfDate @222 ;Internal + LeObjectConvert @223 ;Internal + LeChangeData @224 ;Internal + LeClose @225 ;Internal + LeGetUpdateOptions @226 ;Internal + LeSetUpdateOptions @227 ;Internal + LeExecute @228 ;Internal + LeObjectLong @229 ;Internal + LeCreateInvisible @230 ;Internal + + MfRelease @300 ;Internal + MfGetData @301 ;Internal + MfSaveToStream @302 ;Internal + MfClone @303 ;Internal + MfEqual @304 ;Internal + MfCopy @305 ;Internal + MfQueryBounds @307 ;Internal + MfDraw @308 ;Internal + MfEnumFormat @309 ;Internal + MfChangeData @310 ;Internal + + + BmRelease @400 ;Internal + BmGetData @401 ;Internal + BmSaveToStream @402 ;Internal + BmClone @403 ;Internal + BmEqual @404 ;Internal + BmCopy @405 ;Internal + BmQueryBounds @407 ;Internal + BmDraw @408 ;Internal + BmEnumFormat @409 ;Internal + BmChangeData @410 ;Internal + + + DibRelease @500 ;Internal + DibGetData @501 ;Internal + DibSaveToStream @502 ;Internal + DibClone @503 ;Internal + DibEqual @504 ;Internal + DibCopy @505 ;Internal + DibQueryBounds @507 ;Internal + DibDraw @508 ;Internal + DibEnumFormat @509 ;Internal + DibChangeData @510 ;Internal + + GenRelease @600 ;Internal + GenGetData @601 ;Internal + GenSetData @602 ;Internal + GenSaveToStream @603 ;Internal + GenClone @604 ;Internal + GenEqual @605 ;Internal + GenCopy @606 ;Internal + GenQueryBounds @608 ;Internal + GenDraw @609 ;Internal + GenEnumFormat @610 ;Internal + GenChangeData @611 ;Internal + + + ErrShow @701 ;Internal + ErrSetData @702 ;Internal + ErrSetHostNames @703 ;Internal + ErrSetTargetDevice @704 ;Internal + ErrSetBounds @705 ;Internal + ErrCopyFromLink @706 ;Internal + ErrQueryOpen @707 ;Internal + ErrActivate @708 ;Internal + ErrClose @709 ;Internal + ErrUpdate @710 ;Internal + ErrReconnect @711 ;Internal + ErrQueryProtocol @712 ;Internal + ErrQueryOutOfDate @713 ;Internal + ErrObjectConvert @714 ;Internal + ErrGetUpdateOptions @715 ;Internal + ErrSetUpdateOptions @716 ;Internal + ErrExecute @717 ;Internal + ErrObjectLong @718 ;Internal + + + PbLoadFromStream @800 ;Internal + PbCreateFromClip @801 ;Internal + PbCreateLinkFromClip @802 ;Internal + PbCreateFromTemplate @803 ;Internal + PbCreate @804 ;Internal + PbDraw @805 ;Internal + PbQueryBounds @806 ;Internal + PbCopyToClipboard @807 ;Internal + PbCreateFromFile @808 ;Internal + PbCreateLinkfromFile @809 ;Internal + PbEnumFormats @810 ;Internal + PbGetData @811 ;Internal + PbCreateInvisible @812 ;Internal + + ObjQueryName @910 ;Internal + ObjRename @911 ;Internal + ObjQueryType @912 ;Internal + ObjQuerySize @913 ;Internal + + ConnectDlgProc @950 ;Internal + SetNetName @951 ;Internal + CheckNetDrive @952 ;Internal + SetNextNetDrive @953 ;Internal + GetTaskVisibleWindow @954 diff --git a/private/mvdm/wow16/ole/client/pbhandlr.c b/private/mvdm/wow16/ole/client/pbhandlr.c new file mode 100644 index 000000000..bf448d59a --- /dev/null +++ b/private/mvdm/wow16/ole/client/pbhandlr.c @@ -0,0 +1,511 @@ +/****************************** Module Header ******************************\ +* Module Name: Pbhandlr.C -- Native data based handler (for Pbrush server) +* +* PURPOSE: Contains handler routines for Pbrush server. This handler makes +* use of most of the standard library methods. It replaces only the "Draw", +* "QueryBounds", "CopyToClipboard" methods of the OLE object. Note that this +* handler draws the picture from the native data. +* +* Created: December 1990 +* +* Copyright (c) 1990 Microsoft Corporation +* +* History: +* SriniK (../12/1990) Original +* +\***************************************************************************/ + +#include <windows.h> +#include "dll.h" + + +OLESTATUS FAR PASCAL _loadds PbDraw (LPOLEOBJECT, HDC, LPRECT, LPRECT, HDC); +OLESTATUS FAR PASCAL _loadds PbQueryBounds (LPOLEOBJECT, LPRECT); +OLESTATUS FAR PASCAL _loadds PbCopyToClipboard (LPOLEOBJECT); +OLESTATUS FAR PASCAL _loadds PbGetData (LPOLEOBJECT, OLECLIPFORMAT, HANDLE FAR *); +OLECLIPFORMAT FAR PASCAL _loadds PbEnumFormats (LPOLEOBJECT, OLECLIPFORMAT); + +extern OLESTATUS FARINTERNAL wDibDraw (HANDLE, HDC, LPRECT, LPRECT, HDC, BOOL); + + +void PbGetExtents (LPSTR, LPPOINT); +void PbReplaceFunctions (LPOLEOBJECT); +HANDLE PbGetPicture (LPOLEOBJECT); +BOOL IsStandardPict (LPOLEOBJECT); + +extern void FARINTERNAL DibGetExtents(LPSTR, LPPOINT); + +OLEOBJECTVTBL vtblDLL; + +extern OLECLIPFORMAT cfOwnerLink; +extern OLECLIPFORMAT cfObjectLink; +extern OLECLIPFORMAT cfNative; + +OLESTATUS (FAR PASCAL *DefQueryBounds) (LPVOID, LPRECT); +OLESTATUS (FAR PASCAL *DefDraw) (LPVOID, HDC, LPRECT, LPRECT, HDC); +OLESTATUS (FAR PASCAL *DefCopyToClipboard) (LPVOID); +OLECLIPFORMAT (FAR PASCAL *DefEnumFormats) (LPVOID, OLECLIPFORMAT); +OLESTATUS (FAR PASCAL *DefGetData) (LPVOID, OLECLIPFORMAT, HANDLE FAR *); + + +OLESTATUS FAR PASCAL PbLoadFromStream (lpstream, lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, objType, aClass, cfFormat) +LPOLESTREAM lpstream; +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +LONG objType; +ATOM aClass; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + + if (objType == OT_LINK) + retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + objType, aClass, cfNative); + else + retVal = DefLoadFromStream (lpstream, lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + objType, aClass, cfFormat); + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + + +OLESTATUS FAR PASCAL PbCreateFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, objType) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +LONG objType; +{ + OLESTATUS retVal; + + if ((optRender == olerender_draw) + && (IsClipboardFormatAvailable (cfNative))) { + if (objType == OT_EMBEDDED) + retVal = DefCreateFromClip (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + olerender_none, NULL, objType); + else + retVal = DefCreateFromClip (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + olerender_format, cfNative, objType); + } + else { + retVal = DefCreateFromClip (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat, objType); + } + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + + +OLESTATUS FAR PASCAL PbCreateLinkFromClip (lpprotocol, lpclient, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + + if ((optRender == olerender_draw) + && (IsClipboardFormatAvailable (cfNative))) { + retVal = DefCreateLinkFromClip (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + olerender_format, cfNative); + } + else { + retVal = DefCreateLinkFromClip (lpprotocol, lpclient, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat); + } + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + + +OLESTATUS FAR PASCAL PbCreateFromTemplate (lpprotocol, lpclient, lptemplate, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lptemplate; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + + if (optRender == olerender_draw) + retVal = DefCreateFromTemplate (lpprotocol, lpclient, lptemplate, + lhclientdoc, lpobjname, lplpobj, + olerender_none, NULL); + + else + retVal = DefCreateFromTemplate (lpprotocol, lpclient, lptemplate, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat); + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + + +OLESTATUS FAR PASCAL PbCreate (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + + if (optRender == olerender_draw) + retVal = DefCreate (lpprotocol, lpclient, lpclass, + lhclientdoc, lpobjname, lplpobj, + olerender_none, NULL); + else + retVal = DefCreate (lpprotocol, lpclient, lpclass, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat); + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + + +OLESTATUS FAR PASCAL PbCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + + if (optRender == olerender_draw) + retVal = DefCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, + lhclientdoc, lpobjname, lplpobj, + olerender_none, NULL); + + else + retVal = DefCreateFromFile (lpprotocol, lpclient, lpclass, lpfile, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat); + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + +OLESTATUS FAR PASCAL PbCreateLinkFromFile (lpprotocol, lpclient, lpclass, lpfile, lpitem, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LPSTR lpfile; +LPSTR lpitem; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +{ + OLESTATUS retVal; + + if (optRender == olerender_draw) + retVal = DefCreateLinkFromFile (lpprotocol, lpclient, + lpclass, lpfile, lpitem, + lhclientdoc, lpobjname, lplpobj, + olerender_format, cfNative); + + else + retVal = DefCreateLinkFromFile (lpprotocol, lpclient, + lpclass, lpfile, lpitem, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat); + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + + +OLESTATUS FAR PASCAL PbCreateInvisible (lpprotocol, lpclient, lpclass, lhclientdoc, lpobjname, lplpobj, optRender, cfFormat, fActivate) +LPSTR lpprotocol; +LPOLECLIENT lpclient; +LPSTR lpclass; +LHCLIENTDOC lhclientdoc; +LPSTR lpobjname; +LPOLEOBJECT FAR * lplpobj; +OLEOPT_RENDER optRender; +OLECLIPFORMAT cfFormat; +BOOL fActivate; +{ + OLESTATUS retVal; + + if (optRender == olerender_draw) + retVal = DefCreateInvisible (lpprotocol, lpclient, lpclass, + lhclientdoc, lpobjname, lplpobj, + olerender_none, NULL, fActivate); + else + retVal = DefCreateInvisible (lpprotocol, lpclient, lpclass, + lhclientdoc, lpobjname, lplpobj, + optRender, cfFormat, fActivate); + + if (retVal <= OLE_WAIT_FOR_RELEASE) + PbReplaceFunctions (*lplpobj); + + return retVal; +} + + +void PbReplaceFunctions (lpobj) +LPOLEOBJECT lpobj; +{ + if (IsStandardPict (lpobj)) + return; + + vtblDLL = *lpobj->lpvtbl; + lpobj->lpvtbl = (LPOLEOBJECTVTBL) &vtblDLL; + + DefDraw = lpobj->lpvtbl->Draw; + DefQueryBounds = lpobj->lpvtbl->QueryBounds; + DefCopyToClipboard = lpobj->lpvtbl->CopyToClipboard; + DefEnumFormats = lpobj->lpvtbl->EnumFormats; + DefGetData = lpobj->lpvtbl->GetData; + + lpobj->lpvtbl->Draw = PbDraw; + lpobj->lpvtbl->QueryBounds = PbQueryBounds; + lpobj->lpvtbl->CopyToClipboard = PbCopyToClipboard; + lpobj->lpvtbl->EnumFormats = PbEnumFormats; + lpobj->lpvtbl->GetData = PbGetData; +} + + + +OLESTATUS FAR PASCAL _loadds PbQueryBounds (lpobj, lprc) +LPOLEOBJECT lpobj; +LPRECT lprc; +{ + OLESTATUS retVal; + HANDLE hData; + LPSTR lpData; + POINT point; + + if ((retVal = (*DefQueryBounds) (lpobj, lprc)) == OLE_OK) { + if (lprc->top || lprc->bottom || lprc->right || lprc->left) + return OLE_OK; + } + + if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK) + return retVal; + + if (!hData) + return OLE_ERROR_BLANK; + + if (!(lpData = GlobalLock (hData))) + return OLE_ERROR_MEMORY; + + DibGetExtents ((lpData+sizeof(BITMAPFILEHEADER)), &point); + GlobalUnlock (hData); + + lprc->left = 0; + lprc->top = 0; + lprc->right = point.x; + lprc->bottom = point.y; + + return OLE_OK; +} + + +OLESTATUS FAR PASCAL _loadds PbDraw (lpobj, hdc, lprc, lpWrc, hdcTarget) +LPOLEOBJECT lpobj; +HDC hdc; +LPRECT lprc; +LPRECT lpWrc; +HDC hdcTarget; +{ + HANDLE hData; + + if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK) + return (*DefDraw) (lpobj, hdc, lprc, lpWrc, hdcTarget); + + return wDibDraw (hData, hdc, lprc, lpWrc, hdcTarget, TRUE); +} + + +OLECLIPFORMAT FAR PASCAL _loadds PbEnumFormats (lpobj, cfFormat) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +{ + OLECLIPFORMAT retFormat = NULL; + + if (cfFormat == CF_METAFILEPICT) + return NULL; + + if (!(retFormat = (*DefEnumFormats) (lpobj, cfFormat))) + return CF_METAFILEPICT; + + return retFormat; +} + + +OLESTATUS FAR PASCAL _loadds PbGetData (lpobj, cfFormat, lpHandle) +LPOLEOBJECT lpobj; +OLECLIPFORMAT cfFormat; +HANDLE FAR * lpHandle; +{ + OLESTATUS retval; + + retval = (*DefGetData) (lpobj, cfFormat, lpHandle); + + if (retval == OLE_OK || retval == OLE_BUSY || retval == OLE_ERROR_BLANK) + return retval; + + if (cfFormat == CF_METAFILEPICT) { + if (*lpHandle = PbGetPicture (lpobj)) + return OLE_WARN_DELETE_DATA; + + return OLE_ERROR_MEMORY; + } + + return OLE_ERROR_FORMAT; +} + + + +OLESTATUS FAR PASCAL _loadds PbCopyToClipboard (lpobj) +LPOLEOBJECT lpobj; +{ + OLESTATUS retVal; + HANDLE hPict; + + if ((retVal = (*DefCopyToClipboard) (lpobj)) == OLE_OK) { + if (hPict = PbGetPicture (lpobj)) + SetClipboardData (CF_METAFILEPICT, hPict); + else + retVal = OLE_ERROR_MEMORY; + } + + return retVal; +} + +HANDLE PbGetPicture (lpobj) +LPOLEOBJECT lpobj; +{ + HANDLE hMF, hMfp, hData; + RECT rc = {0, 0, 0, 0}; + POINT point; + HDC hMetaDC; + LPMETAFILEPICT lpmfp; + OLESTATUS retVal; + LPSTR lpData; + + if ((*DefGetData) (lpobj, cfNative, &hData) != OLE_OK) + return NULL; + + if (!hData) + return NULL; + + if (!(lpData = GlobalLock (hData))) + return NULL; + + lpData += sizeof(BITMAPFILEHEADER); + rc.right = (int) ((LPBITMAPINFOHEADER)lpData)->biWidth; + rc.bottom = (int) ((LPBITMAPINFOHEADER)lpData)->biHeight; + DibGetExtents(lpData, &point); + GlobalUnlock (hData); + + if (!(hMetaDC = CreateMetaFile (NULL))) + return NULL; + + SetWindowOrg (hMetaDC, 0, 0); + SetWindowExt (hMetaDC, rc.right, rc.bottom); + retVal = PbDraw (lpobj, hMetaDC, &rc, NULL, NULL); + hMF = CloseMetaFile (hMetaDC); + + if (retVal != OLE_OK) + goto error; + + if (hMF && (hMfp = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT))) + && (lpmfp = (LPMETAFILEPICT) GlobalLock (hMfp))) { + lpmfp->hMF = hMF; + lpmfp->xExt = point.x; + lpmfp->yExt = -point.y; + lpmfp->mm = MM_ANISOTROPIC; + GlobalUnlock (hMfp); + return hMfp; + } + +error: + + if (hMF) + DeleteMetaFile (hMF); + + if (hMfp) + GlobalFree (hMfp); + + return NULL; +} + + +// normal handler can't do this. since this handler is part of olecli.dll, we +// we are doing this. + +BOOL IsStandardPict (lpobj) +LPOLEOBJECT lpobj; +{ + LPOBJECT_LE lpLEobj; + LONG type; + + lpLEobj = (LPOBJECT_LE) lpobj; + if (!lpLEobj->lpobjPict) + return FALSE; + + if ((*lpLEobj->lpobjPict->lpvtbl->QueryType) (lpLEobj->lpobjPict, &type) + == OLE_ERROR_GENERIC) + return FALSE; + + return TRUE; +} + + diff --git a/private/mvdm/wow16/ole/client/pict.h b/private/mvdm/wow16/ole/client/pict.h new file mode 100644 index 000000000..7824c39c8 --- /dev/null +++ b/private/mvdm/wow16/ole/client/pict.h @@ -0,0 +1,190 @@ +/****************************** Module Header ******************************\ +* Module Name: pict.h +* +* PURPOSE: Private definitions file for presentation object related files +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, Srinik (../../90,91) Original +* +\***************************************************************************/ + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in MF.C // +// // +///////////////////////////////////////////////////////////////////////////// + +OLESTATUS FARINTERNAL MfRelease (LPOBJECT_MF); +OLESTATUS FARINTERNAL MfSaveToStream (LPOBJECT_MF, LPOLESTREAM); +OLESTATUS FARINTERNAL MfClone (LPOBJECT_MF, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOBJECT_MF FAR *); +OLESTATUS FARINTERNAL MfEqual (LPOBJECT_MF, LPOBJECT_MF); +OLESTATUS FARINTERNAL MfCopy (LPOBJECT_MF); +OLESTATUS FARINTERNAL MfQueryBounds (LPOBJECT_MF, LPRECT); +OLESTATUS FARINTERNAL MfGetData (LPOBJECT_MF, OLECLIPFORMAT, LPHANDLE); +OLESTATUS FARINTERNAL MfSetData (LPOBJECT_MF, OLECLIPFORMAT, HANDLE); +OLESTATUS FARINTERNAL MfChangeData (LPOBJECT_MF, HANDLE, LPOLECLIENT, BOOL); +OLESTATUS INTERNAL MfCopyToClip (LPOBJECT_MF, HANDLE); +void FARINTERNAL MfSetExtents (LPOBJECT_MF); +DWORD INTERNAL MfGetSize (LPHANDLE); +HANDLE INTERNAL GetHmfp (LPOBJECT_MF); +OLESTATUS INTERNAL MfUpdateStruct (LPOBJECT_MF, LPOLECLIENT, HANDLE, + LPMETAFILEPICT, HANDLE, BOOL); +OLECLIPFORMAT FARINTERNAL MfEnumFormat (LPOBJECT_MF, OLECLIPFORMAT); + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in DIB.C // +// // +///////////////////////////////////////////////////////////////////////////// + +/* The DIB file will be of the following format: */ +/* */ +/* 0004 */ +/* "DIB" */ +/* 4 bytes of xExtent in MM_HIMETIRC units (or) 0 */ +/* 4 bytes of yExtent in MM_HIMETIRC units (or) 0 */ +/* 4 bytes of size of (BITMAPINFOHEADER + RBGQUAD + bit array) */ +/* BITMAPINFOHEADER structure */ +/* RBGQUAD array */ +/* array of DI bits */ +/* */ + +OLESTATUS FARINTERNAL DibRelease (LPOBJECT_DIB); +OLESTATUS FARINTERNAL DibSaveToStream (LPOBJECT_DIB, LPOLESTREAM); +OLESTATUS FARINTERNAL DibClone (LPOBJECT_DIB, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOBJECT_DIB FAR *); +OLESTATUS FARINTERNAL DibEqual (LPOBJECT_DIB, LPOBJECT_DIB); +OLESTATUS FARINTERNAL DibCopy (LPOBJECT_DIB); +OLESTATUS FARINTERNAL DibQueryBounds (LPOBJECT_DIB, LPRECT); +OLESTATUS FARINTERNAL DibGetData (LPOBJECT_DIB, OLECLIPFORMAT, LPHANDLE); +OLESTATUS FARINTERNAL DibChangeData (LPOBJECT_DIB, HANDLE, LPOLECLIENT, BOOL); +BOOL INTERNAL DibStreamRead (LPOLESTREAM,LPOBJECT_DIB); +void INTERNAL DibUpdateStruct (LPOBJECT_DIB, LPOLECLIENT, HANDLE, LPBITMAPINFOHEADER, DWORD); + +OLECLIPFORMAT FARINTERNAL DibEnumFormat (LPOBJECT_DIB, OLECLIPFORMAT); + + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in BM.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +/* The BM file will be of the following format: */ +/* */ +/* 0007 */ +/* "BITMAP" */ +/* 4 bytes of xExtent in MM_HIMETIRC units (or) 0 */ +/* 4 bytes of yExtent in MM_HIMETIRC units (or) 0 */ +/* 4 bytes of size of (BITMAP + bits) */ +/* BITMAP structure */ +/* bitmap bits */ +/* */ + +OLESTATUS FARINTERNAL BmRelease (LPOBJECT_BM); +OLESTATUS FARINTERNAL BmSaveToStream (LPOBJECT_BM, LPOLESTREAM); +OLESTATUS FARINTERNAL BmClone (LPOBJECT_BM, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOBJECT_BM FAR *); +OLESTATUS FARINTERNAL BmEqual (LPOBJECT_BM, LPOBJECT_BM); +OLESTATUS FARINTERNAL BmCopy (LPOBJECT_BM); +OLESTATUS FARINTERNAL BmQueryBounds (LPOBJECT_BM, LPRECT); +OLESTATUS FARINTERNAL BmGetData (LPOBJECT_BM, OLECLIPFORMAT, LPHANDLE); +OLESTATUS FARINTERNAL BmChangeData (LPOBJECT_BM, HBITMAP, LPOLECLIENT, BOOL); +OLESTATUS INTERNAL BmStreamWrite (LPOLESTREAM, LPOBJECT_BM); +BOOL INTERNAL BmStreamRead (LPOLESTREAM, LPOBJECT_BM); +void INTERNAL BmUpdateStruct (LPOBJECT_BM, LPOLECLIENT, HBITMAP, LPBITMAP, DWORD); + +OLECLIPFORMAT FARINTERNAL BmEnumFormat (LPOBJECT_BM, OLECLIPFORMAT); +LPOBJECT_BM INTERNAL BmCreateObject (HBITMAP, LPOLECLIENT, BOOL, + LHCLIENTDOC, LPSTR, LONG); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in GENERIC.C // +// // +///////////////////////////////////////////////////////////////////////////// + + + + +/* The GENERIC file will be of the following format: */ +/* */ +/* 0007 */ +/* "GENERIC" */ +/* 4 bytes of cfFormat */ + +OLESTATUS FARINTERNAL GenRelease (LPOBJECT_GEN); +OLESTATUS FARINTERNAL GenSaveToStream (LPOBJECT_GEN, LPOLESTREAM); +OLESTATUS FARINTERNAL GenEqual (LPOBJECT_GEN, LPOBJECT_GEN); +OLESTATUS FARINTERNAL GenCopy (LPOBJECT_GEN); +OLESTATUS FARINTERNAL GenQueryBounds (LPOBJECT_GEN, LPRECT); +OLESTATUS FARINTERNAL GenGetData (LPOBJECT_GEN, OLECLIPFORMAT, LPHANDLE); +OLESTATUS FARINTERNAL GenSetData (LPOBJECT_GEN, OLECLIPFORMAT, HANDLE); +OLESTATUS FARINTERNAL GenChangeData (LPOBJECT_GEN, HANDLE, LPOLECLIENT, BOOL); +OLESTATUS INTERNAL GenDeleteData (HANDLE); +OLESTATUS FARINTERNAL GenQueryType (LPOLEOBJECT, LPLONG); +OLESTATUS FARINTERNAL GenClone(LPOBJECT_GEN, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOBJECT_GEN FAR *); + +OLECLIPFORMAT FARINTERNAL GenEnumFormat (LPOBJECT_GEN, OLECLIPFORMAT); +LPOBJECT_GEN INTERNAL GenCreateObject (HANDLE, LPOLECLIENT, BOOL, + LHCLIENTDOC, LPSTR, LONG); + + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in ERROR.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FARINTERNAL ErrPlay (LPOLEOBJECT, WORD, BOOL, BOOL); +OLESTATUS FARINTERNAL ErrShow (LPOLEOBJECT, BOOL); +OLESTATUS FARINTERNAL ErrSetHostNames (LPOLEOBJECT, LPSTR, LPSTR); +OLESTATUS FARINTERNAL ErrSetTargetDevice (LPOLEOBJECT, HANDLE); +OLESTATUS FARINTERNAL ErrSetColorScheme (LPOLEOBJECT, LPLOGPALETTE); +OLESTATUS FARINTERNAL ErrSetBounds (LPOLEOBJECT, LPRECT); +OLESTATUS FARINTERNAL ErrQueryOpen (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrActivate (LPOLEOBJECT, WORD, BOOL, BOOL, HWND, LPRECT); +OLESTATUS FARINTERNAL ErrClose (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrUpdate (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrReconnect (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrSetData (LPOLEOBJECT, OLECLIPFORMAT, HANDLE); +OLESTATUS FARINTERNAL ErrQueryOutOfDate (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrGetUpdateOptions (LPOLEOBJECT, OLEOPT_UPDATE FAR *); +OLESTATUS FARINTERNAL ErrSetUpdateOptions (LPOLEOBJECT, OLEOPT_UPDATE); +LPVOID FARINTERNAL ErrQueryProtocol (LPOLEOBJECT, LPSTR); +OLESTATUS FARINTERNAL ErrQueryRelease (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrAbort (LPOLEOBJECT); +OLESTATUS FARINTERNAL ErrCopyFromLink (LPOLEOBJECT, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *); +OLESTATUS FARINTERNAL ErrRequestData (LPOLEOBJECT, OLECLIPFORMAT); +OLESTATUS FARINTERNAL ErrExecute (LPOLEOBJECT, HANDLE, WORD); + +OLESTATUS FARINTERNAL ErrObjectConvert (LPOLEOBJECT, LPSTR, LPOLECLIENT, LHCLIENTDOC, LPSTR, LPOLEOBJECT FAR *); + +OLESTATUS FARINTERNAL ErrObjectLong (LPOLEOBJECT, WORD, LPLONG); + + +///////////////////////////////////////////////////////////////////////////// +// // +// Routines in DRAW.C // +// // +///////////////////////////////////////////////////////////////////////////// + + +OLESTATUS FARINTERNAL DibDraw (LPOBJECT_DIB, HDC, LPRECT, LPRECT, HDC); +OLESTATUS FARINTERNAL BmDraw (LPOBJECT_BM, HDC, LPRECT, LPRECT, HDC); +OLESTATUS FARINTERNAL GenDraw (LPOBJECT_GEN, HDC, LPRECT, LPRECT, HDC); +OLESTATUS FARINTERNAL MfDraw (LPOBJECT_MF, HDC, LPRECT, LPRECT, HDC); +void INTERNAL MfInterruptiblePaint (LPOBJECT_MF, HDC); +int FARINTERNAL MfCallbackFunc (HDC, LPHANDLETABLE, LPMETARECORD, int, BYTE FAR *); diff --git a/private/mvdm/wow16/ole/client/utils.c b/private/mvdm/wow16/ole/client/utils.c new file mode 100644 index 000000000..4ad1ebf00 --- /dev/null +++ b/private/mvdm/wow16/ole/client/utils.c @@ -0,0 +1,669 @@ + +/****************************** Module Header ******************************\ +* Module Name: utils.c +* +* Purpose: Conatains all the utility routines +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, srinik (../../1990,91) Designed and coded +* +\***************************************************************************/ + +#include <windows.h> +#include <shellapi.h> + +#include "dll.h" + +#define KB_64 65536 + +extern ATOM aPackage; +extern OLEOBJECTVTBL vtblMF, vtblBM, vtblDIB, vtblGEN; + +// QuerySize API support +DWORD dwObjSize = NULL; +OLESTREAMVTBL dllStreamVtbl; +OLESTREAM dllStream; + + +#pragma alloc_text(_DDETEXT, UtilMemClr, MapStrToH, MapExtToClass, FileExists) + +BOOL PutStrWithLen(lpstream, lpbytes) +LPOLESTREAM lpstream; +LPSTR lpbytes; +{ + LONG len; + + len = (LONG) lstrlen(lpbytes) + 1; + + if (PutBytes (lpstream, (LPSTR)&len, sizeof(len))) + return TRUE; + + return PutBytes(lpstream, lpbytes, len); + +} + +BOOL GetStrWithLen(lpstream, lpbytes) +LPOLESTREAM lpstream; +LPSTR lpbytes; +{ + if (GetBytes (lpstream, lpbytes, sizeof(LONG))) + return TRUE; + + return GetBytes (lpstream, lpbytes + sizeof(LONG), (*(LONG FAR *)lpbytes)); +} + +ATOM GetAtomFromStream(lpstream) +LPOLESTREAM lpstream; +{ + BOOL err = TRUE; + LONG len; + char str[MAX_STR+1]; + + + if (GetBytes (lpstream, (LPSTR)&len, sizeof(len))) + return NULL; + + if (len == 0) + return NULL; + + if (GetBytes(lpstream, (LPSTR)str, len)) + return NULL; + + return GlobalAddAtom(str); + +} + +BOOL PutAtomIntoStream(lpstream, at) +LPOLESTREAM lpstream; +ATOM at; +{ + LONG len = 0; + char buf[MAX_STR + 1]; + + if (at == 0) + return (PutBytes (lpstream, (LPSTR)&len, sizeof(len))); + + + len = GlobalGetAtomName (at,(LPSTR)buf, MAX_STR) + 1; + + if (PutBytes (lpstream, (LPSTR)&len, sizeof(len))) + return TRUE; + + return PutBytes(lpstream, buf, len); +} + + +// DuplicateAtom: Bump the use count up on a global atom. + +ATOM FARINTERNAL DuplicateAtom (ATOM atom) +{ + char buffer[MAX_ATOM+1]; + + Puts("DuplicateAtom"); + + if (!atom) + return NULL; + + GlobalGetAtomName (atom, buffer, MAX_ATOM); + return GlobalAddAtom (buffer); +} + + + +BOOL GetBytes(lpstream, lpstr, len) +LPOLESTREAM lpstream; +LPSTR lpstr; +LONG len; +{ + + ASSERT (lpstream->lpstbl->Get , "stream get function is null"); + return (((*lpstream->lpstbl->Get)(lpstream, lpstr, (DWORD)len)) != (DWORD)len); +} + + +BOOL PutBytes(lpstream, lpstr, len) +LPOLESTREAM lpstream; +LPSTR lpstr; +LONG len; +{ + + ASSERT (lpstream->lpstbl->Put , "stream get function is null"); + return (((*lpstream->lpstbl->Put)(lpstream, lpstr, (DWORD)len)) != (DWORD)len); +} + + +BOOL FARINTERNAL UtilMemCmp (lpmem1, lpmem2, dwCount) +LPSTR lpmem1; +LPSTR lpmem2; +DWORD dwCount; +{ + WORD HUGE * hpmem1; + WORD HUGE * hpmem2; + WORD FAR * lpwMem1; + WORD FAR * lpwMem2; + DWORD words; + DWORD bytes; + + bytes = dwCount % 2; + words = dwCount >> 1; //* we should compare DWORDS + //* in the 32 bit version + if (dwCount <= KB_64) { + lpwMem1 = (WORD FAR *) lpmem1; + lpwMem2 = (WORD FAR *) lpmem2; + + while (words--) { + if (*lpwMem1++ != *lpwMem2++) + return FALSE; + } + + if (bytes) { + if (* (char FAR *) lpwMem1 != *(char FAR *) lpwMem2) + return FALSE; + } + + } + else { + hpmem1 = (WORD HUGE *) lpmem1; + hpmem2 = (WORD HUGE *) lpmem2; + + while (words--) { + if (*hpmem1++ != *hpmem2++) + return FALSE; + } + + if (bytes) { + if (* (char HUGE *) hpmem1 != * (char HUGE *) hpmem2) + return FALSE; + } + } + + return TRUE; +} + + +void FARINTERNAL UtilMemCpy (lpdst, lpsrc, dwCount) +LPSTR lpdst; +LPSTR lpsrc; +DWORD dwCount; +{ + WORD HUGE * hpdst; + WORD HUGE * hpsrc; + WORD FAR * lpwDst; + WORD FAR * lpwSrc; + DWORD words; + DWORD bytes; + + bytes = dwCount % 2; + words = dwCount >> 1; //* we should compare DWORDS + //* in the 32 bit version + if (dwCount <= KB_64) { + lpwDst = (WORD FAR *) lpdst; + lpwSrc = (WORD FAR *) lpsrc; + + while (words--) + *lpwDst++ = *lpwSrc++; + + if (bytes) + * (char FAR *) lpwDst = * (char FAR *) lpwSrc; + } + else { + hpdst = (WORD HUGE *) lpdst; + hpsrc = (WORD HUGE *) lpsrc; + + while (words--) + *hpdst++ = *hpsrc++; + + if (bytes) + *(char HUGE *) hpdst = * (char HUGE *) hpsrc; + } +} + + +//DuplicateData: Duplicates a given Global data handle. +HANDLE FARINTERNAL DuplicateGlobal (hdata, flags) +HANDLE hdata; +WORD flags; +{ + LPSTR lpdst = NULL; + LPSTR lpsrc = NULL; + HANDLE hdup = NULL; + DWORD size; + BOOL err = TRUE; + + if (!hdata) + return NULL; + + if(!(lpsrc = GlobalLock (hdata))) + return NULL; + + hdup = GlobalAlloc (flags, (size = GlobalSize(hdata))); + + if(!(lpdst = GlobalLock (hdup))) + goto errRtn;; + + err = FALSE; + UtilMemCpy (lpdst, lpsrc, size); + +errRtn: + if(lpsrc) + GlobalUnlock (hdata); + + if(lpdst) + GlobalUnlock (hdup); + + if (err && hdup) { + GlobalFree (hdup); + hdup = NULL; + } + + return hdup; +} + + +BOOL FARINTERNAL CmpGlobals (hdata1, hdata2) +HANDLE hdata1; +HANDLE hdata2; +{ + LPSTR lpdata1 = NULL; + LPSTR lpdata2 = NULL; + DWORD size1; + DWORD size2; + BOOL retval = FALSE; + + + size1 = GlobalSize (hdata1); + size2 = GlobalSize (hdata2); + + if (size1 != size2) + return FALSE; + + if (!(lpdata1 = GlobalLock (hdata1))) + goto errRtn; + + if (!(lpdata2 = GlobalLock (hdata2))) + goto errRtn; + + retval = UtilMemCmp (lpdata1, lpdata2, size1); + +errRtn: + if (lpdata1) + GlobalUnlock (hdata1); + + if (lpdata2) + GlobalUnlock (hdata2); + + return retval; +} + + +int FARINTERNAL GlobalGetAtomLen (aItem) +ATOM aItem; +{ + // !!! Change this + char buf[MAX_STR]; + + if (!aItem) + return NULL; + + return (GlobalGetAtomName (aItem, (LPSTR)buf, MAX_STR)); + +} + + +BOOL FARINTERNAL MapExtToClass (lptemplate, lpbuf, len) +LPSTR lptemplate; +LPSTR lpbuf; +int len; +{ + LONG cb; + + while (*lptemplate && *lptemplate != '.') + lptemplate++; + + cb = len; + if (*(lptemplate+1) == NULL) + return FALSE; + + if (RegQueryValue (HKEY_CLASSES_ROOT, lptemplate, lpbuf, &cb)) + return FALSE; + + return TRUE; +} + + +// Get exe name from aClass and set it as aServer +void INTERNAL SetExeAtom (lpobj) +LPOBJECT_LE lpobj; +{ + char key[MAX_STR]; + + // if old link object assume the class same as the exe file name. + if (lpobj->bOldLink) + lpobj->aServer = DuplicateAtom (lpobj->app); + else { + if (GlobalGetAtomName (lpobj->app, key, sizeof(key))) + lpobj->aServer = GetAppAtom ((LPSTR)key); + } +} + + +ATOM FARINTERNAL GetAppAtom (lpclass) +LPSTR lpclass; +{ + char buf1[MAX_STR]; + + + if (!QueryApp (lpclass, PROTOCOL_EDIT, buf1)) { + return NULL; + } + + return GlobalAddAtom ((LPSTR)buf1); +} + + +BOOL FARINTERNAL QueryVerb (lpobj, verb, lpbuf, cbmax) +LPOBJECT_LE lpobj; +WORD verb; +LPSTR lpbuf; +LONG cbmax; +{ + LONG cb = MAX_STR; + char key[MAX_STR]; + // do not need 256 bytes buffer + char class[MAX_STR]; + int len; + + if (!GlobalGetAtomName (lpobj->app, (LPSTR)class, sizeof(class))) + return FALSE; + + lstrcpy (key, (LPSTR)class); + lstrcat (key, "\\protocol\\StdFileEditing\\verb\\"); + len = lstrlen (key); + key [len++] = (char) ('0' + verb); + key [len++] = 0; + + if (RegQueryValue (HKEY_CLASSES_ROOT, key, lpbuf, &cbmax)) + return FALSE; + return TRUE; +} + + + + +BOOL QueryApp (lpclass, lpprotocol, lpbuf) +LPSTR lpclass; +LPSTR lpprotocol; +LPSTR lpbuf; +{ + LONG cb = MAX_STR; + char key[MAX_STR]; + + lstrcpy (key, lpclass); + lstrcat (key, "\\protocol\\"); + lstrcat (key, lpprotocol); + lstrcat (key, "\\server"); + + if (RegQueryValue (HKEY_CLASSES_ROOT, key, lpbuf, &cb)) + return FALSE; + return TRUE; +} + + +HANDLE MapStrToH (lpstr) +LPSTR lpstr; +{ + + HANDLE hdata = NULL; + LPSTR lpdata = NULL; + + hdata = GlobalAlloc (GMEM_DDESHARE, lstrlen (lpstr) + 1); + if (hdata == NULL || (lpdata = (LPSTR)GlobalLock (hdata)) == NULL) + goto errRtn; + + lstrcpy (lpdata, lpstr); + GlobalUnlock (hdata); + return hdata; + +errRtn: + if (lpdata) + GlobalUnlock (hdata); + + if (hdata) + GlobalFree (hdata); + return NULL; +} + + +HANDLE FARINTERNAL CopyData (lpsrc, dwBytes) +LPSTR lpsrc; +DWORD dwBytes; +{ + HANDLE hnew; + LPSTR lpnew; + BOOL retval = FALSE; + + if (hnew = GlobalAlloc (GMEM_MOVEABLE, dwBytes)){ + if (lpnew = GlobalLock (hnew)){ + UtilMemCpy (lpnew, lpsrc, dwBytes); + GlobalUnlock (hnew); + return hnew; + } + else + GlobalFree (hnew); + } + + return NULL; +} + +void UtilMemClr (pstr, size) +PSTR pstr; +WORD size; +{ + + while (size--) + *pstr++ = 0; + +} + + +OLESTATUS FAR PASCAL ObjQueryName (lpobj, lpBuf, lpcbBuf) +LPOLEOBJECT lpobj; +LPSTR lpBuf; +WORD FAR * lpcbBuf; +{ + if (lpobj->ctype != CT_LINK && lpobj->ctype != CT_EMBEDDED + && lpobj->ctype != CT_STATIC) + return OLE_ERROR_OBJECT; + + PROBE_WRITE(lpBuf); + if (!*lpcbBuf) + return OLE_ERROR_SIZE; + + if (!CheckPointer(lpBuf+*lpcbBuf-1, WRITE_ACCESS)) + return OLE_ERROR_SIZE; + + ASSERT(lpobj->aObjName, "object name ATOM is NULL\n"); + *lpcbBuf = GlobalGetAtomName (lpobj->aObjName, lpBuf, *lpcbBuf); + return OLE_OK; +} + + +OLESTATUS FAR PASCAL ObjRename (lpobj, lpNewName) +LPOLEOBJECT lpobj; +LPSTR lpNewName; +{ + if (lpobj->ctype != CT_LINK && lpobj->ctype != CT_EMBEDDED + && lpobj->ctype != CT_STATIC) + return OLE_ERROR_OBJECT; + + PROBE_READ(lpNewName); + if (!lpNewName[0]) + return OLE_ERROR_NAME; + + if (lpobj->aObjName) + GlobalDeleteAtom (lpobj->aObjName); + lpobj->aObjName = GlobalAddAtom (lpNewName); + return OLE_OK; +} + + + + +BOOL QueryHandler(cfFormat) +WORD cfFormat; +{ + HANDLE hInfo = NULL; + LPSTR lpInfo = NULL; + BOOL fRet = FALSE, fOpen = FALSE; + LONG cb = MAX_STR; + char str[MAX_STR]; + HKEY hKey; + + // we don't have the client app window handle, use the screen handle + fOpen = OpenClipboard (NULL); + + if (!(hInfo = GetClipboardData (cfFormat))) + goto errRtn; + + if (!(lpInfo = GlobalLock(hInfo))) + goto errRtn; + + // First string of lpInfo is CLASS. See whether any handler is installed + // for this class. + + lstrcpy (str, lpInfo); + lstrcat (str, "\\protocol\\StdFileEditing\\handler"); + if (RegOpenKey (HKEY_CLASSES_ROOT, str, &hKey)) + goto errRtn; + RegCloseKey (hKey); + fRet = TRUE; + +errRtn: + if (lpInfo) + GlobalUnlock (hInfo); + + if (fOpen) + CloseClipboard(); + return fRet; +} + +OLESTATUS INTERNAL FileExists (lpobj) +LPOBJECT_LE lpobj; +{ + char filename[MAX_STR]; + OFSTRUCT ofstruct; + + if (!GlobalGetAtomName (lpobj->topic, filename, MAX_STR)) + return OLE_ERROR_MEMORY; + + // For package with link we append "/LINK" to the filename. We don't want + // to check for it's existence here. + if (lpobj->app != aPackage) { + // when OF_EXIST is specified, file is opened and closed immediately + if (OpenFile (filename, &ofstruct, OF_EXIST) == -1) + return OLE_ERROR_OPEN; + } + + return OLE_OK; +} + + +BOOL FARINTERNAL UtilQueryProtocol (lpobj, lpprotocol) +LPOBJECT_LE lpobj; +LPSTR lpprotocol; +{ + char buf[MAX_STR]; + ATOM aExe; + + if (!GlobalGetAtomName (lpobj->app, (LPSTR) buf, MAX_STR)) + return FALSE; + + if (!QueryApp (buf, lpprotocol, (LPSTR) buf)) + return FALSE; + + aExe = GlobalAddAtom (buf); + if (aExe) + GlobalDeleteAtom (aExe); + if (aExe != lpobj->aServer) + return FALSE; + + return TRUE; +} + +WORD FARINTERNAL FarCheckPointer (lp, iAccessType) +LPVOID lp; +int iAccessType; +{ + return (CheckPointer (lp, iAccessType)); +} + + +DWORD PASCAL FAR DllPut (lpstream, lpstr, dwSize) +LPOLESTREAM lpstream; +LPSTR lpstr; +DWORD dwSize; +{ + dwObjSize += dwSize; + return dwSize; +} + + + +OLESTATUS FARINTERNAL ObjQueryType (lpobj, lptype) +LPOLEOBJECT lpobj; +LPLONG lptype; +{ + Puts("ObjQueryType"); + + if (lpobj->ctype != CT_STATIC) + return OLE_ERROR_OBJECT; + + *lptype = lpobj->ctype; + return OLE_OK; +} + +OLESTATUS FARINTERNAL ObjQuerySize (lpobj, lpdwSize) +LPOLEOBJECT lpobj; +DWORD FAR * lpdwSize; +{ + Puts("ObjQuerySize"); + + *lpdwSize = dwObjSize = NULL; + + if ((*lpobj->lpvtbl->SaveToStream) (lpobj, &dllStream) == OLE_OK) { + *lpdwSize = dwObjSize; + return OLE_OK; + } + + return OLE_ERROR_BLANK; +} + +BOOL FARINTERNAL IsObjectBlank (lpobj) +LPOBJECT_LE lpobj; +{ + LPOLEOBJECT lpPictObj; + BOOL retval; + + // Cleaner way is to provide a method like QueryBlank() + + if (!lpobj->hnative) + return TRUE; + + if (!(lpPictObj = lpobj->lpobjPict)) + return FALSE; + + if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblMF) + retval = (BOOL) (((LPOBJECT_MF)lpPictObj)->hmfp); + else if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblBM) + retval = (BOOL) (((LPOBJECT_BM)lpPictObj)->hBitmap); + if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblDIB) + retval = (BOOL) (((LPOBJECT_DIB)lpPictObj)->hDIB); + if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblGEN) + retval = (BOOL) (((LPOBJECT_GEN)lpPictObj)->hData); + + return retval; +} diff --git a/private/mvdm/wow16/ole/server/block.c b/private/mvdm/wow16/ole/server/block.c new file mode 100644 index 000000000..4d0646420 --- /dev/null +++ b/private/mvdm/wow16/ole/server/block.c @@ -0,0 +1,309 @@ +/****************************** Module Header ******************************\ +* Module Name: Block.c +* +* Purpose: Includes OleServerBlock(), OleServerUnblock() and related routines. +* +* Created: Dec. 1990. +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Srinik (../12/1990) Designed, coded +* +\***************************************************************************/ + + +#include "cmacs.h" +#include "windows.h" +#include "dde.h" +#include "ole.h" +#include "srvr.h" + + +OLESTATUS FAR PASCAL OleBlockServer (lhsrvr) +LHSERVER lhsrvr; +{ + LPSRVR lpsrvr; + + if (!CheckServer (lpsrvr = (LPSRVR) lhsrvr)) + return OLE_ERROR_HANDLE; + + PROBE_BLOCK(lpsrvr); + lpsrvr->bBlock = TRUE; + return OLE_OK; +} + + +// On return from this routine, if *lpStatus is TRUE it means that more +// messages are to be unblocked. + +OLESTATUS FAR PASCAL OleUnblockServer (lhsrvr, lpStatus) +LHSERVER lhsrvr; +BOOL FAR * lpStatus; +{ + HANDLE hq; + PQUE pq; + LPSRVR lpsrvr; + + if (!CheckServer (lpsrvr = (LPSRVR) lhsrvr)) + return OLE_ERROR_HANDLE; + + PROBE_WRITE(lpStatus); + + *lpStatus = lpsrvr->bBlock; + if (hq = lpsrvr->hqHead) { + if (!(pq = (PQUE) LocalLock (hq))) + return OLE_ERROR_MEMORY; + lpsrvr->bBlockedMsg = TRUE; + lpsrvr->hqHead = pq->hqNext; + SendMessage (pq->hwnd, pq->msg, pq->wParam, pq->lParam); + LocalUnlock (hq); + LocalFree (hq); + + // Server could've got freed up as a result of the above SendMessage + // Validate server handle before trying to access it. + if (CheckServer (lpsrvr)) { + lpsrvr->bBlockedMsg = FALSE; + + if (!lpsrvr->hqHead) { + lpsrvr->hqTail = NULL; + *lpStatus = lpsrvr->bBlock = FALSE; + } + } + else { + *lpStatus = FALSE; + } + } + else { + *lpStatus = lpsrvr->bBlock = FALSE; + } + + return OLE_OK; +} + + +BOOL INTERNAL AddMessage (hwnd, msg, wParam, lParam, wType) +HWND hwnd; +unsigned msg; +WORD wParam; +LONG lParam; +int wType; +{ + LPSRVR lpsrvr; + HANDLE hq = NULL; + PQUE pq = NULL, pqTmp = NULL; + BOOL bBlocked = TRUE; + + if ((msg <= WM_DDE_INITIATE) || (msg > WM_DDE_LAST)) + return FALSE; + + + if (!(lpsrvr = (LPSRVR) GetWindowLong ((wType == WT_DOC) ? GetParent (hwnd) : hwnd, 0))) + return FALSE; + + if (lpsrvr->bBlockedMsg || !lpsrvr->bBlock) + return FALSE; + +#ifdef LATER + if ((msg == WM_DDE_INITIATE) && (lpsrvr->useFlags == OLE_SERVER_MULTI)) + return TRUE; +#endif + + // Create a queue node and fill up with data + + if (!(hq = LocalAlloc (LMEM_MOVEABLE, sizeof(QUE)))) + goto errRet; + + if (!(pq = (PQUE) LocalLock (hq))) + goto errRet; + + pq->hwnd = hwnd; + pq->msg = msg; + pq->wParam = wParam; + pq->lParam = lParam; + pq->hqNext = NULL; + LocalUnlock (hq); + + // Now we got a node that we can add to the queue + + if (!lpsrvr->hqHead) { + // Queue is empty. +#ifdef FIREWALLS + ASSERT (!lpsrvr->hqTail, "Tail is unexpectedly non NULL") +#endif + lpsrvr->hqHead = lpsrvr->hqTail = hq; + } + else { + if (!(pqTmp = (PQUE) LocalLock (lpsrvr->hqTail))) + goto errRet; + pqTmp->hqNext = hq; + LocalUnlock(lpsrvr->hqTail); + lpsrvr->hqTail = hq; + } + + return TRUE; + +errRet: + + if (pq) + LocalUnlock (hq); + + if (hq) + LocalFree (hq); + + while (bBlocked && !OleUnblockServer ((LHSERVER) lpsrvr, &bBlocked)) + ; + + return FALSE; +} + + + +// dispatches the queued message, till all the messages are posted +// does yielding if necessary. if bPeek is true, may allow some of +// incoming messages to get in. + + +BOOL INTERNAL UnblockPostMsgs (hwnd, bPeek) +HWND hwnd; +BOOL bPeek; +{ + HANDLE hq = NULL; + PQUE pq = NULL; + LPSRVR lpsrvr; + HWND hwndTmp; + + // get the parent windows + while (hwndTmp = GetParent (hwnd)) + hwnd = hwndTmp; + + lpsrvr = (LPSRVR) GetWindowLong (hwnd, 0); + +#ifdef FIREWALLS + ASSERT (lpsrvr, "No server window handle in server window"); + ASSERT (lpsrvr->hqPostHead, "Unexpectedly blocked queue is empty"); +#endif + + + while (hq = lpsrvr->hqPostHead) { + + if (!(pq = (PQUE) LocalLock (hq))) { + +#ifdef FIREWALLS + ASSERT (FALSE, "Local lock failed for blocked messages"); +#endif + break; + } + if (IsWindowValid (pq->hwnd)) { + if (!PostMessage (pq->hwnd, pq->msg, pq->wParam, pq->lParam)) { + LocalUnlock (hq); + break; + } + } + + lpsrvr->hqPostHead = pq->hqNext; + LocalUnlock (hq); + LocalFree (hq); + } + + + if (!lpsrvr->hqPostHead) + lpsrvr->hqPostTail = NULL; + + return TRUE; +} + + +// Moves a message which can not be posted to a server to +// the internal queue. We use this when we have to enumerate +// the properties. When we change the properties stuff to +// some other form, this may not be necassry. + +BOOL INTERNAL BlockPostMsg (hwnd, msg, wParam, lParam) +HWND hwnd; +unsigned msg; +WORD wParam; +LONG lParam; +{ + LPSRVR lpsrvr; + HANDLE hq = NULL; + PQUE pq = NULL, pqTmp = NULL; + HWND hwndTmp; + HWND hwndParent; + + hwndParent = (HWND)wParam; + // get the parent windows + while (hwndTmp = GetParent ((HWND)hwndParent)) + hwndParent = hwndTmp; + + lpsrvr = (LPSRVR) GetWindowLong (hwndParent, 0); + +#ifdef FIREWALLS + ASSERT (lpsrvr, "No server window handle in server window"); +#endif + + // Create a queue node and fill up with data + + if (!(hq = LocalAlloc (LMEM_MOVEABLE, sizeof(QUE)))) + goto errRet; + + if (!(pq = (PQUE) LocalLock (hq))) + goto errRet; + + pq->hwnd = hwnd; + pq->msg = msg; + pq->wParam = wParam; + pq->lParam = lParam; + pq->hqNext = NULL; + LocalUnlock (hq); + + // Now we got a node that we can add to the queue + + if (!lpsrvr->hqPostHead) { + // Queue is empty. +#ifdef FIREWALLS + ASSERT (!lpsrvr->hqPostTail, "Tail is unexpectedly non NULL") +#endif + lpsrvr->hqPostHead = lpsrvr->hqPostTail = hq; + + // create a timer. + if (!SetTimer (lpsrvr->hwnd, 1, 100, NULL)) + return FALSE; + + } + else { + if (!(pqTmp = (PQUE) LocalLock (lpsrvr->hqPostTail))) + goto errRet; + pqTmp->hqNext = hq; + LocalUnlock(lpsrvr->hqPostTail); + lpsrvr->hqPostTail = hq; + } + + return TRUE; + +errRet: + + if (pq) + LocalUnlock (hq); + + if (hq) + LocalFree (hq); + return FALSE; +} + + +BOOL INTERNAL IsBlockQueueEmpty (hwnd) +HWND hwnd; +{ + + LPSRVR lpsrvr; + HWND hwndTmp; + + // get the parent windows + while (hwndTmp = GetParent ((HWND)hwnd)) + hwnd= hwndTmp; + lpsrvr = (LPSRVR) GetWindowLong (hwnd, 0); + return (!lpsrvr->hqPostHead); + + +} diff --git a/private/mvdm/wow16/ole/server/doc.c b/private/mvdm/wow16/ole/server/doc.c new file mode 100644 index 000000000..5716f4d35 --- /dev/null +++ b/private/mvdm/wow16/ole/server/doc.c @@ -0,0 +1,1091 @@ +/****************************** Module Header ******************************\ +* Module Name: Doc.c Document Main module +* +* Purpose: Includes All the document communication related routines. +* +* Created: Oct 1990. +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor (../10/1990) Designed, coded +* +\***************************************************************************/ + +#include "cmacs.h" +#include "windows.h" +#include "ole.h" +#include "dde.h" +#include "srvr.h" + +extern ATOM cfBinary; +extern ATOM aStdClose; +extern ATOM aStdShowItem; +extern ATOM aStdDoVerbItem; +extern ATOM aStdDocName; +extern ATOM aTrue; +extern ATOM aFalse; + +extern FARPROC lpTerminateDocClients; +extern FARPROC lpSendRenameMsg; +extern FARPROC lpFindItemWnd; +extern FARPROC lpEnumForTerminate; + +extern HANDLE hdllInst; +extern HANDLE hddeRename; +extern HWND hwndRename; + + +extern BOOL fAdviseSaveDoc; + +// ### Do we have to create a seperate window for each doc conversation. +// EDF thinks so. + +/***************************** Public Function ****************************\ +* +* OLESTATUS FAR PASCAL OleRegisterServerDoc (lhsrvr, lpdocname, lpoledoc, lplhdoc) +* +* OleRegisterServerDoc: Registers the Document with the server lib. +* +* Parameters: +* 1. Server long handle(server with which the document should +* be registered) +* 2. Document name. +* 3. Handle to the doc of the server app (private to the server app). +* 4. Ptr for returning the Doc handle of the lib (private to the lib). +* +* return values: +* returns OLE_OK if the server is successfully registered . +* else returns the corresponding error. +* +* History: +* Raor: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRegisterServerDoc (lhsrvr, lpdocname, lpoledoc, lplhdoc) +LHSRVR lhsrvr; // handle we passed back as part of registration. +LPSTR lpdocname; // document name +LPOLESERVERDOC lpoledoc; // Private doc handle of the server app. +LHDOC FAR * lplhdoc; // where we will be passing our doc private handle +{ + + LPSRVR lpsrvr = NULL; + LPDOC lpdoc = NULL; + HANDLE hdoc = NULL; + + + Puts ("OleRegisterServerDoc"); + + if (!CheckServer (lpsrvr = (LPSRVR)lhsrvr)) + return OLE_ERROR_HANDLE; + + // server's termination has already started. + if (lpsrvr->bTerminate) + return OLE_ERROR_TERMINATE; + + PROBE_READ(lpdocname); + PROBE_WRITE(lplhdoc); + + // we are using the null from inside the server lib + if (lpoledoc) + PROBE_WRITE(lpoledoc); + + hdoc = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE, sizeof (DOC)); + + if (!(hdoc && (lpdoc = (LPDOC)GlobalLock (hdoc)))) + goto errReturn; + + // set the signature, handle and the doc atom. + lpdoc->sig[0] = 'S'; + lpdoc->sig[1] = 'D'; + lpdoc->hdoc = hdoc; + lpdoc->aDoc = GlobalAddAtom (lpdocname); + lpdoc->lpoledoc = lpoledoc; + + + if (!(lpdoc->hwnd = CreateWindow ("DocWndClass", "Doc", + WS_CHILD,0,0,0,0,lpsrvr->hwnd,NULL, hdllInst, NULL))) + goto errReturn; + + // save the ptr to the struct in the window. + SetWindowLong (lpdoc->hwnd, 0, (LONG)lpdoc); + SetWindowWord (lpdoc->hwnd, WW_LE, WC_LE); + SetWindowWord (lpdoc->hwnd, WW_HANDLE, + (WORD) (GetWindowWord (lpsrvr->hwnd, WW_HANDLE))); + *lplhdoc = (LONG)lpdoc; + + return OLE_OK; + +errReturn: + if (lpdoc){ + if (lpdoc->hwnd) + DestroyWindow (lpsrvr->hwnd); + + if (lpdoc->aDoc) + GlobalDeleteAtom (lpdoc->aDoc); + + GlobalUnlock(hdoc); + } + + if (hdoc) + GlobalFree (hdoc); + + return OLE_ERROR_MEMORY; +} + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleRevokeServerDoc (lhdoc) +* +* OleRevokeServerDoc: Unregisters the document which has been registered. +* +* Parameters: +* 1. DLL Doc handle. +* +* return values: +* returns OLE_OK if the document is successfully unregisterd. +* ( It is Ok for the app to free the associated space). +* If the unregistration is intiated, returns OLE_STARTED. +* Calls the Doc class release entry point when the doc +* can be released. App should wait till the Release is called +* +* History: +* Raor: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRevokeServerDoc (lhdoc) +LHDOC lhdoc; +{ + HWND hwndSrvr; + LPSRVR lpsrvr; + HWND hwndDoc; + LPDOC lpdoc; + + Puts ("OleRevokeServerDoc"); + + if (!CheckServerDoc (lpdoc = (LPDOC)lhdoc)) + return OLE_ERROR_HANDLE; + + if (lpdoc->bTerminate && lpdoc->termNo) + return OLE_WAIT_FOR_RELEASE; + + // ### this code is very similar to the srvr code. + // we should optimize. + + hwndDoc = lpdoc->hwnd; + +#ifdef FIREWALLS + ASSERT (hwndDoc, "No doc window") +#endif + + hwndSrvr = GetParent (hwndDoc); + lpsrvr = (LPSRVR) GetWindowLong (hwndSrvr, 0); +#ifdef FIREWALLS + ASSERT (hwndSrvr, "No srvr window") + ASSERT (lpsrvr, "No srvr structure") +#endif + + // delete all the items(objects) for this doc + DeleteAllItems (lpdoc->hwnd); + + // we are terminating. + lpdoc->bTerminate = TRUE; + lpdoc->termNo = 0; + + // send ack if Revoke is done as a result of StdClose + if (lpdoc->fAckClose) { + // Post the acknowledge to the client + if (!PostMessageToClient (lpdoc->hwndClose, WM_DDE_ACK, lpdoc->hwnd, + MAKELONG (0x8000, lpdoc->hDataClose))) + // if the window died or post failed, delete the atom. + GlobalFree (lpdoc->hDataClose); + } + + // Post termination for each of the doc clients. + EnumProps (hwndDoc, lpTerminateDocClients); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (hwndDoc, TRUE); + +#ifdef WAIT_DDE + if (lpdoc->termNo) + WaitForTerminate((LPSRVR)lpdoc); +#endif + + return ReleaseDoc (lpdoc); +} + + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleRenameServerDoc (lhdoc, lpNewName) +* +* OleRenameServerDoc: Changes the name of the document +* +* Parameters: +* 1. DLL Doc handle. +* 2. New name for document +* +* return values: +* returns OLE_OK if the document is successfully renamed +* +* History: +* Srinik: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRenameServerDoc (lhdoc, lpNewName) +LHDOC lhdoc; +LPSTR lpNewName; +{ + LPDOC lpdoc; + OLESTATUS retVal = OLE_OK; + HANDLE hdata; + HWND hStdWnd; + + if (!CheckServerDoc (lpdoc = (LPDOC)lhdoc)) + return OLE_ERROR_HANDLE; + + PROBE_READ(lpNewName); + + if (!(hdata = MakeGlobal (lpNewName))) + return OLE_ERROR_MEMORY; + + if (lpdoc->aDoc) + GlobalDeleteAtom (lpdoc->aDoc); + lpdoc->aDoc = GlobalAddAtom (lpNewName); + + // if StdDocName item is present send rename to relevant clients + if (hStdWnd = SearchItem (lpdoc, (LPSTR) MAKEINTATOM(aStdDocName))) { + if (!MakeDDEData (hdata, (int)cfBinary, (LPHANDLE)&hddeRename,FALSE)) + retVal = OLE_ERROR_MEMORY; + else { + EnumProps (hStdWnd, lpSendRenameMsg); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (hStdWnd, FALSE); + GlobalFree (hddeRename); + + } + } + + + hwndRename = hStdWnd; + // Post termination for each of the doc clients. + EnumProps (lpdoc->hwnd, lpEnumForTerminate); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (lpdoc->hwnd, TRUE); + + // If it was an embedded object, from now on it won't be + lpdoc->fEmbed = FALSE; + + if (!hStdWnd || retVal != OLE_OK) + GlobalFree(hdata); + + // Do link manager stuff + return retVal; +} + + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleSavedServerDoc (lhdoc) +* +* OleSavedServerDoc: Changes the name of the document +* +* Parameters: +* 1. DLL Doc handle. +* +* return values: +* returns OLE_OK if the link manager is successfully notified +* +* History: +* Srinik: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleSavedServerDoc (lhdoc) +LHDOC lhdoc; +{ + LPDOC lpdoc; + + if (!CheckServerDoc (lpdoc = (LPDOC)lhdoc)) + return OLE_ERROR_HANDLE; + + fAdviseSaveDoc = TRUE; + EnumChildWindows (lpdoc->hwnd, lpFindItemWnd, + MAKELONG (NULL, ITEM_SAVED)); + + if (lpdoc->fEmbed && !fAdviseSaveDoc) + return OLE_ERROR_CANT_UPDATE_CLIENT; + + return OLE_OK; +} + + + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleRevertServerDoc (lhdoc) +* +* OleRevertServerDoc: Changes the name of the document +* +* Parameters: +* 1. DLL Doc handle. +* +* return values: +* returns OLE_OK if the link manager has been successfully informed +* +* History: +* Srinik: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRevertServerDoc (lhdoc) +LHDOC lhdoc; +{ + LPDOC lpdoc; + + if (!CheckServerDoc (lpdoc = (LPDOC)lhdoc)) + return OLE_ERROR_HANDLE; + + return OLE_OK; +} + + + +// TerminateDocClients: Call back for the document window for +// enumerating all the clients. Posts terminate for each of +// the clients. + +BOOL FAR PASCAL TerminateDocClients (hwnd, lpstr, hdata) +HWND hwnd; +LPSTR lpstr; +HANDLE hdata; +{ + LPDOC lpdoc; + + lpdoc = (LPDOC)GetWindowLong (hwnd, 0); + if (IsWindowValid ((HWND)hdata)){ + lpdoc->termNo++; + // irrespective of the post, incremet the count, so + // that client does not die. + PostMessageToClientWithBlock ((HWND)hdata, WM_DDE_TERMINATE, hwnd, NULL); + } + else + ASSERT(FALSE, "TERMINATE: Client's Doc channel is missing"); + return TRUE; +} + + +// ReleaseDoc: If there are no more matching terminates pending +// Call the server for its release. (Server might be waiting for the +// docs to be terminated. Called thru OleRevokeServer). + + +int INTERNAL ReleaseDoc (lpdoc) +LPDOC lpdoc; +{ + + HWND hwndSrvr; + HANDLE hdoc; + LPSRVR lpsrvr; + + + // release srvr is called only when everything is + // cleaned and srvr app can post WM_QUIT. + + if (lpdoc->bTerminate && lpdoc->termNo) + return OLE_WAIT_FOR_RELEASE; + + // Call Release for the app to release its space. + + + if (lpdoc->lpoledoc){ + +#ifdef FIREWALLS + if (!CheckPointer (lpdoc->lpoledoc, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOC") + else if (!CheckPointer (lpdoc->lpoledoc->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOCVTBL") + else + ASSERT (lpdoc->lpoledoc->lpvtbl->Release, + "Invalid pointer to Release method") +#endif + (*lpdoc->lpoledoc->lpvtbl->Release) (lpdoc->lpoledoc); + + } + + if (lpdoc->aDoc) { + GlobalDeleteAtom (lpdoc->aDoc); + lpdoc->aDoc = NULL; + } + + hwndSrvr = GetParent (lpdoc->hwnd); + DestroyWindow (lpdoc->hwnd); + + lpsrvr = (LPSRVR)GetWindowLong (hwndSrvr, 0); + + // if the server is waiting for us, inform the server + // we are done + if (!lpsrvr->bTerminate) { + // if we are not in terminate mode, then send advise to the server + // if server can be revoked. raor (04/09) + + if (QueryRelease (lpsrvr)){ + +#ifdef FIREWALLS + if (!CheckPointer (lpsrvr->lpolesrvr, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVER") + else if (!CheckPointer (lpsrvr->lpolesrvr->lpvtbl, + WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpsrvr->lpolesrvr->lpvtbl->Release, + "Invalid pointer to Release method") +#endif + + (*lpsrvr->lpolesrvr->lpvtbl->Release) (lpsrvr->lpolesrvr); + } + + } else + ReleaseSrvr (lpsrvr); + + GlobalUnlock (hdoc = lpdoc->hdoc); + GlobalFree (hdoc); + + return OLE_OK; +} + + +//RevokeAllDocs : revokes all the documents attached to a given +//server. + +int INTERNAL RevokeAllDocs (lpsrvr) +LPSRVR lpsrvr; +{ + + HWND hwnd; + HWND hwndnext; + + hwnd = GetWindow (lpsrvr->hwnd, GW_CHILD); + + // Go thru each of the child windows and revoke the corresponding + // document. Doc windows are child windows for the server window. + + while (hwnd){ + // sequence is important + hwndnext = GetWindow (hwnd, GW_HWNDNEXT); + OleRevokeServerDoc ((LHDOC)GetWindowLong (hwnd, 0)); + hwnd = hwndnext; + } + return OLE_OK; +} + + + +// FindDoc: Given a document, searches for the document +// in the given server document tree. returns true if the +// document is available. + + +LPDOC INTERNAL FindDoc (lpsrvr, lpdocname) +LPSRVR lpsrvr; +LPSTR lpdocname; +{ + + ATOM aDoc; + HWND hwnd; + LPDOC lpdoc; + + aDoc = (ATOM)GlobalFindAtom (lpdocname); + hwnd = GetWindow (lpsrvr->hwnd, GW_CHILD); + + while (hwnd){ + lpdoc = (LPDOC)GetWindowLong (hwnd, 0); + if (lpdoc->aDoc == aDoc) + return lpdoc; + hwnd = GetWindow (hwnd, GW_HWNDNEXT); + } + return NULL; +} + + + +// DocWndProc: document window procedure. +// ### We might be able to merge this code with +// the server window proc. + + +long FAR PASCAL DocWndProc (hwnd, msg, wParam, lParam) +HWND hwnd; +unsigned msg; +WORD wParam; +LONG lParam; +{ + + LPDOC lpdoc; + WORD status = NULL; + HWND hwndClient; + BOOL fack; + HANDLE hdata = NULL; + OLESTATUS retval; + LPSRVR lpsrvr; + + if (AddMessage (hwnd, msg, wParam, lParam, WT_DOC)) + return 0L; + + lpdoc = (LPDOC)GetWindowLong (hwnd, 0); + + switch (msg){ + + + case WM_CREATE: + DEBUG_OUT ("doc create window", 0) + break; + + case WM_DDE_INITIATE: + + DEBUG_OUT ("doc: DDE init",0); + if (lpdoc->bTerminate){ + DEBUG_OUT ("doc: No action due to termination process",0) + break; + } + + // if we are the documnet then respond. + + if (! (lpdoc->aDoc == (ATOM)(HIWORD(lParam)))) + break; + + // We can enterain this client. Put this window in the client list + // and acknowledge the initiate. + + if (!AddClient (hwnd, (HWND)wParam, (HWND)wParam)) + break; + + lpdoc->cClients++; + lpsrvr = (LPSRVR) GetWindowLong (GetParent(lpdoc->hwnd), 0); + + lpsrvr->bnoRelease = FALSE; + + // post the acknowledge + DuplicateAtom (LOWORD(lParam)); + DuplicateAtom (HIWORD(lParam)); + SendMessage ((HWND)wParam, WM_DDE_ACK, (WORD)hwnd, lParam); + + break; + + case WM_DDE_EXECUTE: + + DEBUG_OUT ("doc: execute", 0) +#ifdef FIREWALLS + // find the client in the client list. + hwndClient = FindClient (lpdoc->hwnd, (HWND)wParam); + ASSERT (hwndClient, "Client is missing from the server") +#endif + // Are we terminating + if (lpdoc->bTerminate || !IsWindowValid ((HWND)wParam)) { + DEBUG_OUT ("doc: execute after terminate posted",0) + // !!! are we supposed to free the data + GlobalFree (HIWORD (lParam)); + break; + + } + + retval = DocExecute (hwnd, HIWORD (lParam), (HWND)wParam); + SET_MSG_STATUS (retval, status); + +#ifdef OLD + // if we posted the terminate because of execute, do not send + // ack. + + if (lpdoc->bTerminate) { + // !!! We got close but, we are posting the + // the terminate. Excel does not complain about + // this. But powerpoint complains. +#ifdef POWERPNT_BUG + GlobalFree (HIWORD(lParam)); +#endif + break; + } +#endif + if (!lpdoc->bTerminate) { + // Post the acknowledge to the client + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG(status, HIWORD(lParam)))) + // the window either died or post failed, delete the data + GlobalFree (HIWORD(lParam)); + } + + break; + + case WM_DDE_TERMINATE: + DEBUG_OUT ("doc: DDE terminate",0) + +#ifdef FIREWALLS + // find the client in the client list. + hwndClient = FindClient (lpdoc->hwnd,(HWND)wParam); + ASSERT(hwndClient || lpdoc->termNo, "Client is missing from the server") +#endif + // We do not need this client any more. Delete him from the + // client list. + + DeleteClient (lpdoc->hwnd, (HWND)wParam); + lpdoc->cClients--; + + if (lpdoc->bTerminate){ + lpsrvr = (LPSRVR) GetWindowLong (GetParent(lpdoc->hwnd), 0); + if (!--lpdoc->termNo) + // Release this Doc and may be the server also + // if the server is waiting to be released also. + ReleaseDoc (lpdoc); + } else { + if (lpdoc->termNo == 0){ + + // If client intiated the terminate. Post matching terminate + + PostMessageToClient ((HWND)wParam, WM_DDE_TERMINATE, + hwnd, NULL); + } else + lpdoc->termNo--; + + //Client initiated the termination. So, we shoudl take him + // out from any of our items client lists. + DeleteFromItemsList (lpdoc->hwnd, (HWND)wParam); + + lpsrvr = (LPSRVR)GetWindowLong (GetParent (lpdoc->hwnd), 0); + + if (QueryRelease (lpsrvr)){ + +#ifdef FIREWALLS + if (!CheckPointer (lpsrvr->lpolesrvr, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVER") + else if (!CheckPointer (lpsrvr->lpolesrvr->lpvtbl, + WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpsrvr->lpolesrvr->lpvtbl->Release, + "Invalid pointer to Release method") +#endif + + (*lpsrvr->lpolesrvr->lpvtbl->Release) (lpsrvr->lpolesrvr); + } + + } + break; + + case WM_DESTROY: + DEBUG_OUT ("doc: Destroy window",0) + break; + + case WM_DDE_POKE: { + int iStdItem; + + if (lpdoc->bTerminate || !IsWindowValid ((HWND) wParam)) { + // we are getting pke message after we have posted the + // the termination or the client got deleted. + PokeErr: + FreePokeData ((HANDLE) (LOWORD (lParam))); +#ifdef OLD + GlobalFree ((HANDLE) (LOWORD (lParam))); +#endif + // !!! Are we supposed to delete the atoms also. + PokeErr1: + if (HIWORD(lParam)) + GlobalDeleteAtom (HIWORD(lParam)); + break; + + } + + if (iStdItem = GetStdItemIndex (HIWORD(lParam))) + retval = PokeStdItems (lpdoc, (HWND)wParam, + MAKELONG((LOWORD(lParam)), iStdItem)); + else + retval = PokeData (lpdoc, (HWND)wParam, lParam); + + SET_MSG_STATUS (retval, status); + // !!! If the fRelease is false and the post fails + // then we are not freeing the hdata. Are we supposed to + + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG(status, HIWORD(lParam)))) + goto PokeErr1; + + break; + } + + case WM_DDE_ADVISE: + + fack = TRUE; + + if (lpdoc->bTerminate || !IsWindowValid ((HWND)wParam)) + goto PokeErr; + + if (IsAdviseStdItems (HIWORD(lParam))) + retval = AdviseStdItems (lpdoc, (HWND)wParam, lParam, (BOOL FAR *)&fack); + else + // advise data will not have any OLE_BUSY + retval = AdviseData (lpdoc, (HWND)wParam, lParam, (BOOL FAR *)&fack); + + SET_MSG_STATUS (retval, status); + + if (fack) { + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG(status, HIWORD(lParam)))) + goto PokeErr; + + } + else if ((ATOM)(HIWORD (lParam))) + GlobalDeleteAtom ((ATOM)(HIWORD (lParam))); + + break; + + case WM_DDE_UNADVISE: + if (lpdoc->bTerminate || !IsWindowValid ((HWND)wParam)) + goto PokeErr; + + retval = UnAdviseData (lpdoc, (HWND)wParam, lParam); + SET_MSG_STATUS (retval, status); + + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG(status, HIWORD(lParam)))) + goto PokeErr; + + break; + + case WM_DDE_REQUEST: + + if (lpdoc->bTerminate || !IsWindowValid ((HWND) wParam)) + goto PokeErr1; + + retval = RequestData (lpdoc, (HWND)wParam, lParam, (HANDLE FAR *)&hdata); + + if(retval == OLE_OK) { + // post the data message and we are not asking for any + // acknowledge. + + if (!PostMessageToClient ((HWND)wParam, WM_DDE_DATA, hwnd, + MAKELONG(hdata, HIWORD(lParam)))) { + GlobalFree (hdata); + goto PokeErr1; + } + break; + } + + if (retval == OLE_BUSY) + status = 0x4000; + else + status = 0; + + // if request failed, then acknowledge with error. + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG(status, HIWORD(lParam)))) + goto PokeErr1; + + + break; + + default: + DEBUG_OUT("doc: Default message",0) + return DefWindowProc (hwnd, msg, wParam, lParam); + + } + + return 0L; + +} + +//DocExecute: Interprets the execute command for the +//document conversation. + + +OLESTATUS INTERNAL DocExecute(hwnd, hdata, hwndClient) +HWND hwnd; +HANDLE hdata; +HWND hwndClient; +{ + + ATOM acmd; + BOOL fShow; + BOOL fActivate; + + HANDLE hdup = NULL; + int retval = OLE_ERROR_MEMORY; + LPDOC lpdoc; + LPOLESERVERDOC lpoledoc; + LPCLIENT lpclient = NULL; + + LPSTR lpitemname; + LPSTR lpopt; + LPSTR lpnextarg; + LPSTR lpdata = NULL; + LPSTR lpverb = NULL; + WORD verb; + WORD wCmdType; + + // !!!Can we modify the string which has been passed to us + // rather than duplicating the data. This will get some speed + // and save some space. + + if(!(hdup = DuplicateData(hdata))) + goto errRtn; + + if (!(lpdata = GlobalLock (hdup))) + goto errRtn; + + DEBUG_OUT (lpdata, 0) + + lpdoc = (LPDOC)GetWindowLong (hwnd, 0); + +#ifdef FIREWALLS + ASSERT (lpdoc, "doc: doc does not exist"); +#endif + lpoledoc = lpdoc->lpoledoc; + + retval = OLE_ERROR_SYNTAX; + + if(*lpdata++ != '[') // commands start with the left sqaure bracket + goto errRtn; + + // scan the command and scan upto the first arg. + if (!(wCmdType = ScanCommand(lpdata, WT_DOC, &lpnextarg, &acmd))) + goto errRtn; + + if (wCmdType == NON_OLE_COMMAND) { + LPSRVR lpsrvr; + + if (lpsrvr = (LPSRVR) GetWindowLong (GetParent (hwnd), 0)) { + if (!UtilQueryProtocol (lpsrvr->aClass, PROTOCOL_EXECUTE)) + retval = OLE_ERROR_PROTOCOL; + else { +#ifdef FIREWALLS + if (!CheckPointer (lpoledoc, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOC") + else if (!CheckPointer (lpoledoc->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOCVTBL") + else + ASSERT (lpoledoc->lpvtbl->Execute, + "Invalid pointer to Execute method") +#endif + + retval = (*lpoledoc->lpvtbl->Execute) (lpoledoc, hdata); + } + } + + goto errRtn; + } + + + ////////////////////////////////////////////////////////////////////////// + // + // [StdCloseDocument] + // + ////////////////////////////////////////////////////////////////////////// + if (acmd == aStdClose){ + + // if not terminated by NULL error + if (*lpnextarg) + goto errRtn; + +#ifdef FIREWALLS + if (!CheckPointer (lpoledoc, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOC") + else if (!CheckPointer (lpoledoc->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOCVTBL") + else + ASSERT (lpoledoc->lpvtbl->Close,"Invalid pointer to Close method") +#endif + lpdoc->fAckClose = TRUE; + lpdoc->hwndClose = hwndClient; + lpdoc->hDataClose = hdata; + retval = (*lpoledoc->lpvtbl->Close) (lpoledoc); + lpdoc->fAckClose = FALSE; + goto end; + } + + ////////////////////////////////////////////////////////////////////////// + // + // [StdDoVerbItem("itemname", verb, BOOL, BOOL] + // + ////////////////////////////////////////////////////////////////////////// + if (acmd == aStdDoVerbItem){ + lpitemname = lpnextarg; + + if(!(lpverb = ScanArg(lpnextarg))) + goto errRtn; + + + if(!(lpnextarg = ScanNumArg(lpverb, (LPINT)&verb))) + goto errRtn; + +#ifdef FIREWALLS + ASSERT (verb < 9 , "Unexpected verb number"); +#endif + + // now scan the show BOOL + + if (!(lpnextarg = ScanBoolArg (lpnextarg, (BOOL FAR *)&fShow))) + goto errRtn; + + fActivate = FALSE; + + // if activate BOOL is present, scan it. + + if (*lpnextarg) { + if (!(lpnextarg = ScanBoolArg (lpnextarg, (BOOL FAR *)&fActivate))) + goto errRtn; + } + + if (*lpnextarg) + goto errRtn; + + + retval = DocDoVerbItem (lpdoc, lpitemname, verb, fShow, !fActivate); + goto end; + } + + + + + + ////////////////////////////////////////////////////////////////////////// + // + // [StdShowItem("itemname"[, "true"])] + // + ////////////////////////////////////////////////////////////////////////// + if (acmd != aStdShowItem) + goto errRtn; + + lpitemname = lpnextarg; + + if(!(lpopt = ScanArg(lpitemname))) + goto errRtn; + + // Now scan for optional parameter. + + fActivate = FALSE; + + if (*lpopt) { + + if(!(lpnextarg = ScanBoolArg (lpopt, (BOOL FAR *)&fActivate))) + goto errRtn; + + if (*lpnextarg) + goto errRtn; + + + } + + retval = DocShowItem (lpdoc, lpitemname, !fActivate); + +end: +errRtn: + if (lpdata) + GlobalUnlock (hdup); + + if (hdup) + GlobalFree (hdup); + + return retval; +} + +int INTERNAL DocShowItem (lpdoc, lpitemname, fAct) +LPDOC lpdoc; +LPSTR lpitemname; +BOOL fAct; + +{ + LPCLIENT lpclient; + int retval; + + if ((retval = FindItem (lpdoc, lpitemname, (LPCLIENT FAR *)&lpclient)) + != OLE_OK) + return retval; + +#ifdef FIREWALLS + if (!CheckPointer (lpclient->lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (lpclient->lpoleobject->lpvtbl->Show, + "Invalid pointer to Show method") +#endif + + // protocol sends false for activating and TRUE for not activating. + // for api send TRUE for avtivating and FALSE for not activating. + + return (*lpclient->lpoleobject->lpvtbl->Show)(lpclient->lpoleobject, fAct); +} + + +int INTERNAL DocDoVerbItem (lpdoc, lpitemname, verb, fShow, fAct) +LPDOC lpdoc; +LPSTR lpitemname; +WORD verb; +BOOL fShow; +BOOL fAct; +{ + LPCLIENT lpclient; + int retval = OLE_ERROR_PROTOCOL; + + if ((retval = FindItem (lpdoc, lpitemname, (LPCLIENT FAR *)&lpclient)) + != OLE_OK) + return retval; + +#ifdef FIREWALLS + if (!CheckPointer (lpclient->lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (lpclient->lpoleobject->lpvtbl->DoVerb, + "Invalid pointer to Run method") +#endif + + // pass TRUE to activate and False not to activate. Differnt from + // protocol. + + retval = (*lpclient->lpoleobject->lpvtbl->DoVerb)(lpclient->lpoleobject, verb, fShow, fAct); + + return retval; +} + + + +// FreePokeData: Frees the poked dats. +void INTERNAL FreePokeData (hdde) +HANDLE hdde; +{ + DDEPOKE FAR * lpdde; + + if (hdde) { + if (lpdde = (DDEPOKE FAR *) GlobalLock (hdde)) { + GlobalUnlock (hdde); + FreeGDIdata (*(LPHANDLE)lpdde->Value, lpdde->cfFormat); + } + + GlobalFree (hdde); + } +} + + + +// Returns TRUE if GDI format else returns FALSE + +BOOL INTERNAL FreeGDIdata (hData, cfFormat) +HANDLE hData; +OLECLIPFORMAT cfFormat; +{ + if (cfFormat == CF_METAFILEPICT) { + LPMETAFILEPICT lpMfp; + + if (lpMfp = (LPMETAFILEPICT) GlobalLock (hData)) { + GlobalUnlock (hData); + DeleteMetaFile (lpMfp->hMF); + } + + GlobalFree (hData); + } + else if (cfFormat == CF_BITMAP) + DeleteObject (hData); + else if (cfFormat == CF_DIB) + GlobalFree (hData); + else + return FALSE; + + return TRUE; +} diff --git a/private/mvdm/wow16/ole/server/give2gdi.asm b/private/mvdm/wow16/ole/server/give2gdi.asm new file mode 100644 index 000000000..e35ef987d --- /dev/null +++ b/private/mvdm/wow16/ole/server/give2gdi.asm @@ -0,0 +1,111 @@ + ;\ + ; give2gdi.asm + ; + ; Copyright (C) 1991, MicroSoft Corporation + ; + ; Contains code which changes memory metafile ownership to GDI + ; + ; History: sriniK 05/22/1991 + ;/ + + +include cmacros.inc +include windows.inc + +.286 + + +;**************************** Data Segment ******************************** + +sBegin data + assumes ds, data + +szGDI db 'GDI', 0 +szWEP db 'WEP', 0 + +sEnd data + + +;*************************** Code Segment ********************************* + +externFP GlobalRealloc +externFP GlobalSize +externFP GetModuleHandle +externFP GetProcAddress + +createSeg Give2GDI, Give2GDI, para, public, code + +sBegin Give2GDI + assumes cs,Give2GDI + assumes ds,data + assumes es,nothing + +;**************************** Public Functions **************************** + +cProc GiveToGDI, <PUBLIC,FAR> +; +; +; HANDLE FAR PASCAL GiveToGDI(HANDLE hMem) +; +; Assign ownership of the given global memory block to GDI +; +; returns a handle to the memory block if successful, otherwise returns NULL +; + + parmW hMem + + localD lpGDIWEP +cBegin + ;************************************************************* + ;** Get address of retf in fixed GDI code segment ** + ;************************************************************* + + push ds + push dataOFFSET szGDI + cCall GetModuleHandle + + push ax + push ds + push dataOFFSET szWEP + cCall GetProcAddress + + mov [word ptr lpGDIWEP[0]], ax + mov [word ptr lpGDIWEP[2]], dx + + ;************************************************************* + ;** Kludge a call to GlobalReAlloc with GDI as caller ** + ;************************************************************* + + push 0 ; Params for WEP + + push cs ; GDI's WEP returns here + push offset ReturnHere + + push hMem ; Params to GlobalReAlloc + push 0 + push 0 + push [GMEM_MOVEABLE or GMEM_SHARE or GMEM_MODIFY] + + push [word ptr lpGDIWEP[2]] ; GlobalReAlloc returns here + push [word ptr lpGDIWEP[0]] ; GlobalReAlloc returns here + + push 0 ; Params for WEP + + push seg GlobalReAlloc ; GDI's WEP returns here + push offset GlobalReAlloc + + jmp lpGDIWEP ; Dive off the end +ReturnHere: + ;************************************************************* + ;** Return handle to reallocated block ** + ;************************************************************* + + mov ax,hMem +cEnd + +;************************************************************************* + +sEnd Give2GDI +end + +;************************************************************************* diff --git a/private/mvdm/wow16/ole/server/item.c b/private/mvdm/wow16/ole/server/item.c new file mode 100644 index 000000000..c41d3c70d --- /dev/null +++ b/private/mvdm/wow16/ole/server/item.c @@ -0,0 +1,1771 @@ +/****************************** Module Header ******************************\ +* Module Name: Item.c Object(item) main module +* +* Purpose: Includes All the object releated routiens. +* +* Created: Oct 1990. +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor (../10/1990) Designed, coded +* +* +\***************************************************************************/ + + +#include "cmacs.h" +#include "windows.h" +#include "ole.h" +#include "dde.h" +#include "srvr.h" + +extern HANDLE hdllInst; +extern FARPROC lpFindItemWnd; +extern FARPROC lpItemCallBack; +extern FARPROC lpSendDataMsg; +extern FARPROC lpSendRenameMsg; +extern FARPROC lpDeleteClientInfo; +extern FARPROC lpEnumForTerminate; + + +extern ATOM cfNative; +extern ATOM cfBinary; +extern ATOM aClose; +extern ATOM aChange; +extern ATOM aSave; +extern ATOM aEditItems; +extern ATOM aStdDocName; + +extern WORD cfLink; +extern WORD cfOwnerLink; + +extern BOOL bWin30; + +HWND hwndItem; +HANDLE hddeRename; +HWND hwndRename; + +WORD enummsg; +WORD enuminfo; +LPOLEOBJECT enumlpoleobject; +OLECLIENTVTBL clVtbl; +BOOL bClientUnlink; + +BOOL fAdviseSaveDoc; +BOOL fAdviseSaveItem; + +char * stdStrTable[STDHOSTNAMES+1] = {NULL, + "StdTargetDevice", + "StdDocDimensions", + "StdColorScheme", + "StdHostNames"}; + + +extern HANDLE (FAR PASCAL *lpfnSetMetaFileBitsBetter) (HANDLE); + +void ChangeOwner (HANDLE hmfp); + +// !!!change child enumeration. +// !!!No consistency in errors (Sometimes Bools and sometimes OLESTATUS). + + +//SearchItem: Searches for a given item in a document tree. +//If found, returns the corresponding child windows handle. + +HWND INTERNAL SearchItem (lpdoc, lpitemname) +LPDOC lpdoc; +LPSTR lpitemname; +{ + ATOM aItem; + + Puts ("SearchItem"); + + // If the item passed is an atom, get its name. + if (!HIWORD(lpitemname)) + aItem = (ATOM) (LOWORD((DWORD)lpitemname)); + else if (!lpitemname[0]) + aItem = NULL; + else + aItem = GlobalFindAtom (lpitemname); + + hwndItem = NULL; + + // !!! We should avoid hwndItem static. It should not cause + // any problems since while enumerating we will not be calling + // any window procs or no PostMessages are entertained. + + EnumChildWindows (lpdoc->hwnd, lpFindItemWnd, + MAKELONG (aItem, ITEM_FIND)); + + return hwndItem; + +} + +// FindItem: Given the itemname and the document handle, +// searches for the the item (object) in the document tree. +// Items are child windows for the document window. + +// !!! change the child windows to somekind of +// linked lists at the item level. This will free up +// the space taken by the item windows. + +int INTERNAL FindItem (lpdoc, lpitemname, lplpclient) +LPDOC lpdoc; +LPSTR lpitemname; +LPCLIENT FAR * lplpclient; +{ + LPCLIENT lpclient; + HWND hwnd; + char buf[MAX_STR]; + + Puts ("FindItem"); + + hwnd = SearchItem (lpdoc, lpitemname); + + if (!HIWORD(lpitemname)){ + if (LOWORD(lpitemname)) + GlobalGetAtomName ((ATOM)LOWORD((DWORD)lpitemname), + (LPSTR)buf, MAX_STR); + else + buf[0] = NULL; + + lpitemname = (LPSTR)buf; + } + + if (hwnd) { + // we found the item window + lpclient = (LPCLIENT)GetWindowLong (hwnd, 0); + +#ifdef FIREWALLS + ASSERT ((CheckPointer(lpclient, WRITE_ACCESS)), + "In Item the client handle missing") + ASSERT ((CheckPointer(lpclient->lpoleobject, WRITE_ACCESS)), + "In Item object handle missing") + +#endif + *lplpclient = lpclient; + return OLE_OK; + + } + + // Item (object)window is not create yet. Let us create one. + return RegisterItem ((LHDOC)lpdoc, lpitemname, lplpclient, TRUE); +} + + + +//RegisterItem: Given the document handle and the item string +//creates item with the given document. + +int INTERNAL RegisterItem (lhdoc, lpitemname, lplpclient, bSrvr) +LHDOC lhdoc; +LPSTR lpitemname; +LPCLIENT FAR * lplpclient; +BOOL bSrvr; +{ + + + LPDOC lpdoc; + HANDLE hclient = NULL; + LPCLIENT lpclient = NULL; + int retval = OLE_ERROR_MEMORY; + LPOLESERVERDOC lpoledoc; + LPOLEOBJECT lpoleobject = NULL; + + + Puts ("CreateItem"); + + lpdoc = (LPDOC)lhdoc; + +#ifdef FIREWALLS + ASSERT ((CheckPointer (lplpclient, WRITE_ACCESS)), "invalid lplpclient"); +#endif + + // First create the callback client structure. + + hclient = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE, sizeof (CLIENT)); + if(!(hclient && (lpclient = (LPCLIENT)GlobalLock (hclient)))) + goto errRtn; + + lpclient->hclient = hclient; + hclient = NULL; + + if (!HIWORD(lpitemname)) { + ASSERT (!bSrvr, "invalid lpitemname in RegisterItem\n"); + lpclient->aItem = LOWORD((DWORD)lpitemname); + } + else if (!lpitemname[0]) + lpclient->aItem = NULL; + else + lpclient->aItem = GlobalAddAtom (lpitemname); + + lpclient->oleClient.lpvtbl = &clVtbl; + lpclient->oleClient.lpvtbl->CallBack = lpItemCallBack; + + lpoledoc = lpdoc->lpoledoc; + + // Call the server app to create its own object structure and link + // it to the given document. + + // Call the server if the item is not one of the standard items. + + if (bSrvr) { + retval = (*lpoledoc->lpvtbl->GetObject)(lpoledoc, lpitemname, + (LPOLEOBJECT FAR *)&lpoleobject, (LPOLECLIENT)lpclient); + if (retval != OLE_OK) + goto errRtn; + } + + lpclient->lpoleobject = lpoleobject; + + lpclient->hwnd = CreateWindow ("ItemWndClass", "ITEM", + WS_CHILD,0,0,0,0,lpdoc->hwnd,NULL, hdllInst, NULL); + + if (lpclient->hwnd == NULL) + goto errRtn; + + // save the ptr to the item in the window. + SetWindowLong (lpclient->hwnd, 0, (LONG)lpclient); + *lplpclient = lpclient; + return OLE_OK; + +errRtn: + + if (lpclient) + RevokeObject ((LPOLECLIENT)lpclient, FALSE); + + else { + if(hclient) + GlobalFree (hclient); + } + + return retval; + +} + + +OLESTATUS FAR PASCAL OleRevokeObject (lpoleclient) +LPOLECLIENT lpoleclient; +{ + return RevokeObject (lpoleclient, TRUE); + +} +// OleRevokeObject: Revokes an object (unregisres an object +// from the document tree. + +OLESTATUS INTERNAL RevokeObject (lpoleclient, bUnlink) +LPOLECLIENT lpoleclient; +BOOL bUnlink; +{ + + HANDLE hclient; + LPCLIENT lpclient; + + lpclient = (LPCLIENT)lpoleclient; + + PROBE_WRITE(lpoleclient); + if (lpclient->lpoleobject) { + // first call the object for deletetion. + +#ifdef FIREWALLS + if (!CheckPointer (lpclient->lpoleobject, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBECT") + + if (!CheckPointer (lpclient->lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT(lpclient->lpoleobject->lpvtbl->Release, + "Invalid pointer to Release method") +#endif + + (*lpclient->lpoleobject->lpvtbl->Release)(lpclient->lpoleobject); + + } + + if (ISATOM(lpclient->aItem)) { + GlobalDeleteAtom (lpclient->aItem); + lpclient->aItem = NULL; + } + + if (lpclient->hwnd) { + SetWindowLong (lpclient->hwnd, 0, (LONG)NULL); + + // another static for enumerating the properties. + // we need to change these . + bClientUnlink = bUnlink; + + EnumProps(lpclient->hwnd, lpDeleteClientInfo); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (lpclient->hwnd, FALSE); + DestroyWindow (lpclient->hwnd); + } + + GlobalUnlock (hclient = lpclient->hclient); + GlobalFree (hclient); + return OLE_OK; + +} + +BOOL FAR PASCAL DeleteClientInfo (hwnd, lpstr, hclinfo) +HWND hwnd; +LPSTR lpstr; +HANDLE hclinfo; +{ + PCLINFO pclinfo = NULL; + HWND hwndDoc; + LPDOC lpdoc; + +#ifdef FIREWALLS + ASSERT (hclinfo, "Client info null in item property list"); +#endif + + + // delete the printer dev info block + if(pclinfo = (PCLINFO)LocalLock (hclinfo)){ + if(pclinfo->hdevInfo) + GlobalFree (pclinfo->hdevInfo); + + + if (bClientUnlink) { + // terminate the conversation for the client. + TerminateDocClients ((hwndDoc = GetParent(hwnd)), NULL, pclinfo->hwnd); + lpdoc = (LPDOC)GetWindowLong (hwndDoc, 0); + // for some reason this delete is gving circular lists for properties + + //DeleteClient (hwndDoc, pclinfo->hwnd); + //lpdoc->cClients--; + } + LocalUnlock (hclinfo); + } + LocalFree (hclinfo); + RemoveProp (hwnd, lpstr); + return TRUE; +} + + + + +// Call back for the Object windows numeration. data field +// has the command and the extra information + + +BOOL FAR PASCAL FindItemWnd (hwnd, data) +HWND hwnd; +LONG data; +{ + + LPCLIENT lpclient; + int cmd; + HANDLE hclinfo; + PCLINFO pclinfo; + + + lpclient = (LPCLIENT)GetWindowLong (hwnd, 0); + +#ifdef FIREWALLS + // ASSERT (lpclient, "In Item the client handle missing") +#endif + + cmd = HIWORD(data); + switch (cmd) { + case ITEM_FIND: + if (lpclient->aItem == (ATOM)(LOWORD (data))) { + // we found the window we required. Remember the + // object window. + + hwndItem = hwnd; + return FALSE; // terminate enumeration. + + } + break; + + case ITEM_SAVED: + if (lpclient->lpoleobject) { + if (ItemCallBack ((LPOLECLIENT) lpclient, OLE_SAVED, + lpclient->lpoleobject) == OLE_ERROR_CANT_UPDATE_CLIENT) + fAdviseSaveDoc = FALSE; + } + break; + + case ITEM_DELETECLIENT: + + // delete the client from our list if we have one + + hclinfo = FindClient (hwnd, (HWND) (LOWORD(data))); + if (hclinfo){ + // delete the printer dev info block + if(pclinfo = (PCLINFO)LocalLock (hclinfo)){ + if(pclinfo->hdevInfo) + GlobalFree (pclinfo->hdevInfo); + LocalUnlock (hclinfo); + } + LocalFree (hclinfo); + DeleteClient ( hwnd, (HWND) (LOWORD(data))); + } + break; + + case ITEM_DELETE: + // delete the client it self. + RevokeObject ((LPOLECLIENT)lpclient, FALSE); + break; + + } + return TRUE; // continue enumeration. +} + + + +//DeleteFromItemsList: Deletes a client from the object lists of +//all the objects of a given document. Thie client possibly +//is terminating the conversation with our doc window. + + +void INTERNAL DeleteFromItemsList (hwndDoc, hwndClient) +HWND hwndDoc; +HWND hwndClient; +{ + + EnumChildWindows (hwndDoc, lpFindItemWnd, + MAKELONG (hwndClient, ITEM_DELETECLIENT)); + +} + + +// DeleteAllItems: Deletes all the objects of a given +// document window. + + +void INTERNAL DeleteAllItems (hwndDoc) +HWND hwndDoc; +{ + + EnumChildWindows (hwndDoc, lpFindItemWnd, + MAKELONG (NULL, ITEM_DELETE)); + +} + + +// Object widnow proc: + +long FAR PASCAL ItemWndProc(hwnd, msg, wParam, lParam) +HWND hwnd; +unsigned msg; +WORD wParam; +LONG lParam; +{ + + LPCLIENT lpclient; + + lpclient = (LPCLIENT)GetWindowLong (hwnd, 0); + + switch (msg) { + case WM_DESTROY: + DEBUG_OUT("Item: Destroy window",0) + +#ifdef FIREWALLS + ASSERT (!lpclient, "while destroy Item client is not null") +#endif + break; + default: + DEBUG_OUT("item: Default message",0) + return DefWindowProc (hwnd, msg, wParam, lParam); + + } + return 0L; + +} + +// PokeData: Prepares and gives the data to the server app thru +// the SetData object method. + +OLESTATUS INTERNAL PokeData (lpdoc, hwndClient, lparam) +LPDOC lpdoc; +HWND hwndClient; +LONG lparam; +{ + int retval = OLE_ERROR_MEMORY; + LPCLIENT lpclient; + DDEPOKE FAR * lpPoke = NULL; + HANDLE hPoke = NULL; + HANDLE hnew = NULL; + int format; + BOOL fRelease = FALSE; + + // Get the object handle first. Look in the registration + // tree and if one is not created otherwise create one. + + retval = FindItem (lpdoc, (LPSTR) MAKEINTATOM(HIWORD(lparam)), + (LPCLIENT FAR *)&lpclient); + + if (retval != OLE_OK) + goto errRtn; + + hPoke = (HANDLE)(LOWORD (lparam)); + if(!(hPoke && (lpPoke = (DDEPOKE FAR *) GlobalLock (hPoke)))) + goto errRtn; + + GlobalUnlock (hPoke); + + format = lpPoke->cfFormat; + fRelease = lpPoke->fRelease; + + // We found the item. Now prepare the data to be given to the object + if (!(hnew = MakeItemData (lpPoke, hPoke, format))) + goto errRtn; + + // Now send the data to the object + +#ifdef FIREWALLS + if (!CheckPointer (lpclient->lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (lpclient->lpoleobject->lpvtbl->SetData, + "Invalid pointer to SetData method") +#endif + + retval = (*lpclient->lpoleobject->lpvtbl->SetData) (lpclient->lpoleobject, + format, hnew); + + // We free the data if server returns OLE_ERROR_SETDATA_FORMAT. + // Otherwise server must've deleted it. + + if (retval == OLE_ERROR_SETDATA_FORMAT) { + if (!FreeGDIdata (hnew, format)) + GlobalFree (hnew); + } + + +errRtn: + if (retval == OLE_OK && fRelease) { + if (hPoke) + GlobalFree (hPoke); + } + + return retval; +} + + + + +OLESTATUS INTERNAL UnAdviseData (lpdoc, hwndClient, lparam) +LPDOC lpdoc; +HWND hwndClient; +LONG lparam; +{ + + + char buf[MAX_STR]; + int options; + LPCLIENT lpclient; + int retval = OLE_ERROR_MEMORY; + HANDLE hclinfo = NULL; + PCLINFO pclinfo = NULL; + + if (!(HIWORD (lparam))) + buf[0] = NULL; + else + GlobalGetAtomName ((ATOM)(HIWORD (lparam)), (LPSTR)buf, MAX_STR); + + // Scan for the advise options like "Close", "Save" etc + // at the end of the item. + + if((retval = ScanItemOptions ((LPSTR)buf, (int far *)&options)) != + OLE_OK) + goto errRtn; + + + if (buf[0] == NULL) { + // Unadvise for null should terminate all the advises + DeleteFromItemsList (lpdoc->hwnd, hwndClient); + return OLE_OK; + } + + // Now get the corresponding object. + retval = FindItem (lpdoc, (LPSTR)buf, (LPCLIENT FAR *)&lpclient); + if (retval != OLE_OK) + goto errRtn; + + + // Find the client structure to be attcahed to the object. + if ((hclinfo = FindClient (lpclient->hwnd, hwndClient)) == NULL || + (pclinfo = (PCLINFO) LocalLock (hclinfo)) == NULL ){ + retval = OLE_ERROR_MEMORY; + goto errRtn; + } + + pclinfo->options &= (~(0x0001 << options)); + +errRtn: + if (pclinfo) + LocalUnlock (hclinfo); + return retval; + +} + + + +// AdviseStdItems: This routine takes care of the DDEADVISE for a +//particular object in given document. Creates a client strutcure +//and attaches to the property list of the object window. + +OLESTATUS INTERNAL AdviseStdItems (lpdoc, hwndClient, lparam, lpfack) +LPDOC lpdoc; +HWND hwndClient; +LONG lparam; +BOOL FAR * lpfack; +{ + + HANDLE hopt = NULL; + DDEADVISE FAR *lpopt; + OLESTATUS retval = OLE_ERROR_MEMORY; + + + hopt = (HANDLE) (LOWORD (lparam)); + if(!(lpopt = (DDEADVISE FAR *) GlobalLock (hopt))) + goto errrtn; + +#ifdef FIREWALLS + ASSERT ((ATOM) (HIWORD (lparam) == aStdDocName), "AdviseStdItem is not Documentname"); +#endif + + *lpfack = lpopt->fAckReq; + retval = SetStdInfo (lpdoc, hwndClient, (LPSTR)"StdDocumentName", NULL); + + if (lpopt) + GlobalUnlock (hopt); + +errrtn: + + if (retval == OLE_OK) + // !!! make sure that we have to free the data for error case + GlobalFree (hopt); + return retval; +} + + + +//AdviseData: This routine takes care of the DDEADVISE for a +//particular object in given document. Creates a client strutcure +//and attaches to the property list of the object window. + +OLESTATUS INTERNAL AdviseData (lpdoc, hwndClient, lparam, lpfack) +LPDOC lpdoc; +HWND hwndClient; +LONG lparam; +BOOL FAR * lpfack; +{ + + + HANDLE hopt = NULL; + DDEADVISE FAR *lpopt = NULL; + int format = NULL; + char buf[MAX_STR]; + int options; + LPCLIENT lpclient; + int retval = OLE_ERROR_MEMORY; + HANDLE hclinfo = NULL; + PCLINFO pclinfo = NULL; + + + + hopt = (HANDLE) (LOWORD (lparam)); + if(!(lpopt = (DDEADVISE FAR *) GlobalLock (hopt))) + goto errRtn; + + if (!(HIWORD (lparam))) + buf[0] = NULL; + else + GlobalGetAtomName ((ATOM)(HIWORD (lparam)), (LPSTR)buf, MAX_STR); + + // Scan for the advise options like "Close", "Save" etc + // at the end of the item. + + if((retval = ScanItemOptions ((LPSTR)buf, (int far *)&options)) != + OLE_OK) + goto errRtn; + + + // Now get the corresponding object. + retval = FindItem (lpdoc, (LPSTR)buf, (LPCLIENT FAR *)&lpclient); + if (retval != OLE_OK) + goto errRtn; + + if (!IsFormatAvailable (lpclient, lpopt->cfFormat)){ + retval = OLE_ERROR_DATATYPE; // this format is not supported; + goto errRtn; + } + + *lpfack = lpopt->fAckReq; + + // Create the client structure to be attcahed to the object. + if (!(hclinfo = FindClient (lpclient->hwnd, hwndClient))) + hclinfo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (CLINFO)); + + if (hclinfo == NULL || (pclinfo = (PCLINFO) LocalLock (hclinfo)) == NULL){ + retval = OLE_ERROR_MEMORY; + goto errRtn; + } + + // Remember the client window (Needed for sending DATA later on + // when the data change message comes from the server) + + pclinfo->hwnd = hwndClient; + if (lpopt->cfFormat == (int)cfNative) + pclinfo->bnative = TRUE; + else + pclinfo->format = lpopt->cfFormat; + + // Remeber the data transfer options. + pclinfo->options |= (0x0001 << options); + pclinfo->bdata = !lpopt->fDeferUpd; + LocalUnlock (hclinfo); + pclinfo = NULL; + + + // if the entry exists already, delete it. + DeleteClient (lpclient->hwnd, hwndClient); + + // Now add this client to item client list + // !!! This error recovery is not correct. + if(!AddClient (lpclient->hwnd, hwndClient, hclinfo)) + goto errRtn; + + +errRtn: + if (lpopt) + GlobalUnlock (hopt); + + if (pclinfo) + LocalUnlock (hclinfo); + + if (retval == OLE_OK) { + // !!! make sure that we have to free the data + GlobalFree (hopt); + + }else { + if (hclinfo) + LocalFree (hclinfo); + } + return retval; + +} + +BOOL INTERNAL IsFormatAvailable (lpclient, cfFormat) +LPCLIENT lpclient; +OLECLIPFORMAT cfFormat; +{ + OLECLIPFORMAT cfNext = 0; + + + do{ + +#ifdef FIREWALLS + if (!CheckPointer (lpclient->lpoleobject, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBECT") + else if (!CheckPointer (lpclient->lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (lpclient->lpoleobject->lpvtbl->EnumFormats, + "Invalid pointer to EnumFormats method") +#endif + + cfNext = (*lpclient->lpoleobject->lpvtbl->EnumFormats) + (lpclient->lpoleobject, cfNext); + if (cfNext == cfFormat) + return TRUE; + + }while (cfNext != 0); + + return FALSE; +} + +//ScanItemOptions: Scan for the item options like Close/Save etc. + +OLESTATUS INTERNAL ScanItemOptions (lpbuf, lpoptions) +LPSTR lpbuf; +int far *lpoptions; +{ + + ATOM aModifier; + + *lpoptions = OLE_CHANGED; + while ( *lpbuf && *lpbuf != '/') + lpbuf++; + + // no modifier same as /change + + if (*lpbuf == NULL) + return OLE_OK; + + *lpbuf++ = NULL; // seperate out the item string + // We are using this in the caller. + + if (!(aModifier = GlobalFindAtom (lpbuf))) + return OLE_ERROR_SYNTAX; + + if (aModifier == aChange) + return OLE_OK; + + // Is it a save? + if (aModifier == aSave){ + *lpoptions = OLE_SAVED; + return OLE_OK; + } + // Is it a Close? + if (aModifier == aClose){ + *lpoptions = OLE_CLOSED; + return OLE_OK; + } + + // unknow modifier + return OLE_ERROR_SYNTAX; + +} + +//RequestData: Sends data in response to a DDE Request message. +// for agiven doc and an object. + +OLESTATUS INTERNAL RequestData (lpdoc, hwndClient, lparam, lphdde) +LPDOC lpdoc; +HWND hwndClient; +LONG lparam; +LPHANDLE lphdde; +{ + + OLESTATUS retval = OLE_OK; + HANDLE hdata; + LPCLIENT lpclient; + char buf[6]; + + // If edit environment Send data if we can + if ((HIWORD (lparam)) == aEditItems) + return RequestDataStd (lparam, lphdde); + + // Get the object. + retval = FindItem (lpdoc, (LPSTR) MAKEINTATOM(HIWORD(lparam)), + (LPCLIENT FAR *)&lpclient); + if (retval != OLE_OK) + goto errRtn; + + retval = OLE_ERROR_DATATYPE; + if (!IsFormatAvailable (lpclient, (int)(LOWORD (lparam)))) + goto errRtn; + + // Now ask the item for the given format data + +#ifdef FIREWALLS + ASSERT (lpclient->lpoleobject->lpvtbl->GetData, + "Invalid pointer to GetData method") +#endif + + MapToHexStr ((LPSTR)buf, hwndClient); + SendDevInfo (lpclient, (LPSTR)buf); + + retval = (*lpclient->lpoleobject->lpvtbl->GetData) (lpclient->lpoleobject, + (int)(LOWORD (lparam)), (LPHANDLE)& hdata); + + if (retval != OLE_OK) + goto errRtn; + + if (LOWORD(lparam) == CF_METAFILEPICT) + ChangeOwner (hdata); + + // Duplicate the DDE data + if(MakeDDEData(hdata, (int)(LOWORD (lparam)), lphdde, TRUE)){ + // !!! Why do we have to duplicate the atom + DuplicateAtom ((ATOM)(HIWORD (lparam))); + return OLE_OK; + } + else + return OLE_ERROR_MEMORY; + +errRtn: + return retval; + +} + +//MakeDDEData: Create a Global DDE data handle from the server +// app data handle. + +BOOL INTERNAL MakeDDEData (hdata, format, lph, fResponse) +HANDLE hdata; +LPHANDLE lph; +int format; +BOOL fResponse; +{ + DWORD size; + HANDLE hdde = NULL; + DDEDATA FAR *lpdata= NULL; + BOOL bnative; + LPSTR lpdst; + LPSTR lpsrc; + + if (!hdata) { + *lph = NULL; + return TRUE; + } + + if (bnative = !(format == CF_METAFILEPICT || format == CF_DIB || + format == CF_BITMAP)) + size = GlobalSize (hdata) + sizeof (DDEDATA); + else + size = sizeof (LONG) + sizeof (DDEDATA); + + + hdde = (HANDLE) GlobalAlloc (GMEM_DDESHARE | GMEM_ZEROINIT, size); + if (hdde == NULL || (lpdata = (DDEDATA FAR *) GlobalLock (hdde)) == NULL) + goto errRtn; + + // set the data otions. Ask the client to delete + // it always. + + lpdata->fRelease = TRUE; // release the data + lpdata->cfFormat = format; + lpdata->fResponse = fResponse; + + if (!bnative) + // If not native, stick in the handle what the server gave us. + *(LPHANDLE)lpdata->Value = hdata; + + else { + // copy the native data junk here. + lpdst = (LPSTR)lpdata->Value; + if(!(lpsrc = (LPSTR)GlobalLock (hdata))) + goto errRtn; + + size -= sizeof (DDEDATA); + UtilMemCpy (lpdst, lpsrc, size); + GlobalUnlock (hdata); + GlobalFree (hdata); + + } + + GlobalUnlock (hdde); + *lph = hdde; + return TRUE; + +errRtn: + if (lpdata) + GlobalUnlock (hdde); + + if (hdde) + GlobalFree (hdde); + + if (bnative) + GlobalFree (hdata); + + return FALSE; +} + + +// ItemCallback: Calback routine for the server to inform the +// data changes. When the change message is received, DDE data +// message is sent to each of the clients depending on the +// options. + +int FAR PASCAL ItemCallback (lpoleclient, msg, lpoleobject) +LPOLECLIENT lpoleclient; +WORD msg; // notification message +LPOLEOBJECT lpoleobject; +{ + + LPCLIENT lpclient; + int retval = OLE_OK; + HANDLE hdata = NULL; + LPSTR lpdata = NULL; + LPDOC lpdoc; + HWND hStdWnd; + + lpclient = (LPCLIENT)lpoleclient; + lpdoc = (LPDOC)GetWindowLong (GetParent (lpclient->hwnd), 0); + + if (msg == OLE_RENAMED) { +#ifdef FIREWALLS + if (!CheckPointer (lpoleobject, WRITE_ACCESS)) + ASSERT (0, "Invalid lpoleobject") + else if (!CheckPointer (lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (lpoleobject->lpvtbl->GetData, + "Invalid pointer to GetData method") +#endif + + if (IsFormatAvailable (lpclient, cfLink)) { + + // Get the link data. + + retval = (*lpoleobject->lpvtbl->GetData) (lpoleobject, + (int)cfLink, (LPHANDLE)&hdata); + } + else { + if(IsFormatAvailable (lpclient, cfOwnerLink)) { + + // Get the link data. + retval = (*lpoleobject->lpvtbl->GetData) (lpoleobject, + (int)cfOwnerLink, (LPHANDLE)& hdata); +#ifdef FIREWALLS + ASSERT (retval != OLE_BUSY, "Getdata returns with OLE_BUSY") +#endif + + + } else + retval = OLE_ERROR_DATATYPE; + } + + if (retval != OLE_OK) + goto errrtn; + + if (!(lpdata = (LPSTR)GlobalLock (hdata))) + goto errrtn; + + if (lpdoc->aDoc) { + GlobalDeleteAtom (lpdoc->aDoc); + lpdoc->aDoc = NULL; + } + + // Move the string to the beginning and still terminated by null; + lstrcpy (lpdata, lpdata + lstrlen (lpdata) + 1); + lpdoc->aDoc = GlobalAddAtom (lpdata); + + // Now make the DDE data block + GlobalUnlock (hdata); + lpdata = NULL; + + // find if any StdDocName item is present at all + if (!(hStdWnd = SearchItem (lpdoc, (LPSTR) MAKEINTATOM(aStdDocName)))) + GlobalFree (hdata); + else { + + // hdata is freed by Makeddedata + if (!MakeDDEData (hdata, (int)cfBinary, (LPHANDLE)&hddeRename, + FALSE)) { + retval = OLE_ERROR_MEMORY; + goto errrtn; + } + + EnumProps(hStdWnd, lpSendRenameMsg); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (hStdWnd, FALSE); + GlobalFree (hddeRename); + } + + // static. Avoid this. This may not cause any problems for now. + // if there is any better way, change it. + hwndRename = hStdWnd; + + // Post termination for each of the doc clients. + EnumProps (lpdoc->hwnd, lpEnumForTerminate); + + lpdoc->fEmbed = FALSE; + + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (lpdoc->hwnd, FALSE); + return OLE_OK; + + errrtn: + if (lpdata) + GlobalUnlock (hdata); + + if (hdata) + GlobalFree (hdata); + + return retval; + + } else { + + // !!! any better way to do instead of putting in static + // (There may not be any problems since we are not allowing + // any messages to get thru while we are posting messages). + + + if ((enummsg = msg) == OLE_SAVED) + fAdviseSaveItem = FALSE; + + enumlpoleobject = lpoleobject; + +#ifdef FIREWALLS + ASSERT (lpclient->hwnd && IsWindowValid (lpclient->hwnd), " Not valid object") +#endif + + // Enumerate all the clients and send DDE_DATA if necessary. + EnumProps(lpclient->hwnd, lpSendDataMsg); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (lpclient->hwnd, FALSE); + + if ((msg == OLE_SAVED) && lpdoc->fEmbed && !fAdviseSaveItem) + return OLE_ERROR_CANT_UPDATE_CLIENT; + + return OLE_OK; + } +} + + +BOOL FAR PASCAL EnumForTerminate (hwnd, lpstr, hdata) +HWND hwnd; +LPSTR lpstr; +HANDLE hdata; +{ + + LPDOC lpdoc; + + lpdoc = (LPDOC)GetWindowLong (hwnd , 0); + + // This client is in the rename list. So, no terminate + if(hwndRename && FindClient (hwndRename, (HWND)hdata)) + return TRUE; + + + if (PostMessageToClientWithBlock ((HWND)hdata, WM_DDE_TERMINATE, hwnd, NULL)) + lpdoc->termNo++; + + //DeleteClient (hwnd, (HWND)hdata); + //lpdoc->cClients--; + return TRUE; +} + + +BOOL FAR PASCAL SendRenameMsg (hwnd, lpstr, hclinfo) +HWND hwnd; +LPSTR lpstr; +HANDLE hclinfo; +{ + ATOM aData = NULL; + HANDLE hdde = NULL; + PCLINFO pclinfo = NULL; + HWND hwndClient; + + if (!(pclinfo = (PCLINFO) LocalLock (hclinfo))) + goto errrtn; + + // Make the item atom with the options. + aData = DuplicateAtom (aStdDocName); + hdde = DuplicateData (hddeRename); + + hwndClient = pclinfo->hwnd; + LocalUnlock (hclinfo); + + // Post the message + if (!PostMessageToClientWithBlock (hwndClient, WM_DDE_DATA, (HWND)GetParent (hwnd), + MAKELONG (hdde, aData))) + goto errrtn; + + return TRUE; + +errrtn: + + if (hdde) + GlobalFree (hdde); + if (aData) + GlobalDeleteAtom (aData); + + return TRUE; + +} + + + +//SendDataMsg: Send data to the clients, if the data change options +//match the data advise options. + +BOOL FAR PASCAL SendDataMsg (hwnd, lpstr, hclinfo) +HWND hwnd; +LPSTR lpstr; +HANDLE hclinfo; +{ + PCLINFO pclinfo = NULL; + HANDLE hdde = NULL; + ATOM aData = NULL; + int retval; + HANDLE hdata; + LPCLIENT lpclient; + + + if (!(pclinfo = (PCLINFO) LocalLock (hclinfo))) + goto errRtn; + + lpclient = (LPCLIENT)GetWindowLong (hwnd, 0); + +#ifdef FIREWALLS + ASSERT ((CheckPointer(lpclient, WRITE_ACCESS)), + "In Item the client handle missing") +#endif + + // if the client dead, then no message + if (!IsWindowValid(pclinfo->hwnd)) + goto errRtn; + + if (pclinfo->options & (0x0001 << enummsg)) { + fAdviseSaveItem = TRUE; + SendDevInfo (lpclient, lpstr); + + // send message if the client needs data for every change or + // only for the selective ones he wants. + + // now look for the data option. + if (pclinfo->bnative){ + // prepare native data + if (pclinfo->bdata){ + + // Wants the data with DDE_DATA message + // Get native data from the server. + +#ifdef FIREWALLS + if (!CheckPointer (enumlpoleobject, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBECT") + else if (!CheckPointer (enumlpoleobject->lpvtbl,WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (enumlpoleobject->lpvtbl->GetData, + "Invalid pointer to GetData method") +#endif + + retval = (*enumlpoleobject->lpvtbl->GetData) (enumlpoleobject, + (int)cfNative, (LPHANDLE)& hdata); +#ifdef FIREWALLS + ASSERT (retval != OLE_BUSY, "Getdata returns with OLE_BUSY"); +#endif + if (retval != OLE_OK) + goto errRtn; + + // Prepare the DDE data block. + if(!MakeDDEData (hdata, (int)cfNative, (LPHANDLE)&hdde, FALSE)) + goto errRtn; + + } + + + // Make the item atom with the options. + aData = MakeDataAtom (lpclient->aItem, enummsg); + // Post the message + if (!PostMessageToClientWithBlock (pclinfo->hwnd, WM_DDE_DATA, + (HWND)GetParent (hwnd), MAKELONG (hdde, aData))) + goto errRtn; + hdde = NULL; + aData = NULL; + } + + // Now post the data for the disply format + if (pclinfo->format){ + if (pclinfo->bdata){ +#ifdef FIREWALLS + if (!CheckPointer (enumlpoleobject, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBECT") + else if (!CheckPointer (enumlpoleobject->lpvtbl,WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (enumlpoleobject->lpvtbl->GetData, + "Invalid pointer to GetData method") +#endif + retval = (*enumlpoleobject->lpvtbl->GetData) (enumlpoleobject, + pclinfo->format, (LPHANDLE)& hdata); + +#ifdef FIREWALLS + ASSERT (retval != OLE_BUSY, "Getdata returns with OLE_BUSY"); +#endif + if (retval != OLE_OK) + goto errRtn; + + if (pclinfo->format == CF_METAFILEPICT) + ChangeOwner (hdata); + + if(!MakeDDEData (hdata, pclinfo->format, (LPHANDLE)&hdde, FALSE)) + goto errRtn; + + } + + // atom is deleted. So, we need to duplicate for every post + aData = MakeDataAtom (lpclient->aItem, enummsg); + // now post the message to the client; + if (!PostMessageToClientWithBlock (pclinfo->hwnd, WM_DDE_DATA, + (HWND)GetParent (hwnd), MAKELONG (hdde, aData))) + goto errRtn; + + hdde = NULL; + aData = NULL; + + } + + } + + +errRtn: + if (pclinfo) + LocalUnlock (hclinfo); + + if (hdde) + GlobalFree (hdde); + + if (aData) + GlobalDeleteAtom (aData); + + return TRUE; + +} + + +// IsAdviseStdItems: returns true if the item is one of the standard items +// StdDocName; +BOOL INTERNAL IsAdviseStdItems (aItem) +ATOM aItem; +{ + + if ( aItem == aStdDocName) + return TRUE; + else + return FALSE; +} + +// GetStdItemIndex: returns index to Stditems in the "stdStrTable" if the item +// is one of the standard items StdHostNames, StdTargetDevice, +// StdDocDimensions, StdColorScheme + +int INTERNAL GetStdItemIndex (aItem) +ATOM aItem; +{ + char str[MAX_STR]; + + if (!aItem) + return NULL; + + if (!GlobalGetAtomName (aItem, (LPSTR) str, MAX_STR)) + return NULL; + + if (!lstrcmpi (str, stdStrTable[STDTARGETDEVICE])) + return STDTARGETDEVICE; + else if (!lstrcmpi (str, stdStrTable[STDHOSTNAMES])) + return STDHOSTNAMES; + else if (!lstrcmpi (str, stdStrTable[STDDOCDIMENSIONS])) + return STDDOCDIMENSIONS; + else if (!lstrcmpi (str, stdStrTable[STDCOLORSCHEME])) + return STDCOLORSCHEME; + + return NULL; +} + + +// PokeStdItems: Pokes the data for the standard items. +// For StdHostnames, StdDocDimensions and SetColorScheme the data is +// sent immediately and for the the StdTargetDeviceinfo the +// data is set in each client block and the data is sent just +// before the GetData call for rendering the right data. + + +OLESTATUS INTERNAL PokeStdItems (lpdoc, hwndClient, lparam) +LPDOC lpdoc; +HWND hwndClient; +LONG lparam; +{ + int index; + DDEDATA FAR * lpdata = NULL; + HANDLE hdata = NULL; + HANDLE hnew = NULL; + LPOLESERVERDOC lpoledoc; + LPHOSTNAMES lphostnames; + OLESTATUS retval = OLE_ERROR_MEMORY; + int format; + BOOL fRelease; + RECT rcDoc; + + index = HIWORD(lparam); + hdata = (HANDLE)(LOWORD (lparam)); + if(!(hdata && (lpdata = (DDEDATA FAR *)GlobalLock (hdata)))) + goto errRtn; + + format = lpdata->cfFormat; + fRelease = lpdata->fRelease; + +#ifdef FIREWALSS + ASSERT (format == (int)cfBinary, "Format is not binary"); +#endif + + // we have extracted the data successfully. + lpoledoc = lpdoc->lpoledoc; +#ifdef FIREWALLS + if (!CheckPointer (lpoledoc, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOC") + else if (!CheckPointer (lpoledoc->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOCVTBL") +#endif + + if (index == STDHOSTNAMES){ + lphostnames = (LPHOSTNAMES)lpdata->Value; +#ifdef FIREWALLS + ASSERT (lpoledoc->lpvtbl->SetHostNames, + "Invalid pointer to SetHostNames method") +#endif + retval = (*lpoledoc->lpvtbl->SetHostNames)(lpdoc->lpoledoc, + (LPSTR)lphostnames->data, + ((LPSTR)lphostnames->data) + + lphostnames->documentNameOffset); + goto end; + } + + if (index == STDDOCDIMENSIONS){ +#ifdef FIREWALLS + ASSERT (lpoledoc->lpvtbl->SetDocDimensions, + "Invalid pointer to SetDocDimensions method") +#endif + rcDoc.left = 0; + rcDoc.top = ((LPRECT)(lpdata->Value))->top; + rcDoc.bottom = 0; + rcDoc.right = ((LPRECT)lpdata->Value)->left; + + retval = (*lpoledoc->lpvtbl->SetDocDimensions)(lpdoc->lpoledoc, + (LPRECT)&rcDoc); + + goto end; + + } + + if (index == STDCOLORSCHEME) { +#ifdef FIREWALLS + ASSERT (lpoledoc->lpvtbl->SetColorScheme, + "Invalid pointer to SetColorScheme method") +#endif + retval = (*lpoledoc->lpvtbl->SetColorScheme)(lpdoc->lpoledoc, + (LPLOGPALETTE) lpdata->Value); + goto end; + } +#ifdef FIREWALLS + ASSERT (index == STDTARGETDEVICE, "Unknown standard item"); +#endif + + // case of the printer decvice info + + if (!(hnew = MakeItemData ((DDEPOKE FAR *)lpdata, hdata, format))) + goto errRtn; + + // Go thru the all the items lists for this doc and replace the + // printer device info information. + // Free the block we duplicated. + retval = SetStdInfo (lpdoc, hwndClient, + (LPSTR) (MAKELONG(STDTARGETDEVICE,0)),hnew); + + +end: +errRtn: + if (hnew) + // can only be global memory block + GlobalFree (hnew); + + if (lpdata) { + GlobalUnlock (hdata); + if (retval == OLE_OK && fRelease) + GlobalFree (hdata); + } + return retval; +} + + +// SetStdInfo: Sets the targetdevice info. Creates a client +// for "StdTargetDevice". This item is created only within the +// lib and it is never visible in server app. When the change +// message comes from the server app, before we ask for +// the data, we send the targetdevice info if there is +// info for the client whom we are trying to send the data +// on advise. + + +int INTERNAL SetStdInfo (lpdoc, hwndClient, lpitemname, hdata) +LPDOC lpdoc; +HWND hwndClient; +LPSTR lpitemname; +HANDLE hdata; +{ + HWND hwnd; + HANDLE hclinfo = NULL; + PCLINFO pclinfo = NULL; + LPCLIENT lpclient; + OLESTATUS retval = OLE_OK; + + + // first create/find the StdTargetDeviceItem. + + if ((hwnd = SearchItem (lpdoc, lpitemname)) + == NULL){ + retval = RegisterItem ((LHDOC)lpdoc, lpitemname, + (LPCLIENT FAR *)&lpclient, FALSE); + + if (retval != OLE_OK) + goto errRtn; + + hwnd = lpclient->hwnd; + + } + +#ifdef FIREWALLS + ASSERT (retval == OLE_OK, "No StdTragetDevice or StdDocname item"); +#endif + + + if(hclinfo = FindClient (hwnd, hwndClient)){ + if (pclinfo = (PCLINFO) LocalLock (hclinfo)){ + if (pclinfo->hdevInfo) + GlobalFree (pclinfo->hdevInfo); + pclinfo->bnewDevInfo = TRUE; + if (hdata) + pclinfo->hdevInfo = DuplicateData (hdata); + else + pclinfo->hdevInfo = NULL; + pclinfo->hwnd = hwndClient; + LocalUnlock (hclinfo); + + // We do not have to reset the client because we did not + // change the handle it self. + } + } else { + // Create the client structure to be attcahed to the object. + hclinfo = LocalAlloc (LMEM_MOVEABLE | LMEM_ZEROINIT, sizeof (CLINFO)); + if (hclinfo == NULL || (pclinfo = (PCLINFO) LocalLock (hclinfo)) == NULL) + goto errRtn; + + pclinfo->bnewDevInfo = TRUE; + if (hdata) + pclinfo->hdevInfo = DuplicateData (hdata); + else + pclinfo->hdevInfo = NULL; + + pclinfo->hwnd = hwndClient; + LocalUnlock (hclinfo); + + + // Now add this client to item client list + // !!! This error recovery is not correct. + if (!AddClient (hwnd, hwndClient, hclinfo)) + goto errRtn; + + } + return OLE_OK; +errRtn: + if (pclinfo) + LocalUnlock (hclinfo); + + if (hclinfo) + LocalFree (hclinfo); + return OLE_ERROR_MEMORY; +} + + +// SendDevInfo: Sends targetdevice info to the the object. +// Caches the last targetdevice info sent to the object. +// If the targetdevice block is same as the one in the +// cache, then no targetdevice info is sent. +// (!!! There might be some problem here getting back +// the same global handle). + +void INTERNAL SendDevInfo (lpclient, lppropname) +LPCLIENT lpclient; +LPSTR lppropname; +{ + + HANDLE hclinfo = NULL; + PCLINFO pclinfo = NULL; + HANDLE hdata; + OLESTATUS retval; + HWND hwnd; + LPDOC lpdoc; + + + + lpdoc = (LPDOC)GetWindowLong (GetParent (lpclient->hwnd), 0); + + // find if any StdTargetDeviceInfo item is present at all + hwnd = SearchItem (lpdoc, (LPSTR) (MAKELONG(STDTARGETDEVICE, 0))); + if (hwnd == NULL) + return; + + hclinfo = GetProp (hwnd, lppropname); + + // This client has not set any target device info. no need to send + // any stdtargetdevice info + if (hclinfo != NULL) { + if (!(pclinfo = (PCLINFO)LocalLock (hclinfo))) + goto end; + + // if we cached it, do not send it again. + if ((!pclinfo->bnewDevInfo) && pclinfo->hdevInfo == lpclient->hdevInfo) + goto end; + + pclinfo->bnewDevInfo = FALSE; + if(!(hdata = DuplicateData (pclinfo->hdevInfo))) + goto end; + } else { + + // already screen + if (!lpclient->hdevInfo) + goto end; + + //for screen send NULL. + hdata = NULL; + } + + + // Now send the targetdevice info +#ifdef FIREWALLS + if (!CheckPointer (lpclient->lpoleobject, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBECT") + else if (!CheckPointer (lpclient->lpoleobject->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLEOBJECTVTBL") + else + ASSERT (lpclient->lpoleobject->lpvtbl->SetTargetDevice, + "Invalid pointer to SetTargetDevice method") +#endif + retval = (*lpclient->lpoleobject->lpvtbl->SetTargetDevice) + (lpclient->lpoleobject, hdata); + + if (retval == OLE_OK) { + if (pclinfo) + lpclient->hdevInfo = pclinfo->hdevInfo; + else + lpclient->hdevInfo = NULL; + + } + // !!! error case who frees the data?' + +end: + if (pclinfo) + LocalUnlock (hclinfo); + + return; +} + +void ChangeOwner (hmfp) +HANDLE hmfp; +{ + LPMETAFILEPICT lpmfp; + + if (lpmfp = (LPMETAFILEPICT) GlobalLock (hmfp)) { + if (bWin30) + GiveToGDI (lpmfp->hMF); + else { + if (lpfnSetMetaFileBitsBetter) + (*lpfnSetMetaFileBitsBetter) (lpmfp->hMF); + } + + GlobalUnlock (hmfp); + } +} + + +HANDLE INTERNAL MakeItemData (lpPoke, hPoke, cfFormat) +DDEPOKE FAR * lpPoke; +HANDLE hPoke; +OLECLIPFORMAT cfFormat; +{ + HANDLE hnew; + LPSTR lpnew; + DWORD dwSize; + + if (cfFormat == CF_METAFILEPICT) + return DuplicateMetaFile (*(LPHANDLE)lpPoke->Value); + + if (cfFormat == CF_BITMAP) + return DuplicateBitmap (*(LPHANDLE)lpPoke->Value); + + if (cfFormat == CF_DIB) + return DuplicateData (*(LPHANDLE)lpPoke->Value); + + // Now we are dealing with normal case + if (!(dwSize = GlobalSize (hPoke))) + return NULL; + + dwSize = dwSize - sizeof (DDEPOKE) + sizeof(BYTE); + + if (hnew = GlobalAlloc (GMEM_MOVEABLE, dwSize)) { + if (lpnew = GlobalLock (hnew)) { + UtilMemCpy (lpnew, (LPSTR) lpPoke->Value, dwSize); + GlobalUnlock (hnew); + } + else { + GlobalFree (hnew); + hnew = NULL; + } + } + + return hnew; +} + + + +HANDLE INTERNAL DuplicateMetaFile (hSrcData) +HANDLE hSrcData; +{ + LPMETAFILEPICT lpSrcMfp; + LPMETAFILEPICT lpDstMfp = NULL; + HANDLE hMF = NULL; + HANDLE hDstMfp = NULL; + + if (!(lpSrcMfp = (LPMETAFILEPICT) GlobalLock(hSrcData))) + return NULL; + + GlobalUnlock (hSrcData); + + if (!(hMF = CopyMetaFile (lpSrcMfp->hMF, NULL))) + return NULL; + + if (!(hDstMfp = GlobalAlloc (GMEM_MOVEABLE, sizeof(METAFILEPICT)))) + goto errMfp; + + if (!(lpDstMfp = (LPMETAFILEPICT) GlobalLock (hDstMfp))) + goto errMfp; + + GlobalUnlock (hDstMfp); + + *lpDstMfp = *lpSrcMfp; + lpDstMfp->hMF = hMF; + return hDstMfp; +errMfp: + if (hMF) + DeleteMetaFile (hMF); + + if (hDstMfp) + GlobalFree (hDstMfp); + + return NULL; +} + + + +HBITMAP INTERNAL DuplicateBitmap (hold) +HBITMAP hold; +{ + HBITMAP hnew; + HANDLE hMem; + LPSTR lpMem; + LONG retVal = TRUE; + DWORD dwSize; + BITMAP bm; + + // !!! another way to duplicate the bitmap + + GetObject (hold, sizeof(BITMAP), (LPSTR) &bm); + dwSize = ((DWORD) bm.bmHeight) * ((DWORD) bm.bmWidthBytes) * + ((DWORD) bm.bmPlanes) * ((DWORD) bm.bmBitsPixel); + + if (!(hMem = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize))) + return NULL; + + if (!(lpMem = GlobalLock (hMem))){ + GlobalFree (hMem); + return NULL; + } + + GetBitmapBits (hold, dwSize, lpMem); + if (hnew = CreateBitmap (bm.bmWidth, bm.bmHeight, + bm.bmPlanes, bm.bmBitsPixel, NULL)) + retVal = SetBitmapBits (hnew, dwSize, lpMem); + + GlobalUnlock (hMem); + GlobalFree (hMem); + + if (hnew && (!retVal)) { + DeleteObject (hnew); + hnew = NULL; + } + + return hnew; +} + + + diff --git a/private/mvdm/wow16/ole/server/makefile b/private/mvdm/wow16/ole/server/makefile new file mode 100644 index 000000000..3dc7d7015 --- /dev/null +++ b/private/mvdm/wow16/ole/server/makefile @@ -0,0 +1,95 @@ +# +# Make file for srvr library +# + +# Flags set assuming small model + +INCLUDE=-I..\..\inc -I..\..\..\inc + + +LIBS= ..\..\lib\sdllcew ..\..\lib\libw ..\..\lib\shell +LIBENTRY_OBJ=..\..\lib\libentry.obj + +########## Path definition so we find 16 bit tools ########## +# Also works around stupid bug in RC 3.1 that doesn't allow rcpp.err to be +# in a directory that is greater than 128 chars down the path, even if +# rc 3.1 is running as an OS/2 app. + +PATH = $(_NTBINDIR)\private\mvdm\tools16;$(PATH) + +!if "$(NTDEBUG)"!="" && "$(NTDEBUG)"!="retail" && "$(NTDEBUG)" != "ntsdnodbg" +DEBUG=1 +CDEBUG = /Od /Oi /Zd +ADEBUG = -Zd +LDEBUG = /LI +!endif + +!ifdef DEBUG +BLD=debug +CFLAGS=-c -ASw -G2sw -Zpe -I..\client -DDEBUG -DFIREWALLS -DSERVERONLY $(INCLUDE) $(CDEBUG) +LFLAGS=/NOD /NOE /M $(LDEBUG) +AFLAGS= -D?WIN=1 -W2 $(INCLUDE) $(ADEBUG) +!else +BLD=retail +CFLAGS=-c -ASw -Ox -G2sw -Zpe -I..\client -DSERVERONLY $(INCLUDE) +LFLAGS=/NOD /NOE /M +AFLAGS= -D?WIN=1 -W2 $(INCLUDE) +!endif + +SRVR_OBJ= $(BLD)\srvrmain.obj $(BLD)\srvr.obj $(BLD)\doc.obj $(BLD)\item.obj \ + $(BLD)\utils.obj $(BLD)\block.obj $(BLD)\olesvr.obj \ + $(BLD)\give2gdi.obj + + +ALL: $(BLD)\olesvr.dll $(BLD)\olesvr.lib + +clean: cleanup all + +cleanup: + if exist *.obj del *.obj + if exist *.dll del *.dll + if exist *.map del *.map + if exist *.sym del *.sym + if exist *.res del *.res + +srvr.res: srvr.rc olesvr.rcv + rc16 -r $(INCLUDE) srvr.rc $@ + +$(BLD)\olesvr.lib: olesvr.def + mkpublic olesvr.def stripped.def + implib $@ stripped.def + del stripped.def + +$(BLD)\olesvr.obj: olesvr.asm + masm -D?PLM=0 $(AFLAGS) olesvr.asm, $@; + +$(BLD)\give2gdi.obj: give2gdi.asm + masm -D?PLM=1 $(AFLAGS) give2gdi.asm, $@; + +{}.c{$(BLD)}.obj: + cl16 $(CFLAGS) $< + copy $(@B).obj $(BLD) + del $(@B).obj + +$(BLD)\olesvr.dll: $(SRVR_OBJ) srvr.res olesvr.def + link16 $(LFLAGS) @<< +$(SRVR_OBJ) $(LIBENTRY_OBJ) +$(BLD)\olesvr.dll +$(BLD)\olesvr.map +$(LIBS) +olesvr.def; +<< + -@ cd $(BLD) + rc16 -t -30 $(INCLUDE) ..\srvr.res olesvr.dll + mapsym olesvr + -binplace olesvr.dll olesvr.map olesvr.sym + -@ cd.. + +HEADERS = srvr.h ..\client\ole.h ..\client\cmacs.h +srvrmain.c: $(HEADERS) +srvr.c: $(HEADERS) +doc.c.c: $(HEADERS) +item.c: $(HEADERS) +utils.c: $(HEADERS) +block.c: $(HEADERS) +#olesvr.rcv: ver.h diff --git a/private/mvdm/wow16/ole/server/olesvr.asm b/private/mvdm/wow16/ole/server/olesvr.asm new file mode 100644 index 000000000..6bce6a452 --- /dev/null +++ b/private/mvdm/wow16/ole/server/olesvr.asm @@ -0,0 +1,61 @@ + ;\ + ; ole.asm + ; + ; Copyright (C) 1991, MicroSoft Corporation + ; + ; Contains pointer vaildation routine + ; + ; History: sriniK 02/26/1991 original + ;/ + +.286p +.MODEL SMALL +.CODE + +;**************************** _CheckPointer **************************** +; +; WORD CheckPointer (lp, access) +; +; Args: +; lp pointer to be verified +; access 0 test the pointer for read access +; 1 test the pointer for write access +; returns: +; FALSE invalid pointer +; TRUE valid pointer +; +; +; + public _CheckPointer + +_CheckPointer proc + + push bp + mov bp, sp + + xor ax, ax + and word ptr [bp+8], -1 + jnz check_write_access + + verr word ptr [bp+6] ; check selector for read access + jnz error + jmp short check_offset + +check_write_access: + verw word ptr [bp+6] ; check selector for write access + jnz error + +check_offset: + lsl bx, word ptr [bp+6] ; segment limit gets copied into BX + jnz error + cmp [bp+4], bx + ja error + or ax, -1 +error: + pop bp + ret + +_CheckPointer endp + end + + diff --git a/private/mvdm/wow16/ole/server/olesvr.def b/private/mvdm/wow16/ole/server/olesvr.def new file mode 100644 index 000000000..1adad0886 --- /dev/null +++ b/private/mvdm/wow16/ole/server/olesvr.def @@ -0,0 +1,48 @@ +LIBRARY OLESVR INITINSTANCE + +DESCRIPTION "OLE Server. (c) Copyright Microsoft Corp. 1990 - All Rights Reserved"; + +EXETYPE WINDOWS + +STUB 'WINSTUB.EXE' + +CODE MOVABLE DISCARDABLE +DATA MOVABLE SINGLE + +SEGMENTS + WEP_TEXT CLASS 'CODE' FIXED + Give2GDI CLASS 'CODE' FIXED + + +HEAPSIZE 8000 + +EXPORTS + WEP @1 RESIDENTNAME ;Internal + + OLEREGISTERSERVER @2 + OLEREVOKESERVER @3 + + OLEBLOCKSERVER @4 + OLEUNBLOCKSERVER @5 + + OLEREGISTERSERVERDOC @6 + OLEREVOKESERVERDOC @7 + OLERENAMESERVERDOC @8 + OLEREVERTSERVERDOC @9 + OLESAVEDSERVERDOC @10 + + OLEREVOKEOBJECT @11 + OLEQUERYSERVERVERSION @12 + + SrvrWndProc @21 ;Internal + DocWndProc @22 ;Internal + ItemWndProc @23 ;Internal + + SendDataMsg @24 ;Internal + FindItemWnd @25 ;Internal + ItemCallBack @26 ;Internal + TerminateClients @27 ;Internal + TerminateDocClients @28 ;Internal + DeleteClientInfo @29 ;Internal + SendRenameMsg @30 ;Internal + EnumForTerminate @31 ;Internal diff --git a/private/mvdm/wow16/ole/server/olesvr.rcv b/private/mvdm/wow16/ole/server/olesvr.rcv new file mode 100644 index 000000000..a12caff97 --- /dev/null +++ b/private/mvdm/wow16/ole/server/olesvr.rcv @@ -0,0 +1,58 @@ +#include <ver.h> +#include <version.h> + +#ifdef NT +#define OLEVER_FILEOS VOS__WINDOWS32 +#define OLEVER_FILEVERSION 1,11,000 +#define OLEVER_FILEVERSION_STR "1.11.000\0" +#else +#define OLEVER_FILEOS VOS_DOS_WINDOWS16 +#define OLEVER_FILEVERSION 1,11,000 +#define OLEVER_FILEVERSION_STR "1.11.000\0" +#endif + +VS_VERSION_INFO VERSIONINFO +FILEVERSION OLEVER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +FILEFLAGSMASK 0x0000003FL +FILEFLAGS VER_FILEFLAGS +FILEOS OLEVER_FILEOS +FILETYPE VFT_DLL +FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "Microsoft Corporation\0" + VALUE "FileDescription", "Object Linking and Embedding Server Library\0" + VALUE "FileVersion", OLEVER_FILEVERSION_STR + VALUE "InternalName", "OLESVR\0" + VALUE "LegalCopyright", "Copyright \251 Microsoft Corp. 1991-1996\0" + VALUE "OriginalFilename", "OLESVR.DLL\0" + VALUE "ProductName", "Microsoft Object Linking and Embedding Libraries for Windows" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + VALUE "WOW Version", "4.0", "\0" + END +#ifdef INTL + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", "Microsoft Corporation\0" + VALUE "FileDescription", "Object Linking and Embedding Server Library\0" + VALUE "FileVersion", OLEVER_FILEVERSION_STR + VALUE "InternalName", "OLESVR\0" + VALUE "LegalCopyright", "Copyright \251 Microsoft Corp. 1991-1996\0" + VALUE "OriginalFilename", "OLESVR.DLL\0" + VALUE "ProductName", "Microsoft Object Linking and Embedding Libraries for Windows" + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + VALUE "WOW Version", "4.0", "\0" + END +#endif + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END + +END diff --git a/private/mvdm/wow16/ole/server/olever.h b/private/mvdm/wow16/ole/server/olever.h new file mode 100644 index 000000000..a84e7261c --- /dev/null +++ b/private/mvdm/wow16/ole/server/olever.h @@ -0,0 +1,38 @@ +#include <ver.h> + +#ifndef DEBUG +#define OLEVER_DEBUG 0 +#else +#define OLEVER_DEBUG 1 +#endif + + +#ifndef OFFICIAL +#define OLEVER_PRIVATEBUILD 1 +#else +#define OLEVER_PRIVATEBUILD 0 +#endif + + +#ifndef FINAL +#define OLEVER_PRERELEASE 1 +#else +#define OLEVER_PRERELEASE 0 +#endif + +#define OLEVER_FILEFLAGS (OLEVER_PRIVATEBUILD|OLEVER_PRERELEASE|OLEVER_DEBUG) + +#ifdef NT +#define OLEVER_FILEOS VOS_WINDOWS32 +#define OLEVER_FILEVERSION 1,03, 001 +#define OLEVER_PRODUCTVERSION 3,10,0,043 +#elseif PWIN +#define OLEVER_FILEOS VOS_DOS_WINDOWS16 +#define OLEVER_FILEVERSION 1,10 +#define OLEVER_PRODUCTVERSION 3,10,0,043 +#else +#define OLEVER_FILEOS VOS_DOS_WINDOWS16 +#define OLEVER_FILEVERSION 1,03, 001 +#define OLEVER_PRODUCTVERSION 3,10,0,043 +#endif + diff --git a/private/mvdm/wow16/ole/server/srvr.c b/private/mvdm/wow16/ole/server/srvr.c new file mode 100644 index 000000000..4ddb7c5c5 --- /dev/null +++ b/private/mvdm/wow16/ole/server/srvr.c @@ -0,0 +1,1136 @@ +/****************************** Module Header ******************************\ +* Module Name: Srvr.c Server Main module +* +* Purpose: Includes All the server communication related routines. +* +* Created: Oct 1990. +* +* Copyright (c) 1985, 1986, 1987, 1988, 1989 Microsoft Corporation +* +* History: +* Raor: Wrote the original version. +* +* +\***************************************************************************/ + +#include <windows.h> +#include <shellapi.h> +#include "cmacs.h" +#include "ole.h" +#include "dde.h" +#include "srvr.h" + +// LOWWORD - BYTE 0 major verision, BYTE1 minor version, +// HIWORD is reserved + +#define OLE_VERSION 0x1001L + + +extern ATOM aOLE; +extern ATOM aSysTopic; +extern ATOM aStdExit; +extern ATOM aStdCreate; +extern ATOM aStdOpen; +extern ATOM aStdEdit; +extern ATOM aStdCreateFromTemplate; +extern ATOM aStdShowItem; +extern ATOM aProtocols; +extern ATOM aTopics; +extern ATOM aFormats; +extern ATOM aStatus; +extern ATOM cfNative; +extern ATOM aEditItems; +extern ATOM aStdClose; + + +extern HANDLE hdllInst; +extern BOOL bProtMode; + +extern FARPROC lpTerminateClients; + +#ifdef FIREWALLS +BOOL bShowed = FALSE; +void ShowVersion (void); +#endif + + +DWORD FAR PASCAL OleQueryServerVersion () +{ + return OLE_VERSION; +} + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleRegisterServer (lpclass, lpolesrvr, lplhsrvr) +* +* OleRegisterServer: Registers the server with the server library. +* +* Parameters: +* 1. Ptr to the server class. +* 2. Ptr to the olesrvr. This is private to the server app. +* (Typically this is the ptr to the private storage area of +* server app server related info). +* 3. Ptr to the LHSRVR. Place where to pass back the long +* handle of the server in DLL (This is private to the DLL). +* +* return values: +* returns OLE_OK if the server is successfully registered . +* else returns the corresponding error. +* +* +* History: +* Raor: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRegisterServer (lpclass, lpolesrvr, lplhsrvr, hInst, useFlags) +LPSTR lpclass; // class name +LPOLESERVER lpolesrvr; // ole srvr(private to srvr app) +LHSRVR FAR * lplhsrvr; // where we pass back our private handle +HANDLE hInst; +OLE_SERVER_USE useFlags; +{ + + HANDLE hsrvr = NULL; + LPSRVR lpsrvr = NULL; + ATOM aExe = NULL; + + Puts ("OleRegisterServer"); + + if (!bProtMode) + return OLE_ERROR_PROTECT_ONLY; + + PROBE_READ(lpclass); + PROBE_WRITE(lpolesrvr); + PROBE_WRITE(lplhsrvr); + + // add the app atom to global list + if (!ValidateSrvrClass (lpclass, &aExe)) + return OLE_ERROR_CLASS; + + hsrvr = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE, sizeof (SRVR)); + if (! (hsrvr && (lpsrvr = (LPSRVR)GlobalLock (hsrvr)))) + goto errReturn; + + // set the signature handle and the app atom. + lpsrvr->sig[0] = 'S'; + lpsrvr->sig[1] = 'R'; + lpsrvr->hsrvr = hsrvr; + lpsrvr->aClass = GlobalAddAtom (lpclass); + lpsrvr->lpolesrvr = lpolesrvr; + lpsrvr->relLock = TRUE; // set the release lock. + lpsrvr->aExe = aExe; + lpsrvr->useFlags = useFlags; + +#ifdef FIREWALLS + ASSERT ((useFlags == OLE_SERVER_SINGLE || useFlags == OLE_SERVER_MULTI), "invalid server options"); +#endif + + // Create the servre window and do not show it. + if (!(lpsrvr->hwnd = CreateWindow ("SrvrWndClass", "Srvr", + WS_OVERLAPPED,0,0,0,0,NULL,NULL, hdllInst, NULL))) + goto errReturn; + + // save the ptr to the srever struct in the window. + SetWindowLong (lpsrvr->hwnd, 0, (LONG)lpsrvr); + + // Set the signature. + SetWindowWord (lpsrvr->hwnd, WW_LE, WC_LE); + SetWindowWord (lpsrvr->hwnd, WW_HANDLE, (WORD)hInst); + *lplhsrvr = (LONG)lpsrvr; + + return OLE_OK; + +errReturn: + if (lpsrvr){ + if (lpsrvr->hwnd) + DestroyWindow (lpsrvr->hwnd); + + if (lpsrvr->aClass) + GlobalDeleteAtom (lpsrvr->aClass); + + if (lpsrvr->aExe) + GlobalDeleteAtom (lpsrvr->aExe); + + GlobalUnlock (hsrvr); + } + + if (hsrvr) + GlobalFree (hsrvr); + + return OLE_ERROR_MEMORY; + +} + + +// ValidateSrvrClass checks whether the given server class is valid by +// looking in the win.ini. + +BOOL INTERNAL ValidateSrvrClass (lpclass, lpAtom) +LPSTR lpclass; +ATOM FAR * lpAtom; +{ + + char buf[MAX_STR]; + LONG cb = MAX_STR; + char key[MAX_STR]; + LPSTR lptmp; + LPSTR lpbuf; + char ch; + + lstrcpy (key, lpclass); + lstrcat (key, "\\protocol\\StdFileEditing\\server"); + + if (RegQueryValue (HKEY_CLASSES_ROOT, key, buf, &cb)) + return FALSE; + + if (!buf[0]) + return FALSE; + + // Get exe name without path and then get an atom for that + + lptmp = lpbuf = (LPSTR)buf; + while ((ch = *lptmp++) && ch != '\0') { + if (ch == '\\' || ch == ':') + lpbuf = lptmp; + } + *lpAtom = GlobalAddAtom (lpbuf); + + return TRUE; +} + + +/***************************** Public Function ****************************\ +* OLESTATUS FAR PASCAL OleRevokeServer (lhsrvr) +* +* OlerevokeServer: Unregisters the server which has been registered. +* +* Parameters: +* 1. DLL server handle. +* +* +* return values: +* returns OLE_OK if the server is successfully unregisterd. +* ( It is Ok for the app free the associated space). +* If the unregistration is intiated, returns OLE_STARTED. +* Calls the Server class release entry point when the server +* can be released. +* +* History: +* Raor: Wrote it, +\***************************************************************************/ + +OLESTATUS FAR PASCAL OleRevokeServer (lhsrvr) +LHSRVR lhsrvr; +{ + + HWND hwndSrvr; + LPSRVR lpsrvr; + + Puts ("OleRevokeServer"); + + if (!CheckServer (lpsrvr = (LPSRVR)lhsrvr)) + return OLE_ERROR_HANDLE; + + if (lpsrvr->bTerminate && lpsrvr->termNo) + return OLE_WAIT_FOR_RELEASE; + + hwndSrvr = lpsrvr->hwnd; + +#ifdef FIREWALLS + ASSERT (hwndSrvr, "Illegal server handle ") +#endif + + // Terminate the conversation with all clients. + // If there are any clients to be terminated + // return back with OLE_STARTED and srvr relase + // will be called for releasing the server finally. + + // we are terminating. + lpsrvr->bTerminate = TRUE; + lpsrvr->termNo = 0; + + // send ack if Revoke is done as a result of StdExit + if (lpsrvr->fAckExit) { + // Post the acknowledge to the client + if (!PostMessageToClient (lpsrvr->hwndExit, WM_DDE_ACK, lpsrvr->hwnd, + MAKELONG (0x8000, lpsrvr->hDataExit))) + // if the window died or post failed, delete the atom. + GlobalFree (lpsrvr->hDataExit); + } + + // revoks all the documents registered with this server. + RevokeAllDocs (lpsrvr); + + // enumerate all the clients which are in your list and post the + // termination. + EnumProps (hwndSrvr, lpTerminateClients); + // post all the messages with yield which have been collected in enum + // UnblockPostMsgs (hwndSrvr, TRUE); + + // reset the release lock. Now it is ok to release the server + // when all the doc clients and server clients have sent back the + // termination. + + lpsrvr->relLock = FALSE; + return ReleaseSrvr (lpsrvr); + +} + + +// ReleaseSrvr: Called when ever a matching WM_TERMINATE is received +// from doc clients or the server clients of a particular server. +// If there are no more terminates pending, it is ok to release the server. +// Calls the server app "release" proc for releasing the server. + +int INTERNAL ReleaseSrvr (lpsrvr) +LPSRVR lpsrvr; +{ + + HANDLE hsrvr; + + + // release srvr is called only when everything is + // cleaned and srvr app can post WM_QUIT + + if (lpsrvr->bTerminate){ + // only if we are revoking server then see whether it is ok to + // call Release. + + // First check whethere any docs are active. + // Doc window is a child window for server window. + + if (lpsrvr->termNo || GetWindow (lpsrvr->hwnd, GW_CHILD)) + return OLE_WAIT_FOR_RELEASE; + + // if the block queue is not empty, do not quit + if (!IsBlockQueueEmpty(lpsrvr->hwnd)) + return OLE_WAIT_FOR_RELEASE; + + } + + if (lpsrvr->relLock) + return OLE_WAIT_FOR_RELEASE; // server is locked. So, delay releasing + + // Inform server app it is time to clean up and post WM_QUIT. + +#ifdef FIREWALLS + if (!CheckPointer (lpsrvr->lpolesrvr, WRITE_ACCESS)) + ASSERT(0, "Invalid LPOLESERVER") + else if (!CheckPointer (lpsrvr->lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT(0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpsrvr->lpolesrvr->lpvtbl->Release, + "Invalid pointer to Release method") +#endif + + (*lpsrvr->lpolesrvr->lpvtbl->Release)(lpsrvr->lpolesrvr); + + if (lpsrvr->aClass) + GlobalDeleteAtom (lpsrvr->aClass); + if (lpsrvr->aExe) + GlobalDeleteAtom (lpsrvr->aExe); + DestroyWindow (lpsrvr->hwnd); + GlobalUnlock (hsrvr = lpsrvr->hsrvr); + GlobalFree (hsrvr); + return OLE_OK; +} + + +//TerminateClients: Call back for the enum properties. + +BOOL FAR PASCAL TerminateClients (hwnd, lpstr, hdata) +HWND hwnd; +LPSTR lpstr; +HANDLE hdata; +{ + LPSRVR lpsrvr; + + lpsrvr = (LPSRVR)GetWindowLong (hwnd, 0); + + // If the client already died, no terminate. + if (IsWindowValid ((HWND)hdata)) { + lpsrvr->termNo++; + + // irrespective of the post, incremet the count, so + // that client does not die. + + PostMessageToClientWithBlock ((HWND)hdata, WM_DDE_TERMINATE, hwnd, NULL); + } + else + ASSERT (FALSE, "TERMINATE: Client's System chanel is missing"); + + return TRUE; +} + + +long FAR PASCAL SrvrWndProc (hwnd, msg, wParam, lParam) +HWND hwnd; +unsigned msg; +WORD wParam; +LONG lParam; +{ + + LPSRVR lpsrvr; + WORD status = NULL; + HWND hwndClient; + HANDLE hdata; + OLESTATUS retval; + + if (AddMessage (hwnd, msg, wParam, lParam, WT_SRVR)) + return 0L; + + lpsrvr = (LPSRVR)GetWindowLong (hwnd, 0); + + + switch (msg){ + + case WM_TIMER: + UnblockPostMsgs (hwnd, FALSE); + + // if no more blocked message empty the queue. + if (IsBlockQueueEmpty (hwnd)) + KillTimer (hwnd, wParam); + + if (lpsrvr->bTerminate && IsBlockQueueEmpty(lpsrvr->hwnd)) + // Now see wheteher we can release the server . + ReleaseSrvr (lpsrvr); + break; + + case WM_CREATE: + DEBUG_OUT ("Srvr create window", 0) + break; + + case WM_DDE_INITIATE: +#ifdef FIREWALLS + ASSERT (lpsrvr, "No server window handle in server window"); +#endif + + DEBUG_OUT ("Srvr: DDE init",0); + if (lpsrvr->bTerminate){ + DEBUG_OUT ("Srvr: No action due to termination process",0) + break; + } + + // class is not matching, so it is not definitely for us. + // for apps sending the EXE for initiate, do not allow if the app + // is mutiple server. + + if (!(lpsrvr->aClass == (ATOM)(LOWORD(lParam)) || + (lpsrvr->aExe == (ATOM)(LOWORD(lParam)) && IsSingleServerInstance ()))) + + break; + + if (!HandleInitMsg (lpsrvr, lParam)) { + if (!(aSysTopic == (ATOM)(HIWORD(lParam)))) { + + // if the server window is not the right window for + // DDE conversation, then try with the doc windows. + SendMsgToChildren (hwnd, msg, wParam, lParam); + + } + break; + } + + // We can enterain this client. Put him in our client list + // and acknowledge the intiate. + + if (!AddClient (hwnd, (HWND)wParam, (HWND)wParam)) + break; + + lpsrvr->cClients++; + lpsrvr->bnoRelease = FALSE; + // add the atoms and post acknowledge + + DuplicateAtom (LOWORD(lParam)); + DuplicateAtom (HIWORD(lParam)); + + SendMessage ((HWND)wParam, WM_DDE_ACK, (WORD)hwnd, lParam); + break; + + case WM_DDE_EXECUTE: +#ifdef FIREWALLS + ASSERT (lpsrvr, "No server window handle in server window"); +#endif + DEBUG_OUT ("srvr: execute", 0) + +#ifdef FIREWALLS + // find the client in the client list. + hwndClient = FindClient (lpsrvr->hwnd, (HWND)wParam); + ASSERT (hwndClient, "Client is missing from the server") +#endif + // Are we terminating + if (lpsrvr->bTerminate) { + DEBUG_OUT ("Srvr: sys execute after terminate posted",0) + // !!! are we supposed to free the data + GlobalFree (HIWORD(lParam)); + break; + } + + + retval = SrvrExecute (hwnd, HIWORD (lParam), (HWND)wParam); + SET_MSG_STATUS (retval, status) + + if (!lpsrvr->bTerminate) { + // Post the acknowledge to the client + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG (status, HIWORD(lParam)))) + // if the window died or post failed, delete the atom. + GlobalFree (HIWORD(lParam)); + } + + break; + + case WM_DDE_TERMINATE: + DEBUG_OUT ("Srvr: DDE terminate",0) + +#ifdef FIREWALLS + // find the client in the client list. + hwndClient = FindClient (lpsrvr->hwnd, (HWND)wParam); + ASSERT (hwndClient, "Client is missing from the server") +#endif + DeleteClient (lpsrvr->hwnd, (HWND)wParam); + lpsrvr->cClients--; + + if (lpsrvr->bTerminate){ + if ((--lpsrvr->termNo == 0) && (IsBlockQueueEmpty (lpsrvr->hwnd))) + // Now see wheteher we can release the server . + ReleaseSrvr (lpsrvr); + + // if we released the server, then + // by the time we come here,, we have destroyed the window + + }else { + // If client intiated the terminate. post matching terminate + PostMessageToClient ((HWND)wParam, WM_DDE_TERMINATE, + hwnd, NULL); + + // callback release tell the srvr app, it can exit if needs. + // Inform server app it is time to clean up and post WM_QUIT. + // only if no docs present. +#if 0 + if (lpsrvr->cClients == 0 + && (GetWindow (lpsrvr->hwnd, GW_CHILD) == NULL)) { +#endif + if (QueryRelease (lpsrvr)){ + +#ifdef FIREWALLS + if (!CheckPointer (lpsrvr->lpolesrvr, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVER") + else if (!CheckPointer (lpsrvr->lpolesrvr->lpvtbl, + WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpsrvr->lpolesrvr->lpvtbl->Release, + "Invalid pointer to Release method") +#endif + + (*lpsrvr->lpolesrvr->lpvtbl->Release) (lpsrvr->lpolesrvr); + } + } + break; + + + case WM_DDE_REQUEST: + if (lpsrvr->bTerminate || !IsWindowValid ((HWND) wParam)) + goto RequestErr; + + if(RequestDataStd (lParam, (HANDLE FAR *)&hdata) != OLE_OK){ + // if request failed, then acknowledge with error. + if (!PostMessageToClient ((HWND)wParam, WM_DDE_ACK, hwnd, + MAKELONG(0x8000, HIWORD(lParam)))) + + RequestErr: + if (HIWORD(lParam)) + GlobalDeleteAtom (HIWORD(lParam)); + } else { + + // post the data message and we are not asking for any + // acknowledge. + + if (!PostMessageToClient ((HWND)wParam, WM_DDE_DATA, hwnd, + MAKELONG(hdata, HIWORD(lParam)))) { + GlobalFree (hdata); + goto RequestErr; + } + } + break; + + + + case WM_DESTROY: + DEBUG_OUT ("Srvr: Destroy window",0) + break; + + default: + DEBUG_OUT ("Srvr: Default message",0) + return DefWindowProc (hwnd, msg, wParam, lParam); + + } + + return 0L; + +} + +BOOL INTERNAL HandleInitMsg (lpsrvr, lParam) +LPSRVR lpsrvr; +LONG lParam; +{ + + + // If it is not system or Ole, this is not the server. + if (!((aSysTopic == (ATOM)(HIWORD(lParam))) || + (aOLE == (ATOM)(HIWORD(lParam))))) + + return FALSE; + + + // single instance MDI accept + if (lpsrvr->useFlags == OLE_SERVER_SINGLE) + return TRUE; + + + // this server is multiple instance. So, check for any clients or docs. + if (!GetWindow (lpsrvr->hwnd, GW_CHILD) && !lpsrvr->cClients) + return TRUE; + + return FALSE; + +} + + +// AddClient: Adds the client as property to the server +// window. Key is the string generated from the window +// handle and the data is the window itself. + + +BOOL INTERNAL AddClient (hwnd, hkey, hdata) +HWND hwnd; +HANDLE hkey; +HANDLE hdata; +{ + char buf[6]; + + MapToHexStr ((LPSTR)buf, hkey); + return SetProp (hwnd, (LPSTR)buf, hdata); + +} + + +//DeleteClient: deletes the client from the server clients list. + +BOOL INTERNAL DeleteClient (hwnd, hkey) +HWND hwnd; +HANDLE hkey; +{ + + char buf[6]; + + MapToHexStr ((LPSTR)buf, hkey); + return RemoveProp (hwnd, (LPSTR)buf); + + +} + +// FindClient: Finds whether a given client is +// in the server client list. + +HANDLE INTERNAL FindClient (hwnd, hkey) +HWND hwnd; +HANDLE hkey; +{ + + char buf[6]; + + + MapToHexStr ((LPSTR)buf, hkey); + return GetProp (hwnd, (LPSTR)buf); +} + + + +// SrvrExecute: takes care of the WM_DDE_EXEXCUTE for the +// server. + + +OLESTATUS INTERNAL SrvrExecute (hwnd, hdata, hwndClient) +HWND hwnd; +HANDLE hdata; +HWND hwndClient; +{ + ATOM aCmd; + BOOL fActivate; + + LPSTR lpdata = NULL; + HANDLE hdup = NULL; + int retval = OLE_ERROR_MEMORY; + + LPSTR lpdocname; + LPSTR lptemplate; + + LPOLESERVERDOC lpoledoc = NULL; + LPDOC lpdoc = NULL; + LPSRVR lpsrvr; + LPOLESERVER lpolesrvr; + LPSTR lpnextarg; + LPSTR lpclassname; + LPSTR lpitemname; + LPSTR lpopt; + char buf[MAX_STR]; + WORD wCmdType; + + // !!! this code can be lot simplified if we do the argument scanning + // seperately and return the ptrs to the args. Rewrite later on. + + if (!(hdup = DuplicateData (hdata))) + goto errRtn; + + if (!(lpdata = GlobalLock (hdup))) + goto errRtn; + + DEBUG_OUT (lpdata, 0) + + lpsrvr = (LPSRVR)GetWindowLong (hwnd, 0); + +#ifdef FIREWALLS + ASSERT (lpsrvr, "Srvr: srvr does not exist"); +#endif + + lpolesrvr = lpsrvr->lpolesrvr; + +#ifdef FIREWALLS + ASSERT ((CheckPointer (lpolesrvr, WRITE_ACCESS)), + "Srvr: lpolesrvr does not exist"); +#endif + + if (*lpdata++ != '[') // commands start with the left sqaure bracket + goto errRtn; + + retval = OLE_ERROR_SYNTAX; + // scan upto the first arg + if (!(wCmdType = ScanCommand (lpdata, WT_SRVR, &lpdocname, &aCmd))) + goto errRtn; + + if (wCmdType == NON_OLE_COMMAND) { + if (!UtilQueryProtocol (lpsrvr->aClass, PROTOCOL_EXECUTE)) + retval = OLE_ERROR_PROTOCOL; + else { +#ifdef FIREWALLS + if (!CheckPointer (lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpolesrvr->lpvtbl->Execute, + "Invalid pointer to Exit method") +#endif + + retval = (*lpolesrvr->lpvtbl->Execute) (lpolesrvr, hdata); + } + + goto errRtn1; + } + + if (aCmd == aStdExit){ + if (*lpdocname) + goto errRtn1; + +#ifdef FIREWALLS + if (!CheckPointer (lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpolesrvr->lpvtbl->Exit, "Invalid pointer to Exit method") +#endif + lpsrvr->fAckExit = TRUE; + lpsrvr->hwndExit = hwndClient; + lpsrvr->hDataExit = hdata; + retval = (*lpolesrvr->lpvtbl->Exit) (lpolesrvr); + lpsrvr->fAckExit = FALSE; + goto end2; + } + + // scan the next argument. + if (!(lpnextarg = ScanArg(lpdocname))) + goto errRtn; + + ////////////////////////////////////////////////////////////////////////// + // + // [StdShowItem("docname", "itemname"[, "true"])] + // + ////////////////////////////////////////////////////////////////////////// + + if (aCmd == aStdShowItem) { + + // first find the documnet. If the doc does not exist, then + // blow it off. + + if (!(lpdoc = FindDoc (lpsrvr, lpdocname))) + goto errRtn1; + + lpitemname = lpnextarg; + + if( !(lpopt = ScanArg(lpitemname))) + goto errRtn1; + + // scan for the optional parameter + // Optional can be only TRUE or FALSE. + + fActivate = FALSE; + if (*lpopt) { + + if( !(lpnextarg = ScanBoolArg (lpopt, (BOOL FAR *)&fActivate))) + goto errRtn1; + + if (*lpnextarg) + goto errRtn1; + + } + + + // scan it. But, igonre the arg. + retval = DocShowItem (lpdoc, lpitemname, !fActivate); + goto end2; + + + + } + + ////////////////////////////////////////////////////////////////////////// + // + // [StdCloseDocument ("docname")] + // + ////////////////////////////////////////////////////////////////////////// + + if (aCmd == aStdClose) { + if (!(lpdoc = FindDoc (lpsrvr, lpdocname))) + goto errRtn1; + + if (*lpnextarg) + goto errRtn1; + + +#ifdef FIREWALLS + if (!CheckPointer (lpdoc->lpoledoc, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOC") + else if (!CheckPointer (lpdoc->lpoledoc->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERDOCVTBL") + else + ASSERT (lpdoc->lpoledoc->lpvtbl->Close, + "Invalid pointer to Close method") +#endif + + retval = (*lpdoc->lpoledoc->lpvtbl->Close)(lpdoc->lpoledoc); + goto end2; + } + + + if (aCmd == aStdOpen) { + // find if any document is already open. + // if the doc is open, then no need to call srvr app. + if (FindDoc (lpsrvr, lpdocname)){ + retval = OLE_OK; + goto end1; + + } + } + + if (aCmd == aStdCreate || aCmd == aStdCreateFromTemplate) { + lpclassname = lpdocname; + lpdocname = lpnextarg; + if( !(lpnextarg = ScanArg(lpdocname))) + goto errRtn1; + + } + + // check whether we can create/open more than one doc. + + if ((lpsrvr->useFlags == OLE_SERVER_MULTI) && + GetWindow (lpsrvr->hwnd, GW_CHILD)) + goto errRtn; + + + + // No Doc. register the document. lpoledoc is being probed + // for validity. So, pass some writeable ptr. It is not + // being used to access anything yet + + if (OleRegisterServerDoc ((LHSRVR)lpsrvr, lpdocname, + (LPOLESERVERDOC)NULL, (LHDOC FAR *)&lpdoc)) + goto errRtn; + + ////////////////////////////////////////////////////////////////////////// + // + // [StdOpenDocument ("docname")] + // + ////////////////////////////////////////////////////////////////////////// + + // Documnet does not exit. + + if(aCmd == aStdOpen) { + +#ifdef FIREWALLS + if (!CheckPointer (lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpolesrvr->lpvtbl->Open, "Invalid pointer to Open method") +#endif + + retval = (*lpolesrvr->lpvtbl->Open)(lpolesrvr, (LHDOC)lpdoc, + lpdocname, (LPOLESERVERDOC FAR *) &lpoledoc); + goto end; + } + else { + lpdoc->fEmbed = TRUE; + } + + + + ////////////////////////////////////////////////////////////////////////// + // + // [StdNewDocument ("classname", "docname")] + // + ////////////////////////////////////////////////////////////////////////// + + if (aCmd == aStdCreate) { +#ifdef FIREWALLS + if (!CheckPointer (lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpolesrvr->lpvtbl->Create, + "Invalid pointer to Create method") +#endif + retval = (*lpolesrvr->lpvtbl->Create) (lpolesrvr, (LHDOC)lpdoc, + lpclassname, lpdocname, + (LPOLESERVERDOC FAR *) &lpoledoc); + + goto end; + } + + ////////////////////////////////////////////////////////////////////////// + // + // [StdEditDocument ("docname")] + // + ////////////////////////////////////////////////////////////////////////// + if (aCmd == aStdEdit){ + + GlobalGetAtomName (lpsrvr->aClass, (LPSTR)buf, MAX_STR); + +#ifdef FIREWALLS + if (!CheckPointer (lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpolesrvr->lpvtbl->Edit, "Invalid pointer to Edit method") +#endif + + retval = (*lpolesrvr->lpvtbl->Edit) (lpolesrvr, (LHDOC)lpdoc, + (LPSTR)buf, lpdocname, + (LPOLESERVERDOC FAR *) &lpoledoc); + goto end; + } + + ////////////////////////////////////////////////////////////////////////// + // + // [StdNewFormTemplate ("classname", "docname". "templatename)] + // + ////////////////////////////////////////////////////////////////////////// + + if (aCmd == aStdCreateFromTemplate){ + lptemplate = lpnextarg; + if(!(lpnextarg = ScanArg(lpnextarg))) + goto errRtn; + +#ifdef FIREWALLS + if (!CheckPointer (lpolesrvr->lpvtbl, WRITE_ACCESS)) + ASSERT (0, "Invalid LPOLESERVERVTBL") + else + ASSERT (lpolesrvr->lpvtbl->CreateFromTemplate, + "Invalid pointer to CreateFromTemplate method") +#endif + retval = (*lpolesrvr->lpvtbl->CreateFromTemplate)(lpolesrvr, + (LHDOC)lpdoc, lpclassname, lpdocname, lptemplate, + (LPOLESERVERDOC FAR *) &lpoledoc); + + goto end; + + } + + + DEBUG_OUT ("Unknown command", 0); + +end: + + if (retval != OLE_OK) + goto errRtn; + + // Successful execute. remember the server app private doc handle here. + + lpdoc->lpoledoc = lpoledoc; + +end1: + // make sure that the srg string is indeed terminated by + // NULL. + if (*lpnextarg) + retval = OLE_ERROR_SYNTAX; + +errRtn: + + if ( retval != OLE_OK){ + // delete the oledoc structure + if (lpdoc) + OleRevokeServerDoc ((LHDOC)lpdoc); + } + +end2: +errRtn1: + + if (lpdata) + GlobalUnlock (hdup); + + if (hdup) + GlobalFree (hdup); + + if (retval == OLE_OK) + lpsrvr->bnoRelease = TRUE; + + return retval; +} + + + + +void SendMsgToChildren (hwnd, msg, wParam, lParam) +HWND hwnd; +unsigned msg; +WORD wParam; +LONG lParam; +{ + + hwnd = GetWindow(hwnd, GW_CHILD); + while (hwnd) { + SendMessage (hwnd, msg, wParam, lParam); + hwnd = GetWindow (hwnd, GW_HWNDNEXT); + } +} + + +OLESTATUS INTERNAL RequestDataStd (lparam, lphdde) +LONG lparam; +LPHANDLE lphdde; +{ + + char buf[MAX_STR]; + ATOM item; + HANDLE hnew = NULL; + + if (!(item = (ATOM)(HIWORD (lparam)))) + goto errRtn; + + GlobalGetAtomName (item, (LPSTR)buf, MAX_STR); + + if (item == aEditItems){ + hnew = MakeGlobal ((LPSTR)"StdHostNames\tStdDocDimensions\tStdTargetDevice"); + goto PostData; + + } + + if (item == aProtocols) { + hnew = MakeGlobal ((LPSTR)"Embedding\tStdFileEditing"); + goto PostData; + } + + if (item == aTopics) { + hnew = MakeGlobal ((LPSTR)"Doc"); + goto PostData; + } + + if (item == aFormats) { + hnew = MakeGlobal ((LPSTR)"Picture\tBitmap"); + goto PostData; + } + + if (item == aStatus) { + hnew = MakeGlobal ((LPSTR)"Ready"); + goto PostData; + } + + // format we do not understand. + goto errRtn; + +PostData: + + // Duplicate the DDE data + if (MakeDDEData (hnew, CF_TEXT, lphdde, TRUE)){ + // !!! why are we duplicating the atom. + DuplicateAtom ((ATOM)(HIWORD (lparam))); + return OLE_OK; + } +errRtn: + return OLE_ERROR_MEMORY; +} + + +BOOL INTERNAL QueryRelease (lpsrvr) +LPSRVR lpsrvr; +{ + + HWND hwnd; + LPDOC lpdoc; + + + // Incase the terminate is called immediately after + // the Std at sys level clear this. + + if (lpsrvr->bnoRelease) { + lpsrvr->bnoRelease = FALSE; + return FALSE; + } + + + if (lpsrvr->cClients) + return FALSE; + + hwnd = GetWindow (lpsrvr->hwnd, GW_CHILD); + + // if either the server or the doc has any clients + // return FALSE; + + while (hwnd){ + lpdoc = (LPDOC)GetWindowLong (hwnd, 0); + if (lpdoc->cClients) + return FALSE; + + hwnd = GetWindow (hwnd, GW_HWNDNEXT); + } + return TRUE; + +} + + +//IsSingleServerInstance: returns true if the app is single server app else +//false. + +BOOL INTERNAL IsSingleServerInstance () +{ + HWND hwnd; + WORD cnt = 0; + HANDLE hTask; + char buf[MAX_STR]; + + + hwnd = GetWindow (GetDesktopWindow(), GW_CHILD); + hTask = GetCurrentTask(); + + while (hwnd) { + if (hTask == GetWindowTask (hwnd)) { + GetClassName (hwnd, (LPSTR)buf, MAX_STR); + if (lstrcmp ((LPSTR)buf, SRVR_CLASS) == 0) + cnt++; + } + hwnd = GetWindow (hwnd, GW_HWNDNEXT); + } +#ifdef FIREWALLS + ASSERT (cnt > 0, "srvr window instance count is zero"); +#endif + if (cnt == 1) + return TRUE; + else + return FALSE; + +} diff --git a/private/mvdm/wow16/ole/server/srvr.h b/private/mvdm/wow16/ole/server/srvr.h new file mode 100644 index 000000000..6f2fceb22 --- /dev/null +++ b/private/mvdm/wow16/ole/server/srvr.h @@ -0,0 +1,294 @@ +/****************************** Module Header ******************************\ +* Module Name: srvr.h +* +* PURPOSE: Private definitions file for server code +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor (../../90,91) Original +* +\***************************************************************************/ + +#define DEFSTD_ITEM_INDEX 0 +#define STDTARGETDEVICE 1 +#define STDDOCDIMENSIONS 2 +#define STDCOLORSCHEME 3 +#define STDHOSTNAMES 4 + + +#define PROTOCOL_EDIT ((LPSTR)"StdFileEditing") +#define PROTOCOL_EXECUTE ((LPSTR)"StdExecute") + +#define SRVR_CLASS ((LPSTR)"SrvrWndClass") +#define DOC_CLASS ((LPSTR)"DocWndClass") +#define ITEM_CLASS ((LPSTR)"ItemWndClass") + + +#define ISATOM(a) ((a >= 0xC000) && (a <= 0xFFFF)) + +#define MAX_STR 124 + +#define WW_LPTR 0 // ptr tosrvr/doc/item +#define WW_LE 4 // signature +#define WW_HANDLE 6 // instance handle + +#define WC_LE 0x4c45 // LE chars + +// If we running under WLO, the HIGHWORD of version number will be >= 0x0A00 +#define VER_WLO 0x0A00 + +extern WORD CheckPointer (LPVOID, int); + +#define READ_ACCESS 0 +#define WRITE_ACCESS 1 + +#define PROBE_READ(lp){\ + if (!CheckPointer(lp, READ_ACCESS))\ + return OLE_ERROR_ADDRESS; \ +} + +#define PROBE_WRITE(lp){\ + if (!CheckPointer(lp, WRITE_ACCESS))\ + return OLE_ERROR_ADDRESS; \ +} + +#define OLE_COMMAND 1 +#define NON_OLE_COMMAND 2 + + +#define WT_SRVR 0 // server window +#define WT_DOC 1 // document window + +#define PROBE_BLOCK(lpsrvr) { \ + if (lpsrvr->bBlock) \ + return OLE_ERROR_SERVER_BLOCKED; \ +} + + +#define SET_MSG_STATUS(retval, status) { \ + if (retval == OLE_OK) \ + status |= 0x8000; \ + if (retval == OLE_BUSY) \ + status |= 0x4000; \ +} + + +typedef LHSERVER LHSRVR; +typedef LHSERVERDOC LHDOC; + +typedef struct _QUE { // nodes in Block/Unblock queue + HWND hwnd; //*** + unsigned msg; // window + WORD wParam; // procedure parameters + LONG lParam; //*** + HANDLE hqNext; // handle to next node +} QUE; + +typedef QUE NEAR * PQUE; +typedef QUE FAR * LPQUE; + + +typedef struct _SRVR { /*srvr*/ // private data + LPOLESERVER lpolesrvr; // corresponding server + char sig[2]; // signature "SR" + HANDLE hsrvr; // global handle + ATOM aClass; // class atom + ATOM aExe; + HWND hwnd; // corresponding window + BOOL bTerminate; // Set if we are terminating. + int termNo; // termination count + BOOL relLock; // ok to release the server. + BOOL bnoRelease; // Block release. call + WORD useFlags; // instance usage flags + int cClients; // no of clients; + BOOL bBlock; // blocked if TRUE + BOOL bBlockedMsg; // msg from block queue if TRUE + HANDLE hqHead; // Head and tail of the blocked + HANDLE hqTail; // messages queue. + + HANDLE hqPostHead; // Head and tail of the blocked post msg + HANDLE hqPostTail; // . + BOOL fAckExit; + HWND hwndExit; + HANDLE hDataExit; +} SRVR; + +typedef SRVR FAR *LPSRVR; + + +LONG FAR PASCAL DocWndProc (HWND, WORD, WORD, LONG); +LONG FAR PASCAL ItemWndProc (HWND, WORD, WORD, LONG); +LONG FAR PASCAL SrvrWndProc (HWND, WORD, WORD, LONG); +BOOL FAR PASCAL TerminateClients (HWND, LPSTR, HANDLE); +void SendMsgToChildren (HWND, WORD, WORD, LONG); + + +OLESTATUS INTERNAL RequestDataStd (LONG, HANDLE FAR *); +BOOL INTERNAL ValidateSrvrClass (LPSTR, ATOM FAR *); +ATOM INTERNAL GetExeAtom (LPSTR); +BOOL INTERNAL AddClient (HWND, HANDLE, HANDLE); +BOOL INTERNAL DeleteClient (HWND, HANDLE); +HANDLE INTERNAL FindClient (HWND, HANDLE); +BOOL INTERNAL MakeSrvrStr(LPSTR, int, LPSTR, HANDLE); +int INTERNAL RevokeAllDocs (LPSRVR); +int INTERNAL ReleaseSrvr (LPSRVR); +void INTERNAL WaitForTerminate (LPSRVR); +OLESTATUS INTERNAL SrvrExecute (HWND, HANDLE, HWND); +BOOL INTERNAL HandleInitMsg (LPSRVR, LONG); +BOOL INTERNAL QueryRelease (LPSRVR); +BOOL INTERNAL IsSingleServerInstance (void); + +void INTERNAL MapToHexStr (LPSTR, HANDLE); +void INTERNAL UtilMemCpy (LPSTR, LPSTR, DWORD); +HANDLE INTERNAL DuplicateData (HANDLE); +LPSTR INTERNAL ScanBoolArg (LPSTR, BOOL FAR *); +LPSTR INTERNAL ScanNumArg (LPSTR, LPINT); +LPSTR INTERNAL ScanArg(LPSTR); +ATOM INTERNAL MakeDataAtom (ATOM, int); +ATOM INTERNAL DuplicateAtom (ATOM); + + +// doc stuff +typedef struct _DOC { /*doc*/ // private data + LPOLESERVERDOC lpoledoc; // corresponding oledoc + char sig[2]; // signature "SD" + HANDLE hdoc; // global handle + ATOM aDoc; + HWND hwnd; + BOOL bTerminate; + int termNo; + int cClients; // no of clients; + BOOL fEmbed; // TRUE if embedded document + BOOL fAckClose; + HWND hwndClose; + HANDLE hDataClose; +} DOC; + +typedef DOC FAR *LPDOC; + + +LPDOC INTERNAL FindDoc (LPSRVR, LPSTR); +int INTERNAL ReleaseDoc (LPDOC); +OLESTATUS INTERNAL DocExecute (HWND, HANDLE, HWND); +BOOL FAR PASCAL TerminateDocClients (HWND, LPSTR, HANDLE); +int INTERNAL DocShowItem (LPDOC, LPSTR, BOOL); +int INTERNAL DocDoVerbItem (LPDOC, LPSTR, WORD, BOOL, BOOL); + + +// client struct definitions. + +typedef struct _CLIENT { /*doc*/ // private data + OLECLIENT oleClient; // oleclient structure + LPOLEOBJECT lpoleobject; // corresponding oledoc + HANDLE hclient; // global handle + ATOM aItem; // item atom or index for some std items + HWND hwnd; // item window + HANDLE hdevInfo; // latest printer dev info sent +} CLIENT; + +typedef CLIENT FAR *LPCLIENT; + +typedef struct _CLINFO { /*clInfo*/ // client transaction info + HWND hwnd; // client window handle + BOOL bnative; // doe sthis client require native + int format; // dusplay format + int options; // transaction advise time otipns + BOOL bdata; // need wdat with advise? + HANDLE hdevInfo; // device info handle + BOOL bnewDevInfo; // new device info +} CLINFO; + +typedef CLINFO *PCLINFO; + + + + +BOOL FAR PASCAL FindItemWnd (HWND, LONG); +BOOL FAR PASCAL SendRenameMsg (HWND, LPSTR, HANDLE); +BOOL FAR PASCAL EnumForTerminate (HWND, LPSTR, HANDLE); +BOOL FAR PASCAL SendDataMsg(HWND, LPSTR, HANDLE); +BOOL FAR PASCAL DeleteClientInfo (HWND, LPSTR, HANDLE); +int FAR PASCAL ItemCallBack (LPOLECLIENT, int, LPOLEOBJECT); + +int INTERNAL RegisterItem (LHDOC, LPSTR, LPCLIENT FAR *, BOOL); +int INTERNAL FindItem (LPDOC, LPSTR, LPCLIENT FAR *); +HWND INTERNAL SearchItem (LPDOC, LPSTR); +void INTERNAL DeleteFromItemsList (HWND, HWND); +void INTERNAL DeleteAllItems (HWND); +OLESTATUS INTERNAL PokeData (LPDOC, HWND, LONG); +HANDLE INTERNAL MakeItemData (DDEPOKE FAR *, HANDLE, OLECLIPFORMAT); +OLESTATUS INTERNAL AdviseData (LPDOC, HWND, LONG, BOOL FAR *); +OLESTATUS INTERNAL AdviseStdItems (LPDOC, HWND, LONG, BOOL FAR *); +OLESTATUS INTERNAL UnAdviseData (LPDOC, HWND, LONG); +OLESTATUS INTERNAL RequestData (LPDOC, HWND, LONG, HANDLE FAR *); +BOOL INTERNAL MakeDDEData (HANDLE, int, LPHANDLE, BOOL); +HANDLE INTERNAL MakeGlobal (LPSTR); +int INTERNAL ScanItemOptions (LPSTR, int far *); +OLESTATUS INTERNAL PokeStdItems (LPDOC, HWND, LONG); +int INTERNAL GetStdItemIndex (ATOM); +BOOL INTERNAL IsAdviseStdItems (ATOM); +int INTERNAL SetStdInfo (LPDOC, HWND, LPSTR, HANDLE); +void INTERNAL SendDevInfo (LPCLIENT, LPSTR); +BOOL INTERNAL IsFormatAvailable (LPCLIENT, OLECLIPFORMAT); +OLESTATUS INTERNAL RevokeObject (LPOLECLIENT, BOOL); + + +BOOL INTERNAL AddMessage (HWND, unsigned, WORD, LONG, int); + +#define ITEM_FIND 1 // find the item +#define ITEM_DELETECLIENT 2 // delete the client from item clients +#define ITEM_DELETE 3 // delete th item window itself +#define ITEM_SAVED 4 // item saved + +// host names data structcure +typedef struct _HOSTNAMES { + WORD clientNameOffset; + WORD documentNameOffset; + BYTE data[]; +} HOSTNAMES; + +typedef HOSTNAMES FAR * LPHOSTNAMES; + + +// routines in UTILS.C + +void INTERNAL MapToHexStr (LPSTR, HANDLE); +void INTERNAL UtilMemCpy (LPSTR, LPSTR, DWORD); +HANDLE INTERNAL DuplicateData (HANDLE); +LPSTR INTERNAL ScanLastBoolArg (LPSTR); +LPSTR INTERNAL ScanArg(LPSTR); +WORD INTERNAL ScanCommand(LPSTR, WORD, LPSTR FAR *, ATOM FAR *); +ATOM INTERNAL MakeDataAtom (ATOM, int); +ATOM INTERNAL DuplicateAtom (ATOM); +WORD INTERNAL StrToInt (LPSTR); +BOOL INTERNAL CheckServer (LPSRVR); +BOOL INTERNAL CheckServerDoc (LPDOC); +BOOL INTERNAL PostMessageToClientWithBlock (HWND, WORD, WORD, DWORD); +BOOL INTERNAL PostMessageToClient (HWND, WORD, WORD, DWORD); +BOOL INTERNAL IsWindowValid (HWND); +BOOL INTERNAL IsOleCommand (ATOM, WORD); +BOOL INTERNAL UtilQueryProtocol (ATOM, LPSTR); + + +// routines for queueing messages and posting them +BOOL INTERNAL UnblockPostMsgs(HWND, BOOL); +BOOL INTERNAL BlockPostMsg (HWND, WORD, WORD, LONG); +BOOL INTERNAL IsBlockQueueEmpty (HWND); + +// routine in GIVE2GDI.ASM +HANDLE FAR PASCAL GiveToGDI (HANDLE); + + +// routine in item.c +HBITMAP INTERNAL DuplicateBitmap (HBITMAP); +HANDLE INTERNAL DuplicateMetaFile (HANDLE); + +// routines in doc.c +void INTERNAL FreePokeData (HANDLE); +BOOL INTERNAL FreeGDIdata (HANDLE, OLECLIPFORMAT); + + + diff --git a/private/mvdm/wow16/ole/server/srvr.rc b/private/mvdm/wow16/ole/server/srvr.rc new file mode 100644 index 000000000..8f1e7ecc1 --- /dev/null +++ b/private/mvdm/wow16/ole/server/srvr.rc @@ -0,0 +1,4 @@ +#include <windows.h> +#include "olesvr.rcv" + + diff --git a/private/mvdm/wow16/ole/server/srvrmain.c b/private/mvdm/wow16/ole/server/srvrmain.c new file mode 100644 index 000000000..eb468726e --- /dev/null +++ b/private/mvdm/wow16/ole/server/srvrmain.c @@ -0,0 +1,319 @@ +/****************************** Module Header ******************************\ +* Module Name: Srvrmain.c Server Main module +* +* Purpose: Includes server intialization and termination code. +* +* Created: Oct 1990. +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor (../10/1990) Designed, coded +* +* +\***************************************************************************/ + +#include "cmacs.h" +#include "windows.h" +#include "ole.h" +#include "dde.h" +#include "srvr.h" + +#ifndef WF_WLO +#define WF_WLO 0x8000 +#endif + +// ordinal number of new Win31 API IsTask +#define ORD_IsTask 320 + +// ordinal number of new Win31 API SetMetaFileBitsBetter +#define ORD_SetMetaFileBitsBetter 196 + + +#ifdef FIREWALLS +short ole_flags; +char szDebugBuffer[80]; +void SetOleFlags(void); +#endif + + +// public vars. + +// atomes used in the systems +ATOM aStdExit; // "StdExit" +ATOM aStdCreate; // "StdNewDicument" +ATOM aStdOpen; // "StdOpenDocument" +ATOM aStdEdit; // "StdOpenDocument" +ATOM aStdCreateFromTemplate; // "StdNewFromTemplate" +ATOM aStdClose; // "StdCloseDocument" +ATOM aStdShowItem; // "StdShowItem" +ATOM aStdDoVerbItem; // "StddoVerbItem" +ATOM aSysTopic; // "System" +ATOM aOLE; // "OLE" +ATOM aStdDocName; // "StdDocumentName" + +ATOM cfBinary; // "Binary format" +ATOM cfNative; // "NativeFormat" +ATOM cfLink; // "ObjectLink" +ATOM cfOwnerLink; // "Ownerlink" + +ATOM aChange; // "Change" +ATOM aSave; // "Save" +ATOM aClose; // "Close" +ATOM aProtocols; // "Protocols" +ATOM aTopics; // "Topics" +ATOM aFormats; // "Formats" +ATOM aStatus; // "Status" +ATOM aEditItems; // "Edit items +ATOM aTrue; // "True" +ATOM aFalse; // "False" + + + + + +// !!! free the proc instances. +FARPROC lpSendRenameMsg; // Call back enum props for rename +FARPROC lpSendDataMsg; // Call back enum props for data +FARPROC lpFindItemWnd; // Callback in enum props of +FARPROC lpItemCallBack; // CallBack for object +FARPROC lpTerminateClients; // Callback in Doc enum properties +FARPROC lpTerminateDocClients; // Callback in Doc enum properties +FARPROC lpDeleteClientInfo; // proc for deleteing each item client +FARPROC lpEnumForTerminate; // proc for terminating clients not in rename list + +FARPROC lpfnSetMetaFileBitsBetter = NULL; +FARPROC lpfnIsTask = NULL; + +HANDLE hdllInst; +BOOL bProtMode; +BOOL bWLO = FALSE; +BOOL bWin30 = FALSE; + +VOID FAR PASCAL WEP (int); +#pragma alloc_text(WEP_TEXT, WEP) + +int FAR PASCAL LibMain (hInst, wDataSeg, cbHeapSize, lpszCmdLine) +HANDLE hInst; +WORD wDataSeg; +WORD cbHeapSize; +LPSTR lpszCmdLine; +{ + WNDCLASS wc; + + Puts("LibMain"); + +#ifdef FIREWALLS + SetOleFlags(); +#endif + + hdllInst = hInst; + + bProtMode = (BOOL) (GetWinFlags() & WF_PMODE & 0x0000FFFF); + bWLO = (BOOL) (GetWinFlags() & WF_WLO); + bWin30 = (!bWLO && ((WORD) GetVersion()) <= 0x0003); + + // !!! Put all this stuff thru soemkind of table so that we can + // save code. + + // register all the atoms. + aStdExit = GlobalAddAtom ((LPSTR)"StdExit"); + aStdCreate = GlobalAddAtom ((LPSTR)"StdNewDocument"); + aStdOpen = GlobalAddAtom ((LPSTR)"StdOpenDocument"); + aStdEdit = GlobalAddAtom ((LPSTR)"StdEditDocument"); + aStdCreateFromTemplate = GlobalAddAtom ((LPSTR)"StdNewfromTemplate"); + + aStdClose = GlobalAddAtom ((LPSTR)"StdCloseDocument"); + aStdShowItem = GlobalAddAtom ((LPSTR)"StdShowItem"); + aStdDoVerbItem = GlobalAddAtom ((LPSTR)"StdDoVerbItem"); + aSysTopic = GlobalAddAtom ((LPSTR)"System"); + aOLE = GlobalAddAtom ((LPSTR)"OLEsystem"); + aStdDocName = GlobalAddAtom ((LPSTR)"StdDocumentName"); + + aProtocols = GlobalAddAtom ((LPSTR)"Protocols"); + aTopics = GlobalAddAtom ((LPSTR)"Topics"); + aFormats = GlobalAddAtom ((LPSTR)"Formats"); + aStatus = GlobalAddAtom ((LPSTR)"Status"); + aEditItems = GlobalAddAtom ((LPSTR)"EditEnvItems"); + + aTrue = GlobalAddAtom ((LPSTR)"True"); + aFalse = GlobalAddAtom ((LPSTR)"False"); + + aChange = GlobalAddAtom ((LPSTR)"Change"); + aSave = GlobalAddAtom ((LPSTR)"Save"); + aClose = GlobalAddAtom ((LPSTR)"Close"); + + // create the proc instances for the required entry pts. + lpSendRenameMsg = MakeProcInstance (SendRenameMsg, hdllInst); + lpSendDataMsg = MakeProcInstance (SendDataMsg, hdllInst); + lpFindItemWnd = MakeProcInstance (FindItemWnd, hdllInst); + lpItemCallBack = MakeProcInstance (ItemCallBack, hdllInst); + lpTerminateClients = MakeProcInstance (TerminateClients, hdllInst); + lpTerminateDocClients = MakeProcInstance (TerminateDocClients, hdllInst); + lpDeleteClientInfo = MakeProcInstance (DeleteClientInfo, hdllInst); + lpEnumForTerminate = MakeProcInstance (EnumForTerminate , hdllInst); + + // register the clipboard formats + cfNative = RegisterClipboardFormat("Native"); + cfBinary = RegisterClipboardFormat("Binary"); + cfLink = RegisterClipboardFormat("ObjectLink"); + cfOwnerLink = RegisterClipboardFormat("OwnerLink"); + + + + wc.style = NULL; + wc.cbClsExtra = 0; + wc.cbWndExtra = sizeof(LONG) + //Ask for extra space for storing the + //ptr to srvr/doc/iteminfo. + sizeof (WORD) + // for LE chars + sizeof (WORD); // for keeping the hDLLInst. + + wc.hInstance = hInst; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground= NULL; + wc.lpszMenuName = NULL; + + + // Srvr window class + wc.lpfnWndProc = SrvrWndProc; + wc.lpszClassName= SRVR_CLASS; + if (!RegisterClass(&wc)) + return 0; + + // document window class + wc.lpfnWndProc = DocWndProc; + wc.lpszClassName = DOC_CLASS; + + if (!RegisterClass(&wc)) + return 0; + + // Item (object) window class + wc.lpfnWndProc = ItemWndProc; + wc.lpszClassName = ITEM_CLASS; + + wc.cbWndExtra = sizeof(LONG); // for items do not need extra stuff. + if (!RegisterClass(&wc)) + return 0; + + + if (!bWin30) { + HANDLE hModule; + + if (hModule = GetModuleHandle ("GDI")) + lpfnSetMetaFileBitsBetter + = GetProcAddress (hModule, + (LPSTR) MAKELONG(ORD_SetMetaFileBitsBetter, 0)); + + if (hModule = GetModuleHandle ("KERNEL")) + lpfnIsTask + = GetProcAddress (hModule, (LPSTR) MAKELONG(ORD_IsTask, 0)); + } + + if (cbHeapSize != 0) + UnlockData(0); + + return 1; +} + + +VOID FAR PASCAL WEP (nParameter) +int nParameter; +{ + + Puts("LibExit"); + + if (nParameter == WEP_SYSTEM_EXIT) + DEBUG_OUT ("---L&E DLL EXIT on system exit---",0) + + else { + if (nParameter == WEP_FREE_DLL) + DEBUG_OUT ("---L&E DLL EXIT---",0) + + else + return; + } + + // free the global atoms. + if (aStdExit) + GlobalDeleteAtom (aStdExit); + if (aStdCreate) + GlobalDeleteAtom (aStdCreate); + if (aStdOpen) + GlobalDeleteAtom (aStdOpen); + if (aStdEdit) + GlobalDeleteAtom (aStdEdit); + if (aStdCreateFromTemplate) + GlobalDeleteAtom (aStdCreateFromTemplate); + if (aStdClose) + GlobalDeleteAtom (aStdClose); + if (aStdShowItem) + GlobalDeleteAtom (aStdShowItem); + if (aStdDoVerbItem) + GlobalDeleteAtom (aStdDoVerbItem); + if (aSysTopic) + GlobalDeleteAtom (aSysTopic); + if (aOLE) + GlobalDeleteAtom (aOLE); + if (aStdDocName) + GlobalDeleteAtom (aStdDocName); + + if (aProtocols) + GlobalDeleteAtom (aProtocols); + if (aTopics) + GlobalDeleteAtom (aTopics); + if (aFormats) + GlobalDeleteAtom (aFormats); + if (aStatus) + GlobalDeleteAtom (aStatus); + if (aEditItems) + GlobalDeleteAtom (aEditItems); + + if (aTrue) + GlobalDeleteAtom (aTrue); + if (aFalse) + GlobalDeleteAtom (aFalse); + + if (aChange) + GlobalDeleteAtom (aChange); + if (aSave) + GlobalDeleteAtom (aSave); + if (aClose) + GlobalDeleteAtom (aClose); + + // !!! for some reason these FreeprocInstances are crashing the system. +#if 0 + FreeProcInstance (lpSendRenameMsg); + FreeProcInstance (lpSendDataMsg); + FreeProcInstance (lpFindItemWnd); + FreeProcInstance (lpItemCallBack); + FreeProcInstance (lpTerminateClients); + FreeProcInstance (lpTerminateDocClients); + FreeProcInstance (lpDeleteClientInfo); + FreeProcInstance (EnumForTerminate); +#endif + +} + + + +#ifdef FIREWALLS +void SetOleFlags() +{ + + char buffer[80]; + + if(GetProfileString ("OleDll", + "Puts","", (LPSTR)buffer, 80)) + ole_flags = DEBUG_PUTS; + else + ole_flags = 0; + + + if(GetProfileString ("OleDll", + "DEBUG_OUT","", (LPSTR)buffer, 80)) + ole_flags |= DEBUG_DEBUG_OUT; + +} + +#endif diff --git a/private/mvdm/wow16/ole/server/utils.c b/private/mvdm/wow16/ole/server/utils.c new file mode 100644 index 000000000..63512e539 --- /dev/null +++ b/private/mvdm/wow16/ole/server/utils.c @@ -0,0 +1,573 @@ +/****************************** Module Header ******************************\ +* Module Name: utils.c +* +* Purpose: Conatains all the utility routines +* +* Created: 1990 +* +* Copyright (c) 1990, 1991 Microsoft Corporation +* +* History: +* Raor, Srinik (../../1990) Designed and coded +* +\***************************************************************************/ + +#include <windows.h> +#include "cmacs.h" +#include <shellapi.h> + +#include "ole.h" +#include "dde.h" +#include "srvr.h" + + +#ifndef HUGE +#define HUGE huge +#endif + +#define KB_64 65536 + +extern ATOM aTrue; +extern ATOM aFalse; +extern BOOL bWLO; +extern BOOL bWin30; + +extern ATOM aStdCreateFromTemplate; +extern ATOM aStdCreate; +extern ATOM aStdOpen; +extern ATOM aStdEdit; +extern ATOM aStdShowItem; +extern ATOM aStdClose; +extern ATOM aStdExit; +extern ATOM aStdDoVerbItem; + +extern BOOL (FAR PASCAL *lpfnIsTask) (HANDLE); + +// MapToHexStr: Converts WORD to hex string. +void INTERNAL MapToHexStr (lpbuf, hdata) +LPSTR lpbuf; +HANDLE hdata; +{ + int i; + char ch; + + *lpbuf++ = '@'; + for ( i = 3; i >= 0; i--) { + + ch = (char) ((((WORD)hdata) >> (i * 4)) & 0x000f); + if(ch > '9') + ch += 'A' - 10; + else + ch += '0'; + + *lpbuf++ = ch; + } + + *lpbuf++ = NULL; + +} + + +void INTERNAL UtilMemCpy (lpdst, lpsrc, dwCount) +LPSTR lpdst; +LPSTR lpsrc; +DWORD dwCount; +{ + WORD HUGE * hpdst; + WORD HUGE * hpsrc; + WORD FAR * lpwDst; + WORD FAR * lpwSrc; + DWORD words; + DWORD bytes; + + bytes = dwCount % 2; + words = dwCount >> 1; //* we should compare DWORDS + //* in the 32 bit version + if (dwCount <= KB_64) { + lpwDst = (WORD FAR *) lpdst; + lpwSrc = (WORD FAR *) lpsrc; + + while (words--) + *lpwDst++ = *lpwSrc++; + + if (bytes) + * (char FAR *) lpwDst = * (char FAR *) lpwSrc; + } + else { + hpdst = (WORD HUGE *) lpdst; + hpsrc = (WORD HUGE *) lpsrc; + + while (words--) + *hpdst++ = *hpsrc++; + + if (bytes) + *(char HUGE *) hpdst = * (char HUGE *) hpsrc; + } +} + + +//DuplicateData: Duplicates a given Global data handle. +HANDLE INTERNAL DuplicateData (hdata) +HANDLE hdata; +{ + LPSTR lpsrc = NULL; + LPSTR lpdst = NULL; + HANDLE hdup = NULL; + DWORD size; + BOOL err = TRUE; + + if(!(lpsrc = GlobalLock (hdata))) + return NULL; + + hdup = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, (size = GlobalSize(hdata))); + + if(!(lpdst = GlobalLock (hdup))) + goto errRtn;; + + err = FALSE; + UtilMemCpy (lpdst, lpsrc, size); + +errRtn: + if(lpsrc) + GlobalUnlock (hdata); + + if(lpdst) + GlobalUnlock (hdup); + + if (err && hdup) + GlobalFree (hdup); + + return hdup; +} + + +//ScanBoolArg: scans the argument which is not included in +//the quotes. These args could be only TRUE or FALSE for +//the time being. !!!The scanning routines should be +//merged and it should be generalized. + +LPSTR INTERNAL ScanBoolArg (lpstr, lpflag) +LPSTR lpstr; +BOOL FAR *lpflag; +{ + + + LPSTR lpbool; + ATOM aShow; + char ch; + + lpbool = lpstr; + + // !!! These routines does not take care of quoted quotes. + + while((ch = *lpstr) && (!(ch == ')' || ch == ','))) + lpstr++; + + if(ch == NULL) + return NULL; + + *lpstr++ = NULL; // terminate the arg by null + + // if terminated by paren, then check for end of command + // syntax. + + // Check for the end of the command string. + if (ch == ')') { + if (*lpstr++ != ']') + return NULL; + + if(*lpstr != NULL) + return NULL; //finally should be terminated by null. + + } + + aShow = GlobalFindAtom (lpbool); + if (aShow == aTrue) + *lpflag = TRUE; + + else { + if (aShow ==aFalse) + *lpflag = FALSE; + else + return NULL;; + } + return lpstr; +} + + + + +//ScannumArg: Checks for the syntax of num arg in Execute and if +//the arg is syntactically correct, returns the ptr to the +//beginning of the next arg and also, returns the number +//Does not take care of the last num arg in the list. + +LPSTR INTERNAL ScanNumArg (lpstr, lpnum) +LPSTR lpstr; +LPINT lpnum; +{ + + WORD val = 0; + char ch; + + while((ch = *lpstr++) && (ch != ',')) { + if (ch < '0' || ch >'9') + return NULL; + val += val * 10 + (ch - '0'); + + } + + if(!ch) + return NULL; + + *lpnum = val; + return lpstr; +} + + + + +//ScanArg: Checks for the syntax of arg in Execute and if +//the arg is syntactically correct, returns the ptr to the +//beginning of the next arg or to the end of the excute string. + +LPSTR INTERNAL ScanArg (lpstr) +LPSTR lpstr; +{ + + + // !!! These routines does not take care of quoted quotes. + + // first char should be quote. + + if (*(lpstr-1) != '\"') + return NULL; + + while(*lpstr && *lpstr != '\"') + lpstr++; + + if(*lpstr == NULL) + return NULL; + + *lpstr++ = NULL; // terminate the arg by null + + if(!(*lpstr == ',' || *lpstr == ')')) + return NULL; + + + if(*lpstr++ == ','){ + + if(*lpstr == '\"') + return ++lpstr; + // If it is not quote, leave the ptr on the first char + return lpstr; + } + + // terminated by paren + // already skiped right paren + + // Check for the end of the command string. + if (*lpstr++ != ']') + return NULL; + + if(*lpstr != NULL) + return NULL; //finally should be terminated by null. + + return lpstr; +} + +// ScanCommand: scanns the command string for the syntax +// correctness. If syntactically correct, returns the ptr +// to the first arg or to the end of the string. + +WORD INTERNAL ScanCommand (lpstr, wType, lplpnextcmd, lpAtom) +LPSTR lpstr; +WORD wType; +LPSTR FAR * lplpnextcmd; +ATOM FAR * lpAtom; +{ + // !!! These routines does not take care of quoted quotes. + // and not taking care of blanks arround the operators + + // !!! We are not allowing blanks after operators. + // Should be allright! since this is arestricted syntax. + + char ch; + LPSTR lptemp = lpstr; + + + while(*lpstr && (!(*lpstr == '(' || *lpstr == ']'))) + lpstr++; + + if(*lpstr == NULL) + return NULL; + + ch = *lpstr; + *lpstr++ = NULL; // set the end of command + + *lpAtom = GlobalFindAtom (lptemp); + + if (!IsOleCommand (*lpAtom, wType)) + return NON_OLE_COMMAND; + + if (ch == '(') { + ch = *lpstr++; + + if (ch == ')') { + if (*lpstr++ != ']') + return NULL; + } + else { + if (ch != '\"') + return NULL; + } + + *lplpnextcmd = lpstr; + return OLE_COMMAND; + } + + // terminated by ']' + + if (*(*lplpnextcmd = lpstr)) // if no nul termination, then it is error. + return NULL; + + return OLE_COMMAND; +} + + +//MakeDataAtom: Creates a data atom from the item string +//and the item data otions. + +ATOM INTERNAL MakeDataAtom (aItem, options) +ATOM aItem; +int options; +{ + char buf[MAX_STR]; + + if (options == OLE_CHANGED) + return DuplicateAtom (aItem); + + if (!aItem) + buf[0] = NULL; + else + GlobalGetAtomName (aItem, (LPSTR)buf, MAX_STR); + + if (options == OLE_CLOSED) + lstrcat ((LPSTR)buf, (LPSTR) "/Close"); + else { + if (options == OLE_SAVED) + lstrcat ((LPSTR)buf, (LPSTR) "/Save"); + } + + if (buf[0]) + return GlobalAddAtom ((LPSTR)buf); + else + return NULL; +} + +//DuplicateAtom: Duplicates an atom +ATOM INTERNAL DuplicateAtom (atom) +ATOM atom; +{ + char buf[MAX_STR]; + + Puts ("DuplicateAtom"); + + if (!atom) + return NULL; + + GlobalGetAtomName (atom, buf, MAX_STR); + return GlobalAddAtom (buf); +} + +// MakeGlobal: makes global out of strings. +// works only for << 64k + +HANDLE INTERNAL MakeGlobal (lpstr) +LPSTR lpstr; +{ + + int len = 0; + HANDLE hdata = NULL; + LPSTR lpdata = NULL; + + len = lstrlen (lpstr) + 1; + + hdata = GlobalAlloc (GMEM_MOVEABLE | GMEM_DDESHARE, len); + if (hdata == NULL || (lpdata = (LPSTR) GlobalLock (hdata)) == NULL) + goto errRtn; + + + UtilMemCpy (lpdata, lpstr, (DWORD)len); + GlobalUnlock (hdata); + return hdata; + +errRtn: + + if (lpdata) + GlobalUnlock (hdata); + + + if (hdata) + GlobalFree (hdata); + + return NULL; + +} + + + +BOOL INTERNAL CheckServer (lpsrvr) +LPSRVR lpsrvr; +{ + if (!CheckPointer(lpsrvr, WRITE_ACCESS)) + return FALSE; + + if ((lpsrvr->sig[0] == 'S') && (lpsrvr->sig[1] == 'R')) + return TRUE; + + return FALSE; +} + + +BOOL INTERNAL CheckServerDoc (lpdoc) +LPDOC lpdoc; +{ + if (!CheckPointer(lpdoc, WRITE_ACCESS)) + return FALSE; + + if ((lpdoc->sig[0] == 'S') && (lpdoc->sig[1] == 'D')) + return TRUE; + + return FALSE; +} + + +BOOL INTERNAL PostMessageToClientWithBlock (hWnd, wMsg, wParam, lParam) +HWND hWnd; +WORD wMsg; +WORD wParam; +DWORD lParam; +{ + if (!IsWindowValid (hWnd)) { + ASSERT(FALSE, "Client's window is missing"); + return FALSE; + } + + if (IsBlockQueueEmpty ((HWND)wParam) && PostMessage (hWnd, wMsg, wParam, lParam)) + return TRUE; + + BlockPostMsg (hWnd, wMsg, wParam, lParam); + return TRUE; +} + + + +BOOL INTERNAL PostMessageToClient (hWnd, wMsg, wParam, lParam) +HWND hWnd; +WORD wMsg; +WORD wParam; +DWORD lParam; +{ + if (!IsWindowValid (hWnd)) { + ASSERT(FALSE, "Client's window is missing"); + return FALSE; + } + + if (IsBlockQueueEmpty ((HWND)wParam) && PostMessage (hWnd, wMsg, wParam, lParam)) + return TRUE; + + BlockPostMsg (hWnd, wMsg, wParam, lParam); + return TRUE; +} + + +BOOL INTERNAL IsWindowValid (hwnd) +HWND hwnd; +{ + +#define TASK_OFFSET 0x00FA + + LPSTR lptask; + HANDLE htask; + + if (!IsWindow (hwnd)) + return FALSE; + + if (bWLO) + return TRUE; + + // now get the task handle and find out it is valid. + htask = GetWindowTask (hwnd); + + if (bWin30 || !lpfnIsTask) { + lptask = (LPSTR)(MAKELONG (TASK_OFFSET, htask)); + + if (!CheckPointer(lptask, READ_ACCESS)) + return FALSE; + + // now check for the signature bytes of task block in kernel + if (*lptask++ == 'T' && *lptask == 'D') + return TRUE; + } + else { + // From win31 onwards the API IsTask() can be used for task validation + if ((*lpfnIsTask)(htask)) + return TRUE; + } + + return FALSE; +} + + + +BOOL INTERNAL UtilQueryProtocol (aClass, lpprotocol) +ATOM aClass; +LPSTR lpprotocol; +{ + HKEY hKey; + char key[MAX_STR]; + char class[MAX_STR]; + + if (!aClass) + return FALSE; + + if (!GlobalGetAtomName (aClass, class, MAX_STR)) + return FALSE; + + lstrcpy (key, class); + lstrcat (key, "\\protocol\\"); + lstrcat (key, lpprotocol); + lstrcat (key, "\\server"); + + if (RegOpenKey (HKEY_CLASSES_ROOT, key, &hKey)) + return FALSE; + + RegCloseKey (hKey); + return TRUE; +} + + +BOOL INTERNAL IsOleCommand (aCmd, wType) +ATOM aCmd; +WORD wType; +{ + if (wType == WT_SRVR) { + if ((aCmd == aStdCreateFromTemplate) + || (aCmd == aStdCreate) + || (aCmd == aStdOpen) + || (aCmd == aStdEdit) + || (aCmd == aStdShowItem) + || (aCmd == aStdClose) + || (aCmd == aStdExit)) + return TRUE; + } + else { + if ((aCmd == aStdClose) + || (aCmd == aStdDoVerbItem) + || (aCmd == aStdShowItem)) + return TRUE; + } + + return FALSE; +} |