Skip to content

Commit

Permalink
add check for microsoft compat package
Browse files Browse the repository at this point in the history
  • Loading branch information
13xforever committed Feb 28, 2024
1 parent 6130dc0 commit c7c3d33
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 8 deletions.
111 changes: 111 additions & 0 deletions VkDiag/Interop/PackageManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using Windows.Win32;
using Windows.Win32.Foundation;

namespace VkDiag.Interop;

public static unsafe class PackageManager
{
public static List<string> FindPackagesByPackageFamily(string packageFamily)
{
uint count = 0, bufferLength = 0;
var result = PInvoke.FindPackagesByPackageFamily(
packageFamily,
PInvoke.PACKAGE_FILTER_HEAD,
ref count,
default,
ref bufferLength,
default,
default
);
if (result is not WIN32_ERROR.ERROR_INSUFFICIENT_BUFFER)
throw new Win32Exception((int)result, "Failed to query package list");

if (count is 0)
return [];

var pkgFullNameList = new PWSTR[count];
var charBuf = new char[bufferLength];
uint props = 0;
fixed (PWSTR* pPkgFullNames = pkgFullNameList)
fixed (char* pBuf = charBuf)
{
var pkgNamesBuf = new PWSTR(pBuf);
result = PInvoke.FindPackagesByPackageFamily(
packageFamily,
PInvoke.PACKAGE_FILTER_HEAD,
ref count,
pPkgFullNames,
ref bufferLength,
pkgNamesBuf,
&props
);
}
if (result is not WIN32_ERROR.NO_ERROR)
throw new Win32Exception((int)result, "Failed to retrieve package names");

return pkgFullNameList.Select(n => n.ToString()).ToList();
}

public static string GetPackageVersion(string packageFullName, string defaultVersion)
{
if (PInvoke.OpenPackageInfoByFullName(packageFullName, out var pkgRef) is WIN32_ERROR.NO_ERROR)
try
{
var handle = Process.GetCurrentProcess().SafeHandle;
uint bufLen = 0;
var result = PInvoke.GetPackageInfo(
pkgRef,
PInvoke.PACKAGE_INFORMATION_BASIC,
&bufLen
);
if (result is not WIN32_ERROR.ERROR_INSUFFICIENT_BUFFER)
return defaultVersion;

var buf = new byte[bufLen];
uint count = 0;
fixed (byte* pBuf = buf)
{
result = PInvoke.GetPackageInfo(
pkgRef,
PInvoke.PACKAGE_INFORMATION_BASIC,
&bufLen,
pBuf,
&count
);
}
if (result is not WIN32_ERROR.NO_ERROR)
return defaultVersion;
// PACKAGE_INFO https://learn.microsoft.com/en-us/windows/win32/api/appmodel/ns-appmodel-package_info

var pkgIdOffset = 4 + 4 + IntPtr.Size * 3;
var revision = BitConverter.ToUInt16(buf, pkgIdOffset + 8);
var build = BitConverter.ToUInt16(buf, pkgIdOffset + 10);
var minor = BitConverter.ToUInt16(buf, pkgIdOffset + 12);
var major = BitConverter.ToUInt16(buf, pkgIdOffset + 14);
return $" v{major}.{minor}.{build}.{revision}";
}
finally
{
PInvoke.ClosePackageInfo(pkgRef);
}
return defaultVersion;
}

public static string GetAppStoreName(string packageFullName, string defaultName)
{
Span<char> staticBuf = stackalloc char[512];
var source = $"@{{{packageFullName}?ms-resource://Microsoft.D3DMappingLayers/Resources/AppStoreName}}";
fixed (char* pBuf = staticBuf)
{
var output = new PWSTR(pBuf);
if (PInvoke.SHLoadIndirectString(source, output, (uint)staticBuf.Length).Succeeded)
return output.ToString();
}
return defaultName;
}
}
9 changes: 9 additions & 0 deletions VkDiag/NativeMethods.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FindPackagesByPackageFamily
PACKAGE_*

OpenPackageInfoByFullName
ClosePackageInfo
GetPackageInfo
GetPackageId

SHLoadIndirectString
42 changes: 42 additions & 0 deletions VkDiag/Program.AppxPackages.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using Windows.Win32;
using Windows.Win32.Foundation;
using VkDiag.Interop;

namespace VkDiag;

internal static partial class Program
{
private static readonly List<(string id, string title)> KnownPackages =
[
("Microsoft.D3DMappingLayers_8wekyb3d8bbwe", "OpenCL, OpenGL, and Vulkan Compatibility Pack"),
];

private static unsafe void CheckAppxPackages()
{
var found = new List<(string name, string version)>();
foreach (var pkg in KnownPackages)
{
try
{
var pkgFullNameList = PackageManager.FindPackagesByPackageFamily(pkg.id);
foreach (var pkgFullName in pkgFullNameList)
{
var appStoreName = PackageManager.GetAppStoreName(pkgFullName, pkg.title);
var ver = PackageManager.GetPackageVersion(pkgFullName, "");
found.Add((appStoreName, ver));
}
}
catch
{}
}
if (found is { Count: > 0 })
{
Console.WriteLine();
WriteLogLine(ConsoleColor.DarkYellow, "!", "Potentially incompatible software:");
foreach (var pkg in found)
WriteLogLine(ConsoleColor.DarkYellow, "!", $" {pkg.name}{pkg.version}");
}
}
}
12 changes: 5 additions & 7 deletions VkDiag/Program.OsInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@ private static Version CheckOs()
try
{
var scope = ManagementPath.DefaultPath.ToString();
using (var searcher = new ManagementObjectSearcher(scope, "SELECT Name FROM CIM_Processor"))
using (var collection = searcher.Get())
using var searcher = new ManagementObjectSearcher(scope, "SELECT Name FROM CIM_Processor");
using var collection = searcher.Get();
foreach (var cpui in collection)
{
foreach (var cpui in collection)
{
var cpuName = cpui.GetPropertyValue("Name") as string;
WriteLogLine(ConsoleColor.Cyan, "i", "CPU: " + cpuName);
}
var cpuName = cpui.GetPropertyValue("Name") as string;
WriteLogLine(ConsoleColor.Cyan, "i", "CPU: " + cpuName);
}
}
#if DEBUG
Expand Down
4 changes: 3 additions & 1 deletion VkDiag/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace VkDiag;

internal static partial class Program
{
private const string VkDiagVersion = "1.2.3";
private const string VkDiagVersion = "1.3.0";

private static bool isAdmin = false;
private static bool autofix = false;
Expand Down Expand Up @@ -52,6 +52,8 @@ public static async Task Main(string[] args)

await CheckVkDiagVersionAsync().ConfigureAwait(false);
var osVer = CheckOs();
if (osVer.Major >= 10)
try { CheckAppxPackages(); } catch { }

var hasInactiveGpus = CheckGpuDrivers();
if (hasInactiveGpus && osVer.Major >= 10)
Expand Down
4 changes: 4 additions & 0 deletions VkDiag/VkDiag.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand All @@ -15,6 +16,9 @@
<PackageReference Include="ILRepack" Version="2.0.18" GeneratePathProperty="true">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.49-beta">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="System.Text.Json" Version="7.0.3" />
</ItemGroup>
Expand Down

0 comments on commit c7c3d33

Please sign in to comment.