/****************************** 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 * curts created portable version for WIN16/32 * \***************************************************************************/ #include #include #include "dll.h" #include "strsafe.h" #define KB_64 65536 #define NULL_WORD 0x0000 extern ATOM aPackage; extern OLEOBJECTVTBL vtblMF, vtblBM, vtblDIB, vtblGEN; // QuerySize API support DWORD dwObjSize = 0; OLESTREAMVTBL dllStreamVtbl; OLESTREAM dllStream; BOOL PutStrWithLen( 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( LPOLESTREAM lpstream, LPSTR lpbytes ){ if (GetBytes (lpstream, lpbytes, sizeof(LONG))) return TRUE; return GetBytes (lpstream, lpbytes + sizeof(LONG), (*(LONG FAR *)lpbytes)); } ATOM GetAtomFromStream( LPOLESTREAM lpstream ){ BOOL err = TRUE; LONG len; char str[MAX_STR+1]; if (GetBytes (lpstream, (LPSTR)&len, sizeof(len))) return (ATOM)0; if (len == 0) return (ATOM)0; if (GetBytes(lpstream, (LPSTR)str, len)) return (ATOM)0; return GlobalAddAtom(str); } BOOL PutAtomIntoStream( 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 (ATOM)0; GlobalGetAtomName (atom, buffer, MAX_ATOM); return GlobalAddAtom (buffer); } BOOL GetBytes( 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( 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 ( LPSTR lpmem1, LPSTR lpmem2, DWORD dwCount ){ UINT HUGE_T * hpmem1; UINT HUGE_T * hpmem2; DWORD words; DWORD bytes; bytes = dwCount % MAPVALUE(2,4); words = dwCount >> MAPVALUE(1,2);//* we compare DWORDS //* in the 32 bit version { hpmem1 = (UINT HUGE_T *) lpmem1; hpmem2 = (UINT HUGE_T *) lpmem2; while (words--) { if (*hpmem1++ != *hpmem2++) return FALSE; } lpmem1 = (LPSTR)hpmem1; lpmem2 = (LPSTR)hpmem2; for (; bytes-- ; ) { if ( *lpmem1++ != *lpmem2++ ) return FALSE; } } return TRUE; } void FARINTERNAL UtilMemCpy ( LPSTR lpdst, LPSTR lpsrc, DWORD dwCount ){ UINT HUGE_T * hpdst; UINT HUGE_T * hpsrc; DWORD words; DWORD bytes; bytes = dwCount % MAPVALUE(2,4); words = dwCount >> MAPVALUE(1,2);//* we compare DWORDS //* in the 32 bit version { hpdst = (UINT HUGE_T *) lpdst; hpsrc = (UINT HUGE_T *) lpsrc; for(;words--; ) *hpdst++ = *hpsrc++; lpdst = (LPSTR)hpdst; lpsrc = (LPSTR)hpsrc; for (;bytes--;) *lpdst++ = *lpsrc++; } } //DuplicateData: Duplicates a given Global data handle. HANDLE FARINTERNAL DuplicateGlobal ( HANDLE hdata, UINT 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 = (DWORD)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 ( HANDLE hdata1, HANDLE hdata2 ){ LPSTR lpdata1 = NULL; LPSTR lpdata2 = NULL; DWORD size1; DWORD size2; BOOL retval = FALSE; size1 = (DWORD)GlobalSize (hdata1); size2 = (DWORD)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 ( ATOM aItem ){ // !!! Change this char buf[MAX_STR]; if (!aItem) return 0; return (GlobalGetAtomName (aItem, (LPSTR)buf, MAX_STR)); } BOOL FARINTERNAL MapExtToClass ( LPSTR lptemplate, LPSTR lpbuf, int len ){ LONG cb; LPSTR lpstrBack = NULL; while (*lptemplate) { if ((*lptemplate) == '\\'){ lpstrBack = lptemplate ; } lptemplate ++ ; } while (lpstrBack && *lpstrBack && *lpstrBack != '.') lpstrBack++ ; cb = len; if (lpstrBack == NULL || *(lpstrBack+1) == '\0') return FALSE; if (QueryClassesRootValueA (lpstrBack, lpbuf, &cb)) return FALSE; return TRUE; } // Get exe name from aClass and set it as aServer void INTERNAL SetExeAtom ( 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 ( LPCSTR lpclass ){ char buf1[MAX_STR]; if (!QueryApp (lpclass, PROTOCOL_EDIT, buf1)) { return (ATOM)0; } return GlobalAddAtom ((LPSTR)buf1); } BOOL FARINTERNAL QueryVerb ( LPOBJECT_LE lpobj, UINT 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; StringCchCopy(key, sizeof(key)/sizeof(key[0]), (LPSTR)class); StringCchCat (key, sizeof(key)/sizeof(key[0]), "\\protocol\\StdFileEditing\\verb\\"); len = lstrlen (key); // If we don't have room to add the char fail if (len >= sizeof(key)/sizeof(key[0]) - 1) return FALSE; key [len++] = (char) ('0' + verb); key [len++] = 0; if (QueryClassesRootValueA (key, lpbuf, &cbmax)) return FALSE; return TRUE; } BOOL QueryApp ( LPCSTR lpclass, LPCSTR lpprotocol, LPSTR lpbuf ){ LONG cb = MAX_STR; char key[MAX_STR]; if (FAILED(StringCchCopy (key, sizeof(key)/sizeof(key[0]), lpclass))) return FALSE; if (FAILED(StringCchCat(key, sizeof(key)/sizeof(key[0]), "\\protocol\\"))) return FALSE; if (FAILED(StringCchCat(key, sizeof(key)/sizeof(key[0]), lpprotocol))) return FALSE; if (FAILED(StringCchCat(key, sizeof(key)/sizeof(key[0]), "\\server"))) return FALSE; if (QueryClassesRootValueA (key, lpbuf, &cb)) return FALSE; return TRUE; } HANDLE MapStrToH ( LPSTR lpstr ){ HANDLE hdata = NULL; LPSTR lpdata = NULL; UINT cch = lstrlen(lpstr) + 1; hdata = GlobalAlloc (GMEM_DDESHARE, cch); if (hdata == NULL || (lpdata = (LPSTR)GlobalLock (hdata)) == NULL) goto errRtn; StringCchCopy(lpdata, cch, lpstr); GlobalUnlock (hdata); return hdata; errRtn: if (lpdata) GlobalUnlock (hdata); if (hdata) GlobalFree (hdata); return NULL; } HANDLE FARINTERNAL CopyData ( 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 pstr, UINT size ){ while (size--) *pstr++ = 0; } OLESTATUS FAR PASCAL ObjQueryName ( LPOLEOBJECT lpobj, LPSTR lpBuf, UINT 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 ( LPOLEOBJECT lpobj, LPCSTR 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( UINT 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. if (FAILED(StringCchCopy (str, sizeof(str)/sizeof(str[0]), lpInfo))) goto errRtn; if (FAILED(StringCchCat (str, sizeof(str)/sizeof(str[0]), "\\protocol\\StdFileEditing\\handler"))) goto errRtn; if (OpenClassesRootKeyA (str, &hKey)) goto errRtn; RegCloseKey (hKey); fRet = TRUE; errRtn: if (lpInfo) GlobalUnlock (hInfo); if (fOpen) CloseClipboard(); return fRet; } OLESTATUS INTERNAL FileExists ( 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 ( LPOBJECT_LE lpobj, LPCSTR 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; } DWORD PASCAL FAR DllPut ( LPOLESTREAM lpstream, OLE_CONST void FAR *lpstr, DWORD dwSize ){ UNREFERENCED_PARAMETER(lpstream); UNREFERENCED_PARAMETER(lpstr); dwObjSize += dwSize; return dwSize; } OLESTATUS FARINTERNAL ObjQueryType ( LPOLEOBJECT lpobj, LPLONG lptype ){ Puts("ObjQueryType"); if (lpobj->ctype != CT_STATIC) return OLE_ERROR_OBJECT; *lptype = lpobj->ctype; return OLE_OK; } OLESTATUS FARINTERNAL ObjQuerySize ( LPOLEOBJECT lpobj, DWORD FAR * lpdwSize ){ Puts("ObjQuerySize"); *lpdwSize = dwObjSize = 0; if ((*lpobj->lpvtbl->SaveToStream) (lpobj, &dllStream) == OLE_OK) { *lpdwSize = dwObjSize; return OLE_OK; } return OLE_ERROR_BLANK; } BOOL FARINTERNAL IsObjectBlank ( LPOBJECT_LE lpobj ){ LPOLEOBJECT lpPictObj; BOOL retval=FALSE; // 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 = (((LPOBJECT_MF)lpPictObj)->hmfp != NULL); else if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblBM) retval = (((LPOBJECT_BM)lpPictObj)->hBitmap != NULL); if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblDIB) retval = (((LPOBJECT_DIB)lpPictObj)->hDIB != NULL); if (lpPictObj->lpvtbl == (LPOLEOBJECTVTBL)&vtblGEN) retval = (((LPOBJECT_GEN)lpPictObj)->hData != NULL); return retval; } BOOL FAR PASCAL OleIsDcMeta (HDC hdc) { return (GetDeviceCaps (hdc, TECHNOLOGY) == DT_METAFILE); } void ConvertBM32to16( LPBITMAP lpsrc, LPWIN16BITMAP lpdest ){ #ifdef WIN32 lpdest->bmType = (short)lpsrc->bmType; lpdest->bmWidth = (short)lpsrc->bmWidth; lpdest->bmHeight = (short)lpsrc->bmHeight; lpdest->bmWidthBytes = (short)lpsrc->bmWidthBytes; lpdest->bmPlanes = (BYTE)lpsrc->bmPlanes; lpdest->bmBitsPixel = (BYTE)lpsrc->bmBitsPixel; #endif #ifdef WIN16 *lpdest = *lpsrc; #endif } void ConvertBM16to32( LPWIN16BITMAP lpsrc, LPBITMAP lpdest ){ #ifdef WIN32 lpdest->bmType = MAKELONG(lpsrc->bmType,NULL_WORD); lpdest->bmWidth = MAKELONG(lpsrc->bmWidth,NULL_WORD); lpdest->bmHeight = MAKELONG(lpsrc->bmHeight,NULL_WORD); lpdest->bmWidthBytes = MAKELONG(lpsrc->bmWidthBytes,NULL_WORD); lpdest->bmPlanes = (WORD)lpsrc->bmPlanes; lpdest->bmBitsPixel = (WORD)lpsrc->bmBitsPixel; #endif #ifdef WIN16 *lpdest = *lpsrc; #endif } void ConvertMF16to32( LPWIN16METAFILEPICT lpsrc, LPMETAFILEPICT lpdest ){ #ifdef WIN32 lpdest->mm = (DWORD)lpsrc->mm; lpdest->xExt = (DWORD)MAKELONG(lpsrc->xExt,NULL_WORD); lpdest->yExt = (DWORD)MAKELONG(lpsrc->yExt,NULL_WORD); #endif #ifdef WIN16 *lpdest = *lpsrc; #endif } void ConvertMF32to16( LPMETAFILEPICT lpsrc, LPWIN16METAFILEPICT lpdest ){ #ifdef WIN32 lpdest->mm = (short)lpsrc->mm; lpdest->xExt = (short)lpsrc->xExt; lpdest->yExt = (short)lpsrc->yExt; #endif #ifdef WIN16 *lpdest = *lpsrc; #endif } DWORD INTERNAL GetFileVersion(LPOLEOBJECT lpoleobj) { if (lpoleobj->lhclientdoc) return ((LPCLIENTDOC)(lpoleobj->lhclientdoc))->dwFileVer; if (lpoleobj->lpParent) return GetFileVersion(lpoleobj->lpParent); return (DWORD)MAKELONG(wReleaseVer,OS_WIN32); }