summaryrefslogtreecommitdiffstats
path: root/private/mvdm/wow16/ole
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/wow16/ole')
-rw-r--r--private/mvdm/wow16/ole/client/amabaabo0
-rw-r--r--private/mvdm/wow16/ole/client/amabaace0
-rw-r--r--private/mvdm/wow16/ole/client/bm.c605
-rw-r--r--private/mvdm/wow16/ole/client/cmacs.h61
-rw-r--r--private/mvdm/wow16/ole/client/dde.c1327
-rw-r--r--private/mvdm/wow16/ole/client/defcreat.c215
-rw-r--r--private/mvdm/wow16/ole/client/dib.c495
-rw-r--r--private/mvdm/wow16/ole/client/dll.h958
-rw-r--r--private/mvdm/wow16/ole/client/doc.c316
-rw-r--r--private/mvdm/wow16/ole/client/draw.c1023
-rw-r--r--private/mvdm/wow16/ole/client/error.c281
-rw-r--r--private/mvdm/wow16/ole/client/funchead.c21
-rw-r--r--private/mvdm/wow16/ole/client/generic.c531
-rw-r--r--private/mvdm/wow16/ole/client/le.c2324
-rw-r--r--private/mvdm/wow16/ole/client/ledde.c2594
-rw-r--r--private/mvdm/wow16/ole/client/main.c781
-rw-r--r--private/mvdm/wow16/ole/client/makefile169
-rw-r--r--private/mvdm/wow16/ole/client/mf.c645
-rw-r--r--private/mvdm/wow16/ole/client/mk.cmd55
-rw-r--r--private/mvdm/wow16/ole/client/net.asv371
-rw-r--r--private/mvdm/wow16/ole/client/net.c371
-rw-r--r--private/mvdm/wow16/ole/client/ole.asm139
-rw-r--r--private/mvdm/wow16/ole/client/ole.c1812
-rw-r--r--private/mvdm/wow16/ole/client/ole.h504
-rw-r--r--private/mvdm/wow16/ole/client/olecli.def233
-rw-r--r--private/mvdm/wow16/ole/client/pbhandlr.c511
-rw-r--r--private/mvdm/wow16/ole/client/pict.h190
-rw-r--r--private/mvdm/wow16/ole/client/utils.c669
-rw-r--r--private/mvdm/wow16/ole/server/block.c309
-rw-r--r--private/mvdm/wow16/ole/server/doc.c1091
-rw-r--r--private/mvdm/wow16/ole/server/give2gdi.asm111
-rw-r--r--private/mvdm/wow16/ole/server/item.c1771
-rw-r--r--private/mvdm/wow16/ole/server/makefile95
-rw-r--r--private/mvdm/wow16/ole/server/olesvr.asm61
-rw-r--r--private/mvdm/wow16/ole/server/olesvr.def48
-rw-r--r--private/mvdm/wow16/ole/server/olesvr.rcv58
-rw-r--r--private/mvdm/wow16/ole/server/olever.h38
-rw-r--r--private/mvdm/wow16/ole/server/srvr.c1136
-rw-r--r--private/mvdm/wow16/ole/server/srvr.h294
-rw-r--r--private/mvdm/wow16/ole/server/srvr.rc4
-rw-r--r--private/mvdm/wow16/ole/server/srvrmain.c319
-rw-r--r--private/mvdm/wow16/ole/server/utils.c573
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, &paramBlock)) <= 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, &paramBlock)) <= 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;
+
+ 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;
+}