701 lines
20 KiB
C++
701 lines
20 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: simpstg2.cxx
|
|
//
|
|
// Contents: SimpStorageOpen class implementation
|
|
//
|
|
// Classes: CSimpStorageOpen, CSafeBYTEArray
|
|
//
|
|
// Functions:
|
|
//
|
|
// Notes: No error labels, tried to use destructors for cleanup
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "simphead.cxx"
|
|
#pragma hdrstop
|
|
|
|
#include <expparam.hxx>
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Class: CSafeBYTEArray
|
|
//
|
|
// Purpose: automatically allocate & destroy an array of BYTEs
|
|
//
|
|
// Interface:
|
|
//
|
|
// History: 04-Jun-96 HenryLee Created
|
|
//
|
|
// Notes: destructor automatically cleans up
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
class CSafeBYTEArray
|
|
{
|
|
public:
|
|
inline CSafeBYTEArray (ULONG cBYTE) {_p = new BYTE[cBYTE]; };
|
|
inline ~CSafeBYTEArray () { delete [] _p; };
|
|
inline operator BYTE* () { return _p; };
|
|
private:
|
|
BYTE *_p; // allowed to be NULL
|
|
};
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::Init, public
|
|
//
|
|
// Synopsis: Init function
|
|
//
|
|
// Arguments: [psdh] -- Pointer to hints structure
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
// 14-Oct-97 HenryLee recoginize CNSS file format
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
SCODE CSimpStorageOpen::Init(WCHAR const * pwcsName, DWORD grfMode,
|
|
SSimpDocfileHints *psdh)
|
|
{
|
|
SCODE sc = S_OK;
|
|
simpDebugOut((DEB_ITRACE,
|
|
"In CSimpStorageOpen::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
|
|
|
|
DWORD dwMode;
|
|
switch (grfMode & (STGM_READ | STGM_WRITE | STGM_READWRITE))
|
|
{
|
|
case STGM_READWRITE : dwMode = GENERIC_READ | GENERIC_WRITE; break;
|
|
case STGM_READ : dwMode = GENERIC_READ; break;
|
|
case STGM_WRITE : dwMode = GENERIC_WRITE; break;
|
|
}
|
|
|
|
_hFile = CreateFileT(atcPath, dwMode, 0,
|
|
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
|
|
if (_hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
return Win32ErrorToScode(GetLastError());
|
|
}
|
|
|
|
_grfMode = grfMode;
|
|
_sectMax = 0;
|
|
_fDirty = FALSE;
|
|
_clsid = IID_NULL;
|
|
_grfStateBits = 0;
|
|
lstrcpyW (_awcsName, pwcsName);
|
|
|
|
ULONG cbRead;
|
|
BOOL f= ReadFile(_hFile, _hdr.GetData(), HEADERSIZE, &cbRead, NULL);
|
|
if (!f)
|
|
{
|
|
return Win32ErrorToScode(GetLastError());
|
|
}
|
|
|
|
if (cbRead != HEADERSIZE)
|
|
{
|
|
return STG_E_READFAULT;
|
|
}
|
|
|
|
if (!SUCCEEDED(sc = ValidateHeader(_hdr)))
|
|
{
|
|
return sc;
|
|
}
|
|
|
|
ULONG ulEndOfFile = GetFileSize(_hFile, NULL);
|
|
if (ulEndOfFile == 0xFFFFFFFF && GetLastError() != NO_ERROR)
|
|
return Win32ErrorToScode(GetLastError());
|
|
|
|
const BOOL fCNSS = _hdr.GetDirStart() == 0;
|
|
const ULONG ulFatStart=_hdr.GetFatStart()*SECTORSIZE + HEADERSIZE;
|
|
const ULONG ulDifStart=_hdr.GetDifStart()*SECTORSIZE + HEADERSIZE;
|
|
const ULONG ulFatLength = _hdr.GetFatLength()*SECTORSIZE;
|
|
const ULONG ulDifLength = _hdr.GetDifLength()*SECTORSIZE;
|
|
const ULONG ulDirLength = fCNSS ?
|
|
(ulDifLength != 0 ? ulDifStart-HEADERSIZE :
|
|
ulFatStart-HEADERSIZE)
|
|
: ulEndOfFile - ulFatStart - ulFatLength;
|
|
const ULONG cBytes = ulDirLength + ulFatLength + ulDifLength;
|
|
|
|
if (ulFatLength == 0 || ulDirLength == 0)
|
|
return STG_E_DOCFILECORRUPT;
|
|
|
|
DWORD dwErr;
|
|
CSafeBYTEArray pByte (cBytes);
|
|
|
|
if (pByte == NULL)
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
|
|
if ((dwErr = SetFilePointer (_hFile, fCNSS ? HEADERSIZE :
|
|
(ulDifLength == 0 ? ulFatStart : ulDifStart),
|
|
NULL, FILE_BEGIN)) == 0xFFFFFFFF)
|
|
{
|
|
return Win32ErrorToScode(GetLastError());
|
|
}
|
|
|
|
// Read the FAT, DIFAT, and Directory into one big buffer
|
|
//
|
|
if (!(f=ReadFile(_hFile, pByte, cBytes, &cbRead, NULL)))
|
|
{
|
|
return Win32ErrorToScode(GetLastError());
|
|
}
|
|
if (cbRead != cBytes)
|
|
{
|
|
return STG_E_READFAULT;
|
|
}
|
|
|
|
if (!SUCCEEDED(sc = ValidateDirectory(
|
|
fCNSS ? pByte+0 : pByte+ulDifLength+ulFatLength, ulDirLength)))
|
|
{
|
|
return sc;
|
|
}
|
|
|
|
if (!SUCCEEDED(sc = ValidateFat ((SECT*)
|
|
(fCNSS ? pByte+ulDirLength+ulDifLength : pByte+ulDifLength),
|
|
ulFatLength)))
|
|
{
|
|
return sc;
|
|
}
|
|
|
|
if (ulDifLength != 0 && !SUCCEEDED(sc = ValidateDIFat ((SECT *)
|
|
(fCNSS ? pByte+ulDirLength : pByte+0),
|
|
ulDifLength, _hdr.GetFatSect(CSECTFAT-1))))
|
|
{
|
|
return sc;
|
|
}
|
|
|
|
simpDebugOut((DEB_ITRACE, "Out CSimpStorage::Init\n"));
|
|
return sc;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::ValidateHeader, public
|
|
//
|
|
// Synopsis: verifies header is in simple mode format
|
|
//
|
|
// Arguments: [hdr] -- reference to a docfile header
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
// 14-Oct-97 HenryLee recoginize CNSS file format
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
SCODE CSimpStorageOpen::ValidateHeader (CMSFHeader &hdr)
|
|
{
|
|
SCODE sc = S_OK;
|
|
|
|
if (!SUCCEEDED(sc = hdr.Validate()))
|
|
{
|
|
return sc;
|
|
}
|
|
|
|
const SECT sectDifStart = hdr.GetDifStart();
|
|
const SECT sectFatStart = hdr.GetFatStart();
|
|
const SECT sectDirStart = hdr.GetDirStart();
|
|
|
|
// in simple mode, DifStart < FatStart < DirStart
|
|
//
|
|
if(hdr.GetMiniFatStart() != ENDOFCHAIN || hdr.GetMiniFatLength() != 0 ||
|
|
(sectDifStart != ENDOFCHAIN && sectDifStart >= sectFatStart))
|
|
{
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
|
|
// in simple mode, DifStart+DifLength = FatStart
|
|
// FatStart+FatLength = DirStart
|
|
//
|
|
// in CNSS mode, DirStart+DirLength = DifStart
|
|
// DifStart+DifLength = FatStart
|
|
// DirStart = 0
|
|
//
|
|
if (sectDifStart != ENDOFCHAIN &&
|
|
(sectDifStart + hdr.GetDifLength() != sectFatStart))
|
|
{
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
|
|
if (sectDirStart != 0 &&
|
|
(sectFatStart + hdr.GetFatLength() != sectDirStart))
|
|
{
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
|
|
// make sure the FAT is contiguous within the header
|
|
//
|
|
for (INT i=1; i < CSECTFAT; i++)
|
|
{
|
|
if (hdr.GetFatSect(i) == FREESECT)
|
|
break;
|
|
|
|
if (hdr.GetFatSect(i-1)+1 != hdr.GetFatSect(i))
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::ValidateDirectory, public
|
|
//
|
|
// Synopsis: verifies stream entries are correct
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
// 14-Oct-97 HenryLee recoginize CNSS file format
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
SCODE CSimpStorageOpen::ValidateDirectory (BYTE *pByte, ULONG ulDirLength)
|
|
{
|
|
SCODE sc = S_OK;
|
|
CDfNameList *pdflRoot = _pdfl;
|
|
SECT sectStartLowest = ENDOFCHAIN;
|
|
ULONG ulSize = 0;
|
|
ULONG cbStorages = 0;
|
|
CDirEntry *pde = (CDirEntry *) pByte;
|
|
|
|
// Read the directory entries until the end of buffer
|
|
CDfNameList *pdflPrev = NULL;
|
|
for (ULONG i=0; i < ulDirLength/sizeof(CDirEntry); i++)
|
|
{
|
|
if (!pde[i].IsFree())
|
|
{
|
|
if (pde[i].GetFlags() != STGTY_ROOT &&
|
|
pde[i].GetFlags() != STGTY_STREAM &&
|
|
pde[i].GetFlags() != STGTY_STORAGE)
|
|
return STG_E_OLDFORMAT;
|
|
|
|
if (STORAGELIKE(pde[i].GetFlags()))
|
|
{
|
|
cbStorages++; // first entry must be a storage
|
|
if (pdflPrev != NULL || cbStorages > 1)
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
|
|
if (pde[i].GetRightSib() == (SID) i ||
|
|
pde[i].GetLeftSib() == (SID) i)
|
|
return STG_E_DOCFILECORRUPT;
|
|
|
|
CDfNameList *pdfl = new CDfNameList;
|
|
if (pdfl != NULL)
|
|
{
|
|
pdfl->SetDfName(pde[i].GetName());
|
|
pdfl->SetStart(pde[i].GetStart());
|
|
|
|
if (sectStartLowest > pdfl->GetStart())
|
|
sectStartLowest = pdfl->GetStart();
|
|
|
|
#ifdef LARGE_STREAMS
|
|
pdfl->SetSize((ULONG)pde[i].GetSize(FALSE));
|
|
#else
|
|
pdfl->SetSize((ULONG)pde[i].GetSize());
|
|
#endif
|
|
pdfl->Insert (&_pdfl, pdflPrev, NULL); //insert at end
|
|
pdflPrev = pdfl;
|
|
}
|
|
else return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
}
|
|
|
|
pdflRoot = _pdfl;
|
|
if (pdflRoot == 0 || pdflRoot->GetStart() != ENDOFCHAIN ||
|
|
pdflRoot->GetSize() != 0)
|
|
{
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
else pdflRoot = pdflRoot->GetNext();
|
|
|
|
// make sure streams are one after another
|
|
//
|
|
for (CDfNameList *pdfl = pdflRoot; pdfl != NULL; pdfl = pdfl->GetNext())
|
|
{
|
|
// start should be after another stream's end
|
|
// In the CNSS case, the pdflRoot points to 1st stream in file
|
|
// In the docfile case, entry with 0 start sector is 1st stream in file
|
|
if (pdfl->GetStart() != sectStartLowest) // skip 1st stream
|
|
{
|
|
CDfNameList *pdfl2 = NULL;
|
|
for (pdfl2 = pdflRoot; pdfl2 != NULL; pdfl2=pdfl2->GetNext())
|
|
{
|
|
if (pdfl->GetStart() == (pdfl2->GetStart() + (
|
|
pdfl2->GetSize()+SECTORSIZE-1)/SECTORSIZE))
|
|
break;
|
|
}
|
|
if (pdfl2 == NULL) // did not find a match
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::ValidateFat, public
|
|
//
|
|
// Synopsis: verifies that stream sectors are contiguous
|
|
//
|
|
// Arguments: [pSect] array of Fat sectors
|
|
// [ulFatLength] length of the Fat
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
SCODE CSimpStorageOpen::ValidateFat (SECT *pSect, ULONG ulFatLength)
|
|
{
|
|
SCODE sc = S_OK;
|
|
|
|
simpAssert (_pdfl != NULL && pSect != NULL);
|
|
|
|
for (CDfNameList *pdfl = _pdfl->GetNext(); pdfl; pdfl = pdfl->GetNext())
|
|
{
|
|
SECT sectStart = pdfl->GetStart();
|
|
ULONG ulSize = pdfl->GetSize();
|
|
|
|
SECT *psect = &pSect[sectStart];
|
|
SECT sectCount = sectStart+1;
|
|
|
|
for (ULONG i = sectStart;
|
|
i < sectStart + (ulSize+SECTORSIZE-1)/SECTORSIZE; i++)
|
|
{
|
|
if (*psect != sectCount && *psect != ENDOFCHAIN)
|
|
return STG_E_OLDFORMAT;
|
|
psect++; // check for sector numbers
|
|
sectCount++; // increasing in order by 1
|
|
}
|
|
|
|
if ((ULONG)(psect - pSect) > ulFatLength / sizeof(SECT))
|
|
{
|
|
return STG_E_OLDFORMAT;
|
|
}
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::ValidateDIFat, public
|
|
//
|
|
// Synopsis: verifies that FAT sectors are contiguous
|
|
//
|
|
// Arguments: [pSect] array of DIFat sectors
|
|
// [ulDIFatLength] length of the DIFat
|
|
// [sectStart] last Fat sector in header
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
SCODE CSimpStorageOpen::ValidateDIFat (SECT *pSect, ULONG ulDIFatLength,
|
|
SECT sectStart)
|
|
{
|
|
SCODE sc = S_OK;
|
|
simpAssert (pSect != NULL);
|
|
simpAssert (sectStart != ENDOFCHAIN);
|
|
|
|
SECT *psect = pSect;
|
|
SECT sectCount = sectStart + 1;
|
|
SECT iLastSect = SECTORSIZE / sizeof(SECT);
|
|
|
|
for (ULONG i = 0; i < ulDIFatLength/sizeof(SECT); i++)
|
|
{
|
|
// skip last sector entry
|
|
if (*psect != FREESECT && ((i+1) % iLastSect) != 0)
|
|
{
|
|
if (*psect != sectCount)
|
|
return STG_E_OLDFORMAT;
|
|
|
|
sectCount++; // check for sector numbers increasing by 1
|
|
}
|
|
psect++;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
//+--------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::Release, public
|
|
//
|
|
// Synopsis: Releases resources for a CSimpStorageOpen
|
|
// override CSimpStorage::Release because of delete this
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDMETHODIMP_(ULONG) CSimpStorageOpen::Release(void)
|
|
{
|
|
simpDebugOut((DEB_TRACE, "In CSimpStorageOpen::Release()\n"));
|
|
simpAssert(_cReferences > 0);
|
|
|
|
LONG lRet = AtomicDec(&_cReferences);
|
|
if (lRet == 0)
|
|
{
|
|
if (_fDirty)
|
|
Commit(STGC_DEFAULT);
|
|
CloseHandle(_hFile); // streams are not reverted
|
|
delete this;
|
|
}
|
|
|
|
simpDebugOut((DEB_TRACE, "Out CSimpStorageOpen::Release()\n"));
|
|
return (ULONG) lRet;
|
|
}
|
|
|
|
//+--------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::Stat, public
|
|
//
|
|
// Synopsis: Fills in a buffer of information about this object
|
|
//
|
|
// Arguments: [pstatstg] - Buffer
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// Modifies: [pstatstg]
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDMETHODIMP CSimpStorageOpen::Stat(STATSTGW *pstatstg, DWORD grfStatFlag)
|
|
{
|
|
SCODE sc = S_OK;
|
|
|
|
simpDebugOut((DEB_TRACE, "In CSimpStorageOpen::Stat(%p)\n", pstatstg));
|
|
|
|
SIMP_VALIDATE(Stat(pstatstg, grfStatFlag));
|
|
|
|
if (GetFileTime(_hFile, &pstatstg->ctime, &pstatstg->atime,
|
|
&pstatstg->mtime) == FALSE)
|
|
{
|
|
return Win32ErrorToScode(GetLastError());
|
|
}
|
|
|
|
if ((grfStatFlag & STATFLAG_NONAME) == 0)
|
|
{
|
|
if ((pstatstg->pwcsName = (WCHAR*) CoTaskMemAlloc(
|
|
(lstrlenW(_awcsName)+1)*sizeof(WCHAR))) == 0)
|
|
{
|
|
return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
lstrcpyW (pstatstg->pwcsName, _awcsName);
|
|
}
|
|
|
|
pstatstg->grfMode = _grfMode;
|
|
pstatstg->clsid = _clsid;
|
|
pstatstg->grfStateBits = _grfStateBits;
|
|
|
|
pstatstg->type = STGTY_STORAGE;
|
|
ULISet32(pstatstg->cbSize, 0);
|
|
pstatstg->grfLocksSupported = 0;
|
|
pstatstg->STATSTG_dwStgFmt = 0;
|
|
|
|
simpDebugOut((DEB_TRACE, "Out CSimpStorageOpen::Stat\n"));
|
|
return sc;
|
|
}
|
|
|
|
//+--------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::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-May-96 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDMETHODIMP CSimpStorageOpen::OpenStream(WCHAR const *pwcsName,
|
|
void *reserved1,
|
|
DWORD grfMode,
|
|
DWORD reserved2,
|
|
IStream **ppstm)
|
|
{
|
|
SCODE sc = S_OK;
|
|
simpAssert (_pdfl != NULL);
|
|
CDfNameList *pdflLoop = _pdfl->GetNext();
|
|
CDfName dfn;
|
|
|
|
simpDebugOut((DEB_TRACE, "In CSimpStorageOpen:OpenStream("
|
|
"%ws, %p, %lX, %lu, %p)\n", pwcsName, reserved1,
|
|
grfMode, reserved2, ppstm));
|
|
|
|
SIMP_VALIDATE(OpenStream(pwcsName,
|
|
reserved1,
|
|
grfMode,
|
|
reserved2,
|
|
ppstm));
|
|
|
|
if (_pdflCurrent != NULL)
|
|
return STG_E_INVALIDFUNCTION;
|
|
|
|
if (grfMode != (STGM_READWRITE | STGM_SHARE_EXCLUSIVE) &&
|
|
grfMode != (STGM_READ | STGM_SHARE_EXCLUSIVE))
|
|
return STG_E_INVALIDFLAG;
|
|
|
|
if (_grfMode == (STGM_READ | STGM_SHARE_EXCLUSIVE) &&
|
|
grfMode == (STGM_READWRITE | STGM_SHARE_EXCLUSIVE))
|
|
return STG_E_ACCESSDENIED;
|
|
|
|
dfn.Set(pwcsName);
|
|
while (pdflLoop != NULL)
|
|
{
|
|
INT iCmp = CDirectory::NameCompare(&dfn, pdflLoop->GetName());
|
|
if (iCmp == 0)
|
|
{
|
|
//Found a stream with this name
|
|
CSimpStreamOpen *pstm = new CSimpStreamOpen ();
|
|
if (pstm != NULL)
|
|
{
|
|
_pdflCurrent = pdflLoop;
|
|
if (!SUCCEEDED(sc = pstm->Init (this, _hFile,
|
|
(_pdflCurrent->GetStart()+1)*SECTORSIZE,
|
|
grfMode, _pdflCurrent)))
|
|
{
|
|
delete pstm;
|
|
pstm = NULL;
|
|
_pdflCurrent = NULL;
|
|
}
|
|
*ppstm = pstm;
|
|
break;
|
|
}
|
|
else return STG_E_INSUFFICIENTMEMORY;
|
|
}
|
|
pdflLoop = pdflLoop->GetNext();
|
|
}
|
|
|
|
if (pdflLoop == NULL)
|
|
{
|
|
sc = STG_E_FILENOTFOUND;
|
|
}
|
|
|
|
simpDebugOut((DEB_TRACE, "Out CSimpStorageOpen::OpenStream => %p\n",
|
|
*ppstm));
|
|
return sc;
|
|
}
|
|
|
|
//+--------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::CreateStream, public
|
|
//
|
|
// Synopsis: stub
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDMETHODIMP CSimpStorageOpen::CreateStream(WCHAR const *pwcsName,
|
|
DWORD grfMode,
|
|
DWORD reserved1,
|
|
DWORD reserved2,
|
|
IStream **ppstm)
|
|
{
|
|
simpDebugOut((DEB_TRACE, "Stb CSimpStorageOpen::CreateStream\n"));
|
|
return STG_E_INVALIDFUNCTION;
|
|
}
|
|
|
|
//+--------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::EnumElements, public
|
|
//
|
|
// Synopsis: Starts an iterator
|
|
//
|
|
// Arguments: [reserved1]
|
|
// [reserved2]
|
|
// [reserved3]
|
|
// [ppenm] - Enumerator return
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// Modifies: [ppenm]
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDMETHODIMP CSimpStorageOpen::EnumElements(DWORD reserved1,
|
|
void *reserved2,
|
|
DWORD reserved3,
|
|
IEnumSTATSTG **ppenm)
|
|
{
|
|
simpDebugOut((DEB_TRACE, "In CSimpStorageOpen::EnumElements\n"));
|
|
SCODE sc = S_OK;
|
|
|
|
SIMP_VALIDATE(EnumElements(reserved1,
|
|
reserved2,
|
|
reserved3,
|
|
ppenm));
|
|
|
|
if ((*ppenm = new CSimpEnumSTATSTG (_pdfl, _pdfl)) == NULL)
|
|
sc = STG_E_INSUFFICIENTMEMORY;
|
|
|
|
simpDebugOut((DEB_TRACE, "Out CSimpStorageOpen::EnumElements => %x\n", sc));
|
|
return sc;
|
|
}
|
|
|
|
//+--------------------------------------------------------------
|
|
//
|
|
// Member: CSimpStorageOpen::SetClass, public
|
|
//
|
|
// Synopsis: Sets storage class
|
|
//
|
|
// Arguments: [clsid] - class id
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 04-May-96 HenryLee Created
|
|
//
|
|
//---------------------------------------------------------------
|
|
|
|
STDMETHODIMP CSimpStorageOpen::SetClass(REFCLSID rclsid)
|
|
{
|
|
simpDebugOut((DEB_TRACE, "Stb CSimpStorageOpen::SetClass\n"));
|
|
return STG_E_INVALIDFUNCTION;
|
|
}
|
|
|