procedure TMainForm.ViewStorage(inID: Integer; lpStorage: IStorage);
var
  lpEnum: IEnumStatStg;
  ss: TStatStg;
  ulCount, ldwType: Longint;
  sc: SCODE;
  pSubStg: IStorage;
  subID: Integer;
  sType: String[12];
  hr: HResult;
  snbExclude: PStr;
  pMyStatStg: TMyStatStg;
begin
  snbExclude := nil;
  pSubStg := nil;
  if FAILEDHR(lpStorage.EnumElements(0, nil, 0, lpEnum)) then
    ShowMessage('Could not get a Storage Enumerator at level: ' + IntToStr(inID))
  else begin
    sc := S_OK;
    while sc = S_OK do begin
      sc := GetSCode(lpEnum.Next(1, ss, ulCount));
      if (sc <> S_OK) and (sc <> S_FALSE) then begin
        ShowMessage('IEnumStatStg returned an error! SCODE = ' + IntToStr(Longint(sc)));
        Exit;
      end
      else
        ldwType := Longint(ss.dwType);
        case ldwType of
          STGTY_STREAM: sType := 'Stream';
          STGTY_STORAGE: sType := 'Storage';
          STGTY_LOCKBYTES: sType := 'LockBytes';
          STGTY_PROPERTY: sType := 'Property';
          else sType := '**Unknown**';
        end;

      { Add this record to the Outline Control. Note that ss.cbSize (the size of
        the stream object) is a 64 bit integer. }
      if sc = S_OK then begin

        { Add this TStatStg record to the outline control. We need to use a
          helper function: GetLowPart to bust up the ss.cbSize 64 bit integer. }
        subID := Outline1.AddChild(inID, StrPas(ss.pwcsName) + ', Type: ' +
          sType + ', Size: ' + IntToStr(GetLowPart(ss.cbSize)));
        if ldwType = STGTY_STORAGE then begin

          { We're in a Storage- Recursively traverse the storage by calling ourself }
          hr := lpStorage.OpenStorage(ss.pwcsName, nil, STGM_READ or
            STGM_SHARE_EXCLUSIVE, nil, Longint(nil), pSubStg);
          if SUCCEEDEDHR(hr) then begin
            pMyStatStg := TMyStatStg.Create(ss.pwcsName, pSubStg, ss.dwType, ss.cbSize);
            m_lstIStorage.Add(pMyStatStg);
            ViewStorage(subID, pSubStg);   { call ourself }
          end
          else
            ShowMessage('Failed substorage open! hr = ' + IntToStr(Longint(hr)));
        end
        else begin

          { This wasn't a storage, so we write the current lpStorage into the table }
          pMyStatStg := TMyStatStg.Create(ss.pwcsName, lpStorage, ss.dwType, ss.cbSize);
          m_lstIStorage.Add(pMyStatStg);
        end;
      end;
    end;
    lpEnum.Release;
    lpEnum := nil;
  end;
Figure 9: Traversing the Directory Tree

