[PATCH] avifil32: Only add the first stream reference to the parent.

Esme Povirk esme at codeweavers.com
Mon Nov 2 15:38:17 CST 2020


Signed-off-by: Esme Povirk <esme at codeweavers.com>
---
This fixes Arena Wars 2, which releases a stream too many times.

 dlls/avifil32/avifile.c   |  4 ++--
 dlls/avifil32/tests/api.c | 34 +++++++++++++++++++++++++++++++++-
 2 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/dlls/avifil32/avifile.c b/dlls/avifil32/avifile.c
index b1654daa690..8f5c5e64562 100644
--- a/dlls/avifil32/avifile.c
+++ b/dlls/avifil32/avifile.c
@@ -699,7 +699,7 @@ static ULONG WINAPI IAVIStream_fnAddRef(IAVIStream *iface)
   TRACE("(%p) ref=%d\n", This, ref);
 
   /* also add ref to parent, so that it doesn't kill us */
-  if (This->paf != NULL)
+  if (This->paf != NULL && ref == 1)
     IAVIFile_AddRef(&This->paf->IAVIFile_iface);
 
   return ref;
@@ -712,7 +712,7 @@ static ULONG WINAPI IAVIStream_fnRelease(IAVIStream *iface)
 
   TRACE("(%p) ref=%d\n", This, ref);
 
-  if (This->paf != NULL)
+  if (This->paf != NULL && ref == 0)
     IAVIFile_Release(&This->paf->IAVIFile_iface);
 
   return ref;
diff --git a/dlls/avifil32/tests/api.c b/dlls/avifil32/tests/api.c
index 66ba2051a06..23c845cb328 100644
--- a/dlls/avifil32/tests/api.c
+++ b/dlls/avifil32/tests/api.c
@@ -352,6 +352,12 @@ static void create_avi_file(const COMMON_AVI_HEADERS *cah, char *filename)
     CloseHandle(hFile);
 }
 
+static ULONG get_file_refcount(PAVIFILE file)
+{
+    AVIFileAddRef(file);
+    return AVIFileRelease(file);
+}
+
 static void test_default_data(void)
 {
     COMMON_AVI_HEADERS cah;
@@ -363,6 +369,7 @@ static void test_default_data(void)
     PAVISTREAM pStream1;
     AVISTREAMINFOA asi0, asi1;
     WAVEFORMATEX wfx;
+    ULONG refcount;
 
     GetTempPathA(MAX_PATH, filename);
     strcpy(filename+strlen(filename), testfilename);
@@ -443,9 +450,34 @@ static void test_default_data(void)
     ok(wfx.nAvgBytesPerSec == 22050, "got %u (expected 22050)\n",wfx.nAvgBytesPerSec);
     ok(wfx.nBlockAlign == 2, "got %u (expected 2)\n",wfx.nBlockAlign);
 
+    refcount = get_file_refcount(pFile);
+    ok(refcount == 3, "got %u (expected 3)\n", refcount);
+
     AVIStreamRelease(pStream0);
+
+    refcount = get_file_refcount(pFile);
+    ok(refcount == 2, "got %u (expected 2)\n", refcount);
+
+    AVIStreamAddRef(pStream1);
+
+    refcount = get_file_refcount(pFile);
+    ok(refcount == 2, "got %u (expected 2)\n", refcount);
+
     AVIStreamRelease(pStream1);
-    AVIFileRelease(pFile);
+    AVIStreamRelease(pStream1);
+
+    refcount = get_file_refcount(pFile);
+    ok(refcount == 1, "got %u (expected 1)\n", refcount);
+
+    refcount = AVIStreamRelease(pStream1);
+    ok(refcount == (ULONG)-1, "got %u (expected 4294967295)\n", refcount);
+
+    refcount = get_file_refcount(pFile);
+    ok(refcount == 1, "got %u (expected 1)\n", refcount);
+
+    refcount = AVIFileRelease(pFile);
+    ok(refcount == 0, "got %u (expected 0)\n", refcount);
+
     ok(DeleteFileA(filename) !=0, "Deleting file %s failed\n", filename);
 }
 
-- 
2.17.1




More information about the wine-devel mailing list