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.
 
 
 
 
 
 

1188 lines
37 KiB

//+-------------------------------------------------------------------------
// Microsoft OLE
// Copyright (C) Microsoft Corporation, 1992 - 1996.
// All rights reserved.
//
// File: vsnode.cxx
//
// Contents: Implementation for in-memory Virtual Stream Node class.
//
// Classes: VirtualStmNode (vsn)
//
// Functions: VirtualStmNode()
// ~VirtualStmNode
// Init
// AppendSisterStm
// Create
// Read
// Write
// Open
// Close
// Seek
// SetSize
// Commit
// Revert
// Stat
// CopyTo
// AddRefCount
// QueryInterface
// LockRegion
// UnlockRegion
// Clone
// Rename
// Destroy
//
// NOTE: All above functions are public
//
// History: DeanE 21-Mar-96 Created
// Narindk 24-Apr-96 Added more functions.
// georgis 02-Apr-98 UpdateCRC
//--------------------------------------------------------------------------
#include <dfheader.hxx>
#pragma hdrstop
// Debug object declaration
DH_DECLARE;
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::VirtualStmNode, public
//
// Synopsis: Constructor. No work done here and this method cannot
// fail. See ::Init method for real initialization work.
//
// Arguments: None.
//
// Returns: Nothing.
//
// History: DeanE 21-Mar-96 Created
//---------------------------------------------------------------------------
VirtualStmNode::VirtualStmNode() : _ptszName(NULL),
_cb(0),
_pvsnSister(NULL),
_pvcnParent(NULL),
_pstm(NULL)
{
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::VirtualStmNode"));
_dwCRC.dwCRCName = CRC_PRECONDITION;
_dwCRC.dwCRCData = CRC_PRECONDITION;
_dwCRC.dwCRCSum = CRC_PRECONDITION;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::~VirtualStmNode, public
//
// Synopsis: Destructor. Frees resources associated with this object,
// including closing the storage if open and removing this
// tree from memory.
//
// Arguments: None.
//
// Returns: Nothing.
//
// History: DeanE 21-Mar-96 Created
//---------------------------------------------------------------------------
VirtualStmNode::~VirtualStmNode()
{
ULONG ulRef = 0;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::~VirtualStmNode"));
if(NULL != _ptszName)
{
delete _ptszName;
_ptszName = NULL;
}
if ( NULL != _pstm )
{
ulRef = _pstm->Release();
// Object is being destructed, assert if reference count is non zero.
DH_ASSERT(0 == ulRef);
_pstm = NULL;
}
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Init, public
//
// Synopsis: Initializes a stream node - does not open or create the
// actual stream.
//
// Arguments: [tszName] - Name of this stream
// [cb] - Size of this stream
//
// Returns: S_OK if node initialized successfully, otherwise an error.
//
// History: DeanE 21-Mar-96 Created
// Narindk 24-Apr-96 Enhanced
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Init( LPTSTR tszName, ULONG cb)
{
HRESULT hr = S_OK;
DH_VDATESTRINGPTR(tszName);
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Init"));
DH_ASSERT(NULL != tszName);
if(S_OK == hr)
{
_ptszName = new TCHAR[_tcslen(tszName)+1];
if (_ptszName == NULL)
{
hr = E_OUTOFMEMORY;
}
else
{
_tcscpy(_ptszName, tszName);
_cb = cb;
}
}
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::AppendSisterStm, public
//
// Synopsis: Appends the node passed to the end of this nodes' sister
// node chain.
//
// Arguments: [pcnNew] - The new node to append.
//
// Returns: S_OK for success or an error code.
//
// History: 17-Apr-96 Narindk Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::AppendSisterStm(VirtualStmNode *pvsnNew)
{
HRESULT hr = S_OK;
VirtualStmNode *pvsnTrav = this;
DH_VDATEPTRIN(pvsnNew, VirtualStmNode);
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::AppendSisterStm"));
DH_ASSERT(NULL != pvsnNew);
if(S_OK == hr)
{
// Find the last sister in the chain
while (NULL != pvsnTrav->_pvsnSister)
{
pvsnTrav = pvsnTrav->_pvsnSister;
}
// Append the new node as a sister of the last node,
// and make the new node point to this nodes parent as it's parent
pvsnTrav->_pvsnSister = pvsnNew;
pvsnNew->_pvcnParent = pvsnTrav->_pvcnParent;
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Create, public
//
// Synopsis: Wrapper for IStorage::CreateStream that will create and
// open a new IStream object within this storage object.
//
// Arguments: [grfmode] - Access mode for creating & opening new storage
// object.
// [dwReserved1] - Reserved by OLE for future use, must be zero.
// [dwReserved2] - Reserved by OLE for future use, must be zero.
//
// Returns: S_OK Stream created successfully.
// STG_E_ACCESSDENIED Insufficient permissions to create.
// STG_E_INVALIDPOINTER Bad pointer was passed in.
// STG_E_FILEALREADYEXISTS File with specified name exists and
// mode is set to STGM_FAILIFTHERE.
// STG_TOOMANYOPENFILES too many open files
// STG_E_INSUFFICIENTMEMORY Out of memory.
// STG_E_INVALIDFLAG Unsuppoeted value in grfmode.
// STG_E_INVALIDPARAMETER Invalid parameter.
// STG_E_INVALIDNAME Invalid value for ptcsName.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
//
// History: 18-Apr-96 NarindK Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Create(
DWORD grfMode,
DWORD dwReserved1,
DWORD dwReserved2)
{
HRESULT hr = S_OK;
LPOLESTR pOleStrTemp = NULL;
DH_ASSERT(0 == dwReserved1);
DH_ASSERT(0 == dwReserved2);
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Create"));
DH_ASSERT(NULL != _pvcnParent);
DH_ASSERT(NULL != _pvcnParent->_pstg);
if(S_OK == hr)
{
// Convert _ptszName to OLECHAR
hr = TStringToOleString(_ptszName, &pOleStrTemp);
DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
}
if(S_OK == hr)
{
hr = _pvcnParent->_pstg->CreateStream(
pOleStrTemp,
grfMode,
dwReserved1,
dwReserved2,
&_pstm);
DH_HRCHECK(hr, TEXT("IStorage::CreateStream")) ;
DH_TRACE ((DH_LVL_DFLIB, TEXT("CreateStream:%s"), _ptszName));
}
// Clean up
if(NULL != pOleStrTemp)
{
delete pOleStrTemp;
pOleStrTemp = NULL;
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Read, public
//
// Synopsis: Reads data from the stream starting at current seek pointer.
//
// Arguments: [pv] - Points to buffer in which stream data should be stored.
// [cb] - Specifies number of bytes to read from the stream.
// [pcbRead] - Points to the number if bytes actually read from
// from the stream. Caller can specify it as NULL if not
// interested in this value.
//
// Returns: S_OK Data successfully read from stream.
// S_FALSE Data couldn't be read from the stream.
// STG_E_ACCESSDENIED Insufficient access.
// STG_E_INVALIDPOINTER Bad pointer passed in pv.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// STG_E_WRITEFAULT Disk error during a write operaion.
// Other errors Any ILockBytes or system errors.
//
// History: 18-Apr-96 NarindK Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Read(
PVOID pv,
ULONG cb,
ULONG *pcbRead)
{
HRESULT hr = S_OK;
LPSTREAM pstm = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Read"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->Read(pv, cb, pcbRead);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Read"));
}
// BUBUG: To check invalid parameter checking, may have to remove DH_
// validate macros.
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Write, public
//
// Synopsis: Writes data cb bytes from buffer pointed to by pv into stream
// starting at current seek pointer.
//
// Arguments: [pv] - Points to buffer containing data to be written to stream
// [cb] - Specifies number of bytes to write into the stream.
// [pcbWritten] - Points to the number if bytes actually written
// to the stream. Caller can specify it as NULL if not
// interested in this value.
//
// Returns: S_OK Data successfully read from stream.
// S_E_MEDIUMFULL No space left on device.
// STG_E_ACCESSDENIED Insufficient access.
// STG_E_CANTSAVE Data cannot be written for reasons other
// than no access or space.
// STG_E_INVALIDPOINTER Bad pointer passed in pv.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// STG_E_WRITEFAULT Disk error during a write operaion.
// Other errors Any ILockBytes or system errors.
//
// History: 18-Apr-96 NarindK Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Write(
PVOID pv,
ULONG cb,
ULONG *pcbWritten)
{
HRESULT hr = S_OK;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Write"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->Write(pv, cb, pcbWritten);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Write"));
}
if (( S_OK == hr) && (NULL != pcbWritten))
{
if (cb != *pcbWritten)
{
hr = E_FAIL;
DH_TRACE((
DH_LVL_ERROR,
TEXT("VirtualStmNode::Write - bytes: Expected=%lu, Actual=%lu"),
cb,
*pcbWritten));
DH_ASSERT(
!TEXT("Expected and actual bytes written mismatch!"));
}
}
// BUBUG: To check invalid parameter checking, may have to remove DH_
// validate macros.
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Open, public
//
// Synopsis: Opens an existing named stream according to grfMode.
// OLE doesn't support opening streams in
// transacted mode, also doesn't allow opening the same stream
// from same open IStorage instance.
//
// Arguments: [pvReserved1] - Reserved for future use. Must be NULL.
// [grfmode] - Mode in which stream should be opened.
// [dwReserved2] - Reserved for future use. Must be NULL.
//
// Returns: HRESULT
// S_OK Stream was opened successfully.
// STG_E_ACCESSDENIED Insufficient access to open stream.
// STG_E_FILENOTFOUND Stream of specified name doesn't exist.
// STG_E_INVALIDFLAG Unsupported value in grfMode.
// STG_E_INVALIDNAME Invalid name.
// STG_E_INVALIDPOINTER Bad pointer passed in pv.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// STG_E_INVALIDPARAMETER Invalid parameter.
//
// History: NarindK 24-Apr-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Open(
PVOID pvReserved1,
DWORD grfmode,
DWORD dwReserved2)
{
HRESULT hr = S_OK;
LPSTREAM pstm = NULL;
LPOLESTR pOleStrTemp = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Open"));
DH_ASSERT(NULL == pvReserved1);
DH_ASSERT(0 == dwReserved2);
DH_ASSERT(NULL != _pvcnParent);
DH_ASSERT(NULL != _pvcnParent->_pstg);
if(S_OK == hr)
{
// Convert _ptszName to OLECHAR
hr = TStringToOleString(_ptszName, &pOleStrTemp);
DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
}
if(S_OK == hr)
{
hr = _pvcnParent->_pstg->OpenStream(pOleStrTemp,
pvReserved1,
grfmode,
dwReserved2,
&pstm);
DH_HRCHECK(hr, TEXT("IStorage::OpenStream"));
DH_TRACE ((DH_LVL_DFLIB, TEXT("OpenStream:%s"), _ptszName));
}
if((S_OK == hr) && (NULL == _pstm))
{
_pstm = pstm;
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::Open"));
// Clean up
if(NULL != pOleStrTemp)
{
delete pOleStrTemp;
pOleStrTemp = NULL;
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Close, public
//
// Synopsis: Closes an open stream.
//
// Arguments: none
//
// Returns: HRESULT
//
// History: NarindK 25-Apr-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Close()
{
HRESULT hr = S_OK;
ULONG ulRef = 0;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Close"));
DH_ASSERT(NULL != _pstm);
// When we create the stream, it is open. We do not call release
// on _pstm normally till the VirtualStmNode object is destructed, or
// if explicitly this function is used to close the stream.
if ( NULL != _pstm )
{
ulRef = _pstm->Release();
}
else
{
DH_ASSERT(!TEXT("_pstm is already NULL!"));
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::Close"));
if(0 == ulRef)
{
_pstm = NULL;
}
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Seek, public
//
// Synopsis: Adjusts the location of seek pointer on the stream.
//
// Arguments: [dlibMove]
// [dwOrigin]
// [plibNewPosition]
//
// Returns: HRESULT
//
// History: NarindK 25-Apr-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Seek(
LARGE_INTEGER dlibMove,
DWORD dwOrigin,
ULARGE_INTEGER *plibNewPosition)
{
HRESULT hr = S_OK;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Seek"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->Seek(dlibMove, dwOrigin, plibNewPosition);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Seek"));
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::SetSize, public
//
// Synopsis: Changes the size of the stream.
//
// Arguments: [libNewSize] Specifies new size of stream
//
// Returns: HRESULT
// S_OK Stream size was successfully changed.
// STG_E_MEDIUMFULL Lack of space prohibited change of size
// STG_E_INVALIDFUNCTIONS High DWORD of libNewSize != 0
// STG_E_WRITEFAULT Disk error during a write operation.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// Other errors Any ILockBytes or system errors.
//
// History: NarindK 29-Apr-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::SetSize(ULARGE_INTEGER libNewSize)
{
HRESULT hr = S_OK;
LPSTREAM pstm = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::SetSize"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->SetSize(libNewSize);
DH_HRCHECK(hr, TEXT("VirtualStmNode::SetSize"));
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Commit, public
//
// Synopsis: Commits any changes made to IStorage object containing the
// stream.
//
// Arguments: [grfCommitFlags] Controls how obect is committed to IStorage
//
// Returns: HRESULT
// S_OK Stream successfully committed.
// STG_E_MEDIUMFULL Commit failde due to lack of space
// STG_E_WRITEFAULT Disk error during a write operation.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// Other errors Any ILockBytes or system errors.
//
// History: NarindK 29-Apr-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Commit(DWORD grfCommitFlags)
{
HRESULT hr = S_OK;
LPSTREAM pstm = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Commit"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->Commit(grfCommitFlags);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Commit"));
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Revert, public
//
// Synopsis: Discards any changes made to stream object since it was opened
// or last committed in transacted mode. This function is a noop
// in direct mode.
//
// Arguments: none
//
// Returns: HRESULT
// S_OK Stream successfully committed.
// STG_E_WRITEFAULT Disk error during a write operation.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// Other errors Any ILockBytes or system errors.
//
// History: NarindK 29-Apr-96 Created
//
// Notes: OLE doesn't support IStream objects being opened in transacted
// mode, os most applications don't need to call this function.
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Revert()
{
HRESULT hr = S_OK;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Revert"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->Revert();
DH_HRCHECK(hr, TEXT("VirtualStmNode::Revert"));
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Stat, public
//
// Synopsis: Returns relevant statistics concerning this open stream.
//
// Arguments: [pStatStg] - pointer to STATSTG structure.
// [grfStatFlag] - Controls levels of returned statistics.
//
// Returns: S_OK Stastics were successfully returned.
// STG_E_ACCESSDENIED Stm cannot be accessed.
// STG_E_REVERTED Object invalidated by a revert operation
// above it in transaction tree.
// STG_E_INSUFFICIENTMEMORY Not enough memory.
// STG_E_INVALIDPOINTER Invalid pointer.
////
// History: NarindK 8-May-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Stat(
STATSTG *pStatStg,
DWORD grfStatFlag)
{
HRESULT hr = S_OK;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Stat"));
DH_ASSERT(_pstm != NULL);
DH_ASSERT(NULL != pStatStg);
DH_ASSERT((
(grfStatFlag == STATFLAG_DEFAULT) ||
(grfStatFlag == STATFLAG_NONAME)));
if(S_OK == hr)
{
hr = _pstm->Stat(pStatStg, grfStatFlag);
DH_HRCHECK(hr, TEXT("VirtualStmNode::Stat"));
}
// BUGBUG: May remove to need DH_ assert macros to do invalid parameter
// checking.
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::CopyTo, public
//
// Synopsis: Copies data from one stream to another strea, starting at the
// current seek pointer in each stream.
//
// Arguments: [pvsn] - pointer to VirtualStmNode into whose stream the data
// should be copied into.
// [cb] - Specifies number of bytes to be read from source stream
// [pcbRead] - Contains the number of bytes actually read from the
// source stream.
// [pcbWritten] - Contains number of bytes actually written to the
// destination stream.
//
// Returns: S_OK Stream successfully copied.
// STG_E_MEDIUMFULL Lack of space prohibited copy.
// STG_E_READFAULT Disk error during read.
// STG_E_WRITEFAULT Disk error during write opearion.
// STG_E_INVALIDPOINTER Invalid pointer.
// STG_E_REVERTED Object invalidated by a revert operation
// above it in transaction tree.
// STG_E_INSUFFICIENTMEMORY Not enough memory.
// Other errors
//
// History: NarindK 9-May-96 Created
//
// Notes: BUGBUG: Currently not updating the _cb datasize member
// of virtualstmnode objects involved. required?
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::CopyTo(
VirtualStmNode *pvsnDest,
ULARGE_INTEGER cb,
ULARGE_INTEGER *pcbRead,
ULARGE_INTEGER *pcbWritten)
{
HRESULT hr = S_OK;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::CopyTo"));
DH_VDATEPTROUT(pvsnDest, VirtualStmNode);
DH_ASSERT(NULL != _pstm);
DH_ASSERT(NULL != pvsnDest);
DH_ASSERT(NULL != pvsnDest->_pstm);
if(S_OK == hr)
{
hr = _pstm->CopyTo(pvsnDest->_pstm, cb, pcbRead, pcbWritten);
DH_HRCHECK(hr, TEXT("VirtualStmNode::CopyTo"));
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::AddRefCount, public
//
// Synopsis: Increments the reference count on IStream object.
//
// Arguments: none
//
// Returns: HRESULT
//
// History: NarindK 21-May-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::AddRefCount()
{
HRESULT hr = S_OK;
ULONG ulTmp = 0;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::AddRefCount"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
ulTmp = _pstm->AddRef();
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::AddRefCount"));
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::QueryInterface, public
//
// Synopsis: Returns pointers to supported objects.
//
// Arguments: none
//
// Returns: HRESULT
//
// History: NarindK 21-May-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::QueryInterface(
REFIID riid,
LPVOID *ppvObj)
{
HRESULT hr = S_OK;
DH_VDATEPTROUT(ppvObj, IUnknown *) ;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::QueryInterface"));
DH_ASSERT(NULL != ppvObj);
DH_ASSERT(NULL != _pstm);
if(S_OK == hr)
{
// Initilze the out parameter
*ppvObj = NULL;
hr = _pstm->QueryInterface(riid, ppvObj);
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::QueryInterface"));
if(S_OK == hr)
{
DH_ASSERT(NULL != *ppvObj);
}
else
{
DH_ASSERT(NULL == *ppvObj);
}
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::LockRegion, public
//
// Synopsis: Locks a range of bytes in the stream.
//
// Arguments: [libOffset] - Specifies beginning of region to lock.
// [cb] - Specifies length of region to be locked in bytes.
// [dwLockType]- Specifies kind of lock beng requested.
//
// Returns: HRESULT
// S_OK Range of bytes was successfully locked.
// STG_E_INVALIDFUNCTION Function not supported in this release
// STG_E_LOCKVIOLATION Requested lock supported, but can't be
// granted presently becoz of existing
// lock.
//
// History: NarindK 22-May-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::LockRegion(
ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType)
{
HRESULT hr = S_OK;
LPSTREAM pstm = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::LockRegion"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->LockRegion(libOffset, cb, dwLockType);
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::LockRegion"));
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::UnlockRegion, public
//
// Synopsis: Unlocks a region of stream previously locked by IStream::
// LockRegion
//
// Arguments: [libOffset] - Specifies beginning of region to lock.
// [cb] - Specifies length of region to be locked in bytes.
// [dwLockType]- Specifies kind of lock beng requested.
//
// Returns: HRESULT
// S_OK Requested unlock granted.
// STG_E_INVALIDFUNCTION Function not supported in this release
// STG_E_LOCKVIOLATION Requested unlock can't be granted.
//
// History: NarindK 22-May-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::UnlockRegion(
ULARGE_INTEGER libOffset,
ULARGE_INTEGER cb,
DWORD dwLockType)
{
HRESULT hr = S_OK;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::UnlockRegion"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
hr = _pstm->UnlockRegion(libOffset, cb, dwLockType);
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::UnlockRegion"));
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Clone, public
//
// Synopsis: Returns a new IStream object that is clone of this stream.
//
// Arguments: [ppstm] - Points to where new stream to be returned.
//
// Returns: HRESULT
// S_OK Stream successfully copied.
// E_OUTOFMEMORY Out of memory
// STG_E_INVALIDPOINTER Bad pointer was passed in.
// STG_E_INSUFFICIENTMEMORY Not enough memory
// STG_E_WRITEFAULT Disk error during a write operation.
// STG_E_REVERTED Object has been invalidated by a revert
// operation above it in transaction tree.
// Other errors Any ILockBytes or system errors.
//
// History: NarindK 22-May-96 Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Clone(LPSTREAM *ppstm)
{
HRESULT hr = S_OK;
LPSTREAM pstm = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Clone"));
DH_ASSERT(_pstm != NULL);
if(S_OK == hr)
{
// Initialize out parameter
*ppstm = NULL;
hr = _pstm->Clone(ppstm);
}
DH_HRCHECK(hr, TEXT("VirtualStmNode::Clone"));
if(S_OK == hr)
{
DH_ASSERT(NULL != *ppstm);
}
else
{
DH_ASSERT(NULL == *ppstm);
}
return(hr);
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Rename, public
//
// Synopsis: Wrapper for IStorage::RenameElement that renames a stream
// contained in an Storage object subject to transaction state
// of IStorage object.
//
// Arguments: [pptcsNewName] - Points to pointer to new name for the element.
//
// Returns: S_OK Object was successfully renamed.
// STG_E_ACCESSDENIED Named element ptcsNewName alreadys exists.
// STG_E_FILENOTFOUND Element couldn't be found.
// STG_E_REVERTED Object invalidated by a revert operation
// above it in transaction tree.
// STG_E_INSUFFICIENTMEMORY Not enough memory to rename element.
// STG_E_INVALIDPOINTER Invalid pointer.
// STG_E_INVALIDNAME Invalid name.
// STG_E_INVALIDPARAMETER Invalid parameter
// STG_E_TOOMANYOPENFILES too many open files.
//
// History: 8-July-96 NarindK Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Rename(LPCTSTR ptcsNewName)
{
HRESULT hr = S_OK;
LPOLESTR pOleStrOld = NULL;
LPOLESTR pOleStrNew = NULL;
DH_VDATESTRINGPTR(ptcsNewName);
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Rename"));
DH_ASSERT(NULL != _pvcnParent);
DH_ASSERT(NULL != _pvcnParent->_pstg);
if(S_OK == hr)
{
// Convert _ptszName to OLECHAR
hr = TStringToOleString(_ptszName, &pOleStrOld);
DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
}
if(S_OK == hr)
{
// Convert ptcsNewName to OLECHAR
hr = TStringToOleString((LPTSTR)ptcsNewName, &pOleStrNew);
DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
}
if(S_OK == hr)
{
hr = _pvcnParent->_pstg->RenameElement(pOleStrOld, pOleStrNew);
DH_HRCHECK(hr, TEXT("IStorage::Rename")) ;
}
if(S_OK == hr)
{
// Change the name of VirtualStmNode i.e. its _ptszName variable also
// First delete the old name
if(NULL != _ptszName)
{
delete _ptszName;
_ptszName = NULL;
}
// Now copy the new name by allocating enough memory
_ptszName = new TCHAR[_tcslen(ptcsNewName)+1];
if (_ptszName == NULL)
{
hr = E_OUTOFMEMORY;
}
else
{
_tcscpy(_ptszName, ptcsNewName);
}
}
// Clean up
if(NULL != pOleStrOld)
{
delete pOleStrOld;
pOleStrOld = NULL;
}
if(NULL != pOleStrNew)
{
delete pOleStrNew;
pOleStrNew = NULL;
}
// BUGBUG: to do valid parameter checking, may need to change prototype
// of function to take old name too. Also remove DH_ validation checking
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::Destroy, public
//
// Synopsis: Wrapper for IStorage::DestroyElement that removes a stream
// from this storage, subject to transaction mode in which it
// was opened. The wrapper for IStorage::DestoryElement that
// destroys a storage from this storage is in VirtualCtrNode::
// Destroy.
//
// Arguments: None
//
// Returns: S_OK Object was successfully renamed.
// STG_E_ACCESSDENIED insufficient permissions.
// STG_E_FILENOTFOUND Element couldn't be found.
// STG_E_REVERTED Object invalidated by a revert operation
// above it in transaction tree.
// STG_E_INSUFFICIENTMEMORY Not enough memory to rename element.
// STG_E_INVALIDPOINTER Invalid pointer.
// STG_E_INVALIDNAME Invalid name.
// STG_E_INVALIDPARAMETER Invalid parameter
// STG_E_TOOMANYOPENFILES too many open files.
//
// History: 8-July-96 NarindK Created
//
// Notes: The existing open instance of this element from this parent
// instance becomes invalid after this function is called.
//
// Use utility function DestroyStream from util.cxx that is a
// wrapper for this function and also readjusts the VirtualDF
// tree.
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::Destroy()
{
HRESULT hr = S_OK;
LPOLESTR pOleStrTemp = NULL;
VirtualStmNode *pvsnTemp = NULL;
VirtualStmNode *pvsnOldSister = NULL;
DH_FUNCENTRY(&hr, DH_LVL_DFLIB, _TEXT("VirtualStmNode::Destroy"));
DH_ASSERT(NULL != _pvcnParent);
DH_ASSERT(NULL != _pvcnParent->_pstg);
if(S_OK == hr)
{
// Convert _ptszName to OLECHAR
hr = TStringToOleString(_ptszName, &pOleStrTemp);
DH_HRCHECK(hr, TEXT("TStringToOleString")) ;
}
if(S_OK == hr)
{
hr = _pvcnParent->_pstg->DestroyElement(pOleStrTemp);
DH_HRCHECK(hr, TEXT("IStorage::DestroyElement")) ;
}
// Clean up
if(NULL != pOleStrTemp)
{
delete pOleStrTemp;
pOleStrTemp = NULL;
}
return hr;
}
//+--------------------------------------------------------------------------
// Member: VirtualStmNode::CalculateCRCs
//
// Synopsis: Updates the name and data crc
//
// Arguments: None.
//
// Returns: HRESULT
//
// History: 02-Apr-98 georgis Created
//---------------------------------------------------------------------------
HRESULT VirtualStmNode::UpdateCRC(DWORD dwChunkSize)
{
HRESULT hr=S_OK;
DH_FUNCENTRY(NULL, DH_LVL_DFLIB, _TEXT("::UpdateCRC"));
// Calculate the CRC for the stream data
hr=CalculateStreamDataCRC(_pstm,0,&_dwCRC.dwCRCData,dwChunkSize);
DH_HRCHECK(hr, TEXT("CalculateStreamDataCRC"));
// Calculate the CRC for the stream name
if ( S_OK == hr )
{
hr = CalculateCRCForName(_ptszName, &_dwCRC.dwCRCName);
DH_HRCHECK(hr, TEXT("CalculateCRCForName")) ;
}
// Munge in dwCRCSum
_dwCRC.dwCRCSum=CRC_PRECONDITION;
MUNGECRC(_dwCRC.dwCRCSum,_dwCRC.dwCRCData);
MUNGECRC(_dwCRC.dwCRCSum,_dwCRC.dwCRCName);
return hr;
}