SOL9 2.0 Sample: StorageWalker

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * StorageWalker.cpp 
 * Copyright (c) 2009 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>


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 <' ') {
                    swprintf(pname, L"[0x%02x]%s", *p, p+1);
                } else {
                    swprintf(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);

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

    } catch (int err) {

    }

    OleUninitialize();
}

Last modified: 11 Nov 2009

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