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 static ULONG WINAPI
IDirectMusicStyle8Impl_IUnknown_AddRef (LPUNKNOWN iface
);
27 static ULONG WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef (LPDIRECTMUSICSTYLE8 iface
);
28 static ULONG WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface
);
29 static ULONG WINAPI
IDirectMusicStyle8Impl_IPersistStream_AddRef (LPPERSISTSTREAM iface
);
31 /*****************************************************************************
32 * IDirectMusicStyleImpl implementation
34 /* IDirectMusicStyleImpl IUnknown part: */
35 static HRESULT WINAPI
IDirectMusicStyle8Impl_IUnknown_QueryInterface (LPUNKNOWN iface
, REFIID riid
, LPVOID
*ppobj
) {
36 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, UnknownVtbl
, iface
);
37 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
39 if (IsEqualIID (riid
, &IID_IUnknown
)) {
40 *ppobj
= (LPVOID
)&This
->UnknownVtbl
;
41 IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
43 } else if (IsEqualIID (riid
, &IID_IDirectMusicStyle
)) {
44 *ppobj
= (LPVOID
)&This
->StyleVtbl
;
45 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef ((LPDIRECTMUSICSTYLE8
)&This
->StyleVtbl
);
47 } else if (IsEqualIID (riid
, &IID_IDirectMusicStyle8
)) {
48 *ppobj
= (LPVOID
)&This
->StyleVtbl
;
49 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef ((LPDIRECTMUSICSTYLE8
)&This
->StyleVtbl
);
51 } else if (IsEqualIID (riid
, &IID_IDirectMusicObject
)) {
52 *ppobj
= (LPVOID
)&This
->ObjectVtbl
;
53 IDirectMusicStyle8Impl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT
)&This
->ObjectVtbl
);
55 } else if (IsEqualIID (riid
, &IID_IPersistStream
)) {
56 *ppobj
= (LPVOID
)&This
->PersistStreamVtbl
;
57 IDirectMusicStyle8Impl_IPersistStream_AddRef ((LPPERSISTSTREAM
)&This
->PersistStreamVtbl
);
61 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ppobj
);
65 static ULONG WINAPI
IDirectMusicStyle8Impl_IUnknown_AddRef (LPUNKNOWN iface
) {
66 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, UnknownVtbl
, iface
);
67 ULONG ref
= InterlockedIncrement(&This
->ref
);
69 TRACE("(%p): AddRef from %d\n", This
, ref
- 1);
76 static ULONG WINAPI
IDirectMusicStyle8Impl_IUnknown_Release (LPUNKNOWN iface
) {
77 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, UnknownVtbl
, iface
);
78 ULONG ref
= InterlockedDecrement(&This
->ref
);
80 TRACE("(%p): ReleaseRef to %d\n", This
, ref
);
83 HeapFree(GetProcessHeap(), 0, This
);
86 DMSTYLE_UnlockModule();
91 static const IUnknownVtbl DirectMusicStyle8_Unknown_Vtbl
= {
92 IDirectMusicStyle8Impl_IUnknown_QueryInterface
,
93 IDirectMusicStyle8Impl_IUnknown_AddRef
,
94 IDirectMusicStyle8Impl_IUnknown_Release
97 /* IDirectMusicStyle8Impl IDirectMusicStyle8 part: */
98 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_QueryInterface (LPDIRECTMUSICSTYLE8 iface
, REFIID riid
, LPVOID
*ppobj
) {
99 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
100 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
103 static ULONG WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef (LPDIRECTMUSICSTYLE8 iface
) {
104 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
105 return IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
108 static ULONG WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_Release (LPDIRECTMUSICSTYLE8 iface
) {
109 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
110 return IDirectMusicStyle8Impl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
113 /* IDirectMusicStyle8Impl IDirectMusicStyle(8) part: */
114 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetBand (LPDIRECTMUSICSTYLE8 iface
, WCHAR
* pwszName
, IDirectMusicBand
** ppBand
) {
115 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
116 FIXME("(%p, %p, %p): stub\n", This
, pwszName
, ppBand
);
120 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumBand (LPDIRECTMUSICSTYLE8 iface
, DWORD dwIndex
, WCHAR
* pwszName
) {
121 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
122 FIXME("(%p, %d, %p): stub\n", This
, dwIndex
, pwszName
);
126 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultBand (LPDIRECTMUSICSTYLE8 iface
, IDirectMusicBand
** ppBand
) {
127 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
128 FIXME("(%p, %p): stub\n", This
, ppBand
);
132 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumMotif (LPDIRECTMUSICSTYLE8 iface
, DWORD dwIndex
, WCHAR
* pwszName
) {
133 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
134 FIXME("(%p, %d, %p): stub\n", This
, dwIndex
, pwszName
);
138 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetMotif (LPDIRECTMUSICSTYLE8 iface
, WCHAR
* pwszName
, IDirectMusicSegment
** ppSegment
) {
139 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
140 FIXME("(%p, %p, %p): stub\n", This
, pwszName
, ppSegment
);
144 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultChordMap (LPDIRECTMUSICSTYLE8 iface
, IDirectMusicChordMap
** ppChordMap
) {
145 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
146 FIXME("(%p, %p): stub\n", This
, ppChordMap
);
150 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumChordMap (LPDIRECTMUSICSTYLE8 iface
, DWORD dwIndex
, WCHAR
* pwszName
) {
151 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
152 FIXME("(%p, %d, %p): stub\n", This
, dwIndex
, pwszName
);
156 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetChordMap (LPDIRECTMUSICSTYLE8 iface
, WCHAR
* pwszName
, IDirectMusicChordMap
** ppChordMap
) {
157 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
158 FIXME("(%p, %p, %p): stub\n", This
, pwszName
, ppChordMap
);
162 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTimeSignature (LPDIRECTMUSICSTYLE8 iface
, DMUS_TIMESIGNATURE
* pTimeSig
) {
163 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
164 FIXME("(%p, %p): stub\n", This
, pTimeSig
);
168 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetEmbellishmentLength (LPDIRECTMUSICSTYLE8 iface
, DWORD dwType
, DWORD dwLevel
, DWORD
* pdwMin
, DWORD
* pdwMax
) {
169 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
170 FIXME("(%p, %d, %d, %p, %p): stub\n", This
, dwType
, dwLevel
, pdwMin
, pdwMax
);
174 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTempo (LPDIRECTMUSICSTYLE8 iface
, double* pTempo
) {
175 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
176 FIXME("(%p, %p): stub\n", This
, pTempo
);
180 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumPattern (LPDIRECTMUSICSTYLE8 iface
, DWORD dwIndex
, DWORD dwPatternType
, WCHAR
* pwszName
) {
181 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, StyleVtbl
, iface
);
182 FIXME("(%p, %d, %d, %p): stub\n", This
, dwIndex
, dwPatternType
, pwszName
);
186 static const IDirectMusicStyle8Vtbl DirectMusicStyle8_Style_Vtbl
= {
187 IDirectMusicStyle8Impl_IDirectMusicStyle8_QueryInterface
,
188 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef
,
189 IDirectMusicStyle8Impl_IDirectMusicStyle8_Release
,
190 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetBand
,
191 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumBand
,
192 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultBand
,
193 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumMotif
,
194 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetMotif
,
195 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetDefaultChordMap
,
196 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumChordMap
,
197 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetChordMap
,
198 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTimeSignature
,
199 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetEmbellishmentLength
,
200 IDirectMusicStyle8Impl_IDirectMusicStyle8_GetTempo
,
201 IDirectMusicStyle8Impl_IDirectMusicStyle8_EnumPattern
204 /* IDirectMusicStyle8Impl IDirectMusicObject part: */
205 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface
, REFIID riid
, LPVOID
*ppobj
) {
206 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, ObjectVtbl
, iface
);
207 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
210 static ULONG WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface
) {
211 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, ObjectVtbl
, iface
);
212 return IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
215 static ULONG WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface
) {
216 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, ObjectVtbl
, iface
);
217 return IDirectMusicStyle8Impl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
220 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
221 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, ObjectVtbl
, iface
);
222 TRACE("(%p, %p)\n", This
, pDesc
);
223 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
224 memcpy (pDesc
, This
->pDesc
, This
->pDesc
->dwSize
);
228 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
229 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, ObjectVtbl
, iface
);
230 TRACE("(%p, %p): setting descriptor:\n%s\n", This
, pDesc
, debugstr_DMUS_OBJECTDESC (pDesc
));
232 /* According to MSDN, we should copy only given values, not whole struct */
233 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
234 This
->pDesc
->guidObject
= pDesc
->guidObject
;
235 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
236 This
->pDesc
->guidClass
= pDesc
->guidClass
;
237 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
238 lstrcpynW (This
->pDesc
->wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
239 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
240 lstrcpynW (This
->pDesc
->wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
241 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
242 lstrcpynW (This
->pDesc
->wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
243 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
244 This
->pDesc
->vVersion
= pDesc
->vVersion
;
245 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
246 This
->pDesc
->ftDate
= pDesc
->ftDate
;
247 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
) {
248 memcpy (&This
->pDesc
->llMemLength
, &pDesc
->llMemLength
, sizeof (pDesc
->llMemLength
));
249 memcpy (This
->pDesc
->pbMemData
, pDesc
->pbMemData
, sizeof (pDesc
->pbMemData
));
251 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
) {
252 /* according to MSDN, we copy the stream */
253 IStream_Clone (pDesc
->pStream
, &This
->pDesc
->pStream
);
257 This
->pDesc
->dwValidData
|= pDesc
->dwValidData
;
262 static HRESULT WINAPI
IDirectMusicStyle8Impl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface
, LPSTREAM pStream
, LPDMUS_OBJECTDESC pDesc
) {
263 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, ObjectVtbl
, iface
);
264 DMUS_PRIVATE_CHUNK Chunk
;
265 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
266 LARGE_INTEGER liMove
; /* used when skipping chunks */
268 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
270 /* FIXME: should this be determined from stream? */
271 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
272 pDesc
->guidClass
= CLSID_DirectMusicStyle
;
274 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
275 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
276 switch (Chunk
.fccID
) {
278 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
279 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
280 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
282 if (Chunk
.fccID
== DMUS_FOURCC_STYLE_FORM
) {
283 TRACE_(dmfile
)(": style form\n");
285 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
286 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
287 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
288 switch (Chunk
.fccID
) {
289 case DMUS_FOURCC_GUID_CHUNK
: {
290 TRACE_(dmfile
)(": GUID chunk\n");
291 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
292 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
295 case DMUS_FOURCC_VERSION_CHUNK
: {
296 TRACE_(dmfile
)(": version chunk\n");
297 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
298 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
301 case DMUS_FOURCC_CATEGORY_CHUNK
: {
302 TRACE_(dmfile
)(": category chunk\n");
303 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
304 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
308 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
309 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
310 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
312 switch (Chunk
.fccID
) {
313 /* evil M$ UNFO list, which can (!?) contain INFO elements */
314 case DMUS_FOURCC_UNFO_LIST
: {
315 TRACE_(dmfile
)(": UNFO list\n");
317 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
318 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
319 TRACE_(dmfile
)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
320 switch (Chunk
.fccID
) {
321 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
322 (though strings seem to be valid unicode) */
323 case mmioFOURCC('I','N','A','M'):
324 case DMUS_FOURCC_UNAM_CHUNK
: {
325 TRACE_(dmfile
)(": name chunk\n");
326 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
327 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
330 case mmioFOURCC('I','A','R','T'):
331 case DMUS_FOURCC_UART_CHUNK
: {
332 TRACE_(dmfile
)(": artist chunk (ignored)\n");
333 liMove
.QuadPart
= Chunk
.dwSize
;
334 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
337 case mmioFOURCC('I','C','O','P'):
338 case DMUS_FOURCC_UCOP_CHUNK
: {
339 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
340 liMove
.QuadPart
= Chunk
.dwSize
;
341 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
344 case mmioFOURCC('I','S','B','J'):
345 case DMUS_FOURCC_USBJ_CHUNK
: {
346 TRACE_(dmfile
)(": subject chunk (ignored)\n");
347 liMove
.QuadPart
= Chunk
.dwSize
;
348 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
351 case mmioFOURCC('I','C','M','T'):
352 case DMUS_FOURCC_UCMT_CHUNK
: {
353 TRACE_(dmfile
)(": comment chunk (ignored)\n");
354 liMove
.QuadPart
= Chunk
.dwSize
;
355 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
359 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
360 liMove
.QuadPart
= Chunk
.dwSize
;
361 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
365 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
366 } while (ListCount
[0] < ListSize
[0]);
370 TRACE_(dmfile
)(": unknown (skipping)\n");
371 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
372 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
379 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
380 liMove
.QuadPart
= Chunk
.dwSize
;
381 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
385 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
386 } while (StreamCount
< StreamSize
);
388 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
389 liMove
.QuadPart
= StreamSize
;
390 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
394 TRACE_(dmfile
)(": reading finished\n");
398 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
399 liMove
.QuadPart
= Chunk
.dwSize
;
400 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
401 return DMUS_E_INVALIDFILE
;
405 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
410 static const IDirectMusicObjectVtbl DirectMusicStyle8_Object_Vtbl
= {
411 IDirectMusicStyle8Impl_IDirectMusicObject_QueryInterface
,
412 IDirectMusicStyle8Impl_IDirectMusicObject_AddRef
,
413 IDirectMusicStyle8Impl_IDirectMusicObject_Release
,
414 IDirectMusicStyle8Impl_IDirectMusicObject_GetDescriptor
,
415 IDirectMusicStyle8Impl_IDirectMusicObject_SetDescriptor
,
416 IDirectMusicStyle8Impl_IDirectMusicObject_ParseDescriptor
419 /* IDirectMusicStyle8Impl IPersistStream part: */
420 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
) {
421 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
422 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
425 static ULONG WINAPI
IDirectMusicStyle8Impl_IPersistStream_AddRef (LPPERSISTSTREAM iface
) {
426 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
427 return IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
430 static ULONG WINAPI
IDirectMusicStyle8Impl_IPersistStream_Release (LPPERSISTSTREAM iface
) {
431 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
432 return IDirectMusicStyle8Impl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
435 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
) {
436 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
437 TRACE("(%p, %p)\n", This
, pClassID
);
438 *pClassID
= CLSID_DirectMusicStyle
;
442 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_IsDirty (LPPERSISTSTREAM iface
) {
443 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
444 FIXME("(%p): stub, always S_FALSE\n", This
);
448 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_LoadBand (LPPERSISTSTREAM iface
, IStream
* pClonedStream
, IDirectMusicBand
** ppBand
) {
451 IPersistStream
* pPersistStream
= NULL
;
453 hr
= CoCreateInstance (&CLSID_DirectMusicBand
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicBand
, (LPVOID
*) ppBand
);
455 ERR(": could not create object\n");
458 /* acquire PersistStream interface */
459 hr
= IDirectMusicBand_QueryInterface (*ppBand
, &IID_IPersistStream
, (LPVOID
*) &pPersistStream
);
461 ERR(": could not acquire IPersistStream\n");
465 hr
= IPersistStream_Load (pPersistStream
, pClonedStream
);
467 ERR(": failed to load object\n");
471 /* release all loading-related stuff */
472 IPersistStream_Release (pPersistStream
);
477 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
, LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif
) {
478 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
480 DMUS_PRIVATE_CHUNK Chunk
;
481 DWORD ListSize
[3], ListCount
[3];
482 LARGE_INTEGER liMove
; /* used when skipping chunks */
484 LPDMUS_PRIVATE_STYLE_PARTREF_ITEM pNewItem
= NULL
;
487 if (pChunk
->fccID
!= DMUS_FOURCC_PARTREF_LIST
) {
488 ERR_(dmfile
)(": %s chunk should be a PARTREF list\n", debugstr_fourcc (pChunk
->fccID
));
492 ListSize
[0] = pChunk
->dwSize
- sizeof(FOURCC
);
496 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
497 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
498 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
499 switch (Chunk
.fccID
) {
500 case DMUS_FOURCC_PARTREF_CHUNK
: {
501 TRACE_(dmfile
)(": PartRef chunk\n");
502 pNewItem
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_STYLE_PARTREF_ITEM
));
503 if (NULL
== pNewItem
) {
504 ERR(": no more memory\n");
505 return E_OUTOFMEMORY
;
507 hr
= IStream_Read (pStm
, &pNewItem
->part_ref
, sizeof(DMUS_IO_PARTREF
), NULL
);
508 /*TRACE_(dmfile)(" - sizeof %lu\n", sizeof(DMUS_IO_PARTREF));*/
509 list_add_tail (&pNewMotif
->Items
, &pNewItem
->entry
);
510 DM_STRUCT_INIT(&pNewItem
->desc
);
514 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
515 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
516 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
518 switch (Chunk
.fccID
) {
519 case DMUS_FOURCC_UNFO_LIST
: {
520 TRACE_(dmfile
)(": UNFO list\n");
522 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
523 ListCount
[1] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
524 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
526 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, &pNewItem
->desc
);
527 if (FAILED(hr
)) return hr
;
530 switch (Chunk
.fccID
) {
532 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
533 liMove
.QuadPart
= Chunk
.dwSize
;
534 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
539 TRACE_(dmfile
)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount
[1], ListSize
[1]);
540 } while (ListCount
[1] < ListSize
[1]);
544 TRACE_(dmfile
)(": unknown chunk (skipping)\n");
545 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
546 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
553 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
554 liMove
.QuadPart
= Chunk
.dwSize
;
555 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
559 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
560 } while (ListCount
[0] < ListSize
[0]);
565 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParsePartList (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
) {
567 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
569 DMUS_PRIVATE_CHUNK Chunk
;
570 DWORD ListSize
[3], ListCount
[3];
571 LARGE_INTEGER liMove
; /* used when skipping chunks */
573 DMUS_OBJECTDESC desc
;
577 if (pChunk
->fccID
!= DMUS_FOURCC_PART_LIST
) {
578 ERR_(dmfile
)(": %s chunk should be a PART list\n", debugstr_fourcc (pChunk
->fccID
));
582 ListSize
[0] = pChunk
->dwSize
- sizeof(FOURCC
);
586 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
587 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
588 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
589 switch (Chunk
.fccID
) {
590 case DMUS_FOURCC_PART_CHUNK
: {
591 TRACE_(dmfile
)(": Part chunk (skipping for now)\n" );
592 liMove
.QuadPart
= Chunk
.dwSize
;
593 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
596 case DMUS_FOURCC_NOTE_CHUNK
: {
597 TRACE_(dmfile
)(": Note chunk (skipping for now)\n");
598 IStream_Read (pStm
, &dwSize
, sizeof(DWORD
), NULL
);
599 cnt
= (Chunk
.dwSize
- sizeof(DWORD
));
600 TRACE_(dmfile
)(" - dwSize: %u\n", dwSize
);
601 TRACE_(dmfile
)(" - cnt: %u (%u / %u)\n", cnt
/ dwSize
, (DWORD
)(Chunk
.dwSize
- sizeof(DWORD
)), dwSize
);
602 if (cnt
% dwSize
!= 0) {
603 ERR("Invalid Array Size\n");
608 liMove
.QuadPart
= cnt
* dwSize
;
609 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
612 case DMUS_FOURCC_CURVE_CHUNK
: {
613 TRACE_(dmfile
)(": Curve chunk (skipping for now)\n");
614 IStream_Read (pStm
, &dwSize
, sizeof(DWORD
), NULL
);
615 cnt
= (Chunk
.dwSize
- sizeof(DWORD
));
616 TRACE_(dmfile
)(" - dwSize: %u\n", dwSize
);
617 TRACE_(dmfile
)(" - cnt: %u (%u / %u)\n", cnt
/ dwSize
, (DWORD
)(Chunk
.dwSize
- sizeof(DWORD
)), dwSize
);
618 if (cnt
% dwSize
!= 0) {
619 ERR("Invalid Array Size\n");
624 liMove
.QuadPart
= cnt
* dwSize
;
625 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
628 case DMUS_FOURCC_MARKER_CHUNK
: {
629 TRACE_(dmfile
)(": Marker chunk (skipping for now)\n");
630 liMove
.QuadPart
= Chunk
.dwSize
;
631 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
634 case DMUS_FOURCC_RESOLUTION_CHUNK
: {
635 TRACE_(dmfile
)(": Resolution chunk (skipping for now)\n");
636 liMove
.QuadPart
= Chunk
.dwSize
;
637 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
640 case DMUS_FOURCC_ANTICIPATION_CHUNK
: {
641 TRACE_(dmfile
)(": Anticipation chunk (skipping for now)\n");
642 liMove
.QuadPart
= Chunk
.dwSize
;
643 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
647 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
648 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
649 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
651 switch (Chunk
.fccID
) {
652 case DMUS_FOURCC_UNFO_LIST
: {
653 TRACE_(dmfile
)(": UNFO list\n");
655 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
656 ListCount
[1] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
657 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
659 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, &desc
);
660 if (FAILED(hr
)) return hr
;
663 switch (Chunk
.fccID
) {
665 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
666 liMove
.QuadPart
= Chunk
.dwSize
;
667 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
672 TRACE_(dmfile
)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount
[1], ListSize
[1]);
673 } while (ListCount
[1] < ListSize
[1]);
677 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
678 liMove
.QuadPart
= Chunk
.dwSize
;
679 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
686 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
687 liMove
.QuadPart
= Chunk
.dwSize
;
688 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
692 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
693 } while (ListCount
[0] < ListSize
[0]);
698 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
) {
700 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
702 DMUS_PRIVATE_CHUNK Chunk
;
703 DWORD ListSize
[3], ListCount
[3];
704 LARGE_INTEGER liMove
; /* used when skipping chunks */
706 DMUS_OBJECTDESC desc
;
707 IDirectMusicBand
* pBand
= NULL
;
708 LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif
= NULL
;
710 DM_STRUCT_INIT(&desc
);
712 if (pChunk
->fccID
!= DMUS_FOURCC_PATTERN_LIST
) {
713 ERR_(dmfile
)(": %s chunk should be a PATTERN list\n", debugstr_fourcc (pChunk
->fccID
));
717 ListSize
[0] = pChunk
->dwSize
- sizeof(FOURCC
);
721 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
722 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
723 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
724 switch (Chunk
.fccID
) {
725 case DMUS_FOURCC_PATTERN_CHUNK
: {
726 TRACE_(dmfile
)(": Pattern chunk\n");
727 /** alloc new motif entry */
728 pNewMotif
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_STYLE_MOTIF
));
729 list_add_tail (&This
->Motifs
, &pNewMotif
->entry
);
730 if (NULL
== pNewMotif
) {
731 ERR(": no more memory\n");
732 return E_OUTOFMEMORY
;
735 IStream_Read (pStm
, &pNewMotif
->pattern
, Chunk
.dwSize
, NULL
);
736 /** TODO trace pattern */
738 /** reset all data, as a new pattern begin */
739 DM_STRUCT_INIT(&pNewMotif
->desc
);
740 list_init (&pNewMotif
->Items
);
743 case DMUS_FOURCC_RHYTHM_CHUNK
: {
744 TRACE_(dmfile
)(": Rhythm chunk\n");
745 IStream_Read (pStm
, &pNewMotif
->dwRhythm
, sizeof(DWORD
), NULL
);
746 TRACE_(dmfile
)(" - dwRhythm: %u\n", pNewMotif
->dwRhythm
);
747 /** TODO understand why some Chunks have size > 4 */
748 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(DWORD
);
749 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
752 case DMUS_FOURCC_MOTIFSETTINGS_CHUNK
: {
753 TRACE_(dmfile
)(": MotifSettings chunk (skipping for now)\n");
754 IStream_Read (pStm
, &pNewMotif
->settings
, Chunk
.dwSize
, NULL
);
755 /** TODO trace settings */
760 * should be embedded Bands into pattern
762 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
763 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
764 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
766 switch (Chunk
.fccID
) {
767 case DMUS_FOURCC_BAND_FORM
: {
768 LPSTREAM pClonedStream
= NULL
;
770 TRACE_(dmfile
)(": BAND RIFF\n");
772 IStream_Clone (pStm
, &pClonedStream
);
775 liMove
.QuadPart
-= sizeof(FOURCC
) + (sizeof(FOURCC
)+sizeof(DWORD
));
776 IStream_Seek (pClonedStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
778 hr
= IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface
, pClonedStream
, &pBand
);
780 ERR(": could not load track\n");
783 IStream_Release (pClonedStream
);
785 pNewMotif
->pBand
= pBand
;
786 IDirectMusicBand_AddRef(pBand
);
788 IDirectMusicTrack_Release(pBand
); pBand
= NULL
; /* now we can release it as it's inserted */
790 /** now safe move the cursor */
791 liMove
.QuadPart
= ListSize
[1];
792 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
797 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
798 liMove
.QuadPart
= ListSize
[1];
799 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
806 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
807 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
808 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
810 switch (Chunk
.fccID
) {
811 case DMUS_FOURCC_UNFO_LIST
: {
812 TRACE_(dmfile
)(": UNFO list\n");
814 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
815 ListCount
[1] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
816 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
818 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, &pNewMotif
->desc
);
819 if (FAILED(hr
)) return hr
;
822 switch (Chunk
.fccID
) {
824 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
825 liMove
.QuadPart
= Chunk
.dwSize
;
826 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
831 TRACE_(dmfile
)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount
[1], ListSize
[1]);
832 } while (ListCount
[1] < ListSize
[1]);
835 case DMUS_FOURCC_PARTREF_LIST
: {
836 TRACE_(dmfile
)(": PartRef list\n");
837 hr
= IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface
, &Chunk
, pStm
, pNewMotif
);
838 if (FAILED(hr
)) return hr
;
842 TRACE_(dmfile
)(": unknown (skipping)\n");
843 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
844 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
851 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
852 liMove
.QuadPart
= Chunk
.dwSize
;
853 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
857 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
858 } while (ListCount
[0] < ListSize
[0]);
863 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
) {
864 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
867 DMUS_PRIVATE_CHUNK Chunk
;
868 DWORD StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
869 LARGE_INTEGER liMove
; /* used when skipping chunks */
871 IDirectMusicBand
* pBand
= NULL
;
873 if (pChunk
->fccID
!= DMUS_FOURCC_STYLE_FORM
) {
874 ERR_(dmfile
)(": %s chunk should be a STYLE form\n", debugstr_fourcc (pChunk
->fccID
));
878 StreamSize
= pChunk
->dwSize
- sizeof(FOURCC
);
882 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
883 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
884 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
886 hr
= IDirectMusicUtils_IPersistStream_ParseDescGeneric(&Chunk
, pStm
, This
->pDesc
);
887 if (FAILED(hr
)) return hr
;
890 switch (Chunk
.fccID
) {
891 case DMUS_FOURCC_STYLE_CHUNK
: {
892 TRACE_(dmfile
)(": Style chunk\n");
893 IStream_Read (pStm
, &This
->style
, sizeof(DMUS_IO_STYLE
), NULL
);
894 /** TODO dump DMUS_IO_TIMESIG style.timeSig */
895 TRACE_(dmfile
)(" - dblTempo: %g\n", This
->style
.dblTempo
);
900 * should be embedded Bands into style
902 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
903 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
904 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
906 switch (Chunk
.fccID
) {
907 case DMUS_FOURCC_BAND_FORM
: {
908 LPSTREAM pClonedStream
= NULL
;
909 LPDMUS_PRIVATE_STYLE_BAND pNewBand
;
911 TRACE_(dmfile
)(": BAND RIFF\n");
913 IStream_Clone (pStm
, &pClonedStream
);
916 liMove
.QuadPart
-= sizeof(FOURCC
) + (sizeof(FOURCC
)+sizeof(DWORD
));
917 IStream_Seek (pClonedStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
919 hr
= IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface
, pClonedStream
, &pBand
);
921 ERR(": could not load track\n");
924 IStream_Release (pClonedStream
);
926 pNewBand
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_STYLE_BAND
));
927 if (NULL
== pNewBand
) {
928 ERR(": no more memory\n");
929 return E_OUTOFMEMORY
;
931 pNewBand
->pBand
= pBand
;
932 IDirectMusicBand_AddRef(pBand
);
933 list_add_tail (&This
->Bands
, &pNewBand
->entry
);
935 IDirectMusicTrack_Release(pBand
); pBand
= NULL
; /* now we can release it as it's inserted */
937 /** now safely move the cursor */
938 liMove
.QuadPart
= ListSize
[0];
939 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
944 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
945 liMove
.QuadPart
= ListSize
[0];
946 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
953 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
954 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
955 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
957 switch (Chunk
.fccID
) {
958 case DMUS_FOURCC_UNFO_LIST
: {
959 TRACE_(dmfile
)(": UNFO list\n");
961 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
962 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
963 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
965 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, This
->pDesc
);
966 if (FAILED(hr
)) return hr
;
969 switch (Chunk
.fccID
) {
971 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
972 liMove
.QuadPart
= Chunk
.dwSize
;
973 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
978 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
979 } while (ListCount
[0] < ListSize
[0]);
982 case DMUS_FOURCC_PART_LIST
: {
983 TRACE_(dmfile
)(": PART list\n");
984 hr
= IDirectMusicStyle8Impl_IPersistStream_ParsePartList (iface
, &Chunk
, pStm
);
985 if (FAILED(hr
)) return hr
;
988 case DMUS_FOURCC_PATTERN_LIST
: {
989 TRACE_(dmfile
)(": PATTERN list\n");
990 hr
= IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (iface
, &Chunk
, pStm
);
991 if (FAILED(hr
)) return hr
;
995 TRACE_(dmfile
)(": unknown (skipping)\n");
996 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
997 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
1004 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
1005 liMove
.QuadPart
= Chunk
.dwSize
;
1006 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
1011 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
1012 } while (StreamCount
< StreamSize
);
1017 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
1018 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
1020 DMUS_PRIVATE_CHUNK Chunk
;
1021 LARGE_INTEGER liMove
; /* used when skipping chunks */
1024 FIXME("(%p, %p): Loading\n", This
, pStm
);
1026 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
1027 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
1028 switch (Chunk
.fccID
) {
1030 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
1031 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
1032 switch (Chunk
.fccID
) {
1033 case DMUS_FOURCC_STYLE_FORM
: {
1034 TRACE_(dmfile
)(": Style form\n");
1035 hr
= IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (iface
, &Chunk
, pStm
);
1036 if (FAILED(hr
)) return hr
;
1040 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
1041 liMove
.QuadPart
= Chunk
.dwSize
;
1042 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
1046 TRACE_(dmfile
)(": reading finished\n");
1050 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
1051 liMove
.QuadPart
= Chunk
.dwSize
;
1052 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
1060 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
1061 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
1062 FIXME("(%p): Saving not implemented yet\n", This
);
1066 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
1067 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
1068 FIXME("(%p, %p): stub\n", This
, pcbSize
);
1073 static const IPersistStreamVtbl DirectMusicStyle8_PersistStream_Vtbl
= {
1074 IDirectMusicStyle8Impl_IPersistStream_QueryInterface
,
1075 IDirectMusicStyle8Impl_IPersistStream_AddRef
,
1076 IDirectMusicStyle8Impl_IPersistStream_Release
,
1077 IDirectMusicStyle8Impl_IPersistStream_GetClassID
,
1078 IDirectMusicStyle8Impl_IPersistStream_IsDirty
,
1079 IDirectMusicStyle8Impl_IPersistStream_Load
,
1080 IDirectMusicStyle8Impl_IPersistStream_Save
,
1081 IDirectMusicStyle8Impl_IPersistStream_GetSizeMax
1084 /* for ClassFactory */
1085 HRESULT WINAPI
DMUSIC_CreateDirectMusicStyleImpl (LPCGUID lpcGUID
, LPVOID
* ppobj
, LPUNKNOWN pUnkOuter
) {
1086 IDirectMusicStyle8Impl
* obj
;
1088 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicStyle8Impl
));
1091 return E_OUTOFMEMORY
;
1093 obj
->UnknownVtbl
= &DirectMusicStyle8_Unknown_Vtbl
;
1094 obj
->StyleVtbl
= &DirectMusicStyle8_Style_Vtbl
;
1095 obj
->ObjectVtbl
= &DirectMusicStyle8_Object_Vtbl
;
1096 obj
->PersistStreamVtbl
= &DirectMusicStyle8_PersistStream_Vtbl
;
1097 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
1098 DM_STRUCT_INIT(obj
->pDesc
);
1099 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
1100 obj
->pDesc
->guidClass
= CLSID_DirectMusicStyle
;
1101 obj
->ref
= 0; /* will be inited by QueryInterface */
1102 list_init (&obj
->Bands
);
1103 list_init (&obj
->Motifs
);
1105 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN
)&obj
->UnknownVtbl
, lpcGUID
, ppobj
);