ntdll: NtWaitForMultipleObjects()'s third arguments means 'wait_any', not 'wait_all'.
[wine.git] / dlls / dmstyle / style.c
blobed4079185c39615a866129910f9c5e1db88d7b19
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
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (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 GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "dmstyle_private.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(dmstyle);
24 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
26 /*****************************************************************************
27 * IDirectMusicStyleImpl implementation
29 typedef struct IDirectMusicStyle8Impl {
30 IDirectMusicStyle8 IDirectMusicStyle8_iface;
31 const IDirectMusicObjectVtbl *ObjectVtbl;
32 const IPersistStreamVtbl *PersistStreamVtbl;
33 LONG ref;
34 DMUS_OBJECTDESC *pDesc;
35 DMUS_IO_STYLE style;
36 struct list Motifs;
37 struct list Bands;
38 } IDirectMusicStyle8Impl;
40 static inline IDirectMusicStyle8Impl *impl_from_IDirectMusicStyle8(IDirectMusicStyle8 *iface)
42 return CONTAINING_RECORD(iface, IDirectMusicStyle8Impl, IDirectMusicStyle8_iface);
45 /* DirectMusicStyle8Impl IDirectMusicStyle8 part: */
46 static HRESULT WINAPI IDirectMusicStyle8Impl_QueryInterface(IDirectMusicStyle8 *iface, REFIID riid,
47 void **ret_iface)
49 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
51 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
53 *ret_iface = NULL;
55 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicStyle) ||
56 IsEqualIID(riid, &IID_IDirectMusicStyle8))
57 *ret_iface = iface;
58 else if (IsEqualIID(riid, &IID_IDirectMusicObject))
59 *ret_iface = &This->ObjectVtbl;
60 else if (IsEqualIID(riid, &IID_IPersistStream))
61 *ret_iface = &This->PersistStreamVtbl;
62 else {
63 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
64 return E_NOINTERFACE;
67 IUnknown_AddRef((IUnknown*)*ret_iface);
68 return S_OK;
71 static ULONG WINAPI IDirectMusicStyle8Impl_AddRef(IDirectMusicStyle8 *iface)
73 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
74 LONG ref = InterlockedIncrement(&This->ref);
76 TRACE("(%p) ref=%d\n", This, ref);
78 return ref;
81 static ULONG WINAPI IDirectMusicStyle8Impl_Release(IDirectMusicStyle8 *iface)
83 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
84 LONG ref = InterlockedDecrement(&This->ref);
86 TRACE("(%p) ref=%d\n", This, ref);
88 if (!ref) {
89 HeapFree(GetProcessHeap(), 0, This->pDesc);
90 HeapFree(GetProcessHeap(), 0, This);
91 DMSTYLE_UnlockModule();
94 return ref;
97 /* IDirectMusicStyle8Impl IDirectMusicStyle(8) part: */
98 static HRESULT WINAPI IDirectMusicStyle8Impl_GetBand(IDirectMusicStyle8 *iface, WCHAR *pwszName,
99 IDirectMusicBand **ppBand)
101 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
102 FIXME("(%p, %p, %p): stub\n", This, pwszName, ppBand);
103 return S_OK;
106 static HRESULT WINAPI IDirectMusicStyle8Impl_EnumBand(IDirectMusicStyle8 *iface, DWORD dwIndex,
107 WCHAR *pwszName)
109 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
110 FIXME("(%p, %d, %p): stub\n", This, dwIndex, pwszName);
111 return S_OK;
114 static HRESULT WINAPI IDirectMusicStyle8Impl_GetDefaultBand(IDirectMusicStyle8 *iface,
115 IDirectMusicBand **ppBand)
117 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
118 FIXME("(%p, %p): stub\n", This, ppBand);
119 return S_OK;
122 static HRESULT WINAPI IDirectMusicStyle8Impl_EnumMotif(IDirectMusicStyle8 *iface, DWORD dwIndex,
123 WCHAR *pwszName)
125 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
126 FIXME("(%p, %d, %p): stub\n", This, dwIndex, pwszName);
127 return S_OK;
130 static HRESULT WINAPI IDirectMusicStyle8Impl_GetMotif(IDirectMusicStyle8 *iface, WCHAR *pwszName,
131 IDirectMusicSegment **ppSegment)
133 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
134 FIXME("(%p, %p, %p): stub\n", This, pwszName, ppSegment);
135 return S_OK;
138 static HRESULT WINAPI IDirectMusicStyle8Impl_GetDefaultChordMap(IDirectMusicStyle8 *iface,
139 IDirectMusicChordMap **ppChordMap)
141 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
142 FIXME("(%p, %p): stub\n", This, ppChordMap);
143 return S_OK;
146 static HRESULT WINAPI IDirectMusicStyle8Impl_EnumChordMap(IDirectMusicStyle8 *iface, DWORD dwIndex,
147 WCHAR *pwszName)
149 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
150 FIXME("(%p, %d, %p): stub\n", This, dwIndex, pwszName);
151 return S_OK;
154 static HRESULT WINAPI IDirectMusicStyle8Impl_GetChordMap(IDirectMusicStyle8 *iface, WCHAR *pwszName,
155 IDirectMusicChordMap **ppChordMap)
157 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
158 FIXME("(%p, %p, %p): stub\n", This, pwszName, ppChordMap);
159 return S_OK;
162 static HRESULT WINAPI IDirectMusicStyle8Impl_GetTimeSignature(IDirectMusicStyle8 *iface,
163 DMUS_TIMESIGNATURE *pTimeSig)
165 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
166 FIXME("(%p, %p): stub\n", This, pTimeSig);
167 return S_OK;
170 static HRESULT WINAPI IDirectMusicStyle8Impl_GetEmbellishmentLength(IDirectMusicStyle8 *iface,
171 DWORD dwType, DWORD dwLevel, DWORD *pdwMin, DWORD *pdwMax)
173 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
174 FIXME("(%p, %d, %d, %p, %p): stub\n", This, dwType, dwLevel, pdwMin, pdwMax);
175 return S_OK;
178 static HRESULT WINAPI IDirectMusicStyle8Impl_GetTempo(IDirectMusicStyle8 *iface, double *pTempo)
180 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
181 FIXME("(%p, %p): stub\n", This, pTempo);
182 return S_OK;
185 static HRESULT WINAPI IDirectMusicStyle8Impl_EnumPattern(IDirectMusicStyle8 *iface, DWORD dwIndex,
186 DWORD dwPatternType, WCHAR *pwszName)
188 IDirectMusicStyle8Impl *This = impl_from_IDirectMusicStyle8(iface);
189 FIXME("(%p, %d, %d, %p): stub\n", This, dwIndex, dwPatternType, pwszName);
190 return S_OK;
193 static const IDirectMusicStyle8Vtbl dmstyle8_vtbl = {
194 IDirectMusicStyle8Impl_QueryInterface,
195 IDirectMusicStyle8Impl_AddRef,
196 IDirectMusicStyle8Impl_Release,
197 IDirectMusicStyle8Impl_GetBand,
198 IDirectMusicStyle8Impl_EnumBand,
199 IDirectMusicStyle8Impl_GetDefaultBand,
200 IDirectMusicStyle8Impl_EnumMotif,
201 IDirectMusicStyle8Impl_GetMotif,
202 IDirectMusicStyle8Impl_GetDefaultChordMap,
203 IDirectMusicStyle8Impl_EnumChordMap,
204 IDirectMusicStyle8Impl_GetChordMap,
205 IDirectMusicStyle8Impl_GetTimeSignature,
206 IDirectMusicStyle8Impl_GetEmbellishmentLength,
207 IDirectMusicStyle8Impl_GetTempo,
208 IDirectMusicStyle8Impl_EnumPattern
211 /* IDirectMusicStyle8Impl IDirectMusicObject part: */
212 static HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
213 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
214 return IDirectMusicStyle8_QueryInterface(&This->IDirectMusicStyle8_iface, riid, ppobj);
217 static ULONG WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
218 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
219 return IDirectMusicStyle8_AddRef(&This->IDirectMusicStyle8_iface);
222 static ULONG WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
223 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
224 return IDirectMusicStyle8_Release(&This->IDirectMusicStyle8_iface);
227 static HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
228 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
229 TRACE("(%p, %p)\n", This, pDesc);
230 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
231 memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
232 return S_OK;
235 static HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
236 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
237 TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc));
239 /* According to MSDN, we should copy only given values, not whole struct */
240 if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
241 This->pDesc->guidObject = pDesc->guidObject;
242 if (pDesc->dwValidData & DMUS_OBJ_CLASS)
243 This->pDesc->guidClass = pDesc->guidClass;
244 if (pDesc->dwValidData & DMUS_OBJ_NAME)
245 lstrcpynW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
246 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
247 lstrcpynW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
248 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
249 lstrcpynW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
250 if (pDesc->dwValidData & DMUS_OBJ_VERSION)
251 This->pDesc->vVersion = pDesc->vVersion;
252 if (pDesc->dwValidData & DMUS_OBJ_DATE)
253 This->pDesc->ftDate = pDesc->ftDate;
254 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
255 This->pDesc->llMemLength = pDesc->llMemLength;
256 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, pDesc->llMemLength);
258 if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
259 /* according to MSDN, we copy the stream */
260 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
263 /* add new flags */
264 This->pDesc->dwValidData |= pDesc->dwValidData;
266 return S_OK;
269 static HRESULT WINAPI IDirectMusicStyle8Impl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
270 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, ObjectVtbl, iface);
271 DMUS_PRIVATE_CHUNK Chunk;
272 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
273 LARGE_INTEGER liMove; /* used when skipping chunks */
275 TRACE("(%p, %p, %p)\n", This, pStream, pDesc);
277 /* FIXME: should this be determined from stream? */
278 pDesc->dwValidData |= DMUS_OBJ_CLASS;
279 pDesc->guidClass = CLSID_DirectMusicStyle;
281 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
282 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
283 switch (Chunk.fccID) {
284 case FOURCC_RIFF: {
285 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
286 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
287 StreamSize = Chunk.dwSize - sizeof(FOURCC);
288 StreamCount = 0;
289 if (Chunk.fccID == DMUS_FOURCC_STYLE_FORM) {
290 TRACE_(dmfile)(": style form\n");
291 do {
292 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
293 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
294 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
295 switch (Chunk.fccID) {
296 case DMUS_FOURCC_GUID_CHUNK: {
297 TRACE_(dmfile)(": GUID chunk\n");
298 pDesc->dwValidData |= DMUS_OBJ_OBJECT;
299 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
300 break;
302 case DMUS_FOURCC_VERSION_CHUNK: {
303 TRACE_(dmfile)(": version chunk\n");
304 pDesc->dwValidData |= DMUS_OBJ_VERSION;
305 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
306 break;
308 case DMUS_FOURCC_CATEGORY_CHUNK: {
309 TRACE_(dmfile)(": category chunk\n");
310 pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
311 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
312 break;
314 case FOURCC_LIST: {
315 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
316 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
317 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
318 ListCount[0] = 0;
319 switch (Chunk.fccID) {
320 /* evil M$ UNFO list, which can (!?) contain INFO elements */
321 case DMUS_FOURCC_UNFO_LIST: {
322 TRACE_(dmfile)(": UNFO list\n");
323 do {
324 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
325 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
326 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
327 switch (Chunk.fccID) {
328 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
329 (though strings seem to be valid unicode) */
330 case mmioFOURCC('I','N','A','M'):
331 case DMUS_FOURCC_UNAM_CHUNK: {
332 TRACE_(dmfile)(": name chunk\n");
333 pDesc->dwValidData |= DMUS_OBJ_NAME;
334 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
335 break;
337 case mmioFOURCC('I','A','R','T'):
338 case DMUS_FOURCC_UART_CHUNK: {
339 TRACE_(dmfile)(": artist chunk (ignored)\n");
340 liMove.QuadPart = Chunk.dwSize;
341 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
342 break;
344 case mmioFOURCC('I','C','O','P'):
345 case DMUS_FOURCC_UCOP_CHUNK: {
346 TRACE_(dmfile)(": copyright chunk (ignored)\n");
347 liMove.QuadPart = Chunk.dwSize;
348 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
349 break;
351 case mmioFOURCC('I','S','B','J'):
352 case DMUS_FOURCC_USBJ_CHUNK: {
353 TRACE_(dmfile)(": subject chunk (ignored)\n");
354 liMove.QuadPart = Chunk.dwSize;
355 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
356 break;
358 case mmioFOURCC('I','C','M','T'):
359 case DMUS_FOURCC_UCMT_CHUNK: {
360 TRACE_(dmfile)(": comment chunk (ignored)\n");
361 liMove.QuadPart = Chunk.dwSize;
362 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
363 break;
365 default: {
366 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
367 liMove.QuadPart = Chunk.dwSize;
368 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
369 break;
372 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
373 } while (ListCount[0] < ListSize[0]);
374 break;
376 default: {
377 TRACE_(dmfile)(": unknown (skipping)\n");
378 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
379 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
380 break;
383 break;
385 default: {
386 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
387 liMove.QuadPart = Chunk.dwSize;
388 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
389 break;
392 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
393 } while (StreamCount < StreamSize);
394 } else {
395 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
396 liMove.QuadPart = StreamSize;
397 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
398 return E_FAIL;
401 TRACE_(dmfile)(": reading finished\n");
402 break;
404 default: {
405 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
406 liMove.QuadPart = Chunk.dwSize;
407 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
408 return DMUS_E_INVALIDFILE;
412 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc));
414 return S_OK;
417 static const IDirectMusicObjectVtbl DirectMusicStyle8_Object_Vtbl = {
418 IDirectMusicStyle8Impl_IDirectMusicObject_QueryInterface,
419 IDirectMusicStyle8Impl_IDirectMusicObject_AddRef,
420 IDirectMusicStyle8Impl_IDirectMusicObject_Release,
421 IDirectMusicStyle8Impl_IDirectMusicObject_GetDescriptor,
422 IDirectMusicStyle8Impl_IDirectMusicObject_SetDescriptor,
423 IDirectMusicStyle8Impl_IDirectMusicObject_ParseDescriptor
426 /* IDirectMusicStyle8Impl IPersistStream part: */
427 static HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
428 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
429 return IDirectMusicStyle8_QueryInterface(&This->IDirectMusicStyle8_iface, riid, ppobj);
432 static ULONG WINAPI IDirectMusicStyle8Impl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
433 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
434 return IDirectMusicStyle8_AddRef(&This->IDirectMusicStyle8_iface);
437 static ULONG WINAPI IDirectMusicStyle8Impl_IPersistStream_Release (LPPERSISTSTREAM iface) {
438 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
439 return IDirectMusicStyle8_Release(&This->IDirectMusicStyle8_iface);
442 static HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
443 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
444 TRACE("(%p, %p)\n", This, pClassID);
445 *pClassID = CLSID_DirectMusicStyle;
446 return S_OK;
449 static HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
450 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
451 FIXME("(%p): stub, always S_FALSE\n", This);
452 return S_FALSE;
455 static HRESULT IDirectMusicStyle8Impl_IPersistStream_LoadBand (LPPERSISTSTREAM iface, IStream* pClonedStream, IDirectMusicBand** ppBand) {
457 HRESULT hr = E_FAIL;
458 IPersistStream* pPersistStream = NULL;
460 hr = CoCreateInstance (&CLSID_DirectMusicBand, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicBand, (LPVOID*) ppBand);
461 if (FAILED(hr)) {
462 ERR(": could not create object\n");
463 return hr;
465 /* acquire PersistStream interface */
466 hr = IDirectMusicBand_QueryInterface (*ppBand, &IID_IPersistStream, (LPVOID*) &pPersistStream);
467 if (FAILED(hr)) {
468 ERR(": could not acquire IPersistStream\n");
469 return hr;
471 /* load */
472 hr = IPersistStream_Load (pPersistStream, pClonedStream);
473 if (FAILED(hr)) {
474 ERR(": failed to load object\n");
475 return hr;
478 /* release all loading-related stuff */
479 IPersistStream_Release (pPersistStream);
481 return S_OK;
484 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif) {
485 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
486 HRESULT hr = E_FAIL;
487 DMUS_PRIVATE_CHUNK Chunk;
488 DWORD ListSize[3], ListCount[3];
489 LARGE_INTEGER liMove; /* used when skipping chunks */
491 LPDMUS_PRIVATE_STYLE_PARTREF_ITEM pNewItem = NULL;
494 if (pChunk->fccID != DMUS_FOURCC_PARTREF_LIST) {
495 ERR_(dmfile)(": %s chunk should be a PARTREF list\n", debugstr_fourcc (pChunk->fccID));
496 return E_FAIL;
499 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
500 ListCount[0] = 0;
502 do {
503 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
504 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
505 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
506 switch (Chunk.fccID) {
507 case DMUS_FOURCC_PARTREF_CHUNK: {
508 TRACE_(dmfile)(": PartRef chunk\n");
509 pNewItem = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_PARTREF_ITEM));
510 if (!pNewItem) {
511 ERR(": no more memory\n");
512 return E_OUTOFMEMORY;
514 hr = IStream_Read (pStm, &pNewItem->part_ref, sizeof(DMUS_IO_PARTREF), NULL);
515 /*TRACE_(dmfile)(" - sizeof %lu\n", sizeof(DMUS_IO_PARTREF));*/
516 list_add_tail (&pNewMotif->Items, &pNewItem->entry);
517 DM_STRUCT_INIT(&pNewItem->desc);
518 break;
520 case FOURCC_LIST: {
521 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
522 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
523 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
524 ListCount[1] = 0;
525 switch (Chunk.fccID) {
526 case DMUS_FOURCC_UNFO_LIST: {
527 TRACE_(dmfile)(": UNFO list\n");
528 do {
529 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
530 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
531 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
533 if (!pNewItem) {
534 ERR(": pNewItem not yet allocated, chunk order bad?\n");
535 return E_OUTOFMEMORY;
537 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &pNewItem->desc);
538 if (FAILED(hr)) return hr;
540 if (hr == S_FALSE) {
541 switch (Chunk.fccID) {
542 default: {
543 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
544 liMove.QuadPart = Chunk.dwSize;
545 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
546 break;
550 TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
551 } while (ListCount[1] < ListSize[1]);
552 break;
554 default: {
555 TRACE_(dmfile)(": unknown chunk (skipping)\n");
556 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
557 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
558 break;
561 break;
563 default: {
564 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
565 liMove.QuadPart = Chunk.dwSize;
566 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
567 break;
570 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
571 } while (ListCount[0] < ListSize[0]);
573 return S_OK;
576 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePartList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
578 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
579 HRESULT hr = E_FAIL;
580 DMUS_PRIVATE_CHUNK Chunk;
581 DWORD ListSize[3], ListCount[3];
582 LARGE_INTEGER liMove; /* used when skipping chunks */
584 DMUS_OBJECTDESC desc;
585 DWORD dwSize = 0;
586 DWORD cnt = 0;
588 if (pChunk->fccID != DMUS_FOURCC_PART_LIST) {
589 ERR_(dmfile)(": %s chunk should be a PART list\n", debugstr_fourcc (pChunk->fccID));
590 return E_FAIL;
593 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
594 ListCount[0] = 0;
596 do {
597 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
598 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
599 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
600 switch (Chunk.fccID) {
601 case DMUS_FOURCC_PART_CHUNK: {
602 TRACE_(dmfile)(": Part chunk (skipping for now)\n" );
603 liMove.QuadPart = Chunk.dwSize;
604 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
605 break;
607 case DMUS_FOURCC_NOTE_CHUNK: {
608 TRACE_(dmfile)(": Note chunk (skipping for now)\n");
609 IStream_Read (pStm, &dwSize, sizeof(DWORD), NULL);
610 cnt = (Chunk.dwSize - sizeof(DWORD));
611 TRACE_(dmfile)(" - dwSize: %u\n", dwSize);
612 TRACE_(dmfile)(" - cnt: %u (%u / %u)\n", cnt / dwSize, (DWORD)(Chunk.dwSize - sizeof(DWORD)), dwSize);
613 if (cnt % dwSize != 0) {
614 ERR("Invalid Array Size\n");
615 return E_FAIL;
617 cnt /= dwSize;
618 /** skip for now */
619 liMove.QuadPart = cnt * dwSize;
620 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
621 break;
623 case DMUS_FOURCC_CURVE_CHUNK: {
624 TRACE_(dmfile)(": Curve chunk (skipping for now)\n");
625 IStream_Read (pStm, &dwSize, sizeof(DWORD), NULL);
626 cnt = (Chunk.dwSize - sizeof(DWORD));
627 TRACE_(dmfile)(" - dwSize: %u\n", dwSize);
628 TRACE_(dmfile)(" - cnt: %u (%u / %u)\n", cnt / dwSize, (DWORD)(Chunk.dwSize - sizeof(DWORD)), dwSize);
629 if (cnt % dwSize != 0) {
630 ERR("Invalid Array Size\n");
631 return E_FAIL;
633 cnt /= dwSize;
634 /** skip for now */
635 liMove.QuadPart = cnt * dwSize;
636 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
637 break;
639 case DMUS_FOURCC_MARKER_CHUNK: {
640 TRACE_(dmfile)(": Marker chunk (skipping for now)\n");
641 liMove.QuadPart = Chunk.dwSize;
642 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
643 break;
645 case DMUS_FOURCC_RESOLUTION_CHUNK: {
646 TRACE_(dmfile)(": Resolution chunk (skipping for now)\n");
647 liMove.QuadPart = Chunk.dwSize;
648 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
649 break;
651 case DMUS_FOURCC_ANTICIPATION_CHUNK: {
652 TRACE_(dmfile)(": Anticipation chunk (skipping for now)\n");
653 liMove.QuadPart = Chunk.dwSize;
654 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
655 break;
657 case FOURCC_LIST: {
658 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
659 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
660 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
661 ListCount[1] = 0;
662 switch (Chunk.fccID) {
663 case DMUS_FOURCC_UNFO_LIST: {
664 TRACE_(dmfile)(": UNFO list\n");
665 do {
666 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
667 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
668 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
670 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &desc);
671 if (FAILED(hr)) return hr;
673 if (hr == S_FALSE) {
674 switch (Chunk.fccID) {
675 default: {
676 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
677 liMove.QuadPart = Chunk.dwSize;
678 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
679 break;
683 TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
684 } while (ListCount[1] < ListSize[1]);
685 break;
687 default: {
688 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
689 liMove.QuadPart = Chunk.dwSize;
690 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
691 break;
694 break;
696 default: {
697 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
698 liMove.QuadPart = Chunk.dwSize;
699 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
700 break;
703 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
704 } while (ListCount[0] < ListSize[0]);
706 return S_OK;
709 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
711 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
712 HRESULT hr = E_FAIL;
713 DMUS_PRIVATE_CHUNK Chunk;
714 DWORD ListSize[3], ListCount[3];
715 LARGE_INTEGER liMove; /* used when skipping chunks */
717 DMUS_OBJECTDESC desc;
718 IDirectMusicBand* pBand = NULL;
719 LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif = NULL;
721 DM_STRUCT_INIT(&desc);
723 if (pChunk->fccID != DMUS_FOURCC_PATTERN_LIST) {
724 ERR_(dmfile)(": %s chunk should be a PATTERN list\n", debugstr_fourcc (pChunk->fccID));
725 return E_FAIL;
728 ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
729 ListCount[0] = 0;
731 do {
732 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
733 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
734 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
735 switch (Chunk.fccID) {
736 case DMUS_FOURCC_PATTERN_CHUNK: {
737 TRACE_(dmfile)(": Pattern chunk\n");
738 /** alloc new motif entry */
739 pNewMotif = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_MOTIF));
740 if (NULL == pNewMotif) {
741 ERR(": no more memory\n");
742 return E_OUTOFMEMORY;
744 list_add_tail (&This->Motifs, &pNewMotif->entry);
746 IStream_Read (pStm, &pNewMotif->pattern, Chunk.dwSize, NULL);
747 /** TODO trace pattern */
749 /** reset all data, as a new pattern begin */
750 DM_STRUCT_INIT(&pNewMotif->desc);
751 list_init (&pNewMotif->Items);
752 break;
754 case DMUS_FOURCC_RHYTHM_CHUNK: {
755 TRACE_(dmfile)(": Rhythm chunk\n");
756 IStream_Read (pStm, &pNewMotif->dwRhythm, sizeof(DWORD), NULL);
757 TRACE_(dmfile)(" - dwRhythm: %u\n", pNewMotif->dwRhythm);
758 /** TODO understand why some Chunks have size > 4 */
759 liMove.QuadPart = Chunk.dwSize - sizeof(DWORD);
760 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
761 break;
763 case DMUS_FOURCC_MOTIFSETTINGS_CHUNK: {
764 TRACE_(dmfile)(": MotifSettings chunk (skipping for now)\n");
765 IStream_Read (pStm, &pNewMotif->settings, Chunk.dwSize, NULL);
766 /** TODO trace settings */
767 break;
769 case FOURCC_RIFF: {
771 * should be embedded Bands into pattern
773 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
774 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
775 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
776 ListCount[1] = 0;
777 switch (Chunk.fccID) {
778 case DMUS_FOURCC_BAND_FORM: {
779 LPSTREAM pClonedStream = NULL;
781 TRACE_(dmfile)(": BAND RIFF\n");
783 IStream_Clone (pStm, &pClonedStream);
785 liMove.QuadPart = 0;
786 liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
787 IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
789 hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand);
790 if (FAILED(hr)) {
791 ERR(": could not load track\n");
792 return hr;
794 IStream_Release (pClonedStream);
796 pNewMotif->pBand = pBand;
797 IDirectMusicBand_AddRef(pBand);
799 IDirectMusicTrack_Release(pBand); pBand = NULL; /* now we can release it as it's inserted */
801 /** now safe move the cursor */
802 liMove.QuadPart = ListSize[1];
803 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
805 break;
807 default: {
808 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
809 liMove.QuadPart = ListSize[1];
810 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
811 break;
814 break;
816 case FOURCC_LIST: {
817 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
818 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
819 ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
820 ListCount[1] = 0;
821 switch (Chunk.fccID) {
822 case DMUS_FOURCC_UNFO_LIST: {
823 TRACE_(dmfile)(": UNFO list\n");
824 do {
825 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
826 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
827 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
829 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, &pNewMotif->desc);
830 if (FAILED(hr)) return hr;
832 if (hr == S_FALSE) {
833 switch (Chunk.fccID) {
834 default: {
835 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
836 liMove.QuadPart = Chunk.dwSize;
837 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
838 break;
842 TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
843 } while (ListCount[1] < ListSize[1]);
844 break;
846 case DMUS_FOURCC_PARTREF_LIST: {
847 TRACE_(dmfile)(": PartRef list\n");
848 hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface, &Chunk, pStm, pNewMotif);
849 if (FAILED(hr)) return hr;
850 break;
852 default: {
853 TRACE_(dmfile)(": unknown (skipping)\n");
854 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
855 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
856 break;
859 break;
861 default: {
862 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
863 liMove.QuadPart = Chunk.dwSize;
864 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
865 break;
868 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
869 } while (ListCount[0] < ListSize[0]);
871 return S_OK;
874 static HRESULT IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm) {
875 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
877 HRESULT hr = E_FAIL;
878 DMUS_PRIVATE_CHUNK Chunk;
879 DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
880 LARGE_INTEGER liMove; /* used when skipping chunks */
882 IDirectMusicBand* pBand = NULL;
884 if (pChunk->fccID != DMUS_FOURCC_STYLE_FORM) {
885 ERR_(dmfile)(": %s chunk should be a STYLE form\n", debugstr_fourcc (pChunk->fccID));
886 return E_FAIL;
889 StreamSize = pChunk->dwSize - sizeof(FOURCC);
890 StreamCount = 0;
892 do {
893 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
894 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
895 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
897 hr = IDirectMusicUtils_IPersistStream_ParseDescGeneric(&Chunk, pStm, This->pDesc);
898 if (FAILED(hr)) return hr;
900 if (hr == S_FALSE) {
901 switch (Chunk.fccID) {
902 case DMUS_FOURCC_STYLE_CHUNK: {
903 TRACE_(dmfile)(": Style chunk\n");
904 IStream_Read (pStm, &This->style, sizeof(DMUS_IO_STYLE), NULL);
905 /** TODO dump DMUS_IO_TIMESIG style.timeSig */
906 TRACE_(dmfile)(" - dblTempo: %g\n", This->style.dblTempo);
907 break;
909 case FOURCC_RIFF: {
911 * should be embedded Bands into style
913 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
914 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
915 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
916 ListCount[0] = 0;
917 switch (Chunk.fccID) {
918 case DMUS_FOURCC_BAND_FORM: {
919 LPSTREAM pClonedStream = NULL;
920 LPDMUS_PRIVATE_STYLE_BAND pNewBand;
922 TRACE_(dmfile)(": BAND RIFF\n");
924 IStream_Clone (pStm, &pClonedStream);
926 liMove.QuadPart = 0;
927 liMove.QuadPart -= sizeof(FOURCC) + (sizeof(FOURCC)+sizeof(DWORD));
928 IStream_Seek (pClonedStream, liMove, STREAM_SEEK_CUR, NULL);
930 hr = IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface, pClonedStream, &pBand);
931 if (FAILED(hr)) {
932 ERR(": could not load track\n");
933 return hr;
935 IStream_Release (pClonedStream);
937 pNewBand = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_STYLE_BAND));
938 if (NULL == pNewBand) {
939 ERR(": no more memory\n");
940 return E_OUTOFMEMORY;
942 pNewBand->pBand = pBand;
943 IDirectMusicBand_AddRef(pBand);
944 list_add_tail (&This->Bands, &pNewBand->entry);
946 IDirectMusicTrack_Release(pBand); pBand = NULL; /* now we can release it as it's inserted */
948 /** now safely move the cursor */
949 liMove.QuadPart = ListSize[0];
950 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
952 break;
954 default: {
955 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
956 liMove.QuadPart = ListSize[0];
957 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
958 break;
961 break;
963 case FOURCC_LIST: {
964 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
965 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
966 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
967 ListCount[0] = 0;
968 switch (Chunk.fccID) {
969 case DMUS_FOURCC_UNFO_LIST: {
970 TRACE_(dmfile)(": UNFO list\n");
971 do {
972 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
973 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
974 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
976 hr = IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk, pStm, This->pDesc);
977 if (FAILED(hr)) return hr;
979 if (hr == S_FALSE) {
980 switch (Chunk.fccID) {
981 default: {
982 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
983 liMove.QuadPart = Chunk.dwSize;
984 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
985 break;
989 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
990 } while (ListCount[0] < ListSize[0]);
991 break;
993 case DMUS_FOURCC_PART_LIST: {
994 TRACE_(dmfile)(": PART list\n");
995 hr = IDirectMusicStyle8Impl_IPersistStream_ParsePartList (iface, &Chunk, pStm);
996 if (FAILED(hr)) return hr;
997 break;
999 case DMUS_FOURCC_PATTERN_LIST: {
1000 TRACE_(dmfile)(": PATTERN list\n");
1001 hr = IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (iface, &Chunk, pStm);
1002 if (FAILED(hr)) return hr;
1003 break;
1005 default: {
1006 TRACE_(dmfile)(": unknown (skipping)\n");
1007 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
1008 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
1009 break;
1012 break;
1014 default: {
1015 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
1016 liMove.QuadPart = Chunk.dwSize;
1017 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
1018 break;
1022 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
1023 } while (StreamCount < StreamSize);
1025 return S_OK;
1028 static HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
1029 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
1031 DMUS_PRIVATE_CHUNK Chunk;
1032 LARGE_INTEGER liMove; /* used when skipping chunks */
1033 HRESULT hr;
1035 FIXME("(%p, %p): Loading\n", This, pStm);
1037 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
1038 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
1039 switch (Chunk.fccID) {
1040 case FOURCC_RIFF: {
1041 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
1042 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
1043 switch (Chunk.fccID) {
1044 case DMUS_FOURCC_STYLE_FORM: {
1045 TRACE_(dmfile)(": Style form\n");
1046 hr = IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (iface, &Chunk, pStm);
1047 if (FAILED(hr)) return hr;
1048 break;
1050 default: {
1051 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
1052 liMove.QuadPart = Chunk.dwSize;
1053 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
1054 return E_FAIL;
1057 TRACE_(dmfile)(": reading finished\n");
1058 break;
1060 default: {
1061 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
1062 liMove.QuadPart = Chunk.dwSize;
1063 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
1064 return E_FAIL;
1068 return S_OK;
1071 static HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
1072 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
1073 FIXME("(%p): Saving not implemented yet\n", This);
1074 return E_NOTIMPL;
1077 static HRESULT WINAPI IDirectMusicStyle8Impl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
1078 ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);
1079 FIXME("(%p, %p): stub\n", This, pcbSize);
1080 return E_NOTIMPL;
1084 static const IPersistStreamVtbl DirectMusicStyle8_PersistStream_Vtbl = {
1085 IDirectMusicStyle8Impl_IPersistStream_QueryInterface,
1086 IDirectMusicStyle8Impl_IPersistStream_AddRef,
1087 IDirectMusicStyle8Impl_IPersistStream_Release,
1088 IDirectMusicStyle8Impl_IPersistStream_GetClassID,
1089 IDirectMusicStyle8Impl_IPersistStream_IsDirty,
1090 IDirectMusicStyle8Impl_IPersistStream_Load,
1091 IDirectMusicStyle8Impl_IPersistStream_Save,
1092 IDirectMusicStyle8Impl_IPersistStream_GetSizeMax
1095 /* for ClassFactory */
1096 HRESULT WINAPI create_dmstyle(REFIID lpcGUID, void **ppobj)
1098 IDirectMusicStyle8Impl* obj;
1099 HRESULT hr;
1101 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicStyle8Impl));
1102 if (NULL == obj) {
1103 *ppobj = NULL;
1104 return E_OUTOFMEMORY;
1106 obj->IDirectMusicStyle8_iface.lpVtbl = &dmstyle8_vtbl;
1107 obj->ObjectVtbl = &DirectMusicStyle8_Object_Vtbl;
1108 obj->PersistStreamVtbl = &DirectMusicStyle8_PersistStream_Vtbl;
1109 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
1110 DM_STRUCT_INIT(obj->pDesc);
1111 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
1112 obj->pDesc->guidClass = CLSID_DirectMusicStyle;
1113 obj->ref = 1;
1114 list_init (&obj->Bands);
1115 list_init (&obj->Motifs);
1117 DMSTYLE_LockModule();
1118 hr = IDirectMusicStyle8_QueryInterface(&obj->IDirectMusicStyle8_iface, lpcGUID, ppobj);
1119 IDirectMusicStyle8_Release(&obj->IDirectMusicStyle8_iface);
1121 return hr;