/*
 *    ITSS Storage implementation
 *
 * Copyright 2004 Mike McCormack
 *
 *  see http://bonedaddy.net/pabs3/hhm/#chmspec
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"

#include <stdarg.h>
#include <stdio.h>

#define COBJMACROS

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "ole2.h"

#include "chm_lib.h"
#include "itsstor.h"

#include "wine/itss.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(itss);

/************************************************************************/

typedef struct _ITSS_IStorageImpl
{
    IStorage IStorage_iface;
    LONG ref;
    struct chmFile *chmfile;
    WCHAR dir[1];
} ITSS_IStorageImpl;

struct enum_info
{
    struct enum_info *next, *prev;
    struct chmUnitInfo ui;
};

typedef struct _IEnumSTATSTG_Impl
{
    IEnumSTATSTG IEnumSTATSTG_iface;
    LONG ref;
    struct enum_info *first, *last, *current;
} IEnumSTATSTG_Impl;

typedef struct _IStream_Impl
{
    IStream IStream_iface;
    LONG ref;
    ITSS_IStorageImpl *stg;
    ULONGLONG addr;
    struct chmUnitInfo ui;
} IStream_Impl;

static inline ITSS_IStorageImpl *impl_from_IStorage(IStorage *iface)
{
    return CONTAINING_RECORD(iface, ITSS_IStorageImpl, IStorage_iface);
}

static inline IEnumSTATSTG_Impl *impl_from_IEnumSTATSTG(IEnumSTATSTG *iface)
{
    return CONTAINING_RECORD(iface, IEnumSTATSTG_Impl, IEnumSTATSTG_iface);
}

static inline IStream_Impl *impl_from_IStream(IStream *iface)
{
    return CONTAINING_RECORD(iface, IStream_Impl, IStream_iface);
}

static HRESULT ITSS_create_chm_storage(
           struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen );
static IStream_Impl* ITSS_create_stream( 
           ITSS_IStorageImpl *stg, struct chmUnitInfo *ui );

/************************************************************************/

static HRESULT WINAPI ITSS_IEnumSTATSTG_QueryInterface(
    IEnumSTATSTG* iface,
    REFIID riid,
    void** ppvObject)
{
    IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);

    if (IsEqualGUID(riid, &IID_IUnknown)
	|| IsEqualGUID(riid, &IID_IEnumSTATSTG))
    {
	IEnumSTATSTG_AddRef(iface);
	*ppvObject = This;
	return S_OK;
    }

    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI ITSS_IEnumSTATSTG_AddRef(
    IEnumSTATSTG* iface)
{
    IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI ITSS_IEnumSTATSTG_Release(
    IEnumSTATSTG* iface)
{
    IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);

    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        while( This->first )
        {
            struct enum_info *t = This->first->next;
            HeapFree( GetProcessHeap(), 0, This->first );
            This->first = t;
        }
        HeapFree(GetProcessHeap(), 0, This);
        ITSS_UnlockModule();
    }

    return ref;
}

static HRESULT WINAPI ITSS_IEnumSTATSTG_Next(
        IEnumSTATSTG* iface,
        ULONG celt,
        STATSTG* rgelt,
        ULONG* pceltFetched)
{
    IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
    DWORD len, n;
    struct enum_info *cur;

    TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched );

    cur = This->current;
    n = 0;
    while( (n<celt) && cur) 
    {
        WCHAR *str;

        memset( rgelt, 0, sizeof *rgelt );

        /* copy the name */
        str = cur->ui.path;
        if( *str == '/' )
            str++;
        len = strlenW( str ) + 1;
        rgelt->pwcsName = CoTaskMemAlloc( len*sizeof(WCHAR) );
        strcpyW( rgelt->pwcsName, str );

        /* determine the type */
        if( rgelt->pwcsName[len-2] == '/' )
        {
            rgelt->pwcsName[len-2] = 0;
            rgelt->type = STGTY_STORAGE;
        }
        else
            rgelt->type = STGTY_STREAM;

        /* copy the size */
        rgelt->cbSize.QuadPart = cur->ui.length;

        /* advance to the next item if it exists */
        n++;
        cur = cur->next;
    }

    This->current = cur;
    *pceltFetched = n;

    if( n < celt )
        return S_FALSE;

    return S_OK;
}

