|
|
/*---------------------------------------------------------------------------
| PERS.C | This file has the IPersistStorage and IPersistfile interface implementation. | | Created By: Vij Rajarajan (VijR) +---------------------------------------------------------------------------*/ #define SERVERONLY
#include <Windows.h>
#include "mpole.h"
#include "mplayer.h"
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
#define STGM_SALL (STGM_READWRITE | STGM_SHARE_EXCLUSIVE)
/**************************************************************************
*************** IPersistStorage INTERFACE IMPLEMENTATION. **************************************************************************/ //delegate to the common IUnknown implementation.
STDMETHODIMP PSQueryInterface( LPPERSISTSTORAGE lpPersStg, // persist storage object ptr
REFIID riidReq, // IID required
LPVOID FAR * lplpUnk // pre for returning the interface
) { return UnkQueryInterface((LPUNKNOWN)lpPersStg, riidReq, lplpUnk); }
STDMETHODIMP_(ULONG) PSAddRef( LPPERSISTSTORAGE lpPersStg // persist storage object ptr
) { return UnkAddRef((LPUNKNOWN) lpPersStg); }
STDMETHODIMP_(ULONG) PSRelease ( LPPERSISTSTORAGE lpPersStg // persist storage object ptr
) { return UnkRelease((LPUNKNOWN) lpPersStg); }
STDMETHODIMP PSGetClassID ( LPPERSISTSTORAGE lpPersStg, CLSID FAR* pClsid ) { DPF("PSGetClassID\n");
/* Return the actual class ID that gets stored:
*/ *pClsid = gClsIDOLE1Compat;
return NOERROR; }
STDMETHODIMP PSIsDirty ( LPPERSISTSTORAGE lpPersStg ) {DPF("PSIsDirty\n");
RETURN_RESULT( (fDocChanged && !(gfPlayingInPlace || gfOle2IPPlaying)) ? S_OK : S_FALSE); }
STDMETHODIMP PSInitNew ( LPPERSISTSTORAGE lpPersStg, LPSTORAGE lpStorage ) { return NOERROR; }
/**************************************************************************
* PSLoad: * The Load method reads the embedded data from the "\1Ole10Native" * stream of the IStorage passed as an argument. This is because * we always pretend to be an OLE1 server when transferring data. * ItemSetData is called with this embedded data to to run the required * object. **************************************************************************/ STDMETHODIMP PSLoad ( LPPERSISTSTORAGE lpPersStg, LPSTORAGE lpStorage ) { LPDOC lpdoc; SCODE error; LPSTREAM pstm; ULONG cbRead; DWORD size = 0; HGLOBAL hNative = NULL; LPTSTR lpnative = NULL;
DPF("\nPSLoad is being called\n"); lpdoc = ((struct CPersistStorageImpl FAR*)lpPersStg)->lpdoc;
error = GetScode(IStorage_OpenStream(lpStorage, sz1Ole10Native, NULL, STGM_SALL, 0, &pstm)); if (error == S_OK) { error = GetScode(IStream_Read(pstm, &size, 4, &cbRead)); } if (error == S_OK) { hNative = GlobalAlloc(GMEM_DDESHARE |GMEM_ZEROINIT, (LONG)size); if (hNative) lpdoc->native = GLOBALLOCK(hNative); }
if(lpdoc->native ) { error = GetScode(IStream_Read(pstm, lpdoc->native, size, &cbRead));
if (cbRead != size) error = E_FAIL; // REVIEW SCODE stream size error
IStream_Release(pstm); } else error = E_OUTOFMEMORY;
if (error == S_OK) { error = ItemSetData((LPBYTE)lpdoc->native); fDocChanged = FALSE; lpdoc->doctype = doctypeEmbedded; }
if(hNative) { GLOBALUNLOCK(hNative); GLOBALFREE(hNative); }
RETURN_RESULT( error); }
/**************************************************************************
* PSSave: * The Save method saves the native data in "\1Ole10Native" stream. * This is because we always pretend to be an OLE1 server when transferring * data. This ensures backward compatibility. GetLink is called to get * the embedding data. **************************************************************************/ STDMETHODIMP PSSave ( LPPERSISTSTORAGE lpPersStg, LPSTORAGE lpStorage, BOOL fSameAsLoad ) { LPDOC lpdoc; SCODE error; LPSTREAM pstm = NULL; ULONG cbWritten; DWORD_PTR size; HGLOBAL hNative = NULL; LPTSTR lpnative = NULL; LPWSTR lpszUserType;
DPF("* in pssave *"); lpdoc = ((struct CPersistStorageImpl FAR*)lpPersStg)->lpdoc;
#if 0
// Allow saves if we're playing so that broken links can be fixed.
if (fSameAsLoad && (gfOle2IPPlaying || gfPlayingInPlace)) RETURN_RESULT(S_OK); #endif
//Mark as OLE1 mplayer object.
#ifndef UNICODE
lpszUserType = AllocateUnicodeString(gachClassRoot); #else
lpszUserType = gachClassRoot; #endif
error = GetScode(WriteClassStg(lpStorage, &gClsIDOLE1Compat));
error = GetScode(WriteFmtUserTypeStg(lpStorage, cfMPlayer, lpszUserType)); #ifndef UNICODE
FreeUnicodeString(lpszUserType); #endif
if(error != S_OK) RETURN_RESULT(error); error = GetScode(IStorage_CreateStream(lpStorage, sz1Ole10Native, STGM_SALL | STGM_FAILIFTHERE, 0,0, &pstm)); if (error == STG_E_FILEALREADYEXISTS) { error = GetScode(IStorage_OpenStream(lpStorage, sz1Ole10Native, NULL, STGM_SALL, 0,&pstm)); DPF("*pssave--openstream*"); }
if(pstm && (error == S_OK)) hNative = GetLink();
if (hNative) { lpnative = GLOBALLOCK(hNative); size = GlobalSize(hNative); } else error = E_OUTOFMEMORY;
if (lpnative && (size != 0L)) { error = GetScode(IStream_Write(pstm, &size, 4, &cbWritten)); error = GetScode(IStream_Write(pstm, lpnative, (ULONG)size, &cbWritten));
DPF("\n*After pssave write"); if (cbWritten != size) error = E_FAIL ; // REVIEW SCODE stream full error
IStream_Release(pstm); }
CleanObject(); GLOBALUNLOCK(hNative); GLOBALFREE(hNative); RETURN_RESULT(error); }
/* InPowerPointSlideView
* * Check the class name of the container window to see if we're in PowerPoint. * This is to support the horrible hack to get around problem of PowerPoint * crashing if we delete an empty Media Clip. * */ STATICFN BOOL InPowerPointSlideView() { TCHAR ClassName[256];
if (GetClassName(ghwndCntr, ClassName, CHAR_COUNT(ClassName)) > 0) { if (lstrcmp(ClassName, TEXT("paneClassDC")) == 0) { return TRUE; } }
return FALSE; }
STDMETHODIMP PSSaveCompleted ( LPPERSISTSTORAGE lpPersStg, LPSTORAGE lpStorage ) { LPDOC lpdoc; DPF("\n**pssavecompleted**"); lpdoc = ((struct CPersistStorageImpl FAR*)lpPersStg)->lpdoc;
/* Win95 HOT bug #11142
* * Stop PowerPoint crashing horribly: */ if ((gwDeviceID == 0) && InPowerPointSlideView()) SendDocMsg(lpdoc, OLE_CHANGED);
// inform clients that the object has been saved
return SendDocMsg (lpdoc, OLE_SAVED); }
STDMETHODIMP PSHandsOffStorage ( LPPERSISTSTORAGE lpPersStg ) { return NOERROR; }
/**************************************************************************
************ IPersistFile INTERFACE IMPLEMENTATION. **************************************************************************/ //delegate to common IUnknown implementation.
STDMETHODIMP PFQueryInterface( LPPERSISTFILE lpPersFile, // persist storage object ptr
REFIID riidReq, // IID required
LPVOID FAR * lplpUnk // pre for returning the interface
) { return UnkQueryInterface((LPUNKNOWN)lpPersFile, riidReq, lplpUnk); }
STDMETHODIMP_(ULONG) PFAddRef( LPPERSISTFILE lpPersFile // persist storage object ptr
) { return UnkAddRef((LPUNKNOWN) lpPersFile); }
STDMETHODIMP_(ULONG) PFRelease ( LPPERSISTFILE lpPersFile // persist storage object ptr
) { return UnkRelease((LPUNKNOWN) lpPersFile); }
STDMETHODIMP PFGetClassID ( LPPERSISTFILE lpPersFile, CLSID FAR* pCid ) { DPF("\n* PFGetclassid");
/* The docs are confusing here, but apparently IPersist interfaces
* should return the old class ID: */ *pCid = gClsIDOLE1Compat;
return NOERROR; }
STDMETHODIMP PFIsDirty ( LPPERSISTFILE lpPersFile ) { RETURN_RESULT( gfDirty ? S_OK : S_FALSE); }
//This will be called when the user does a "Insert->Create from file".
//Open the file with OpenMciDevice and we will be ready to transfer the
//object.
STDMETHODIMP PFLoad ( LPPERSISTFILE lpPersFile, LPCWSTR lpszFileName, DWORD grfMode ) { size_t nLen; LPDOC lpdoc; TCHAR szFileName[256];
if(FAILED(StringCchLength(lpszFileName, 256, &nLen))) RETURN_RESULT(E_FAIL);
//Don't even attempt to deal with file names greater then 256
//Don't worry about nonUnincode so casting as LPTSTR
if(nLen > 255) RETURN_RESULT(E_FAIL);
lpdoc = ((struct CPersistStorageImpl FAR*)lpPersFile)->lpdoc; DPF("\n***IN PFLOAD: "DTS"\n", lpszFileName); #if UNICODE
lstrcpy(szFileName, lpszFileName); #else
UnicodeToAnsiString(lpszFileName, szFileName, UNKNOWN_LENGTH); #endif
if(OpenMciDevice(szFileName, NULL)) RETURN_RESULT(S_OK); else RETURN_RESULT(E_FAIL); }
STDMETHODIMP PFSave ( LPPERSISTFILE lpPersFile, LPCWSTR lpszFileName, BOOL fRemember ) { return NOERROR; }
STDMETHODIMP PFSaveCompleted ( LPPERSISTFILE lpPersFile, LPCWSTR lpszFileName ) { LPDOC lpdoc;
lpdoc = ((struct CPersistStorageImpl FAR*)lpPersFile)->lpdoc;
// inform clients that the object has been saved
return SendDocMsg(lpdoc, OLE_SAVED); }
STDMETHODIMP PFGetCurFile ( LPPERSISTFILE lpPersFile, LPWSTR FAR* lplpszFileName ) { RETURN_RESULT( E_NOTIMPL); }
|