[PATCH] dmime: Reimplement the reference list parser

Michael Stefaniuc mstefani at winehq.org
Sun Jul 12 16:40:22 CDT 2020


Bits and pieces from a patch by Alistair Leslie-Hughes.

Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
 dlls/dmime/Makefile.in       |   1 -
 dlls/dmime/dmobject.c        |  41 +++++++++
 dlls/dmime/dmobject.h        |   4 +
 dlls/dmime/dmutils.c         | 163 -----------------------------------
 dlls/dmime/dmutils.h         |   5 --
 dlls/dmime/segtriggertrack.c |  10 ++-
 6 files changed, 52 insertions(+), 172 deletions(-)
 delete mode 100644 dlls/dmime/dmutils.c

diff --git a/dlls/dmime/Makefile.in b/dlls/dmime/Makefile.in
index 0785176786..ed6264903e 100644
--- a/dlls/dmime/Makefile.in
+++ b/dlls/dmime/Makefile.in
@@ -7,7 +7,6 @@ C_SRCS = \
 	audiopath.c \
 	dmime_main.c \
 	dmobject.c \
-	dmutils.c \
 	graph.c \
 	lyricstrack.c \
 	markertrack.c \
diff --git a/dlls/dmime/dmobject.c b/dlls/dmime/dmobject.c
index 1c9c1020ba..2a0a540fdb 100644
--- a/dlls/dmime/dmobject.c
+++ b/dlls/dmime/dmobject.c
@@ -572,6 +572,47 @@ HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff,
     return hr;
 }
 
