NT4/private/ole32/stg/docfile/sngprop.cxx
2020-09-30 17:12:29 +02:00

239 lines
7.1 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: sngprop.cxx
//
// Contents: CSingleProperty implementation
//
// History: 13-Oct-92 DrewB Created
//
//----------------------------------------------------------------------------
#include <dfhead.cxx>
#pragma hdrstop
#include <memalloc.h>
#include <pbstream.hxx>
#include <sngprop.hxx>
#include <props.hxx>
//+---------------------------------------------------------------------------
//
// Member: CSingleProp::Get, public
//
// Synopsis: Gets the value of a property
//
// Arguments: [pdfn] - Name
// [pdpv] - Value to fill in
// [pcbSize] - Data size return
// [ppbBuffer] - Data return
//
// Returns: Appropriate status code
//
// Modifies: [pdpv]
// [pcbSize]
// [ppbBuffer]
//
// History: 13-Oct-92 DrewB Created
//
//----------------------------------------------------------------------------
SCODE CSingleProp::Get(CDfName *pdfn,
DFPROPVAL *pdpv,
ULONG *pcbSize,
BYTE **ppbBuffer)
{
CPubDocFile *pdf;
CPubStream *pstm;
SCODE sc;
ULONG cbRead;
ULONG ulOff = 0;
BYTE *pb;
olDebugOut((DEB_ITRACE, "In CSingleProp::Get:%p("
"%p, %p, %p, %p, %p)\n", this, pdfn, pdfn,
pdpv, pcbSize, ppbBuffer));
sc = _pstg->GetStream(pdfn, DF_READ | DF_DENYALL,
STGTY_PROPFLAG | STGTY_STREAM, &pstm);
if (sc == STG_E_FILENOTFOUND)
{
olChk(_pstg->GetDocFile(pdfn, DF_READ | DF_DENYALL,
STGTY_PROPFLAG | STGTY_STORAGE, &pdf));
sc = pdf->GetPropType(&pdpv->vt);
// If the property successfully opened as a storage then
// it can't have anything we can read so just close it and
// leave
pdf->CPubDocFile::vRelease();
return sc;
}
else if (FAILED(sc))
olErr(EH_Err, sc);
olChkTo(EH_pstm, pstm->GetPropType(&pdpv->vt));
if (pdpv->vt == VT_STREAM || pdpv->vt == VT_STREAMED_OBJECT)
{
// We don't want to touch the data in a stream-like object
// so just return
pstm->CPubStream::vRelease();
return sc;
}
olChkTo(EH_pstm, pstm->ReadAt(ulOff, pcbSize, sizeof(ULONG),
(ULONG STACKBASED *)&cbRead));
if (cbRead != sizeof(ULONG))
olErr(EH_pstm, STG_E_READFAULT);
ulOff += sizeof(ULONG);
*ppbBuffer = NULL;
if (VT_NOT_IN_VALUE(pdpv->vt))
{
olMemTo(EH_pstm, *ppbBuffer = (BYTE *)TaskMemAlloc(*pcbSize));
pb = *ppbBuffer;
}
else
pb = (BYTE *)&pdpv->iVal;
if (*pcbSize > 0)
{
olChkTo(EH_buffer, pstm->ReadAt(ulOff, pb, *pcbSize,
(ULONG STACKBASED *)&cbRead));
if (cbRead != *pcbSize)
olErr(EH_buffer, STG_E_READFAULT);
}
olDebugOut((DEB_ITRACE, "Out CSingleProp::Get\n"));
pstm->vRelease();
return S_OK;
EH_buffer:
TaskMemFree(*ppbBuffer);
EH_pstm:
pstm->vRelease();
EH_Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CSingleProp::Set, public
//
// Synopsis: Sets the value of a property
//
// Arguments: [pdfn] - Name
// [pdpv] - Property value
// [cbSize] - Size of value
// [pbBuffer] - Value
//
// Returns: Appropriate status code
//
// History: 13-Oct-92 DrewB Created
//
//----------------------------------------------------------------------------
SCODE CSingleProp::Set(CDfName *pdfn,
DFPROPVAL *pdpv,
ULONG const cbSize,
BYTE *pbBuffer)
{
CPubStream *pstm;
SCODE sc;
ULONG cbWritten;
BOOL fCreated = FALSE;
ULONG ulOff = 0;
olDebugOut((DEB_ITRACE, "In CSingleProp::Set:%p("
"%p, %p, %lu, %p)\n", this, pdfn, pdpv,
cbSize, pbBuffer));
// Check for existing stream property
sc = _pstg->GetStream(pdfn, DF_WRITE | DF_DENYALL,
STGTY_PROPFLAG | STGTY_STREAM, &pstm);
if (SUCCEEDED(sc))
{
// If it exists, truncate it so that new contents replace old
sc = pstm->SetSize(0);
if (FAILED(sc))
pstm->CPubStream::vRelease();
}
else if (sc == STG_E_FILENOTFOUND)
{
CPubDocFile *pstg;
// If no stream property was found, check for a storage property
sc = _pstg->GetDocFile(pdfn, DF_WRITE | DF_DENYALL,
STGTY_PROPFLAG | STGTY_STORAGE, &pstg);
if (SUCCEEDED(sc))
{
// If we found one, we have an error because we
// can't replace a storage with a stream
pstg->CPubDocFile::vRelease();
sc = STG_E_FILEALREADYEXISTS;
}
else if (sc == STG_E_FILENOTFOUND)
// If we didn't find anything, no property exists for the given
// name so we need to create one
sc = S_OK;
if (SUCCEEDED(sc))
{
// If no property exists, create one. Storage properties
// are created in WriteMultiple so we only need to create
// streams here
sc = _pstg->CreateStream(pdfn, DF_WRITE | DF_DENYALL,
STGTY_PROPFLAG | STGTY_STREAM, &pstm);
fCreated = TRUE;
}
}
// Check for any errors from the above procedure
olChk(sc);
olChkTo(EH_pstm, pstm->SetPropType(pdpv->vt));
olChkTo(EH_pstm, pstm->WriteAt(ulOff, (void *)&cbSize, sizeof(ULONG),
(ULONG STACKBASED *)&cbWritten));
if (cbWritten != sizeof(ULONG))
olErr(EH_pstm, STG_E_WRITEFAULT);
ulOff += sizeof(ULONG);
if (cbSize > 0)
{
olAssert(pbBuffer != NULL);
olChkTo(EH_pstm, pstm->WriteAt(ulOff, pbBuffer, cbSize,
(ULONG STACKBASED *)&cbWritten));
if (cbWritten != cbSize)
olErr(EH_pstm, STG_E_WRITEFAULT);
}
olDebugOut((DEB_ITRACE, "Out CSingleProp::Set\n"));
// Fall through
EH_pstm:
pstm->vRelease();
if (FAILED(sc) && fCreated)
olVerSucc(_pstg->DestroyEntry(pdfn, TRUE));
EH_Err:
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CSingleProp::Exists, public
//
// Synopsis: Determines whether a given property exists or not
//
// Arguments: [pdfn] - Name
//
// Returns: Appropriate status code
//
// History: 12-Jul-93 DrewB Created
//
//----------------------------------------------------------------------------
SCODE CSingleProp::Exists(CDfName *pdfn)
{
SEntryBuffer eb;
SCODE sc;
olDebugOut((DEB_ITRACE, "In CSingleProp::Exists:%p(%d:%ws)\n",
this, pdfn->GetLength(), pdfn->GetBuffer()));
sc = _pstg->IsEntry(pdfn, &eb);
olDebugOut((DEB_ITRACE, "Out CSingleProp::Exists => 0x%lX\n", sc));
return sc;
}