mirror of
https://github.com/Orbmu2k/nvidiaProfileInspector.git
synced 2025-12-23 23:18:07 -05:00
added support for descriptions in CSN added setting name filter (CTRL + F) revert with ESCAPE added devmode view (CTRL + ALT + D) and some fixes
241 lines
9.5 KiB
C#
241 lines
9.5 KiB
C#
using nspector.Common.Helper;
|
|
using nspector.Native.NVAPI2;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using nvw = nspector.Native.NVAPI2.NvapiDrsWrapper;
|
|
|
|
namespace nspector.Common
|
|
{
|
|
|
|
|
|
internal class DrsScannerService : DrsSettingsServiceBase
|
|
{
|
|
|
|
public DrsScannerService(DrsSettingsMetaService metaService, DrsDecrypterService decrpterService)
|
|
: base(metaService, decrpterService)
|
|
{ }
|
|
|
|
|
|
internal List<CachedSettings> CachedSettings = new List<CachedSettings>();
|
|
internal List<string> ModifiedProfiles = new List<string>();
|
|
internal HashSet<string> UserProfiles = new HashSet<string>();
|
|
|
|
// most common setting ids as start pattern for the heuristic scan
|
|
private readonly uint[] _commonSettingIds = new uint[] { 0x1095DEF8, 0x1033DCD2, 0x1033CEC1,
|
|
0x10930F46, 0x00A06946, 0x10ECDB82, 0x20EBD7B8, 0x0095DEF9, 0x00D55F7D,
|
|
0x1033DCD3, 0x1033CEC2, 0x2072F036, 0x00664339, 0x002C7F45, 0x209746C1,
|
|
0x0076E164, 0x20FF7493, 0x204CFF7B };
|
|
|
|
|
|
private bool CheckCommonSetting(IntPtr hSession, IntPtr hProfile, NVDRS_PROFILE profile,
|
|
ref int checkedSettingsCount, uint checkSettingId, bool addToScanResult,
|
|
ref List<uint> alreadyCheckedSettingIds)
|
|
{
|
|
|
|
if (checkedSettingsCount >= profile.numOfSettings)
|
|
return false;
|
|
|
|
var setting = new NVDRS_SETTING();
|
|
setting.version = nvw.NVDRS_SETTING_VER;
|
|
|
|
if (nvw.DRS_GetSetting(hSession, hProfile, checkSettingId, ref setting) != NvAPI_Status.NVAPI_OK)
|
|
return false;
|
|
|
|
if (setting.settingLocation != NVDRS_SETTING_LOCATION.NVDRS_CURRENT_PROFILE_LOCATION)
|
|
return false;
|
|
|
|
if (!addToScanResult && setting.isCurrentPredefined == 1)
|
|
{
|
|
checkedSettingsCount++;
|
|
}
|
|
else if (addToScanResult)
|
|
{
|
|
if (decrypter != null)
|
|
{
|
|
decrypter.DecryptSettingIfNeeded(profile.profileName, ref setting);
|
|
}
|
|
|
|
checkedSettingsCount++;
|
|
AddScannedSettingToCache(profile, setting);
|
|
alreadyCheckedSettingIds.Add(setting.settingId);
|
|
return (setting.isCurrentPredefined != 1);
|
|
}
|
|
else if (setting.isCurrentPredefined != 1)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
private int CalcPercent(int current, int max)
|
|
{
|
|
return (current > 0) ? (int)Math.Round((current * 100f) / max) : 0; ;
|
|
}
|
|
|
|
public async Task ScanProfileSettingsAsync(bool justModified, IProgress<int> progress, CancellationToken token = default(CancellationToken))
|
|
{
|
|
await Task.Run(() =>
|
|
{
|
|
ModifiedProfiles = new List<string>();
|
|
UserProfiles = new HashSet<string>();
|
|
var knownPredefines = new List<uint>(_commonSettingIds);
|
|
|
|
DrsSession((hSession) =>
|
|
{
|
|
IntPtr hBaseProfile = GetProfileHandle(hSession, "");
|
|
var profileHandles = EnumProfileHandles(hSession);
|
|
|
|
var maxProfileCount = profileHandles.Count;
|
|
int curProfilePos = 0;
|
|
|
|
foreach (IntPtr hProfile in profileHandles)
|
|
{
|
|
if (token.IsCancellationRequested) break;
|
|
|
|
progress?.Report(CalcPercent(curProfilePos++, maxProfileCount));
|
|
|
|
var profile = GetProfileInfo(hSession, hProfile);
|
|
|
|
int checkedSettingsCount = 0;
|
|
var alreadyChecked = new List<uint>();
|
|
|
|
bool foundModifiedProfile = false;
|
|
if (profile.isPredefined == 0)
|
|
{
|
|
ModifiedProfiles.Add(profile.profileName);
|
|
UserProfiles.Add(profile.profileName);
|
|
foundModifiedProfile = true;
|
|
if (justModified) continue;
|
|
}
|
|
|
|
|
|
foreach (uint kpd in knownPredefines)
|
|
{
|
|
if (CheckCommonSetting(hSession, hProfile, profile,
|
|
ref checkedSettingsCount, kpd, !justModified, ref alreadyChecked))
|
|
{
|
|
if (!foundModifiedProfile)
|
|
{
|
|
foundModifiedProfile = true;
|
|
ModifiedProfiles.Add(profile.profileName);
|
|
if (justModified) break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((foundModifiedProfile && justModified) || checkedSettingsCount >= profile.numOfSettings)
|
|
continue;
|
|
|
|
var settings = GetProfileSettings(hSession, hProfile);
|
|
foreach (var setting in settings)
|
|
{
|
|
if (knownPredefines.IndexOf(setting.settingId) < 0)
|
|
knownPredefines.Add(setting.settingId);
|
|
|
|
if (!justModified && alreadyChecked.IndexOf(setting.settingId) < 0)
|
|
AddScannedSettingToCache(profile, setting);
|
|
|
|
if (setting.isCurrentPredefined != 1)
|
|
{
|
|
if (!foundModifiedProfile)
|
|
{
|
|
foundModifiedProfile = true;
|
|
ModifiedProfiles.Add(profile.profileName);
|
|
if (justModified) break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
});
|
|
}
|
|
|
|
|
|
private void AddScannedSettingToCache(NVDRS_PROFILE profile, NVDRS_SETTING setting)
|
|
{
|
|
// 3D Vision is dead so dont bother scanning those values for improved scan performance
|
|
bool allowAddValue = !((setting.settingId & 0x70000000) == 0x70000000);
|
|
//bool allowAddValue = true;
|
|
|
|
var cachedSetting = CachedSettings
|
|
.FirstOrDefault(x => x.SettingId.Equals(setting.settingId));
|
|
|
|
bool cacheEntryExists = true;
|
|
if (cachedSetting == null)
|
|
{
|
|
cacheEntryExists = false;
|
|
cachedSetting = new CachedSettings(setting.settingId, setting.settingType);
|
|
}
|
|
|
|
if (setting.isPredefinedValid == 1)
|
|
{
|
|
if (allowAddValue)
|
|
{
|
|
if (setting.settingType == NVDRS_SETTING_TYPE.NVDRS_WSTRING_TYPE)
|
|
cachedSetting.AddStringValue(setting.predefinedValue.stringValue, profile.profileName);
|
|
else if (setting.settingType == NVDRS_SETTING_TYPE.NVDRS_DWORD_TYPE)
|
|
cachedSetting.AddDwordValue(setting.predefinedValue.dwordValue, profile.profileName);
|
|
else if (setting.settingType == NVDRS_SETTING_TYPE.NVDRS_BINARY_TYPE)
|
|
cachedSetting.AddBinaryValue(setting.predefinedValue.binaryValue, profile.profileName);
|
|
|
|
}
|
|
else
|
|
cachedSetting.ProfileCount++;
|
|
|
|
if (!cacheEntryExists)
|
|
CachedSettings.Add(cachedSetting);
|
|
}
|
|
|
|
}
|
|
|
|
public string FindProfilesUsingApplication(string applicationName)
|
|
{
|
|
string lowerApplicationName = applicationName.ToLower();
|
|
string tmpfile = TempFile.GetTempFileName();
|
|
|
|
try
|
|
{
|
|
var matchingProfiles = new List<string>();
|
|
|
|
DrsSession((hSession) =>
|
|
{
|
|
SaveSettingsFileEx(hSession, tmpfile);
|
|
});
|
|
|
|
if (File.Exists(tmpfile))
|
|
{
|
|
string content = File.ReadAllText(tmpfile);
|
|
string pattern = "\\sProfile\\s\\\"(?<profile>.*?)\\\"(?<scope>.*?Executable.*?)EndProfile";
|
|
foreach (Match m in Regex.Matches(content, pattern, RegexOptions.Singleline))
|
|
{
|
|
string scope = m.Result("${scope}");
|
|
foreach (Match ms in Regex.Matches(scope, "Executable\\s\\\"(?<app>.*?)\\\"", RegexOptions.Singleline))
|
|
{
|
|
if (ms.Result("${app}").ToLower() == lowerApplicationName)
|
|
{
|
|
matchingProfiles.Add(m.Result("${profile}"));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return string.Join(";", matchingProfiles);
|
|
}
|
|
finally
|
|
{
|
|
if (File.Exists(tmpfile))
|
|
File.Delete(tmpfile);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|