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 * IDirectMusicGraphImpl implementation
28 /* IDirectMusicGraphImpl IUnknown part: */
29 HRESULT WINAPI
IDirectMusicGraphImpl_IUnknown_QueryInterface (LPUNKNOWN iface
, REFIID riid
, LPVOID
*ppobj
) {
30 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, UnknownVtbl
, iface
);
31 TRACE("(%p, %s, %p)\n", This
, debugstr_guid(riid
), ppobj
);
33 if (IsEqualIID (riid
, &IID_IUnknown
)) {
34 *ppobj
= (LPVOID
)&This
->UnknownVtbl
;
35 IDirectMusicGraphImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
37 } else if (IsEqualIID (riid
, &IID_IDirectMusicGraph
)) {
38 *ppobj
= (LPVOID
)&This
->GraphVtbl
;
39 IDirectMusicGraphImpl_IDirectMusicGraph_AddRef ((LPDIRECTMUSICGRAPH
)&This
->GraphVtbl
);
41 } else if (IsEqualIID (riid
, &IID_IDirectMusicObject
)) {
42 *ppobj
= (LPVOID
)&This
->ObjectVtbl
;
43 IDirectMusicGraphImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT
)&This
->ObjectVtbl
);
45 } else if (IsEqualIID (riid
, &IID_IPersistStream
)) {
46 *ppobj
= (LPVOID
)&This
->PersistStreamVtbl
;
47 IDirectMusicGraphImpl_IPersistStream_AddRef ((LPPERSISTSTREAM
)&This
->PersistStreamVtbl
);
51 WARN("(%p, %s, %p): not found\n", This
, debugstr_guid(riid
), ppobj
);
55 ULONG WINAPI
IDirectMusicGraphImpl_IUnknown_AddRef (LPUNKNOWN iface
) {
56 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, UnknownVtbl
, iface
);
57 TRACE("(%p): AddRef from %ld\n", This
, This
->ref
);
61 ULONG WINAPI
IDirectMusicGraphImpl_IUnknown_Release (LPUNKNOWN iface
) {
62 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, UnknownVtbl
, iface
);
63 ULONG ref
= --This
->ref
;
64 TRACE("(%p): ReleaseRef to %ld\n", This
, This
->ref
);
66 HeapFree(GetProcessHeap(), 0, This
);
71 IUnknownVtbl DirectMusicGraph_Unknown_Vtbl
= {
72 IDirectMusicGraphImpl_IUnknown_QueryInterface
,
73 IDirectMusicGraphImpl_IUnknown_AddRef
,
74 IDirectMusicGraphImpl_IUnknown_Release
77 /* IDirectMusicGraphImpl IDirectMusicGraph part: */
78 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_QueryInterface (LPDIRECTMUSICGRAPH iface
, REFIID riid
, LPVOID
*ppobj
) {
79 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
80 return IDirectMusicGraphImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
83 ULONG WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_AddRef (LPDIRECTMUSICGRAPH iface
) {
84 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
85 return IDirectMusicGraphImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
88 ULONG WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_Release (LPDIRECTMUSICGRAPH iface
) {
89 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
90 return IDirectMusicGraphImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
93 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_StampPMsg (LPDIRECTMUSICGRAPH iface
, DMUS_PMSG
* pPMSG
) {
94 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
95 FIXME("(%p, %p): stub\n", This
, pPMSG
);
99 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_InsertTool (LPDIRECTMUSICGRAPH iface
, IDirectMusicTool
* pTool
, DWORD
* pdwPChannels
, DWORD cPChannels
, LONG lIndex
) {
100 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
103 struct list
* pEntry
= NULL
;
104 struct list
* pPrevEntry
= NULL
;
105 LPDMUS_PRIVATE_GRAPH_TOOL pIt
= NULL
;
106 LPDMUS_PRIVATE_GRAPH_TOOL pNewTool
= NULL
;
109 FIXME("(%p, %p, %p, %ld, %li): use of pdwPChannels\n", This
, pTool
, pdwPChannels
, cPChannels
, lIndex
);
116 lIndex
= This
->num_tools
+ lIndex
;
119 pPrevEntry
= &This
->Tools
;
120 LIST_FOR_EACH (pEntry
, &This
->Tools
) {
121 pIt
= LIST_ENTRY(pEntry
, DMUS_PRIVATE_GRAPH_TOOL
, entry
);
122 if (pIt
->dwIndex
== lIndex
) {
123 return DMUS_E_ALREADY_EXISTS
;
125 if (pIt
->dwIndex
> lIndex
) {
132 pNewTool
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_GRAPH_TOOL
));
133 pNewTool
->pTool
= pTool
;
134 pNewTool
->dwIndex
= lIndex
;
135 IDirectMusicTool8_AddRef(pTool
);
136 hr
= IDirectMusicTool8_Init(pTool
, iface
);
137 list_add_tail (pPrevEntry
->next
, &pNewTool
->entry
);
141 hr
= IDirectMusicTool8_GetMediaTypes(pTool
, &dwNum
);
147 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_GetTool (LPDIRECTMUSICGRAPH iface
, DWORD dwIndex
, IDirectMusicTool
** ppTool
) {
148 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
149 struct list
* pEntry
= NULL
;
150 LPDMUS_PRIVATE_GRAPH_TOOL pIt
= NULL
;
152 FIXME("(%p, %ld, %p): stub\n", This
, dwIndex
, ppTool
);
154 LIST_FOR_EACH (pEntry
, &This
->Tools
) {
155 pIt
= LIST_ENTRY(pEntry
, DMUS_PRIVATE_GRAPH_TOOL
, entry
);
156 if (pIt
->dwIndex
== dwIndex
) {
157 *ppTool
= pIt
->pTool
;
158 if (NULL
!= *ppTool
) {
159 IDirectMusicTool8Impl_AddRef((LPDIRECTMUSICTOOL8
) *ppTool
);
163 if (pIt
->dwIndex
> dwIndex
) {
168 return DMUS_E_NOT_FOUND
;
171 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicGraph_RemoveTool (LPDIRECTMUSICGRAPH iface
, IDirectMusicTool
* pTool
) {
172 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, GraphVtbl
, iface
);
173 FIXME("(%p, %p): stub\n", This
, pTool
);
177 IDirectMusicGraphVtbl DirectMusicGraph_Graph_Vtbl
= {
178 IDirectMusicGraphImpl_IDirectMusicGraph_QueryInterface
,
179 IDirectMusicGraphImpl_IDirectMusicGraph_AddRef
,
180 IDirectMusicGraphImpl_IDirectMusicGraph_Release
,
181 IDirectMusicGraphImpl_IDirectMusicGraph_StampPMsg
,
182 IDirectMusicGraphImpl_IDirectMusicGraph_InsertTool
,
183 IDirectMusicGraphImpl_IDirectMusicGraph_GetTool
,
184 IDirectMusicGraphImpl_IDirectMusicGraph_RemoveTool
188 /* IDirectMusicGraphImpl IDirectMusicObject part: */
189 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface
, REFIID riid
, LPVOID
*ppobj
) {
190 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, ObjectVtbl
, iface
);
191 return IDirectMusicGraphImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
194 ULONG WINAPI
IDirectMusicGraphImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface
) {
195 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, ObjectVtbl
, iface
);
196 return IDirectMusicGraphImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
199 ULONG WINAPI
IDirectMusicGraphImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface
) {
200 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, ObjectVtbl
, iface
);
201 return IDirectMusicGraphImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
204 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
205 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, ObjectVtbl
, iface
);
206 TRACE("(%p, %p)\n", This
, pDesc
);
207 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
208 memcpy (pDesc
, This
->pDesc
, This
->pDesc
->dwSize
);
212 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
213 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, ObjectVtbl
, iface
);
214 TRACE("(%p, %p): setting descriptor:\n%s\n", This
, pDesc
, debugstr_DMUS_OBJECTDESC (pDesc
));
216 /* According to MSDN, we should copy only given values, not whole struct */
217 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
218 memcpy (&This
->pDesc
->guidObject
, &pDesc
->guidObject
, sizeof (pDesc
->guidObject
));
219 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
220 memcpy (&This
->pDesc
->guidClass
, &pDesc
->guidClass
, sizeof (pDesc
->guidClass
));
221 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
222 strncpyW (This
->pDesc
->wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
223 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
224 strncpyW (This
->pDesc
->wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
225 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
226 strncpyW (This
->pDesc
->wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
227 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
228 memcpy (&This
->pDesc
->vVersion
, &pDesc
->vVersion
, sizeof (pDesc
->vVersion
));
229 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
230 memcpy (&This
->pDesc
->ftDate
, &pDesc
->ftDate
, sizeof (pDesc
->ftDate
));
231 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
) {
232 memcpy (&This
->pDesc
->llMemLength
, &pDesc
->llMemLength
, sizeof (pDesc
->llMemLength
));
233 memcpy (This
->pDesc
->pbMemData
, pDesc
->pbMemData
, sizeof (pDesc
->pbMemData
));
235 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
) {
236 /* according to MSDN, we copy the stream */
237 IStream_Clone (pDesc
->pStream
, &This
->pDesc
->pStream
);
241 This
->pDesc
->dwValidData
|= pDesc
->dwValidData
;
246 HRESULT WINAPI
IDirectMusicGraphImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface
, LPSTREAM pStream
, LPDMUS_OBJECTDESC pDesc
) {
247 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, ObjectVtbl
, iface
);
248 DMUS_PRIVATE_CHUNK Chunk
;
249 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
250 LARGE_INTEGER liMove
; /* used when skipping chunks */
252 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
254 /* FIXME: should this be determined from stream? */
255 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
256 memcpy (&pDesc
->guidClass
, &CLSID_DirectMusicGraph
, sizeof(CLSID
));
258 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
259 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
260 switch (Chunk
.fccID
) {
262 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
263 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
264 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
266 if (Chunk
.fccID
== DMUS_FOURCC_TOOLGRAPH_FORM
) {
267 TRACE_(dmfile
)(": graph form\n");
269 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
270 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
271 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
272 switch (Chunk
.fccID
) {
273 case DMUS_FOURCC_GUID_CHUNK
: {
274 TRACE_(dmfile
)(": GUID chunk\n");
275 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
276 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
279 case DMUS_FOURCC_VERSION_CHUNK
: {
280 TRACE_(dmfile
)(": version chunk\n");
281 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
282 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
285 case DMUS_FOURCC_CATEGORY_CHUNK
: {
286 TRACE_(dmfile
)(": category chunk\n");
287 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
288 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
292 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
293 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
294 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
296 switch (Chunk
.fccID
) {
297 /* evil M$ UNFO list, which can (!?) contain INFO elements */
298 case DMUS_FOURCC_UNFO_LIST
: {
299 TRACE_(dmfile
)(": UNFO list\n");
301 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
302 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
303 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
304 switch (Chunk
.fccID
) {
305 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
306 (though strings seem to be valid unicode) */
307 case mmioFOURCC('I','N','A','M'):
308 case DMUS_FOURCC_UNAM_CHUNK
: {
309 TRACE_(dmfile
)(": name chunk\n");
310 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
311 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
314 case mmioFOURCC('I','A','R','T'):
315 case DMUS_FOURCC_UART_CHUNK
: {
316 TRACE_(dmfile
)(": artist chunk (ignored)\n");
317 liMove
.QuadPart
= Chunk
.dwSize
;
318 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
321 case mmioFOURCC('I','C','O','P'):
322 case DMUS_FOURCC_UCOP_CHUNK
: {
323 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
324 liMove
.QuadPart
= Chunk
.dwSize
;
325 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
328 case mmioFOURCC('I','S','B','J'):
329 case DMUS_FOURCC_USBJ_CHUNK
: {
330 TRACE_(dmfile
)(": subject chunk (ignored)\n");
331 liMove
.QuadPart
= Chunk
.dwSize
;
332 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
335 case mmioFOURCC('I','C','M','T'):
336 case DMUS_FOURCC_UCMT_CHUNK
: {
337 TRACE_(dmfile
)(": comment chunk (ignored)\n");
338 liMove
.QuadPart
= Chunk
.dwSize
;
339 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
343 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
344 liMove
.QuadPart
= Chunk
.dwSize
;
345 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
349 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
350 } while (ListCount
[0] < ListSize
[0]);
354 TRACE_(dmfile
)(": unknown (skipping)\n");
355 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
356 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
363 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
364 liMove
.QuadPart
= Chunk
.dwSize
;
365 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
369 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
370 } while (StreamCount
< StreamSize
);
373 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
374 liMove
.QuadPart
= StreamSize
;
375 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
379 TRACE_(dmfile
)(": reading finished\n");
383 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
384 liMove
.QuadPart
= Chunk
.dwSize
;
385 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
386 return DMUS_E_INVALIDFILE
;
390 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
395 IDirectMusicObjectVtbl DirectMusicGraph_Object_Vtbl
= {
396 IDirectMusicGraphImpl_IDirectMusicObject_QueryInterface
,
397 IDirectMusicGraphImpl_IDirectMusicObject_AddRef
,
398 IDirectMusicGraphImpl_IDirectMusicObject_Release
,
399 IDirectMusicGraphImpl_IDirectMusicObject_GetDescriptor
,
400 IDirectMusicGraphImpl_IDirectMusicObject_SetDescriptor
,
401 IDirectMusicGraphImpl_IDirectMusicObject_ParseDescriptor
404 /* IDirectMusicGraphImpl IPersistStream part: */
405 HRESULT WINAPI
IDirectMusicGraphImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
) {
406 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, PersistStreamVtbl
, iface
);
407 return IDirectMusicGraphImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
410 ULONG WINAPI
IDirectMusicGraphImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface
) {
411 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, PersistStreamVtbl
, iface
);
412 return IDirectMusicGraphImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
415 ULONG WINAPI
IDirectMusicGraphImpl_IPersistStream_Release (LPPERSISTSTREAM iface
) {
416 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, PersistStreamVtbl
, iface
);
417 return IDirectMusicGraphImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
420 HRESULT WINAPI
IDirectMusicGraphImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
) {
424 HRESULT WINAPI
IDirectMusicGraphImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface
) {
428 HRESULT WINAPI
IDirectMusicGraphImpl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
429 ICOM_THIS_MULTI(IDirectMusicGraphImpl
, PersistStreamVtbl
, iface
);
431 DWORD chunkSize
, StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
432 LARGE_INTEGER liMove
; /* used when skipping chunks */
434 FIXME("(%p, %p): Loading not implemented yet\n", This
, pStm
);
435 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
436 IStream_Read (pStm
, &chunkSize
, sizeof(DWORD
), NULL
);
437 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
440 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
441 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(chunkID
));
442 StreamSize
= chunkSize
- sizeof(FOURCC
);
445 case DMUS_FOURCC_TOOLGRAPH_FORM
: {
446 TRACE_(dmfile
)(": graph form\n");
448 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
449 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
450 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
451 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
453 case DMUS_FOURCC_GUID_CHUNK
: {
454 TRACE_(dmfile
)(": GUID chunk\n");
455 This
->pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
456 IStream_Read (pStm
, &This
->pDesc
->guidObject
, chunkSize
, NULL
);
459 case DMUS_FOURCC_VERSION_CHUNK
: {
460 TRACE_(dmfile
)(": version chunk\n");
461 This
->pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
462 IStream_Read (pStm
, &This
->pDesc
->vVersion
, chunkSize
, NULL
);
465 case DMUS_FOURCC_CATEGORY_CHUNK
: {
466 TRACE_(dmfile
)(": category chunk\n");
467 This
->pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
468 IStream_Read (pStm
, This
->pDesc
->wszCategory
, chunkSize
, NULL
);
472 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
473 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(chunkID
));
474 ListSize
[0] = chunkSize
- sizeof(FOURCC
);
477 case DMUS_FOURCC_UNFO_LIST
: {
478 TRACE_(dmfile
)(": UNFO list\n");
480 IStream_Read (pStm
, &chunkID
, sizeof(FOURCC
), NULL
);
481 IStream_Read (pStm
, &chunkSize
, sizeof(FOURCC
), NULL
);
482 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + chunkSize
;
483 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID
), chunkSize
);
485 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
486 (though strings seem to be valid unicode) */
487 case mmioFOURCC('I','N','A','M'):
488 case DMUS_FOURCC_UNAM_CHUNK
: {
489 TRACE_(dmfile
)(": name chunk\n");
490 This
->pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
491 IStream_Read (pStm
, This
->pDesc
->wszName
, chunkSize
, NULL
);
494 case mmioFOURCC('I','A','R','T'):
495 case DMUS_FOURCC_UART_CHUNK
: {
496 TRACE_(dmfile
)(": artist chunk (ignored)\n");
497 liMove
.QuadPart
= chunkSize
;
498 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
501 case mmioFOURCC('I','C','O','P'):
502 case DMUS_FOURCC_UCOP_CHUNK
: {
503 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
504 liMove
.QuadPart
= chunkSize
;
505 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
508 case mmioFOURCC('I','S','B','J'):
509 case DMUS_FOURCC_USBJ_CHUNK
: {
510 TRACE_(dmfile
)(": subject chunk (ignored)\n");
511 liMove
.QuadPart
= chunkSize
;
512 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
515 case mmioFOURCC('I','C','M','T'):
516 case DMUS_FOURCC_UCMT_CHUNK
: {
517 TRACE_(dmfile
)(": comment chunk (ignored)\n");
518 liMove
.QuadPart
= chunkSize
;
519 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
523 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
524 liMove
.QuadPart
= chunkSize
;
525 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
529 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
530 } while (ListCount
[0] < ListSize
[0]);
534 TRACE_(dmfile
)(": unknown (skipping)\n");
535 liMove
.QuadPart
= chunkSize
- sizeof(FOURCC
);
536 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
543 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
544 liMove
.QuadPart
= chunkSize
;
545 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
549 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
550 } while (StreamCount
< StreamSize
);
554 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
555 liMove
.QuadPart
= StreamSize
;
556 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
560 TRACE_(dmfile
)(": reading finished\n");
564 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
565 liMove
.QuadPart
= chunkSize
;
566 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
574 HRESULT WINAPI
IDirectMusicGraphImpl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
578 HRESULT WINAPI
IDirectMusicGraphImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
582 IPersistStreamVtbl DirectMusicGraph_PersistStream_Vtbl
= {
583 IDirectMusicGraphImpl_IPersistStream_QueryInterface
,
584 IDirectMusicGraphImpl_IPersistStream_AddRef
,
585 IDirectMusicGraphImpl_IPersistStream_Release
,
586 IDirectMusicGraphImpl_IPersistStream_GetClassID
,
587 IDirectMusicGraphImpl_IPersistStream_IsDirty
,
588 IDirectMusicGraphImpl_IPersistStream_Load
,
589 IDirectMusicGraphImpl_IPersistStream_Save
,
590 IDirectMusicGraphImpl_IPersistStream_GetSizeMax
593 /* for ClassFactory */
594 HRESULT WINAPI
DMUSIC_CreateDirectMusicGraphImpl (LPCGUID lpcGUID
, LPVOID
* ppobj
, LPUNKNOWN pUnkOuter
) {
595 IDirectMusicGraphImpl
* obj
;
597 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicGraphImpl
));
599 *ppobj
= (LPVOID
) NULL
;
600 return E_OUTOFMEMORY
;
602 obj
->UnknownVtbl
= &DirectMusicGraph_Unknown_Vtbl
;
603 obj
->GraphVtbl
= &DirectMusicGraph_Graph_Vtbl
;
604 obj
->ObjectVtbl
= &DirectMusicGraph_Object_Vtbl
;
605 obj
->PersistStreamVtbl
= &DirectMusicGraph_PersistStream_Vtbl
;
606 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
607 DM_STRUCT_INIT(obj
->pDesc
);
608 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
609 memcpy (&obj
->pDesc
->guidClass
, &CLSID_DirectMusicGraph
, sizeof (CLSID
));
610 obj
->ref
= 0; /* will be inited by QueryInterface */
611 list_init (&obj
->Tools
);
613 return IDirectMusicGraphImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&obj
->UnknownVtbl
, lpcGUID
, ppobj
);