static HRESULT WINAPI ITSS_IEnumSTATSTG_Skip(
        IEnumSTATSTG* iface,
        ULONG celt)
{
    IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
    DWORD n;
    struct enum_info *cur;

    TRACE("%p %u\n", This, celt );

    cur = This->current;
    n = 0;
    while( (n<celt) && cur) 
    {
        n++;
        cur = cur->next;
    }
    This->current = cur;

    if( n < celt )
        return S_FALSE;

    return S_OK;
}

static HRESULT WINAPI ITSS_IEnumSTATSTG_Reset(
        IEnumSTATSTG* iface)
{
    IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);

    TRACE("%p\n", This );

    This->current = This->first;

    return S_OK;
}

static HRESULT WINAPI ITSS_IEnumSTATSTG_Clone(
        IEnumSTATSTG* iface,
        IEnumSTATSTG** ppenum)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const IEnumSTATSTGVtbl IEnumSTATSTG_vtbl =
{
    ITSS_IEnumSTATSTG_QueryInterface,
    ITSS_IEnumSTATSTG_AddRef,
    ITSS_IEnumSTATSTG_Release,
    ITSS_IEnumSTATSTG_Next,
    ITSS_IEnumSTATSTG_Skip,
    ITSS_IEnumSTATSTG_Reset,
    ITSS_IEnumSTATSTG_Clone
};

static IEnumSTATSTG_Impl *ITSS_create_enum( void )
{
    IEnumSTATSTG_Impl *stgenum;

    stgenum = HeapAlloc( GetProcessHeap(), 0, sizeof (IEnumSTATSTG_Impl) );
    stgenum->IEnumSTATSTG_iface.lpVtbl = &IEnumSTATSTG_vtbl;
    stgenum->ref = 1;
    stgenum->first = NULL;
    stgenum->last = NULL;
    stgenum->current = NULL;

    ITSS_LockModule();
    TRACE(" -> %p\n", stgenum );

    return stgenum;
}

/************************************************************************/