+HRESULT dmobj_parsereference(IStream *stream, const struct chunk_entry *list,
+        IDirectMusicObject **dmobj)
+{
+    struct chunk_entry chunk = {.parent = list};
+    IDirectMusicGetLoader *getloader;
+    IDirectMusicLoader *loader;
+    DMUS_OBJECTDESC desc;
+    DMUS_IO_REFERENCE reference;
+    HRESULT hr;
+
+    if (FAILED(hr = stream_next_chunk(stream, &chunk)))
+        return hr;
+    if (chunk.id != DMUS_FOURCC_REF_CHUNK)
+        return DMUS_E_UNSUPPORTED_STREAM;
+
+    if (FAILED(hr = stream_chunk_get_data(stream, &chunk, &reference, sizeof(reference)))) {
+        WARN("Failed to read data of %s\n", debugstr_chunk(&chunk));
+        return hr;
+    }
+    TRACE("REFERENCE guidClassID %s, dwValidData %#x\n", debugstr_dmguid(&reference.guidClassID),
+            reference.dwValidData);
+
+    if (FAILED(hr = dmobj_parsedescriptor(stream, list, &desc, reference.dwValidData)))
+        return hr;
+    desc.guidClass = reference.guidClassID;
+    desc.dwValidData |= DMUS_OBJ_CLASS;
+    dump_DMUS_OBJECTDESC(&desc);
+
+    if (FAILED(hr = IStream_QueryInterface(stream, &IID_IDirectMusicGetLoader, (void**)&getloader)))
+        return hr;
+    hr = IDirectMusicGetLoader_GetLoader(getloader, &loader);
+    IDirectMusicGetLoader_Release(getloader);
+    if (FAILED(hr))
+        return hr;
+
+    hr = IDirectMusicLoader_GetObject(loader, &desc, &IID_IDirectMusicObject, (void**)dmobj);
+    IDirectMusicLoader_Release(loader);
+
+    return hr;
+}
+
 /* Generic IPersistStream methods */
 static inline struct dmobject *impl_from_IPersistStream(IPersistStream *iface)
 {
diff --git a/dlls/dmime/dmobject.h b/dlls/dmime/dmobject.h
index d347020691..fcbb89fd28 100644
--- a/dlls/dmime/dmobject.h
+++ b/dlls/dmime/dmobject.h
@@ -89,6 +89,10 @@ HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff,
 #define DMUS_OBJ_NAME_INAM   0x1000     /* 'INAM' chunk in UNFO list */
 #define DMUS_OBJ_NAME_INFO   0x2000     /* 'INAM' chunk in INFO list */
 
+/* 'DMRF' (reference list) helper */
+HRESULT dmobj_parsereference(IStream *stream, const struct chunk_entry *list,
+        IDirectMusicObject **dmobj) DECLSPEC_HIDDEN;
+
 /* Generic IPersistStream methods */
 HRESULT WINAPI dmobj_IPersistStream_QueryInterface(IPersistStream *iface, REFIID riid,
         void **ret_iface) DECLSPEC_HIDDEN;
diff --git a/dlls/dmime/dmutils.c b/dlls/dmime/dmutils.c
deleted file mode 100644
index a61fd5a463..0000000000
--- a/dlls/dmime/dmutils.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Debug and Helper Functions
- *
- * Copyright (C) 2004 Rok Mandeljc
- * Copyright (C) 2004 Raphael Junqueira
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#define COBJMACROS
-
-
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-
-#include "windef.h"
-#include "winbase.h"
-#include "winnt.h"
-#include "wingdi.h"
-#include "winuser.h"
-
-#include "wine/debug.h"
-#include "objbase.h"
-
-#include "dmusici.h"
-#include "dmusicf.h"
-#include "dmusics.h"
-
-#include "dmutils.h"
-#include "dmobject.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(dmfile);
-
-static HRESULT IDirectMusicUtils_IPersistStream_ParseDescGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc) {
-
-  switch (pChunk->fccID) {
-  case DMUS_FOURCC_GUID_CHUNK: {
-    TRACE(": GUID chunk\n");
-    pDesc->dwValidData |= DMUS_OBJ_OBJECT;
-    IStream_Read (pStm, &pDesc->guidObject, pChunk->dwSize, NULL);
-    break;
-  }
-  case DMUS_FOURCC_DATE_CHUNK: {
-    TRACE(": file date chunk\n");
-    pDesc->dwValidData |= DMUS_OBJ_DATE;
-    IStream_Read (pStm, &pDesc->ftDate, pChunk->dwSize, NULL);
-    break;
-  }
-  case DMUS_FOURCC_NAME_CHUNK: {
-    TRACE(": name chunk\n");
-    pDesc->dwValidData |= DMUS_OBJ_NAME;
-    IStream_Read (pStm, pDesc->wszName, pChunk->dwSize, NULL);
-    break;
-  }
-  case DMUS_FOURCC_FILE_CHUNK: {
-    TRACE(": file name chunk\n");
-    pDesc->dwValidData |= DMUS_OBJ_FILENAME;
-    IStream_Read (pStm, pDesc->wszFileName, pChunk->dwSize, NULL);
-    break;
-  }
-  case DMUS_FOURCC_VERSION_CHUNK: {
-    TRACE(": version chunk\n");
-    pDesc->dwValidData |= DMUS_OBJ_VERSION;
-    IStream_Read (pStm, &pDesc->vVersion, pChunk->dwSize, NULL);
-    break;
-  }
-  case DMUS_FOURCC_CATEGORY_CHUNK: {
-    TRACE(": category chunk\n");
-    pDesc->dwValidData |= DMUS_OBJ_CATEGORY;
-    IStream_Read (pStm, pDesc->wszCategory, pChunk->dwSize, NULL);
-    break;
-  }
-  default:
-    /* not handled */
-    return S_FALSE;
-  }
-
-  return S_OK;
-}
-
-HRESULT IDirectMusicUtils_IPersistStream_ParseReference (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, IDirectMusicObject** ppObject) {
-  DMUS_PRIVATE_CHUNK Chunk;
-  DWORD ListSize[3], ListCount[3];
-  LARGE_INTEGER liMove; /* used when skipping chunks */
-  HRESULT hr;
-
-  DMUS_IO_REFERENCE ref;
-  DMUS_OBJECTDESC ref_desc;
-
-  memset(&ref, 0, sizeof(ref));
-  memset(&ref_desc, 0, sizeof(ref_desc));
-
-  if (pChunk->fccID != DMUS_FOURCC_REF_LIST) {
-    ERR(": %s chunk should be a REF list\n", debugstr_fourcc (pChunk->fccID));
-    return E_FAIL;
-  }
-
-  ListSize[0] = pChunk->dwSize - sizeof(FOURCC);
-  ListCount[0] = 0;
-
-  do {
-    IStream_Read (pStm, &Chunk, sizeof(FOURCC)+sizeof(DWORD), NULL);
-    ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + Chunk.dwSize;
-    TRACE(": %s chunk (size = %d)", debugstr_fourcc (Chunk.fccID), Chunk.dwSize);
-
-    hr = IDirectMusicUtils_IPersistStream_ParseDescGeneric(&Chunk, pStm, &ref_desc);
-    if (FAILED(hr)) return hr;
-    
-    if (hr == S_FALSE) {
-      switch (Chunk.fccID) { 
-      case DMUS_FOURCC_REF_CHUNK: {
-	TRACE(": Reference chunk\n");
-	if (Chunk.dwSize != sizeof(DMUS_IO_REFERENCE)) return E_FAIL;
-	IStream_Read (pStm, &ref, sizeof(DMUS_IO_REFERENCE), NULL);
-	TRACE(" - guidClassID: %s\n", debugstr_dmguid(&ref.guidClassID));
-	TRACE(" - dwValidData: %u\n", ref.dwValidData);
-	break;
-      } 
-      default: {
-	TRACE(": unknown chunk (irrelevant & skipping)\n");
-	liMove.QuadPart = Chunk.dwSize;
-	IStream_Seek (pStm, liMove, STREAM_SEEK_CUR, NULL);
-	break;						
-      }
-      }
-    }
-    TRACE(": ListCount[0] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
-  } while (ListCount[0] < ListSize[0]);
-
-  ref_desc.dwValidData |= DMUS_OBJ_CLASS;
-  ref_desc.guidClass = ref.guidClassID;
-
-  TRACE("** DM Reference Begin of Load ***\n");
-  TRACE("With Desc:\n");
-  dump_DMUS_OBJECTDESC(&ref_desc);
-
-  {
-    LPDIRECTMUSICGETLOADER pGetLoader = NULL;
-    LPDIRECTMUSICLOADER pLoader = NULL;
-
-    IStream_QueryInterface (pStm, &IID_IDirectMusicGetLoader, (LPVOID*)&pGetLoader);
-    IDirectMusicGetLoader_GetLoader (pGetLoader, &pLoader);
-    IDirectMusicGetLoader_Release (pGetLoader);
-  
-    hr = IDirectMusicLoader_GetObject (pLoader, &ref_desc, &IID_IDirectMusicObject, (LPVOID*)ppObject);
-    IDirectMusicLoader_Release (pLoader); /* release loader */
-  }
-  TRACE("** DM Reference End of Load ***\n");
-
-  return hr;
-}
diff --git a/dlls/dmime/dmutils.h b/dlls/dmime/dmutils.h
index 913bccfabd..521b148604 100644
--- a/dlls/dmime/dmutils.h
+++ b/dlls/dmime/dmutils.h
@@ -27,9 +27,4 @@ typedef struct _DMUS_PRIVATE_CHUNK {
 	DWORD dwSize; /* size of the chunk */
 } DMUS_PRIVATE_CHUNK, *LPDMUS_PRIVATE_CHUNK;
 
-/**
- * Parsing utilities
- */
-extern HRESULT IDirectMusicUtils_IPersistStream_ParseReference (LPPERSISTSTREAM iface, DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, IDirectMusicObject** ppObject) DECLSPEC_HIDDEN;
-
 #endif /* __WINE_DMUTILS_H */
diff --git a/dlls/dmime/segtriggertrack.c b/dlls/dmime/segtriggertrack.c
index d36412cfc3..3e7503ac0c 100644
--- a/dlls/dmime/segtriggertrack.c
+++ b/dlls/dmime/segtriggertrack.c
@@ -304,15 +304,19 @@ static HRESULT parse_segment(IDirectMusicSegTriggerTrack *This, DMUS_PRIVATE_CHU
       break;
     }
     case FOURCC_LIST: {
+      struct chunk_entry list = {.id = FOURCC_LIST, .size = Chunk.dwSize};
+      static const LARGE_INTEGER zero;
+      IStream_Seek(pStm, zero, STREAM_SEEK_CUR, &list.offset);
+      list.offset.QuadPart -= sizeof(FOURCC) + sizeof(DWORD);
       IStream_Read (pStm, &Chunk.fccID, sizeof(FOURCC), NULL);
       TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(Chunk.fccID));
+      list.type = Chunk.fccID;
       ListSize[1] = Chunk.dwSize - sizeof(FOURCC);
       ListCount[1] = 0;
       switch (Chunk.fccID) { 
       case DMUS_FOURCC_REF_LIST: {
-	FIXME_(dmfile)(": DMRF (DM References) list\n");
-        hr = IDirectMusicUtils_IPersistStream_ParseReference(&This->dmobj.IPersistStream_iface,
-                &Chunk, pStm, &pObject);
+        TRACE_(dmfile)(": DMRF (DM References) list\n");
+        hr = dmobj_parsereference(pStm, &list, &pObject);
 	if (FAILED(hr)) {
 	  ERR(": could not load Reference\n");
 	  return hr;
-- 
2.26.2




More information about the wine-devel mailing list