mshtml: Use get_elem_attr_value helper in npplugin.c.
[wine.git] / dlls / dmcompos / chordmap.c
blob9d2d8a9246586020dff34fb94b59a8308dfcfaee
1 /* IDirectMusicChordMap Implementation
3 * Copyright (C) 2003-2004 Rok Mandeljc
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (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 GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include "dmcompos_private.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(dmcompos);
23 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
25 /*****************************************************************************
26 * IDirectMusicChordMapImpl implementation
29 /* IDirectMusicChordMapImpl IDirectMusicChordMap part: */
30 static inline IDirectMusicChordMapImpl *impl_from_IDirectMusicChordMap(IDirectMusicChordMap *iface)
32 return CONTAINING_RECORD(iface, IDirectMusicChordMapImpl, IDirectMusicChordMap_iface);
35 static HRESULT WINAPI IDirectMusicChordMapImpl_QueryInterface(IDirectMusicChordMap *iface,
36 REFIID riid, void **ret_iface)
38 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
40 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
42 *ret_iface = NULL;
44 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicChordMap))
45 *ret_iface = iface;
46 else if (IsEqualIID(riid, &IID_IDirectMusicObject))
47 *ret_iface = &This->ObjectVtbl;
48 else if (IsEqualIID(riid, &IID_IPersistStream))
49 *ret_iface = &This->PersistStreamVtbl;
50 else {
51 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
52 return E_NOINTERFACE;
55 IUnknown_AddRef((IUnknown*)*ret_iface);
56 return S_OK;
59 static ULONG WINAPI IDirectMusicChordMapImpl_AddRef(IDirectMusicChordMap *iface)
61 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
62 LONG ref = InterlockedIncrement(&This->ref);
64 TRACE("(%p) ref=%d\n", This, ref);
66 return ref;
69 static ULONG WINAPI IDirectMusicChordMapImpl_Release(IDirectMusicChordMap *iface)
71 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
72 LONG ref = InterlockedDecrement(&This->ref);
74 TRACE("(%p) ref=%d\n", This, ref);
76 if (!ref) {
77 HeapFree(GetProcessHeap(), 0, This->pDesc);
78 HeapFree(GetProcessHeap(), 0, This);
79 DMCOMPOS_UnlockModule();
82 return ref;
85 static HRESULT WINAPI IDirectMusicChordMapImpl_GetScale(IDirectMusicChordMap *iface,
86 DWORD *pdwScale)
88 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
89 FIXME("(%p, %p): stub\n", This, pdwScale);
90 return S_OK;
93 static const IDirectMusicChordMapVtbl dmchordmap_vtbl = {
94 IDirectMusicChordMapImpl_QueryInterface,
95 IDirectMusicChordMapImpl_AddRef,
96 IDirectMusicChordMapImpl_Release,
97 IDirectMusicChordMapImpl_GetScale
100 /* IDirectMusicChordMapImpl IDirectMusicObject part: */
101 static HRESULT WINAPI IDirectMusicChordMapImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) {
102 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, ObjectVtbl, iface);
103 return IDirectMusicChordMap_QueryInterface(&This->IDirectMusicChordMap_iface, riid, ppobj);
106 static ULONG WINAPI IDirectMusicChordMapImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) {
107 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, ObjectVtbl, iface);
108 return IDirectMusicChordMap_AddRef(&This->IDirectMusicChordMap_iface);
111 static ULONG WINAPI IDirectMusicChordMapImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) {
112 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, ObjectVtbl, iface);
113 return IDirectMusicChordMap_Release(&This->IDirectMusicChordMap_iface);
116 static HRESULT WINAPI IDirectMusicChordMapImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
117 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, ObjectVtbl, iface);
118 TRACE("(%p, %p)\n", This, pDesc);
119 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
120 memcpy (pDesc, This->pDesc, This->pDesc->dwSize);
121 return S_OK;
124 static HRESULT WINAPI IDirectMusicChordMapImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) {
125 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, ObjectVtbl, iface);
126 TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc));
128 /* According to MSDN, we should copy only given values, not whole struct */
129 if (pDesc->dwValidData & DMUS_OBJ_OBJECT)
130 This->pDesc->guidObject = pDesc->guidObject;
131 if (pDesc->dwValidData & DMUS_OBJ_CLASS)
132 This->pDesc->guidClass = pDesc->guidClass;
133 if (pDesc->dwValidData & DMUS_OBJ_NAME)
134 lstrcpynW (This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME);
135 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY)
136 lstrcpynW (This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY);
137 if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
138 lstrcpynW (This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME);
139 if (pDesc->dwValidData & DMUS_OBJ_VERSION)
140 This->pDesc->vVersion = pDesc->vVersion;
141 if (pDesc->dwValidData & DMUS_OBJ_DATE)
142 This->pDesc->ftDate = pDesc->ftDate;
143 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
144 This->pDesc->llMemLength = pDesc->llMemLength;
145 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, pDesc->llMemLength);
147 if (pDesc->dwValidData & DMUS_OBJ_STREAM) {
148 /* according to MSDN, we copy the stream */
149 IStream_Clone (pDesc->pStream, &This->pDesc->pStream);
152 /* add new flags */
153 This->pDesc->dwValidData |= pDesc->dwValidData;
155 return S_OK;
158 static HRESULT WINAPI IDirectMusicChordMapImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) {
159 DMUS_PRIVATE_CHUNK Chunk;
160 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
161 LARGE_INTEGER liMove; /* used when skipping chunks */
163 TRACE("(%p, %p)\n", pStream, pDesc);
165 /* FIXME: should this be determined from stream? */
166 pDesc->dwValidData |= DMUS_OBJ_CLASS;
167 pDesc->guidClass = CLSID_DirectMusicChordMap;
169 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
170 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
171 switch (Chunk.fccID) {
172 case FOURCC_RIFF: {
173 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
174 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
175 StreamSize = Chunk.dwSize - sizeof(FOURCC);
176 StreamCount = 0;
177 if (Chunk.fccID == DMUS_FOURCC_CHORDMAP_FORM) {
178 TRACE_(dmfile)(": chord map form\n");
179 do {
180 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
181 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
182 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
183 switch (Chunk.fccID) {
184 case DMUS_FOURCC_GUID_CHUNK: {
185 TRACE_(dmfile)(": GUID chunk\n");
186 pDesc->dwValidData |= DMUS_OBJ_OBJECT;
187 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL);
188 break;
190 case DMUS_FOURCC_VERSION_CHUNK: {
191 TRACE_(dmfile)(": version chunk\n");
192 pDesc->dwValidData |= DMUS_OBJ_VERSION;
193 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL);
194 break;
196 case DMUS_FOURCC_CATEGORY_CHUNK: {
197 TRACE_(dmfile)(": category chunk\n");
198 pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
199 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL);
200 break;
202 case FOURCC_LIST: {
203 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL);
204 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
205 ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
206 ListCount[0] = 0;
207 switch (Chunk.fccID) {
208 /* evil M$ UNFO list, which can (!?) contain INFO elements */
209 case DMUS_FOURCC_UNFO_LIST: {
210 TRACE_(dmfile)(": UNFO list\n");
211 do {
212 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
213 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
214 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
215 switch (Chunk.fccID) {
216 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
217 (though strings seem to be valid unicode) */
218 case mmioFOURCC('I','N','A','M'):
219 case DMUS_FOURCC_UNAM_CHUNK: {
220 TRACE_(dmfile)(": name chunk\n");
221 pDesc->dwValidData |= DMUS_OBJ_NAME;
222 IStream_Read (pStream, pDesc->wszName, Chunk.dwSize, NULL);
223 break;
225 case mmioFOURCC('I','A','R','T'):
226 case DMUS_FOURCC_UART_CHUNK: {
227 TRACE_(dmfile)(": artist chunk (ignored)\n");
228 liMove.QuadPart = Chunk.dwSize;
229 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
230 break;
232 case mmioFOURCC('I','C','O','P'):
233 case DMUS_FOURCC_UCOP_CHUNK: {
234 TRACE_(dmfile)(": copyright chunk (ignored)\n");
235 liMove.QuadPart = Chunk.dwSize;
236 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
237 break;
239 case mmioFOURCC('I','S','B','J'):
240 case DMUS_FOURCC_USBJ_CHUNK: {
241 TRACE_(dmfile)(": subject chunk (ignored)\n");
242 liMove.QuadPart = Chunk.dwSize;
243 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
244 break;
246 case mmioFOURCC('I','C','M','T'):
247 case DMUS_FOURCC_UCMT_CHUNK: {
248 TRACE_(dmfile)(": comment chunk (ignored)\n");
249 liMove.QuadPart = Chunk.dwSize;
250 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
251 break;
253 default: {
254 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
255 liMove.QuadPart = Chunk.dwSize;
256 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
257 break;
260 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
261 } while (ListCount[0] < ListSize[0]);
262 break;
264 default: {
265 TRACE_(dmfile)(": unknown (skipping)\n");
266 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
267 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
268 break;
271 break;
273 default: {
274 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
275 liMove.QuadPart = Chunk.dwSize;
276 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL);
277 break;
280 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
281 } while (StreamCount < StreamSize);
282 } else {
283 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
284 liMove.QuadPart = StreamSize;
285 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
286 return E_FAIL;
289 TRACE_(dmfile)(": reading finished\n");
290 break;
292 default: {
293 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
294 liMove.QuadPart = Chunk.dwSize;
295 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
296 return DMUS_E_INVALIDFILE;
300 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc));
302 return S_OK;
305 static const IDirectMusicObjectVtbl DirectMusicChordMap_Object_Vtbl = {
306 IDirectMusicChordMapImpl_IDirectMusicObject_QueryInterface,
307 IDirectMusicChordMapImpl_IDirectMusicObject_AddRef,
308 IDirectMusicChordMapImpl_IDirectMusicObject_Release,
309 IDirectMusicChordMapImpl_IDirectMusicObject_GetDescriptor,
310 IDirectMusicChordMapImpl_IDirectMusicObject_SetDescriptor,
311 IDirectMusicChordMapImpl_IDirectMusicObject_ParseDescriptor
315 /* IDirectMusicChordMapImpl IPersistStream part: */
316 static HRESULT WINAPI IDirectMusicChordMapImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) {
317 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, PersistStreamVtbl, iface);
318 return IDirectMusicChordMap_QueryInterface(&This->IDirectMusicChordMap_iface, riid, ppobj);
321 static ULONG WINAPI IDirectMusicChordMapImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface) {
322 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, PersistStreamVtbl, iface);
323 return IDirectMusicChordMap_AddRef(&This->IDirectMusicChordMap_iface);
326 static ULONG WINAPI IDirectMusicChordMapImpl_IPersistStream_Release (LPPERSISTSTREAM iface) {
327 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, PersistStreamVtbl, iface);
328 return IDirectMusicChordMap_Release(&This->IDirectMusicChordMap_iface);
331 static HRESULT WINAPI IDirectMusicChordMapImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) {
332 return E_NOTIMPL;
335 static HRESULT WINAPI IDirectMusicChordMapImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) {
336 return E_NOTIMPL;
339 static HRESULT WINAPI IDirectMusicChordMapImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) {
340 ICOM_THIS_MULTI(IDirectMusicChordMapImpl, PersistStreamVtbl, iface);
342 FOURCC chunkID;
343 DWORD chunkSize, StreamSize, StreamCount, ListSize[3], ListCount[3];
344 LARGE_INTEGER liMove; /* used when skipping chunks */
346 FIXME("(%p, %p): Loading not implemented yet\n", This, pStm);
347 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
348 IStream_Read (pStm, &chunkSize, sizeof(DWORD), NULL);
349 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
350 switch (chunkID) {
351 case FOURCC_RIFF: {
352 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
353 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(chunkID));
354 StreamSize = chunkSize - sizeof(FOURCC);
355 StreamCount = 0;
356 switch (chunkID) {
357 case DMUS_FOURCC_CHORDMAP_FORM: {
358 TRACE_(dmfile)(": chordmap form\n");
359 do {
360 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
361 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
362 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
363 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
364 switch (chunkID) {
365 case DMUS_FOURCC_GUID_CHUNK: {
366 TRACE_(dmfile)(": GUID chunk\n");
367 This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
368 IStream_Read (pStm, &This->pDesc->guidObject, chunkSize, NULL);
369 break;
371 case DMUS_FOURCC_VERSION_CHUNK: {
372 TRACE_(dmfile)(": version chunk\n");
373 This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
374 IStream_Read (pStm, &This->pDesc->vVersion, chunkSize, NULL);
375 break;
377 case DMUS_FOURCC_CATEGORY_CHUNK: {
378 TRACE_(dmfile)(": category chunk\n");
379 This->pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
380 IStream_Read (pStm, This->pDesc->wszCategory, chunkSize, NULL);
381 break;
383 case FOURCC_LIST: {
384 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
385 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunkID));
386 ListSize[0] = chunkSize - sizeof(FOURCC);
387 ListCount[0] = 0;
388 switch (chunkID) {
389 case DMUS_FOURCC_UNFO_LIST: {
390 TRACE_(dmfile)(": UNFO list\n");
391 do {
392 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
393 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
394 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
395 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
396 switch (chunkID) {
397 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
398 (though strings seem to be valid unicode) */
399 case mmioFOURCC('I','N','A','M'):
400 case DMUS_FOURCC_UNAM_CHUNK: {
401 TRACE_(dmfile)(": name chunk\n");
402 This->pDesc->dwValidData |= DMUS_OBJ_NAME;
403 IStream_Read (pStm, This->pDesc->wszName, chunkSize, NULL);
404 break;
406 case mmioFOURCC('I','A','R','T'):
407 case DMUS_FOURCC_UART_CHUNK: {
408 TRACE_(dmfile)(": artist chunk (ignored)\n");
409 liMove.QuadPart = chunkSize;
410 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
411 break;
413 case mmioFOURCC('I','C','O','P'):
414 case DMUS_FOURCC_UCOP_CHUNK: {
415 TRACE_(dmfile)(": copyright chunk (ignored)\n");
416 liMove.QuadPart = chunkSize;
417 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
418 break;
420 case mmioFOURCC('I','S','B','J'):
421 case DMUS_FOURCC_USBJ_CHUNK: {
422 TRACE_(dmfile)(": subject chunk (ignored)\n");
423 liMove.QuadPart = chunkSize;
424 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
425 break;
427 case mmioFOURCC('I','C','M','T'):
428 case DMUS_FOURCC_UCMT_CHUNK: {
429 TRACE_(dmfile)(": comment chunk (ignored)\n");
430 liMove.QuadPart = chunkSize;
431 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
432 break;
434 default: {
435 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
436 liMove.QuadPart = chunkSize;
437 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
438 break;
441 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
442 } while (ListCount[0] < ListSize[0]);
443 break;
445 default: {
446 TRACE_(dmfile)(": unknown (skipping)\n");
447 liMove.QuadPart = chunkSize - sizeof(FOURCC);
448 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
449 break;
452 break;
454 default: {
455 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
456 liMove.QuadPart = chunkSize;
457 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
458 break;
461 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
462 } while (StreamCount < StreamSize);
463 break;
465 default: {
466 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
467 liMove.QuadPart = StreamSize;
468 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
469 return E_FAIL;
472 TRACE_(dmfile)(": reading finished\n");
473 break;
475 default: {
476 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
477 liMove.QuadPart = chunkSize;
478 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
479 return E_FAIL;
483 return S_OK;
486 static HRESULT WINAPI IDirectMusicChordMapImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) {
487 return E_NOTIMPL;
490 static HRESULT WINAPI IDirectMusicChordMapImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) {
491 return E_NOTIMPL;
494 static const IPersistStreamVtbl DirectMusicChordMap_PersistStream_Vtbl = {
495 IDirectMusicChordMapImpl_IPersistStream_QueryInterface,
496 IDirectMusicChordMapImpl_IPersistStream_AddRef,
497 IDirectMusicChordMapImpl_IPersistStream_Release,
498 IDirectMusicChordMapImpl_IPersistStream_GetClassID,
499 IDirectMusicChordMapImpl_IPersistStream_IsDirty,
500 IDirectMusicChordMapImpl_IPersistStream_Load,
501 IDirectMusicChordMapImpl_IPersistStream_Save,
502 IDirectMusicChordMapImpl_IPersistStream_GetSizeMax
505 /* for ClassFactory */
506 HRESULT WINAPI create_dmchordmap(REFIID lpcGUID, void **ppobj)
508 IDirectMusicChordMapImpl* obj;
509 HRESULT hr;
511 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicChordMapImpl));
512 if (NULL == obj) {
513 *ppobj = NULL;
514 return E_OUTOFMEMORY;
516 obj->IDirectMusicChordMap_iface.lpVtbl = &dmchordmap_vtbl;
517 obj->ObjectVtbl = &DirectMusicChordMap_Object_Vtbl;
518 obj->PersistStreamVtbl = &DirectMusicChordMap_PersistStream_Vtbl;
519 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC));
520 DM_STRUCT_INIT(obj->pDesc);
521 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS;
522 obj->pDesc->guidClass = CLSID_DirectMusicChordMap;
523 obj->ref = 1;
525 DMCOMPOS_LockModule();
526 hr = IDirectMusicChordMap_QueryInterface(&obj->IDirectMusicChordMap_iface, lpcGUID, ppobj);
527 IDirectMusicChordMap_Release(&obj->IDirectMusicChordMap_iface);
529 return hr;