Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

516 lines
11 KiB

// itemutil.h//
// routines used by item.cpp
// They used to be in item.cpp but it got too big.
#include "ole2int.h"
#include "srvr.h"
#include "itemutil.h"
#include "ddedebug.h"
ASSERTDATA
//ScanItemOptions: Scan for the item options like Close/Save etc.
INTERNAL_(HRESULT) ScanItemOptions
(
LPOLESTR lpbuf,
int far *lpoptions
)
{
ATOM aModifier;
*lpoptions = OLE_CHANGED;
while ( *lpbuf && *lpbuf != '/') lpbuf++;
// no modifier same as /change
if (*lpbuf == NULL)
return NOERROR;
*lpbuf++ = NULL; // seperate out the item string
// We are using this in the caller.
if (!(aModifier = GlobalFindAtom (lpbuf)))
return ReportResult(0, RPC_E_DDE_SYNTAX_ITEM, 0, 0);
if (aModifier == aChange)
return NOERROR;
// Is it a save?
if (aModifier == aSave){
*lpoptions = OLE_SAVED;
return NOERROR;
}
// Is it a Close?
if (aModifier == aClose){
*lpoptions = OLE_CLOSED;
return NOERROR;
}
// unknow modifier
return ReportResult(0, RPC_E_DDE_SYNTAX_ITEM, 0, 0);
}
//MakeDDEData: Create a Global DDE data handle from the server
// app data handle.
INTERNAL_(BOOL) MakeDDEData
(
HANDLE hdata,
int format,
LPHANDLE lph,
BOOL fResponse
)
{
DWORD size;
HANDLE hdde = NULL;
DDEDATA FAR *lpdata= NULL;
BOOL bnative;
LPSTR lpdst;
LPSTR lpsrc;
Puts ("MakeDDEData\r\n");
if (!hdata) {
*lph = NULL;
return TRUE;
}
if (bnative = !(format == CF_METAFILEPICT
|| format == CF_DIB
|| format == CF_BITMAP))
{
// g_cfNative, CF_TEXT, g_cfBinary
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->fAckReq = FALSE;
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);
memcpy (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;
}
// IsAdviseStdItems: returns true if the item is one of the standard items
// StdDocName;
INTERNAL_(BOOL) IsAdviseStdItems (
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
WCHAR * stdStrTable[STDHOSTNAMES+1] = {NULL,
OLESTR("StdTargetDevice"),
OLESTR("StdDocDimensions"),
OLESTR("StdColorScheme"),
OLESTR("StdHostNames")};
INTERNAL_(int) GetStdItemIndex (
ATOM aItem
)
{
WCHAR str[MAX_STR];
if (!aItem)
return NULL;
if (!GlobalGetAtomName (aItem, str, MAX_STR))
return NULL;
if (!lstrcmpiW (str, stdStrTable[STDTARGETDEVICE]))
return STDTARGETDEVICE;
else if (!lstrcmpiW (str, stdStrTable[STDHOSTNAMES]))
return STDHOSTNAMES;
else if (!lstrcmpiW (str, stdStrTable[STDDOCDIMENSIONS]))
return STDDOCDIMENSIONS;
else if (!lstrcmpiW (str, stdStrTable[STDCOLORSCHEME]))
return STDCOLORSCHEME;
return NULL;
}
void ChangeOwner
(HANDLE hmfp)
{
#ifndef WIN32
LPMETAFILEPICT lpmfp;
if (lpmfp = (LPMETAFILEPICT) GlobalLock (hmfp))
{
SetMetaFileBitsBetter (lpmfp->hMF);
GlobalUnlock (hmfp);
}
#endif
}
INTERNAL_(HANDLE) MakeItemData
(
DDEPOKE FAR * lpPoke,
HANDLE hPoke,
CLIPFORMAT cfFormat
)
{
HANDLE hnew;
LPBYTE lpnew;
DWORD dwSize;
Puts ("MakeItemData\r\n");
if (cfFormat == CF_METAFILEPICT)
return DuplicateMetaFile (*(LPHANDLE)lpPoke->Value);
if (cfFormat == CF_BITMAP)
return (HANDLE)DuplicateBitmap (*(HBITMAP *)lpPoke->Value);
if (cfFormat == CF_DIB)
return UtDupGlobal (*(LPHANDLE)lpPoke->Value,GMEM_MOVEABLE);
// Now we are dealing with normal case
if (!(dwSize = GlobalSize (hPoke)))
return NULL;
dwSize -= sizeof (DDEPOKE) - sizeof(BYTE);
// Use GMEM_ZEROINIT so there is no garbage after the data in field Value.
// This may be important when making an IStorage from native data,
// but I'm not sure.
// Note that the Value field itself could have garbage
// at the end if the hData of the DDE_POKE message is bigger than
// necessary, i.e.,
// GlobalSize(hData) > sizeof(DDEPOKE) - sizeof(Value) + realsize(Value)
// A DocFile is of size 512n
DebugOnly (
if (cfFormat==g_cfNative && dwSize%512 != 0)
{
Putsi(dwSize);
Puts ("DDE_POKE.Value not of size 512n\r\n");
}
)
if (hnew = GlobalAlloc (GMEM_MOVEABLE|GMEM_ZEROINIT, dwSize)) {
if (lpnew = (LPBYTE) GlobalLock (hnew)) {
memcpy (lpnew, lpPoke->Value, dwSize);
GlobalUnlock (hnew);
}
else {
GlobalFree (hnew);
hnew = NULL;
}
}
return hnew;
}
INTERNAL_(HANDLE) DuplicateMetaFile
(
HANDLE hSrcData
)
{
LPMETAFILEPICT lpSrcMfp;
LPMETAFILEPICT lpDstMfp = NULL;
HANDLE hMF = NULL;
HANDLE hDstMfp = NULL;
Puts ("DuplicateMetaFile\r\n");
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 = (HMETAFILE)hMF;
return hDstMfp;
errMfp:
//
// The following Metafile was created in this
// process. Therefore, the delete shouldn't need to
// call the DDE functions for deleting the DDE pair
//
if (hMF)
DeleteMetaFile ((HMETAFILE)hMF);
if (hDstMfp)
GlobalFree (hDstMfp);
return NULL;
}
INTERNAL_(HBITMAP) DuplicateBitmap
(
HBITMAP hold
)
{
HBITMAP hnew;
HANDLE hMem;
LPBYTE lpMem;
LONG retVal = TRUE;
DWORD dwSize;
BITMAP bm;
// !!! another way to duplicate the bitmap
Puts ("DuplicateBitmap\r\n");
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 = (LPBYTE) 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;
}
// CDefClient::GetData
//
// Perform a normal GetData on m_lpdataObj, but if g_cfNative is requested,
// do an OleSave onto our IStorage implemented
// on top of an ILockBytes, then convert the ILockBytes to an hGlobal.
// This flattened IStorage will be used as the native data.
//
INTERNAL CDefClient::GetData
(LPFORMATETC pformatetc,
LPSTGMEDIUM pmedium)
{
LPPERSISTSTORAGE pPersistStg=NULL;
HANDLE hNative =NULL;
HANDLE hNativeDup =NULL;
HRESULT hresult =NOERROR;
BOOL fFreeHNative = FALSE;
CLSID clsid;
intrDebugOut((DEB_ITRACE,
"%x _IN CDefClient::GetData(%x,%x)\n",
this,
pformatetc,
pmedium));
intrDebugOut((DEB_ITRACE,
" ::GetData format=%x\n",
pformatetc->cfFormat));
if (pformatetc->cfFormat==g_cfNative)
{
ErrRtnH (m_lpdataObj->QueryInterface (IID_IPersistStorage,
(LPLPVOID) &pPersistStg));
ErrZ (pPersistStg);
if (NULL==m_pstgNative)
{
// Embed from file case
Assert (NULL==m_plkbytNative);
ErrRtnH (CreateILockBytesOnHGlobal (NULL,
/*fDeleteOnRelease*/TRUE,
&m_plkbytNative));
Assert (m_plkbytNative);
ErrRtnH (StgCreateDocfileOnILockBytes (m_plkbytNative,
grfCreateStg, 0, &m_pstgNative));
ErrZ (m_pstgNative);
Assert (NOERROR==StgIsStorageILockBytes(m_plkbytNative));
m_fInOleSave = TRUE;
hresult = OleSave (pPersistStg, m_pstgNative, FALSE);
pPersistStg->SaveCompleted(NULL);
m_fInOleSave = FALSE;
ErrRtnH (hresult);
}
else
{
// Get the native data by calling OleSave
m_fInOleSave = TRUE;
hresult = OleSave (pPersistStg, m_pstgNative, TRUE);
pPersistStg->SaveCompleted(NULL);
m_fInOleSave = FALSE;
ErrRtnH (hresult);
}
ErrRtnH (ReadClassStg (m_pstgNative, &clsid));
if (CoIsOle1Class (clsid))
{
// TreatAs case:
// Get Native data from "\1Ole10Native" stream
fFreeHNative = TRUE;
ErrRtnH (StRead10NativeData (m_pstgNative, &hNative));
}
else
{
Assert (NOERROR==StgIsStorageILockBytes (m_plkbytNative));
ErrRtnH (GetHGlobalFromILockBytes (m_plkbytNative, &hNative));
}
ErrZ (wIsValidHandle (hNative, g_cfNative));
// Must duplicate because we let the client free the handle,
// so it can't be the one our ILockBytes depends on.
hNativeDup = UtDupGlobal (hNative, GMEM_DDESHARE | GMEM_MOVEABLE);
ErrZ (wIsValidHandle (hNativeDup, g_cfNative));
if (GlobalSize(hNativeDup) % 512 != 0)
{
Puts ("WARNING:\r\n\t");
Putsi (GlobalSize(hNativeDup));
}
pmedium->tymed = TYMED_HGLOBAL;
pmedium->hGlobal = hNativeDup;
pmedium->pUnkForRelease = NULL;
pPersistStg->Release();
hresult = NOERROR;
goto exitRtn;
}
else
{
// Anything but native
hresult = m_lpdataObj->GetData (pformatetc, pmedium);
// AssertOutStgmedium(hresult, pmedium);
goto exitRtn;
}
errRtn:
if (hNative && fFreeHNative)
GlobalFree (hNative);
if (pPersistStg)
pPersistStg->Release();
pmedium->tymed = TYMED_NULL;
pmedium->pUnkForRelease = NULL;
exitRtn:
intrDebugOut((DEB_ITRACE,
"%x OUT CDefClient::GetData() return %x\n",
this,
hresult));
return hresult;
}
// Set pformatetc->tymed based on pformatetc->cfFormat
//
INTERNAL wSetTymed
(LPFORMATETC pformatetc)
{
if (pformatetc->cfFormat == CF_METAFILEPICT)
{
pformatetc->tymed = TYMED_MFPICT;
}
else if (pformatetc->cfFormat == CF_PALETTE ||
pformatetc->cfFormat == CF_BITMAP)
{
pformatetc->tymed = TYMED_GDI;
}
else
{
pformatetc->tymed = TYMED_HGLOBAL;
}
return NOERROR;
}