1 /* IDirectMusicAudioPath 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 "dmime_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(dmime
);
24 WINE_DECLARE_DEBUG_CHANNEL(dmfile
);
26 struct IDirectMusicAudioPathImpl
{
27 IDirectMusicAudioPath IDirectMusicAudioPath_iface
;
28 struct dmobject dmobj
;
30 IDirectMusicPerformance8
* pPerf
;
31 IDirectMusicGraph
* pToolGraph
;
32 IDirectSoundBuffer
* pDSBuffer
;
33 IDirectSoundBuffer
* pPrimary
;
38 static inline struct IDirectMusicAudioPathImpl
*impl_from_IDirectMusicAudioPath(IDirectMusicAudioPath
*iface
)
40 return CONTAINING_RECORD(iface
, struct IDirectMusicAudioPathImpl
, IDirectMusicAudioPath_iface
);
43 static inline struct IDirectMusicAudioPathImpl
*impl_from_IDirectMusicObject(IDirectMusicObject
*iface
)
45 return CONTAINING_RECORD(iface
, struct IDirectMusicAudioPathImpl
, dmobj
.IDirectMusicObject_iface
);
48 static inline struct IDirectMusicAudioPathImpl
*impl_from_IPersistStream(IPersistStream
*iface
)
50 return CONTAINING_RECORD(iface
, struct IDirectMusicAudioPathImpl
, dmobj
.IPersistStream_iface
);
53 void set_audiopath_perf_pointer(IDirectMusicAudioPath
*iface
, IDirectMusicPerformance8
*performance
)
55 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
56 This
->pPerf
= performance
;
59 void set_audiopath_dsound_buffer(IDirectMusicAudioPath
*iface
, IDirectSoundBuffer
*buffer
)
61 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
62 This
->pDSBuffer
= buffer
;
65 void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath
*iface
, IDirectSoundBuffer
*buffer
)
67 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
68 This
->pPrimary
= buffer
;
71 /*****************************************************************************
72 * IDirectMusicAudioPathImpl implementation
74 static HRESULT WINAPI
IDirectMusicAudioPathImpl_QueryInterface (IDirectMusicAudioPath
*iface
, REFIID riid
, void **ppobj
)
76 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
78 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
82 if (IsEqualIID (riid
, &IID_IDirectMusicAudioPath
) || IsEqualIID (riid
, &IID_IUnknown
))
83 *ppobj
= &This
->IDirectMusicAudioPath_iface
;
84 else if (IsEqualIID (riid
, &IID_IDirectMusicObject
))
85 *ppobj
= &This
->dmobj
.IDirectMusicObject_iface
;
86 else if (IsEqualIID (riid
, &IID_IPersistStream
))
87 *ppobj
= &This
->dmobj
.IPersistStream_iface
;
90 IUnknown_AddRef((IUnknown
*)*ppobj
);
94 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ppobj
);
98 static ULONG WINAPI
IDirectMusicAudioPathImpl_AddRef (IDirectMusicAudioPath
*iface
)
100 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
101 ULONG ref
= InterlockedIncrement(&This
->ref
);
103 TRACE("(%p): AddRef from %d\n", This
, ref
- 1);
109 static ULONG WINAPI
IDirectMusicAudioPathImpl_Release (IDirectMusicAudioPath
*iface
)
111 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
112 ULONG ref
= InterlockedDecrement(&This
->ref
);
114 TRACE("(%p): ReleaseRef to %d\n", This
, ref
);
118 IDirectSoundBuffer8_Release(This
->pDSBuffer
);
120 HeapFree(GetProcessHeap(), 0, This
);
123 DMIME_UnlockModule();
127 static HRESULT WINAPI
IDirectMusicAudioPathImpl_GetObjectInPath (IDirectMusicAudioPath
*iface
, DWORD dwPChannel
, DWORD dwStage
, DWORD dwBuffer
,
128 REFGUID guidObject
, WORD dwIndex
, REFGUID iidInterface
, void** ppObject
)
130 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
133 FIXME("(%p, %d, %d, %d, %s, %d, %s, %p): stub\n", This
, dwPChannel
, dwStage
, dwBuffer
, debugstr_dmguid(guidObject
),
134 dwIndex
, debugstr_dmguid(iidInterface
), ppObject
);
137 case DMUS_PATH_BUFFER
:
140 if (IsEqualIID (iidInterface
, &IID_IUnknown
) ||
141 IsEqualIID (iidInterface
, &IID_IDirectSoundBuffer
) ||
142 IsEqualIID (iidInterface
, &IID_IDirectSoundBuffer8
) ||
143 IsEqualIID (iidInterface
, &IID_IDirectSound3DBuffer
)) {
144 return IDirectSoundBuffer8_QueryInterface (This
->pDSBuffer
, iidInterface
, ppObject
);
147 WARN("Unsupported interface %s\n", debugstr_dmguid(iidInterface
));
149 return E_NOINTERFACE
;
153 case DMUS_PATH_PRIMARY_BUFFER
: {
154 if (IsEqualIID (iidInterface
, &IID_IDirectSound3DListener
)) {
155 IDirectSoundBuffer8_QueryInterface (This
->pPrimary
, &IID_IDirectSound3DListener
, ppObject
);
158 FIXME("bad iid...\n");
163 case DMUS_PATH_AUDIOPATH_GRAPH
:
165 if (IsEqualIID (iidInterface
, &IID_IDirectMusicGraph
)) {
166 if (NULL
== This
->pToolGraph
) {
167 IDirectMusicGraphImpl
* pGraph
;
168 hr
= create_dmgraph(&IID_IDirectMusicGraph
, (void**)&pGraph
);
171 This
->pToolGraph
= (IDirectMusicGraph
*) pGraph
;
173 *ppObject
= This
->pToolGraph
;
174 IDirectMusicGraph_AddRef((LPDIRECTMUSICGRAPH
) *ppObject
);
180 case DMUS_PATH_AUDIOPATH_TOOL
:
186 case DMUS_PATH_PERFORMANCE
:
188 /* TODO check wanted GUID */
189 *ppObject
= This
->pPerf
;
190 IUnknown_AddRef((LPUNKNOWN
) *ppObject
);
195 case DMUS_PATH_PERFORMANCE_GRAPH
:
197 IDirectMusicGraph
* pPerfoGraph
= NULL
;
198 IDirectMusicPerformance8_GetGraph(This
->pPerf
, &pPerfoGraph
);
199 if (NULL
== pPerfoGraph
) {
200 IDirectMusicGraphImpl
* pGraph
= NULL
;
201 hr
= create_dmgraph(&IID_IDirectMusicGraph
, (void**)&pGraph
);
204 IDirectMusicPerformance8_SetGraph(This
->pPerf
, (IDirectMusicGraph
*) pGraph
);
205 /* we need release as SetGraph do an AddRef */
206 IDirectMusicGraph_Release((LPDIRECTMUSICGRAPH
) pGraph
);
207 pPerfoGraph
= (LPDIRECTMUSICGRAPH
) pGraph
;
209 *ppObject
= pPerfoGraph
;
214 case DMUS_PATH_PERFORMANCE_TOOL
:
223 static HRESULT WINAPI
IDirectMusicAudioPathImpl_Activate (IDirectMusicAudioPath
*iface
, BOOL fActivate
)
225 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
226 FIXME("(%p, %d): stub\n", This
, fActivate
);
228 if (!This
->fActive
) return S_OK
;
229 This
->fActive
= FALSE
;
231 if (This
->fActive
) return S_OK
;
232 This
->fActive
= TRUE
;
233 if (NULL
!= This
->pDSBuffer
) {
234 IDirectSoundBuffer_Stop(This
->pDSBuffer
);
240 static HRESULT WINAPI
IDirectMusicAudioPathImpl_SetVolume (IDirectMusicAudioPath
*iface
, LONG lVolume
, DWORD dwDuration
)
242 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
243 FIXME("(%p, %i, %d): stub\n", This
, lVolume
, dwDuration
);
247 static HRESULT WINAPI
IDirectMusicAudioPathImpl_ConvertPChannel (IDirectMusicAudioPath
*iface
, DWORD dwPChannelIn
, DWORD
* pdwPChannelOut
)
249 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicAudioPath(iface
);
250 FIXME("(%p, %d, %p): stub\n", This
, dwPChannelIn
, pdwPChannelOut
);
254 static const IDirectMusicAudioPathVtbl DirectMusicAudioPathVtbl
= {
255 IDirectMusicAudioPathImpl_QueryInterface
,
256 IDirectMusicAudioPathImpl_AddRef
,
257 IDirectMusicAudioPathImpl_Release
,
258 IDirectMusicAudioPathImpl_GetObjectInPath
,
259 IDirectMusicAudioPathImpl_Activate
,
260 IDirectMusicAudioPathImpl_SetVolume
,
261 IDirectMusicAudioPathImpl_ConvertPChannel
264 /* IDirectMusicObject */
265 static HRESULT WINAPI
DirectMusicObject_ParseDescriptor(IDirectMusicObject
*iface
, IStream
*pStream
, DMUS_OBJECTDESC
*pDesc
)
267 struct IDirectMusicAudioPathImpl
*This
= impl_from_IDirectMusicObject(iface
);
268 DMUS_PRIVATE_CHUNK Chunk
;
269 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
270 LARGE_INTEGER liMove
; /* used when skipping chunks */
272 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
274 /* FIXME: should this be determined from stream? */
275 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
276 pDesc
->guidClass
= This
->dmobj
.desc
.guidClass
;
278 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
279 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
280 switch (Chunk
.fccID
) {
282 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
283 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
284 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
286 if (Chunk
.fccID
== DMUS_FOURCC_AUDIOPATH_FORM
) {
287 TRACE_(dmfile
)(": audio path form\n");
289 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
290 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
291 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
292 switch (Chunk
.fccID
) {
293 case DMUS_FOURCC_GUID_CHUNK
: {
294 TRACE_(dmfile
)(": GUID chunk\n");
295 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
296 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
299 case DMUS_FOURCC_VERSION_CHUNK
: {
300 TRACE_(dmfile
)(": version chunk\n");
301 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
302 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
305 case DMUS_FOURCC_CATEGORY_CHUNK
: {
306 TRACE_(dmfile
)(": category chunk\n");
307 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
308 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
312 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
313 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
314 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
316 switch (Chunk
.fccID
) {
317 /* evil M$ UNFO list, which can (!?) contain INFO elements */
318 case DMUS_FOURCC_UNFO_LIST
: {
319 TRACE_(dmfile
)(": UNFO list\n");
321 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
322 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
323 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
324 switch (Chunk
.fccID
) {
325 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
326 (though strings seem to be valid unicode) */
327 case mmioFOURCC('I','N','A','M'):
328 case DMUS_FOURCC_UNAM_CHUNK
: {
329 TRACE_(dmfile
)(": name chunk\n");
330 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
331 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
334 case mmioFOURCC('I','A','R','T'):
335 case DMUS_FOURCC_UART_CHUNK
: {
336 TRACE_(dmfile
)(": artist chunk (ignored)\n");
337 liMove
.QuadPart
= Chunk
.dwSize
;
338 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
341 case mmioFOURCC('I','C','O','P'):
342 case DMUS_FOURCC_UCOP_CHUNK
: {
343 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
344 liMove
.QuadPart
= Chunk
.dwSize
;
345 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
348 case mmioFOURCC('I','S','B','J'):
349 case DMUS_FOURCC_USBJ_CHUNK
: {
350 TRACE_(dmfile
)(": subject chunk (ignored)\n");
351 liMove
.QuadPart
= Chunk
.dwSize
;
352 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
355 case mmioFOURCC('I','C','M','T'):
356 case DMUS_FOURCC_UCMT_CHUNK
: {
357 TRACE_(dmfile
)(": comment chunk (ignored)\n");
358 liMove
.QuadPart
= Chunk
.dwSize
;
359 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
363 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
364 liMove
.QuadPart
= Chunk
.dwSize
;
365 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
369 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
370 } while (ListCount
[0] < ListSize
[0]);
374 TRACE_(dmfile
)(": unknown (skipping)\n");
375 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
376 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
383 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
384 liMove
.QuadPart
= Chunk
.dwSize
;
385 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
389 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
390 } while (StreamCount
< StreamSize
);
392 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
393 liMove
.QuadPart
= StreamSize
;
394 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
398 TRACE_(dmfile
)(": reading finished\n");
402 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
403 liMove
.QuadPart
= Chunk
.dwSize
;
404 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
405 return DMUS_E_INVALIDFILE
;
409 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
414 static const IDirectMusicObjectVtbl dmobject_vtbl
= {
415 dmobj_IDirectMusicObject_QueryInterface
,
416 dmobj_IDirectMusicObject_AddRef
,
417 dmobj_IDirectMusicObject_Release
,
418 dmobj_IDirectMusicObject_GetDescriptor
,
419 dmobj_IDirectMusicObject_SetDescriptor
,
420 DirectMusicObject_ParseDescriptor
424 static HRESULT WINAPI
PersistStream_Load(IPersistStream
*iface
, IStream
*pStm
)
426 struct IDirectMusicAudioPathImpl
*This
= impl_from_IPersistStream(iface
);
429 DWORD chunkSize
, StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
430 LARGE_INTEGER liMove
; /* used when skipping chunks */
432 FIXME("(%p, %p): Loading not implemented yet\n", This
, pStm
);
433 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
434 IStream_Read (pStm
, &chunkSize
, sizeof(DWORD
), NULL
);
435 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (chunkID
), chunkSize
);
438 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
439 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(chunkID
));
440 StreamSize
= chunkSize
- sizeof(FOURCC
);
443 case DMUS_FOURCC_AUDIOPATH_FORM
: {
444 TRACE_(dmfile
)(": audio path form\n");
446 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
447 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
448 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
449 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (chunkID
), chunkSize
);
451 case DMUS_FOURCC_GUID_CHUNK
: {
452 TRACE_(dmfile
)(": GUID chunk\n");
453 This
->dmobj
.desc
.dwValidData
|= DMUS_OBJ_OBJECT
;
454 IStream_Read (pStm
, &This
->dmobj
.desc
.guidObject
, chunkSize
, NULL
);
457 case DMUS_FOURCC_VERSION_CHUNK
: {
458 TRACE_(dmfile
)(": version chunk\n");
459 This
->dmobj
.desc
.dwValidData
|= DMUS_OBJ_VERSION
;
460 IStream_Read (pStm
, &This
->dmobj
.desc
.vVersion
, chunkSize
, NULL
);
463 case DMUS_FOURCC_CATEGORY_CHUNK
: {
464 TRACE_(dmfile
)(": category chunk\n");
465 This
->dmobj
.desc
.dwValidData
|= DMUS_OBJ_CATEGORY
;
466 IStream_Read (pStm
, This
->dmobj
.desc
.wszCategory
, chunkSize
, NULL
);
470 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
471 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(chunkID
));
472 ListSize
[0] = chunkSize
- sizeof(FOURCC
);
475 case DMUS_FOURCC_UNFO_LIST
: {
476 TRACE_(dmfile
)(": UNFO list\n");
478 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
479 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
480 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
481 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (chunkID
), chunkSize
);
483 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
484 (though strings seem to be valid unicode) */
485 case mmioFOURCC('I','N','A','M'):
486 case DMUS_FOURCC_UNAM_CHUNK
: {
487 TRACE_(dmfile
)(": name chunk\n");
488 This
->dmobj
.desc
.dwValidData
|= DMUS_OBJ_NAME
;
489 IStream_Read (pStm
, This
->dmobj
.desc
.wszName
, chunkSize
, NULL
);
492 case mmioFOURCC('I','A','R','T'):
493 case DMUS_FOURCC_UART_CHUNK
: {
494 TRACE_(dmfile
)(": artist chunk (ignored)\n");
495 liMove
.QuadPart
= chunkSize
;
496 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
499 case mmioFOURCC('I','C','O','P'):
500 case DMUS_FOURCC_UCOP_CHUNK
: {
501 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
502 liMove
.QuadPart
= chunkSize
;
503 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
506 case mmioFOURCC('I','S','B','J'):
507 case DMUS_FOURCC_USBJ_CHUNK
: {
508 TRACE_(dmfile
)(": subject chunk (ignored)\n");
509 liMove
.QuadPart
= chunkSize
;
510 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
513 case mmioFOURCC('I','C','M','T'):
514 case DMUS_FOURCC_UCMT_CHUNK
: {
515 TRACE_(dmfile
)(": comment chunk (ignored)\n");
516 liMove
.QuadPart
= chunkSize
;
517 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
521 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
522 liMove
.QuadPart
= chunkSize
;
523 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
527 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
528 } while (ListCount
[0] < ListSize
[0]);
532 TRACE_(dmfile
)(": unknown (skipping)\n");
533 liMove
.QuadPart
= chunkSize
- sizeof(FOURCC
);
534 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
541 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
542 liMove
.QuadPart
= chunkSize
;
543 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
547 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
548 } while (StreamCount
< StreamSize
);
552 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
553 liMove
.QuadPart
= StreamSize
;
554 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
558 TRACE_(dmfile
)(": reading finished\n");
562 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
563 liMove
.QuadPart
= chunkSize
;
564 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
572 static const IPersistStreamVtbl persiststream_vtbl
= {
573 dmobj_IPersistStream_QueryInterface
,
574 dmobj_IPersistStream_AddRef
,
575 dmobj_IPersistStream_Release
,
576 dmobj_IPersistStream_GetClassID
,
577 unimpl_IPersistStream_IsDirty
,
579 unimpl_IPersistStream_Save
,
580 unimpl_IPersistStream_GetSizeMax
583 /* for ClassFactory */
584 HRESULT WINAPI
create_dmaudiopath(REFIID riid
, void **ppobj
)
586 IDirectMusicAudioPathImpl
* obj
;
589 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicAudioPathImpl
));
592 return E_OUTOFMEMORY
;
594 obj
->IDirectMusicAudioPath_iface
.lpVtbl
= &DirectMusicAudioPathVtbl
;
596 dmobject_init(&obj
->dmobj
, &CLSID_DirectMusicAudioPathConfig
,
597 (IUnknown
*)&obj
->IDirectMusicAudioPath_iface
);
598 obj
->dmobj
.IDirectMusicObject_iface
.lpVtbl
= &dmobject_vtbl
;
599 obj
->dmobj
.IPersistStream_iface
.lpVtbl
= &persiststream_vtbl
;
601 hr
= IDirectMusicAudioPath_QueryInterface(&obj
->IDirectMusicAudioPath_iface
, riid
, ppobj
);
602 IDirectMusicAudioPath_Release(&obj
->IDirectMusicAudioPath_iface
);