Leaked source code of windows server 2003
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

#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;
}