[QUARTZ_WINETEST]
[reactos.git] / rostests / winetests / quartz / filtermapper.c
index 4a8a3bb..a67df1d 100644 (file)
@@ -24,6 +24,9 @@
 #include "winbase.h"
 #include "initguid.h"
 #include "dshow.h"
+#include "winternl.h"
+
+#include "fil_data.h"
 
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 
@@ -101,8 +104,8 @@ static void test_fm2_enummatchingfilters(void)
     /* Test that a test renderer filter is returned when enumerating filters with bRender=FALSE */
     rgf2.dwVersion = 2;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S1(U(rgf2)).cPins2 = 1;
-    S1(U(rgf2)).rgPins2 = rgPins2;
+    S2(U(rgf2)).cPins2 = 1;
+    S2(U(rgf2)).rgPins2 = rgPins2;
 
     rgPins2[0].dwFlags = REG_PINFLAG_B_RENDERER;
     rgPins2[0].cInstances = 1;
@@ -117,58 +120,63 @@ static void test_fm2_enummatchingfilters(void)
 
     hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter1, wszFilterName1, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+    if (hr == E_ACCESSDENIED)
+        skip("Not authorized to register filters\n");
+    else
+    {
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
-    rgPins2[0].dwFlags = 0;
+        rgPins2[0].dwFlags = 0;
 
-    rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
-    rgPins2[1].cInstances = 1;
-    rgPins2[1].nMediaTypes = 1;
-    rgPins2[1].lpMediaType = &rgPinType;
-    rgPins2[1].nMediums = 0;
-    rgPins2[1].lpMedium = NULL;
-    rgPins2[1].clsPinCategory = NULL;
+        rgPins2[1].dwFlags = REG_PINFLAG_B_OUTPUT;
+        rgPins2[1].cInstances = 1;
+        rgPins2[1].nMediaTypes = 1;
+        rgPins2[1].lpMediaType = &rgPinType;
+        rgPins2[1].nMediums = 0;
+        rgPins2[1].lpMedium = NULL;
+        rgPins2[1].clsPinCategory = NULL;
 
-    S1(U(rgf2)).cPins2 = 2;
+        S2(U(rgf2)).cPins2 = 2;
 
-    hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter2, wszFilterName2, NULL,
+        hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter2, wszFilterName2, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
-    ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
+        ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName1, pEnum);
-        ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
-    }
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName1, pEnum);
+            ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
+        }
 
-    if (pEnum) IEnumMoniker_Release(pEnum);
-    pEnum = NULL;
+        if (pEnum) IEnumMoniker_Release(pEnum);
+        pEnum = NULL;
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName2, pEnum);
-        ok(found, "EnumMatchingFilters failed to return the test filter 2\n");
-    }
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName2, pEnum);
+            ok(found, "EnumMatchingFilters failed to return the test filter 2\n");
+        }
 
-    if (pEnum) IEnumMoniker_Release(pEnum);
-    pEnum = NULL;
+        if (pEnum) IEnumMoniker_Release(pEnum);
+        pEnum = NULL;
 
-    /* Non renderer must not be returned with bRender=TRUE */
+        /* Non renderer must not be returned with bRender=TRUE */
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, TRUE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
 
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName1, pEnum);
-        ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName1, pEnum);
+            ok(found, "EnumMatchingFilters failed to return the test filter 1\n");
+        }
     }
 
     if (pEnum) IEnumMoniker_Release(pEnum);
@@ -225,7 +233,7 @@ static void test_legacy_filter_registration(void)
     ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr);
     if (FAILED(hr)) goto out;
 
-    hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterMapper, (LPVOID)&pMapper);
+    hr = IFilterMapper2_QueryInterface(pMapper2, &IID_IFilterMapper, (void **)&pMapper);
     ok(hr == S_OK, "IFilterMapper2_QueryInterface failed with %x\n", hr);
     if (FAILED(hr)) goto out;
 
@@ -245,67 +253,72 @@ static void test_legacy_filter_registration(void)
     /* Register---- functions need a filter class key to write pin and pin media type data to. Create a bogus
      * class key for it. */
     lRet = RegCreateKeyExA(HKEY_CLASSES_ROOT, szRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL);
