ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

collection.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.