// //---------------------------------------------------------------------------- // ObjectComponents // (C) Copyright 1994 by Borland International, All Rights Reserved // // Implementation of TOcStorage & TOcStream IStorage/IStream encapsulation //---------------------------------------------------------------------------- #include #include #include #include #include DIAG_DEFINE_GROUP(OcExcept, true, 1); // Simple refcount debug assistant // #if defined(CHECK_REFCOUNT) static void RefCountCheck(IStorage far* 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, const char far* arg) { if (FAILED(stat)) Throw(err, stat, arg); } static char* sObjCompErrMsgs[] = { "", // xNoError "Could not locate " BOLEDLL, // xBOleLoadFail "Incompatible version of " BOLEDLL, // xBOleVersFail "Could not obtain BOle ClassMgr", // xBOleBindFail "Document factory [un]registration failed", // xDocFactoryFail "Missing Root IStorage in OcDocument", // xMissingRootIStorage "Internal OcPart creation error", // xInternalPartError "OcPart initialization failure", // xPartInitError "Unable to open/create RootStorage on '%s'", // xRootStorageOpenError "Unable to open/create Storage '%s'", // xStorageOpenError "Unable to open/create Storage on ILockBytes",// xStorageILockError "Unable to open/create Stream '%s'" // xStreamOpenError }; void TXObjComp::Throw(TError err, HRESULT hr, const char far* arg) { if (!InstanceCount) { char buf[128+1]; wsprintf(buf, sObjCompErrMsgs[err], arg); if (hr != HR_FAIL) { // generic error, dont bother with message. strcat(buf, ": "); int len = strlen(buf); OleErrorFromCode(hr, buf + len, sizeof buf - len - 2); } strcat(buf, "."); WARNX(OcExcept, hr != HR_NOERROR, 0, buf); throw TXObjComp(err, buf, hr); } } //---------------------------------------------------------------------------- // TOcStream // // // TOcStream::TOcStream(TOcStorage& storage, const char far* 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 HUGE* pv, ulong cb, ulong far* read) { PRECONDITION(pv && read && StreamI); return StreamI->Read(pv, cb, read); } // // // HRESULT TOcStream::Write(void const HUGE* pv, ulong cb, ulong far* written) { PRECONDITION(pv && written && StreamI); return StreamI->Write(pv, cb, written); } // // // HRESULT TOcStream::Seek(int64 move, uint32 origin, uint64 far* newPosition) { PRECONDITION(newPosition && StreamI); return StreamI->Seek(move, origin, (ULARGE_INTEGER*)newPosition); } // // // HRESULT TOcStream::SetSize(uint64 newSize) { return StreamI->SetSize(newSize); } // // // HRESULT TOcStream::CopyTo(TOcStream& stream, uint64 cb, uint64 far* read, uint64 far* written) { PRECONDITION(read); return StreamI->CopyTo(stream.GetIStream(), 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(offset, cb, lockType); } // // // HRESULT TOcStream::UnlockRegion(uint64 offset, uint64 cb, uint32 lockType) { return StreamI->UnlockRegion(offset, cb, lockType); } // // // HRESULT TOcStream::Stat(STATSTG far* statstg, uint32 statFlag) { PRECONDITION(statstg); return StreamI->Stat(statstg, statFlag); } // // // HRESULT TOcStream::Clone(IStream far* far* stream) { PRECONDITION(stream); return StreamI->Clone(stream); } //---------------------------------------------------------------------------- // TOcStorage // // // TOcStorage::TOcStorage(const char far* 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 far* 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, const char far* 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 far* rgiidExclude, SNB snbExclude, TOcStorage& dest) { return StorageI->CopyTo(ciidExclude, rgiidExclude, snbExclude, dest.GetIStorage()); } // // // HRESULT TOcStorage::MoveElementTo(char const far* name, TOcStorage& dest, char const far* 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 far* rsrvd2, uint32 rsrvd3, IEnumSTATSTG far*far* enm) { return StorageI->EnumElements(rsrvd1, rsrvd2, rsrvd3, enm); } // // // HRESULT TOcStorage::DestroyElement(const char far* name) { PRECONDITION(name); return StorageI->DestroyElement(OleStr(name)); } // // // HRESULT TOcStorage::RenameElement(const char far* oldName, const char far* newName) { return StorageI->RenameElement(OleStr(oldName), OleStr(newName)); } // // // HRESULT TOcStorage::SetElementTimes(const char far* name, FILETIME const far* ctime, FILETIME const far* atime, FILETIME const far* mtime) { return StorageI->SetElementTimes(OleStr(name), ctime, atime, mtime); } // // // HRESULT TOcStorage::SetClass(const IID far& clsid) { return StorageI->SetClass(clsid); } // // // HRESULT TOcStorage::SetStateBits(uint32 stateBits, uint32 mask) { return StorageI->SetStateBits(stateBits, mask); } // // // HRESULT TOcStorage::Stat(STATSTG far* statstg, uint32 statFlag) { PRECONDITION(statstg); return StorageI->Stat(statstg, statFlag); } // // // HRESULT TOcStorage::SwitchToFile(const char far* newPath) { if (!newPath) return HR_INVALIDARG; IRootStorage* rootStorageI; HRESULT hr = StorageI->QueryInterface(IID_IRootStorage, &(void far*)rootStorageI); if (HRSucceeded(hr)) { hr = rootStorageI->SwitchToFile(OleStr(const_cast(newPath))); rootStorageI->Release(); } return hr; } // // // HRESULT TOcStorage::CreateStream(const char far* name, uint32 mode, uint32 rsrvd1, uint32 rsrvd2, IStream far* far* stream) { PRECONDITION(name); return StorageI->CreateStream(OleStr(name), mode, rsrvd1, rsrvd2, stream); } // // // HRESULT TOcStorage::OpenStream(const char far* name, void far *rsrvd1, uint32 mode, uint32 rsrvd2, IStream far*far* stream) { PRECONDITION(name); return StorageI->OpenStream(OleStr(name), rsrvd1, mode, rsrvd2, stream); } // // // HRESULT TOcStorage::CreateStorage(const char far* name, uint32 mode, uint32 rsrvd1, uint32 rsrvd2, IStorage far*far* storage) { PRECONDITION(StorageI && name); return StorageI->CreateStorage(OleStr(name), mode, rsrvd1, rsrvd2, storage); } // // // HRESULT TOcStorage::OpenStorage(const char far* name, IStorage far* stgPriority, uint32 mode, SNB snbExclude, uint32 rsrvd, IStorage far*far* storage) { PRECONDITION(name); return StorageI->OpenStorage(OleStr(name), stgPriority, mode, snbExclude, rsrvd, storage); } // // // HRESULT TOcStorage::IsStorageFile(const char far* name) { PRECONDITION(name); return ::StgIsStorageFile(OleStr(name)); } // // // HRESULT TOcStorage::IsStorageILockBytes(ILockBytes far* lkbyt) { PRECONDITION(lkbyt); return ::StgIsStorageILockBytes(lkbyt); } // // // HRESULT TOcStorage::SetTimes(char const far* name, FILETIME const far* ctime, FILETIME const far* atime, FILETIME const far* mtime) { PRECONDITION(name); return ::StgSetTimes(OleStr(name), ctime, atime, mtime); }