ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2024
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
October 2019
----- 2024 -----
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
23 participants
180 discussions
Start a n
N
ew thread
[reactos] 01/01: [DEVENUM_WINETEST] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8cc0d363dc0a4a42def0f…
commit 8cc0d363dc0a4a42def0fa7e5eeaa22aa0431182 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Oct 20 18:56:45 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Oct 20 18:56:45 2019 +0100 [DEVENUM_WINETEST] Sync with Wine Staging 4.18. CORE-16441 --- modules/rostests/winetests/devenum/CMakeLists.txt | 2 +- modules/rostests/winetests/devenum/devenum.c | 123 +++++++++++++++++----- 2 files changed, 97 insertions(+), 28 deletions(-) diff --git a/modules/rostests/winetests/devenum/CMakeLists.txt b/modules/rostests/winetests/devenum/CMakeLists.txt index 840011078f1..bdda324e435 100644 --- a/modules/rostests/winetests/devenum/CMakeLists.txt +++ b/modules/rostests/winetests/devenum/CMakeLists.txt @@ -1,5 +1,5 @@ add_executable(devenum_winetest devenum.c testlist.c) set_module_type(devenum_winetest win32cui) -add_importlibs(devenum_winetest advapi32 dsound msvfw32 oleaut32 ole32 winmm msvcrt kernel32) +add_importlibs(devenum_winetest advapi32 dsound msvfw32 oleaut32 ole32 winmm msdmo msvcrt kernel32) add_rostests_file(TARGET devenum_winetest) diff --git a/modules/rostests/winetests/devenum/devenum.c b/modules/rostests/winetests/devenum/devenum.c index f47ab420261..cda17c200e7 100644 --- a/modules/rostests/winetests/devenum/devenum.c +++ b/modules/rostests/winetests/devenum/devenum.c @@ -32,15 +32,16 @@ #include "dsound.h" #include "mmddk.h" #include "vfw.h" +#include "dmoreg.h" +#include "setupapi.h" DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); static const WCHAR friendly_name[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; -static const WCHAR fcc_handlerW[] = {'F','c','c','H','a','n','d','l','e','r',0}; static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0}; static const WCHAR clsidW[] = {'C','L','S','I','D',0}; static const WCHAR waveW[] = {'w','a','v','e',':',0}; -static const WCHAR mrleW[] = {'m','r','l','e',0}; +static const WCHAR dmoW[] = {'d','m','o',':',0}; static const WCHAR swW[] = {'s','w',':',0}; static const WCHAR cmW[] = {'c','m',':',0}; static const WCHAR backslashW[] = {'\\',0}; @@ -64,10 +65,11 @@ static void test_devenum(IBindCtx *bind_ctx) ICreateDevEnum* create_devenum; IPropertyBag *prop_bag; IMoniker *moniker; - BOOL have_mrle = FALSE; GUID cat_guid, clsid; + WCHAR *displayname; VARIANT var; HRESULT hr; + int count; hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (LPVOID*)&create_devenum); @@ -82,19 +84,20 @@ static void test_devenum(IBindCtx *bind_ctx) ok(hr == S_OK, "IMoniker_BindToStorage failed: %#x\n", hr); VariantInit(&var); - hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); - ok(hr == S_OK, "Failed to read FriendlyName: %#x\n", hr); - - if (winetest_debug > 1) - trace("%s:\n", wine_dbgstr_w(V_BSTR(&var))); - - VariantClear(&var); hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL); ok(hr == S_OK, "Failed to read CLSID: %#x\n", hr); hr = CLSIDFromString(V_BSTR(&var), &cat_guid); ok(hr == S_OK, "got %#x\n", hr); + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + ok(hr == S_OK, "Failed to read FriendlyName: %#x\n", hr); + + if (winetest_debug > 1) + trace("%s %s:\n", wine_dbgstr_guid(&cat_guid), wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); IPropertyBag_Release(prop_bag); IMoniker_Release(moniker); @@ -103,8 +106,13 @@ static void test_devenum(IBindCtx *bind_ctx) if (hr == S_OK) { + count = 0; + while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK) { + hr = IMoniker_GetDisplayName(moniker, NULL, NULL, &displayname); + ok(hr == S_OK, "got %#x\n", hr); + hr = IMoniker_GetClassID(moniker, NULL); ok(hr == E_INVALIDARG, "IMoniker_GetClassID should failed %x\n", hr); @@ -118,38 +126,31 @@ static void test_devenum(IBindCtx *bind_ctx) ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr); hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); - ok(hr == S_OK, "IPropertyBag_Read failed: %#x\n", hr); + ok((hr == S_OK) | (hr == ERROR_KEY_DOES_NOT_EXIST), + "IPropertyBag_Read failed: %#x\n", hr); if (winetest_debug > 1) - trace(" %s\n", wine_dbgstr_w(V_BSTR(&var))); - - if (IsEqualGUID(&CLSID_VideoCompressorCategory, &cat_guid)) { - /* Test well known compressor to ensure that we really enumerate codecs */ - hr = IPropertyBag_Read(prop_bag, fcc_handlerW, &var, NULL); - if (SUCCEEDED(hr)) { - ok(V_VT(&var) == VT_BSTR, "V_VT(var) = %d\n", V_VT(&var)); - if(!lstrcmpW(V_BSTR(&var), mrleW)) - have_mrle = TRUE; - VariantClear(&var); - } - } + trace(" %s %s\n", wine_dbgstr_w(displayname), wine_dbgstr_w(V_BSTR(&var))); hr = IMoniker_BindToObject(moniker, bind_ctx, NULL, &IID_IUnknown, NULL); ok(hr == E_POINTER, "got %#x\n", hr); + VariantClear(&var); + CoTaskMemFree(displayname); IPropertyBag_Release(prop_bag); IMoniker_Release(moniker); + count++; } IEnumMoniker_Release(enum_moniker); + + ok(count > 0, "CreateClassEnumerator() returned S_OK but no devices were enumerated.\n"); } } + IEnumMoniker_Release(enum_cat); ICreateDevEnum_Release(create_devenum); - - /* 64-bit windows are missing mrle codec */ - if(sizeof(void*) == 4) - ok(have_mrle, "mrle codec not found\n"); } + static void test_moniker_isequal(void) { HRESULT res; @@ -476,6 +477,7 @@ static void test_codec(void) * enumerating them will destroy the key */ ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n"); + VariantClear(&var); hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr); @@ -485,6 +487,69 @@ static void test_codec(void) IParseDisplayName_Release(parser); } +static void test_dmo(void) +{ + static const WCHAR name[] = {'d','e','v','e','n','u','m',' ','t','e','s','t',0}; + IParseDisplayName *parser; + IPropertyBag *prop_bag; + WCHAR buffer[200]; + IMoniker *mon; + VARIANT var; + HRESULT hr; + + hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser); + ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr); + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, dmoW); + StringFromGUID2(&CLSID_TestFilter, buffer + lstrlenW(buffer), CHARS_IN_GUID); + StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID); + mon = check_display_name(parser, buffer); + + ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should not be registered\n"); + + hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); + ok(hr == S_OK, "got %#x\n", hr); + + VariantInit(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + ok(hr == E_FAIL, "got %#x\n", hr); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(name); + hr = IPropertyBag_Write(prop_bag, friendly_name, &var); + ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr); + + hr = DMORegister(name, &CLSID_TestFilter, &CLSID_AudioRendererCategory, 0, 0, NULL, 0, NULL); + if (hr != E_FAIL) + { + ok(hr == S_OK, "got %#x\n", hr); + + ok(find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should be registered\n"); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL); + ok(hr == S_OK, "got %#x\n", hr); + ok(!lstrcmpW(V_BSTR(&var), name), "got %s\n", wine_dbgstr_w(V_BSTR(&var))); + + VariantClear(&var); + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(name); + hr = IPropertyBag_Write(prop_bag, friendly_name, &var); + ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr); + + VariantClear(&var); + hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL); + ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr); + + hr = DMOUnregister(&CLSID_TestFilter, &CLSID_AudioRendererCategory); + ok(hr == S_OK, "got %#x\n", hr); + } + IPropertyBag_Release(prop_bag); + IMoniker_Release(mon); + IParseDisplayName_Release(parser); +} + static void test_legacy_filter(void) { static const WCHAR nameW[] = {'t','e','s','t',0}; @@ -536,6 +601,7 @@ static void test_legacy_filter(void) ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n", wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); IPropertyBag_Release(prop_bag); hr = IFilterMapper_UnregisterFilter(mapper, CLSID_TestFilter); @@ -631,6 +697,7 @@ static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *mod ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n", wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); IPropertyBag_Release(prop_bag); IMoniker_Release(mon); IParseDisplayName_Release(parser); @@ -946,6 +1013,7 @@ static void test_vfw(void) ok(!lstrcmpW(name, V_BSTR(&var)), "expected %s, got %s\n", wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var))); + VariantClear(&var); IPropertyBag_Release(prop_bag); IMoniker_Release(mon); } @@ -974,6 +1042,7 @@ START_TEST(devenum) test_register_filter(); test_directshow_filter(); test_codec(); + test_dmo(); test_legacy_filter(); hr = DirectSoundEnumerateW(test_dsound, NULL);
5 years
1
0
0
0
[reactos] 01/01: [DEVENUM] Sync with Wine Staging 4.18. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c1585bb868c74c267d9a6…
commit c1585bb868c74c267d9a66e0ca8daedc51f7b772 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Oct 20 18:56:05 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Oct 20 18:56:05 2019 +0100 [DEVENUM] Sync with Wine Staging 4.18. CORE-16441 --- dll/directx/wine/devenum/CMakeLists.txt | 6 +- dll/directx/wine/devenum/createdevenum.c | 568 ++++++++------------- dll/directx/wine/devenum/devenum_main.c | 112 +++- dll/directx/wine/devenum/devenum_private.h | 28 +- dll/directx/wine/devenum/factory.c | 134 ----- dll/directx/wine/devenum/mediacatenum.c | 171 +++++-- dll/directx/wine/devenum/parsedisplayname.c | 56 +- media/doc/README.WINE | 2 +- sdk/include/reactos/wine/CMakeLists.txt | 2 +- .../include/reactos/wine}/fil_data.idl | 19 +- 10 files changed, 484 insertions(+), 614 deletions(-) diff --git a/dll/directx/wine/devenum/CMakeLists.txt b/dll/directx/wine/devenum/CMakeLists.txt index 671921748a7..d147a1b006a 100644 --- a/dll/directx/wine/devenum/CMakeLists.txt +++ b/dll/directx/wine/devenum/CMakeLists.txt @@ -4,13 +4,11 @@ add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600) add_definitions(-D__WINESRC__) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) -add_idl_headers(devenum_fil_data_header fil_data.idl) spec2def(devenum.dll devenum.spec) list(APPEND SOURCE createdevenum.c devenum_main.c - factory.c mediacatenum.c parsedisplayname.c precomp.h) @@ -24,7 +22,7 @@ set_source_files_properties(devenum.rc PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT set_module_type(devenum win32dll UNICODE) target_link_libraries(devenum strmiids uuid wine) add_delay_importlibs(devenum msvfw32) -add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msvcrt kernel32 ntdll) -add_dependencies(devenum devenum_fil_data_header) +add_importlibs(devenum advapi32 advapi32_vista ole32 oleaut32 winmm user32 avicap32 msacm32 dsound msdmo msvcrt kernel32 ntdll) +add_dependencies(devenum wineheaders) add_pch(devenum precomp.h SOURCE) add_cd_file(TARGET devenum DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/devenum/createdevenum.c b/dll/directx/wine/devenum/createdevenum.c index 1f0005049bd..be6a814fc7d 100644 --- a/dll/directx/wine/devenum/createdevenum.c +++ b/dll/directx/wine/devenum/createdevenum.c @@ -32,17 +32,14 @@ #include "dsound.h" #include "wine/debug.h" -#include "wine/unicode.h" #include "wine/heap.h" #include "mmddk.h" #include "initguid.h" -#include "fil_data.h" +#include "wine/fil_data.h" WINE_DEFAULT_DEBUG_CHANNEL(devenum); -extern HINSTANCE DEVENUM_hInstance; - static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0}; static const WCHAR wszMeritName[] = {'M','e','r','i','t',0}; static const WCHAR wszPins[] = {'P','i','n','s',0}; @@ -55,7 +52,6 @@ static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a', static const WCHAR wszFilterData[] = {'F','i','l','t','e','r','D','a','t','a',0}; static ULONG WINAPI DEVENUM_ICreateDevEnum_AddRef(ICreateDevEnum * iface); -static HRESULT register_codecs(void); static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory); /********************************************************************** @@ -106,11 +102,16 @@ static ULONG WINAPI DEVENUM_ICreateDevEnum_Release(ICreateDevEnum * iface) return 1; /* non-heap based object */ } -static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **ret) +static HRESULT register_codec(const GUID *class, const WCHAR *name, + const GUID *clsid, const WCHAR *friendly_name, IPropertyBag **ret) { static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':','c','m',':',0}; + WCHAR guidstr[CHARS_IN_GUID]; IParseDisplayName *parser; + IPropertyBag *propbag; + IMoniker *mon; WCHAR *buffer; + VARIANT var; ULONG eaten; HRESULT hr; @@ -118,22 +119,48 @@ static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker ** if (FAILED(hr)) return hr; - buffer = heap_alloc((strlenW(deviceW) + CHARS_IN_GUID + strlenW(name) + 1) * sizeof(WCHAR)); + buffer = heap_alloc((lstrlenW(deviceW) + CHARS_IN_GUID + lstrlenW(name) + 1) * sizeof(WCHAR)); if (!buffer) { IParseDisplayName_Release(parser); return E_OUTOFMEMORY; } - strcpyW(buffer, deviceW); - StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID); - strcatW(buffer, backslashW); - strcatW(buffer, name); + lstrcpyW(buffer, deviceW); + StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + lstrcatW(buffer, name); - hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, ret); + IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon); IParseDisplayName_Release(parser); heap_free(buffer); - return hr; + + IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&propbag); + IMoniker_Release(mon); + + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(friendly_name); + hr = IPropertyBag_Write(propbag, wszFriendlyName, &var); + VariantClear(&var); + if (FAILED(hr)) + { + IPropertyBag_Release(propbag); + return hr; + } + + V_VT(&var) = VT_BSTR; + StringFromGUID2(clsid, guidstr, ARRAY_SIZE(guidstr)); + V_BSTR(&var) = SysAllocString(guidstr); + hr = IPropertyBag_Write(propbag, clsidW, &var); + VariantClear(&var); + if (FAILED(hr)) + { + IPropertyBag_Release(propbag); + return hr; + } + + *ret = propbag; + return S_OK; } static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin) @@ -157,7 +184,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin) { HKEY hkeyMajorType = NULL; WCHAR wszMajorTypeName[64]; - DWORD cName = sizeof(wszMajorTypeName) / sizeof(WCHAR); + DWORD cName = ARRAY_SIZE(wszMajorTypeName); DWORD dwMinorTypes, i1; if (RegEnumKeyExW(hkeyTypes, i, wszMajorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue; @@ -177,7 +204,7 @@ static void DEVENUM_ReadPinTypes(HKEY hkeyPinKey, REGFILTERPINS2 *rgPin) CLSID *clsMajorType = NULL, *clsMinorType = NULL; HRESULT hr; - cName = sizeof(wszMinorTypeName) / sizeof(WCHAR); + cName = ARRAY_SIZE(wszMinorTypeName); if (RegEnumKeyExW(hkeyMajorType, i1, wszMinorTypeName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue; clsMinorType = CoTaskMemAlloc(sizeof(CLSID)); @@ -263,7 +290,7 @@ static void DEVENUM_ReadPins(HKEY hkeyFilterClass, REGFILTER2 *rgf2) { HKEY hkeyPinKey = NULL; WCHAR wszPinName[MAX_PATH]; - DWORD cName = sizeof(wszPinName) / sizeof(WCHAR); + DWORD cName = ARRAY_SIZE(wszPinName); REGFILTERPINS2 *rgPin = &rgPins[rgf2->u.s2.cPins2]; DWORD value, size, Type; LONG lRet; @@ -352,9 +379,9 @@ static void free_regfilter2(REGFILTER2 *rgf) static void write_filter_data(IPropertyBag *prop_bag, REGFILTER2 *rgf) { + BYTE *data = NULL, *array; IAMFilterData *fildata; SAFEARRAYBOUND sabound; - BYTE *data, *array; VARIANT var; ULONG size; HRESULT hr; @@ -410,59 +437,53 @@ static void register_legacy_filters(void) for (i = 0; i < dwFilterSubkeys; i++) { WCHAR wszFilterSubkeyName[64]; - DWORD cName = sizeof(wszFilterSubkeyName) / sizeof(WCHAR); + DWORD cName = ARRAY_SIZE(wszFilterSubkeyName); IPropertyBag *prop_bag = NULL; WCHAR wszRegKey[MAX_PATH]; HKEY classkey = NULL; - IMoniker *mon = NULL; - VARIANT var; REGFILTER2 rgf2; DWORD Type, len; + GUID clsid; if (RegEnumKeyExW(hkeyFilter, i, wszFilterSubkeyName, &cName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) continue; TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName)); - strcpyW(wszRegKey, clsidW); - strcatW(wszRegKey, wszFilterSubkeyName); - - if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS) + hr = CLSIDFromString(wszFilterSubkeyName, &clsid); + if (FAILED(hr)) continue; - hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, &mon); - if (FAILED(hr)) goto cleanup; + lstrcpyW(wszRegKey, clsidW); + lstrcatW(wszRegKey, backslashW); + lstrcatW(wszRegKey, wszFilterSubkeyName); - hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); - if (FAILED(hr)) goto cleanup; + if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS) + continue; - /* write friendly name */ len = 0; - V_VT(&var) = VT_BSTR; if (!RegQueryValueExW(classkey, NULL, NULL, &Type, NULL, &len)) { WCHAR *friendlyname = heap_alloc(len); if (!friendlyname) - goto cleanup; + { + RegCloseKey(classkey); + continue; + } RegQueryValueExW(classkey, NULL, NULL, &Type, (BYTE *)friendlyname, &len); - V_BSTR(&var) = SysAllocStringLen(friendlyname, len/sizeof(WCHAR)); + + hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, + &clsid, friendlyname, &prop_bag); + heap_free(friendlyname); } else - V_BSTR(&var) = SysAllocString(wszFilterSubkeyName); - - if (!V_BSTR(&var)) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write clsid */ - V_VT(&var) = VT_BSTR; - if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); + hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, + &clsid, wszFilterSubkeyName, &prop_bag); + if (FAILED(hr)) + { + RegCloseKey(classkey); + continue; + } /* write filter data */ rgf2.dwMerit = MERIT_NORMAL; @@ -474,11 +495,8 @@ static void register_legacy_filters(void) write_filter_data(prop_bag, &rgf2); -cleanup: - if (prop_bag) IPropertyBag_Release(prop_bag); - if (mon) IMoniker_Release(mon); + IPropertyBag_Release(prop_bag); RegCloseKey(classkey); - VariantClear(&var); free_regfilter2(&rgf2); } } @@ -496,50 +514,30 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons REGPINTYPES rgtypes = {0}; REGFILTER2 rgf = {0}; WCHAR clsid[CHARS_IN_GUID]; - IMoniker *mon = NULL; VARIANT var; HRESULT hr; hr = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory); - if (FAILED(hr)) goto cleanup; + if (FAILED(hr)) + return FALSE; - V_VT(&var) = VT_BSTR; if (guid) { - WCHAR *name = heap_alloc(sizeof(defaultW) + strlenW(desc) * sizeof(WCHAR)); + WCHAR *name = heap_alloc(sizeof(defaultW) + lstrlenW(desc) * sizeof(WCHAR)); if (!name) - goto cleanup; - strcpyW(name, directsoundW); - strcatW(name, desc); + return FALSE; + lstrcpyW(name, directsoundW); + lstrcatW(name, desc); - V_BSTR(&var) = SysAllocString(name); + hr = register_codec(&CLSID_AudioRendererCategory, name, + &CLSID_DSoundRender, name, &prop_bag); heap_free(name); } else - V_BSTR(&var) = SysAllocString(defaultW); - - if (!V_BSTR(&var)) - goto cleanup; - - hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon); - if (FAILED(hr)) goto cleanup; - - hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); - if (FAILED(hr)) goto cleanup; - - /* write friendly name */ - hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write clsid */ - V_VT(&var) = VT_BSTR; - StringFromGUID2(&CLSID_DSoundRender, clsid, CHARS_IN_GUID); - if (!(V_BSTR(&var) = SysAllocString(clsid))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); + hr = register_codec(&CLSID_AudioRendererCategory, defaultW, + &CLSID_DSoundRender, defaultW, &prop_bag); + if (FAILED(hr)) + return FALSE; /* write filter data */ rgf.dwVersion = 2; @@ -558,16 +556,11 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons /* write DSound guid */ V_VT(&var) = VT_BSTR; StringFromGUID2(guid ? guid : &GUID_NULL, clsid, CHARS_IN_GUID); - if (!(V_BSTR(&var) = SysAllocString(clsid))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, dsguidW, &var); - if (FAILED(hr)) goto cleanup; + if ((V_BSTR(&var) = SysAllocString(clsid))) + hr = IPropertyBag_Write(prop_bag, dsguidW, &var); -cleanup: VariantClear(&var); - if (prop_bag) IPropertyBag_Release(prop_bag); - if (mon) IMoniker_Release(mon); - + IPropertyBag_Release(prop_bag); return TRUE; } @@ -579,9 +572,8 @@ static void register_waveout_devices(void) REGFILTERPINS2 rgpins = {0}; REGPINTYPES rgtypes = {0}; REGFILTER2 rgf = {0}; - WCHAR clsid[CHARS_IN_GUID]; - IMoniker *mon = NULL; WAVEOUTCAPSW caps; + const WCHAR *name; int i, count; VARIANT var; HRESULT hr; @@ -595,34 +587,12 @@ static void register_waveout_devices(void) { waveOutGetDevCapsW(i, &caps, sizeof(caps)); - V_VT(&var) = VT_BSTR; - - if (i == -1) /* WAVE_MAPPER */ - V_BSTR(&var) = SysAllocString(defaultW); - else - V_BSTR(&var) = SysAllocString(caps.szPname); - if (!(V_BSTR(&var))) - goto cleanup; + name = (i == -1) ? defaultW : caps.szPname; - hr = register_codec(&CLSID_AudioRendererCategory, V_BSTR(&var), &mon); - if (FAILED(hr)) goto cleanup; - - hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); - if (FAILED(hr)) goto cleanup; - - /* write friendly name */ - hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write clsid */ - V_VT(&var) = VT_BSTR; - StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID); - if (!(V_BSTR(&var) = SysAllocString(clsid))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); + hr = register_codec(&CLSID_AudioRendererCategory, name, + &CLSID_AudioRender, name, &prop_bag); + if (FAILED(hr)) + continue; /* write filter data */ rgf.dwVersion = 2; @@ -640,13 +610,10 @@ static void register_waveout_devices(void) /* write WaveOutId */ V_VT(&var) = VT_I4; V_I4(&var) = i; - hr = IPropertyBag_Write(prop_bag, waveoutidW, &var); - if (FAILED(hr)) goto cleanup; + IPropertyBag_Write(prop_bag, waveoutidW, &var); -cleanup: VariantClear(&var); if (prop_bag) IPropertyBag_Release(prop_bag); - if (mon) IMoniker_Release(mon); } } @@ -655,8 +622,6 @@ static void register_wavein_devices(void) static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0}; IPropertyBag *prop_bag = NULL; REGFILTER2 rgf = {0}; - WCHAR clsid[CHARS_IN_GUID]; - IMoniker *mon = NULL; WAVEINCAPSW caps; int i, count; VARIANT var; @@ -671,31 +636,10 @@ static void register_wavein_devices(void) { waveInGetDevCapsW(i, &caps, sizeof(caps)); - V_VT(&var) = VT_BSTR; - - V_BSTR(&var) = SysAllocString(caps.szPname); - if (!(V_BSTR(&var))) - goto cleanup; - - hr = register_codec(&CLSID_AudioInputDeviceCategory, V_BSTR(&var), &mon); - if (FAILED(hr)) goto cleanup; - - hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); - if (FAILED(hr)) goto cleanup; - - /* write friendly name */ - hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write clsid */ - V_VT(&var) = VT_BSTR; - StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID); - if (!(V_BSTR(&var) = SysAllocString(clsid))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); + hr = register_codec(&CLSID_AudioInputDeviceCategory, caps.szPname, + &CLSID_AudioRecord, caps.szPname, &prop_bag); + if (FAILED(hr)) + continue; /* write filter data */ rgf.dwVersion = 2; @@ -706,13 +650,10 @@ static void register_wavein_devices(void) /* write WaveInId */ V_VT(&var) = VT_I4; V_I4(&var) = i; - hr = IPropertyBag_Write(prop_bag, waveinidW, &var); - if (FAILED(hr)) goto cleanup; + IPropertyBag_Write(prop_bag, waveinidW, &var); -cleanup: VariantClear(&var); - if (prop_bag) IPropertyBag_Release(prop_bag); - if (mon) IMoniker_Release(mon); + IPropertyBag_Release(prop_bag); } } @@ -724,9 +665,8 @@ static void register_midiout_devices(void) REGFILTERPINS2 rgpins = {0}; REGPINTYPES rgtypes = {0}; REGFILTER2 rgf = {0}; - WCHAR clsid[CHARS_IN_GUID]; - IMoniker *mon = NULL; MIDIOUTCAPSW caps; + const WCHAR *name; int i, count; VARIANT var; HRESULT hr; @@ -740,34 +680,12 @@ static void register_midiout_devices(void) { midiOutGetDevCapsW(i, &caps, sizeof(caps)); - V_VT(&var) = VT_BSTR; - - if (i == -1) /* MIDI_MAPPER */ - V_BSTR(&var) = SysAllocString(defaultW); - else - V_BSTR(&var) = SysAllocString(caps.szPname); - if (!(V_BSTR(&var))) - goto cleanup; + name = (i == -1) ? defaultW : caps.szPname; - hr = register_codec(&CLSID_MidiRendererCategory, V_BSTR(&var), &mon); - if (FAILED(hr)) goto cleanup; - - hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); - if (FAILED(hr)) goto cleanup; - - /* write friendly name */ - hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write clsid */ - V_VT(&var) = VT_BSTR; - StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID); - if (!(V_BSTR(&var) = SysAllocString(clsid))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); + hr = register_codec(&CLSID_MidiRendererCategory, name, + &CLSID_AVIMIDIRender, name, &prop_bag); + if (FAILED(hr)) + continue; /* write filter data */ rgf.dwVersion = 2; @@ -785,13 +703,10 @@ static void register_midiout_devices(void) /* write MidiOutId */ V_VT(&var) = VT_I4; V_I4(&var) = i; - hr = IPropertyBag_Write(prop_bag, midioutidW, &var); - if (FAILED(hr)) goto cleanup; + IPropertyBag_Write(prop_bag, midioutidW, &var); -cleanup: VariantClear(&var); - if (prop_bag) IPropertyBag_Release(prop_bag); - if (mon) IMoniker_Release(mon); + IPropertyBag_Release(prop_bag); } } @@ -802,8 +717,6 @@ static void register_vfw_codecs(void) IPropertyBag *prop_bag = NULL; REGPINTYPES rgtypes[2]; REGFILTER2 rgf; - WCHAR clsid[CHARS_IN_GUID]; - IMoniker *mon = NULL; GUID typeguid; ICINFO info; VARIANT var; @@ -823,40 +736,10 @@ static void register_vfw_codecs(void) ICGetInfo(hic, &info, sizeof(info)); ICClose(hic); - V_VT(&var) = VT_BSTR; - - V_BSTR(&var) = SysAllocString(name); - if (!(V_BSTR(&var))) - goto cleanup; - - hr = register_codec(&CLSID_VideoCompressorCategory, V_BSTR(&var), &mon); - if (FAILED(hr)) goto cleanup; - - hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag); - if (FAILED(hr)) goto cleanup; - - /* write WaveInId */ - hr = IPropertyBag_Write(prop_bag, fcchandlerW, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write friendly name */ - V_VT(&var) = VT_BSTR; - if (!(V_BSTR(&var) = SysAllocString(info.szDescription))) - goto cleanup; - - hr = IPropertyBag_Write(prop_bag, wszFriendlyName, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); - - /* write clsid */ - V_VT(&var) = VT_BSTR; - StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID); - if (!(V_BSTR(&var) = SysAllocString(clsid))) - goto cleanup; - hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var); - if (FAILED(hr)) goto cleanup; - VariantClear(&var); + hr = register_codec(&CLSID_VideoCompressorCategory, name, + &CLSID_AVICo, info.szDescription, &prop_bag); + if (FAILED(hr)) + continue; /* write filter data */ rgf.dwVersion = 2; @@ -878,10 +761,65 @@ static void register_vfw_codecs(void) write_filter_data(prop_bag, &rgf); -cleanup: + /* write WaveInId */ + V_VT(&var) = VT_BSTR; + V_BSTR(&var) = SysAllocString(name); + IPropertyBag_Write(prop_bag, fcchandlerW, &var); + VariantClear(&var); - if (prop_bag) IPropertyBag_Release(prop_bag); - if (mon) IMoniker_Release(mon); + IPropertyBag_Release(prop_bag); + } +} + +static void register_avicap_devices(void) +{ + static const WCHAR vfwindexW[] = {'V','F','W','I','n','d','e','x',0}; + WCHAR name[] = {'v','i','d','e','o','0',0}; + WCHAR friendlyname[32], version[32]; + IPropertyBag *prop_bag = NULL; + REGFILTERPINS2 rgpins = {0}; + REGPINTYPES rgtypes; + REGFILTER2 rgf; + VARIANT var; + HRESULT hr; + int i = 0; + + hr = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory); + if (FAILED(hr)) + return; + + for (i = 0; i < 10; ++i) + { + if (!capGetDriverDescriptionW(i, friendlyname, ARRAY_SIZE(friendlyname), + version, ARRAY_SIZE(version))) + continue; + + name[5] = '0' + i; + + hr = register_codec(&CLSID_VideoInputDeviceCategory, name, + &CLSID_VfwCapture, friendlyname, &prop_bag); + if (FAILED(hr)) + continue; + + rgf.dwVersion = 2; + rgf.dwMerit = MERIT_DO_NOT_USE; + rgf.u.s2.cPins2 = 1; + rgf.u.s2.rgPins2 = &rgpins; + rgpins.dwFlags = 0; + rgpins.nMediaTypes = 1; + rgpins.lpMediaType = &rgtypes; + rgtypes.clsMajorType = &MEDIATYPE_Video; + rgtypes.clsMinorType = &MEDIASUBTYPE_None; + + write_filter_data(prop_bag, &rgf); + + /* write VFWIndex */ + V_VT(&var) = VT_I4; + V_I4(&var) = i; + IPropertyBag_Write(prop_bag, vfwindexW, &var); + + VariantClear(&var); + IPropertyBag_Release(prop_bag); } } @@ -889,30 +827,58 @@ cleanup: * DEVENUM_ICreateDevEnum_CreateClassEnumerator */ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator( - ICreateDevEnum * iface, - REFCLSID clsidDeviceClass, - IEnumMoniker **ppEnumMoniker, - DWORD dwFlags) + ICreateDevEnum *iface, REFCLSID class, IEnumMoniker **out, DWORD flags) { + WCHAR guidstr[CHARS_IN_GUID]; HRESULT hr; + HKEY key; - TRACE("(%p)->(%s, %p, %x)\n", iface, debugstr_guid(clsidDeviceClass), ppEnumMoniker, dwFlags); + TRACE("iface %p, class %s, out %p, flags %#x.\n", iface, debugstr_guid(class), out, flags); - if (!ppEnumMoniker) + if (!out) return E_POINTER; - *ppEnumMoniker = NULL; + *out = NULL; - register_codecs(); - register_legacy_filters(); - hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL); - if (FAILED(hr)) return hr; - register_waveout_devices(); - register_wavein_devices(); - register_midiout_devices(); - register_vfw_codecs(); + if (!RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &key)) + { + StringFromGUID2(class, guidstr, ARRAY_SIZE(guidstr)); + RegDeleteTreeW(key, guidstr); + } - return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker); + if (IsEqualGUID(class, &CLSID_LegacyAmFilterCategory)) + register_legacy_filters(); + else if (IsEqualGUID(class, &CLSID_AudioRendererCategory)) + { + hr = DirectSoundEnumerateW(®ister_dsound_devices, NULL); + if (FAILED(hr)) return hr; + register_waveout_devices(); + register_midiout_devices(); + } + else if (IsEqualGUID(class, &CLSID_AudioInputDeviceCategory)) + register_wavein_devices(); + else if (IsEqualGUID(class, &CLSID_VideoCompressorCategory)) + register_vfw_codecs(); + else if (IsEqualGUID(class, &CLSID_VideoInputDeviceCategory)) + register_avicap_devices(); + + if (SUCCEEDED(hr = create_EnumMoniker(class, out))) + { + IMoniker *mon; + hr = IEnumMoniker_Next(*out, 1, &mon, NULL); + if (hr == S_OK) + { + IMoniker_Release(mon); + IEnumMoniker_Reset(*out); + } + else + { + IEnumMoniker_Release(*out); + *out = NULL; + } + } + + return hr; } /********************************************************************** @@ -943,9 +909,9 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory) HRESULT res = S_OK; HKEY hkeyDummy = NULL; - strcpyW(wszRegKey, wszActiveMovieKey); + lstrcpyW(wszRegKey, wszActiveMovieKey); - if (!StringFromGUID2(clsidCategory, wszRegKey + strlenW(wszRegKey), sizeof(wszRegKey)/sizeof(wszRegKey[0]) - strlenW(wszRegKey))) + if (!StringFromGUID2(clsidCategory, wszRegKey + lstrlenW(wszRegKey), ARRAY_SIZE(wszRegKey) - lstrlenW(wszRegKey))) res = E_INVALIDARG; if (SUCCEEDED(res)) @@ -962,111 +928,3 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory) return res; } - -static HRESULT register_codecs(void) -{ - HRESULT res; - WCHAR class[CHARS_IN_GUID]; - DWORD iDefaultDevice = -1; - IFilterMapper2 * pMapper = NULL; - REGFILTER2 rf2; - REGFILTERPINS2 rfp2; - HKEY basekey; - - /* Since devices can change between session, for example because you just plugged in a webcam - * or switched from pulseaudio to alsa, delete all old devices first - */ - RegOpenKeyW(HKEY_CURRENT_USER, wszActiveMovieKey, &basekey); - StringFromGUID2(&CLSID_LegacyAmFilterCategory, class, CHARS_IN_GUID); - RegDeleteTreeW(basekey, class); - StringFromGUID2(&CLSID_AudioRendererCategory, class, CHARS_IN_GUID); - RegDeleteTreeW(basekey, class); - StringFromGUID2(&CLSID_AudioInputDeviceCategory, class, CHARS_IN_GUID); - RegDeleteTreeW(basekey, class); - StringFromGUID2(&CLSID_VideoInputDeviceCategory, class, CHARS_IN_GUID); - RegDeleteTreeW(basekey, class); - StringFromGUID2(&CLSID_MidiRendererCategory, class, CHARS_IN_GUID); - RegDeleteTreeW(basekey, class); - StringFromGUID2(&CLSID_VideoCompressorCategory, class, CHARS_IN_GUID); - RegDeleteTreeW(basekey, class); - RegCloseKey(basekey); - - rf2.dwVersion = 2; - rf2.dwMerit = MERIT_PREFERRED; - rf2.u.s2.cPins2 = 1; - rf2.u.s2.rgPins2 = &rfp2; - rfp2.cInstances = 1; - rfp2.nMediums = 0; - rfp2.lpMedium = NULL; - rfp2.clsPinCategory = &IID_NULL; - - res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, - &IID_IFilterMapper2, (void **) &pMapper); - /* - * Fill in info for devices - */ - if (SUCCEEDED(res)) - { - UINT i; - REGPINTYPES * pTypes; - IPropertyBag * pPropBag = NULL; - - res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory); - if (SUCCEEDED(res)) - for (i = 0; i < 10; i++) - { - WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10]; - - if (capGetDriverDescriptionW ((WORD) i, - szDeviceName, sizeof(szDeviceName)/sizeof(WCHAR), - szDeviceVersion, sizeof(szDeviceVersion)/sizeof(WCHAR))) - { - IMoniker * pMoniker = NULL; - WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 }; - snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf, i); - /* The above code prevents 1 device with a different ID overwriting another */ - - rfp2.nMediaTypes = 1; - pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES)); - if (!pTypes) { - IFilterMapper2_Release(pMapper); - return E_OUTOFMEMORY; - } - - pTypes[0].clsMajorType = &MEDIATYPE_Video; - pTypes[0].clsMinorType = &MEDIASUBTYPE_None; - - rfp2.lpMediaType = pTypes; - - res = IFilterMapper2_RegisterFilter(pMapper, - &CLSID_VfwCapture, - szDeviceName, - &pMoniker, - &CLSID_VideoInputDeviceCategory, - szDevicePath, - &rf2); - - if (pMoniker) { - OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 }; - VARIANT var; - V_VT(&var) = VT_I4; - V_I4(&var) = i; - res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag); - if (SUCCEEDED(res)) { - res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var); - IPropertyBag_Release(pPropBag); - } - IMoniker_Release(pMoniker); - } - - if (i == iDefaultDevice) FIXME("Default device\n"); - CoTaskMemFree(pTypes); - } - } - } - - if (pMapper) - IFilterMapper2_Release(pMapper); - - return res; -} diff --git a/dll/directx/wine/devenum/devenum_main.c b/dll/directx/wine/devenum/devenum_main.c index 55963581176..3f60c2906f7 100644 --- a/dll/directx/wine/devenum/devenum_main.c +++ b/dll/directx/wine/devenum/devenum_main.c @@ -1,5 +1,5 @@ /* - * exported dll functions for devenum.dll + * Device Enumeration * * Copyright (C) 2002 John K. Hohm * Copyright (C) 2002 Robert Shearman @@ -26,24 +26,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum); DECLSPEC_HIDDEN LONG dll_refs; -DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance; - -typedef struct -{ - REFCLSID clsid; - LPCWSTR friendly_name; - BOOL instance; -} register_info; +static HINSTANCE devenum_instance; #ifdef __REACTOS__ static void DEVENUM_RegisterQuartz(void); #endif -/*********************************************************************** - * Global string constant definitions - */ -const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 }; - /*********************************************************************** * DllEntryPoint */ @@ -53,29 +41,101 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad) switch(fdwReason) { case DLL_PROCESS_ATTACH: - DEVENUM_hInstance = hinstDLL; + devenum_instance = hinstDLL; DisableThreadLibraryCalls(hinstDLL); break; } return TRUE; } +struct class_factory +{ + IClassFactory IClassFactory_iface; + IUnknown *obj; +}; + +static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface ) +{ + return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface ); +} + +static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj) +{ + TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *obj = iface; + return S_OK; + } + + *obj = NULL; + WARN("no interface for %s\n", debugstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +{ + DEVENUM_LockModule(); + return 2; +} + +static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +{ + DEVENUM_UnlockModule(); + return 1; +} + +static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, + IUnknown *outer, REFIID iid, void **obj) +{ + struct class_factory *This = impl_from_IClassFactory( iface ); + + TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj); + + if (!obj) return E_POINTER; + + if (outer) return CLASS_E_NOAGGREGATION; + + return IUnknown_QueryInterface(This->obj, iid, obj); +} + +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock) +{ + if (lock) + DEVENUM_LockModule(); + else + DEVENUM_UnlockModule(); + return S_OK; +} + +static const IClassFactoryVtbl ClassFactory_vtbl = { + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + ClassFactory_CreateInstance, + ClassFactory_LockServer +}; + +static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_CreateDevEnum }; +static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_ParseDisplayName }; + /*********************************************************************** * DllGetClassObject (DEVENUM.@) */ -HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj) { - TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj); - *ppv = NULL; + *obj = NULL; - /* FIXME: we should really have two class factories. - * Oh well - works just fine as it is */ - if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) || - IsEqualGUID(rclsid, &CLSID_CDeviceMoniker)) - return IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv); + if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum)) + return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj); + else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker)) + return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj); - FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid)); + FIXME("class %s not available\n", debugstr_guid(clsid)); return CLASS_E_CLASSNOTAVAILABLE; } @@ -98,7 +158,7 @@ HRESULT WINAPI DllRegisterServer(void) TRACE("\n"); - res = __wine_register_resources( DEVENUM_hInstance ); + res = __wine_register_resources( devenum_instance ); if (FAILED(res)) return res; @@ -151,7 +211,7 @@ HRESULT WINAPI DllRegisterServer(void) HRESULT WINAPI DllUnregisterServer(void) { FIXME("stub!\n"); - return __wine_unregister_resources( DEVENUM_hInstance ); + return __wine_unregister_resources( devenum_instance ); } #ifdef __REACTOS__ diff --git a/dll/directx/wine/devenum/devenum_private.h b/dll/directx/wine/devenum/devenum_private.h index 005f0b56e66..61287ef0e3e 100644 --- a/dll/directx/wine/devenum/devenum_private.h +++ b/dll/directx/wine/devenum/devenum_private.h @@ -42,10 +42,6 @@ #include "olectl.h" #include "uuids.h" -#ifndef RC_INVOKED -#include "wine/unicode.h" -#endif - /********************************************************************** * Dll lifetime tracking declaration for devenum.dll */ @@ -53,19 +49,11 @@ extern LONG dll_refs DECLSPEC_HIDDEN; static inline void DEVENUM_LockModule(void) { InterlockedIncrement(&dll_refs); } static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&dll_refs); } - -/********************************************************************** - * ClassFactory declaration for devenum.dll - */ -typedef struct -{ - IClassFactory IClassFactory_iface; -} ClassFactoryImpl; - enum device_type { DEVICE_FILTER, DEVICE_CODEC, + DEVICE_DMO, }; typedef struct @@ -75,13 +63,16 @@ typedef struct CLSID class; BOOL has_class; enum device_type type; - WCHAR *name; + union + { + WCHAR *name; /* for filters and codecs */ + CLSID clsid; /* for DMOs */ + }; } MediaCatMoniker; MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN; HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) DECLSPEC_HIDDEN; -extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN; extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN; extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN; @@ -90,12 +81,13 @@ extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN; */ static const WCHAR backslashW[] = {'\\',0}; -static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0}; +static const WCHAR clsidW[] = {'C','L','S','I','D',0}; static const WCHAR instanceW[] = {'\\','I','n','s','t','a','n','c','e',0}; static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\', 'M','i','c','r','o','s','o','f','t','\\', 'A','c','t','i','v','e','M','o','v','i','e','\\', 'd','e','v','e','n','u','m','\\',0}; static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0}; - -extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN; +static const WCHAR dmoW[] = {'d','m','o',':',0}; +static const WCHAR swW[] = {'s','w',':',0}; +static const WCHAR cmW[] = {'c','m',':',0}; diff --git a/dll/directx/wine/devenum/factory.c b/dll/directx/wine/devenum/factory.c deleted file mode 100644 index c808fa532df..00000000000 --- a/dll/directx/wine/devenum/factory.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * ClassFactory implementation for DEVENUM.dll - * - * Copyright (C) 2002 John K. Hohm - * Copyright (C) 2002 Robert Shearman - * - * This library 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 library 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 library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "devenum_private.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(devenum); - -/********************************************************************** - * DEVENUM_IClassFactory_QueryInterface (also IUnknown) - */ -static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, - void **ppvObj) -{ - TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj); - - if (ppvObj == NULL) return E_POINTER; - - if (IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IClassFactory)) - { - *ppvObj = iface; - IClassFactory_AddRef(iface); - return S_OK; - } - else if (IsEqualGUID(riid, &IID_IParseDisplayName)) - { - return IClassFactory_CreateInstance(iface, NULL, riid, ppvObj); - } - - FIXME("- no interface IID: %s\n", debugstr_guid(riid)); - return E_NOINTERFACE; -} - -/********************************************************************** - * DEVENUM_IClassFactory_AddRef (also IUnknown) - */ -static ULONG WINAPI DEVENUM_IClassFactory_AddRef(IClassFactory *iface) -{ - TRACE("\n"); - - DEVENUM_LockModule(); - - return 2; /* non-heap based object */ -} - -/********************************************************************** - * DEVENUM_IClassFactory_Release (also IUnknown) - */ -static ULONG WINAPI DEVENUM_IClassFactory_Release(IClassFactory *iface) -{ - TRACE("\n"); - - DEVENUM_UnlockModule(); - - return 1; /* non-heap based object */ -} - -/********************************************************************** - * DEVENUM_IClassFactory_CreateInstance - */ -static HRESULT WINAPI DEVENUM_IClassFactory_CreateInstance(IClassFactory *iface, - IUnknown *pUnkOuter, REFIID riid, void **ppvObj) -{ - TRACE("(%p)->(%p, %s, %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj); - - if (ppvObj == NULL) return E_POINTER; - - /* Don't support aggregation (Windows doesn't) */ - if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION; - - if (IsEqualGUID(&IID_ICreateDevEnum, riid)) - { - *ppvObj = &DEVENUM_CreateDevEnum; - return S_OK; - } - if (IsEqualGUID(&IID_IParseDisplayName, riid)) - { - *ppvObj = &DEVENUM_ParseDisplayName; - return S_OK; - } - - return CLASS_E_CLASSNOTAVAILABLE; -} - -/********************************************************************** - * DEVENUM_IClassFactory_LockServer - */ -static HRESULT WINAPI DEVENUM_IClassFactory_LockServer(IClassFactory *iface, BOOL fLock) -{ - TRACE("\n"); - - if (fLock) - DEVENUM_LockModule(); - else - DEVENUM_UnlockModule(); - return S_OK; -} - -/********************************************************************** - * IClassFactory_Vtbl - */ -static const IClassFactoryVtbl IClassFactory_Vtbl = -{ - DEVENUM_IClassFactory_QueryInterface, - DEVENUM_IClassFactory_AddRef, - DEVENUM_IClassFactory_Release, - DEVENUM_IClassFactory_CreateInstance, - DEVENUM_IClassFactory_LockServer -}; - -/********************************************************************** - * static ClassFactory instance - */ -ClassFactoryImpl DEVENUM_ClassFactory = { { &IClassFactory_Vtbl } }; diff --git a/dll/directx/wine/devenum/mediacatenum.c b/dll/directx/wine/devenum/mediacatenum.c index a76c7bebfb2..e728be342b1 100644 --- a/dll/directx/wine/devenum/mediacatenum.c +++ b/dll/directx/wine/devenum/mediacatenum.c @@ -25,6 +25,7 @@ #include "devenum_private.h" #include "oleauto.h" #include "ocidl.h" +#include "dmoreg.h" #include "wine/debug.h" @@ -35,6 +36,7 @@ typedef struct IEnumMoniker IEnumMoniker_iface; CLSID class; LONG ref; + IEnumDMO *dmo_enum; HKEY sw_key; DWORD sw_index; HKEY cm_key; @@ -46,7 +48,11 @@ typedef struct IPropertyBag IPropertyBag_iface; LONG ref; enum device_type type; - WCHAR path[MAX_PATH]; + union + { + WCHAR path[MAX_PATH]; /* for filters and codecs */ + CLSID clsid; /* for DMOs */ + }; } RegPropBagImpl; @@ -114,12 +120,14 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read( VARIANT* pVar, IErrorLog* pErrorLog) { + static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0}; LPVOID pData = NULL; DWORD received; DWORD type = 0; RegPropBagImpl *This = impl_from_IPropertyBag(iface); HRESULT res = S_OK; LONG reswin32 = ERROR_SUCCESS; + WCHAR name[80]; HKEY hkey; TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog); @@ -127,6 +135,21 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read( if (!pszPropName || !pVar) return E_POINTER; + if (This->type == DEVICE_DMO) + { + if (!lstrcmpW(pszPropName, FriendlyNameW)) + { + res = DMOGetName(&This->clsid, name); + if (SUCCEEDED(res)) + { + V_VT(pVar) = VT_BSTR; + V_BSTR(pVar) = SysAllocString(name); + } + return res; + } + return HRESULT_FROM_WIN32(ERROR_NOT_FOUND); + } + if (This->type == DEVICE_FILTER) reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey); else if (This->type == DEVICE_CODEC) @@ -246,6 +269,9 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write( TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar); + if (This->type == DEVICE_DMO) + return E_ACCESSDENIED; + switch (V_VT(pVar)) { case VT_BSTR: @@ -316,18 +342,30 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag) rpb->ref = 1; rpb->type = mon->type; - if (rpb->type == DEVICE_FILTER) - strcpyW(rpb->path, clsidW); + if (rpb->type == DEVICE_DMO) + rpb->clsid = mon->clsid; + else if (rpb->type == DEVICE_FILTER) + { + lstrcpyW(rpb->path, clsidW); + lstrcatW(rpb->path, backslashW); + if (mon->has_class) + { + StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID); + lstrcatW(rpb->path, instanceW); + lstrcatW(rpb->path, backslashW); + } + lstrcatW(rpb->path, mon->name); + } else if (rpb->type == DEVICE_CODEC) - strcpyW(rpb->path, wszActiveMovieKey); - if (mon->has_class) { - StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID); - if (rpb->type == DEVICE_FILTER) - strcatW(rpb->path, instanceW); - strcatW(rpb->path, backslashW); + lstrcpyW(rpb->path, wszActiveMovieKey); + if (mon->has_class) + { + StringFromGUID2(&mon->class, rpb->path + lstrlenW(rpb->path), CHARS_IN_GUID); + lstrcatW(rpb->path, backslashW); + } + lstrcatW(rpb->path, mon->name); } - strcatW(rpb->path, mon->name); *ppBag = &rpb->IPropertyBag_iface; DEVENUM_LockModule(); @@ -459,7 +497,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBi if (SUCCEEDED(res)) { V_VT(&var) = VT_LPWSTR; - res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL); + res = IPropertyBag_Read(pProp, clsidW, &var, NULL); } if (SUCCEEDED(res)) { @@ -658,8 +696,6 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker *iface, I static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc, IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName) { - static const WCHAR swW[] = {'s','w',':',0}; - static const WCHAR cmW[] = {'c','m',':',0}; MediaCatMoniker *This = impl_from_IMoniker(iface); WCHAR *buffer; @@ -667,23 +703,36 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, I *ppszDisplayName = NULL; - buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID : 0) - + strlenW(This->name) + 1) * sizeof(WCHAR)); - if (!buffer) - return E_OUTOFMEMORY; + if (This->type == DEVICE_DMO) + { + buffer = CoTaskMemAlloc((lstrlenW(deviceW) + lstrlenW(dmoW) + + 2 * CHARS_IN_GUID + 1) * sizeof(WCHAR)); + if (!buffer) return E_OUTOFMEMORY; + + lstrcpyW(buffer, deviceW); + lstrcatW(buffer, dmoW); + StringFromGUID2(&This->clsid, buffer + lstrlenW(buffer), CHARS_IN_GUID); + StringFromGUID2(&This->class, buffer + lstrlenW(buffer), CHARS_IN_GUID); + } + else + { + buffer = CoTaskMemAlloc((lstrlenW(deviceW) + 3 + (This->has_class ? CHARS_IN_GUID : 0) + + lstrlenW(This->name) + 1) * sizeof(WCHAR)); + if (!buffer) return E_OUTOFMEMORY; - strcpyW(buffer, deviceW); - if (This->type == DEVICE_FILTER) - strcatW(buffer, swW); - else if (This->type == DEVICE_CODEC) - strcatW(buffer, cmW); + lstrcpyW(buffer, deviceW); + if (This->type == DEVICE_FILTER) + lstrcatW(buffer, swW); + else if (This->type == DEVICE_CODEC) + lstrcatW(buffer, cmW); - if (This->has_class) - { - StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID); - strcatW(buffer, backslashW); + if (This->has_class) + { + StringFromGUID2(&This->class, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, backslashW); + } + lstrcatW(buffer, This->name); } - strcatW(buffer, This->name); *ppszDisplayName = buffer; return S_OK; @@ -798,6 +847,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface) if (!ref) { + IEnumDMO_Release(This->dmo_enum); RegCloseKey(This->sw_key); RegCloseKey(This->cm_key); CoTaskMemFree(This); @@ -815,16 +865,30 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, LONG res; ULONG fetched = 0; MediaCatMoniker * pMoniker; + CLSID clsid; + HRESULT hr; HKEY hkey; TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched); while (fetched < celt) { - /* FIXME: try PNP devices and DMOs first */ + /* FIXME: try PNP devices first */ + + /* try DMOs */ + if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, NULL, NULL)) == S_OK) + { + if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct())) + return E_OUTOFMEMORY; + + pMoniker->type = DEVICE_DMO; + pMoniker->clsid = clsid; + StringFromGUID2(&clsid, buffer, CHARS_IN_GUID); + StringFromGUID2(&This->class, buffer + CHARS_IN_GUID - 1, CHARS_IN_GUID); + } /* try DirectShow filters */ - if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR)))) + else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, ARRAY_SIZE(buffer)))) { This->sw_index++; if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey))) @@ -834,9 +898,16 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, return E_OUTOFMEMORY; pMoniker->type = DEVICE_FILTER; + + if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR)))) + { + IMoniker_Release(&pMoniker->IMoniker_iface); + return E_OUTOFMEMORY; + } + lstrcpyW(pMoniker->name, buffer); } /* then try codecs */ - else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR)))) + else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, ARRAY_SIZE(buffer)))) { This->cm_index++; @@ -847,16 +918,17 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt, return E_OUTOFMEMORY; pMoniker->type = DEVICE_CODEC; + + if (!(pMoniker->name = CoTaskMemAlloc((lstrlenW(buffer) + 1) * sizeof(WCHAR)))) + { + IMoniker_Release(&pMoniker->IMoniker_iface); + return E_OUTOFMEMORY; + } + lstrcpyW(pMoniker->name, buffer); } else break; - if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR)))) - { - IMoniker_Release(&pMoniker->IMoniker_iface); - return E_OUTOFMEMORY; - } - strcpyW(pMoniker->name, buffer); pMoniker->has_class = TRUE; pMoniker->class = This->class; @@ -883,10 +955,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt) while (celt--) { - /* FIXME: try PNP devices and DMOs first */ + /* FIXME: try PNP devices first */ + /* try DMOs */ + if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK) + ; /* try DirectShow filters */ - if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS) + else if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS) { This->sw_index++; } @@ -908,6 +983,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface) TRACE("(%p)->()\n", iface); + IEnumDMO_Reset(This->dmo_enum); This->sw_index = 0; This->cm_index = 0; @@ -939,6 +1015,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker) { EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl)); WCHAR buffer[78]; + HRESULT hr; if (!pEnumMoniker) return E_OUTOFMEMORY; @@ -949,17 +1026,25 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker) pEnumMoniker->cm_index = 0; pEnumMoniker->class = *class; - strcpyW(buffer, clsidW); - StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID); - strcatW(buffer, instanceW); + lstrcpyW(buffer, clsidW); + lstrcatW(buffer, backslashW); + StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID); + lstrcatW(buffer, instanceW); if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->sw_key)) pEnumMoniker->sw_key = NULL; - strcpyW(buffer, wszActiveMovieKey); - StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID); + lstrcpyW(buffer, wszActiveMovieKey); + StringFromGUID2(class, buffer + lstrlenW(buffer), CHARS_IN_GUID); if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key)) pEnumMoniker->cm_key = NULL; + hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &pEnumMoniker->dmo_enum); + if (FAILED(hr)) + { + IEnumMoniker_Release(&pEnumMoniker->IEnumMoniker_iface); + return hr; + } + *ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface; DEVENUM_LockModule(); diff --git a/dll/directx/wine/devenum/parsedisplayname.c b/dll/directx/wine/devenum/parsedisplayname.c index 0f3ef3be5a0..62523c08d8a 100644 --- a/dll/directx/wine/devenum/parsedisplayname.c +++ b/dll/directx/wine/devenum/parsedisplayname.c @@ -87,20 +87,25 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa *ret = NULL; if (eaten) - *eaten = strlenW(name); + *eaten = lstrlenW(name); - name = strchrW(name, ':') + 1; + name = wcschr(name, ':') + 1; - if (name[0] == 's' && name[1] == 'w' && name[2] == ':') + if (!wcsncmp(name, swW, 3)) { type = DEVICE_FILTER; name += 3; } - else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':') + else if (!wcsncmp(name, cmW, 3)) { type = DEVICE_CODEC; name += 3; } + else if (!wcsncmp(name, dmoW, 4)) + { + type = DEVICE_DMO; + name += 4; + } else { FIXME("unhandled device type %s\n", debugstr_w(name)); @@ -110,22 +115,41 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa if (!(mon = DEVENUM_IMediaCatMoniker_Construct())) return E_OUTOFMEMORY; - lstrcpynW(buffer, name, CHARS_IN_GUID); - if (CLSIDFromString(buffer, &class) == S_OK) + if (type == DEVICE_DMO) { - mon->has_class = TRUE; - mon->class = class; - name += CHARS_IN_GUID; + lstrcpynW(buffer, name, CHARS_IN_GUID); + if (FAILED(CLSIDFromString(buffer, &mon->clsid))) + { + IMoniker_Release(&mon->IMoniker_iface); + return MK_E_SYNTAX; + } + + lstrcpynW(buffer, name + CHARS_IN_GUID - 1, CHARS_IN_GUID); + if (FAILED(CLSIDFromString(buffer, &mon->class))) + { + IMoniker_Release(&mon->IMoniker_iface); + return MK_E_SYNTAX; + } } - - mon->type = type; - - if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR)))) + else { - IMoniker_Release(&mon->IMoniker_iface); - return E_OUTOFMEMORY; + lstrcpynW(buffer, name, CHARS_IN_GUID); + if (CLSIDFromString(buffer, &class) == S_OK) + { + mon->has_class = TRUE; + mon->class = class; + name += CHARS_IN_GUID; + } + + if (!(mon->name = CoTaskMemAlloc((lstrlenW(name) + 1) * sizeof(WCHAR)))) + { + IMoniker_Release(&mon->IMoniker_iface); + return E_OUTOFMEMORY; + } + lstrcpyW(mon->name, name); } - strcpyW(mon->name, name); + + mon->type = type; *ret = &mon->IMoniker_iface; diff --git a/media/doc/README.WINE b/media/doc/README.WINE index c6f0d42d836..a94f3ca32fa 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -29,7 +29,7 @@ dll/directx/wine/d3drm # Synced to WineStaging-4.0 dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-4.0 dll/directx/wine/d3dxof # Synced to WineStaging-3.17 dll/directx/wine/ddraw # Synced to WineStaging-3.3 -dll/directx/wine/devenum # Synced to WineStaging-3.9 +dll/directx/wine/devenum # Synced to WineStaging-4.18 dll/directx/wine/dinput # Synced to WineStaging-4.0 dll/directx/wine/dinput8 # Synced to WineStaging-3.3 dll/directx/wine/dmusic # Synced to WineStaging-4.0 diff --git a/sdk/include/reactos/wine/CMakeLists.txt b/sdk/include/reactos/wine/CMakeLists.txt index 5a5b7095e3f..709ed1b8c23 100644 --- a/sdk/include/reactos/wine/CMakeLists.txt +++ b/sdk/include/reactos/wine/CMakeLists.txt @@ -1,2 +1,2 @@ -add_idl_headers(wineheaders itss.idl) +add_idl_headers(wineheaders fil_data.idl itss.idl) diff --git a/dll/directx/wine/devenum/fil_data.idl b/sdk/include/reactos/wine/fil_data.idl similarity index 69% rename from dll/directx/wine/devenum/fil_data.idl rename to sdk/include/reactos/wine/fil_data.idl index 7e37a755d91..2475163f2e1 100644 --- a/dll/directx/wine/devenum/fil_data.idl +++ b/sdk/include/reactos/wine/fil_data.idl @@ -18,14 +18,9 @@ #pragma makedep header -import "objidl.idl"; -import "strmif.idl"; import "unknwn.idl"; +import "strmif.idl"; - -/***************************************************************************** - * IAMFilterData interface - */ [ object, uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d), @@ -33,15 +28,7 @@ import "unknwn.idl"; ] interface IAMFilterData : IUnknown { - typedef [unique] IAMFilterData *LPIAMFILTERDATA; - - HRESULT ParseFilterData( - [in] BYTE * rgbFilterData, - [in] ULONG cb, - [out] BYTE ** prgbRegFilter2); + HRESULT ParseFilterData( [in] BYTE *data, [in] ULONG size, [out] BYTE **regfilter ); - HRESULT CreateFilterData( - [in] REGFILTER2 * prf2, - [out] BYTE ** prgbFilterData, - [out] ULONG * pcb); + HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG *size ); }
5 years
1
0
0
0
[reactos] 01/01: [PSDK] Add missing OVERLAPPED_ENTRY. CORE-16441
by Amine Khaldi
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=a186e66945db22a6edd87…
commit a186e66945db22a6edd87d5994c4b1a2fa002052 Author: Amine Khaldi <amine.khaldi(a)reactos.org> AuthorDate: Sun Oct 20 17:58:55 2019 +0100 Commit: Amine Khaldi <amine.khaldi(a)reactos.org> CommitDate: Sun Oct 20 17:58:55 2019 +0100 [PSDK] Add missing OVERLAPPED_ENTRY. CORE-16441 --- sdk/include/psdk/winbase.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sdk/include/psdk/winbase.h b/sdk/include/psdk/winbase.h index a1adf48268c..cd7446c5c4c 100644 --- a/sdk/include/psdk/winbase.h +++ b/sdk/include/psdk/winbase.h @@ -792,6 +792,13 @@ typedef struct _OVERLAPPED { HANDLE hEvent; } OVERLAPPED, *POVERLAPPED, *LPOVERLAPPED; +typedef struct _OVERLAPPED_ENTRY { + ULONG_PTR lpCompletionKey; + LPOVERLAPPED lpOverlapped; + ULONG_PTR Internal; + DWORD dwNumberOfBytesTransferred; +} OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; + typedef struct _STARTUPINFOA { DWORD cb; LPSTR lpReserved;
5 years
1
0
0
0
[reactos] 08/08: [SHELL32] CDefaultContextMenu: Don't render a medium just to query if it is present
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1f362c1a5a242b6608d2b…
commit 1f362c1a5a242b6608d2b9663593aecce22407a5 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 20 14:21:28 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:12 2019 +0200 [SHELL32] CDefaultContextMenu: Don't render a medium just to query if it is present --- dll/win32/shell32/CDefaultContextMenu.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp b/dll/win32/shell32/CDefaultContextMenu.cpp index d64d9423ff0..aa250481a08 100644 --- a/dll/win32/shell32/CDefaultContextMenu.cpp +++ b/dll/win32/shell32/CDefaultContextMenu.cpp @@ -325,18 +325,13 @@ HasClipboardData() if (SUCCEEDED(OleGetClipboard(&pDataObj))) { - STGMEDIUM medium; FORMATETC formatetc; TRACE("pDataObj=%p\n", pDataObj.p); /* Set the FORMATETC structure*/ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL); - if (SUCCEEDED(pDataObj->GetData(&formatetc, &medium))) - { - bRet = TRUE; - ReleaseStgMedium(&medium); - } + bRet = SUCCEEDED(pDataObj->QueryGetData(&formatetc)); } return bRet;
5 years
1
0
0
0
[reactos] 07/08: [SHELL32] CDefaultContextMenu: Always add the wanted operation to the IDataObject
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e45beb55f83a5bb6ae766…
commit e45beb55f83a5bb6ae766dcda7235ce5263c32b0 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 20 00:54:11 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:12 2019 +0200 [SHELL32] CDefaultContextMenu: Always add the wanted operation to the IDataObject --- dll/win32/shell32/CDefaultContextMenu.cpp | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/dll/win32/shell32/CDefaultContextMenu.cpp b/dll/win32/shell32/CDefaultContextMenu.cpp index 55e0121a749..d64d9423ff0 100644 --- a/dll/win32/shell32/CDefaultContextMenu.cpp +++ b/dll/win32/shell32/CDefaultContextMenu.cpp @@ -840,18 +840,16 @@ HRESULT CDefaultContextMenu::DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy if (!m_cidl || !m_pDataObj) return E_FAIL; - if (!bCopy) - { - FORMATETC formatetc; - STGMEDIUM medium; - InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT), TYMED_HGLOBAL); - m_pDataObj->GetData(&formatetc, &medium); - DWORD * pdwFlag = (DWORD*)GlobalLock(medium.hGlobal); - if (pdwFlag) - *pdwFlag = DROPEFFECT_MOVE; - GlobalUnlock(medium.hGlobal); - m_pDataObj->SetData(&formatetc, &medium, TRUE); - } + FORMATETC formatetc; + InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECT), TYMED_HGLOBAL); + STGMEDIUM medium = {0}; + medium.tymed = TYMED_HGLOBAL; + medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD)); + DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal); + if (pdwFlag) + *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE; + GlobalUnlock(medium.hGlobal); + m_pDataObj->SetData(&formatetc, &medium, TRUE); HRESULT hr = OleSetClipboard(m_pDataObj); if (FAILED_UNEXPECTEDLY(hr))
5 years
1
0
0
0
[reactos] 06/08: [SDK][SHELL32] Augment the internally used IDataObject with some extra formats This is needed because our code seems to use CF_HDROP a lot, instead of HIDA...
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c31327114b40aa0acbca0…
commit c31327114b40aa0acbca014aaf896d919a56985c Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 20 00:44:03 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:12 2019 +0200 [SDK][SHELL32] Augment the internally used IDataObject with some extra formats This is needed because our code seems to use CF_HDROP a lot, instead of HIDA... --- dll/win32/shell32/CIDLDataObj.cpp | 35 ++++++++++++++++++----- dll/win32/shell32/folders/CControlPanelFolder.cpp | 2 +- dll/win32/shell32/folders/CDesktopFolder.cpp | 2 +- dll/win32/shell32/folders/CDrivesFolder.cpp | 2 +- dll/win32/shell32/folders/CFSFolder.cpp | 2 +- dll/win32/shell32/folders/CNetFolder.cpp | 2 +- dll/win32/shell32/folders/CRegFolder.cpp | 2 +- dll/win32/shell32/wine/shell32_main.h | 2 +- dll/win32/shell32/wine/shellord.c | 2 +- sdk/include/reactos/shellutils.h | 22 ++++++++++++++ 10 files changed, 58 insertions(+), 15 deletions(-) diff --git a/dll/win32/shell32/CIDLDataObj.cpp b/dll/win32/shell32/CIDLDataObj.cpp index b1704ff9b5a..8e1993e2a66 100644 --- a/dll/win32/shell32/CIDLDataObj.cpp +++ b/dll/win32/shell32/CIDLDataObj.cpp @@ -143,7 +143,7 @@ private: public: CIDLDataObj(); ~CIDLDataObj(); - HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx); + HRESULT WINAPI Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats); // *** IDataObject methods *** virtual HRESULT WINAPI GetData(LPFORMATETC pformatetcIn, STGMEDIUM *pmedium); @@ -187,7 +187,7 @@ CIDLDataObj::~CIDLDataObj() m_Storage.RemoveAll(); } -HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx) +HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidlx, UINT cidlx, BOOL bAddAdditionalFormats) { HGLOBAL hida = RenderSHELLIDLIST((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx); if (!hida) @@ -198,12 +198,33 @@ HRESULT WINAPI CIDLDataObj::Initialize(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl m_cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLIST); - FORMATETC HIDAFormat = { (CLIPFORMAT)m_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + FORMATETC Format = { (CLIPFORMAT)m_cfShellIDList, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; STGMEDIUM medium = {0}; medium.tymed = TYMED_HGLOBAL; medium.hGlobal = hida; + HRESULT hr = SetData(&Format, &medium, TRUE); + if (!FAILED_UNEXPECTEDLY(hr) && bAddAdditionalFormats) + { + Format.cfFormat = CF_HDROP; + medium.hGlobal = RenderHDROP((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx); + hr = SetData(&Format, &medium, TRUE); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + Format.cfFormat = RegisterClipboardFormatA(CFSTR_FILENAMEA); + medium.hGlobal = RenderFILENAMEA((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx); + hr = SetData(&Format, &medium, TRUE); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + + Format.cfFormat = RegisterClipboardFormatW(CFSTR_FILENAMEW); + medium.hGlobal = RenderFILENAMEW((LPITEMIDLIST)pMyPidl, (LPITEMIDLIST*)apidlx, cidlx); + hr = SetData(&Format, &medium, TRUE); + if (FAILED_UNEXPECTEDLY(hr)) + return hr; + } - return SetData(&HIDAFormat, &medium, TRUE); + return hr; } @@ -355,11 +376,11 @@ HRESULT WINAPI CIDLDataObj::EndOperation(HRESULT hResult, IBindCtx *pbcReserved, /************************************************************************** * IDataObject_Constructor */ -HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, IDataObject **dataObject) +HRESULT IDataObject_Constructor(HWND hwndOwner, PCIDLIST_ABSOLUTE pMyPidl, PCUIDLIST_RELATIVE_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject) { if (!dataObject) return E_INVALIDARG; - return ShellObjectCreatorInit<CIDLDataObj>(hwndOwner, pMyPidl, apidl, cidl, IID_PPV_ARG(IDataObject, dataObject)); + return ShellObjectCreatorInit<CIDLDataObj>(hwndOwner, pMyPidl, apidl, cidl, bExtendedObject, IID_PPV_ARG(IDataObject, dataObject)); } /************************************************************************* @@ -373,7 +394,7 @@ HRESULT WINAPI SHCreateDataObject(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUIT { if (pdtInner) UNIMPLEMENTED; - return CIDLData_CreateFromIDArray(pidlFolder, cidl, apidl, (IDataObject **)ppv); + return IDataObject_Constructor(NULL, pidlFolder, apidl, cidl, TRUE, (IDataObject **)ppv); } return E_FAIL; } diff --git a/dll/win32/shell32/folders/CControlPanelFolder.cpp b/dll/win32/shell32/folders/CControlPanelFolder.cpp index 53bd9cb6313..84e2abe69f7 100644 --- a/dll/win32/shell32/folders/CControlPanelFolder.cpp +++ b/dll/win32/shell32/folders/CControlPanelFolder.cpp @@ -459,7 +459,7 @@ HRESULT WINAPI CControlPanelFolder::GetUIObjectOf(HWND hwndOwner, else hr = m_regFolder->GetUIObjectOf(hwndOwner, cidl, apidl, riid, prgfInOut, &pObj); } else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) { - hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj); + hr = IDataObject_Constructor(hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); } else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) { if (_ILGetCPanelPointer(apidl[0])) hr = CCPLExtractIcon_CreateInstance(this, apidl[0], riid, &pObj); diff --git a/dll/win32/shell32/folders/CDesktopFolder.cpp b/dll/win32/shell32/folders/CDesktopFolder.cpp index 20c5f667f63..f2d6c32e09c 100644 --- a/dll/win32/shell32/folders/CDesktopFolder.cpp +++ b/dll/win32/shell32/folders/CDesktopFolder.cpp @@ -636,7 +636,7 @@ HRESULT WINAPI CDesktopFolder::GetUIObjectOf( } else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) { - hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj); + hr = IDataObject_Constructor( hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); } else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1)) { diff --git a/dll/win32/shell32/folders/CDrivesFolder.cpp b/dll/win32/shell32/folders/CDrivesFolder.cpp index d8c35a79150..35f6a7d735a 100644 --- a/dll/win32/shell32/folders/CDrivesFolder.cpp +++ b/dll/win32/shell32/folders/CDrivesFolder.cpp @@ -784,7 +784,7 @@ HRESULT WINAPI CDrivesFolder::GetUIObjectOf(HWND hwndOwner, else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) { hr = IDataObject_Constructor (hwndOwner, - pidlRoot, apidl, cidl, (IDataObject **)&pObj); + pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); } else if ((IsEqualIID (riid, IID_IExtractIconA) || IsEqualIID (riid, IID_IExtractIconW)) && (cidl == 1)) { diff --git a/dll/win32/shell32/folders/CFSFolder.cpp b/dll/win32/shell32/folders/CFSFolder.cpp index f3c758d93fc..a356bb927a3 100644 --- a/dll/win32/shell32/folders/CFSFolder.cpp +++ b/dll/win32/shell32/folders/CFSFolder.cpp @@ -1064,7 +1064,7 @@ HRESULT WINAPI CFSFolder::GetUIObjectOf(HWND hwndOwner, { if (cidl >= 1) { - hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, (IDataObject **)&pObj); + hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); } else { diff --git a/dll/win32/shell32/folders/CNetFolder.cpp b/dll/win32/shell32/folders/CNetFolder.cpp index 93d91ab6dbb..5479deddb1a 100644 --- a/dll/win32/shell32/folders/CNetFolder.cpp +++ b/dll/win32/shell32/folders/CNetFolder.cpp @@ -427,7 +427,7 @@ HRESULT WINAPI CNetFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH else if (IsEqualIID(riid, IID_IDataObject) && (cidl >= 1)) { IDataObject * pDo = NULL; - hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, &pDo); + hr = IDataObject_Constructor (hwndOwner, pidlRoot, apidl, cidl, TRUE, &pDo); pObj = pDo; } else if ((IsEqualIID(riid, IID_IExtractIconA) || IsEqualIID(riid, IID_IExtractIconW)) && (cidl == 1)) diff --git a/dll/win32/shell32/folders/CRegFolder.cpp b/dll/win32/shell32/folders/CRegFolder.cpp index 33539816b11..6398109247d 100644 --- a/dll/win32/shell32/folders/CRegFolder.cpp +++ b/dll/win32/shell32/folders/CRegFolder.cpp @@ -533,7 +533,7 @@ HRESULT WINAPI CRegFolder::GetUIObjectOf(HWND hwndOwner, UINT cidl, PCUITEMID_CH } else if (IsEqualIID (riid, IID_IDataObject) && (cidl >= 1)) { - hr = IDataObject_Constructor (hwndOwner, m_pidlRoot, apidl, cidl, (IDataObject **)&pObj); + hr = IDataObject_Constructor (hwndOwner, m_pidlRoot, apidl, cidl, TRUE, (IDataObject **)&pObj); } else { diff --git a/dll/win32/shell32/wine/shell32_main.h b/dll/win32/shell32/wine/shell32_main.h index 16536975384..1585f60aedd 100644 --- a/dll/win32/shell32/wine/shell32_main.h +++ b/dll/win32/shell32/wine/shell32_main.h @@ -63,7 +63,7 @@ DWORD WINAPI ParseFieldW(LPCWSTR src, DWORD nField, LPWSTR dst, DWORD len) DECLS /**************************************************************************** * Class constructors */ -HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, PCUITEMID_CHILD_ARRAY apidl, UINT cidl, IDataObject **dataObject); +HRESULT IDataObject_Constructor(HWND hwndOwner, LPCITEMIDLIST pMyPidl, PCUITEMID_CHILD_ARRAY apidl, UINT cidl, BOOL bExtendedObject, IDataObject **dataObject); HRESULT IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[], IEnumFORMATETC **enumerator); LPCLASSFACTORY IClassFactory_Constructor(REFCLSID); diff --git a/dll/win32/shell32/wine/shellord.c b/dll/win32/shell32/wine/shellord.c index fac2d20dea3..71f35e4d866 100644 --- a/dll/win32/shell32/wine/shellord.c +++ b/dll/win32/shell32/wine/shellord.c @@ -1791,7 +1791,7 @@ HRESULT WINAPI CIDLData_CreateFromIDArray( pdump (pidlFolder); for (i=0; i<cpidlFiles; i++) pdump (lppidlFiles[i]); } - hResult = IDataObject_Constructor(hwnd, pidlFolder, lppidlFiles, cpidlFiles, ppdataObject); + hResult = IDataObject_Constructor(hwnd, pidlFolder, lppidlFiles, cpidlFiles, FALSE, ppdataObject); return hResult; } diff --git a/sdk/include/reactos/shellutils.h b/sdk/include/reactos/shellutils.h index 2f5d72ece0f..467f142c4ae 100644 --- a/sdk/include/reactos/shellutils.h +++ b/sdk/include/reactos/shellutils.h @@ -378,6 +378,28 @@ HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 return hResult; } +template<class T, class T1, class T2, class T3, class T4, class T5> +HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, T5 initArg5, REFIID riid, void ** ppv) +{ + _CComObject<T> *pobj; + HRESULT hResult; + + hResult = _CComObject<T>::CreateInstance(&pobj); + if (FAILED(hResult)) + return hResult; + + pobj->AddRef(); /* CreateInstance returns object with 0 ref count */ + + hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4, initArg5); + + if (SUCCEEDED(hResult)) + hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv)); + + pobj->Release(); /* In case of failure the object will be released */ + + return hResult; +} + HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCSTR pstrValue) { pStrRet->uType = STRRET_CSTR;
5 years
1
0
0
0
[reactos] 05/08: [SHELL32] Mark an unexpected failure as unexpected
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f9d3c2c608af3551a1927…
commit f9d3c2c608af3551a192709fec472b615b90cab2 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 20 00:42:16 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:11 2019 +0200 [SHELL32] Mark an unexpected failure as unexpected --- dll/win32/shell32/dialogs/filedefext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dll/win32/shell32/dialogs/filedefext.cpp b/dll/win32/shell32/dialogs/filedefext.cpp index 1fe3215f80f..f4b587dae1e 100644 --- a/dll/win32/shell32/dialogs/filedefext.cpp +++ b/dll/win32/shell32/dialogs/filedefext.cpp @@ -1190,7 +1190,7 @@ CFileDefExt::Initialize(PCIDLIST_ABSOLUTE pidlFolder, IDataObject *pDataObj, HKE format.tymed = TYMED_HGLOBAL; hr = pDataObj->GetData(&format, &stgm); - if (FAILED(hr)) + if (FAILED_UNEXPECTEDLY(hr)) return hr; if (!DragQueryFileW((HDROP)stgm.hGlobal, 0, m_wszPath, _countof(m_wszPath)))
5 years
1
0
0
0
[reactos] 04/08: [SHELL32_APITEST] Show that SHCreateDataObject behaves exactly like CIDLData_CreateFromIDArray
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2318bda651ee1a8a17585…
commit 2318bda651ee1a8a175859e3e05ee3f821404151 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 20 00:37:05 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:11 2019 +0200 [SHELL32_APITEST] Show that SHCreateDataObject behaves exactly like CIDLData_CreateFromIDArray --- modules/rostests/apitests/shell32/CMakeLists.txt | 1 + .../apitests/shell32/SHCreateDataObject.cpp | 466 +++++++++++++++++++++ modules/rostests/apitests/shell32/testlist.c | 2 + 3 files changed, 469 insertions(+) diff --git a/modules/rostests/apitests/shell32/CMakeLists.txt b/modules/rostests/apitests/shell32/CMakeLists.txt index df1e6cf8af2..02b28625d63 100644 --- a/modules/rostests/apitests/shell32/CMakeLists.txt +++ b/modules/rostests/apitests/shell32/CMakeLists.txt @@ -20,6 +20,7 @@ list(APPEND SOURCE IShellFolderViewCB.cpp OpenAs_RunDLL.cpp PathResolve.cpp + SHCreateDataObject.cpp SHCreateFileExtractIconW.cpp SHParseDisplayName.cpp ShellExecCmdLine.cpp diff --git a/modules/rostests/apitests/shell32/SHCreateDataObject.cpp b/modules/rostests/apitests/shell32/SHCreateDataObject.cpp new file mode 100644 index 00000000000..186134f33ea --- /dev/null +++ b/modules/rostests/apitests/shell32/SHCreateDataObject.cpp @@ -0,0 +1,466 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later
) + * PURPOSE: Test for SHCreateDataObject + * COPYRIGHT: Copyright 2019 Mark Jansen (mark.jansen(a)reactos.org) + */ + +#include "shelltest.h" +#include <ndk/rtlfuncs.h> +#include <stdio.h> +#include <shellutils.h> +#include <shlwapi.h> + +static DWORD g_WinVersion; + +typedef HRESULT (WINAPI *tSHCreateDataObject)(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IDataObject *pdtInner, REFIID riid, void **ppv); +static tSHCreateDataObject pSHCreateDataObject; + + +static void TestAdviseAndCanonical(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUIDLIST_RELATIVE_ARRAY apidl) +{ + CComPtr<IDataObject> spDataObj; + HRESULT hr = pSHCreateDataObject(pidlFolder, cidl, apidl, NULL, IID_PPV_ARG(IDataObject, &spDataObj)); + + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + hr = spDataObj->DAdvise(NULL, 0, NULL, NULL); + ok_hex(hr, OLE_E_ADVISENOTSUPPORTED); + + hr = spDataObj->DUnadvise(0); + ok_hex(hr, OLE_E_ADVISENOTSUPPORTED); + + hr = spDataObj->EnumDAdvise(NULL); + ok_hex(hr, OLE_E_ADVISENOTSUPPORTED); + + + FORMATETC in = {1, (DVTARGETDEVICE*)2, 3, 4, 5}; + FORMATETC out = {6, (DVTARGETDEVICE*)7, 8, 9, 10}; + + hr = spDataObj->GetCanonicalFormatEtc(&in, &out); + ok_hex(hr, DATA_S_SAMEFORMATETC); + + if (g_WinVersion < _WIN32_WINNT_VISTA) + { + ok_int(out.cfFormat, 6); + ok_ptr(out.ptd, (void*)7); + ok_int(out.dwAspect, 8); + ok_int(out.lindex, 9); + ok_int(out.tymed, 10); + trace("out unmodified\n"); + } + else + { + ok_int(out.cfFormat, in.cfFormat); + ok_ptr(out.ptd, NULL); + ok_int(out.dwAspect, (int)in.dwAspect); + ok_int(out.lindex, in.lindex); + ok_int(out.tymed, (int)in.tymed); + trace("in copied to out\n"); + } +} + + +static inline PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const* pida) +{ + return (PCUIDLIST_ABSOLUTE)(((LPBYTE)pida) + (pida)->aoffset[0]); +} + +static inline PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const* pida, SIZE_T i) +{ + return (PCUIDLIST_RELATIVE)(((LPBYTE)pida) + (pida)->aoffset[i + 1]); +} + +#define ok_wstri(x, y) \ + ok(wcsicmp(x, y) == 0, "Wrong string. Expected '%S', got '%S'\n", y, x) + +static void TestHIDA(PVOID pData, SIZE_T Size, LPCWSTR ExpectRoot, LPCWSTR ExpectPath1, LPCWSTR ExpectPath2) +{ + LPIDA pida = (LPIDA)pData; + + ok_int(pida->cidl, 2); + if (pida->cidl != 2) + return; + + WCHAR FolderPath[MAX_PATH], Item1[MAX_PATH], Item2[MAX_PATH]; + BOOL bRet = SHGetPathFromIDListW(HIDA_GetPIDLFolder(pida), FolderPath); + ok_int(bRet, TRUE); + if (!bRet) + return; + ok_wstri(FolderPath, ExpectRoot); + + CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidl1(ILCombine(HIDA_GetPIDLFolder(pida), HIDA_GetPIDLItem(pida, 0))); + CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidl2(ILCombine(HIDA_GetPIDLFolder(pida), HIDA_GetPIDLItem(pida, 1))); + + bRet = SHGetPathFromIDListW(pidl1, Item1); + ok_int(bRet, TRUE); + if (!bRet) + return; + ok_wstri(Item1, ExpectPath1); + + bRet = SHGetPathFromIDListW(pidl2, Item2); + ok_int(bRet, TRUE); + if (!bRet) + return; + ok_wstri(Item2, ExpectPath2); +} + +static void TestHDROP(PVOID pData, SIZE_T Size, LPCWSTR ExpectRoot, LPCWSTR ExpectPath1, LPCWSTR ExpectPath2) +{ + DROPFILES* pDropFiles = (DROPFILES*)pData; + ok_int(pDropFiles->fWide, TRUE); + + LPCWSTR Expected[2] = { ExpectPath1, ExpectPath2 }; + + DWORD offset = pDropFiles->pFiles; + UINT Count = 0; + for (;;Count++) + { + LPCWSTR ptr = (LPCWSTR)(((BYTE*)pDropFiles) + offset); + if (!*ptr) + break; + + if (Count < _countof(Expected)) + ok_wstri(Expected[Count], ptr); + + offset += (wcslen(ptr) + 1) * sizeof(WCHAR); + } + ok_int(Count, 2); +} + +static void TestFilenameA(PVOID pData, SIZE_T Size, LPCWSTR ExpectRoot, LPCWSTR ExpectPath1, LPCWSTR ExpectPath2) +{ + LPCSTR FirstFile = (LPCSTR)pData; + LPWSTR FirstFileW; + + HRESULT hr = SHStrDupA(FirstFile, &FirstFileW); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + ok_wstri(ExpectPath1, FirstFileW); + CoTaskMemFree(FirstFileW); +} + +static void TestFilenameW(PVOID pData, SIZE_T Size, LPCWSTR ExpectRoot, LPCWSTR ExpectPath1, LPCWSTR ExpectPath2) +{ + LPCWSTR FirstFile = (LPCWSTR)pData; + ok_wstri(ExpectPath1, FirstFile); +} + + +static void TestDefaultFormat(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUIDLIST_RELATIVE_ARRAY apidl) +{ + CComPtr<IDataObject> spDataObj; + HRESULT hr = pSHCreateDataObject(pidlFolder, cidl, apidl, NULL, IID_PPV_ARG(IDataObject, &spDataObj)); + + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + CComPtr<IEnumFORMATETC> pEnumFmt; + hr = spDataObj->EnumFormatEtc(DATADIR_GET, &pEnumFmt); + + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + UINT Expected[4] = { + RegisterClipboardFormatA(CFSTR_SHELLIDLISTA), + CF_HDROP, + RegisterClipboardFormatA(CFSTR_FILENAMEA), + RegisterClipboardFormatA("FileNameW"), + }; + + UINT Count = 0; + FORMATETC fmt; + while (S_OK == (hr=pEnumFmt->Next(1, &fmt, NULL))) + { + char szGot[512], szExpected[512]; + GetClipboardFormatNameA(fmt.cfFormat, szGot, sizeof(szGot)); + ok(Count < _countof(Expected), "%u\n", Count); + if (Count < _countof(Expected)) + { + GetClipboardFormatNameA(Expected[Count], szExpected, sizeof(szExpected)); + ok(fmt.cfFormat == Expected[Count], "Got 0x%x(%s), expected 0x%x(%s) for %u\n", + fmt.cfFormat, szGot, Expected[Count], szExpected, Count); + } + + ok(fmt.ptd == NULL, "Got 0x%p, expected 0x%p for [%u].ptd\n", fmt.ptd, (void*)NULL, Count); + ok(fmt.dwAspect == DVASPECT_CONTENT, "Got 0x%lu, expected 0x%d for [%u].dwAspect\n", fmt.dwAspect, DVASPECT_CONTENT, Count); + ok(fmt.lindex == -1, "Got 0x%lx, expected 0x%x for [%u].lindex\n", fmt.lindex, -1, Count); + ok(fmt.tymed == TYMED_HGLOBAL, "Got 0x%lu, expected 0x%d for [%u].tymed\n", fmt.tymed, TYMED_HGLOBAL, Count); + + Count++; + } + trace("Got %u formats\n", Count); + ULONG ExpectedCount = (g_WinVersion < _WIN32_WINNT_WIN8) ? 1 : 4; + ok_int(Count, (int)ExpectedCount); + ok_hex(hr, S_FALSE); + + typedef void (*TestFunction)(PVOID pData, SIZE_T Size, LPCWSTR ExpectRoot, LPCWSTR ExpectPath1, LPCWSTR ExpectPath2); + TestFunction TestFormats[] = { + TestHIDA, + TestHDROP, + TestFilenameA, + TestFilenameW, + }; + + WCHAR ExpectRoot[MAX_PATH], ExpectItem1[MAX_PATH], ExpectItem2[MAX_PATH]; + + hr = SHGetFolderPathW(NULL, CSIDL_WINDOWS, NULL, 0, ExpectRoot); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + hr = SHGetFolderPathW(NULL, CSIDL_SYSTEM, NULL, 0, ExpectItem1); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + hr = SHGetFolderPathW(NULL, CSIDL_RESOURCES, NULL, 0, ExpectItem2); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + + /* The formats are not synthesized on request */ + for (Count = 0; Count < _countof(Expected); ++Count) + { + STGMEDIUM medium = {0}; + FORMATETC etc = { (CLIPFORMAT)Expected[Count], NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + char szExpected[512]; + + GetClipboardFormatNameA(etc.cfFormat, szExpected, sizeof(szExpected)); + hr = spDataObj->GetData(&etc, &medium); + HRESULT hr2 = spDataObj->QueryGetData(&etc); + ok_hex(hr2, SUCCEEDED(hr) ? S_OK : S_FALSE); + + if (Count < ExpectedCount) + { + ok(hr == S_OK, "0x%x (0x%x(%s))\n", (unsigned int)hr, Expected[Count], szExpected); + ok(medium.tymed == TYMED_HGLOBAL, "0x%lx (0x%x(%s))\n", medium.tymed, Expected[Count], szExpected); + if (hr == S_OK && medium.tymed == TYMED_HGLOBAL) + { + PVOID pData = GlobalLock(medium.hGlobal); + SIZE_T Size = GlobalSize(medium.hGlobal); + TestFormats[Count](pData, Size, ExpectRoot, ExpectItem1, ExpectItem2); + GlobalUnlock(medium.hGlobal); + } + } + else + { + if (g_WinVersion < _WIN32_WINNT_VISTA) + ok(hr == E_INVALIDARG, "0x%x (0x%x(%s))\n", (unsigned int)hr, Expected[Count], szExpected); + else + ok(hr == DV_E_FORMATETC, "0x%x (0x%x(%s))\n", (unsigned int)hr, Expected[Count], szExpected); + } + + if (SUCCEEDED(hr)) + ReleaseStgMedium(&medium); + } + + CLIPFORMAT Format = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); + FORMATETC formatetc = { Format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium; + + hr = spDataObj->GetData(&formatetc, &medium); + if (g_WinVersion < _WIN32_WINNT_VISTA) + ok_hex(hr, E_INVALIDARG); + else + ok_hex(hr, DV_E_FORMATETC); +} + + +static void TestSetAndGetExtraFormat(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUIDLIST_RELATIVE_ARRAY apidl) +{ + CComPtr<IDataObject> spDataObj; + HRESULT hr = pSHCreateDataObject(pidlFolder, cidl, apidl, NULL, IID_PPV_ARG(IDataObject, &spDataObj)); + + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + STGMEDIUM medium = {0}; + medium.tymed = TYMED_HGLOBAL; + medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD)); + ok(medium.hGlobal != NULL, "Download more ram\n"); + PDWORD data = (PDWORD)GlobalLock(medium.hGlobal); + *data = 12345; + GlobalUnlock(medium.hGlobal); + + UINT flags = GlobalFlags(medium.hGlobal); + SIZE_T size = GlobalSize(medium.hGlobal); + ok_hex(flags, 0); + ok_size_t(size, sizeof(DWORD)); + + FORMATETC etc = { (CLIPFORMAT)RegisterClipboardFormatA(CFSTR_INDRAGLOOPA), NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + FORMATETC etc2 = etc; + + /* Not supported! */ + hr = spDataObj->SetData(&etc, &medium, FALSE); + if (g_WinVersion < _WIN32_WINNT_WIN8) + ok_hex(hr, E_INVALIDARG); + else + ok_hex(hr, E_NOTIMPL); + + /* Object takes ownership! */ + hr = spDataObj->SetData(&etc, &medium, TRUE); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + /* Does not touch the hGlobal! */ + flags = GlobalFlags(medium.hGlobal); + size = GlobalSize(medium.hGlobal); + ok_hex(flags, 0); + ok_size_t(size, sizeof(DWORD)); + + STGMEDIUM medium2 = {0}; + + /* No conversion */ + etc2.dwAspect = DVASPECT_DOCPRINT; + hr = spDataObj->GetData(&etc2, &medium2); + HRESULT hr2 = spDataObj->QueryGetData(&etc2); + ok_hex(hr2, SUCCEEDED(hr) ? S_OK : S_FALSE); + if (g_WinVersion < _WIN32_WINNT_VISTA) + ok_hex(hr, E_INVALIDARG); + else + ok_hex(hr, DV_E_FORMATETC); + + etc2.dwAspect = DVASPECT_CONTENT; + etc2.tymed = TYMED_NULL; + hr = spDataObj->GetData(&etc2, &medium2); + hr2 = spDataObj->QueryGetData(&etc2); + ok_hex(hr2, SUCCEEDED(hr) ? S_OK : S_FALSE); + if (g_WinVersion < _WIN32_WINNT_VISTA) + ok_hex(hr, E_INVALIDARG); + else + ok_hex(hr, DV_E_FORMATETC); + etc2.tymed = TYMED_HGLOBAL; + + ok_ptr(medium2.pUnkForRelease, NULL); + hr = spDataObj->GetData(&etc2, &medium2); + hr2 = spDataObj->QueryGetData(&etc2); + ok_hex(hr2, SUCCEEDED(hr) ? S_OK : S_FALSE); + ok_hex(hr, S_OK); + if (hr == S_OK) + { + ok_hex(medium2.tymed, TYMED_HGLOBAL); + if (g_WinVersion < _WIN32_WINNT_VISTA) + { + /* The IDataObject is set as pUnkForRelease */ + ok(medium2.pUnkForRelease == (IUnknown*)spDataObj, "Expected the data object (0x%p), got 0x%p\n", + (IUnknown*)spDataObj, medium2.pUnkForRelease); + ok(medium.hGlobal == medium2.hGlobal, "Pointers are not the same!, got 0x%p and 0x%p\n", medium.hGlobal, medium2.hGlobal); + } + else + { + ok_ptr(medium2.pUnkForRelease, NULL); + ok(medium.hGlobal != medium2.hGlobal, "Pointers are the same!\n"); + } + + flags = GlobalFlags(medium2.hGlobal); + size = GlobalSize(medium2.hGlobal); + ok_hex(flags, 0); + ok_size_t(size, sizeof(DWORD)); + + data = (PDWORD)GlobalLock(medium2.hGlobal); + if (data) + ok_int(*data, 12345); + else + ok(0, "GlobalLock: %lu\n", GetLastError()); + GlobalUnlock(medium2.hGlobal); + + HGLOBAL backup = medium2.hGlobal; + ReleaseStgMedium(&medium2); + + flags = GlobalFlags(backup); + size = GlobalSize(backup); + if (g_WinVersion < _WIN32_WINNT_VISTA) + { + /* Same object! just the pUnkForRelease was set, so original hGlobal is still valid */ + ok_hex(flags, 0); + ok_size_t(size, sizeof(DWORD)); + } + else + { + ok_hex(flags, GMEM_INVALID_HANDLE); + ok_size_t(size, 0); + } + + /* Original is still intact (but no longer ours!) */ + flags = GlobalFlags(medium.hGlobal); + size = GlobalSize(medium.hGlobal); + ok_hex(flags, 0); + ok_size_t(size, sizeof(DWORD)); + } + + HGLOBAL backup = medium.hGlobal; + spDataObj.Release(); + + /* Now our hGlobal is deleted */ + flags = GlobalFlags(backup); + size = GlobalSize(backup); + ok_hex(flags, GMEM_INVALID_HANDLE); + ok_size_t(size, 0); +} + +START_TEST(SHCreateDataObject) +{ + HRESULT hr; + + pSHCreateDataObject = (tSHCreateDataObject)GetProcAddress(GetModuleHandleA("shell32.dll"), "SHCreateDataObject"); + if (!pSHCreateDataObject) + { + skip("shell32!SHCreateDataObject not exported\n"); + } + + + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + + RTL_OSVERSIONINFOEXW rtlinfo = {0}; + + rtlinfo.dwOSVersionInfoSize = sizeof(rtlinfo); + RtlGetVersion((PRTL_OSVERSIONINFOW)&rtlinfo); + g_WinVersion = (rtlinfo.dwMajorVersion << 8) | rtlinfo.dwMinorVersion; + + CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlWindows; + CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlSystem32; + CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlResources; + + hr = SHGetFolderLocation(NULL, CSIDL_WINDOWS, NULL, 0, &pidlWindows); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + hr = SHGetFolderLocation(NULL, CSIDL_SYSTEM, NULL, 0, &pidlSystem32); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + hr = SHGetFolderLocation(NULL, CSIDL_RESOURCES, NULL, 0, &pidlResources); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + CComPtr<IShellFolder> shellFolder; + PCUITEMID_CHILD child1; + hr = SHBindToParent(pidlSystem32, IID_PPV_ARG(IShellFolder, &shellFolder), &child1); + ok_hex(hr, S_OK); + if (!SUCCEEDED(hr)) + return; + + PCUITEMID_CHILD child2 = ILFindLastID(pidlResources); + + UINT cidl = 2; + PCUIDLIST_RELATIVE apidl[2] = { + child1, child2 + }; + + TestAdviseAndCanonical(pidlWindows, cidl, apidl); + TestDefaultFormat(pidlWindows, cidl, apidl); + TestSetAndGetExtraFormat(pidlWindows, cidl, apidl); +} diff --git a/modules/rostests/apitests/shell32/testlist.c b/modules/rostests/apitests/shell32/testlist.c index ffd832f0ba2..7b603dff147 100644 --- a/modules/rostests/apitests/shell32/testlist.c +++ b/modules/rostests/apitests/shell32/testlist.c @@ -15,6 +15,7 @@ extern void func_IShellFolderViewCB(void); extern void func_menu(void); extern void func_OpenAs_RunDLL(void); extern void func_PathResolve(void); +extern void func_SHCreateDataObject(void); extern void func_SHCreateFileExtractIconW(void); extern void func_ShellExecCmdLine(void); extern void func_ShellExecuteEx(void); @@ -35,6 +36,7 @@ const struct test winetest_testlist[] = { "menu", func_menu }, { "OpenAs_RunDLL", func_OpenAs_RunDLL }, { "PathResolve", func_PathResolve }, + { "SHCreateDataObject", func_SHCreateDataObject }, { "SHCreateFileExtractIconW", func_SHCreateFileExtractIconW }, { "ShellExecCmdLine", func_ShellExecCmdLine }, { "ShellExecuteEx", func_ShellExecuteEx },
5 years
1
0
0
0
[reactos] 03/08: [SHELL32] Properly release an StgMedium
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=75cabb07be07c5cc40196…
commit 75cabb07be07c5cc401960f4a0633f8416c4636c Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sun Oct 20 00:27:58 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:11 2019 +0200 [SHELL32] Properly release an StgMedium --- dll/win32/shell32/COpenWithMenu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dll/win32/shell32/COpenWithMenu.cpp b/dll/win32/shell32/COpenWithMenu.cpp index db2a76eac05..6ccc664afc9 100644 --- a/dll/win32/shell32/COpenWithMenu.cpp +++ b/dll/win32/shell32/COpenWithMenu.cpp @@ -1369,14 +1369,14 @@ COpenWithMenu::Initialize(PCIDLIST_ABSOLUTE pidlFolder, { TRACE("pidl is not a file\n"); GlobalUnlock(medium.hGlobal); - GlobalFree(medium.hGlobal); + ReleaseStgMedium(&medium); return E_FAIL; } pidl = ILCombine(pidlFolder2, pidlChild); GlobalUnlock(medium.hGlobal); - GlobalFree(medium.hGlobal); + ReleaseStgMedium(&medium); if (!pidl) {
5 years
1
0
0
0
[reactos] 02/08: [SHELL32_APITEST] Show that the default data object does not have a preferred drop effect
by Mark Jansen
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0f2cb5abc7a5a7a75dbd3…
commit 0f2cb5abc7a5a7a75dbd36a18e2c4949ee12f9a7 Author: Mark Jansen <mark.jansen(a)reactos.org> AuthorDate: Sat Oct 19 23:56:19 2019 +0200 Commit: Mark Jansen <mark.jansen(a)reactos.org> CommitDate: Sun Oct 20 17:10:11 2019 +0200 [SHELL32_APITEST] Show that the default data object does not have a preferred drop effect --- modules/rostests/apitests/shell32/CIDLData.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/rostests/apitests/shell32/CIDLData.cpp b/modules/rostests/apitests/shell32/CIDLData.cpp index 8169666977b..f64fb3f7178 100644 --- a/modules/rostests/apitests/shell32/CIDLData.cpp +++ b/modules/rostests/apitests/shell32/CIDLData.cpp @@ -258,6 +258,17 @@ static void TestDefaultFormat(PCIDLIST_ABSOLUTE pidlFolder, UINT cidl, PCUIDLIST if (SUCCEEDED(hr)) ReleaseStgMedium(&medium); } + + // Not registered + CLIPFORMAT Format = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW); + FORMATETC formatetc = { Format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; + STGMEDIUM medium; + + hr = spDataObj->GetData(&formatetc, &medium); + if (g_WinVersion < _WIN32_WINNT_VISTA) + ok_hex(hr, E_INVALIDARG); + else + ok_hex(hr, DV_E_FORMATETC); }
5 years
1
0
0
0
← Newer
1
...
7
8
9
10
11
12
13
...
18
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Results per page:
10
25
50
100
200