NT4/private/ole32/stg/docfile/wdfiter.cxx
2020-09-30 17:12:29 +02:00

290 lines
8.1 KiB
C++

//+--------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1992.
//
// File: wdfiter.cxx
//
// Contents: CWrappedDocFile iterator methods
//
// History: 22-Jan-92 DrewB Created
//
//---------------------------------------------------------------
#include <dfhead.cxx>
#pragma hdrstop
//+---------------------------------------------------------------------------
//
// Member: CWrappedDocFile::FindGreaterEntry, public
//
// Synopsis: Returns the next greater child
//
// Arguments: [pdfnKey] - Previous key
// [pib] - Fast iterator buffer
// [pstat] - Full iterator buffer
//
// Returns: Appropriate status code
//
// Modifies: [pib] or [pstat]
//
// History: 16-Apr-93 DrewB Created
//
// Notes: Either [pib] or [pstat] must be NULL
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CWrappedDocFile_FindGreaterEntry) // Iterate_TEXT
#endif
SCODE CWrappedDocFile::FindGreaterEntry(CDfName const *pdfnKey,
SIterBuffer *pib,
STATSTGW *pstat)
{
SCODE sc;
CDfName *pdfnGreater, *pdfn;
CUpdate *pud, *pudGreater;
BOOL fFilled = FALSE;
WCHAR *pwcsName;
olDebugOut((DEB_ITRACE, "In CWrappedDocFile::FindGreaterEntry:%p("
"%p, %p, %p)\n", this, pdfnKey, pib, pstat));
olAssert(pib == NULL || pstat == NULL);
// Find the update entry that has the next greater name than the key
pudGreater = NULL;
for (pud = _ulChanged.GetHead(); pud; pud = pud->GetNext())
{
if (pud->IsCreate() || pud->IsRename())
{
pdfn = pud->GetCurrentName();
if (_ulChanged.IsEntry(pdfn, NULL) == UIE_CURRENT &&
CDirectory::NameCompare(pdfn, pdfnKey) > 0 &&
(pudGreater == NULL ||
CDirectory::NameCompare(pdfn,
pudGreater->GetCurrentName()) < 0))
{
pudGreater = pud;
pdfnGreater = pdfn;
}
}
}
// Request the next greater name from the base
if (_pdfBase != NULL)
{
CDfName dfnKey;
// Loop until we either get a valid name or we run out
dfnKey.Set(pdfnKey);
for (;;)
{
if (FAILED(sc = _pdfBase->FindGreaterEntry(&dfnKey, pib, pstat)))
{
if (sc != STG_E_NOMOREFILES)
{
olErr(EH_Err, sc);
}
else
{
break;
}
}
if (pib)
dfnKey.Set(&pib->dfnName);
else
{
olAssert(pstat != NULL);
dfnKey.CopyString(pstat->pwcsName);
}
// Filter this name against the update list
pdfn = &dfnKey;
if (_ulChanged.IsEntry(pdfn, NULL) == UIE_ORIGINAL)
{
if (pstat)
TaskMemFree(pstat->pwcsName);
continue;
}
// If this name is less than the update list name, use
// the stat entry
if (pudGreater == NULL ||
CDirectory::NameCompare(pdfn,
pudGreater->GetCurrentName()) < 0)
{
PTSetMember *ptsm;
fFilled = TRUE;
if (pstat && (ptsm = _ppubdf->FindXSMember(pdfn, GetName())))
{
pwcsName = pstat->pwcsName;
// We want to keep the name already in pstat but pick
// up any new times on the XSM
olChkTo(EH_name, ptsm->Stat(pstat, STATFLAG_NONAME));
pstat->pwcsName = pwcsName;
}
// No need to check for renames because Exists would
// have failed if there was a rename
}
else if (pstat)
{
TaskMemFree(pstat->pwcsName);
}
// Found a valid name, so stop looping
break;
}
}
if (!fFilled)
{
if (pudGreater == NULL)
{
sc = STG_E_NOMOREFILES;
}
else
{
if (pstat)
{
if (pudGreater->IsCreate())
{
olChk(pudGreater->GetXSM()->Stat(pstat, 0));
}
else
{
olAssert(pudGreater->IsRename());
olChk(StatEntry(pudGreater->GetCurrentName(), pib, pstat));
}
}
else
{
olAssert(pib != NULL);
pib->dfnName.Set(pudGreater->GetCurrentName());
pib->type = pudGreater->GetFlags() & ULF_TYPEFLAGS;
}
sc = S_OK;
}
}
olDebugOut((DEB_ITRACE, "Out CWrappedDocFile::FindGreaterEntry\n"));
EH_Err:
return sc;
EH_name:
if (pstat)
TaskMemFree(pwcsName);
return sc;
}
//+---------------------------------------------------------------------------
//
// Member: CWrappedDocFile::StatEntry, public
//
// Synopsis: Gets information for a child
//
// Arguments: [pdfn] - Child name
// [pib] - Short information
// [pstat] - Full information
//
// Returns: Appropriate status code
//
// Modifies: [pib] or [pstat]
//
// History: 16-Apr-93 DrewB Created
//
// Notes: Either [pib] or [pstat] must be NULL
//
//----------------------------------------------------------------------------
#ifdef CODESEGMENTS
#pragma code_seg(SEG_CWrappedDocFile_StatEntry)
#endif
SCODE CWrappedDocFile::StatEntry(CDfName const *pdfn,
SIterBuffer *pib,
STATSTGW *pstat)
{
CUpdate *pud;
UlIsEntry uie;
SCODE sc = S_FALSE;
CDfName const *pdfnBase = pdfn;
BOOL fResult = FALSE;
olDebugOut((DEB_ITRACE, "In CWrappedDocFile::StatEntry:%p(%p, %p, %p)\n",
this, pdfn, pib, pstat));
olAssert((pib != NULL) != (pstat != NULL));
// Attempt to find the name in the update list
uie = _ulChanged.IsEntry(pdfn, &pud);
if (uie == UIE_ORIGINAL)
{
// Name has been renamed or deleted
sc = STG_E_FILENOTFOUND;
fResult = TRUE;
}
else if (uie == UIE_CURRENT)
{
if (pib)
{
pib->dfnName.Set(pud->GetCurrentName());
pib->type = pud->GetFlags() & ULF_TYPEFLAGS;
fResult = TRUE;
sc = S_OK;
}
else
{
olAssert(pstat != NULL);
// Find whether the given name came from a create entry
// or resolve the name to the base name
pud = CUpdateList::FindBase(pud, &pdfnBase);
if (pud != NULL)
{
// Stat creation update entry
olChk(pud->GetXSM()->Stat(pstat, 0));
fResult = TRUE;
}
// else the update entry is a rename of an object in the base
// and FindBase changed pdfnBase to the base name
}
}
olAssert(fResult || sc == S_FALSE);
if (!fResult)
{
// Haven't found the entry so try the base
if (_pdfBase)
{
olChk(_pdfBase->StatEntry(pdfnBase, pib, pstat));
// Check to see if we need to return a renamed name
if (!pdfn->IsEqual(pdfnBase))
{
if (pib)
pib->dfnName.Set(pdfn);
else
{
TaskMemFree(pstat->pwcsName);
olMem(pstat->pwcsName =
(WCHAR *)TaskMemAlloc(pdfn->GetLength()));
memcpy(pstat->pwcsName, pdfn->GetBuffer(),
pdfn->GetLength());
}
}
}
else
sc = STG_E_FILENOTFOUND;
}
olDebugOut((DEB_ITRACE, "Out CWrappedDocFile::StatEntry\n"));
EH_Err:
return sc;
}