We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Problem with user directories when sandboxing is disabled
Hi, i have strange problem in recent version. I have disabled wineprefix sandboxing, so my user directories were configured as symlinks. But in recent version programs (or even wine config) do not start with error:

Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/lutris/runners/wine.py", line 676, in run_winecfg
    self.prelaunch()
  File "/usr/lib/python3.7/site-packages/lutris/runners/wine.py", line 778, in prelaunch
    self.sandbox(prefix_manager)
  File "/usr/lib/python3.7/site-packages/lutris/runners/wine.py", line 926, in sandbox
    wine_prefix.desktop_integration(restore=True)
  File "/usr/lib/python3.7/site-packages/lutris/util/wine/prefix.py", line 132, in desktop_integration
    os.rename(old_path, path)
NotADirectoryError: [Errno 20] není adresářem: '/home/petr/.local/share/lutris/runners/winegames/drive_c/users/petr/Plocha.winecfg' -> '/home/petr/.local/share/lutris/runners/winegames/drive_c/users/petr/Plocha'

which is true, because "Plocha" is symlink to proper Desktop directory. When i delete "Plocha.winecfg", same error moves to next user directory "Mé dokumenty" (Documents). When i delete all "winecfg" files, all symlinks to existing user directories are replaced by empty directories. I.e. i am not able to run programs linked to standard user directories despite sandboxing is disabled.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lutris/util/wine/prefix.py`
Content:
```
1 """Wine prefix management"""
2 import os
3 from lutris.util.wine.registry import WineRegistry
4 from lutris.util.log import logger
5 from lutris.util import joypad, system, xdgshortcuts
6 from lutris.util.display import DISPLAY_MANAGER
7 
8 DESKTOP_KEYS = ["Desktop", "Personal", "My Music", "My Videos", "My Pictures"]
9 DEFAULT_DESKTOP_FOLDERS = ["Desktop", "My Documents", "My Music", "My Videos", "My Pictures"]
10 DESKTOP_XDG = ["DESKTOP", "DOCUMENTS", "MUSIC", "VIDEOS", "PICTURES"]
11 
12 
13 class WinePrefixManager:
14     """Class to allow modification of Wine prefixes without the use of Wine"""
15 
16     hkcu_prefix = "HKEY_CURRENT_USER"
17 
18     def __init__(self, path):
19         if not path:
20             logger.warning("No path specified for Wine prefix")
21         self.path = path
22 
23     def setup_defaults(self):
24         """Sets the defaults for newly created prefixes"""
25         self.override_dll("winemenubuilder.exe", "")
26         try:
27             self.desktop_integration()
28         except OSError as ex:
29             logger.error(
30                 "Failed to setup desktop integration, the prefix may not be valid."
31             )
32             logger.exception(ex)
33 
34     def get_registry_path(self, key):
35         """Matches registry keys to a registry file
36 
37         Currently, only HKEY_CURRENT_USER keys are supported.
38         """
39         if key.startswith(self.hkcu_prefix):
40             return os.path.join(self.path, "user.reg")
41         raise ValueError("Unsupported key '{}'".format(key))
42 
43     def get_key_path(self, key):
44         if key.startswith(self.hkcu_prefix):
45             return key[len(self.hkcu_prefix) + 1:]
46         raise ValueError(
47             "The key {} is currently not supported by WinePrefixManager".format(key)
48         )
49 
50     def get_registry_key(self, key, subkey):
51         registry = WineRegistry(self.get_registry_path(key))
52         return registry.query(self.get_key_path(key), subkey)
53 
54     def set_registry_key(self, key, subkey, value):
55         registry = WineRegistry(self.get_registry_path(key))
56         registry.set_value(self.get_key_path(key), subkey, value)
57         registry.save()
58 
59     def clear_registry_key(self, key):
60         registry = WineRegistry(self.get_registry_path(key))
61         registry.clear_key(self.get_key_path(key))
62         registry.save()
63 
64     def clear_registry_subkeys(self, key, subkeys):
65         registry = WineRegistry(self.get_registry_path(key))
66         registry.clear_subkeys(self.get_key_path(key), subkeys)
67         registry.save()
68 
69     def override_dll(self, dll, mode):
70         key = self.hkcu_prefix + "/Software/Wine/DllOverrides"
71         if mode.startswith("dis"):
72             mode = ""
73         if mode not in ("builtin", "native", "builtin,native", "native,builtin", ""):
74             logger.error("DLL override '%s' mode is not valid", mode)
75             return
76         self.set_registry_key(key, dll, mode)
77 
78     def get_desktop_folders(self):
79         """Return the list of desktop folder names loaded from the Windows registry"""
80         desktop_folders = []
81         for key in DESKTOP_KEYS:
82             folder = self.get_registry_key(
83                 self.hkcu_prefix
84                 + "/Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders",
85                 key,
86             )
87             if not folder:
88                 logger.warning("Couldn't load shell folder name for %s", key)
89                 continue
90             desktop_folders.append(folder[folder.rfind("\\") + 1:])
91         return desktop_folders or DEFAULT_DESKTOP_FOLDERS
92 
93     def desktop_integration(self, desktop_dir=None, restore=False):
94         """Overwrite desktop integration"""
95         user = os.getenv("USER")
96         user_dir = os.path.join(self.path, "drive_c/users/", user)
97         desktop_folders = self.get_desktop_folders()
98 
99         if desktop_dir:
100             desktop_dir = os.path.expanduser(desktop_dir)
101         else:
102             desktop_dir = user_dir
103 
104         if system.path_exists(user_dir):
105             # Replace or restore desktop integration symlinks
106             for i, item in enumerate(desktop_folders):
107                 path = os.path.join(user_dir, item)
108                 old_path = path + ".winecfg"
109 
110                 if os.path.islink(path):
111                     if not restore:
112                         os.unlink(path)
113                 elif os.path.isdir(path):
114                     try:
115                         os.rmdir(path)
116                     # We can't delete nonempty dir, so we rename as wine do.
117                     except OSError:
118                         os.rename(path, old_path)
119 
120                 if restore and not os.path.isdir(path):
121                     os.symlink(xdgshortcuts.get_xdg_entry(DESKTOP_XDG[i]), path)
122                     # We don't need all the others process of the loop
123                     continue
124 
125                 if desktop_dir != user_dir:
126                     try:
127                         src_path = os.path.join(desktop_dir, item)
128                     except TypeError:
129                         # There is supposedly a None value in there
130                         # The current code shouldn't allow that
131                         # Just raise a exception with the values
132                         raise RuntimeError("Missing value desktop_dir=%s or item=%s"
133                                            % (desktop_dir, item))
134 
135                     os.makedirs(src_path, exist_ok=True)
136                     os.symlink(src_path, path)
137                 else:
138                     # We use first the renamed dir, otherwise we make it.
139                     if os.path.isdir(old_path):
140                         os.rename(old_path, path)
141                     else:
142                         os.makedirs(path, exist_ok=True)
143 
144             # Security: Remove other symlinks.
145             for item in os.listdir(user_dir):
146                 path = os.path.join(user_dir, item)
147                 if item not in DEFAULT_DESKTOP_FOLDERS and os.path.islink(path):
148                     os.unlink(path)
149                     os.makedirs(path)
150 
151     def set_crash_dialogs(self, enabled):
152         """Enable or diable Wine crash dialogs"""
153         self.set_registry_key(
154             self.hkcu_prefix + "/Software/Wine/WineDbg",
155             "ShowCrashDialog",
156             1 if enabled else 0,
157         )
158 
159     def set_virtual_desktop(self, enabled):
160         """Enable or disable wine virtual desktop.
161         The Lutris virtual desktop is refered to as 'WineDesktop', in Wine the
162         virtual desktop name is 'default'.
163         """
164         path = self.hkcu_prefix + "/Software/Wine/Explorer"
165         if enabled:
166             self.set_registry_key(path, "Desktop", "WineDesktop")
167             default_resolution = "x".join(DISPLAY_MANAGER.get_current_resolution())
168             logger.debug(
169                 "Enabling wine virtual desktop with default resolution of %s",
170                 default_resolution,
171             )
172             self.set_registry_key(
173                 self.hkcu_prefix + "/Software/Wine/Explorer/Desktops",
174                 "WineDesktop",
175                 default_resolution,
176             )
177         else:
178             self.clear_registry_key(path)
179 
180     def set_desktop_size(self, desktop_size):
181         """Sets the desktop size if one is given but do not reset the key if
182         one isn't.
183         """
184         path = self.hkcu_prefix + "/Software/Wine/Explorer/Desktops"
185         if desktop_size:
186             self.set_registry_key(path, "WineDesktop", desktop_size)
187 
188     def use_xvid_mode(self, enabled):
189         """Set this to "Y" to allow wine switch the resolution using XVidMode extension."""
190         self.set_registry_key(
191             self.hkcu_prefix + "/Software/Wine/X11 Driver",
192             "UseXVidMode",
193             "Y" if enabled else "N",
194         )
195 
196     def configure_joypads(self):
197         joypads = joypad.get_joypads()
198         key = self.hkcu_prefix + "/Software/Wine/DirectInput/Joysticks"
199         self.clear_registry_key(key)
200         for device, joypad_name in joypads:
201             if "event" in device:
202                 disabled_joypad = "{} (js)".format(joypad_name)
203             else:
204                 disabled_joypad = "{} (event)".format(joypad_name)
205             self.set_registry_key(key, disabled_joypad, "disabled")
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/lutris/util/wine/prefix.py b/lutris/util/wine/prefix.py
--- a/lutris/util/wine/prefix.py
+++ b/lutris/util/wine/prefix.py
@@ -117,7 +117,11 @@
                     except OSError:
                         os.rename(path, old_path)
 
