- Add the same new files (dmutils.c/dmutils.h) into dmime,dmband and
[wine.git] / dlls / dmstyle / style.c
blob1e6aad35cb95c60f79d96a6a0a1cb3a71e30c9f3
1 /* IDirectMusicStyle8 Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2003-2004 Raphael Junqueira
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Library General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "dmstyle_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(dmstyle);
24 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
26 /*****************************************************************************
27 * IDirectMusicStyleImpl implementation
29 /* IDirectMusicStyleImpl IUnknown part: */
30 HRESULT WINAPI IDirectMusicStyle8Impl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
31 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, UnknownVtbl, iface);
32 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
34 if (IsEqualIID (riid, &IID_IUnknown)) {
35 *ppobj = (LPVOID)&This->UnknownVtbl;
36 IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
37 return S_OK;
38 } else if (IsEqualIID (riid, &IID_IDirectMusicStyle)) {
39 *ppobj = (LPVOID)&This->StyleVtbl;
40 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef ((LPDIRECTMUSICSTYLE8)&This->StyleVtbl);
41 return S_OK;
42 } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) {
43 *ppobj = (LPVOID)&This->ObjectVtbl;
44 IDirectMusicStyle8Impl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT)&This->ObjectVtbl);
45 return S_OK;
46 } else if (IsEqualIID (riid, &IID_IPersistStream)) {
47 *ppobj = (LPVOID)&This->PersistStreamVtbl;
48 IDirectMusicStyle8Impl_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl);
49 return S_OK;
52 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
53 return E_NOINTERFACE;
56 ULONG WINAPI IDirectMusicStyle8Impl_IUnknown_AddRef (LPUNKNOWN iface) {
57 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, UnknownVtbl, iface);
58 TRACE("(%p): AddRef from %ld\n", This, This->ref);
59 return ++(This->ref);
62 ULONG WINAPI IDirectMusicStyle8Impl_IUnknown_Release (LPUNKNOWN iface) {
63 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, UnknownVtbl, iface);
64 ULONG ref = --This->ref;
65 TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
66 if (ref == 0) {
67 HeapFree(GetProcessHeap(), 0, This);
69 return ref;
72 ICOM_VTABLE(IUnknown) DirectMusicStyle8_Unknown_Vtbl = {
73 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
74 IDirectMusicStyle8Impl_IUnknown_QueryInterface,
75 IDirectMusicStyle8Impl_IUnknown_AddRef,
76 IDirectMusicStyle8Impl_IUnknown_Release
79 /* IDirectMusicStyle8Impl IDirectMusicStyle8 part: */
80 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_QueryInterface (LPDIRECTMUSICSTYLE8 iface, REFIID riid, LPVOID *ppobj) {
81 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
82 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
85 ULONG WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef (LPDIRECTMUSICSTYLE8 iface) {
86 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
87 return IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
90 ULONG WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_Release (LPDIRECTMUSICSTYLE8 iface) {
91 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
92 return IDirectMusicStyle8Impl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
95 /* IDirectMusicStyle8Impl IDirectMusicStyle(8) part: */
96 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetBand (LPDIRECTMUSICSTYLE8 iface, WCHAR* pwszName, IDirectMusicBand** ppBand) {
97 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
98 FIXME("(%p, %p, %p): stub\n", This, pwszName, ppBand);
99 return S_OK;
102 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumBand (LPDIRECTMUSICSTYLE8 iface, DWORD dwIndex, WCHAR* pwszName) {
103 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
104 FIXME("(%p, %ld, %p): stub\n", This, dwIndex, pwszName);
105 return S_OK;
108 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultBand (LPDIRECTMUSICSTYLE8 iface, IDirectMusicBand** ppBand) {
109 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
110 FIXME("(%p, %p): stub\n", This, ppBand);
111 return S_OK;
114 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumMotif (LPDIRECTMUSICSTYLE8 iface, DWORD dwIndex, WCHAR* pwszName) {
115 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
116 FIXME("(%p, %ld, %p): stub\n", This, dwIndex, pwszName);
117 return S_OK;
120 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetMotif (LPDIRECTMUSICSTYLE8 iface, WCHAR* pwszName, IDirectMusicSegment** ppSegment) {
121 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
122 FIXME("(%p, %p, %p): stub\n", This, pwszName, ppSegment);
123 return S_OK;
126 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultChordMap (LPDIRECTMUSICSTYLE8 iface, IDirectMusicChordMap** ppChordMap) {
127 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
128 FIXME("(%p, %p): stub\n", This, ppChordMap);
129 return S_OK;
132 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumChordMap (LPDIRECTMUSICSTYLE8 iface, DWORD dwIndex, WCHAR* pwszName) {
133 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
134 FIXME("(%p, %ld, %p): stub\n", This, dwIndex, pwszName);
135 return S_OK;
138 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetChordMap (LPDIRECTMUSICSTYLE8 iface, WCHAR* pwszName, IDirectMusicChordMap** ppChordMap) {
139 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
140 FIXME("(%p, %p, %p): stub\n", This, pwszName, ppChordMap);
141 return S_OK;
144 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTimeSignature (LPDIRECTMUSICSTYLE8 iface, DMUS_TIMESIGNATURE* pTimeSig) {
145 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
146 FIXME("(%p, %p): stub\n", This, pTimeSig);
147 return S_OK;
150 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetEmbellishmentLength (LPDIRECTMUSICSTYLE8 iface, DWORD dwType, DWORD dwLevel, DWORD* pdwMin, DWORD* pdwMax) {
151 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
152 FIXME("(%p, %ld, %ld, %p, %p): stub\n", This, dwType, dwLevel, pdwMin, pdwMax);
153 return S_OK;
156 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTempo (LPDIRECTMUSICSTYLE8 iface, double* pTempo) {
157 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
158 FIXME("(%p, %p): stub\n", This, pTempo);
159 return S_OK;
162 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumPattern (LPDIRECTMUSICSTYLE8 iface, DWORD dwIndex, DWORD dwPatternType, WCHAR* pwszName) {
163 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, StyleVtbl, iface);
164 FIXME("(%p, %ld, %ld, %p): stub\n", This, dwIndex, dwPatternType, pwszName);
165 return S_OK;
168 ICOM_VTABLE(IDirectMusicStyle8) DirectMusicStyle8_Style_Vtbl = {
169 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
170 IDirectMusicStyle8Impl_IDirectMusicStyle8_QueryInterface,
171 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef,
172 IDirectMusicStyle8Impl_IDirectMusicStyle8_Release,
173 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetBand,
174 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumBand,
175 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultBand,
176 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumMotif,
177 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetMotif,
178 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultChordMap,
179 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumChordMap,
180 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetChordMap,
181 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTimeSignature,
182 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetEmbellishmentLength,
183 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTempo,
184 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumPattern
187 /* IDirectMusicStyle8Impl IDirectMusicObject part: */
188 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
189 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
190 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
193 ULONG WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
194 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
195 return IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
198 ULONG WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
199 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
200 return IDirectMusicStyle8Impl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
203 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
204 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
205 TRACE("(%p, %p)\n", This, pDesc);
206 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
207 memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
208 return S_OK;
211 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
212 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
213 TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc));
215 /* According to MSDN, we should copy only given values, not whole struct */
216 if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
217 memcpy (&This->pDesc->guidObject, &pDesc->guidObject, sizeof (pDesc->guidObject));
218 if (pDesc->dwValidData & DMUS_OBJ_CLASS)
219 memcpy (&This->pDesc->guidClass, &pDesc->guidClass, sizeof (pDesc->guidClass));
220 if (pDesc->dwValidData & DMUS_OBJ_NAME)
221 strncpyW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
222 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
223 strncpyW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
224 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
225 strncpyW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
226 if (pDesc->dwValidData & DMUS_OBJ_VERSION)
227 memcpy (&This->pDesc->vVersion, &pDesc->vVersion, sizeof (pDesc->vVersion));
228 if (pDesc->dwValidData & DMUS_OBJ_DATE)
229 memcpy (&This->pDesc->ftDate, &pDesc->ftDate, sizeof (pDesc->ftDate));
230 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
231 memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength));
232 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData));
234 if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
235 /* according to MSDN, we copy the stream */
236 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
239 /* add new flags */
240 This->pDesc->dwValidData |= pDesc->dwValidData;
242 return S_OK;
245 HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
246 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
247 DMUS_PRIVATE_CHUNK Chunk;
248 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
249 LARGE_INTEGER liMove; /* used when skipping chunks */
251 TRACE("(%p, %p, %p)\n", This, pStream, pDesc);
253 /* FIXME: should this be determined from stream? */
254 pDesc->dwValidData |= DMUS_OBJ_CLASS;
255 memcpy (&pDesc->guidClass, &CLSID_DirectMusicStyle, sizeof(CLSID));
257 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
258 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
259 switch (Chunk.fccID) {
260 case FOURCC_RIFF: {
261 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
262 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
263 StreamSize = Chunk.dwSize - sizeof(FOURCC);
264 StreamCount = 0;
265 if (Chunk.fccID == DMUS_FOURCC_STYLE_FORM) {
266 TRACE_(dmfile)(": style form\n");
267 do {
268 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
269 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
270 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
271 switch (Chunk.fccID) {
272 case DMUS_FOURCC_GUID_CHUNK: {
273 TRACE_(dmfile)(": GUID chunk\n");
274 pDesc->dwValidData |= DMUS_OBJ_OBJECT;
275 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
276 break;
278 case DMUS_FOURCC_VERSION_CHUNK: {
279 TRACE_(dmfile)(": version chunk\n");
280 pDesc->dwValidData |= DMUS_OBJ_VERSION;
281 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
282 break;
284 case DMUS_FOURCC_CATEGORY_CHUNK: {
285 TRACE_(dmfile)(": category chunk\n");
286 pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
287 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
288 break;
290 case FOURCC_LIST: {
291 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
292 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
293 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
294 ListCount[0] = 0;
295 switch (Chunk.fccID) {
296 /* evil M$ UNFO list, which can (!?) contain INFO elements */
297 case DMUS_FOURCC_UNFO_LIST: {
298 TRACE_(dmfile)(": UNFO list\n");
299 do {
300 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
301 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
302 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
303 switch (Chunk.fccID) {
304 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
305 (though strings seem to be valid unicode) */
306 case mmioFOURCC('I','N','A','M'):
307 case DMUS_FOURCC_UNAM_CHUNK: {
308 TRACE_(dmfile)(": name chunk\n");
309 pDesc->dwValidData |= DMUS_OBJ_NAME;
310 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
311 break;
313 case mmioFOURCC('I','A','R','T'):
314 case DMUS_FOURCC_UART_CHUNK: {
315 TRACE_(dmfile)(": artist chunk (ignored)\n");
316 liMove.QuadPart = Chunk.dwSize;
317 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
318 break;
320 case mmioFOURCC('I','C','O','P'):
321 case DMUS_FOURCC_UCOP_CHUNK: {
322 TRACE_(dmfile)(": copyright chunk (ignored)\n");
323 liMove.QuadPart = Chunk.dwSize;
324 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
325 break;
327 case mmioFOURCC('I','S','B','J'):
328 case DMUS_FOURCC_USBJ_CHUNK: {
329 TRACE_(dmfile)(": subject chunk (ignored)\n");
330 liMove.QuadPart = Chunk.dwSize;
331 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
332 break;
334 case mmioFOURCC('I','C','M','T'):
335 case DMUS_FOURCC_UCMT_CHUNK: {
336 TRACE_(dmfile)(": comment chunk (ignored)\n");
337 liMove.QuadPart = Chunk.dwSize;
338 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
339 break;
341 default: {
342 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
343 liMove.QuadPart = Chunk.dwSize;
344 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
345 break;
348 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
349 } while (ListCount[0] < ListSize[0]);
350 break;
352 default: {
353 TRACE_(dmfile)(": unknown (skipping)\n");
354 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
355 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
356 break;
359 break;
361 default: {
362 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
363 liMove.QuadPart = Chunk.dwSize;
364 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
365 break;
368 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
369 } while (StreamCount < StreamSize);
370 break;
371 } else {
372 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
373 liMove.QuadPart = StreamSize;
374 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
375 return E_FAIL;
378 TRACE_(dmfile)(": reading finished\n");
379 break;
381 default: {
382 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
383 liMove.QuadPart = Chunk.dwSize;
384 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
385 return DMUS_E_INVALIDFILE;
389 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc));
391 return S_OK;
394 ICOM_VTABLE(IDirectMusicObject) DirectMusicStyle8_Object_Vtbl = {
395 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
396 IDirectMusicStyle8Impl_IDirectMusicObject_QueryInterface,
397 IDirectMusicStyle8Impl_IDirectMusicObject_AddRef,
398 IDirectMusicStyle8Impl_IDirectMusicObject_Release,
399 IDirectMusicStyle8Impl_IDirectMusicObject_GetDescriptor,
400 IDirectMusicStyle8Impl_IDirectMusicObject_SetDescriptor,
401 IDirectMusicStyle8Impl_IDirectMusicObject_ParseDescriptor
404 /* IDirectMusicStyle8Impl IPersistStream part: */
405 HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
406 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
407 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
410 ULONG WINAPI IDirectMusicStyle8Impl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
411 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
412 return IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
415 ULONG WINAPI IDirectMusicStyle8Impl_IPersistStream_Release (LPPERSISTSTREAM iface) {
416 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
417 return IDirectMusicStyle8Impl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
420 HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
421 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
422 TRACE("(%p, %p)\n", This, pClassID);
423 memcpy(pClassID, &CLSID_DirectMusicStyle, sizeof(CLSID));
424 return S_OK;
427 HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
428 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
429 FIXME("(%p): stub, always S_FALSE\n", This);
430 return S_FALSE;
433 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
434 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
435 HRESULT hr = E_FAIL;
436 DMUS_PRIVATE_CHUNK Chunk;
437 DWORD ListSize[3], ListCount[3];
438 LARGE_INTEGER liMove; /* used when skipping chunks */
440 DMUS_OBJECTDESC desc;
442 if (pChunk->fccID != DMUS_FOURCC_PARTREF_LIST) {
443 ERR_(dmfile)(": %s chunk should be a PARTREF list\n", debugstr_fourcc (pChunk->fccID));
444 return E_FAIL;
447 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
448 ListCount[0] = 0;
450 do {
451 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
452 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
453 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
454 switch (Chunk.fccID) {
455 case DMUS_FOURCC_PARTREF_CHUNK: {
456 TRACE_(dmfile)(": PartRef chunk (skipping for now)\n");
457 liMove.QuadPart = Chunk.dwSize;
458 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
459 break;
461 case FOURCC_LIST: {
462 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
463 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
464 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
465 ListCount[1] = 0;
466 switch (Chunk.fccID) {
467 case DMUS_FOURCC_UNFO_LIST: {
468 TRACE_(dmfile)(": UNFO list\n");
469 do {
470 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
471 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
472 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
474 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &desc);
475 if (FAILED(hr)) return hr;
477 if (hr == S_FALSE) {
478 switch (Chunk.fccID) {
479 default: {
480 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
481 liMove.QuadPart = Chunk.dwSize;
482 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
483 break;
487 TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
488 } while (ListCount[1] < ListSize[1]);
489 break;
491 default: {
492 TRACE_(dmfile)(": unknown chunk (skipping)\n");
493 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
494 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
495 break;
498 break;
500 default: {
501 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
502 liMove.QuadPart = Chunk.dwSize;
503 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
504 break;
507 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
508 } while (ListCount[0] < ListSize[0]);
510 return S_OK;
513 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
515 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
516 HRESULT hr = E_FAIL;
517 DMUS_PRIVATE_CHUNK Chunk;
518 DWORD ListSize[3], ListCount[3];
519 LARGE_INTEGER liMove; /* used when skipping chunks */
521 DMUS_OBJECTDESC desc;
523 if (pChunk->fccID != DMUS_FOURCC_PART_LIST) {
524 ERR_(dmfile)(": %s chunk should be a PART list\n", debugstr_fourcc (pChunk->fccID));
525 return E_FAIL;
528 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
529 ListCount[0] = 0;
531 do {
532 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
533 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
534 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
535 switch (Chunk.fccID) {
536 case DMUS_FOURCC_PART_CHUNK: {
537 TRACE_(dmfile)(": Part chunk (skipping for now)\n");
538 liMove.QuadPart = Chunk.dwSize;
539 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
540 break;
542 case DMUS_FOURCC_NOTE_CHUNK: {
543 TRACE_(dmfile)(": Note chunk (skipping for now)\n");
544 liMove.QuadPart = Chunk.dwSize;
545 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
546 break;
548 case DMUS_FOURCC_CURVE_CHUNK: {
549 TRACE_(dmfile)(": Curve chunk (skipping for now)\n");
550 liMove.QuadPart = Chunk.dwSize;
551 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
552 break;
554 case DMUS_FOURCC_MARKER_CHUNK: {
555 TRACE_(dmfile)(": Marker chunk (skipping for now)\n");
556 liMove.QuadPart = Chunk.dwSize;
557 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
558 break;
560 case DMUS_FOURCC_RESOLUTION_CHUNK: {
561 TRACE_(dmfile)(": Resolution chunk (skipping for now)\n");
562 liMove.QuadPart = Chunk.dwSize;
563 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
564 break;
566 case DMUS_FOURCC_ANTICIPATION_CHUNK: {
567 TRACE_(dmfile)(": Anticipation chunk (skipping for now)\n");
568 liMove.QuadPart = Chunk.dwSize;
569 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
570 break;
572 case FOURCC_LIST: {
573 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
574 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
575 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
576 ListCount[1] = 0;
577 switch (Chunk.fccID) {
578 case DMUS_FOURCC_UNFO_LIST: {
579 TRACE_(dmfile)(": UNFO list\n");
580 do {
581 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
582 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
583 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
585 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &desc);
586 if (FAILED(hr)) return hr;
588 if (hr == S_FALSE) {
589 switch (Chunk.fccID) {
590 default: {
591 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
592 liMove.QuadPart = Chunk.dwSize;
593 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
594 break;
598 TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
599 } while (ListCount[1] < ListSize[1]);
600 break;
602 default: {
603 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
604 liMove.QuadPart = Chunk.dwSize;
605 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
606 break;
609 break;
611 default: {
612 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
613 liMove.QuadPart = Chunk.dwSize;
614 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
615 break;
618 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
619 } while (ListCount[0] < ListSize[0]);
621 return S_OK;
624 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
626 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
627 HRESULT hr = E_FAIL;
628 DMUS_PRIVATE_CHUNK Chunk;
629 DWORD ListSize[3], ListCount[3];
630 LARGE_INTEGER liMove; /* used when skipping chunks */
632 DMUS_IO_PATTERN pattern;
633 DWORD dwRythm = 0;
634 DMUS_OBJECTDESC desc;
636 memset(&pattern, 0, sizeof(pattern));
638 if (pChunk->fccID != DMUS_FOURCC_PATTERN_LIST) {
639 ERR_(dmfile)(": %s chunk should be a PATTERN list\n", debugstr_fourcc (pChunk->fccID));
640 return E_FAIL;
643 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
644 ListCount[0] = 0;
646 do {
647 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
648 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
649 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
650 switch (Chunk.fccID) {
651 case DMUS_FOURCC_PATTERN_CHUNK: {
652 TRACE_(dmfile)(": Pattern chunk\n");
653 IStream_Read (pStm, &pattern, Chunk.dwSize, NULL);
654 /** TODO trace pattern */
655 break;
657 case DMUS_FOURCC_RHYTHM_CHUNK: {
658 TRACE_(dmfile)(": Rythm chunk\n");
659 IStream_Read (pStm, &dwRythm, sizeof(DWORD), NULL);
660 TRACE_(dmfile)(" - dwRythm: %lu\n", dwRythm);
661 /** TODO understand why some Chunks have size > 4 */
662 liMove.QuadPart = Chunk.dwSize - sizeof(DWORD);
663 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
664 break;
666 case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: {
667 TRACE_(dmfile)(": MotifSettigns chunk (skipping for now)\n");
668 liMove.QuadPart = Chunk.dwSize;
669 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
670 break;
672 case FOURCC_LIST: {
673 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
674 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
675 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
676 ListCount[1] = 0;
677 switch (Chunk.fccID) {
678 case DMUS_FOURCC_UNFO_LIST: {
679 TRACE_(dmfile)(": UNFO list\n");
680 do {
681 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
682 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
683 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
685 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &desc);
686 if (FAILED(hr)) return hr;
688 if (hr == S_FALSE) {
689 switch (Chunk.fccID) {
690 default: {
691 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
692 liMove.QuadPart = Chunk.dwSize;
693 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
694 break;
698 TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
699 } while (ListCount[1] < ListSize[1]);
700 break;
702 case DMUS_FOURCC_PARTREF_LIST: {
703 TRACE_(dmfile)(": PartRef list\n");
704 hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface, &Chunk, pStm);
705 if (FAILED(hr)) return hr;
706 break;
708 default: {
709 TRACE_(dmfile)(": unknown (skipping)\n");
710 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
711 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
712 break;
715 break;
717 default: {
718 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
719 liMove.QuadPart = Chunk.dwSize;
720 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
721 break;
724 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
725 } while (ListCount[0] < ListSize[0]);
727 return S_OK;
730 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
731 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
733 HRESULT hr = E_FAIL;
734 DMUS_PRIVATE_CHUNK Chunk;
735 DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
736 LARGE_INTEGER liMove; /* used when skipping chunks */
738 if (pChunk->fccID != DMUS_FOURCC_STYLE_FORM) {
739 ERR_(dmfile)(": %s chunk should be a STYLE form\n", debugstr_fourcc (pChunk->fccID));
740 return E_FAIL;
743 StreamSize = pChunk->dwSize - sizeof(FOURCC);
744 StreamCount = 0;
746 do {
747 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
748 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
749 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
751 hr = IDirectMusicUtils_IPersistStream_ParseDescGeneric(&Chunk, pStm, This->pDesc);
752 if (FAILED(hr)) return hr;
754 if (hr == S_FALSE) {
755 switch (Chunk.fccID) {
756 case DMUS_FOURCC_STYLE_CHUNK: {
757 TRACE_(dmfile)(": Style chunk\n");
758 IStream_Read (pStm, &This->style, sizeof(DMUS_IO_STYLE), NULL);
759 /** TODO dump DMUS_IO_TIMESIG style.timeSig */
760 TRACE_(dmfile)(" - dblTempo: %g\n", This->style.dblTempo);
761 break;
763 case FOURCC_RIFF: {
765 * sould be embededs Bands into style
767 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
768 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
769 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
770 ListCount[0] = 0;
771 switch (Chunk.fccID) {
772 case DMUS_FOURCC_BAND_FORM: {
773 TRACE_(dmfile)(": BAND RIFF (TODO load it)\n");
775 LPSTREAM pClonedStream = NULL;
776 TRACE_(dmfile)(": BAND RIFF\n");
778 IStream_Clone (pStm, &pClonedStream);
780 liMove.QuadPart = 0;
781 liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
782 IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
784 hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand, &header);
785 if (FAILED(hr)) {
786 ERR(": could not load track\n");
787 return hr;
789 IStream_Release (pClonedStream);
791 IDirectMusicTrack_Release(pBand); pBand = NULL;
793 /** now safe move the cursor */
794 liMove.QuadPart = ListSize[0];
795 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
797 break;
799 default: {
800 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
801 liMove.QuadPart = ListSize[0];
802 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
803 break;
806 break;
808 case FOURCC_LIST: {
809 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
810 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
811 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
812 ListCount[0] = 0;
813 switch (Chunk.fccID) {
814 case DMUS_FOURCC_UNFO_LIST: {
815 TRACE_(dmfile)(": UNFO list\n");
816 do {
817 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
818 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
819 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
821 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, This->pDesc);
822 if (FAILED(hr)) return hr;
824 if (hr == S_FALSE) {
825 switch (Chunk.fccID) {
826 default: {
827 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
828 liMove.QuadPart = Chunk.dwSize;
829 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
830 break;
834 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
835 } while (ListCount[0] < ListSize[0]);
836 break;
838 case DMUS_FOURCC_PART_LIST: {
839 TRACE_(dmfile)(": PART list\n");
840 hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartList (iface, &Chunk, pStm);
841 if (FAILED(hr)) return hr;
842 break;
844 case DMUS_FOURCC_PATTERN_LIST: {
845 TRACE_(dmfile)(": PATTERN list\n");
846 hr = IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (iface, &Chunk, pStm);
847 if (FAILED(hr)) return hr;
848 break;
850 default: {
851 TRACE_(dmfile)(": unknown (skipping)\n");
852 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
853 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
854 break;
857 break;
859 default: {
860 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
861 liMove.QuadPart = Chunk.dwSize;
862 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
863 break;
867 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
868 } while (StreamCount < StreamSize);
870 return S_OK;
873 HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
874 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
876 DMUS_PRIVATE_CHUNK Chunk;
877 LARGE_INTEGER liMove; /* used when skipping chunks */
878 HRESULT hr;
880 FIXME("(%p, %p): Loading\n", This, pStm);
882 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
883 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
884 switch (Chunk.fccID) {
885 case FOURCC_RIFF: {
886 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
887 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
888 switch (Chunk.fccID) {
889 case DMUS_FOURCC_STYLE_FORM: {
890 TRACE_(dmfile)(": Style form\n");
891 hr = IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (iface, &Chunk, pStm);
892 if (FAILED(hr)) return hr;
893 break;
895 default: {
896 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
897 liMove.QuadPart = Chunk.dwSize;
898 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
899 return E_FAIL;
902 TRACE_(dmfile)(": reading finished\n");
903 break;
905 default: {
906 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
907 liMove.QuadPart = Chunk.dwSize;
908 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
909 return E_FAIL;
913 return S_OK;
916 HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
917 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
918 FIXME("(%p): Saving not implemented yet\n", This);
919 return E_NOTIMPL;
922 HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
923 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
924 FIXME("(%p, %p): stub\n", This, pcbSize);
925 return E_NOTIMPL;
929 ICOM_VTABLE(IPersistStream) DirectMusicStyle8_PersistStream_Vtbl = {
930 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
931 IDirectMusicStyle8Impl_IPersistStream_QueryInterface,
932 IDirectMusicStyle8Impl_IPersistStream_AddRef,
933 IDirectMusicStyle8Impl_IPersistStream_Release,
934 IDirectMusicStyle8Impl_IPersistStream_GetClassID,
935 IDirectMusicStyle8Impl_IPersistStream_IsDirty,
936 IDirectMusicStyle8Impl_IPersistStream_Load,
937 IDirectMusicStyle8Impl_IPersistStream_Save,
938 IDirectMusicStyle8Impl_IPersistStream_GetSizeMax
941 /* for ClassFactory */
942 HRESULT WINAPI DMUSIC_CreateDirectMusicStyleImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) {
943 IDirectMusicStyle8Impl* obj;
945 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicStyle8Impl));
946 if (NULL == obj) {
947 *ppobj = (LPVOID) NULL;
948 return E_OUTOFMEMORY;
950 obj->UnknownVtbl = &DirectMusicStyle8_Unknown_Vtbl;
951 obj->StyleVtbl = &DirectMusicStyle8_Style_Vtbl;
952 obj->ObjectVtbl = &DirectMusicStyle8_Object_Vtbl;
953 obj->PersistStreamVtbl = &DirectMusicStyle8_PersistStream_Vtbl;
954 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
955 DM_STRUCT_INIT(obj->pDesc);
956 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
957 memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicStyle, sizeof (CLSID));
958 obj->ref = 0; /* will be inited by QueryInterface */
960 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);