1 /* IDirectMusicWave Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "dswave_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dswave);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
25 /* an interface that is, according to my tests, obtained by loader after loading object; is it acting
26 as some sort of bridge between object and loader? */
27 static const GUID IID_IDirectMusicWavePRIVATE = {0x69e934e4,0x97f1,0x4f1d,{0x88,0xe8,0xf2,0xac,0x88,0x67,0x13,0x27}};
29 /*****************************************************************************
30 * IDirectMusicWaveImpl implementation
32 /* IDirectMusicWaveImpl IUnknown part: */
33 HRESULT WINAPI IDirectMusicWaveImpl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
34 ICOM_THIS_MULTI(IDirectMusicWaveImpl, UnknownVtbl, iface);
36 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
38 if (IsEqualIID (riid, &IID_IUnknown)) {
39 *ppobj = (LPVOID)&This->UnknownVtbl;
40 IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
42 } else if (IsEqualIID (riid, &IID_IDirectMusicSegment)
43 || IsEqualIID (riid, &IID_IDirectMusicSegment2)
44 || IsEqualIID (riid, &IID_IDirectMusicSegment8)) {
45 *ppobj = (LPVOID)&This->SegmentVtbl;
46 IDirectMusicWaveImpl_IDirectMusicSegment8_AddRef ((LPDIRECTMUSICSEGMENT8)&This->SegmentVtbl);
48 } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) {
49 *ppobj = (LPVOID)&This->ObjectVtbl;
50 IDirectMusicWaveImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT)&This->ObjectVtbl);
52 } else if (IsEqualIID (riid, &IID_IPersistStream)) {
53 *ppobj = (LPVOID)&This->PersistStreamVtbl;
54 IDirectMusicWaveImpl_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl);
56 } else if (IsEqualIID (riid, &IID_IDirectMusicWavePRIVATE)) {
57 WARN(": requested private interface, expect crash\n");
61 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
65 ULONG WINAPI IDirectMusicWaveImpl_IUnknown_AddRef (LPUNKNOWN iface) {
66 ICOM_THIS_MULTI(IDirectMusicWaveImpl, UnknownVtbl, iface);
67 ULONG refCount = InterlockedIncrement(&This->ref);
69 TRACE("(%p)->(ref before=%lu)\n", This, refCount - 1);
76 ULONG WINAPI IDirectMusicWaveImpl_IUnknown_Release (LPUNKNOWN iface) {
77 ICOM_THIS_MULTI(IDirectMusicWaveImpl, UnknownVtbl, iface);
78 ULONG refCount = InterlockedDecrement(&This->ref);
80 TRACE("(%p)->(ref before=%lu)\n", This, refCount + 1);
83 HeapFree(GetProcessHeap(), 0, This);
86 DSWAVE_UnlockModule();
91 static const IUnknownVtbl DirectMusicWave_Unknown_Vtbl = {
92 IDirectMusicWaveImpl_IUnknown_QueryInterface,
93 IDirectMusicWaveImpl_IUnknown_AddRef,
94 IDirectMusicWaveImpl_IUnknown_Release
97 /* IDirectMusicSegment8Impl IDirectMusicSegment part: */
98 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_QueryInterface (LPDIRECTMUSICSEGMENT8 iface, REFIID riid, LPVOID *ppobj) {
99 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
100 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
103 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_AddRef (LPDIRECTMUSICSEGMENT8 iface) {
104 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
105 return IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
108 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Release (LPDIRECTMUSICSEGMENT8 iface) {
109 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
110 return IDirectMusicWaveImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
113 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtLength) {
114 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
115 FIXME("(%p, %p): stub\n", This, pmtLength);
119 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtLength) {
120 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
121 FIXME("(%p, %ld): stub\n", This, mtLength);
125 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwRepeats) {
126 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
127 FIXME("(%p, %p): stub\n", This, pdwRepeats);
131 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD dwRepeats) {
132 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
133 FIXME("(%p, %ld): stub\n", This, dwRepeats);
137 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwResolution) {
138 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
139 FIXME("(%p, %p): stub\n", This, pdwResolution);
143 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD dwResolution) {
144 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
145 FIXME("(%p, %ld): stub\n", This, dwResolution);
149 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrack (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, IDirectMusicTrack** ppTrack) {
150 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
151 FIXME("(%p, %s, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, ppTrack);
155 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrackGroup (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD* pdwGroupBits) {
156 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
157 FIXME("(%p, %p, %p): stub\n", This, pTrack, pdwGroupBits);
161 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits) {
162 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
163 FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
167 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack) {
168 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
169 FIXME("(%p, %p): stub\n", This, pTrack);
173 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags) {
174 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
175 FIXME("(%p, %p, %p, %ld): stub\n", This, ppSegState, pPerformance, dwFlags);
179 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph** ppGraph) {
180 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
181 FIXME("(%p, %p): stub\n", This, ppGraph);
185 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph* pGraph) {
186 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
187 FIXME("(%p, %p): stub\n", This, pGraph);
191 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_AddNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType) {
192 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
193 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
197 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType) {
198 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
199 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
203 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam) {
204 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
205 FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
209 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam) {
210 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
211 FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
215 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Clone (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicSegment** ppSegment) {
216 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
217 FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppSegment);
221 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart) {
222 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
223 FIXME("(%p, %ld): stub\n", This, mtStart);
227 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart) {
228 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
229 FIXME("(%p, %p): stub\n", This, pmtStart);
233 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd) {
234 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
235 FIXME("(%p, %ld, %ld): stub\n", This, mtStart, mtEnd);
239 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart, MUSIC_TIME* pmtEnd) {
240 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
241 FIXME("(%p, %p, %p): stub\n", This, pmtStart, pmtEnd);
245 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetPChannelsUsed (LPDIRECTMUSICSEGMENT8 iface, DWORD dwNumPChannels, DWORD* paPChannels) {
246 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
247 FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);
251 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetTrackConfig (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff) {
252 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
253 FIXME("(%p, %s, %ld, %ld, %ld, %ld): stub\n", This, debugstr_dmguid(rguidTrackClassID), dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
257 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetAudioPathConfig (LPDIRECTMUSICSEGMENT8 iface, IUnknown** ppAudioPathConfig){
258 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
259 FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
263 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Compose (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtTime, IDirectMusicSegment* pFromSegment, IDirectMusicSegment* pToSegment, IDirectMusicSegment** ppComposedSegment) {
264 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
265 FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
269 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Download (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath) {
270 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
271 FIXME("(%p, %p): stub\n", This, pAudioPath);
275 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Unload (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath) {
276 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
277 FIXME("(%p, %p): stub\n", This, pAudioPath);
281 static const IDirectMusicSegment8Vtbl DirectMusicSegment8_Segment_Vtbl = {
282 IDirectMusicWaveImpl_IDirectMusicSegment8_QueryInterface,
283 IDirectMusicWaveImpl_IDirectMusicSegment8_AddRef,
284 IDirectMusicWaveImpl_IDirectMusicSegment8_Release,
285 IDirectMusicWaveImpl_IDirectMusicSegment8_GetLength,
286 IDirectMusicWaveImpl_IDirectMusicSegment8_SetLength,
287 IDirectMusicWaveImpl_IDirectMusicSegment8_GetRepeats,
288 IDirectMusicWaveImpl_IDirectMusicSegment8_SetRepeats,
289 IDirectMusicWaveImpl_IDirectMusicSegment8_GetDefaultResolution,
290 IDirectMusicWaveImpl_IDirectMusicSegment8_SetDefaultResolution,
291 IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrack,
292 IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrackGroup,
293 IDirectMusicWaveImpl_IDirectMusicSegment8_InsertTrack,
294 IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveTrack,
295 IDirectMusicWaveImpl_IDirectMusicSegment8_InitPlay,
296 IDirectMusicWaveImpl_IDirectMusicSegment8_GetGraph,
297 IDirectMusicWaveImpl_IDirectMusicSegment8_SetGraph,
298 IDirectMusicWaveImpl_IDirectMusicSegment8_AddNotificationType,
299 IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveNotificationType,
300 IDirectMusicWaveImpl_IDirectMusicSegment8_GetParam,
301 IDirectMusicWaveImpl_IDirectMusicSegment8_SetParam,
302 IDirectMusicWaveImpl_IDirectMusicSegment8_Clone,
303 IDirectMusicWaveImpl_IDirectMusicSegment8_SetStartPoint,
304 IDirectMusicWaveImpl_IDirectMusicSegment8_GetStartPoint,
305 IDirectMusicWaveImpl_IDirectMusicSegment8_SetLoopPoints,
306 IDirectMusicWaveImpl_IDirectMusicSegment8_GetLoopPoints,
307 IDirectMusicWaveImpl_IDirectMusicSegment8_SetPChannelsUsed,
308 IDirectMusicWaveImpl_IDirectMusicSegment8_SetTrackConfig,
309 IDirectMusicWaveImpl_IDirectMusicSegment8_GetAudioPathConfig,
310 IDirectMusicWaveImpl_IDirectMusicSegment8_Compose,
311 IDirectMusicWaveImpl_IDirectMusicSegment8_Download,
312 IDirectMusicWaveImpl_IDirectMusicSegment8_Unload
315 /* IDirectMusicWaveImpl IDirectMusicObject part: */
316 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
317 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
318 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
321 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
322 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
323 return IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
326 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
327 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
328 return IDirectMusicWaveImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
331 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
332 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
333 TRACE("(%p, %p)\n", This, pDesc);
334 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
335 memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
339 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
340 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
341 TRACE("(%p, %p, %s): setting descriptor:\n", This, pDesc, debugstr_DMUS_OBJECTDESC(pDesc));
343 /* According to MSDN, we should copy only given values, not whole struct */
344 if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
345 memcpy (&This->pDesc->guidObject, &pDesc->guidObject, sizeof (pDesc->guidObject));
346 if (pDesc->dwValidData & DMUS_OBJ_CLASS)
347 memcpy (&This->pDesc->guidClass, &pDesc->guidClass, sizeof (pDesc->guidClass));
348 if (pDesc->dwValidData & DMUS_OBJ_NAME)
349 lstrcpynW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
350 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
351 lstrcpynW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
352 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
353 lstrcpynW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
354 if (pDesc->dwValidData & DMUS_OBJ_VERSION)
355 memcpy (&This->pDesc->vVersion, &pDesc->vVersion, sizeof (pDesc->vVersion));
356 if (pDesc->dwValidData & DMUS_OBJ_DATE)
357 memcpy (&This->pDesc->ftDate, &pDesc->ftDate, sizeof (pDesc->ftDate));
358 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
359 memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength));
360 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData));
362 if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
363 /* according to MSDN, we copy the stream */
364 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
368 This->pDesc->dwValidData |= pDesc->dwValidData;
373 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
374 DMUS_PRIVATE_CHUNK Chunk;
375 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
376 LARGE_INTEGER liMove; /* used when skipping chunks */
378 TRACE("(%p, %p)\n", pStream, pDesc);
380 /* FIXME: should this be determined from stream? */
381 pDesc->dwValidData |= DMUS_OBJ_CLASS;
382 memcpy (&pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof(CLSID));
384 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
385 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
386 switch (Chunk.fccID) {
388 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
389 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
390 StreamSize = Chunk.dwSize - sizeof(FOURCC);
392 if (Chunk.fccID == mmioFOURCC('W','A','V','E')) {
393 TRACE_(dmfile)(": wave form\n");
395 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
396 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
397 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
398 switch (Chunk.fccID) {
399 case DMUS_FOURCC_GUID_CHUNK: {
400 TRACE_(dmfile)(": GUID chunk\n");
401 pDesc->dwValidData |= DMUS_OBJ_OBJECT;
402 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
405 case DMUS_FOURCC_VERSION_CHUNK: {
406 TRACE_(dmfile)(": version chunk\n");
407 pDesc->dwValidData |= DMUS_OBJ_VERSION;
408 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
411 case DMUS_FOURCC_CATEGORY_CHUNK: {
412 TRACE_(dmfile)(": category chunk\n");
413 pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
414 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
418 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
419 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
420 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
422 switch (Chunk.fccID) {
423 /* evil M$ UNFO list, which can (!?) contain INFO elements */
424 case DMUS_FOURCC_UNFO_LIST: {
425 TRACE_(dmfile)(": UNFO list\n");
427 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
428 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
429 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
430 switch (Chunk.fccID) {
431 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
432 (though strings seem to be valid unicode) */
433 case mmioFOURCC('I','N','A','M'):
434 case DMUS_FOURCC_UNAM_CHUNK: {
435 TRACE_(dmfile)(": name chunk\n");
436 pDesc->dwValidData |= DMUS_OBJ_NAME;
437 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
440 case mmioFOURCC('I','A','R','T'):
441 case DMUS_FOURCC_UART_CHUNK: {
442 TRACE_(dmfile)(": artist chunk (ignored)\n");
443 liMove.QuadPart = Chunk.dwSize;
444 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
447 case mmioFOURCC('I','C','O','P'):
448 case DMUS_FOURCC_UCOP_CHUNK: {
449 TRACE_(dmfile)(": copyright chunk (ignored)\n");
450 liMove.QuadPart = Chunk.dwSize;
451 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
454 case mmioFOURCC('I','S','B','J'):
455 case DMUS_FOURCC_USBJ_CHUNK: {
456 TRACE_(dmfile)(": subject chunk (ignored)\n");
457 liMove.QuadPart = Chunk.dwSize;
458 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
461 case mmioFOURCC('I','C','M','T'):
462 case DMUS_FOURCC_UCMT_CHUNK: {
463 TRACE_(dmfile)(": comment chunk (ignored)\n");
464 liMove.QuadPart = Chunk.dwSize;
465 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
469 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
470 liMove.QuadPart = Chunk.dwSize;
471 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
475 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
476 } while (ListCount[0] < ListSize[0]);
480 TRACE_(dmfile)(": unknown (skipping)\n");
481 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
482 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
489 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
490 liMove.QuadPart = Chunk.dwSize;
491 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
495 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
496 } while (StreamCount < StreamSize);
498 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
499 liMove.QuadPart = StreamSize;
500 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
504 TRACE_(dmfile)(": reading finished\n");
508 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
509 liMove.QuadPart = Chunk.dwSize;
510 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
511 return DMUS_E_INVALIDFILE;
515 TRACE(": returning descriptor: %s\n", debugstr_DMUS_OBJECTDESC (pDesc));
520 static const IDirectMusicObjectVtbl DirectMusicWave_Object_Vtbl = {
521 IDirectMusicWaveImpl_IDirectMusicObject_QueryInterface,
522 IDirectMusicWaveImpl_IDirectMusicObject_AddRef,
523 IDirectMusicWaveImpl_IDirectMusicObject_Release,
524 IDirectMusicWaveImpl_IDirectMusicObject_GetDescriptor,
525 IDirectMusicWaveImpl_IDirectMusicObject_SetDescriptor,
526 IDirectMusicWaveImpl_IDirectMusicObject_ParseDescriptor
529 /* IDirectMusicWaveImpl IPersistStream part: */
530 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
531 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
532 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
535 ULONG WINAPI IDirectMusicWaveImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
536 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
537 return IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
540 ULONG WINAPI IDirectMusicWaveImpl_IPersistStream_Release (LPPERSISTSTREAM iface) {
541 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
542 return IDirectMusicWaveImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
545 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
549 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
553 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
554 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
556 DMUS_PRIVATE_CHUNK Chunk;
557 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
558 LARGE_INTEGER liMove; /* used when skipping chunks */
560 FIXME("(%p, %p): loading not implemented yet (only descriptor is loaded)\n", This, pStm);
562 /* FIXME: should this be determined from stream? */
563 This->pDesc->dwValidData |= DMUS_OBJ_CLASS;
564 memcpy (&This->pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof(CLSID));
566 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
567 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
568 switch (Chunk.fccID) {
570 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
571 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
572 StreamSize = Chunk.dwSize - sizeof(FOURCC);
574 if (Chunk.fccID == mmioFOURCC('W','A','V','E')) {
575 TRACE_(dmfile)(": wave form\n");
577 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
578 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
579 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
580 switch (Chunk.fccID) {
581 case DMUS_FOURCC_GUID_CHUNK: {
582 TRACE_(dmfile)(": GUID chunk\n");
583 This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
584 IStream_Read (pStm, &This->pDesc->guidObject, Chunk.dwSize, NULL);
587 case DMUS_FOURCC_VERSION_CHUNK: {
588 TRACE_(dmfile)(": version chunk\n");
589 This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
590 IStream_Read (pStm, &This->pDesc->vVersion, Chunk.dwSize, NULL);
593 case DMUS_FOURCC_CATEGORY_CHUNK: {
594 TRACE_(dmfile)(": category chunk\n");
595 This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
596 IStream_Read (pStm, This->pDesc->wszCategory, Chunk.dwSize, NULL);
600 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
601 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
602 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
604 switch (Chunk.fccID) {
605 /* evil M$ UNFO list, which can (!?) contain INFO elements */
606 case DMUS_FOURCC_UNFO_LIST: {
607 TRACE_(dmfile)(": UNFO list\n");
609 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
610 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
611 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
612 switch (Chunk.fccID) {
613 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
614 (though strings seem to be valid unicode) */
615 case mmioFOURCC('I','N','A','M'):
616 case DMUS_FOURCC_UNAM_CHUNK: {
617 TRACE_(dmfile)(": name chunk\n");
618 This->pDesc->dwValidData |= DMUS_OBJ_NAME;
619 IStream_Read (pStm, This->pDesc->wszName, Chunk.dwSize, NULL);
622 case mmioFOURCC('I','A','R','T'):
623 case DMUS_FOURCC_UART_CHUNK: {
624 TRACE_(dmfile)(": artist chunk (ignored)\n");
625 liMove.QuadPart = Chunk.dwSize;
626 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
629 case mmioFOURCC('I','C','O','P'):
630 case DMUS_FOURCC_UCOP_CHUNK: {
631 TRACE_(dmfile)(": copyright chunk (ignored)\n");
632 liMove.QuadPart = Chunk.dwSize;
633 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
636 case mmioFOURCC('I','S','B','J'):
637 case DMUS_FOURCC_USBJ_CHUNK: {
638 TRACE_(dmfile)(": subject chunk (ignored)\n");
639 liMove.QuadPart = Chunk.dwSize;
640 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
643 case mmioFOURCC('I','C','M','T'):
644 case DMUS_FOURCC_UCMT_CHUNK: {
645 TRACE_(dmfile)(": comment chunk (ignored)\n");
646 liMove.QuadPart = Chunk.dwSize;
647 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
651 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
652 liMove.QuadPart = Chunk.dwSize;
653 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
657 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
658 } while (ListCount[0] < ListSize[0]);
662 TRACE_(dmfile)(": unknown (skipping)\n");
663 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
664 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
671 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
672 liMove.QuadPart = Chunk.dwSize;
673 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
677 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
678 } while (StreamCount < StreamSize);
680 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
681 liMove.QuadPart = StreamSize;
682 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
686 TRACE_(dmfile)(": reading finished\n");
690 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
691 liMove.QuadPart = Chunk.dwSize;
692 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
693 return DMUS_E_INVALIDFILE;
700 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
704 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
708 static const IPersistStreamVtbl DirectMusicWave_PersistStream_Vtbl = {
709 IDirectMusicWaveImpl_IPersistStream_QueryInterface,
710 IDirectMusicWaveImpl_IPersistStream_AddRef,
711 IDirectMusicWaveImpl_IPersistStream_Release,
712 IDirectMusicWaveImpl_IPersistStream_GetClassID,
713 IDirectMusicWaveImpl_IPersistStream_IsDirty,
714 IDirectMusicWaveImpl_IPersistStream_Load,
715 IDirectMusicWaveImpl_IPersistStream_Save,
716 IDirectMusicWaveImpl_IPersistStream_GetSizeMax
720 /* for ClassFactory */
721 HRESULT WINAPI DMUSIC_CreateDirectMusicWaveImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) {
722 IDirectMusicWaveImpl* obj;
724 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicWaveImpl));
727 return E_OUTOFMEMORY;
729 obj->UnknownVtbl = &DirectMusicWave_Unknown_Vtbl;
730 obj->ObjectVtbl = &DirectMusicWave_Object_Vtbl;
731 obj->PersistStreamVtbl = &DirectMusicWave_PersistStream_Vtbl;
732 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
733 DM_STRUCT_INIT(obj->pDesc);
734 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
735 memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof (CLSID)); /* shown by tests */
736 obj->ref = 0; /* will be inited by QueryInterface */
738 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);