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 */
32 LPDMUS_OBJECTDESC pDesc
;
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
);
221 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
222 memcpy(desc
, This
->pDesc
, This
->pDesc
->dwSize
);
226 static HRESULT WINAPI
DirectMusicObject_SetDescriptor(IDirectMusicObject
*iface
, DMUS_OBJECTDESC
*pDesc
)
228 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
230 TRACE("(%p, %p): %s\n", This
, pDesc
, debugstr_DMUS_OBJECTDESC(pDesc
));
232 /* According to MSDN, we should copy only given values, not whole struct */
233 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
234 This
->pDesc
->guidObject
= pDesc
->guidObject
;
235 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
236 This
->pDesc
->guidClass
= pDesc
->guidClass
;
237 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
238 lstrcpynW (This
->pDesc
->wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
239 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
240 lstrcpynW (This
->pDesc
->wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
241 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
242 lstrcpynW (This
->pDesc
->wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
243 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
244 This
->pDesc
->vVersion
= pDesc
->vVersion
;
245 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
246 This
->pDesc
->ftDate
= pDesc
->ftDate
;
247 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
)
249 This
->pDesc
->llMemLength
= pDesc
->llMemLength
;
250 memcpy(This
->pDesc
->pbMemData
, pDesc
->pbMemData
, pDesc
->llMemLength
);
253 /* according to MSDN, we copy the stream */
254 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
)
255 IStream_Clone(pDesc
->pStream
, &This
->pDesc
->pStream
);
258 This
->pDesc
->dwValidData
|= pDesc
->dwValidData
;
262 static HRESULT WINAPI
DirectMusicObject_ParseDescriptor(IDirectMusicObject
*iface
, IStream
*pStream
, DMUS_OBJECTDESC
*pDesc
)
264 IDirectMusicGraphImpl
*This
= impl_from_IDirectMusicObject(iface
);
265 DMUS_PRIVATE_CHUNK Chunk
;
266 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
267 LARGE_INTEGER liMove
; /* used when skipping chunks */
269 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
271 /* FIXME: should this be determined from stream? */
272 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
273 pDesc
->guidClass
= CLSID_DirectMusicGraph
;
275 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
276 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
277 switch (Chunk
.fccID
) {
279 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
280 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
281 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
283 if (Chunk
.fccID
== DMUS_FOURCC_TOOLGRAPH_FORM
) {
284 TRACE_(dmfile
)(": graph form\n");
286 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
287 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
288 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
289 switch (Chunk
.fccID
) {
290 case DMUS_FOURCC_GUID_CHUNK
: {
291 TRACE_(dmfile
)(": GUID chunk\n");
292 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
293 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
296 case DMUS_FOURCC_VERSION_CHUNK
: {
297 TRACE_(dmfile
)(": version chunk\n");
298 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
299 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
302 case DMUS_FOURCC_CATEGORY_CHUNK
: {
303 TRACE_(dmfile
)(": category chunk\n");
304 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
305 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
309 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
310 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
311 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
313 switch (Chunk
.fccID
) {
314 /* evil M$ UNFO list, which can (!?) contain INFO elements */
315 case DMUS_FOURCC_UNFO_LIST
: {
316 TRACE_(dmfile
)(": UNFO list\n");
318 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
319 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
320 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
321 switch (Chunk
.fccID
) {
322 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
323 (though strings seem to be valid unicode) */
324 case mmioFOURCC('I','N','A','M'):
325 case DMUS_FOURCC_UNAM_CHUNK
: {
326 TRACE_(dmfile
)(": name chunk\n");
327 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
328 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
331 case mmioFOURCC('I','A','R','T'):
332 case DMUS_FOURCC_UART_CHUNK
: {
333 TRACE_(dmfile
)(": artist chunk (ignored)\n");
334 liMove
.QuadPart
= Chunk
.dwSize
;
335 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
338 case mmioFOURCC('I','C','O','P'):
339 case DMUS_FOURCC_UCOP_CHUNK
: {
340 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
341 liMove
.QuadPart
= Chunk
.dwSize
;
342 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
345 case mmioFOURCC('I','S','B','J'):
346 case DMUS_FOURCC_USBJ_CHUNK
: {
347 TRACE_(dmfile
)(": subject chunk (ignored)\n");
348 liMove
.QuadPart
= Chunk
.dwSize
;
349 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
352 case mmioFOURCC('I','C','M','T'):
353 case DMUS_FOURCC_UCMT_CHUNK
: {
354 TRACE_(dmfile
)(": comment chunk (ignored)\n");
355 liMove
.QuadPart
= Chunk
.dwSize
;
356 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
360 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
361 liMove
.QuadPart
= Chunk
.dwSize
;
362 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
366 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
367 } while (ListCount
[0] < ListSize
[0]);
371 TRACE_(dmfile
)(": unknown (skipping)\n");
372 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
373 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
380 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
381 liMove
.QuadPart
= Chunk
.dwSize
;
382 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
386 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
387 } while (StreamCount
< StreamSize
);
389 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
390 liMove
.QuadPart
= StreamSize
;
391 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
395 TRACE_(dmfile
)(": reading finished\n");
399 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
400 liMove
.QuadPart
= Chunk
.dwSize
;
401 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
402 return DMUS_E_INVALIDFILE
;
406 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
411 static const IDirectMusicObjectVtbl DirectMusicObjectVtbl
=
413 DirectMusicObject_QueryInterface
,
414 DirectMusicObject_AddRef
,
415 DirectMusicObject_Release
,
416 DirectMusicObject_GetDescriptor
,
417 DirectMusicObject_SetDescriptor
,
418 DirectMusicObject_ParseDescriptor
421 static HRESULT WINAPI
PersistStream_QueryInterface(IPersistStream
*iface
, REFIID riid
, void **ret_iface
)
423 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
424 return IDirectMusicGraph_QueryInterface(&This
->IDirectMusicGraph_iface
, riid
, ret_iface
);
427 static ULONG WINAPI
PersistStream_AddRef(IPersistStream
*iface
)
429 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
430 return IDirectMusicGraph_AddRef(&This
->IDirectMusicGraph_iface
);
433 static ULONG WINAPI
PersistStream_Release(IPersistStream
*iface
)
435 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
436 return IDirectMusicGraph_Release(&This
->IDirectMusicGraph_iface
);
439 static HRESULT WINAPI
PersistStream_GetClassID(IPersistStream
*iface
, CLSID
*clsid
)
441 IDirectMusicGraphImpl
*This
= impl_from_IPersistStream(iface
);
442 FIXME("(%p) %p: stub\n", This
, clsid
);
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
->pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
482 IStream_Read (pStm
, &This
->pDesc
->guidObject
, chunkSize
, NULL
);
485 case DMUS_FOURCC_VERSION_CHUNK
: {
486 TRACE_(dmfile
)(": version chunk\n");
487 This
->pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
488 IStream_Read (pStm
, &This
->pDesc
->vVersion
, chunkSize
, NULL
);
491 case DMUS_FOURCC_CATEGORY_CHUNK
: {
492 TRACE_(dmfile
)(": category chunk\n");
493 This
->pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
494 IStream_Read (pStm
, This
->pDesc
->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
->pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
517 IStream_Read (pStm
, This
->pDesc
->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 FIXME("(%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 FIXME("(%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 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
642 DM_STRUCT_INIT(obj
->pDesc
);
643 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
644 obj
->pDesc
->guidClass
= CLSID_DirectMusicGraph
;
646 list_init(&obj
->Tools
);
648 hr
= IDirectMusicGraph_QueryInterface(&obj
->IDirectMusicGraph_iface
, riid
, ret_iface
);
649 IDirectMusicGraph_Release(&obj
->IDirectMusicGraph_iface
);