ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

storage.c
Go to the documentation of this file.
00001 /*
00002  *    ITSS Storage implementation
00003  *
00004  * Copyright 2004 Mike McCormack
00005  *
00006  *  see http://bonedaddy.net/pabs3/hhm/#chmspec
00007  *
00008  * This library is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with this library; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00021  */
00022 
00023 #include "config.h"
00024 
00025 #include <stdarg.h>
00026 #include <stdio.h>
00027 
00028 #define COBJMACROS
00029 
00030 #include "windef.h"
00031 #include "winbase.h"
00032 #include "winuser.h"
00033 #include "ole2.h"
00034 
00035 #include "chm_lib.h"
00036 #include "itsstor.h"
00037 
00038 #include "wine/itss.h"
00039 #include "wine/unicode.h"
00040 #include "wine/debug.h"
00041 
00042 WINE_DEFAULT_DEBUG_CHANNEL(itss);
00043 
00044 /************************************************************************/
00045 
00046 typedef struct _ITSS_IStorageImpl
00047 {
00048     IStorage IStorage_iface;
00049     LONG ref;
00050     struct chmFile *chmfile;
00051     WCHAR dir[1];
00052 } ITSS_IStorageImpl;
00053 
00054 struct enum_info
00055 {
00056     struct enum_info *next, *prev;
00057     struct chmUnitInfo ui;
00058 };
00059 
00060 typedef struct _IEnumSTATSTG_Impl
00061 {
00062     IEnumSTATSTG IEnumSTATSTG_iface;
00063     LONG ref;
00064     struct enum_info *first, *last, *current;
00065 } IEnumSTATSTG_Impl;
00066 
00067 typedef struct _IStream_Impl
00068 {
00069     IStream IStream_iface;
00070     LONG ref;
00071     ITSS_IStorageImpl *stg;
00072     ULONGLONG addr;
00073     struct chmUnitInfo ui;
00074 } IStream_Impl;
00075 
00076 static inline ITSS_IStorageImpl *impl_from_IStorage(IStorage *iface)
00077 {
00078     return CONTAINING_RECORD(iface, ITSS_IStorageImpl, IStorage_iface);
00079 }
00080 
00081 static inline IEnumSTATSTG_Impl *impl_from_IEnumSTATSTG(IEnumSTATSTG *iface)
00082 {
00083     return CONTAINING_RECORD(iface, IEnumSTATSTG_Impl, IEnumSTATSTG_iface);
00084 }
00085 
00086 static inline IStream_Impl *impl_from_IStream(IStream *iface)
00087 {
00088     return CONTAINING_RECORD(iface, IStream_Impl, IStream_iface);
00089 }
00090 
00091 static HRESULT ITSS_create_chm_storage(
00092            struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen );
00093 static IStream_Impl* ITSS_create_stream( 
00094            ITSS_IStorageImpl *stg, struct chmUnitInfo *ui );
00095 
00096 /************************************************************************/
00097 
00098 static HRESULT WINAPI ITSS_IEnumSTATSTG_QueryInterface(
00099     IEnumSTATSTG* iface,
00100     REFIID riid,
00101     void** ppvObject)
00102 {
00103     IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
00104 
00105     if (IsEqualGUID(riid, &IID_IUnknown)
00106     || IsEqualGUID(riid, &IID_IEnumSTATSTG))
00107     {
00108     IEnumSTATSTG_AddRef(iface);
00109     *ppvObject = This;
00110     return S_OK;
00111     }
00112 
00113     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
00114     return E_NOINTERFACE;
00115 }
00116 
00117 static ULONG WINAPI ITSS_IEnumSTATSTG_AddRef(
00118     IEnumSTATSTG* iface)
00119 {
00120     IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
00121     return InterlockedIncrement(&This->ref);
00122 }
00123 
00124 static ULONG WINAPI ITSS_IEnumSTATSTG_Release(
00125     IEnumSTATSTG* iface)
00126 {
00127     IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
00128 
00129     ULONG ref = InterlockedDecrement(&This->ref);
00130 
00131     if (ref == 0)
00132     {
00133         while( This->first )
00134         {
00135             struct enum_info *t = This->first->next;
00136             HeapFree( GetProcessHeap(), 0, This->first );
00137             This->first = t;
00138         }
00139         HeapFree(GetProcessHeap(), 0, This);
00140         ITSS_UnlockModule();
00141     }
00142 
00143     return ref;
00144 }
00145 
00146 static HRESULT WINAPI ITSS_IEnumSTATSTG_Next(
00147         IEnumSTATSTG* iface,
00148         ULONG celt,
00149         STATSTG* rgelt,
00150         ULONG* pceltFetched)
00151 {
00152     IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
00153     DWORD len, n;
00154     struct enum_info *cur;
00155 
00156     TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched );
00157 
00158     cur = This->current;
00159     n = 0;
00160     while( (n<celt) && cur) 
00161     {
00162         WCHAR *str;
00163 
00164         memset( rgelt, 0, sizeof *rgelt );
00165 
00166         /* copy the name */
00167         str = cur->ui.path;
00168         if( *str == '/' )
00169             str++;
00170         len = strlenW( str ) + 1;
00171         rgelt->pwcsName = CoTaskMemAlloc( len*sizeof(WCHAR) );
00172         strcpyW( rgelt->pwcsName, str );
00173 
00174         /* determine the type */
00175         if( rgelt->pwcsName[len-2] == '/' )
00176         {
00177             rgelt->pwcsName[len-2] = 0;
00178             rgelt->type = STGTY_STORAGE;
00179         }
00180         else
00181             rgelt->type = STGTY_STREAM;
00182 
00183         /* copy the size */
00184         rgelt->cbSize.QuadPart = cur->ui.length;
00185 
00186         /* advance to the next item if it exists */
00187         n++;
00188         cur = cur->next;
00189     }
00190 
00191     This->current = cur;
00192     *pceltFetched = n;
00193 
00194     if( n < celt )
00195         return S_FALSE;
00196 
00197     return S_OK;
00198 }
00199 
00200 static HRESULT WINAPI ITSS_IEnumSTATSTG_Skip(
00201         IEnumSTATSTG* iface,
00202         ULONG celt)
00203 {
00204     IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
00205     DWORD n;
00206     struct enum_info *cur;
00207 
00208     TRACE("%p %u\n", This, celt );
00209 
00210     cur = This->current;
00211     n = 0;
00212     while( (n<celt) && cur) 
00213     {
00214         n++;
00215         cur = cur->next;
00216     }
00217     This->current = cur;
00218 
00219     if( n < celt )
00220         return S_FALSE;
00221 
00222     return S_OK;
00223 }
00224 
00225 static HRESULT WINAPI ITSS_IEnumSTATSTG_Reset(
00226         IEnumSTATSTG* iface)
00227 {
00228     IEnumSTATSTG_Impl *This = impl_from_IEnumSTATSTG(iface);
00229 
00230     TRACE("%p\n", This );
00231 
00232     This->current = This->first;
00233 
00234     return S_OK;
00235 }
00236 
00237 static HRESULT WINAPI ITSS_IEnumSTATSTG_Clone(
00238         IEnumSTATSTG* iface,
00239         IEnumSTATSTG** ppenum)
00240 {
00241     FIXME("\n");
00242     return E_NOTIMPL;
00243 }
00244 
00245 static const IEnumSTATSTGVtbl IEnumSTATSTG_vtbl =
00246 {
00247     ITSS_IEnumSTATSTG_QueryInterface,
00248     ITSS_IEnumSTATSTG_AddRef,
00249     ITSS_IEnumSTATSTG_Release,
00250     ITSS_IEnumSTATSTG_Next,
00251     ITSS_IEnumSTATSTG_Skip,
00252     ITSS_IEnumSTATSTG_Reset,
00253     ITSS_IEnumSTATSTG_Clone
00254 };
00255 
00256 static IEnumSTATSTG_Impl *ITSS_create_enum( void )
00257 {
00258     IEnumSTATSTG_Impl *stgenum;
00259 
00260     stgenum = HeapAlloc( GetProcessHeap(), 0, sizeof (IEnumSTATSTG_Impl) );
00261     stgenum->IEnumSTATSTG_iface.lpVtbl = &IEnumSTATSTG_vtbl;
00262     stgenum->ref = 1;
00263     stgenum->first = NULL;
00264     stgenum->last = NULL;
00265     stgenum->current = NULL;
00266 
00267     ITSS_LockModule();
00268     TRACE(" -> %p\n", stgenum );
00269 
00270     return stgenum;
00271 }
00272 
00273 /************************************************************************/
00274 
00275 static HRESULT WINAPI ITSS_IStorageImpl_QueryInterface(
00276     IStorage* iface,
00277     REFIID riid,
00278     void** ppvObject)
00279 {
00280     ITSS_IStorageImpl *This = impl_from_IStorage(iface);
00281 
00282     if (IsEqualGUID(riid, &IID_IUnknown)
00283     || IsEqualGUID(riid, &IID_IStorage))
00284     {
00285     IStorage_AddRef(iface);
00286     *ppvObject = This;
00287     return S_OK;
00288     }
00289 
00290     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
00291     return E_NOINTERFACE;
00292 }
00293 
00294 static ULONG WINAPI ITSS_IStorageImpl_AddRef(
00295     IStorage* iface)
00296 {
00297     ITSS_IStorageImpl *This = impl_from_IStorage(iface);
00298     return InterlockedIncrement(&This->ref);
00299 }
00300 
00301 static ULONG WINAPI ITSS_IStorageImpl_Release(
00302     IStorage* iface)
00303 {
00304     ITSS_IStorageImpl *This = impl_from_IStorage(iface);
00305 
00306     ULONG ref = InterlockedDecrement(&This->ref);
00307 
00308     if (ref == 0)
00309     {
00310         chm_close(This->chmfile);
00311         HeapFree(GetProcessHeap(), 0, This);
00312         ITSS_UnlockModule();
00313     }
00314 
00315     return ref;
00316 }
00317 
00318 static HRESULT WINAPI ITSS_IStorageImpl_CreateStream(
00319     IStorage* iface,
00320     LPCOLESTR pwcsName,
00321     DWORD grfMode,
00322     DWORD reserved1,
00323     DWORD reserved2,
00324     IStream** ppstm)
00325 {
00326     FIXME("\n");
00327     return E_NOTIMPL;
00328 }
00329 
00330 static HRESULT WINAPI ITSS_IStorageImpl_OpenStream(
00331     IStorage* iface,
00332     LPCOLESTR pwcsName,
00333     void* reserved1,
00334     DWORD grfMode,
00335     DWORD reserved2,
00336     IStream** ppstm)
00337 {
00338     ITSS_IStorageImpl *This = impl_from_IStorage(iface);
00339     IStream_Impl *stm;
00340     DWORD len;
00341     struct chmUnitInfo ui;
00342     int r;
00343     WCHAR *path, *p;
00344 
00345     TRACE("%p %s %p %u %u %p\n", This, debugstr_w(pwcsName),
00346           reserved1, grfMode, reserved2, ppstm );
00347 
00348     len = strlenW( This->dir ) + strlenW( pwcsName ) + 1;
00349     path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
00350     strcpyW( path, This->dir );
00351 
00352     if( pwcsName[0] == '/' || pwcsName[0] == '\\' )
00353     {
00354         p = &path[strlenW( path ) - 1];
00355         while( ( path <= p ) && ( *p == '/' ) )
00356             *p-- = 0;
00357     }
00358     strcatW( path, pwcsName );
00359 
00360     for(p=path; *p; p++) {
00361         if(*p == '\\')
00362             *p = '/';
00363     }
00364 
00365     if(*--p == '/')
00366         *p = 0;
00367 
00368     TRACE("Resolving %s\n", debugstr_w(path));
00369 
00370     r = chm_resolve_object(This->chmfile, path, &ui);
00371     HeapFree( GetProcessHeap(), 0, path );
00372 
00373     if( r != CHM_RESOLVE_SUCCESS ) {
00374         WARN("Could not resolve object\n");
00375         return STG_E_FILENOTFOUND;
00376     }
00377 
00378     stm = ITSS_create_stream( This, &ui );
00379     if( !stm )
00380         return E_FAIL;
00381 
00382     *ppstm = &stm->IStream_iface;
00383 
00384     return S_OK;
00385 }
00386 
00387 static HRESULT WINAPI ITSS_IStorageImpl_CreateStorage(
00388     IStorage* iface,
00389     LPCOLESTR pwcsName,
00390     DWORD grfMode,
00391     DWORD dwStgFmt,
00392     DWORD reserved2,
00393     IStorage** ppstg)
00394 {
00395     FIXME("\n");
00396     return E_NOTIMPL;
00397 }
00398 
00399 static HRESULT WINAPI ITSS_IStorageImpl_OpenStorage(
00400     IStorage* iface,
00401     LPCOLESTR pwcsName,
00402     IStorage* pstgPriority,
00403     DWORD grfMode,
00404     SNB snbExclude,
00405     DWORD reserved,
00406     IStorage** ppstg)
00407 {
00408     ITSS_IStorageImpl *This = impl_from_IStorage(iface);
00409     struct chmFile *chmfile;
00410     WCHAR *path, *p;
00411     DWORD len;
00412 
00413     TRACE("%p %s %p %u %p %u %p\n", This, debugstr_w(pwcsName),
00414           pstgPriority, grfMode, snbExclude, reserved, ppstg);
00415 
00416     chmfile = chm_dup( This->chmfile );
00417     if( !chmfile )
00418         return E_FAIL;
00419 
00420     len = strlenW( This->dir ) + strlenW( pwcsName ) + 2; /* need room for a terminating slash */
00421     path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
00422     strcpyW( path, This->dir );
00423 
00424     if( pwcsName[0] == '/' || pwcsName[0] == '\\' )
00425     {
00426         p = &path[strlenW( path ) - 1];
00427         while( ( path <= p ) && ( *p == '/' ) )
00428             *p-- = 0;
00429     }
00430     strcatW( path, pwcsName );
00431 
00432     for(p=path; *p; p++) {
00433         if(*p == '\\')
00434             *p = '/';
00435     }
00436 
00437     /* add a terminating slash if one does not already exist */
00438     if(*(p-1) != '/')
00439     {
00440         *p++ = '/';
00441         *p = 0;
00442     }
00443 
00444     TRACE("Resolving %s\n", debugstr_w(path));
00445 
00446     return ITSS_create_chm_storage(chmfile, path, ppstg);
00447 }
00448 
00449 static HRESULT WINAPI ITSS_IStorageImpl_CopyTo(
00450     IStorage* iface,
00451     DWORD ciidExclude,
00452     const IID* rgiidExclude,
00453     SNB snbExclude,
00454     IStorage* pstgDest)
00455 {
00456     FIXME("\n");
00457     return E_NOTIMPL;
00458 }
00459 
00460 static HRESULT WINAPI ITSS_IStorageImpl_MoveElementTo(
00461     IStorage* iface,
00462     LPCOLESTR pwcsName,
00463     IStorage* pstgDest,
00464     LPCOLESTR pwcsNewName,
00465     DWORD grfFlags)
00466 {
00467     FIXME("\n");
00468     return E_NOTIMPL;
00469 }
00470 
00471 static HRESULT WINAPI ITSS_IStorageImpl_Commit(
00472     IStorage* iface,
00473     DWORD grfCommitFlags)
00474 {
00475     FIXME("\n");
00476     return E_NOTIMPL;
00477 }
00478 
00479 static HRESULT WINAPI ITSS_IStorageImpl_Revert(
00480     IStorage* iface)
00481 {
00482     FIXME("\n");
00483     return E_NOTIMPL;
00484 }
00485 
00486 static int ITSS_chm_enumerator(
00487     struct chmFile *h,
00488     struct chmUnitInfo *ui,
00489     void *context)
00490 {
00491     struct enum_info *info;
00492     IEnumSTATSTG_Impl* stgenum = context;
00493 
00494     TRACE("adding %s to enumeration\n", debugstr_w(ui->path) );
00495 
00496     info = HeapAlloc( GetProcessHeap(), 0, sizeof (struct enum_info) );
00497     info->ui = *ui;
00498 
00499     info->next = NULL;
00500     info->prev = stgenum->last;
00501     if( stgenum->last )
00502         stgenum->last->next = info;
00503     else
00504         stgenum->first = info;
00505     stgenum->last = info;
00506     
00507     return CHM_ENUMERATOR_CONTINUE;
00508 }
00509 
00510 static HRESULT WINAPI ITSS_IStorageImpl_EnumElements(
00511     IStorage* iface,
00512     DWORD reserved1,
00513     void* reserved2,
00514     DWORD reserved3,
00515     IEnumSTATSTG** ppenum)
00516 {
00517     ITSS_IStorageImpl *This = impl_from_IStorage(iface);
00518     IEnumSTATSTG_Impl* stgenum;
00519 
00520     TRACE("%p %d %p %d %p\n", This, reserved1, reserved2, reserved3, ppenum );
00521 
00522     stgenum = ITSS_create_enum();
00523     if( !stgenum )
00524         return E_FAIL;
00525 
00526     chm_enumerate_dir(This->chmfile,
00527                   This->dir,
00528                   CHM_ENUMERATE_ALL,
00529                   ITSS_chm_enumerator,
00530                   stgenum );
00531 
00532     stgenum->current = stgenum->first;
00533 
00534     *ppenum = &stgenum->IEnumSTATSTG_iface;
00535 
00536     return S_OK;
00537 }
00538 
00539 static HRESULT WINAPI ITSS_IStorageImpl_DestroyElement(
00540     IStorage* iface,
00541     LPCOLESTR pwcsName)
00542 {
00543     FIXME("\n");
00544     return E_NOTIMPL;
00545 }
00546 
00547 static HRESULT WINAPI ITSS_IStorageImpl_RenameElement(
00548     IStorage* iface,
00549     LPCOLESTR pwcsOldName,
00550     LPCOLESTR pwcsNewName)
00551 {
00552     FIXME("\n");
00553     return E_NOTIMPL;
00554 }
00555 
00556 static HRESULT WINAPI ITSS_IStorageImpl_SetElementTimes(
00557     IStorage* iface,
00558     LPCOLESTR pwcsName,
00559     const FILETIME* pctime,
00560     const FILETIME* patime,
00561     const FILETIME* pmtime)
00562 {
00563     FIXME("\n");
00564     return E_NOTIMPL;
00565 }
00566 
00567 static HRESULT WINAPI ITSS_IStorageImpl_SetClass(
00568     IStorage* iface,
00569     REFCLSID clsid)
00570 {
00571     FIXME("\n");
00572     return E_NOTIMPL;
00573 }
00574 
00575 static HRESULT WINAPI ITSS_IStorageImpl_SetStateBits(
00576     IStorage* iface,
00577     DWORD grfStateBits,
00578     DWORD grfMask)
00579 {
00580     FIXME("\n");
00581     return E_NOTIMPL;
00582 }
00583 
00584 static HRESULT WINAPI ITSS_IStorageImpl_Stat(
00585     IStorage* iface,
00586     STATSTG* pstatstg,
00587     DWORD grfStatFlag)
00588 {
00589     FIXME("\n");
00590     return E_NOTIMPL;
00591 }
00592 
00593 static const IStorageVtbl ITSS_IStorageImpl_Vtbl =
00594 {
00595     ITSS_IStorageImpl_QueryInterface,
00596     ITSS_IStorageImpl_AddRef,
00597     ITSS_IStorageImpl_Release,
00598     ITSS_IStorageImpl_CreateStream,
00599     ITSS_IStorageImpl_OpenStream,
00600     ITSS_IStorageImpl_CreateStorage,
00601     ITSS_IStorageImpl_OpenStorage,
00602     ITSS_IStorageImpl_CopyTo,
00603     ITSS_IStorageImpl_MoveElementTo,
00604     ITSS_IStorageImpl_Commit,
00605     ITSS_IStorageImpl_Revert,
00606     ITSS_IStorageImpl_EnumElements,
00607     ITSS_IStorageImpl_DestroyElement,
00608     ITSS_IStorageImpl_RenameElement,
00609     ITSS_IStorageImpl_SetElementTimes,
00610     ITSS_IStorageImpl_SetClass,
00611     ITSS_IStorageImpl_SetStateBits,
00612     ITSS_IStorageImpl_Stat,
00613 };
00614 
00615 static HRESULT ITSS_create_chm_storage(
00616       struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen )
00617 {
00618     ITSS_IStorageImpl *stg;
00619     DWORD len;
00620 
00621     TRACE("%p %s\n", chmfile, debugstr_w( dir ) );
00622 
00623     len = strlenW( dir ) + 1;
00624     stg = HeapAlloc( GetProcessHeap(), 0, 
00625                      sizeof (ITSS_IStorageImpl) + len*sizeof(WCHAR) );
00626     stg->IStorage_iface.lpVtbl = &ITSS_IStorageImpl_Vtbl;
00627     stg->ref = 1;
00628     stg->chmfile = chmfile;
00629     strcpyW( stg->dir, dir );
00630 
00631     *ppstgOpen = &stg->IStorage_iface;
00632 
00633     ITSS_LockModule();
00634     return S_OK;
00635 }
00636 
00637 HRESULT ITSS_StgOpenStorage( 
00638     const WCHAR* pwcsName,
00639     IStorage* pstgPriority,
00640     DWORD grfMode,
00641     SNB snbExclude,
00642     DWORD reserved,
00643     IStorage** ppstgOpen)
00644 {
00645     struct chmFile *chmfile;
00646     static const WCHAR szRoot[] = { '/', 0 };
00647 
00648     TRACE("%s\n", debugstr_w(pwcsName) );
00649 
00650     chmfile = chm_openW( pwcsName );
00651     if( !chmfile )
00652         return E_FAIL;
00653 
00654     return ITSS_create_chm_storage( chmfile, szRoot, ppstgOpen );
00655 }
00656 
00657 /************************************************************************/
00658 
00659 static HRESULT WINAPI ITSS_IStream_QueryInterface(
00660     IStream* iface,
00661     REFIID riid,
00662     void** ppvObject)
00663 {
00664     IStream_Impl *This = impl_from_IStream(iface);
00665 
00666     if (IsEqualGUID(riid, &IID_IUnknown)
00667     || IsEqualGUID(riid, &IID_ISequentialStream)
00668     || IsEqualGUID(riid, &IID_IStream))
00669     {
00670     IStream_AddRef(iface);
00671     *ppvObject = This;
00672     return S_OK;
00673     }
00674 
00675     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
00676     return E_NOINTERFACE;
00677 }
00678 
00679 static ULONG WINAPI ITSS_IStream_AddRef(
00680     IStream* iface)
00681 {
00682     IStream_Impl *This = impl_from_IStream(iface);
00683     return InterlockedIncrement(&This->ref);
00684 }
00685 
00686 static ULONG WINAPI ITSS_IStream_Release(
00687     IStream* iface)
00688 {
00689     IStream_Impl *This = impl_from_IStream(iface);
00690 
00691     ULONG ref = InterlockedDecrement(&This->ref);
00692 
00693     if (ref == 0)
00694     {
00695         IStorage_Release( &This->stg->IStorage_iface );
00696         HeapFree(GetProcessHeap(), 0, This);
00697         ITSS_UnlockModule();
00698     }
00699 
00700     return ref;
00701 }
00702 
00703 static HRESULT WINAPI ITSS_IStream_Read(
00704         IStream* iface,
00705         void* pv,
00706         ULONG cb,
00707         ULONG* pcbRead)
00708 {
00709     IStream_Impl *This = impl_from_IStream(iface);
00710     ULONG count;
00711 
00712     TRACE("%p %p %u %p\n", This, pv, cb, pcbRead);
00713 
00714     count = chm_retrieve_object(This->stg->chmfile, 
00715                           &This->ui, pv, This->addr, cb);
00716     This->addr += count;
00717     if( pcbRead )
00718         *pcbRead = count;
00719 
00720     return count ? S_OK : S_FALSE;
00721 }
00722 
00723 static HRESULT WINAPI ITSS_IStream_Write(
00724         IStream* iface,
00725         const void* pv,
00726         ULONG cb,
00727         ULONG* pcbWritten)
00728 {
00729     FIXME("\n");
00730     return E_NOTIMPL;
00731 }
00732 
00733 static HRESULT WINAPI ITSS_IStream_Seek(
00734         IStream* iface,
00735         LARGE_INTEGER dlibMove,
00736         DWORD dwOrigin,
00737         ULARGE_INTEGER* plibNewPosition)
00738 {
00739     IStream_Impl *This = impl_from_IStream(iface);
00740     LONGLONG newpos;
00741 
00742     TRACE("%p %s %u %p\n", This,
00743           wine_dbgstr_longlong( dlibMove.QuadPart ), dwOrigin, plibNewPosition );
00744 
00745     newpos = This->addr;
00746     switch( dwOrigin )
00747     {
00748     case STREAM_SEEK_CUR:
00749         newpos = This->addr + dlibMove.QuadPart;
00750         break;
00751     case STREAM_SEEK_SET:
00752         newpos = dlibMove.QuadPart;
00753         break;
00754     case STREAM_SEEK_END:
00755         newpos = This->ui.length + dlibMove.QuadPart;
00756         break;
00757     }
00758 
00759     if( ( newpos < 0 ) || ( newpos > This->ui.length ) )
00760         return STG_E_INVALIDPOINTER;
00761 
00762     This->addr = newpos;
00763     if( plibNewPosition )
00764         plibNewPosition->QuadPart = This->addr;
00765 
00766     return S_OK;
00767 }
00768 
00769 static HRESULT WINAPI ITSS_IStream_SetSize(
00770         IStream* iface,
00771         ULARGE_INTEGER libNewSize)
00772 {
00773     FIXME("\n");
00774     return E_NOTIMPL;
00775 }
00776 
00777 static HRESULT WINAPI ITSS_IStream_CopyTo(
00778         IStream* iface,
00779         IStream* pstm,
00780         ULARGE_INTEGER cb,
00781         ULARGE_INTEGER* pcbRead,
00782         ULARGE_INTEGER* pcbWritten)
00783 {
00784     FIXME("\n");
00785     return E_NOTIMPL;
00786 }
00787 
00788 static HRESULT WINAPI ITSS_IStream_Commit(
00789         IStream* iface,
00790         DWORD grfCommitFlags)
00791 {
00792     FIXME("\n");
00793     return E_NOTIMPL;
00794 }
00795 
00796 static HRESULT WINAPI ITSS_IStream_Revert(
00797         IStream* iface)
00798 {
00799     FIXME("\n");
00800     return E_NOTIMPL;
00801 }
00802 
00803 static HRESULT WINAPI ITSS_IStream_LockRegion(
00804         IStream* iface,
00805         ULARGE_INTEGER libOffset,
00806         ULARGE_INTEGER cb,
00807         DWORD dwLockType)
00808 {
00809     FIXME("\n");
00810     return E_NOTIMPL;
00811 }
00812 
00813 static HRESULT WINAPI ITSS_IStream_UnlockRegion(
00814         IStream* iface,
00815         ULARGE_INTEGER libOffset,
00816         ULARGE_INTEGER cb,
00817         DWORD dwLockType)
00818 {
00819     FIXME("\n");
00820     return E_NOTIMPL;
00821 }
00822 
00823 static HRESULT WINAPI ITSS_IStream_Stat(
00824         IStream* iface,
00825         STATSTG* pstatstg,
00826         DWORD grfStatFlag)
00827 {
00828     IStream_Impl *This = impl_from_IStream(iface);
00829 
00830     TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);
00831 
00832     memset( pstatstg, 0, sizeof *pstatstg );
00833     if( !( grfStatFlag & STATFLAG_NONAME ) )
00834     {
00835         FIXME("copy the name\n");
00836     }
00837     pstatstg->type = STGTY_STREAM;
00838     pstatstg->cbSize.QuadPart = This->ui.length;
00839     pstatstg->grfMode = STGM_READ;
00840     pstatstg->clsid = CLSID_ITStorage;
00841 
00842     return S_OK;
00843 }
00844 
00845 static HRESULT WINAPI ITSS_IStream_Clone(
00846         IStream* iface,
00847         IStream** ppstm)
00848 {
00849     FIXME("\n");
00850     return E_NOTIMPL;
00851 }
00852 
00853 static const IStreamVtbl ITSS_IStream_vtbl =
00854 {
00855     ITSS_IStream_QueryInterface,
00856     ITSS_IStream_AddRef,
00857     ITSS_IStream_Release,
00858     ITSS_IStream_Read,
00859     ITSS_IStream_Write,
00860     ITSS_IStream_Seek,
00861     ITSS_IStream_SetSize,
00862     ITSS_IStream_CopyTo,
00863     ITSS_IStream_Commit,
00864     ITSS_IStream_Revert,
00865     ITSS_IStream_LockRegion,
00866     ITSS_IStream_UnlockRegion,
00867     ITSS_IStream_Stat,
00868     ITSS_IStream_Clone,
00869 };
00870 
00871 static IStream_Impl *ITSS_create_stream(
00872            ITSS_IStorageImpl *stg, struct chmUnitInfo *ui )
00873 {
00874     IStream_Impl *stm;
00875 
00876     stm = HeapAlloc( GetProcessHeap(), 0, sizeof (IStream_Impl) );
00877     stm->IStream_iface.lpVtbl = &ITSS_IStream_vtbl;
00878     stm->ref = 1;
00879     stm->addr = 0;
00880     stm->ui = *ui;
00881     stm->stg = stg;
00882     IStorage_AddRef( &stg->IStorage_iface );
00883 
00884     ITSS_LockModule();
00885 
00886     TRACE(" -> %p\n", stm );
00887 
00888     return stm;
00889 }

Generated on Fri May 25 2012 04:21:26 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.