-                if restore and not os.path.isdir(path):
+                # if we want to create a symlink and one is already there, just skip to the next item.
+                # this also makes sure the elif doesn't find a dir (isdir only looks at the target of the symlink).
+                if restore and os.path.islink(path):
+                    continue
+                elif restore and not os.path.isdir(path):
                     os.symlink(xdgshortcuts.get_xdg_entry(DESKTOP_XDG[i]), path)
                     # We don't need all the others process of the loop
                     continue

{"golden_diff": "diff --git a/lutris/util/wine/prefix.py b/lutris/util/wine/prefix.py\n--- a/lutris/util/wine/prefix.py\n+++ b/lutris/util/wine/prefix.py\n@@ -117,7 +117,11 @@\n                     except OSError:\n                         os.rename(path, old_path)\n \n-                if restore and not os.path.isdir(path):\n+                # if we want to create a symlink and one is already there, just skip to the next item.\n+                # this also makes sure the elif doesn't find a dir (isdir only looks at the target of the symlink).\n+                if restore and os.path.islink(path):\n+                    continue\n+                elif restore and not os.path.isdir(path):\n                     os.symlink(xdgshortcuts.get_xdg_entry(DESKTOP_XDG[i]), path)\n                     # We don't need all the others process of the loop\n                     continue\n", "issue": "Problem with user directories when sandboxing is disabled\nHi, i have strange problem in recent version. I have disabled wineprefix sandboxing, so my user directories were configured as symlinks. But in recent version programs (or even wine config) do not start with error:\r\n\r\nTraceback (most recent call last):\r\n  File \"/usr/lib/python3.7/site-packages/lutris/runners/wine.py\", line 676, in run_winecfg\r\n    self.prelaunch()\r\n  File \"/usr/lib/python3.7/site-packages/lutris/runners/wine.py\", line 778, in prelaunch\r\n    self.sandbox(prefix_manager)\r\n  File \"/usr/lib/python3.7/site-packages/lutris/runners/wine.py\", line 926, in sandbox\r\n    wine_prefix.desktop_integration(restore=True)\r\n  File \"/usr/lib/python3.7/site-packages/lutris/util/wine/prefix.py\", line 132, in desktop_integration\r\n    os.rename(old_path, path)\r\nNotADirectoryError: [Errno 20] nen\u00ed adres\u00e1\u0159em: '/home/petr/.local/share/lutris/runners/winegames/drive_c/users/petr/Plocha.winecfg' -> '/home/petr/.local/share/lutris/runners/winegames/drive_c/users/petr/Plocha'\r\n\r\nwhich is true, because \"Plocha\" is symlink to proper Desktop directory. When i delete \"Plocha.winecfg\", same error moves to next user directory \"M\u00e9 dokumenty\" (Documents). When i delete all \"winecfg\" files, all symlinks to existing user directories are replaced by empty directories. I.e. i am not able to run programs linked to standard user directories despite sandboxing is disabled.\n", "before_files": [{"content": "\"\"\"Wine prefix management\"\"\"\nimport os\nfrom lutris.util.wine.registry import WineRegistry\nfrom lutris.util.log import logger\nfrom lutris.util import joypad, system, xdgshortcuts\nfrom lutris.util.display import DISPLAY_MANAGER\n\nDESKTOP_KEYS = [\"Desktop\", \"Personal\", \"My Music\", \"My Videos\", \"My Pictures\"]\nDEFAULT_DESKTOP_FOLDERS = [\"Desktop\", \"My Documents\", \"My Music\", \"My Videos\", \"My Pictures\"]\nDESKTOP_XDG = [\"DESKTOP\", \"DOCUMENTS\", \"MUSIC\", \"VIDEOS\", \"PICTURES\"]\n\n\nclass WinePrefixManager:\n    \"\"\"Class to allow modification of Wine prefixes without the use of Wine\"\"\"\n\n    hkcu_prefix = \"HKEY_CURRENT_USER\"\n\n    def __init__(self, path):\n        if not path:\n            logger.warning(\"No path specified for Wine prefix\")\n        self.path = path\n\n    def setup_defaults(self):\n        \"\"\"Sets the defaults for newly created prefixes\"\"\"\n        self.override_dll(\"winemenubuilder.exe\", \"\")\n        try:\n            self.desktop_integration()\n        except OSError as ex:\n            logger.error(\n                \"Failed to setup desktop integration, the prefix may not be valid.\"\n            )\n            logger.exception(ex)\n\n    def get_registry_path(self, key):\n        \"\"\"Matches registry keys to a registry file\n\n        Currently, only HKEY_CURRENT_USER keys are supported.\n        \"\"\"\n        if key.startswith(self.hkcu_prefix):\n            return os.path.join(self.path, \"user.reg\")\n        raise ValueError(\"Unsupported key '{}'\".format(key))\n\n    def get_key_path(self, key):\n        if key.startswith(self.hkcu_prefix):\n            return key[len(self.hkcu_prefix) + 1:]\n        raise ValueError(\n            \"The key {} is currently not supported by WinePrefixManager\".format(key)\n        )\n\n    def get_registry_key(self, key, subkey):\n        registry = WineRegistry(self.get_registry_path(key))\n        return registry.query(self.get_key_path(key), subkey)\n\n    def set_registry_key(self, key, subkey, value):\n        registry = WineRegistry(self.get_registry_path(key))\n        registry.set_value(self.get_key_path(key), subkey, value)\n        registry.save()\n\n    def clear_registry_key(self, key):\n        registry = WineRegistry(self.get_registry_path(key))\n        registry.clear_key(self.get_key_path(key))\n        registry.save()\n\n    def clear_registry_subkeys(self, key, subkeys):\n        registry = WineRegistry(self.get_registry_path(key))\n        registry.clear_subkeys(self.get_key_path(key), subkeys)\n        registry.save()\n\n    def override_dll(self, dll, mode):\n        key = self.hkcu_prefix + \"/Software/Wine/DllOverrides\"\n        if mode.startswith(\"dis\"):\n            mode = \"\"\n        if mode not in (\"builtin\", \"native\", \"builtin,native\", \"native,builtin\", \"\"):\n            logger.error(\"DLL override '%s' mode is not valid\", mode)\n            return\n        self.set_registry_key(key, dll, mode)\n\n    def get_desktop_folders(self):\n        \"\"\"Return the list of desktop folder names loaded from the Windows registry\"\"\"\n        desktop_folders = []\n        for key in DESKTOP_KEYS:\n            folder = self.get_registry_key(\n                self.hkcu_prefix\n                + \"/Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders\",\n                key,\n            )\n            if not folder:\n                logger.warning(\"Couldn't load shell folder name for %s\", key)\n                continue\n            desktop_folders.append(folder[folder.rfind(\"\\\\\") + 1:])\n        return desktop_folders or DEFAULT_DESKTOP_FOLDERS\n\n    def desktop_integration(self, desktop_dir=None, restore=False):\n        \"\"\"Overwrite desktop integration\"\"\"\n        user = os.getenv(\"USER\")\n        user_dir = os.path.join(self.path, \"drive_c/users/\", user)\n        desktop_folders = self.get_desktop_folders()\n\n        if desktop_dir:\n            desktop_dir = os.path.expanduser(desktop_dir)\n        else:\n            desktop_dir = user_dir\n\n        if system.path_exists(user_dir):\n            # Replace or restore desktop integration symlinks\n            for i, item in enumerate(desktop_folders):\n                path = os.path.join(user_dir, item)\n                old_path = path + \".winecfg\"\n\n                if os.path.islink(path):\n                    if not restore:\n                        os.unlink(path)\n                elif os.path.isdir(path):\n                    try:\n                        os.rmdir(path)\n                    # We can't delete nonempty dir, so we rename as wine do.\n                    except OSError:\n                        os.rename(path, old_path)\n\n                if restore and not os.path.isdir(path):\n                    os.symlink(xdgshortcuts.get_xdg_entry(DESKTOP_XDG[i]), path)\n                    # We don't need all the others process of the loop\n                    continue\n\n                if desktop_dir != user_dir:\n                    try:\n                        src_path = os.path.join(desktop_dir, item)\n                    except TypeError:\n                        # There is supposedly a None value in there\n                        # The current code shouldn't allow that\n                        # Just raise a exception with the values\n                        raise RuntimeError(\"Missing value desktop_dir=%s or item=%s\"\n                                           % (desktop_dir, item))\n\n                    os.makedirs(src_path, exist_ok=True)\n                    os.symlink(src_path, path)\n                else:\n                    # We use first the renamed dir, otherwise we make it.\n                    if os.path.isdir(old_path):\n                        os.rename(old_path, path)\n                    else:\n                        os.makedirs(path, exist_ok=True)\n\n            # Security: Remove other symlinks.\n            for item in os.listdir(user_dir):\n                path = os.path.join(user_dir, item)\n                if item not in DEFAULT_DESKTOP_FOLDERS and os.path.islink(path):\n                    os.unlink(path)\n                    os.makedirs(path)\n\n    def set_crash_dialogs(self, enabled):\n        \"\"\"Enable or diable Wine crash dialogs\"\"\"\n        self.set_registry_key(\n            self.hkcu_prefix + \"/Software/Wine/WineDbg\",\n            \"ShowCrashDialog\",\n            1 if enabled else 0,\n        )\n\n    def set_virtual_desktop(self, enabled):\n        \"\"\"Enable or disable wine virtual desktop.\n        The Lutris virtual desktop is refered to as 'WineDesktop', in Wine the\n        virtual desktop name is 'default'.\n        \"\"\"\n        path = self.hkcu_prefix + \"/Software/Wine/Explorer\"\n        if enabled:\n            self.set_registry_key(path, \"Desktop\", \"WineDesktop\")\n            default_resolution = \"x\".join(DISPLAY_MANAGER.get_current_resolution())\n            logger.debug(\n                \"Enabling wine virtual desktop with default resolution of %s\",\n                default_resolution,\n            )\n            self.set_registry_key(\n                self.hkcu_prefix + \"/Software/Wine/Explorer/Desktops\",\n                \"WineDesktop\",\n                default_resolution,\n            )\n        else:\n            self.clear_registry_key(path)\n\n    def set_desktop_size(self, desktop_size):\n        \"\"\"Sets the desktop size if one is given but do not reset the key if\n        one isn't.\n        \"\"\"\n        path = self.hkcu_prefix + \"/Software/Wine/Explorer/Desktops\"\n        if desktop_size:\n            self.set_registry_key(path, \"WineDesktop\", desktop_size)\n\n    def use_xvid_mode(self, enabled):\n        \"\"\"Set this to \"Y\" to allow wine switch the resolution using XVidMode extension.\"\"\"\n        self.set_registry_key(\n            self.hkcu_prefix + \"/Software/Wine/X11 Driver\",\n            \"UseXVidMode\",\n            \"Y\" if enabled else \"N\",\n        )\n\n    def configure_joypads(self):\n        joypads = joypad.get_joypads()\n        key = self.hkcu_prefix + \"/Software/Wine/DirectInput/Joysticks\"\n        self.clear_registry_key(key)\n        for device, joypad_name in joypads:\n            if \"event\" in device:\n                disabled_joypad = \"{} (js)\".format(joypad_name)\n            else:\n                disabled_joypad = \"{} (event)\".format(joypad_name)\n            self.set_registry_key(key, disabled_joypad, \"disabled\")\n", "path": "lutris/util/wine/prefix.py"}], "after_files": [{"content": "\"\"\"Wine prefix management\"\"\"\nimport os\nfrom lutris.util.wine.registry import WineRegistry\nfrom lutris.util.log import logger\nfrom lutris.util import joypad, system, xdgshortcuts\nfrom lutris.util.display import DISPLAY_MANAGER\n\nDESKTOP_KEYS = [\"Desktop\", \"Personal\", \"My Music\", \"My Videos\", \"My Pictures\"]\nDEFAULT_DESKTOP_FOLDERS = [\"Desktop\", \"My Documents\", \"My Music\", \"My Videos\", \"My Pictures\"]\nDESKTOP_XDG = [\"DESKTOP\", \"DOCUMENTS\", \"MUSIC\", \"VIDEOS\", \"PICTURES\"]\n\n\nclass WinePrefixManager:\n    \"\"\"Class to allow modification of Wine prefixes without the use of Wine\"\"\"\n\n    hkcu_prefix = \"HKEY_CURRENT_USER\"\n\n    def __init__(self, path):\n        if not path:\n            logger.warning(\"No path specified for Wine prefix\")\n        self.path = path\n\n    def setup_defaults(self):\n        \"\"\"Sets the defaults for newly created prefixes\"\"\"\n        self.override_dll(\"winemenubuilder.exe\", \"\")\n        try:\n            self.desktop_integration()\n        except OSError as ex:\n            logger.error(\n                \"Failed to setup desktop integration, the prefix may not be valid.\"\n            )\n            logger.exception(ex)\n\n    def get_registry_path(self, key):\n        \"\"\"Matches registry keys to a registry file\n\n        Currently, only HKEY_CURRENT_USER keys are supported.\n        \"\"\"\n        if key.startswith(self.hkcu_prefix):\n            return os.path.join(self.path, \"user.reg\")\n        raise ValueError(\"Unsupported key '{}'\".format(key))\n\n    def get_key_path(self, key):\n        if key.startswith(self.hkcu_prefix):\n            return key[len(self.hkcu_prefix) + 1:]\n        raise ValueError(\n            \"The key {} is currently not supported by WinePrefixManager\".format(key)\n        )\n\n    def get_registry_key(self, key, subkey):\n        registry = WineRegistry(self.get_registry_path(key))\n        return registry.query(self.get_key_path(key), subkey)\n\n    def set_registry_key(self, key, subkey, value):\n        registry = WineRegistry(self.get_registry_path(key))\n        registry.set_value(self.get_key_path(key), subkey, value)\n        registry.save()\n\n    def clear_registry_key(self, key):\n        registry = WineRegistry(self.get_registry_path(key))\n        registry.clear_key(self.get_key_path(key))\n        registry.save()\n\n    def clear_registry_subkeys(self, key, subkeys):\n        registry = WineRegistry(self.get_registry_path(key))\n        registry.clear_subkeys(self.get_key_path(key), subkeys)\n        registry.save()\n\n    def override_dll(self, dll, mode):\n        key = self.hkcu_prefix + \"/Software/Wine/DllOverrides\"\n        if mode.startswith(\"dis\"):\n            mode = \"\"\n        if mode not in (\"builtin\", \"native\", \"builtin,native\", \"native,builtin\", \"\"):\n            logger.error(\"DLL override '%s' mode is not valid\", mode)\n            return\n        self.set_registry_key(key, dll, mode)\n\n    def get_desktop_folders(self):\n        \"\"\"Return the list of desktop folder names loaded from the Windows registry\"\"\"\n        desktop_folders = []\n        for key in DESKTOP_KEYS:\n            folder = self.get_registry_key(\n                self.hkcu_prefix\n                + \"/Software/Microsoft/Windows/CurrentVersion/Explorer/Shell Folders\",\n                key,\n            )\n            if not folder:\n                logger.warning(\"Couldn't load shell folder name for %s\", key)\n                continue\n            desktop_folders.append(folder[folder.rfind(\"\\\\\") + 1:])\n        return desktop_folders or DEFAULT_DESKTOP_FOLDERS\n\n    def desktop_integration(self, desktop_dir=None, restore=False):\n        \"\"\"Overwrite desktop integration\"\"\"\n        user = os.getenv(\"USER\")\n        user_dir = os.path.join(self.path, \"drive_c/users/\", user)\n        desktop_folders = self.get_desktop_folders()\n\n        if desktop_dir:\n            desktop_dir = os.path.expanduser(desktop_dir)\n        else:\n            desktop_dir = user_dir\n\n        if system.path_exists(user_dir):\n            # Replace or restore desktop integration symlinks\n            for i, item in enumerate(desktop_folders):\n                path = os.path.join(user_dir, item)\n                old_path = path + \".winecfg\"\n\n                if os.path.islink(path):\n                    if not restore:\n                        os.unlink(path)\n                elif os.path.isdir(path):\n                    try:\n                        os.rmdir(path)\n                    # We can't delete nonempty dir, so we rename as wine do.\n                    except OSError:\n                        os.rename(path, old_path)\n\n                # if we want to create a symlink and one is already there, just skip to the next item.\n                # this also makes sure the elif doesn't find a dir (isdir only looks at the target of the symlink).\n                if restore and os.path.islink(path):\n                    continue\n                elif restore and not os.path.isdir(path):\n                    os.symlink(xdgshortcuts.get_xdg_entry(DESKTOP_XDG[i]), path)\n                    # We don't need all the others process of the loop\n                    continue\n\n                if desktop_dir != user_dir:\n                    try:\n                        src_path = os.path.join(desktop_dir, item)\n                    except TypeError:\n                        # There is supposedly a None value in there\n                        # The current code shouldn't allow that\n                        # Just raise a exception with the values\n                        raise RuntimeError(\"Missing value desktop_dir=%s or item=%s\"\n                                           % (desktop_dir, item))\n\n                    os.makedirs(src_path, exist_ok=True)\n                    os.symlink(src_path, path)\n                else:\n                    # We use first the renamed dir, otherwise we make it.\n                    if os.path.isdir(old_path):\n                        os.rename(old_path, path)\n                    else:\n                        os.makedirs(path, exist_ok=True)\n\n            # Security: Remove other symlinks.\n            for item in os.listdir(user_dir):\n                path = os.path.join(user_dir, item)\n                if item not in DEFAULT_DESKTOP_FOLDERS and os.path.islink(path):\n                    os.unlink(path)\n                    os.makedirs(path)\n\n    def set_crash_dialogs(self, enabled):\n        \"\"\"Enable or diable Wine crash dialogs\"\"\"\n        self.set_registry_key(\n            self.hkcu_prefix + \"/Software/Wine/WineDbg\",\n            \"ShowCrashDialog\",\n            1 if enabled else 0,\n        )\n\n    def set_virtual_desktop(self, enabled):\n        \"\"\"Enable or disable wine virtual desktop.\n        The Lutris virtual desktop is refered to as 'WineDesktop', in Wine the\n        virtual desktop name is 'default'.\n        \"\"\"\n        path = self.hkcu_prefix + \"/Software/Wine/Explorer\"\n        if enabled:\n            self.set_registry_key(path, \"Desktop\", \"WineDesktop\")\n            default_resolution = \"x\".join(DISPLAY_MANAGER.get_current_resolution())\n            logger.debug(\n                \"Enabling wine virtual desktop with default resolution of %s\",\n                default_resolution,\n            )\n            self.set_registry_key(\n                self.hkcu_prefix + \"/Software/Wine/Explorer/Desktops\",\n                \"WineDesktop\",\n                default_resolution,\n            )\n        else:\n            self.clear_registry_key(path)\n\n    def set_desktop_size(self, desktop_size):\n        \"\"\"Sets the desktop size if one is given but do not reset the key if\n        one isn't.\n        \"\"\"\n        path = self.hkcu_prefix + \"/Software/Wine/Explorer/Desktops\"\n        if desktop_size:\n            self.set_registry_key(path, \"WineDesktop\", desktop_size)\n\n    def use_xvid_mode(self, enabled):\n        \"\"\"Set this to \"Y\" to allow wine switch the resolution using XVidMode extension.\"\"\"\n        self.set_registry_key(\n            self.hkcu_prefix + \"/Software/Wine/X11 Driver\",\n            \"UseXVidMode\",\n            \"Y\" if enabled else \"N\",\n        )\n\n    def configure_joypads(self):\n        joypads = joypad.get_joypads()\n        key = self.hkcu_prefix + \"/Software/Wine/DirectInput/Joysticks\"\n        self.clear_registry_key(key)\n        for device, joypad_name in joypads:\n            if \"event\" in device:\n                disabled_joypad = \"{} (js)\".format(joypad_name)\n            else:\n                disabled_joypad = \"{} (event)\".format(joypad_name)\n            self.set_registry_key(key, disabled_joypad, \"disabled\")\n", "path": "lutris/util/wine/prefix.py"}]}