|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1994.
//
// File: simpstg.cxx
//
// Contents: SimpStorage class implementation
//
// Classes:
//
// Functions:
//
// History: 04-Aug-94 PhilipLa Created
// 26-Feb-97 Danl QI support for IID_IPropertySetStorage
//
//----------------------------------------------------------------------------
#include "simphead.cxx"
#pragma hdrstop
#include <ole.hxx>
#include <logfile.hxx>
#include <expparam.hxx>
#ifdef SECURE_BUFFER
BYTE s_bufSecure[MINISTREAMSIZE]; #endif
ULONG ConvertSect(SECT sect) { return (ULONG)(sect << SECTORSHIFT512) + SECTORSIZE; }
//+---------------------------------------------------------------------------
//
// Member: CSimpStorage::Init, public
//
// Synopsis: Init function
//
// Arguments: [psdh] -- Pointer to hints structure
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//----------------------------------------------------------------------------
SCODE CSimpStorage::Init(WCHAR const * pwcsName, SSimpDocfileHints *psdh) { simpDebugOut((DEB_ITRACE, "In CSimpStorage::Init:%p(%ws)\n", this, pwcsName));
#ifdef UNICODE
TCHAR const *atcPath = pwcsName; #else
TCHAR atcPath[_MAX_PATH+1];
UINT uCodePage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
if (!WideCharToMultiByte( uCodePage, 0, pwcsName, -1, atcPath, _MAX_PATH + 1, NULL, NULL)) { return STG_E_INVALIDNAME; } #endif
_hFile = CreateFileT(atcPath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (_hFile == INVALID_HANDLE_VALUE) { return STG_SCODE(GetLastError()); }
if (FALSE == SetEndOfFile (_hFile)) { return STG_SCODE(GetLastError()); }
_sectMax = 0; //From this point on, we need to try to produce a docfile.
_fDirty = TRUE; _clsid = IID_NULL;
#ifdef SECURE_SIMPLE_MODE
memset(s_bufSecure, SECURECHAR, MINISTREAMSIZE); #endif
simpDebugOut((DEB_ITRACE, "Out CSimpStorage::Init\n")); return S_OK; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::Release, public
//
// Synopsis: Releases resources for a CSimpStorage
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP_(ULONG) CSimpStorage::Release(void) { LONG lRet;
olLog(("%p::In CSimpStorage::Release()\n", this)); simpDebugOut((DEB_TRACE, "In CSimpStorage::Release()\n"));
simpAssert(_cReferences > 0); lRet = AtomicDec(&_cReferences); if (lRet == 0) { //Clean up
if (_hFile != INVALID_HANDLE_VALUE) { if (_fDirty) Commit(STGC_DEFAULT); CloseHandle(_hFile); } delete this; }
simpDebugOut((DEB_TRACE, "Out CSimpStorage::Release()\n")); olLog(("%p::Out CSimpStorage::Release(). ret == %lu\n", this, lRet)); FreeLogFile(); return (ULONG)lRet; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::CreateStream, public
//
// Synopsis: Creates a stream
//
// Arguments: [pwcsName] - Name
// [grfMode] - Permissions
// [reserved1]
// [reserved2]
// [ppstm] - Stream return
//
// Returns: Appropriate status code
//
// Modifies: [ppstm]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::CreateStream(WCHAR const *pwcsName, DWORD grfMode, DWORD reserved1, DWORD reserved2, IStream **ppstm) { SCODE sc; CSimpStream *pstm; CDfNameList *pdfl, *pdflPrev = NULL; CDfNameList *pdflLoop = _pdfl; int iCmp;
olLog(("%p::In CSimpStorage::CreateStream(%ws, %lX, %lu, %lu, %p)\n", this, pwcsName, grfMode, reserved1, reserved2, ppstm));
SIMP_VALIDATE(CreateStream(pwcsName, grfMode, reserved1, reserved2, ppstm));
if (grfMode != (STGM_READWRITE | STGM_SHARE_EXCLUSIVE)) return STG_E_INVALIDFLAG;
if (_pdflCurrent != NULL) { return STG_E_INVALIDFUNCTION; }
//Check the name. If it isn't already in the list, create a new
// CDfNameList object (in pdfl), and create a new stream object for it.
pdfl = new CDfNameList; if (pdfl == NULL) { return STG_E_INSUFFICIENTMEMORY; }
pstm = new CSimpStream; if (pstm == NULL) { delete pdfl; return STG_E_INSUFFICIENTMEMORY; }
pdfl->SetName(pwcsName); pdfl->SetStart(_sectMax); pdfl->SetSize(0);
while (pdflLoop != NULL) { iCmp = CDirectory::NameCompare(pdfl->GetName(), pdflLoop->GetName()); if (iCmp == 0) { //Already have a stream of this name.
delete pdfl; delete pstm; return STG_E_FILEALREADYEXISTS; }
if (iCmp < 0) { //We found the right spot.
break; }
pdflPrev = pdflLoop; pdflLoop = pdflLoop->GetNext(); }
if (FAILED(sc = pstm->Init(this, _hFile, ConvertSect(_sectMax)))) { delete pdfl; delete pstm; return sc; }
//Insert pdfl into list.
pdfl->Insert(&_pdfl, pdflPrev, pdflLoop);
_pdflCurrent = pdfl; _fDirty = TRUE; _cStreams++; *ppstm = pstm;
olLog(("%p::Out CSimpStorage::CreateStream(). " "*ppstm == %p, ret == %lx\n", this, *ppstm, S_OK));
return S_OK; }
//+---------------------------------------------------------------------------
//
// Member: CSimpStorage::ReleaseCurrentStream, public
//
// Synopsis: Signal release of the current open stream
//
// Arguments: None.
//
// Returns: void.
//
// History: 05-Aug-94 PhilipLa Created
//
//----------------------------------------------------------------------------
#ifdef SECURE_SIMPLE_MODE
void CSimpStorage::ReleaseCurrentStream(ULONG ulHighWater) #else
void CSimpStorage::ReleaseCurrentStream(void) #endif
{ simpDebugOut((DEB_ITRACE, "In CSimpStorage::ReleaseCurrentStream:%p()\n", this));
ULONG cbSize; ULONG ulEndOfFile;
ulEndOfFile = GetFileSize(_hFile, NULL);
cbSize = ulEndOfFile - ConvertSect(_sectMax); cbSize = max(cbSize, MINISTREAMSIZE);
_pdflCurrent->SetSize(cbSize);
ULONG sectUsed; sectUsed = (cbSize + SECTORSIZE - 1) / SECTORSIZE;
#ifdef SECURE_SIMPLE_MODE
ULONG cbBytesToWrite = ConvertSect(sectUsed + _sectMax) - ulHighWater; simpAssert(ConvertSect(sectUsed + _sectMax) >= ulHighWater);
ULONG cbWritten;
if ((cbBytesToWrite > 0) && (SetFilePointer(_hFile, ulHighWater, NULL, FILE_BEGIN) != INVALID_SET_FILE_POINTER)) { while (cbBytesToWrite > 0) { if (!WriteFile(_hFile, s_bufSecure, min(MINISTREAMSIZE, cbBytesToWrite), &cbWritten, NULL)) { break; } cbBytesToWrite -= cbWritten; } } #endif
_sectMax += sectUsed; _pdflCurrent = NULL;
simpDebugOut((DEB_ITRACE, "Out CSimpStorage::ReleaseCurrentStream\n")); }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::OpenStream, public
//
// Synopsis: Opens an existing stream
//
// Arguments: [pwcsName] - Name
// [reserved1]
// [grfMode] - Permissions
// [reserved2]
// [ppstm] - Stream return
//
// Returns: Appropriate status code
//
// Modifies: [ppstm]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::OpenStream(WCHAR const *pwcsName, void *reserved1, DWORD grfMode, DWORD reserved2, IStream **ppstm) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::CreateStorage, public
//
// Synopsis: Creates an embedded DocFile
//
// Arguments: [pwcsName] - Name
// [grfMode] - Permissions
// [reserved1]
// [reserved2]
// [ppstg] - New DocFile return
//
// Returns: Appropriate status code
//
// Modifies: [ppstg]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::CreateStorage(WCHAR const *pwcsName, DWORD grfMode, DWORD reserved1, LPSTGSECURITY reserved2, IStorage **ppstg) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::OpenStorage, public
//
// Synopsis: Gets an existing embedded DocFile
//
// Arguments: [pwcsName] - Name
// [pstgPriority] - Priority reopens
// [grfMode] - Permissions
// [snbExclude] - Priority reopens
// [reserved]
// [ppstg] - DocFile return
//
// Returns: Appropriate status code
//
// Modifies: [ppstg]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::OpenStorage(WCHAR const *pwcsName, IStorage *pstgPriority, DWORD grfMode, SNBW snbExclude, DWORD reserved, IStorage **ppstg) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::CopyTo, public
//
// Synopsis: Makes a copy of a DocFile
//
// Arguments: [ciidExclude] - Length of rgiid array
// [rgiidExclude] - Array of IIDs to exclude
// [snbExclude] - Names to exclude
// [pstgDest] - Parent of copy
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::CopyTo(DWORD ciidExclude, IID const *rgiidExclude, SNBW snbExclude, IStorage *pstgDest) { return STG_E_INVALIDFUNCTION; }
//+---------------------------------------------------------------------------
//
// Member: CSimpStorage::BuildTree, private
//
// Synopsis: Construct the btree given the sorted array of entries.
//
// Arguments: [ade] -- Array of CDirEntry to operate on. These are
// already sorted.
// [sidStart] -- SID of first entry on this segment
// [cStreams] -- Length of segment to process
//
// Returns: SID of root of tree
//
// History: 09-Aug-94 PhilipLa Created
//
// Notes: This is a recursive function. Yes, I know...
//
//----------------------------------------------------------------------------
SID CSimpStorage::BuildTree(CDirEntry *ade, SID sidStart, ULONG cStreams) { simpDebugOut((DEB_ITRACE, "In CSimpStorage::BuildTree:%p()\n", this));
if (cStreams > 3) { SID sidSplit;
sidSplit = sidStart + (cStreams / 2);
simpAssert(cStreams == 1 + (sidSplit - sidStart) + (cStreams + sidStart - 1) - sidSplit);
ade[sidSplit].SetLeftSib(BuildTree(ade, sidStart, sidSplit - sidStart)); ade[sidSplit].SetRightSib(BuildTree(ade, sidSplit + 1, (cStreams + sidStart - 1) - sidSplit));
return sidSplit; } //Base cases:
// cStreams == 1 -- return sidStart
// cStreams == 2 -- Left child of sidStart + 1 == sidStart, return
// sidStart + 1
// cStreams == 3 -- Root is sidStart + 1, with children sidStart and
// sidStart + 2
if (cStreams == 1) { return sidStart; }
if (cStreams == 3) ade[sidStart + 1].SetRightSib(sidStart + 2);
ade[sidStart + 1].SetLeftSib(sidStart); return sidStart + 1;
simpDebugOut((DEB_ITRACE, "Out CSimpStorage::BuildTree\n")); }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::Commit, public
//
// Synopsis: Commits transacted changes
//
// Arguments: [dwFlags] - DFC_*
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::Commit(DWORD dwFlags) { CDfName const dfnRoot(L"Root Entry"); SCODE sc; olLog(("%p::In CSimpStorage::Commit(%lX)\n",this, dwFlags));
SIMP_VALIDATE(Commit(dwFlags)); // Simple mode commit does not allow open stream elements
// While we could possibly revert the stream instead of returning an error,
// it would not have the same semantics as normal mode transactions
if (_pdflCurrent != NULL) return STG_E_INVALIDFUNCTION;
if (!_fDirty) return S_OK;
//Allocate a buffer big enough for all the control structures.
const USHORT cdePerSect = SECTORSIZE / sizeof(CDirEntry); const USHORT cSectPerFat = SECTORSIZE / sizeof(SECT);
ULONG cDifSect = 0; ULONG cFatSect = 0; ULONG cFatSectOld = (ULONG)-1; ULONG cDifSectOld = (ULONG)-1; ULONG cDirSect; ULONG cSect; ULONG cbSize;
cDirSect = (_cStreams + 1 + cdePerSect - 1) / cdePerSect; cSect = _sectMax + cDirSect;
//At this point, csect is the number of sectors needed to hold
// everything but the fat itself (and the DIFat, if necessary).
while ((cFatSect != cFatSectOld) || (cDifSect != cDifSectOld)) { //Now, compute the number of fat sectors needed to hold everything.
cFatSectOld = cFatSect; cFatSect = (cSect + cFatSect + cDifSect + cSectPerFat - 1) / cSectPerFat;
cDifSectOld = cDifSect; if (cFatSect >= CSECTFAT) { cDifSect = (cFatSect - CSECTFAT + cSectPerFat - 2) / (cSectPerFat - 1); } }
//At this point, we know how big the buffer needs to be. Allocate
// it.
_pbBuf = new BYTE[(cFatSect + cDirSect + cDifSect) * SECTORSIZE];
if (_pbBuf == NULL) { return STG_E_INSUFFICIENTMEMORY; }
//The fat is placed in the buffer first, followed by the directory.
SECT sect; SECT *asectFat; SECT *asectDif; CDirEntry *adeDir;
SECT sectDifStart = _sectMax; SECT sectFatStart = _sectMax + cDifSect; SECT sectDirStart = _sectMax + cDifSect + cFatSect;
asectDif = (SECT *)_pbBuf; asectFat = (SECT *)(_pbBuf + (cDifSect * SECTORSIZE)); adeDir = (CDirEntry *)(_pbBuf + ((cFatSect + cDifSect) * SECTORSIZE)); //asectFat and adeDir can be used as arrays.
//Need to get the buffer to a correct 'empty' state.
// 1) Initialize fat and difat to all 0xff.
memset(asectDif, 0xff, cDifSect * SECTORSIZE); memset(asectFat, 0xff, cFatSect * SECTORSIZE);
// 2) Initialize dir to all empty state
for (USHORT i = 0; i < cDirSect * cdePerSect; i++) { adeDir[i].Init(STGTY_INVALID); simpAssert((BYTE *)&adeDir[i] < _pbBuf + ((cFatSect + cDifSect + cDirSect) * SECTORSIZE)); }
if (cDifSect > 0) { //Put dif into fat.
for (sect = sectDifStart; sect < sectFatStart; sect++) { asectFat[sect] = DIFSECT; simpAssert((BYTE *)&asectFat[sect] < (BYTE *)adeDir);
ULONG ulOffset = sect - sectDifStart;
asectDif[ulOffset * cSectPerFat + (cSectPerFat - 1)] = sect + 1; } asectDif[((cDifSect - 1) * cSectPerFat) + (cSectPerFat - 1)] = ENDOFCHAIN; _hdr.SetDifStart(sectDifStart); _hdr.SetDifLength(cDifSect); }
for (sect = sectFatStart; sect < sectDirStart; sect++) { asectFat[sect] = FATSECT; simpAssert((BYTE *)&asectFat[sect] < (BYTE *)adeDir);
ULONG ulOffset = sect - sectFatStart;
if (ulOffset < CSECTFAT) { _hdr.SetFatSect(ulOffset, sect); } else { ulOffset -= CSECTFAT; asectDif[(ulOffset / (cSectPerFat - 1)) * cSectPerFat + (ulOffset % (cSectPerFat - 1))] = sect; } }
for (sect = sectDirStart; sect < sectDirStart + cDirSect; sect++) { asectFat[sect] = sect + 1; simpAssert((BYTE *)&asectFat[sect] < (BYTE *)adeDir); } asectFat[sectDirStart + cDirSect - 1] = ENDOFCHAIN; simpAssert((BYTE *)&asectFat[sectDirStart + cDirSect - 1] < (BYTE *)adeDir);
_hdr.SetDirStart(sectDirStart); _hdr.SetFatLength(cFatSect);
//Fat, directory, and header are set up. Woowoo.
//Walk name list and construct directory and fat structures for
// user streams.
//Write them out, then write out header.
CDfNameList *pdfl; SID sid; pdfl = _pdfl; sid = 1;
while (pdfl != NULL) { //Set up fat chain.
SECT sectStart = pdfl->GetStart(); cSect = (pdfl->GetSize() + SECTORSIZE - 1) / SECTORSIZE;
for (sect = sectStart; sect < sectStart + cSect; sect++) { asectFat[sect] = sect + 1; simpAssert((BYTE *)&asectFat[sect] < (BYTE *)adeDir); } asectFat[sectStart + cSect - 1] = ENDOFCHAIN; simpAssert((BYTE *)&asectFat[sectStart + cSect - 1] < (BYTE *)adeDir);
adeDir[sid].SetFlags(STGTY_STREAM); adeDir[sid].SetName(pdfl->GetName()); adeDir[sid].SetStart(pdfl->GetStart()); adeDir[sid].SetSize(pdfl->GetSize()); adeDir[sid].SetColor(DE_BLACK); simpAssert((BYTE *)&adeDir[sid] < _pbBuf + ((cFatSect + cDifSect + cDirSect) * SECTORSIZE)); pdfl = pdfl->GetNext(); sid++; }
//Set up root entry.
adeDir[0].Init(STGTY_ROOT); adeDir[0].SetName(&dfnRoot); adeDir[0].SetClassId(_clsid); adeDir[0].SetColor(DE_BLACK);
//This recursively builds the btree and sets the root in the child
// of the root entry.
adeDir[0].SetChild(BuildTree(adeDir, 1, _cStreams));
//Write out buffer
ULONG cbWritten; DWORD dwErr;
dwErr = SetFilePointer(_hFile, ConvertSect(_sectMax), NULL, FILE_BEGIN); if (dwErr == INVALID_SET_FILE_POINTER) { sc = STG_SCODE(GetLastError()); delete _pbBuf; _pbBuf = NULL; return sc; } BOOL f= WriteFile(_hFile, _pbBuf, (cFatSect + cDifSect + cDirSect) * SECTORSIZE, &cbWritten, NULL); if (!f) { sc = STG_SCODE(GetLastError()); delete _pbBuf; _pbBuf = NULL; return sc; }
//Write out header
dwErr= SetFilePointer(_hFile, 0, NULL, FILE_BEGIN); if (dwErr == INVALID_SET_FILE_POINTER) { sc = STG_SCODE(GetLastError()); delete _pbBuf; _pbBuf = NULL; return sc; }
f= WriteFile(_hFile, _hdr.GetData(), sizeof(CMSFHeaderData), &cbWritten, NULL); if (!f) { sc = STG_SCODE(GetLastError()); delete _pbBuf; _pbBuf = NULL; return sc; }
if (!(dwFlags & STGC_DANGEROUSLYCOMMITMERELYTODISKCACHE)) { f = FlushFileBuffers(_hFile); if (!f) { sc = STG_SCODE(GetLastError()); delete _pbBuf; _pbBuf = NULL; return sc; } }
delete _pbBuf; _pbBuf = NULL;
_fDirty = FALSE;
olLog(("%p::Out CSimpStorage::Commit(). ret == %lx\n",this, S_OK)); return S_OK; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::Revert, public
//
// Synopsis: Reverts transacted changes
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::Revert(void) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::EnumElements, public
//
// Synopsis: Starts an iterator
//
// Arguments: [reserved1]
// [reserved2]
// [reserved3]
// [ppenm] - Enumerator return
//
// Returns: Appropriate status code
//
// Modifies: [ppenm]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::EnumElements(DWORD reserved1, void *reserved2, DWORD reserved3, IEnumSTATSTG **ppenm) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::DestroyElement, public
//
// Synopsis: Permanently deletes an element of a DocFile
//
// Arguments: [pwcsName] - Name of element
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::DestroyElement(WCHAR const *pwcsName) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::MoveElementTo, public
//
// Synopsis: Move an element of a DocFile to an IStorage
//
// Arguments: [pwcsName] - Current name
// [ptcsNewName] - New name
//
// Returns: Appropriate status code
//
// Algorithm: Open source as storage or stream (whatever works)
// Create appropriate destination
// Copy source to destination
// Set create time of destination equal to create time of source
// If appropriate, delete source
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::MoveElementTo(WCHAR const *pwcsName, IStorage *pstgParent, OLECHAR const *ptcsNewName, DWORD grfFlags) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::RenameElement, public
//
// Synopsis: Renames an element of a DocFile
//
// Arguments: [pwcsName] - Current name
// [pwcsNewName] - New name
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::RenameElement(WCHAR const *pwcsName, WCHAR const *pwcsNewName) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::SetElementTimes, public
//
// Synopsis: Sets element time stamps
//
// Arguments: [pwcsName] - Name
// [pctime] - create time
// [patime] - access time
// [pmtime] - modify time
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::SetElementTimes(WCHAR const *pwcsName, FILETIME const *pctime, FILETIME const *patime, FILETIME const *pmtime) { SCODE sc; olLog(("%p::In CSimpStorage::SetElementTimes(%ws, %p, %p, %p)\n", this, pwcsName, pctime, patime, pmtime));
SIMP_VALIDATE(SetElementTimes(pwcsName, pctime, patime, pmtime)); if (pwcsName != NULL) return STG_E_INVALIDFUNCTION;
if (!SetFileTime(_hFile, pctime, patime, pmtime)) { return STG_SCODE(GetLastError()); } olLog(("%p::Out CSimpStorage::SetElementTimes(). ret == %lx\n", this, S_OK)); return S_OK; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::SetClass, public
//
// Synopsis: Sets storage class
//
// Arguments: [clsid] - class id
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::SetClass(REFCLSID rclsid) { olLog(("%p::In CSimpStorage::SetClass(?)\n", this)); SCODE sc; SIMP_VALIDATE(SetClass(rclsid)); _clsid = rclsid; _fDirty = TRUE; olLog(("%p::Out CSimpStorage::SetClass(). ret == %lx\n", this, S_OK)); return S_OK; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::SetStateBits, public
//
// Synopsis: Sets state bits
//
// Arguments: [grfStateBits] - state bits
// [grfMask] - state bits mask
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::SetStateBits(DWORD grfStateBits, DWORD grfMask) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::Stat, public
//
// Synopsis: Fills in a buffer of information about this object
//
// Arguments: [pstatstg] - Buffer
//
// Returns: Appropriate status code
//
// Modifies: [pstatstg]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
_OLESTDMETHODIMP CSimpStorage::Stat(STATSTGW *pstatstg, DWORD grfStatFlag) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::AddRef, public
//
// Synopsis: Increments the ref count
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP_(ULONG) CSimpStorage::AddRef(void) { ULONG ulRet;
olLog(("%p::In CSimpStorage::AddRef()\n", this)); simpDebugOut((DEB_TRACE, "In CSimpStorage::AddRef()\n"));
AtomicInc(&_cReferences); ulRet = _cReferences;
simpDebugOut((DEB_TRACE, "Out CSimpStorage::AddRef\n")); olLog(("%p::Out CSimpStorage::AddRef(). ret == %lu\n", this, ulRet)); return ulRet; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::QueryInterface, public
//
// Synopsis: Returns an object for the requested interface
//
// Arguments: [iid] - Interface ID
// [ppvObj] - Object return
//
// Returns: Appropriate status code
//
// Modifies: [ppvObj]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::QueryInterface(REFIID iid, void **ppvObj) { SCODE sc;
olLog(("%p::In CSimpStorage::QueryInterface(?, %p)\n", this, ppvObj)); simpDebugOut((DEB_TRACE, "In CSimpStorage::QueryInterface(?, %p)\n", ppvObj));
SIMP_VALIDATE(QueryInterface(iid, ppvObj));
sc = S_OK; if (IsEqualIID(iid, IID_IStorage) || IsEqualIID(iid, IID_IUnknown)) { *ppvObj = (IStorage *)this; CSimpStorage::AddRef(); } else if (IsEqualIID(iid, IID_IMarshal)) { *ppvObj = (IMarshal *)this; CSimpStorage::AddRef(); } else if (IsEqualIID(iid, IID_IPropertySetStorage)) { *ppvObj = (IPropertySetStorage *)this; CSimpStorage::AddRef(); } else sc = E_NOINTERFACE;
olLog(("%p::Out CSimpStorage::QueryInterface(). " "*ppvObj == %p ret == %lx\n", this, *ppvObj, sc)); simpDebugOut((DEB_TRACE, "Out CSimpStorage::QueryInterface => %p\n", ppvObj)); return ResultFromScode(sc); }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::GetUnmarshalClass, public
//
// Synopsis: Returns the class ID
//
// Arguments: [riid] - IID of object
// [pv] - Unreferenced
// [dwDestContext] - Unreferenced
// [pvDestContext] - Unreferenced
// [mshlflags] - Unreferenced
// [pcid] - CLSID return
//
// Returns: Invalid function.
//
// Modifies: [pcid]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::GetUnmarshalClass(REFIID riid, void *pv, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPCLSID pcid) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::GetMarshalSizeMax, public
//
// Synopsis: Returns the size needed for the marshal buffer
//
// Arguments: [riid] - IID of object being marshaled
// [pv] - Unreferenced
// [dwDestContext] - Unreferenced
// [pvDestContext] - Unreferenced
// [mshlflags] - Unreferenced
// [pcbSize] - Size return
//
// Returns: Appropriate status code
//
// Modifies: [pcbSize]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::GetMarshalSizeMax(REFIID riid, void *pv, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags, LPDWORD pcbSize) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::MarshalInterface, public
//
// Synopsis: Marshals a given object
//
// Arguments: [pstStm] - Stream to write marshal data into
// [riid] - Interface to marshal
// [pv] - Unreferenced
// [dwDestContext] - Unreferenced
// [pvDestContext] - Unreferenced
// [mshlflags] - Unreferenced
//
// Returns: Appropriate status code
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::MarshalInterface(IStream *pstStm, REFIID riid, void *pv, DWORD dwDestContext, LPVOID pvDestContext, DWORD mshlflags) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::UnmarshalInterface, public
//
// Synopsis: Non-functional
//
// Arguments: [pstStm] -
// [riid] -
// [ppvObj] -
//
// Returns: Appropriate status code
//
// Modifies: [ppvObj]
//
// History: 04-Aug-94 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::UnmarshalInterface(IStream *pstStm, REFIID riid, void **ppvObj) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::ReleaseMarshalData, public
//
// Synopsis: Non-functional
//
// Arguments: [pstStm] -
//
// Returns: Appropriate status code
//
// History: 18-Sep-92 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::ReleaseMarshalData(IStream *pstStm) { return STG_E_INVALIDFUNCTION; }
//+--------------------------------------------------------------
//
// Member: CSimpStorage::DisconnectObject, public
//
// Synopsis: Non-functional
//
// Arguments: [dwRevserved] -
//
// Returns: Appropriate status code
//
// History: 18-Sep-92 PhilipLa Created
//
//---------------------------------------------------------------
STDMETHODIMP CSimpStorage::DisconnectObject(DWORD dwReserved) { return STG_E_INVALIDFUNCTION; }
|