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.
322 lines
9.7 KiB
322 lines
9.7 KiB
#include "privcpp.h"
|
|
|
|
|
|
HRESULT CPackage::InitNew(IStorage *pstg)
|
|
{
|
|
HRESULT hr;
|
|
LPSTREAM pstm;
|
|
|
|
DebugMsg(DM_TRACE, "pack ps - InitNew() called.");
|
|
|
|
if (_psState != PSSTATE_UNINIT)
|
|
return E_UNEXPECTED;
|
|
|
|
if (!pstg)
|
|
return E_POINTER;
|
|
|
|
// Create a stream to save the package and cache the pointer. By doing
|
|
// this now we ensure being able to save in low memory conditions.
|
|
//
|
|
hr = pstg->CreateStream(SZCONTENTS,STGM_DIRECT | STGM_CREATE |
|
|
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0,
|
|
&pstm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = WriteFmtUserTypeStg(pstg, (CLIPFORMAT)_cf,SZUSERTYPE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
_fIsDirty = TRUE;
|
|
_psState = PSSTATE_SCRIBBLE;
|
|
|
|
DebugMsg(DM_TRACE, " leaving InitNew()");
|
|
}
|
|
pstm->Release();
|
|
pstm = NULL;
|
|
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CPackage::Load(IStorage *pstg)
|
|
{
|
|
HRESULT hr;
|
|
LPSTREAM pstm = NULL; // package contents
|
|
CLSID clsid;
|
|
|
|
DebugMsg(DM_TRACE, "pack ps - Load() called.");
|
|
|
|
if (_psState != PSSTATE_UNINIT)
|
|
{
|
|
DebugMsg(DM_TRACE," wrong state!!");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
if (!pstg)
|
|
{
|
|
DebugMsg(DM_TRACE," bad pointer!!");
|
|
return E_POINTER;
|
|
}
|
|
|
|
|
|
// check to make sure this is one of our storages
|
|
hr = ReadClassStg(pstg, &clsid);
|
|
if (SUCCEEDED(hr) &&
|
|
(clsid != CLSID_CPackage && clsid != CLSID_OldPackage) || FAILED(hr))
|
|
{
|
|
DebugMsg(DM_TRACE," bad storage type!!");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
hr = pstg->OpenStream(SZCONTENTS,0, STGM_DIRECT | STGM_READWRITE |
|
|
STGM_SHARE_EXCLUSIVE, 0, &pstm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = PackageReadFromStream(pstm);
|
|
|
|
_psState = PSSTATE_SCRIBBLE;
|
|
_fIsDirty = FALSE;
|
|
_fLoaded = TRUE;
|
|
|
|
pstm->Release();
|
|
}
|
|
else
|
|
{
|
|
DebugMsg(DM_TRACE," couldn't open contents stream!!");
|
|
DebugMsg(DM_TRACE," hr==%Xh",hr);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CPackage::Save(IStorage *pstg, BOOL fSameAsLoad)
|
|
{
|
|
HRESULT hr;
|
|
LPSTREAM pstm;
|
|
|
|
DebugMsg(DM_TRACE, "pack ps - Save() called.");
|
|
|
|
if(!_pEmbed || !(*_pEmbed->fd.cFileName))
|
|
return S_OK;
|
|
|
|
// must come here from scribble state
|
|
if ((_psState != PSSTATE_SCRIBBLE) && fSameAsLoad)
|
|
{
|
|
DebugMsg(DM_TRACE," bad state!!");
|
|
return E_UNEXPECTED;
|
|
}
|
|
|
|
// must have an IStorage if not SameAsLoad
|
|
if (!pstg && !fSameAsLoad)
|
|
{
|
|
DebugMsg(DM_TRACE," bad pointer!!");
|
|
return E_POINTER;
|
|
}
|
|
|
|
CreateTempFile(); // Make sure we have the temp file created
|
|
|
|
// hopefully, the container calls WriteClassStg with our CLSID before
|
|
// we get here, that way we can overwrite that and write out the old
|
|
// packager's CLSID so that the old packager can read new packages.
|
|
//
|
|
if (FAILED(WriteClassStg(pstg, CLSID_OldPackage)))
|
|
{
|
|
DebugMsg(DM_TRACE,
|
|
" couldn't write CLSID to storage!!");
|
|
return E_FAIL;
|
|
}
|
|
|
|
|
|
//
|
|
// ok, we have four possible ways we could be calling Save:
|
|
// 1. we're creating a new package and saving to the same
|
|
// storage we received in InitNew
|
|
// 2. We're creating a new package and saving to a different
|
|
// storage than we received in InitNew
|
|
// 3. We were loaded by a container and we're saving to the
|
|
// same stream we received in Load
|
|
// 4. We were loaded by a container and we're saving to a
|
|
// different stream than we received in Load
|
|
//
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// Same Storage as Load
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
if (fSameAsLoad)
|
|
{
|
|
|
|
DebugMsg(DM_TRACE," Same as load.");
|
|
|
|
LARGE_INTEGER li = {0,0};
|
|
|
|
// If we're not dirty, so there's nothing new to save.
|
|
|
|
if (FALSE == _fIsDirty) {
|
|
DebugMsg(DM_TRACE, " not saving cause we're not dirty!!");
|
|
return S_OK;
|
|
}
|
|
|
|
hr = pstg->OpenStream(SZCONTENTS,0, STGM_DIRECT | STGM_READWRITE |
|
|
STGM_SHARE_EXCLUSIVE, 0, &pstm);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// case 1: new package
|
|
if (!_fLoaded)
|
|
{
|
|
switch(_panetype)
|
|
{
|
|
LPTSTR temp;
|
|
case PEMBED:
|
|
// if haven't created a temp file yet, then use the the
|
|
// file to be packaged to get our file contents from,
|
|
// otherwise we just use the temp file, because if we
|
|
// have a temp file, it contains the most recent info.
|
|
//
|
|
temp = _pEmbed->pszTempName;
|
|
|
|
if (!_pEmbed->pszTempName)
|
|
{
|
|
DebugMsg(DM_TRACE, " case 1a:not loaded, using initFile.");
|
|
_pEmbed->pszTempName = _pEmbed->fd.cFileName;
|
|
}
|
|
else {
|
|
DebugMsg(DM_TRACE, " case 1b:not loaded, using tempfile.");
|
|
}
|
|
|
|
hr = PackageWriteToStream(pstm);
|
|
// reset our temp name back, since we might have changed it
|
|
// basically, this just sets it to NULL if it was before
|
|
_pEmbed->pszTempName = temp;
|
|
break;
|
|
|
|
case CMDLINK:
|
|
// nothing screwy to do here...just write out the info
|
|
// which we already have in memory.
|
|
hr = PackageWriteToStream(pstm);
|
|
break;
|
|
}
|
|
|
|
}
|
|
// case 3: loaded package
|
|
else {
|
|
hr = PackageWriteToStream(pstm);
|
|
}
|
|
|
|
pstm->Release();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
}
|
|
}
|
|
//////////////////////////////////////////////////////////////////
|
|
//
|
|
// NEW Storage
|
|
//
|
|
//////////////////////////////////////////////////////////////////
|
|
|
|
else
|
|
{
|
|
|
|
DebugMsg(DM_TRACE," NOT same as load.");
|
|
hr = pstg->CreateStream(SZCONTENTS,STGM_DIRECT | STGM_CREATE |
|
|
STGM_READWRITE | STGM_SHARE_EXCLUSIVE, 0, 0,
|
|
&pstm);
|
|
if (FAILED(hr))
|
|
{
|
|
DebugMsg(DM_TRACE, " couldn't create contents stream!!");
|
|
return hr;
|
|
}
|
|
|
|
WriteFmtUserTypeStg(pstg, (CLIPFORMAT)_cf,SZUSERTYPE);
|
|
|
|
// case 2:
|
|
if (!_fLoaded)
|
|
{
|
|
switch(_panetype)
|
|
{
|
|
LPTSTR temp;
|
|
case PEMBED:
|
|
|
|
temp = _pEmbed->pszTempName;
|
|
if (!_pEmbed->pszTempName)
|
|
{
|
|
DebugMsg(DM_TRACE, " case 2a:not loaded, using initFile.");
|
|
_pEmbed->pszTempName = _pEmbed->fd.cFileName;
|
|
}
|
|
else
|
|
{
|
|
DebugMsg(DM_TRACE, " case 2b:not loaded, using tempfile.");
|
|
}
|
|
|
|
hr = PackageWriteToStream(pstm);
|
|
|
|
// reset our temp name back, since we might have changed it
|
|
// basically, this just sets it to NULL if it was before
|
|
_pEmbed->pszTempName = temp;
|
|
break;
|
|
|
|
case CMDLINK:
|
|
// nothing interesting to do here, other than write out
|
|
// the package.
|
|
hr = PackageWriteToStream(pstm);
|
|
break;
|
|
}
|
|
}
|
|
// case 4:
|
|
else
|
|
{
|
|
DebugMsg(DM_TRACE," case 4:loaded.");
|
|
hr = PackageWriteToStream(pstm);
|
|
}
|
|
|
|
pstm->Release();
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
_psState = PSSTATE_ZOMBIE;
|
|
|
|
DebugMsg(DM_TRACE, " leaving Save()");
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CPackage::SaveCompleted(IStorage *pstg)
|
|
{
|
|
DebugMsg(DM_TRACE, "pack ps - SaveCompleted() called.");
|
|
|
|
// must be called from no-scribble or hands-off state
|
|
if (!(_psState == PSSTATE_ZOMBIE || _psState == PSSTATE_HANDSOFF))
|
|
return E_UNEXPECTED;
|
|
|
|
// if we're hands-off, we'd better get a storage to re-init from
|
|
if (!pstg && _psState == PSSTATE_HANDSOFF)
|
|
return E_UNEXPECTED;
|
|
|
|
_psState = PSSTATE_SCRIBBLE;
|
|
_fIsDirty = FALSE;
|
|
DebugMsg(DM_TRACE, " leaving SaveCompleted()");
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT CPackage::HandsOffStorage(void)
|
|
{
|
|
DebugMsg(DM_TRACE, "pack ps - HandsOffStorage() called.");
|
|
|
|
// must come from scribble or no-scribble. a repeated call to
|
|
// HandsOffStorage is an unexpected error (bug in client).
|
|
//
|
|
if (_psState == PSSTATE_UNINIT || _psState == PSSTATE_HANDSOFF)
|
|
return E_UNEXPECTED;
|
|
|
|
_psState = PSSTATE_HANDSOFF;
|
|
DebugMsg(DM_TRACE, " leaving HandsOffStorage()");
|
|
return S_OK;
|
|
}
|