1 /* IDirectMusicWave Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "dswave_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dswave
);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile
);
25 /* an interface that is, according to my tests, obtained by loader after loading object; is it acting
26 as some sort of bridge between object and loader? */
27 static const GUID IID_IDirectMusicWavePRIVATE
= {0x69e934e4,0x97f1,0x4f1d,{0x88,0xe8,0xf2,0xac,0x88,0x67,0x13,0x27}};
29 /*****************************************************************************
30 * IDirectMusicWaveImpl implementation
32 typedef struct IDirectMusicWaveImpl
{
33 IUnknown IUnknown_iface
;
34 const IDirectMusicObjectVtbl
*ObjectVtbl
;
35 const IPersistStreamVtbl
*PersistStreamVtbl
;
37 LPDMUS_OBJECTDESC pDesc
;
38 } IDirectMusicWaveImpl
;
40 /* IDirectMusicWaveImpl IUnknown part: */
41 static inline IDirectMusicWaveImpl
*impl_from_IUnknown(IUnknown
*iface
)
43 return CONTAINING_RECORD(iface
, IDirectMusicWaveImpl
, IUnknown_iface
);
46 static HRESULT WINAPI
IUnknownImpl_QueryInterface(IUnknown
*iface
, REFIID riid
, void **ret_iface
)
48 IDirectMusicWaveImpl
*This
= impl_from_IUnknown(iface
);
50 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ret_iface
);
54 if (IsEqualIID(riid
, &IID_IUnknown
))
56 else if (IsEqualIID(riid
, &IID_IDirectMusicObject
))
57 *ret_iface
= &This
->ObjectVtbl
;
58 else if (IsEqualIID(riid
, &IID_IPersistStream
))
59 *ret_iface
= &This
->PersistStreamVtbl
;
60 else if (IsEqualIID(riid
, &IID_IDirectMusicWavePRIVATE
)) {
61 FIXME("(%p, %s, %p): Unsupported private interface\n", This
, debugstr_guid(riid
), ret_iface
);
64 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ret_iface
);
68 IUnknown_AddRef((IUnknown
*)*ret_iface
);
72 static ULONG WINAPI
IUnknownImpl_AddRef(IUnknown
*iface
)
74 IDirectMusicWaveImpl
*This
= impl_from_IUnknown(iface
);
75 LONG ref
= InterlockedIncrement(&This
->ref
);
77 TRACE("(%p) ref=%d\n", This
, ref
);
82 static ULONG WINAPI
IUnknownImpl_Release(IUnknown
*iface
)
84 IDirectMusicWaveImpl
*This
= impl_from_IUnknown(iface
);
85 LONG ref
= InterlockedDecrement(&This
->ref
);
87 TRACE("(%p) ref=%d\n", This
, ref
);
90 HeapFree(GetProcessHeap(), 0, This
->pDesc
);
91 HeapFree(GetProcessHeap(), 0, This
);
92 DSWAVE_UnlockModule();
98 static const IUnknownVtbl unknown_vtbl
= {
99 IUnknownImpl_QueryInterface
,
104 /* IDirectMusicWaveImpl IDirectMusicObject part: */
105 static HRESULT WINAPI
IDirectMusicWaveImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface
, REFIID riid
, LPVOID
*ppobj
) {
106 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, ObjectVtbl
, iface
);
107 return IUnknown_QueryInterface(&This
->IUnknown_iface
, riid
, ppobj
);
110 static ULONG WINAPI
IDirectMusicWaveImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface
) {
111 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, ObjectVtbl
, iface
);
112 return IUnknown_AddRef(&This
->IUnknown_iface
);
115 static ULONG WINAPI
IDirectMusicWaveImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface
) {
116 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, ObjectVtbl
, iface
);
117 return IUnknown_Release(&This
->IUnknown_iface
);
120 static HRESULT WINAPI
IDirectMusicWaveImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
121 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, ObjectVtbl
, iface
);
122 TRACE("(%p, %p)\n", This
, pDesc
);
123 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
124 memcpy (pDesc
, This
->pDesc
, This
->pDesc
->dwSize
);
128 static HRESULT WINAPI
IDirectMusicWaveImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
129 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, ObjectVtbl
, iface
);
130 TRACE("(%p, %p, %s): setting descriptor:\n", This
, pDesc
, debugstr_DMUS_OBJECTDESC(pDesc
));
132 /* According to MSDN, we should copy only given values, not whole struct */
133 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
134 This
->pDesc
->guidObject
= pDesc
->guidObject
;
135 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
136 This
->pDesc
->guidClass
= pDesc
->guidClass
;
137 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
138 lstrcpynW (This
->pDesc
->wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
139 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
140 lstrcpynW (This
->pDesc
->wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
141 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
142 lstrcpynW (This
->pDesc
->wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
143 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
144 This
->pDesc
->vVersion
= pDesc
->vVersion
;
145 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
146 This
->pDesc
->ftDate
= pDesc
->ftDate
;
147 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
) {
148 This
->pDesc
->llMemLength
= pDesc
->llMemLength
;
149 memcpy (This
->pDesc
->pbMemData
, pDesc
->pbMemData
, pDesc
->llMemLength
);
151 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
) {
152 /* according to MSDN, we copy the stream */
153 IStream_Clone (pDesc
->pStream
, &This
->pDesc
->pStream
);
157 This
->pDesc
->dwValidData
|= pDesc
->dwValidData
;
162 static HRESULT WINAPI
IDirectMusicWaveImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface
, LPSTREAM pStream
, LPDMUS_OBJECTDESC pDesc
) {
163 DMUS_PRIVATE_CHUNK Chunk
;
164 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
165 LARGE_INTEGER liMove
; /* used when skipping chunks */
167 TRACE("(%p, %p)\n", pStream
, pDesc
);
169 /* FIXME: should this be determined from stream? */
170 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
171 pDesc
->guidClass
= CLSID_DirectMusicSegment
;
173 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
174 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
175 switch (Chunk
.fccID
) {
177 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
178 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
179 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
181 if (Chunk
.fccID
== mmioFOURCC('W','A','V','E')) {
182 TRACE_(dmfile
)(": wave form\n");
184 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
185 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
186 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
187 switch (Chunk
.fccID
) {
188 case DMUS_FOURCC_GUID_CHUNK
: {
189 TRACE_(dmfile
)(": GUID chunk\n");
190 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
191 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
194 case DMUS_FOURCC_VERSION_CHUNK
: {
195 TRACE_(dmfile
)(": version chunk\n");
196 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
197 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
200 case DMUS_FOURCC_CATEGORY_CHUNK
: {
201 TRACE_(dmfile
)(": category chunk\n");
202 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
203 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
207 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
208 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
209 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
211 switch (Chunk
.fccID
) {
212 /* evil M$ UNFO list, which can (!?) contain INFO elements */
213 case DMUS_FOURCC_UNFO_LIST
: {
214 TRACE_(dmfile
)(": UNFO list\n");
216 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
217 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
218 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
219 switch (Chunk
.fccID
) {
220 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
221 (though strings seem to be valid unicode) */
222 case mmioFOURCC('I','N','A','M'):
223 case DMUS_FOURCC_UNAM_CHUNK
: {
224 TRACE_(dmfile
)(": name chunk\n");
225 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
226 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
229 case mmioFOURCC('I','A','R','T'):
230 case DMUS_FOURCC_UART_CHUNK
: {
231 TRACE_(dmfile
)(": artist chunk (ignored)\n");
232 liMove
.QuadPart
= Chunk
.dwSize
;
233 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
236 case mmioFOURCC('I','C','O','P'):
237 case DMUS_FOURCC_UCOP_CHUNK
: {
238 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
239 liMove
.QuadPart
= Chunk
.dwSize
;
240 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
243 case mmioFOURCC('I','S','B','J'):
244 case DMUS_FOURCC_USBJ_CHUNK
: {
245 TRACE_(dmfile
)(": subject chunk (ignored)\n");
246 liMove
.QuadPart
= Chunk
.dwSize
;
247 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
250 case mmioFOURCC('I','C','M','T'):
251 case DMUS_FOURCC_UCMT_CHUNK
: {
252 TRACE_(dmfile
)(": comment chunk (ignored)\n");
253 liMove
.QuadPart
= Chunk
.dwSize
;
254 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
258 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
259 liMove
.QuadPart
= Chunk
.dwSize
;
260 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
264 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
265 } while (ListCount
[0] < ListSize
[0]);
269 TRACE_(dmfile
)(": unknown (skipping)\n");
270 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
271 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
278 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
279 liMove
.QuadPart
= Chunk
.dwSize
;
280 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
284 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
285 } while (StreamCount
< StreamSize
);
287 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
288 liMove
.QuadPart
= StreamSize
;
289 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
293 TRACE_(dmfile
)(": reading finished\n");
297 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
298 liMove
.QuadPart
= Chunk
.dwSize
;
299 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
300 return DMUS_E_INVALIDFILE
;
304 TRACE(": returning descriptor: %s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
309 static const IDirectMusicObjectVtbl DirectMusicWave_Object_Vtbl
= {
310 IDirectMusicWaveImpl_IDirectMusicObject_QueryInterface
,
311 IDirectMusicWaveImpl_IDirectMusicObject_AddRef
,
312 IDirectMusicWaveImpl_IDirectMusicObject_Release
,
313 IDirectMusicWaveImpl_IDirectMusicObject_GetDescriptor
,
314 IDirectMusicWaveImpl_IDirectMusicObject_SetDescriptor
,
315 IDirectMusicWaveImpl_IDirectMusicObject_ParseDescriptor
318 /* IDirectMusicWaveImpl IPersistStream part: */
319 static HRESULT WINAPI
IDirectMusicWaveImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
) {
320 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, PersistStreamVtbl
, iface
);
321 return IUnknown_QueryInterface(&This
->IUnknown_iface
, riid
, ppobj
);
324 static ULONG WINAPI
IDirectMusicWaveImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface
) {
325 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, PersistStreamVtbl
, iface
);
326 return IUnknown_AddRef(&This
->IUnknown_iface
);
329 static ULONG WINAPI
IDirectMusicWaveImpl_IPersistStream_Release (LPPERSISTSTREAM iface
) {
330 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, PersistStreamVtbl
, iface
);
331 return IUnknown_Release(&This
->IUnknown_iface
);
334 static HRESULT WINAPI
IDirectMusicWaveImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
) {
338 static HRESULT WINAPI
IDirectMusicWaveImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface
) {
342 static HRESULT WINAPI
IDirectMusicWaveImpl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
343 ICOM_THIS_MULTI(IDirectMusicWaveImpl
, PersistStreamVtbl
, iface
);
345 DMUS_PRIVATE_CHUNK Chunk
;
346 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
347 LARGE_INTEGER liMove
; /* used when skipping chunks */
349 FIXME("(%p, %p): loading not implemented yet (only descriptor is loaded)\n", This
, pStm
);
351 /* FIXME: should this be determined from stream? */
352 This
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
353 This
->pDesc
->guidClass
= CLSID_DirectMusicSegment
;
355 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
356 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
357 switch (Chunk
.fccID
) {
359 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
360 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
361 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
363 if (Chunk
.fccID
== mmioFOURCC('W','A','V','E')) {
364 TRACE_(dmfile
)(": wave form\n");
366 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
367 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
368 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
369 switch (Chunk
.fccID
) {
370 case DMUS_FOURCC_GUID_CHUNK
: {
371 TRACE_(dmfile
)(": GUID chunk\n");
372 This
->pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
373 IStream_Read (pStm
, &This
->pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
376 case DMUS_FOURCC_VERSION_CHUNK
: {
377 TRACE_(dmfile
)(": version chunk\n");
378 This
->pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
379 IStream_Read (pStm
, &This
->pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
382 case DMUS_FOURCC_CATEGORY_CHUNK
: {
383 TRACE_(dmfile
)(": category chunk\n");
384 This
->pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
385 IStream_Read (pStm
, This
->pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
389 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
390 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
391 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
393 switch (Chunk
.fccID
) {
394 /* evil M$ UNFO list, which can (!?) contain INFO elements */
395 case DMUS_FOURCC_UNFO_LIST
: {
396 TRACE_(dmfile
)(": UNFO list\n");
398 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
399 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
400 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
401 switch (Chunk
.fccID
) {
402 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
403 (though strings seem to be valid unicode) */
404 case mmioFOURCC('I','N','A','M'):
405 case DMUS_FOURCC_UNAM_CHUNK
: {
406 TRACE_(dmfile
)(": name chunk\n");
407 This
->pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
408 IStream_Read (pStm
, This
->pDesc
->wszName
, Chunk
.dwSize
, NULL
);
411 case mmioFOURCC('I','A','R','T'):
412 case DMUS_FOURCC_UART_CHUNK
: {
413 TRACE_(dmfile
)(": artist chunk (ignored)\n");
414 liMove
.QuadPart
= Chunk
.dwSize
;
415 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
418 case mmioFOURCC('I','C','O','P'):
419 case DMUS_FOURCC_UCOP_CHUNK
: {
420 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
421 liMove
.QuadPart
= Chunk
.dwSize
;
422 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
425 case mmioFOURCC('I','S','B','J'):
426 case DMUS_FOURCC_USBJ_CHUNK
: {
427 TRACE_(dmfile
)(": subject chunk (ignored)\n");
428 liMove
.QuadPart
= Chunk
.dwSize
;
429 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
432 case mmioFOURCC('I','C','M','T'):
433 case DMUS_FOURCC_UCMT_CHUNK
: {
434 TRACE_(dmfile
)(": comment chunk (ignored)\n");
435 liMove
.QuadPart
= Chunk
.dwSize
;
436 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
440 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
441 liMove
.QuadPart
= Chunk
.dwSize
;
442 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
446 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
447 } while (ListCount
[0] < ListSize
[0]);
451 TRACE_(dmfile
)(": unknown (skipping)\n");
452 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
453 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
460 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
461 liMove
.QuadPart
= Chunk
.dwSize
;
462 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
466 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
467 } while (StreamCount
< StreamSize
);
469 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
470 liMove
.QuadPart
= StreamSize
;
471 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
475 TRACE_(dmfile
)(": reading finished\n");
479 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
480 liMove
.QuadPart
= Chunk
.dwSize
;
481 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
482 return DMUS_E_INVALIDFILE
;
489 static HRESULT WINAPI
IDirectMusicWaveImpl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
493 static HRESULT WINAPI
IDirectMusicWaveImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
497 static const IPersistStreamVtbl DirectMusicWave_PersistStream_Vtbl
= {
498 IDirectMusicWaveImpl_IPersistStream_QueryInterface
,
499 IDirectMusicWaveImpl_IPersistStream_AddRef
,
500 IDirectMusicWaveImpl_IPersistStream_Release
,
501 IDirectMusicWaveImpl_IPersistStream_GetClassID
,
502 IDirectMusicWaveImpl_IPersistStream_IsDirty
,
503 IDirectMusicWaveImpl_IPersistStream_Load
,
504 IDirectMusicWaveImpl_IPersistStream_Save
,
505 IDirectMusicWaveImpl_IPersistStream_GetSizeMax
509 /* for ClassFactory */
510 HRESULT WINAPI
create_dswave(REFIID lpcGUID
, void **ppobj
)
512 IDirectMusicWaveImpl
* obj
;
515 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicWaveImpl
));
518 return E_OUTOFMEMORY
;
520 obj
->IUnknown_iface
.lpVtbl
= &unknown_vtbl
;
521 obj
->ObjectVtbl
= &DirectMusicWave_Object_Vtbl
;
522 obj
->PersistStreamVtbl
= &DirectMusicWave_PersistStream_Vtbl
;
523 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
524 DM_STRUCT_INIT(obj
->pDesc
);
525 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
526 obj
->pDesc
->guidClass
= CLSID_DirectMusicSegment
; /* shown by tests */
530 hr
= IUnknown_QueryInterface(&obj
->IUnknown_iface
, lpcGUID
, ppobj
);
531 IUnknown_Release(&obj
->IUnknown_iface
);