blob: 6f9f70555b796a292ec5d536f7d034970c05c3a7 [file] [log] [blame]
Rok Mandeljc473c5652003-07-21 22:10:14 +00001/* IDirectMusicGraph
2 *
Rok Mandeljc0382ea12004-01-20 00:21:40 +00003 * Copyright (C) 2003-2004 Rok Mandeljc
Rok Mandeljc473c5652003-07-21 22:10:14 +00004 *
Alexandre Julliard7718d2b2007-05-30 12:54:07 +02005 * 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.
Rok Mandeljc473c5652003-07-21 22:10:14 +00009 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Alexandre Julliard7718d2b2007-05-30 12:54:07 +020012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
Rok Mandeljc473c5652003-07-21 22:10:14 +000014 *
Alexandre Julliard7718d2b2007-05-30 12:54:07 +020015 * 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
Rok Mandeljc473c5652003-07-21 22:10:14 +000018 */
19
Rok Mandeljc473c5652003-07-21 22:10:14 +000020#include "dmime_private.h"
21
Rok Mandeljcdf167d12003-08-22 23:53:27 +000022WINE_DEFAULT_DEBUG_CHANNEL(dmime);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000023WINE_DECLARE_DEBUG_CHANNEL(dmfile);
Rok Mandeljc473c5652003-07-21 22:10:14 +000024
Rok Mandeljc0382ea12004-01-20 00:21:40 +000025/*****************************************************************************
26 * IDirectMusicGraphImpl implementation
27 */
28/* IDirectMusicGraphImpl IUnknown part: */
Mike McCormack06e23da2005-06-21 09:44:28 +000029static HRESULT WINAPI IDirectMusicGraphImpl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000030 ICOM_THIS_MULTI(IDirectMusicGraphImpl, UnknownVtbl, iface);
Rok Mandeljcb26d65b2004-02-25 01:30:03 +000031 TRACE("(%p, %s, %p)\n", This, debugstr_guid(riid), ppobj);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000032
33 if (IsEqualIID (riid, &IID_IUnknown)) {
Michael Stefaniuc49177a02009-01-13 10:56:24 +010034 *ppobj = &This->UnknownVtbl;
Mike McCormack06e23da2005-06-21 09:44:28 +000035 IUnknown_AddRef (iface);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000036 return S_OK;
37 } else if (IsEqualIID (riid, &IID_IDirectMusicGraph)) {
Michael Stefaniuc49177a02009-01-13 10:56:24 +010038 *ppobj = &This->GraphVtbl;
Mike McCormack06e23da2005-06-21 09:44:28 +000039 IUnknown_AddRef (iface);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000040 return S_OK;
41 } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) {
Michael Stefaniuc49177a02009-01-13 10:56:24 +010042 *ppobj = &This->ObjectVtbl;
Mike McCormack06e23da2005-06-21 09:44:28 +000043 IUnknown_AddRef (iface);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000044 return S_OK;
45 } else if (IsEqualIID (riid, &IID_IPersistStream)) {
Michael Stefaniuc49177a02009-01-13 10:56:24 +010046 *ppobj = &This->PersistStreamVtbl;
Mike McCormack06e23da2005-06-21 09:44:28 +000047 IUnknown_AddRef (iface);
Rok Mandeljc473c5652003-07-21 22:10:14 +000048 return S_OK;
49 }
Rok Mandeljcdf167d12003-08-22 23:53:27 +000050
Rok Mandeljcb26d65b2004-02-25 01:30:03 +000051 WARN("(%p, %s, %p): not found\n", This, debugstr_guid(riid), ppobj);
Rok Mandeljc473c5652003-07-21 22:10:14 +000052 return E_NOINTERFACE;
53}
54
Mike McCormack06e23da2005-06-21 09:44:28 +000055static ULONG WINAPI IDirectMusicGraphImpl_IUnknown_AddRef (LPUNKNOWN iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000056 ICOM_THIS_MULTI(IDirectMusicGraphImpl, UnknownVtbl, iface);
Paul Vriens3da85242005-01-11 16:02:21 +000057 ULONG ref = InterlockedIncrement(&This->ref);
58
Michael Stefaniuc891e0162006-10-10 01:07:26 +020059 TRACE("(%p): AddRef from %d\n", This, ref - 1);
Paul Vriens3da85242005-01-11 16:02:21 +000060
James Hawkins1727eb42005-02-02 09:31:06 +000061 DMIME_LockModule();
62
Paul Vriens3da85242005-01-11 16:02:21 +000063 return ref;
Rok Mandeljc473c5652003-07-21 22:10:14 +000064}
65
Mike McCormackff536fb2005-06-20 16:01:04 +000066static ULONG WINAPI IDirectMusicGraphImpl_IUnknown_Release (LPUNKNOWN iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000067 ICOM_THIS_MULTI(IDirectMusicGraphImpl, UnknownVtbl, iface);
Paul Vriens3da85242005-01-11 16:02:21 +000068 ULONG ref = InterlockedDecrement(&This->ref);
Michael Stefaniuc891e0162006-10-10 01:07:26 +020069 TRACE("(%p): ReleaseRef to %d\n", This, ref);
James Hawkins1727eb42005-02-02 09:31:06 +000070
Rok Mandeljcdf167d12003-08-22 23:53:27 +000071 if (ref == 0) {
Rok Mandeljc473c5652003-07-21 22:10:14 +000072 HeapFree(GetProcessHeap(), 0, This);
73 }
James Hawkins1727eb42005-02-02 09:31:06 +000074
75 DMIME_UnlockModule();
76
Rok Mandeljc473c5652003-07-21 22:10:14 +000077 return ref;
78}
79
Dmitry Timoshkov247246e2005-05-30 10:01:08 +000080static const IUnknownVtbl DirectMusicGraph_Unknown_Vtbl = {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000081 IDirectMusicGraphImpl_IUnknown_QueryInterface,
82 IDirectMusicGraphImpl_IUnknown_AddRef,
83 IDirectMusicGraphImpl_IUnknown_Release
84};
Rok Mandeljc473c5652003-07-21 22:10:14 +000085
Rok Mandeljc0382ea12004-01-20 00:21:40 +000086/* IDirectMusicGraphImpl IDirectMusicGraph part: */
Mike McCormack06e23da2005-06-21 09:44:28 +000087static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_QueryInterface (LPDIRECTMUSICGRAPH iface, REFIID riid, LPVOID *ppobj) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000088 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
Mike McCormack06e23da2005-06-21 09:44:28 +000089 return IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000090}
91
Mike McCormack06e23da2005-06-21 09:44:28 +000092static ULONG WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_AddRef (LPDIRECTMUSICGRAPH iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000093 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
Mike McCormack06e23da2005-06-21 09:44:28 +000094 return IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
Rok Mandeljc0382ea12004-01-20 00:21:40 +000095}
96
Mike McCormackff536fb2005-06-20 16:01:04 +000097static ULONG WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_Release (LPDIRECTMUSICGRAPH iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +000098 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
Mike McCormack06e23da2005-06-21 09:44:28 +000099 return IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000100}
101
Mike McCormackff536fb2005-06-20 16:01:04 +0000102static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_StampPMsg (LPDIRECTMUSICGRAPH iface, DMUS_PMSG* pPMSG) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000103 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
Rok Mandeljc473c5652003-07-21 22:10:14 +0000104 FIXME("(%p, %p): stub\n", This, pPMSG);
Rok Mandeljc473c5652003-07-21 22:10:14 +0000105 return S_OK;
106}
107
Mike McCormackff536fb2005-06-20 16:01:04 +0000108static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_InsertTool (LPDIRECTMUSICGRAPH iface, IDirectMusicTool* pTool, DWORD* pdwPChannels, DWORD cPChannels, LONG lIndex) {
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000109 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
Rok Mandeljc473c5652003-07-21 22:10:14 +0000110
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000111 struct list* pEntry = NULL;
112 struct list* pPrevEntry = NULL;
113 LPDMUS_PRIVATE_GRAPH_TOOL pIt = NULL;
114 LPDMUS_PRIVATE_GRAPH_TOOL pNewTool = NULL;
Rok Mandeljc473c5652003-07-21 22:10:14 +0000115
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000116
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200117 FIXME("(%p, %p, %p, %d, %i): use of pdwPChannels\n", This, pTool, pdwPChannels, cPChannels, lIndex);
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000118
119 if (NULL == pTool) {
120 return E_POINTER;
121 }
122
123 if (0 > lIndex) {
124 lIndex = This->num_tools + lIndex;
125 }
126
127 pPrevEntry = &This->Tools;
128 LIST_FOR_EACH (pEntry, &This->Tools) {
129 pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_GRAPH_TOOL, entry);
130 if (pIt->dwIndex == lIndex) {
131 return DMUS_E_ALREADY_EXISTS;
132 }
133 if (pIt->dwIndex > lIndex) {
134 break ;
135 }
136 pPrevEntry = pEntry;
137 }
138
139 ++This->num_tools;
140 pNewTool = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_GRAPH_TOOL));
141 pNewTool->pTool = pTool;
142 pNewTool->dwIndex = lIndex;
143 IDirectMusicTool8_AddRef(pTool);
Andrew Talbota73ab622008-04-15 21:33:30 +0100144 IDirectMusicTool8_Init(pTool, iface);
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000145 list_add_tail (pPrevEntry->next, &pNewTool->entry);
146
147#if 0
148 DWORD dwNum = 0;
Andrew Talbota73ab622008-04-15 21:33:30 +0100149 IDirectMusicTool8_GetMediaTypes(pTool, &dwNum);
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000150#endif
Andrew Talbota73ab622008-04-15 21:33:30 +0100151
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000152 return DS_OK;
Rok Mandeljc473c5652003-07-21 22:10:14 +0000153}
154
Mike McCormackff536fb2005-06-20 16:01:04 +0000155static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_GetTool (LPDIRECTMUSICGRAPH iface, DWORD dwIndex, IDirectMusicTool** ppTool) {
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000156 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
157 struct list* pEntry = NULL;
158 LPDMUS_PRIVATE_GRAPH_TOOL pIt = NULL;
159
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200160 FIXME("(%p, %d, %p): stub\n", This, dwIndex, ppTool);
Rok Mandeljc473c5652003-07-21 22:10:14 +0000161
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000162 LIST_FOR_EACH (pEntry, &This->Tools) {
163 pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_GRAPH_TOOL, entry);
164 if (pIt->dwIndex == dwIndex) {
165 *ppTool = pIt->pTool;
166 if (NULL != *ppTool) {
Mike McCormack06e23da2005-06-21 09:44:28 +0000167 IDirectMusicTool8_AddRef((LPDIRECTMUSICTOOL8) *ppTool);
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000168 }
169 return S_OK;
170 }
171 if (pIt->dwIndex > dwIndex) {
172 break ;
173 }
174 }
175
176 return DMUS_E_NOT_FOUND;
Rok Mandeljc473c5652003-07-21 22:10:14 +0000177}
178
Mike McCormackff536fb2005-06-20 16:01:04 +0000179static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicGraph_RemoveTool (LPDIRECTMUSICGRAPH iface, IDirectMusicTool* pTool) {
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000180 ICOM_THIS_MULTI(IDirectMusicGraphImpl, GraphVtbl, iface);
181 FIXME("(%p, %p): stub\n", This, pTool);
182 return S_OK;
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000183}
184
Dmitry Timoshkov247246e2005-05-30 10:01:08 +0000185static const IDirectMusicGraphVtbl DirectMusicGraph_Graph_Vtbl = {
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000186 IDirectMusicGraphImpl_IDirectMusicGraph_QueryInterface,
187 IDirectMusicGraphImpl_IDirectMusicGraph_AddRef,
188 IDirectMusicGraphImpl_IDirectMusicGraph_Release,
189 IDirectMusicGraphImpl_IDirectMusicGraph_StampPMsg,
190 IDirectMusicGraphImpl_IDirectMusicGraph_InsertTool,
191 IDirectMusicGraphImpl_IDirectMusicGraph_GetTool,
192 IDirectMusicGraphImpl_IDirectMusicGraph_RemoveTool
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000193};
194
195
196/* IDirectMusicGraphImpl IDirectMusicObject part: */
Mike McCormack06e23da2005-06-21 09:44:28 +0000197static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000198 ICOM_THIS_MULTI(IDirectMusicGraphImpl, ObjectVtbl, iface);
Mike McCormack06e23da2005-06-21 09:44:28 +0000199 return IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000200}
201
Mike McCormack06e23da2005-06-21 09:44:28 +0000202static ULONG WINAPI IDirectMusicGraphImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000203 ICOM_THIS_MULTI(IDirectMusicGraphImpl, ObjectVtbl, iface);
Mike McCormack06e23da2005-06-21 09:44:28 +0000204 return IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000205}
206
Mike McCormackff536fb2005-06-20 16:01:04 +0000207static ULONG WINAPI IDirectMusicGraphImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000208 ICOM_THIS_MULTI(IDirectMusicGraphImpl, ObjectVtbl, iface);
Mike McCormack06e23da2005-06-21 09:44:28 +0000209 return IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000210}
211
Mike McCormackff536fb2005-06-20 16:01:04 +0000212static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000213 ICOM_THIS_MULTI(IDirectMusicGraphImpl, ObjectVtbl, iface);
214 TRACE("(%p, %p)\n", This, pDesc);
215 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
216 memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
217 return S_OK;
218}
219
Mike McCormackff536fb2005-06-20 16:01:04 +0000220static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000221 ICOM_THIS_MULTI(IDirectMusicGraphImpl, ObjectVtbl, iface);
Rok Mandeljcb26d65b2004-02-25 01:30:03 +0000222 TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc));
Andrew Talbot13afbc02008-02-23 15:19:04 +0000223
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000224 /* According to MSDN, we should copy only given values, not whole struct */
225 if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
Andrew Talbot13afbc02008-02-23 15:19:04 +0000226 This->pDesc->guidObject = pDesc->guidObject;
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000227 if (pDesc->dwValidData & DMUS_OBJ_CLASS)
Andrew Talbot13afbc02008-02-23 15:19:04 +0000228 This->pDesc->guidClass = pDesc->guidClass;
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000229 if (pDesc->dwValidData & DMUS_OBJ_NAME)
Peter Berg Larsen6e3bcb52005-04-18 10:30:55 +0000230 lstrcpynW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000231 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
Peter Berg Larsen6e3bcb52005-04-18 10:30:55 +0000232 lstrcpynW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000233 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
Peter Berg Larsen6e3bcb52005-04-18 10:30:55 +0000234 lstrcpynW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000235 if (pDesc->dwValidData & DMUS_OBJ_VERSION)
Andrew Talbot13afbc02008-02-23 15:19:04 +0000236 This->pDesc->vVersion = pDesc->vVersion;
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000237 if (pDesc->dwValidData & DMUS_OBJ_DATE)
Andrew Talbot13afbc02008-02-23 15:19:04 +0000238 This->pDesc->ftDate = pDesc->ftDate;
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000239 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
240 memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength));
241 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData));
242 }
243 if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
244 /* according to MSDN, we copy the stream */
245 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
246 }
247
248 /* add new flags */
249 This->pDesc->dwValidData |= pDesc->dwValidData;
Rok Mandeljc473c5652003-07-21 22:10:14 +0000250
251 return S_OK;
252}
253
Mike McCormackff536fb2005-06-20 16:01:04 +0000254static HRESULT WINAPI IDirectMusicGraphImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000255 ICOM_THIS_MULTI(IDirectMusicGraphImpl, ObjectVtbl, iface);
256 DMUS_PRIVATE_CHUNK Chunk;
257 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
258 LARGE_INTEGER liMove; /* used when skipping chunks */
259
260 TRACE("(%p, %p, %p)\n", This, pStream, pDesc);
Andrew Talbot13afbc02008-02-23 15:19:04 +0000261
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000262 /* FIXME: should this be determined from stream? */
263 pDesc->dwValidData |= DMUS_OBJ_CLASS;
Andrew Talbot13afbc02008-02-23 15:19:04 +0000264 pDesc->guidClass = CLSID_DirectMusicGraph;
265
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000266 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200267 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000268 switch (Chunk.fccID) {
269 case FOURCC_RIFF: {
270 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
271 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
272 StreamSize = Chunk.dwSize - sizeof(FOURCC);
273 StreamCount = 0;
274 if (Chunk.fccID == DMUS_FOURCC_TOOLGRAPH_FORM) {
275 TRACE_(dmfile)(": graph form\n");
276 do {
277 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
278 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200279 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000280 switch (Chunk.fccID) {
281 case DMUS_FOURCC_GUID_CHUNK: {
282 TRACE_(dmfile)(": GUID chunk\n");
283 pDesc->dwValidData |= DMUS_OBJ_OBJECT;
284 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
285 break;
286 }
287 case DMUS_FOURCC_VERSION_CHUNK: {
288 TRACE_(dmfile)(": version chunk\n");
289 pDesc->dwValidData |= DMUS_OBJ_VERSION;
290 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
291 break;
292 }
293 case DMUS_FOURCC_CATEGORY_CHUNK: {
294 TRACE_(dmfile)(": category chunk\n");
295 pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
296 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
297 break;
298 }
299 case FOURCC_LIST: {
300 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
301 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
302 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
303 ListCount[0] = 0;
304 switch (Chunk.fccID) {
305 /* evil M$ UNFO list, which can (!?) contain INFO elements */
306 case DMUS_FOURCC_UNFO_LIST: {
307 TRACE_(dmfile)(": UNFO list\n");
308 do {
309 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
310 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200311 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000312 switch (Chunk.fccID) {
313 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
314 (though strings seem to be valid unicode) */
315 case mmioFOURCC('I','N','A','M'):
316 case DMUS_FOURCC_UNAM_CHUNK: {
317 TRACE_(dmfile)(": name chunk\n");
318 pDesc->dwValidData |= DMUS_OBJ_NAME;
319 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
320 break;
321 }
322 case mmioFOURCC('I','A','R','T'):
323 case DMUS_FOURCC_UART_CHUNK: {
324 TRACE_(dmfile)(": artist chunk (ignored)\n");
325 liMove.QuadPart = Chunk.dwSize;
326 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
327 break;
328 }
329 case mmioFOURCC('I','C','O','P'):
330 case DMUS_FOURCC_UCOP_CHUNK: {
331 TRACE_(dmfile)(": copyright chunk (ignored)\n");
332 liMove.QuadPart = Chunk.dwSize;
333 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
334 break;
335 }
336 case mmioFOURCC('I','S','B','J'):
337 case DMUS_FOURCC_USBJ_CHUNK: {
338 TRACE_(dmfile)(": subject chunk (ignored)\n");
339 liMove.QuadPart = Chunk.dwSize;
340 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
341 break;
342 }
343 case mmioFOURCC('I','C','M','T'):
344 case DMUS_FOURCC_UCMT_CHUNK: {
345 TRACE_(dmfile)(": comment chunk (ignored)\n");
346 liMove.QuadPart = Chunk.dwSize;
347 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
348 break;
349 }
350 default: {
351 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
352 liMove.QuadPart = Chunk.dwSize;
353 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
354 break;
355 }
356 }
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200357 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000358 } while (ListCount[0] < ListSize[0]);
359 break;
360 }
361 default: {
362 TRACE_(dmfile)(": unknown (skipping)\n");
363 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
364 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
365 break;
366 }
367 }
368 break;
369 }
370 default: {
371 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
372 liMove.QuadPart = Chunk.dwSize;
373 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
374 break;
375 }
376 }
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200377 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000378 } while (StreamCount < StreamSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000379 } else {
380 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
381 liMove.QuadPart = StreamSize;
382 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
383 return E_FAIL;
384 }
385
386 TRACE_(dmfile)(": reading finished\n");
387 break;
388 }
389 default: {
390 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
391 liMove.QuadPart = Chunk.dwSize;
392 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
393 return DMUS_E_INVALIDFILE;
394 }
395 }
396
Rok Mandeljcb26d65b2004-02-25 01:30:03 +0000397 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc));
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000398
399 return S_OK;
400}
401
Dmitry Timoshkov247246e2005-05-30 10:01:08 +0000402static const IDirectMusicObjectVtbl DirectMusicGraph_Object_Vtbl = {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000403 IDirectMusicGraphImpl_IDirectMusicObject_QueryInterface,
404 IDirectMusicGraphImpl_IDirectMusicObject_AddRef,
405 IDirectMusicGraphImpl_IDirectMusicObject_Release,
406 IDirectMusicGraphImpl_IDirectMusicObject_GetDescriptor,
407 IDirectMusicGraphImpl_IDirectMusicObject_SetDescriptor,
408 IDirectMusicGraphImpl_IDirectMusicObject_ParseDescriptor
409};
410
411/* IDirectMusicGraphImpl IPersistStream part: */
Mike McCormack06e23da2005-06-21 09:44:28 +0000412static HRESULT WINAPI IDirectMusicGraphImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000413 ICOM_THIS_MULTI(IDirectMusicGraphImpl, PersistStreamVtbl, iface);
414 return IDirectMusicGraphImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
415}
416
Mike McCormack06e23da2005-06-21 09:44:28 +0000417static ULONG WINAPI IDirectMusicGraphImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000418 ICOM_THIS_MULTI(IDirectMusicGraphImpl, PersistStreamVtbl, iface);
419 return IDirectMusicGraphImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
420}
421
Mike McCormackff536fb2005-06-20 16:01:04 +0000422static ULONG WINAPI IDirectMusicGraphImpl_IPersistStream_Release (LPPERSISTSTREAM iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000423 ICOM_THIS_MULTI(IDirectMusicGraphImpl, PersistStreamVtbl, iface);
424 return IDirectMusicGraphImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
425}
426
Mike McCormackff536fb2005-06-20 16:01:04 +0000427static HRESULT WINAPI IDirectMusicGraphImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000428 return E_NOTIMPL;
429}
430
Mike McCormackff536fb2005-06-20 16:01:04 +0000431static HRESULT WINAPI IDirectMusicGraphImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000432 return E_NOTIMPL;
433}
434
Mike McCormackff536fb2005-06-20 16:01:04 +0000435static HRESULT WINAPI IDirectMusicGraphImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000436 ICOM_THIS_MULTI(IDirectMusicGraphImpl, PersistStreamVtbl, iface);
437 FOURCC chunkID;
438 DWORD chunkSize, StreamSize, StreamCount, ListSize[3], ListCount[3];
439 LARGE_INTEGER liMove; /* used when skipping chunks */
440
441 FIXME("(%p, %p): Loading not implemented yet\n", This, pStm);
442 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
443 IStream_Read (pStm, &chunkSize, sizeof(DWORD), NULL);
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200444 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000445 switch (chunkID) {
446 case FOURCC_RIFF: {
447 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
448 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(chunkID));
449 StreamSize = chunkSize - sizeof(FOURCC);
450 StreamCount = 0;
451 switch (chunkID) {
452 case DMUS_FOURCC_TOOLGRAPH_FORM: {
453 TRACE_(dmfile)(": graph form\n");
454 do {
455 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
456 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
457 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200458 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000459 switch (chunkID) {
460 case DMUS_FOURCC_GUID_CHUNK: {
461 TRACE_(dmfile)(": GUID chunk\n");
462 This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
463 IStream_Read (pStm, &This->pDesc->guidObject, chunkSize, NULL);
464 break;
465 }
466 case DMUS_FOURCC_VERSION_CHUNK: {
467 TRACE_(dmfile)(": version chunk\n");
468 This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
469 IStream_Read (pStm, &This->pDesc->vVersion, chunkSize, NULL);
470 break;
471 }
472 case DMUS_FOURCC_CATEGORY_CHUNK: {
473 TRACE_(dmfile)(": category chunk\n");
474 This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
475 IStream_Read (pStm, This->pDesc->wszCategory, chunkSize, NULL);
476 break;
477 }
478 case FOURCC_LIST: {
479 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
480 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunkID));
481 ListSize[0] = chunkSize - sizeof(FOURCC);
482 ListCount[0] = 0;
483 switch (chunkID) {
484 case DMUS_FOURCC_UNFO_LIST: {
485 TRACE_(dmfile)(": UNFO list\n");
486 do {
487 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
488 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
489 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200490 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000491 switch (chunkID) {
492 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
493 (though strings seem to be valid unicode) */
494 case mmioFOURCC('I','N','A','M'):
495 case DMUS_FOURCC_UNAM_CHUNK: {
496 TRACE_(dmfile)(": name chunk\n");
497 This->pDesc->dwValidData |= DMUS_OBJ_NAME;
498 IStream_Read (pStm, This->pDesc->wszName, chunkSize, NULL);
499 break;
500 }
501 case mmioFOURCC('I','A','R','T'):
502 case DMUS_FOURCC_UART_CHUNK: {
503 TRACE_(dmfile)(": artist chunk (ignored)\n");
504 liMove.QuadPart = chunkSize;
505 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
506 break;
507 }
508 case mmioFOURCC('I','C','O','P'):
509 case DMUS_FOURCC_UCOP_CHUNK: {
510 TRACE_(dmfile)(": copyright chunk (ignored)\n");
511 liMove.QuadPart = chunkSize;
512 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
513 break;
514 }
515 case mmioFOURCC('I','S','B','J'):
516 case DMUS_FOURCC_USBJ_CHUNK: {
517 TRACE_(dmfile)(": subject chunk (ignored)\n");
518 liMove.QuadPart = chunkSize;
519 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
520 break;
521 }
522 case mmioFOURCC('I','C','M','T'):
523 case DMUS_FOURCC_UCMT_CHUNK: {
524 TRACE_(dmfile)(": comment chunk (ignored)\n");
525 liMove.QuadPart = chunkSize;
526 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
527 break;
528 }
529 default: {
530 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
531 liMove.QuadPart = chunkSize;
532 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
533 break;
534 }
535 }
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200536 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000537 } while (ListCount[0] < ListSize[0]);
538 break;
539 }
540 default: {
541 TRACE_(dmfile)(": unknown (skipping)\n");
542 liMove.QuadPart = chunkSize - sizeof(FOURCC);
543 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
544 break;
545 }
546 }
547 break;
548 }
549 default: {
550 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
551 liMove.QuadPart = chunkSize;
552 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
553 break;
554 }
555 }
Michael Stefaniuc891e0162006-10-10 01:07:26 +0200556 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000557 } while (StreamCount < StreamSize);
558 break;
559 }
560 default: {
561 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
562 liMove.QuadPart = StreamSize;
563 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
564 return E_FAIL;
565 }
566 }
567 TRACE_(dmfile)(": reading finished\n");
568 break;
569 }
570 default: {
571 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
572 liMove.QuadPart = chunkSize;
573 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
574 return E_FAIL;
575 }
576 }
577
578 return S_OK;
579}
580
Mike McCormackff536fb2005-06-20 16:01:04 +0000581static HRESULT WINAPI IDirectMusicGraphImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000582 return E_NOTIMPL;
583}
584
Mike McCormackff536fb2005-06-20 16:01:04 +0000585static HRESULT WINAPI IDirectMusicGraphImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000586 return E_NOTIMPL;
587}
588
Dmitry Timoshkov247246e2005-05-30 10:01:08 +0000589static const IPersistStreamVtbl DirectMusicGraph_PersistStream_Vtbl = {
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000590 IDirectMusicGraphImpl_IPersistStream_QueryInterface,
591 IDirectMusicGraphImpl_IPersistStream_AddRef,
592 IDirectMusicGraphImpl_IPersistStream_Release,
593 IDirectMusicGraphImpl_IPersistStream_GetClassID,
594 IDirectMusicGraphImpl_IPersistStream_IsDirty,
595 IDirectMusicGraphImpl_IPersistStream_Load,
596 IDirectMusicGraphImpl_IPersistStream_Save,
597 IDirectMusicGraphImpl_IPersistStream_GetSizeMax
Rok Mandeljc473c5652003-07-21 22:10:14 +0000598};
599
600/* for ClassFactory */
Rok Mandeljc0382ea12004-01-20 00:21:40 +0000601HRESULT WINAPI DMUSIC_CreateDirectMusicGraphImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) {
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000602 IDirectMusicGraphImpl* obj;
603
604 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicGraphImpl));
605 if (NULL == obj) {
Francois Gougetee0344a2004-12-22 15:13:20 +0000606 *ppobj = NULL;
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000607 return E_OUTOFMEMORY;
608 }
609 obj->UnknownVtbl = &DirectMusicGraph_Unknown_Vtbl;
610 obj->GraphVtbl = &DirectMusicGraph_Graph_Vtbl;
611 obj->ObjectVtbl = &DirectMusicGraph_Object_Vtbl;
612 obj->PersistStreamVtbl = &DirectMusicGraph_PersistStream_Vtbl;
613 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
614 DM_STRUCT_INIT(obj->pDesc);
615 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
Andrew Talbot13afbc02008-02-23 15:19:04 +0000616 obj->pDesc->guidClass = CLSID_DirectMusicGraph;
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000617 obj->ref = 0; /* will be inited by QueryInterface */
618 list_init (&obj->Tools);
Andrew Talbot13afbc02008-02-23 15:19:04 +0000619
Raphael Junqueiraca7ee472004-05-20 01:15:30 +0000620 return IDirectMusicGraphImpl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);
Rok Mandeljc473c5652003-07-21 22:10:14 +0000621}