From e669113b1319ba08847a05dcdf578b801ef59db1 Mon Sep 17 00:00:00 2001 From: winesync Date: Thu, 4 Jan 2024 12:57:41 +0100 Subject: [PATCH] [WINESYNC] setupapi: Add support for creating registry symlinks from a .inf file. wine commit id f6b3dba7a08a718f633804da508e4586ae72e6f5 by Alexandre Julliard SYNC NOTE: This is Wine-specific functionality, placed in __WINESRC__ REG_LINK is _NOT_ supported by (official) Windows INF AddReg section. See the WDK ChkInf.pm tool (from Win2003 up to Win10), for example at: https://github.com/skycipher/CNGProvider/blob/master/Windows%20Kits/10/Tools/x86/ChkInf/chkinf.pm#L3870 --- dll/win32/setupapi/install.c | 39 +++++++++++++++++++++++++-------- sdk/tools/winesync/setupapi.cfg | 2 +- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/dll/win32/setupapi/install.c b/dll/win32/setupapi/install.c index c1dd8fb413e..cddbfb9780b 100644 --- a/dll/win32/setupapi/install.c +++ b/dll/win32/setupapi/install.c @@ -381,6 +381,9 @@ static BOOL do_reg_operation( HKEY hkey, const WCHAR *value, INFCONTEXT *context { if (!(str = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ))) return FALSE; SetupGetStringFieldW( context, 5, str, size, NULL ); +#ifdef __WINESRC__ + if (type == REG_LINK) size--; /* no terminating null for symlinks */ +#endif } } @@ -476,6 +479,7 @@ static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg ) for (; ok; ok = SetupFindNextLine( &context, &context )) { + DWORD options = 0; WCHAR buffer[MAX_INF_STRING_LENGTH]; INT flags; @@ -501,20 +505,37 @@ static BOOL registry_callback( HINF hinf, PCWSTR field, void *arg ) if (!flags) flags = FLG_ADDREG_DELREG_BIT; else if (!(flags & FLG_ADDREG_DELREG_BIT)) continue; /* ignore this entry */ } +#ifdef __WINESRC__ + /* Wine extension: magic support for symlinks */ + if (flags >> 16 == REG_LINK) options = REG_OPTION_OPEN_LINK | REG_OPTION_CREATE_LINK; +#endif if (info->delete || (flags & FLG_ADDREG_OVERWRITEONLY)) { - if (RegOpenKeyW( root_key, buffer, &hkey )) continue; /* ignore if it doesn't exist */ + if (RegOpenKeyExW( root_key, buffer, options, MAXIMUM_ALLOWED, &hkey )) + continue; /* ignore if it doesn't exist */ } -#ifdef __REACTOS__ - else if (RegCreateKeyExW( root_key, buffer, 0, NULL, 0, MAXIMUM_ALLOWED, - sd ? &security_attributes : NULL, &hkey, NULL )) -#else - else if (RegCreateKeyW( root_key, buffer, &hkey )) -#endif + else { - ERR( "could not create key %p %s\n", root_key, debugstr_w(buffer) ); - continue; +#ifdef __REACTOS__ + DWORD res = RegCreateKeyExW( root_key, buffer, 0, NULL, options, + MAXIMUM_ALLOWED, + sd ? &security_attributes : NULL, + &hkey, NULL ); +#else + DWORD res = RegCreateKeyExW( root_key, buffer, 0, NULL, options, + MAXIMUM_ALLOWED, NULL, &hkey, NULL ); +#endif +#ifdef __WINESRC__ + if (res == ERROR_ALREADY_EXISTS && (options & REG_OPTION_CREATE_LINK)) + res = RegCreateKeyExW( root_key, buffer, 0, NULL, REG_OPTION_OPEN_LINK, + MAXIMUM_ALLOWED, NULL, &hkey, NULL ); +#endif + if (res) + { + ERR( "could not create key %p %s\n", root_key, debugstr_w(buffer) ); + continue; + } } TRACE( "key %p %s\n", root_key, debugstr_w(buffer) ); diff --git a/sdk/tools/winesync/setupapi.cfg b/sdk/tools/winesync/setupapi.cfg index 25040483614..6ba046c61ad 100644 --- a/sdk/tools/winesync/setupapi.cfg +++ b/sdk/tools/winesync/setupapi.cfg @@ -5,4 +5,4 @@ files: dlls/setupapi/misc.c: dll/win32/setupapi/misc.c dlls/setupapi/stubs.c: dll/win32/setupapi/stubs.c tags: - wine: c7d4b0c69fb8de9a2344c7d9d4bcda6e3feef094 + wine: f6b3dba7a08a718f633804da508e4586ae72e6f5