static HRESULT WINAPI ITSS_IStorageImpl_QueryInterface(
    IStorage* iface,
    REFIID riid,
    void** ppvObject)
{
    ITSS_IStorageImpl *This = impl_from_IStorage(iface);

    if (IsEqualGUID(riid, &IID_IUnknown)
	|| IsEqualGUID(riid, &IID_IStorage))
    {
	IStorage_AddRef(iface);
	*ppvObject = This;
	return S_OK;
    }

    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI ITSS_IStorageImpl_AddRef(
    IStorage* iface)
{
    ITSS_IStorageImpl *This = impl_from_IStorage(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI ITSS_IStorageImpl_Release(
    IStorage* iface)
{
    ITSS_IStorageImpl *This = impl_from_IStorage(iface);

    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        chm_close(This->chmfile);
        HeapFree(GetProcessHeap(), 0, This);
        ITSS_UnlockModule();
    }

    return ref;
}

static HRESULT WINAPI ITSS_IStorageImpl_CreateStream(
    IStorage* iface,
    LPCOLESTR pwcsName,
    DWORD grfMode,
    DWORD reserved1,
    DWORD reserved2,
    IStream** ppstm)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_OpenStream(
    IStorage* iface,
    LPCOLESTR pwcsName,
    void* reserved1,
    DWORD grfMode,
    DWORD reserved2,
    IStream** ppstm)
{
    ITSS_IStorageImpl *This = impl_from_IStorage(iface);
    IStream_Impl *stm;
    DWORD len;
    struct chmUnitInfo ui;
    int r;
    WCHAR *path, *p;

    TRACE("%p %s %p %u %u %p\n", This, debugstr_w(pwcsName),
          reserved1, grfMode, reserved2, ppstm );

    len = strlenW( This->dir ) + strlenW( pwcsName ) + 1;
    path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
    strcpyW( path, This->dir );

    if( pwcsName[0] == '/' || pwcsName[0] == '\\' )
    {
        p = &path[strlenW( path ) - 1];
        while( ( path <= p ) && ( *p == '/' ) )
            *p-- = 0;
    }
    strcatW( path, pwcsName );

    for(p=path; *p; p++) {
        if(*p == '\\')
            *p = '/';
    }

    if(*--p == '/')
        *p = 0;

    TRACE("Resolving %s\n", debugstr_w(path));

    r = chm_resolve_object(This->chmfile, path, &ui);
    HeapFree( GetProcessHeap(), 0, path );

    if( r != CHM_RESOLVE_SUCCESS ) {
        WARN("Could not resolve object\n");
        return STG_E_FILENOTFOUND;
    }

    stm = ITSS_create_stream( This, &ui );
    if( !stm )
        return E_FAIL;

    *ppstm = &stm->IStream_iface;

    return S_OK;
}

static HRESULT WINAPI ITSS_IStorageImpl_CreateStorage(
    IStorage* iface,
    LPCOLESTR pwcsName,
    DWORD grfMode,
    DWORD dwStgFmt,
    DWORD reserved2,
    IStorage** ppstg)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_OpenStorage(
    IStorage* iface,
    LPCOLESTR pwcsName,
    IStorage* pstgPriority,
    DWORD grfMode,
    SNB snbExclude,
    DWORD reserved,
    IStorage** ppstg)
{
    ITSS_IStorageImpl *This = impl_from_IStorage(iface);
    struct chmFile *chmfile;
    WCHAR *path, *p;
    DWORD len;

    TRACE("%p %s %p %u %p %u %p\n", This, debugstr_w(pwcsName),
          pstgPriority, grfMode, snbExclude, reserved, ppstg);

    chmfile = chm_dup( This->chmfile );
    if( !chmfile )
        return E_FAIL;

    len = strlenW( This->dir ) + strlenW( pwcsName ) + 2; /* need room for a terminating slash */
    path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
    strcpyW( path, This->dir );

    if( pwcsName[0] == '/' || pwcsName[0] == '\\' )
    {
        p = &path[strlenW( path ) - 1];
        while( ( path <= p ) && ( *p == '/' ) )
            *p-- = 0;
    }
    strcatW( path, pwcsName );

    for(p=path; *p; p++) {
        if(*p == '\\')
            *p = '/';
    }

    /* add a terminating slash if one does not already exist */
    if(*(p-1) != '/')
    {
        *p++ = '/';
        *p = 0;
    }

    TRACE("Resolving %s\n", debugstr_w(path));

    return ITSS_create_chm_storage(chmfile, path, ppstg);
}

static HRESULT WINAPI ITSS_IStorageImpl_CopyTo(
    IStorage* iface,
    DWORD ciidExclude,
    const IID* rgiidExclude,
    SNB snbExclude,
    IStorage* pstgDest)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_MoveElementTo(
    IStorage* iface,
    LPCOLESTR pwcsName,
    IStorage* pstgDest,
    LPCOLESTR pwcsNewName,
    DWORD grfFlags)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_Commit(
    IStorage* iface,
    DWORD grfCommitFlags)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_Revert(
    IStorage* iface)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static int ITSS_chm_enumerator(
    struct chmFile *h,
    struct chmUnitInfo *ui,
    void *context)
{
    struct enum_info *info;
    IEnumSTATSTG_Impl* stgenum = context;

    TRACE("adding %s to enumeration\n", debugstr_w(ui->path) );

    info = HeapAlloc( GetProcessHeap(), 0, sizeof (struct enum_info) );
    info->ui = *ui;

    info->next = NULL;
    info->prev = stgenum->last;
    if( stgenum->last )
        stgenum->last->next = info;
    else
        stgenum->first = info;
    stgenum->last = info;
    
    return CHM_ENUMERATOR_CONTINUE;
}

static HRESULT WINAPI ITSS_IStorageImpl_EnumElements(
    IStorage* iface,
    DWORD reserved1,
    void* reserved2,
    DWORD reserved3,
    IEnumSTATSTG** ppenum)
{
    ITSS_IStorageImpl *This = impl_from_IStorage(iface);
    IEnumSTATSTG_Impl* stgenum;

    TRACE("%p %d %p %d %p\n", This, reserved1, reserved2, reserved3, ppenum );

    stgenum = ITSS_create_enum();
    if( !stgenum )
        return E_FAIL;

    chm_enumerate_dir(This->chmfile,
                  This->dir,
                  CHM_ENUMERATE_ALL,
                  ITSS_chm_enumerator,
                  stgenum );

    stgenum->current = stgenum->first;

    *ppenum = &stgenum->IEnumSTATSTG_iface;

    return S_OK;
}

static HRESULT WINAPI ITSS_IStorageImpl_DestroyElement(
    IStorage* iface,
    LPCOLESTR pwcsName)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_RenameElement(
    IStorage* iface,
    LPCOLESTR pwcsOldName,
    LPCOLESTR pwcsNewName)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_SetElementTimes(
    IStorage* iface,
    LPCOLESTR pwcsName,
    const FILETIME* pctime,
    const FILETIME* patime,
    const FILETIME* pmtime)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_SetClass(
    IStorage* iface,
    REFCLSID clsid)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_SetStateBits(
    IStorage* iface,
    DWORD grfStateBits,
    DWORD grfMask)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStorageImpl_Stat(
    IStorage* iface,
    STATSTG* pstatstg,
    DWORD grfStatFlag)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const IStorageVtbl ITSS_IStorageImpl_Vtbl =
{
    ITSS_IStorageImpl_QueryInterface,
    ITSS_IStorageImpl_AddRef,
    ITSS_IStorageImpl_Release,
    ITSS_IStorageImpl_CreateStream,
    ITSS_IStorageImpl_OpenStream,
    ITSS_IStorageImpl_CreateStorage,
    ITSS_IStorageImpl_OpenStorage,
    ITSS_IStorageImpl_CopyTo,
    ITSS_IStorageImpl_MoveElementTo,
    ITSS_IStorageImpl_Commit,
    ITSS_IStorageImpl_Revert,
    ITSS_IStorageImpl_EnumElements,
    ITSS_IStorageImpl_DestroyElement,
    ITSS_IStorageImpl_RenameElement,
    ITSS_IStorageImpl_SetElementTimes,
    ITSS_IStorageImpl_SetClass,
    ITSS_IStorageImpl_SetStateBits,
    ITSS_IStorageImpl_Stat,
};

static HRESULT ITSS_create_chm_storage(
      struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen )
{
    ITSS_IStorageImpl *stg;
    DWORD len;

    TRACE("%p %s\n", chmfile, debugstr_w( dir ) );

    len = strlenW( dir ) + 1;
    stg = HeapAlloc( GetProcessHeap(), 0, 
                     sizeof (ITSS_IStorageImpl) + len*sizeof(WCHAR) );
    stg->IStorage_iface.lpVtbl = &ITSS_IStorageImpl_Vtbl;
    stg->ref = 1;
    stg->chmfile = chmfile;
    strcpyW( stg->dir, dir );

    *ppstgOpen = &stg->IStorage_iface;

    ITSS_LockModule();
    return S_OK;
}

HRESULT ITSS_StgOpenStorage( 
    const WCHAR* pwcsName,
    IStorage* pstgPriority,
    DWORD grfMode,
    SNB snbExclude,
    DWORD reserved,
    IStorage** ppstgOpen)
{
    struct chmFile *chmfile;
    static const WCHAR szRoot[] = { '/', 0 };

    TRACE("%s\n", debugstr_w(pwcsName) );

    chmfile = chm_openW( pwcsName );
    if( !chmfile )
        return E_FAIL;

    return ITSS_create_chm_storage( chmfile, szRoot, ppstgOpen );
}

/************************************************************************/

static HRESULT WINAPI ITSS_IStream_QueryInterface(
    IStream* iface,
    REFIID riid,
    void** ppvObject)
{
    IStream_Impl *This = impl_from_IStream(iface);

    if (IsEqualGUID(riid, &IID_IUnknown)
	|| IsEqualGUID(riid, &IID_ISequentialStream)
	|| IsEqualGUID(riid, &IID_IStream))
    {
	IStream_AddRef(iface);
	*ppvObject = This;
	return S_OK;
    }

    WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
    return E_NOINTERFACE;
}

static ULONG WINAPI ITSS_IStream_AddRef(
    IStream* iface)
{
    IStream_Impl *This = impl_from_IStream(iface);
    return InterlockedIncrement(&This->ref);
}

static ULONG WINAPI ITSS_IStream_Release(
    IStream* iface)
{
    IStream_Impl *This = impl_from_IStream(iface);

    ULONG ref = InterlockedDecrement(&This->ref);

    if (ref == 0)
    {
        IStorage_Release( &This->stg->IStorage_iface );
        HeapFree(GetProcessHeap(), 0, This);
        ITSS_UnlockModule();
    }

    return ref;
}

static HRESULT WINAPI ITSS_IStream_Read(
        IStream* iface,
        void* pv,
        ULONG cb,
        ULONG* pcbRead)
{
    IStream_Impl *This = impl_from_IStream(iface);
    ULONG count;

    TRACE("%p %p %u %p\n", This, pv, cb, pcbRead);

    count = chm_retrieve_object(This->stg->chmfile, 
                          &This->ui, pv, This->addr, cb);
    This->addr += count;
    if( pcbRead )
        *pcbRead = count;

    return count ? S_OK : S_FALSE;
}

static HRESULT WINAPI ITSS_IStream_Write(
        IStream* iface,
        const void* pv,
        ULONG cb,
        ULONG* pcbWritten)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_Seek(
        IStream* iface,
        LARGE_INTEGER dlibMove,
        DWORD dwOrigin,
        ULARGE_INTEGER* plibNewPosition)
{
    IStream_Impl *This = impl_from_IStream(iface);
    LONGLONG newpos;

    TRACE("%p %s %u %p\n", This,
          wine_dbgstr_longlong( dlibMove.QuadPart ), dwOrigin, plibNewPosition );

    newpos = This->addr;
    switch( dwOrigin )
    {
    case STREAM_SEEK_CUR:
        newpos = This->addr + dlibMove.QuadPart;
        break;
    case STREAM_SEEK_SET:
        newpos = dlibMove.QuadPart;
        break;
    case STREAM_SEEK_END:
        newpos = This->ui.length + dlibMove.QuadPart;
        break;
    }

    if( ( newpos < 0 ) || ( newpos > This->ui.length ) )
        return STG_E_INVALIDPOINTER;

    This->addr = newpos;
    if( plibNewPosition )
        plibNewPosition->QuadPart = This->addr;

    return S_OK;
}

static HRESULT WINAPI ITSS_IStream_SetSize(
        IStream* iface,
        ULARGE_INTEGER libNewSize)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_CopyTo(
        IStream* iface,
        IStream* pstm,
        ULARGE_INTEGER cb,
        ULARGE_INTEGER* pcbRead,
        ULARGE_INTEGER* pcbWritten)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_Commit(
        IStream* iface,
        DWORD grfCommitFlags)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_Revert(
        IStream* iface)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_LockRegion(
        IStream* iface,
        ULARGE_INTEGER libOffset,
        ULARGE_INTEGER cb,
        DWORD dwLockType)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_UnlockRegion(
        IStream* iface,
        ULARGE_INTEGER libOffset,
        ULARGE_INTEGER cb,
        DWORD dwLockType)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ITSS_IStream_Stat(
        IStream* iface,
        STATSTG* pstatstg,
        DWORD grfStatFlag)
{
    IStream_Impl *This = impl_from_IStream(iface);

    TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);

    memset( pstatstg, 0, sizeof *pstatstg );
    if( !( grfStatFlag & STATFLAG_NONAME ) )
    {
        FIXME("copy the name\n");
    }
    pstatstg->type = STGTY_STREAM;
    pstatstg->cbSize.QuadPart = This->ui.length;
    pstatstg->grfMode = STGM_READ;
    pstatstg->clsid = CLSID_ITStorage;

    return S_OK;
}

static HRESULT WINAPI ITSS_IStream_Clone(
        IStream* iface,
        IStream** ppstm)
{
    FIXME("\n");
    return E_NOTIMPL;
}

static const IStreamVtbl ITSS_IStream_vtbl =
{
    ITSS_IStream_QueryInterface,
    ITSS_IStream_AddRef,
    ITSS_IStream_Release,
    ITSS_IStream_Read,
    ITSS_IStream_Write,
    ITSS_IStream_Seek,
    ITSS_IStream_SetSize,
    ITSS_IStream_CopyTo,
    ITSS_IStream_Commit,
    ITSS_IStream_Revert,
    ITSS_IStream_LockRegion,
    ITSS_IStream_UnlockRegion,
    ITSS_IStream_Stat,
    ITSS_IStream_Clone,
};

static IStream_Impl *ITSS_create_stream(
           ITSS_IStorageImpl *stg, struct chmUnitInfo *ui )
{
    IStream_Impl *stm;

    stm = HeapAlloc( GetProcessHeap(), 0, sizeof (IStream_Impl) );
    stm->IStream_iface.lpVtbl = &ITSS_IStream_vtbl;
    stm->ref = 1;
    stm->addr = 0;
    stm->ui = *ui;
    stm->stg = stg;
    IStorage_AddRef( &stg->IStorage_iface );

    ITSS_LockModule();

    TRACE(" -> %p\n", stm );

    return stm;
}
