Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- 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
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
September 2018
- 70 participants
- 1549 messages
[PATCH 2/2] wineboot: Set Flags and ProfileImagePath user profile values
by Alex Henrie
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38659
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
programs/wineboot/Makefile.in | 2 +-
programs/wineboot/wineboot.c | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/programs/wineboot/Makefile.in b/programs/wineboot/Makefile.in
index 2006067c4e..1069626b87 100644
--- a/programs/wineboot/Makefile.in
+++ b/programs/wineboot/Makefile.in
@@ -1,6 +1,6 @@
MODULE = wineboot.exe
APPMODE = -mconsole
-IMPORTS = uuid advapi32
+IMPORTS = uuid advapi32 userenv
DELAYIMPORTS = shell32 shlwapi version user32
C_SRCS = \
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 043cc64ab6..cf9c04b6c2 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -82,6 +82,7 @@
#include <shlwapi.h>
#include <shellapi.h>
#include <sddl.h>
+#include <userenv.h>
#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
@@ -426,6 +427,9 @@ static void create_volatile_environment_registry_key(void)
/* create a profile key for the current user */
static void create_user_profile_registry_key(void)
{
+ static const WCHAR FlagsW[] = {'F','l','a','g','s',0};
+ static const WCHAR ProfileImagePathW[] = {'P','r','o','f','i','l','e','I','m','a','g','e','P','a','t','h',0};
+ static const DWORD flags = 0;
WCHAR profile_key_path[512] = {'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
'W','i','n','d','o','w','s',' ','N','T','\\',
@@ -435,6 +439,8 @@ static void create_user_profile_registry_key(void)
char buffer[512];
WCHAR *sid_str;
HKEY profile_key;
+ WCHAR profile_dir[MAX_PATH];
+ DWORD profile_dir_len = ARRAY_SIZE(profile_dir);
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
GetTokenInformation(token, TokenUser, buffer, sizeof(buffer), NULL);
@@ -444,6 +450,11 @@ static void create_user_profile_registry_key(void)
RegCreateKeyExW(HKEY_LOCAL_MACHINE, profile_key_path, 0, NULL, 0, KEY_WRITE, NULL, &profile_key, NULL);
+ RegSetValueExW(profile_key, FlagsW, 0, REG_DWORD, (BYTE *)&flags, sizeof(flags));
+
+ GetUserProfileDirectoryW(token, profile_dir, &profile_dir_len);
+ RegSetValueExW(profile_key, ProfileImagePathW, 0, REG_SZ, (BYTE *)profile_dir, (profile_dir_len + 1) * sizeof(WCHAR));
+
RegCloseKey(profile_key);
CloseHandle(token);
}
--
2.19.0
Sept. 23, 2018
[PATCH 1/2] wineboot: Create user profile registry key
by Alex Henrie
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=15670
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
programs/wineboot/wineboot.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 075b4c8b08..043cc64ab6 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -81,6 +81,7 @@
#include <shobjidl.h>
#include <shlwapi.h>
#include <shellapi.h>
+#include <sddl.h>
#include "resource.h"
WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
@@ -422,6 +423,31 @@ static void create_volatile_environment_registry_key(void)
RegCloseKey( hkey );
}
+/* create a profile key for the current user */
+static void create_user_profile_registry_key(void)
+{
+ WCHAR profile_key_path[512] = {'S','o','f','t','w','a','r','e','\\',
+ 'M','i','c','r','o','s','o','f','t','\\',
+ 'W','i','n','d','o','w','s',' ','N','T','\\',
+ 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+ 'P','r','o','f','i','l','e','L','i','s','t','\\',0};
+ HANDLE token;
+ char buffer[512];
+ WCHAR *sid_str;
+ HKEY profile_key;
+
+ OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
+ GetTokenInformation(token, TokenUser, buffer, sizeof(buffer), NULL);
+ ConvertSidToStringSidW(((TOKEN_USER *)buffer)->User.Sid, &sid_str);
+ strcatW(profile_key_path, sid_str);
+ LocalFree(sid_str);
+
+ RegCreateKeyExW(HKEY_LOCAL_MACHINE, profile_key_path, 0, NULL, 0, KEY_WRITE, NULL, &profile_key, NULL);
+
+ RegCloseKey(profile_key);
+ CloseHandle(token);
+}
+
/* Performs the rename operations dictated in %SystemRoot%\Wininit.ini.
* Returns FALSE if there was an error, or otherwise if all is ok.
*/
@@ -1247,6 +1273,7 @@ int main( int argc, char *argv[] )
if (init || update) update_wineprefix( update );
create_volatile_environment_registry_key();
+ create_user_profile_registry_key();
ProcessRunKeys( HKEY_LOCAL_MACHINE, RunOnceW, TRUE, TRUE );
--
2.19.0
Sept. 23, 2018
[PATCH] quartz: Don't round a <1sec difference to 0 in WAVEParserImpl_seek
by Alex Henrie
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=34302
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
For some reason, the game sets the audio stream position to a negative
value, then seeks to 0. If Wine decides that it doesn't actually need to
do the seek operation, it then reads garbage data from the negative
offset.
Unfortunately, there is still another bug with the audio in this game:
Wine keeps reading past the end of the audio stream, causing a crash at
the end of the audio clip.
---
dlls/quartz/waveparser.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/quartz/waveparser.c b/dlls/quartz/waveparser.c
index fa9cd45d27..995e43196d 100644
--- a/dlls/quartz/waveparser.c
+++ b/dlls/quartz/waveparser.c
@@ -211,10 +211,9 @@ static HRESULT WINAPI WAVEParserImpl_seek(IMediaSeeking *iface)
return E_INVALIDARG;
}
- if (curpos/1000000 == newpos/1000000)
+ if (curpos == newpos)
{
- TRACE("Requesting position %s same as current position %s\n",
- wine_dbgstr_longlong(newpos), wine_dbgstr_longlong(curpos));
+ TRACE("Requesting position %s same as current position\n", wine_dbgstr_longlong(newpos));
return S_OK;
}
--
2.19.0
Sept. 23, 2018
[PATCH] kernel32: Add GetQueuedCompletionStatusEx stub.
by Gijs Vermeulen
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=43878
Signed-off-by: Gijs Vermeulen <gijsvrm(a)gmail.com>
---
.../api-ms-win-core-io-l1-1-0.spec | 2 +-
.../api-ms-win-core-io-l1-1-1.spec | 2 +-
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernel32/sync.c | 12 ++++++++++++
dlls/kernelbase/kernelbase.spec | 2 +-
include/winbase.h | 7 +++++++
6 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec b/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec
index f73e427782..44d42d1266 100644
--- a/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec
+++ b/dlls/api-ms-win-core-io-l1-1-0/api-ms-win-core-io-l1-1-0.spec
@@ -3,5 +3,5 @@
@ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) kernel32.DeviceIoControl
@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult
@ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus
-@ stub GetQueuedCompletionStatusEx
+@ stdcall GetQueuedCompletionStatusEx(long ptr long ptr long long) kernel32.GetQueuedCompletionStatusEx
@ stdcall PostQueuedCompletionStatus(long long ptr ptr) kernel32.PostQueuedCompletionStatus
diff --git a/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec b/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec
index 73aae1aa9a..d335efaee8 100644
--- a/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec
+++ b/dlls/api-ms-win-core-io-l1-1-1/api-ms-win-core-io-l1-1-1.spec
@@ -6,5 +6,5 @@
@ stdcall GetOverlappedResult(long ptr ptr long) kernel32.GetOverlappedResult
@ stub GetOverlappedResultEx
@ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus
-@ stub GetQueuedCompletionStatusEx
+@ stdcall GetQueuedCompletionStatusEx(long ptr long ptr long long) kernel32.GetQueuedCompletionStatusEx
@ stdcall PostQueuedCompletionStatus(long long ptr ptr) kernel32.PostQueuedCompletionStatus
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 9db7d98f41..cb9c73aef8 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -804,7 +804,7 @@
@ stdcall GetProfileStringA(str str str ptr long)
@ stdcall GetProfileStringW(wstr wstr wstr ptr long)
@ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long)
-# @ stub GetQueuedCompletionStatusEx
+@ stdcall GetQueuedCompletionStatusEx(long ptr long ptr long long)
@ stub -i386 GetSLCallbackTarget
@ stub -i386 GetSLCallbackTemplate
@ stdcall GetShortPathNameA(str ptr long)
diff --git a/dlls/kernel32/sync.c b/dlls/kernel32/sync.c
index a855e95117..58ecc09003 100644
--- a/dlls/kernel32/sync.c
+++ b/dlls/kernel32/sync.c
@@ -2377,6 +2377,18 @@ BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOf
return FALSE;
}
+/******************************************************************************
+ * GetQueuedCompletionStatusEx (KERNEL32.@)
+ */
+BOOL WINAPI GetQueuedCompletionStatusEx(HANDLE completion_port, LPOVERLAPPED_ENTRY completion_port_entries,
+ ULONG count, ULONG *num_entries_removed, DWORD milliseconds,
+ BOOL alertable)
+{
+ FIXME("(%p, %p, %d, %p, %d, %d) stub!\n",
+ completion_port, completion_port_entries, count, num_entries_removed, milliseconds, alertable);
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ return FALSE;
+}
/******************************************************************************
* PostQueuedCompletionStatus (KERNEL32.@)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec
index 29805760da..7d8439fbd6 100644
--- a/dlls/kernelbase/kernelbase.spec
+++ b/dlls/kernelbase/kernelbase.spec
@@ -645,7 +645,7 @@
# @ stub GetPublisherCacheFolder
# @ stub GetPublisherRootFolder
@ stdcall GetQueuedCompletionStatus(long ptr ptr ptr long) kernel32.GetQueuedCompletionStatus
-@ stub GetQueuedCompletionStatusEx
+@ stdcall GetQueuedCompletionStatusEx(long ptr long ptr long long) kernel32.GetQueuedCompletionStatusEx
# @ stub GetRegistryExtensionFlags
# @ stub GetRoamingLastObservedChangeTime
@ stdcall GetSecurityDescriptorControl(ptr ptr ptr) advapi32.GetSecurityDescriptorControl
diff --git a/include/winbase.h b/include/winbase.h
index 4d959d0da6..de52e5a55b 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -565,6 +565,13 @@ typedef struct _OVERLAPPED {
HANDLE hEvent;
} OVERLAPPED, *LPOVERLAPPED;
+typedef struct _OVERLAPPED_ENTRY {
+ ULONG_PTR lpCompletionKey;
+ LPOVERLAPPED lpOverlapped;
+ ULONG_PTR Internal;
+ DWORD dwNumberOfBytesTransferred;
+} OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY;
+
typedef VOID (CALLBACK *LPOVERLAPPED_COMPLETION_ROUTINE)(DWORD,DWORD,LPOVERLAPPED);
/* Process startup information.
--
2.19.0
Sept. 23, 2018
Re: [PATCH] find: First simple implementation and tests
by Fabian Maurer
For some reason it cut off my mail...
I tried using ReadConsoleW to make things easier, but that doesn't work with
redirected console handles. So I have to do it with ReadFile. I also planned to use that
function to read from an handle for reading line-by-line from files, too.
reg uses GetConsoleOutputCP, which would break the tests
I wrote for find - so I can't really use that either.
Question is, is mine still a bad approach, what'd you suggest?
Regards,
Fabian Maurer
Sept. 23, 2018
Re: [PATCH] find: First simple implementation and tests
by Fabian Maurer
reg uses GetConsoleOutputCP, which would break the tests
I wrote for find.
Which solution would you use?
Regards,
Fabian Maurer
Sept. 23, 2018
[PATCH 4/4] quartz/filtergraph: Improve HRESULT propagation from IFilterGraph2_Connect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/filtergraph.c | 15 +++++++++---
dlls/quartz/tests/filtergraph.c | 51 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 0468cb5..7148990 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -1181,8 +1181,17 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
/* Try direct connection first */
hr = IPin_Connect(ppinOut, ppinIn, NULL);
- if (SUCCEEDED(hr))
- goto out;
+
+ /* If direct connection succeeded, we should propagate that return value.
+ * If it returned VFW_E_NOT_CONNECTED or VFW_E_NO_AUDIO_HARDWARE, then don't
+ * even bother trying intermediate filters, since they won't succeed. */
+ if (SUCCEEDED(hr) || hr == VFW_E_NOT_CONNECTED || hr == VFW_E_NO_AUDIO_HARDWARE)
+ {
+ --This->recursioncount;
+ LeaveCriticalSection(&This->cs);
+ TRACE("--> %#x\n", hr);
+ return hr;
+ }
TRACE("Direct connection failed, trying to render using extra filters\n");
@@ -1391,7 +1400,7 @@ out:
--This->recursioncount;
LeaveCriticalSection(&This->cs);
TRACE("--> %08x\n", hr);
- return SUCCEEDED(hr) ? S_OK : hr;
+ return SUCCEEDED(hr) ? S_OK : VFW_E_CANNOT_CONNECT;
}
/* Render all output pins of the given filter. Helper for FilterGraph2_Render(). */
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index 6c8b9fa..b40145a 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -609,7 +609,6 @@ static void test_render_run(const WCHAR *file)
ok(!refs, "Graph has %u references\n", refs);
hr = test_graph_builder_connect_file(filename);
-todo_wine
ok(hr == VFW_E_CANNOT_CONNECT, "got %#x\n", hr);
}
else
@@ -776,6 +775,7 @@ struct testpin
unsigned int type_count, enum_idx;
AM_MEDIA_TYPE *request_mt, *accept_mt;
+ HRESULT Connect_hr;
HRESULT QueryInternalConnections_hr;
};
@@ -1063,6 +1063,7 @@ static void testpin_init(struct testpin *pin, const IPinVtbl *vtbl, PIN_DIRECTIO
pin->IEnumMediaTypes_iface.lpVtbl = &testenummt_vtbl;
pin->ref = 1;
pin->dir = dir;
+ pin->Connect_hr = S_OK;
pin->QueryInternalConnections_hr = E_NOTIMPL;
}
@@ -1077,12 +1078,16 @@ static HRESULT WINAPI testsource_Connect(IPin *iface, IPin *peer, const AM_MEDIA
HRESULT hr;
if (winetest_debug > 1) trace("%p->Connect(%p)\n", pin, peer);
+ if (FAILED(pin->Connect_hr))
+ return pin->Connect_hr;
+
ok(!mt, "Got media type %p.\n", mt);
if (SUCCEEDED(hr = IPin_ReceiveConnection(peer, &pin->IPin_iface, pin->request_mt)))
{
pin->peer = peer;
IPin_AddRef(peer);
+ return pin->Connect_hr;
}
return hr;
}
@@ -1711,12 +1716,39 @@ static void test_graph_builder_connect(void)
IFilterGraph2_Disconnect(graph, source_pin.peer);
IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
+ for (source_pin.Connect_hr = 0x00040200; source_pin.Connect_hr <= 0x000402ff;
+ ++source_pin.Connect_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ ok(hr == source_pin.Connect_hr, "Got hr %#x for Connect() hr %#x.\n",
+ hr, source_pin.Connect_hr);
+ ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
+ IFilterGraph2_Disconnect(graph, source_pin.peer);
+ IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
+ }
+ source_pin.Connect_hr = S_OK;
+
sink_pin.accept_mt = &sink_type;
hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
-todo_wine
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
+ for (source_pin.Connect_hr = 0x80040200; source_pin.Connect_hr <= 0x800402ff;
+ ++source_pin.Connect_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ if (source_pin.Connect_hr == VFW_E_NOT_CONNECTED
+ || source_pin.Connect_hr == VFW_E_NO_AUDIO_HARDWARE)
+ ok(hr == source_pin.Connect_hr, "Got hr %#x for Connect() hr %#x.\n",
+ hr, source_pin.Connect_hr);
+ else
+ ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x for Connect() hr %#x.\n",
+ hr, source_pin.Connect_hr);
+ ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
+ ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
+ }
+ source_pin.Connect_hr = S_OK;
+
/* Test usage of intermediate filters. Similarly to Render(), filters are
* simply tried in enumeration order. */
@@ -1740,6 +1772,20 @@ todo_wine
IFilterGraph2_Disconnect(graph, sink_pin.peer);
IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
+ for (source_pin.Connect_hr = 0x00040200; source_pin.Connect_hr <= 0x000402ff;
+ ++source_pin.Connect_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ ok(hr == S_OK, "Got hr %#x for Connect() hr %#x.\n", hr, source_pin.Connect_hr);
+ ok(source_pin.peer == &parser2_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
+ ok(sink_pin.peer == &parser2_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
+ IFilterGraph2_Disconnect(graph, source_pin.peer);
+ IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
+ IFilterGraph2_Disconnect(graph, sink_pin.peer);
+ IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
+ }
+ source_pin.Connect_hr = S_OK;
+
IFilterGraph2_RemoveFilter(graph, &parser1.IBaseFilter_iface);
IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
@@ -1805,7 +1851,6 @@ todo_wine
parser1_pins[1].name[0] = '~';
hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
-todo_wine
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
--
2.7.4
Sept. 23, 2018
[PATCH 3/4] devenum: Only scan for devices for the requested filter category.
by Zebediah Figura
This matches native behaviour, and greatly reduces the overhead of
IFilterMapper2_EnumMatchingFilters().
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/createdevenum.c | 70 ++++++++++++++++++--------------------------
1 file changed, 28 insertions(+), 42 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index fa096be..9b7ee3f 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -53,7 +53,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 void register_codecs(void);
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
/**********************************************************************
@@ -828,31 +827,42 @@ static void register_avicap_devices(void)
* 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();
- register_avicap_devices();
+ 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();
+
+ return create_EnumMoniker(class, out);
}
/**********************************************************************
@@ -902,27 +912,3 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
return res;
}
-
-static void register_codecs(void)
-{
- WCHAR class[CHARS_IN_GUID];
- 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);
-}
--
2.7.4
Sept. 23, 2018
[PATCH 2/4] devenum: Register AVI capture devices as codec devices.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/createdevenum.c | 139 +++++++++++++++++--------------------------
1 file changed, 54 insertions(+), 85 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index ad1022e..fa096be 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -53,7 +53,7 @@ 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 void register_codecs(void);
static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory);
/**********************************************************************
@@ -773,6 +773,57 @@ static void register_vfw_codecs(void)
}
}
+static void register_avicap_devices(void)
+{
+ static const WCHAR vfwindexW[] = {'V','F','W','I','n','d','e','x',0};
+ WCHAR friendlyname[] = {'v','i','d','e','o','0',0};
+ IPropertyBag *prop_bag = NULL;
+ WCHAR name[32], version[32];
+ REGFILTERPINS2 rgpins;
+ 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, name, sizeof(name), version, sizeof(version)))
+ break;
+
+ friendlyname[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);
+ }
+}
+
/**********************************************************************
* DEVENUM_ICreateDevEnum_CreateClassEnumerator
*/
@@ -799,6 +850,7 @@ static HRESULT WINAPI DEVENUM_ICreateDevEnum_CreateClassEnumerator(
register_wavein_devices();
register_midiout_devices();
register_vfw_codecs();
+ register_avicap_devices();
return create_EnumMoniker(clsidDeviceClass, ppEnumMoniker);
}
@@ -851,14 +903,9 @@ static HRESULT DEVENUM_CreateAMCategoryKey(const CLSID * clsidCategory)
return res;
}
-static HRESULT register_codecs(void)
+static void 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
@@ -878,82 +925,4 @@ static HRESULT register_codecs(void)
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 (i, szDeviceName, ARRAY_SIZE(szDeviceName),
- szDeviceVersion, ARRAY_SIZE(szDeviceVersion)))
- {
- IMoniker * pMoniker = NULL;
- WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 };
- snprintfW(szDevicePath, ARRAY_SIZE(szDevicePath), 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;
}
--
2.7.4
Sept. 23, 2018
[PATCH 1/4] devenum: Factor friendly name and CLSID registration into register_codec().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/createdevenum.c | 307 ++++++++++++++-----------------------------
1 file changed, 98 insertions(+), 209 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index 8fbf323..ad1022e 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -104,11 +104,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;
@@ -128,10 +133,36 @@ static HRESULT register_codec(const CLSID *class, const WCHAR *name, IMoniker **
strcatW(buffer, backslashW);
strcatW(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)
@@ -412,15 +443,18 @@ static void register_legacy_filters(void)
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));
+ hr = CLSIDFromString(wszFilterSubkeyName, &clsid);
+ if (FAILED(hr))
+ continue;
+
strcpyW(wszRegKey, clsidW);
strcatW(wszRegKey, backslashW);
strcatW(wszRegKey, wszFilterSubkeyName);
@@ -428,40 +462,30 @@ static void register_legacy_filters(void)
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
continue;
- hr = register_codec(&CLSID_LegacyAmFilterCategory, wszFilterSubkeyName, &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 */
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, clsidW, &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;
@@ -473,11 +497,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);
}
}
@@ -495,50 +516,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));
if (!name)
- goto cleanup;
+ return FALSE;
strcpyW(name, directsoundW);
strcatW(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, clsidW, &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;
@@ -557,16 +558,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;
}
@@ -578,9 +574,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;
@@ -594,34 +589,12 @@ static void register_waveout_devices(void)
{
waveOutGetDevCapsW(i, &caps, sizeof(caps));
- V_VT(&var) = VT_BSTR;
+ name = (i == -1) ? defaultW : caps.szPname;
- if (i == -1) /* WAVE_MAPPER */
- V_BSTR(&var) = SysAllocString(defaultW);
- else
- V_BSTR(&var) = SysAllocString(caps.szPname);
- 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_AudioRender, clsid, CHARS_IN_GUID);
- if (!(V_BSTR(&var) = SysAllocString(clsid)))
- goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsidW, &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;
@@ -639,13 +612,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);
}
}
@@ -654,8 +624,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;
@@ -670,31 +638,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, clsidW, &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;
@@ -705,13 +652,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);
}
}
@@ -723,9 +667,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;
@@ -739,34 +682,12 @@ static void register_midiout_devices(void)
{
midiOutGetDevCapsW(i, &caps, sizeof(caps));
- V_VT(&var) = VT_BSTR;
+ name = (i == -1) ? defaultW : caps.szPname;
- if (i == -1) /* MIDI_MAPPER */
- V_BSTR(&var) = SysAllocString(defaultW);
- else
- V_BSTR(&var) = SysAllocString(caps.szPname);
- if (!(V_BSTR(&var)))
- goto cleanup;
-
- 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, clsidW, &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;
@@ -784,13 +705,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);
}
}
@@ -801,8 +719,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;
@@ -822,40 +738,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, clsidW, &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;
@@ -877,10 +763,13 @@ 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);
}
}
--
2.7.4
Sept. 23, 2018