Get rid of the no longer used ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
[wine/dcerpc.git] / dlls / dswave / dswave.c
blob3e657e927b5bae4de3b7aaa33181f8db900e22c7
1 /* IDirectMusicWave Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "dswave_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dswave);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
25 /* an interface that is, according to my tests, obtained by loader after loading object; is it acting
26 as some sort of bridge between object and loader? */
27 const GUID IID_IDirectMusicWavePRIVATE = {0x69e934e4,0x97f1,0x4f1d,{0x88,0xe8,0xf2,0xac,0x88,0x67,0x13,0x27}};
29 /*****************************************************************************
30 * IDirectMusicWaveImpl implementation
32 /* IDirectMusicWaveImpl IUnknown part: */
33 HRESULT WINAPI IDirectMusicWaveImpl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) {
34 ICOM_THIS_MULTI(IDirectMusicWaveImpl, UnknownVtbl, iface);
36 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj);
38 if (IsEqualIID (riid, &IID_IUnknown)) {
39 *ppobj = (LPVOID)&This->UnknownVtbl;
40 IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
41 return S_OK;
42 } else if (IsEqualIID (riid, &IID_IDirectMusicSegment)
43 || IsEqualIID (riid, &IID_IDirectMusicSegment2)
44 || IsEqualIID (riid, &IID_IDirectMusicSegment8)) {
45 *ppobj = (LPVOID)&This->SegmentVtbl;
46 IDirectMusicWaveImpl_IDirectMusicSegment8_AddRef ((LPDIRECTMUSICSEGMENT8)&This->SegmentVtbl);
47 return S_OK;
48 } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) {
49 *ppobj = (LPVOID)&This->ObjectVtbl;
50 IDirectMusicWaveImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT)&This->ObjectVtbl);
51 return S_OK;
52 } else if (IsEqualIID (riid, &IID_IPersistStream)) {
53 *ppobj = (LPVOID)&This->PersistStreamVtbl;
54 IDirectMusicWaveImpl_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl);
55 return S_OK;
56 } else if (IsEqualIID (riid, &IID_IDirectMusicWavePRIVATE)) {
57 WARN(": requested private interface, expect crash\n");
58 return E_NOINTERFACE;
61 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj);
62 return E_NOINTERFACE;
65 ULONG WINAPI IDirectMusicWaveImpl_IUnknown_AddRef (LPUNKNOWN iface) {
66 ICOM_THIS_MULTI(IDirectMusicWaveImpl, UnknownVtbl, iface);
67 TRACE("(%p): AddRef from %ld\n", This, This->ref);
68 return ++(This->ref);
71 ULONG WINAPI IDirectMusicWaveImpl_IUnknown_Release (LPUNKNOWN iface) {
72 ICOM_THIS_MULTI(IDirectMusicWaveImpl, UnknownVtbl, iface);
73 ULONG ref = --This->ref;
74 TRACE("(%p): ReleaseRef to %ld\n", This, This->ref);
75 if (ref == 0) {
76 HeapFree(GetProcessHeap(), 0, This);
78 return ref;
81 IUnknownVtbl DirectMusicWave_Unknown_Vtbl = {
82 IDirectMusicWaveImpl_IUnknown_QueryInterface,
83 IDirectMusicWaveImpl_IUnknown_AddRef,
84 IDirectMusicWaveImpl_IUnknown_Release
87 /* IDirectMusicSegment8Impl IDirectMusicSegment part: */
88 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_QueryInterface (LPDIRECTMUSICSEGMENT8 iface, REFIID riid, LPVOID *ppobj) {
89 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
90 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
93 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_AddRef (LPDIRECTMUSICSEGMENT8 iface) {
94 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
95 return IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
98 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Release (LPDIRECTMUSICSEGMENT8 iface) {
99 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
100 return IDirectMusicWaveImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
103 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtLength) {
104 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
105 FIXME("(%p, %p): stub\n", This, pmtLength);
106 return S_OK;
109 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetLength (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtLength) {
110 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
111 FIXME("(%p, %ld): stub\n", This, mtLength);
112 return S_OK;
115 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwRepeats) {
116 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
117 FIXME("(%p, %p): stub\n", This, pdwRepeats);
118 return S_OK;
121 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetRepeats (LPDIRECTMUSICSEGMENT8 iface, DWORD dwRepeats) {
122 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
123 FIXME("(%p, %ld): stub\n", This, dwRepeats);
124 return S_OK;
127 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD* pdwResolution) {
128 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
129 FIXME("(%p, %p): stub\n", This, pdwResolution);
130 return S_OK;
133 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetDefaultResolution (LPDIRECTMUSICSEGMENT8 iface, DWORD dwResolution) {
134 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
135 FIXME("(%p, %ld): stub\n", This, dwResolution);
136 return S_OK;
139 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrack (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, IDirectMusicTrack** ppTrack) {
140 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
141 FIXME("(%p, %s, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, ppTrack);
142 return S_OK;
145 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrackGroup (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD* pdwGroupBits) {
146 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
147 FIXME("(%p, %p, %p): stub\n", This, pTrack, pdwGroupBits);
148 return S_OK;
151 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_InsertTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack, DWORD dwGroupBits) {
152 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
153 FIXME("(%p, %p, %ld): stub\n", This, pTrack, dwGroupBits);
154 return S_OK;
157 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveTrack (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicTrack* pTrack) {
158 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
159 FIXME("(%p, %p): stub\n", This, pTrack);
160 return S_OK;
163 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_InitPlay (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicSegmentState** ppSegState, IDirectMusicPerformance* pPerformance, DWORD dwFlags) {
164 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
165 FIXME("(%p, %p, %p, %ld): stub\n", This, ppSegState, pPerformance, dwFlags);
166 return S_OK;
169 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph** ppGraph) {
170 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
171 FIXME("(%p, %p): stub\n", This, ppGraph);
172 return S_OK;
175 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetGraph (LPDIRECTMUSICSEGMENT8 iface, IDirectMusicGraph* pGraph) {
176 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
177 FIXME("(%p, %p): stub\n", This, pGraph);
178 return S_OK;
181 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_AddNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType) {
182 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
183 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
184 return S_OK;
187 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveNotificationType (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidNotificationType) {
188 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
189 FIXME("(%p, %s): stub\n", This, debugstr_dmguid(rguidNotificationType));
190 return S_OK;
193 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, MUSIC_TIME* pmtNext, void* pParam) {
194 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
195 FIXME("(%p, %s, %ld, %ld, %ld, %p, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pmtNext, pParam);
196 return S_OK;
199 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetParam (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidType, DWORD dwGroupBits, DWORD dwIndex, MUSIC_TIME mtTime, void* pParam) {
200 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
201 FIXME("(%p, %s, %ld, %ld, %ld, %p): stub\n", This, debugstr_dmguid(rguidType), dwGroupBits, dwIndex, mtTime, pParam);
202 return S_OK;
205 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Clone (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd, IDirectMusicSegment** ppSegment) {
206 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
207 FIXME("(%p, %ld, %ld, %p): stub\n", This, mtStart, mtEnd, ppSegment);
208 return S_OK;
211 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart) {
212 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
213 FIXME("(%p, %ld): stub\n", This, mtStart);
214 return S_OK;
217 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetStartPoint (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart) {
218 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
219 FIXME("(%p, %p): stub\n", This, pmtStart);
220 return S_OK;
223 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtStart, MUSIC_TIME mtEnd) {
224 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
225 FIXME("(%p, %ld, %ld): stub\n", This, mtStart, mtEnd);
226 return S_OK;
229 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetLoopPoints (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME* pmtStart, MUSIC_TIME* pmtEnd) {
230 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
231 FIXME("(%p, %p, %p): stub\n", This, pmtStart, pmtEnd);
232 return S_OK;
235 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetPChannelsUsed (LPDIRECTMUSICSEGMENT8 iface, DWORD dwNumPChannels, DWORD* paPChannels) {
236 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
237 FIXME("(%p, %ld, %p): stub\n", This, dwNumPChannels, paPChannels);
238 return S_OK;
241 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_SetTrackConfig (LPDIRECTMUSICSEGMENT8 iface, REFGUID rguidTrackClassID, DWORD dwGroupBits, DWORD dwIndex, DWORD dwFlagsOn, DWORD dwFlagsOff) {
242 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
243 FIXME("(%p, %s, %ld, %ld, %ld, %ld): stub\n", This, debugstr_dmguid(rguidTrackClassID), dwGroupBits, dwIndex, dwFlagsOn, dwFlagsOff);
244 return S_OK;
247 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_GetAudioPathConfig (LPDIRECTMUSICSEGMENT8 iface, IUnknown** ppAudioPathConfig){
248 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
249 FIXME("(%p, %p): stub\n", This, ppAudioPathConfig);
250 return S_OK;
253 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Compose (LPDIRECTMUSICSEGMENT8 iface, MUSIC_TIME mtTime, IDirectMusicSegment* pFromSegment, IDirectMusicSegment* pToSegment, IDirectMusicSegment** ppComposedSegment) {
254 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
255 FIXME("(%p, %ld, %p, %p, %p): stub\n", This, mtTime, pFromSegment, pToSegment, ppComposedSegment);
256 return S_OK;
259 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Download (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath) {
260 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
261 FIXME("(%p, %p): stub\n", This, pAudioPath);
262 return S_OK;
265 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicSegment8_Unload (LPDIRECTMUSICSEGMENT8 iface, IUnknown *pAudioPath) {
266 ICOM_THIS_MULTI(IDirectMusicWaveImpl, SegmentVtbl, iface);
267 FIXME("(%p, %p): stub\n", This, pAudioPath);
268 return S_OK;
271 IDirectMusicSegment8Vtbl DirectMusicSegment8_Segment_Vtbl = {
272 IDirectMusicWaveImpl_IDirectMusicSegment8_QueryInterface,
273 IDirectMusicWaveImpl_IDirectMusicSegment8_AddRef,
274 IDirectMusicWaveImpl_IDirectMusicSegment8_Release,
275 IDirectMusicWaveImpl_IDirectMusicSegment8_GetLength,
276 IDirectMusicWaveImpl_IDirectMusicSegment8_SetLength,
277 IDirectMusicWaveImpl_IDirectMusicSegment8_GetRepeats,
278 IDirectMusicWaveImpl_IDirectMusicSegment8_SetRepeats,
279 IDirectMusicWaveImpl_IDirectMusicSegment8_GetDefaultResolution,
280 IDirectMusicWaveImpl_IDirectMusicSegment8_SetDefaultResolution,
281 IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrack,
282 IDirectMusicWaveImpl_IDirectMusicSegment8_GetTrackGroup,
283 IDirectMusicWaveImpl_IDirectMusicSegment8_InsertTrack,
284 IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveTrack,
285 IDirectMusicWaveImpl_IDirectMusicSegment8_InitPlay,
286 IDirectMusicWaveImpl_IDirectMusicSegment8_GetGraph,
287 IDirectMusicWaveImpl_IDirectMusicSegment8_SetGraph,
288 IDirectMusicWaveImpl_IDirectMusicSegment8_AddNotificationType,
289 IDirectMusicWaveImpl_IDirectMusicSegment8_RemoveNotificationType,
290 IDirectMusicWaveImpl_IDirectMusicSegment8_GetParam,
291 IDirectMusicWaveImpl_IDirectMusicSegment8_SetParam,
292 IDirectMusicWaveImpl_IDirectMusicSegment8_Clone,
293 IDirectMusicWaveImpl_IDirectMusicSegment8_SetStartPoint,
294 IDirectMusicWaveImpl_IDirectMusicSegment8_GetStartPoint,
295 IDirectMusicWaveImpl_IDirectMusicSegment8_SetLoopPoints,
296 IDirectMusicWaveImpl_IDirectMusicSegment8_GetLoopPoints,
297 IDirectMusicWaveImpl_IDirectMusicSegment8_SetPChannelsUsed,
298 IDirectMusicWaveImpl_IDirectMusicSegment8_SetTrackConfig,
299 IDirectMusicWaveImpl_IDirectMusicSegment8_GetAudioPathConfig,
300 IDirectMusicWaveImpl_IDirectMusicSegment8_Compose,
301 IDirectMusicWaveImpl_IDirectMusicSegment8_Download,
302 IDirectMusicWaveImpl_IDirectMusicSegment8_Unload
305 /* IDirectMusicWaveImpl IDirectMusicObject part: */
306 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
307 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
308 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
311 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
312 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
313 return IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
316 ULONG WINAPI IDirectMusicWaveImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
317 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
318 return IDirectMusicWaveImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
321 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
322 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
323 TRACE("(%p, %p)\n", This, pDesc);
324 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
325 memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
326 return S_OK;
329 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
330 ICOM_THIS_MULTI(IDirectMusicWaveImpl, ObjectVtbl, iface);
331 TRACE("(%p, %p, %s): setting descriptor:\n", This, pDesc, debugstr_DMUS_OBJECTDESC(pDesc));
333 /* According to MSDN, we should copy only given values, not whole struct */
334 if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
335 memcpy (&This->pDesc->guidObject, &pDesc->guidObject, sizeof (pDesc->guidObject));
336 if (pDesc->dwValidData & DMUS_OBJ_CLASS)
337 memcpy (&This->pDesc->guidClass, &pDesc->guidClass, sizeof (pDesc->guidClass));
338 if (pDesc->dwValidData & DMUS_OBJ_NAME)
339 strncpyW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
340 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
341 strncpyW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
342 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
343 strncpyW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
344 if (pDesc->dwValidData & DMUS_OBJ_VERSION)
345 memcpy (&This->pDesc->vVersion, &pDesc->vVersion, sizeof (pDesc->vVersion));
346 if (pDesc->dwValidData & DMUS_OBJ_DATE)
347 memcpy (&This->pDesc->ftDate, &pDesc->ftDate, sizeof (pDesc->ftDate));
348 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
349 memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength));
350 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData));
352 if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
353 /* according to MSDN, we copy the stream */
354 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
357 /* add new flags */
358 This->pDesc->dwValidData |= pDesc->dwValidData;
360 return S_OK;
363 HRESULT WINAPI IDirectMusicWaveImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
364 DMUS_PRIVATE_CHUNK Chunk;
365 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
366 LARGE_INTEGER liMove; /* used when skipping chunks */
368 TRACE("(%p, %p)\n", pStream, pDesc);
370 /* FIXME: should this be determined from stream? */
371 pDesc->dwValidData |= DMUS_OBJ_CLASS;
372 memcpy (&pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof(CLSID));
374 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
375 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
376 switch (Chunk.fccID) {
377 case FOURCC_RIFF: {
378 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
379 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
380 StreamSize = Chunk.dwSize - sizeof(FOURCC);
381 StreamCount = 0;
382 if (Chunk.fccID == mmioFOURCC('W','A','V','E')) {
383 TRACE_(dmfile)(": wave form\n");
384 do {
385 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
386 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
387 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
388 switch (Chunk.fccID) {
389 case DMUS_FOURCC_GUID_CHUNK: {
390 TRACE_(dmfile)(": GUID chunk\n");
391 pDesc->dwValidData |= DMUS_OBJ_OBJECT;
392 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
393 break;
395 case DMUS_FOURCC_VERSION_CHUNK: {
396 TRACE_(dmfile)(": version chunk\n");
397 pDesc->dwValidData |= DMUS_OBJ_VERSION;
398 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
399 break;
401 case DMUS_FOURCC_CATEGORY_CHUNK: {
402 TRACE_(dmfile)(": category chunk\n");
403 pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
404 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
405 break;
407 case FOURCC_LIST: {
408 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
409 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
410 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
411 ListCount[0] = 0;
412 switch (Chunk.fccID) {
413 /* evil M$ UNFO list, which can (!?) contain INFO elements */
414 case DMUS_FOURCC_UNFO_LIST: {
415 TRACE_(dmfile)(": UNFO list\n");
416 do {
417 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
418 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
419 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
420 switch (Chunk.fccID) {
421 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
422 (though strings seem to be valid unicode) */
423 case mmioFOURCC('I','N','A','M'):
424 case DMUS_FOURCC_UNAM_CHUNK: {
425 TRACE_(dmfile)(": name chunk\n");
426 pDesc->dwValidData |= DMUS_OBJ_NAME;
427 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
428 break;
430 case mmioFOURCC('I','A','R','T'):
431 case DMUS_FOURCC_UART_CHUNK: {
432 TRACE_(dmfile)(": artist chunk (ignored)\n");
433 liMove.QuadPart = Chunk.dwSize;
434 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
435 break;
437 case mmioFOURCC('I','C','O','P'):
438 case DMUS_FOURCC_UCOP_CHUNK: {
439 TRACE_(dmfile)(": copyright chunk (ignored)\n");
440 liMove.QuadPart = Chunk.dwSize;
441 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
442 break;
444 case mmioFOURCC('I','S','B','J'):
445 case DMUS_FOURCC_USBJ_CHUNK: {
446 TRACE_(dmfile)(": subject chunk (ignored)\n");
447 liMove.QuadPart = Chunk.dwSize;
448 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
449 break;
451 case mmioFOURCC('I','C','M','T'):
452 case DMUS_FOURCC_UCMT_CHUNK: {
453 TRACE_(dmfile)(": comment chunk (ignored)\n");
454 liMove.QuadPart = Chunk.dwSize;
455 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
456 break;
458 default: {
459 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
460 liMove.QuadPart = Chunk.dwSize;
461 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
462 break;
465 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
466 } while (ListCount[0] < ListSize[0]);
467 break;
469 default: {
470 TRACE_(dmfile)(": unknown (skipping)\n");
471 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
472 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
473 break;
476 break;
478 default: {
479 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
480 liMove.QuadPart = Chunk.dwSize;
481 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
482 break;
485 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
486 } while (StreamCount < StreamSize);
487 break;
488 } else {
489 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
490 liMove.QuadPart = StreamSize;
491 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
492 return E_FAIL;
495 TRACE_(dmfile)(": reading finished\n");
496 break;
498 default: {
499 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
500 liMove.QuadPart = Chunk.dwSize;
501 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
502 return DMUS_E_INVALIDFILE;
506 TRACE(": returning descriptor: %s\n", debugstr_DMUS_OBJECTDESC (pDesc));
508 return S_OK;
511 IDirectMusicObjectVtbl DirectMusicWave_Object_Vtbl = {
512 IDirectMusicWaveImpl_IDirectMusicObject_QueryInterface,
513 IDirectMusicWaveImpl_IDirectMusicObject_AddRef,
514 IDirectMusicWaveImpl_IDirectMusicObject_Release,
515 IDirectMusicWaveImpl_IDirectMusicObject_GetDescriptor,
516 IDirectMusicWaveImpl_IDirectMusicObject_SetDescriptor,
517 IDirectMusicWaveImpl_IDirectMusicObject_ParseDescriptor
520 /* IDirectMusicWaveImpl IPersistStream part: */
521 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
522 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
523 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj);
526 ULONG WINAPI IDirectMusicWaveImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
527 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
528 return IDirectMusicWaveImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl);
531 ULONG WINAPI IDirectMusicWaveImpl_IPersistStream_Release (LPPERSISTSTREAM iface) {
532 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
533 return IDirectMusicWaveImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl);
536 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
537 return E_NOTIMPL;
540 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
541 return E_NOTIMPL;
544 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
545 ICOM_THIS_MULTI(IDirectMusicWaveImpl, PersistStreamVtbl, iface);
547 DMUS_PRIVATE_CHUNK Chunk;
548 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
549 LARGE_INTEGER liMove; /* used when skipping chunks */
551 FIXME("(%p, %p): loading not implemented yet (only descriptor is loaded)\n", This, pStm);
553 /* FIXME: should this be determined from stream? */
554 This->pDesc->dwValidData |= DMUS_OBJ_CLASS;
555 memcpy (&This->pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof(CLSID));
557 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
558 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
559 switch (Chunk.fccID) {
560 case FOURCC_RIFF: {
561 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
562 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
563 StreamSize = Chunk.dwSize - sizeof(FOURCC);
564 StreamCount = 0;
565 if (Chunk.fccID == mmioFOURCC('W','A','V','E')) {
566 TRACE_(dmfile)(": wave form\n");
567 do {
568 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
569 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
570 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
571 switch (Chunk.fccID) {
572 case DMUS_FOURCC_GUID_CHUNK: {
573 TRACE_(dmfile)(": GUID chunk\n");
574 This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
575 IStream_Read (pStm, &This->pDesc->guidObject, Chunk.dwSize, NULL);
576 break;
578 case DMUS_FOURCC_VERSION_CHUNK: {
579 TRACE_(dmfile)(": version chunk\n");
580 This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
581 IStream_Read (pStm, &This->pDesc->vVersion, Chunk.dwSize, NULL);
582 break;
584 case DMUS_FOURCC_CATEGORY_CHUNK: {
585 TRACE_(dmfile)(": category chunk\n");
586 This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
587 IStream_Read (pStm, This->pDesc->wszCategory, Chunk.dwSize, NULL);
588 break;
590 case FOURCC_LIST: {
591 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
592 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
593 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
594 ListCount[0] = 0;
595 switch (Chunk.fccID) {
596 /* evil M$ UNFO list, which can (!?) contain INFO elements */
597 case DMUS_FOURCC_UNFO_LIST: {
598 TRACE_(dmfile)(": UNFO list\n");
599 do {
600 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
601 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
602 TRACE_(dmfile)(": %s chunk (size = 0x%04lx)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
603 switch (Chunk.fccID) {
604 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
605 (though strings seem to be valid unicode) */
606 case mmioFOURCC('I','N','A','M'):
607 case DMUS_FOURCC_UNAM_CHUNK: {
608 TRACE_(dmfile)(": name chunk\n");
609 This->pDesc->dwValidData |= DMUS_OBJ_NAME;
610 IStream_Read (pStm, This->pDesc->wszName, Chunk.dwSize, NULL);
611 break;
613 case mmioFOURCC('I','A','R','T'):
614 case DMUS_FOURCC_UART_CHUNK: {
615 TRACE_(dmfile)(": artist chunk (ignored)\n");
616 liMove.QuadPart = Chunk.dwSize;
617 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
618 break;
620 case mmioFOURCC('I','C','O','P'):
621 case DMUS_FOURCC_UCOP_CHUNK: {
622 TRACE_(dmfile)(": copyright chunk (ignored)\n");
623 liMove.QuadPart = Chunk.dwSize;
624 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
625 break;
627 case mmioFOURCC('I','S','B','J'):
628 case DMUS_FOURCC_USBJ_CHUNK: {
629 TRACE_(dmfile)(": subject chunk (ignored)\n");
630 liMove.QuadPart = Chunk.dwSize;
631 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
632 break;
634 case mmioFOURCC('I','C','M','T'):
635 case DMUS_FOURCC_UCMT_CHUNK: {
636 TRACE_(dmfile)(": comment chunk (ignored)\n");
637 liMove.QuadPart = Chunk.dwSize;
638 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
639 break;
641 default: {
642 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
643 liMove.QuadPart = Chunk.dwSize;
644 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
645 break;
648 TRACE_(dmfile)(": ListCount[0] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]);
649 } while (ListCount[0] < ListSize[0]);
650 break;
652 default: {
653 TRACE_(dmfile)(": unknown (skipping)\n");
654 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
655 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
656 break;
659 break;
661 default: {
662 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n");
663 liMove.QuadPart = Chunk.dwSize;
664 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
665 break;
668 TRACE_(dmfile)(": StreamCount[0] = %ld < StreamSize[0] = %ld\n", StreamCount, StreamSize);
669 } while (StreamCount < StreamSize);
670 break;
671 } else {
672 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
673 liMove.QuadPart = StreamSize;
674 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
675 return E_FAIL;
678 TRACE_(dmfile)(": reading finished\n");
679 break;
681 default: {
682 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
683 liMove.QuadPart = Chunk.dwSize;
684 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
685 return DMUS_E_INVALIDFILE;
689 return S_OK;
692 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
693 return E_NOTIMPL;
696 HRESULT WINAPI IDirectMusicWaveImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
697 return E_NOTIMPL;
700 IPersistStreamVtbl DirectMusicWave_PersistStream_Vtbl = {
701 IDirectMusicWaveImpl_IPersistStream_QueryInterface,
702 IDirectMusicWaveImpl_IPersistStream_AddRef,
703 IDirectMusicWaveImpl_IPersistStream_Release,
704 IDirectMusicWaveImpl_IPersistStream_GetClassID,
705 IDirectMusicWaveImpl_IPersistStream_IsDirty,
706 IDirectMusicWaveImpl_IPersistStream_Load,
707 IDirectMusicWaveImpl_IPersistStream_Save,
708 IDirectMusicWaveImpl_IPersistStream_GetSizeMax
712 /* for ClassFactory */
713 HRESULT WINAPI DMUSIC_CreateDirectMusicWaveImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) {
714 IDirectMusicWaveImpl* obj;
716 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicWaveImpl));
717 if (NULL == obj) {
718 *ppobj = (LPVOID) NULL;
719 return E_OUTOFMEMORY;
721 obj->UnknownVtbl = &DirectMusicWave_Unknown_Vtbl;
722 obj->ObjectVtbl = &DirectMusicWave_Object_Vtbl;
723 obj->PersistStreamVtbl = &DirectMusicWave_PersistStream_Vtbl;
724 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
725 DM_STRUCT_INIT(obj->pDesc);
726 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
727 memcpy (&obj->pDesc->guidClass, &CLSID_DirectMusicSegment, sizeof (CLSID)); /* shown by tests */
728 obj->ref = 0; /* will be inited by QueryInterface */
730 return IDirectMusicWaveImpl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj);