kernel32: Get rid of the last parameter to PROFILE_CopyEntry().
[wine.git] / dlls / dmcompos / chordmap.c
blobc58857e04c41bd8c516898ebd613eb365f2ff7eb
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"
21 #include "dmobject.h"
23 WINE_DEFAULT_DEBUG_CHANNEL(dmcompos);
24 WINE_DECLARE_DEBUG_CHANNEL(dmfile);
26 /*****************************************************************************
27 * IDirectMusicChordMapImpl implementation
29 typedef struct IDirectMusicChordMapImpl {
30 IDirectMusicChordMap IDirectMusicChordMap_iface;
31 struct dmobject dmobj;
32 LONG ref;
33 } IDirectMusicChordMapImpl;
35 /* IDirectMusicChordMapImpl IDirectMusicChordMap part: */
36 static inline IDirectMusicChordMapImpl *impl_from_IDirectMusicChordMap(IDirectMusicChordMap *iface)
38 return CONTAINING_RECORD(iface, IDirectMusicChordMapImpl, IDirectMusicChordMap_iface);
41 static HRESULT WINAPI IDirectMusicChordMapImpl_QueryInterface(IDirectMusicChordMap *iface,
42 REFIID riid, void **ret_iface)
44 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
46 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
48 *ret_iface = NULL;
50 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IDirectMusicChordMap))
51 *ret_iface = iface;
52 else if (IsEqualIID(riid, &IID_IDirectMusicObject))
53 *ret_iface = &This->dmobj.IDirectMusicObject_iface;
54 else if (IsEqualIID(riid, &IID_IPersistStream))
55 *ret_iface = &This->dmobj.IPersistStream_iface;
56 else {
57 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ret_iface);
58 return E_NOINTERFACE;
61 IUnknown_AddRef((IUnknown*)*ret_iface);
62 return S_OK;
65 static ULONG WINAPI IDirectMusicChordMapImpl_AddRef(IDirectMusicChordMap *iface)
67 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
68 LONG ref = InterlockedIncrement(&This->ref);
70 TRACE("(%p) ref=%d\n", This, ref);
72 return ref;
75 static ULONG WINAPI IDirectMusicChordMapImpl_Release(IDirectMusicChordMap *iface)
77 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
78 LONG ref = InterlockedDecrement(&This->ref);
80 TRACE("(%p) ref=%d\n", This, ref);
82 if (!ref) {
83 HeapFree(GetProcessHeap(), 0, This);
84 DMCOMPOS_UnlockModule();
87 return ref;
90 static HRESULT WINAPI IDirectMusicChordMapImpl_GetScale(IDirectMusicChordMap *iface,
91 DWORD *pdwScale)
93 IDirectMusicChordMapImpl *This = impl_from_IDirectMusicChordMap(iface);
94 FIXME("(%p, %p): stub\n", This, pdwScale);
95 return S_OK;
98 static const IDirectMusicChordMapVtbl dmchordmap_vtbl = {
99 IDirectMusicChordMapImpl_QueryInterface,
100 IDirectMusicChordMapImpl_AddRef,
101 IDirectMusicChordMapImpl_Release,
102 IDirectMusicChordMapImpl_GetScale
105 /* IDirectMusicChordMapImpl IDirectMusicObject part: */
106 static HRESULT WINAPI chord_IDirectMusicObject_ParseDescriptor(IDirectMusicObject *iface,
107 IStream *stream, DMUS_OBJECTDESC *desc)
109 struct chunk_entry riff = {0};
110 HRESULT hr;
112 TRACE("(%p, %p, %p)\n", iface, stream, desc);
114 if (!stream || !desc)
115 return E_POINTER;
117 if ((hr = stream_get_chunk(stream, &riff)) != S_OK)
118 return hr;
119 if (riff.id != FOURCC_RIFF || riff.type != DMUS_FOURCC_CHORDMAP_FORM) {
120 TRACE("loading failed: unexpected %s\n", debugstr_chunk(&riff));
121 stream_skip_chunk(stream, &riff);
122 return DMUS_E_CHUNKNOTFOUND;
125 hr = dmobj_parsedescriptor(stream, &riff, desc, DMUS_OBJ_OBJECT);
126 if (FAILED(hr))
127 return hr;
129 desc->guidClass = CLSID_DirectMusicChordMap;
130 desc->dwValidData |= DMUS_OBJ_CLASS;
132 TRACE("returning descriptor:\n");
133 dump_DMUS_OBJECTDESC(desc);
135 return S_OK;
138 static const IDirectMusicObjectVtbl dmobject_vtbl = {
139 dmobj_IDirectMusicObject_QueryInterface,
140 dmobj_IDirectMusicObject_AddRef,
141 dmobj_IDirectMusicObject_Release,
142 dmobj_IDirectMusicObject_GetDescriptor,
143 dmobj_IDirectMusicObject_SetDescriptor,
144 chord_IDirectMusicObject_ParseDescriptor
147 /* IDirectMusicChordMapImpl IPersistStream part: */
148 static inline IDirectMusicChordMapImpl *impl_from_IPersistStream(IPersistStream *iface)
150 return CONTAINING_RECORD(iface, IDirectMusicChordMapImpl, dmobj.IPersistStream_iface);
153 static HRESULT WINAPI IPersistStreamImpl_Load(IPersistStream *iface, IStream *pStm)
155 IDirectMusicChordMapImpl *This = impl_from_IPersistStream(iface);
156 FOURCC chunkID;
157 DWORD chunkSize, StreamSize, StreamCount, ListSize[3], ListCount[3];
158 LARGE_INTEGER liMove; /* used when skipping chunks */
160 FIXME("(%p, %p): Loading not implemented yet\n", This, pStm);
161 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
162 IStream_Read (pStm, &chunkSize, sizeof(DWORD), NULL);
163 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
164 switch (chunkID) {
165 case FOURCC_RIFF: {
166 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
167 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(chunkID));
168 StreamSize = chunkSize - sizeof(FOURCC);
169 StreamCount = 0;
170 switch (chunkID) {
171 case DMUS_FOURCC_CHORDMAP_FORM: {
172 TRACE_(dmfile)(": chordmap form\n");
173 do {
174 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
175 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
176 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
177 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
178 switch (chunkID) {
179 case DMUS_FOURCC_GUID_CHUNK: {
180 TRACE_(dmfile)(": GUID chunk\n");
181 This->dmobj.desc.dwValidData |= DMUS_OBJ_OBJECT;
182 IStream_Read (pStm, &This->dmobj.desc.guidObject, chunkSize, NULL);
183 break;
185 case DMUS_FOURCC_VERSION_CHUNK: {
186 TRACE_(dmfile)(": version chunk\n");
187 This->dmobj.desc.dwValidData |= DMUS_OBJ_VERSION;
188 IStream_Read (pStm, &This->dmobj.desc.vVersion, chunkSize, NULL);
189 break;
191 case DMUS_FOURCC_CATEGORY_CHUNK: {
192 TRACE_(dmfile)(": category chunk\n");
193 This->dmobj.desc.dwValidData |= DMUS_OBJ_CATEGORY;
194 IStream_Read (pStm, This->dmobj.desc.wszCategory, chunkSize, NULL);
195 break;
197 case FOURCC_LIST: {
198 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
199 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunkID));
200 ListSize[0] = chunkSize - sizeof(FOURCC);
201 ListCount[0] = 0;
202 switch (chunkID) {
203 case DMUS_FOURCC_UNFO_LIST: {
204 TRACE_(dmfile)(": UNFO list\n");
205 do {
206 IStream_Read (pStm, &chunkID, sizeof(FOURCC), NULL);
207 IStream_Read (pStm, &chunkSize, sizeof(FOURCC), NULL);
208 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunkSize;
209 TRACE_(dmfile)(": %s chunk (size = %d)", debugstr_fourcc (chunkID), chunkSize);
210 switch (chunkID) {
211 /* don't ask me why, but M$ puts INFO elements in UNFO list sometimes
212 (though strings seem to be valid unicode) */
213 case mmioFOURCC('I','N','A','M'):
214 case DMUS_FOURCC_UNAM_CHUNK: {
215 TRACE_(dmfile)(": name chunk\n");
216 This->dmobj.desc.dwValidData |= DMUS_OBJ_NAME;
217 IStream_Read (pStm, This->dmobj.desc.wszName, chunkSize, NULL);
218 break;
220 case mmioFOURCC('I','A','R','T'):
221 case DMUS_FOURCC_UART_CHUNK: {
222 TRACE_(dmfile)(": artist chunk (ignored)\n");
223 liMove.QuadPart = chunkSize;
224 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
225 break;
227 case mmioFOURCC('I','C','O','P'):
228 case DMUS_FOURCC_UCOP_CHUNK: {
229 TRACE_(dmfile)(": copyright chunk (ignored)\n");
230 liMove.QuadPart = chunkSize;
231 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
232 break;
234 case mmioFOURCC('I','S','B','J'):
235 case DMUS_FOURCC_USBJ_CHUNK: {
236 TRACE_(dmfile)(": subject chunk (ignored)\n");
237 liMove.QuadPart = chunkSize;
238 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
239 break;
241 case mmioFOURCC('I','C','M','T'):
242 case DMUS_FOURCC_UCMT_CHUNK: {
243 TRACE_(dmfile)(": comment chunk (ignored)\n");
244 liMove.QuadPart = chunkSize;
245 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
246 break;
248 default: {
249 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
250 liMove.QuadPart = chunkSize;
251 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
252 break;
255 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
256 } while (ListCount[0] < ListSize[0]);
257 break;
259 default: {
260 TRACE_(dmfile)(": unknown (skipping)\n");
261 liMove.QuadPart = chunkSize - sizeof(FOURCC);
262 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
263 break;
266 break;
268 default: {
269 TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
270 liMove.QuadPart = chunkSize;
271 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
272 break;
275 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
276 } while (StreamCount < StreamSize);
277 break;
279 default: {
280 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
281 liMove.QuadPart = StreamSize;
282 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
283 return E_FAIL;
286 TRACE_(dmfile)(": reading finished\n");
287 break;
289 default: {
290 TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
291 liMove.QuadPart = chunkSize;
292 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
293 return E_FAIL;
297 return S_OK;
300 static const IPersistStreamVtbl persiststream_vtbl = {
301 dmobj_IPersistStream_QueryInterface,
302 dmobj_IPersistStream_AddRef,
303 dmobj_IPersistStream_Release,
304 dmobj_IPersistStream_GetClassID,
305 unimpl_IPersistStream_IsDirty,
306 IPersistStreamImpl_Load,
307 unimpl_IPersistStream_Save,
308 unimpl_IPersistStream_GetSizeMax
311 /* for ClassFactory */
312 HRESULT WINAPI create_dmchordmap(REFIID lpcGUID, void **ppobj)
314 IDirectMusicChordMapImpl* obj;
315 HRESULT hr;
317 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicChordMapImpl));
318 if (NULL == obj) {
319 *ppobj = NULL;
320 return E_OUTOFMEMORY;
322 obj->IDirectMusicChordMap_iface.lpVtbl = &dmchordmap_vtbl;
323 obj->ref = 1;
324 dmobject_init(&obj->dmobj, &CLSID_DirectMusicChordMap,
325 (IUnknown *)&obj->IDirectMusicChordMap_iface);
326 obj->dmobj.IDirectMusicObject_iface.lpVtbl = &dmobject_vtbl;
327 obj->dmobj.IPersistStream_iface.lpVtbl = &persiststream_vtbl;
329 DMCOMPOS_LockModule();
330 hr = IDirectMusicChordMap_QueryInterface(&obj->IDirectMusicChordMap_iface, lpcGUID, ppobj);
331 IDirectMusicChordMap_Release(&obj->IDirectMusicChordMap_iface);
333 return hr;