dmusic: Set instrument stream position where the instrument begins, not at the beginning of the instruments list. Simplify CustomLoad accordingly.

This commit is contained in:
Christian Costa 2012-12-19 09:58:03 +01:00 committed by Alexandre Julliard
parent cdf727ebd1
commit f30c18f3d2
3 changed files with 43 additions and 113 deletions

View file

@ -118,7 +118,7 @@ static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_GetInstr
if (patch == inst_patch) {
*instrument = inst_entry->pInstrument;
IDirectMusicInstrument_AddRef(inst_entry->pInstrument);
IDirectMusicInstrumentImpl_Custom_Load(inst_entry->pInstrument, This->pStm);
IDirectMusicInstrumentImpl_CustomLoad(inst_entry->pInstrument, This->pStm);
TRACE(": returning instrument %p\n", *instrument);
return S_OK;
}
@ -665,10 +665,11 @@ static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Load(LPPERSISTST
DMUSIC_CreateDirectMusicInstrumentImpl(&IID_IDirectMusicInstrument, (LPVOID*)&new_instrument->pInstrument, NULL);
{
IDirectMusicInstrumentImpl *instrument = impl_from_IDirectMusicInstrument(new_instrument->pInstrument);
/* Store offset and length, they will be needed when loading the instrument */
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));
instrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart;
instrument->length = ListSize[1];
do {
IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL);
ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;

View file

@ -230,6 +230,7 @@ struct IDirectMusicInstrumentImpl {
/* IDirectMusicInstrumentImpl fields */
LARGE_INTEGER liInstrumentPosition; /* offset in a stream where instrument chunk can be found */
ULONG length; /* Length of the instrument in the stream */
LPGUID pInstrumentID;
LPINSTHEADER pHeader;
WCHAR wszName[DMUS_MAX_NAME];
@ -242,7 +243,7 @@ static inline IDirectMusicInstrumentImpl *impl_from_IDirectMusicInstrument(IDire
}
/* custom :) */
extern HRESULT IDirectMusicInstrumentImpl_Custom_Load (LPDIRECTMUSICINSTRUMENT iface, LPSTREAM pStm) DECLSPEC_HIDDEN;
extern HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream) DECLSPEC_HIDDEN;
/**********************************************************************
* Dll lifetime tracking declaration for dmusic.dll

View file

@ -156,140 +156,68 @@ static inline DWORD subtract_bytes(DWORD len, DWORD bytes)
return len - bytes;
}
static HRESULT load_instrument(IDirectMusicInstrumentImpl *This, IStream *stream, DWORD length)
static inline HRESULT advance_stream(IStream *stream, ULONG bytes)
{
HRESULT hr;
FOURCC fourcc;
DWORD bytes;
LARGE_INTEGER move;
HRESULT ret;
while(length){
hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
if(FAILED(hr))
return hr;
move.QuadPart = bytes;
hr = read_from_stream(stream, &bytes, sizeof(bytes));
if(FAILED(hr))
return hr;
ret = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
if (FAILED(ret))
WARN("IStream_Seek failed: %08x\n", ret);
length = subtract_bytes(length, sizeof(fourcc) + sizeof(bytes));
switch(fourcc){
case FOURCC_INSH:
TRACE("INSH chunk: %u bytes\n", bytes);
hr = read_from_stream(stream, This->pHeader, sizeof(*This->pHeader));
if(FAILED(hr))
return hr;
move.QuadPart = bytes - sizeof(*This->pHeader);
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
if(FAILED(hr)){
WARN("IStream_Seek failed: %08x\n", hr);
return hr;
}
length = subtract_bytes(length, bytes);
break;
case FOURCC_DLID:
TRACE("DLID chunk: %u bytes\n", bytes);
hr = read_from_stream(stream, This->pInstrumentID, sizeof(*This->pInstrumentID));
if(FAILED(hr))
return hr;
move.QuadPart = bytes - sizeof(*This->pInstrumentID);
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
if(FAILED(hr)){
WARN("IStream_Seek failed: %08x\n", hr);
return hr;
}
length = subtract_bytes(length, bytes);
break;
default:
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(fourcc), bytes);
move.QuadPart = bytes;
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
if(FAILED(hr)){
WARN("IStream_Seek failed: %08x\n", hr);
return hr;
}
length = subtract_bytes(length, bytes);
break;
}
}
return S_OK;
return ret;
}
/* aux. function that completely loads instrument; my tests indicate that it's
called somewhere around IDirectMusicCollection_GetInstrument */
HRESULT IDirectMusicInstrumentImpl_Custom_Load(LPDIRECTMUSICINSTRUMENT iface, LPSTREAM stream)
/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
HRESULT IDirectMusicInstrumentImpl_CustomLoad(IDirectMusicInstrument *iface, IStream *stream)
{
IDirectMusicInstrumentImpl *This = impl_from_IDirectMusicInstrument(iface);
LARGE_INTEGER move;
FOURCC fourcc;
DWORD bytes;
HRESULT hr;
DMUS_PRIVATE_CHUNK chunk;
ULONG length = This->length;
TRACE("(%p, %p, offset = %s)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart));
TRACE("(%p, %p): offset = 0x%s, length = %u)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);
hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL);
if(FAILED(hr)){
if (FAILED(hr))
{
WARN("IStream_Seek failed: %08x\n", hr);
goto load_failure;
return DMUS_E_UNSUPPORTED_STREAM;
}
hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
if(FAILED(hr))
goto load_failure;
while (length)
{
hr = read_from_stream(stream, &chunk, sizeof(chunk));
if (FAILED(hr))
return DMUS_E_UNSUPPORTED_STREAM;
if(fourcc != FOURCC_LIST){
WARN("Loading failed: Expected LIST chunk, got: %s\n", debugstr_fourcc(fourcc));
goto load_failure;
}
length = subtract_bytes(length, sizeof(chunk) + chunk.dwSize);
hr = read_from_stream(stream, &bytes, sizeof(bytes));
if(FAILED(hr))
goto load_failure;
switch (chunk.fccID)
{
case FOURCC_INSH:
case FOURCC_DLID:
TRACE("Chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
TRACE("LIST chunk: %u bytes\n", bytes);
while(1){
hr = read_from_stream(stream, &fourcc, sizeof(fourcc));
if(FAILED(hr))
goto load_failure;
/* Instrument header and id are already set so just skip */
hr = advance_stream(stream, chunk.dwSize);
if (FAILED(hr))
return DMUS_E_UNSUPPORTED_STREAM;
switch(fourcc){
case FOURCC_INS:
TRACE("INS chunk: (no byte count)\n");
hr = load_instrument(This, stream, bytes - sizeof(FOURCC));
if(FAILED(hr))
goto load_failure;
break;
break;
default:
hr = read_from_stream(stream, &bytes, sizeof(bytes));
if(FAILED(hr))
goto load_failure;
default:
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
TRACE("Unknown chunk %s: %u bytes\n", debugstr_fourcc(fourcc), bytes);
hr = advance_stream(stream, chunk.dwSize);
if (FAILED(hr))
return DMUS_E_UNSUPPORTED_STREAM;
move.QuadPart = bytes;
hr = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL);
if(FAILED(hr)){
WARN("IStream_Seek failed: %08x\n", hr);
return hr;
}
break;
break;
}
}
return S_OK;
load_failure:
return DMUS_E_UNSUPPORTED_STREAM;
}