From f173066520e724b2a6b80f0097b6df715db899aa Mon Sep 17 00:00:00 2001
From: Daniel Wendt <daniel.wendt@linux.com>
Date: Mon, 3 Dec 2018 14:33:44 +0100
Subject: [PATCH] explorer: unload graphics driver and delete registry
 keys

Registry keys are no longer used after the driver has been unloaded.

The string constant is divided and set globally so that the created
key and folder can be completely removed from the registry.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46233
---
 programs/explorer/desktop.c | 76 ++++++++++++++++++++++++++++++++-----
 1 file changed, 66 insertions(+), 10 deletions(-)

diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index 27b9b24901..029afd74cc 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -773,16 +773,18 @@ static BOOL get_default_enable_shell( const WCHAR *name )
     return result;
 }
 
+static const WCHAR device_keyW[] = {
+    'S','y','s','t','e','m','\\',
+    'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
+    'C','o','n','t','r','o','l','\\',
+    'V','i','d','e','o','\\',
+    '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
+    '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x',
+    '%','0','2','x','%','0','2','x','%','0','2','x','}',0};
+static const WCHAR device_subkeyW[] = {'\\','0','0','0','0',0};
+
 static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
 {
-    static const WCHAR device_keyW[] = {
-        'S','y','s','t','e','m','\\',
-        'C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
-        'C','o','n','t','r','o','l','\\',
-        'V','i','d','e','o','\\',
-        '{','%','0','8','x','-','%','0','4','x','-','%','0','4','x','-',
-        '%','0','2','x','%','0','2','x','-','%','0','2','x','%','0','2','x','%','0','2','x',
-        '%','0','2','x','%','0','2','x','%','0','2','x','}','\\','0','0','0','0',0};
     static const WCHAR graphics_driverW[] = {'G','r','a','p','h','i','c','s','D','r','i','v','e','r',0};
     static const WCHAR driversW[] = {'S','o','f','t','w','a','r','e','\\',
                                      'W','i','n','e','\\','D','r','i','v','e','r','s',0};
@@ -790,7 +792,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
     static const WCHAR drv_formatW[] = {'w','i','n','e','%','s','.','d','r','v',0};
 
     WCHAR buffer[MAX_PATH], libname[32], *name, *next;
-    WCHAR key[ARRAY_SIZE( device_keyW ) + 39];
+    WCHAR key[ARRAY_SIZE( device_keyW ) + ARRAY_SIZE( device_subkeyW ) + 39];
     HMODULE module = 0;
     HKEY hkey;
     char error[80];
@@ -841,7 +843,7 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
     sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3,
               guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
               guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
-
+    strcatW( key, device_subkeyW );
     if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, key, 0, NULL,
                           REG_OPTION_VOLATILE, KEY_SET_VALUE, NULL, &hkey, NULL  ))
     {
@@ -856,6 +858,59 @@ static HMODULE load_graphics_driver( const WCHAR *driver, const GUID *guid )
     return module;
 }
 
+static void unload_graphics_driver( HMODULE graphics_driver, const GUID *guid )
+{
+    HKEY hkey;
+    LONG reg_ret;
+    WCHAR key[ARRAY_SIZE( device_keyW ) + ARRAY_SIZE( device_subkeyW ) + 39];
+
+    if(graphics_driver)
+    {
+        if (!FreeLibrary( graphics_driver ))
+        switch (GetLastError())
+        {
+        default:
+            WINE_ERR("Could not unload graphics driver: Unknown error (%u).\n", GetLastError());
+            break;
+        }
+    }
+
+    sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3,
+          guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+          guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
+
+    strcatW( key, device_subkeyW);
+    reg_ret = RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey );
+    if (reg_ret == ERROR_SUCCESS)
+    {
+        RegDeleteKeyW( HKEY_LOCAL_MACHINE, key );
+        RegCloseKey( hkey );
+    }
+    reg_ret = RegOpenKeyW( HKEY_CURRENT_CONFIG, key, &hkey );
+    if (reg_ret == ERROR_SUCCESS)
+    {
+        RegDeleteKeyW( HKEY_CURRENT_CONFIG, key );
+        RegCloseKey( hkey );
+    }
+
+    sprintfW( key, device_keyW, guid->Data1, guid->Data2, guid->Data3,
+          guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
+          guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7] );
+
+    reg_ret = RegOpenKeyW( HKEY_LOCAL_MACHINE, key, &hkey );
+    if (reg_ret == ERROR_SUCCESS)
+    {
+        RegDeleteKeyW( HKEY_LOCAL_MACHINE, key );
+        RegCloseKey( hkey );
+    }
+    reg_ret = RegOpenKeyW( HKEY_CURRENT_CONFIG, key, &hkey );
+    if (reg_ret == ERROR_SUCCESS)
+    {
+        RegDeleteKeyW( HKEY_CURRENT_CONFIG, key );
+        RegCloseKey( hkey );
+    }
+}
+
 static void initialize_display_settings(void)
 {
     DEVMODEW dmW;
@@ -1036,6 +1091,7 @@ void manage_desktop( WCHAR *arg )
     }
 
     if (pShellDDEInit) pShellDDEInit( FALSE );
+    unload_graphics_driver(graphics_driver, &guid);
 
     ExitProcess( 0 );
 }
-- 
2.19.2

