<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <br>
    <br>
    <div class="moz-cite-prefix">On 11/25/21 09:34, Jacek Caban wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:3de0b4fb-c4d9-57e4-764a-cc9518e3a8d6@codeweavers.com">Signed-off-by:
      Jacek Caban <a class="moz-txt-link-rfc2396E" href="mailto:jacek@codeweavers.com"><jacek@codeweavers.com></a>
      <br>
      ---
      <br>
       dlls/win32u/font.c      |  4 ++-
      <br>
       dlls/win32u/sysparams.c | 71
      ++++++++++++++++++++++++++++++++++++++++-
      <br>
       2 files changed, 73 insertions(+), 2 deletions(-)
      <br>
      <br>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"><legend
          class="mimeAttachmentHeaderName">0004-win32u-Implement-display-adapter-registration.txt</legend></fieldset>
      <pre class="moz-quote-pre" wrap="">diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
index 1f284d775f4..40467bb82f5 100644
--- a/dlls/win32u/font.c
+++ b/dlls/win32u/font.c
@@ -584,9 +584,11 @@ HKEY reg_create_key( HKEY root, const WCHAR *name, ULONG name_len,
         if (i == len) return 0;
         for (;;)
         {
+            unsigned int subkey_options = options;
+            if (i < len) subkey_options &= ~(REG_OPTION_CREATE_LINK | REG_OPTION_OPEN_LINK);
             nameW.Buffer = (WCHAR *)name + pos;
             nameW.Length = (i - pos) * sizeof(WCHAR);
-            status = NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, options, disposition );
+            status = NtCreateKey( &ret, MAXIMUM_ALLOWED, &attr, 0, NULL, subkey_options, disposition );
 
             if (attr.RootDirectory != root) NtClose( attr.RootDirectory );
             if (!NT_SUCCESS(status)) return 0;
diff --git a/dlls/win32u/sysparams.c b/dlls/win32u/sysparams.c
index d5368e96d47..e2e123e1fb1 100644
--- a/dlls/win32u/sysparams.c
+++ b/dlls/win32u/sysparams.c
@@ -125,6 +125,8 @@ static const WCHAR controlW[] = {'C','o','n','t','r','o','l'};
 static const WCHAR device_parametersW[] =
     {'D','e','v','i','c','e',' ','P','a','r','a','m','e','t','e','r','s'};
 static const WCHAR linkedW[] = {'L','i','n','k','e','d',0};
+static const WCHAR symbolic_link_valueW[] =
+    {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0};
 static const WCHAR state_flagsW[] = {'S','t','a','t','e','F','l','a','g','s',0};
 static const WCHAR gpu_idW[] = {'G','P','U','I','D',0};
 static const WCHAR hardware_idW[] = {'H','a','r','d','w','a','r','e','I','D',0};
@@ -791,7 +793,74 @@ static void add_gpu( const struct gdi_gpu *gpu, void *param )
 
 static void add_adapter( const struct gdi_adapter *adapter, void *param )
 {
-    FIXME( "\n" );
+    struct device_manager_ctx *ctx = param;
+    unsigned int adapter_index, video_index, len;
+    char name[64], buffer[MAX_PATH];
+    WCHAR nameW[64], bufferW[MAX_PATH];
+    HKEY hkey;
+
+    TRACE( "\n" );
+
+    if (!ctx->gpu_count)
+    {
+        static const struct gdi_gpu default_gpu;</pre>
    </blockquote>
    <br>
    Maybe a name for the GPU at least?<br>
    <br>
    <blockquote type="cite"
      cite="mid:3de0b4fb-c4d9-57e4-764a-cc9518e3a8d6@codeweavers.com">
      <pre class="moz-quote-pre" wrap="">
+        TRACE( "adding default fake GPU\n" );
+        add_gpu( &default_gpu, ctx );
+    }
+
+    if (ctx->adapter_key)
+    {
+        NtClose( ctx->adapter_key );
+        ctx->adapter_key = NULL;
+    }
+
+    adapter_index = ctx->adapter_count++;
+    video_index = ctx->video_count++;
+    ctx->monitor_count = 0;</pre>
    </blockquote>
    <br>
    This is making DeviceID and DeviceKey for monitors wrong. For
    example, a system with two monitors attached and active produces the
    following results with the attached test program.<br>
    <br>
    master:src/wine$ wine
    ~/Dropbox/Stage/EnumAdapters/Release/EnumAdapters.exe<br>
    #0<br>
    DeviceName: \\.\DISPLAY1<br>
    DeviceString: NVIDIA GeForce GTX 1650 SUPER<br>
    StateFlags: 0x5 DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
    DISPLAY_DEVICE_PRIMARY_DEVICE<br>
    DeviceID: PCI\VEN_10DE&DEV_2187&SUBSYS_00000000&REV_00<br>
    DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Video\{b27a3cb2-1986-4fa0-9233-a457231397dc}\0000<br>
    <br>
            #0<br>
            DeviceName: \\.\DISPLAY1\Monitor0<br>
            DeviceString: Generic Non-PnP Monitor<br>
            StateFlags: 0x3 DISPLAY_DEVICE_ACTIVE
    DISPLAY_DEVICE_ATTACHED<br>
            DeviceID:
    MONITOR\Default_Monitor\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000<br>
            DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Class\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000<br>
    <br>
    #1<br>
    DeviceName: \\.\DISPLAY2<br>
    DeviceString: NVIDIA GeForce GTX 1650 SUPER<br>
    StateFlags: 0x1 DISPLAY_DEVICE_ATTACHED_TO_DESKTOP<br>
    DeviceID: PCI\VEN_10DE&DEV_2187&SUBSYS_00000000&REV_00<br>
    DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Video\{b27a3cb2-1986-4fa0-9233-a457231397dc}\0001<br>
    <br>
            #0<br>
            DeviceName: \\.\DISPLAY2\Monitor0<br>
            DeviceString: Generic Non-PnP Monitor<br>
            StateFlags: 0x3 DISPLAY_DEVICE_ACTIVE
    DISPLAY_DEVICE_ATTACHED<br>
            DeviceID:
    MONITOR\Default_Monitor\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0001<br>
            DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Class\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0001<br>
    <br>
    <br>
    After this patch series.<br>
    <br>
    #0<br>
    DeviceName: \\.\DISPLAY1<br>
    DeviceString: NVIDIA GeForce GTX 1650 SUPER<br>
    StateFlags: 0x5 DISPLAY_DEVICE_ATTACHED_TO_DESKTOP
    DISPLAY_DEVICE_PRIMARY_DEVICE<br>
    DeviceID: PCI\VEN_10DE&DEV_2187&SUBSYS_00000000&REV_00<br>
    DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Video\{b27a3cb2-1986-4fa0-9233-a457231397dc}\0000<br>
    <br>
            #0<br>
            DeviceName: \\.\DISPLAY1\Monitor0<br>
            DeviceString: Generic Non-PnP Monitor<br>
            StateFlags: 0x3 DISPLAY_DEVICE_ACTIVE
    DISPLAY_DEVICE_ATTACHED<br>
            DeviceID:
    MONITOR\Default_Monitor\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000<br>
            DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Class\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000<br>
    <br>
    #1<br>
    DeviceName: \\.\DISPLAY2<br>
    DeviceString: NVIDIA GeForce GTX 1650 SUPER<br>
    StateFlags: 0x1 DISPLAY_DEVICE_ATTACHED_TO_DESKTOP<br>
    DeviceID: PCI\VEN_10DE&DEV_2187&SUBSYS_00000000&REV_00<br>
    DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Video\{b27a3cb2-1986-4fa0-9233-a457231397dc}\0001<br>
    <br>
            #0<br>
            DeviceName: \\.\DISPLAY2\Monitor0<br>
            DeviceString: Generic Non-PnP Monitor<br>
            StateFlags: 0x3 DISPLAY_DEVICE_ACTIVE
    DISPLAY_DEVICE_ATTACHED<br>
            DeviceID:
    MONITOR\Default_Monitor\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000<br>
            DeviceKey:
\Registry\Machine\System\CurrentControlSet\Control\Class\{4D36E96E-E325-11CE-BFC1-08002BE10318}\0000<br>
    <br>
    Notice that the DeviceID and DeviceKey for both monitors are now
    having 0000 at the end.<br>
    <br>
    I put the test program in the attachment. It can be built with
    Visual Studio Community 2019 and I didn't bother to create makefile
    for it.<br>
    <br>
    <blockquote type="cite"
      cite="mid:3de0b4fb-c4d9-57e4-764a-cc9518e3a8d6@codeweavers.com">
      <pre class="moz-quote-pre" wrap="">
+
+    if (!video_key && !(video_key = reg_create_key( NULL, devicemap_video_keyW, sizeof(devicemap_video_keyW),
+                                                    REG_OPTION_VOLATILE, NULL )))
+        return;
+
+    len = asciiz_to_unicode( bufferW, "\\Registry\\Machine\\System\\CurrentControlSet\\"
+                             "Control\\Video\\" ) / sizeof(WCHAR) - 1;
+    lstrcpyW( bufferW + len, ctx->gpu_guid );
+    len += lstrlenW( bufferW + len );
+    sprintf( buffer, "\\%04x", adapter_index );
+    len += asciiz_to_unicode( bufferW + len, buffer ) / sizeof(WCHAR) - 1;
+    hkey = reg_create_key( NULL, bufferW, len * sizeof(WCHAR),
+                          REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK, NULL );
+    if (!hkey) hkey = reg_create_key( NULL, bufferW, len * sizeof(WCHAR),
+                                     REG_OPTION_VOLATILE | REG_OPTION_OPEN_LINK, NULL );
+
+    sprintf( name, "\\Device\\Video%u", video_index );
+    asciiz_to_unicode( nameW, name );
+    set_reg_value( video_key, nameW, REG_SZ, bufferW, (lstrlenW( bufferW ) + 1) * sizeof(WCHAR) );
+
+    if (hkey)
+    {
+        sprintf( buffer, "\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
+                 "%s\\%04X", guid_devclass_displayA, ctx->gpu_count - 1 );
+        len = asciiz_to_unicode( bufferW, buffer ) - sizeof(WCHAR);
+        set_reg_value( hkey, symbolic_link_valueW, REG_LINK, bufferW, len );
+        NtClose( hkey );
+    }
+    else ERR( "failed to create link key\n" );
+
+    /* Following information is Wine specific, it doesn't really exist on Windows. */
+    len = asciiz_to_unicode( bufferW, "System\\CurrentControlSet\\Control\\Video\\" )
+        / sizeof(WCHAR) - 1;
+    lstrcpyW( bufferW + len, ctx->gpu_guid );
+    len += lstrlenW( bufferW + len );
+    sprintf( buffer, "\\%04x", adapter_index );
+    len += asciiz_to_unicode( bufferW + len, buffer ) / sizeof(WCHAR) - 1;
+    ctx->adapter_key = reg_create_key( config_key, bufferW, len * sizeof(WCHAR),
+                                       REG_OPTION_VOLATILE, NULL );
+
+    set_reg_value( ctx->adapter_key, gpu_idW, REG_SZ, ctx->gpuid,
+                   (lstrlenW( ctx->gpuid ) + 1) * sizeof(WCHAR) );
+    set_reg_value( ctx->adapter_key, state_flagsW, REG_DWORD, &adapter->state_flags,
+                   sizeof(adapter->state_flags) );
 }
 
 static void add_monitor( const struct gdi_monitor *monitor, void *param )

</pre>
    </blockquote>
    <br>
  </body>
</html>