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 HeapFree(GetProcessHeap(), 0, This
->pHeader
);
76 HeapFree(GetProcessHeap(), 0, This
->pVersion
);
77 HeapFree(GetProcessHeap(), 0, This
->pwzLanguage
);
78 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
);
369 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
370 liMove
.QuadPart
= StreamSize
;
371 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
375 TRACE_(dmfile
)(": reading finished\n");
379 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
380 liMove
.QuadPart
= Chunk
.dwSize
;
381 IStream_Seek (pStream
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
382 return DMUS_E_INVALIDFILE
;
386 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc
));
391 IDirectMusicObjectVtbl DirectMusicScript_Object_Vtbl
= {
392 IDirectMusicScriptImpl_IDirectMusicObject_QueryInterface
,
393 IDirectMusicScriptImpl_IDirectMusicObject_AddRef
,
394 IDirectMusicScriptImpl_IDirectMusicObject_Release
,
395 IDirectMusicScriptImpl_IDirectMusicObject_GetDescriptor
,
396 IDirectMusicScriptImpl_IDirectMusicObject_SetDescriptor
,
397 IDirectMusicScriptImpl_IDirectMusicObject_ParseDescriptor
400 /* IDirectMusicScriptImpl IPersistStream part: */
401 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface
, REFIID riid
, LPVOID
*ppobj
) {
402 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
403 return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&This
->UnknownVtbl
, riid
, ppobj
);
406 ULONG WINAPI
IDirectMusicScriptImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface
) {
407 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
408 return IDirectMusicScriptImpl_IUnknown_AddRef ((LPUNKNOWN
)&This
->UnknownVtbl
);
411 ULONG WINAPI
IDirectMusicScriptImpl_IPersistStream_Release (LPPERSISTSTREAM iface
) {
412 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
413 return IDirectMusicScriptImpl_IUnknown_Release ((LPUNKNOWN
)&This
->UnknownVtbl
);
416 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface
, CLSID
* pClassID
) {
417 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
418 TRACE("(%p, %p)\n", This
, pClassID
);
419 memcpy(pClassID
, &CLSID_DirectMusicScript
, sizeof(CLSID
));
423 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface
) {
424 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
425 FIXME("(%p): stub, always S_FALSE\n", This
);
429 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_Load (LPPERSISTSTREAM iface
, IStream
* pStm
) {
430 ICOM_THIS_MULTI(IDirectMusicScriptImpl
, PersistStreamVtbl
, iface
);
432 DMUS_PRIVATE_CHUNK Chunk
;
433 DWORD StreamSize
, StreamCount
, ListSize
[3], ListCount
[3];
434 LARGE_INTEGER liMove
; /* used when skipping chunks */
435 LPDIRECTMUSICGETLOADER pGetLoader
= NULL
;
436 LPDIRECTMUSICLOADER pLoader
= NULL
;
438 FIXME("(%p, %p): Loading not implemented yet\n", This
, pStm
);
439 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
440 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
441 switch (Chunk
.fccID
) {
443 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
444 TRACE_(dmfile
)(": RIFF chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
445 StreamSize
= Chunk
.dwSize
- sizeof(FOURCC
);
447 switch (Chunk
.fccID
) {
448 case DMUS_FOURCC_SCRIPT_FORM
: {
449 TRACE_(dmfile
)(": script form\n");
451 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
452 StreamCount
+= sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
453 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
454 switch (Chunk
.fccID
) {
455 case DMUS_FOURCC_SCRIPT_CHUNK
: {
456 TRACE_(dmfile
)(": script header chunk\n");
457 This
->pHeader
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
458 IStream_Read (pStm
, This
->pHeader
, Chunk
.dwSize
, NULL
);
461 case DMUS_FOURCC_SCRIPTVERSION_CHUNK
: {
462 TRACE_(dmfile
)(": script version chunk\n");
463 This
->pVersion
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
464 IStream_Read (pStm
, This
->pVersion
, Chunk
.dwSize
, NULL
);
465 TRACE_(dmfile
)("version: 0x%08lx.0x%08lx \n", This
->pVersion
->dwVersionMS
, This
->pVersion
->dwVersionLS
);
468 case DMUS_FOURCC_SCRIPTLANGUAGE_CHUNK
: {
469 TRACE_(dmfile
)(": script language chunk\n");
470 This
->pwzLanguage
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
471 IStream_Read (pStm
, This
->pwzLanguage
, Chunk
.dwSize
, NULL
);
472 TRACE_(dmfile
)("using language: %s \n", debugstr_w(This
->pwzLanguage
));
475 case DMUS_FOURCC_SCRIPTSOURCE_CHUNK
: {
476 TRACE_(dmfile
)(": script source chunk\n");
477 This
->pwzSource
= HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY
, Chunk
.dwSize
);
478 IStream_Read (pStm
, This
->pwzSource
, Chunk
.dwSize
, NULL
);
479 if (TRACE_ON(dmscript
)) {
480 int count
= WideCharToMultiByte(CP_ACP
, 0, This
->pwzSource
, -1, NULL
, 0, NULL
, NULL
);
481 LPSTR str
= HeapAlloc(GetProcessHeap (), 0, count
);
482 WideCharToMultiByte(CP_ACP
, 0, This
->pwzSource
, -1, str
, count
, NULL
, NULL
);
485 write( 2, str
, count
);
486 HeapFree(GetProcessHeap(), 0, str
);
490 case DMUS_FOURCC_GUID_CHUNK
: {
491 TRACE_(dmfile
)(": GUID chunk\n");
492 This
->pDesc
->dwValidData
|= DMUS_OBJ_OBJECT
;
493 IStream_Read (pStm
, &This
->pDesc
->guidObject
, Chunk
.dwSize
, NULL
);
496 case DMUS_FOURCC_VERSION_CHUNK
: {
497 TRACE_(dmfile
)(": version chunk\n");
498 This
->pDesc
->dwValidData
|= DMUS_OBJ_VERSION
;
499 IStream_Read (pStm
, &This
->pDesc
->vVersion
, Chunk
.dwSize
, NULL
);
502 case DMUS_FOURCC_CATEGORY_CHUNK
: {
503 TRACE_(dmfile
)(": category chunk\n");
504 This
->pDesc
->dwValidData
|= DMUS_OBJ_CATEGORY
;
505 IStream_Read (pStm
, This
->pDesc
->wszCategory
, Chunk
.dwSize
, NULL
);
509 IDirectMusicObject
* pObject
= NULL
;
510 DMUS_OBJECTDESC desc
;
512 ZeroMemory ((LPVOID
)&desc
, sizeof(DMUS_OBJECTDESC
));
513 desc
.dwSize
= sizeof(DMUS_OBJECTDESC
);
514 desc
.dwValidData
= DMUS_OBJ_STREAM
| DMUS_OBJ_CLASS
;
515 desc
.guidClass
= CLSID_DirectMusicContainer
;
517 IStream_Clone (pStm
, &desc
.pStream
);
520 liMove
.QuadPart
-= (sizeof(FOURCC
) + sizeof(DWORD
));
521 IStream_Seek (desc
.pStream
, liMove
, STREAM_SEEK_CUR
, NULL
);
523 IStream_QueryInterface (pStm
, &IID_IDirectMusicGetLoader
, (LPVOID
*)&pGetLoader
);
524 IDirectMusicGetLoader_GetLoader (pGetLoader
, &pLoader
);
525 IDirectMusicGetLoader_Release (pGetLoader
);
527 if (SUCCEEDED(IDirectMusicLoader_GetObject (pLoader
, &desc
, &IID_IDirectMusicObject
, (LPVOID
*) &pObject
))) {
528 IDirectMusicObject_Release (pObject
);
530 ERR_(dmfile
)("Error on GetObject while trying to load Scrip SubContainer\n");
533 IDirectMusicLoader_Release (pLoader
); pLoader
= NULL
; /* release loader */
534 IStream_Release(desc
.pStream
); desc
.pStream
= NULL
; /* release cloned stream */
536 liMove
.QuadPart
= Chunk
.dwSize
;
537 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
539 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
540 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
541 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
544 switch (Chunk.fccID) {
546 TRACE_(dmfile)(": unknown (skipping)\n");
547 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
548 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
556 IStream_Read (pStm
, &Chunk
.fccID
, sizeof(FOURCC
), NULL
);
557 TRACE_(dmfile
)(": LIST chunk of type %s", debugstr_fourcc(Chunk
.fccID
));
558 ListSize
[0] = Chunk
.dwSize
- sizeof(FOURCC
);
560 switch (Chunk
.fccID
) {
561 case DMUS_FOURCC_UNFO_LIST
: {
562 TRACE_(dmfile
)(": UNFO list\n");
564 IStream_Read (pStm
, &Chunk
, sizeof(FOURCC
)+sizeof(DWORD
), NULL
);
565 ListCount
[0] += sizeof(FOURCC
) + sizeof(DWORD
) + Chunk
.dwSize
;
566 TRACE_(dmfile
)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk
.fccID
), Chunk
.dwSize
);
567 switch (Chunk
.fccID
) {
568 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
569 (though strings seem to be valid unicode) */
570 case mmioFOURCC('I','N','A','M'):
571 case DMUS_FOURCC_UNAM_CHUNK
: {
572 TRACE_(dmfile
)(": name chunk\n");
573 This
->pDesc
->dwValidData
|= DMUS_OBJ_NAME
;
574 IStream_Read (pStm
, This
->pDesc
->wszName
, Chunk
.dwSize
, NULL
);
577 case mmioFOURCC('I','A','R','T'):
578 case DMUS_FOURCC_UART_CHUNK
: {
579 TRACE_(dmfile
)(": artist chunk (ignored)\n");
580 liMove
.QuadPart
= Chunk
.dwSize
;
581 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
584 case mmioFOURCC('I','C','O','P'):
585 case DMUS_FOURCC_UCOP_CHUNK
: {
586 TRACE_(dmfile
)(": copyright chunk (ignored)\n");
587 liMove
.QuadPart
= Chunk
.dwSize
;
588 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
591 case mmioFOURCC('I','S','B','J'):
592 case DMUS_FOURCC_USBJ_CHUNK
: {
593 TRACE_(dmfile
)(": subject chunk (ignored)\n");
594 liMove
.QuadPart
= Chunk
.dwSize
;
595 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
598 case mmioFOURCC('I','C','M','T'):
599 case DMUS_FOURCC_UCMT_CHUNK
: {
600 TRACE_(dmfile
)(": comment chunk (ignored)\n");
601 liMove
.QuadPart
= Chunk
.dwSize
;
602 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
606 TRACE_(dmfile
)(": unknown sub-chunk (irrevelant & skipping)\n");
607 liMove
.QuadPart
= Chunk
.dwSize
;
608 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
612 TRACE_(dmfile
)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount
[0], ListSize
[0]);
613 } while (ListCount
[0] < ListSize
[0]);
617 TRACE_(dmfile
)(": unknown (skipping)\n");
618 liMove
.QuadPart
= Chunk
.dwSize
- sizeof(FOURCC
);
619 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
626 TRACE_(dmfile
)(": unknown chunk (irrevelant & skipping)\n");
627 liMove
.QuadPart
= Chunk
.dwSize
;
628 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
);
632 TRACE_(dmfile
)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount
, StreamSize
);
633 } while (StreamCount
< StreamSize
);
637 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
638 liMove
.QuadPart
= StreamSize
;
639 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
643 TRACE_(dmfile
)(": reading finished\n");
647 TRACE_(dmfile
)(": unexpected chunk; loading failed)\n");
648 liMove
.QuadPart
= Chunk
.dwSize
;
649 IStream_Seek (pStm
, liMove
, STREAM_SEEK_CUR
, NULL
); /* skip the rest of the chunk */
657 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_Save (LPPERSISTSTREAM iface
, IStream
* pStm
, BOOL fClearDirty
) {
661 HRESULT WINAPI
IDirectMusicScriptImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface
, ULARGE_INTEGER
* pcbSize
) {
665 IPersistStreamVtbl DirectMusicScript_PersistStream_Vtbl
= {
666 IDirectMusicScriptImpl_IPersistStream_QueryInterface
,
667 IDirectMusicScriptImpl_IPersistStream_AddRef
,
668 IDirectMusicScriptImpl_IPersistStream_Release
,
669 IDirectMusicScriptImpl_IPersistStream_GetClassID
,
670 IDirectMusicScriptImpl_IPersistStream_IsDirty
,
671 IDirectMusicScriptImpl_IPersistStream_Load
,
672 IDirectMusicScriptImpl_IPersistStream_Save
,
673 IDirectMusicScriptImpl_IPersistStream_GetSizeMax
676 /* for ClassFactory */
677 HRESULT WINAPI
DMUSIC_CreateDirectMusicScriptImpl (LPCGUID lpcGUID
, LPVOID
* ppobj
, LPUNKNOWN pUnkOuter
) {
678 IDirectMusicScriptImpl
* obj
;
680 obj
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirectMusicScriptImpl
));
682 *ppobj
= (LPVOID
) NULL
;
683 return E_OUTOFMEMORY
;
685 obj
->UnknownVtbl
= &DirectMusicScript_Unknown_Vtbl
;
686 obj
->ScriptVtbl
= &DirectMusicScript_Script_Vtbl
;
687 obj
->ObjectVtbl
= &DirectMusicScript_Object_Vtbl
;
688 obj
->PersistStreamVtbl
= &DirectMusicScript_PersistStream_Vtbl
;
689 obj
->pDesc
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(DMUS_OBJECTDESC
));
690 DM_STRUCT_INIT(obj
->pDesc
);
691 obj
->pDesc
->dwValidData
|= DMUS_OBJ_CLASS
;
692 memcpy (&obj
->pDesc
->guidClass
, &CLSID_DirectMusicScript
, sizeof (CLSID
));
693 obj
->ref
= 0; /* will be inited by QueryInterface */
695 return IDirectMusicScriptImpl_IUnknown_QueryInterface ((LPUNKNOWN
)&obj
->UnknownVtbl
, lpcGUID
, ppobj
);