dmusic: Simplify IPersistStream_Load by checking DLS header first and exit if it is wrong.

This commit is contained in:
Christian Costa 2012-05-21 09:39:54 +02:00 committed by Alexandre Julliard
parent fc999cb362
commit 4c7fb67fc1
1 changed files with 300 additions and 304 deletions

View File

@ -485,314 +485,310 @@ static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_IsDirty(LPPERSIS
return E_NOTIMPL;
}
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Load (LPPERSISTSTREAM iface, IStream* pStm)
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Load(LPPERSISTSTREAM iface, IStream* stream)
{
IDirectMusicCollectionImpl *This = impl_from_IPersistStream(iface);
DMUS_PRIVATE_CHUNK Chunk;
DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
LARGE_INTEGER liMove; /* used when skipping chunks */
ULARGE_INTEGER dlibCollectionPosition, dlibInstrumentPosition, dlibWavePoolPosition;
IStream_AddRef (pStm); /* add count for later references */
liMove.QuadPart = 0;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, &dlibCollectionPosition); /* store offset, in case it'll be needed later */
This->liCollectionPosition.QuadPart = dlibCollectionPosition.QuadPart;
This->pStm = pStm;
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
switch (Chunk.fccID) {
case FOURCC_RIFF: {
IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(Chunk.fccID));
StreamSize = Chunk.dwSize - sizeof(FOURCC);
StreamCount = 0;
switch (Chunk.fccID) {
case FOURCC_DLS: {
TRACE_(dmfile)(": collection form\n");
do {
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
StreamCount += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
switch (Chunk.fccID) {
case FOURCC_COLH: {
TRACE_(dmfile)(": collection header chunk\n");
This->pHeader = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
IStream_Read (pStm, This->pHeader, Chunk.dwSize, NULL);
break;
}
case FOURCC_DLID: {
TRACE_(dmfile)(": DLID (GUID) chunk\n");
This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
IStream_Read (pStm, &This->pDesc->guidObject, Chunk.dwSize, NULL);
break;
}
case FOURCC_VERS: {
TRACE_(dmfile)(": version chunk\n");
This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
IStream_Read (pStm, &This->pDesc->vVersion, Chunk.dwSize, NULL);
break;
}
case FOURCC_PTBL: {
TRACE_(dmfile)(": pool table chunk\n");
This->pPoolTable = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(POOLTABLE));
IStream_Read (pStm, This->pPoolTable, sizeof(POOLTABLE), NULL);
Chunk.dwSize -= sizeof(POOLTABLE);
This->pPoolCues = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, This->pPoolTable->cCues*sizeof(POOLCUE));
IStream_Read (pStm, This->pPoolCues, Chunk.dwSize, NULL);
break;
}
case FOURCC_LIST: {
IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
ListSize[0] = Chunk.dwSize - sizeof(FOURCC);
ListCount[0] = 0;
switch (Chunk.fccID) {
case mmioFOURCC('I','N','F','O'): {
TRACE_(dmfile)(": INFO list\n");
do {
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
switch (Chunk.fccID) {
case mmioFOURCC('I','N','A','M'): {
CHAR szName[DMUS_MAX_NAME];
TRACE_(dmfile)(": name chunk\n");
This->pDesc->dwValidData |= DMUS_OBJ_NAME;
IStream_Read (pStm, szName, Chunk.dwSize, NULL);
MultiByteToWideChar (CP_ACP, 0, szName, -1, This->pDesc->wszName, DMUS_MAX_NAME);
if (even_or_odd(Chunk.dwSize)) {
ListCount[0] ++;
liMove.QuadPart = 1;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
}
break;
}
case mmioFOURCC('I','A','R','T'): {
TRACE_(dmfile)(": artist chunk (ignored)\n");
if (even_or_odd(Chunk.dwSize)) {
ListCount[0] ++;
Chunk.dwSize++;
}
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case mmioFOURCC('I','C','O','P'): {
TRACE_(dmfile)(": copyright chunk\n");
This->szCopyright = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
IStream_Read (pStm, This->szCopyright, Chunk.dwSize, NULL);
if (even_or_odd(Chunk.dwSize)) {
ListCount[0] ++;
liMove.QuadPart = 1;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
}
break;
}
case mmioFOURCC('I','S','B','J'): {
TRACE_(dmfile)(": subject chunk (ignored)\n");
if (even_or_odd(Chunk.dwSize)) {
ListCount[0] ++;
Chunk.dwSize++;
}
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case mmioFOURCC('I','C','M','T'): {
TRACE_(dmfile)(": comment chunk (ignored)\n");
if (even_or_odd(Chunk.dwSize)) {
ListCount[0] ++;
Chunk.dwSize++;
}
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
if (even_or_odd(Chunk.dwSize)) {
ListCount[0] ++;
Chunk.dwSize++;
}
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
} while (ListCount[0] < ListSize[0]);
break;
}
case FOURCC_WVPL: {
TRACE_(dmfile)(": wave pool list (mark & skip)\n");
liMove.QuadPart = 0;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, &dlibWavePoolPosition); /* store position */
This->liWavePoolTablePosition.QuadPart = dlibWavePoolPosition.QuadPart;
liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case FOURCC_LINS: {
TRACE_(dmfile)(": instruments list\n");
do {
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
switch (Chunk.fccID) {
case FOURCC_LIST: {
IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
ListCount[1] = 0;
switch (Chunk.fccID) {
case FOURCC_INS: {
LPDMUS_PRIVATE_INSTRUMENTENTRY pNewInstrument = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY));
TRACE_(dmfile)(": instrument list\n");
DMUSIC_CreateDirectMusicInstrumentImpl (&IID_IDirectMusicInstrument, (LPVOID*)&pNewInstrument->pInstrument, NULL); /* only way to create this one... even M$ does it discretely */
{
IDirectMusicInstrumentImpl *pInstrument = impl_from_IDirectMusicInstrument(pNewInstrument->pInstrument);
liMove.QuadPart = 0;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, &dlibInstrumentPosition);
pInstrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart - (2*sizeof(FOURCC) + sizeof(DWORD)); /* store offset, it'll be needed later */
IDirectMusicCollectionImpl *This = impl_from_IPersistStream(iface);
DMUS_PRIVATE_CHUNK chunk;
DWORD StreamSize, StreamCount, ListSize[3], ListCount[3];
LARGE_INTEGER liMove; /* used when skipping chunks */
ULARGE_INTEGER dlibCollectionPosition, dlibInstrumentPosition, dlibWavePoolPosition;
do {
IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
switch (Chunk.fccID) {
case FOURCC_INSH: {
TRACE_(dmfile)(": instrument header chunk\n");
pInstrument->pHeader = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
IStream_Read (pStm, pInstrument->pHeader, Chunk.dwSize, NULL);
break;
}
case FOURCC_DLID: {
TRACE_(dmfile)(": DLID (GUID) chunk\n");
pInstrument->pInstrumentID = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, Chunk.dwSize);
IStream_Read (pStm, pInstrument->pInstrumentID, Chunk.dwSize, NULL);
break;
}
case FOURCC_LIST: {
IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
ListSize[2] = Chunk.dwSize - sizeof(FOURCC);
ListCount[2] = 0;
switch (Chunk.fccID) {
default: {
TRACE_(dmfile)(": unknown (skipping)\n");
liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
} while (ListCount[1] < ListSize[1]);
/* DEBUG: dumps whole instrument object tree: */
if (TRACE_ON(dmusic)) {
TRACE("*** IDirectMusicInstrument (%p) ***\n", pInstrument);
if (pInstrument->pInstrumentID)
TRACE(" - GUID = %s\n", debugstr_dmguid(pInstrument->pInstrumentID));
TRACE(" - Instrument header:\n");
TRACE(" - cRegions: %d\n", pInstrument->pHeader->cRegions);
TRACE(" - Locale:\n");
TRACE(" - ulBank: %d\n", pInstrument->pHeader->Locale.ulBank);
TRACE(" - ulInstrument: %d\n", pInstrument->pHeader->Locale.ulInstrument);
TRACE(" => dwPatch: %d\n", MIDILOCALE2Patch(&pInstrument->pHeader->Locale));
}
list_add_tail (&This->Instruments, &pNewInstrument->entry);
}
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
} while (ListCount[0] < ListSize[0]);
break;
}
default: {
TRACE_(dmfile)(": unknown (skipping)\n");
liMove.QuadPart = Chunk.dwSize - sizeof(FOURCC);
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": StreamCount = %d < StreamSize = %d\n", StreamCount, StreamSize);
} while (StreamCount < StreamSize);
break;
}
default: {
TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
liMove.QuadPart = StreamSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
return E_FAIL;
}
}
TRACE_(dmfile)(": reading finished\n");
break;
}
default: {
TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
liMove.QuadPart = Chunk.dwSize;
IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
return E_FAIL;
}
}
IStream_AddRef(stream); /* add count for later references */
liMove.QuadPart = 0;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dlibCollectionPosition); /* store offset, in case it'll be needed later */
This->liCollectionPosition.QuadPart = dlibCollectionPosition.QuadPart;
This->pStm = stream;
/* DEBUG: dumps whole collection object tree: */
if (TRACE_ON(dmusic)) {
int r = 0;
DMUS_PRIVATE_INSTRUMENTENTRY *tmpEntry;
struct list *listEntry;
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
TRACE("*** IDirectMusicCollection (%p) ***\n", &This->IDirectMusicCollection_iface);
if (This->pDesc->dwValidData & DMUS_OBJ_OBJECT)
TRACE(" - GUID = %s\n", debugstr_dmguid(&This->pDesc->guidObject));
if (This->pDesc->dwValidData & DMUS_OBJ_VERSION)
TRACE(" - Version = %i,%i,%i,%i\n", (This->pDesc->vVersion.dwVersionMS >> 8) & 0x0000FFFF, This->pDesc->vVersion.dwVersionMS & 0x0000FFFF,
(This->pDesc->vVersion.dwVersionLS >> 8) & 0x0000FFFF, This->pDesc->vVersion.dwVersionLS & 0x0000FFFF);
if (This->pDesc->dwValidData & DMUS_OBJ_NAME)
TRACE(" - Name = %s\n", debugstr_w(This->pDesc->wszName));
TRACE(" - Collection header:\n");
TRACE(" - cInstruments: %d\n", This->pHeader->cInstruments);
TRACE(" - Instruments:\n");
LIST_FOR_EACH (listEntry, &This->Instruments) {
tmpEntry = LIST_ENTRY( listEntry, DMUS_PRIVATE_INSTRUMENTENTRY, entry );
TRACE(" - Instrument[%i]: %p\n", r, tmpEntry->pInstrument);
r++;
}
}
return S_OK;
if (chunk.fccID != FOURCC_RIFF) {
TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
return E_FAIL;
}
IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(chunk.fccID));
StreamSize = chunk.dwSize - sizeof(FOURCC);
StreamCount = 0;
if (chunk.fccID != FOURCC_DLS) {
TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
liMove.QuadPart = StreamSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
return E_FAIL;
}
TRACE_(dmfile)(": collection form\n");
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
StreamCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
switch (chunk.fccID) {
case FOURCC_COLH: {
TRACE_(dmfile)(": collection header chunk\n");
This->pHeader = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, chunk.dwSize);
IStream_Read(stream, This->pHeader, chunk.dwSize, NULL);
break;
}
case FOURCC_DLID: {
TRACE_(dmfile)(": DLID (GUID) chunk\n");
This->pDesc->dwValidData |= DMUS_OBJ_OBJECT;
IStream_Read(stream, &This->pDesc->guidObject, chunk.dwSize, NULL);
break;
}
case FOURCC_VERS: {
TRACE_(dmfile)(": version chunk\n");
This->pDesc->dwValidData |= DMUS_OBJ_VERSION;
IStream_Read(stream, &This->pDesc->vVersion, chunk.dwSize, NULL);
break;
}
case FOURCC_PTBL: {
TRACE_(dmfile)(": pool table chunk\n");
This->pPoolTable = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POOLTABLE));
IStream_Read(stream, This->pPoolTable, sizeof(POOLTABLE), NULL);
chunk.dwSize -= sizeof(POOLTABLE);
This->pPoolCues = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->pPoolTable->cCues * sizeof(POOLCUE));
IStream_Read(stream, This->pPoolCues, chunk.dwSize, NULL);
break;
}
case FOURCC_LIST: {
IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID));
ListSize[0] = chunk.dwSize - sizeof(FOURCC);
ListCount[0] = 0;
switch (chunk.fccID) {
case mmioFOURCC('I','N','F','O'): {
TRACE_(dmfile)(": INFO list\n");
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
switch (chunk.fccID) {
case mmioFOURCC('I','N','A','M'): {
CHAR szName[DMUS_MAX_NAME];
TRACE_(dmfile)(": name chunk\n");
This->pDesc->dwValidData |= DMUS_OBJ_NAME;
IStream_Read(stream, szName, chunk.dwSize, NULL);
MultiByteToWideChar(CP_ACP, 0, szName, -1, This->pDesc->wszName, DMUS_MAX_NAME);
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
liMove.QuadPart = 1;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
}
break;
}
case mmioFOURCC('I','A','R','T'): {
TRACE_(dmfile)(": artist chunk (ignored)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case mmioFOURCC('I','C','O','P'): {
TRACE_(dmfile)(": copyright chunk\n");
This->szCopyright = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, chunk.dwSize);
IStream_Read(stream, This->szCopyright, chunk.dwSize, NULL);
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
liMove.QuadPart = 1;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
}
break;
}
case mmioFOURCC('I','S','B','J'): {
TRACE_(dmfile)(": subject chunk (ignored)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case mmioFOURCC('I','C','M','T'): {
TRACE_(dmfile)(": comment chunk (ignored)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
if (even_or_odd(chunk.dwSize)) {
ListCount[0]++;
chunk.dwSize++;
}
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
} while (ListCount[0] < ListSize[0]);
break;
}
case FOURCC_WVPL: {
TRACE_(dmfile)(": wave pool list (mark & skip)\n");
liMove.QuadPart = 0;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dlibWavePoolPosition); /* store position */
This->liWavePoolTablePosition.QuadPart = dlibWavePoolPosition.QuadPart;
liMove.QuadPart = chunk.dwSize - sizeof(FOURCC);
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
case FOURCC_LINS: {
TRACE_(dmfile)(": instruments list\n");
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
switch (chunk.fccID) {
case FOURCC_LIST: {
IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID));
ListSize[1] = chunk.dwSize - sizeof(FOURCC);
ListCount[1] = 0;
switch (chunk.fccID) {
case FOURCC_INS: {
LPDMUS_PRIVATE_INSTRUMENTENTRY new_instrument = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY));
TRACE_(dmfile)(": instrument list\n");
/* Only way to create this one... even M$ does it discretely */
DMUSIC_CreateDirectMusicInstrumentImpl(&IID_IDirectMusicInstrument, (LPVOID*)&new_instrument->pInstrument, NULL);
{
IDirectMusicInstrumentImpl *instrument = impl_from_IDirectMusicInstrument(new_instrument->pInstrument);
liMove.QuadPart = 0;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dlibInstrumentPosition);
/* Store offset, it'll be needed later */
instrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart - (2 * sizeof(FOURCC) + sizeof(DWORD));
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
switch (chunk.fccID) {
case FOURCC_INSH: {
TRACE_(dmfile)(": instrument header chunk\n");
instrument->pHeader = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, chunk.dwSize);
IStream_Read(stream, instrument->pHeader, chunk.dwSize, NULL);
break;
}
case FOURCC_DLID: {
TRACE_(dmfile)(": DLID (GUID) chunk\n");
instrument->pInstrumentID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, chunk.dwSize);
IStream_Read(stream, instrument->pInstrumentID, chunk.dwSize, NULL);
break;
}
case FOURCC_LIST: {
IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL);
TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID));
ListSize[2] = chunk.dwSize - sizeof(FOURCC);
ListCount[2] = 0;
switch (chunk.fccID) {
default: {
TRACE_(dmfile)(": unknown (skipping)\n");
liMove.QuadPart = chunk.dwSize - sizeof(FOURCC);
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[1] = %d < ListSize[1] = %d\n", ListCount[1], ListSize[1]);
} while (ListCount[1] < ListSize[1]);
/* DEBUG: dumps whole instrument object tree: */
if (TRACE_ON(dmusic)) {
TRACE("*** IDirectMusicInstrument (%p) ***\n", instrument);
if (instrument->pInstrumentID)
TRACE(" - GUID = %s\n", debugstr_dmguid(instrument->pInstrumentID));
TRACE(" - Instrument header:\n");
TRACE(" - cRegions: %d\n", instrument->pHeader->cRegions);
TRACE(" - Locale:\n");
TRACE(" - ulBank: %d\n", instrument->pHeader->Locale.ulBank);
TRACE(" - ulInstrument: %d\n", instrument->pHeader->Locale.ulInstrument);
TRACE(" => dwPatch: %d\n", MIDILOCALE2Patch(&instrument->pHeader->Locale));
}
list_add_tail(&This->Instruments, &new_instrument->entry);
}
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
} while (ListCount[0] < ListSize[0]);
break;
}
default: {
TRACE_(dmfile)(": unknown (skipping)\n");
liMove.QuadPart = chunk.dwSize - sizeof(FOURCC);
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
break;
}
default: {
TRACE_(dmfile)(": unknown chunk (irrelevant & skipping)\n");
liMove.QuadPart = chunk.dwSize;
IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL);
break;
}
}
TRACE_(dmfile)(": StreamCount = %d < StreamSize = %d\n", StreamCount, StreamSize);
} while (StreamCount < StreamSize);
TRACE_(dmfile)(": reading finished\n");
/* DEBUG: dumps whole collection object tree: */
if (TRACE_ON(dmusic)) {
int r = 0;
DMUS_PRIVATE_INSTRUMENTENTRY *tmpEntry;
struct list *listEntry;
TRACE("*** IDirectMusicCollection (%p) ***\n", &This->IDirectMusicCollection_iface);
if (This->pDesc->dwValidData & DMUS_OBJ_OBJECT)
TRACE(" - GUID = %s\n", debugstr_dmguid(&This->pDesc->guidObject));
if (This->pDesc->dwValidData & DMUS_OBJ_VERSION)
TRACE(" - Version = %i,%i,%i,%i\n", (This->pDesc->vVersion.dwVersionMS >> 8) & 0x0000FFFF, This->pDesc->vVersion.dwVersionMS & 0x0000FFFF,
(This->pDesc->vVersion.dwVersionLS >> 8) & 0x0000FFFF, This->pDesc->vVersion.dwVersionLS & 0x0000FFFF);
if (This->pDesc->dwValidData & DMUS_OBJ_NAME)
TRACE(" - Name = %s\n", debugstr_w(This->pDesc->wszName));
TRACE(" - Collection header:\n");
TRACE(" - cInstruments: %d\n", This->pHeader->cInstruments);
TRACE(" - Instruments:\n");
LIST_FOR_EACH(listEntry, &This->Instruments) {
tmpEntry = LIST_ENTRY( listEntry, DMUS_PRIVATE_INSTRUMENTENTRY, entry );
TRACE(" - Instrument[%i]: %p\n", r, tmpEntry->pInstrument);
r++;
}
}
return S_OK;
}
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Save(LPPERSISTSTREAM iface, IStream* pStm, BOOL fClearDirty)