Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencollection.c
Go to the documentation of this file.
00001 /* IDirectMusicCollection Implementation 00002 * 00003 * Copyright (C) 2003-2004 Rok Mandeljc 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00018 */ 00019 00020 #include "dmusic_private.h" 00021 00022 WINE_DEFAULT_DEBUG_CHANNEL(dmusic); 00023 WINE_DECLARE_DEBUG_CHANNEL(dmfile); 00024 00025 static ULONG WINAPI IDirectMusicCollectionImpl_IUnknown_AddRef (LPUNKNOWN iface); 00026 static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_AddRef (LPDIRECTMUSICCOLLECTION iface); 00027 static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface); 00028 static ULONG WINAPI IDirectMusicCollectionImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface); 00029 00030 /***************************************************************************** 00031 * IDirectMusicCollectionImpl implementation 00032 */ 00033 /* IDirectMusicCollectionImpl IUnknown part: */ 00034 static HRESULT WINAPI IDirectMusicCollectionImpl_IUnknown_QueryInterface (LPUNKNOWN iface, REFIID riid, LPVOID *ppobj) { 00035 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, UnknownVtbl, iface); 00036 TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj); 00037 00038 if (IsEqualIID (riid, &IID_IUnknown)) { 00039 *ppobj = &This->UnknownVtbl; 00040 IDirectMusicCollectionImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); 00041 return S_OK; 00042 } else if (IsEqualIID (riid, &IID_IDirectMusicCollection)) { 00043 *ppobj = &This->CollectionVtbl; 00044 IDirectMusicCollectionImpl_IDirectMusicCollection_AddRef ((LPDIRECTMUSICCOLLECTION)&This->CollectionVtbl); 00045 return S_OK; 00046 } else if (IsEqualIID (riid, &IID_IDirectMusicObject)) { 00047 *ppobj = &This->ObjectVtbl; 00048 IDirectMusicCollectionImpl_IDirectMusicObject_AddRef ((LPDIRECTMUSICOBJECT)&This->ObjectVtbl); 00049 return S_OK; 00050 } else if (IsEqualIID (riid, &IID_IPersistStream)) { 00051 *ppobj = &This->PersistStreamVtbl; 00052 IDirectMusicCollectionImpl_IPersistStream_AddRef ((LPPERSISTSTREAM)&This->PersistStreamVtbl); 00053 return S_OK; 00054 } 00055 00056 WARN("(%p, %s, %p): not found\n", This, debugstr_dmguid(riid), ppobj); 00057 return E_NOINTERFACE; 00058 } 00059 00060 static ULONG WINAPI IDirectMusicCollectionImpl_IUnknown_AddRef (LPUNKNOWN iface) { 00061 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, UnknownVtbl, iface); 00062 ULONG refCount = InterlockedIncrement(&This->ref); 00063 00064 TRACE("(%p)->(ref before=%u)\n", This, refCount - 1); 00065 00066 DMUSIC_LockModule(); 00067 00068 return refCount; 00069 } 00070 00071 static ULONG WINAPI IDirectMusicCollectionImpl_IUnknown_Release (LPUNKNOWN iface) { 00072 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, UnknownVtbl, iface); 00073 ULONG refCount = InterlockedDecrement(&This->ref); 00074 00075 TRACE("(%p)->(ref before=%u)\n", This, refCount + 1); 00076 00077 if (!refCount) { 00078 HeapFree(GetProcessHeap(), 0, This); 00079 } 00080 00081 DMUSIC_UnlockModule(); 00082 00083 return refCount; 00084 } 00085 00086 static const IUnknownVtbl DirectMusicCollection_Unknown_Vtbl = { 00087 IDirectMusicCollectionImpl_IUnknown_QueryInterface, 00088 IDirectMusicCollectionImpl_IUnknown_AddRef, 00089 IDirectMusicCollectionImpl_IUnknown_Release 00090 }; 00091 00092 /* IDirectMusicCollectionImpl IDirectMusicCollection part: */ 00093 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_QueryInterface (LPDIRECTMUSICCOLLECTION iface, REFIID riid, LPVOID *ppobj) { 00094 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, CollectionVtbl, iface); 00095 return IDirectMusicCollectionImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); 00096 } 00097 00098 static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_AddRef (LPDIRECTMUSICCOLLECTION iface) { 00099 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, CollectionVtbl, iface); 00100 return IDirectMusicCollectionImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); 00101 } 00102 00103 static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_Release (LPDIRECTMUSICCOLLECTION iface) { 00104 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, CollectionVtbl, iface); 00105 return IDirectMusicCollectionImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); 00106 } 00107 00108 /* IDirectMusicCollection Interface follow: */ 00109 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_GetInstrument (LPDIRECTMUSICCOLLECTION iface, DWORD dwPatch, IDirectMusicInstrument** ppInstrument) { 00110 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, CollectionVtbl, iface); 00111 DMUS_PRIVATE_INSTRUMENTENTRY *tmpEntry; 00112 struct list *listEntry; 00113 DWORD dwInstPatch; 00114 00115 TRACE("(%p, %d, %p)\n", This, dwPatch, ppInstrument); 00116 00117 LIST_FOR_EACH (listEntry, &This->Instruments) { 00118 tmpEntry = LIST_ENTRY(listEntry, DMUS_PRIVATE_INSTRUMENTENTRY, entry); 00119 IDirectMusicInstrument_GetPatch (tmpEntry->pInstrument, &dwInstPatch); 00120 if (dwPatch == dwInstPatch) { 00121 *ppInstrument = tmpEntry->pInstrument; 00122 IDirectMusicInstrument_AddRef (tmpEntry->pInstrument); 00123 IDirectMusicInstrumentImpl_Custom_Load (tmpEntry->pInstrument, This->pStm); /* load instrument before returning it */ 00124 TRACE(": returning instrument %p\n", *ppInstrument); 00125 return S_OK; 00126 } 00127 00128 } 00129 TRACE(": instrument not found\n"); 00130 00131 return DMUS_E_INVALIDPATCH; 00132 } 00133 00134 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_EnumInstrument (LPDIRECTMUSICCOLLECTION iface, DWORD dwIndex, DWORD* pdwPatch, LPWSTR pwszName, DWORD dwNameLen) { 00135 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, CollectionVtbl, iface); 00136 unsigned int r = 0; 00137 DMUS_PRIVATE_INSTRUMENTENTRY *tmpEntry; 00138 struct list *listEntry; 00139 DWORD dwLen; 00140 00141 TRACE("(%p, %d, %p, %p, %d)\n", This, dwIndex, pdwPatch, pwszName, dwNameLen); 00142 LIST_FOR_EACH (listEntry, &This->Instruments) { 00143 tmpEntry = LIST_ENTRY(listEntry, DMUS_PRIVATE_INSTRUMENTENTRY, entry); 00144 if (r == dwIndex) { 00145 ICOM_NAME_MULTI (IDirectMusicInstrumentImpl, InstrumentVtbl, tmpEntry->pInstrument, pInstrument); 00146 IDirectMusicInstrument_GetPatch (tmpEntry->pInstrument, pdwPatch); 00147 if (pwszName) { 00148 dwLen = min(strlenW(pInstrument->wszName),dwNameLen-1); 00149 memcpy (pwszName, pInstrument->wszName, dwLen * sizeof(WCHAR)); 00150 pwszName[dwLen] = '\0'; 00151 } 00152 return S_OK; 00153 } 00154 r++; 00155 } 00156 00157 return S_FALSE; 00158 } 00159 00160 static const IDirectMusicCollectionVtbl DirectMusicCollection_Collection_Vtbl = { 00161 IDirectMusicCollectionImpl_IDirectMusicCollection_QueryInterface, 00162 IDirectMusicCollectionImpl_IDirectMusicCollection_AddRef, 00163 IDirectMusicCollectionImpl_IDirectMusicCollection_Release, 00164 IDirectMusicCollectionImpl_IDirectMusicCollection_GetInstrument, 00165 IDirectMusicCollectionImpl_IDirectMusicCollection_EnumInstrument 00166 }; 00167 00168 /* IDirectMusicCollectionImpl IDirectMusicObject part: */ 00169 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_QueryInterface (LPDIRECTMUSICOBJECT iface, REFIID riid, LPVOID *ppobj) { 00170 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, ObjectVtbl, iface); 00171 return IDirectMusicCollectionImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); 00172 } 00173 00174 static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_AddRef (LPDIRECTMUSICOBJECT iface) { 00175 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, ObjectVtbl, iface); 00176 return IDirectMusicCollectionImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); 00177 } 00178 00179 static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_Release (LPDIRECTMUSICOBJECT iface) { 00180 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, ObjectVtbl, iface); 00181 return IDirectMusicCollectionImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); 00182 } 00183 00184 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_GetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) { 00185 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, ObjectVtbl, iface); 00186 TRACE("(%p, %p)\n", This, pDesc); 00187 /* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */ 00188 memcpy (pDesc, This->pDesc, This->pDesc->dwSize); 00189 return S_OK; 00190 } 00191 00192 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_SetDescriptor (LPDIRECTMUSICOBJECT iface, LPDMUS_OBJECTDESC pDesc) { 00193 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, ObjectVtbl, iface); 00194 TRACE("(%p, %p): setting descriptor:\n%s\n", This, pDesc, debugstr_DMUS_OBJECTDESC (pDesc)); 00195 00196 /* According to MSDN, we should copy only given values, not whole struct */ 00197 if (pDesc->dwValidData & DMUS_OBJ_OBJECT) 00198 This->pDesc->guidObject = pDesc->guidObject; 00199 if (pDesc->dwValidData & DMUS_OBJ_CLASS) 00200 This->pDesc->guidClass = pDesc->guidClass; 00201 if (pDesc->dwValidData & DMUS_OBJ_NAME) 00202 lstrcpynW(This->pDesc->wszName, pDesc->wszName, DMUS_MAX_NAME); 00203 if (pDesc->dwValidData & DMUS_OBJ_CATEGORY) 00204 lstrcpynW(This->pDesc->wszCategory, pDesc->wszCategory, DMUS_MAX_CATEGORY); 00205 if (pDesc->dwValidData & DMUS_OBJ_FILENAME) 00206 lstrcpynW(This->pDesc->wszFileName, pDesc->wszFileName, DMUS_MAX_FILENAME); 00207 if (pDesc->dwValidData & DMUS_OBJ_VERSION) 00208 This->pDesc->vVersion = pDesc->vVersion; 00209 if (pDesc->dwValidData & DMUS_OBJ_DATE) 00210 This->pDesc->ftDate = pDesc->ftDate; 00211 if (pDesc->dwValidData & DMUS_OBJ_MEMORY) { 00212 memcpy (&This->pDesc->llMemLength, &pDesc->llMemLength, sizeof (pDesc->llMemLength)); 00213 memcpy (This->pDesc->pbMemData, pDesc->pbMemData, sizeof (pDesc->pbMemData)); 00214 } 00215 if (pDesc->dwValidData & DMUS_OBJ_STREAM) { 00216 /* according to MSDN, we copy the stream */ 00217 IStream_Clone (pDesc->pStream, &This->pDesc->pStream); 00218 } 00219 00220 /* add new flags */ 00221 This->pDesc->dwValidData |= pDesc->dwValidData; 00222 00223 return S_OK; 00224 } 00225 00226 static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_ParseDescriptor (LPDIRECTMUSICOBJECT iface, LPSTREAM pStream, LPDMUS_OBJECTDESC pDesc) { 00227 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, ObjectVtbl, iface); 00228 DMUS_PRIVATE_CHUNK Chunk; 00229 DWORD StreamSize, StreamCount, ListSize[1], ListCount[1]; 00230 LARGE_INTEGER liMove; /* used when skipping chunks */ 00231 00232 TRACE("(%p, %p, %p)\n", This, pStream, pDesc); 00233 00234 /* FIXME: should this be determined from stream? */ 00235 pDesc->dwValidData |= DMUS_OBJ_CLASS; 00236 pDesc->guidClass = CLSID_DirectMusicCollection; 00237 00238 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00239 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00240 switch (Chunk.fccID) { 00241 case FOURCC_RIFF: { 00242 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL); 00243 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID)); 00244 StreamSize = Chunk.dwSize - sizeof(FOURCC); 00245 StreamCount = 0; 00246 if (Chunk.fccID == mmioFOURCC('D','L','S',' ')) { 00247 TRACE_(dmfile)(": collection form\n"); 00248 do { 00249 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00250 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; 00251 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00252 switch (Chunk.fccID) { 00253 case FOURCC_DLID: { 00254 TRACE_(dmfile)(": GUID chunk\n"); 00255 pDesc->dwValidData |= DMUS_OBJ_OBJECT; 00256 IStream_Read (pStream, &pDesc->guidObject, Chunk.dwSize, NULL); 00257 break; 00258 } 00259 case DMUS_FOURCC_VERSION_CHUNK: { 00260 TRACE_(dmfile)(": version chunk\n"); 00261 pDesc->dwValidData |= DMUS_OBJ_VERSION; 00262 IStream_Read (pStream, &pDesc->vVersion, Chunk.dwSize, NULL); 00263 break; 00264 } 00265 case DMUS_FOURCC_CATEGORY_CHUNK: { 00266 TRACE_(dmfile)(": category chunk\n"); 00267 pDesc->dwValidData |= DMUS_OBJ_CATEGORY; 00268 IStream_Read (pStream, pDesc->wszCategory, Chunk.dwSize, NULL); 00269 break; 00270 } 00271 case FOURCC_LIST: { 00272 IStream_Read (pStream, &Chunk.fccID, sizeof(FOURCC), NULL); 00273 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); 00274 ListSize[0] = Chunk.dwSize - sizeof(FOURCC); 00275 ListCount[0] = 0; 00276 switch (Chunk.fccID) { 00277 /* pure INFO list, such can be found in dls collections */ 00278 case mmioFOURCC('I','N','F','O'): { 00279 TRACE_(dmfile)(": INFO list\n"); 00280 do { 00281 IStream_Read (pStream, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00282 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; 00283 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00284 switch (Chunk.fccID) { 00285 case mmioFOURCC('I','N','A','M'):{ 00286 CHAR szName[DMUS_MAX_NAME]; 00287 TRACE_(dmfile)(": name chunk\n"); 00288 pDesc->dwValidData |= DMUS_OBJ_NAME; 00289 IStream_Read (pStream, szName, Chunk.dwSize, NULL); 00290 MultiByteToWideChar (CP_ACP, 0, szName, -1, pDesc->wszName, DMUS_MAX_NAME); 00291 if (even_or_odd(Chunk.dwSize)) { 00292 ListCount[0] ++; 00293 liMove.QuadPart = 1; 00294 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00295 } 00296 break; 00297 } 00298 case mmioFOURCC('I','A','R','T'): { 00299 TRACE_(dmfile)(": artist chunk (ignored)\n"); 00300 if (even_or_odd(Chunk.dwSize)) { 00301 ListCount[0] ++; 00302 Chunk.dwSize++; 00303 } 00304 liMove.QuadPart = Chunk.dwSize; 00305 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00306 break; 00307 } 00308 case mmioFOURCC('I','C','O','P'): { 00309 TRACE_(dmfile)(": copyright chunk (ignored)\n"); 00310 if (even_or_odd(Chunk.dwSize)) { 00311 ListCount[0] ++; 00312 Chunk.dwSize++; 00313 } 00314 liMove.QuadPart = Chunk.dwSize; 00315 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00316 break; 00317 } 00318 case mmioFOURCC('I','S','B','J'): { 00319 TRACE_(dmfile)(": subject chunk (ignored)\n"); 00320 if (even_or_odd(Chunk.dwSize)) { 00321 ListCount[0] ++; 00322 Chunk.dwSize++; 00323 } 00324 liMove.QuadPart = Chunk.dwSize; 00325 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00326 break; 00327 } 00328 case mmioFOURCC('I','C','M','T'): { 00329 TRACE_(dmfile)(": comment chunk (ignored)\n"); 00330 if (even_or_odd(Chunk.dwSize)) { 00331 ListCount[0] ++; 00332 Chunk.dwSize++; 00333 } 00334 liMove.QuadPart = Chunk.dwSize; 00335 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00336 break; 00337 } 00338 default: { 00339 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); 00340 if (even_or_odd(Chunk.dwSize)) { 00341 ListCount[0] ++; 00342 Chunk.dwSize++; 00343 } 00344 liMove.QuadPart = Chunk.dwSize; 00345 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00346 break; 00347 } 00348 } 00349 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]); 00350 } while (ListCount[0] < ListSize[0]); 00351 break; 00352 } 00353 default: { 00354 TRACE_(dmfile)(": unknown (skipping)\n"); 00355 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); 00356 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00357 break; 00358 } 00359 } 00360 break; 00361 } 00362 default: { 00363 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); 00364 liMove.QuadPart = Chunk.dwSize; 00365 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); 00366 break; 00367 } 00368 } 00369 TRACE_(dmfile)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize); 00370 } while (StreamCount < StreamSize); 00371 } else { 00372 TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); 00373 liMove.QuadPart = StreamSize; 00374 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ 00375 return E_FAIL; 00376 } 00377 00378 TRACE_(dmfile)(": reading finished\n"); 00379 break; 00380 } 00381 default: { 00382 TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); 00383 liMove.QuadPart = Chunk.dwSize; 00384 IStream_Seek (pStream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ 00385 return DMUS_E_INVALIDFILE; 00386 } 00387 } 00388 00389 TRACE(": returning descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC (pDesc)); 00390 00391 return S_OK; 00392 } 00393 00394 static const IDirectMusicObjectVtbl DirectMusicCollection_Object_Vtbl = { 00395 IDirectMusicCollectionImpl_IDirectMusicObject_QueryInterface, 00396 IDirectMusicCollectionImpl_IDirectMusicObject_AddRef, 00397 IDirectMusicCollectionImpl_IDirectMusicObject_Release, 00398 IDirectMusicCollectionImpl_IDirectMusicObject_GetDescriptor, 00399 IDirectMusicCollectionImpl_IDirectMusicObject_SetDescriptor, 00400 IDirectMusicCollectionImpl_IDirectMusicObject_ParseDescriptor 00401 }; 00402 00403 /* IDirectMusicCollectionImpl IPersistStream part: */ 00404 static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_QueryInterface (LPPERSISTSTREAM iface, REFIID riid, LPVOID *ppobj) { 00405 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, PersistStreamVtbl, iface); 00406 return IDirectMusicCollectionImpl_IUnknown_QueryInterface ((LPUNKNOWN)&This->UnknownVtbl, riid, ppobj); 00407 } 00408 00409 static ULONG WINAPI IDirectMusicCollectionImpl_IPersistStream_AddRef (LPPERSISTSTREAM iface) { 00410 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, PersistStreamVtbl, iface); 00411 return IDirectMusicCollectionImpl_IUnknown_AddRef ((LPUNKNOWN)&This->UnknownVtbl); 00412 } 00413 00414 static ULONG WINAPI IDirectMusicCollectionImpl_IPersistStream_Release (LPPERSISTSTREAM iface) { 00415 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, PersistStreamVtbl, iface); 00416 return IDirectMusicCollectionImpl_IUnknown_Release ((LPUNKNOWN)&This->UnknownVtbl); 00417 } 00418 00419 static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_GetClassID (LPPERSISTSTREAM iface, CLSID* pClassID) { 00420 return E_NOTIMPL; 00421 } 00422 00423 static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_IsDirty (LPPERSISTSTREAM iface) { 00424 return E_NOTIMPL; 00425 } 00426 00427 static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm) { 00428 ICOM_THIS_MULTI(IDirectMusicCollectionImpl, PersistStreamVtbl, iface); 00429 00430 DMUS_PRIVATE_CHUNK Chunk; 00431 DWORD StreamSize, StreamCount, ListSize[3], ListCount[3]; 00432 LARGE_INTEGER liMove; /* used when skipping chunks */ 00433 ULARGE_INTEGER dlibCollectionPosition, dlibInstrumentPosition, dlibWavePoolPosition; 00434 00435 IStream_AddRef (pStm); /* add count for later references */ 00436 liMove.QuadPart = 0; 00437 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, &dlibCollectionPosition); /* store offset, in case it'll be needed later */ 00438 This->liCollectionPosition.QuadPart = dlibCollectionPosition.QuadPart; 00439 This->pStm = pStm; 00440 00441 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00442 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00443 switch (Chunk.fccID) { 00444 case FOURCC_RIFF: { 00445 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); 00446 TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID)); 00447 StreamSize = Chunk.dwSize - sizeof(FOURCC); 00448 StreamCount = 0; 00449 switch (Chunk.fccID) { 00450 case FOURCC_DLS: { 00451 TRACE_(dmfile)(": collection form\n"); 00452 do { 00453 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00454 StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; 00455 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00456 switch (Chunk.fccID) { 00457 case FOURCC_COLH: { 00458 TRACE_(dmfile)(": collection header chunk\n"); 00459 This->pHeader = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize); 00460 IStream_Read (pStm, This->pHeader, Chunk.dwSize, NULL); 00461 break; 00462 } 00463 case FOURCC_DLID: { 00464 TRACE_(dmfile)(": DLID (GUID) chunk\n"); 00465 This->pDesc->dwValidData |= DMUS_OBJ_OBJECT; 00466 IStream_Read (pStm, &This->pDesc->guidObject, Chunk.dwSize, NULL); 00467 break; 00468 } 00469 case FOURCC_VERS: { 00470 TRACE_(dmfile)(": version chunk\n"); 00471 This->pDesc->dwValidData |= DMUS_OBJ_VERSION; 00472 IStream_Read (pStm, &This->pDesc->vVersion, Chunk.dwSize, NULL); 00473 break; 00474 } 00475 case FOURCC_PTBL: { 00476 TRACE_(dmfile)(": pool table chunk\n"); 00477 This->pPoolTable = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(POOLTABLE)); 00478 IStream_Read (pStm, This->pPoolTable, sizeof(POOLTABLE), NULL); 00479 Chunk.dwSize -= sizeof(POOLTABLE); 00480 This->pPoolCues = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, This->pPoolTable->cCues*sizeof(POOLCUE)); 00481 IStream_Read (pStm, This->pPoolCues, Chunk.dwSize, NULL); 00482 break; 00483 } 00484 case FOURCC_LIST: { 00485 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); 00486 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); 00487 ListSize[0] = Chunk.dwSize - sizeof(FOURCC); 00488 ListCount[0] = 0; 00489 switch (Chunk.fccID) { 00490 case mmioFOURCC('I','N','F','O'): { 00491 TRACE_(dmfile)(": INFO list\n"); 00492 do { 00493 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00494 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; 00495 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00496 switch (Chunk.fccID) { 00497 case mmioFOURCC('I','N','A','M'): { 00498 CHAR szName[DMUS_MAX_NAME]; 00499 TRACE_(dmfile)(": name chunk\n"); 00500 This->pDesc->dwValidData |= DMUS_OBJ_NAME; 00501 IStream_Read (pStm, szName, Chunk.dwSize, NULL); 00502 MultiByteToWideChar (CP_ACP, 0, szName, -1, This->pDesc->wszName, DMUS_MAX_NAME); 00503 if (even_or_odd(Chunk.dwSize)) { 00504 ListCount[0] ++; 00505 liMove.QuadPart = 1; 00506 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00507 } 00508 break; 00509 } 00510 case mmioFOURCC('I','A','R','T'): { 00511 TRACE_(dmfile)(": artist chunk (ignored)\n"); 00512 if (even_or_odd(Chunk.dwSize)) { 00513 ListCount[0] ++; 00514 Chunk.dwSize++; 00515 } 00516 liMove.QuadPart = Chunk.dwSize; 00517 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00518 break; 00519 } 00520 case mmioFOURCC('I','C','O','P'): { 00521 TRACE_(dmfile)(": copyright chunk\n"); 00522 This->szCopyright = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize); 00523 IStream_Read (pStm, This->szCopyright, Chunk.dwSize, NULL); 00524 if (even_or_odd(Chunk.dwSize)) { 00525 ListCount[0] ++; 00526 liMove.QuadPart = 1; 00527 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00528 } 00529 break; 00530 } 00531 case mmioFOURCC('I','S','B','J'): { 00532 TRACE_(dmfile)(": subject chunk (ignored)\n"); 00533 if (even_or_odd(Chunk.dwSize)) { 00534 ListCount[0] ++; 00535 Chunk.dwSize++; 00536 } 00537 liMove.QuadPart = Chunk.dwSize; 00538 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00539 break; 00540 } 00541 case mmioFOURCC('I','C','M','T'): { 00542 TRACE_(dmfile)(": comment chunk (ignored)\n"); 00543 if (even_or_odd(Chunk.dwSize)) { 00544 ListCount[0] ++; 00545 Chunk.dwSize++; 00546 } 00547 liMove.QuadPart = Chunk.dwSize; 00548 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00549 break; 00550 } 00551 default: { 00552 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); 00553 if (even_or_odd(Chunk.dwSize)) { 00554 ListCount[0] ++; 00555 Chunk.dwSize++; 00556 } 00557 liMove.QuadPart = Chunk.dwSize; 00558 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00559 break; 00560 } 00561 } 00562 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]); 00563 } while (ListCount[0] < ListSize[0]); 00564 break; 00565 } 00566 case FOURCC_WVPL: { 00567 TRACE_(dmfile)(": wave pool list (mark & skip)\n"); 00568 liMove.QuadPart = 0; 00569 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, &dlibWavePoolPosition); /* store position */ 00570 This->liWavePoolTablePosition.QuadPart = dlibWavePoolPosition.QuadPart; 00571 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); 00572 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00573 break; 00574 } 00575 case FOURCC_LINS: { 00576 TRACE_(dmfile)(": instruments list\n"); 00577 do { 00578 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00579 ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; 00580 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00581 switch (Chunk.fccID) { 00582 case FOURCC_LIST: { 00583 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); 00584 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); 00585 ListSize[1] = Chunk.dwSize - sizeof(FOURCC); 00586 ListCount[1] = 0; 00587 switch (Chunk.fccID) { 00588 case FOURCC_INS: { 00589 LPDMUS_PRIVATE_INSTRUMENTENTRY pNewInstrument = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY)); 00590 TRACE_(dmfile)(": instrument list\n"); 00591 DMUSIC_CreateDirectMusicInstrumentImpl (&IID_IDirectMusicInstrument, (LPVOID*)&pNewInstrument->pInstrument, NULL); /* only way to create this one... even M$ does it discretely */ 00592 { 00593 ICOM_NAME_MULTI (IDirectMusicInstrumentImpl, InstrumentVtbl, pNewInstrument->pInstrument, pInstrument); 00594 liMove.QuadPart = 0; 00595 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, &dlibInstrumentPosition); 00596 pInstrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart - (2*sizeof(FOURCC) + sizeof(DWORD)); /* store offset, it'll be needed later */ 00597 00598 do { 00599 IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL); 00600 ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize; 00601 TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize); 00602 switch (Chunk.fccID) { 00603 case FOURCC_INSH: { 00604 TRACE_(dmfile)(": instrument header chunk\n"); 00605 pInstrument->pHeader = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize); 00606 IStream_Read (pStm, pInstrument->pHeader, Chunk.dwSize, NULL); 00607 break; 00608 } 00609 case FOURCC_DLID: { 00610 TRACE_(dmfile)(": DLID (GUID) chunk\n"); 00611 pInstrument->pInstrumentID = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize); 00612 IStream_Read (pStm, pInstrument->pInstrumentID, Chunk.dwSize, NULL); 00613 break; 00614 } 00615 case FOURCC_LIST: { 00616 IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL); 00617 TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID)); 00618 ListSize[2] = Chunk.dwSize - sizeof(FOURCC); 00619 ListCount[2] = 0; 00620 switch (Chunk.fccID) { 00621 default: { 00622 TRACE_(dmfile)(": unknown (skipping)\n"); 00623 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); 00624 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00625 break; 00626 } 00627 } 00628 break; 00629 } 00630 default: { 00631 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); 00632 liMove.QuadPart = Chunk.dwSize; 00633 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00634 break; 00635 } 00636 } 00637 TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]); 00638 } while (ListCount[1] < ListSize[1]); 00639 /* DEBUG: dumps whole instrument object tree: */ 00640 if (TRACE_ON(dmusic)) { 00641 TRACE("*** IDirectMusicInstrument (%p) ***\n", pInstrument); 00642 if (pInstrument->pInstrumentID) 00643 TRACE(" - GUID = %s\n", debugstr_dmguid(pInstrument->pInstrumentID)); 00644 00645 TRACE(" - Instrument header:\n"); 00646 TRACE(" - cRegions: %d\n", pInstrument->pHeader->cRegions); 00647 TRACE(" - Locale:\n"); 00648 TRACE(" - ulBank: %d\n", pInstrument->pHeader->Locale.ulBank); 00649 TRACE(" - ulInstrument: %d\n", pInstrument->pHeader->Locale.ulInstrument); 00650 TRACE(" => dwPatch: %d\n", MIDILOCALE2Patch(&pInstrument->pHeader->Locale)); 00651 } 00652 list_add_tail (&This->Instruments, &pNewInstrument->entry); 00653 } 00654 break; 00655 } 00656 } 00657 break; 00658 } 00659 default: { 00660 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); 00661 liMove.QuadPart = Chunk.dwSize; 00662 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00663 break; 00664 } 00665 } 00666 TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]); 00667 } while (ListCount[0] < ListSize[0]); 00668 break; 00669 } 00670 default: { 00671 TRACE_(dmfile)(": unknown (skipping)\n"); 00672 liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC); 00673 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00674 break; 00675 } 00676 } 00677 break; 00678 } 00679 default: { 00680 TRACE_(dmfile)(": unknown chunk (irrevelant & skipping)\n"); 00681 liMove.QuadPart = Chunk.dwSize; 00682 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); 00683 break; 00684 } 00685 } 00686 TRACE_(dmfile)(": StreamCount = %d < StreamSize = %d\n", StreamCount, StreamSize); 00687 } while (StreamCount < StreamSize); 00688 break; 00689 } 00690 default: { 00691 TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); 00692 liMove.QuadPart = StreamSize; 00693 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ 00694 return E_FAIL; 00695 } 00696 } 00697 TRACE_(dmfile)(": reading finished\n"); 00698 break; 00699 } 00700 default: { 00701 TRACE_(dmfile)(": unexpected chunk; loading failed)\n"); 00702 liMove.QuadPart = Chunk.dwSize; 00703 IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */ 00704 return E_FAIL; 00705 } 00706 } 00707 00708 /* DEBUG: dumps whole collection object tree: */ 00709 if (TRACE_ON(dmusic)) { 00710 int r = 0; 00711 DMUS_PRIVATE_INSTRUMENTENTRY *tmpEntry; 00712 struct list *listEntry; 00713 00714 TRACE("*** IDirectMusicCollection (%p) ***\n", This->CollectionVtbl); 00715 if (This->pDesc->dwValidData & DMUS_OBJ_OBJECT) 00716 TRACE(" - GUID = %s\n", debugstr_dmguid(&This->pDesc->guidObject)); 00717 if (This->pDesc->dwValidData & DMUS_OBJ_VERSION) 00718 TRACE(" - Version = %i,%i,%i,%i\n", (This->pDesc->vVersion.dwVersionMS >> 8) & 0x0000FFFF, This->pDesc->vVersion.dwVersionMS & 0x0000FFFF, 00719 (This->pDesc->vVersion.dwVersionLS >> 8) & 0x0000FFFF, This->pDesc->vVersion.dwVersionLS & 0x0000FFFF); 00720 if (This->pDesc->dwValidData & DMUS_OBJ_NAME) 00721 TRACE(" - Name = %s\n", debugstr_w(This->pDesc->wszName)); 00722 00723 TRACE(" - Collection header:\n"); 00724 TRACE(" - cInstruments: %d\n", This->pHeader->cInstruments); 00725 TRACE(" - Instruments:\n"); 00726 00727 LIST_FOR_EACH (listEntry, &This->Instruments) { 00728 tmpEntry = LIST_ENTRY( listEntry, DMUS_PRIVATE_INSTRUMENTENTRY, entry ); 00729 TRACE(" - Instrument[%i]: %p\n", r, tmpEntry->pInstrument); 00730 r++; 00731 } 00732 } 00733 00734 return S_OK; 00735 } 00736 00737 static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Save (LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty) { 00738 return E_NOTIMPL; 00739 } 00740 00741 static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_GetSizeMax (LPPERSISTSTREAM iface, ULARGE_INTEGER* pcbSize) { 00742 return E_NOTIMPL; 00743 } 00744 00745 static const IPersistStreamVtbl DirectMusicCollection_PersistStream_Vtbl = { 00746 IDirectMusicCollectionImpl_IPersistStream_QueryInterface, 00747 IDirectMusicCollectionImpl_IPersistStream_AddRef, 00748 IDirectMusicCollectionImpl_IPersistStream_Release, 00749 IDirectMusicCollectionImpl_IPersistStream_GetClassID, 00750 IDirectMusicCollectionImpl_IPersistStream_IsDirty, 00751 IDirectMusicCollectionImpl_IPersistStream_Load, 00752 IDirectMusicCollectionImpl_IPersistStream_Save, 00753 IDirectMusicCollectionImpl_IPersistStream_GetSizeMax 00754 }; 00755 00756 00757 /* for ClassFactory */ 00758 HRESULT WINAPI DMUSIC_CreateDirectMusicCollectionImpl (LPCGUID lpcGUID, LPVOID* ppobj, LPUNKNOWN pUnkOuter) { 00759 IDirectMusicCollectionImpl* obj; 00760 00761 obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicCollectionImpl)); 00762 if (NULL == obj) { 00763 *ppobj = NULL; 00764 return E_OUTOFMEMORY; 00765 } 00766 obj->UnknownVtbl = &DirectMusicCollection_Unknown_Vtbl; 00767 obj->CollectionVtbl = &DirectMusicCollection_Collection_Vtbl; 00768 obj->ObjectVtbl = &DirectMusicCollection_Object_Vtbl; 00769 obj->PersistStreamVtbl = &DirectMusicCollection_PersistStream_Vtbl; 00770 obj->pDesc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_OBJECTDESC)); 00771 DM_STRUCT_INIT(obj->pDesc); 00772 obj->pDesc->dwValidData |= DMUS_OBJ_CLASS; 00773 obj->pDesc->guidClass = CLSID_DirectMusicCollection; 00774 obj->ref = 0; /* will be inited by QueryInterface */ 00775 list_init (&obj->Instruments); 00776 00777 return IDirectMusicCollectionImpl_IUnknown_QueryInterface ((LPUNKNOWN)&obj->UnknownVtbl, lpcGUID, ppobj); 00778 } Generated on Sat May 26 2012 04:20:07 for ReactOS by
1.7.6.1
|