-    ok(lRet == ERROR_SUCCESS, "RegCreateKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+    if (lRet == ERROR_ACCESS_DENIED)
+        skip("Not authorized to register filters\n");
+    else
+    {
+        ok(lRet == ERROR_SUCCESS, "RegCreateKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
 
-    /* Set default value - this is interpreted as "friendly name" later. */
-    lRet = RegSetValueExA(hKey, NULL, 0, REG_SZ, (LPBYTE)szFilterName, lstrlenA(szFilterName) + 1);
-    ok(lRet == ERROR_SUCCESS, "RegSetValueExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+        /* Set default value - this is interpreted as "friendly name" later. */
+        lRet = RegSetValueExA(hKey, NULL, 0, REG_SZ, (LPBYTE)szFilterName, lstrlenA(szFilterName) + 1);
+        ok(lRet == ERROR_SUCCESS, "RegSetValueExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
 
-    if (hKey) RegCloseKey(hKey);
-    hKey = NULL;
+        if (hKey) RegCloseKey(hKey);
+        hKey = NULL;
 
-    hr = IFilterMapper_RegisterFilter(pMapper, clsidFilter, wszFilterName, MERIT_UNLIKELY);
-    ok(hr == S_OK, "IFilterMapper_RegisterFilter failed with %x\n", hr);
+        hr = IFilterMapper_RegisterFilter(pMapper, clsidFilter, wszFilterName, MERIT_UNLIKELY);
+        ok(hr == S_OK, "IFilterMapper_RegisterFilter failed with %x\n", hr);
 
-    hr = IFilterMapper_RegisterPin(pMapper, clsidFilter, wszPinName, TRUE, FALSE, FALSE, FALSE, GUID_NULL, NULL);
-    ok(hr == S_OK, "IFilterMapper_RegisterPin failed with %x\n", hr);
+        hr = IFilterMapper_RegisterPin(pMapper, clsidFilter, wszPinName, TRUE, FALSE, FALSE, FALSE, GUID_NULL, NULL);
+        ok(hr == S_OK, "IFilterMapper_RegisterPin failed with %x\n", hr);
 
-    hr = IFilterMapper_RegisterPinType(pMapper, clsidFilter, wszPinName, GUID_NULL, GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper_RegisterPinType failed with %x\n", hr);
+        hr = IFilterMapper_RegisterPinType(pMapper, clsidFilter, wszPinName, GUID_NULL, GUID_NULL);
+        ok(hr == S_OK, "IFilterMapper_RegisterPinType failed with %x\n", hr);
 
-    hr = IFilterMapper2_EnumMatchingFilters(pMapper2, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
+        hr = IFilterMapper2_EnumMatchingFilters(pMapper2, &pEnum, 0, TRUE, MERIT_UNLIKELY, TRUE,
                 0, NULL, NULL, &GUID_NULL, FALSE, FALSE, 0, NULL, NULL, &GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pEnum)
-    {
-        found = enum_find_filter(wszFilterName, pEnum);
-        ok(found, "IFilterMapper2_EnumMatchingFilters failed to return the test filter\n");
-    }
+        ok(hr == S_OK, "IFilterMapper2_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pEnum)
+        {
+            found = enum_find_filter(wszFilterName, pEnum);
+            ok(found, "IFilterMapper2_EnumMatchingFilters failed to return the test filter\n");
+        }
 
-    if (pEnum) IEnumMoniker_Release(pEnum);
-    pEnum = NULL;
+        if (pEnum) IEnumMoniker_Release(pEnum);
+        pEnum = NULL;
 
-    found = FALSE;
-    hr = IFilterMapper_EnumMatchingFilters(pMapper, &pRegEnum, MERIT_UNLIKELY, TRUE, GUID_NULL, GUID_NULL,
+        found = FALSE;
+        hr = IFilterMapper_EnumMatchingFilters(pMapper, &pRegEnum, MERIT_UNLIKELY, TRUE, GUID_NULL, GUID_NULL,
             FALSE, FALSE, GUID_NULL, GUID_NULL);
-    ok(hr == S_OK, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr);
-    if (SUCCEEDED(hr) && pRegEnum)
-    {
-        ULONG cFetched;
-        REGFILTER *prgf;
-
-        while(!found && IEnumRegFilters_Next(pRegEnum, 1, &prgf, &cFetched) == S_OK)
+        ok(hr == S_OK, "IFilterMapper_EnumMatchingFilters failed with %x\n", hr);
+        if (SUCCEEDED(hr) && pRegEnum)
         {
-            CHAR val[512];
+            ULONG cFetched;
+            REGFILTER *prgf;
 
-            WideCharToMultiByte(CP_ACP, 0, prgf->Name, -1, val, sizeof(val), 0, 0);
-            if (!lstrcmpA(val, szFilterName)) found = TRUE;
+            while(!found && IEnumRegFilters_Next(pRegEnum, 1, &prgf, &cFetched) == S_OK)
+            {
+                CHAR val[512];
 
-            CoTaskMemFree(prgf);
-        }
+                WideCharToMultiByte(CP_ACP, 0, prgf->Name, -1, val, sizeof(val), 0, 0);
+                if (!lstrcmpA(val, szFilterName)) found = TRUE;
 
-        IEnumRegFilters_Release(pRegEnum);
-    }
-    ok(found, "IFilterMapper_EnumMatchingFilters failed to return the test filter\n");
+                CoTaskMemFree(prgf);
+            }
 
-    hr = IFilterMapper_UnregisterFilter(pMapper, clsidFilter);
-    ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
+            IEnumRegFilters_Release(pRegEnum);
+        }
+        ok(found, "IFilterMapper_EnumMatchingFilters failed to return the test filter\n");
+
+        hr = IFilterMapper_UnregisterFilter(pMapper, clsidFilter);
+        ok(hr == S_OK, "FilterMapper_UnregisterFilter failed with %x\n", hr);
 
-    lRet = RegOpenKeyExA(HKEY_CLASSES_ROOT, szClsid, 0, KEY_WRITE | DELETE, &hKey);
-    ok(lRet == ERROR_SUCCESS, "RegOpenKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+        lRet = RegOpenKeyExA(HKEY_CLASSES_ROOT, szClsid, 0, KEY_WRITE | DELETE, &hKey);
+        ok(lRet == ERROR_SUCCESS, "RegOpenKeyExA failed with %x\n", HRESULT_FROM_WIN32(lRet));
 
-    lRet = RegDeleteKeyA(hKey, szGuidstring);
-    ok(lRet == ERROR_SUCCESS, "RegDeleteKeyA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+        lRet = RegDeleteKeyA(hKey, szGuidstring);
+        ok(lRet == ERROR_SUCCESS, "RegDeleteKeyA failed with %x\n", HRESULT_FROM_WIN32(lRet));
+    }
 
     if (hKey) RegCloseKey(hKey);
     hKey = NULL;
@@ -405,8 +418,8 @@ static void test_register_filter_with_null_clsMinorType(void)
     ZeroMemory(&rgf2, sizeof(rgf2));
     rgf2.dwVersion = 1;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S(U(rgf2)).cPins = 1;
-    S(U(rgf2)).rgPins = &rgPins;
+    S1(U(rgf2)).cPins = 1;
+    S1(U(rgf2)).rgPins = &rgPins;
 
     rgPins.strName = wszPinName;
     rgPins.bRendered = 1;
@@ -420,6 +433,11 @@ static void test_register_filter_with_null_clsMinorType(void)
 
     hr = IFilterMapper2_RegisterFilter(pMapper, &clsidFilter1, wszFilterName1, NULL,
                     &CLSID_LegacyAmFilterCategory, NULL, &rgf2);
+    if (hr == E_ACCESSDENIED)
+    {
+        skip("Not authorized to register filters\n");
+        goto out;
+    }
     ok(hr == S_OK, "IFilterMapper2_RegisterFilter failed with %x\n", hr);
 
     hr = IFilterMapper2_UnregisterFilter(pMapper, &CLSID_LegacyAmFilterCategory, NULL, &clsidFilter1);
@@ -429,8 +447,8 @@ static void test_register_filter_with_null_clsMinorType(void)
     ZeroMemory(&rgf2, sizeof(rgf2));
     rgf2.dwVersion = 2;
     rgf2.dwMerit = MERIT_UNLIKELY;
-    S1(U(rgf2)).cPins2 = 1;
-    S1(U(rgf2)).rgPins2 = &rgPins2;
+    S2(U(rgf2)).cPins2 = 1;
+    S2(U(rgf2)).rgPins2 = &rgPins2;
 
     rgPins2.dwFlags = REG_PINFLAG_B_RENDERER;
     rgPins2.cInstances = 1;
@@ -452,6 +470,70 @@ static void test_register_filter_with_null_clsMinorType(void)
     if (pMapper) IFilterMapper2_Release(pMapper);
 }
 
+static void test_parse_filter_data(void)
+{
+    static const BYTE data_block[] = {
+  0x02,0x00,0x00,0x00,0xff,0xff,0x5f,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x70,0x69,0x33,
+  0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x31,0x70,0x69,0x33,
+  0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x30,0x74,0x79,0x33,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x76,0x69,0x64,0x73,
+  0x00,0x00,0x10,0x00,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+    BYTE *prgbRegFilter2 = NULL;
+    REGFILTER2 *pRegFilter = NULL;
+    IFilterMapper2 *pMapper = NULL;
+    SAFEARRAYBOUND saBound;
+    SAFEARRAY *psa = NULL;
+    LPBYTE pbSAData = NULL;
+    HRESULT hr;
+
+    IAMFilterData *pData = NULL;
+
+    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IFilterMapper2, (LPVOID*)&pMapper);
+    ok((hr == S_OK || broken(hr != S_OK)), "CoCreateInstance failed with %x\n", hr);
+    if (FAILED(hr)) goto out;
+
+    hr = IFilterMapper2_QueryInterface(pMapper, &IID_IAMFilterData, (LPVOID*)&pData);
+    ok((hr == S_OK || broken(hr != S_OK)), "Unable to find IID_IAMFilterData interface\n");
+    if (FAILED(hr)) goto out;
+
+    saBound.lLbound = 0;
+    saBound.cElements = sizeof(data_block);
+    psa = SafeArrayCreate(VT_UI1, 1, &saBound);
+    ok(psa != NULL, "Unable to crate safe array\n");
+    if (!psa) goto out;
+    hr = SafeArrayAccessData(psa, (LPVOID *)&pbSAData);
+    ok(hr == S_OK, "Unable to access array data\n");
+    if (FAILED(hr)) goto out;
+    memcpy(pbSAData, data_block, sizeof(data_block));
+
+    hr = IAMFilterData_ParseFilterData(pData, pbSAData, sizeof(data_block), &prgbRegFilter2);
+    /* We cannot do anything here.  prgbRegFilter2 is very unstable */
+    /* Pre Vista, this is a stack pointer so anything that changes the stack invalidats it */
+    /* Post Vista, it is a static pointer in the data section of the module */
+    pRegFilter =((REGFILTER2**)prgbRegFilter2)[0];
+    ok (hr==S_OK,"Failed to Parse filter Data\n");
+
+    ok(IsBadReadPtr(prgbRegFilter2,sizeof(REGFILTER2*))==0,"Bad read pointer returned\n");
+    ok(IsBadReadPtr(pRegFilter,sizeof(REGFILTER2))==0,"Bad read pointer for FilterData\n");
+    ok(pRegFilter->dwMerit == 0x5fffff,"Incorrect merit returned\n");
+
+out:
+    if (pRegFilter)
+        CoTaskMemFree(pRegFilter);
+    if (psa)
+    {
+        SafeArrayUnaccessData(psa);
+        SafeArrayDestroy(psa);
+    }
+    if (pData)
+        IAMFilterData_Release(pData);
+    if (pMapper)
+        IFilterMapper2_Release(pMapper);
+}
 
 START_TEST(filtermapper)
 {
@@ -461,6 +543,7 @@ START_TEST(filtermapper)
     test_legacy_filter_registration();
     test_ifiltermapper_from_filtergraph();
     test_register_filter_with_null_clsMinorType();
+    test_parse_filter_data();
 
     CoUninitialize();
 }