windows-nt/Source/XPSP1/NT/base/mvdm/wow16/ole/client/utils.c
2020-09-26 16:20:57 +08:00

670 lines
14 KiB
C

/****************************** 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;
}