}
else
{
// We start at the beginning of the list and move forward:
ULONG ElementsToGo = AdjustedElementToGet;
ElementFound = (LIST_ENTRY *) &Table->LLHead;
while(ElementsToGo--)
ElementFound = ElementFound->Flink;
}
}
else
{
// The element has a higher index than LastElementIndex. Let’s see
// if it’s closer to the end of the list or to LastElementIndex:
ULONG ElementsToLastFound = AdjustedElementToGet - LastIndexFound;
ULONG ElementsToEnd = TotalElementCount - AdjustedElementToGet+ 1;
if (ElementsToLastFound <= ElementsToEnd)
{
// The element is closer (or at the same distance) to the last
// element found than to the end of the list. We traverse the
// list forward starting at LastElementFound.
while (ElementsToLastFound--)
ElementFound = ElementFound->Flink;
}
else
{
// The element is closer to the end of the list than to the last
// element found. We start at the head pointer and traverse the
// list backward.
ElementFound = (LIST_ENTRY *) &Table->LLHead;
while (ElementsToEnd--)
ElementFound = ElementFound->Blink;
}
}
// Cache the element for next time.
Table->LastElementFound = ElementFound;
Table->LastElementIndex = AdjustedElementToGet;
}
// Skip the header and return the element.
// Note that we don’t have a full definition for the element struct
// yet, so I’m just incrementing by 3 ULONGs.
return (PVOID) ((PULONG) ElementFound + 3);
}
Listing 5.4 (continued)
Beyond the Documentation 167