3 * Copyright (C) 2003-2004 Rok Mandeljc
4 * Copyright (C) 2003-2004 Raphael Junqueira
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Library General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "wine/port.h"
28 #include "dmscript_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dmscript
);
31 WINE_DECLARE_DEBUG_CHANNEL(dmfile
);
34 /*****************************************************************************
35 * IDirectMusicScriptImpl implementation
37 /* IDirectMusicScriptImpl IUnknown part: */
38 HRESULT WINAPI
IDirectMusicScriptImpl_IUnknown_QueryInterface (LPUNKNOWN iface
, REFIID riid
, LPVOID
*ppobj
) {
39 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, UnknownVtbl
, iface
);
40 TRACE("(%p, %s, %p)\n", This
, debugstr_dmguid(riid
), ppobj
);
42 if (IsEqualIID (riid
, &IID_IUnknown
)) {
43 *ppobj
= (LPVOID
)&This
->UnknownVtbl
;
44 IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
46 } else if (IsEqualIID (riid
, &IID_IDirectMusicScript
)) {
47 *ppobj
= (LPVOID
)&This
->ScriptVtbl
;
48 IDirectMusicScriptImpl_IDirectMusicScript_AddRef ((LPDIRECTMUSICSCRIPT
)&This
->ScriptVtbl
);
50 } else if (IsEqualIID (riid
, &IID_IDirectMusicObject
)) {
51 *ppobj
= (LPVOID
)&This
->ObjectVtbl
;
52 IDirectMusicScriptImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT
)&This
->ObjectVtbl
);
54 } else if (IsEqualIID (riid
, &IID_IPersistStream
)) {
55 *ppobj
= (LPVOID
)&This
->PersistStreamVtbl
;
56 IDirectMusicScriptImpl_IPersistStream_AddRef ((LPPERSISTSTREAM
)&This
->PersistStreamVtbl
);
60 WARN("(%p, %s, %p): not found\n", This
, debugstr_dmguid(riid
), ppobj
);
64 ULONG WINAPI
IDirectMusicScriptImpl_IUnknown_AddRef (LPUNKNOWN iface
) {
65 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, UnknownVtbl
, iface
);
66 TRACE("(%p): AddRef from %ld\n", This
, This
->ref
);
70 ULONG WINAPI
IDirectMusicScriptImpl_IUnknown_Release (LPUNKNOWN iface
) {
71 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, UnknownVtbl
, iface
);
72 ULONG ref
= --This
->ref
;
73 TRACE("(%p): ReleaseRef to %ld\n", This
, This
->ref
);
75 if (NULL
!= This
->pHeader
) HeapFree(GetProcessHeap(), 0, This
->pHeader
);
76 if (NULL
!= This
->pVersion
) HeapFree(GetProcessHeap(), 0, This
->pVersion
);
77 if (NULL
!= This
->pwzLanguage
) HeapFree(GetProcessHeap(), 0, This
->pwzLanguage
);
78 if (NULL
!= This
->pwzSource
) HeapFree(GetProcessHeap(), 0, This
->pwzSource
);
79 HeapFree(GetProcessHeap(), 0, This
);
84 IUnknownVtbl DirectMusicScript_Unknown_Vtbl
= {
85 IDirectMusicScriptImpl_IUnknown_QueryInterface
,
86 IDirectMusicScriptImpl_IUnknown_AddRef
,
87 IDirectMusicScriptImpl_IUnknown_Release
90 /* IDirectMusicScriptImpl IDirectMusicScript part: */
91 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_QueryInterface (LPDIRECTMUSICSCRIPT iface
, REFIID riid
, LPVOID
*ppobj
) {
92 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
93 return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
96 ULONG WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_AddRef (LPDIRECTMUSICSCRIPT iface
) {
97 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
98 return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
101 ULONG WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_Release (LPDIRECTMUSICSCRIPT iface
) {
102 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
103 return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
106 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_Init (LPDIRECTMUSICSCRIPT iface
, IDirectMusicPerformance
* pPerformance
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
107 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
108 FIXME("(%p, %p, %p): stub\n", This
, pPerformance
, pErrorInfo
);
109 This
->pPerformance
= pPerformance
;
113 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_CallRoutine (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszRoutineName
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
114 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
115 FIXME("(%p, %s, %p): stub\n", This
, debugstr_w(pwszRoutineName
), pErrorInfo
);
116 /*return E_NOTIMPL;*/
121 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_SetVariableVariant (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszVariableName
, VARIANT varValue
, BOOL fSetRef
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
122 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
123 FIXME("(%p, %s, FIXME, %d, %p): stub\n", This
, debugstr_w(pwszVariableName
),/* varValue,*/ fSetRef
, pErrorInfo
);
127 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_GetVariableVariant (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszVariableName
, VARIANT
* pvarValue
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
128 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
129 FIXME("(%p, %s, %p, %p): stub\n", This
, debugstr_w(pwszVariableName
), pvarValue
, pErrorInfo
);
133 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_SetVariableNumber (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszVariableName
, LONG lValue
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
134 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
135 FIXME("(%p, %s, %li, %p): stub\n", This
, debugstr_w(pwszVariableName
), lValue
, pErrorInfo
);
139 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_GetVariableNumber (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszVariableName
, LONG
* plValue
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
140 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
141 FIXME("(%p, %s, %p, %p): stub\n", This
, debugstr_w(pwszVariableName
), plValue
, pErrorInfo
);
145 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_SetVariableObject (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszVariableName
, IUnknown
* punkValue
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
146 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
147 FIXME("(%p, %s, %p, %p): stub\n", This
, debugstr_w(pwszVariableName
), punkValue
, pErrorInfo
);
151 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_GetVariableObject (LPDIRECTMUSICSCRIPT iface
, WCHAR
* pwszVariableName
, REFIID riid
, LPVOID
* ppv
, DMUS_SCRIPT_ERRORINFO
* pErrorInfo
) {
152 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
153 FIXME("(%p, %s, %s, %p, %p): stub\n", This
, debugstr_w(pwszVariableName
), debugstr_dmguid(riid
), ppv
, pErrorInfo
);
157 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_EnumRoutine (LPDIRECTMUSICSCRIPT iface
, DWORD dwIndex
, WCHAR
* pwszName
) {
158 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
159 FIXME("(%p, %ld, %p): stub\n", This
, dwIndex
, pwszName
);
163 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicScript_EnumVariable (LPDIRECTMUSICSCRIPT iface
, DWORD dwIndex
, WCHAR
* pwszName
) {
164 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ScriptVtbl
, iface
);
165 FIXME("(%p, %ld, %p): stub\n", This
, dwIndex
, pwszName
);
169 IDirectMusicScriptVtbl DirectMusicScript_Script_Vtbl
= {
170 IDirectMusicScriptImpl_IDirectMusicScript_QueryInterface
,
171 IDirectMusicScriptImpl_IDirectMusicScript_AddRef
,
172 IDirectMusicScriptImpl_IDirectMusicScript_Release
,
173 IDirectMusicScriptImpl_IDirectMusicScript_Init
,
174 IDirectMusicScriptImpl_IDirectMusicScript_CallRoutine
,
175 IDirectMusicScriptImpl_IDirectMusicScript_SetVariableVariant
,
176 IDirectMusicScriptImpl_IDirectMusicScript_GetVariableVariant
,
177 IDirectMusicScriptImpl_IDirectMusicScript_SetVariableNumber
,
178 IDirectMusicScriptImpl_IDirectMusicScript_GetVariableNumber
,
179 IDirectMusicScriptImpl_IDirectMusicScript_SetVariableObject
,
180 IDirectMusicScriptImpl_IDirectMusicScript_GetVariableObject
,
181 IDirectMusicScriptImpl_IDirectMusicScript_EnumRoutine
,
182 IDirectMusicScriptImpl_IDirectMusicScript_EnumVariable
185 /* IDirectMusicScriptImpl IDirectMusicObject part: */
186 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface
, REFIID riid
, LPVOID
*ppobj
) {
187 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ObjectVtbl
, iface
);
188 return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
191 ULONG WINAPI
IDirectMusicScriptImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface
) {
192 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ObjectVtbl
, iface
);
193 return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
196 ULONG WINAPI
IDirectMusicScriptImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface
) {
197 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ObjectVtbl
, iface
);
198 return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
201 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
202 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ObjectVtbl
, iface
);
203 TRACE("(%p, %p)\n", This
, pDesc
);
204 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
205 memcpy (pDesc
, This
->pDesc
, This
->pDesc
->dwSize
);
209 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface
, LPDMUS_OBJECTDESC pDesc
) {
210 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ObjectVtbl
, iface
);
211 TRACE("(%p, %p): setting descriptor:\n%s\n", This
, pDesc
, debugstr_DMUS_OBJECTDESC (pDesc
));
213 /* According to MSDN, we should copy only given values, not whole struct */
214 if (pDesc
->dwValidData
& DMUS_OBJ_OBJECT
)
215 memcpy (&This
->pDesc
->guidObject
, &pDesc
->guidObject
, sizeof (pDesc
->guidObject
));
216 if (pDesc
->dwValidData
& DMUS_OBJ_CLASS
)
217 memcpy (&This
->pDesc
->guidClass
, &pDesc
->guidClass
, sizeof (pDesc
->guidClass
));
218 if (pDesc
->dwValidData
& DMUS_OBJ_NAME
)
219 strncpyW (This
->pDesc
->wszName
, pDesc
->wszName
, DMUS_MAX_NAME
);
220 if (pDesc
->dwValidData
& DMUS_OBJ_CATEGORY
)
221 strncpyW (This
->pDesc
->wszCategory
, pDesc
->wszCategory
, DMUS_MAX_CATEGORY
);
222 if (pDesc
->dwValidData
& DMUS_OBJ_FILENAME
)
223 strncpyW (This
->pDesc
->wszFileName
, pDesc
->wszFileName
, DMUS_MAX_FILENAME
);
224 if (pDesc
->dwValidData
& DMUS_OBJ_VERSION
)
225 memcpy (&This
->pDesc
->vVersion
, &pDesc
->vVersion
, sizeof (pDesc
->vVersion
));
226 if (pDesc
->dwValidData
& DMUS_OBJ_DATE
)
227 memcpy (&This
->pDesc
->ftDate
, &pDesc
->ftDate
, sizeof (pDesc
->ftDate
));
228 if (pDesc
->dwValidData
& DMUS_OBJ_MEMORY
) {
229 memcpy (&This
->pDesc
->llMemLength
, &pDesc
->llMemLength
, sizeof (pDesc
->llMemLength
));
230 memcpy (This
->pDesc
->pbMemData
, pDesc
->pbMemData
, sizeof (pDesc
->pbMemData
));
232 if (pDesc
->dwValidData
& DMUS_OBJ_STREAM
) {
233 /* according to MSDN, we copy the stream */
234 IStream_Clone (pDesc
->pStream
, &This
->pDesc
->pStream
);
238 This
->pDesc
->dwValidData
|= pDesc
->dwValidData
;
243 HRESULT WINAPI
IDirectMusicScriptImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface
, LPSTREAM pStream
, LPDMUS_OBJECTDESC pDesc
) {
244 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, ObjectVtbl
, iface
);
245 DMUS_PRIVATE_CHUNK Chunk
;
246 DWORD StreamSize
, StreamCount
, ListSize
[1], ListCount
[1];
247 LARGE_INTEGER liMove
; /* used when skipping chunks */
249 TRACE("(%p, %p, %p)\n", This
, pStream
, pDesc
);
251 /* FIXME: should this be determined from stream? */
252 pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
253 memcpy (&pDesc
->guidClass
, &CLSID_DirectMusicScript
, sizeof(CLSID
));
255 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
256 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
257 switch (Chunk
.fccID
) {
259 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
260 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
261 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
263 if (Chunk
.fccID
== DMUS_FOURCC_SCRIPT_FORM
) {
264 TRACE_(dmfile
)(": script form\n");
266 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
267 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
268 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
269 switch (Chunk
.fccID
) {
270 case DMUS_FOURCC_GUID_CHUNK
: {
271 TRACE_(dmfile
)(": GUID chunk\n");
272 pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
273 IStream_Read (pStream
, &pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
276 case DMUS_FOURCC_VERSION_CHUNK
: {
277 TRACE_(dmfile
)(": version chunk\n");
278 pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
279 IStream_Read (pStream
, &pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
282 case DMUS_FOURCC_CATEGORY_CHUNK
: {
283 TRACE_(dmfile
)(": category chunk\n");
284 pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
285 IStream_Read (pStream
, pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
289 IStream_Read (pStream
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
290 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
291 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
293 switch (Chunk
.fccID
) {
294 /* evil M$ UNFO list, which can (!?) contain INFO elements */
295 case DMUS_FOURCC_UNFO_LIST
: {
296 TRACE_(dmfile
)(": UNFO list\n");
298 IStream_Read (pStream
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
299 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
300 TRACE_(dmfile
)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
301 switch (Chunk
.fccID
) {
302 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
303 (though strings seem to be valid unicode) */
304 case mmioFOURCC('I','N','A','M'):
305 case DMUS_FOURCC_UNAM_CHUNK
: {
306 TRACE_(dmfile
)(": name chunk\n");
307 pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
308 IStream_Read (pStream
, pDesc
->wszName
, Chunk
.dwSize
, NULL
);
311 case mmioFOURCC('I','A','R','T'):
312 case DMUS_FOURCC_UART_CHUNK
: {
313 TRACE_(dmfile
)(": artist chunk (ignored)\n");
314 liMove
.QuadPart
= Chunk
.dwSize
;
315 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
318 case mmioFOURCC('I','C','O','P'):
319 case DMUS_FOURCC_UCOP_CHUNK
: {
320 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
321 liMove
.QuadPart
= Chunk
.dwSize
;
322 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
325 case mmioFOURCC('I','S','B','J'):
326 case DMUS_FOURCC_USBJ_CHUNK
: {
327 TRACE_(dmfile
)(": subject chunk (ignored)\n");
328 liMove
.QuadPart
= Chunk
.dwSize
;
329 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
332 case mmioFOURCC('I','C','M','T'):
333 case DMUS_FOURCC_UCMT_CHUNK
: {
334 TRACE_(dmfile
)(": comment chunk (ignored)\n");
335 liMove
.QuadPart
= Chunk
.dwSize
;
336 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
340 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
341 liMove
.QuadPart
= Chunk
.dwSize
;
342 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
346 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
347 } while (ListCount
[0] < ListSize
[0]);
351 TRACE_(dmfile
)(": unknown (skipping)\n");
352 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
353 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
360 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
361 liMove
.QuadPart
= Chunk
.dwSize
;
362 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
366 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
367 } while (StreamCount
< StreamSize
);
370 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
371 liMove
.QuadPart
= StreamSize
;
372 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
376 TRACE_(dmfile
)(": reading finished\n");
380 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
381 liMove
.QuadPart
= Chunk
.dwSize
;
382 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
383 return DMUS_E_INVALIDFILE
;
387 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
392 IDirectMusicObjectVtbl DirectMusicScript_Object_Vtbl
= {
393 IDirectMusicScriptImpl_IDirectMusicObject_QueryInterface
,
394 IDirectMusicScriptImpl_IDirectMusicObject_AddRef
,
395 IDirectMusicScriptImpl_IDirectMusicObject_Release
,
396 IDirectMusicScriptImpl_IDirectMusicObject_GetDescriptor
,
397 IDirectMusicScriptImpl_IDirectMusicObject_SetDescriptor
,
398 IDirectMusicScriptImpl_IDirectMusicObject_ParseDescriptor
401 /* IDirectMusicScriptImpl IPersistStream part: */
402 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
) {
403 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
404 return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
407 ULONG WINAPI
IDirectMusicScriptImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface
) {
408 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
409 return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
412 ULONG WINAPI
IDirectMusicScriptImpl_IPersistStream_Release (LPPERSISTSTREAM iface
) {
413 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
414 return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
417 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
) {
418 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
419 TRACE("(%p, %p)\n", This
, pClassID
);
420 memcpy(pClassID
, &CLSID_DirectMusicScript
, sizeof(CLSID
));
424 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface
) {
425 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
426 FIXME("(%p): stub, always S_FALSE\n", This
);
430 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
431 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
433 DMUS_PRIVATE_CHUNK Chunk
;
434 DWORD StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
435 LARGE_INTEGER liMove
; /* used when skipping chunks */
436 LPDIRECTMUSICGETLOADER pGetLoader
= NULL
;
437 LPDIRECTMUSICLOADER pLoader
= NULL
;
439 FIXME("(%p, %p): Loading not implemented yet\n", This
, pStm
);
440 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
441 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
442 switch (Chunk
.fccID
) {
444 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
445 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
446 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
448 switch (Chunk
.fccID
) {
449 case DMUS_FOURCC_SCRIPT_FORM
: {
450 TRACE_(dmfile
)(": script form\n");
452 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
453 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
454 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
455 switch (Chunk
.fccID
) {
456 case DMUS_FOURCC_SCRIPT_CHUNK
: {
457 TRACE_(dmfile
)(": script header chunk\n");
458 This
->pHeader
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
459 IStream_Read (pStm
, This
->pHeader
, Chunk
.dwSize
, NULL
);
462 case DMUS_FOURCC_SCRIPTVERSION_CHUNK
: {
463 TRACE_(dmfile
)(": script version chunk\n");
464 This
->pVersion
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
465 IStream_Read (pStm
, This
->pVersion
, Chunk
.dwSize
, NULL
);
466 TRACE_(dmfile
)("version: 0x%08lx.0x%08lx \n", This
->pVersion
->dwVersionMS
, This
->pVersion
->dwVersionLS
);
469 case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK
: {
470 TRACE_(dmfile
)(": script language chunk\n");
471 This
->pwzLanguage
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
472 IStream_Read (pStm
, This
->pwzLanguage
, Chunk
.dwSize
, NULL
);
473 TRACE_(dmfile
)("using language: %s \n", debugstr_w(This
->pwzLanguage
));
476 case DMUS_FOURCC_SCRIPTSOURCE_CHUNK
: {
477 TRACE_(dmfile
)(": script source chunk\n");
478 This
->pwzSource
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
479 IStream_Read (pStm
, This
->pwzSource
, Chunk
.dwSize
, NULL
);
480 if (TRACE_ON(dmscript
)) {
481 int count
= WideCharToMultiByte(CP_ACP
, 0, This
->pwzSource
, -1, NULL
, 0, NULL
, NULL
);
482 LPSTR str
= HeapAlloc(GetProcessHeap (), 0, count
);
483 WideCharToMultiByte(CP_ACP
, 0, This
->pwzSource
, -1, str
, count
, NULL
, NULL
);
486 write( 2, str
, count
);
487 HeapFree(GetProcessHeap(), 0, str
);
491 case DMUS_FOURCC_GUID_CHUNK
: {
492 TRACE_(dmfile
)(": GUID chunk\n");
493 This
->pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
494 IStream_Read (pStm
, &This
->pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
497 case DMUS_FOURCC_VERSION_CHUNK
: {
498 TRACE_(dmfile
)(": version chunk\n");
499 This
->pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
500 IStream_Read (pStm
, &This
->pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
503 case DMUS_FOURCC_CATEGORY_CHUNK
: {
504 TRACE_(dmfile
)(": category chunk\n");
505 This
->pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
506 IStream_Read (pStm
, This
->pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
510 IDirectMusicObject
* pObject
= NULL
;
511 DMUS_OBJECTDESC desc
;
513 ZeroMemory ((LPVOID
)&desc
, sizeof(DMUS_OBJECTDESC
));
514 desc
.dwSize
= sizeof(DMUS_OBJECTDESC
);
515 desc
.dwValidData
= DMUS_OBJ_STREAM
| DMUS_OBJ_CLASS
;
516 desc
.guidClass
= CLSID_DirectMusicContainer
;
518 IStream_Clone (pStm
, &desc
.pStream
);
521 liMove
.QuadPart
-= (sizeof(FOURCC
) + sizeof(DWORD
));
522 IStream_Seek (desc
.pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
524 IStream_QueryInterface (pStm
, &IID_IDirectMusicGetLoader
, (LPVOID
*)&pGetLoader
);
525 IDirectMusicGetLoader_GetLoader (pGetLoader
, &pLoader
);
526 IDirectMusicGetLoader_Release (pGetLoader
);
528 if (SUCCEEDED(IDirectMusicLoader_GetObject (pLoader
, &desc
, &IID_IDirectMusicObject
, (LPVOID
*) &pObject
))) {
529 IDirectMusicObject_Release (pObject
);
531 ERR_(dmfile
)("Error on GetObject while trying to load Scrip SubContainer\n");
534 IDirectMusicLoader_Release (pLoader
); pLoader
= NULL
; /* release loader */
535 IStream_Release(desc
.pStream
); desc
.pStream
= NULL
; /* release cloned stream */
537 liMove
.QuadPart
= Chunk
.dwSize
;
538 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
540 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
541 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
542 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
545 switch (Chunk.fccID) {
547 TRACE_(dmfile)(": unknown (skipping)\n");
548 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
549 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
557 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
558 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
559 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
561 switch (Chunk
.fccID
) {
562 case DMUS_FOURCC_UNFO_LIST
: {
563 TRACE_(dmfile
)(": UNFO list\n");
565 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
566 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
567 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
568 switch (Chunk
.fccID
) {
569 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
570 (though strings seem to be valid unicode) */
571 case mmioFOURCC('I','N','A','M'):
572 case DMUS_FOURCC_UNAM_CHUNK
: {
573 TRACE_(dmfile
)(": name chunk\n");
574 This
->pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
575 IStream_Read (pStm
, This
->pDesc
->wszName
, Chunk
.dwSize
, NULL
);
578 case mmioFOURCC('I','A','R','T'):
579 case DMUS_FOURCC_UART_CHUNK
: {
580 TRACE_(dmfile
)(": artist chunk (ignored)\n");
581 liMove
.QuadPart
= Chunk
.dwSize
;
582 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
585 case mmioFOURCC('I','C','O','P'):
586 case DMUS_FOURCC_UCOP_CHUNK
: {
587 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
588 liMove
.QuadPart
= Chunk
.dwSize
;
589 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
592 case mmioFOURCC('I','S','B','J'):
593 case DMUS_FOURCC_USBJ_CHUNK
: {
594 TRACE_(dmfile
)(": subject chunk (ignored)\n");
595 liMove
.QuadPart
= Chunk
.dwSize
;
596 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
599 case mmioFOURCC('I','C','M','T'):
600 case DMUS_FOURCC_UCMT_CHUNK
: {
601 TRACE_(dmfile
)(": comment chunk (ignored)\n");
602 liMove
.QuadPart
= Chunk
.dwSize
;
603 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
607 TRACE_(dmfile
)(": unknown sub-chunk (irrevelant & skipping)\n");
608 liMove
.QuadPart
= Chunk
.dwSize
;
609 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
613 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
614 } while (ListCount
[0] < ListSize
[0]);
618 TRACE_(dmfile
)(": unknown (skipping)\n");
619 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
620 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
627 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
628 liMove
.QuadPart
= Chunk
.dwSize
;
629 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
633 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
634 } while (StreamCount
< StreamSize
);
638 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
639 liMove
.QuadPart
= StreamSize
;
640 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
644 TRACE_(dmfile
)(": reading finished\n");
648 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
649 liMove
.QuadPart
= Chunk
.dwSize
;
650 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
658 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
662 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
666 IPersistStreamVtbl DirectMusicScript_PersistStream_Vtbl
= {
667 IDirectMusicScriptImpl_IPersistStream_QueryInterface
,
668 IDirectMusicScriptImpl_IPersistStream_AddRef
,
669 IDirectMusicScriptImpl_IPersistStream_Release
,
670 IDirectMusicScriptImpl_IPersistStream_GetClassID
,
671 IDirectMusicScriptImpl_IPersistStream_IsDirty
,
672 IDirectMusicScriptImpl_IPersistStream_Load
,
673 IDirectMusicScriptImpl_IPersistStream_Save
,
674 IDirectMusicScriptImpl_IPersistStream_GetSizeMax
677 /* for ClassFactory */
678 HRESULT WINAPI
DMUSIC_CreateDirectMusicScriptImpl (LPCGUID lpcGUID
, LPVOID
* ppobj
, LPUNKNOWN pUnkOuter
) {
679 IDirectMusicScriptImpl
* obj
;
681 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicScriptImpl
));
683 *ppobj
= (LPVOID
) NULL
;
684 return E_OUTOFMEMORY
;
686 obj
->UnknownVtbl
= &DirectMusicScript_Unknown_Vtbl
;
687 obj
->ScriptVtbl
= &DirectMusicScript_Script_Vtbl
;
688 obj
->ObjectVtbl
= &DirectMusicScript_Object_Vtbl
;
689 obj
->PersistStreamVtbl
= &DirectMusicScript_PersistStream_Vtbl
;
690 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
691 DM_STRUCT_INIT(obj
->pDesc
);
692 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
693 memcpy (&obj
->pDesc
->guidClass
, &CLSID_DirectMusicScript
, sizeof (CLSID
));
694 obj
->ref
= 0; /* will be inited by QueryInterface */
696 return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&obj
->UnknownVtbl
, lpcGUID
, ppobj
);