proton: Sync pfx creation and create a guard file.

Due to unlucky power off or a crash crash when first starting the game
the prefix can end up in corrupted state with no obvious way of
troubleshooting.

This is an attempt at ensuring that the prefix was created successfully
and force-recreate it if it wasn't.

CW-Bug-Id: #19720
This commit is contained in:
Arkadiusz Hiler 2023-02-13 16:42:19 +02:00
parent 8d19973b01
commit e909367230

29
proton
View File

@ -16,6 +16,7 @@ import sys
import shlex import shlex
import uuid import uuid
import json import json
import time
from ctypes import CDLL from ctypes import CDLL
from ctypes import CFUNCTYPE from ctypes import CFUNCTYPE
@ -40,7 +41,7 @@ from random import randrange
#To enable debug logging, copy "user_settings.sample.py" to "user_settings.py" #To enable debug logging, copy "user_settings.sample.py" to "user_settings.py"
#and edit it if needed. #and edit it if needed.
CURRENT_PREFIX_VERSION="10.0-104" CURRENT_PREFIX_VERSION="10.0-105"
PFX="Proton: " PFX="Proton: "
ld_path_var = "LD_LIBRARY_PATH" ld_path_var = "LD_LIBRARY_PATH"
@ -585,6 +586,7 @@ class CompatData:
def __init__(self, compatdata): def __init__(self, compatdata):
self.base_dir = compatdata + "/" self.base_dir = compatdata + "/"
self.prefix_dir = self.path("pfx/") self.prefix_dir = self.path("pfx/")
self.creation_sync_guard = self.path("pfx/creation_sync_guard")
self.version_file = self.path("version") self.version_file = self.path("version")
self.config_info_file = self.path("config_info") self.config_info_file = self.path("config_info")
self.tracked_files_file = self.path("tracked_files") self.tracked_files_file = self.path("tracked_files")
@ -739,6 +741,13 @@ class CompatData:
log("Unable to write new registry file to " + sysreg_fp) log("Unable to write new registry file to " + sysreg_fp)
pass pass
if int(old_proton_maj) < 10 or (int(old_proton_maj) == 10 and
int(old_proton_min) == 0 and
int(old_prefix_ver) < 105):
with open(self.creation_sync_guard, "w"):
pass
os.sync()
stale_builtins = [self.prefix_dir + "/drive_c/windows/system32/amd_ags_x64.dll", stale_builtins = [self.prefix_dir + "/drive_c/windows/system32/amd_ags_x64.dll",
self.prefix_dir + "/drive_c/windows/syswow64/amd_ags_x64.dll", self.prefix_dir + "/drive_c/windows/syswow64/amd_ags_x64.dll",
self.prefix_dir + "/drive_c/windows/system32/ir50_32.dll", self.prefix_dir + "/drive_c/windows/system32/ir50_32.dll",
@ -908,16 +917,32 @@ class CompatData:
self.upgrade_pfx(old_ver) self.upgrade_pfx(old_ver)
# not fully-created prefix, copy it for future investigation
if file_exists(self.prefix_dir, follow_symlinks=True) and not file_exists(self.creation_sync_guard, follow_symlinks=True):
shutil.move(self.prefix_dir, self.path(f"corrupted_pfx-{time.time()}.bak"))
# remove files created for the corrupted prefix, we usually append to them
if file_exists(self.version_file, follow_symlinks=False):
os.remove(self.version_file)
if file_exists(self.config_info_file, follow_symlinks=False):
os.remove(self.config_info_file)
if file_exists(self.tracked_files_file, follow_symlinks=False):
os.remove(self.tracked_files_file)
if not file_exists(self.prefix_dir, follow_symlinks=True): if not file_exists(self.prefix_dir, follow_symlinks=True):
makedirs(self.prefix_dir + "/drive_c") makedirs(self.prefix_dir + "/drive_c")
set_dir_casefold_bit(self.prefix_dir + "/drive_c") set_dir_casefold_bit(self.prefix_dir + "/drive_c")
if not file_exists(self.prefix_dir + "/user.reg", follow_symlinks=True):
self.copy_pfx() self.copy_pfx()
machine_guid = self.old_machine_guid machine_guid = self.old_machine_guid
if machine_guid is None: if machine_guid is None:
machine_guid = "\"" + str(uuid.uuid4()) + "\"" machine_guid = "\"" + str(uuid.uuid4()) + "\""
get_replace_reg_value(self.prefix_dir + "system.reg", "Software\\\\Microsoft\\\\Cryptography", "MachineGuid", machine_guid) get_replace_reg_value(self.prefix_dir + "system.reg", "Software\\\\Microsoft\\\\Cryptography", "MachineGuid", machine_guid)
os.sync()
with open(self.creation_sync_guard, "w"):
pass
os.sync()
self.migrate_user_paths() self.migrate_user_paths()