comdlg32: DPRINTF -> TRACE.
[wine] / dlls / itss / storage.c
CommitLineData
5f6e3c88
AJ
1/*
2 * ITSS Storage implementation
3 *
4 * Copyright 2004 Mike McCormack
5 *
6 * see http://bonedaddy.net/pabs3/hhm/#chmspec
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
360a3f91 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
5f6e3c88
AJ
21 */
22
23#include "config.h"
24
25#include <stdarg.h>
26#include <stdio.h>
27
486d020c
FG
28#define COBJMACROS
29
5f6e3c88
AJ
30#include "windef.h"
31#include "winbase.h"
32#include "winuser.h"
5f6e3c88
AJ
33#include "ole2.h"
34
5f6e3c88 35#include "chm_lib.h"
332408b8 36#include "itsstor.h"
5f6e3c88 37
5a07e6ed 38#include "wine/itss.h"
5f6e3c88
AJ
39#include "wine/unicode.h"
40#include "wine/debug.h"
41
42WINE_DEFAULT_DEBUG_CHANNEL(itss);
43
44/************************************************************************/
45
46typedef struct _ITSS_IStorageImpl
47{
b67da5b9 48 const IStorageVtbl *vtbl_IStorage;
bda7ace2 49 LONG ref;
5f6e3c88
AJ
50 struct chmFile *chmfile;
51 WCHAR dir[1];
52} ITSS_IStorageImpl;
53
54struct enum_info
55{
56 struct enum_info *next, *prev;
57 struct chmUnitInfo ui;
58};
59
60typedef struct _IEnumSTATSTG_Impl
61{
b67da5b9 62 const IEnumSTATSTGVtbl *vtbl_IEnumSTATSTG;
bda7ace2 63 LONG ref;
5f6e3c88
AJ
64 struct enum_info *first, *last, *current;
65} IEnumSTATSTG_Impl;
66
67typedef struct _IStream_Impl
68{
b67da5b9 69 const IStreamVtbl *vtbl_IStream;
bda7ace2 70 LONG ref;
5f6e3c88
AJ
71 ITSS_IStorageImpl *stg;
72 ULONGLONG addr;
73 struct chmUnitInfo ui;
74} IStream_Impl;
75
76static HRESULT ITSS_create_chm_storage(
77 struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen );
78static IStream_Impl* ITSS_create_stream(
79 ITSS_IStorageImpl *stg, struct chmUnitInfo *ui );
80
81/************************************************************************/
82
83static HRESULT WINAPI ITSS_IEnumSTATSTG_QueryInterface(
84 IEnumSTATSTG* iface,
85 REFIID riid,
86 void** ppvObject)
87{
39a696a1 88 IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
5f6e3c88
AJ
89
90 if (IsEqualGUID(riid, &IID_IUnknown)
91 || IsEqualGUID(riid, &IID_IEnumSTATSTG))
92 {
93 IEnumSTATSTG_AddRef(iface);
94 *ppvObject = This;
95 return S_OK;
96 }
97
98 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
99 return E_NOINTERFACE;
100}
101
102static ULONG WINAPI ITSS_IEnumSTATSTG_AddRef(
103 IEnumSTATSTG* iface)
104{
39a696a1 105 IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
a8d9c87c 106 return InterlockedIncrement(&This->ref);
5f6e3c88
AJ
107}
108
109static ULONG WINAPI ITSS_IEnumSTATSTG_Release(
110 IEnumSTATSTG* iface)
111{
39a696a1 112 IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
5f6e3c88 113
a8d9c87c 114 ULONG ref = InterlockedDecrement(&This->ref);
5f6e3c88
AJ
115
116 if (ref == 0)
117 {
118 while( This->first )
119 {
120 struct enum_info *t = This->first->next;
121 HeapFree( GetProcessHeap(), 0, This->first );
122 This->first = t;
123 }
a8d9c87c 124 HeapFree(GetProcessHeap(), 0, This);
162b3350 125 ITSS_UnlockModule();
5f6e3c88
AJ
126 }
127
128 return ref;
129}
130
131static HRESULT WINAPI ITSS_IEnumSTATSTG_Next(
132 IEnumSTATSTG* iface,
133 ULONG celt,
134 STATSTG* rgelt,
135 ULONG* pceltFetched)
136{
39a696a1 137 IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
5f6e3c88
AJ
138 DWORD len, n;
139 struct enum_info *cur;
140
2492abbb 141 TRACE("%p %u %p %p\n", This, celt, rgelt, pceltFetched );
5f6e3c88
AJ
142
143 cur = This->current;
144 n = 0;
145 while( (n<celt) && cur)
146 {
147 WCHAR *str;
148
149 memset( rgelt, 0, sizeof *rgelt );
150
151 /* copy the name */
152 str = cur->ui.path;
153 if( *str == '/' )
154 str++;
155 len = strlenW( str ) + 1;
156 rgelt->pwcsName = CoTaskMemAlloc( len*sizeof(WCHAR) );
157 strcpyW( rgelt->pwcsName, str );
158
159 /* determine the type */
160 if( rgelt->pwcsName[len-2] == '/' )
161 {
162 rgelt->pwcsName[len-2] = 0;
163 rgelt->type = STGTY_STORAGE;
164 }
165 else
166 rgelt->type = STGTY_STREAM;
167
168 /* copy the size */
169 rgelt->cbSize.QuadPart = cur->ui.length;
170
171 /* advance to the next item if it exists */
172 n++;
173 cur = cur->next;
174 }
175
176 This->current = cur;
177 *pceltFetched = n;
178
179 if( n < celt )
180 return S_FALSE;
181
182 return S_OK;
183}
184
185static HRESULT WINAPI ITSS_IEnumSTATSTG_Skip(
186 IEnumSTATSTG* iface,
187 ULONG celt)
188{
39a696a1 189 IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
5f6e3c88
AJ
190 DWORD n;
191 struct enum_info *cur;
192
2492abbb 193 TRACE("%p %u\n", This, celt );
5f6e3c88
AJ
194
195 cur = This->current;
196 n = 0;
197 while( (n<celt) && cur)
198 {
199 n++;
200 cur = cur->next;
201 }
202 This->current = cur;
203
204 if( n < celt )
205 return S_FALSE;
206
207 return S_OK;
208}
209
210static HRESULT WINAPI ITSS_IEnumSTATSTG_Reset(
211 IEnumSTATSTG* iface)
212{
39a696a1 213 IEnumSTATSTG_Impl *This = (IEnumSTATSTG_Impl *)iface;
5f6e3c88
AJ
214
215 TRACE("%p\n", This );
216
217 This->current = This->first;
218
219 return S_OK;
220}
221
222static HRESULT WINAPI ITSS_IEnumSTATSTG_Clone(
223 IEnumSTATSTG* iface,
224 IEnumSTATSTG** ppenum)
225{
226 FIXME("\n");
227 return E_NOTIMPL;
228}
229
b67da5b9 230static const IEnumSTATSTGVtbl IEnumSTATSTG_vtbl =
5f6e3c88
AJ
231{
232 ITSS_IEnumSTATSTG_QueryInterface,
233 ITSS_IEnumSTATSTG_AddRef,
234 ITSS_IEnumSTATSTG_Release,
235 ITSS_IEnumSTATSTG_Next,
236 ITSS_IEnumSTATSTG_Skip,
237 ITSS_IEnumSTATSTG_Reset,
238 ITSS_IEnumSTATSTG_Clone
239};
240
241static IEnumSTATSTG_Impl *ITSS_create_enum( void )
242{
243 IEnumSTATSTG_Impl *stgenum;
244
245 stgenum = HeapAlloc( GetProcessHeap(), 0, sizeof (IEnumSTATSTG_Impl) );
246 stgenum->vtbl_IEnumSTATSTG = &IEnumSTATSTG_vtbl;
247 stgenum->ref = 1;
248 stgenum->first = NULL;
249 stgenum->last = NULL;
250 stgenum->current = NULL;
251
162b3350 252 ITSS_LockModule();
5f6e3c88
AJ
253 TRACE(" -> %p\n", stgenum );
254
255 return stgenum;
256}
257
258/************************************************************************/
259
383302c1 260static HRESULT WINAPI ITSS_IStorageImpl_QueryInterface(
5f6e3c88
AJ
261 IStorage* iface,
262 REFIID riid,
263 void** ppvObject)
264{
39a696a1 265 ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
5f6e3c88
AJ
266
267 if (IsEqualGUID(riid, &IID_IUnknown)
268 || IsEqualGUID(riid, &IID_IStorage))
269 {
270 IStorage_AddRef(iface);
271 *ppvObject = This;
272 return S_OK;
273 }
274
275 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
276 return E_NOINTERFACE;
277}
278
383302c1 279static ULONG WINAPI ITSS_IStorageImpl_AddRef(
5f6e3c88
AJ
280 IStorage* iface)
281{
39a696a1 282 ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
a8d9c87c 283 return InterlockedIncrement(&This->ref);
5f6e3c88
AJ
284}
285
383302c1 286static ULONG WINAPI ITSS_IStorageImpl_Release(
5f6e3c88
AJ
287 IStorage* iface)
288{
39a696a1 289 ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
5f6e3c88 290
a8d9c87c 291 ULONG ref = InterlockedDecrement(&This->ref);
5f6e3c88
AJ
292
293 if (ref == 0)
294 {
05d2aa45 295 chm_close(This->chmfile);
a8d9c87c 296 HeapFree(GetProcessHeap(), 0, This);
162b3350 297 ITSS_UnlockModule();
5f6e3c88
AJ
298 }
299
300 return ref;
301}
302
383302c1 303static HRESULT WINAPI ITSS_IStorageImpl_CreateStream(
5f6e3c88
AJ
304 IStorage* iface,
305 LPCOLESTR pwcsName,
306 DWORD grfMode,
307 DWORD reserved1,
308 DWORD reserved2,
309 IStream** ppstm)
310{
311 FIXME("\n");
312 return E_NOTIMPL;
313}
314
383302c1 315static HRESULT WINAPI ITSS_IStorageImpl_OpenStream(
5f6e3c88
AJ
316 IStorage* iface,
317 LPCOLESTR pwcsName,
318 void* reserved1,
319 DWORD grfMode,
320 DWORD reserved2,
321 IStream** ppstm)
322{
39a696a1 323 ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
5f6e3c88
AJ
324 IStream_Impl *stm;
325 DWORD len;
326 struct chmUnitInfo ui;
327 int r;
18632c2b 328 WCHAR *path, *p;
5f6e3c88 329
2492abbb 330 TRACE("%p %s %p %u %u %p\n", This, debugstr_w(pwcsName),
5f6e3c88
AJ
331 reserved1, grfMode, reserved2, ppstm );
332
333 len = strlenW( This->dir ) + strlenW( pwcsName ) + 1;
334 path = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
335 strcpyW( path, This->dir );
18632c2b
JC
336
337 if( pwcsName[0] == '/' || pwcsName[0] == '\\' )
332408b8 338 {
18632c2b 339 p = &path[strlenW( path ) - 1];
eefb72c8 340 while( ( path <= p ) && ( *p == '/' ) )
332408b8
MM
341 *p-- = 0;
342 }
5f6e3c88
AJ
343 strcatW( path, pwcsName );
344
18632c2b
JC
345 for(p=path; *p; p++) {
346 if(*p == '\\')
347 *p = '/';
348 }
349
ff0a6136
JC
350 if(*--p == '/')
351 *p = 0;
352
332408b8
MM
353 TRACE("Resolving %s\n", debugstr_w(path));
354
5f6e3c88
AJ
355 r = chm_resolve_object(This->chmfile, path, &ui);
356 HeapFree( GetProcessHeap(), 0, path );
357
18632c2b
JC
358 if( r != CHM_RESOLVE_SUCCESS ) {
359 WARN("Could not resolve object\n");
5f6e3c88 360 return STG_E_FILENOTFOUND;
18632c2b 361 }
5f6e3c88
AJ
362
363 stm = ITSS_create_stream( This, &ui );
364 if( !stm )
365 return E_FAIL;
366
367 *ppstm = (IStream*) stm;
368
369 return S_OK;
370}
371
383302c1 372static HRESULT WINAPI ITSS_IStorageImpl_CreateStorage(
5f6e3c88
AJ
373 IStorage* iface,
374 LPCOLESTR pwcsName,
375 DWORD grfMode,
376 DWORD dwStgFmt,
377 DWORD reserved2,
378 IStorage** ppstg)
379{
380 FIXME("\n");
381 return E_NOTIMPL;
382}
383
383302c1 384static HRESULT WINAPI ITSS_IStorageImpl_OpenStorage(
5f6e3c88
AJ
385 IStorage* iface,
386 LPCOLESTR pwcsName,
387 IStorage* pstgPriority,
388 DWORD grfMode,
389 SNB snbExclude,
390 DWORD reserved,
391 IStorage** ppstg)
392{
39a696a1 393 ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
332408b8 394
2492abbb 395 FIXME("%p %s %p %u %p %u %p\n", This, debugstr_w(pwcsName),
332408b8 396 pstgPriority, grfMode, snbExclude, reserved, ppstg);
5f6e3c88
AJ
397 return E_NOTIMPL;
398}
399
383302c1 400static HRESULT WINAPI ITSS_IStorageImpl_CopyTo(
5f6e3c88
AJ
401 IStorage* iface,
402 DWORD ciidExclude,
403 const IID* rgiidExclude,
404 SNB snbExclude,
405 IStorage* pstgDest)
406{
407 FIXME("\n");
408 return E_NOTIMPL;
409}
410
383302c1 411static HRESULT WINAPI ITSS_IStorageImpl_MoveElementTo(
5f6e3c88
AJ
412 IStorage* iface,
413 LPCOLESTR pwcsName,
414 IStorage* pstgDest,
415 LPCOLESTR pwcsNewName,
416 DWORD grfFlags)
417{
418 FIXME("\n");
419 return E_NOTIMPL;
420}
421
383302c1 422static HRESULT WINAPI ITSS_IStorageImpl_Commit(
5f6e3c88
AJ
423 IStorage* iface,
424 DWORD grfCommitFlags)
425{
426 FIXME("\n");
427 return E_NOTIMPL;
428}
429
383302c1 430static HRESULT WINAPI ITSS_IStorageImpl_Revert(
5f6e3c88
AJ
431 IStorage* iface)
432{
433 FIXME("\n");
434 return E_NOTIMPL;
435}
436
437static int ITSS_chm_enumerator(
438 struct chmFile *h,
439 struct chmUnitInfo *ui,
440 void *context)
441{
442 struct enum_info *info;
443 IEnumSTATSTG_Impl* stgenum = context;
444
445 TRACE("adding %s to enumeration\n", debugstr_w(ui->path) );
446
447 info = HeapAlloc( GetProcessHeap(), 0, sizeof (struct enum_info) );
448 memcpy( &info->ui, ui, sizeof info->ui );
449
450 info->next = NULL;
451 info->prev = stgenum->last;
452 if( stgenum->last )
453 stgenum->last->next = info;
454 else
455 stgenum->first = info;
456 stgenum->last = info;
457
458 return CHM_ENUMERATOR_CONTINUE;
459}
460
383302c1 461static HRESULT WINAPI ITSS_IStorageImpl_EnumElements(
5f6e3c88
AJ
462 IStorage* iface,
463 DWORD reserved1,
464 void* reserved2,
465 DWORD reserved3,
466 IEnumSTATSTG** ppenum)
467{
39a696a1 468 ITSS_IStorageImpl *This = (ITSS_IStorageImpl *)iface;
5f6e3c88
AJ
469 IEnumSTATSTG_Impl* stgenum;
470
2492abbb 471 TRACE("%p %d %p %d %p\n", This, reserved1, reserved2, reserved3, ppenum );
5f6e3c88
AJ
472
473 stgenum = ITSS_create_enum();
474 if( !stgenum )
475 return E_FAIL;
476
477 chm_enumerate_dir(This->chmfile,
478 This->dir,
479 CHM_ENUMERATE_ALL,
480 ITSS_chm_enumerator,
481 stgenum );
482
483 stgenum->current = stgenum->first;
484
485 *ppenum = (IEnumSTATSTG*) stgenum;
486
487 return S_OK;
488}
489
383302c1 490static HRESULT WINAPI ITSS_IStorageImpl_DestroyElement(
5f6e3c88
AJ
491 IStorage* iface,
492 LPCOLESTR pwcsName)
493{
494 FIXME("\n");
495 return E_NOTIMPL;
496}
497
383302c1 498static HRESULT WINAPI ITSS_IStorageImpl_RenameElement(
5f6e3c88
AJ
499 IStorage* iface,
500 LPCOLESTR pwcsOldName,
501 LPCOLESTR pwcsNewName)
502{
503 FIXME("\n");
504 return E_NOTIMPL;
505}
506
383302c1 507static HRESULT WINAPI ITSS_IStorageImpl_SetElementTimes(
5f6e3c88
AJ
508 IStorage* iface,
509 LPCOLESTR pwcsName,
510 const FILETIME* pctime,
511 const FILETIME* patime,
512 const FILETIME* pmtime)
513{
514 FIXME("\n");
515 return E_NOTIMPL;
516}
517
383302c1 518static HRESULT WINAPI ITSS_IStorageImpl_SetClass(
5f6e3c88
AJ
519 IStorage* iface,
520 REFCLSID clsid)
521{
522 FIXME("\n");
523 return E_NOTIMPL;
524}
525
383302c1 526static HRESULT WINAPI ITSS_IStorageImpl_SetStateBits(
5f6e3c88
AJ
527 IStorage* iface,
528 DWORD grfStateBits,
529 DWORD grfMask)
530{
531 FIXME("\n");
532 return E_NOTIMPL;
533}
534
383302c1 535static HRESULT WINAPI ITSS_IStorageImpl_Stat(
5f6e3c88
AJ
536 IStorage* iface,
537 STATSTG* pstatstg,
538 DWORD grfStatFlag)
539{
540 FIXME("\n");
541 return E_NOTIMPL;
542}
543
b67da5b9 544static const IStorageVtbl ITSS_IStorageImpl_Vtbl =
5f6e3c88
AJ
545{
546 ITSS_IStorageImpl_QueryInterface,
547 ITSS_IStorageImpl_AddRef,
548 ITSS_IStorageImpl_Release,
549 ITSS_IStorageImpl_CreateStream,
550 ITSS_IStorageImpl_OpenStream,
551 ITSS_IStorageImpl_CreateStorage,
552 ITSS_IStorageImpl_OpenStorage,
553 ITSS_IStorageImpl_CopyTo,
554 ITSS_IStorageImpl_MoveElementTo,
555 ITSS_IStorageImpl_Commit,
556 ITSS_IStorageImpl_Revert,
557 ITSS_IStorageImpl_EnumElements,
558 ITSS_IStorageImpl_DestroyElement,
559 ITSS_IStorageImpl_RenameElement,
560 ITSS_IStorageImpl_SetElementTimes,
561 ITSS_IStorageImpl_SetClass,
562 ITSS_IStorageImpl_SetStateBits,
563 ITSS_IStorageImpl_Stat,
564};
565
566static HRESULT ITSS_create_chm_storage(
567 struct chmFile *chmfile, const WCHAR *dir, IStorage** ppstgOpen )
568{
569 ITSS_IStorageImpl *stg;
570 DWORD len;
571
572 TRACE("%p %s\n", chmfile, debugstr_w( dir ) );
573
574 len = strlenW( dir ) + 1;
575 stg = HeapAlloc( GetProcessHeap(), 0,
576 sizeof (ITSS_IStorageImpl) + len*sizeof(WCHAR) );
577 stg->vtbl_IStorage = &ITSS_IStorageImpl_Vtbl;
578 stg->ref = 1;
579 stg->chmfile = chmfile;
580 strcpyW( stg->dir, dir );
581
582 *ppstgOpen = (IStorage*) stg;
583
162b3350 584 ITSS_LockModule();
5f6e3c88
AJ
585 return S_OK;
586}
587
588HRESULT ITSS_StgOpenStorage(
589 const WCHAR* pwcsName,
590 IStorage* pstgPriority,
591 DWORD grfMode,
592 SNB snbExclude,
593 DWORD reserved,
594 IStorage** ppstgOpen)
595{
596 struct chmFile *chmfile;
597 static const WCHAR szRoot[] = { '/', 0 };
598
599 TRACE("%s\n", debugstr_w(pwcsName) );
600
601 chmfile = chm_openW( pwcsName );
602 if( !chmfile )
603 return E_FAIL;
604
605 return ITSS_create_chm_storage( chmfile, szRoot, ppstgOpen );
606}
607
608/************************************************************************/
609
610static HRESULT WINAPI ITSS_IStream_QueryInterface(
611 IStream* iface,
612 REFIID riid,
613 void** ppvObject)
614{
39a696a1 615 IStream_Impl *This = (IStream_Impl *)iface;
5f6e3c88
AJ
616
617 if (IsEqualGUID(riid, &IID_IUnknown)
618 || IsEqualGUID(riid, &IID_ISequentialStream)
619 || IsEqualGUID(riid, &IID_IStream))
620 {
621 IStream_AddRef(iface);
622 *ppvObject = This;
623 return S_OK;
624 }
625
626 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppvObject);
627 return E_NOINTERFACE;
628}
629
630static ULONG WINAPI ITSS_IStream_AddRef(
631 IStream* iface)
632{
39a696a1 633 IStream_Impl *This = (IStream_Impl *)iface;
a8d9c87c 634 return InterlockedIncrement(&This->ref);
5f6e3c88
AJ
635}
636
637static ULONG WINAPI ITSS_IStream_Release(
638 IStream* iface)
639{
39a696a1 640 IStream_Impl *This = (IStream_Impl *)iface;
5f6e3c88 641
a8d9c87c 642 ULONG ref = InterlockedDecrement(&This->ref);
5f6e3c88
AJ
643
644 if (ref == 0)
645 {
646 IStorage_Release( (IStorage*) This->stg );
162b3350
JC
647 HeapFree(GetProcessHeap(), 0, This);
648 ITSS_UnlockModule();
5f6e3c88
AJ
649 }
650
651 return ref;
652}
653
654static HRESULT WINAPI ITSS_IStream_Read(
655 IStream* iface,
656 void* pv,
657 ULONG cb,
658 ULONG* pcbRead)
659{
39a696a1 660 IStream_Impl *This = (IStream_Impl *)iface;
5f6e3c88
AJ
661 ULONG count;
662
2492abbb 663 TRACE("%p %p %u %p\n", This, pv, cb, pcbRead);
5f6e3c88
AJ
664
665 count = chm_retrieve_object(This->stg->chmfile,
666 &This->ui, pv, This->addr, cb);
667 This->addr += count;
668 if( pcbRead )
669 *pcbRead = count;
18632c2b 670
f925e0c0 671 return count ? S_OK : S_FALSE;
5f6e3c88
AJ
672}
673
674static HRESULT WINAPI ITSS_IStream_Write(
675 IStream* iface,
676 const void* pv,
677 ULONG cb,
678 ULONG* pcbWritten)
679{
680 FIXME("\n");
681 return E_NOTIMPL;
682}
683
684static HRESULT WINAPI ITSS_IStream_Seek(
685 IStream* iface,
686 LARGE_INTEGER dlibMove,
687 DWORD dwOrigin,
688 ULARGE_INTEGER* plibNewPosition)
689{
39a696a1 690 IStream_Impl *This = (IStream_Impl *)iface;
5f6e3c88
AJ
691 LONGLONG newpos;
692
2492abbb 693 TRACE("%p %s %u %p\n", This,
5f6e3c88
AJ
694 wine_dbgstr_longlong( dlibMove.QuadPart ), dwOrigin, plibNewPosition );
695
696 newpos = This->addr;
697 switch( dwOrigin )
698 {
699 case STREAM_SEEK_CUR:
700 newpos = This->addr + dlibMove.QuadPart;
701 break;
702 case STREAM_SEEK_SET:
703 newpos = dlibMove.QuadPart;
704 break;
705 case STREAM_SEEK_END:
706 newpos = This->ui.length + dlibMove.QuadPart;
707 break;
708 }
709
710 if( ( newpos < 0 ) || ( newpos > This->ui.length ) )
711 return STG_E_INVALIDPOINTER;
712
713 This->addr = newpos;
714 if( plibNewPosition )
715 plibNewPosition->QuadPart = This->addr;
716
717 return S_OK;
718}
719
720static HRESULT WINAPI ITSS_IStream_SetSize(
721 IStream* iface,
722 ULARGE_INTEGER libNewSize)
723{
724 FIXME("\n");
725 return E_NOTIMPL;
726}
727
728static HRESULT WINAPI ITSS_IStream_CopyTo(
729 IStream* iface,
730 IStream* pstm,
731 ULARGE_INTEGER cb,
732 ULARGE_INTEGER* pcbRead,
733 ULARGE_INTEGER* pcbWritten)
734{
735 FIXME("\n");
736 return E_NOTIMPL;
737}
738
739static HRESULT WINAPI ITSS_IStream_Commit(
740 IStream* iface,
741 DWORD grfCommitFlags)
742{
743 FIXME("\n");
744 return E_NOTIMPL;
745}
746
747static HRESULT WINAPI ITSS_IStream_Revert(
748 IStream* iface)
749{
750 FIXME("\n");
751 return E_NOTIMPL;
752}
753
754static HRESULT WINAPI ITSS_IStream_LockRegion(
755 IStream* iface,
756 ULARGE_INTEGER libOffset,
757 ULARGE_INTEGER cb,
758 DWORD dwLockType)
759{
760 FIXME("\n");
761 return E_NOTIMPL;
762}
763
764static HRESULT WINAPI ITSS_IStream_UnlockRegion(
765 IStream* iface,
766 ULARGE_INTEGER libOffset,
767 ULARGE_INTEGER cb,
768 DWORD dwLockType)
769{
770 FIXME("\n");
771 return E_NOTIMPL;
772}
773
774static HRESULT WINAPI ITSS_IStream_Stat(
775 IStream* iface,
776 STATSTG* pstatstg,
777 DWORD grfStatFlag)
778{
39a696a1 779 IStream_Impl *This = (IStream_Impl *)iface;
332408b8 780
2492abbb 781 TRACE("%p %p %d\n", This, pstatstg, grfStatFlag);
332408b8
MM
782
783 memset( pstatstg, 0, sizeof *pstatstg );
784 if( !( grfStatFlag & STATFLAG_NONAME ) )
785 {
786 FIXME("copy the name\n");
787 }
788 pstatstg->type = STGTY_STREAM;
789 pstatstg->cbSize.QuadPart = This->ui.length;
790 pstatstg->grfMode = STGM_READ;
791 memcpy( &pstatstg->clsid, &CLSID_ITStorage, sizeof (CLSID) );
792
793 return S_OK;
5f6e3c88
AJ
794}
795
796static HRESULT WINAPI ITSS_IStream_Clone(
797 IStream* iface,
798 IStream** ppstm)
799{
800 FIXME("\n");
801 return E_NOTIMPL;
802}
803
b67da5b9 804static const IStreamVtbl ITSS_IStream_vtbl =
5f6e3c88
AJ
805{
806 ITSS_IStream_QueryInterface,
807 ITSS_IStream_AddRef,
808 ITSS_IStream_Release,
809 ITSS_IStream_Read,
810 ITSS_IStream_Write,
811 ITSS_IStream_Seek,
812 ITSS_IStream_SetSize,
813 ITSS_IStream_CopyTo,
814 ITSS_IStream_Commit,
815 ITSS_IStream_Revert,
816 ITSS_IStream_LockRegion,
817 ITSS_IStream_UnlockRegion,
818 ITSS_IStream_Stat,
819 ITSS_IStream_Clone,
820};
821
822static IStream_Impl *ITSS_create_stream(
823 ITSS_IStorageImpl *stg, struct chmUnitInfo *ui )
824{
825 IStream_Impl *stm;
826
827 stm = HeapAlloc( GetProcessHeap(), 0, sizeof (IStream_Impl) );
828 stm->vtbl_IStream = &ITSS_IStream_vtbl;
829 stm->ref = 1;
830 stm->addr = 0;
831 memcpy( &stm->ui, ui, sizeof stm->ui );
832 stm->stg = stg;
833 IStorage_AddRef( (IStorage*) stg );
162b3350
JC
834
835 ITSS_LockModule();
5f6e3c88
AJ
836
837 TRACE(" -> %p\n", stm );
838
839 return stm;
840}