- Applied to all MCI drivers Dmitry's fix for MCI_STATUS_TIME_FORMAT
[wine.git] / dlls / dmime / segment.c
blob39d63262e10b10f85e433035294defa6b3ab70f6
1 /* IDirectMusicSegment8 Implementation
3 * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include <stdarg.h>
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winuser.h"
25 #include "wingdi.h"
26 #include "wine/debug.h"
28 #include "dmime_private.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
31 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
33 /*****************************************************************************
34 * IDirectMusicSegment8Impl implementation
36 /* IDirectMusicSegment8 IUnknown part: */
37 HRESULT WINAPI IDirectMusicSegment8Impl_QueryInterface (LPDIRECTMUSICSEGMENT8 iface, REFIID riid, LPVOID *ppobj)
39 ICOM_THIS(IDirectMusicSegment8Impl,iface);
41 if (IsEqualIID (riid, &IID_IUnknown) ||
42 IsEqualIID (riid, &IID_IDirectMusicSegment) ||
43 IsEqualIID (riid, &IID_IDirectMusicSegment8)) {
44 IDirectMusicSegment8Impl_AddRef(iface);
45 *ppobj = This;
46 return S_OK;
49 WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
50 return E_NOINTERFACE;
53 ULONG WINAPI IDirectMusicSegment8Impl_AddRef (LPDIRECTMUSICSEGMENT8 iface)
55 ICOM_THIS(IDirectMusicSegment8Impl,iface);
56 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
57 return ++(This->ref);
60 ULONG WINAPI IDirectMusicSegment8Impl_Release (LPDIRECTMUSICSEGMENT8 iface)
62 ICOM_THIS(IDirectMusicSegment8Impl,iface);
63 ULONG ref = --This->ref;
64 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
65 if (ref == 0) {
66 HeapFree(GetProcessHeap(), 0, This);
68 return ref;
71 /* IDirectMusicSegment8 IDirectMusicSegment part: */
72 HRESULT WINAPI IDirectMusicSegment8Impl_GetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtLength)
74 ICOM_THIS(IDirectMusicSegment8Impl,iface);
76 TRACE("(%p, %p)\n", This, pmtLength);
77 *pmtLength = This->segHeader.mtLength;
79 return S_OK;
82 HRESULT WINAPI IDirectMusicSegment8Impl_SetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtLength)
84 ICOM_THIS(IDirectMusicSegment8Impl,iface);
86 TRACE("(%p, %ld)\n", This, mtLength);
87 This->segHeader.mtLength = mtLength;
89 return S_OK;
92 HRESULT WINAPI IDirectMusicSegment8Impl_GetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwRepeats)
94 ICOM_THIS(IDirectMusicSegment8Impl,iface);
96 TRACE("(%p, %p)\n", This, pdwRepeats);
97 *pdwRepeats = This->segHeader.dwRepeats;
99 return S_OK;
102 HRESULT WINAPI IDirectMusicSegment8Impl_SetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD dwRepeats)
104 ICOM_THIS(IDirectMusicSegment8Impl,iface);
106 TRACE("(%p, %ld)\n", This, dwRepeats);
107 This->segHeader.dwRepeats = dwRepeats;
109 return S_OK;
112 HRESULT WINAPI IDirectMusicSegment8Impl_GetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwResolution)
114 ICOM_THIS(IDirectMusicSegment8Impl,iface);
116 TRACE("(%p, %p)\n", This, pdwResolution);
117 *pdwResolution = This->segHeader.dwResolution;
119 return S_OK;
122 HRESULT WINAPI IDirectMusicSegment8Impl_SetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD dwResolution)
124 ICOM_THIS(IDirectMusicSegment8Impl,iface);
126 TRACE("(%p, %ld)\n", This, dwResolution);
127 This->segHeader.dwResolution = dwResolution;
129 return S_OK;
132 HRESULT WINAPI IDirectMusicSegment8Impl_GetTrack (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, IDirectMusicTrack** ppTrack)
134 ICOM_THIS(IDirectMusicSegment8Impl,iface);
136 FIXME("(%p, %s, %ld, %ld, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, ppTrack);
138 return S_OK;
141 HRESULT WINAPI IDirectMusicSegment8Impl_GetTrackGroup (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD* pdwGroupBits)
143 ICOM_THIS(IDirectMusicSegment8Impl,iface);
145 FIXME("(%p, %p, %p): stub\n", This, pTrack, pdwGroupBits);
147 return S_OK;
150 HRESULT WINAPI IDirectMusicSegment8Impl_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits)
152 ICOM_THIS(IDirectMusicSegment8Impl,iface);
154 FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
156 return S_OK;
159 HRESULT WINAPI IDirectMusicSegment8Impl_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack)
161 ICOM_THIS(IDirectMusicSegment8Impl,iface);
163 FIXME("(%p, %p): stub\n", This, pTrack);
165 return S_OK;
168 HRESULT WINAPI IDirectMusicSegment8Impl_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags)
170 ICOM_THIS(IDirectMusicSegment8Impl,iface);
172 FIXME("(%p, %p, %p, %ld): stub\n", This, ppSegState, pPerformance, dwFlags);
174 return S_OK;
177 HRESULT WINAPI IDirectMusicSegment8Impl_GetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph** ppGraph)
179 ICOM_THIS(IDirectMusicSegment8Impl,iface);
181 FIXME("(%p, %p): stub\n", This, ppGraph);
183 return S_OK;
186 HRESULT WINAPI IDirectMusicSegment8Impl_SetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph* pGraph)
188 ICOM_THIS(IDirectMusicSegment8Impl,iface);
190 FIXME("(%p, %p): stub\n", This, pGraph);
192 return S_OK;
195 HRESULT WINAPI IDirectMusicSegment8Impl_AddNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType)
197 ICOM_THIS(IDirectMusicSegment8Impl,iface);
199 FIXME("(%p, %s): stub\n", This, debugstr_guid(rguidNotificationType));
201 return S_OK;
204 HRESULT WINAPI IDirectMusicSegment8Impl_RemoveNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType)
206 ICOM_THIS(IDirectMusicSegment8Impl,iface);
208 FIXME("(%p, %s): stub\n", This, debugstr_guid(rguidNotificationType));
210 return S_OK;
213 HRESULT WINAPI IDirectMusicSegment8Impl_GetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam)
215 ICOM_THIS(IDirectMusicSegment8Impl,iface);
217 FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
219 return S_OK;
222 HRESULT WINAPI IDirectMusicSegment8Impl_SetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam)
224 ICOM_THIS(IDirectMusicSegment8Impl,iface);
226 FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
228 return S_OK;
231 HRESULT WINAPI IDirectMusicSegment8Impl_Clone (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicSegment** ppSegment)
233 ICOM_THIS(IDirectMusicSegment8Impl,iface);
235 FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppSegment);
237 return S_OK;
240 HRESULT WINAPI IDirectMusicSegment8Impl_SetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart)
242 ICOM_THIS(IDirectMusicSegment8Impl,iface);
244 TRACE("(%p, %ld): stub\n", This, mtStart);
245 This->segHeader.mtPlayStart = mtStart;
247 return S_OK;
250 HRESULT WINAPI IDirectMusicSegment8Impl_GetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart)
252 ICOM_THIS(IDirectMusicSegment8Impl,iface);
254 TRACE("(%p, %p): stub\n", This, pmtStart);
255 *pmtStart = This->segHeader.mtPlayStart;
257 return S_OK;
260 HRESULT WINAPI IDirectMusicSegment8Impl_SetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd)
262 ICOM_THIS(IDirectMusicSegment8Impl,iface);
264 TRACE("(%p, %ld, %ld): stub\n", This, mtStart, mtEnd);
265 This->segHeader.mtLoopStart = mtStart;
266 This->segHeader.mtLoopEnd = mtEnd;
268 return S_OK;
271 HRESULT WINAPI IDirectMusicSegment8Impl_GetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart, MUSIC_TIME* pmtEnd)
273 ICOM_THIS(IDirectMusicSegment8Impl,iface);
275 TRACE("(%p, %p, %p): stub\n", This, pmtStart, pmtEnd);
276 *pmtStart = This->segHeader.mtLoopStart;
277 *pmtEnd = This->segHeader.mtLoopEnd;
279 return S_OK;
282 HRESULT WINAPI IDirectMusicSegment8Impl_SetPChannelsUsed (LPDIRECTMUSICSEGMENT8 iface, DWORD dwNumPChannels, DWORD* paPChannels)
284 ICOM_THIS(IDirectMusicSegment8Impl,iface);
286 FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);
288 return S_OK;
291 /* IDirectMusicSegment8 IDirectMusicSegment8 part: */
292 HRESULT WINAPI IDirectMusicSegment8Impl_SetTrackConfig (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff)
294 ICOM_THIS(IDirectMusicSegment8Impl,iface);
296 FIXME("(%p, %s, %ld, %ld, %ld, %ld): stub\n", This, debugstr_guid(rguidTrackClassID), dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
298 return S_OK;
301 HRESULT WINAPI IDirectMusicSegment8Impl_GetAudioPathConfig (LPDIRECTMUSICSEGMENT8 iface, IUnknown** ppAudioPathConfig)
303 ICOM_THIS(IDirectMusicSegment8Impl,iface);
305 FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
307 return S_OK;
310 HRESULT WINAPI IDirectMusicSegment8Impl_Compose (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtTime, IDirectMusicSegment* pFromSegment, IDirectMusicSegment* pToSegment, IDirectMusicSegment** ppComposedSegment)
312 ICOM_THIS(IDirectMusicSegment8Impl,iface);
314 FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
316 return S_OK;
319 HRESULT WINAPI IDirectMusicSegment8Impl_Download (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath)
321 ICOM_THIS(IDirectMusicSegment8Impl,iface);
323 FIXME("(%p, %p): stub\n", This, pAudioPath);
325 return S_OK;
328 HRESULT WINAPI IDirectMusicSegment8Impl_Unload (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath)
330 ICOM_THIS(IDirectMusicSegment8Impl,iface);
332 FIXME("(%p, %p): stub\n", This, pAudioPath);
334 return S_OK;
337 ICOM_VTABLE(IDirectMusicSegment8) DirectMusicSegment8_Vtbl =
339 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
340 IDirectMusicSegment8Impl_QueryInterface,
341 IDirectMusicSegment8Impl_AddRef,
342 IDirectMusicSegment8Impl_Release,
343 IDirectMusicSegment8Impl_GetLength,
344 IDirectMusicSegment8Impl_SetLength,
345 IDirectMusicSegment8Impl_GetRepeats,
346 IDirectMusicSegment8Impl_SetRepeats,
347 IDirectMusicSegment8Impl_GetDefaultResolution,
348 IDirectMusicSegment8Impl_SetDefaultResolution,
349 IDirectMusicSegment8Impl_GetTrack,
350 IDirectMusicSegment8Impl_GetTrackGroup,
351 IDirectMusicSegment8Impl_InsertTrack,
352 IDirectMusicSegment8Impl_RemoveTrack,
353 IDirectMusicSegment8Impl_InitPlay,
354 IDirectMusicSegment8Impl_GetGraph,
355 IDirectMusicSegment8Impl_SetGraph,
356 IDirectMusicSegment8Impl_AddNotificationType,
357 IDirectMusicSegment8Impl_RemoveNotificationType,
358 IDirectMusicSegment8Impl_GetParam,
359 IDirectMusicSegment8Impl_SetParam,
360 IDirectMusicSegment8Impl_Clone,
361 IDirectMusicSegment8Impl_SetStartPoint,
362 IDirectMusicSegment8Impl_GetStartPoint,
363 IDirectMusicSegment8Impl_SetLoopPoints,
364 IDirectMusicSegment8Impl_GetLoopPoints,
365 IDirectMusicSegment8Impl_SetPChannelsUsed,
366 IDirectMusicSegment8Impl_SetTrackConfig,
367 IDirectMusicSegment8Impl_GetAudioPathConfig,
368 IDirectMusicSegment8Impl_Compose,
369 IDirectMusicSegment8Impl_Download,
370 IDirectMusicSegment8Impl_Unload
373 /* for ClassFactory */
374 HRESULT WINAPI DMUSIC_CreateDirectMusicSegment (LPCGUID lpcGUID, LPDIRECTMUSICSEGMENT8 *ppDMSeg, LPUNKNOWN pUnkOuter)
376 IDirectMusicSegment8Impl *segment;
378 TRACE("(%p,%p,%p)\n", lpcGUID, ppDMSeg, pUnkOuter);
379 if (IsEqualIID (lpcGUID, &IID_IDirectMusicSegment)
380 || IsEqualIID (lpcGUID, &IID_IDirectMusicSegment2)
381 || IsEqualIID (lpcGUID, &IID_IDirectMusicSegment8)) {
382 segment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegment8Impl));
383 if (NULL == segment) {
384 *ppDMSeg = (LPDIRECTMUSICSEGMENT8) NULL;
385 return E_OUTOFMEMORY;
387 segment->lpVtbl = &DirectMusicSegment8_Vtbl;
388 segment->ref = 1;
389 *ppDMSeg = (LPDIRECTMUSICSEGMENT8) segment;
390 return S_OK;
393 WARN("No interface found\n");
394 return E_NOINTERFACE;
398 /*****************************************************************************
399 * IDirectMusicSegmentObject implementation
401 /* IDirectMusicSegmentObject IUnknown part: */
402 HRESULT WINAPI IDirectMusicSegmentObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj)
404 ICOM_THIS(IDirectMusicSegmentObject,iface);
406 if (IsEqualGUID(riid, &IID_IUnknown)
407 || IsEqualGUID(riid, &IID_IDirectMusicObject)) {
408 IDirectMusicSegmentObject_AddRef(iface);
409 *ppobj = This;
410 return S_OK;
411 } else if (IsEqualGUID (riid, &IID_IPersistStream)) {
412 IDirectMusicSegmentObjectStream_AddRef ((LPPERSISTSTREAM)This->pStream);
413 *ppobj = This->pStream;
414 return S_OK;
415 } else if (IsEqualGUID (riid, &IID_IDirectMusicSegment)
416 || IsEqualGUID (riid, &IID_IDirectMusicSegment8)) {
417 IDirectMusicSegment8Impl_AddRef ((LPDIRECTMUSICSEGMENT8)This->pSegment);
418 *ppobj = This->pSegment;
419 return S_OK;
421 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
422 return E_NOINTERFACE;
425 ULONG WINAPI IDirectMusicSegmentObject_AddRef (LPDIRECTMUSICOBJECT iface)
427 ICOM_THIS(IDirectMusicSegmentObject,iface);
428 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
429 return ++(This->ref);
432 ULONG WINAPI IDirectMusicSegmentObject_Release (LPDIRECTMUSICOBJECT iface)
434 ICOM_THIS(IDirectMusicSegmentObject,iface);
435 ULONG ref = --This->ref;
436 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
437 if (ref == 0)
439 HeapFree(GetProcessHeap(), 0, This);
441 return ref;
444 /* IDirectMusicSegmentObject IDirectMusicObject part: */
445 HRESULT WINAPI IDirectMusicSegmentObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc)
447 ICOM_THIS(IDirectMusicSegmentObject,iface);
449 TRACE("(%p, %p)\n", This, pDesc);
450 pDesc = This->pDesc;
452 return S_OK;
455 HRESULT WINAPI IDirectMusicSegmentObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc)
457 ICOM_THIS(IDirectMusicSegmentObject,iface);
459 TRACE("(%p, %p)\n", This, pDesc);
460 This->pDesc = pDesc;
462 return S_OK;
465 HRESULT WINAPI IDirectMusicSegmentObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc)
467 ICOM_THIS(IDirectMusicSegmentObject,iface);
469 FIXME("(%p, %p, %p): stub\n", This, pStream, pDesc);
471 return S_OK;
474 ICOM_VTABLE(IDirectMusicObject) DirectMusicSegmentObject_Vtbl =
476 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
477 IDirectMusicSegmentObject_QueryInterface,
478 IDirectMusicSegmentObject_AddRef,
479 IDirectMusicSegmentObject_Release,
480 IDirectMusicSegmentObject_GetDescriptor,
481 IDirectMusicSegmentObject_SetDescriptor,
482 IDirectMusicSegmentObject_ParseDescriptor
485 /* for ClassFactory */
486 HRESULT WINAPI DMUSIC_CreateDirectMusicSegmentObject (LPCGUID lpcGUID, LPDIRECTMUSICOBJECT* ppObject, LPUNKNOWN pUnkOuter)
488 IDirectMusicSegmentObject *obj;
490 TRACE("(%p,%p,%p)\n", lpcGUID, ppObject, pUnkOuter);
491 if (IsEqualGUID (lpcGUID, &IID_IDirectMusicObject)) {
492 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegmentObject));
493 if (NULL == obj) {
494 *ppObject = (LPDIRECTMUSICOBJECT) NULL;
495 return E_OUTOFMEMORY;
497 obj->lpVtbl = &DirectMusicSegmentObject_Vtbl;
498 obj->ref = 1;
499 /* prepare IPersistStream */
500 obj->pStream = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegmentObjectStream));
501 obj->pStream->lpVtbl = &DirectMusicSegmentObjectStream_Vtbl;
502 obj->pStream->ref = 1;
503 obj->pStream->pParentObject = obj;
504 /* prepare IDirectMusicSegment8 */
505 DMUSIC_CreateDirectMusicSegment (&IID_IDirectMusicSegment8, (LPDIRECTMUSICSEGMENT8*)&obj->pSegment, NULL);
506 obj->pSegment->pObject = obj;
507 *ppObject = (LPDIRECTMUSICOBJECT) obj;
508 return S_OK;
510 WARN("No interface found\n");
512 return E_NOINTERFACE;
515 /*****************************************************************************
516 * IDirectMusicSegmentObjectStream implementation
518 /* IDirectMusicSegmentObjectStream IUnknown part: */
519 HRESULT WINAPI IDirectMusicSegmentObjectStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj)
521 ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
523 if (IsEqualGUID(riid, &IID_IUnknown)
524 || IsEqualGUID(riid, &IID_IPersistStream)) {
525 IDirectMusicSegmentObjectStream_AddRef (iface);
526 *ppobj = This;
527 return S_OK;
529 WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
530 return E_NOINTERFACE;
533 ULONG WINAPI IDirectMusicSegmentObjectStream_AddRef (LPPERSISTSTREAM iface)
535 ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
536 TRACE("(%p) : AddRef from %ld\n", This, This->ref);
537 return ++(This->ref);
540 ULONG WINAPI IDirectMusicSegmentObjectStream_Release (LPPERSISTSTREAM iface)
542 ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
543 ULONG ref = --This->ref;
544 TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
545 if (ref == 0)
547 HeapFree(GetProcessHeap(), 0, This);
549 return ref;
552 /* IDirectMusicSegmentObjectStream IPersist part: */
553 HRESULT WINAPI IDirectMusicSegmentObjectStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID)
555 return E_NOTIMPL;
558 /* IDirectMusicSegmentObjectStream IPersistStream part: */
559 HRESULT WINAPI IDirectMusicSegmentObjectStream_IsDirty (LPPERSISTSTREAM iface)
561 return E_NOTIMPL;
564 HRESULT WINAPI IDirectMusicSegmentObjectStream_Load (LPPERSISTSTREAM iface, IStream* pStm)
566 ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
567 FOURCC chunkID;
568 DWORD chunkSize, StreamSize, StreamCount, ListSize[10], ListCount[10];
569 LARGE_INTEGER liMove; /* used when skipping chunks */
570 IDirectMusicSegment8Impl* pSegment = This->pParentObject->pSegment; /* that's where we load data */
571 DMUS_IO_TRACK_HEADER tempHeader;
572 DMUS_IO_TRACK_EXTRAS_HEADER tempXHeader;
574 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
575 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
576 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
577 switch (chunkID)
579 case FOURCC_RIFF: {
580 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
581 TRACE_(dmfile)(": RIFF chunk containing %s", debugstr_fourcc (chunkID));
582 StreamSize = chunkSize - sizeof(FOURCC);
583 StreamCount = 0;
584 switch (chunkID)
586 case DMUS_FOURCC_SEGMENT_FORM: {
587 TRACE_(dmfile)(": segment form\n");
588 do {
589 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
590 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
591 StreamCount += sizeof (FOURCC) + sizeof (DWORD) + chunkSize;
592 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
593 switch (chunkID) {
594 case DMUS_FOURCC_SEGMENT_CHUNK: {
595 TRACE_(dmfile)(": segment header chunk\n");
596 IStream_Read (pStm, &pSegment->segHeader, chunkSize, NULL);
597 break;
599 case DMUS_FOURCC_GUID_CHUNK: {
600 TRACE_(dmfile)(": GUID chunk\n");
601 IStream_Read (pStm, &pSegment->vVersion, chunkSize, NULL);
602 break;
604 case DMUS_FOURCC_VERSION_CHUNK: {
605 TRACE_(dmfile)(": version chunk\n");
606 IStream_Read (pStm, &pSegment->guidID, chunkSize, NULL);
607 break;
609 case FOURCC_LIST: {
610 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
611 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunkID));
612 ListSize[0] = chunkSize - sizeof(FOURCC);
613 ListCount[0] = 0;
614 switch (chunkID) {
615 case DMUS_FOURCC_UNFO_LIST: {
616 TRACE_(dmfile)(": UNFO list\n");
617 do {
618 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
619 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
620 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
621 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
622 switch (chunkID) {
623 case DMUS_FOURCC_UNAM_CHUNK: {
624 TRACE_(dmfile)(": name chunk\n");
625 pSegment->wszName = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
626 IStream_Read (pStm, pSegment->wszName, chunkSize, NULL);
627 break;
629 case DMUS_FOURCC_UART_CHUNK: {
630 TRACE_(dmfile)(": artist chunk\n");
631 pSegment->wszArtist = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
632 IStream_Read (pStm, pSegment->wszArtist, chunkSize, NULL);
633 break;
635 case DMUS_FOURCC_UCOP_CHUNK: {
636 TRACE_(dmfile)(": copyright chunk\n");
637 pSegment->wszCopyright = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
638 IStream_Read (pStm, pSegment->wszCopyright, chunkSize, NULL);
639 break;
641 case DMUS_FOURCC_USBJ_CHUNK: {
642 TRACE_(dmfile)(": subject chunk\n");
643 pSegment->wszSubject = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
644 IStream_Read (pStm, pSegment->wszSubject, chunkSize, NULL);
645 break;
647 case DMUS_FOURCC_UCMT_CHUNK: {
648 TRACE_(dmfile)(": comment chunk\n");
649 pSegment->wszComment = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, chunkSize);
650 IStream_Read (pStm, pSegment->wszComment, chunkSize, NULL);
651 break;
653 default: {
654 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
655 liMove.QuadPart = chunkSize;
656 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
657 break;
660 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
661 } while (ListCount[0] < ListSize[0]);
662 break;
664 case DMUS_FOURCC_TRACK_LIST: {
665 TRACE_(dmfile)(": track list\n");
666 do {
667 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
668 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
669 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
670 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
671 switch (chunkID)
673 case FOURCC_RIFF: {
674 TRACE_(dmfile)(": RIFF chunk");
675 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
676 switch (chunkID)
678 case DMUS_FOURCC_TRACK_FORM: {
679 TRACE_(dmfile)(": containing %s: track form\n", debugstr_fourcc(chunkID));
680 ListSize[1] = chunkSize - sizeof(FOURCC);
681 ListCount[1] = 0;
682 do {
683 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
684 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
685 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
686 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
687 switch (chunkID) {
688 case DMUS_FOURCC_TRACK_CHUNK: {
689 TRACE_(dmfile)(": track header chunk\n");
690 IStream_Read (pStm, &tempHeader, chunkSize, NULL);
691 break;
693 case DMUS_FOURCC_TRACK_EXTRAS_CHUNK: {
694 TRACE_(dmfile)(": track extra header chunk\n");
695 IStream_Read (pStm, &tempXHeader, chunkSize, NULL);
696 break;
698 /* add other stuff (look at note below) */
699 default: {
700 TRACE_(dmfile)(": unknown chunk (skipping)\n");
701 liMove.QuadPart = chunkSize;
702 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
703 break;
706 TRACE_(dmfile)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]);
707 } while (ListCount[1] < ListSize[1]);
708 FIXME(": loading tracks not supported yet\n");
709 /* sigh... now comes track creation... currently I have some problems with implementing
710 this one because my test are contradicting:
711 - tracks are not loaded by loader (at least my dxdiag test with native dmime doesn't show it)
712 therefore i guess they're created with CoCreateInstance with CLSID specified in header and
713 IID_IDirectMusicTrack(8). Tracks are then probably passed to IDirectMusicSegment_Insert
714 (not quite sure, but behaviour complies with the one described in MSDN (about calling IDirectMusicTrack_Init)
715 - but on the other hand, track's stream implementation gets only <data> chunk (look in MSDN for more info)
716 (tested with native dmime and builtin dmband and dmstyle) => this means that all info about track (header, extra header
717 UNFO, GUID and version are read by segment's stream... now, how the hell is all this info set on track?!
718 => I believe successful approach would be to create structure like this:
719 _DMUSIC_PRIVATE_TRACK_ENTRY {
720 DMUS_IO_TRACK_HEADER trkHeader;
721 DMUS_IO_TRACK_EXTRAS_HEADER trkXHeader;
722 WCHAR* name, ...;
723 GUID guidID;
724 DMUS_VERSION vVersion;
726 IDirectMusicTrack* pTrack;
727 } DMUSIC_PRIVATE_TRACK_ENTRY;
728 and then load all stuff into it
729 => anyway, I'll try to implement it when I find some time again, but this note is here for anyone that wants to give it a try :)
731 break;
733 default: {
734 TRACE_(dmfile)(": unknown chunk (only DMTK expected; skipping)\n");
735 liMove.QuadPart = chunkSize - sizeof(FOURCC);
736 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
737 break;
740 break;
742 default: {
743 TRACE_(dmfile)("(unexpected) non-RIFF chunk (skipping, but expect errors)\n");
744 liMove.QuadPart = chunkSize;
745 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
746 break;
749 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
750 } while (ListCount[0] < ListSize[0]);
751 break;
753 default: {
754 TRACE_(dmfile)(": unknown (skipping)\n");
755 liMove.QuadPart = chunkSize - sizeof(FOURCC);
756 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
757 break;
760 break;
762 default: {
763 TRACE_(dmfile)(": unknown chunk (skipping)\n");
764 liMove.QuadPart = chunkSize;
765 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
766 break;
769 TRACE_(dmfile)(": StreamCount = %ld < StreamSize = %ld\n", StreamCount, StreamSize);
770 } while (StreamCount < StreamSize);
771 break;
773 default: {
774 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
775 liMove.QuadPart = StreamSize;
776 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
777 return E_FAIL;
780 TRACE_(dmfile)(": reading finished\n");
781 break;
783 default: {
784 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
785 liMove.QuadPart = chunkSize;
786 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
787 return E_FAIL;
791 return S_OK;
794 HRESULT WINAPI IDirectMusicSegmentObjectStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty)
796 return E_NOTIMPL;
799 HRESULT WINAPI IDirectMusicSegmentObjectStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize)
801 return E_NOTIMPL;
804 ICOM_VTABLE(IPersistStream) DirectMusicSegmentObjectStream_Vtbl =
806 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
807 IDirectMusicSegmentObjectStream_QueryInterface,
808 IDirectMusicSegmentObjectStream_AddRef,
809 IDirectMusicSegmentObjectStream_Release,
810 IDirectMusicSegmentObjectStream_GetClassID,
811 IDirectMusicSegmentObjectStream_IsDirty,
812 IDirectMusicSegmentObjectStream_Load,
813 IDirectMusicSegmentObjectStream_Save,
814 IDirectMusicSegmentObjectStream_GetSizeMax