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
= &This
->UnknownVtbl
;
41 IDirectMusicStyle8Impl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
43 } else if (IsEqualIID (riid
, &IID_IDirectMusicStyle
)) {
44 *ppobj
= &This
->StyleVtbl
;
45 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef ((LPDIRECTMUSICSTYLE8
)&This
->StyleVtbl
);
47 } else if (IsEqualIID (riid
, &IID_IDirectMusicStyle8
)) {
48 *ppobj
= &This
->StyleVtbl
;
49 IDirectMusicStyle8Impl_IDirectMusicStyle8_AddRef ((LPDIRECTMUSICSTYLE8
)&This
->StyleVtbl
);
51 } else if (IsEqualIID (riid
, &IID_IDirectMusicObject
)) {
52 *ppobj
= &This
->ObjectVtbl
;
53 IDirectMusicStyle8Impl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT
)&This
->ObjectVtbl
);
55 } else if (IsEqualIID (riid
, &IID_IPersistStream
)) {
56 *ppobj
= &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 (irrelevant & 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 (irrelevant & 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
));
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
);
527 ERR(": pNewItem not yet allocated, chunk order bad?\n");
528 return E_OUTOFMEMORY
;
530 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, &pNewItem
->desc
);
531 if (FAILED(hr
)) return hr
;
534 switch (Chunk
.fccID
) {
536 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
537 liMove
.QuadPart
= Chunk
.dwSize
;
538 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
543 TRACE_(dmfile
)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount
[1], ListSize
[1]);
544 } while (ListCount
[1] < ListSize
[1]);
548 TRACE_(dmfile
)(": unknown chunk (skipping)\n");
549 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
550 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
557 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
558 liMove
.QuadPart
= Chunk
.dwSize
;
559 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
563 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
564 } while (ListCount
[0] < ListSize
[0]);
569 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParsePartList (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
) {
571 /*ICOM_THIS_MULTI(IDirectMusicStyle8Impl, PersistStreamVtbl, iface);*/
573 DMUS_PRIVATE_CHUNK Chunk
;
574 DWORD ListSize
[3], ListCount
[3];
575 LARGE_INTEGER liMove
; /* used when skipping chunks */
577 DMUS_OBJECTDESC desc
;
581 if (pChunk
->fccID
!= DMUS_FOURCC_PART_LIST
) {
582 ERR_(dmfile
)(": %s chunk should be a PART list\n", debugstr_fourcc (pChunk
->fccID
));
586 ListSize
[0] = pChunk
->dwSize
- sizeof(FOURCC
);
590 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
591 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
592 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
593 switch (Chunk
.fccID
) {
594 case DMUS_FOURCC_PART_CHUNK
: {
595 TRACE_(dmfile
)(": Part chunk (skipping for now)\n" );
596 liMove
.QuadPart
= Chunk
.dwSize
;
597 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
600 case DMUS_FOURCC_NOTE_CHUNK
: {
601 TRACE_(dmfile
)(": Note chunk (skipping for now)\n");
602 IStream_Read (pStm
, &dwSize
, sizeof(DWORD
), NULL
);
603 cnt
= (Chunk
.dwSize
- sizeof(DWORD
));
604 TRACE_(dmfile
)(" - dwSize: %u\n", dwSize
);
605 TRACE_(dmfile
)(" - cnt: %u (%u / %u)\n", cnt
/ dwSize
, (DWORD
)(Chunk
.dwSize
- sizeof(DWORD
)), dwSize
);
606 if (cnt
% dwSize
!= 0) {
607 ERR("Invalid Array Size\n");
612 liMove
.QuadPart
= cnt
* dwSize
;
613 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
616 case DMUS_FOURCC_CURVE_CHUNK
: {
617 TRACE_(dmfile
)(": Curve chunk (skipping for now)\n");
618 IStream_Read (pStm
, &dwSize
, sizeof(DWORD
), NULL
);
619 cnt
= (Chunk
.dwSize
- sizeof(DWORD
));
620 TRACE_(dmfile
)(" - dwSize: %u\n", dwSize
);
621 TRACE_(dmfile
)(" - cnt: %u (%u / %u)\n", cnt
/ dwSize
, (DWORD
)(Chunk
.dwSize
- sizeof(DWORD
)), dwSize
);
622 if (cnt
% dwSize
!= 0) {
623 ERR("Invalid Array Size\n");
628 liMove
.QuadPart
= cnt
* dwSize
;
629 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
632 case DMUS_FOURCC_MARKER_CHUNK
: {
633 TRACE_(dmfile
)(": Marker chunk (skipping for now)\n");
634 liMove
.QuadPart
= Chunk
.dwSize
;
635 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
638 case DMUS_FOURCC_RESOLUTION_CHUNK
: {
639 TRACE_(dmfile
)(": Resolution chunk (skipping for now)\n");
640 liMove
.QuadPart
= Chunk
.dwSize
;
641 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
644 case DMUS_FOURCC_ANTICIPATION_CHUNK
: {
645 TRACE_(dmfile
)(": Anticipation chunk (skipping for now)\n");
646 liMove
.QuadPart
= Chunk
.dwSize
;
647 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
651 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
652 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
653 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
655 switch (Chunk
.fccID
) {
656 case DMUS_FOURCC_UNFO_LIST
: {
657 TRACE_(dmfile
)(": UNFO list\n");
659 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
660 ListCount
[1] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
661 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
663 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, &desc
);
664 if (FAILED(hr
)) return hr
;
667 switch (Chunk
.fccID
) {
669 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
670 liMove
.QuadPart
= Chunk
.dwSize
;
671 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
676 TRACE_(dmfile
)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount
[1], ListSize
[1]);
677 } while (ListCount
[1] < ListSize
[1]);
681 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
682 liMove
.QuadPart
= Chunk
.dwSize
;
683 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
690 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
691 liMove
.QuadPart
= Chunk
.dwSize
;
692 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
696 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
697 } while (ListCount
[0] < ListSize
[0]);
702 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
) {
704 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
706 DMUS_PRIVATE_CHUNK Chunk
;
707 DWORD ListSize
[3], ListCount
[3];
708 LARGE_INTEGER liMove
; /* used when skipping chunks */
710 DMUS_OBJECTDESC desc
;
711 IDirectMusicBand
* pBand
= NULL
;
712 LPDMUS_PRIVATE_STYLE_MOTIF pNewMotif
= NULL
;
714 DM_STRUCT_INIT(&desc
);
716 if (pChunk
->fccID
!= DMUS_FOURCC_PATTERN_LIST
) {
717 ERR_(dmfile
)(": %s chunk should be a PATTERN list\n", debugstr_fourcc (pChunk
->fccID
));
721 ListSize
[0] = pChunk
->dwSize
- sizeof(FOURCC
);
725 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
726 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
727 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
728 switch (Chunk
.fccID
) {
729 case DMUS_FOURCC_PATTERN_CHUNK
: {
730 TRACE_(dmfile
)(": Pattern chunk\n");
731 /** alloc new motif entry */
732 pNewMotif
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_STYLE_MOTIF
));
733 if (NULL
== pNewMotif
) {
734 ERR(": no more memory\n");
735 return E_OUTOFMEMORY
;
737 list_add_tail (&This
->Motifs
, &pNewMotif
->entry
);
739 IStream_Read (pStm
, &pNewMotif
->pattern
, Chunk
.dwSize
, NULL
);
740 /** TODO trace pattern */
742 /** reset all data, as a new pattern begin */
743 DM_STRUCT_INIT(&pNewMotif
->desc
);
744 list_init (&pNewMotif
->Items
);
747 case DMUS_FOURCC_RHYTHM_CHUNK
: {
748 TRACE_(dmfile
)(": Rhythm chunk\n");
749 IStream_Read (pStm
, &pNewMotif
->dwRhythm
, sizeof(DWORD
), NULL
);
750 TRACE_(dmfile
)(" - dwRhythm: %u\n", pNewMotif
->dwRhythm
);
751 /** TODO understand why some Chunks have size > 4 */
752 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(DWORD
);
753 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
756 case DMUS_FOURCC_MOTIFSETTINGS_CHUNK
: {
757 TRACE_(dmfile
)(": MotifSettings chunk (skipping for now)\n");
758 IStream_Read (pStm
, &pNewMotif
->settings
, Chunk
.dwSize
, NULL
);
759 /** TODO trace settings */
764 * should be embedded Bands into pattern
766 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
767 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
768 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
770 switch (Chunk
.fccID
) {
771 case DMUS_FOURCC_BAND_FORM
: {
772 LPSTREAM pClonedStream
= NULL
;
774 TRACE_(dmfile
)(": BAND RIFF\n");
776 IStream_Clone (pStm
, &pClonedStream
);
779 liMove
.QuadPart
-= sizeof(FOURCC
) + (sizeof(FOURCC
)+sizeof(DWORD
));
780 IStream_Seek (pClonedStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
782 hr
= IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface
, pClonedStream
, &pBand
);
784 ERR(": could not load track\n");
787 IStream_Release (pClonedStream
);
789 pNewMotif
->pBand
= pBand
;
790 IDirectMusicBand_AddRef(pBand
);
792 IDirectMusicTrack_Release(pBand
); pBand
= NULL
; /* now we can release it as it's inserted */
794 /** now safe move the cursor */
795 liMove
.QuadPart
= ListSize
[1];
796 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
801 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
802 liMove
.QuadPart
= ListSize
[1];
803 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
810 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
811 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
812 ListSize
[1] = Chunk
.dwSize
- sizeof(FOURCC
);
814 switch (Chunk
.fccID
) {
815 case DMUS_FOURCC_UNFO_LIST
: {
816 TRACE_(dmfile
)(": UNFO list\n");
818 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
819 ListCount
[1] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
820 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
822 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, &pNewMotif
->desc
);
823 if (FAILED(hr
)) return hr
;
826 switch (Chunk
.fccID
) {
828 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
829 liMove
.QuadPart
= Chunk
.dwSize
;
830 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
835 TRACE_(dmfile
)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount
[1], ListSize
[1]);
836 } while (ListCount
[1] < ListSize
[1]);
839 case DMUS_FOURCC_PARTREF_LIST
: {
840 TRACE_(dmfile
)(": PartRef list\n");
841 hr
= IDirectMusicStyle8Impl_IPersistStream_ParsePartRefList (iface
, &Chunk
, pStm
, pNewMotif
);
842 if (FAILED(hr
)) return hr
;
846 TRACE_(dmfile
)(": unknown (skipping)\n");
847 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
848 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
855 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
856 liMove
.QuadPart
= Chunk
.dwSize
;
857 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
861 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
862 } while (ListCount
[0] < ListSize
[0]);
867 static HRESULT
IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (LPPERSISTSTREAM iface
, DMUS_PRIVATE_CHUNK
* pChunk
, IStream
* pStm
) {
868 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
871 DMUS_PRIVATE_CHUNK Chunk
;
872 DWORD StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
873 LARGE_INTEGER liMove
; /* used when skipping chunks */
875 IDirectMusicBand
* pBand
= NULL
;
877 if (pChunk
->fccID
!= DMUS_FOURCC_STYLE_FORM
) {
878 ERR_(dmfile
)(": %s chunk should be a STYLE form\n", debugstr_fourcc (pChunk
->fccID
));
882 StreamSize
= pChunk
->dwSize
- sizeof(FOURCC
);
886 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
887 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
888 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
890 hr
= IDirectMusicUtils_IPersistStream_ParseDescGeneric(&Chunk
, pStm
, This
->pDesc
);
891 if (FAILED(hr
)) return hr
;
894 switch (Chunk
.fccID
) {
895 case DMUS_FOURCC_STYLE_CHUNK
: {
896 TRACE_(dmfile
)(": Style chunk\n");
897 IStream_Read (pStm
, &This
->style
, sizeof(DMUS_IO_STYLE
), NULL
);
898 /** TODO dump DMUS_IO_TIMESIG style.timeSig */
899 TRACE_(dmfile
)(" - dblTempo: %g\n", This
->style
.dblTempo
);
904 * should be embedded Bands into style
906 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
907 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
908 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
910 switch (Chunk
.fccID
) {
911 case DMUS_FOURCC_BAND_FORM
: {
912 LPSTREAM pClonedStream
= NULL
;
913 LPDMUS_PRIVATE_STYLE_BAND pNewBand
;
915 TRACE_(dmfile
)(": BAND RIFF\n");
917 IStream_Clone (pStm
, &pClonedStream
);
920 liMove
.QuadPart
-= sizeof(FOURCC
) + (sizeof(FOURCC
)+sizeof(DWORD
));
921 IStream_Seek (pClonedStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
923 hr
= IDirectMusicStyle8Impl_IPersistStream_LoadBand (iface
, pClonedStream
, &pBand
);
925 ERR(": could not load track\n");
928 IStream_Release (pClonedStream
);
930 pNewBand
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, sizeof(DMUS_PRIVATE_STYLE_BAND
));
931 if (NULL
== pNewBand
) {
932 ERR(": no more memory\n");
933 return E_OUTOFMEMORY
;
935 pNewBand
->pBand
= pBand
;
936 IDirectMusicBand_AddRef(pBand
);
937 list_add_tail (&This
->Bands
, &pNewBand
->entry
);
939 IDirectMusicTrack_Release(pBand
); pBand
= NULL
; /* now we can release it as it's inserted */
941 /** now safely move the cursor */
942 liMove
.QuadPart
= ListSize
[0];
943 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
948 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
949 liMove
.QuadPart
= ListSize
[0];
950 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
957 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
958 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
959 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
961 switch (Chunk
.fccID
) {
962 case DMUS_FOURCC_UNFO_LIST
: {
963 TRACE_(dmfile
)(": UNFO list\n");
965 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
966 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
967 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
969 hr
= IDirectMusicUtils_IPersistStream_ParseUNFOGeneric(&Chunk
, pStm
, This
->pDesc
);
970 if (FAILED(hr
)) return hr
;
973 switch (Chunk
.fccID
) {
975 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
976 liMove
.QuadPart
= Chunk
.dwSize
;
977 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
982 TRACE_(dmfile
)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount
[0], ListSize
[0]);
983 } while (ListCount
[0] < ListSize
[0]);
986 case DMUS_FOURCC_PART_LIST
: {
987 TRACE_(dmfile
)(": PART list\n");
988 hr
= IDirectMusicStyle8Impl_IPersistStream_ParsePartList (iface
, &Chunk
, pStm
);
989 if (FAILED(hr
)) return hr
;
992 case DMUS_FOURCC_PATTERN_LIST
: {
993 TRACE_(dmfile
)(": PATTERN list\n");
994 hr
= IDirectMusicStyle8Impl_IPersistStream_ParsePatternList (iface
, &Chunk
, pStm
);
995 if (FAILED(hr
)) return hr
;
999 TRACE_(dmfile
)(": unknown (skipping)\n");
1000 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
1001 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
1008 TRACE_(dmfile
)(": unknown chunk (irrelevant & skipping)\n");
1009 liMove
.QuadPart
= Chunk
.dwSize
;
1010 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
1015 TRACE_(dmfile
)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount
, StreamSize
);
1016 } while (StreamCount
< StreamSize
);
1021 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
1022 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
1024 DMUS_PRIVATE_CHUNK Chunk
;
1025 LARGE_INTEGER liMove
; /* used when skipping chunks */
1028 FIXME("(%p, %p): Loading\n", This
, pStm
);
1030 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
1031 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
1032 switch (Chunk
.fccID
) {
1034 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
1035 TRACE_(dmfile
)(": %s chunk (size = %d)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
1036 switch (Chunk
.fccID
) {
1037 case DMUS_FOURCC_STYLE_FORM
: {
1038 TRACE_(dmfile
)(": Style form\n");
1039 hr
= IDirectMusicStyle8Impl_IPersistStream_ParseStyleForm (iface
, &Chunk
, pStm
);
1040 if (FAILED(hr
)) return hr
;
1044 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
1045 liMove
.QuadPart
= Chunk
.dwSize
;
1046 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
1050 TRACE_(dmfile
)(": reading finished\n");
1054 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
1055 liMove
.QuadPart
= Chunk
.dwSize
;
1056 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
1064 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
1065 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
1066 FIXME("(%p): Saving not implemented yet\n", This
);
1070 static HRESULT WINAPI
IDirectMusicStyle8Impl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
1071 ICOM_THIS_MULTI(IDirectMusicStyle8Impl
, PersistStreamVtbl
, iface
);
1072 FIXME("(%p, %p): stub\n", This
, pcbSize
);
1077 static const IPersistStreamVtbl DirectMusicStyle8_PersistStream_Vtbl
= {
1078 IDirectMusicStyle8Impl_IPersistStream_QueryInterface
,
1079 IDirectMusicStyle8Impl_IPersistStream_AddRef
,
1080 IDirectMusicStyle8Impl_IPersistStream_Release
,
1081 IDirectMusicStyle8Impl_IPersistStream_GetClassID
,
1082 IDirectMusicStyle8Impl_IPersistStream_IsDirty
,
1083 IDirectMusicStyle8Impl_IPersistStream_Load
,
1084 IDirectMusicStyle8Impl_IPersistStream_Save
,
1085 IDirectMusicStyle8Impl_IPersistStream_GetSizeMax
1088 /* for ClassFactory */
1089 HRESULT WINAPI
DMUSIC_CreateDirectMusicStyleImpl (LPCGUID lpcGUID
, LPVOID
* ppobj
, LPUNKNOWN pUnkOuter
) {
1090 IDirectMusicStyle8Impl
* obj
;
1092 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicStyle8Impl
));
1095 return E_OUTOFMEMORY
;
1097 obj
->UnknownVtbl
= &DirectMusicStyle8_Unknown_Vtbl
;
1098 obj
->StyleVtbl
= &DirectMusicStyle8_Style_Vtbl
;
1099 obj
->ObjectVtbl
= &DirectMusicStyle8_Object_Vtbl
;
1100 obj
->PersistStreamVtbl
= &DirectMusicStyle8_PersistStream_Vtbl
;
1101 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
1102 DM_STRUCT_INIT(obj
->pDesc
);
1103 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
1104 obj
->pDesc
->guidClass
= CLSID_DirectMusicStyle
;
1105 obj
->ref
= 0; /* will be inited by QueryInterface */
1106 list_init (&obj
->Bands
);
1107 list_init (&obj
->Motifs
);
1109 return IDirectMusicStyle8Impl_IUnknown_QueryInterface ((LPUNKNOWN
)&obj
->UnknownVtbl
, lpcGUID
, ppobj
);