Added stubs for AccessCheckByType, AddAuditAccessAce,
[wine] / dlls / dmime / segment.c
1 /* IDirectMusicSegment8 Implementation
2  *
3  * Copyright (C) 2003 Rok Mandeljc
4  *
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.
9  *
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.
14  *
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.
18  */
19
20 #include <stdarg.h>
21
22 #include "windef.h"
23 #include "winbase.h"
24 #include "winuser.h"
25 #include "wingdi.h"
26 #include "wine/debug.h"
27
28 #include "dmime_private.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
31 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
32
33 /*****************************************************************************
34  * IDirectMusicSegment8Impl implementation
35  */
36 /* IDirectMusicSegment8 IUnknown part: */
37 HRESULT WINAPI IDirectMusicSegment8Impl_QueryInterface (LPDIRECTMUSICSEGMENT8 iface, REFIID riid, LPVOID *ppobj)
38 {
39         ICOM_THIS(IDirectMusicSegment8Impl,iface);
40
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;
47         }
48         
49         WARN("(%p)->(%s,%p),not found\n", This, debugstr_guid(riid), ppobj);
50         return E_NOINTERFACE;
51 }
52
53 ULONG WINAPI IDirectMusicSegment8Impl_AddRef (LPDIRECTMUSICSEGMENT8 iface)
54 {
55         ICOM_THIS(IDirectMusicSegment8Impl,iface);
56         TRACE("(%p) : AddRef from %ld\n", This, This->ref);
57         return ++(This->ref);
58 }
59
60 ULONG WINAPI IDirectMusicSegment8Impl_Release (LPDIRECTMUSICSEGMENT8 iface)
61 {
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);
67         }
68         return ref;
69 }
70
71 /* IDirectMusicSegment8 IDirectMusicSegment part: */
72 HRESULT WINAPI IDirectMusicSegment8Impl_GetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtLength)
73 {
74         ICOM_THIS(IDirectMusicSegment8Impl,iface);
75
76         TRACE("(%p, %p)\n", This, pmtLength);
77         *pmtLength = This->segHeader.mtLength;
78
79         return S_OK;
80 }
81
82 HRESULT WINAPI IDirectMusicSegment8Impl_SetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtLength)
83 {
84         ICOM_THIS(IDirectMusicSegment8Impl,iface);
85
86         TRACE("(%p, %ld)\n", This, mtLength);
87         This->segHeader.mtLength = mtLength;
88
89         return S_OK;
90 }
91
92 HRESULT WINAPI IDirectMusicSegment8Impl_GetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwRepeats)
93 {
94         ICOM_THIS(IDirectMusicSegment8Impl,iface);
95
96         TRACE("(%p, %p)\n", This, pdwRepeats);
97         *pdwRepeats = This->segHeader.dwRepeats;
98
99         return S_OK;
100 }
101
102 HRESULT WINAPI IDirectMusicSegment8Impl_SetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD dwRepeats)
103 {
104         ICOM_THIS(IDirectMusicSegment8Impl,iface);
105
106         TRACE("(%p, %ld)\n", This, dwRepeats);
107         This->segHeader.dwRepeats = dwRepeats;
108         
109         return S_OK;
110 }
111
112 HRESULT WINAPI IDirectMusicSegment8Impl_GetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwResolution)
113 {
114         ICOM_THIS(IDirectMusicSegment8Impl,iface);
115
116         TRACE("(%p, %p)\n", This, pdwResolution);
117         *pdwResolution = This->segHeader.dwResolution;
118         
119         return S_OK;
120 }
121
122 HRESULT WINAPI IDirectMusicSegment8Impl_SetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD dwResolution)
123 {
124         ICOM_THIS(IDirectMusicSegment8Impl,iface);
125
126         TRACE("(%p, %ld)\n", This, dwResolution);
127         This->segHeader.dwResolution = dwResolution;
128         
129         return S_OK;
130 }
131
132 HRESULT WINAPI IDirectMusicSegment8Impl_GetTrack (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, IDirectMusicTrack** ppTrack)
133 {
134         ICOM_THIS(IDirectMusicSegment8Impl,iface);
135
136         FIXME("(%p, %s, %ld, %ld, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, ppTrack);
137
138         return S_OK;
139 }
140
141 HRESULT WINAPI IDirectMusicSegment8Impl_GetTrackGroup (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD* pdwGroupBits)
142 {
143         ICOM_THIS(IDirectMusicSegment8Impl,iface);
144
145         FIXME("(%p, %p, %p): stub\n", This, pTrack, pdwGroupBits);
146
147         return S_OK;
148 }
149
150 HRESULT WINAPI IDirectMusicSegment8Impl_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits)
151 {
152         ICOM_THIS(IDirectMusicSegment8Impl,iface);
153
154         FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
155
156         return S_OK;
157 }
158
159 HRESULT WINAPI IDirectMusicSegment8Impl_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack)
160 {
161         ICOM_THIS(IDirectMusicSegment8Impl,iface);
162
163         FIXME("(%p, %p): stub\n", This, pTrack);
164
165         return S_OK;
166 }
167
168 HRESULT WINAPI IDirectMusicSegment8Impl_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags)
169 {
170         ICOM_THIS(IDirectMusicSegment8Impl,iface);
171
172         FIXME("(%p, %p, %p, %ld): stub\n", This, ppSegState, pPerformance, dwFlags);
173
174         return S_OK;
175 }
176
177 HRESULT WINAPI IDirectMusicSegment8Impl_GetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph** ppGraph)
178 {
179         ICOM_THIS(IDirectMusicSegment8Impl,iface);
180
181         FIXME("(%p, %p): stub\n", This, ppGraph);
182
183         return S_OK;
184 }
185
186 HRESULT WINAPI IDirectMusicSegment8Impl_SetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph* pGraph)
187 {
188         ICOM_THIS(IDirectMusicSegment8Impl,iface);
189
190         FIXME("(%p, %p): stub\n", This, pGraph);
191
192         return S_OK;
193 }
194
195 HRESULT WINAPI IDirectMusicSegment8Impl_AddNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType)
196 {
197         ICOM_THIS(IDirectMusicSegment8Impl,iface);
198
199         FIXME("(%p, %s): stub\n", This, debugstr_guid(rguidNotificationType));
200
201         return S_OK;
202 }
203
204 HRESULT WINAPI IDirectMusicSegment8Impl_RemoveNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType)
205 {
206         ICOM_THIS(IDirectMusicSegment8Impl,iface);
207
208         FIXME("(%p, %s): stub\n", This, debugstr_guid(rguidNotificationType));
209
210         return S_OK;
211 }
212
213 HRESULT WINAPI IDirectMusicSegment8Impl_GetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam)
214 {
215         ICOM_THIS(IDirectMusicSegment8Impl,iface);
216
217         FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
218
219         return S_OK;
220 }
221
222 HRESULT WINAPI IDirectMusicSegment8Impl_SetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam)
223 {
224         ICOM_THIS(IDirectMusicSegment8Impl,iface);
225
226         FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_guid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
227
228         return S_OK;
229 }
230
231 HRESULT WINAPI IDirectMusicSegment8Impl_Clone (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicSegment** ppSegment)
232 {
233         ICOM_THIS(IDirectMusicSegment8Impl,iface);
234
235         FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppSegment);
236
237         return S_OK;
238 }
239
240 HRESULT WINAPI IDirectMusicSegment8Impl_SetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart)
241 {
242         ICOM_THIS(IDirectMusicSegment8Impl,iface);
243
244         TRACE("(%p, %ld): stub\n", This, mtStart);
245         This->segHeader.mtPlayStart = mtStart;
246         
247         return S_OK;
248 }
249
250 HRESULT WINAPI IDirectMusicSegment8Impl_GetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart)
251 {
252         ICOM_THIS(IDirectMusicSegment8Impl,iface);
253
254         TRACE("(%p, %p): stub\n", This, pmtStart);
255         *pmtStart = This->segHeader.mtPlayStart;
256
257         return S_OK;
258 }
259
260 HRESULT WINAPI IDirectMusicSegment8Impl_SetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd)
261 {
262         ICOM_THIS(IDirectMusicSegment8Impl,iface);
263
264         TRACE("(%p, %ld, %ld): stub\n", This, mtStart, mtEnd);
265         This->segHeader.mtLoopStart = mtStart;
266         This->segHeader.mtLoopEnd = mtEnd;
267         
268         return S_OK;
269 }
270
271 HRESULT WINAPI IDirectMusicSegment8Impl_GetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart, MUSIC_TIME* pmtEnd)
272 {
273         ICOM_THIS(IDirectMusicSegment8Impl,iface);
274
275         TRACE("(%p, %p, %p): stub\n", This, pmtStart, pmtEnd);
276         *pmtStart = This->segHeader.mtLoopStart;
277         *pmtEnd = This->segHeader.mtLoopEnd;
278         
279         return S_OK;
280 }
281
282 HRESULT WINAPI IDirectMusicSegment8Impl_SetPChannelsUsed (LPDIRECTMUSICSEGMENT8 iface, DWORD dwNumPChannels, DWORD* paPChannels)
283 {
284         ICOM_THIS(IDirectMusicSegment8Impl,iface);
285
286         FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);      
287
288         return S_OK;
289 }
290
291 /* IDirectMusicSegment8 IDirectMusicSegment8 part: */
292 HRESULT WINAPI IDirectMusicSegment8Impl_SetTrackConfig (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff)
293 {
294         ICOM_THIS(IDirectMusicSegment8Impl,iface);
295
296         FIXME("(%p, %s, %ld, %ld, %ld, %ld): stub\n", This, debugstr_guid(rguidTrackClassID), dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
297
298         return S_OK;
299 }
300
301 HRESULT WINAPI IDirectMusicSegment8Impl_GetAudioPathConfig (LPDIRECTMUSICSEGMENT8 iface, IUnknown** ppAudioPathConfig)
302 {
303         ICOM_THIS(IDirectMusicSegment8Impl,iface);
304
305         FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
306
307         return S_OK;
308 }
309
310 HRESULT WINAPI IDirectMusicSegment8Impl_Compose (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtTime, IDirectMusicSegment* pFromSegment, IDirectMusicSegment* pToSegment, IDirectMusicSegment** ppComposedSegment)
311 {
312         ICOM_THIS(IDirectMusicSegment8Impl,iface);
313
314         FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
315
316         return S_OK;
317 }
318
319 HRESULT WINAPI IDirectMusicSegment8Impl_Download (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath)
320 {
321         ICOM_THIS(IDirectMusicSegment8Impl,iface);
322
323         FIXME("(%p, %p): stub\n", This, pAudioPath);
324
325         return S_OK;
326 }
327
328 HRESULT WINAPI IDirectMusicSegment8Impl_Unload (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath)
329 {
330         ICOM_THIS(IDirectMusicSegment8Impl,iface);
331
332         FIXME("(%p, %p): stub\n", This, pAudioPath);
333
334         return S_OK;
335 }
336
337 ICOM_VTABLE(IDirectMusicSegment8) DirectMusicSegment8_Vtbl =
338 {
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
371 };
372
373 /* for ClassFactory */
374 HRESULT WINAPI DMUSIC_CreateDirectMusicSegment (LPCGUID lpcGUID, LPDIRECTMUSICSEGMENT8 *ppDMSeg, LPUNKNOWN pUnkOuter)
375 {
376         IDirectMusicSegment8Impl *segment;
377         
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;
386                 }
387                 segment->lpVtbl = &DirectMusicSegment8_Vtbl;
388                 segment->ref = 1;
389                 *ppDMSeg = (LPDIRECTMUSICSEGMENT8) segment;
390                 return S_OK;
391         }
392         
393         WARN("No interface found\n");
394         return E_NOINTERFACE;
395 }
396
397
398 /*****************************************************************************
399  * IDirectMusicSegmentObject implementation
400  */
401 /* IDirectMusicSegmentObject IUnknown part: */
402 HRESULT WINAPI IDirectMusicSegmentObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj)
403 {
404         ICOM_THIS(IDirectMusicSegmentObject,iface);
405
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;
420         }
421         WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
422         return E_NOINTERFACE;
423 }
424
425 ULONG WINAPI IDirectMusicSegmentObject_AddRef (LPDIRECTMUSICOBJECT iface)
426 {
427         ICOM_THIS(IDirectMusicSegmentObject,iface);
428         TRACE("(%p) : AddRef from %ld\n", This, This->ref);
429         return ++(This->ref);
430 }
431
432 ULONG WINAPI IDirectMusicSegmentObject_Release (LPDIRECTMUSICOBJECT iface)
433 {
434         ICOM_THIS(IDirectMusicSegmentObject,iface);
435         ULONG ref = --This->ref;
436         TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
437         if (ref == 0)
438         {
439                 HeapFree(GetProcessHeap(), 0, This);
440         }
441         return ref;
442 }
443
444 /* IDirectMusicSegmentObject IDirectMusicObject part: */
445 HRESULT WINAPI IDirectMusicSegmentObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc)
446 {
447         ICOM_THIS(IDirectMusicSegmentObject,iface);
448
449         TRACE("(%p, %p)\n", This, pDesc);
450         pDesc = This->pDesc;
451         
452         return S_OK;
453 }
454
455 HRESULT WINAPI IDirectMusicSegmentObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc)
456 {
457         ICOM_THIS(IDirectMusicSegmentObject,iface);
458
459         TRACE("(%p, %p)\n", This, pDesc);
460         This->pDesc = pDesc;
461
462         return S_OK;
463 }
464
465 HRESULT WINAPI IDirectMusicSegmentObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc)
466 {
467         ICOM_THIS(IDirectMusicSegmentObject,iface);
468
469         FIXME("(%p, %p, %p): stub\n", This, pStream, pDesc);
470
471         return S_OK;
472 }
473
474 ICOM_VTABLE(IDirectMusicObject) DirectMusicSegmentObject_Vtbl =
475 {
476     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
477         IDirectMusicSegmentObject_QueryInterface,
478         IDirectMusicSegmentObject_AddRef,
479         IDirectMusicSegmentObject_Release,
480         IDirectMusicSegmentObject_GetDescriptor,
481         IDirectMusicSegmentObject_SetDescriptor,
482         IDirectMusicSegmentObject_ParseDescriptor
483 };
484
485 /* for ClassFactory */
486 HRESULT WINAPI DMUSIC_CreateDirectMusicSegmentObject (LPCGUID lpcGUID, LPDIRECTMUSICOBJECT* ppObject, LPUNKNOWN pUnkOuter)
487 {
488         IDirectMusicSegmentObject *obj;
489         
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;
496                 }
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;
509         }
510         WARN("No interface found\n");
511         
512         return E_NOINTERFACE;
513 }
514
515 /*****************************************************************************
516  * IDirectMusicSegmentObjectStream implementation
517  */
518 /* IDirectMusicSegmentObjectStream IUnknown part: */
519 HRESULT WINAPI IDirectMusicSegmentObjectStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj)
520 {
521         ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
522
523         if (IsEqualGUID(riid, &IID_IUnknown)
524                 || IsEqualGUID(riid, &IID_IPersistStream)) {
525                 IDirectMusicSegmentObjectStream_AddRef (iface);
526                 *ppobj = This;
527                 return S_OK;
528         }
529         WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
530         return E_NOINTERFACE;
531 }
532
533 ULONG WINAPI IDirectMusicSegmentObjectStream_AddRef (LPPERSISTSTREAM iface)
534 {
535         ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
536         TRACE("(%p) : AddRef from %ld\n", This, This->ref);
537         return ++(This->ref);
538 }
539
540 ULONG WINAPI IDirectMusicSegmentObjectStream_Release (LPPERSISTSTREAM iface)
541 {
542         ICOM_THIS(IDirectMusicSegmentObjectStream,iface);
543         ULONG ref = --This->ref;
544         TRACE("(%p) : ReleaseRef to %ld\n", This, This->ref);
545         if (ref == 0)
546         {
547                 HeapFree(GetProcessHeap(), 0, This);
548         }
549         return ref;
550 }
551
552 /* IDirectMusicSegmentObjectStream IPersist part: */
553 HRESULT WINAPI IDirectMusicSegmentObjectStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID)
554 {
555         return E_NOTIMPL;
556 }
557
558 /* IDirectMusicSegmentObjectStream IPersistStream part: */
559 HRESULT WINAPI IDirectMusicSegmentObjectStream_IsDirty (LPPERSISTSTREAM iface)
560 {
561         return E_NOTIMPL;
562 }
563
564 HRESULT WINAPI IDirectMusicSegmentObjectStream_Load (LPPERSISTSTREAM iface, IStream* pStm)
565 {
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;
573         
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)
578         {
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)
585                         {                               
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;
598                                                         }
599                                                         case DMUS_FOURCC_GUID_CHUNK: {
600                                                                 TRACE_(dmfile)(": GUID chunk\n");
601                                                                 IStream_Read (pStm, &pSegment->vVersion, chunkSize, NULL);
602                                                                 break;
603                                                         }
604                                                         case DMUS_FOURCC_VERSION_CHUNK: {
605                                                                 TRACE_(dmfile)(": version chunk\n");
606                                                                 IStream_Read (pStm, &pSegment->guidID, chunkSize, NULL);
607                                                                 break;
608                                                         }
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;
628                                                                                                 }
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;
634                                                                                                 }
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;
640                                                                                                 }
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;
646                                                                                                 }
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;
652                                                                                                 }
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;                                          
658                                                                                                 }       
659                                                                                         }
660                                                                                         TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
661                                                                                 } while (ListCount[0] < ListSize[0]);
662                                                                                 break;
663                                                                         }
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)
672                                                                                         {
673                                                                                                 case FOURCC_RIFF: {
674                                                                                                         TRACE_(dmfile)(": RIFF chunk");
675                                                                                                         IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
676                                                                                                         switch (chunkID)
677                                                                                                         {
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;
692                                                                                                                                         } 
693                                                                                                                                         case DMUS_FOURCC_TRACK_EXTRAS_CHUNK: {
694                                                                                                                                                 TRACE_(dmfile)(": track extra header chunk\n");
695                                                                                                                                                 IStream_Read (pStm, &tempXHeader, chunkSize, NULL);
696                                                                                                                                                 break;
697                                                                                                                                         }
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;                                          
704                                                                                                                                         }
705                                                                                                                                 }
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;
725                                                                                                                                 ...
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 :)
730                                                                                                                         */
731                                                                                                                         break;
732                                                                                                                 }
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;
738                                                                                                                 }
739                                                                                                         }
740                                                                                                         break;
741                                                                                                 }
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;
747                                                                                                 }
748                                                                                         }
749                                                                                         TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
750                                                                                 } while (ListCount[0] < ListSize[0]);
751                                                                                 break;
752                                                                         }
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;                                          
758                                                                         }                                                               
759                                                                 }
760                                                                 break;  
761                                                         }
762                                                         default: {
763                                                                 TRACE_(dmfile)(": unknown chunk (skipping)\n");
764                                                                 liMove.QuadPart = chunkSize;
765                                                                 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
766                                                                 break;                                          
767                                                         }                                       
768                                                 }
769                                                 TRACE_(dmfile)(": StreamCount = %ld < StreamSize = %ld\n", StreamCount, StreamSize);
770                                         } while (StreamCount < StreamSize);
771                                         break;
772                                 } 
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;
778                                 }
779                         }
780                         TRACE_(dmfile)(": reading finished\n");
781                         break;
782                 }
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;
788                 }
789         }
790         
791         return S_OK;
792 }
793
794 HRESULT WINAPI IDirectMusicSegmentObjectStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty)
795 {
796         return E_NOTIMPL;
797 }
798
799 HRESULT WINAPI IDirectMusicSegmentObjectStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize)
800 {
801         return E_NOTIMPL;
802 }
803
804 ICOM_VTABLE(IPersistStream) DirectMusicSegmentObjectStream_Vtbl =
805 {
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
815 };