327 lines
8.3 KiB
C++
327 lines
8.3 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
||
|
//
|
||
|
// File: fsenm.cxx
|
||
|
//
|
||
|
// Contents: File storage enumerator
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
#include "headers.cxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include "fsenm.hxx"
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::QueryInterface, public
|
||
|
//
|
||
|
// Synopsis: Returns an object for the requested interface
|
||
|
//
|
||
|
// Arguments: [iid] - Interface ID
|
||
|
// [ppvObj] - Object return
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [ppvObj]
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CFileEnum::QueryInterface(REFIID iid, void **ppvObj)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "In CFileEnum::QueryInterface:%p(riid, %p)\n",
|
||
|
this, ppvObj));
|
||
|
if (!IsValidIid(iid))
|
||
|
ssErr(EH_Err, STG_E_INVALIDPARAMETER);
|
||
|
ssChk(Validate());
|
||
|
if (IsEqualIID(iid, IID_IEnumSTATSTG) || IsEqualIID(iid, IID_IUnknown))
|
||
|
{
|
||
|
*ppvObj = (IEnumSTATSTG *)this;
|
||
|
CFileEnum::AddRef();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
sc = E_NOINTERFACE;
|
||
|
*ppvObj = NULL;
|
||
|
}
|
||
|
ssDebugOut((DEB_TRACE, "Out CFileEnum::QueryInterface => %p\n",
|
||
|
*ppvObj));
|
||
|
EH_Err:
|
||
|
return ssResult(sc);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::CFileEnum, public
|
||
|
//
|
||
|
// Synopsis: Constructor
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CFileEnum::CFileEnum(void)
|
||
|
{
|
||
|
ssDebugOut((DEB_ITRACE, "In CFileEnum::CFileEnum:%p()\n", this));
|
||
|
_sig = 0;
|
||
|
ssDebugOut((DEB_ITRACE, "Out CFileEnum::CFileEnum\n"));
|
||
|
ENLIST_TRACKING(CFileEnum);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::InitFromHandle, public
|
||
|
//
|
||
|
// Synopsis: Initializes from the given information
|
||
|
//
|
||
|
// Arguments: [h] - Handle
|
||
|
// [fDone] - Done status
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
// Notes: Takes a new reference on the handle
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
SCODE CFileEnum::InitFromHandle(HANDLE h, BOOL fDone)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
|
||
|
ssDebugOut((DEB_ITRACE, "In CFileEnum::InitFromHandle:%p(%p, %d)\n",
|
||
|
this, h, fDone));
|
||
|
|
||
|
ssChk(DupNtHandle(h, &_h));
|
||
|
|
||
|
_fDone = fDone;
|
||
|
_sig = CFILEENUM_SIG;
|
||
|
|
||
|
ssDebugOut((DEB_ITRACE, "Out CFileEnum::InitFromHandle\n"));
|
||
|
EH_Err:
|
||
|
return sc;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::~CFileEnum, public
|
||
|
//
|
||
|
// Synopsis: Destructor
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CFileEnum::~CFileEnum(void)
|
||
|
{
|
||
|
ssDebugOut((DEB_ITRACE, "In CFileEnum::~CFileEnum:%p()\n", this));
|
||
|
_sig = CFILEENUM_SIGDEL;
|
||
|
ssDebugOut((DEB_ITRACE, "Out CFileEnum::~CFileEnum\n"));
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::Next, public
|
||
|
//
|
||
|
// Synopsis: Gets N entries from an iterator
|
||
|
//
|
||
|
// Arguments: [celt] - Count of elements
|
||
|
// [rgelt] - Array for element return
|
||
|
// [pceltFetched] - If non-NULL, contains the number of
|
||
|
// elements fetched
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [rgelt]
|
||
|
// [pceltFetched]
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CFileEnum::Next(ULONG celt,
|
||
|
STATSTG *rgelt,
|
||
|
ULONG *pceltFetched)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
STATSTG stat;
|
||
|
FILE_STANDARD_INFORMATION fi;
|
||
|
NTSTATUS nts;
|
||
|
IO_STATUS_BLOCK iosb;
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "In CFileEnum::Next:%p(%lu, %p, %p)\n",
|
||
|
this, celt, rgelt, pceltFetched));
|
||
|
|
||
|
if (pceltFetched == NULL && celt > 1)
|
||
|
ssErr(EH_Err, STG_E_INVALIDPARAMETER);
|
||
|
ssChk(Validate());
|
||
|
|
||
|
ssAssert(_h != NULL);
|
||
|
__try
|
||
|
{
|
||
|
if (celt == 0)
|
||
|
{
|
||
|
if (pceltFetched)
|
||
|
*pceltFetched = 0;
|
||
|
ssErr(EH_Err, S_OK);
|
||
|
}
|
||
|
|
||
|
stat.pwcsName = NULL;
|
||
|
if (!_fDone)
|
||
|
{
|
||
|
nts = NtQueryInformationFile(_h, &iosb, &fi,
|
||
|
sizeof(FILE_STANDARD_INFORMATION),
|
||
|
FileStandardInformation);
|
||
|
if (!NT_SUCCESS(nts))
|
||
|
ssErr(EH_Err, NtStatusToScode(nts));
|
||
|
|
||
|
ssChk(CoMemAlloc(sizeof(CONTENTS_STREAM),
|
||
|
(void **)&stat.pwcsName));
|
||
|
lstrcpyW(stat.pwcsName, CONTENTS_STREAM);
|
||
|
|
||
|
stat.type = STGTY_STREAM;
|
||
|
stat.cbSize = *(ULARGE_INTEGER *)&fi.EndOfFile;
|
||
|
stat.mtime.dwLowDateTime = stat.mtime.dwHighDateTime = 0;
|
||
|
stat.atime.dwLowDateTime = stat.atime.dwHighDateTime = 0;
|
||
|
stat.ctime.dwLowDateTime = stat.ctime.dwHighDateTime = 0;
|
||
|
stat.grfMode = 0;
|
||
|
stat.grfLocksSupported = 0;
|
||
|
stat.clsid = CLSID_NULL;
|
||
|
stat.grfStateBits = 0;
|
||
|
stat.STATSTG_dwStgFmt = STGFMT_DOCUMENT;
|
||
|
|
||
|
rgelt[0] = stat;
|
||
|
if (pceltFetched)
|
||
|
*pceltFetched = 1;
|
||
|
|
||
|
_fDone = TRUE;
|
||
|
|
||
|
if (celt > 1)
|
||
|
sc = S_FALSE;
|
||
|
else
|
||
|
sc = S_OK;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (pceltFetched)
|
||
|
*pceltFetched = 0;
|
||
|
sc = S_FALSE;
|
||
|
}
|
||
|
}
|
||
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
||
|
{
|
||
|
if (stat.pwcsName)
|
||
|
ssVerSucc(CoMemFree(stat.pwcsName));
|
||
|
sc = HRESULT_FROM_NT(GetExceptionCode());
|
||
|
}
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "Out CFileEnum::Next => 0x%lX\n", sc));
|
||
|
EH_Err:
|
||
|
return ssResult(sc);
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::Skip, public
|
||
|
//
|
||
|
// Synopsis: Skips N entries from an iterator
|
||
|
//
|
||
|
// Arguments: [celt] - Count of elements
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CFileEnum::Skip(ULONG celt)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "In CFileEnum::Skip:%p(%lu)\n", this, celt));
|
||
|
|
||
|
ssChk(Validate());
|
||
|
|
||
|
if (celt > 0)
|
||
|
{
|
||
|
if (_fDone)
|
||
|
sc = S_FALSE;
|
||
|
else
|
||
|
_fDone = TRUE;
|
||
|
}
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "Out CFileEnum::Skip\n"));
|
||
|
EH_Err:
|
||
|
return ssResult(sc);
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::Reset, public
|
||
|
//
|
||
|
// Synopsis: Rewinds the iterator
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CFileEnum::Reset(void)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "In CFileEnum::Reset:%p()\n", this));
|
||
|
|
||
|
ssChk(Validate());
|
||
|
_fDone = FALSE;
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "Out CFileEnum::Reset\n"));
|
||
|
EH_Err:
|
||
|
return ssResult(sc);
|
||
|
}
|
||
|
|
||
|
//+--------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CFileEnum::Clone, public
|
||
|
//
|
||
|
// Synopsis: Clones this iterator
|
||
|
//
|
||
|
// Arguments: [ppenm] - Clone return
|
||
|
//
|
||
|
// Returns: Appropriate status code
|
||
|
//
|
||
|
// Modifies: [ppenm]
|
||
|
//
|
||
|
// History: 21-Jul-93 DrewB Created
|
||
|
//
|
||
|
//---------------------------------------------------------------
|
||
|
|
||
|
STDMETHODIMP CFileEnum::Clone(IEnumSTATSTG **ppenm)
|
||
|
{
|
||
|
SCODE sc;
|
||
|
SafeCFileEnum pfe;
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "In CFileEnum::Clone:%p(%p)\n", this, ppenm));
|
||
|
|
||
|
ssChk(Validate());
|
||
|
|
||
|
pfe.Attach(new CFileEnum());
|
||
|
ssMem((CFileEnum *)pfe);
|
||
|
ssAssert(_h != NULL);
|
||
|
ssChk(pfe->InitFromHandle(_h, _fDone));
|
||
|
TRANSFER_INTERFACE(pfe, IEnumSTATSTG, ppenm);
|
||
|
|
||
|
ssDebugOut((DEB_TRACE, "Out CFileEnum::Clone => %p\n", *ppenm));
|
||
|
EH_Err:
|
||
|
return ssResult(sc);
|
||
|
}
|