Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenstorage.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
1.7.6.1
|