//+-------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1992. // // File: wdfiter.cxx // // Contents: CWrappedDocFile iterator methods // // History: 22-Jan-92 DrewB Created // //--------------------------------------------------------------- #include #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 // //---------------------------------------------------------------------------- SCODE CWrappedDocFile::FindGreaterEntry(CDfName const *pdfnKey, SIterBuffer *pib, STATSTGW *pstat) { SCODE sc = STG_E_UNKNOWN; 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 // //---------------------------------------------------------------------------- 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; }