Started implementing support for the SubSystemTib field in the TEB of
[wine] / dlls / dmime / segment.c
1 /* IDirectMusicSegment8 Implementation
2  *
3  * Copyright (C) 2003-2004 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 "dmime_private.h"
21
22 WINE_DEFAULT_DEBUG_CHANNEL(dmime);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
24
25 /*****************************************************************************
26  * IDirectMusicSegmentImpl implementation
27  */
28 /* IDirectMusicSegment IUnknown part: */
29 HRESULT WINAPI IDirectMusicSegment8Impl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
30         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, UnknownVtbl, iface);
31         TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
32         
33         if (IsEqualIID (riid, &IID_IUnknown)) {
34                 *ppobj = (LPVOID)&This->UnknownVtbl;
35                 IDirectMusicSegment8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
36                 return S_OK;    
37         } else if (IsEqualIID (riid, &IID_IDirectMusicSegment)
38         || IsEqualIID (riid, &IID_IDirectMusicSegment2)
39         || IsEqualIID (riid, &IID_IDirectMusicSegment8)) {
40                 *ppobj = (LPVOID)&This->SegmentVtbl;
41                 IDirectMusicSegment8Impl_IDirectMusicSegment8_AddRef ((LPDIRECTMUSICSEGMENT8)&This->SegmentVtbl);
42                 return S_OK;
43         } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) {
44                 *ppobj = (LPVOID)&This->ObjectVtbl;
45                 IDirectMusicSegment8Impl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT)&This->ObjectVtbl);            
46                 return S_OK;
47         } else if (IsEqualIID (riid, &IID_IPersistStream)) {
48                 *ppobj = (LPVOID)&This->PersistStreamVtbl;
49                 IDirectMusicSegment8Impl_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl);             
50                 return S_OK;
51         }
52         
53         WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
54         return E_NOINTERFACE;
55 }
56
57 ULONG WINAPI IDirectMusicSegment8Impl_IUnknown_AddRef (LPUNKNOWN iface) {
58         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, UnknownVtbl, iface);
59         TRACE("(%p): AddRef from %ld\n", This, This->ref);
60         return ++(This->ref);
61 }
62
63 ULONG WINAPI IDirectMusicSegment8Impl_IUnknown_Release (LPUNKNOWN iface) {
64         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, UnknownVtbl, iface);
65         ULONG ref = --This->ref;
66         TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
67         if (ref == 0) {
68                 HeapFree(GetProcessHeap(), 0, This);
69         }
70         return ref;
71 }
72
73 ICOM_VTABLE(IUnknown) DirectMusicSegment8_Unknown_Vtbl = {
74     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
75         IDirectMusicSegment8Impl_IUnknown_QueryInterface,
76         IDirectMusicSegment8Impl_IUnknown_AddRef,
77         IDirectMusicSegment8Impl_IUnknown_Release
78 };
79
80 /* IDirectMusicSegmentImpl IDirectMusicSegment part: */
81 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_QueryInterface (LPDIRECTMUSICSEGMENT8 iface, REFIID riid, LPVOID *ppobj) {
82         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
83         return IDirectMusicSegment8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
84 }
85
86 ULONG WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_AddRef (LPDIRECTMUSICSEGMENT8 iface) {
87         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
88         return IDirectMusicSegment8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
89 }
90
91 ULONG WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_Release (LPDIRECTMUSICSEGMENT8 iface) {
92         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
93         return IDirectMusicSegment8Impl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
94 }
95
96 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtLength) {
97         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
98         FIXME("(%p, %p): stub\n", This, pmtLength);
99         return S_OK;
100 }
101
102 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtLength) {
103         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
104         FIXME("(%p, %ld): stub\n", This, mtLength);
105         return S_OK;
106 }
107
108 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwRepeats) { 
109         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
110         FIXME("(%p, %p): stub\n", This, pdwRepeats);
111         return S_OK;
112 }
113
114 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD dwRepeats) {
115         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
116         FIXME("(%p, %ld): stub\n", This, dwRepeats);    
117         return S_OK;
118 }
119
120 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwResolution) {
121         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
122         FIXME("(%p, %p): stub\n", This, pdwResolution);
123         return S_OK;
124 }
125
126 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD dwResolution) {
127         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
128         FIXME("(%p, %ld): stub\n", This, dwResolution);
129         return S_OK;
130 }
131
132 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetTrack (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, IDirectMusicTrack** ppTrack) {
133         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
134         FIXME("(%p, %s, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, ppTrack);
135         return S_OK;
136 }
137
138 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetTrackGroup (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD* pdwGroupBits) {
139         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
140         FIXME("(%p, %p, %p): stub\n", This, pTrack, pdwGroupBits);
141         return S_OK;
142 }
143
144 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits) {
145         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
146         FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
147         return S_OK;
148 }
149
150 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack) {
151         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
152         FIXME("(%p, %p): stub\n", This, pTrack);
153         return S_OK;
154 }
155
156 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags) {
157         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
158         FIXME("(%p, %p, %p, %ld): stub\n", This, ppSegState, pPerformance, dwFlags);
159         return S_OK;
160 }
161
162 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph** ppGraph) {
163         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
164         FIXME("(%p, %p): stub\n", This, ppGraph);
165         return S_OK;
166 }
167
168 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph* pGraph) {
169         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
170         FIXME("(%p, %p): stub\n", This, pGraph);
171         return S_OK;
172 }
173
174 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_AddNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType) {
175         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
176         FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
177         return S_OK;
178 }
179
180 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_RemoveNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType) {
181         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
182         FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
183         return S_OK;
184 }
185
186 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam) {
187         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
188         FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
189         return S_OK;
190 }
191
192 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam) {
193         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
194         FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
195         return S_OK;
196 }
197
198 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_Clone (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicSegment** ppSegment) {
199         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
200         FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppSegment);
201         return S_OK;
202 }
203
204 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart) {
205         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
206         FIXME("(%p, %ld): stub\n", This, mtStart);
207         return S_OK;
208 }
209
210 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart) {
211         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
212         FIXME("(%p, %p): stub\n", This, pmtStart);
213         return S_OK;
214 }
215
216 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd) {
217         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
218         FIXME("(%p, %ld, %ld): stub\n", This, mtStart, mtEnd);
219         return S_OK;
220 }
221
222 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart, MUSIC_TIME* pmtEnd) {
223         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
224         FIXME("(%p, %p, %p): stub\n", This, pmtStart, pmtEnd);
225         return S_OK;
226 }
227
228 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetPChannelsUsed (LPDIRECTMUSICSEGMENT8 iface, DWORD dwNumPChannels, DWORD* paPChannels) {
229         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
230         FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);      
231         return S_OK;
232 }
233
234 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_SetTrackConfig (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff) {
235         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
236         FIXME("(%p, %s, %ld, %ld, %ld, %ld): stub\n", This, debugstr_dmguid(rguidTrackClassID), dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
237         return S_OK;
238 }
239
240 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_GetAudioPathConfig (LPDIRECTMUSICSEGMENT8 iface, IUnknown** ppAudioPathConfig){
241         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
242         FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
243         return S_OK;
244 }
245
246 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_Compose (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtTime, IDirectMusicSegment* pFromSegment, IDirectMusicSegment* pToSegment, IDirectMusicSegment** ppComposedSegment) {
247         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
248         FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
249         return S_OK;
250 }
251
252 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_Download (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath) {
253         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
254         FIXME("(%p, %p): stub\n", This, pAudioPath);
255         return S_OK;
256 }
257
258 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicSegment8_Unload (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath) {
259         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, SegmentVtbl, iface);
260         FIXME("(%p, %p): stub\n", This, pAudioPath);
261         return S_OK;
262 }
263
264 ICOM_VTABLE(IDirectMusicSegment8) DirectMusicSegment8_Segment_Vtbl = {
265     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
266         IDirectMusicSegment8Impl_IDirectMusicSegment8_QueryInterface,
267         IDirectMusicSegment8Impl_IDirectMusicSegment8_AddRef,
268         IDirectMusicSegment8Impl_IDirectMusicSegment8_Release,
269         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetLength,
270         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetLength,
271         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetRepeats,
272         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetRepeats,
273         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetDefaultResolution,
274         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetDefaultResolution,
275         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetTrack,
276         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetTrackGroup,
277         IDirectMusicSegment8Impl_IDirectMusicSegment8_InsertTrack,
278         IDirectMusicSegment8Impl_IDirectMusicSegment8_RemoveTrack,
279         IDirectMusicSegment8Impl_IDirectMusicSegment8_InitPlay,
280         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetGraph,
281         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetGraph,
282         IDirectMusicSegment8Impl_IDirectMusicSegment8_AddNotificationType,
283         IDirectMusicSegment8Impl_IDirectMusicSegment8_RemoveNotificationType,
284         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetParam,
285         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetParam,
286         IDirectMusicSegment8Impl_IDirectMusicSegment8_Clone,
287         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetStartPoint,
288         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetStartPoint,
289         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetLoopPoints,
290         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetLoopPoints,
291         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetPChannelsUsed,
292         IDirectMusicSegment8Impl_IDirectMusicSegment8_SetTrackConfig,
293         IDirectMusicSegment8Impl_IDirectMusicSegment8_GetAudioPathConfig,
294         IDirectMusicSegment8Impl_IDirectMusicSegment8_Compose,
295         IDirectMusicSegment8Impl_IDirectMusicSegment8_Download,
296         IDirectMusicSegment8Impl_IDirectMusicSegment8_Unload
297 };
298
299 /* IDirectMusicSegment8Impl IDirectMusicObject part: */
300 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
301         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, ObjectVtbl, iface);
302         return IDirectMusicSegment8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
303 }
304
305 ULONG WINAPI IDirectMusicSegment8Impl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
306         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, ObjectVtbl, iface);
307         return IDirectMusicSegment8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
308 }
309
310 ULONG WINAPI IDirectMusicSegment8Impl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
311         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, ObjectVtbl, iface);
312         return IDirectMusicSegment8Impl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
313 }
314
315 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
316         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, ObjectVtbl, iface);
317         TRACE("(%p, %p)\n", This, pDesc);
318         /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
319         memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
320         return S_OK;
321 }
322
323 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
324         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, ObjectVtbl, iface);
325         TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc));
326         
327         /* According to MSDN, we should copy only given values, not whole struct */     
328         if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
329                 memcpy (&This->pDesc->guidObject, &pDesc->guidObject, sizeof (pDesc->guidObject));
330         if (pDesc->dwValidData & DMUS_OBJ_CLASS)
331                 memcpy (&This->pDesc->guidClass, &pDesc->guidClass, sizeof (pDesc->guidClass));         
332         if (pDesc->dwValidData & DMUS_OBJ_NAME)
333                 strncpyW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
334         if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
335                 strncpyW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);             
336         if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
337                 strncpyW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);             
338         if (pDesc->dwValidData & DMUS_OBJ_VERSION)
339                 memcpy (&This->pDesc->vVersion, &pDesc->vVersion, sizeof (pDesc->vVersion));                            
340         if (pDesc->dwValidData & DMUS_OBJ_DATE)
341                 memcpy (&This->pDesc->ftDate, &pDesc->ftDate, sizeof (pDesc->ftDate));                          
342         if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
343                 memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength));                           
344                 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData));
345         }
346         if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
347                 /* according to MSDN, we copy the stream */
348                 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);  
349         }
350         
351         /* add new flags */
352         This->pDesc->dwValidData |= pDesc->dwValidData;
353
354         return S_OK;
355 }
356
357 HRESULT WINAPI IDirectMusicSegment8Impl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
358         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, ObjectVtbl, iface);
359         DMUS_PRIVATE_CHUNK Chunk;
360         DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
361         LARGE_INTEGER liMove; /* used when skipping chunks */
362
363         TRACE("(%p,%p, %p)\n", This, pStream, pDesc);
364         
365         /* FIXME: should this be determined from stream? */
366         pDesc->dwValidData |= DMUS_OBJ_CLASS;
367         memcpy (&pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof(CLSID));
368         
369         IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
370         TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
371         switch (Chunk.fccID) {  
372                 case FOURCC_RIFF: {
373                         IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);                             
374                         TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
375                         StreamSize = Chunk.dwSize - sizeof(FOURCC);
376                         StreamCount = 0;
377                         if (Chunk.fccID == DMUS_FOURCC_SEGMENT_FORM) {
378                                 TRACE_(dmfile)(": segment form\n");
379                                 do {
380                                         IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
381                                         StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
382                                         TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
383                                         switch (Chunk.fccID) {
384                                                 case DMUS_FOURCC_GUID_CHUNK: {
385                                                         TRACE_(dmfile)(": GUID chunk\n");
386                                                         pDesc->dwValidData |= DMUS_OBJ_OBJECT;
387                                                         IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
388                                                         break;
389                                                 }
390                                                 case DMUS_FOURCC_VERSION_CHUNK: {
391                                                         TRACE_(dmfile)(": version chunk\n");
392                                                         pDesc->dwValidData |= DMUS_OBJ_VERSION;
393                                                         IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
394                                                         break;
395                                                 }
396                                                 case DMUS_FOURCC_CATEGORY_CHUNK: {
397                                                         TRACE_(dmfile)(": category chunk\n");
398                                                         pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
399                                                         IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
400                                                         break;
401                                                 }
402                                                 case FOURCC_LIST: {
403                                                         IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);                             
404                                                         TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
405                                                         ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
406                                                         ListCount[0] = 0;
407                                                         switch (Chunk.fccID) {
408                                                                 /* evil M$ UNFO list, which can (!?) contain INFO elements */
409                                                                 case DMUS_FOURCC_UNFO_LIST: {
410                                                                         TRACE_(dmfile)(": UNFO list\n");
411                                                                         do {
412                                                                                 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
413                                                                                 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
414                                                                                 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
415                                                                                 switch (Chunk.fccID) {
416                                                                                         /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
417                                                                                            (though strings seem to be valid unicode) */
418                                                                                         case mmioFOURCC('I','N','A','M'):
419                                                                                         case DMUS_FOURCC_UNAM_CHUNK: {
420                                                                                                 TRACE_(dmfile)(": name chunk\n");
421                                                                                                 pDesc->dwValidData |= DMUS_OBJ_NAME;
422                                                                                                 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
423                                                                                                 break;
424                                                                                         }
425                                                                                         case mmioFOURCC('I','A','R','T'):
426                                                                                         case DMUS_FOURCC_UART_CHUNK: {
427                                                                                                 TRACE_(dmfile)(": artist chunk (ignored)\n");
428                                                                                                 liMove.QuadPart = Chunk.dwSize;
429                                                                                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
430                                                                                                 break;
431                                                                                         }
432                                                                                         case mmioFOURCC('I','C','O','P'):
433                                                                                         case DMUS_FOURCC_UCOP_CHUNK: {
434                                                                                                 TRACE_(dmfile)(": copyright chunk (ignored)\n");
435                                                                                                 liMove.QuadPart = Chunk.dwSize;
436                                                                                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
437                                                                                                 break;
438                                                                                         }
439                                                                                         case mmioFOURCC('I','S','B','J'):
440                                                                                         case DMUS_FOURCC_USBJ_CHUNK: {
441                                                                                                 TRACE_(dmfile)(": subject chunk (ignored)\n");
442                                                                                                 liMove.QuadPart = Chunk.dwSize;
443                                                                                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
444                                                                                                 break;
445                                                                                         }
446                                                                                         case mmioFOURCC('I','C','M','T'):
447                                                                                         case DMUS_FOURCC_UCMT_CHUNK: {
448                                                                                                 TRACE_(dmfile)(": comment chunk (ignored)\n");
449                                                                                                 liMove.QuadPart = Chunk.dwSize;
450                                                                                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
451                                                                                                 break;
452                                                                                         }
453                                                                                         default: {
454                                                                                                 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
455                                                                                                 liMove.QuadPart = Chunk.dwSize;
456                                                                                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
457                                                                                                 break;                                          
458                                                                                         }
459                                                                                 }
460                                                                                 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
461                                                                         } while (ListCount[0] < ListSize[0]);
462                                                                         break;
463                                                                 }
464                                                                 case DMUS_FOURCC_TRACK_LIST: {
465                                                                   TRACE_(dmfile)(": TRACK list\n");
466                                                                   do {
467                                                                     IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
468                                                                     ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
469                                                                     TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
470                                                                     switch (Chunk.fccID) {
471                                                                     default: {
472                                                                       TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
473                                                                       liMove.QuadPart = Chunk.dwSize;
474                                                                       IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
475                                                                       break;                                            
476                                                                     }
477                                                                     }
478                                                                     TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
479                                                                   } while (ListCount[0] < ListSize[0]);
480                                                                   break;
481                                                                 }
482                                                                 default: {
483                                                                   TRACE_(dmfile)(": unknown (skipping)\n");
484                                                                   liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
485                                                                   IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
486                                                                   break;                                                
487                                                                 }
488                                                         }
489                                                         break;
490                                                 }       
491                                                 default: {
492                                                         TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
493                                                         liMove.QuadPart = Chunk.dwSize;
494                                                         IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
495                                                         break;                                          
496                                                 }
497                                         }
498                                         TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
499                                 } while (StreamCount < StreamSize);
500                                 break;
501                         } else if (Chunk.fccID == mmioFOURCC('W','A','V','E')) {
502                                 TRACE_(dmfile)(": wave form, loading not yet implemented\n");
503                                 liMove.QuadPart = StreamSize;
504                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
505                         } else {
506                                 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
507                                 liMove.QuadPart = StreamSize;
508                                 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
509                                 return E_FAIL;
510                         }
511                 
512                         TRACE_(dmfile)(": reading finished\n");
513                         break;
514                 }
515                 default: {
516                         TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
517                         liMove.QuadPart = Chunk.dwSize;
518                         IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
519                         return DMUS_E_INVALIDFILE;
520                 }
521         }       
522         
523         TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc));
524         
525         return S_OK;
526 }
527
528 ICOM_VTABLE(IDirectMusicObject) DirectMusicSegment8_Object_Vtbl = {
529     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
530         IDirectMusicSegment8Impl_IDirectMusicObject_QueryInterface,
531         IDirectMusicSegment8Impl_IDirectMusicObject_AddRef,
532         IDirectMusicSegment8Impl_IDirectMusicObject_Release,
533         IDirectMusicSegment8Impl_IDirectMusicObject_GetDescriptor,
534         IDirectMusicSegment8Impl_IDirectMusicObject_SetDescriptor,
535         IDirectMusicSegment8Impl_IDirectMusicObject_ParseDescriptor
536 };
537
538 /* IDirectMusicSegment8Impl IPersistStream part: */
539 HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
540         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, PersistStreamVtbl, iface);
541         return IDirectMusicSegment8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
542 }
543
544 ULONG WINAPI IDirectMusicSegment8Impl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
545         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, PersistStreamVtbl, iface);
546         return IDirectMusicSegment8Impl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
547 }
548
549 ULONG WINAPI IDirectMusicSegment8Impl_IPersistStream_Release (LPPERSISTSTREAM iface) {
550         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, PersistStreamVtbl, iface);
551         return IDirectMusicSegment8Impl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
552 }
553
554 HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
555         return E_NOTIMPL;
556 }
557
558 HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
559         return E_NOTIMPL;
560 }
561
562 HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
563         ICOM_THIS_MULTI(IDirectMusicSegment8Impl, PersistStreamVtbl, iface);
564         FOURCC chunkID;
565         DWORD chunkSize;
566         DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
567         LARGE_INTEGER liMove; /* used when skipping chunks */
568
569         FIXME("(%p, %p): Loading not implemented yet\n", This, pStm);
570         IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
571         IStream_Read (pStm, &chunkSize, sizeof(DWORD), NULL);
572         TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
573         switch (chunkID) {      
574                 case FOURCC_RIFF: {
575                         IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);                            
576                         TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(chunkID));
577                         StreamSize = chunkSize - sizeof(FOURCC);
578                         StreamCount = 0;
579                         switch (chunkID) {
580                                 case DMUS_FOURCC_SEGMENT_FORM: {
581                                         TRACE_(dmfile)(": segment form\n");
582                                         do {
583                                                 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
584                                                 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
585                                                 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
586                                                 TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
587                                                 switch (chunkID) {
588                                                         case DMUS_FOURCC_GUID_CHUNK: {
589                                                                 TRACE_(dmfile)(": GUID chunk\n");
590                                                                 This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
591                                                                 IStream_Read (pStm, &This->pDesc->guidObject, chunkSize, NULL);
592                                                                 break;
593                                                         }
594                                                         case DMUS_FOURCC_VERSION_CHUNK: {
595                                                                 TRACE_(dmfile)(": version chunk\n");
596                                                                 This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
597                                                                 IStream_Read (pStm, &This->pDesc->vVersion, chunkSize, NULL);
598                                                                 break;
599                                                         }
600                                                         case DMUS_FOURCC_CATEGORY_CHUNK: {
601                                                                 TRACE_(dmfile)(": category chunk\n");
602                                                                 This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
603                                                                 IStream_Read (pStm, This->pDesc->wszCategory, chunkSize, NULL);
604                                                                 break;
605                                                         }
606                                                         case FOURCC_LIST: {
607                                                                 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);                            
608                                                                 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunkID));
609                                                                 ListSize[0] = chunkSize - sizeof(FOURCC);
610                                                                 ListCount[0] = 0;
611                                                                 switch (chunkID) {
612                                                                         case DMUS_FOURCC_UNFO_LIST: {
613                                                                                 TRACE_(dmfile)(": UNFO list\n");
614                                                                                 do {
615                                                                                         IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
616                                                                                         IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
617                                                                                         ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
618                                                                                         TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
619                                                                                         switch (chunkID) {
620                                                                                                 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
621                                                                                                    (though strings seem to be valid unicode) */
622                                                                                                 case mmioFOURCC('I','N','A','M'):
623                                                                                                 case DMUS_FOURCC_UNAM_CHUNK: {
624                                                                                                         TRACE_(dmfile)(": name chunk\n");
625                                                                                                         This->pDesc->dwValidData |= DMUS_OBJ_NAME;
626                                                                                                         IStream_Read (pStm, This->pDesc->wszName, chunkSize, NULL);
627                                                                                                         break;
628                                                                                                 }
629                                                                                                 case mmioFOURCC('I','A','R','T'):
630                                                                                                 case DMUS_FOURCC_UART_CHUNK: {
631                                                                                                         TRACE_(dmfile)(": artist chunk (ignored)\n");
632                                                                                                         liMove.QuadPart = chunkSize;
633                                                                                                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
634                                                                                                         break;
635                                                                                                 }
636                                                                                                 case mmioFOURCC('I','C','O','P'):
637                                                                                                 case DMUS_FOURCC_UCOP_CHUNK: {
638                                                                                                         TRACE_(dmfile)(": copyright chunk (ignored)\n");
639                                                                                                         liMove.QuadPart = chunkSize;
640                                                                                                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
641                                                                                                         break;
642                                                                                                 }
643                                                                                                 case mmioFOURCC('I','S','B','J'):
644                                                                                                 case DMUS_FOURCC_USBJ_CHUNK: {
645                                                                                                         TRACE_(dmfile)(": subject chunk (ignored)\n");
646                                                                                                         liMove.QuadPart = chunkSize;
647                                                                                                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
648                                                                                                         break;
649                                                                                                 }
650                                                                                                 case mmioFOURCC('I','C','M','T'):
651                                                                                                 case DMUS_FOURCC_UCMT_CHUNK: {
652                                                                                                         TRACE_(dmfile)(": comment chunk (ignored)\n");
653                                                                                                         liMove.QuadPart = chunkSize;
654                                                                                                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
655                                                                                                         break;
656                                                                                                 }
657                                                                                                 default: {
658                                                                                                         TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
659                                                                                                         liMove.QuadPart = chunkSize;
660                                                                                                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
661                                                                                                         break;                                          
662                                                                                                 }
663                                                                                         }
664                                                                                         TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
665                                                                                 } while (ListCount[0] < ListSize[0]);
666                                                                                 break;
667                                                                         }
668                                                                         case DMUS_FOURCC_TRACK_LIST: {
669                                                                           TRACE_(dmfile)(": TRACK list\n");
670                                                                           do {
671                                                                             IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
672                                                                             IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
673                                                                             ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
674                                                                             TRACE_(dmfile)(": %s chunk (size = %ld)", debugstr_fourcc (chunkID), chunkSize);
675                                                                             switch (chunkID) {
676                                                                               default: {
677                                                                                 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
678                                                                                 liMove.QuadPart = chunkSize;
679                                                                                 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
680                                                                                 break;                                          
681                                                                               }
682                                                                             }
683                                                                             TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
684                                                                           } while (ListCount[0] < ListSize[0]);
685                                                                           break;
686                                                                         }
687                                                                         default: {
688                                                                                 TRACE_(dmfile)(": unknown (skipping)\n");
689                                                                                 liMove.QuadPart = chunkSize - sizeof(FOURCC);
690                                                                                 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
691                                                                                 break;                                          
692                                                                         }
693                                                                 }
694                                                                 break;
695                                                         }       
696                                                         default: {
697                                                                 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
698                                                                 liMove.QuadPart = chunkSize;
699                                                                 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
700                                                                 break;                                          
701                                                         }
702                                                 }
703                                                 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
704                                         } while (StreamCount < StreamSize);
705                                         break;
706                                 }
707                                 default: {
708                                         TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
709                                         liMove.QuadPart = StreamSize;
710                                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
711                                         return E_FAIL;
712                                 }
713                         }
714                         TRACE_(dmfile)(": reading finished\n");
715                         break;
716                 }
717                 default: {
718                         TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
719                         liMove.QuadPart = chunkSize;
720                         IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
721                         return E_FAIL;
722                 }
723         }
724
725         return S_OK;
726 }
727
728 HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
729         return E_NOTIMPL;
730 }
731
732 HRESULT WINAPI IDirectMusicSegment8Impl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
733         return E_NOTIMPL;
734 }
735
736 ICOM_VTABLE(IPersistStream) DirectMusicSegment8_PersistStream_Vtbl = {
737     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
738         IDirectMusicSegment8Impl_IPersistStream_QueryInterface,
739         IDirectMusicSegment8Impl_IPersistStream_AddRef,
740         IDirectMusicSegment8Impl_IPersistStream_Release,
741         IDirectMusicSegment8Impl_IPersistStream_GetClassID,
742         IDirectMusicSegment8Impl_IPersistStream_IsDirty,
743         IDirectMusicSegment8Impl_IPersistStream_Load,
744         IDirectMusicSegment8Impl_IPersistStream_Save,
745         IDirectMusicSegment8Impl_IPersistStream_GetSizeMax
746 };
747
748 /* for ClassFactory */
749 HRESULT WINAPI DMUSIC_CreateDirectMusicSegmentImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) {
750         IDirectMusicSegment8Impl* obj;
751         
752         obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicSegment8Impl));
753         if (NULL == obj) {
754                 *ppobj = (LPVOID) NULL;
755                 return E_OUTOFMEMORY;
756         }
757         obj->UnknownVtbl = &DirectMusicSegment8_Unknown_Vtbl;
758         obj->SegmentVtbl = &DirectMusicSegment8_Segment_Vtbl;
759         obj->ObjectVtbl = &DirectMusicSegment8_Object_Vtbl;
760         obj->PersistStreamVtbl = &DirectMusicSegment8_PersistStream_Vtbl;
761         obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
762         DM_STRUCT_INIT(obj->pDesc);
763         obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
764         memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof (CLSID));
765         obj->ref = 0; /* will be inited by QueryInterface */
766         
767         return IDirectMusicSegment8Impl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);
768 }