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"
22 WINE_DEFAULT_DEBUG_CHANNEL(dmime
);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile
);
25 struct IDirectMusicGraphImpl
{
26 IDirectMusicGraph IDirectMusicGraph_iface
;
27 IDirectMusicObject IDirectMusicObject_iface
;
28 IPersistStream IPersistStream_iface
;
31 /* IDirectMusicGraphImpl fields */
37 static inline IDirectMusicGraphImpl
*impl_from_IDirectMusicGraph(IDirectMusicGraph
*iface
)
39 return CONTAINING_RECORD(iface
, IDirectMusicGraphImpl
, IDirectMusicGraph_iface
);
42 static inline IDirectMusicGraphImpl
*impl_from_IDirectMusicObject(IDirectMusicObject
*iface
)
44 return CONTAINING_RECORD(iface
, IDirectMusicGraphImpl
, IDirectMusicObject_iface
);
47 static inline IDirectMusicGraphImpl
*impl_from_IPersistStream(IPersistStream
*iface
)
49 return CONTAINING_RECORD(iface
, IDirectMusicGraphImpl
, IPersistStream_iface
);
52 static HRESULT WINAPI
DirectMusicGraph_QueryInterface(IDirectMusicGraph
*iface
, REFIID riid
, void **ret_iface
)
54 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
56 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ret_iface
);
60 if (IsEqualIID(riid
, &IID_IUnknown
) ||
61 IsEqualIID(riid
, &IID_IDirectMusicGraph
))
63 *ret_iface
= &This
->IDirectMusicGraph_iface
;
65 else if (IsEqualIID(riid
, &IID_IDirectMusicObject
))
66 *ret_iface
= &This
->IDirectMusicObject_iface
;
67 else if (IsEqualIID(riid
, &IID_IPersistStream
))
68 *ret_iface
= &This
->IPersistStream_iface
;
72 IDirectMusicGraph_AddRef(iface
);
76 WARN("(%p, %s, %p): not found\n", This
, debugstr_guid(riid
), ret_iface
);
80 static ULONG WINAPI
DirectMusicGraph_AddRef(IDirectMusicGraph
*iface
)
82 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
83 ULONG ref
= InterlockedIncrement(&This
->ref
);
85 TRACE("(%p): %d\n", This
, ref
);
91 static ULONG WINAPI
DirectMusicGraph_Release(IDirectMusicGraph
*iface
)
93 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
94 ULONG ref
= InterlockedDecrement(&This
->ref
);
96 TRACE("(%p): %d\n", This
, ref
);
99 HeapFree(GetProcessHeap(), 0, This
);
101 DMIME_UnlockModule();
105 static HRESULT WINAPI
DirectMusicGraph_StampPMsg(IDirectMusicGraph
*iface
, DMUS_PMSG
*msg
)
107 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
108 FIXME("(%p, %p): stub\n", This
, msg
);
112 static HRESULT WINAPI
DirectMusicGraph_InsertTool(IDirectMusicGraph
*iface
, IDirectMusicTool
* pTool
, DWORD
* pdwPChannels
, DWORD cPChannels
, LONG lIndex
)
114 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
115 struct list
* pEntry
= NULL
;
116 struct list
* pPrevEntry
= NULL
;
117 LPDMUS_PRIVATE_GRAPH_TOOL pIt
= NULL
;
118 LPDMUS_PRIVATE_GRAPH_TOOL pNewTool
= NULL
;
120 FIXME("(%p, %p, %p, %d, %i): use of pdwPChannels\n", This
, pTool
, pdwPChannels
, cPChannels
, lIndex
);
126 lIndex
= This
->num_tools
+ lIndex
;
128 pPrevEntry
= &This
->Tools
;
129 LIST_FOR_EACH(pEntry
, &This
->Tools
)
131 pIt
= LIST_ENTRY(pEntry
, DMUS_PRIVATE_GRAPH_TOOL
, entry
);
132 if (pIt
->dwIndex
== lIndex
)
133 return DMUS_E_ALREADY_EXISTS
;
135 if (pIt
->dwIndex
> lIndex
)
141 pNewTool
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_GRAPH_TOOL
));
142 pNewTool
->pTool
= pTool
;
143 pNewTool
->dwIndex
= lIndex
;
144 IDirectMusicTool8_AddRef(pTool
);
145 IDirectMusicTool8_Init(pTool
, iface
);
146 list_add_tail (pPrevEntry
->next
, &pNewTool
->entry
);
150 IDirectMusicTool8_GetMediaTypes(pTool
, &dwNum
);
156 static HRESULT WINAPI
DirectMusicGraph_GetTool(IDirectMusicGraph
*iface
, DWORD dwIndex
, IDirectMusicTool
** ppTool
)
158 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
159 struct list
* pEntry
= NULL
;
160 LPDMUS_PRIVATE_GRAPH_TOOL pIt
= NULL
;
162 FIXME("(%p, %d, %p): stub\n", This
, dwIndex
, ppTool
);
164 LIST_FOR_EACH (pEntry
, &This
->Tools
)
166 pIt
= LIST_ENTRY(pEntry
, DMUS_PRIVATE_GRAPH_TOOL
, entry
);
167 if (pIt
->dwIndex
== dwIndex
)
169 *ppTool
= pIt
->pTool
;
171 IDirectMusicTool_AddRef(*ppTool
);
174 if (pIt
->dwIndex
> dwIndex
)
178 return DMUS_E_NOT_FOUND
;
181 static HRESULT WINAPI
DirectMusicGraph_RemoveTool(IDirectMusicGraph
*iface
, IDirectMusicTool
* pTool
)
183 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicGraph(iface
);
184 FIXME("(%p, %p): stub\n", This
, pTool
);
188 static const IDirectMusicGraphVtbl DirectMusicGraphVtbl
=
190 DirectMusicGraph_QueryInterface
,
191 DirectMusicGraph_AddRef
,
192 DirectMusicGraph_Release
,
193 DirectMusicGraph_StampPMsg
,
194 DirectMusicGraph_InsertTool
,
195 DirectMusicGraph_GetTool
,
196 DirectMusicGraph_RemoveTool
199 static HRESULT WINAPI
DirectMusicObject_QueryInterface(IDirectMusicObject
*iface
, REFIID riid
, void **ret_iface
)
201 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
202 return IDirectMusicGraph_QueryInterface(&This
->IDirectMusicGraph_iface
, riid
, ret_iface
);
205 static ULONG WINAPI
DirectMusicObject_AddRef(IDirectMusicObject
*iface
)
207 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
208 return IDirectMusicGraph_AddRef(&This
->IDirectMusicGraph_iface
);
211 static ULONG WINAPI
DirectMusicObject_Release(IDirectMusicObject
*iface
)
213 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
214 return IDirectMusicGraph_Release(&This
->IDirectMusicGraph_iface
);
217 static HRESULT WINAPI
DirectMusicObject_GetDescriptor(IDirectMusicObject
*iface
, DMUS_OBJECTDESC
*desc
)
219 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
220 TRACE("(%p, %p)\n", This
, desc
);
225 static HRESULT WINAPI
DirectMusicObject_SetDescriptor(IDirectMusicObject
*iface
, DMUS_OBJECTDESC
*pDesc
)
227 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
229 TRACE("(%p, %p): %s\n", This
, pDesc
, debugstr_DMUS_OBJECTDESC(pDesc
));
231 /* According to MSDN, we should copy only given values, not whole struct */
232 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
233 This
->desc
.guidObject
= pDesc
->guidObject
;
234 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
235 This
->desc
.guidClass
= pDesc
->guidClass
;
236 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
237 lstrcpynW (This
->desc
.wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
238 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
239 lstrcpynW (This
->desc
.wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
240 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
241 lstrcpynW (This
->desc
.wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
242 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
243 This
->desc
.vVersion
= pDesc
->vVersion
;
244 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
245 This
->desc
.ftDate
= pDesc
->ftDate
;
246 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
)
248 This
->desc
.llMemLength
= pDesc
->llMemLength
;
249 memcpy(This
->desc
.pbMemData
, pDesc
->pbMemData
, pDesc
->llMemLength
);
252 /* according to MSDN, we copy the stream */
253 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
)
254 IStream_Clone(pDesc
->pStream
, &This
->desc
.pStream
);
257 This
->desc
.dwValidData
|= pDesc
->dwValidData
;
261 static HRESULT WINAPI
DirectMusicObject_ParseDescriptor(IDirectMusicObject
*iface
, IStream
*pStream
, DMUS_OBJECTDESC
*pDesc
)
263 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
264 DMUS_PRIVATE_CHUNK Chunk
;
265 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
266 LARGE_INTEGER liMove
; /* used when skipping chunks */
268 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
270 /* FIXME: should this be determined from stream? */
271 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
272 pDesc
->guidClass
= CLSID_DirectMusicGraph
;
274 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
275 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
276 switch (Chunk
.fccID
) {
278 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
279 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
280 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
282 if (Chunk
.fccID
== DMUS_FOURCC_TOOLGRAPH_FORM
) {
283 TRACE_(dmfile
)(": graph form\n");
285 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
286 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
287 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
288 switch (Chunk
.fccID
) {
289 case DMUS_FOURCC_GUID_CHUNK
: {
290 TRACE_(dmfile
)(": GUID chunk\n");
291 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
292 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
295 case DMUS_FOURCC_VERSION_CHUNK
: {
296 TRACE_(dmfile
)(": version chunk\n");
297 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
298 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
301 case DMUS_FOURCC_CATEGORY_CHUNK
: {
302 TRACE_(dmfile
)(": category chunk\n");
303 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
304 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
308 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
309 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
310 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
312 switch (Chunk
.fccID
) {
313 /* evil M$ UNFO list, which can (!?) contain INFO elements */
314 case DMUS_FOURCC_UNFO_LIST
: {
315 TRACE_(dmfile
)(": UNFO list\n");
317 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
318 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
319 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
320 switch (Chunk
.fccID
) {
321 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
322 (though strings seem to be valid unicode) */
323 case mmioFOURCC('I','N','A','M'):
324 case DMUS_FOURCC_UNAM_CHUNK
: {
325 TRACE_(dmfile
)(": name chunk\n");
326 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
327 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
330 case mmioFOURCC('I','A','R','T'):
331 case DMUS_FOURCC_UART_CHUNK
: {
332 TRACE_(dmfile
)(": artist chunk (ignored)\n");
333 liMove
.QuadPart
= Chunk
.dwSize
;
334 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
337 case mmioFOURCC('I','C','O','P'):
338 case DMUS_FOURCC_UCOP_CHUNK
: {
339 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
340 liMove
.QuadPart
= Chunk
.dwSize
;
341 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
344 case mmioFOURCC('I','S','B','J'):
345 case DMUS_FOURCC_USBJ_CHUNK
: {
346 TRACE_(dmfile
)(": subject chunk (ignored)\n");
347 liMove
.QuadPart
= Chunk
.dwSize
;
348 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
351 case mmioFOURCC('I','C','M','T'):
352 case DMUS_FOURCC_UCMT_CHUNK
: {
353 TRACE_(dmfile
)(": comment chunk (ignored)\n");
354 liMove
.QuadPart
= Chunk
.dwSize
;
355 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
359 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
360 liMove
.QuadPart
= Chunk
.dwSize
;
361 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
365 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
366 } while (ListCount
[0] < ListSize
[0]);
370 TRACE_(dmfile
)(": unknown (skipping)\n");
371 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
372 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
379 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
380 liMove
.QuadPart
= Chunk
.dwSize
;
381 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
385 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
386 } while (StreamCount
< StreamSize
);
388 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
389 liMove
.QuadPart
= StreamSize
;
390 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
394 TRACE_(dmfile
)(": reading finished\n");
398 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
399 liMove
.QuadPart
= Chunk
.dwSize
;
400 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
401 return DMUS_E_INVALIDFILE
;
405 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
410 static const IDirectMusicObjectVtbl DirectMusicObjectVtbl
=
412 DirectMusicObject_QueryInterface
,
413 DirectMusicObject_AddRef
,
414 DirectMusicObject_Release
,
415 DirectMusicObject_GetDescriptor
,
416 DirectMusicObject_SetDescriptor
,
417 DirectMusicObject_ParseDescriptor
420 static HRESULT WINAPI
PersistStream_QueryInterface(IPersistStream
*iface
, REFIID riid
, void **ret_iface
)
422 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
423 return IDirectMusicGraph_QueryInterface(&This
->IDirectMusicGraph_iface
, riid
, ret_iface
);
426 static ULONG WINAPI
PersistStream_AddRef(IPersistStream
*iface
)
428 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
429 return IDirectMusicGraph_AddRef(&This
->IDirectMusicGraph_iface
);
432 static ULONG WINAPI
PersistStream_Release(IPersistStream
*iface
)
434 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
435 return IDirectMusicGraph_Release(&This
->IDirectMusicGraph_iface
);
438 static HRESULT WINAPI
PersistStream_GetClassID(IPersistStream
*iface
, CLSID
*clsid
)
440 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
441 TRACE("(%p) %p\n", This
, clsid
);
442 *clsid
= CLSID_DirectMusicGraph
;
446 static HRESULT WINAPI
PersistStream_IsDirty(IPersistStream
*iface
)
448 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
449 FIXME("(%p): stub\n", This
);
453 static HRESULT WINAPI
PersistStream_Load(IPersistStream
*iface
, IStream
* pStm
)
455 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
457 DWORD chunkSize
, StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
458 LARGE_INTEGER liMove
; /* used when skipping chunks */
460 FIXME("(%p, %p): Loading not implemented yet\n", This
, pStm
);
461 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
462 IStream_Read (pStm
, &chunkSize
, sizeof(DWORD
), NULL
);
463 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (chunkID
), chunkSize
);
466 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
467 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(chunkID
));
468 StreamSize
= chunkSize
- sizeof(FOURCC
);
471 case DMUS_FOURCC_TOOLGRAPH_FORM
: {
472 TRACE_(dmfile
)(": graph form\n");
474 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
475 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
476 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
477 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (chunkID
), chunkSize
);
479 case DMUS_FOURCC_GUID_CHUNK
: {
480 TRACE_(dmfile
)(": GUID chunk\n");
481 This
->desc
.dwValidData
|= DMUS_OBJ_OBJECT
;
482 IStream_Read (pStm
, &This
->desc
.guidObject
, chunkSize
, NULL
);
485 case DMUS_FOURCC_VERSION_CHUNK
: {
486 TRACE_(dmfile
)(": version chunk\n");
487 This
->desc
.dwValidData
|= DMUS_OBJ_VERSION
;
488 IStream_Read (pStm
, &This
->desc
.vVersion
, chunkSize
, NULL
);
491 case DMUS_FOURCC_CATEGORY_CHUNK
: {
492 TRACE_(dmfile
)(": category chunk\n");
493 This
->desc
.dwValidData
|= DMUS_OBJ_CATEGORY
;
494 IStream_Read (pStm
, This
->desc
.wszCategory
, chunkSize
, NULL
);
498 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
499 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(chunkID
));
500 ListSize
[0] = chunkSize
- sizeof(FOURCC
);
503 case DMUS_FOURCC_UNFO_LIST
: {
504 TRACE_(dmfile
)(": UNFO list\n");
506 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
507 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
508 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
509 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (chunkID
), chunkSize
);
511 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
512 (though strings seem to be valid unicode) */
513 case mmioFOURCC('I','N','A','M'):
514 case DMUS_FOURCC_UNAM_CHUNK
: {
515 TRACE_(dmfile
)(": name chunk\n");
516 This
->desc
.dwValidData
|= DMUS_OBJ_NAME
;
517 IStream_Read (pStm
, This
->desc
.wszName
, chunkSize
, NULL
);
520 case mmioFOURCC('I','A','R','T'):
521 case DMUS_FOURCC_UART_CHUNK
: {
522 TRACE_(dmfile
)(": artist chunk (ignored)\n");
523 liMove
.QuadPart
= chunkSize
;
524 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
527 case mmioFOURCC('I','C','O','P'):
528 case DMUS_FOURCC_UCOP_CHUNK
: {
529 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
530 liMove
.QuadPart
= chunkSize
;
531 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
534 case mmioFOURCC('I','S','B','J'):
535 case DMUS_FOURCC_USBJ_CHUNK
: {
536 TRACE_(dmfile
)(": subject chunk (ignored)\n");
537 liMove
.QuadPart
= chunkSize
;
538 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
541 case mmioFOURCC('I','C','M','T'):
542 case DMUS_FOURCC_UCMT_CHUNK
: {
543 TRACE_(dmfile
)(": comment chunk (ignored)\n");
544 liMove
.QuadPart
= chunkSize
;
545 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
549 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
550 liMove
.QuadPart
= chunkSize
;
551 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
555 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
556 } while (ListCount
[0] < ListSize
[0]);
560 TRACE_(dmfile
)(": unknown (skipping)\n");
561 liMove
.QuadPart
= chunkSize
- sizeof(FOURCC
);
562 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
569 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
570 liMove
.QuadPart
= chunkSize
;
571 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
575 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
576 } while (StreamCount
< StreamSize
);
580 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
581 liMove
.QuadPart
= StreamSize
;
582 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
586 TRACE_(dmfile
)(": reading finished\n");
590 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
591 liMove
.QuadPart
= chunkSize
;
592 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
600 static HRESULT WINAPI
PersistStream_Save(IPersistStream
*iface
, IStream
*stream
, BOOL clear_dirty
)
602 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
603 TRACE("(%p) %p %d\n", This
, stream
, clear_dirty
);
607 static HRESULT WINAPI
PersistStream_GetSizeMax(IPersistStream
*iface
, ULARGE_INTEGER
*size
)
609 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
610 TRACE("(%p) %p\n", This
, size
);
614 static const IPersistStreamVtbl PersistStreamVtbl
=
616 PersistStream_QueryInterface
,
617 PersistStream_AddRef
,
618 PersistStream_Release
,
619 PersistStream_GetClassID
,
620 PersistStream_IsDirty
,
623 PersistStream_GetSizeMax
626 /* for ClassFactory */
627 HRESULT WINAPI
create_dmgraph(REFIID riid
, void **ret_iface
)
629 IDirectMusicGraphImpl
* obj
;
634 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicGraphImpl
));
636 return E_OUTOFMEMORY
;
638 obj
->IDirectMusicGraph_iface
.lpVtbl
= &DirectMusicGraphVtbl
;
639 obj
->IDirectMusicObject_iface
.lpVtbl
= &DirectMusicObjectVtbl
;
640 obj
->IPersistStream_iface
.lpVtbl
= &PersistStreamVtbl
;
641 DM_STRUCT_INIT(&obj
->desc
);
642 obj
->desc
.dwValidData
|= DMUS_OBJ_CLASS
;
643 obj
->desc
.guidClass
= CLSID_DirectMusicGraph
;
645 list_init(&obj
->Tools
);
647 hr
= IDirectMusicGraph_QueryInterface(&obj
->IDirectMusicGraph_iface
, riid
, ret_iface
);
648 IDirectMusicGraph_Release(&obj
->IDirectMusicGraph_iface
);