1 /* IDirectMusicAudioPath Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (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
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "dmime_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dmime
);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile
);
25 /*****************************************************************************
26 * IDirectMusicAudioPathImpl implementation
28 /* IDirectMusicAudioPath IUnknown part: */
29 HRESULT WINAPI
IDirectMusicAudioPathImpl_IUnknown_QueryInterface (LPUNKNOWN iface
, REFIID riid
, LPVOID
*ppobj
) {
30 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, UnknownVtbl
, iface
);
32 if (IsEqualIID (riid
, &IID_IUnknown
)) {
33 *ppobj
= (LPVOID
)&This
->UnknownVtbl
;
34 IDirectMusicAudioPathImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
36 } else if (IsEqualIID (riid
, &IID_IDirectMusicAudioPath
)) {
37 *ppobj
= (LPVOID
)&This
->AudioPathVtbl
;
38 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_AddRef ((LPDIRECTMUSICAUDIOPATH
)&This
->AudioPathVtbl
);
40 } else if (IsEqualIID (riid
, &IID_IDirectMusicObject
)) {
41 *ppobj
= (LPVOID
)&This
->ObjectVtbl
;
42 IDirectMusicAudioPathImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT
)&This
->ObjectVtbl
);
44 } else if (IsEqualIID (riid
, &IID_IPersistStream
)) {
45 *ppobj
= (LPVOID
)&This
->PersistStreamVtbl
;
46 IDirectMusicAudioPathImpl_IPersistStream_AddRef ((LPPERSISTSTREAM
)&This
->PersistStreamVtbl
);
50 WARN("(%p)->(%s,%p),not found\n", This
, debugstr_guid(riid
), ppobj
);
54 ULONG WINAPI
IDirectMusicAudioPathImpl_IUnknown_AddRef (LPUNKNOWN iface
) {
55 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, UnknownVtbl
, iface
);
56 TRACE("(%p) : AddRef from %ld\n", This
, This
->ref
);
60 ULONG WINAPI
IDirectMusicAudioPathImpl_IUnknown_Release (LPUNKNOWN iface
) {
61 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, UnknownVtbl
, iface
);
62 ULONG ref
= --This
->ref
;
63 TRACE("(%p) : ReleaseRef to %ld\n", This
, This
->ref
);
65 HeapFree(GetProcessHeap(), 0, This
);
70 ICOM_VTABLE(IUnknown
) DirectMusicAudioPath_Unknown_Vtbl
= {
71 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
72 IDirectMusicAudioPathImpl_IUnknown_QueryInterface
,
73 IDirectMusicAudioPathImpl_IUnknown_AddRef
,
74 IDirectMusicAudioPathImpl_IUnknown_Release
77 /* IDirectMusicAudioPathImpl IDirectMusicAudioPath part: */
78 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_QueryInterface (LPDIRECTMUSICAUDIOPATH iface
, REFIID riid
, LPVOID
*ppobj
) {
79 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
80 return IDirectMusicAudioPathImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
83 ULONG WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_AddRef (LPDIRECTMUSICAUDIOPATH iface
) {
84 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
85 return IDirectMusicAudioPathImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
88 ULONG WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_Release (LPDIRECTMUSICAUDIOPATH iface
) {
89 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
90 return IDirectMusicAudioPathImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
93 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_GetObjectInPath (LPDIRECTMUSICAUDIOPATH iface
, DWORD dwPChannel
, DWORD dwStage
, DWORD dwBuffer
, REFGUID guidObject
, WORD dwIndex
, REFGUID iidInterface
, void** ppObject
) {
94 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
96 FIXME("(%p, %ld, %ld, %ld, %s, %d, %s, %p): stub\n", This
, dwPChannel
, dwStage
, dwBuffer
, debugstr_guid(guidObject
), dwIndex
, debugstr_guid(iidInterface
), ppObject
);
99 case DMUS_PATH_BUFFER
:
101 if (IsEqualIID (iidInterface
, &IID_IDirectSoundBuffer8
)) {
102 IDirectSoundBuffer8_QueryInterface (This
->pDSBuffer
, &IID_IDirectSoundBuffer8
, ppObject
);
103 TRACE("returning %p\n",*ppObject
);
105 } else if (IsEqualIID (iidInterface
, &IID_IDirectSound3DBuffer
)) {
106 IDirectSoundBuffer8_QueryInterface (This
->pDSBuffer
, &IID_IDirectSound3DBuffer
, ppObject
);
107 TRACE("returning %p\n",*ppObject
);
115 case DMUS_PATH_PRIMARY_BUFFER
: {
116 if (IsEqualIID (iidInterface
, &IID_IDirectSound3DListener
)) {
117 IDirectSoundBuffer8_QueryInterface (This
->pPrimary
, &IID_IDirectSound3DListener
, ppObject
);
120 FIXME("bad iid...\n");
125 case DMUS_PATH_AUDIOPATH_GRAPH
:
127 if (IsEqualIID (iidInterface
, &IID_IDirectMusicGraph
)) {
128 if (NULL
== This
->pToolGraph
) {
129 IDirectMusicGraphImpl
* pGraph
;
130 DMUSIC_CreateDirectMusicGraphImpl (&IID_IDirectMusicGraph
, (LPVOID
*)&pGraph
, NULL
);
131 This
->pToolGraph
= (IDirectMusicGraph
*) pGraph
;
133 *ppObject
= (LPDIRECTMUSICGRAPH
) This
->pToolGraph
;
134 IDirectMusicGraph_AddRef((LPDIRECTMUSICGRAPH
) *ppObject
);
140 case DMUS_PATH_AUDIOPATH_TOOL
:
146 case DMUS_PATH_PERFORMANCE
:
148 /* TODO check wanted GUID */
149 *ppObject
= (LPDIRECTMUSICPERFORMANCE8
) This
->pPerf
;
150 IDirectMusicPerformance8Impl_AddRef((LPDIRECTMUSICPERFORMANCE8
) *ppObject
);
155 case DMUS_PATH_PERFORMANCE_GRAPH
:
157 IDirectMusicGraph
* pPerfoGraph
= NULL
;
158 IDirectMusicPerformance8Impl_GetGraph((LPDIRECTMUSICPERFORMANCE8
) This
->pPerf
, &pPerfoGraph
);
159 if (NULL
== pPerfoGraph
) {
160 IDirectMusicGraphImpl
* pGraph
= NULL
;
161 DMUSIC_CreateDirectMusicGraphImpl (&IID_IDirectMusicGraph
, (LPVOID
*)&pGraph
, NULL
);
162 IDirectMusicPerformance8Impl_SetGraph((LPDIRECTMUSICPERFORMANCE8
) This
->pPerf
, (IDirectMusicGraph
*) pGraph
);
163 /* we need release as SetGraph do an AddRef */
164 IDirectMusicGraph_Release((LPDIRECTMUSICGRAPH
) pGraph
);
165 pPerfoGraph
= (LPDIRECTMUSICGRAPH
) pGraph
;
167 *ppObject
= (LPDIRECTMUSICGRAPH
) pPerfoGraph
;
172 case DMUS_PATH_PERFORMANCE_TOOL
:
181 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_Activate (LPDIRECTMUSICAUDIOPATH iface
, BOOL fActivate
) {
182 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
183 FIXME("(%p, %d): stub\n", This
, fActivate
);
187 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_SetVolume (LPDIRECTMUSICAUDIOPATH iface
, long lVolume
, DWORD dwDuration
) {
188 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
189 FIXME("(%p, %li, %ld): stub\n", This
, lVolume
, dwDuration
);
193 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicAudioPath_ConvertPChannel (LPDIRECTMUSICAUDIOPATH iface
, DWORD dwPChannelIn
, DWORD
* pdwPChannelOut
) {
194 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, AudioPathVtbl
, iface
);
195 FIXME("(%p, %ld, %p): stub\n", This
, dwPChannelIn
, pdwPChannelOut
);
199 ICOM_VTABLE(IDirectMusicAudioPath
) DirectMusicAudioPath_AudioPath_Vtbl
= {
200 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
201 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_QueryInterface
,
202 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_AddRef
,
203 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_Release
,
204 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_GetObjectInPath
,
205 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_Activate
,
206 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_SetVolume
,
207 IDirectMusicAudioPathImpl_IDirectMusicAudioPath_ConvertPChannel
210 /* IDirectMusicAudioPathImpl IDirectMusicObject part: */
211 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface
, REFIID riid
, LPVOID
*ppobj
) {
212 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, ObjectVtbl
, iface
);
213 return IDirectMusicAudioPathImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
216 ULONG WINAPI
IDirectMusicAudioPathImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface
) {
217 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, ObjectVtbl
, iface
);
218 return IDirectMusicAudioPathImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
221 ULONG WINAPI
IDirectMusicAudioPathImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface
) {
222 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, ObjectVtbl
, iface
);
223 return IDirectMusicAudioPathImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
226 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
227 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, ObjectVtbl
, iface
);
228 TRACE("(%p, %p)\n", This
, pDesc
);
229 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
230 memcpy (pDesc
, This
->pDesc
, This
->pDesc
->dwSize
);
234 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
235 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, ObjectVtbl
, iface
);
236 TRACE("(%p, %p): setting descriptor:\n", This
, pDesc
);
237 if (TRACE_ON(dmime
)) {
238 DMUSIC_dump_DMUS_OBJECTDESC (pDesc
);
241 /* According to MSDN, we should copy only given values, not whole struct */
242 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
243 memcpy (&This
->pDesc
->guidObject
, &pDesc
->guidObject
, sizeof (pDesc
->guidObject
));
244 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
245 memcpy (&This
->pDesc
->guidClass
, &pDesc
->guidClass
, sizeof (pDesc
->guidClass
));
246 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
247 strncpyW (This
->pDesc
->wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
248 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
249 strncpyW (This
->pDesc
->wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
250 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
251 strncpyW (This
->pDesc
->wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
252 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
253 memcpy (&This
->pDesc
->vVersion
, &pDesc
->vVersion
, sizeof (pDesc
->vVersion
));
254 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
255 memcpy (&This
->pDesc
->ftDate
, &pDesc
->ftDate
, sizeof (pDesc
->ftDate
));
256 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
) {
257 memcpy (&This
->pDesc
->llMemLength
, &pDesc
->llMemLength
, sizeof (pDesc
->llMemLength
));
258 memcpy (This
->pDesc
->pbMemData
, pDesc
->pbMemData
, sizeof (pDesc
->pbMemData
));
260 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
) {
261 /* according to MSDN, we copy the stream */
262 IStream_Clone (pDesc
->pStream
, &This
->pDesc
->pStream
);
266 This
->pDesc
->dwValidData
|= pDesc
->dwValidData
;
271 HRESULT WINAPI
IDirectMusicAudioPathImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface
, LPSTREAM pStream
, LPDMUS_OBJECTDESC pDesc
) {
272 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, ObjectVtbl
, iface
);
273 DMUS_PRIVATE_CHUNK Chunk
;
274 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
275 LARGE_INTEGER liMove
; /* used when skipping chunks */
277 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
279 /* FIXME: should this be determined from stream? */
280 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
281 memcpy (&pDesc
->guidClass
, &CLSID_DirectMusicAudioPath
, sizeof(CLSID
));
283 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
284 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
285 switch (Chunk
.fccID
) {
287 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
288 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
289 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
291 if (Chunk
.fccID
== DMUS_FOURCC_AUDIOPATH_FORM
) {
292 TRACE_(dmfile
)(": audio path form\n");
294 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
295 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
296 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
297 switch (Chunk
.fccID
) {
298 case DMUS_FOURCC_GUID_CHUNK
: {
299 TRACE_(dmfile
)(": GUID chunk\n");
300 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
301 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
304 case DMUS_FOURCC_VERSION_CHUNK
: {
305 TRACE_(dmfile
)(": version chunk\n");
306 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
307 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
310 case DMUS_FOURCC_CATEGORY_CHUNK
: {
311 TRACE_(dmfile
)(": category chunk\n");
312 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
313 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
317 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
318 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
319 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
321 switch (Chunk
.fccID
) {
322 /* evil M$ UNFO list, which can (!?) contain INFO elements */
323 case DMUS_FOURCC_UNFO_LIST
: {
324 TRACE_(dmfile
)(": UNFO list\n");
326 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
327 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
328 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
329 switch (Chunk
.fccID
) {
330 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
331 (though strings seem to be valid unicode) */
332 case mmioFOURCC('I','N','A','M'):
333 case DMUS_FOURCC_UNAM_CHUNK
: {
334 TRACE_(dmfile
)(": name chunk\n");
335 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
336 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
339 case mmioFOURCC('I','A','R','T'):
340 case DMUS_FOURCC_UART_CHUNK
: {
341 TRACE_(dmfile
)(": artist chunk (ignored)\n");
342 liMove
.QuadPart
= Chunk
.dwSize
;
343 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
346 case mmioFOURCC('I','C','O','P'):
347 case DMUS_FOURCC_UCOP_CHUNK
: {
348 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
349 liMove
.QuadPart
= Chunk
.dwSize
;
350 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
353 case mmioFOURCC('I','S','B','J'):
354 case DMUS_FOURCC_USBJ_CHUNK
: {
355 TRACE_(dmfile
)(": subject chunk (ignored)\n");
356 liMove
.QuadPart
= Chunk
.dwSize
;
357 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
360 case mmioFOURCC('I','C','M','T'):
361 case DMUS_FOURCC_UCMT_CHUNK
: {
362 TRACE_(dmfile
)(": comment chunk (ignored)\n");
363 liMove
.QuadPart
= Chunk
.dwSize
;
364 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
368 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
369 liMove
.QuadPart
= Chunk
.dwSize
;
370 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
374 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
375 } while (ListCount
[0] < ListSize
[0]);
379 TRACE_(dmfile
)(": unknown (skipping)\n");
380 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
381 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
388 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
389 liMove
.QuadPart
= Chunk
.dwSize
;
390 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
394 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
395 } while (StreamCount
< StreamSize
);
398 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
399 liMove
.QuadPart
= StreamSize
;
400 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
404 TRACE_(dmfile
)(": reading finished\n");
408 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
409 liMove
.QuadPart
= Chunk
.dwSize
;
410 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
411 return DMUS_E_INVALIDFILE
;
415 TRACE(": returning descriptor:\n");
416 if (TRACE_ON(dmime
)) {
417 DMUSIC_dump_DMUS_OBJECTDESC (pDesc
);
423 ICOM_VTABLE(IDirectMusicObject
) DirectMusicAudioPath_Object_Vtbl
= {
424 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
425 IDirectMusicAudioPathImpl_IDirectMusicObject_QueryInterface
,
426 IDirectMusicAudioPathImpl_IDirectMusicObject_AddRef
,
427 IDirectMusicAudioPathImpl_IDirectMusicObject_Release
,
428 IDirectMusicAudioPathImpl_IDirectMusicObject_GetDescriptor
,
429 IDirectMusicAudioPathImpl_IDirectMusicObject_SetDescriptor
,
430 IDirectMusicAudioPathImpl_IDirectMusicObject_ParseDescriptor
433 /* IDirectMusicAudioPathImpl IPersistStream part: */
434 HRESULT WINAPI
IDirectMusicAudioPathImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
) {
435 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, PersistStreamVtbl
, iface
);
436 return IDirectMusicAudioPathImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
439 ULONG WINAPI
IDirectMusicAudioPathImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface
) {
440 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, PersistStreamVtbl
, iface
);
441 return IDirectMusicAudioPathImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
444 ULONG WINAPI
IDirectMusicAudioPathImpl_IPersistStream_Release (LPPERSISTSTREAM iface
) {
445 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, PersistStreamVtbl
, iface
);
446 return IDirectMusicAudioPathImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
449 HRESULT WINAPI
IDirectMusicAudioPathImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
) {
453 HRESULT WINAPI
IDirectMusicAudioPathImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface
) {
457 HRESULT WINAPI
IDirectMusicAudioPathImpl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
458 ICOM_THIS_MULTI(IDirectMusicAudioPathImpl
, PersistStreamVtbl
, iface
);
461 DWORD chunkSize
, StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
462 LARGE_INTEGER liMove
; /* used when skipping chunks */
464 FIXME("(%p, %p): Loading not implemented yet\n", This
, pStm
);
465 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
466 IStream_Read (pStm
, &chunkSize
, sizeof(DWORD
), NULL
);
467 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
470 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
471 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(chunkID
));
472 StreamSize
= chunkSize
- sizeof(FOURCC
);
475 case DMUS_FOURCC_AUDIOPATH_FORM
: {
476 TRACE_(dmfile
)(": audio path form\n");
478 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
479 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
480 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
481 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
483 case DMUS_FOURCC_GUID_CHUNK
: {
484 TRACE_(dmfile
)(": GUID chunk\n");
485 This
->pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
486 IStream_Read (pStm
, &This
->pDesc
->guidObject
, chunkSize
, NULL
);
489 case DMUS_FOURCC_VERSION_CHUNK
: {
490 TRACE_(dmfile
)(": version chunk\n");
491 This
->pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
492 IStream_Read (pStm
, &This
->pDesc
->vVersion
, chunkSize
, NULL
);
495 case DMUS_FOURCC_CATEGORY_CHUNK
: {
496 TRACE_(dmfile
)(": category chunk\n");
497 This
->pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
498 IStream_Read (pStm
, This
->pDesc
->wszCategory
, chunkSize
, NULL
);
502 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
503 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(chunkID
));
504 ListSize
[0] = chunkSize
- sizeof(FOURCC
);
507 case DMUS_FOURCC_UNFO_LIST
: {
508 TRACE_(dmfile
)(": UNFO list\n");
510 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
511 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
512 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
513 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
515 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
516 (though strings seem to be valid unicode) */
517 case mmioFOURCC('I','N','A','M'):
518 case DMUS_FOURCC_UNAM_CHUNK
: {
519 TRACE_(dmfile
)(": name chunk\n");
520 This
->pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
521 IStream_Read (pStm
, This
->pDesc
->wszName
, chunkSize
, NULL
);
524 case mmioFOURCC('I','A','R','T'):
525 case DMUS_FOURCC_UART_CHUNK
: {
526 TRACE_(dmfile
)(": artist chunk (ignored)\n");
527 liMove
.QuadPart
= chunkSize
;
528 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
531 case mmioFOURCC('I','C','O','P'):
532 case DMUS_FOURCC_UCOP_CHUNK
: {
533 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
534 liMove
.QuadPart
= chunkSize
;
535 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
538 case mmioFOURCC('I','S','B','J'):
539 case DMUS_FOURCC_USBJ_CHUNK
: {
540 TRACE_(dmfile
)(": subject chunk (ignored)\n");
541 liMove
.QuadPart
= chunkSize
;
542 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
545 case mmioFOURCC('I','C','M','T'):
546 case DMUS_FOURCC_UCMT_CHUNK
: {
547 TRACE_(dmfile
)(": comment chunk (ignored)\n");
548 liMove
.QuadPart
= chunkSize
;
549 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
553 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
554 liMove
.QuadPart
= chunkSize
;
555 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
559 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
560 } while (ListCount
[0] < ListSize
[0]);
564 TRACE_(dmfile
)(": unknown (skipping)\n");
565 liMove
.QuadPart
= chunkSize
- sizeof(FOURCC
);
566 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
573 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
574 liMove
.QuadPart
= chunkSize
;
575 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
579 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
580 } while (StreamCount
< StreamSize
);
584 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
585 liMove
.QuadPart
= StreamSize
;
586 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
590 TRACE_(dmfile
)(": reading finished\n");
594 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
595 liMove
.QuadPart
= chunkSize
;
596 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
604 HRESULT WINAPI
IDirectMusicAudioPathImpl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
608 HRESULT WINAPI
IDirectMusicAudioPathImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
612 ICOM_VTABLE(IPersistStream
) DirectMusicAudioPath_PersistStream_Vtbl
= {
613 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
614 IDirectMusicAudioPathImpl_IPersistStream_QueryInterface
,
615 IDirectMusicAudioPathImpl_IPersistStream_AddRef
,
616 IDirectMusicAudioPathImpl_IPersistStream_Release
,
617 IDirectMusicAudioPathImpl_IPersistStream_GetClassID
,
618 IDirectMusicAudioPathImpl_IPersistStream_IsDirty
,
619 IDirectMusicAudioPathImpl_IPersistStream_Load
,
620 IDirectMusicAudioPathImpl_IPersistStream_Save
,
621 IDirectMusicAudioPathImpl_IPersistStream_GetSizeMax
624 /* for ClassFactory */
625 HRESULT WINAPI
DMUSIC_CreateDirectMusicAudioPathImpl (LPCGUID lpcGUID
, LPVOID
* ppobj
, LPUNKNOWN pUnkOuter
) {
626 IDirectMusicAudioPathImpl
* obj
;
628 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicAudioPathImpl
));
630 *ppobj
= (LPVOID
) NULL
;
631 return E_OUTOFMEMORY
;
633 obj
->UnknownVtbl
= &DirectMusicAudioPath_Unknown_Vtbl
;
634 obj
->AudioPathVtbl
= &DirectMusicAudioPath_AudioPath_Vtbl
;
635 obj
->ObjectVtbl
= &DirectMusicAudioPath_Object_Vtbl
;
636 obj
->PersistStreamVtbl
= &DirectMusicAudioPath_PersistStream_Vtbl
;
637 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
638 DM_STRUCT_INIT(obj
->pDesc
);
639 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
640 memcpy (&obj
->pDesc
->guidClass
, &CLSID_DirectMusicAudioPath
, sizeof (CLSID
));
641 obj
->ref
= 0; /* will be inited by QueryInterface */
643 return IDirectMusicAudioPathImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&obj
->UnknownVtbl
, lpcGUID
, ppobj
);