mirror of
https://github.com/ZuneDev/ZuneModdingHelper.git
synced 2026-07-27 13:12:21 -07:00
Added initial version of Win11 driver fix
This commit is contained in:
@@ -3,7 +3,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using ZuneModCore.Mods;
|
||||
|
||||
namespace ZuneModCore
|
||||
@@ -15,8 +14,9 @@ namespace ZuneModCore
|
||||
/// </summary>
|
||||
public static readonly IReadOnlyList<Mod> AvailableMods = new List<Mod>
|
||||
{
|
||||
new FeaturesOverrideMod(),
|
||||
new VideoSyncMod(),
|
||||
new Win11DriverMod(),
|
||||
new FeaturesOverrideMod(),
|
||||
new WebservicesMod(),
|
||||
new BackgroundImageMod(),
|
||||
new MbidLocatorMod(),
|
||||
|
||||
@@ -0,0 +1,153 @@
|
||||
using CommunityToolkit.Diagnostics;
|
||||
using OwlCore.Extensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ZuneModCore.Mods
|
||||
{
|
||||
public class Win11DriverMod : Mod
|
||||
{
|
||||
public override string Id => nameof(Win11DriverMod);
|
||||
|
||||
public override string Title => "Fix Zune Drivers for Windows 11";
|
||||
|
||||
public override string Description => "Resolves the \"This operation requires an interactive window station\" error " +
|
||||
"when attempting to install the Zune device drivers on Windows 11.";
|
||||
|
||||
public override string Author => "ส็็็Codix#4833 and Joshua \"Yoshi\" Askharoun";
|
||||
|
||||
public override IReadOnlyList<ModDependency>? DependentMods => null;
|
||||
|
||||
protected override async Task<string?> ApplyCore()
|
||||
{
|
||||
if (Environment.OSVersion.Platform != PlatformID.Win32NT
|
||||
|| Environment.OSVersion.Version < new Version(10, 0, 22000, 0))
|
||||
return "This mod is intended only for Windows 11 or later.";
|
||||
|
||||
const string MuiFilename = "ZuneCoInst.dll.mui";
|
||||
string srcDriverDir = Path.Combine(ModManager.ZuneInstallDir, "Drivers", "Zune");
|
||||
string driverFilePath = Path.Combine(srcDriverDir, "Zune.inf");
|
||||
string dstDriverRoot = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "System32");
|
||||
string installScriptPath = Path.Combine(StorageDirectory, "install.bat");
|
||||
|
||||
try
|
||||
{
|
||||
// Remove the old broken driver, if it was installed
|
||||
ProcessStartInfo startInfo = new("pnputil", "/enum-drivers")
|
||||
{
|
||||
RedirectStandardInput = true,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
};
|
||||
Process enumProc = new()
|
||||
{
|
||||
StartInfo = startInfo
|
||||
};
|
||||
|
||||
// Redirect standard output to get data
|
||||
string? zuneInfPublishedName = null;
|
||||
string? enumDriversPreviousLine = null;
|
||||
Regex rx = new(@"^\s*[\w ]+:\s+zune\.inf$", RegexOptions.Multiline | RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
|
||||
enumProc.Start();
|
||||
while (!enumProc.StandardOutput.EndOfStream)
|
||||
{
|
||||
string? currentLine = await enumProc.StandardOutput.ReadLineAsync();
|
||||
Debug.WriteLine(currentLine);
|
||||
|
||||
if (enumDriversPreviousLine != null && currentLine != null
|
||||
&& rx.IsMatch(currentLine) && enumDriversPreviousLine.EndsWith(".inf"))
|
||||
{
|
||||
// Found the "Published Name" and "Original Name" lines
|
||||
int idx = enumDriversPreviousLine.LastIndexOf(' ');
|
||||
zuneInfPublishedName = enumDriversPreviousLine[idx..].Trim();
|
||||
}
|
||||
|
||||
enumDriversPreviousLine = currentLine;
|
||||
}
|
||||
await enumProc.WaitForExitAsync();
|
||||
|
||||
//if (zuneInfPublishedName != null)
|
||||
//{
|
||||
// // There may be a corrupted driver from previous attempts,
|
||||
// // removing it before installing brings better results
|
||||
// startInfo.Arguments = $"/delete-driver {zuneInfPublishedName} /uninstall";
|
||||
// Process deleteProc = new()
|
||||
// {
|
||||
// StartInfo = startInfo
|
||||
// };
|
||||
|
||||
// deleteProc.Start();
|
||||
// while (!deleteProc.StandardOutput.EndOfStream)
|
||||
// {
|
||||
// string? currentLine = await deleteProc.StandardOutput.ReadLineAsync();
|
||||
// Debug.WriteLine(currentLine);
|
||||
// }
|
||||
// await deleteProc.WaitForExitAsync();
|
||||
//}
|
||||
|
||||
// Copy all .dll.mui files, then install the driver.
|
||||
// This loop generates a batch script that can run as TrustedInstaller
|
||||
// to copy all the necessary files to System32. If we don't run this
|
||||
// as TI, we'll still get the "interactive window station" error
|
||||
// when attempting to install the driver.
|
||||
using (var installScript = File.CreateText(installScriptPath))
|
||||
{
|
||||
await installScript.WriteLineAsync($"pnputil /delete-driver {zuneInfPublishedName} /uninstall");
|
||||
|
||||
foreach (string localeDir in Directory.GetDirectories(srcDriverDir))
|
||||
{
|
||||
string locale = Path.GetFileName(localeDir);
|
||||
if (locale == null || locale.Length != 5 || locale[2] != '-')
|
||||
continue;
|
||||
|
||||
FileInfo srcDriver = new(Path.Combine(localeDir, MuiFilename));
|
||||
FileInfo dstDriver = new(Path.Combine(dstDriverRoot, locale, MuiFilename));
|
||||
|
||||
await installScript.WriteLineAsync($"del \"{dstDriver.FullName}\"");
|
||||
await installScript.WriteLineAsync($"copy \"{srcDriver.FullName}\" \"{dstDriver.FullName}\"");
|
||||
}
|
||||
|
||||
await installScript.WriteLineAsync($"pnputil /add-driver \"{driverFilePath}\" /install");
|
||||
await installScript.WriteLineAsync("echo \"Script complete. If there are any errors reported above, " +
|
||||
"please note them and file a report at https://github.com/ZuneDev/ZuneModdingHelper/issues/new\"");
|
||||
}
|
||||
|
||||
// Set up ExecTI
|
||||
var tiSvc = Win32.ExecTI.StartTrustedInstallerService();
|
||||
|
||||
// Manually copy files and install the driver
|
||||
string? installErrorMsg = null;
|
||||
using (var procInfo = Win32.ExecTI.CreateProcessAsTrustedInstaller(tiSvc, $"cmd /k {installScriptPath}"))
|
||||
{
|
||||
Debug.WriteLine(procInfo.hProcess.DangerousGetHandle().ToString("X"));
|
||||
Process installProc = Process.GetProcessById(unchecked((int)procInfo!.dwProcessId));
|
||||
await installProc.WaitForExitAsync();
|
||||
|
||||
if (Vanara.PInvoke.Kernel32.GetExitCodeProcess(procInfo.hProcess, out var exitCode)
|
||||
&& (exitCode != 0 || exitCode != 0xc000013A))
|
||||
installErrorMsg = "An unknown error occurred while attempting to install driver.";
|
||||
|
||||
//Vanara.PInvoke.Kernel32.CloseHandle(procInfo.hProcess.DangerousGetHandle());
|
||||
}
|
||||
|
||||
return installErrorMsg;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return ex.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task<string?> ResetCore()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
+17
-11
@@ -34,17 +34,17 @@ namespace ZuneModCore.Win32
|
||||
}
|
||||
else
|
||||
{
|
||||
CloseHandle(hSnapshot.DangerousGetHandle());
|
||||
CloseHandle(hSnapshot.DangerousGetHandle(), nameof(hSnapshot));
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
if (unchecked((int)pid) == -1)
|
||||
{
|
||||
CloseHandle(hSnapshot.DangerousGetHandle());
|
||||
CloseHandle(hSnapshot.DangerousGetHandle(), nameof(hSnapshot));
|
||||
throw new Exception("Process not found: " + processName);
|
||||
}
|
||||
|
||||
CloseHandle(hSnapshot.DangerousGetHandle());
|
||||
CloseHandle(hSnapshot.DangerousGetHandle(), nameof(hSnapshot));
|
||||
return pid;
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ namespace ZuneModCore.Win32
|
||||
(TokenAccess)MAXIMUM_ALLOWED,
|
||||
out var hSystemToken))
|
||||
{
|
||||
CloseHandle(hSystemProcess.DangerousGetHandle());
|
||||
CloseHandle(hSystemProcess.DangerousGetHandle(), nameof(hSystemProcess));
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
@@ -137,19 +137,19 @@ namespace ZuneModCore.Win32
|
||||
TOKEN_TYPE.TokenImpersonation,
|
||||
out var hDupToken))
|
||||
{
|
||||
CloseHandle(hSystemToken.DangerousGetHandle());
|
||||
CloseHandle(hSystemToken.DangerousGetHandle(), nameof(hSystemToken));
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
if (!ImpersonateLoggedOnUser(hDupToken))
|
||||
{
|
||||
CloseHandle(hDupToken.DangerousGetHandle());
|
||||
CloseHandle(hSystemToken.DangerousGetHandle());
|
||||
CloseHandle(hDupToken.DangerousGetHandle(), nameof(hDupToken));
|
||||
CloseHandle(hSystemToken.DangerousGetHandle(), nameof(hSystemToken));
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
CloseHandle(hDupToken.DangerousGetHandle());
|
||||
CloseHandle(hSystemToken.DangerousGetHandle());
|
||||
CloseHandle(hDupToken.DangerousGetHandle(), nameof(hDupToken));
|
||||
CloseHandle(hSystemToken.DangerousGetHandle(), nameof(hSystemToken));
|
||||
}
|
||||
|
||||
public static SafePROCESS_INFORMATION? CreateProcessAsTrustedInstaller(uint pid, string commandLine)
|
||||
@@ -170,7 +170,7 @@ namespace ZuneModCore.Win32
|
||||
TokenAccess.TOKEN_ALL_ACCESS,
|
||||
out var hTIToken))
|
||||
{
|
||||
CloseHandle(hTIProcess.DangerousGetHandle());
|
||||
CloseHandle(hTIProcess.DangerousGetHandle(), nameof(hTIProcess));
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace ZuneModCore.Win32
|
||||
TOKEN_TYPE.TokenImpersonation,
|
||||
out var hDupToken))
|
||||
{
|
||||
CloseHandle(hTIToken.DangerousGetHandle());
|
||||
CloseHandle(hTIToken.DangerousGetHandle(), nameof(hTIToken));
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
@@ -211,5 +211,11 @@ namespace ZuneModCore.Win32
|
||||
|
||||
return processInfo;
|
||||
}
|
||||
|
||||
private static void CloseHandle(IntPtr hObject, string name)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"{name} = {hObject:X}");
|
||||
Kernel32.CloseHandle(hObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user