SOL9 Sample: StorageWalker

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * StorageWalker.cpp 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL9
// 2008/08/11
// 2009/04/04 Modified to include StorageWalker class into this cpp file.

#include <sol\Object.h>

#include <sol\StringConverter.h>
#include <sol\SmartPtr.h>
// 2011/09/04 Added the following line.
#include <sol\Locale.h>

namespace SOL {

/**
 * CompoundFile Storage Walker
 */
class StorageWalker :public Object {

private:
  static const DWORD flags = STGM_READ|STGM_SHARE_EXCLUSIVE;
private:
  int  indent;

private:
  StringConverter converter;

public:
  /**
   * Constructor
   */
  StorageWalker()
  {

  }

public:
  /**
   * Walk the storage of the compound file of fileName.
   */    
  void walk(const TCHAR* fileName)
  {
    indent = 0;
    SmartPtr<wchar_t> name(converter.toWideChar(fileName));
    wprintf(L"[%s]\n", (const wchar_t*)name);

    IStorage* pIStorage=NULL;


    HRESULT hr = StgOpenStorageEx((const wchar_t*)name, flags, 0, 0, 
        NULL, NULL, IID_IStorage, (void**)&pIStorage);    

    if (SUCCEEDED(hr)) {      
      walk(pIStorage, indent);

      pIStorage->Release();
    } else {
      wprintf(L"Failed to open a storage file=%s\n", fileName);      
    }    
  }

private:
  /**
   * Walk substorage recursively.
   */
  void walk(IStorage* pIStorage, int indent)
  {
    IEnumSTATSTG* pIEnum = NULL;
  
    HRESULT hr = pIStorage->EnumElements(0, NULL, 0, &pIEnum);

    if (SUCCEEDED(hr)) {
      ULONG uCount;

      STATSTG stat; 

      while (pIEnum->Next(1, &stat, &uCount)==S_OK) {

        wchar_t* p = stat.pwcsName;
        wchar_t pname[MAX_PATH];
        if (*p < (wchar_t)' ') {
          swprintf_s(pname, SizeOf(pname), L"[0x%02x]%s", *p, p+1);
        } else {
          swprintf_s(pname, SizeOf(pname), L"%s", p);
        }

        for (int i =0; i<indent; i++) {
          wprintf(L" ");          
        }
        if (stat.type == STGTY_STORAGE) {
          wprintf(L"Storage:%s\n", pname);//(LPSTR)stat.pwcsName);
          IStorage* pISubStorage=NULL;

          hr = pIStorage->OpenStorage(stat.pwcsName, NULL,
              flags, NULL, 0, &pISubStorage);
          if (SUCCEEDED(hr)) {
            //Walk a subStorage
            walk(pISubStorage, indent+1);
            pISubStorage->Release();

          }
        }
        else if (stat.type==STGTY_STREAM) {
          wprintf(L"Stream:%s\n", pname);//(LPSTR)stat.pwcsName);
         } else {
          wprintf(L"Unknown:%s\n", (LPSTR)stat.pwcsName);
        }
        
        CoTaskMemFree(stat.pwcsName);
      };
      pIEnum->Release();
    }
  }
};

}




void _tmain(int argc, TCHAR* argv[])
{
  if (argc != 2) {
    printf("Usage: StorageWalker.exe CompoundFile\n");
    printf("Example:StorageWalker.exe c:\\work\\abc.doc\n");

    return;
  }

  const TCHAR* fileName = argv[1];

  if (GetFileAttributes(fileName) == 0xffffffff) {
    _tprintf(_T("File not found %s\n"), fileName);
    return;
  }

  OleInitialize(NULL);
  // 2011/09/04 Added the following line.
  Locale locale;

  try {
    StorageWalker walker;
    walker.walk(fileName);

  } catch (int err) {
    printf("Exception: %d\n", err);
  }

  OleUninitialize();
}

Last modified: 2 May 2016

Copyright (c) 2016 Antillia.com ALL RIGHTS RESERVED.