/******************************* 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 #include #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 to the stream based on the * structure. It will return TRUE on success. This is the only object * function for which it is not an error to pass a NULL . 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 * 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 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 . * The 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)); }