//----------------------------------------------------------------------------
// ObjectComponents
// Copyright (c) 1994, 1996 by Borland International, All Rights Reserved
//
/// \file
/// Implementation of TOcStorage & TOcStream IStorage/IStream encapsulation
//----------------------------------------------------------------------------
#include <ocf/pch.h>
#include <ocf/ocobject.h>
#include <ocf/ocstorag.h>
#include <ocf/ocbocole.h>
#include <owl/geometry.h>
#include <owl/private/strmdefs.h>
namespace ocf {
using namespace owl;
using namespace owl;
DIAG_DEFINE_GROUP_INIT(OWL_INI, OcfExcept, 1, 0);
// Simple refcount debug assistant
//
#if defined(CHECK_REFCOUNT)
static void RefCountCheck(IStorage * si) {
uint32 count = si->AddRef();
count = si->Release();
}
#else
# define RefCountCheck(si)
#endif
//
// Storage sharing mode bit mask
//
#define STGM_SHARE_MASK (STGM_SHARE_DENY_NONE | STGM_SHARE_DENY_READ| \
STGM_SHARE_DENY_WRITE | STGM_SHARE_EXCLUSIVE)
//----------------------------------------------------------------------------
// TXObjComp
TXObjComp::~TXObjComp()
{
}
TXObjComp*
TXObjComp::Clone()
{
return new TXObjComp(*this);
}
void TXObjComp::Throw()
{
throw *this;
}
void TXObjComp::Check(HRESULT stat, TError err, LPCTSTR arg)
{
if (FAILED(stat))
Throw(err, stat, arg);
}
static LPCTSTR sObjCompErrMsgs[] = {
_T(""), // xNoError
_T("Could not locate " BOLEDLL), // xBOleLoadFail
_T("Incompatible version of " BOLEDLL), // xBOleVersFail
_T("Could not obtain BOle ClassMgr"), // xBOleBindFail
_T("Document factory [un]registration failed"), // xDocFactoryFail
_T("Missing Root IStorage in OcDocument"), // xMissingRootIStorage
_T("Internal OcPart creation error"), // xInternalPartError
_T("OcPart initialization failure"), // xPartInitError
_T("Unable to open/create RootStorage on '%s'"), // xRootStorageOpenError
_T("Unable to open/create Storage '%s'"), // xStorageOpenError
_T("Unable to open/create Storage on ILockBytes"),// xStorageILockError
_T("Unable to open/create Stream '%s'") // xStreamOpenError
};
void TXObjComp::Throw(TError err, HRESULT hr, LPCTSTR arg)
{
_TCHAR buf[128+1];
wsprintf(buf, sObjCompErrMsgs[err], arg);
if (hr != HR_FAIL) { // generic error, dont bother with message.
_tcscat(buf, _T(": "));
int len = static_cast<int>(_tcslen(buf));
OleErrorFromCode(hr, buf + len, sizeof buf - len - 2);
}
_tcscat(buf, _T("."));
WARNX(OcfExcept, hr != HR_NOERROR, 0, buf);
throw TXObjComp(err, buf, hr);
}
//----------------------------------------------------------------------------
// TOcStream
//
//
//
TOcStream::TOcStream(TOcStorage& storage, LPCTSTR name, bool create, uint32 mode)
{
// Make sure that the transacted mode is off since streams don't support
// this mode. Also make sure that the stream is opened in exclusive mode.
//
mode &= ~STGM_TRANSACTED;
mode = (mode & ~STGM_SHARE_MASK) | STGM_SHARE_EXCLUSIVE;
HRESULT hr = storage.OpenStream(name, 0, mode, 0, &StreamI);
if (!StreamI && create)
hr = storage.CreateStream(name, mode, 0, 0, &StreamI);
TXObjComp::Check(hr, TXObjComp::xStreamOpenError, name);
}
//
//
//
TOcStream::TOcStream(TOcStream& stream)
{
stream.Clone(&StreamI);
// if (!StreamI) throw...?
}
//
//
//
TOcStream::TOcStream(IStream* stream)
:
StreamI(stream)
{
}
//
//
//
TOcStream::~TOcStream()
{
if (StreamI)
StreamI->Release();
}
//
//
//
IStream*
TOcStream::GetIStream()
{
return StreamI;
}
//
//
//
HRESULT
TOcStream::Read(void * pv, ulong cb, ulong * read)
{
PRECONDITION(pv && StreamI);
return StreamI->Read(pv, cb, read);
}
//
//
//
HRESULT
TOcStream::Write(void const * pv, ulong cb, ulong * written)
{
PRECONDITION(pv && StreamI);
return StreamI->Write(pv, cb, written);
}
//
//
//
HRESULT
TOcStream::Seek(int64 move, uint32 origin, uint64 * newPosition)
{
PRECONDITION(StreamI);
return StreamI->Seek(*(LARGE_INTEGER*)&move, origin, (ULARGE_INTEGER*)newPosition);
}
//
//
//
HRESULT
TOcStream::SetSize(uint64 newSize)
{
return StreamI->SetSize(*(ULARGE_INTEGER*)&newSize);
}
//
//
//
HRESULT
TOcStream::CopyTo(TOcStream& stream, uint64 cb, uint64 * read, uint64 * written)
{
PRECONDITION(StreamI);
return StreamI->CopyTo(stream.GetIStream(), *(ULARGE_INTEGER*)&cb, (ULARGE_INTEGER*)read,
(ULARGE_INTEGER*)written);
}
//
//
//
HRESULT
TOcStream::Commit(uint32 commitFlags)
{
return StreamI->Commit(commitFlags);
}
//
//
//
HRESULT
TOcStream::Revert()
{
return StreamI->Revert();
}
//
//
//
HRESULT
TOcStream::LockRegion(uint64 offset, uint64 cb, uint32 lockType)
{
return StreamI->LockRegion(*(ULARGE_INTEGER*)&offset, *(ULARGE_INTEGER*)&cb, lockType);
}
//
//
//
HRESULT
TOcStream::UnlockRegion(uint64 offset, uint64 cb, uint32 lockType)
{
return StreamI->UnlockRegion(*(ULARGE_INTEGER*)&offset, *(ULARGE_INTEGER*)&cb, lockType);
}
//
//
//
HRESULT
TOcStream::Stat(STATSTG * statstg, uint32 statFlag)
{
PRECONDITION(statstg);
return StreamI->Stat(statstg, statFlag);
}
//
//
//
HRESULT
TOcStream::Clone(IStream * * stream)
{
PRECONDITION(stream);
return StreamI->Clone(stream);
}
//----------------------------------------------------------------------------
// TOcStorage
//
//
//
TOcStorage::TOcStorage(LPCTSTR fileName, bool create, uint32 mode)
{
// Parent = 0;
// Fill in the sharing mode based on the access
//
if ((mode & STGM_WRITE) || (mode & STGM_READWRITE))
mode = (mode & ~STGM_SHARE_MASK) | STGM_SHARE_DENY_WRITE;
else
mode = (mode & ~STGM_SHARE_MASK) | STGM_SHARE_DENY_NONE;
HRESULT hr;
if (create) {
mode |= STGM_CREATE;
if (!fileName)
mode |= STGM_DELETEONRELEASE;
hr = ::StgCreateDocfile(OleStr(fileName), mode, 0, &StorageI);
}
else {
hr = ::StgOpenStorage(OleStr(fileName), 0, mode, 0, 0, &StorageI);
}
RefCountCheck(StorageI);
TXObjComp::Check(hr, TXObjComp::xRootStorageOpenError, fileName);
}
//
//
//
TOcStorage::TOcStorage(ILockBytes * lkbyt, bool create, uint32 mode)
{
PRECONDITION(lkbyt);
// Fill in the sharing mode based on the access
//
if ((mode & STGM_WRITE) || (mode & STGM_READWRITE))
mode = (mode & ~STGM_SHARE_MASK) | STGM_SHARE_DENY_WRITE;
else
mode = (mode & ~STGM_SHARE_MASK) | STGM_SHARE_DENY_NONE;
HRESULT hr;
if (create) {
mode |= STGM_CREATE;
hr = ::StgCreateDocfileOnILockBytes(lkbyt, mode, 0, &StorageI);
}
else {
hr = ::StgOpenStorageOnILockBytes(lkbyt, 0, // IStorage* priority???
mode, 0, 0, &StorageI);
}
RefCountCheck(StorageI);
TXObjComp::Check(hr, TXObjComp::xStorageILockError);
}
//
//
//
TOcStorage::TOcStorage(TOcStorage& parent, LPCTSTR name, bool create, uint32 mode)
{
// Parent = &parent;
mode = (mode & ~STGM_SHARE_MASK) | STGM_SHARE_EXCLUSIVE;
HRESULT hr;
hr = parent.OpenStorage(name, 0, mode, 0, 0, &StorageI);
if (!StorageI && create)
hr = parent.CreateStorage(name, mode, 0, 0, &StorageI);
RefCountCheck(StorageI);
TXObjComp::Check(hr, TXObjComp::xStorageOpenError, name);
}
//
//
//
TOcStorage::TOcStorage(IStorage* storage)
:
StorageI(storage)
{
if (StorageI) {
StorageI->AddRef();
RefCountCheck(StorageI);
}
}
//
//
//
TOcStorage::~TOcStorage()
{
if (StorageI) {
RefCountCheck(StorageI);
StorageI->Release();
}
}
//
//
//
ulong
TOcStorage::AddRef()
{
return StorageI? StorageI->AddRef() : 0;
}
//
//
//
ulong
TOcStorage::Release()
{
return StorageI? StorageI->Release() : 0;
}
//
//
//
IStorage*
TOcStorage::GetIStorage()
{
return StorageI;
}
//
//
//
HRESULT
TOcStorage::CopyTo(uint32 ciidExclude, IID const * rgiidExclude, SNB snbExclude, TOcStorage& dest)
{
return StorageI->CopyTo(ciidExclude, rgiidExclude, snbExclude, dest.GetIStorage());
}
//
//
//
HRESULT
TOcStorage::MoveElementTo(LPCTSTR name, TOcStorage& dest, LPCTSTR newName, uint32 flags)
{
return StorageI->MoveElementTo(OleStr(name), dest.GetIStorage(), OleStr(newName), flags);
}
//
//
//
HRESULT
TOcStorage::Commit(uint32 commitFlags)
{
return StorageI->Commit(commitFlags);
}
//
//
//
HRESULT
TOcStorage::Revert()
{
return StorageI->Revert();
}
//
//
//
HRESULT
TOcStorage::EnumElements(uint32 rsrvd1, void * rsrvd2, uint32 rsrvd3, IEnumSTATSTG ** enm)
{
return StorageI->EnumElements(rsrvd1, rsrvd2, rsrvd3, enm);
}
//
//
//
HRESULT
TOcStorage::DestroyElement(LPCTSTR name)
{
PRECONDITION(name);
return StorageI->DestroyElement(OleStr(name));
}
//
//
//
HRESULT
TOcStorage::RenameElement(LPCTSTR oldName, LPCTSTR newName)
{
return StorageI->RenameElement(OleStr(oldName), OleStr(newName));
}
//
//
//
HRESULT
TOcStorage::SetElementTimes(LPCTSTR name, FILETIME const * ctime, FILETIME const * atime, FILETIME const * mtime)
{
return StorageI->SetElementTimes(OleStr(name), ctime, atime, mtime);
}
//
//
//
HRESULT
TOcStorage::SetClass(const IID & clsid)
{
return StorageI->SetClass(clsid);
}
//
//
//
HRESULT
TOcStorage::SetStateBits(uint32 stateBits, uint32 mask)
{
return StorageI->SetStateBits(stateBits, mask);
}
//
//
//
HRESULT
TOcStorage::Stat(STATSTG * statstg, uint32 statFlag)
{
PRECONDITION(statstg);
return StorageI->Stat(statstg, statFlag);
}
//
//
//
HRESULT
TOcStorage::SwitchToFile(LPCTSTR newPath)
{
if (!newPath)
return HR_INVALIDARG;
IRootStorage* rootStorageI;
HRESULT hr = StorageI->QueryInterface(IID_IRootStorage, (LPVOID *)&rootStorageI);
if (HRSucceeded(hr)) {
hr = rootStorageI->SwitchToFile(OleStr(const_cast<LPTSTR>(newPath)));
rootStorageI->Release();
}
return hr;
}
//
//
//
HRESULT
TOcStorage::CreateStream(LPCTSTR name, uint32 mode, uint32 rsrvd1, uint32 rsrvd2, IStream * * stream)
{
PRECONDITION(name);
return StorageI->CreateStream(OleStr(name), mode, rsrvd1, rsrvd2, stream);
}
//
//
//
HRESULT
TOcStorage::OpenStream(LPCTSTR name, void *rsrvd1, uint32 mode, uint32 rsrvd2, IStream ** stream)
{
PRECONDITION(name);
return StorageI->OpenStream(OleStr(name), rsrvd1, mode, rsrvd2, stream);
}
//
//
//
HRESULT
TOcStorage::CreateStorage(LPCTSTR name, uint32 mode, uint32 rsrvd1, uint32 rsrvd2, IStorage ** storage)
{
PRECONDITION(StorageI && name);
return StorageI->CreateStorage(OleStr(name), mode, rsrvd1, rsrvd2, storage);
}
//
//
//
HRESULT
TOcStorage::OpenStorage(LPCTSTR name, IStorage * stgPriority, uint32 mode, SNB snbExclude, uint32 rsrvd, IStorage ** storage)
{
PRECONDITION(name);
return StorageI->OpenStorage(OleStr(name), stgPriority, mode, snbExclude, rsrvd, storage);
}
//
//
//
HRESULT
TOcStorage::IsStorageFile(LPCTSTR name)
{
PRECONDITION(name);
return ::StgIsStorageFile(OleStr(name));
}
//
//
//
HRESULT
TOcStorage::IsStorageILockBytes(ILockBytes * lkbyt)
{
PRECONDITION(lkbyt);
return ::StgIsStorageILockBytes(lkbyt);
}
//
//
//
HRESULT
TOcStorage::SetTimes(LPCTSTR name, FILETIME const * ctime, FILETIME const * atime, FILETIME const * mtime)
{
PRECONDITION(name);
return ::StgSetTimes(OleStr(name), ctime, atime, mtime);
}
} // OCF namespace
//==============================================================================
↑ V1004 The 'lkbyt' pointer was used unsafely after it was verified against nullptr. Check lines: 570, 572.
↑ V1004 The 'lkbyt' pointer was used unsafely after it was verified against nullptr. Check lines: 299, 311.