mirror of
https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite.git
synced 2025-12-22 15:59:01 +00:00
Merge pull request #329 from godylockz/master
Fix Internet Explorer Enumeration
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Current Active Window Application");
|
Beaprint.MainPrint("Current Active Window Application");
|
||||||
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
string title = ApplicationInfoHelper.GetActiveWindowTitle();
|
||||||
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> permsFile = PermissionsHelper.GetPermissionsFile(title, Checks.CurrentUserSiDs);
|
||||||
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> permsFolder = PermissionsHelper.GetPermissionsFolder(title, Checks.CurrentUserSiDs);
|
||||||
if (permsFile.Count > 0)
|
if (permsFile.Count > 0)
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" " + title);
|
Beaprint.BadPrint(" " + title);
|
||||||
@@ -188,8 +188,8 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
foreach (Dictionary<string, string> sapp in scheduled_apps)
|
||||||
{
|
{
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(sapp["Action"], Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(sapp["Action"], Checks.CurrentUserSiDs);
|
||||||
string formString = " ({0}) {1}: {2}";
|
string formString = " ({0}) {1}: {2}";
|
||||||
|
|
||||||
if (fileRights.Count > 0)
|
if (fileRights.Count > 0)
|
||||||
@@ -238,8 +238,8 @@ namespace winPEAS.Checks
|
|||||||
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
foreach (var driver in DeviceDrivers.GetDeviceDriversNoMicrosoft())
|
||||||
{
|
{
|
||||||
string pathDriver = driver.Key;
|
string pathDriver = driver.Key;
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(pathDriver, Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> dirRights = PermissionsHelper.GetPermissionsFolder(pathDriver, Checks.CurrentUserSiDs);
|
||||||
|
|
||||||
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
Dictionary<string, string> colorsD = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -363,8 +363,8 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.GrayPrint(" - Creating disabled users list...");
|
Beaprint.GrayPrint(" - Creating disabled users list...");
|
||||||
Checks.PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
PaintDisabledUsers = string.Join("|", User.GetMachineUsers(false, true, false, false, false));
|
||||||
PaintDisabledUsersNoAdministrator = Checks.PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
PaintDisabledUsersNoAdministrator = PaintDisabledUsers.Replace("|Administrator", "").Replace("Administrator|", "").Replace("Administrator", "");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -411,7 +411,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
|
if (RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "" && RegistryHelper.GetRegValue("HKCU", "CONSOLE", "VirtualTerminalLevel") == "")
|
||||||
System.Console.WriteLine(@"ANSI color bit for Windows is not set. If you are execcuting this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
Console.WriteLine(@"ANSI color bit for Windows is not set. If you are executing this from a Windows terminal inside the host you should run 'REG ADD HKCU\Console /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -425,7 +425,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
|
if (RegistryHelper.GetRegValue("HKLM", @"SYSTEM\CurrentControlSet\Control\FileSystem", "LongPathsEnabled") != "1")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
Console.WriteLine(@"Long paths are disabled, so the maximum length of a path supported is 260 chars (this may cause false negatives when looking for files). If you are admin, you can enable it with 'REG ADD HKLM\SYSTEM\CurrentControlSet\Control\FileSystem /v VirtualTerminalLevel /t REG_DWORD /d 1' and then start a new CMD");
|
||||||
IsLongPath = false;
|
IsLongPath = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace winPEAS.Checks
|
|||||||
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
}.ForEach(action => CheckRunner.Run(action, isDebug));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles=true)
|
private static List<CustomFileInfo> InitializeFileSearch(bool useProgramFiles = true)
|
||||||
{
|
{
|
||||||
var files = new List<CustomFileInfo>();
|
var files = new List<CustomFileInfo>();
|
||||||
var systemDrive = $"{SearchHelper.SystemDrive}\\";
|
var systemDrive = $"{SearchHelper.SystemDrive}\\";
|
||||||
@@ -118,7 +118,8 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (isFileFound)
|
if (isFileFound)
|
||||||
{
|
{
|
||||||
if (!somethingFound) {
|
if (!somethingFound)
|
||||||
|
{
|
||||||
Beaprint.MainPrint($"Found {searchName} Files");
|
Beaprint.MainPrint($"Found {searchName} Files");
|
||||||
somethingFound = true;
|
somethingFound = true;
|
||||||
}
|
}
|
||||||
@@ -352,7 +353,7 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string text = System.IO.File.ReadAllText(f.FullPath);
|
string text = File.ReadAllText(f.FullPath);
|
||||||
|
|
||||||
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
results = SearchContent(text, regex.regex, (bool)regex.caseinsensitive);
|
||||||
if (results.Count > 0)
|
if (results.Count > 0)
|
||||||
@@ -451,7 +452,7 @@ namespace winPEAS.Checks
|
|||||||
// If contains undesireable string, stop processing
|
// If contains undesireable string, stop processing
|
||||||
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
|
if (fileSettings.remove_path != null && fileSettings.remove_path.Length > 0)
|
||||||
{
|
{
|
||||||
foreach(var rem_path in fileSettings.remove_path.Split('|'))
|
foreach (var rem_path in fileSettings.remove_path.Split('|'))
|
||||||
{
|
{
|
||||||
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
|
if (fileInfo.FullPath.ToLower().Contains(rem_path.ToLower()))
|
||||||
return false;
|
return false;
|
||||||
@@ -460,19 +461,23 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (fileSettings.type == "f")
|
if (fileSettings.type == "f")
|
||||||
{
|
{
|
||||||
var colors = new Dictionary<string, string>();
|
var colors = new Dictionary<string, string>
|
||||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
{
|
||||||
|
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||||
|
};
|
||||||
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
Beaprint.AnsiPrint($"File: {fileInfo.FullPath}", colors);
|
||||||
|
|
||||||
if (!(bool)fileSettings.just_list_file)
|
if (!(bool)fileSettings.just_list_file)
|
||||||
{
|
{
|
||||||
GrepResult(fileInfo, fileSettings);
|
GrepResult(fileInfo, fileSettings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (fileSettings.type == "d")
|
else if (fileSettings.type == "d")
|
||||||
{
|
{
|
||||||
var colors = new Dictionary<string, string>();
|
var colors = new Dictionary<string, string>
|
||||||
colors.Add(fileInfo.Filename, Beaprint.ansi_color_bad);
|
{
|
||||||
|
{ fileInfo.Filename, Beaprint.ansi_color_bad }
|
||||||
|
};
|
||||||
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
Beaprint.AnsiPrint($"Folder: {fileInfo.FullPath}", colors);
|
||||||
|
|
||||||
// just list the directory
|
// just list the directory
|
||||||
@@ -487,7 +492,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// should not happen
|
// should not happen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace winPEAS.Checks
|
|||||||
internal class FilesInfo : ISystemCheck
|
internal class FilesInfo : ISystemCheck
|
||||||
{
|
{
|
||||||
static readonly string _patternsFileCredsColor = @"RDCMan.settings|.rdg|_history|httpd.conf|.htpasswd|.gitconfig|.git-credentials|Dockerfile|docker-compose.ymlaccess_tokens.db|accessTokens.json|azureProfile.json|appcmd.exe|scclient.exe|unattend.txt|access.log|error.log|credential|password|.gpg|.pgp|config.php|elasticsearch|kibana.|.p12|\.der|.csr|.crt|.cer|.pem|known_hosts|id_rsa|id_dsa|.ovpn|tomcat-users.xml|web.config|.kdbx|.key|KeePass.config|ntds.dir|Ntds.dit|sam|system|SAM|SYSTEM|security|software|SECURITY|SOFTWARE|FreeSSHDservice.ini|sysprep.inf|sysprep.xml|unattend.xml|unattended.xml|vnc|groups.xml|services.xml|scheduledtasks.xml|printers.xml|drives.xml|datasources.xml|php.ini|https.conf|https-xampp.conf|my.ini|my.cnf|access.log|error.log|server.xml|setupinfo|pagefile.sys|NetSetup.log|iis6.log|AppEvent.Evt|SecEvent.Evt|default.sav|security.sav|software.sav|system.sav|ntuser.dat|index.dat|bash.exe|wsl.exe";
|
static readonly string _patternsFileCredsColor = @"RDCMan.settings|.rdg|_history|httpd.conf|.htpasswd|.gitconfig|.git-credentials|Dockerfile|docker-compose.ymlaccess_tokens.db|accessTokens.json|azureProfile.json|appcmd.exe|scclient.exe|unattend.txt|access.log|error.log|credential|password|.gpg|.pgp|config.php|elasticsearch|kibana.|.p12|\.der|.csr|.crt|.cer|.pem|known_hosts|id_rsa|id_dsa|.ovpn|tomcat-users.xml|web.config|.kdbx|.key|KeePass.config|ntds.dir|Ntds.dit|sam|system|SAM|SYSTEM|security|software|SECURITY|SOFTWARE|FreeSSHDservice.ini|sysprep.inf|sysprep.xml|unattend.xml|unattended.xml|vnc|groups.xml|services.xml|scheduledtasks.xml|printers.xml|drives.xml|datasources.xml|php.ini|https.conf|https-xampp.conf|my.ini|my.cnf|access.log|error.log|server.xml|setupinfo|pagefile.sys|NetSetup.log|iis6.log|AppEvent.Evt|SecEvent.Evt|default.sav|security.sav|software.sav|system.sav|ntuser.dat|index.dat|bash.exe|wsl.exe";
|
||||||
// static readonly string _patternsFileCreds = @"RDCMan.settings;*.rdg;*_history*;httpd.conf;.htpasswd;.gitconfig;.git-credentials;Dockerfile;docker-compose.yml;access_tokens.db;accessTokens.json;azureProfile.json;appcmd.exe;scclient.exe;*.gpg$;*.pgp$;*config*.php;elasticsearch.y*ml;kibana.y*ml;*.p12$;*.cer$;known_hosts;*id_rsa*;*id_dsa*;*.ovpn;tomcat-users.xml;web.config;*.kdbx;KeePass.config;Ntds.dit;SAM;SYSTEM;security;software;FreeSSHDservice.ini;sysprep.inf;sysprep.xml;*vnc*.ini;*vnc*.c*nf*;*vnc*.txt;*vnc*.xml;php.ini;https.conf;https-xampp.conf;my.ini;my.cnf;access.log;error.log;server.xml;ConsoleHost_history.txt;pagefile.sys;NetSetup.log;iis6.log;AppEvent.Evt;SecEvent.Evt;default.sav;security.sav;software.sav;system.sav;ntuser.dat;index.dat;bash.exe;wsl.exe;unattend.txt;*.der$;*.csr$;unattend.xml;unattended.xml;groups.xml;services.xml;scheduledtasks.xml;printers.xml;drives.xml;datasources.xml;setupinfo;setupinfo.bak";
|
// static readonly string _patternsFileCreds = @"RDCMan.settings;*.rdg;*_history*;httpd.conf;.htpasswd;.gitconfig;.git-credentials;Dockerfile;docker-compose.yml;access_tokens.db;accessTokens.json;azureProfile.json;appcmd.exe;scclient.exe;*.gpg$;*.pgp$;*config*.php;elasticsearch.y*ml;kibana.y*ml;*.p12$;*.cer$;known_hosts;*id_rsa*;*id_dsa*;*.ovpn;tomcat-users.xml;web.config;*.kdbx;KeePass.config;Ntds.dit;SAM;SYSTEM;security;software;FreeSSHDservice.ini;sysprep.inf;sysprep.xml;*vnc*.ini;*vnc*.c*nf*;*vnc*.txt;*vnc*.xml;php.ini;https.conf;https-xampp.conf;my.ini;my.cnf;access.log;error.log;server.xml;ConsoleHost_history.txt;pagefile.sys;NetSetup.log;iis6.log;AppEvent.Evt;SecEvent.Evt;default.sav;security.sav;software.sav;system.sav;ntuser.dat;index.dat;bash.exe;wsl.exe;unattend.txt;*.der$;*.csr$;unattend.xml;unattended.xml;groups.xml;services.xml;scheduledtasks.xml;printers.xml;drives.xml;datasources.xml;setupinfo;setupinfo.bak";
|
||||||
|
|
||||||
private static readonly IList<string> patternsFileCreds = new List<string>()
|
private static readonly IList<string> patternsFileCreds = new List<string>()
|
||||||
{
|
{
|
||||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
string formString = " {0} ({1})\n Accessed:{2} -- Size:{3}";
|
||||||
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
Beaprint.BadPrint(string.Format(formString, cc["file"], cc["Description"], cc["Accessed"], cc["Size"]));
|
||||||
System.Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -182,7 +182,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
List<string> pwds = Unattended.ExtractUnattendedPwd(path);
|
||||||
Beaprint.BadPrint(" " + path);
|
Beaprint.BadPrint(" " + path);
|
||||||
System.Console.WriteLine(string.Join("\n", pwds));
|
Console.WriteLine(string.Join("\n", pwds));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -233,11 +233,11 @@ namespace winPEAS.Checks
|
|||||||
foreach (var site in sitelistFilesInfo.Sites)
|
foreach (var site in sitelistFilesInfo.Sites)
|
||||||
{
|
{
|
||||||
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
Beaprint.NoColorPrint($" Share Name : {site.ShareName}");
|
||||||
PrintColored( $" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
PrintColored($" User Name : {site.UserName}", !string.IsNullOrWhiteSpace(site.UserName));
|
||||||
PrintColored( $" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
PrintColored($" Server : {site.Server}", !string.IsNullOrWhiteSpace(site.Server));
|
||||||
PrintColored( $" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
PrintColored($" Encrypted Password : {site.EncPassword}", !string.IsNullOrWhiteSpace(site.EncPassword));
|
||||||
PrintColored( $" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
PrintColored($" Decrypted Password : {site.DecPassword}", !string.IsNullOrWhiteSpace(site.DecPassword));
|
||||||
Beaprint.NoColorPrint( $" Domain Name : {site.DomainName}\n" +
|
Beaprint.NoColorPrint($" Domain Name : {site.DomainName}\n" +
|
||||||
$" Name : {site.Name}\n" +
|
$" Name : {site.Name}\n" +
|
||||||
$" Type : {site.Type}\n" +
|
$" Type : {site.Type}\n" +
|
||||||
$" Relative Path : {site.RelativePath}\n");
|
$" Relative Path : {site.RelativePath}\n");
|
||||||
@@ -480,7 +480,7 @@ namespace winPEAS.Checks
|
|||||||
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
if (Regex.Match(rec_file["Name"], pattern.Replace("*", ".*"), RegexOptions.IgnoreCase).Success)
|
||||||
{
|
{
|
||||||
Beaprint.DictPrint(rec_file, colorF, true);
|
Beaprint.DictPrint(rec_file, colorF, true);
|
||||||
System.Console.WriteLine();
|
Console.WriteLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -828,11 +828,11 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
Beaprint.NoColorPrint($" Issuer : {certificateInfo.Issuer}\n" +
|
||||||
$" Subject : {certificateInfo.Subject}\n" +
|
$" Subject : {certificateInfo.Subject}\n" +
|
||||||
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
$" ValidDate : {certificateInfo.ValidDate}\n" +
|
||||||
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
$" ExpiryDate : {certificateInfo.ExpiryDate}\n" +
|
||||||
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
$" HasPrivateKey : {certificateInfo.HasPrivateKey}\n" +
|
||||||
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
$" StoreLocation : {certificateInfo.StoreLocation}\n" +
|
||||||
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
$" KeyExportable : {certificateInfo.KeyExportable}\n" +
|
||||||
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
$" Thumbprint : {certificateInfo.Thumbprint}\n");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
if (!string.IsNullOrEmpty(certificateInfo.Template))
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
if (line.Length > 0 && line[0] != '#')
|
if (line.Length > 0 && line[0] != '#')
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" " + line.Replace("\t", " "));
|
Console.WriteLine(" " + line.Replace("\t", " "));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -304,8 +304,8 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.GrayPrint(" DENY rules:");
|
Beaprint.GrayPrint(" DENY rules:");
|
||||||
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
foreach (Dictionary<string, string> rule in Firewall.GetFirewallRules())
|
||||||
{
|
{
|
||||||
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
string filePerms = string.Join(", ", PermissionsHelper.GetPermissionsFile(rule["AppName"], Checks.CurrentUserSiDs));
|
||||||
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], winPEAS.Checks.Checks.CurrentUserSiDs));
|
string folderPerms = string.Join(", ", PermissionsHelper.GetPermissionsFolder(rule["AppName"], Checks.CurrentUserSiDs));
|
||||||
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
string formString = " ({0}){1}[{2}]: {3} {4} {5} from {6} --> {7}";
|
||||||
if (filePerms.Length > 0)
|
if (filePerms.Length > 0)
|
||||||
formString += "\n File Permissions: {8}";
|
formString += "\n File Permissions: {8}";
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
CheckRunner.Run(() =>
|
CheckRunner.Run(() =>
|
||||||
{
|
{
|
||||||
modifiableServices = ServicesInfoHelper.GetModifiableServices(winPEAS.Checks.Checks.CurrentUserSiDs);
|
modifiableServices = ServicesInfoHelper.GetModifiableServices(Checks.CurrentUserSiDs);
|
||||||
}, isDebug);
|
}, isDebug);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -53,12 +53,12 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (Dictionary<string, string> serviceInfo in services_info)
|
foreach (Dictionary<string, string> serviceInfo in services_info)
|
||||||
{
|
{
|
||||||
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> fileRights = PermissionsHelper.GetPermissionsFile(serviceInfo["FilteredPath"], Checks.CurrentUserSiDs);
|
||||||
List<string> dirRights = new List<string>();
|
List<string> dirRights = new List<string>();
|
||||||
|
|
||||||
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
|
if (serviceInfo["FilteredPath"] != null && serviceInfo["FilteredPath"] != "")
|
||||||
{
|
{
|
||||||
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), winPEAS.Checks.Checks.CurrentUserSiDs);
|
dirRights = PermissionsHelper.GetPermissionsFolder(Path.GetDirectoryName(serviceInfo["FilteredPath"]), Checks.CurrentUserSiDs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
|
bool noQuotesAndSpace = MyUtils.CheckQuoteAndSpace(serviceInfo["PathName"]);
|
||||||
@@ -159,7 +159,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking if you can modify any service registry");
|
Beaprint.MainPrint("Looking if you can modify any service registry");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services-registry-permissions", "Check if you can modify the registry of a service");
|
||||||
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<Dictionary<string, string>> regPerms = ServicesInfoHelper.GetWriteServiceRegs(Checks.CurrentUserSiDs);
|
||||||
|
|
||||||
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
|
Dictionary<string, string> colorsWR = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using winPEAS._3rdParty.Watson;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.AppLocker;
|
using winPEAS.Helpers.AppLocker;
|
||||||
using winPEAS._3rdParty.Watson;
|
|
||||||
using winPEAS.Info.SystemInfo.Printers;
|
|
||||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
|
||||||
using winPEAS.Info.SystemInfo;
|
|
||||||
using winPEAS.Info.SystemInfo.SysMon;
|
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
using winPEAS.Info.SystemInfo;
|
||||||
using winPEAS.Info.SystemInfo.AuditPolicies;
|
using winPEAS.Info.SystemInfo.AuditPolicies;
|
||||||
using winPEAS.Info.SystemInfo.DotNet;
|
using winPEAS.Info.SystemInfo.DotNet;
|
||||||
using winPEAS.Info.SystemInfo.GroupPolicy;
|
using winPEAS.Info.SystemInfo.GroupPolicy;
|
||||||
using winPEAS.Info.SystemInfo.WindowsDefender;
|
using winPEAS.Info.SystemInfo.NamedPipes;
|
||||||
using winPEAS.Info.SystemInfo.PowerShell;
|
|
||||||
using winPEAS.Info.SystemInfo.Ntlm;
|
using winPEAS.Info.SystemInfo.Ntlm;
|
||||||
|
using winPEAS.Info.SystemInfo.PowerShell;
|
||||||
|
using winPEAS.Info.SystemInfo.Printers;
|
||||||
|
using winPEAS.Info.SystemInfo.SysMon;
|
||||||
|
using winPEAS.Info.SystemInfo.WindowsDefender;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
namespace winPEAS.Checks
|
namespace winPEAS.Checks
|
||||||
@@ -107,7 +107,7 @@ namespace winPEAS.Checks
|
|||||||
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
{ Globals.StrTrue, Beaprint.ansi_color_bad },
|
||||||
};
|
};
|
||||||
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
Beaprint.DictPrint(basicDictSystem, colorsSI, false);
|
||||||
System.Console.WriteLine();
|
Console.WriteLine();
|
||||||
Watson.FindVulns();
|
Watson.FindVulns();
|
||||||
|
|
||||||
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
|
//To update Watson, update the CVEs and add the new ones and update the main function so it uses new CVEs (becausfull with the Beaprints inside the FindVulns function)
|
||||||
@@ -200,7 +200,7 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.MainPrint("PS default transcripts history");
|
Beaprint.MainPrint("PS default transcripts history");
|
||||||
Beaprint.InfoPrint("Read the PS history inside these files (if any)");
|
Beaprint.InfoPrint("Read the PS history inside these files (if any)");
|
||||||
string drive = Path.GetPathRoot(Environment.SystemDirectory);
|
string drive = Path.GetPathRoot(Environment.SystemDirectory);
|
||||||
string transcriptsPath = drive + @"transcripts\";
|
string transcriptsPath = drive + @"transcripts\";
|
||||||
string usersPath = $"{drive}users";
|
string usersPath = $"{drive}users";
|
||||||
|
|
||||||
var users = Directory.EnumerateDirectories(usersPath, "*", SearchOption.TopDirectoryOnly);
|
var users = Directory.EnumerateDirectories(usersPath, "*", SearchOption.TopDirectoryOnly);
|
||||||
@@ -369,12 +369,12 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
if (lsaCfgFlags == "1")
|
if (lsaCfgFlags == "1")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
||||||
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
|
Beaprint.GoodPrint(" CredentialGuard is active with UEFI lock");
|
||||||
}
|
}
|
||||||
else if (lsaCfgFlags == "2")
|
else if (lsaCfgFlags == "2")
|
||||||
{
|
{
|
||||||
System.Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
Console.WriteLine(" Please, note that this only checks the LsaCfgFlags key value. This is not enough to enable Credentials Guard (but it's a strong indicator).");
|
||||||
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
|
Beaprint.GoodPrint(" CredentialGuard is active without UEFI lock");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -572,7 +572,7 @@ namespace winPEAS.Checks
|
|||||||
else if (using_HKLM_WSUS == "0")
|
else if (using_HKLM_WSUS == "0")
|
||||||
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
Beaprint.GoodPrint(" But UseWUServer is equals to 0, so it is not vulnerable!");
|
||||||
else
|
else
|
||||||
System.Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
|
Console.WriteLine(" But UseWUServer is equals to " + using_HKLM_WSUS + ", so it may work or not");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1070,7 +1070,7 @@ namespace winPEAS.Checks
|
|||||||
}
|
}
|
||||||
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
|
else if (kvp.Value.GetType().IsArray && (kvp.Value.GetType().GetElementType().ToString() == "System.Byte"))
|
||||||
{
|
{
|
||||||
val = System.BitConverter.ToString((byte[])kvp.Value);
|
val = BitConverter.ToString((byte[])kvp.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1086,12 +1086,12 @@ namespace winPEAS.Checks
|
|||||||
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
|
Beaprint.BadPrint(" [!] WDigest is enabled - plaintext password extraction is possible!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.Equals("RunAsPPL", System.StringComparison.InvariantCultureIgnoreCase) && val == "1")
|
if (key.Equals("RunAsPPL", StringComparison.InvariantCultureIgnoreCase) && val == "1")
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
|
Beaprint.BadPrint(" [!] LSASS Protected Mode is enabled! You will not be able to access lsass.exe's memory easily.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.Equals("DisableRestrictedAdmin", System.StringComparison.InvariantCultureIgnoreCase) && val == "0")
|
if (key.Equals("DisableRestrictedAdmin", StringComparison.InvariantCultureIgnoreCase) && val == "0")
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
|
Beaprint.BadPrint(" [!] RDP Restricted Admin Mode is enabled! You can use pass-the-hash to access RDP on this system.");
|
||||||
}
|
}
|
||||||
@@ -1107,7 +1107,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine" );
|
Beaprint.MainPrint("Display Local Group Policy settings - local users/machine");
|
||||||
|
|
||||||
var infos = GroupPolicy.GetLocalGroupPolicyInfos();
|
var infos = GroupPolicy.GetLocalGroupPolicyInfos();
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Extensions;
|
using winPEAS.Helpers.Extensions;
|
||||||
@@ -158,7 +156,7 @@ namespace winPEAS.Checks
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("RDP Sessions");
|
Beaprint.MainPrint("RDP Sessions");
|
||||||
List<Dictionary<string, string>> rdp_sessions = Info.UserInfo.UserInfoHelper.GetRDPSessions();
|
List<Dictionary<string, string>> rdp_sessions = UserInfoHelper.GetRDPSessions();
|
||||||
if (rdp_sessions.Count > 0)
|
if (rdp_sessions.Count > 0)
|
||||||
{
|
{
|
||||||
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
|
string format = " {0,-10}{1,-15}{2,-15}{3,-25}{4,-10}{5}";
|
||||||
@@ -263,7 +261,7 @@ namespace winPEAS.Checks
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Password Policies");
|
Beaprint.MainPrint("Password Policies");
|
||||||
Beaprint.LinkPrint("", "Check for a possible brute-force");
|
Beaprint.LinkPrint("", "Check for a possible brute-force");
|
||||||
List<Dictionary<string, string>> PPy = Info.UserInfo.UserInfoHelper.GetPasswordPolicy();
|
List<Dictionary<string, string>> PPy = UserInfoHelper.GetPasswordPolicy();
|
||||||
Beaprint.DictPrint(PPy, ColorsU(), false);
|
Beaprint.DictPrint(PPy, ColorsU(), false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -282,7 +280,7 @@ namespace winPEAS.Checks
|
|||||||
|
|
||||||
foreach (var logonSession in logonSessions)
|
foreach (var logonSession in logonSessions)
|
||||||
{
|
{
|
||||||
Beaprint.NoColorPrint ($" Method: {logonSession.Method}\n" +
|
Beaprint.NoColorPrint($" Method: {logonSession.Method}\n" +
|
||||||
$" Logon Server: {logonSession.LogonServer}\n" +
|
$" Logon Server: {logonSession.LogonServer}\n" +
|
||||||
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
$" Logon Server Dns Domain: {logonSession.LogonServerDnsDomain}\n" +
|
||||||
$" Logon Id: {logonSession.LogonId}\n" +
|
$" Logon Id: {logonSession.LogonId}\n" +
|
||||||
@@ -317,7 +315,7 @@ namespace winPEAS.Checks
|
|||||||
if (User32.GetLastInputInfo(ref lastInputInfo))
|
if (User32.GetLastInputInfo(ref lastInputInfo))
|
||||||
{
|
{
|
||||||
var currentUser = WindowsIdentity.GetCurrent().Name;
|
var currentUser = WindowsIdentity.GetCurrent().Name;
|
||||||
var idleTimeMiliSeconds = (uint) Environment.TickCount - lastInputInfo.Time;
|
var idleTimeMiliSeconds = (uint)Environment.TickCount - lastInputInfo.Time;
|
||||||
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
var timeSpan = TimeSpan.FromMilliseconds(idleTimeMiliSeconds);
|
||||||
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
var idleTimeString = $"{timeSpan.Hours:D2}h:{timeSpan.Minutes:D2}m:{timeSpan.Seconds:D2}s:{timeSpan.Milliseconds:D3}ms";
|
||||||
|
|
||||||
@@ -364,7 +362,7 @@ namespace winPEAS.Checks
|
|||||||
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
|
lastLogon = lastLogon.AddSeconds(localUser.last_logon).ToLocalTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
Beaprint.AnsiPrint( $" Computer Name : {computerName}\n" +
|
Beaprint.AnsiPrint($" Computer Name : {computerName}\n" +
|
||||||
$" User Name : {localUser.name}\n" +
|
$" User Name : {localUser.name}\n" +
|
||||||
$" User Id : {localUser.user_id}\n" +
|
$" User Id : {localUser.user_id}\n" +
|
||||||
$" Is Enabled : {enabled}\n" +
|
$" Is Enabled : {enabled}\n" +
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
|
var color = GetColorBySid(filePublisherRule.UserOrGroupSid);
|
||||||
|
|
||||||
Beaprint.ColorPrint( $" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
|
Beaprint.ColorPrint($" User Or Group Sid: {filePublisherRule.UserOrGroupSid}\n", color);
|
||||||
|
|
||||||
Beaprint.GoodPrint($" Conditions");
|
Beaprint.GoodPrint($" Conditions");
|
||||||
|
|
||||||
@@ -153,7 +153,7 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
var color = GetColorBySid(filePathRule.UserOrGroupSid);
|
var color = GetColorBySid(filePathRule.UserOrGroupSid);
|
||||||
|
|
||||||
Beaprint.ColorPrint( $" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
|
Beaprint.ColorPrint($" User Or Group Sid: {filePathRule.UserOrGroupSid}\n", color);
|
||||||
|
|
||||||
Beaprint.GoodPrint($" Conditions");
|
Beaprint.GoodPrint($" Conditions");
|
||||||
|
|
||||||
@@ -328,39 +328,42 @@ namespace winPEAS.Helpers.AppLocker
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var subfolders = Directory.EnumerateDirectories(path);
|
if (Directory.Exists(path))
|
||||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
|
||||||
|
|
||||||
ruleType = ruleType.ToLower();
|
|
||||||
|
|
||||||
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
|
|
||||||
{
|
{
|
||||||
throw new ArgumentException(nameof(ruleType));
|
var subfolders = Directory.EnumerateDirectories(path);
|
||||||
}
|
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
var filteredFiles =
|
ruleType = ruleType.ToLower();
|
||||||
(from file in files
|
|
||||||
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
|
|
||||||
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
|
|
||||||
select file).ToList();
|
|
||||||
|
|
||||||
// first check write access for files
|
if (!_appLockerFileExtensionsByType.ContainsKey(ruleType))
|
||||||
if (filteredFiles.Any(CheckFileWriteAccess))
|
{
|
||||||
{
|
throw new ArgumentException(nameof(ruleType));
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// if we have not found any writable file,
|
var filteredFiles =
|
||||||
// check subfolders for write access
|
(from file in files
|
||||||
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
|
let extension = Path.GetExtension(file)?.ToLower() ?? string.Empty
|
||||||
{
|
where _appLockerFileExtensionsByType[ruleType].Contains(extension)
|
||||||
return true;
|
select file).ToList();
|
||||||
}
|
|
||||||
|
|
||||||
// check recursively all the subfolders for files/sub-subfolders
|
// first check write access for files
|
||||||
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
|
if (filteredFiles.Any(CheckFileWriteAccess))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we have not found any writable file,
|
||||||
|
// check subfolders for write access
|
||||||
|
if (subfolders.Any(subfolder => CheckDirectoryWriteAccess(subfolder, out bool _, isGoodPrint: false)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check recursively all the subfolders for files/sub-subfolders
|
||||||
|
if (subfolders.Any(subfolder => CheckFilesAndSubfolders(subfolder, ruleType, depth + 1)))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -5,79 +5,79 @@ using System.Runtime.InteropServices;
|
|||||||
namespace winPEAS.Helpers.AppLocker
|
namespace winPEAS.Helpers.AppLocker
|
||||||
{
|
{
|
||||||
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
||||||
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
|
[TypeLibType(TypeLibTypeFlags.FDual | TypeLibTypeFlags.FNonExtensible | TypeLibTypeFlags.FDispatchable)]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public interface IAppIdPolicyHandler
|
public interface IAppIdPolicyHandler
|
||||||
{
|
{
|
||||||
// Token: 0x06000001 RID: 1
|
// Token: 0x06000001 RID: 1
|
||||||
[DispId(1)]
|
[DispId(1)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
||||||
|
|
||||||
// Token: 0x06000002 RID: 2
|
// Token: 0x06000002 RID: 2
|
||||||
[DispId(2)]
|
[DispId(2)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
||||||
|
|
||||||
// Token: 0x06000003 RID: 3
|
// Token: 0x06000003 RID: 3
|
||||||
[DispId(3)]
|
[DispId(3)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
string GetEffectivePolicy();
|
string GetEffectivePolicy();
|
||||||
|
|
||||||
// Token: 0x06000004 RID: 4
|
// Token: 0x06000004 RID: 4
|
||||||
[DispId(4)]
|
[DispId(4)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
|
|
||||||
// Token: 0x06000005 RID: 5
|
// Token: 0x06000005 RID: 5
|
||||||
[DispId(5)]
|
[DispId(5)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token: 0x02000003 RID: 3
|
// Token: 0x02000003 RID: 3
|
||||||
[CoClass(typeof(AppIdPolicyHandlerClass))]
|
[CoClass(typeof(AppIdPolicyHandlerClass))]
|
||||||
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
[Guid("B6FEA19E-32DD-4367-B5B7-2F5DA140E87D")]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public interface AppIdPolicyHandler : IAppIdPolicyHandler
|
public interface AppIdPolicyHandler : IAppIdPolicyHandler
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Token: 0x02000004 RID: 4
|
// Token: 0x02000004 RID: 4
|
||||||
[Guid("F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3")]
|
[Guid("F1ED7D4C-F863-4DE6-A1CA-7253EFDEE1F3")]
|
||||||
[ClassInterface(ClassInterfaceType.None)]
|
[ClassInterface(ClassInterfaceType.None)]
|
||||||
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
[TypeLibType(TypeLibTypeFlags.FCanCreate)]
|
||||||
[ComImport]
|
[ComImport]
|
||||||
public class AppIdPolicyHandlerClass : IAppIdPolicyHandler, AppIdPolicyHandler
|
public class AppIdPolicyHandlerClass : IAppIdPolicyHandler, AppIdPolicyHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
// Token: 0x06000007 RID: 7
|
// Token: 0x06000007 RID: 7
|
||||||
[DispId(1)]
|
[DispId(1)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
public virtual extern void SetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath, [MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy);
|
||||||
|
|
||||||
// Token: 0x06000008 RID: 8
|
// Token: 0x06000008 RID: 8
|
||||||
[DispId(2)]
|
[DispId(2)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
public virtual extern string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
public virtual extern string GetPolicy([MarshalAs(UnmanagedType.BStr)][In] string bstrLdapPath);
|
||||||
|
|
||||||
// Token: 0x06000009 RID: 9
|
// Token: 0x06000009 RID: 9
|
||||||
[DispId(3)]
|
[DispId(3)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
[return: MarshalAs(UnmanagedType.BStr)]
|
[return: MarshalAs(UnmanagedType.BStr)]
|
||||||
public virtual extern string GetEffectivePolicy();
|
public virtual extern string GetEffectivePolicy();
|
||||||
|
|
||||||
// Token: 0x0600000A RID: 10
|
// Token: 0x0600000A RID: 10
|
||||||
[DispId(4)]
|
[DispId(4)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
public virtual extern int IsFileAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrFilePath, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
|
|
||||||
// Token: 0x0600000B RID: 11
|
// Token: 0x0600000B RID: 11
|
||||||
[DispId(5)]
|
[DispId(5)]
|
||||||
[MethodImpl(MethodImplOptions.InternalCall)]
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
public virtual extern int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
public virtual extern int IsPackageAllowed([MarshalAs(UnmanagedType.BStr)][In] string bstrXmlPolicy, [MarshalAs(UnmanagedType.BStr)][In] string bstrPublisherName, [MarshalAs(UnmanagedType.BStr)][In] string bstrPackageName, [In] ulong ullPackageVersion, [MarshalAs(UnmanagedType.BStr)][In] string bstrUserSid, out Guid pguidResponsibleRuleId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -105,7 +104,7 @@ namespace winPEAS.Helpers
|
|||||||
|
|
||||||
PrintLegend();
|
PrintLegend();
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: "+YELLOW+"https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
|
Console.WriteLine(BLUE + " You can find a Windows local PE Checklist here: " + YELLOW + "https://book.hacktricks.xyz/windows-hardening/checklist-windows-privilege-escalation");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintLegend()
|
static void PrintLegend()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
using System.Text;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.Win32.SafeHandles;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
namespace winPEAS.Helpers.CredentialManager
|
namespace winPEAS.Helpers.CredentialManager
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -244,7 +242,7 @@ namespace winPEAS.Helpers
|
|||||||
{
|
{
|
||||||
|
|
||||||
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
string perm = PermissionsHelper.PermInt2Str((int)h.GrantedAccess, PermissionType.WRITEABLE_OR_EQUIVALENT);
|
||||||
if (perm != null && perm.Length> 0)
|
if (perm != null && perm.Length > 0)
|
||||||
{
|
{
|
||||||
vulnHandler.isVuln = true;
|
vulnHandler.isVuln = true;
|
||||||
vulnHandler.reason = perm;
|
vulnHandler.reason = perm;
|
||||||
@@ -438,9 +436,11 @@ namespace winPEAS.Helpers
|
|||||||
// Get the owner of a process given the PID
|
// Get the owner of a process given the PID
|
||||||
public static Dictionary<string, string> GetProcU(Process p)
|
public static Dictionary<string, string> GetProcU(Process p)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> data = new Dictionary<string, string>();
|
Dictionary<string, string> data = new Dictionary<string, string>
|
||||||
data["name"] = "";
|
{
|
||||||
data["sid"] = "";
|
["name"] = "",
|
||||||
|
["sid"] = ""
|
||||||
|
};
|
||||||
IntPtr pHandle = IntPtr.Zero;
|
IntPtr pHandle = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -471,7 +471,7 @@ namespace winPEAS.Helpers
|
|||||||
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
PT_RELEVANT_INFO pri = new PT_RELEVANT_INFO();
|
||||||
|
|
||||||
Process proc = Process.GetProcessById(pid);
|
Process proc = Process.GetProcessById(pid);
|
||||||
Dictionary<string,string> user = GetProcU(proc);
|
Dictionary<string, string> user = GetProcU(proc);
|
||||||
|
|
||||||
StringBuilder fileName = new StringBuilder(2000);
|
StringBuilder fileName = new StringBuilder(2000);
|
||||||
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
Native.Psapi.GetProcessImageFileName(proc.Handle, fileName, 2000);
|
||||||
@@ -586,7 +586,7 @@ namespace winPEAS.Helpers
|
|||||||
{ // This shouldn't be needed
|
{ // This shouldn't be needed
|
||||||
if (path.StartsWith("\\"))
|
if (path.StartsWith("\\"))
|
||||||
path = path.Substring(1);
|
path = path.Substring(1);
|
||||||
hive = Helpers.Registry.RegistryHelper.CheckIfExists(path);
|
hive = Registry.RegistryHelper.CheckIfExists(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path.StartsWith("\\"))
|
if (path.StartsWith("\\"))
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace winPEAS.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Check if rundll32
|
//Check if rundll32
|
||||||
string[] binaryPathdll32 = binaryPath.Split(new string[] {"Rundll32.exe"}, StringSplitOptions.None);
|
string[] binaryPathdll32 = binaryPath.Split(new string[] { "Rundll32.exe" }, StringSplitOptions.None);
|
||||||
|
|
||||||
if (binaryPathdll32.Length > 1)
|
if (binaryPathdll32.Length > 1)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ namespace winPEAS.Helpers
|
|||||||
return strOutput;
|
return strOutput;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string[] suffixes = new[] {" B", " KB", " MB", " GB", " TB", " PB"};
|
private static string[] suffixes = new[] { " B", " KB", " MB", " GB", " TB", " PB" };
|
||||||
|
|
||||||
public static string ConvertBytesToHumanReadable(double number, int precision = 2)
|
public static string ConvertBytesToHumanReadable(double number, int precision = 2)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
@@ -354,14 +354,17 @@ namespace winPEAS.Helpers
|
|||||||
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
results[path] = String.Join(", ", GetPermissionsFolder(path, Checks.Checks.CurrentUserSiDs));
|
||||||
if (string.IsNullOrEmpty(results[path]))
|
if (string.IsNullOrEmpty(results[path]))
|
||||||
{
|
{
|
||||||
foreach (string d in Directory.EnumerateDirectories(path))
|
if (Directory.Exists(path))
|
||||||
{
|
{
|
||||||
foreach (string f in Directory.EnumerateFiles(d))
|
foreach (string d in Directory.EnumerateDirectories(path))
|
||||||
{
|
{
|
||||||
results[f] = String.Join(", ", GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs));
|
foreach (string f in Directory.EnumerateFiles(d))
|
||||||
|
{
|
||||||
|
results[f] = String.Join(", ", GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs));
|
||||||
|
}
|
||||||
|
cont += 1;
|
||||||
|
results.Concat(GetRecursivePrivs(d, cont)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
||||||
}
|
}
|
||||||
cont += 1;
|
|
||||||
results.Concat(GetRecursivePrivs(d, cont)).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,85 +4,85 @@ using System.Threading;
|
|||||||
|
|
||||||
namespace winPEAS.Helpers
|
namespace winPEAS.Helpers
|
||||||
{
|
{
|
||||||
internal class ProgressBar : IDisposable, IProgress<double>
|
internal class ProgressBar : IDisposable, IProgress<double>
|
||||||
{
|
{
|
||||||
private const int blockCount = 10;
|
private const int blockCount = 10;
|
||||||
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
|
private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8);
|
||||||
private const string animation = @"|/-\";
|
private const string animation = @"|/-\";
|
||||||
|
|
||||||
private readonly Timer timer;
|
private readonly Timer timer;
|
||||||
|
|
||||||
private double currentProgress = 0;
|
private double currentProgress = 0;
|
||||||
private string currentText = string.Empty;
|
private string currentText = string.Empty;
|
||||||
private bool disposed = false;
|
private bool disposed = false;
|
||||||
private int animationIndex = 0;
|
private int animationIndex = 0;
|
||||||
|
|
||||||
public ProgressBar()
|
public ProgressBar()
|
||||||
{
|
{
|
||||||
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
|
timer = new Timer(TimerHandler, new object(), animationInterval, animationInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Report(double value)
|
public void Report(double value)
|
||||||
{
|
{
|
||||||
// Make sure value is in [0..1] range
|
// Make sure value is in [0..1] range
|
||||||
value = Math.Max(0, Math.Min(1, value));
|
value = Math.Max(0, Math.Min(1, value));
|
||||||
Interlocked.Exchange(ref currentProgress, value);
|
Interlocked.Exchange(ref currentProgress, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TimerHandler(object state)
|
private void TimerHandler(object state)
|
||||||
{
|
{
|
||||||
lock (timer)
|
lock (timer)
|
||||||
{
|
{
|
||||||
if (disposed) return;
|
if (disposed) return;
|
||||||
|
|
||||||
int progressBlockCount = (int)(currentProgress * blockCount);
|
int progressBlockCount = (int)(currentProgress * blockCount);
|
||||||
int percent = (int)(currentProgress * 100);
|
int percent = (int)(currentProgress * 100);
|
||||||
string text = string.Format("[{0}{1}] {2,3}% {3}",
|
string text = string.Format("[{0}{1}] {2,3}% {3}",
|
||||||
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
|
new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount),
|
||||||
percent,
|
percent,
|
||||||
animation[animationIndex++ % animation.Length]);
|
animation[animationIndex++ % animation.Length]);
|
||||||
UpdateText(text);
|
UpdateText(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateText(string text)
|
private void UpdateText(string text)
|
||||||
{
|
{
|
||||||
// Get length of common portion
|
// Get length of common portion
|
||||||
int commonPrefixLength = 0;
|
int commonPrefixLength = 0;
|
||||||
int commonLength = Math.Min(currentText.Length, text.Length);
|
int commonLength = Math.Min(currentText.Length, text.Length);
|
||||||
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
|
while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength])
|
||||||
{
|
{
|
||||||
commonPrefixLength++;
|
commonPrefixLength++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backtrack to the first differing character
|
// Backtrack to the first differing character
|
||||||
StringBuilder outputBuilder = new StringBuilder();
|
StringBuilder outputBuilder = new StringBuilder();
|
||||||
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
|
outputBuilder.Append('\b', currentText.Length - commonPrefixLength);
|
||||||
|
|
||||||
// Output new suffix
|
// Output new suffix
|
||||||
outputBuilder.Append(text.Substring(commonPrefixLength));
|
outputBuilder.Append(text.Substring(commonPrefixLength));
|
||||||
|
|
||||||
// If the new text is shorter than the old one: delete overlapping characters
|
// If the new text is shorter than the old one: delete overlapping characters
|
||||||
int overlapCount = currentText.Length - text.Length;
|
int overlapCount = currentText.Length - text.Length;
|
||||||
if (overlapCount > 0)
|
if (overlapCount > 0)
|
||||||
{
|
{
|
||||||
outputBuilder.Append(' ', overlapCount);
|
outputBuilder.Append(' ', overlapCount);
|
||||||
outputBuilder.Append('\b', overlapCount);
|
outputBuilder.Append('\b', overlapCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.Write(outputBuilder);
|
Console.Write(outputBuilder);
|
||||||
currentText = text;
|
currentText = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
lock (timer)
|
lock (timer)
|
||||||
{
|
{
|
||||||
disposed = true;
|
disposed = true;
|
||||||
UpdateText(string.Empty);
|
UpdateText(string.Empty);
|
||||||
timer.Dispose();
|
timer.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Win32;
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers.Registry
|
namespace winPEAS.Helpers.Registry
|
||||||
{
|
{
|
||||||
@@ -177,7 +177,7 @@ namespace winPEAS.Helpers.Registry
|
|||||||
|
|
||||||
internal static uint? GetDwordValue(string hive, string key, string val)
|
internal static uint? GetDwordValue(string hive, string key, string val)
|
||||||
{
|
{
|
||||||
string strValue = RegistryHelper.GetRegValue(hive, key, val);
|
string strValue = GetRegValue(hive, key, val);
|
||||||
|
|
||||||
if (uint.TryParse(strValue, out uint res))
|
if (uint.TryParse(strValue, out uint res))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
Beaprint.LongPathWarning(f.FullName);
|
Beaprint.LongPathWarning(f.FullName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) ;
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -221,43 +221,43 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
// c:\users
|
// c:\users
|
||||||
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
string rootUsersSearchPath = $"{SystemDrive}\\Users\\";
|
||||||
SearchHelper.RootDirUsers = SearchHelper.GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
RootDirUsers = GetFilesFast(rootUsersSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\users\current_user
|
// c:\users\current_user
|
||||||
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
string rootCurrentUserSearchPath = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
SearchHelper.RootDirCurrentUser = SearchHelper.GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
RootDirCurrentUser = GetFilesFast(rootCurrentUserSearchPath, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Program Files\
|
// c:\Program Files\
|
||||||
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
string rootProgramFiles = $"{SystemDrive}\\Program Files\\";
|
||||||
SearchHelper.ProgramFiles = SearchHelper.GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
|
ProgramFiles = GetFilesFast(rootProgramFiles, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Program Files (x86)\
|
// c:\Program Files (x86)\
|
||||||
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
string rootProgramFilesX86 = $"{SystemDrive}\\Program Files (x86)\\";
|
||||||
SearchHelper.ProgramFilesX86 = SearchHelper.GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
ProgramFilesX86 = GetFilesFast(rootProgramFilesX86, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Documents and Settings\
|
// c:\Documents and Settings\
|
||||||
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
string documentsAndSettings = $"{SystemDrive}\\Documents and Settings\\";
|
||||||
SearchHelper.DocumentsAndSettings = SearchHelper.GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
|
DocumentsAndSettings = GetFilesFast(documentsAndSettings, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\ProgramData\Microsoft\Group Policy\History
|
// c:\ProgramData\Microsoft\Group Policy\History
|
||||||
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistory = $"{SystemDrive}\\ProgramData\\Microsoft\\Group Policy\\History";
|
||||||
SearchHelper.GroupPolicyHistory = SearchHelper.GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
|
GroupPolicyHistory = GetFilesFast(groupPolicyHistory, GlobalPattern, isFoldersIncluded: true);
|
||||||
|
|
||||||
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
// c:\Documents and Settings\All Users\Application Data\\Microsoft\\Group Policy\\History
|
||||||
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
string groupPolicyHistoryLegacy = $"{documentsAndSettings}\\All Users\\Application Data\\Microsoft\\Group Policy\\History";
|
||||||
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
//SearchHelper.GroupPolicyHistoryLegacy = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, globalPattern);
|
||||||
var groupPolicyHistoryLegacyFiles = SearchHelper.GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
var groupPolicyHistoryLegacyFiles = GetFilesFast(groupPolicyHistoryLegacy, GlobalPattern, isFoldersIncluded: true);
|
||||||
SearchHelper.GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
GroupPolicyHistory.AddRange(groupPolicyHistoryLegacyFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void CleanLists()
|
internal static void CleanLists()
|
||||||
{
|
{
|
||||||
SearchHelper.RootDirUsers = null;
|
RootDirUsers = null;
|
||||||
SearchHelper.RootDirCurrentUser = null;
|
RootDirCurrentUser = null;
|
||||||
SearchHelper.ProgramFiles = null;
|
ProgramFiles = null;
|
||||||
SearchHelper.ProgramFilesX86 = null;
|
ProgramFilesX86 = null;
|
||||||
SearchHelper.DocumentsAndSettings = null;
|
DocumentsAndSettings = null;
|
||||||
SearchHelper.GroupPolicyHistory = null;
|
GroupPolicyHistory = null;
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".*password.*"
|
".*password.*"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirUsers)
|
foreach (var file in RootDirUsers)
|
||||||
{
|
{
|
||||||
//string extLower = file.Extension.ToLower();
|
//string extLower = file.Extension.ToLower();
|
||||||
|
|
||||||
@@ -297,7 +297,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
{
|
{
|
||||||
var result = new List<string>();
|
var result = new List<string>();
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
foreach (var file in RootDirCurrentUser)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -337,7 +337,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".xml"
|
".xml"
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.GroupPolicyHistory)
|
foreach (var file in GroupPolicyHistory)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -361,14 +361,14 @@ namespace winPEAS.Helpers.Search
|
|||||||
};
|
};
|
||||||
|
|
||||||
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
string programDataPath = $"{SystemDrive}\\ProgramData\\";
|
||||||
var programData = SearchHelper.GetFilesFast(programDataPath, GlobalPattern);
|
var programData = GetFilesFast(programDataPath, GlobalPattern);
|
||||||
|
|
||||||
var searchFiles = new List<CustomFileInfo>();
|
var searchFiles = new List<CustomFileInfo>();
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFiles);
|
searchFiles.AddRange(ProgramFiles);
|
||||||
searchFiles.AddRange(SearchHelper.ProgramFilesX86);
|
searchFiles.AddRange(ProgramFilesX86);
|
||||||
searchFiles.AddRange(programData);
|
searchFiles.AddRange(programData);
|
||||||
searchFiles.AddRange(SearchHelper.DocumentsAndSettings);
|
searchFiles.AddRange(DocumentsAndSettings);
|
||||||
searchFiles.AddRange(SearchHelper.RootDirUsers);
|
searchFiles.AddRange(RootDirUsers);
|
||||||
|
|
||||||
foreach (var file in searchFiles)
|
foreach (var file in searchFiles)
|
||||||
{
|
{
|
||||||
@@ -403,7 +403,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".pdf",
|
".pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirCurrentUser)
|
foreach (var file in RootDirCurrentUser)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
@@ -451,7 +451,7 @@ namespace winPEAS.Helpers.Search
|
|||||||
".pdf",
|
".pdf",
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var file in SearchHelper.RootDirUsers)
|
foreach (var file in RootDirUsers)
|
||||||
{
|
{
|
||||||
if (!file.IsDirectory)
|
if (!file.IsDirectory)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public RegularExpression[] regexes { get; set; }
|
public RegularExpression[] regexes { get; set; }
|
||||||
public class RegularExpression {
|
public class RegularExpression
|
||||||
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public string regex { get; set; }
|
public string regex { get; set; }
|
||||||
|
|
||||||
@@ -25,65 +26,65 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
|
|
||||||
public class FileParam
|
public class FileParam
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public FileSettings value { get; set; }
|
public FileSettings value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchParameters
|
public class SearchParameters
|
||||||
{
|
{
|
||||||
public class FileSettings
|
public class FileSettings
|
||||||
{
|
{
|
||||||
public string bad_regex { get; set; }
|
public string bad_regex { get; set; }
|
||||||
// public string check_extra_path { get; set; } // not used in Winpeas
|
// public string check_extra_path { get; set; } // not used in Winpeas
|
||||||
public string good_regex { get; set; }
|
public string good_regex { get; set; }
|
||||||
public bool? just_list_file { get; set; }
|
public bool? just_list_file { get; set; }
|
||||||
public string line_grep { get; set; }
|
public string line_grep { get; set; }
|
||||||
public bool? only_bad_lines { get; set; }
|
public bool? only_bad_lines { get; set; }
|
||||||
public bool? remove_empty_lines { get; set; }
|
public bool? remove_empty_lines { get; set; }
|
||||||
// public string remove_path { get; set; } // not used in Winpeas
|
// public string remove_path { get; set; } // not used in Winpeas
|
||||||
public string remove_regex { get; set; }
|
public string remove_regex { get; set; }
|
||||||
public string remove_path { get; set; }
|
public string remove_path { get; set; }
|
||||||
// public string[] search_in { get; set; } // not used in Winpeas
|
// public string[] search_in { get; set; } // not used in Winpeas
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
public FileParam[] files { get; set; }
|
public FileParam[] files { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FileParameters
|
public class FileParameters
|
||||||
{
|
{
|
||||||
public string file { get; set; }
|
public string file { get; set; }
|
||||||
public FileSettings options { get; set; }
|
public FileSettings options { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Config
|
public class Config
|
||||||
{
|
{
|
||||||
public bool auto_check { get; set; }
|
public bool auto_check { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public Config config { get; set; }
|
public Config config { get; set; }
|
||||||
public string[] disable { get; set; } // disabled scripts - linpeas/winpeas
|
public string[] disable { get; set; } // disabled scripts - linpeas/winpeas
|
||||||
public FileParam[] files { get; set; }
|
public FileParam[] files { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SearchParams
|
public class SearchParams
|
||||||
{
|
{
|
||||||
public string name { get; set; }
|
public string name { get; set; }
|
||||||
public SearchParameters value { get; set; }
|
public SearchParameters value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Defaults
|
public class Defaults
|
||||||
{
|
{
|
||||||
public bool auto_check { get; set; }
|
public bool auto_check { get; set; }
|
||||||
public string bad_regex { get; set; }
|
public string bad_regex { get; set; }
|
||||||
//public string check_extra_path { get; set; } not used in winpeas
|
//public string check_extra_path { get; set; } not used in winpeas
|
||||||
public string good_regex { get; set; }
|
public string good_regex { get; set; }
|
||||||
public bool just_list_file { get; set; }
|
public bool just_list_file { get; set; }
|
||||||
public string line_grep { get; set; }
|
public string line_grep { get; set; }
|
||||||
public bool only_bad_lines { get; set; }
|
public bool only_bad_lines { get; set; }
|
||||||
public bool remove_empty_lines { get; set; }
|
public bool remove_empty_lines { get; set; }
|
||||||
public string remove_path { get; set; }
|
public string remove_path { get; set; }
|
||||||
public string remove_regex { get; set; }
|
public string remove_regex { get; set; }
|
||||||
public string[] search_in { get; set; }
|
public string[] search_in { get; set; }
|
||||||
public string type { get; set; }
|
public string type { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Variable
|
public class Variable
|
||||||
@@ -92,9 +93,9 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
public string value { get; set; }
|
public string value { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public SearchParams[] search { get; set; }
|
public SearchParams[] search { get; set; }
|
||||||
|
|
||||||
public Defaults defaults { get; set; }
|
public Defaults defaults { get; set; }
|
||||||
|
|
||||||
public Variable[] variables { get; set; }
|
public Variable[] variables { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Yaml.Serialization;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Yaml.Serialization;
|
||||||
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
using static winPEAS.Helpers.YamlConfig.YamlConfig;
|
||||||
using static winPEAS.Helpers.YamlConfig.YamlRegexConfig;
|
|
||||||
|
|
||||||
|
|
||||||
namespace winPEAS.Helpers.YamlConfig
|
namespace winPEAS.Helpers.YamlConfig
|
||||||
@@ -30,7 +29,7 @@ namespace winPEAS.Helpers.YamlConfig
|
|||||||
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
|
YamlRegexConfig yamlConfig = (YamlRegexConfig)yamlSerializer.Deserialize(configFileContent, typeof(YamlRegexConfig))[0];
|
||||||
|
|
||||||
// check
|
// check
|
||||||
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
|
if (yamlConfig.regular_expresions == null || yamlConfig.regular_expresions.Length == 0)
|
||||||
{
|
{
|
||||||
throw new System.Exception("No configuration was read");
|
throw new System.Exception("No configuration was read");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
{
|
{
|
||||||
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
|
autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name, autorunLocationKey[2]
|
||||||
}
|
}
|
||||||
: new List<string> {autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name});
|
: new List<string> { autorunLocationKey[0], autorunLocationKey[1] + "\\" + clsid_name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,15 +344,18 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var userDirs = Directory.EnumerateDirectories(usersPath);
|
if (Directory.Exists(usersPath))
|
||||||
|
|
||||||
foreach (var userDir in userDirs)
|
|
||||||
{
|
{
|
||||||
string startupPath = $@"{userDir}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup";
|
var userDirs = Directory.EnumerateDirectories(usersPath);
|
||||||
|
|
||||||
if (Directory.Exists(startupPath))
|
foreach (var userDir in userDirs)
|
||||||
{
|
{
|
||||||
autorunLocations.Add(startupPath);
|
string startupPath = $@"{userDir}\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup";
|
||||||
|
|
||||||
|
if (Directory.Exists(startupPath))
|
||||||
|
{
|
||||||
|
autorunLocations.Add(startupPath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -364,22 +367,25 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
if (Directory.Exists(path))
|
||||||
|
|
||||||
foreach (string filepath in files)
|
|
||||||
{
|
{
|
||||||
string folder = Path.GetDirectoryName(filepath);
|
var files = Directory.EnumerateFiles(path, "*", SearchOption.TopDirectoryOnly);
|
||||||
results.Add(new Dictionary<string, string>() {
|
|
||||||
{ "Reg", "" },
|
foreach (string filepath in files)
|
||||||
{ "RegKey", "" },
|
{
|
||||||
{ "RegPermissions", "" },
|
string folder = Path.GetDirectoryName(filepath);
|
||||||
{ "Folder", folder },
|
results.Add(new Dictionary<string, string>() {
|
||||||
{ "File", filepath },
|
{ "Reg", "" },
|
||||||
{ "isWritableReg", ""},
|
{ "RegKey", "" },
|
||||||
{ "interestingFolderRights", string.Join(", ", PermissionsHelper.GetPermissionsFolder(folder, Checks.Checks.CurrentUserSiDs))},
|
{ "RegPermissions", "" },
|
||||||
{ "interestingFileRights", string.Join(", ", PermissionsHelper.GetPermissionsFile(filepath, Checks.Checks.CurrentUserSiDs))},
|
{ "Folder", folder },
|
||||||
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(path).ToString() }
|
{ "File", filepath },
|
||||||
});
|
{ "isWritableReg", ""},
|
||||||
|
{ "interestingFolderRights", string.Join(", ", PermissionsHelper.GetPermissionsFolder(folder, Checks.Checks.CurrentUserSiDs))},
|
||||||
|
{ "interestingFileRights", string.Join(", ", PermissionsHelper.GetPermissionsFile(filepath, Checks.Checks.CurrentUserSiDs))},
|
||||||
|
{ "isUnquotedSpaced", MyUtils.CheckQuoteAndSpace(path).ToString() }
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -71,16 +71,19 @@ namespace winPEAS.Info.ApplicationInfo
|
|||||||
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
var results = new SortedDictionary<string, Dictionary<string, string>>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
foreach (string f in Directory.EnumerateFiles(fpath))
|
if (Directory.Exists(fpath))
|
||||||
{
|
{
|
||||||
results[f] = new Dictionary<string, string>
|
foreach (string f in Directory.EnumerateFiles(fpath))
|
||||||
|
{
|
||||||
|
results[f] = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
{ f, string.Join(", ", PermissionsHelper.GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs)) }
|
{ f, string.Join(", ", PermissionsHelper.GetPermissionsFile(f, Checks.Checks.CurrentUserSiDs)) }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
foreach (string d in Directory.EnumerateDirectories(fpath))
|
foreach (string d in Directory.EnumerateDirectories(fpath))
|
||||||
{
|
{
|
||||||
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
results[d] = PermissionsHelper.GetRecursivePrivs(d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Info.EventsInfo.PowerShell;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
namespace winPEAS.Info.EventsInfo.ProcessCreation
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,19 +34,19 @@ namespace winPEAS.Info.FilesInfo.Certificates
|
|||||||
switch (ext.Oid.FriendlyName)
|
switch (ext.Oid.FriendlyName)
|
||||||
{
|
{
|
||||||
case "Enhanced Key Usage":
|
case "Enhanced Key Usage":
|
||||||
{
|
|
||||||
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
|
||||||
|
|
||||||
if (extUsages.Count == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (var extUsage in extUsages)
|
|
||||||
{
|
{
|
||||||
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
var extUsages = ((X509EnhancedKeyUsageExtension)ext).EnhancedKeyUsages;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
if (extUsages.Count == 0)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
|
foreach (var extUsage in extUsages)
|
||||||
|
{
|
||||||
|
enhancedKeyUsages.Add(extUsage.FriendlyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "Certificate Template Name":
|
case "Certificate Template Name":
|
||||||
case "Certificate Template Information":
|
case "Certificate Template Information":
|
||||||
template = ext.Format(false);
|
template = ext.Format(false);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ namespace winPEAS.Info.FilesInfo.McAfee
|
|||||||
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
byte[] XORKey = { 0x12, 0x15, 0x0F, 0x10, 0x11, 0x1C, 0x1A, 0x06, 0x0A, 0x1F, 0x1B, 0x18, 0x17, 0x16, 0x05, 0x19 };
|
||||||
|
|
||||||
// xor the input b64 string with the static XOR key
|
// xor the input b64 string with the static XOR key
|
||||||
var passwordBytes = System.Convert.FromBase64String(base64password);
|
var passwordBytes = Convert.FromBase64String(base64password);
|
||||||
for (var i = 0; i < passwordBytes.Length; i++)
|
for (var i = 0; i < passwordBytes.Length; i++)
|
||||||
{
|
{
|
||||||
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
passwordBytes[i] = (byte)(passwordBytes[i] ^ XORKey[i % XORKey.Length]);
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
using winPEAS.Info.FilesInfo.Office.OneDrive;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
|
||||||
@@ -25,7 +24,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
Type firewall = Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"));
|
||||||
object firewallObj = Activator.CreateInstance(firewall);
|
object firewallObj = Activator.CreateInstance(firewall);
|
||||||
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
object types = ReflectionHelper.InvokeMemberProperty(firewallObj, "CurrentProfileTypes");
|
||||||
result = $"{(FirewallProfiles) int.Parse(types.ToString())}";
|
result = $"{(FirewallProfiles)int.Parse(types.ToString())}";
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,12 +191,12 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
foreach (var listener in props.GetActiveTcpListeners())
|
foreach (var listener in props.GetActiveTcpListeners())
|
||||||
{
|
{
|
||||||
bool repeated = false;
|
bool repeated = false;
|
||||||
foreach(List<string> inside_entry in results)
|
foreach (List<string> inside_entry in results)
|
||||||
{
|
{
|
||||||
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
|
if (inside_entry.SequenceEqual(new List<string>() { "TCP", listener.ToString(), "", "Listening" }))
|
||||||
repeated = true;
|
repeated = true;
|
||||||
}
|
}
|
||||||
if (! repeated)
|
if (!repeated)
|
||||||
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
results.Add(new List<string>() { "TCP", listener.ToString(), "", "Listening" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +337,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
// Determine if IPv4 or IPv6.
|
// Determine if IPv4 or IPv6.
|
||||||
if (ipVersion == IPVersion.IPv4)
|
if (ipVersion == IPVersion.IPv4)
|
||||||
{
|
{
|
||||||
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
|
MIB_TCPTABLE_OWNER_PID tcpRecordsTable = (MIB_TCPTABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCPTABLE_OWNER_PID));
|
||||||
|
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
@@ -373,7 +373,7 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
}
|
}
|
||||||
else if (ipVersion == IPVersion.IPv6)
|
else if (ipVersion == IPVersion.IPv6)
|
||||||
{
|
{
|
||||||
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID) Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
|
MIB_TCP6TABLE_OWNER_PID tcpRecordsTable = (MIB_TCP6TABLE_OWNER_PID)Marshal.PtrToStructure(tcpTableRecordsPtr, typeof(MIB_TCP6TABLE_OWNER_PID));
|
||||||
|
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)tcpTableRecordsPtr + Marshal.SizeOf(tcpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
@@ -461,14 +461,14 @@ namespace winPEAS.Info.NetworkInfo
|
|||||||
// Determine if IPv4 or IPv6.
|
// Determine if IPv4 or IPv6.
|
||||||
if (ipVersion == IPVersion.IPv4)
|
if (ipVersion == IPVersion.IPv4)
|
||||||
{
|
{
|
||||||
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID) Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
|
MIB_UDPTABLE_OWNER_PID udpRecordsTable = (MIB_UDPTABLE_OWNER_PID)Marshal.PtrToStructure(udpTableRecordsPtr, typeof(MIB_UDPTABLE_OWNER_PID));
|
||||||
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
|
IntPtr tableRowPtr = (IntPtr)((long)udpTableRecordsPtr + Marshal.SizeOf(udpRecordsTable.dwNumEntries));
|
||||||
|
|
||||||
// Read and parse the UDP records from the table and store them in list
|
// Read and parse the UDP records from the table and store them in list
|
||||||
// 'UdpConnection' structure type objects.
|
// 'UdpConnection' structure type objects.
|
||||||
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
|
for (int i = 0; i < udpRecordsTable.dwNumEntries; i++)
|
||||||
{
|
{
|
||||||
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID) Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
|
MIB_UDPROW_OWNER_PID udpRow = (MIB_UDPROW_OWNER_PID)Marshal.PtrToStructure(tableRowPtr, typeof(MIB_UDPROW_OWNER_PID));
|
||||||
udpTableRecords.Add(new UdpConnectionInfo(
|
udpTableRecords.Add(new UdpConnectionInfo(
|
||||||
Protocol.UDP,
|
Protocol.UDP,
|
||||||
new IPAddress(udpRow.localAddr),
|
new IPAddress(udpRow.localAddr),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
|||||||
public struct MIB_UDP6TABLE_OWNER_PID
|
public struct MIB_UDP6TABLE_OWNER_PID
|
||||||
{
|
{
|
||||||
public uint dwNumEntries;
|
public uint dwNumEntries;
|
||||||
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)]
|
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
|
||||||
public MIB_UDP6ROW_OWNER_PID[] table;
|
public MIB_UDP6ROW_OWNER_PID[] table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace winPEAS.Info.NetworkInfo.Structs
|
|||||||
public struct MIB_UDPTABLE_OWNER_PID
|
public struct MIB_UDPTABLE_OWNER_PID
|
||||||
{
|
{
|
||||||
public uint dwNumEntries;
|
public uint dwNumEntries;
|
||||||
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct,SizeConst = 1)]
|
[MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
|
||||||
public MIB_UDPROW_OWNER_PID[] table;
|
public MIB_UDPROW_OWNER_PID[] table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Linq;
|
|||||||
using System.Management;
|
using System.Management;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
@@ -33,7 +32,7 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
Proc = p,
|
Proc = p,
|
||||||
Pth = (string)mo["ExecutablePath"],
|
Pth = (string)mo["ExecutablePath"],
|
||||||
CommLine = (string)mo["CommandLine"],
|
CommLine = (string)mo["CommandLine"],
|
||||||
Owner = Helpers.HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
Owner = HandlesHelper.GetProcU(p)["name"], //Needed inside the next foreach
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (var itm in queRy)
|
foreach (var itm in queRy)
|
||||||
@@ -54,14 +53,16 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
}
|
}
|
||||||
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
if ((string.IsNullOrEmpty(companyName)) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||||
to_add["Name"] = itm.Proc.ProcessName;
|
{
|
||||||
to_add["ProcessID"] = itm.Proc.Id.ToString();
|
["Name"] = itm.Proc.ProcessName,
|
||||||
to_add["ExecutablePath"] = itm.Pth;
|
["ProcessID"] = itm.Proc.Id.ToString(),
|
||||||
to_add["Product"] = companyName;
|
["ExecutablePath"] = itm.Pth,
|
||||||
to_add["Owner"] = itm.Owner == null ? "" : itm.Owner;
|
["Product"] = companyName,
|
||||||
to_add["isDotNet"] = isDotNet;
|
["Owner"] = itm.Owner == null ? "" : itm.Owner,
|
||||||
to_add["CommandLine"] = itm.CommLine;
|
["isDotNet"] = isDotNet,
|
||||||
|
["CommandLine"] = itm.CommLine
|
||||||
|
};
|
||||||
f_results.Add(to_add);
|
f_results.Add(to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,11 +124,13 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
|
|
||||||
string hName = HandlesHelper.GetObjectName(dupHandle);
|
string hName = HandlesHelper.GetObjectName(dupHandle);
|
||||||
|
|
||||||
Dictionary<string, string> to_add = new Dictionary<string, string>();
|
Dictionary<string, string> to_add = new Dictionary<string, string>
|
||||||
to_add["Handle Name"] = hName;
|
{
|
||||||
to_add["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")";
|
["Handle Name"] = hName,
|
||||||
to_add["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName;
|
["Handle"] = h.HandleValue.ToString() + "(" + typeName + ")",
|
||||||
to_add["Reason"] = handlerExp.reason;
|
["Handle Owner"] = "Pid is " + h.UniqueProcessId.ToString() + "(" + origProcInfo.name + ") with owner: " + origProcInfo.userName,
|
||||||
|
["Reason"] = handlerExp.reason
|
||||||
|
};
|
||||||
|
|
||||||
if (typeName == "process" || typeName == "thread")
|
if (typeName == "process" || typeName == "thread")
|
||||||
{
|
{
|
||||||
@@ -208,7 +211,7 @@ namespace winPEAS.Info.ProcessInfo
|
|||||||
else if (typeName == "key")
|
else if (typeName == "key")
|
||||||
{
|
{
|
||||||
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
HandlesHelper.KEY_RELEVANT_INFO kri = HandlesHelper.getKeyHandlerInfo(dupHandle);
|
||||||
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length> 0)
|
if (kri.path.Length == 0 && kri.hive != null && kri.hive.Length > 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
RegistryKey regKey = Helpers.Registry.RegistryHelper.GetReg(kri.hive, kri.path);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -8,10 +9,8 @@ using System.Runtime.InteropServices;
|
|||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
|
|
||||||
namespace winPEAS.Info.ServicesInfo
|
namespace winPEAS.Info.ServicesInfo
|
||||||
@@ -51,17 +50,18 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
if (string.IsNullOrEmpty(companyName) || (!Regex.IsMatch(companyName, @"^Microsoft.*", RegexOptions.IgnoreCase)))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> toadd = new Dictionary<string, string>();
|
Dictionary<string, string> toadd = new Dictionary<string, string>
|
||||||
|
{
|
||||||
toadd["Name"] = GetStringOrEmpty(result["Name"]);
|
["Name"] = GetStringOrEmpty(result["Name"]),
|
||||||
toadd["DisplayName"] = GetStringOrEmpty(result["DisplayName"]);
|
["DisplayName"] = GetStringOrEmpty(result["DisplayName"]),
|
||||||
toadd["CompanyName"] = companyName;
|
["CompanyName"] = companyName,
|
||||||
toadd["State"] = GetStringOrEmpty(result["State"]);
|
["State"] = GetStringOrEmpty(result["State"]),
|
||||||
toadd["StartMode"] = GetStringOrEmpty(result["StartMode"]);
|
["StartMode"] = GetStringOrEmpty(result["StartMode"]),
|
||||||
toadd["PathName"] = GetStringOrEmpty(result["PathName"]);
|
["PathName"] = GetStringOrEmpty(result["PathName"]),
|
||||||
toadd["FilteredPath"] = binaryPath;
|
["FilteredPath"] = binaryPath,
|
||||||
toadd["isDotNet"] = isDotNet;
|
["isDotNet"] = isDotNet,
|
||||||
toadd["Description"] = GetStringOrEmpty(result["Description"]);
|
["Description"] = GetStringOrEmpty(result["Description"])
|
||||||
|
};
|
||||||
|
|
||||||
results.Add(toadd);
|
results.Add(toadd);
|
||||||
}
|
}
|
||||||
@@ -232,7 +232,7 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
if (permissions.Count > 0)
|
if (permissions.Count > 0)
|
||||||
{
|
{
|
||||||
string perms = String.Join(", ", permissions);
|
string perms = String.Join(", ", permissions);
|
||||||
if (perms.Replace("Start", "").Replace("Stop","").Length > 3) //Check if any other permissions appart from Start and Stop
|
if (perms.Replace("Start", "").Replace("Stop", "").Length > 3) //Check if any other permissions appart from Start and Stop
|
||||||
results.Add(sc.ServiceName, perms);
|
results.Add(sc.ServiceName, perms);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,9 +249,9 @@ namespace winPEAS.Info.ServicesInfo
|
|||||||
/////// Find Write reg. Services ////////
|
/////// Find Write reg. Services ////////
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
/// Find Services which Reg you have write or equivalent access
|
/// Find Services which Reg you have write or equivalent access
|
||||||
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string,string> NtAccountNames)
|
public static List<Dictionary<string, string>> GetWriteServiceRegs(Dictionary<string, string> NtAccountNames)
|
||||||
{
|
{
|
||||||
List<Dictionary<string,string>> results = new List<Dictionary<string, string>>();
|
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
|
RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"system\currentcontrolset\services");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using Microsoft.Win32;
|
||||||
using Microsoft.Win32;
|
using System.Collections.Generic;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.IO;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using System.Security.Principal;
|
|
||||||
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.NamedPipes
|
namespace winPEAS.Info.SystemInfo.NamedPipes
|
||||||
@@ -51,7 +50,7 @@ namespace winPEAS.Info.SystemInfo.NamedPipes
|
|||||||
{
|
{
|
||||||
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
var security = File.GetAccessControl($"\\\\.\\pipe\\{namedPipe}");
|
||||||
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
|
sddl = security.GetSecurityDescriptorSddlForm(AccessControlSections.All);
|
||||||
List<string> currentUserPermsList = winPEAS.Helpers.PermissionsHelper.GetMyPermissionsF(security, winPEAS.Checks.Checks.CurrentUserSiDs);
|
List<string> currentUserPermsList = Helpers.PermissionsHelper.GetMyPermissionsF(security, Checks.Checks.CurrentUserSiDs);
|
||||||
currentUserPerms = string.Join(", ", currentUserPermsList);
|
currentUserPerms = string.Join(", ", currentUserPermsList);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics.Eventing.Reader;
|
using System.Diagnostics.Eventing.Reader;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ using System.Net.NetworkInformation;
|
|||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo
|
namespace winPEAS.Info.SystemInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
@@ -17,7 +15,7 @@ namespace winPEAS.Info.SystemInfo.WindowsDefender
|
|||||||
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
public WindowsDefenderSettings(string defenderBaseKeyPath)
|
||||||
{
|
{
|
||||||
PathExclusions = new List<string>();
|
PathExclusions = new List<string>();
|
||||||
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{ defenderBaseKeyPath}\\Exclusions\\Paths");
|
var pathExclusionData = RegistryHelper.GetRegValues("HKLM", $"{defenderBaseKeyPath}\\Exclusions\\Paths");
|
||||||
if (pathExclusionData != null)
|
if (pathExclusionData != null)
|
||||||
{
|
{
|
||||||
foreach (var kvp in pathExclusionData)
|
foreach (var kvp in pathExclusionData)
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.Info.SystemInfo.WindowsDefender
|
|
||||||
{
|
{
|
||||||
class WindowsDefenderSettingsInfo
|
class WindowsDefenderSettingsInfo
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Classes;
|
using winPEAS.Native.Classes;
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.NetworkInformation;
|
using System.Net.NetworkInformation;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
|
|
||||||
namespace winPEAS.Info.UserInfo
|
namespace winPEAS.Info.UserInfo
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using winPEAS.Helpers;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Structs;
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace winPEAS.Info.UserInfo.Token
|
|||||||
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
Advapi32.LookupPrivilegeName(null, luidPointer, null, ref luidNameLen);
|
||||||
strBuilder.EnsureCapacity(luidNameLen + 1);
|
strBuilder.EnsureCapacity(luidNameLen + 1);
|
||||||
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
if (Advapi32.LookupPrivilegeName(null, luidPointer, strBuilder, ref luidNameLen))
|
||||||
results[strBuilder.ToString()] = $"{(LuidAttributes) laa.Attributes}";
|
results[strBuilder.ToString()] = $"{(LuidAttributes)laa.Attributes}";
|
||||||
Marshal.FreeHGlobal(luidPointer);
|
Marshal.FreeHGlobal(luidPointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ using System.Management;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Structs;
|
using winPEAS.Native.Structs;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ using System.Windows.Forms;
|
|||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
using winPEAS.Info.UserInfo.SAM;
|
using winPEAS.Info.UserInfo.SAM;
|
||||||
using winPEAS.KnownFileCreds;
|
|
||||||
using winPEAS.Native;
|
using winPEAS.Native;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
|
|
||||||
@@ -251,14 +250,15 @@ namespace winPEAS.Info.UserInfo
|
|||||||
|
|
||||||
public static Dictionary<string, string> GetAutoLogon()
|
public static Dictionary<string, string> GetAutoLogon()
|
||||||
{
|
{
|
||||||
Dictionary<string, string> results = new Dictionary<string, string>();
|
Dictionary<string, string> results = new Dictionary<string, string>
|
||||||
|
{
|
||||||
results["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName");
|
["DefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultDomainName"),
|
||||||
results["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName");
|
["DefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultUserName"),
|
||||||
results["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword");
|
["DefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "DefaultPassword"),
|
||||||
results["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName");
|
["AltDefaultDomainName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultDomainName"),
|
||||||
results["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName");
|
["AltDefaultUserName"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultUserName"),
|
||||||
results["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword");
|
["AltDefaultPassword"] = RegistryHelper.GetRegValue("HKLM", "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "AltDefaultPassword")
|
||||||
|
};
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,7 +281,7 @@ namespace winPEAS.Info.UserInfo
|
|||||||
c = $"{Clipboard.GetFileDropList()}";
|
c = $"{Clipboard.GetFileDropList()}";
|
||||||
|
|
||||||
//else if (Clipboard.ContainsImage()) //No system.Drwing import
|
//else if (Clipboard.ContainsImage()) //No system.Drwing import
|
||||||
//c = string.Format("{0}", Clipboard.GetImage());
|
//c = string.Format("{0}", Clipboard.GetImage());
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string allUsers = System.Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
string allUsers = Environment.GetEnvironmentVariable("ALLUSERSPROFILE");
|
||||||
|
|
||||||
if (!allUsers.Contains("ProgramData"))
|
if (!allUsers.Contains("ProgramData"))
|
||||||
{
|
{
|
||||||
@@ -225,11 +225,13 @@ namespace winPEAS.InterestingFiles
|
|||||||
Changed = "[BLANK]";
|
Changed = "[BLANK]";
|
||||||
}
|
}
|
||||||
|
|
||||||
results[file] = new Dictionary<string, string>();
|
results[file] = new Dictionary<string, string>
|
||||||
results[file]["UserName"] = UserName;
|
{
|
||||||
results[file]["NewName"] = NewName;
|
["UserName"] = UserName,
|
||||||
results[file]["cPassword"] = cPassword;
|
["NewName"] = NewName,
|
||||||
results[file]["Changed"] = Changed;
|
["cPassword"] = cPassword,
|
||||||
|
["Changed"] = Changed
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
$@"{systemRoot}\System32\config\RegBack\SYSTEM",
|
||||||
};
|
};
|
||||||
|
|
||||||
results.AddRange(searchLocations.Where(searchLocation => System.IO.File.Exists(searchLocation)));
|
results.AddRange(searchLocations.Where(searchLocation => File.Exists(searchLocation)));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -102,7 +102,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
|
// Reference: https://stackoverflow.com/questions/18071412/list-filenames-in-the-recyclebin-with-c-sharp-without-using-any-external-files
|
||||||
int lastDays = 30;
|
int lastDays = 30;
|
||||||
|
|
||||||
var startTime = System.DateTime.Now.AddDays(-lastDays);
|
var startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
// Shell COM object GUID
|
// Shell COM object GUID
|
||||||
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
Type shell = Type.GetTypeFromCLSID(new Guid("13709620-C279-11CE-A49E-444553540000"));
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var winDir = System.Environment.GetEnvironmentVariable("windir");
|
var winDir = Environment.GetEnvironmentVariable("windir");
|
||||||
string[] searchLocations =
|
string[] searchLocations =
|
||||||
{
|
{
|
||||||
$"{winDir}\\sysprep\\sysprep.xml",
|
$"{winDir}\\sysprep\\sysprep.xml",
|
||||||
@@ -56,7 +56,7 @@ namespace winPEAS.InterestingFiles
|
|||||||
$"{winDir}\\..\\unattend.inf",
|
$"{winDir}\\..\\unattend.inf",
|
||||||
};
|
};
|
||||||
|
|
||||||
results.AddRange(searchLocations.Where(System.IO.File.Exists));
|
results.AddRange(searchLocations.Where(File.Exists));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Web.Script.Serialization;
|
using System.Web.Script.Serialization;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
@@ -27,7 +28,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for Chrome DBs");
|
Beaprint.MainPrint("Looking for Chrome DBs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, string> chromeDBs = Chrome.GetChromeDbs();
|
Dictionary<string, string> chromeDBs = GetChromeDbs();
|
||||||
|
|
||||||
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
|
if (chromeDBs.ContainsKey("userChromeCookiesPath"))
|
||||||
{
|
{
|
||||||
@@ -59,7 +60,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
|
Beaprint.MainPrint("Looking for GET credentials in Chrome history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, List<string>> chromeHistBook = Chrome.GetChromeHistBook();
|
Dictionary<string, List<string>> chromeHistBook = GetChromeHistBook();
|
||||||
List<string> history = chromeHistBook["history"];
|
List<string> history = chromeHistBook["history"];
|
||||||
List<string> bookmarks = chromeHistBook["bookmarks"];
|
List<string> bookmarks = chromeHistBook["bookmarks"];
|
||||||
|
|
||||||
@@ -77,8 +78,11 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"Chrome history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -130,14 +134,14 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userChromeCookiesPath =
|
string userChromeCookiesPath =
|
||||||
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
|
$"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Cookies";
|
||||||
if (File.Exists(userChromeCookiesPath))
|
if (File.Exists(userChromeCookiesPath))
|
||||||
{
|
{
|
||||||
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
results["userChromeCookiesPath"] = userChromeCookiesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
string userChromeLoginDataPath =
|
string userChromeLoginDataPath =
|
||||||
$"{System.Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
|
$"{Environment.GetEnvironmentVariable("USERPROFILE")}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data";
|
||||||
if (File.Exists(userChromeLoginDataPath))
|
if (File.Exists(userChromeLoginDataPath))
|
||||||
{
|
{
|
||||||
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
results["userChromeLoginDataPath"] = userChromeLoginDataPath;
|
||||||
@@ -156,7 +160,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
List<string> results = new List<string>();
|
List<string> results = new List<string>();
|
||||||
|
|
||||||
// parses a Chrome history file via regex
|
// parses a Chrome history file via regex
|
||||||
if (System.IO.File.Exists(path))
|
if (File.Exists(path))
|
||||||
{
|
{
|
||||||
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
Regex historyRegex = new Regex(@"(http|ftp|https|file)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?");
|
||||||
|
|
||||||
@@ -217,10 +221,10 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userChromeHistoryPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
results["history"] = ParseChromeHistory(userChromeHistoryPath);
|
||||||
|
|
||||||
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userChromeBookmarkPath = string.Format("{0}\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Bookmarks", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
|
||||||
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
results["bookmarks"] = ParseChromeBookmarks(userChromeBookmarkPath);
|
||||||
}
|
}
|
||||||
@@ -241,7 +245,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Chrome
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string contents = System.IO.File.ReadAllText(path);
|
string contents = File.ReadAllText(path);
|
||||||
|
|
||||||
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
// reference: http://www.tomasvera.com/programming/using-javascriptserializer-to-parse-json-objects/
|
||||||
JavaScriptSerializer json = new JavaScriptSerializer();
|
JavaScriptSerializer json = new JavaScriptSerializer();
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
using System;
|
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|
||||||
{
|
{
|
||||||
class FFLogins
|
class FFLogins
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ using System.Data;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Web.Script.Serialization;
|
||||||
|
using winPEAS._3rdParty.SQLite;
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.KnownFileCreds.Browsers.Models;
|
using winPEAS.KnownFileCreds.Browsers.Models;
|
||||||
using winPEAS._3rdParty.SQLite;
|
|
||||||
using System.Web.Script.Serialization;
|
|
||||||
|
|
||||||
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
||||||
{
|
{
|
||||||
@@ -29,7 +29,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for Firefox DBs");
|
Beaprint.MainPrint("Looking for Firefox DBs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> firefoxDBs = Firefox.GetFirefoxDbs();
|
List<string> firefoxDBs = GetFirefoxDbs();
|
||||||
if (firefoxDBs.Count > 0)
|
if (firefoxDBs.Count > 0)
|
||||||
{
|
{
|
||||||
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
|
foreach (string firefoxDB in firefoxDBs) //No Beaprints because line needs red
|
||||||
@@ -56,21 +56,26 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
|
Beaprint.MainPrint("Looking for GET credentials in Firefox history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> firefoxHist = Firefox.GetFirefoxHistory();
|
List<string> history = GetFirefoxHistory();
|
||||||
if (firefoxHist.Count > 0)
|
if (history.Count > 0)
|
||||||
{
|
{
|
||||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
{ Globals.PrintCredStrings, Beaprint.ansi_color_bad },
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (string url in firefoxHist)
|
foreach (string url in history)
|
||||||
{
|
{
|
||||||
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
if (MyUtils.ContainsAnyRegex(url.ToUpper(), Browser.CredStringsRegex))
|
||||||
{
|
{
|
||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"Firefox history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -101,7 +106,7 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
string userFirefoxBasePath = $"{dir}\\AppData\\Roaming\\Mozilla\\Firefox\\Profiles\\";
|
||||||
if (System.IO.Directory.Exists(userFirefoxBasePath))
|
if (Directory.Exists(userFirefoxBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
var directories = Directory.EnumerateDirectories(userFirefoxBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -249,25 +254,28 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
|
|
||||||
foreach (string dir in dirs)
|
foreach (string dir in dirs)
|
||||||
{
|
{
|
||||||
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
if (Directory.Exists(dir))
|
||||||
if (files.Length > 0)
|
|
||||||
{
|
{
|
||||||
signonsFile = files[0];
|
string[] files = Directory.EnumerateFiles(dir, "signons.sqlite").ToArray();
|
||||||
signonsFound = true;
|
if (files.Length > 0)
|
||||||
}
|
{
|
||||||
|
signonsFile = files[0];
|
||||||
|
signonsFound = true;
|
||||||
|
}
|
||||||
|
|
||||||
// find "logins.json"file
|
// find "logins.json"file
|
||||||
files = Directory.EnumerateFiles(dir, "logins.json").ToArray();
|
files = Directory.EnumerateFiles(dir, "logins.json").ToArray();
|
||||||
if (files.Length > 0)
|
if (files.Length > 0)
|
||||||
{
|
{
|
||||||
loginsFile = files[0];
|
loginsFile = files[0];
|
||||||
loginsFound = true;
|
loginsFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loginsFound || signonsFound)
|
if (loginsFound || signonsFound)
|
||||||
{
|
{
|
||||||
FFDecryptor.NSS_Init(dir);
|
FFDecryptor.NSS_Init(dir);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -313,8 +321,8 @@ namespace winPEAS.KnownFileCreds.Browsers.Firefox
|
|||||||
|
|
||||||
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
foreach (Browsers.Firefox.LoginData loginData in ffLoginData.logins)
|
||||||
{
|
{
|
||||||
string username = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedUsername);
|
string username = FFDecryptor.Decrypt(loginData.encryptedUsername);
|
||||||
string password = Browsers.Firefox.FFDecryptor.Decrypt(loginData.encryptedPassword);
|
string password = FFDecryptor.Decrypt(loginData.encryptedPassword);
|
||||||
logins.Add(new CredentialModel
|
logins.Add(new CredentialModel
|
||||||
{
|
{
|
||||||
Username = username,
|
Username = username,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
internal interface IBrowser
|
internal interface IBrowser
|
||||||
{
|
{
|
||||||
string Name { get; }
|
string Name { get; }
|
||||||
void PrintInfo();
|
void PrintInfo();
|
||||||
IEnumerable<CredentialModel> GetSavedCredentials();
|
IEnumerable<CredentialModel> GetSavedCredentials();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Checks;
|
using winPEAS.Checks;
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
@@ -30,7 +30,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Current IE tabs");
|
Beaprint.MainPrint("Current IE tabs");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
List<string> urls = InternetExplorer.GetCurrentIETabs();
|
List<string> urls = GetCurrentIETabs();
|
||||||
|
|
||||||
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
Dictionary<string, string> colorsB = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -51,9 +51,9 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
Beaprint.MainPrint("Looking for GET credentials in IE history");
|
||||||
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
Beaprint.LinkPrint("https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history");
|
||||||
Dictionary<string, List<string>> chromeHistBook = InternetExplorer.GetIEHistFav();
|
Dictionary<string, List<string>> ieHistoryBook = GetIEHistFav();
|
||||||
List<string> history = chromeHistBook["history"];
|
List<string> history = ieHistoryBook["history"];
|
||||||
List<string> favorites = chromeHistBook["favorites"];
|
List<string> favorites = ieHistoryBook["favorites"];
|
||||||
|
|
||||||
if (history.Count > 0)
|
if (history.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -69,8 +69,15 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
Beaprint.AnsiPrint(" " + url, colorsB);
|
Beaprint.AnsiPrint(" " + url, colorsB);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
|
int limit = 50;
|
||||||
|
Beaprint.MainPrint($"IE history -- limit {limit}\n");
|
||||||
|
Beaprint.ListPrint(history.Take(limit).ToList());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Beaprint.NotFoundPrint();
|
||||||
}
|
}
|
||||||
|
|
||||||
Beaprint.MainPrint("IE favorites");
|
Beaprint.MainPrint("IE favorites");
|
||||||
@@ -91,7 +98,7 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{ "favorites", new List<string>() },
|
{ "favorites", new List<string>() },
|
||||||
};
|
};
|
||||||
|
|
||||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -167,39 +174,31 @@ namespace winPEAS.KnownFileCreds.Browsers
|
|||||||
{
|
{
|
||||||
foreach (KeyValuePair<string, object> kvp in settings)
|
foreach (KeyValuePair<string, object> kvp in settings)
|
||||||
{
|
{
|
||||||
byte[] timeBytes = RegistryHelper.GetRegValueBytes("HKCU", "SOFTWARE\\Microsoft\\Internet Explorer\\TypedURLsTime", kvp.Key.ToString().Trim());
|
results["history"].Add(kvp.Value.ToString().Trim());
|
||||||
if (timeBytes != null)
|
|
||||||
{
|
|
||||||
long timeLong = (long)(BitConverter.ToInt64(timeBytes, 0));
|
|
||||||
DateTime urlTime = DateTime.FromFileTime(timeLong);
|
|
||||||
if (urlTime > startTime)
|
|
||||||
{
|
|
||||||
results["history"].Add(kvp.Value.ToString().Trim());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string userIEBookmarkPath = string.Format("{0}\\Favorites\\", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userIEBookmarkPath = string.Format("{0}\\Favorites\\", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
if (Directory.Exists(userIEBookmarkPath))
|
||||||
string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
|
|
||||||
|
|
||||||
foreach (string bookmarkPath in bookmarkPaths)
|
|
||||||
{
|
{
|
||||||
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
string[] bookmarkPaths = Directory.EnumerateFiles(userIEBookmarkPath, "*.url", SearchOption.AllDirectories).ToArray();
|
||||||
|
foreach (string bookmarkPath in bookmarkPaths)
|
||||||
{
|
{
|
||||||
string line;
|
using (StreamReader rdr = new StreamReader(bookmarkPath))
|
||||||
string url = "";
|
|
||||||
while ((line = rdr.ReadLine()) != null)
|
|
||||||
{
|
{
|
||||||
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
string line;
|
||||||
|
string url = "";
|
||||||
|
while ((line = rdr.ReadLine()) != null)
|
||||||
{
|
{
|
||||||
if (line.Length > 4)
|
if (line.StartsWith("URL=", StringComparison.InvariantCultureIgnoreCase))
|
||||||
url = line.Substring(4);
|
{
|
||||||
break;
|
if (line.Length > 4)
|
||||||
|
url = line.Substring(4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
results["favorites"].Add(url.ToString().Trim());
|
||||||
}
|
}
|
||||||
results["favorites"].Add(url.ToString().Trim());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -6,7 +7,6 @@ using System.Reflection;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
var currentUserDir = Environment.GetEnvironmentVariable("USERPROFILE");
|
||||||
userDirs = new List<string>{ currentUserDir };
|
userDirs = new List<string> { currentUserDir };
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var userDir in userDirs)
|
foreach (var userDir in userDirs)
|
||||||
@@ -123,7 +123,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
// parses recent file shortcuts via COM
|
// parses recent file shortcuts via COM
|
||||||
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
List<Dictionary<string, string>> results = new List<Dictionary<string, string>>();
|
||||||
int lastDays = 7;
|
int lastDays = 7;
|
||||||
DateTime startTime = System.DateTime.Now.AddDays(-lastDays);
|
DateTime startTime = DateTime.Now.AddDays(-lastDays);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -145,31 +145,34 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
string recentPath = string.Format("{0}\\AppData\\Roaming\\Microsoft\\Windows\\Recent\\", dir);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
if (Directory.Exists(recentPath))
|
||||||
|
|
||||||
if (recentFiles.Length != 0)
|
|
||||||
{
|
{
|
||||||
Console.WriteLine(" {0} :\r\n", userName);
|
string[] recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories).ToArray();
|
||||||
foreach (string recentFile in recentFiles)
|
|
||||||
|
if (recentFiles.Length != 0)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
Console.WriteLine(" {0} :\r\n", userName);
|
||||||
|
foreach (string recentFile in recentFiles)
|
||||||
if (lastAccessed > startTime)
|
|
||||||
{
|
{
|
||||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
|
||||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
|
||||||
|
|
||||||
if (TargetPath.ToString().Trim() != "")
|
if (lastAccessed > startTime)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>()
|
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||||
|
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||||
|
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||||
|
|
||||||
|
if (TargetPath.ToString().Trim() != "")
|
||||||
|
{
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Target", TargetPath.ToString() },
|
{ "Target", TargetPath.ToString() },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) }
|
{ "Accessed", string.Format("{0}", lastAccessed) }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Marshal.ReleaseComObject(shortcut);
|
||||||
|
shortcut = null;
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(shortcut);
|
|
||||||
shortcut = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,33 +183,35 @@ namespace winPEAS.KnownFileCreds
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", System.Environment.GetEnvironmentVariable("APPDATA"));
|
string recentPath = string.Format("{0}\\Microsoft\\Windows\\Recent\\", Environment.GetEnvironmentVariable("APPDATA"));
|
||||||
|
if (Directory.Exists(recentPath))
|
||||||
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
|
||||||
|
|
||||||
foreach (string recentFile in recentFiles)
|
|
||||||
{
|
{
|
||||||
// old method (needed interop dll)
|
var recentFiles = Directory.EnumerateFiles(recentPath, "*.lnk", SearchOption.AllDirectories);
|
||||||
//WshShell shell = new WshShell();
|
|
||||||
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(recentFile);
|
foreach (string recentFile in recentFiles)
|
||||||
|
|
||||||
if (lastAccessed > startTime)
|
|
||||||
{
|
{
|
||||||
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
// old method (needed interop dll)
|
||||||
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
//WshShell shell = new WshShell();
|
||||||
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
//IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(recentFile);
|
||||||
if (TargetPath.ToString().Trim() != "")
|
|
||||||
|
DateTime lastAccessed = File.GetLastAccessTime(recentFile);
|
||||||
|
|
||||||
|
if (lastAccessed > startTime)
|
||||||
{
|
{
|
||||||
results.Add(new Dictionary<string, string>()
|
// invoke the WshShell com object, creating a shortcut to then extract the TargetPath from
|
||||||
|
Object shortcut = shellObj.GetType().InvokeMember("CreateShortcut", BindingFlags.InvokeMethod, null, shellObj, new object[] { recentFile });
|
||||||
|
Object TargetPath = shortcut.GetType().InvokeMember("TargetPath", BindingFlags.GetProperty, null, shortcut, new object[] { });
|
||||||
|
if (TargetPath.ToString().Trim() != "")
|
||||||
|
{
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "Target", TargetPath.ToString() },
|
{ "Target", TargetPath.ToString() },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) }
|
{ "Accessed", string.Format("{0}", lastAccessed) }
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
Marshal.ReleaseComObject(shortcut);
|
||||||
|
shortcut = null;
|
||||||
}
|
}
|
||||||
Marshal.ReleaseComObject(shortcut);
|
|
||||||
shortcut = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,13 +242,15 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string userName = parts[parts.Length - 1];
|
string userName = parts[parts.Length - 1];
|
||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
List<string> userDPAPIBasePaths = new List<string>();
|
List<string> userDPAPIBasePaths = new List<string>
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
if (Directory.Exists(userDPAPIBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -254,9 +261,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
{
|
{
|
||||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
results.Add(new Dictionary<string, string>()
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "MasterKey", file },
|
{ "MasterKey", file },
|
||||||
@@ -274,13 +281,15 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
List<string> userDPAPIBasePaths = new List<string>();
|
List<string> userDPAPIBasePaths = new List<string>
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userDPAPIBasePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Protect\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
foreach (string userDPAPIBasePath in userDPAPIBasePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userDPAPIBasePath))
|
if (Directory.Exists(userDPAPIBasePath))
|
||||||
{
|
{
|
||||||
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
var directories = Directory.EnumerateDirectories(userDPAPIBasePath);
|
||||||
foreach (string directory in directories)
|
foreach (string directory in directories)
|
||||||
@@ -291,9 +300,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
{
|
{
|
||||||
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
if (Regex.IsMatch(file, @"[0-9A-Fa-f]{8}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{4}[-][0-9A-Fa-f]{12}"))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
results.Add(new Dictionary<string, string>()
|
results.Add(new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ "MasterKey", file },
|
{ "MasterKey", file },
|
||||||
@@ -331,23 +340,25 @@ namespace winPEAS.KnownFileCreds
|
|||||||
string userName = parts[parts.Length - 1];
|
string userName = parts[parts.Length - 1];
|
||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
List<string> userCredFilePaths = new List<string>();
|
List<string> userCredFilePaths = new List<string>
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir));
|
{
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir));
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", dir),
|
||||||
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", dir)
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userCredFilePath in userCredFilePaths)
|
foreach (string userCredFilePath in userCredFilePaths)
|
||||||
{
|
{
|
||||||
if (System.IO.Directory.Exists(userCredFilePath))
|
if (Directory.Exists(userCredFilePath))
|
||||||
{
|
{
|
||||||
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
var systemFiles = Directory.EnumerateFiles(userCredFilePath);
|
||||||
if ((systemFiles != null))
|
if ((systemFiles != null))
|
||||||
{
|
{
|
||||||
foreach (string file in systemFiles)
|
foreach (string file in systemFiles)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
long size = new FileInfo(file).Length;
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
@@ -381,49 +392,54 @@ namespace winPEAS.KnownFileCreds
|
|||||||
}
|
}
|
||||||
|
|
||||||
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
string systemFolder = string.Format("{0}\\System32\\config\\systemprofile\\AppData\\Local\\Microsoft\\Credentials", Environment.GetEnvironmentVariable("SystemRoot"));
|
||||||
var files = Directory.EnumerateFiles(systemFolder);
|
if (Directory.Exists(systemFolder))
|
||||||
if ((files != null))
|
|
||||||
{
|
{
|
||||||
foreach (string file in files)
|
var files = Directory.EnumerateFiles(systemFolder);
|
||||||
|
if ((files != null))
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
foreach (string file in files)
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
|
||||||
byte[] credentialArray = File.ReadAllBytes(file);
|
|
||||||
byte[] guidMasterKeyArray = new byte[16];
|
|
||||||
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
|
||||||
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
|
||||||
|
|
||||||
byte[] stringLenArray = new byte[16];
|
|
||||||
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
|
||||||
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
|
||||||
|
|
||||||
byte[] descBytes = new byte[descLen];
|
|
||||||
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
|
||||||
|
|
||||||
string desc = Encoding.Unicode.GetString(descBytes);
|
|
||||||
results.Add(new Dictionary<string, string>()
|
|
||||||
{
|
{
|
||||||
{ "CredFile", file },
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
{ "Description", desc },
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
{ "MasterKey", string.Format("{0}", guidMasterKey) },
|
long size = new System.IO.FileInfo(file).Length;
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
string fileName = Path.GetFileName(file);
|
||||||
{ "Modified", string.Format("{0}", lastModified) },
|
|
||||||
{ "Size", string.Format("{0}", size) },
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
});
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
|
byte[] credentialArray = File.ReadAllBytes(file);
|
||||||
|
byte[] guidMasterKeyArray = new byte[16];
|
||||||
|
Array.Copy(credentialArray, 36, guidMasterKeyArray, 0, 16);
|
||||||
|
Guid guidMasterKey = new Guid(guidMasterKeyArray);
|
||||||
|
|
||||||
|
byte[] stringLenArray = new byte[16];
|
||||||
|
Array.Copy(credentialArray, 56, stringLenArray, 0, 4);
|
||||||
|
int descLen = BitConverter.ToInt32(stringLenArray, 0);
|
||||||
|
|
||||||
|
byte[] descBytes = new byte[descLen];
|
||||||
|
Array.Copy(credentialArray, 60, descBytes, 0, descLen - 4);
|
||||||
|
|
||||||
|
string desc = Encoding.Unicode.GetString(descBytes);
|
||||||
|
results.Add(new Dictionary<string, string>()
|
||||||
|
{
|
||||||
|
{ "CredFile", file },
|
||||||
|
{ "Description", desc },
|
||||||
|
{ "MasterKey", string.Format("{0}", guidMasterKey) },
|
||||||
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
|
{ "Modified", string.Format("{0}", lastModified) },
|
||||||
|
{ "Size", string.Format("{0}", size) },
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
List<string> userCredFilePaths = new List<string>();
|
List<string> userCredFilePaths = new List<string>
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
{
|
||||||
userCredFilePaths.Add(string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", System.Environment.GetEnvironmentVariable("USERPROFILE")));
|
string.Format("{0}\\AppData\\Local\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE")),
|
||||||
|
string.Format("{0}\\AppData\\Roaming\\Microsoft\\Credentials\\", Environment.GetEnvironmentVariable("USERPROFILE"))
|
||||||
|
};
|
||||||
|
|
||||||
foreach (string userCredFilePath in userCredFilePaths)
|
foreach (string userCredFilePath in userCredFilePaths)
|
||||||
{
|
{
|
||||||
@@ -433,10 +449,10 @@ namespace winPEAS.KnownFileCreds
|
|||||||
|
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(file);
|
DateTime lastAccessed = File.GetLastAccessTime(file);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(file);
|
DateTime lastModified = File.GetLastWriteTime(file);
|
||||||
long size = new System.IO.FileInfo(file).Length;
|
long size = new System.IO.FileInfo(file).Length;
|
||||||
string fileName = System.IO.Path.GetFileName(file);
|
string fileName = Path.GetFileName(file);
|
||||||
|
|
||||||
// jankily parse the bytes to extract the credential type and master key GUID
|
// jankily parse the bytes to extract the credential type and master key GUID
|
||||||
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
// reference- https://github.com/gentilkiwi/mimikatz/blob/3d8be22fff9f7222f9590aa007629e18300cf643/modules/kull_m_dpapi.h#L24-L54
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Putty Sessions");
|
Beaprint.MainPrint("Putty Sessions");
|
||||||
List<Dictionary<string, string>> putty_sess = Putty.GetPuttySessions();
|
List<Dictionary<string, string>> putty_sess = GetPuttySessions();
|
||||||
|
|
||||||
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
@@ -39,7 +39,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
Beaprint.MainPrint("Putty SSH Host keys");
|
Beaprint.MainPrint("Putty SSH Host keys");
|
||||||
List<Dictionary<string, string>> putty_sess = Putty.ListPuttySSHHostKeys();
|
List<Dictionary<string, string>> putty_sess = ListPuttySSHHostKeys();
|
||||||
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
Dictionary<string, string> colorF = new Dictionary<string, string>()
|
||||||
{
|
{
|
||||||
{ ".*", Beaprint.ansi_color_bad },
|
{ ".*", Beaprint.ansi_color_bad },
|
||||||
@@ -182,8 +182,10 @@ namespace winPEAS.KnownFileCreds
|
|||||||
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
Dictionary<string, object> hostKeys = RegistryHelper.GetRegValues("HKU", string.Format("{0}\\Software\\SimonTatham\\PuTTY\\SshHostKeys\\", SID));
|
||||||
if ((hostKeys != null) && (hostKeys.Count != 0))
|
if ((hostKeys != null) && (hostKeys.Count != 0))
|
||||||
{
|
{
|
||||||
Dictionary<string, string> putty_ssh = new Dictionary<string, string>();
|
Dictionary<string, string> putty_ssh = new Dictionary<string, string>
|
||||||
putty_ssh["UserSID"] = SID;
|
{
|
||||||
|
["UserSID"] = SID
|
||||||
|
};
|
||||||
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
foreach (KeyValuePair<string, object> kvp in hostKeys)
|
||||||
{
|
{
|
||||||
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
putty_ssh[kvp.Key] = ""; //Looks like only matters the key name, not the value
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using Microsoft.Win32;
|
|
||||||
using winPEAS.Helpers;
|
using winPEAS.Helpers;
|
||||||
using winPEAS.Helpers.Registry;
|
using winPEAS.Helpers.Registry;
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ namespace winPEAS.KnownFileCreds
|
|||||||
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
if (!(dir.EndsWith("Public") || dir.EndsWith("Default") || dir.EndsWith("Default User") || dir.EndsWith("All Users")))
|
||||||
{
|
{
|
||||||
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", dir);
|
||||||
if (System.IO.File.Exists(userRDManFile))
|
if (File.Exists(userRDManFile))
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
XmlDocument xmlDoc = new XmlDocument();
|
||||||
xmlDoc.Load(userRDManFile);
|
xmlDoc.Load(userRDManFile);
|
||||||
@@ -87,8 +87,8 @@ namespace winPEAS.KnownFileCreds
|
|||||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||||
XmlNode node = items[0];
|
XmlNode node = items[0];
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||||
{ "RDCManFile", userRDManFile },
|
{ "RDCManFile", userRDManFile },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
@@ -107,9 +107,9 @@ namespace winPEAS.KnownFileCreds
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
string userName = Environment.GetEnvironmentVariable("USERNAME");
|
||||||
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", System.Environment.GetEnvironmentVariable("USERPROFILE"));
|
string userRDManFile = string.Format("{0}\\AppData\\Local\\Microsoft\\Remote Desktop Connection Manager\\RDCMan.settings", Environment.GetEnvironmentVariable("USERPROFILE"));
|
||||||
|
|
||||||
if (System.IO.File.Exists(userRDManFile))
|
if (File.Exists(userRDManFile))
|
||||||
{
|
{
|
||||||
XmlDocument xmlDoc = new XmlDocument();
|
XmlDocument xmlDoc = new XmlDocument();
|
||||||
xmlDoc.Load(userRDManFile);
|
xmlDoc.Load(userRDManFile);
|
||||||
@@ -119,8 +119,8 @@ namespace winPEAS.KnownFileCreds
|
|||||||
XmlNodeList items = filesToOpen[0].ChildNodes;
|
XmlNodeList items = filesToOpen[0].ChildNodes;
|
||||||
XmlNode node = items[0];
|
XmlNode node = items[0];
|
||||||
|
|
||||||
DateTime lastAccessed = System.IO.File.GetLastAccessTime(userRDManFile);
|
DateTime lastAccessed = File.GetLastAccessTime(userRDManFile);
|
||||||
DateTime lastModified = System.IO.File.GetLastWriteTime(userRDManFile);
|
DateTime lastModified = File.GetLastWriteTime(userRDManFile);
|
||||||
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
Dictionary<string, string> rdg = new Dictionary<string, string>(){
|
||||||
{ "RDCManFile", userRDManFile },
|
{ "RDCManFile", userRDManFile },
|
||||||
{ "Accessed", string.Format("{0}", lastAccessed) },
|
{ "Accessed", string.Format("{0}", lastAccessed) },
|
||||||
|
|||||||
@@ -209,7 +209,7 @@ namespace winPEAS.KnownFileCreds.SecurityPackages
|
|||||||
{
|
{
|
||||||
return new NtlmHashInfo(
|
return new NtlmHashInfo(
|
||||||
"NetNTLMv2",
|
"NetNTLMv2",
|
||||||
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp,16, nt_resp.Length - 16))
|
FormatNetNtlmV2Hash(challenge, user, domain, SubArray(nt_resp, 0, 16), SubArray(nt_resp, 16, nt_resp.Length - 16))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -24,11 +24,14 @@ namespace winPEAS.KnownFileCreds.SuperPutty
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
var path = $"{dir}\\Documents\\SuperPuTTY\\";
|
||||||
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
if (Directory.Exists(path))
|
||||||
|
|
||||||
foreach (var file in files)
|
|
||||||
{
|
{
|
||||||
Beaprint.BadPrint($" {file}");
|
var files = Directory.EnumerateFiles(path, filter, SearchOption.TopDirectoryOnly);
|
||||||
|
|
||||||
|
foreach (var file in files)
|
||||||
|
{
|
||||||
|
Beaprint.BadPrint($" {file}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
|
|||||||
@@ -45,16 +45,18 @@ namespace winPEAS.KnownFileCreds.Vault
|
|||||||
|
|
||||||
// Create dictionary to translate Guids to human readable elements
|
// Create dictionary to translate Guids to human readable elements
|
||||||
IntPtr guidAddress = vaultGuidPtr;
|
IntPtr guidAddress = vaultGuidPtr;
|
||||||
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>();
|
Dictionary<Guid, string> vaultSchema = new Dictionary<Guid, string>
|
||||||
vaultSchema.Add(new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note");
|
{
|
||||||
vaultSchema.Add(new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential");
|
{ new Guid("2F1A6504-0641-44CF-8BB5-3612D865F2E5"), "Windows Secure Note" },
|
||||||
vaultSchema.Add(new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector");
|
{ new Guid("3CCD5499-87A8-4B10-A215-608888DD3B55"), "Windows Web Password Credential" },
|
||||||
vaultSchema.Add(new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials");
|
{ new Guid("154E23D0-C644-4E6F-8CE6-5069272F999F"), "Windows Credential Picker Protector" },
|
||||||
vaultSchema.Add(new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials");
|
{ new Guid("4BF4C442-9B8A-41A0-B380-DD4A704DDB28"), "Web Credentials" },
|
||||||
vaultSchema.Add(new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential");
|
{ new Guid("77BC582B-F0A6-4E15-4E80-61736B6F3B29"), "Windows Credentials" },
|
||||||
vaultSchema.Add(new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential");
|
{ new Guid("E69D7838-91B5-4FC9-89D5-230D4D4CC2BC"), "Windows Domain Certificate Credential" },
|
||||||
vaultSchema.Add(new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential");
|
{ new Guid("3E0E35BE-1B77-43E7-B873-AED901B6275B"), "Windows Domain Password Credential" },
|
||||||
vaultSchema.Add(new Guid("00000000-0000-0000-0000-000000000000"), null);
|
{ new Guid("3C886FF3-2669-4AA2-A8FB-3F6759A77548"), "Windows Extended Credential" },
|
||||||
|
{ new Guid("00000000-0000-0000-0000-000000000000"), null }
|
||||||
|
};
|
||||||
|
|
||||||
for (int i = 0; i < vaultCount; i++)
|
for (int i = 0; i < vaultCount; i++)
|
||||||
{
|
{
|
||||||
@@ -167,7 +169,7 @@ namespace winPEAS.KnownFileCreds.Vault
|
|||||||
vault_cred["PacakgeSid"] = string.Format("{0}", packageSid);
|
vault_cred["PacakgeSid"] = string.Format("{0}", packageSid);
|
||||||
}
|
}
|
||||||
vault_cred["Credential"] = string.Format("{0}", cred);
|
vault_cred["Credential"] = string.Format("{0}", cred);
|
||||||
vault_cred["Last Modified"] = string.Format("{0}", System.DateTime.FromFileTimeUtc((long)lastModified));
|
vault_cred["Last Modified"] = string.Format("{0}", DateTime.FromFileTimeUtc((long)lastModified));
|
||||||
results.Add(vault_cred);
|
results.Add(vault_cred);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Native.Enums;
|
using winPEAS.Native.Enums;
|
||||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
|
||||||
|
|
||||||
namespace winPEAS.Native.Classes
|
namespace winPEAS.Native.Classes
|
||||||
{
|
{
|
||||||
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
public partial class SafeTokenHandle : Microsoft.Win32.SafeHandles.SafeHandleZeroOrMinusOneIsInvalid
|
||||||
{
|
{
|
||||||
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
|
private const Int32 ERROR_NO_TOKEN = 0x000003F0;
|
||||||
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
|
private const Int32 ERROR_INSUFFICIENT_BUFFER = 122;
|
||||||
private static SafeTokenHandle currentProcessToken = null;
|
private static SafeTokenHandle currentProcessToken = null;
|
||||||
|
|
||||||
private SafeTokenHandle() : base(true) { }
|
private SafeTokenHandle() : base(true) { }
|
||||||
|
|
||||||
@@ -20,102 +19,102 @@ namespace winPEAS.Native.Classes
|
|||||||
|
|
||||||
protected override bool ReleaseHandle() => Kernel32.CloseHandle(handle);
|
protected override bool ReleaseHandle() => Kernel32.CloseHandle(handle);
|
||||||
|
|
||||||
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
|
public T GetInfo<T>(TOKEN_INFORMATION_CLASS type)
|
||||||
{
|
{
|
||||||
int cbSize = Marshal.SizeOf(typeof(T));
|
int cbSize = Marshal.SizeOf(typeof(T));
|
||||||
IntPtr pType = Marshal.AllocHGlobal(cbSize);
|
IntPtr pType = Marshal.AllocHGlobal(cbSize);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Retrieve token information.
|
// Retrieve token information.
|
||||||
if (!Advapi32.GetTokenInformation(this, type, pType, cbSize, out cbSize))
|
if (!Advapi32.GetTokenInformation(this, type, pType, cbSize, out cbSize))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
|
|
||||||
// Marshal from native to .NET.
|
// Marshal from native to .NET.
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case TOKEN_INFORMATION_CLASS.TokenType:
|
case TOKEN_INFORMATION_CLASS.TokenType:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
|
case TOKEN_INFORMATION_CLASS.TokenImpersonationLevel:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSessionId:
|
case TOKEN_INFORMATION_CLASS.TokenSessionId:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
|
case TOKEN_INFORMATION_CLASS.TokenSandBoxInert:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenOrigin:
|
case TOKEN_INFORMATION_CLASS.TokenOrigin:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenElevationType:
|
case TOKEN_INFORMATION_CLASS.TokenElevationType:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
|
case TOKEN_INFORMATION_CLASS.TokenHasRestrictions:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
|
case TOKEN_INFORMATION_CLASS.TokenUIAccess:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
|
case TOKEN_INFORMATION_CLASS.TokenVirtualizationAllowed:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
|
case TOKEN_INFORMATION_CLASS.TokenVirtualizationEnabled:
|
||||||
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
|
return (T)Convert.ChangeType(Marshal.ReadInt32(pType), typeof(T));
|
||||||
|
|
||||||
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
|
case TOKEN_INFORMATION_CLASS.TokenLinkedToken:
|
||||||
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
|
return (T)Convert.ChangeType(Marshal.ReadIntPtr(pType), typeof(T));
|
||||||
|
|
||||||
case TOKEN_INFORMATION_CLASS.TokenUser:
|
case TOKEN_INFORMATION_CLASS.TokenUser:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenGroups:
|
case TOKEN_INFORMATION_CLASS.TokenGroups:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
|
case TOKEN_INFORMATION_CLASS.TokenPrivileges:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenOwner:
|
case TOKEN_INFORMATION_CLASS.TokenOwner:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
|
case TOKEN_INFORMATION_CLASS.TokenPrimaryGroup:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
|
case TOKEN_INFORMATION_CLASS.TokenDefaultDacl:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSource:
|
case TOKEN_INFORMATION_CLASS.TokenSource:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenStatistics:
|
case TOKEN_INFORMATION_CLASS.TokenStatistics:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
|
case TOKEN_INFORMATION_CLASS.TokenRestrictedSids:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
|
case TOKEN_INFORMATION_CLASS.TokenGroupsAndPrivileges:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenElevation:
|
case TOKEN_INFORMATION_CLASS.TokenElevation:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
|
case TOKEN_INFORMATION_CLASS.TokenAccessInformation:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
|
case TOKEN_INFORMATION_CLASS.TokenIntegrityLevel:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
|
case TOKEN_INFORMATION_CLASS.TokenMandatoryPolicy:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
|
case TOKEN_INFORMATION_CLASS.TokenLogonSid:
|
||||||
return (T)Marshal.PtrToStructure(pType, typeof(T));
|
return (T)Marshal.PtrToStructure(pType, typeof(T));
|
||||||
|
|
||||||
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
|
case TOKEN_INFORMATION_CLASS.TokenSessionReference:
|
||||||
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
|
case TOKEN_INFORMATION_CLASS.TokenAuditPolicy:
|
||||||
default:
|
default:
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(pType);
|
Marshal.FreeHGlobal(pType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
public static SafeTokenHandle FromCurrentProcess(AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||||
{
|
{
|
||||||
lock (currentProcessToken)
|
lock (currentProcessToken)
|
||||||
{
|
{
|
||||||
if (currentProcessToken == null)
|
if (currentProcessToken == null)
|
||||||
currentProcessToken = FromProcess(Kernel32.GetCurrentProcess(), desiredAccess);
|
currentProcessToken = FromProcess(Kernel32.GetCurrentProcess(), desiredAccess);
|
||||||
return currentProcessToken;
|
return currentProcessToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
public static SafeTokenHandle FromCurrentThread(AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||||
=> FromThread(Kernel32.GetCurrentThread(), desiredAccess, openAsSelf);
|
=> FromThread(Kernel32.GetCurrentThread(), desiredAccess, openAsSelf);
|
||||||
|
|
||||||
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
public static SafeTokenHandle FromProcess(IntPtr hProcess, AccessTypes desiredAccess = AccessTypes.TokenDuplicate)
|
||||||
{
|
{
|
||||||
SafeTokenHandle val;
|
SafeTokenHandle val;
|
||||||
if (!Advapi32.OpenProcessToken(hProcess, desiredAccess, out val))
|
if (!Advapi32.OpenProcessToken(hProcess, desiredAccess, out val))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
public static SafeTokenHandle FromThread(IntPtr hThread, AccessTypes desiredAccess = AccessTypes.TokenDuplicate, bool openAsSelf = true)
|
||||||
{
|
{
|
||||||
SafeTokenHandle val;
|
SafeTokenHandle val;
|
||||||
if (!Advapi32.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
|
if (!Advapi32.OpenThreadToken(hThread, desiredAccess, openAsSelf, out val))
|
||||||
{
|
{
|
||||||
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
|
if (Marshal.GetLastWin32Error() == ERROR_NO_TOKEN)
|
||||||
{
|
{
|
||||||
SafeTokenHandle pval = FromCurrentProcess();
|
SafeTokenHandle pval = FromCurrentProcess();
|
||||||
if (!Advapi32.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
|
if (!Advapi32.DuplicateTokenEx(pval, AccessTypes.TokenImpersonate | desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.Impersonation, TokenType.TokenImpersonation, ref val))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
if (!Advapi32.SetThreadToken(IntPtr.Zero, val))
|
if (!Advapi32.SetThreadToken(IntPtr.Zero, val))
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new System.ComponentModel.Win32Exception();
|
throw new System.ComponentModel.Win32Exception();
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides formats to use for input and output names for the DsCrackNames function.
|
/// Provides formats to use for input and output names for the DsCrackNames function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum DS_NAME_FORMAT
|
public enum DS_NAME_FORMAT
|
||||||
{
|
{
|
||||||
///<summary>Indicates the name is using an unknown name type. This format can impact performance because it forces the server to attempt to match all possible formats. Only use this value if the input format is unknown.</summary>
|
///<summary>Indicates the name is using an unknown name type. This format can impact performance because it forces the server to attempt to match all possible formats. Only use this value if the input format is unknown.</summary>
|
||||||
DS_UNKNOWN_NAME = 0,
|
DS_UNKNOWN_NAME = 0,
|
||||||
|
|
||||||
///<summary>Indicates that the fully qualified distinguished name is used. For example: "CN = someone, OU = Users, DC = Engineering, DC = Fabrikam, DC = Com"</summary>
|
///<summary>Indicates that the fully qualified distinguished name is used. For example: "CN = someone, OU = Users, DC = Engineering, DC = Fabrikam, DC = Com"</summary>
|
||||||
DS_FQDN_1779_NAME = 1,
|
DS_FQDN_1779_NAME = 1,
|
||||||
|
|
||||||
///<summary>Indicates a Windows NT 4.0 account name. For example: "Engineering\someone" The domain-only version includes two trailing backslashes (\\).</summary>
|
///<summary>Indicates a Windows NT 4.0 account name. For example: "Engineering\someone" The domain-only version includes two trailing backslashes (\\).</summary>
|
||||||
DS_NT4_ACCOUNT_NAME = 2,
|
DS_NT4_ACCOUNT_NAME = 2,
|
||||||
|
|
||||||
///<summary>Indicates a user-friendly display name, for example, Jeff Smith. The display name is not necessarily the same as relative distinguished name (RDN).</summary>
|
///<summary>Indicates a user-friendly display name, for example, Jeff Smith. The display name is not necessarily the same as relative distinguished name (RDN).</summary>
|
||||||
DS_DISPLAY_NAME = 3,
|
DS_DISPLAY_NAME = 3,
|
||||||
|
|
||||||
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
|
///<summary>Indicates a GUID string that the IIDFromString function returns. For example: "{4fa050f0-f561-11cf-bdd9-00aa003a77b6}"</summary>
|
||||||
DS_UNIQUE_ID_NAME = 6,
|
DS_UNIQUE_ID_NAME = 6,
|
||||||
|
|
||||||
///<summary>Indicates a complete canonical name. For example: "engineering.fabrikam.com/software/someone" The domain-only version includes a trailing forward slash (/).</summary>
|
///<summary>Indicates a complete canonical name. For example: "engineering.fabrikam.com/software/someone" The domain-only version includes a trailing forward slash (/).</summary>
|
||||||
DS_CANONICAL_NAME = 7,
|
DS_CANONICAL_NAME = 7,
|
||||||
|
|
||||||
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
|
///<summary>Indicates that it is using the user principal name (UPN). For example: "someone@engineering.fabrikam.com"</summary>
|
||||||
DS_USER_PRINCIPAL_NAME = 8,
|
DS_USER_PRINCIPAL_NAME = 8,
|
||||||
|
|
||||||
///<summary>This element is the same as DS_CANONICAL_NAME except that the rightmost forward slash (/) is replaced with a newline character (\n), even in a domain-only case. For example: "engineering.fabrikam.com/software\nsomeone"</summary>
|
///<summary>This element is the same as DS_CANONICAL_NAME except that the rightmost forward slash (/) is replaced with a newline character (\n), even in a domain-only case. For example: "engineering.fabrikam.com/software\nsomeone"</summary>
|
||||||
DS_CANONICAL_NAME_EX = 9,
|
DS_CANONICAL_NAME_EX = 9,
|
||||||
|
|
||||||
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
|
///<summary>Indicates it is using a generalized service principal name. For example: "www/www.fabrikam.com@fabrikam.com"</summary>
|
||||||
DS_SERVICE_PRINCIPAL_NAME = 10,
|
DS_SERVICE_PRINCIPAL_NAME = 10,
|
||||||
|
|
||||||
///<summary>Indicates a Security Identifier (SID) for the object. This can be either the current SID or a SID from the object SID history. The SID string can use either the standard string representation of a SID, or one of the string constants defined in Sddl.h. For more information about converting a binary SID into a SID string, see SID Strings. The following is an example of a SID string: "S-1-5-21-397955417-626881126-188441444-501"</summary>
|
///<summary>Indicates a Security Identifier (SID) for the object. This can be either the current SID or a SID from the object SID history. The SID string can use either the standard string representation of a SID, or one of the string constants defined in Sddl.h. For more information about converting a binary SID into a SID string, see SID Strings. The following is an example of a SID string: "S-1-5-21-397955417-626881126-188441444-501"</summary>
|
||||||
DS_SID_OR_SID_HISTORY_NAME = 11,
|
DS_SID_OR_SID_HISTORY_NAME = 11,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
public enum SECURITY_IMPERSONATION_LEVEL
|
public enum SECURITY_IMPERSONATION_LEVEL
|
||||||
{
|
{
|
||||||
Anonymous,
|
Anonymous,
|
||||||
Identification,
|
Identification,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ServerTypes : uint
|
public enum ServerTypes : uint
|
||||||
{
|
{
|
||||||
Workstation = 0x00000001,
|
Workstation = 0x00000001,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
public enum TOKEN_ELEVATION_TYPE
|
public enum TOKEN_ELEVATION_TYPE
|
||||||
{
|
{
|
||||||
Default = 1,
|
Default = 1,
|
||||||
Full,
|
Full,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace winPEAS.Native.Enums
|
namespace winPEAS.Native.Enums
|
||||||
{
|
{
|
||||||
public enum TOKEN_INFORMATION_CLASS
|
public enum TOKEN_INFORMATION_CLASS
|
||||||
{
|
{
|
||||||
TokenUser = 1,
|
TokenUser = 1,
|
||||||
TokenGroups,
|
TokenGroups,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.ConstrainedExecution;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using winPEAS.Info.SystemInfo.NamedPipes;
|
|
||||||
|
|
||||||
namespace winPEAS.Native
|
namespace winPEAS.Native
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,5 +27,5 @@ namespace winPEAS.Native
|
|||||||
|
|
||||||
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
[DllImport("ntdsapi.dll", CharSet = CharSet.Auto)]
|
||||||
internal static extern uint DsUnBind(ref IntPtr phDS);
|
internal static extern uint DsUnBind(ref IntPtr phDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace winPEAS.Native.Structs
|
namespace winPEAS.Native.Structs
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||||
public struct LUID
|
public struct LUID
|
||||||
{
|
{
|
||||||
public uint LowPart;
|
public uint LowPart;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace winPEAS.Native.Structs
|
namespace winPEAS.Native.Structs
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SID_AND_ATTRIBUTES
|
public struct SID_AND_ATTRIBUTES
|
||||||
{
|
{
|
||||||
public IntPtr Sid;
|
public IntPtr Sid;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace winPEAS.Native.Structs
|
namespace winPEAS.Native.Structs
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct TOKEN_ELEVATION
|
public struct TOKEN_ELEVATION
|
||||||
{
|
{
|
||||||
public Int32 TokenIsElevated;
|
public Int32 TokenIsElevated;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
// General Information about an assembly is controlled through the following
|
// General Information about an assembly is controlled through the following
|
||||||
|
|||||||
@@ -2,93 +2,91 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.AccessControl;
|
using System.Security.AccessControl;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Extensions for classes in the System.Security.AccessControl namespace.</summary>
|
/// <summary>Extensions for classes in the System.Security.AccessControl namespace.</summary>
|
||||||
public static class AccessControlExtension
|
public static class AccessControlExtension
|
||||||
{
|
{
|
||||||
/// <summary>Canonicalizes the specified Access Control List.</summary>
|
/// <summary>Canonicalizes the specified Access Control List.</summary>
|
||||||
/// <param name="acl">The Access Control List.</param>
|
/// <param name="acl">The Access Control List.</param>
|
||||||
public static void Canonicalize(this RawAcl acl)
|
public static void Canonicalize(this RawAcl acl)
|
||||||
{
|
{
|
||||||
if (acl == null) throw new ArgumentNullException(nameof(acl));
|
if (acl == null) throw new ArgumentNullException(nameof(acl));
|
||||||
|
|
||||||
// Extract aces to list
|
// Extract aces to list
|
||||||
var aces = new System.Collections.Generic.List<GenericAce>(acl.Cast<GenericAce>());
|
var aces = new System.Collections.Generic.List<GenericAce>(acl.Cast<GenericAce>());
|
||||||
|
|
||||||
// Sort aces based on canonical order
|
// Sort aces based on canonical order
|
||||||
aces.Sort((a, b) => System.Collections.Generic.Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
|
aces.Sort((a, b) => Comparer<byte>.Default.Compare(GetComparisonValue(a), GetComparisonValue(b)));
|
||||||
|
|
||||||
// Add sorted aces back to ACL
|
// Add sorted aces back to ACL
|
||||||
while (acl.Count > 0) acl.RemoveAce(0);
|
while (acl.Count > 0) acl.RemoveAce(0);
|
||||||
var aceIndex = 0;
|
var aceIndex = 0;
|
||||||
aces.ForEach(ace => acl.InsertAce(aceIndex++, ace));
|
aces.ForEach(ace => acl.InsertAce(aceIndex++, ace));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sort ACEs according to canonical form for this <see cref="ObjectSecurity"/>.</summary>
|
/// <summary>Sort ACEs according to canonical form for this <see cref="ObjectSecurity"/>.</summary>
|
||||||
/// <param name="objectSecurity">The object security whose DiscretionaryAcl will be made canonical.</param>
|
/// <param name="objectSecurity">The object security whose DiscretionaryAcl will be made canonical.</param>
|
||||||
public static void CanonicalizeAccessRules(this ObjectSecurity objectSecurity)
|
public static void CanonicalizeAccessRules(this ObjectSecurity objectSecurity)
|
||||||
{
|
{
|
||||||
if (objectSecurity == null) throw new ArgumentNullException(nameof(objectSecurity));
|
if (objectSecurity == null) throw new ArgumentNullException(nameof(objectSecurity));
|
||||||
if (objectSecurity.AreAccessRulesCanonical) return;
|
if (objectSecurity.AreAccessRulesCanonical) return;
|
||||||
|
|
||||||
// Get raw SD from objectSecurity and canonicalize DACL
|
// Get raw SD from objectSecurity and canonicalize DACL
|
||||||
var sd = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorBinaryForm(), 0);
|
var sd = new RawSecurityDescriptor(objectSecurity.GetSecurityDescriptorBinaryForm(), 0);
|
||||||
sd.DiscretionaryAcl.Canonicalize();
|
sd.DiscretionaryAcl.Canonicalize();
|
||||||
|
|
||||||
// Convert SD back into objectSecurity
|
// Convert SD back into objectSecurity
|
||||||
objectSecurity.SetSecurityDescriptorBinaryForm(sd.GetBinaryForm());
|
objectSecurity.SetSecurityDescriptorBinaryForm(sd.GetBinaryForm());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns an array of byte values that represents the information contained in this <see cref="GenericSecurityDescriptor"/> object.</summary>
|
/// <summary>Returns an array of byte values that represents the information contained in this <see cref="GenericSecurityDescriptor"/> object.</summary>
|
||||||
/// <param name="sd">The <see cref="GenericSecurityDescriptor"/> object.</param>
|
/// <param name="sd">The <see cref="GenericSecurityDescriptor"/> object.</param>
|
||||||
/// <returns>The byte array into which the contents of the <see cref="GenericSecurityDescriptor"/> is marshaled.</returns>
|
/// <returns>The byte array into which the contents of the <see cref="GenericSecurityDescriptor"/> is marshaled.</returns>
|
||||||
public static byte[] GetBinaryForm(this GenericSecurityDescriptor sd)
|
public static byte[] GetBinaryForm(this GenericSecurityDescriptor sd)
|
||||||
{
|
{
|
||||||
if (sd == null) throw new ArgumentNullException(nameof(sd));
|
if (sd == null) throw new ArgumentNullException(nameof(sd));
|
||||||
var bin = new byte[sd.BinaryLength];
|
var bin = new byte[sd.BinaryLength];
|
||||||
sd.GetBinaryForm(bin, 0);
|
sd.GetBinaryForm(bin, 0);
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A canonical ACL must have ACES sorted according to the following order:
|
// A canonical ACL must have ACES sorted according to the following order:
|
||||||
// 1. Access-denied on the object
|
// 1. Access-denied on the object
|
||||||
// 2. Access-denied on a child or property
|
// 2. Access-denied on a child or property
|
||||||
// 3. Access-allowed on the object
|
// 3. Access-allowed on the object
|
||||||
// 4. Access-allowed on a child or property
|
// 4. Access-allowed on a child or property
|
||||||
// 5. All inherited ACEs
|
// 5. All inherited ACEs
|
||||||
private static byte GetComparisonValue(GenericAce ace)
|
private static byte GetComparisonValue(GenericAce ace)
|
||||||
{
|
{
|
||||||
if ((ace.AceFlags & AceFlags.Inherited) != 0)
|
if ((ace.AceFlags & AceFlags.Inherited) != 0)
|
||||||
return 5;
|
return 5;
|
||||||
switch (ace.AceType)
|
switch (ace.AceType)
|
||||||
{
|
{
|
||||||
case AceType.AccessDenied:
|
case AceType.AccessDenied:
|
||||||
case AceType.AccessDeniedCallback:
|
case AceType.AccessDeniedCallback:
|
||||||
case AceType.SystemAudit:
|
case AceType.SystemAudit:
|
||||||
case AceType.SystemAlarm:
|
case AceType.SystemAlarm:
|
||||||
case AceType.SystemAuditCallback:
|
case AceType.SystemAuditCallback:
|
||||||
case AceType.SystemAlarmCallback:
|
case AceType.SystemAlarmCallback:
|
||||||
return 0;
|
return 0;
|
||||||
case AceType.AccessDeniedObject:
|
case AceType.AccessDeniedObject:
|
||||||
case AceType.AccessDeniedCallbackObject:
|
case AceType.AccessDeniedCallbackObject:
|
||||||
case AceType.SystemAuditObject:
|
case AceType.SystemAuditObject:
|
||||||
case AceType.SystemAlarmObject:
|
case AceType.SystemAlarmObject:
|
||||||
case AceType.SystemAuditCallbackObject:
|
case AceType.SystemAuditCallbackObject:
|
||||||
case AceType.SystemAlarmCallbackObject:
|
case AceType.SystemAlarmCallbackObject:
|
||||||
return 1;
|
return 1;
|
||||||
case AceType.AccessAllowed:
|
case AceType.AccessAllowed:
|
||||||
case AceType.AccessAllowedCallback:
|
case AceType.AccessAllowedCallback:
|
||||||
return 2;
|
return 2;
|
||||||
case AceType.AccessAllowedObject:
|
case AceType.AccessAllowedObject:
|
||||||
case AceType.AccessAllowedCallbackObject:
|
case AceType.AccessAllowedCallbackObject:
|
||||||
return 3;
|
return 3;
|
||||||
default:
|
default:
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,27 +1,23 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
internal class CultureSwitcher : IDisposable
|
internal class CultureSwitcher : IDisposable
|
||||||
{
|
{
|
||||||
private readonly System.Globalization.CultureInfo cur, curUI;
|
private readonly System.Globalization.CultureInfo cur, curUI;
|
||||||
|
|
||||||
public CultureSwitcher([NotNull] System.Globalization.CultureInfo culture)
|
public CultureSwitcher([NotNull] System.Globalization.CultureInfo culture)
|
||||||
{
|
{
|
||||||
cur = Thread.CurrentThread.CurrentCulture;
|
cur = Thread.CurrentThread.CurrentCulture;
|
||||||
curUI = Thread.CurrentThread.CurrentUICulture;
|
curUI = Thread.CurrentThread.CurrentUICulture;
|
||||||
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = culture;
|
Thread.CurrentThread.CurrentCulture = Thread.CurrentThread.CurrentUICulture = culture;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Thread.CurrentThread.CurrentCulture = cur;
|
Thread.CurrentThread.CurrentCulture = cur;
|
||||||
Thread.CurrentThread.CurrentUICulture = curUI;
|
Thread.CurrentThread.CurrentUICulture = curUI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,72 +8,72 @@ namespace winPEAS.TaskScheduler
|
|||||||
/// Functions to provide localized strings for enumerated types and values.
|
/// Functions to provide localized strings for enumerated types and values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class TaskEnumGlobalizer
|
public static class TaskEnumGlobalizer
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a string representing the localized value of the provided enum.
|
/// Gets a string representing the localized value of the provided enum.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="enumValue">The enum value.</param>
|
/// <param name="enumValue">The enum value.</param>
|
||||||
/// <returns>A localized string, if available.</returns>
|
/// <returns>A localized string, if available.</returns>
|
||||||
public static string GetString(object enumValue)
|
public static string GetString(object enumValue)
|
||||||
{
|
{
|
||||||
switch (enumValue.GetType().Name)
|
switch (enumValue.GetType().Name)
|
||||||
{
|
{
|
||||||
case "DaysOfTheWeek":
|
case "DaysOfTheWeek":
|
||||||
return GetCultureEquivalentString((DaysOfTheWeek)enumValue);
|
return GetCultureEquivalentString((DaysOfTheWeek)enumValue);
|
||||||
case "MonthsOfTheYear":
|
case "MonthsOfTheYear":
|
||||||
return GetCultureEquivalentString((MonthsOfTheYear)enumValue);
|
return GetCultureEquivalentString((MonthsOfTheYear)enumValue);
|
||||||
case "TaskTriggerType":
|
case "TaskTriggerType":
|
||||||
return BuildEnumString("TriggerType", enumValue);
|
return BuildEnumString("TriggerType", enumValue);
|
||||||
case "WhichWeek":
|
case "WhichWeek":
|
||||||
return BuildEnumString("WW", enumValue);
|
return BuildEnumString("WW", enumValue);
|
||||||
case "TaskActionType":
|
case "TaskActionType":
|
||||||
return BuildEnumString("ActionType", enumValue);
|
return BuildEnumString("ActionType", enumValue);
|
||||||
case "TaskState":
|
case "TaskState":
|
||||||
return BuildEnumString("TaskState", enumValue);
|
return BuildEnumString("TaskState", enumValue);
|
||||||
}
|
}
|
||||||
return enumValue.ToString();
|
return enumValue.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCultureEquivalentString(DaysOfTheWeek val)
|
private static string GetCultureEquivalentString(DaysOfTheWeek val)
|
||||||
{
|
{
|
||||||
if (val == DaysOfTheWeek.AllDays)
|
if (val == DaysOfTheWeek.AllDays)
|
||||||
return Properties.Resources.DOWAllDays;
|
return Properties.Resources.DOWAllDays;
|
||||||
|
|
||||||
var s = new List<string>(7);
|
var s = new List<string>(7);
|
||||||
var vals = Enum.GetValues(val.GetType());
|
var vals = Enum.GetValues(val.GetType());
|
||||||
for (var i = 0; i < vals.Length - 1; i++)
|
for (var i = 0; i < vals.Length - 1; i++)
|
||||||
{
|
{
|
||||||
if ((val & (DaysOfTheWeek)vals.GetValue(i)) > 0)
|
if ((val & (DaysOfTheWeek)vals.GetValue(i)) > 0)
|
||||||
s.Add(DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)i));
|
s.Add(DateTimeFormatInfo.CurrentInfo.GetDayName((DayOfWeek)i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetCultureEquivalentString(MonthsOfTheYear val)
|
private static string GetCultureEquivalentString(MonthsOfTheYear val)
|
||||||
{
|
{
|
||||||
if (val == MonthsOfTheYear.AllMonths)
|
if (val == MonthsOfTheYear.AllMonths)
|
||||||
return Properties.Resources.MOYAllMonths;
|
return Properties.Resources.MOYAllMonths;
|
||||||
|
|
||||||
var s = new List<string>(12);
|
var s = new List<string>(12);
|
||||||
var vals = Enum.GetValues(val.GetType());
|
var vals = Enum.GetValues(val.GetType());
|
||||||
for (var i = 0; i < vals.Length - 1; i++)
|
for (var i = 0; i < vals.Length - 1; i++)
|
||||||
{
|
{
|
||||||
if ((val & (MonthsOfTheYear)vals.GetValue(i)) > 0)
|
if ((val & (MonthsOfTheYear)vals.GetValue(i)) > 0)
|
||||||
s.Add(DateTimeFormatInfo.CurrentInfo.GetMonthName(i + 1));
|
s.Add(DateTimeFormatInfo.CurrentInfo.GetMonthName(i + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
return string.Join(Properties.Resources.ListSeparator, s.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string BuildEnumString(string preface, object enumValue)
|
private static string BuildEnumString(string preface, object enumValue)
|
||||||
{
|
{
|
||||||
var vals = enumValue.ToString().Split(new[] { ", " }, StringSplitOptions.None);
|
var vals = enumValue.ToString().Split(new[] { ", " }, StringSplitOptions.None);
|
||||||
if (vals.Length == 0)
|
if (vals.Length == 0)
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
for (var i = 0; i < vals.Length; i++)
|
for (var i = 0; i < vals.Length; i++)
|
||||||
vals[i] = Properties.Resources.ResourceManager.GetString(preface + vals[i]);
|
vals[i] = Properties.Resources.ResourceManager.GetString(preface + vals[i]);
|
||||||
return string.Join(Properties.Resources.ListSeparator, vals);
|
return string.Join(Properties.Resources.ListSeparator, vals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,150 +1,147 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
internal static class EnumUtil
|
internal static class EnumUtil
|
||||||
{
|
{
|
||||||
public static void CheckIsEnum<T>(bool checkHasFlags = false)
|
public static void CheckIsEnum<T>(bool checkHasFlags = false)
|
||||||
{
|
{
|
||||||
if (!typeof(T).IsEnum)
|
if (!typeof(T).IsEnum)
|
||||||
throw new ArgumentException($"Type '{typeof(T).FullName}' is not an enum");
|
throw new ArgumentException($"Type '{typeof(T).FullName}' is not an enum");
|
||||||
if (checkHasFlags && !IsFlags<T>())
|
if (checkHasFlags && !IsFlags<T>())
|
||||||
throw new ArgumentException($"Type '{typeof(T).FullName}' doesn't have the 'Flags' attribute");
|
throw new ArgumentException($"Type '{typeof(T).FullName}' doesn't have the 'Flags' attribute");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsFlags<T>() => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
|
public static bool IsFlags<T>() => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
|
||||||
|
|
||||||
public static void CheckHasValue<T>(T value, string argName = null)
|
public static void CheckHasValue<T>(T value, string argName = null)
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>();
|
CheckIsEnum<T>();
|
||||||
if (IsFlags<T>())
|
if (IsFlags<T>())
|
||||||
{
|
{
|
||||||
var allFlags = 0L;
|
var allFlags = 0L;
|
||||||
foreach (T flag in Enum.GetValues(typeof(T)))
|
foreach (T flag in Enum.GetValues(typeof(T)))
|
||||||
allFlags |= Convert.ToInt64(flag);
|
allFlags |= Convert.ToInt64(flag);
|
||||||
if ((allFlags & Convert.ToInt64(value)) != 0L)
|
if ((allFlags & Convert.ToInt64(value)) != 0L)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (Enum.IsDefined(typeof(T), value))
|
else if (Enum.IsDefined(typeof(T), value))
|
||||||
return;
|
return;
|
||||||
throw new InvalidEnumArgumentException(argName ?? "value", Convert.ToInt32(value), typeof(T));
|
throw new InvalidEnumArgumentException(argName ?? "value", Convert.ToInt32(value), typeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte BitPosition<T>(this T flags) where T : struct, IConvertible
|
public static byte BitPosition<T>(this T flags) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var flagValue = Convert.ToInt64(flags);
|
var flagValue = Convert.ToInt64(flags);
|
||||||
if (flagValue == 0) throw new ArgumentException("The flag value is zero and has no bit position.");
|
if (flagValue == 0) throw new ArgumentException("The flag value is zero and has no bit position.");
|
||||||
var r = Math.Log(flagValue, 2);
|
var r = Math.Log(flagValue, 2);
|
||||||
if (r % 1 > 0) throw new ArithmeticException("The flag value has more than a single bit set.");
|
if (r % 1 > 0) throw new ArithmeticException("The flag value has more than a single bit set.");
|
||||||
return Convert.ToByte(r);
|
return Convert.ToByte(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsFlagSet<T>(this T flags, T flag) where T : struct, IConvertible
|
public static bool IsFlagSet<T>(this T flags, T flag) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var flagValue = Convert.ToInt64(flag);
|
var flagValue = Convert.ToInt64(flag);
|
||||||
return (Convert.ToInt64(flags) & flagValue) == flagValue;
|
return (Convert.ToInt64(flags) & flagValue) == flagValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsValidFlagValue<T>(this T flags) where T : struct, IConvertible
|
public static bool IsValidFlagValue<T>(this T flags) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var found = 0L;
|
var found = 0L;
|
||||||
foreach (T flag in Enum.GetValues(typeof(T)))
|
foreach (T flag in Enum.GetValues(typeof(T)))
|
||||||
{
|
{
|
||||||
if (flags.IsFlagSet(flag))
|
if (flags.IsFlagSet(flag))
|
||||||
found |= Convert.ToInt64(flag);
|
found |= Convert.ToInt64(flag);
|
||||||
}
|
}
|
||||||
return found == Convert.ToInt64(flags);
|
return found == Convert.ToInt64(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetFlags<T>(ref T flags, T flag, bool set = true) where T : struct, IConvertible
|
public static void SetFlags<T>(ref T flags, T flag, bool set = true) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
var flagsValue = Convert.ToInt64(flags);
|
var flagsValue = Convert.ToInt64(flags);
|
||||||
var flagValue = Convert.ToInt64(flag);
|
var flagValue = Convert.ToInt64(flag);
|
||||||
if (set)
|
if (set)
|
||||||
flagsValue |= flagValue;
|
flagsValue |= flagValue;
|
||||||
else
|
else
|
||||||
flagsValue &= (~flagValue);
|
flagsValue &= (~flagValue);
|
||||||
flags = (T)Enum.ToObject(typeof(T), flagsValue);
|
flags = (T)Enum.ToObject(typeof(T), flagsValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T SetFlags<T>(this T flags, T flag, bool set = true) where T : struct, IConvertible
|
public static T SetFlags<T>(this T flags, T flag, bool set = true) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
var ret = flags;
|
var ret = flags;
|
||||||
SetFlags<T>(ref ret, flag, set);
|
SetFlags<T>(ref ret, flag, set);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T ClearFlags<T>(this T flags, T flag) where T : struct, IConvertible => flags.SetFlags(flag, false);
|
public static T ClearFlags<T>(this T flags, T flag) where T : struct, IConvertible => flags.SetFlags(flag, false);
|
||||||
|
|
||||||
public static IEnumerable<T> GetFlags<T>(this T value) where T : struct, IConvertible
|
public static IEnumerable<T> GetFlags<T>(this T value) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
foreach (T flag in Enum.GetValues(typeof(T)))
|
foreach (T flag in Enum.GetValues(typeof(T)))
|
||||||
{
|
{
|
||||||
if (value.IsFlagSet(flag))
|
if (value.IsFlagSet(flag))
|
||||||
yield return flag;
|
yield return flag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct, IConvertible
|
public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>(true);
|
CheckIsEnum<T>(true);
|
||||||
long lValue = 0;
|
long lValue = 0;
|
||||||
foreach (var flag in flags)
|
foreach (var flag in flags)
|
||||||
{
|
{
|
||||||
var lFlag = Convert.ToInt64(flag);
|
var lFlag = Convert.ToInt64(flag);
|
||||||
lValue |= lFlag;
|
lValue |= lFlag;
|
||||||
}
|
}
|
||||||
return (T)Enum.ToObject(typeof(T), lValue);
|
return (T)Enum.ToObject(typeof(T), lValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetDescription<T>(this T value) where T : struct, IConvertible
|
public static string GetDescription<T>(this T value) where T : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<T>();
|
CheckIsEnum<T>();
|
||||||
var name = Enum.GetName(typeof(T), value);
|
var name = Enum.GetName(typeof(T), value);
|
||||||
if (name != null)
|
if (name != null)
|
||||||
{
|
{
|
||||||
var field = typeof(T).GetField(name);
|
var field = typeof(T).GetField(name);
|
||||||
if (field != null)
|
if (field != null)
|
||||||
{
|
{
|
||||||
var attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
|
var attr = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
|
||||||
if (attr != null)
|
if (attr != null)
|
||||||
{
|
{
|
||||||
return attr.Description;
|
return attr.Description;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object or returns the value of <paramref name="defaultVal"/>. If <paramref name="defaultVal"/> is undefined, it returns the first declared item in the enumerated type.
|
/// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object or returns the value of <paramref name="defaultVal"/>. If <paramref name="defaultVal"/> is undefined, it returns the first declared item in the enumerated type.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TEnum">The enumeration type to which to convert <paramref name="value"/>.</typeparam>
|
/// <typeparam name="TEnum">The enumeration type to which to convert <paramref name="value"/>.</typeparam>
|
||||||
/// <param name="value">The string representation of the enumeration name or underlying value to convert.</param>
|
/// <param name="value">The string representation of the enumeration name or underlying value to convert.</param>
|
||||||
/// <param name="ignoreCase"><c>true</c> to ignore case; <c>false</c> to consider case.</param>
|
/// <param name="ignoreCase"><c>true</c> to ignore case; <c>false</c> to consider case.</param>
|
||||||
/// <param name="defaultVal">The default value.</param>
|
/// <param name="defaultVal">The default value.</param>
|
||||||
/// <returns>An object of type <typeparamref name="TEnum"/> whose value is represented by value.</returns>
|
/// <returns>An object of type <typeparamref name="TEnum"/> whose value is represented by value.</returns>
|
||||||
public static TEnum TryParse<TEnum>(string value, bool ignoreCase = false, TEnum defaultVal = default(TEnum)) where TEnum : struct, IConvertible
|
public static TEnum TryParse<TEnum>(string value, bool ignoreCase = false, TEnum defaultVal = default(TEnum)) where TEnum : struct, IConvertible
|
||||||
{
|
{
|
||||||
CheckIsEnum<TEnum>();
|
CheckIsEnum<TEnum>();
|
||||||
try { return (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); } catch { }
|
try { return (TEnum)Enum.Parse(typeof(TEnum), value, ignoreCase); } catch { }
|
||||||
if (!Enum.IsDefined(typeof(TEnum), defaultVal))
|
if (!Enum.IsDefined(typeof(TEnum), defaultVal))
|
||||||
{
|
{
|
||||||
var v = Enum.GetValues(typeof(TEnum));
|
var v = Enum.GetValues(typeof(TEnum));
|
||||||
if (v != null && v.Length > 0)
|
if (v != null && v.Length > 0)
|
||||||
return (TEnum)v.GetValue(0);
|
return (TEnum)v.GetValue(0);
|
||||||
}
|
}
|
||||||
return defaultVal;
|
return defaultVal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,131 +1,127 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Security.Permissions;
|
using System.Security.Permissions;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Abstract class for throwing a method specific exception.
|
/// Abstract class for throwing a method specific exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public abstract class TSNotSupportedException : Exception
|
public abstract class TSNotSupportedException : Exception
|
||||||
{
|
{
|
||||||
/// <summary>Defines the minimum supported version for the action not allowed by this exception.</summary>
|
/// <summary>Defines the minimum supported version for the action not allowed by this exception.</summary>
|
||||||
protected readonly TaskCompatibility min;
|
protected readonly TaskCompatibility min;
|
||||||
private readonly string myMessage;
|
private readonly string myMessage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TSNotSupportedException"/> class.
|
/// Initializes a new instance of the <see cref="TSNotSupportedException"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected TSNotSupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext)
|
protected TSNotSupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext)
|
||||||
: base(serializationInfo, streamingContext)
|
: base(serializationInfo, streamingContext)
|
||||||
{
|
{
|
||||||
try { min = (TaskCompatibility)serializationInfo.GetValue("min", typeof(TaskCompatibility)); }
|
try { min = (TaskCompatibility)serializationInfo.GetValue("min", typeof(TaskCompatibility)); }
|
||||||
catch { min = TaskCompatibility.V1; }
|
catch { min = TaskCompatibility.V1; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TSNotSupportedException(TaskCompatibility minComp)
|
internal TSNotSupportedException(TaskCompatibility minComp)
|
||||||
{
|
{
|
||||||
min = minComp;
|
min = minComp;
|
||||||
var stackTrace = new StackTrace();
|
var stackTrace = new StackTrace();
|
||||||
var stackFrame = stackTrace.GetFrame(2);
|
var stackFrame = stackTrace.GetFrame(2);
|
||||||
var methodBase = stackFrame.GetMethod();
|
var methodBase = stackFrame.GetMethod();
|
||||||
myMessage = $"{methodBase.DeclaringType?.Name}.{methodBase.Name} is not supported on {LibName}";
|
myMessage = $"{methodBase.DeclaringType?.Name}.{methodBase.Name} is not supported on {LibName}";
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TSNotSupportedException(string message, TaskCompatibility minComp)
|
internal TSNotSupportedException(string message, TaskCompatibility minComp)
|
||||||
{
|
{
|
||||||
myMessage = message;
|
myMessage = message;
|
||||||
min = minComp;
|
min = minComp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a message that describes the current exception.
|
/// Gets a message that describes the current exception.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override string Message => myMessage;
|
public override string Message => myMessage;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the minimum supported TaskScheduler version required for this method or property.
|
/// Gets the minimum supported TaskScheduler version required for this method or property.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TaskCompatibility MinimumSupportedVersion => min;
|
public TaskCompatibility MinimumSupportedVersion => min;
|
||||||
|
|
||||||
internal abstract string LibName { get; }
|
internal abstract string LibName { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the object data.
|
/// Gets the object data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="info">The information.</param>
|
/// <param name="info">The information.</param>
|
||||||
/// <param name="context">The context.</param>
|
/// <param name="context">The context.</param>
|
||||||
[SecurityCritical, SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
[SecurityCritical, SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
|
||||||
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
public override void GetObjectData(SerializationInfo info, StreamingContext context)
|
||||||
{
|
{
|
||||||
if (info == null)
|
if (info == null)
|
||||||
throw new ArgumentNullException(nameof(info));
|
throw new ArgumentNullException(nameof(info));
|
||||||
info.AddValue("min", min);
|
info.AddValue("min", min);
|
||||||
base.GetObjectData(info, context);
|
base.GetObjectData(info, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when the calling method is not supported by Task Scheduler 1.0.
|
/// Thrown when the calling method is not supported by Task Scheduler 1.0.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
public class NotV1SupportedException : TSNotSupportedException
|
public class NotV1SupportedException : TSNotSupportedException
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected NotV1SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
protected NotV1SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||||
internal NotV1SupportedException() : base(TaskCompatibility.V2) { }
|
internal NotV1SupportedException() : base(TaskCompatibility.V2) { }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message">The message.</param>
|
/// <param name="message">The message.</param>
|
||||||
public NotV1SupportedException(string message) : base(message, TaskCompatibility.V2) { }
|
public NotV1SupportedException(string message) : base(message, TaskCompatibility.V2) { }
|
||||||
internal override string LibName => "Task Scheduler 1.0";
|
internal override string LibName => "Task Scheduler 1.0";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when the calling method is not supported by Task Scheduler 2.0.
|
/// Thrown when the calling method is not supported by Task Scheduler 2.0.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
public class NotV2SupportedException : TSNotSupportedException
|
public class NotV2SupportedException : TSNotSupportedException
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected NotV2SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
protected NotV2SupportedException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||||
internal NotV2SupportedException() : base(TaskCompatibility.V1) { }
|
internal NotV2SupportedException() : base(TaskCompatibility.V1) { }
|
||||||
internal NotV2SupportedException(string message) : base(message, TaskCompatibility.V1) { }
|
internal NotV2SupportedException(string message) : base(message, TaskCompatibility.V1) { }
|
||||||
internal override string LibName => "Task Scheduler 2.0 (1.2)";
|
internal override string LibName => "Task Scheduler 2.0 (1.2)";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Thrown when the calling method is not supported by Task Scheduler versions prior to the one specified.
|
/// Thrown when the calling method is not supported by Task Scheduler versions prior to the one specified.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerStepThrough, Serializable]
|
[DebuggerStepThrough, Serializable]
|
||||||
public class NotSupportedPriorToException : TSNotSupportedException
|
public class NotSupportedPriorToException : TSNotSupportedException
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
/// Initializes a new instance of the <see cref="NotV1SupportedException" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="serializationInfo">The serialization information.</param>
|
/// <param name="serializationInfo">The serialization information.</param>
|
||||||
/// <param name="streamingContext">The streaming context.</param>
|
/// <param name="streamingContext">The streaming context.</param>
|
||||||
protected NotSupportedPriorToException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
protected NotSupportedPriorToException(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { }
|
||||||
internal NotSupportedPriorToException(TaskCompatibility supportedVersion) : base(supportedVersion) { }
|
internal NotSupportedPriorToException(TaskCompatibility supportedVersion) : base(supportedVersion) { }
|
||||||
internal override string LibName => $"Task Scheduler versions prior to 2.{((int)min) - 2} (1.{(int)min})";
|
internal override string LibName => $"Task Scheduler versions prior to 2.{((int)min) - 2} (1.{(int)min})";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,139 +1,135 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Extensions related to <c>System.Reflection</c></summary>
|
/// <summary>Extensions related to <c>System.Reflection</c></summary>
|
||||||
internal static class ReflectionHelper
|
internal static class ReflectionHelper
|
||||||
{
|
{
|
||||||
/// <summary>Loads a type from a named assembly.</summary>
|
/// <summary>Loads a type from a named assembly.</summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <param name="asmRef">The name or path of the file that contains the manifest of the assembly.</param>
|
/// <param name="asmRef">The name or path of the file that contains the manifest of the assembly.</param>
|
||||||
/// <returns>The <see cref="Type"/> reference, or <c>null</c> if type or assembly not found.</returns>
|
/// <returns>The <see cref="Type"/> reference, or <c>null</c> if type or assembly not found.</returns>
|
||||||
public static Type LoadType(string typeName, string asmRef)
|
public static Type LoadType(string typeName, string asmRef)
|
||||||
{
|
{
|
||||||
Type ret = null;
|
Type ret = null;
|
||||||
if (!TryGetType(Assembly.GetCallingAssembly(), typeName, ref ret))
|
if (!TryGetType(Assembly.GetCallingAssembly(), typeName, ref ret))
|
||||||
if (!TryGetType(asmRef, typeName, ref ret))
|
if (!TryGetType(asmRef, typeName, ref ret))
|
||||||
if (!TryGetType(Assembly.GetExecutingAssembly(), typeName, ref ret))
|
if (!TryGetType(Assembly.GetExecutingAssembly(), typeName, ref ret))
|
||||||
TryGetType(Assembly.GetEntryAssembly(), typeName, ref ret);
|
TryGetType(Assembly.GetEntryAssembly(), typeName, ref ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <param name="asmRef">The assembly reference name from which to load the type.</param>
|
/// <param name="asmRef">The assembly reference name from which to load the type.</param>
|
||||||
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
||||||
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
||||||
private static bool TryGetType(string asmRef, string typeName, ref Type type)
|
private static bool TryGetType(string asmRef, string typeName, ref Type type)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (System.IO.File.Exists(asmRef))
|
if (System.IO.File.Exists(asmRef))
|
||||||
return TryGetType(Assembly.LoadFrom(asmRef), typeName, ref type);
|
return TryGetType(Assembly.LoadFrom(asmRef), typeName, ref type);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
/// <summary>Tries the retrieve a <see cref="Type"/> reference from an assembly.</summary>
|
||||||
/// <param name="typeName">Name of the type.</param>
|
/// <param name="typeName">Name of the type.</param>
|
||||||
/// <param name="asm">The assembly from which to load the type.</param>
|
/// <param name="asm">The assembly from which to load the type.</param>
|
||||||
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
/// <param name="type">The <see cref="Type"/> reference, if found.</param>
|
||||||
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the type was found in the assembly; otherwise, <c>false</c>.</returns>
|
||||||
private static bool TryGetType(Assembly asm, string typeName, ref Type type)
|
private static bool TryGetType(Assembly asm, string typeName, ref Type type)
|
||||||
{
|
{
|
||||||
if (asm != null)
|
if (asm != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
type = asm.GetType(typeName, false, false);
|
type = asm.GetType(typeName, false, false);
|
||||||
return (type != null);
|
return (type != null);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
||||||
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
||||||
/// <param name="type">The type to be instantiated and then used to invoke the method. This method assumes the type has a default public constructor.</param>
|
/// <param name="type">The type to be instantiated and then used to invoke the method. This method assumes the type has a default public constructor.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
/// <returns>The value returned from the method.</returns>
|
/// <returns>The value returned from the method.</returns>
|
||||||
public static T InvokeMethod<T>(Type type, string methodName, params object[] args)
|
public static T InvokeMethod<T>(Type type, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
object o = Activator.CreateInstance(type);
|
object o = Activator.CreateInstance(type);
|
||||||
return InvokeMethod<T>(o, methodName, args);
|
return InvokeMethod<T>(o, methodName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
/// <summary>Invokes a named method on a created instance of a type with parameters.</summary>
|
||||||
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
||||||
/// <param name="type">The type to be instantiated and then used to invoke the method.</param>
|
/// <param name="type">The type to be instantiated and then used to invoke the method.</param>
|
||||||
/// <param name="instArgs">The arguments to supply to the constructor.</param>
|
/// <param name="instArgs">The arguments to supply to the constructor.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
/// <returns>The value returned from the method.</returns>
|
/// <returns>The value returned from the method.</returns>
|
||||||
public static T InvokeMethod<T>(Type type, object[] instArgs, string methodName, params object[] args)
|
public static T InvokeMethod<T>(Type type, object[] instArgs, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
object o = Activator.CreateInstance(type, instArgs);
|
object o = Activator.CreateInstance(type, instArgs);
|
||||||
return InvokeMethod<T>(o, methodName, args);
|
return InvokeMethod<T>(o, methodName, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
||||||
/// <param name="obj">The object on which to invoke the method.</param>
|
/// <param name="obj">The object on which to invoke the method.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
public static T InvokeMethod<T>(object obj, string methodName, params object[] args)
|
public static T InvokeMethod<T>(object obj, string methodName, params object[] args)
|
||||||
{
|
{
|
||||||
Type[] argTypes = (args == null || args.Length == 0) ? Type.EmptyTypes : Array.ConvertAll(args, delegate (object o) { return o == null ? typeof(object) : o.GetType(); });
|
Type[] argTypes = (args == null || args.Length == 0) ? Type.EmptyTypes : Array.ConvertAll(args, delegate (object o) { return o == null ? typeof(object) : o.GetType(); });
|
||||||
return InvokeMethod<T>(obj, methodName, argTypes, args);
|
return InvokeMethod<T>(obj, methodName, argTypes, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
/// <summary>Invokes a named method on an object with parameters and no return value.</summary>
|
||||||
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
/// <typeparam name="T">The expected type of the method's return value.</typeparam>
|
||||||
/// <param name="obj">The object on which to invoke the method.</param>
|
/// <param name="obj">The object on which to invoke the method.</param>
|
||||||
/// <param name="methodName">Name of the method.</param>
|
/// <param name="methodName">Name of the method.</param>
|
||||||
/// <param name="argTypes">The types of the <paramref name="args"/>.</param>
|
/// <param name="argTypes">The types of the <paramref name="args"/>.</param>
|
||||||
/// <param name="args">The arguments to provide to the method invocation.</param>
|
/// <param name="args">The arguments to provide to the method invocation.</param>
|
||||||
/// <returns>The value returned from the method.</returns>
|
/// <returns>The value returned from the method.</returns>
|
||||||
public static T InvokeMethod<T>(object obj, string methodName, Type[] argTypes, object[] args)
|
public static T InvokeMethod<T>(object obj, string methodName, Type[] argTypes, object[] args)
|
||||||
{
|
{
|
||||||
MethodInfo mi = obj?.GetType().GetMethod(methodName, argTypes);
|
MethodInfo mi = obj?.GetType().GetMethod(methodName, argTypes);
|
||||||
if (mi != null)
|
if (mi != null)
|
||||||
return (T)Convert.ChangeType(mi.Invoke(obj, args), typeof(T));
|
return (T)Convert.ChangeType(mi.Invoke(obj, args), typeof(T));
|
||||||
return default(T);
|
return default(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets a named property value from an object.</summary>
|
/// <summary>Gets a named property value from an object.</summary>
|
||||||
/// <typeparam name="T">The expected type of the property to be returned.</typeparam>
|
/// <typeparam name="T">The expected type of the property to be returned.</typeparam>
|
||||||
/// <param name="obj">The object from which to retrieve the property.</param>
|
/// <param name="obj">The object from which to retrieve the property.</param>
|
||||||
/// <param name="propName">Name of the property.</param>
|
/// <param name="propName">Name of the property.</param>
|
||||||
/// <param name="defaultValue">The default value to return in the instance that the property is not found.</param>
|
/// <param name="defaultValue">The default value to return in the instance that the property is not found.</param>
|
||||||
/// <returns>The property value, if found, or the <paramref name="defaultValue"/> if not.</returns>
|
/// <returns>The property value, if found, or the <paramref name="defaultValue"/> if not.</returns>
|
||||||
public static T GetProperty<T>(object obj, string propName, T defaultValue = default(T))
|
public static T GetProperty<T>(object obj, string propName, T defaultValue = default(T))
|
||||||
{
|
{
|
||||||
if (obj != null)
|
if (obj != null)
|
||||||
{
|
{
|
||||||
try { return (T)Convert.ChangeType(obj.GetType().InvokeMember(propName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, null, null), typeof(T)); }
|
try { return (T)Convert.ChangeType(obj.GetType().InvokeMember(propName, BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, null, null), typeof(T)); }
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Sets a named property on an object.</summary>
|
/// <summary>Sets a named property on an object.</summary>
|
||||||
/// <typeparam name="T">The type of the property to be set.</typeparam>
|
/// <typeparam name="T">The type of the property to be set.</typeparam>
|
||||||
/// <param name="obj">The object on which to set the property.</param>
|
/// <param name="obj">The object on which to set the property.</param>
|
||||||
/// <param name="propName">Name of the property.</param>
|
/// <param name="propName">Name of the property.</param>
|
||||||
/// <param name="value">The property value to set on the object.</param>
|
/// <param name="value">The property value to set on the object.</param>
|
||||||
public static void SetProperty<T>(object obj, string propName, T value)
|
public static void SetProperty<T>(object obj, string propName, T value)
|
||||||
{
|
{
|
||||||
try { obj?.GetType().InvokeMember(propName, BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, new object[] { value }, null); }
|
try { obj?.GetType().InvokeMember(propName, BindingFlags.SetProperty | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, obj, new object[] { value }, null); }
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -9,395 +9,395 @@ using winPEAS.TaskScheduler.V2;
|
|||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Collection of running tasks in a <see cref="TaskService"/>. This class has no public constructor and can only be accessed via the
|
/// Collection of running tasks in a <see cref="TaskService"/>. This class has no public constructor and can only be accessed via the
|
||||||
/// properties and functions within <see cref="TaskService"/>.
|
/// properties and functions within <see cref="TaskService"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class RunningTaskCollection : IReadOnlyList<RunningTask>, IDisposable
|
public sealed class RunningTaskCollection : IReadOnlyList<RunningTask>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly IRunningTaskCollection v2Coll;
|
private readonly IRunningTaskCollection v2Coll;
|
||||||
|
|
||||||
internal RunningTaskCollection([NotNull] TaskService svc) => this.svc = svc;
|
internal RunningTaskCollection([NotNull] TaskService svc) => this.svc = svc;
|
||||||
|
|
||||||
internal RunningTaskCollection([NotNull] TaskService svc, [NotNull] IRunningTaskCollection iTaskColl)
|
internal RunningTaskCollection([NotNull] TaskService svc, [NotNull] IRunningTaskCollection iTaskColl)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
v2Coll = iTaskColl;
|
v2Coll = iTaskColl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return v2Coll.Count;
|
return v2Coll.Count;
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var v1Enum = new V1RunningTaskEnumerator(svc);
|
var v1Enum = new V1RunningTaskEnumerator(svc);
|
||||||
while (v1Enum.MoveNext())
|
while (v1Enum.MoveNext())
|
||||||
i++;
|
i++;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the specified running task from the collection.</summary>
|
/// <summary>Gets the specified running task from the collection.</summary>
|
||||||
/// <param name="index">The index of the running task to be retrieved.</param>
|
/// <param name="index">The index of the running task to be retrieved.</param>
|
||||||
/// <returns>A <see cref="RunningTask"/> instance.</returns>
|
/// <returns>A <see cref="RunningTask"/> instance.</returns>
|
||||||
public RunningTask this[int index]
|
public RunningTask this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
{
|
{
|
||||||
var irt = v2Coll[++index];
|
var irt = v2Coll[++index];
|
||||||
return new RunningTask(svc, TaskService.GetTask(svc.v2TaskService, irt.Path), irt);
|
return new RunningTask(svc, TaskService.GetTask(svc.v2TaskService, irt.Path), irt);
|
||||||
}
|
}
|
||||||
|
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var v1Enum = new V1RunningTaskEnumerator(svc);
|
var v1Enum = new V1RunningTaskEnumerator(svc);
|
||||||
while (v1Enum.MoveNext())
|
while (v1Enum.MoveNext())
|
||||||
if (i++ == index)
|
if (i++ == index)
|
||||||
return v1Enum.Current;
|
return v1Enum.Current;
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
Marshal.ReleaseComObject(v2Coll);
|
Marshal.ReleaseComObject(v2Coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets an IEnumerator instance for this collection.</summary>
|
/// <summary>Gets an IEnumerator instance for this collection.</summary>
|
||||||
/// <returns>An enumerator.</returns>
|
/// <returns>An enumerator.</returns>
|
||||||
public IEnumerator<RunningTask> GetEnumerator()
|
public IEnumerator<RunningTask> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return new ComEnumerator<RunningTask, IRunningTask>(() => v2Coll.Count, (object o) => v2Coll[o], o =>
|
return new ComEnumerator<RunningTask, IRunningTask>(() => v2Coll.Count, (object o) => v2Coll[o], o =>
|
||||||
{
|
{
|
||||||
IRegisteredTask task = null;
|
IRegisteredTask task = null;
|
||||||
try { task = TaskService.GetTask(svc.v2TaskService, o.Path); } catch { }
|
try { task = TaskService.GetTask(svc.v2TaskService, o.Path); } catch { }
|
||||||
return task == null ? null : new RunningTask(svc, task, o);
|
return task == null ? null : new RunningTask(svc, task, o);
|
||||||
});
|
});
|
||||||
return new V1RunningTaskEnumerator(svc);
|
return new V1RunningTaskEnumerator(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
||||||
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
||||||
public override string ToString() => $"RunningTaskCollection; Count: {Count}";
|
public override string ToString() => $"RunningTaskCollection; Count: {Count}";
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
private class V1RunningTaskEnumerator : IEnumerator<RunningTask>
|
private class V1RunningTaskEnumerator : IEnumerator<RunningTask>
|
||||||
{
|
{
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly TaskCollection.V1TaskEnumerator tEnum;
|
private readonly TaskCollection.V1TaskEnumerator tEnum;
|
||||||
|
|
||||||
internal V1RunningTaskEnumerator([NotNull] TaskService svc)
|
internal V1RunningTaskEnumerator([NotNull] TaskService svc)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
tEnum = new TaskCollection.V1TaskEnumerator(svc);
|
tEnum = new TaskCollection.V1TaskEnumerator(svc);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RunningTask Current => new RunningTask(svc, tEnum.ICurrent);
|
public RunningTask Current => new RunningTask(svc, tEnum.ICurrent);
|
||||||
|
|
||||||
object System.Collections.IEnumerator.Current => Current;
|
object System.Collections.IEnumerator.Current => Current;
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose() => tEnum.Dispose();
|
public void Dispose() => tEnum.Dispose();
|
||||||
|
|
||||||
public bool MoveNext() => tEnum.MoveNext() && (tEnum.Current?.State == TaskState.Running || MoveNext());
|
public bool MoveNext() => tEnum.MoveNext() && (tEnum.Current?.State == TaskState.Running || MoveNext());
|
||||||
|
|
||||||
public void Reset() => tEnum.Reset();
|
public void Reset() => tEnum.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains all the tasks that are registered within a <see cref="TaskFolder"/>. This class has no public constructor and can only be
|
/// Contains all the tasks that are registered within a <see cref="TaskFolder"/>. This class has no public constructor and can only be
|
||||||
/// accessed via the properties and functions within <see cref="TaskFolder"/>.
|
/// accessed via the properties and functions within <see cref="TaskFolder"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Potentially breaking change in 1.6.2 and later where under V1 the list previously included the '.job' extension on the task name.
|
/// Potentially breaking change in 1.6.2 and later where under V1 the list previously included the '.job' extension on the task name.
|
||||||
/// This has been removed so that it is consistent with V2.
|
/// This has been removed so that it is consistent with V2.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// <code>public class Program
|
/// <code>public class Program
|
||||||
/// {
|
/// {
|
||||||
/// bool RootFolderHasTask(string taskName)
|
/// bool RootFolderHasTask(string taskName)
|
||||||
/// {
|
/// {
|
||||||
/// if (TaskService.Instance.RootFolder.Tasks.Count > 0)
|
/// if (TaskService.Instance.RootFolder.Tasks.Count > 0)
|
||||||
/// {
|
/// {
|
||||||
/// return TaskService.Instance.RootFolder.Tasks.Exists(taskName);
|
/// return TaskService.Instance.RootFolder.Tasks.Exists(taskName);
|
||||||
/// }
|
/// }
|
||||||
/// return false;
|
/// return false;
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// TaskCollection GetRootTasksStartingWith(string value)
|
/// TaskCollection GetRootTasksStartingWith(string value)
|
||||||
/// {
|
/// {
|
||||||
/// var pattern = $"^{Regex.Escape(value)}.*$";
|
/// var pattern = $"^{Regex.Escape(value)}.*$";
|
||||||
/// return TaskService.Instance.RootFolder.GetTasks(new Regex(pattern));
|
/// return TaskService.Instance.RootFolder.GetTasks(new Regex(pattern));
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// public static void Main()
|
/// public static void Main()
|
||||||
/// {
|
/// {
|
||||||
/// foreach (var task in GetRootTasksStartingWith("MyCo"))
|
/// foreach (var task in GetRootTasksStartingWith("MyCo"))
|
||||||
/// if (RootFolderHasTask(task.Name))
|
/// if (RootFolderHasTask(task.Name))
|
||||||
/// Console.WriteLine(task.Name);
|
/// Console.WriteLine(task.Name);
|
||||||
/// }
|
/// }
|
||||||
/// }</code>
|
/// }</code>
|
||||||
/// </example>
|
/// </example>
|
||||||
[PublicAPI]
|
[PublicAPI]
|
||||||
public sealed class TaskCollection : IReadOnlyList<Task>, IDisposable
|
public sealed class TaskCollection : IReadOnlyList<Task>, IDisposable
|
||||||
{
|
{
|
||||||
private readonly TaskFolder fld;
|
private readonly TaskFolder fld;
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly IRegisteredTaskCollection v2Coll;
|
private readonly IRegisteredTaskCollection v2Coll;
|
||||||
private Regex filter;
|
private Regex filter;
|
||||||
private ITaskScheduler v1TS;
|
private ITaskScheduler v1TS;
|
||||||
|
|
||||||
internal TaskCollection([NotNull] TaskService svc, Regex filter = null)
|
internal TaskCollection([NotNull] TaskService svc, Regex filter = null)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
Filter = filter;
|
Filter = filter;
|
||||||
v1TS = svc.v1TaskScheduler;
|
v1TS = svc.v1TaskScheduler;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TaskCollection([NotNull] TaskFolder folder, [NotNull] IRegisteredTaskCollection iTaskColl, Regex filter = null)
|
internal TaskCollection([NotNull] TaskFolder folder, [NotNull] IRegisteredTaskCollection iTaskColl, Regex filter = null)
|
||||||
{
|
{
|
||||||
svc = folder.TaskService;
|
svc = folder.TaskService;
|
||||||
Filter = filter;
|
Filter = filter;
|
||||||
fld = folder;
|
fld = folder;
|
||||||
v2Coll = iTaskColl;
|
v2Coll = iTaskColl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
/// <summary>Gets the number of registered tasks in the collection.</summary>
|
||||||
public int Count
|
public int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
{
|
{
|
||||||
var v2Enum = new V2TaskEnumerator(fld, v2Coll, filter);
|
var v2Enum = new V2TaskEnumerator(fld, v2Coll, filter);
|
||||||
while (v2Enum.MoveNext())
|
while (v2Enum.MoveNext())
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var v1Enum = new V1TaskEnumerator(svc, filter);
|
var v1Enum = new V1TaskEnumerator(svc, filter);
|
||||||
return v1Enum.Count;
|
return v1Enum.Count;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets or sets the regular expression filter for task names.</summary>
|
/// <summary>Gets or sets the regular expression filter for task names.</summary>
|
||||||
/// <value>The regular expression filter.</value>
|
/// <value>The regular expression filter.</value>
|
||||||
private Regex Filter
|
private Regex Filter
|
||||||
{
|
{
|
||||||
get => filter;
|
get => filter;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
var sfilter = value?.ToString().TrimStart('^').TrimEnd('$') ?? string.Empty;
|
var sfilter = value?.ToString().TrimStart('^').TrimEnd('$') ?? string.Empty;
|
||||||
if (sfilter == string.Empty || sfilter == "*")
|
if (sfilter == string.Empty || sfilter == "*")
|
||||||
filter = null;
|
filter = null;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (value != null && value.ToString().TrimEnd('$').EndsWith("\\.job", StringComparison.InvariantCultureIgnoreCase))
|
if (value != null && value.ToString().TrimEnd('$').EndsWith("\\.job", StringComparison.InvariantCultureIgnoreCase))
|
||||||
filter = new Regex(value.ToString().Replace("\\.job", ""));
|
filter = new Regex(value.ToString().Replace("\\.job", ""));
|
||||||
else
|
else
|
||||||
filter = value;
|
filter = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the specified registered task from the collection.</summary>
|
/// <summary>Gets the specified registered task from the collection.</summary>
|
||||||
/// <param name="index">The index of the registered task to be retrieved.</param>
|
/// <param name="index">The index of the registered task to be retrieved.</param>
|
||||||
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
||||||
public Task this[int index]
|
public Task this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
var te = GetEnumerator();
|
var te = GetEnumerator();
|
||||||
while (te.MoveNext())
|
while (te.MoveNext())
|
||||||
if (i++ == index)
|
if (i++ == index)
|
||||||
return te.Current;
|
return te.Current;
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the named registered task from the collection.</summary>
|
/// <summary>Gets the named registered task from the collection.</summary>
|
||||||
/// <param name="name">The name of the registered task to be retrieved.</param>
|
/// <param name="name">The name of the registered task to be retrieved.</param>
|
||||||
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
/// <returns>A <see cref="Task"/> instance that contains the requested context.</returns>
|
||||||
public Task this[string name]
|
public Task this[string name]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return Task.CreateTask(svc, v2Coll[name]);
|
return Task.CreateTask(svc, v2Coll[name]);
|
||||||
|
|
||||||
var v1Task = svc.GetTask(name);
|
var v1Task = svc.GetTask(name);
|
||||||
if (v1Task != null)
|
if (v1Task != null)
|
||||||
return v1Task;
|
return v1Task;
|
||||||
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(name));
|
throw new ArgumentOutOfRangeException(nameof(name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
v1TS = null;
|
v1TS = null;
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
Marshal.ReleaseComObject(v2Coll);
|
Marshal.ReleaseComObject(v2Coll);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the specified task exists.</summary>
|
/// <summary>Determines whether the specified task exists.</summary>
|
||||||
/// <param name="taskName">The name of the task.</param>
|
/// <param name="taskName">The name of the task.</param>
|
||||||
/// <returns>true if task exists; otherwise, false.</returns>
|
/// <returns>true if task exists; otherwise, false.</returns>
|
||||||
public bool Exists([NotNull] string taskName)
|
public bool Exists([NotNull] string taskName)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return v2Coll[taskName] != null;
|
return v2Coll[taskName] != null;
|
||||||
|
|
||||||
return svc.GetTask(taskName) != null;
|
return svc.GetTask(taskName) != null;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the collection enumerator for the register task collection.</summary>
|
/// <summary>Gets the collection enumerator for the register task collection.</summary>
|
||||||
/// <returns>An <see cref="System.Collections.IEnumerator"/> for this collection.</returns>
|
/// <returns>An <see cref="System.Collections.IEnumerator"/> for this collection.</returns>
|
||||||
public IEnumerator<Task> GetEnumerator()
|
public IEnumerator<Task> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v1TS != null)
|
if (v1TS != null)
|
||||||
return new V1TaskEnumerator(svc, filter);
|
return new V1TaskEnumerator(svc, filter);
|
||||||
return new V2TaskEnumerator(fld, v2Coll, filter);
|
return new V2TaskEnumerator(fld, v2Coll, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
/// <summary>Returns a <see cref="System.String"/> that represents this instance.</summary>
|
||||||
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
/// <returns>A <see cref="System.String"/> that represents this instance.</returns>
|
||||||
public override string ToString() => $"TaskCollection; Count: {Count}";
|
public override string ToString() => $"TaskCollection; Count: {Count}";
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
internal class V1TaskEnumerator : IEnumerator<Task>
|
internal class V1TaskEnumerator : IEnumerator<Task>
|
||||||
{
|
{
|
||||||
private readonly Regex filter;
|
private readonly Regex filter;
|
||||||
private readonly TaskService svc;
|
private readonly TaskService svc;
|
||||||
private readonly IEnumWorkItems wienum;
|
private readonly IEnumWorkItems wienum;
|
||||||
private string curItem;
|
private string curItem;
|
||||||
private ITaskScheduler ts;
|
private ITaskScheduler ts;
|
||||||
|
|
||||||
/// <summary>Internal constructor</summary>
|
/// <summary>Internal constructor</summary>
|
||||||
/// <param name="svc">TaskService instance</param>
|
/// <param name="svc">TaskService instance</param>
|
||||||
/// <param name="filter">The filter.</param>
|
/// <param name="filter">The filter.</param>
|
||||||
internal V1TaskEnumerator(TaskService svc, Regex filter = null)
|
internal V1TaskEnumerator(TaskService svc, Regex filter = null)
|
||||||
{
|
{
|
||||||
this.svc = svc;
|
this.svc = svc;
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
ts = svc.v1TaskScheduler;
|
ts = svc.v1TaskScheduler;
|
||||||
wienum = ts?.Enum();
|
wienum = ts?.Enum();
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Retrieves the current task. See <see cref="System.Collections.IEnumerator.Current"/> for more information.</summary>
|
/// <summary>Retrieves the current task. See <see cref="System.Collections.IEnumerator.Current"/> for more information.</summary>
|
||||||
public Task Current => new Task(svc, ICurrent);
|
public Task Current => new Task(svc, ICurrent);
|
||||||
|
|
||||||
object System.Collections.IEnumerator.Current => Current;
|
object System.Collections.IEnumerator.Current => Current;
|
||||||
|
|
||||||
internal int Count
|
internal int Count
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var i = 0;
|
var i = 0;
|
||||||
Reset();
|
Reset();
|
||||||
while (MoveNext())
|
while (MoveNext())
|
||||||
i++;
|
i++;
|
||||||
Reset();
|
Reset();
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ITask ICurrent => TaskService.GetTask(ts, curItem);
|
internal ITask ICurrent => TaskService.GetTask(ts, curItem);
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (wienum != null) Marshal.ReleaseComObject(wienum);
|
if (wienum != null) Marshal.ReleaseComObject(wienum);
|
||||||
ts = null;
|
ts = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Moves to the next task. See MoveNext for more information.</summary>
|
/// <summary>Moves to the next task. See MoveNext for more information.</summary>
|
||||||
/// <returns>true if next task found, false if no more tasks.</returns>
|
/// <returns>true if next task found, false if no more tasks.</returns>
|
||||||
public bool MoveNext()
|
public bool MoveNext()
|
||||||
{
|
{
|
||||||
var names = IntPtr.Zero;
|
var names = IntPtr.Zero;
|
||||||
var valid = false;
|
var valid = false;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
curItem = null;
|
curItem = null;
|
||||||
uint uFetched = 0;
|
uint uFetched = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wienum?.Next(1, out names, out uFetched);
|
wienum?.Next(1, out names, out uFetched);
|
||||||
if (uFetched != 1)
|
if (uFetched != 1)
|
||||||
break;
|
break;
|
||||||
using (var name = new CoTaskMemString(Marshal.ReadIntPtr(names)))
|
using (var name = new CoTaskMemString(Marshal.ReadIntPtr(names)))
|
||||||
curItem = name.ToString();
|
curItem = name.ToString();
|
||||||
if (curItem != null && curItem.EndsWith(".job", StringComparison.InvariantCultureIgnoreCase))
|
if (curItem != null && curItem.EndsWith(".job", StringComparison.InvariantCultureIgnoreCase))
|
||||||
curItem = curItem.Remove(curItem.Length - 4);
|
curItem = curItem.Remove(curItem.Length - 4);
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
finally { Marshal.FreeCoTaskMem(names); names = IntPtr.Zero; }
|
finally { Marshal.FreeCoTaskMem(names); names = IntPtr.Zero; }
|
||||||
|
|
||||||
// If name doesn't match filter, look for next item
|
// If name doesn't match filter, look for next item
|
||||||
if (filter != null && curItem != null)
|
if (filter != null && curItem != null)
|
||||||
{
|
{
|
||||||
if (!filter.IsMatch(curItem))
|
if (!filter.IsMatch(curItem))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ITask itask = null;
|
ITask itask = null;
|
||||||
try { itask = ICurrent; valid = true; }
|
try { itask = ICurrent; valid = true; }
|
||||||
catch { valid = false; }
|
catch { valid = false; }
|
||||||
finally { Marshal.ReleaseComObject(itask); }
|
finally { Marshal.ReleaseComObject(itask); }
|
||||||
} while (!valid);
|
} while (!valid);
|
||||||
|
|
||||||
return (curItem != null);
|
return (curItem != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Reset task enumeration. See Reset for more information.</summary>
|
/// <summary>Reset task enumeration. See Reset for more information.</summary>
|
||||||
public void Reset()
|
public void Reset()
|
||||||
{
|
{
|
||||||
curItem = null;
|
curItem = null;
|
||||||
wienum?.Reset();
|
wienum?.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class V2TaskEnumerator : ComEnumerator<Task, IRegisteredTask>
|
private class V2TaskEnumerator : ComEnumerator<Task, IRegisteredTask>
|
||||||
{
|
{
|
||||||
private readonly Regex filter;
|
private readonly Regex filter;
|
||||||
|
|
||||||
internal V2TaskEnumerator(TaskFolder folder, IRegisteredTaskCollection iTaskColl, Regex filter = null) :
|
internal V2TaskEnumerator(TaskFolder folder, IRegisteredTaskCollection iTaskColl, Regex filter = null) :
|
||||||
base(() => iTaskColl.Count, (object o) => iTaskColl[o], o => Task.CreateTask(folder.TaskService, o)) => this.filter = filter;
|
base(() => iTaskColl.Count, (object o) => iTaskColl[o], o => Task.CreateTask(folder.TaskService, o)) => this.filter = filter;
|
||||||
|
|
||||||
public override bool MoveNext()
|
public override bool MoveNext()
|
||||||
{
|
{
|
||||||
var hasNext = base.MoveNext();
|
var hasNext = base.MoveNext();
|
||||||
while (hasNext)
|
while (hasNext)
|
||||||
{
|
{
|
||||||
if (filter == null || filter.IsMatch(iEnum?.Current?.Name ?? ""))
|
if (filter == null || filter.IsMatch(iEnum?.Current?.Name ?? ""))
|
||||||
break;
|
break;
|
||||||
hasNext = base.MoveNext();
|
hasNext = base.MoveNext();
|
||||||
}
|
}
|
||||||
return hasNext;
|
return hasNext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,147 +1,144 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static class InteropUtil
|
internal static class InteropUtil
|
||||||
{
|
{
|
||||||
private const int cbBuffer = 256;
|
private const int cbBuffer = 256;
|
||||||
|
|
||||||
public static T ToStructure<T>(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
|
public static T ToStructure<T>(IntPtr ptr) => (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||||
|
|
||||||
public static IntPtr StructureToPtr(object value)
|
public static IntPtr StructureToPtr(object value)
|
||||||
{
|
{
|
||||||
IntPtr ret = Marshal.AllocHGlobal(Marshal.SizeOf(value));
|
IntPtr ret = Marshal.AllocHGlobal(Marshal.SizeOf(value));
|
||||||
Marshal.StructureToPtr(value, ret, false);
|
Marshal.StructureToPtr(value, ret, false);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AllocString(ref IntPtr ptr, ref uint size)
|
public static void AllocString(ref IntPtr ptr, ref uint size)
|
||||||
{
|
{
|
||||||
FreeString(ref ptr, ref size);
|
FreeString(ref ptr, ref size);
|
||||||
if (size == 0) size = cbBuffer;
|
if (size == 0) size = cbBuffer;
|
||||||
ptr = Marshal.AllocHGlobal(cbBuffer);
|
ptr = Marshal.AllocHGlobal(cbBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FreeString(ref IntPtr ptr, ref uint size)
|
public static void FreeString(ref IntPtr ptr, ref uint size)
|
||||||
{
|
{
|
||||||
if (ptr != IntPtr.Zero)
|
if (ptr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Marshal.FreeHGlobal(ptr);
|
Marshal.FreeHGlobal(ptr);
|
||||||
ptr = IntPtr.Zero;
|
ptr = IntPtr.Zero;
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetString(IntPtr pString) => Marshal.PtrToStringUni(pString);
|
public static string GetString(IntPtr pString) => Marshal.PtrToStringUni(pString);
|
||||||
|
|
||||||
public static bool SetString(ref IntPtr ptr, ref uint size, string value = null)
|
public static bool SetString(ref IntPtr ptr, ref uint size, string value = null)
|
||||||
{
|
{
|
||||||
string s = GetString(ptr);
|
string s = GetString(ptr);
|
||||||
if (value == string.Empty) value = null;
|
if (value == string.Empty) value = null;
|
||||||
if (string.CompareOrdinal(s, value) != 0)
|
if (string.CompareOrdinal(s, value) != 0)
|
||||||
{
|
{
|
||||||
FreeString(ref ptr, ref size);
|
FreeString(ref ptr, ref size);
|
||||||
if (value != null)
|
if (value != null)
|
||||||
{
|
{
|
||||||
ptr = Marshal.StringToHGlobalUni(value);
|
ptr = Marshal.StringToHGlobalUni(value);
|
||||||
size = (uint)value.Length + 1;
|
size = (uint)value.Length + 1;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TS">Type of native structure used by the C-style array.</typeparam>
|
/// <typeparam name="TS">Type of native structure used by the C-style array.</typeparam>
|
||||||
/// <typeparam name="T">Output type for the CLI array. <typeparamref name="TS"/> must be able to convert to <typeparamref name="T"/>.</typeparam>
|
/// <typeparam name="T">Output type for the CLI array. <typeparamref name="TS"/> must be able to convert to <typeparamref name="T"/>.</typeparam>
|
||||||
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
||||||
/// <param name="count">The number of items in the native array.</param>
|
/// <param name="count">The number of items in the native array.</param>
|
||||||
/// <returns>An array of type <typeparamref name="T"/> containing the converted elements of the native array.</returns>
|
/// <returns>An array of type <typeparamref name="T"/> containing the converted elements of the native array.</returns>
|
||||||
public static T[] ToArray<TS, T>(IntPtr ptr, int count) where TS : IConvertible
|
public static T[] ToArray<TS, T>(IntPtr ptr, int count) where TS : IConvertible
|
||||||
{
|
{
|
||||||
var ret = new T[count];
|
var ret = new T[count];
|
||||||
var stSize = Marshal.SizeOf(typeof(TS));
|
var stSize = Marshal.SizeOf(typeof(TS));
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
||||||
var val = ToStructure<TS>(tempPtr);
|
var val = ToStructure<TS>(tempPtr);
|
||||||
ret[i] = (T)Convert.ChangeType(val, typeof(T));
|
ret[i] = (T)Convert.ChangeType(val, typeof(T));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
/// Converts an <see cref="IntPtr"/> that points to a C-style array into a CLI array.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">Type of native structure used by the C-style array.</typeparam>
|
/// <typeparam name="T">Type of native structure used by the C-style array.</typeparam>
|
||||||
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
/// <param name="ptr">The <see cref="IntPtr"/> pointing to the native array.</param>
|
||||||
/// <param name="count">The number of items in the native array.</param>
|
/// <param name="count">The number of items in the native array.</param>
|
||||||
/// <returns>An array of type <typeparamref name="T"/> containing the elements of the native array.</returns>
|
/// <returns>An array of type <typeparamref name="T"/> containing the elements of the native array.</returns>
|
||||||
public static T[] ToArray<T>(IntPtr ptr, int count)
|
public static T[] ToArray<T>(IntPtr ptr, int count)
|
||||||
{
|
{
|
||||||
var ret = new T[count];
|
var ret = new T[count];
|
||||||
var stSize = Marshal.SizeOf(typeof(T));
|
var stSize = Marshal.SizeOf(typeof(T));
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
var tempPtr = new IntPtr(ptr.ToInt64() + (i * stSize));
|
||||||
ret[i] = ToStructure<T>(tempPtr);
|
ret[i] = ToStructure<T>(tempPtr);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ComEnumerator<T, TIn> : IEnumerator<T> where T : class where TIn : class
|
internal class ComEnumerator<T, TIn> : IEnumerator<T> where T : class where TIn : class
|
||||||
{
|
{
|
||||||
protected readonly Func<TIn, T> converter;
|
protected readonly Func<TIn, T> converter;
|
||||||
protected IEnumerator<TIn> iEnum;
|
protected IEnumerator<TIn> iEnum;
|
||||||
|
|
||||||
public ComEnumerator(Func<int> getCount, Func<int, TIn> indexer, Func<TIn, T> converter)
|
public ComEnumerator(Func<int> getCount, Func<int, TIn> indexer, Func<TIn, T> converter)
|
||||||
{
|
{
|
||||||
IEnumerator<TIn> Enumerate()
|
IEnumerator<TIn> Enumerate()
|
||||||
{
|
{
|
||||||
for (var x = 1; x <= getCount(); x++)
|
for (var x = 1; x <= getCount(); x++)
|
||||||
yield return indexer(x);
|
yield return indexer(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
iEnum = Enumerate();
|
iEnum = Enumerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ComEnumerator(Func<int> getCount, Func<object, TIn> indexer, Func<TIn, T> converter)
|
public ComEnumerator(Func<int> getCount, Func<object, TIn> indexer, Func<TIn, T> converter)
|
||||||
{
|
{
|
||||||
IEnumerator<TIn> Enumerate()
|
IEnumerator<TIn> Enumerate()
|
||||||
{
|
{
|
||||||
for (var x = 1; x <= getCount(); x++)
|
for (var x = 1; x <= getCount(); x++)
|
||||||
yield return indexer(x);
|
yield return indexer(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.converter = converter;
|
this.converter = converter;
|
||||||
iEnum = Enumerate();
|
iEnum = Enumerate();
|
||||||
}
|
}
|
||||||
|
|
||||||
object IEnumerator.Current => Current;
|
object IEnumerator.Current => Current;
|
||||||
|
|
||||||
public virtual T Current => converter(iEnum?.Current);
|
public virtual T Current => converter(iEnum?.Current);
|
||||||
|
|
||||||
public virtual void Dispose()
|
public virtual void Dispose()
|
||||||
{
|
{
|
||||||
iEnum?.Dispose();
|
iEnum?.Dispose();
|
||||||
iEnum = null;
|
iEnum = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool MoveNext() => iEnum?.MoveNext() ?? false;
|
public virtual bool MoveNext() => iEnum?.MoveNext() ?? false;
|
||||||
|
|
||||||
public virtual void Reset()
|
public virtual void Reset()
|
||||||
{
|
{
|
||||||
iEnum?.Reset();
|
iEnum?.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,145 +8,145 @@ using winPEAS.Native.Enums;
|
|||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static partial class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the errors returned by the status member of the DS_NAME_RESULT_ITEM structure. These are potential errors that may be encountered while a name is converted by the DsCrackNames function.
|
/// Defines the errors returned by the status member of the DS_NAME_RESULT_ITEM structure. These are potential errors that may be encountered while a name is converted by the DsCrackNames function.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum DS_NAME_ERROR : uint
|
public enum DS_NAME_ERROR : uint
|
||||||
{
|
{
|
||||||
/// <summary>The conversion was successful.</summary>
|
/// <summary>The conversion was successful.</summary>
|
||||||
DS_NAME_NO_ERROR = 0,
|
DS_NAME_NO_ERROR = 0,
|
||||||
|
|
||||||
///<summary>Generic processing error occurred.</summary>
|
///<summary>Generic processing error occurred.</summary>
|
||||||
DS_NAME_ERROR_RESOLVING = 1,
|
DS_NAME_ERROR_RESOLVING = 1,
|
||||||
|
|
||||||
///<summary>The name cannot be found or the caller does not have permission to access the name.</summary>
|
///<summary>The name cannot be found or the caller does not have permission to access the name.</summary>
|
||||||
DS_NAME_ERROR_NOT_FOUND = 2,
|
DS_NAME_ERROR_NOT_FOUND = 2,
|
||||||
|
|
||||||
///<summary>The input name is mapped to more than one output name or the desired format did not have a single, unique value for the object found.</summary>
|
///<summary>The input name is mapped to more than one output name or the desired format did not have a single, unique value for the object found.</summary>
|
||||||
DS_NAME_ERROR_NOT_UNIQUE = 3,
|
DS_NAME_ERROR_NOT_UNIQUE = 3,
|
||||||
|
|
||||||
///<summary>The input name was found, but the associated output format cannot be found. This can occur if the object does not have all the required attributes.</summary>
|
///<summary>The input name was found, but the associated output format cannot be found. This can occur if the object does not have all the required attributes.</summary>
|
||||||
DS_NAME_ERROR_NO_MAPPING = 4,
|
DS_NAME_ERROR_NO_MAPPING = 4,
|
||||||
|
|
||||||
///<summary>Unable to resolve entire name, but was able to determine in which domain object resides. The caller is expected to retry the call at a domain controller for the specified domain. The entire name cannot be resolved, but the domain that the object resides in could be determined. The pDomain member of the DS_NAME_RESULT_ITEM contains valid data when this error is specified.</summary>
|
///<summary>Unable to resolve entire name, but was able to determine in which domain object resides. The caller is expected to retry the call at a domain controller for the specified domain. The entire name cannot be resolved, but the domain that the object resides in could be determined. The pDomain member of the DS_NAME_RESULT_ITEM contains valid data when this error is specified.</summary>
|
||||||
DS_NAME_ERROR_DOMAIN_ONLY = 5,
|
DS_NAME_ERROR_DOMAIN_ONLY = 5,
|
||||||
|
|
||||||
///<summary>A syntactical mapping cannot be performed on the client without transmitting over the network.</summary>
|
///<summary>A syntactical mapping cannot be performed on the client without transmitting over the network.</summary>
|
||||||
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6,
|
DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING = 6,
|
||||||
|
|
||||||
///<summary>The name is from an external trusted forest.</summary>
|
///<summary>The name is from an external trusted forest.</summary>
|
||||||
DS_NAME_ERROR_TRUST_REFERRAL = 7
|
DS_NAME_ERROR_TRUST_REFERRAL = 7
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Class that provides methods against a AD domain service.
|
/// Class that provides methods against a AD domain service.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="System.IDisposable" />
|
/// <seealso cref="System.IDisposable" />
|
||||||
[SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
[SuppressUnmanagedCodeSecurity, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
|
||||||
public class DomainService : IDisposable
|
public class DomainService : IDisposable
|
||||||
{
|
{
|
||||||
IntPtr handle = IntPtr.Zero;
|
IntPtr handle = IntPtr.Zero;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="DomainService"/> class.
|
/// Initializes a new instance of the <see cref="DomainService"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="domainControllerName">Name of the domain controller.</param>
|
/// <param name="domainControllerName">Name of the domain controller.</param>
|
||||||
/// <param name="dnsDomainName">Name of the DNS domain.</param>
|
/// <param name="dnsDomainName">Name of the DNS domain.</param>
|
||||||
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
|
/// <exception cref="System.ComponentModel.Win32Exception"></exception>
|
||||||
public DomainService(string domainControllerName = null, string dnsDomainName = null)
|
public DomainService(string domainControllerName = null, string dnsDomainName = null)
|
||||||
{
|
{
|
||||||
Ntdsapi.DsBind(domainControllerName, dnsDomainName, out handle);
|
Ntdsapi.DsBind(domainControllerName, dnsDomainName, out handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a directory service object name from any format to the UPN.
|
/// Converts a directory service object name from any format to the UPN.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name to convert.</param>
|
/// <param name="name">The name to convert.</param>
|
||||||
/// <returns>The corresponding UPN.</returns>
|
/// <returns>The corresponding UPN.</returns>
|
||||||
/// <exception cref="System.Security.SecurityException">Unable to resolve user name.</exception>
|
/// <exception cref="System.Security.SecurityException">Unable to resolve user name.</exception>
|
||||||
public string CrackName(string name)
|
public string CrackName(string name)
|
||||||
{
|
{
|
||||||
var res = CrackNames(new string[] { name });
|
var res = CrackNames(new string[] { name });
|
||||||
if (res == null || res.Length == 0 || res[0].status != NativeMethods.DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
if (res == null || res.Length == 0 || res[0].status != DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||||
throw new SecurityException("Unable to resolve user name.");
|
throw new SecurityException("Unable to resolve user name.");
|
||||||
return res[0].pName;
|
return res[0].pName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects.
|
/// Converts an array of directory service object names from one format to another. Name conversion enables client applications to map between the multiple names used to identify various directory service objects.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="names">The names to convert.</param>
|
/// <param name="names">The names to convert.</param>
|
||||||
/// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
|
/// <param name="flags">Values used to determine how the name syntax will be cracked.</param>
|
||||||
/// <param name="formatOffered">Format of the input names.</param>
|
/// <param name="formatOffered">Format of the input names.</param>
|
||||||
/// <param name="formatDesired">Desired format for the output names.</param>
|
/// <param name="formatDesired">Desired format for the output names.</param>
|
||||||
/// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
|
/// <returns>An array of DS_NAME_RESULT_ITEM structures. Each element of this array represents a single converted name.</returns>
|
||||||
public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS, DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_UNKNOWN_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
|
public DS_NAME_RESULT_ITEM[] CrackNames(string[] names = null, DS_NAME_FLAGS flags = DS_NAME_FLAGS.DS_NAME_NO_FLAGS, DS_NAME_FORMAT formatOffered = DS_NAME_FORMAT.DS_UNKNOWN_NAME, DS_NAME_FORMAT formatDesired = DS_NAME_FORMAT.DS_USER_PRINCIPAL_NAME)
|
||||||
{
|
{
|
||||||
IntPtr pResult;
|
IntPtr pResult;
|
||||||
uint err = Ntdsapi.DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
|
uint err = Ntdsapi.DsCrackNames(handle, flags, formatOffered, formatDesired, (uint)(names?.Length ?? 0), names, out pResult);
|
||||||
if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
if (err != (uint)DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||||
throw new System.ComponentModel.Win32Exception((int)err);
|
throw new System.ComponentModel.Win32Exception((int)err);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Next convert the returned structure to managed environment
|
// Next convert the returned structure to managed environment
|
||||||
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
|
DS_NAME_RESULT Result = (DS_NAME_RESULT)Marshal.PtrToStructure(pResult, typeof(DS_NAME_RESULT));
|
||||||
return Result.Items;
|
return Result.Items;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Ntdsapi.DsFreeNameResult(pResult);
|
Ntdsapi.DsFreeNameResult(pResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
uint ret = Ntdsapi.DsUnBind(ref handle);
|
uint ret = Ntdsapi.DsUnBind(ref handle);
|
||||||
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
|
System.Diagnostics.Debug.WriteLineIf(ret != 0, "Error unbinding :\t" + ret.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
public struct DS_NAME_RESULT
|
public struct DS_NAME_RESULT
|
||||||
{
|
{
|
||||||
public uint cItems;
|
public uint cItems;
|
||||||
internal IntPtr rItems; // PDS_NAME_RESULT_ITEM
|
internal IntPtr rItems; // PDS_NAME_RESULT_ITEM
|
||||||
|
|
||||||
public DS_NAME_RESULT_ITEM[] Items
|
public DS_NAME_RESULT_ITEM[] Items
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (rItems == IntPtr.Zero)
|
if (rItems == IntPtr.Zero)
|
||||||
return new DS_NAME_RESULT_ITEM[0];
|
return new DS_NAME_RESULT_ITEM[0];
|
||||||
var ResultArray = new DS_NAME_RESULT_ITEM[cItems];
|
var ResultArray = new DS_NAME_RESULT_ITEM[cItems];
|
||||||
Type strType = typeof(DS_NAME_RESULT_ITEM);
|
Type strType = typeof(DS_NAME_RESULT_ITEM);
|
||||||
int stSize = Marshal.SizeOf(strType);
|
int stSize = Marshal.SizeOf(strType);
|
||||||
IntPtr curptr;
|
IntPtr curptr;
|
||||||
for (uint i = 0; i < cItems; i++)
|
for (uint i = 0; i < cItems; i++)
|
||||||
{
|
{
|
||||||
curptr = new IntPtr(rItems.ToInt64() + (i * stSize));
|
curptr = new IntPtr(rItems.ToInt64() + (i * stSize));
|
||||||
ResultArray[i] = (DS_NAME_RESULT_ITEM)Marshal.PtrToStructure(curptr, strType);
|
ResultArray[i] = (DS_NAME_RESULT_ITEM)Marshal.PtrToStructure(curptr, strType);
|
||||||
}
|
}
|
||||||
return ResultArray;
|
return ResultArray;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
||||||
public struct DS_NAME_RESULT_ITEM
|
public struct DS_NAME_RESULT_ITEM
|
||||||
{
|
{
|
||||||
public DS_NAME_ERROR status;
|
public DS_NAME_ERROR status;
|
||||||
public string pDomain;
|
public string pDomain;
|
||||||
public string pName;
|
public string pName;
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (status == DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
if (status == DS_NAME_ERROR.DS_NAME_NO_ERROR)
|
||||||
return pName;
|
return pName;
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,131 +7,131 @@ using winPEAS.Native.Enums;
|
|||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static partial class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
const int MAX_PREFERRED_LENGTH = -1;
|
const int MAX_PREFERRED_LENGTH = -1;
|
||||||
|
|
||||||
public enum ServerPlatform
|
public enum ServerPlatform
|
||||||
{
|
{
|
||||||
DOS = 300,
|
DOS = 300,
|
||||||
OS2 = 400,
|
OS2 = 400,
|
||||||
NT = 500,
|
NT = 500,
|
||||||
OSF = 600,
|
OSF = 600,
|
||||||
VMS = 700
|
VMS = 700
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SERVER_INFO_100
|
public struct SERVER_INFO_100
|
||||||
{
|
{
|
||||||
public ServerPlatform PlatformId;
|
public ServerPlatform PlatformId;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Name;
|
public string Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SERVER_INFO_101
|
public struct SERVER_INFO_101
|
||||||
{
|
{
|
||||||
public ServerPlatform PlatformId;
|
public ServerPlatform PlatformId;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Name;
|
public string Name;
|
||||||
public int VersionMajor;
|
public int VersionMajor;
|
||||||
public int VersionMinor;
|
public int VersionMinor;
|
||||||
public ServerTypes Type;
|
public ServerTypes Type;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Comment;
|
public string Comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct SERVER_INFO_102
|
public struct SERVER_INFO_102
|
||||||
{
|
{
|
||||||
public ServerPlatform PlatformId;
|
public ServerPlatform PlatformId;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Name;
|
public string Name;
|
||||||
public int VersionMajor;
|
public int VersionMajor;
|
||||||
public int VersionMinor;
|
public int VersionMinor;
|
||||||
public ServerTypes Type;
|
public ServerTypes Type;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string Comment;
|
public string Comment;
|
||||||
public int MaxUsers;
|
public int MaxUsers;
|
||||||
public int AutoDisconnectMinutes;
|
public int AutoDisconnectMinutes;
|
||||||
[MarshalAs(UnmanagedType.Bool)]
|
[MarshalAs(UnmanagedType.Bool)]
|
||||||
public bool Hidden;
|
public bool Hidden;
|
||||||
public int NetworkAnnounceRate;
|
public int NetworkAnnounceRate;
|
||||||
public int NetworkAnnounceRateDelta;
|
public int NetworkAnnounceRateDelta;
|
||||||
public int UsersPerLicense;
|
public int UsersPerLicense;
|
||||||
[MarshalAs(UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
public string UserDirectoryPath;
|
public string UserDirectoryPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct NetworkComputerInfo // SERVER_INFO_101
|
public struct NetworkComputerInfo // SERVER_INFO_101
|
||||||
{
|
{
|
||||||
ServerPlatform sv101_platform_id;
|
ServerPlatform sv101_platform_id;
|
||||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
string sv101_name;
|
string sv101_name;
|
||||||
int sv101_version_major;
|
int sv101_version_major;
|
||||||
int sv101_version_minor;
|
int sv101_version_minor;
|
||||||
ServerTypes sv101_type;
|
ServerTypes sv101_type;
|
||||||
[MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
string sv101_comment;
|
string sv101_comment;
|
||||||
|
|
||||||
public ServerPlatform Platform => sv101_platform_id;
|
public ServerPlatform Platform => sv101_platform_id;
|
||||||
public string Name => sv101_name;
|
public string Name => sv101_name;
|
||||||
public string Comment => sv101_comment;
|
public string Comment => sv101_comment;
|
||||||
public ServerTypes ServerTypes => sv101_type;
|
public ServerTypes ServerTypes => sv101_type;
|
||||||
public Version Version => new Version(sv101_version_major, sv101_version_minor);
|
public Version Version => new Version(sv101_version_major, sv101_version_minor);
|
||||||
};
|
};
|
||||||
|
|
||||||
public static IEnumerable<string> GetNetworkComputerNames(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
public static IEnumerable<string> GetNetworkComputerNames(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
||||||
Array.ConvertAll(NetServerEnum<SERVER_INFO_100>(serverTypes, domain), si => si.Name);
|
Array.ConvertAll(NetServerEnum<SERVER_INFO_100>(serverTypes, domain), si => si.Name);
|
||||||
|
|
||||||
public static IEnumerable<NetworkComputerInfo> GetNetworkComputerInfo(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
public static IEnumerable<NetworkComputerInfo> GetNetworkComputerInfo(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null) =>
|
||||||
NetServerEnum<NetworkComputerInfo>(serverTypes, domain, 101);
|
NetServerEnum<NetworkComputerInfo>(serverTypes, domain, 101);
|
||||||
|
|
||||||
public static T[] NetServerEnum<T>(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null, int level = 0) where T : struct
|
public static T[] NetServerEnum<T>(ServerTypes serverTypes = ServerTypes.Workstation | ServerTypes.Server, string domain = null, int level = 0) where T : struct
|
||||||
{
|
{
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
||||||
|
|
||||||
IntPtr bufptr = IntPtr.Zero;
|
IntPtr bufptr = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int entriesRead, totalEntries;
|
int entriesRead, totalEntries;
|
||||||
IntPtr resumeHandle = IntPtr.Zero;
|
IntPtr resumeHandle = IntPtr.Zero;
|
||||||
|
|
||||||
int ret = Netapi32.NetServerEnum(null, level, out bufptr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, serverTypes, domain, resumeHandle);
|
int ret = Netapi32.NetServerEnum(null, level, out bufptr, MAX_PREFERRED_LENGTH, out entriesRead, out totalEntries, serverTypes, domain, resumeHandle);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return InteropUtil.ToArray<T>(bufptr, entriesRead);
|
return InteropUtil.ToArray<T>(bufptr, entriesRead);
|
||||||
throw new System.ComponentModel.Win32Exception(ret);
|
throw new System.ComponentModel.Win32Exception(ret);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Netapi32.NetApiBufferFree(bufptr);
|
Netapi32.NetApiBufferFree(bufptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T NetServerGetInfo<T>(string serverName, int level = 0) where T : struct
|
public static T NetServerGetInfo<T>(string serverName, int level = 0) where T : struct
|
||||||
{
|
{
|
||||||
if (level == 0)
|
if (level == 0)
|
||||||
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
level = int.Parse(System.Text.RegularExpressions.Regex.Replace(typeof(T).Name, @"[^\d]", ""));
|
||||||
|
|
||||||
IntPtr ptr = IntPtr.Zero;
|
IntPtr ptr = IntPtr.Zero;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
int ret = Netapi32.NetServerGetInfo(serverName, level, out ptr);
|
int ret = Netapi32.NetServerGetInfo(serverName, level, out ptr);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
{
|
{
|
||||||
throw new System.ComponentModel.Win32Exception(ret);
|
throw new System.ComponentModel.Win32Exception(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (T)Marshal.PtrToStructure(ptr, typeof(T));
|
return (T)Marshal.PtrToStructure(ptr, typeof(T));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (ptr != IntPtr.Zero)
|
if (ptr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
Netapi32.NetApiBufferFree(ptr);
|
Netapi32.NetApiBufferFree(ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,114 +3,114 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
namespace winPEAS.TaskScheduler.TaskEditor.Native
|
||||||
{
|
{
|
||||||
internal static partial class NativeMethods
|
internal static partial class NativeMethods
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||||
internal struct SYSTEMTIME : IConvertible
|
internal struct SYSTEMTIME : IConvertible
|
||||||
{
|
{
|
||||||
public ushort Year;
|
public ushort Year;
|
||||||
public ushort Month;
|
public ushort Month;
|
||||||
public ushort DayOfWeek;
|
public ushort DayOfWeek;
|
||||||
public ushort Day;
|
public ushort Day;
|
||||||
public ushort Hour;
|
public ushort Hour;
|
||||||
public ushort Minute;
|
public ushort Minute;
|
||||||
public ushort Second;
|
public ushort Second;
|
||||||
public ushort Milliseconds;
|
public ushort Milliseconds;
|
||||||
|
|
||||||
public SYSTEMTIME(DateTime dt)
|
public SYSTEMTIME(DateTime dt)
|
||||||
{
|
{
|
||||||
dt = dt.ToLocalTime();
|
dt = dt.ToLocalTime();
|
||||||
Year = Convert.ToUInt16(dt.Year);
|
Year = Convert.ToUInt16(dt.Year);
|
||||||
Month = Convert.ToUInt16(dt.Month);
|
Month = Convert.ToUInt16(dt.Month);
|
||||||
DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
|
DayOfWeek = Convert.ToUInt16(dt.DayOfWeek);
|
||||||
Day = Convert.ToUInt16(dt.Day);
|
Day = Convert.ToUInt16(dt.Day);
|
||||||
Hour = Convert.ToUInt16(dt.Hour);
|
Hour = Convert.ToUInt16(dt.Hour);
|
||||||
Minute = Convert.ToUInt16(dt.Minute);
|
Minute = Convert.ToUInt16(dt.Minute);
|
||||||
Second = Convert.ToUInt16(dt.Second);
|
Second = Convert.ToUInt16(dt.Second);
|
||||||
Milliseconds = Convert.ToUInt16(dt.Millisecond);
|
Milliseconds = Convert.ToUInt16(dt.Millisecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
|
public SYSTEMTIME(ushort year, ushort month, ushort day, ushort hour = 0, ushort minute = 0, ushort second = 0, ushort millisecond = 0)
|
||||||
{
|
{
|
||||||
Year = year;
|
Year = year;
|
||||||
Month = month;
|
Month = month;
|
||||||
Day = day;
|
Day = day;
|
||||||
Hour = hour;
|
Hour = hour;
|
||||||
Minute = minute;
|
Minute = minute;
|
||||||
Second = second;
|
Second = second;
|
||||||
Milliseconds = millisecond;
|
Milliseconds = millisecond;
|
||||||
DayOfWeek = 0;
|
DayOfWeek = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator DateTime(SYSTEMTIME st)
|
public static implicit operator DateTime(SYSTEMTIME st)
|
||||||
{
|
{
|
||||||
if (st.Year == 0 || st == MinValue)
|
if (st.Year == 0 || st == MinValue)
|
||||||
return DateTime.MinValue;
|
return DateTime.MinValue;
|
||||||
if (st == MaxValue)
|
if (st == MaxValue)
|
||||||
return DateTime.MaxValue;
|
return DateTime.MaxValue;
|
||||||
return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Local);
|
return new DateTime(st.Year, st.Month, st.Day, st.Hour, st.Minute, st.Second, st.Milliseconds, DateTimeKind.Local);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator SYSTEMTIME(DateTime dt) => new SYSTEMTIME(dt);
|
public static implicit operator SYSTEMTIME(DateTime dt) => new SYSTEMTIME(dt);
|
||||||
|
|
||||||
public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2) => (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
|
public static bool operator ==(SYSTEMTIME s1, SYSTEMTIME s2) => (s1.Year == s2.Year && s1.Month == s2.Month && s1.Day == s2.Day && s1.Hour == s2.Hour && s1.Minute == s2.Minute && s1.Second == s2.Second && s1.Milliseconds == s2.Milliseconds);
|
||||||
|
|
||||||
public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2) => !(s1 == s2);
|
public static bool operator !=(SYSTEMTIME s1, SYSTEMTIME s2) => !(s1 == s2);
|
||||||
|
|
||||||
public static readonly SYSTEMTIME MinValue, MaxValue;
|
public static readonly SYSTEMTIME MinValue, MaxValue;
|
||||||
|
|
||||||
static SYSTEMTIME()
|
static SYSTEMTIME()
|
||||||
{
|
{
|
||||||
MinValue = new SYSTEMTIME(1601, 1, 1);
|
MinValue = new SYSTEMTIME(1601, 1, 1);
|
||||||
MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
|
MaxValue = new SYSTEMTIME(30827, 12, 31, 23, 59, 59, 999);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
if (obj is SYSTEMTIME)
|
if (obj is SYSTEMTIME)
|
||||||
return ((SYSTEMTIME)obj) == this;
|
return ((SYSTEMTIME)obj) == this;
|
||||||
if (obj is DateTime)
|
if (obj is DateTime)
|
||||||
return ((DateTime)this).Equals(obj);
|
return ((DateTime)this).Equals(obj);
|
||||||
return base.Equals(obj);
|
return base.Equals(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => ((DateTime)this).GetHashCode();
|
public override int GetHashCode() => ((DateTime)this).GetHashCode();
|
||||||
|
|
||||||
public override string ToString() => ((DateTime)this).ToString();
|
public override string ToString() => ((DateTime)this).ToString();
|
||||||
|
|
||||||
TypeCode IConvertible.GetTypeCode() => ((IConvertible)(DateTime)this).GetTypeCode();
|
TypeCode IConvertible.GetTypeCode() => ((IConvertible)(DateTime)this).GetTypeCode();
|
||||||
|
|
||||||
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToBoolean(provider);
|
bool IConvertible.ToBoolean(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToBoolean(provider);
|
||||||
|
|
||||||
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToByte(provider);
|
byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToByte(provider);
|
||||||
|
|
||||||
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToChar(provider);
|
char IConvertible.ToChar(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToChar(provider);
|
||||||
|
|
||||||
DateTime IConvertible.ToDateTime(IFormatProvider provider) => (DateTime)this;
|
DateTime IConvertible.ToDateTime(IFormatProvider provider) => (DateTime)this;
|
||||||
|
|
||||||
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDecimal(provider);
|
decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDecimal(provider);
|
||||||
|
|
||||||
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDouble(provider);
|
double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToDouble(provider);
|
||||||
|
|
||||||
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt16(provider);
|
short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt16(provider);
|
||||||
|
|
||||||
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt32(provider);
|
int IConvertible.ToInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt32(provider);
|
||||||
|
|
||||||
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt64(provider);
|
long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToInt64(provider);
|
||||||
|
|
||||||
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSByte(provider);
|
sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSByte(provider);
|
||||||
|
|
||||||
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSingle(provider);
|
float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToSingle(provider);
|
||||||
|
|
||||||
string IConvertible.ToString(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToString(provider);
|
string IConvertible.ToString(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToString(provider);
|
||||||
|
|
||||||
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)(DateTime)this).ToType(conversionType, provider);
|
object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)(DateTime)this).ToType(conversionType, provider);
|
||||||
|
|
||||||
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt16(provider);
|
ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt16(provider);
|
||||||
|
|
||||||
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt32(provider);
|
uint IConvertible.ToUInt32(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt32(provider);
|
||||||
|
|
||||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt64(provider);
|
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)(DateTime)this).ToUInt64(provider);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -2,173 +2,170 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||||
using winPEAS.TaskScheduler.V2;
|
using winPEAS.TaskScheduler.V2;
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Provides information and control for a collection of folders that contain tasks.</summary>
|
/// <summary>Provides information and control for a collection of folders that contain tasks.</summary>
|
||||||
public sealed class TaskFolderCollection : ICollection<TaskFolder>, IDisposable, INotifyCollectionChanged, INotifyPropertyChanged
|
public sealed class TaskFolderCollection : ICollection<TaskFolder>, IDisposable, INotifyCollectionChanged, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private const string IndexerName = "Item[]";
|
private const string IndexerName = "Item[]";
|
||||||
private readonly TaskFolder parent;
|
private readonly TaskFolder parent;
|
||||||
private readonly TaskFolder[] v1FolderList;
|
private readonly TaskFolder[] v1FolderList;
|
||||||
private readonly ITaskFolderCollection v2FolderList;
|
private readonly ITaskFolderCollection v2FolderList;
|
||||||
|
|
||||||
internal TaskFolderCollection() => v1FolderList = new TaskFolder[0];
|
internal TaskFolderCollection() => v1FolderList = new TaskFolder[0];
|
||||||
|
|
||||||
internal TaskFolderCollection([NotNull] TaskFolder folder, [NotNull] ITaskFolderCollection iCollection)
|
internal TaskFolderCollection([NotNull] TaskFolder folder, [NotNull] ITaskFolderCollection iCollection)
|
||||||
{
|
{
|
||||||
parent = folder;
|
parent = folder;
|
||||||
v2FolderList = iCollection;
|
v2FolderList = iCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Occurs when a collection changes.</summary>
|
/// <summary>Occurs when a collection changes.</summary>
|
||||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||||
|
|
||||||
/// <summary>Occurs when a property value changes.</summary>
|
/// <summary>Occurs when a property value changes.</summary>
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
/// <summary>Gets the number of items in the collection.</summary>
|
/// <summary>Gets the number of items in the collection.</summary>
|
||||||
public int Count => v2FolderList?.Count ?? v1FolderList.Length;
|
public int Count => v2FolderList?.Count ?? v1FolderList.Length;
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether the <see cref="ICollection{T}"/> is read-only.</summary>
|
/// <summary>Gets a value indicating whether the <see cref="ICollection{T}"/> is read-only.</summary>
|
||||||
bool ICollection<TaskFolder>.IsReadOnly => false;
|
bool ICollection<TaskFolder>.IsReadOnly => false;
|
||||||
|
|
||||||
/// <summary>Gets the specified folder from the collection.</summary>
|
/// <summary>Gets the specified folder from the collection.</summary>
|
||||||
/// <param name="index">The index of the folder to be retrieved.</param>
|
/// <param name="index">The index of the folder to be retrieved.</param>
|
||||||
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
||||||
public TaskFolder this[int index]
|
public TaskFolder this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
return new TaskFolder(parent.TaskService, v2FolderList[++index]);
|
return new TaskFolder(parent.TaskService, v2FolderList[++index]);
|
||||||
return v1FolderList[index];
|
return v1FolderList[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets the specified folder from the collection.</summary>
|
/// <summary>Gets the specified folder from the collection.</summary>
|
||||||
/// <param name="path">The path of the folder to be retrieved.</param>
|
/// <param name="path">The path of the folder to be retrieved.</param>
|
||||||
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
/// <returns>A TaskFolder instance that represents the requested folder.</returns>
|
||||||
public TaskFolder this[[NotNull] string path]
|
public TaskFolder this[[NotNull] string path]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
return parent.GetFolder(path);
|
return parent.GetFolder(path);
|
||||||
if (v1FolderList != null && v1FolderList.Length > 0 && (path == string.Empty || path == "\\"))
|
if (v1FolderList != null && v1FolderList.Length > 0 && (path == string.Empty || path == "\\"))
|
||||||
return v1FolderList[0];
|
return v1FolderList[0];
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
throw new ArgumentException(@"Path not found", nameof(path));
|
throw new ArgumentException(@"Path not found", nameof(path));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Adds an item to the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Adds an item to the <see cref="ICollection{T}"/>.</summary>
|
||||||
/// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to add to the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <exception cref="System.NotImplementedException">
|
/// <exception cref="System.NotImplementedException">
|
||||||
/// This action is technically unfeasible due to limitations of the underlying library. Use the <see
|
/// This action is technically unfeasible due to limitations of the underlying library. Use the <see
|
||||||
/// cref="TaskFolder.CreateFolder(string, string, bool)"/> instead.
|
/// cref="TaskFolder.CreateFolder(string, string, bool)"/> instead.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void Add([NotNull] TaskFolder item) => throw new NotImplementedException();
|
public void Add([NotNull] TaskFolder item) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <summary>Removes all items from the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Removes all items from the <see cref="ICollection{T}"/>.</summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
for (var i = v2FolderList.Count; i > 0; i--)
|
for (var i = v2FolderList.Count; i > 0; i--)
|
||||||
parent.DeleteFolder(v2FolderList[i].Name, false);
|
parent.DeleteFolder(v2FolderList[i].Name, false);
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the <see cref="ICollection{T}"/> contains a specific value.</summary>
|
/// <summary>Determines whether the <see cref="ICollection{T}"/> contains a specific value.</summary>
|
||||||
/// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <returns>true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.</returns>
|
/// <returns>true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.</returns>
|
||||||
public bool Contains([NotNull] TaskFolder item)
|
public bool Contains([NotNull] TaskFolder item)
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
for (var i = v2FolderList.Count; i > 0; i--)
|
for (var i = v2FolderList.Count; i > 0; i--)
|
||||||
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return item.Path == "\\";
|
return item.Path == "\\";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Copies the elements of the ICollection to an Array, starting at a particular Array index.</summary>
|
/// <summary>Copies the elements of the ICollection to an Array, starting at a particular Array index.</summary>
|
||||||
/// <param name="array">
|
/// <param name="array">
|
||||||
/// The one-dimensional Array that is the destination of the elements copied from <see cref="ICollection{T}"/>. The Array must have
|
/// The one-dimensional Array that is the destination of the elements copied from <see cref="ICollection{T}"/>. The Array must have
|
||||||
/// zero-based indexing.
|
/// zero-based indexing.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
|
/// <param name="arrayIndex">The zero-based index in array at which copying begins.</param>
|
||||||
public void CopyTo(TaskFolder[] array, int arrayIndex)
|
public void CopyTo(TaskFolder[] array, int arrayIndex)
|
||||||
{
|
{
|
||||||
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
if (arrayIndex < 0) throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||||
if (array == null) throw new ArgumentNullException(nameof(array));
|
if (array == null) throw new ArgumentNullException(nameof(array));
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
if (arrayIndex + Count > array.Length)
|
if (arrayIndex + Count > array.Length)
|
||||||
throw new ArgumentException();
|
throw new ArgumentException();
|
||||||
foreach (var f in this)
|
foreach (var f in this)
|
||||||
array[arrayIndex++] = f;
|
array[arrayIndex++] = f;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (arrayIndex + v1FolderList.Length > array.Length)
|
if (arrayIndex + v1FolderList.Length > array.Length)
|
||||||
throw new ArgumentException();
|
throw new ArgumentException();
|
||||||
v1FolderList.CopyTo(array, arrayIndex);
|
v1FolderList.CopyTo(array, arrayIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (v1FolderList != null && v1FolderList.Length > 0)
|
if (v1FolderList != null && v1FolderList.Length > 0)
|
||||||
{
|
{
|
||||||
v1FolderList[0].Dispose();
|
v1FolderList[0].Dispose();
|
||||||
v1FolderList[0] = null;
|
v1FolderList[0] = null;
|
||||||
}
|
}
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
System.Runtime.InteropServices.Marshal.ReleaseComObject(v2FolderList);
|
System.Runtime.InteropServices.Marshal.ReleaseComObject(v2FolderList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the specified folder exists.</summary>
|
/// <summary>Determines whether the specified folder exists.</summary>
|
||||||
/// <param name="path">The path of the folder.</param>
|
/// <param name="path">The path of the folder.</param>
|
||||||
/// <returns>true if folder exists; otherwise, false.</returns>
|
/// <returns>true if folder exists; otherwise, false.</returns>
|
||||||
public bool Exists([NotNull] string path)
|
public bool Exists([NotNull] string path)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parent.GetFolder(path);
|
parent.GetFolder(path);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets a list of items in a collection.</summary>
|
/// <summary>Gets a list of items in a collection.</summary>
|
||||||
/// <returns>Enumerated list of items in the collection.</returns>
|
/// <returns>Enumerated list of items in the collection.</returns>
|
||||||
public IEnumerator<TaskFolder> GetEnumerator()
|
public IEnumerator<TaskFolder> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
return new ComEnumerator<TaskFolder, ITaskFolder>(() => v2FolderList.Count, (object o) => v2FolderList[o], o => new TaskFolder(parent.TaskService, o));
|
return new ComEnumerator<TaskFolder, ITaskFolder>(() => v2FolderList.Count, (object o) => v2FolderList[o], o => new TaskFolder(parent.TaskService, o));
|
||||||
return Array.AsReadOnly(v1FolderList).GetEnumerator();
|
return Array.AsReadOnly(v1FolderList).GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/// <summary>Returns the index of the TaskFolder within the collection.</summary>
|
/// <summary>Returns the index of the TaskFolder within the collection.</summary>
|
||||||
/// <param name="item">TaskFolder to find.</param>
|
/// <param name="item">TaskFolder to find.</param>
|
||||||
/// <returns>Index of the TaskFolder; -1 if not found.</returns>
|
/// <returns>Index of the TaskFolder; -1 if not found.</returns>
|
||||||
@@ -196,42 +193,42 @@ namespace winPEAS.TaskScheduler
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// <summary>Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.</summary>
|
||||||
/// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method
|
/// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method
|
||||||
/// also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.
|
/// also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool Remove([NotNull] TaskFolder item)
|
public bool Remove([NotNull] TaskFolder item)
|
||||||
{
|
{
|
||||||
if (v2FolderList != null)
|
if (v2FolderList != null)
|
||||||
{
|
{
|
||||||
for (var i = v2FolderList.Count; i > 0; i--)
|
for (var i = v2FolderList.Count; i > 0; i--)
|
||||||
{
|
{
|
||||||
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
if (string.Equals(item.Path, v2FolderList[i].Path, StringComparison.CurrentCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
parent.DeleteFolder(v2FolderList[i].Name);
|
parent.DeleteFolder(v2FolderList[i].Name);
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, i));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, i));
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
/// <summary>Called when a property has changed to notify any attached elements.</summary>
|
/// <summary>Called when a property has changed to notify any attached elements.</summary>
|
||||||
/// <param name="propertyName">Name of the property.</param>
|
/// <param name="propertyName">Name of the property.</param>
|
||||||
private void OnNotifyPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
private void OnNotifyPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,58 +1,54 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the methods that are called by the Task Scheduler service to manage a COM handler.
|
/// Defines the methods that are called by the Task Scheduler service to manage a COM handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This interface must be implemented for a task to perform a COM handler action. When the Task Scheduler performs a COM handler action, it creates and activates the handler and calls the methods of this interface as needed. For information on specifying a COM handler action, see the <see cref="ComHandlerAction"/> class.
|
/// This interface must be implemented for a task to perform a COM handler action. When the Task Scheduler performs a COM handler action, it creates and activates the handler and calls the methods of this interface as needed. For information on specifying a COM handler action, see the <see cref="ComHandlerAction"/> class.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ComImport, Guid("839D7762-5121-4009-9234-4F0D19394F04"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
[ComImport, Guid("839D7762-5121-4009-9234-4F0D19394F04"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
public interface ITaskHandler
|
public interface ITaskHandler
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to start the COM handler. This method must be implemented by the handler.
|
/// Called to start the COM handler. This method must be implemented by the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pHandlerServices">An <c>IUnkown</c> interface that is used to communicate back with the Task Scheduler.</param>
|
/// <param name="pHandlerServices">An <c>IUnkown</c> interface that is used to communicate back with the Task Scheduler.</param>
|
||||||
/// <param name="data">The arguments that are required by the handler. These arguments are defined in the <see cref="ComHandlerAction.Data"/> property of the COM handler action.</param>
|
/// <param name="data">The arguments that are required by the handler. These arguments are defined in the <see cref="ComHandlerAction.Data"/> property of the COM handler action.</param>
|
||||||
void Start([In, MarshalAs(UnmanagedType.IUnknown)] object pHandlerServices, [In, MarshalAs(UnmanagedType.BStr)] string data);
|
void Start([In, MarshalAs(UnmanagedType.IUnknown)] object pHandlerServices, [In, MarshalAs(UnmanagedType.BStr)] string data);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to stop the COM handler. This method must be implemented by the handler.
|
/// Called to stop the COM handler. This method must be implemented by the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="pRetCode">The return code that the Task Schedule will raise as an event when the COM handler action is completed.</param>
|
/// <param name="pRetCode">The return code that the Task Schedule will raise as an event when the COM handler action is completed.</param>
|
||||||
void Stop([MarshalAs(UnmanagedType.Error)] out int pRetCode);
|
void Stop([MarshalAs(UnmanagedType.Error)] out int pRetCode);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to pause the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to pause and restart the handler.
|
/// Called to pause the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to pause and restart the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Pause();
|
void Pause();
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called to resume the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to resume the handler.
|
/// Called to resume the COM handler. This method is optional and should only be implemented to give the Task Scheduler the ability to resume the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Resume();
|
void Resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides the methods that are used by COM handlers to notify the Task Scheduler about the status of the handler.
|
/// Provides the methods that are used by COM handlers to notify the Task Scheduler about the status of the handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ComImport, Guid("EAEC7A8F-27A0-4DDC-8675-14726A01A38A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
[ComImport, Guid("EAEC7A8F-27A0-4DDC-8675-14726A01A38A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), System.Security.SuppressUnmanagedCodeSecurity]
|
||||||
public interface ITaskHandlerStatus
|
public interface ITaskHandlerStatus
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tells the Task Scheduler about the percentage of completion of the COM handler.
|
/// Tells the Task Scheduler about the percentage of completion of the COM handler.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="percentComplete">A value that indicates the percentage of completion for the COM handler.</param>
|
/// <param name="percentComplete">A value that indicates the percentage of completion for the COM handler.</param>
|
||||||
/// <param name="statusMessage">The message that is displayed in the Task Scheduler UI.</param>
|
/// <param name="statusMessage">The message that is displayed in the Task Scheduler UI.</param>
|
||||||
void UpdateStatus([In] short percentComplete, [In, MarshalAs(UnmanagedType.BStr)] string statusMessage);
|
void UpdateStatus([In] short percentComplete, [In, MarshalAs(UnmanagedType.BStr)] string statusMessage);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tells the Task Scheduler that the COM handler is completed.
|
/// Tells the Task Scheduler that the COM handler is completed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="taskErrCode">The error code that the Task Scheduler will raise as an event.</param>
|
/// <param name="taskErrCode">The error code that the Task Scheduler will raise as an event.</param>
|
||||||
void TaskCompleted([In, MarshalAs(UnmanagedType.Error)] int taskErrCode);
|
void TaskCompleted([In, MarshalAs(UnmanagedType.Error)] int taskErrCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,456 +9,456 @@ namespace winPEAS.TaskScheduler
|
|||||||
/// Specifies the access control rights that can be applied to Task Scheduler tasks.
|
/// Specifies the access control rights that can be applied to Task Scheduler tasks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum TaskRights
|
public enum TaskRights
|
||||||
{
|
{
|
||||||
/// <summary>Specifies the right to exert full control over a task folder or task, and to modify access control and audit rules. This value represents the right to do anything with a task and is the combination of all rights in this enumeration.</summary>
|
/// <summary>Specifies the right to exert full control over a task folder or task, and to modify access control and audit rules. This value represents the right to do anything with a task and is the combination of all rights in this enumeration.</summary>
|
||||||
FullControl = 0x1f01ff,
|
FullControl = 0x1f01ff,
|
||||||
/// <summary>Specifies the right to create tasks and folders, and to add or remove data from tasks. This right includes the following rights: .</summary>
|
/// <summary>Specifies the right to create tasks and folders, and to add or remove data from tasks. This right includes the following rights: .</summary>
|
||||||
Write = 0x120116,
|
Write = 0x120116,
|
||||||
/// <summary>Specifies the right to open and copy folders or tasks as read-only. This right includes the following rights: .</summary>
|
/// <summary>Specifies the right to open and copy folders or tasks as read-only. This right includes the following rights: .</summary>
|
||||||
Read = 0x120089,
|
Read = 0x120089,
|
||||||
/// <summary>Specifies the right run tasks. This right includes the following rights: .</summary>
|
/// <summary>Specifies the right run tasks. This right includes the following rights: .</summary>
|
||||||
Execute = 0x120089,
|
Execute = 0x120089,
|
||||||
/// <summary>The right to wait on a task.</summary>
|
/// <summary>The right to wait on a task.</summary>
|
||||||
Synchronize = 0x100000,
|
Synchronize = 0x100000,
|
||||||
/// <summary>The right to change the owner of a task.</summary>
|
/// <summary>The right to change the owner of a task.</summary>
|
||||||
TakeOwnership = 0x80000,
|
TakeOwnership = 0x80000,
|
||||||
/// <summary>Specifies the right to change the security and audit rules associated with a task or folder.</summary>
|
/// <summary>Specifies the right to change the security and audit rules associated with a task or folder.</summary>
|
||||||
ChangePermissions = 0x40000,
|
ChangePermissions = 0x40000,
|
||||||
/// <summary>The right to open and copy the access rules and audit rules for a task.</summary>
|
/// <summary>The right to open and copy the access rules and audit rules for a task.</summary>
|
||||||
ReadPermissions = 0x20000,
|
ReadPermissions = 0x20000,
|
||||||
/// <summary>The right to delete a folder or task.</summary>
|
/// <summary>The right to delete a folder or task.</summary>
|
||||||
Delete = 0x10000,
|
Delete = 0x10000,
|
||||||
/// <summary>Specifies the right to open and write file system attributes to a folder or file. This does not include the ability to write data, extended attributes, or access and audit rules.</summary>
|
/// <summary>Specifies the right to open and write file system attributes to a folder or file. This does not include the ability to write data, extended attributes, or access and audit rules.</summary>
|
||||||
WriteAttributes = 0x100,
|
WriteAttributes = 0x100,
|
||||||
/// <summary>Specifies the right to open and copy file system attributes from a folder or task. For example, this value specifies the right to view the file creation or modified date. This does not include the right to read data, extended file system attributes, or access and audit rules.</summary>
|
/// <summary>Specifies the right to open and copy file system attributes from a folder or task. For example, this value specifies the right to view the file creation or modified date. This does not include the right to read data, extended file system attributes, or access and audit rules.</summary>
|
||||||
ReadAttributes = 0x80,
|
ReadAttributes = 0x80,
|
||||||
/// <summary>Specifies the right to delete a folder and any tasks contained within that folder.</summary>
|
/// <summary>Specifies the right to delete a folder and any tasks contained within that folder.</summary>
|
||||||
DeleteChild = 0x40,
|
DeleteChild = 0x40,
|
||||||
/// <summary>Specifies the right to run a task.</summary>
|
/// <summary>Specifies the right to run a task.</summary>
|
||||||
ExecuteFile = 0x20,
|
ExecuteFile = 0x20,
|
||||||
/// <summary>Specifies the right to open and write extended file system attributes to a folder or file. This does not include the ability to write data, attributes, or access and audit rules.</summary>
|
/// <summary>Specifies the right to open and write extended file system attributes to a folder or file. This does not include the ability to write data, attributes, or access and audit rules.</summary>
|
||||||
WriteExtendedAttributes = 0x10,
|
WriteExtendedAttributes = 0x10,
|
||||||
/// <summary>Specifies the right to open and copy extended system attributes from a folder or task. For example, this value specifies the right to view author and content information. This does not include the right to read data, system attributes, or access and audit rules.</summary>
|
/// <summary>Specifies the right to open and copy extended system attributes from a folder or task. For example, this value specifies the right to view author and content information. This does not include the right to read data, system attributes, or access and audit rules.</summary>
|
||||||
ReadExtendedAttributes = 8,
|
ReadExtendedAttributes = 8,
|
||||||
/// <summary>Specifies the right to append data to the end of a file.</summary>
|
/// <summary>Specifies the right to append data to the end of a file.</summary>
|
||||||
AppendData = 4,
|
AppendData = 4,
|
||||||
/// <summary>Specifies the right to open and write to a file or folder. This does not include the right to open and write file system attributes, extended file system attributes, or access and audit rules.</summary>
|
/// <summary>Specifies the right to open and write to a file or folder. This does not include the right to open and write file system attributes, extended file system attributes, or access and audit rules.</summary>
|
||||||
WriteData = 2,
|
WriteData = 2,
|
||||||
/// <summary>Specifies the right to open and copy a task or folder. This does not include the right to read file system attributes, extended file system attributes, or access and audit rules.</summary>
|
/// <summary>Specifies the right to open and copy a task or folder. This does not include the right to read file system attributes, extended file system attributes, or access and audit rules.</summary>
|
||||||
ReadData = 1,
|
ReadData = 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a set of access rights allowed or denied for a user or group. This class cannot be inherited.
|
/// Represents a set of access rights allowed or denied for a user or group. This class cannot be inherited.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class TaskAccessRule : AccessRule
|
public sealed class TaskAccessRule : AccessRule
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TaskAccessRule"/> class, specifying the user or group the rule applies to, the access rights, and whether the specified access rights are allowed or denied.
|
/// Initializes a new instance of the <see cref="TaskAccessRule"/> class, specifying the user or group the rule applies to, the access rights, and whether the specified access rights are allowed or denied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identity">The user or group the rule applies to. Must be of type <see cref="SecurityIdentifier"/> or a type such as <see cref="NTAccount"/> that can be converted to type <see cref="SecurityIdentifier"/>.</param>
|
/// <param name="identity">The user or group the rule applies to. Must be of type <see cref="SecurityIdentifier"/> or a type such as <see cref="NTAccount"/> that can be converted to type <see cref="SecurityIdentifier"/>.</param>
|
||||||
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights"/> values specifying the rights allowed or denied.</param>
|
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights"/> values specifying the rights allowed or denied.</param>
|
||||||
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
|
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
|
||||||
public TaskAccessRule([NotNull] IdentityReference identity, TaskRights eventRights, AccessControlType type)
|
public TaskAccessRule([NotNull] IdentityReference identity, TaskRights eventRights, AccessControlType type)
|
||||||
: this(identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, type)
|
: this(identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TaskAccessRule"/> class, specifying the name of the user or group the rule applies to, the access rights, and whether the specified access rights are allowed or denied.
|
/// Initializes a new instance of the <see cref="TaskAccessRule"/> class, specifying the name of the user or group the rule applies to, the access rights, and whether the specified access rights are allowed or denied.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identity">The name of the user or group the rule applies to.</param>
|
/// <param name="identity">The name of the user or group the rule applies to.</param>
|
||||||
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights"/> values specifying the rights allowed or denied.</param>
|
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights"/> values specifying the rights allowed or denied.</param>
|
||||||
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
|
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
|
||||||
public TaskAccessRule([NotNull] string identity, TaskRights eventRights, AccessControlType type)
|
public TaskAccessRule([NotNull] string identity, TaskRights eventRights, AccessControlType type)
|
||||||
: this(new NTAccount(identity), (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, type)
|
: this(new NTAccount(identity), (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskAccessRule([NotNull] IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
|
private TaskAccessRule([NotNull] IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type)
|
||||||
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, type)
|
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the rights allowed or denied by the access rule.
|
/// Gets the rights allowed or denied by the access rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A bitwise combination of <see cref="TaskRights"/> values indicating the rights allowed or denied by the access rule.
|
/// A bitwise combination of <see cref="TaskRights"/> values indicating the rights allowed or denied by the access rule.
|
||||||
/// </value>
|
/// </value>
|
||||||
public TaskRights TaskRights => (TaskRights)AccessMask;
|
public TaskRights TaskRights => (TaskRights)AccessMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a set of access rights to be audited for a user or group. This class cannot be inherited.
|
/// Represents a set of access rights to be audited for a user or group. This class cannot be inherited.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class TaskAuditRule : AuditRule
|
public sealed class TaskAuditRule : AuditRule
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TaskAuditRule" /> class, specifying the user or group to audit, the rights to audit, and whether to audit success, failure, or both.
|
/// Initializes a new instance of the <see cref="TaskAuditRule" /> class, specifying the user or group to audit, the rights to audit, and whether to audit success, failure, or both.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identity">The user or group the rule applies to. Must be of type <see cref="SecurityIdentifier" /> or a type such as <see cref="NTAccount" /> that can be converted to type <see cref="SecurityIdentifier" />.</param>
|
/// <param name="identity">The user or group the rule applies to. Must be of type <see cref="SecurityIdentifier" /> or a type such as <see cref="NTAccount" /> that can be converted to type <see cref="SecurityIdentifier" />.</param>
|
||||||
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights" /> values specifying the kinds of access to audit.</param>
|
/// <param name="eventRights">A bitwise combination of <see cref="TaskRights" /> values specifying the kinds of access to audit.</param>
|
||||||
/// <param name="flags">The audit flags.</param>
|
/// <param name="flags">The audit flags.</param>
|
||||||
public TaskAuditRule([NotNull] IdentityReference identity, TaskRights eventRights, AuditFlags flags)
|
public TaskAuditRule([NotNull] IdentityReference identity, TaskRights eventRights, AuditFlags flags)
|
||||||
: this(identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, flags)
|
: this(identity, (int)eventRights, false, InheritanceFlags.None, PropagationFlags.None, flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
internal TaskAuditRule([NotNull] IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
|
internal TaskAuditRule([NotNull] IdentityReference identity, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags)
|
||||||
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, flags)
|
: base(identity, accessMask, isInherited, inheritanceFlags, propagationFlags, flags)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the access rights affected by the audit rule.
|
/// Gets the access rights affected by the audit rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>
|
/// <value>
|
||||||
/// A bitwise combination of <see cref="TaskRights"/> values that indicates the rights affected by the audit rule.
|
/// A bitwise combination of <see cref="TaskRights"/> values that indicates the rights affected by the audit rule.
|
||||||
/// </value>
|
/// </value>
|
||||||
/// <remarks><see cref="TaskAuditRule"/> objects are immutable. You can create a new audit rule representing a different user, different rights, or a different combination of AuditFlags values, but you cannot modify an existing audit rule.</remarks>
|
/// <remarks><see cref="TaskAuditRule"/> objects are immutable. You can create a new audit rule representing a different user, different rights, or a different combination of AuditFlags values, but you cannot modify an existing audit rule.</remarks>
|
||||||
public TaskRights TaskRights => (TaskRights)AccessMask;
|
public TaskRights TaskRights => (TaskRights)AccessMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents the Windows access control security for a Task Scheduler task. This class cannot be inherited.
|
/// Represents the Windows access control security for a Task Scheduler task. This class cannot be inherited.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// <para>A TaskSecurity object specifies access rights for a Task Scheduler task, and also specifies how access attempts are audited. Access rights to the task are expressed as rules, with each access rule represented by a <see cref="TaskAccessRule"/> object. Each auditing rule is represented by a <see cref="TaskAuditRule"/> object.</para>
|
/// <para>A TaskSecurity object specifies access rights for a Task Scheduler task, and also specifies how access attempts are audited. Access rights to the task are expressed as rules, with each access rule represented by a <see cref="TaskAccessRule"/> object. Each auditing rule is represented by a <see cref="TaskAuditRule"/> object.</para>
|
||||||
/// <para>This mirrors the underlying Windows security system, in which each securable object has at most one discretionary access control list (DACL) that controls access to the secured object, and at most one system access control list (SACL) that specifies which access attempts are audited. The DACL and SACL are ordered lists of access control entries (ACE) that specify access and auditing for users and groups. A <see cref="TaskAccessRule"/> or <see cref="TaskAuditRule"/> object might represent more than one ACE.</para>
|
/// <para>This mirrors the underlying Windows security system, in which each securable object has at most one discretionary access control list (DACL) that controls access to the secured object, and at most one system access control list (SACL) that specifies which access attempts are audited. The DACL and SACL are ordered lists of access control entries (ACE) that specify access and auditing for users and groups. A <see cref="TaskAccessRule"/> or <see cref="TaskAuditRule"/> object might represent more than one ACE.</para>
|
||||||
/// <para>Note</para>
|
/// <para>Note</para>
|
||||||
/// <para>A <see cref="Task"/> object can represent a local task or a Task Scheduler task. Windows access control security is meaningful only for Task Scheduler tasks.</para>
|
/// <para>A <see cref="Task"/> object can represent a local task or a Task Scheduler task. Windows access control security is meaningful only for Task Scheduler tasks.</para>
|
||||||
/// <para>The TaskSecurity, <see cref="TaskAccessRule"/>, and <see cref="TaskAuditRule"/> classes hide the implementation details of ACLs and ACEs. They allow you to ignore the seventeen different ACE types and the complexity of correctly maintaining inheritance and propagation of access rights. These objects are also designed to prevent the following common access control errors:</para>
|
/// <para>The TaskSecurity, <see cref="TaskAccessRule"/>, and <see cref="TaskAuditRule"/> classes hide the implementation details of ACLs and ACEs. They allow you to ignore the seventeen different ACE types and the complexity of correctly maintaining inheritance and propagation of access rights. These objects are also designed to prevent the following common access control errors:</para>
|
||||||
/// <list type="bullet">
|
/// <list type="bullet">
|
||||||
/// <item><description>Creating a security descriptor with a null DACL. A null reference to a DACL allows any user to add access rules to an object, potentially creating a denial-of-service attack. A new TaskSecurity object always starts with an empty DACL, which denies all access for all users.</description></item>
|
/// <item><description>Creating a security descriptor with a null DACL. A null reference to a DACL allows any user to add access rules to an object, potentially creating a denial-of-service attack. A new TaskSecurity object always starts with an empty DACL, which denies all access for all users.</description></item>
|
||||||
/// <item><description>Violating the canonical ordering of ACEs. If the ACE list in the DACL is not kept in the canonical order, users might inadvertently be given access to the secured object. For example, denied access rights must always appear before allowed access rights. TaskSecurity objects maintain the correct order internally. </description></item>
|
/// <item><description>Violating the canonical ordering of ACEs. If the ACE list in the DACL is not kept in the canonical order, users might inadvertently be given access to the secured object. For example, denied access rights must always appear before allowed access rights. TaskSecurity objects maintain the correct order internally. </description></item>
|
||||||
/// <item><description>Manipulating security descriptor flags, which should be under resource manager control only.</description></item>
|
/// <item><description>Manipulating security descriptor flags, which should be under resource manager control only.</description></item>
|
||||||
/// <item><description>Creating invalid combinations of ACE flags.</description></item>
|
/// <item><description>Creating invalid combinations of ACE flags.</description></item>
|
||||||
/// <item><description>Manipulating inherited ACEs. Inheritance and propagation are handled by the resource manager, in response to changes you make to access and audit rules.</description></item>
|
/// <item><description>Manipulating inherited ACEs. Inheritance and propagation are handled by the resource manager, in response to changes you make to access and audit rules.</description></item>
|
||||||
/// <item><description>Inserting meaningless ACEs into ACLs.</description></item>
|
/// <item><description>Inserting meaningless ACEs into ACLs.</description></item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// <para>The only capabilities not supported by the .NET security objects are dangerous activities that should be avoided by the majority of application developers, such as the following:</para>
|
/// <para>The only capabilities not supported by the .NET security objects are dangerous activities that should be avoided by the majority of application developers, such as the following:</para>
|
||||||
/// <list type="bullet">
|
/// <list type="bullet">
|
||||||
/// <item><description>Low-level tasks that are normally performed by the resource manager.</description></item>
|
/// <item><description>Low-level tasks that are normally performed by the resource manager.</description></item>
|
||||||
/// <item><description>Adding or removing access control entries in ways that do not maintain the canonical ordering.</description></item>
|
/// <item><description>Adding or removing access control entries in ways that do not maintain the canonical ordering.</description></item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// <para>To modify Windows access control security for a task, use the <see cref="Task.GetAccessControl()"/> method to get the TaskSecurity object. Modify the security object by adding and removing rules, and then use the <see cref="Task.SetAccessControl"/> method to reattach it. </para>
|
/// <para>To modify Windows access control security for a task, use the <see cref="Task.GetAccessControl()"/> method to get the TaskSecurity object. Modify the security object by adding and removing rules, and then use the <see cref="Task.SetAccessControl"/> method to reattach it. </para>
|
||||||
/// <para>Important: Changes you make to a TaskSecurity object do not affect the access levels of the task until you call the <see cref="Task.SetAccessControl"/> method to assign the altered security object to the task.</para>
|
/// <para>Important: Changes you make to a TaskSecurity object do not affect the access levels of the task until you call the <see cref="Task.SetAccessControl"/> method to assign the altered security object to the task.</para>
|
||||||
/// <para>To copy access control security from one task to another, use the <see cref="Task.GetAccessControl()"/> method to get a TaskSecurity object representing the access and audit rules for the first task, then use the <see cref="Task.SetAccessControl"/> method, or a constructor that accepts a TaskSecurity object, to assign those rules to the second task.</para>
|
/// <para>To copy access control security from one task to another, use the <see cref="Task.GetAccessControl()"/> method to get a TaskSecurity object representing the access and audit rules for the first task, then use the <see cref="Task.SetAccessControl"/> method, or a constructor that accepts a TaskSecurity object, to assign those rules to the second task.</para>
|
||||||
/// <para>Users with an investment in the security descriptor definition language (SDDL) can use the <see cref="Task.SetSecurityDescriptorSddlForm"/> method to set access rules for a task, and the <see cref="Task.GetSecurityDescriptorSddlForm"/> method to obtain a string that represents the access rules in SDDL format. This is not recommended for new development.</para>
|
/// <para>Users with an investment in the security descriptor definition language (SDDL) can use the <see cref="Task.SetSecurityDescriptorSddlForm"/> method to set access rules for a task, and the <see cref="Task.GetSecurityDescriptorSddlForm"/> method to obtain a string that represents the access rules in SDDL format. This is not recommended for new development.</para>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public sealed class TaskSecurity : CommonObjectSecurity
|
public sealed class TaskSecurity : CommonObjectSecurity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TaskSecurity"/> class with default values.
|
/// Initializes a new instance of the <see cref="TaskSecurity"/> class with default values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TaskSecurity()
|
public TaskSecurity()
|
||||||
: base(false)
|
: base(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TaskSecurity" /> class with the specified sections of the access control security rules from the specified task.
|
/// Initializes a new instance of the <see cref="TaskSecurity" /> class with the specified sections of the access control security rules from the specified task.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="task">The task.</param>
|
/// <param name="task">The task.</param>
|
||||||
/// <param name="sections">The sections of the ACL to retrieve.</param>
|
/// <param name="sections">The sections of the ACL to retrieve.</param>
|
||||||
public TaskSecurity([NotNull] Task task, AccessControlSections sections = Task.defaultAccessControlSections)
|
public TaskSecurity([NotNull] Task task, AccessControlSections sections = Task.defaultAccessControlSections)
|
||||||
: base(false)
|
: base(false)
|
||||||
{
|
{
|
||||||
SetSecurityDescriptorSddlForm(task.GetSecurityDescriptorSddlForm(Convert(sections)), sections);
|
SetSecurityDescriptorSddlForm(task.GetSecurityDescriptorSddlForm(Convert(sections)), sections);
|
||||||
this.CanonicalizeAccessRules();
|
this.CanonicalizeAccessRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TaskSecurity" /> class with the specified sections of the access control security rules from the specified task.
|
/// Initializes a new instance of the <see cref="TaskSecurity" /> class with the specified sections of the access control security rules from the specified task.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="folder">The folder.</param>
|
/// <param name="folder">The folder.</param>
|
||||||
/// <param name="sections">The sections of the ACL to retrieve.</param>
|
/// <param name="sections">The sections of the ACL to retrieve.</param>
|
||||||
public TaskSecurity([NotNull] TaskFolder folder, AccessControlSections sections = Task.defaultAccessControlSections)
|
public TaskSecurity([NotNull] TaskFolder folder, AccessControlSections sections = Task.defaultAccessControlSections)
|
||||||
: base(false)
|
: base(false)
|
||||||
{
|
{
|
||||||
SetSecurityDescriptorSddlForm(folder.GetSecurityDescriptorSddlForm(Convert(sections)), sections);
|
SetSecurityDescriptorSddlForm(folder.GetSecurityDescriptorSddlForm(Convert(sections)), sections);
|
||||||
this.CanonicalizeAccessRules();
|
this.CanonicalizeAccessRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the enumeration that the <see cref="TaskSecurity"/> class uses to represent access rights.
|
/// Gets the enumeration that the <see cref="TaskSecurity"/> class uses to represent access rights.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskRights"/> enumeration.</returns>
|
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskRights"/> enumeration.</returns>
|
||||||
public override Type AccessRightType => typeof(TaskRights);
|
public override Type AccessRightType => typeof(TaskRights);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type that the TaskSecurity class uses to represent access rules.
|
/// Gets the type that the TaskSecurity class uses to represent access rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskAccessRule"/> class.</returns>
|
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskAccessRule"/> class.</returns>
|
||||||
public override Type AccessRuleType => typeof(TaskAccessRule);
|
public override Type AccessRuleType => typeof(TaskAccessRule);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the type that the TaskSecurity class uses to represent audit rules.
|
/// Gets the type that the TaskSecurity class uses to represent audit rules.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskAuditRule"/> class.</returns>
|
/// <returns>A <see cref="Type"/> object representing the <see cref="TaskAuditRule"/> class.</returns>
|
||||||
public override Type AuditRuleType => typeof(TaskAuditRule);
|
public override Type AuditRuleType => typeof(TaskAuditRule);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a <see cref="TaskSecurity"/> object that represent the default access rights.
|
/// Gets a <see cref="TaskSecurity"/> object that represent the default access rights.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The default task security.</value>
|
/// <value>The default task security.</value>
|
||||||
public static TaskSecurity DefaultTaskSecurity
|
public static TaskSecurity DefaultTaskSecurity
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var ret = new TaskSecurity();
|
var ret = new TaskSecurity();
|
||||||
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), TaskRights.FullControl, AccessControlType.Allow));
|
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null), TaskRights.FullControl, AccessControlType.Allow));
|
||||||
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null), TaskRights.Read | TaskRights.Write | TaskRights.Execute, AccessControlType.Allow));
|
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null), TaskRights.Read | TaskRights.Write | TaskRights.Execute, AccessControlType.Allow));
|
||||||
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null), TaskRights.Read, AccessControlType.Allow));
|
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.LocalServiceSid, null), TaskRights.Read, AccessControlType.Allow));
|
||||||
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), TaskRights.Read, AccessControlType.Allow));
|
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null), TaskRights.Read, AccessControlType.Allow));
|
||||||
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null), TaskRights.Read, AccessControlType.Allow));
|
ret.AddAccessRule(new TaskAccessRule(new SecurityIdentifier(WellKnownSidType.NetworkServiceSid, null), TaskRights.Read, AccessControlType.Allow));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new access control rule for the specified user, with the specified access rights, access control, and flags.
|
/// Creates a new access control rule for the specified user, with the specified access rights, access control, and flags.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identityReference">An <see cref="IdentityReference"/> that identifies the user or group the rule applies to.</param>
|
/// <param name="identityReference">An <see cref="IdentityReference"/> that identifies the user or group the rule applies to.</param>
|
||||||
/// <param name="accessMask">A bitwise combination of <see cref="TaskRights"/> values specifying the access rights to allow or deny, cast to an integer.</param>
|
/// <param name="accessMask">A bitwise combination of <see cref="TaskRights"/> values specifying the access rights to allow or deny, cast to an integer.</param>
|
||||||
/// <param name="isInherited">Meaningless for tasks, because they have no hierarchy.</param>
|
/// <param name="isInherited">Meaningless for tasks, because they have no hierarchy.</param>
|
||||||
/// <param name="inheritanceFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
/// <param name="inheritanceFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
||||||
/// <param name="propagationFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
/// <param name="propagationFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
||||||
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
|
/// <param name="type">One of the <see cref="AccessControlType"/> values specifying whether the rights are allowed or denied.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The <see cref="T:System.Security.AccessControl.AccessRule" /> object that this method creates.
|
/// The <see cref="T:System.Security.AccessControl.AccessRule" /> object that this method creates.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) => new TaskAccessRule(identityReference, (TaskRights)accessMask, type);
|
public override AccessRule AccessRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AccessControlType type) => new TaskAccessRule(identityReference, (TaskRights)accessMask, type);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for a matching rule with which the new rule can be merged. If none are found, adds the new rule.
|
/// Searches for a matching rule with which the new rule can be merged. If none are found, adds the new rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The access control rule to add.</param>
|
/// <param name="rule">The access control rule to add.</param>
|
||||||
public void AddAccessRule([NotNull] TaskAccessRule rule)
|
public void AddAccessRule([NotNull] TaskAccessRule rule)
|
||||||
{
|
{
|
||||||
base.AddAccessRule(rule);
|
base.AddAccessRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an audit rule with which the new rule can be merged. If none are found, adds the new rule.
|
/// Searches for an audit rule with which the new rule can be merged. If none are found, adds the new rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The audit rule to add. The user specified by this rule determines the search.</param>
|
/// <param name="rule">The audit rule to add. The user specified by this rule determines the search.</param>
|
||||||
public void AddAuditRule([NotNull] TaskAuditRule rule)
|
public void AddAuditRule([NotNull] TaskAuditRule rule)
|
||||||
{
|
{
|
||||||
base.AddAuditRule(rule);
|
base.AddAuditRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new audit rule, specifying the user the rule applies to, the access rights to audit, and the outcome that triggers the audit rule.
|
/// Creates a new audit rule, specifying the user the rule applies to, the access rights to audit, and the outcome that triggers the audit rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="identityReference">An <see cref="IdentityReference"/> that identifies the user or group the rule applies to.</param>
|
/// <param name="identityReference">An <see cref="IdentityReference"/> that identifies the user or group the rule applies to.</param>
|
||||||
/// <param name="accessMask">A bitwise combination of <see cref="TaskRights"/> values specifying the access rights to audit, cast to an integer.</param>
|
/// <param name="accessMask">A bitwise combination of <see cref="TaskRights"/> values specifying the access rights to audit, cast to an integer.</param>
|
||||||
/// <param name="isInherited">Meaningless for tasks, because they have no hierarchy.</param>
|
/// <param name="isInherited">Meaningless for tasks, because they have no hierarchy.</param>
|
||||||
/// <param name="inheritanceFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
/// <param name="inheritanceFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
||||||
/// <param name="propagationFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
/// <param name="propagationFlags">Meaningless for tasks, because they have no hierarchy.</param>
|
||||||
/// <param name="flags">One of the <see cref="AuditFlags"/> values specifying whether to audit successful access, failed access, or both.</param>
|
/// <param name="flags">One of the <see cref="AuditFlags"/> values specifying whether to audit successful access, failed access, or both.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// A <see cref="TaskAuditRule"/> object representing the specified audit rule for the specified user. The return type of the method is the base class, <see cref="AuditRule"/>, but the return value can be cast safely to the derived class.
|
/// A <see cref="TaskAuditRule"/> object representing the specified audit rule for the specified user. The return type of the method is the base class, <see cref="AuditRule"/>, but the return value can be cast safely to the derived class.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) => new TaskAuditRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags);
|
public override AuditRule AuditRuleFactory(IdentityReference identityReference, int accessMask, bool isInherited, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags, AuditFlags flags) => new TaskAuditRule(identityReference, accessMask, isInherited, inheritanceFlags, propagationFlags, flags);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an access control rule with the same user and <see cref="AccessControlType"/> (allow or deny) as the specified rule, and with compatible inheritance and propagation flags; if such a rule is found, the rights contained in the specified access rule are removed from it.
|
/// Searches for an access control rule with the same user and <see cref="AccessControlType"/> (allow or deny) as the specified rule, and with compatible inheritance and propagation flags; if such a rule is found, the rights contained in the specified access rule are removed from it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">A <see cref="TaskAccessRule"/> that specifies the user and <see cref="AccessControlType"/> to search for, and a set of inheritance and propagation flags that a matching rule, if found, must be compatible with. Specifies the rights to remove from the compatible rule, if found.</param>
|
/// <param name="rule">A <see cref="TaskAccessRule"/> that specifies the user and <see cref="AccessControlType"/> to search for, and a set of inheritance and propagation flags that a matching rule, if found, must be compatible with. Specifies the rights to remove from the compatible rule, if found.</param>
|
||||||
/// <returns><c>true</c> if a compatible rule is found; otherwise <c>false</c>.</returns>
|
/// <returns><c>true</c> if a compatible rule is found; otherwise <c>false</c>.</returns>
|
||||||
public bool RemoveAccessRule([NotNull] TaskAccessRule rule) => base.RemoveAccessRule(rule);
|
public bool RemoveAccessRule([NotNull] TaskAccessRule rule) => base.RemoveAccessRule(rule);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for all access control rules with the same user and <see cref="AccessControlType"/> (allow or deny) as the specified rule and, if found, removes them.
|
/// Searches for all access control rules with the same user and <see cref="AccessControlType"/> (allow or deny) as the specified rule and, if found, removes them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">A <see cref="TaskAccessRule"/> that specifies the user and <see cref="AccessControlType"/> to search for, and a set of inheritance and propagation flags that a matching rule, if found, must be compatible with. Any rights specified by this rule are ignored.</param>
|
/// <param name="rule">A <see cref="TaskAccessRule"/> that specifies the user and <see cref="AccessControlType"/> to search for, and a set of inheritance and propagation flags that a matching rule, if found, must be compatible with. Any rights specified by this rule are ignored.</param>
|
||||||
public void RemoveAccessRuleAll([NotNull] TaskAccessRule rule)
|
public void RemoveAccessRuleAll([NotNull] TaskAccessRule rule)
|
||||||
{
|
{
|
||||||
base.RemoveAccessRuleAll(rule);
|
base.RemoveAccessRuleAll(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an access control rule that exactly matches the specified rule and, if found, removes it.
|
/// Searches for an access control rule that exactly matches the specified rule and, if found, removes it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The <see cref="TaskAccessRule"/> to remove.</param>
|
/// <param name="rule">The <see cref="TaskAccessRule"/> to remove.</param>
|
||||||
public void RemoveAccessRuleSpecific([NotNull] TaskAccessRule rule)
|
public void RemoveAccessRuleSpecific([NotNull] TaskAccessRule rule)
|
||||||
{
|
{
|
||||||
base.RemoveAccessRuleSpecific(rule);
|
base.RemoveAccessRuleSpecific(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an audit control rule with the same user as the specified rule, and with compatible inheritance and propagation flags; if a compatible rule is found, the rights contained in the specified rule are removed from it.
|
/// Searches for an audit control rule with the same user as the specified rule, and with compatible inheritance and propagation flags; if a compatible rule is found, the rights contained in the specified rule are removed from it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">A <see cref="TaskAuditRule"/> that specifies the user to search for, and a set of inheritance and propagation flags that a matching rule, if found, must be compatible with. Specifies the rights to remove from the compatible rule, if found.</param>
|
/// <param name="rule">A <see cref="TaskAuditRule"/> that specifies the user to search for, and a set of inheritance and propagation flags that a matching rule, if found, must be compatible with. Specifies the rights to remove from the compatible rule, if found.</param>
|
||||||
/// <returns><c>true</c> if a compatible rule is found; otherwise <c>false</c>.</returns>
|
/// <returns><c>true</c> if a compatible rule is found; otherwise <c>false</c>.</returns>
|
||||||
public bool RemoveAuditRule([NotNull] TaskAuditRule rule) => base.RemoveAuditRule(rule);
|
public bool RemoveAuditRule([NotNull] TaskAuditRule rule) => base.RemoveAuditRule(rule);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for all audit rules with the same user as the specified rule and, if found, removes them.
|
/// Searches for all audit rules with the same user as the specified rule and, if found, removes them.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">A <see cref="TaskAuditRule"/> that specifies the user to search for. Any rights specified by this rule are ignored.</param>
|
/// <param name="rule">A <see cref="TaskAuditRule"/> that specifies the user to search for. Any rights specified by this rule are ignored.</param>
|
||||||
public void RemoveAuditRuleAll(TaskAuditRule rule)
|
public void RemoveAuditRuleAll(TaskAuditRule rule)
|
||||||
{
|
{
|
||||||
base.RemoveAuditRuleAll(rule);
|
base.RemoveAuditRuleAll(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an audit rule that exactly matches the specified rule and, if found, removes it.
|
/// Searches for an audit rule that exactly matches the specified rule and, if found, removes it.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The <see cref="TaskAuditRule"/> to remove.</param>
|
/// <param name="rule">The <see cref="TaskAuditRule"/> to remove.</param>
|
||||||
public void RemoveAuditRuleSpecific([NotNull] TaskAuditRule rule)
|
public void RemoveAuditRuleSpecific([NotNull] TaskAuditRule rule)
|
||||||
{
|
{
|
||||||
base.RemoveAuditRuleSpecific(rule);
|
base.RemoveAuditRuleSpecific(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all access control rules with the same user as the specified rule, regardless of <see cref="AccessControlType"/>, and then adds the specified rule.
|
/// Removes all access control rules with the same user as the specified rule, regardless of <see cref="AccessControlType"/>, and then adds the specified rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The <see cref="TaskAccessRule"/> to add. The user specified by this rule determines the rules to remove before this rule is added.</param>
|
/// <param name="rule">The <see cref="TaskAccessRule"/> to add. The user specified by this rule determines the rules to remove before this rule is added.</param>
|
||||||
public void ResetAccessRule([NotNull] TaskAccessRule rule)
|
public void ResetAccessRule([NotNull] TaskAccessRule rule)
|
||||||
{
|
{
|
||||||
base.ResetAccessRule(rule);
|
base.ResetAccessRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all access control rules with the same user and <see cref="AccessControlType"/> (allow or deny) as the specified rule, and then adds the specified rule.
|
/// Removes all access control rules with the same user and <see cref="AccessControlType"/> (allow or deny) as the specified rule, and then adds the specified rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The <see cref="TaskAccessRule"/> to add. The user and <see cref="AccessControlType"/> of this rule determine the rules to remove before this rule is added.</param>
|
/// <param name="rule">The <see cref="TaskAccessRule"/> to add. The user and <see cref="AccessControlType"/> of this rule determine the rules to remove before this rule is added.</param>
|
||||||
public void SetAccessRule([NotNull] TaskAccessRule rule)
|
public void SetAccessRule([NotNull] TaskAccessRule rule)
|
||||||
{
|
{
|
||||||
base.SetAccessRule(rule);
|
base.SetAccessRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Removes all audit rules with the same user as the specified rule, regardless of the <see cref="AuditFlags"/> value, and then adds the specified rule.
|
/// Removes all audit rules with the same user as the specified rule, regardless of the <see cref="AuditFlags"/> value, and then adds the specified rule.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="rule">The <see cref="TaskAuditRule"/> to add. The user specified by this rule determines the rules to remove before this rule is added.</param>
|
/// <param name="rule">The <see cref="TaskAuditRule"/> to add. The user specified by this rule determines the rules to remove before this rule is added.</param>
|
||||||
public void SetAuditRule([NotNull] TaskAuditRule rule)
|
public void SetAuditRule([NotNull] TaskAuditRule rule)
|
||||||
{
|
{
|
||||||
base.SetAuditRule(rule);
|
base.SetAuditRule(rule);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns a <see cref="System.String" /> that represents this instance.
|
/// Returns a <see cref="System.String" /> that represents this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// A <see cref="System.String" /> that represents this instance.
|
/// A <see cref="System.String" /> that represents this instance.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public override string ToString() => GetSecurityDescriptorSddlForm(Task.defaultAccessControlSections);
|
public override string ToString() => GetSecurityDescriptorSddlForm(Task.defaultAccessControlSections);
|
||||||
|
|
||||||
private static SecurityInfos Convert(AccessControlSections si)
|
private static SecurityInfos Convert(AccessControlSections si)
|
||||||
{
|
{
|
||||||
SecurityInfos ret = 0;
|
SecurityInfos ret = 0;
|
||||||
if ((si & AccessControlSections.Audit) != 0)
|
if ((si & AccessControlSections.Audit) != 0)
|
||||||
ret |= SecurityInfos.SystemAcl;
|
ret |= SecurityInfos.SystemAcl;
|
||||||
if ((si & AccessControlSections.Access) != 0)
|
if ((si & AccessControlSections.Access) != 0)
|
||||||
ret |= SecurityInfos.DiscretionaryAcl;
|
ret |= SecurityInfos.DiscretionaryAcl;
|
||||||
if ((si & AccessControlSections.Group) != 0)
|
if ((si & AccessControlSections.Group) != 0)
|
||||||
ret |= SecurityInfos.Group;
|
ret |= SecurityInfos.Group;
|
||||||
if ((si & AccessControlSections.Owner) != 0)
|
if ((si & AccessControlSections.Owner) != 0)
|
||||||
ret |= SecurityInfos.Owner;
|
ret |= SecurityInfos.Owner;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static AccessControlSections Convert(SecurityInfos si)
|
private static AccessControlSections Convert(SecurityInfos si)
|
||||||
{
|
{
|
||||||
AccessControlSections ret = AccessControlSections.None;
|
AccessControlSections ret = AccessControlSections.None;
|
||||||
if ((si & SecurityInfos.SystemAcl) != 0)
|
if ((si & SecurityInfos.SystemAcl) != 0)
|
||||||
ret |= AccessControlSections.Audit;
|
ret |= AccessControlSections.Audit;
|
||||||
if ((si & SecurityInfos.DiscretionaryAcl) != 0)
|
if ((si & SecurityInfos.DiscretionaryAcl) != 0)
|
||||||
ret |= AccessControlSections.Access;
|
ret |= AccessControlSections.Access;
|
||||||
if ((si & SecurityInfos.Group) != 0)
|
if ((si & SecurityInfos.Group) != 0)
|
||||||
ret |= AccessControlSections.Group;
|
ret |= AccessControlSections.Group;
|
||||||
if ((si & SecurityInfos.Owner) != 0)
|
if ((si & SecurityInfos.Owner) != 0)
|
||||||
ret |= AccessControlSections.Owner;
|
ret |= AccessControlSections.Owner;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private AccessControlSections GetAccessControlSectionsFromChanges()
|
private AccessControlSections GetAccessControlSectionsFromChanges()
|
||||||
{
|
{
|
||||||
AccessControlSections none = AccessControlSections.None;
|
AccessControlSections none = AccessControlSections.None;
|
||||||
if (AccessRulesModified)
|
if (AccessRulesModified)
|
||||||
{
|
{
|
||||||
none = AccessControlSections.Access;
|
none = AccessControlSections.Access;
|
||||||
}
|
}
|
||||||
if (AuditRulesModified)
|
if (AuditRulesModified)
|
||||||
{
|
{
|
||||||
none |= AccessControlSections.Audit;
|
none |= AccessControlSections.Audit;
|
||||||
}
|
}
|
||||||
if (OwnerModified)
|
if (OwnerModified)
|
||||||
{
|
{
|
||||||
none |= AccessControlSections.Owner;
|
none |= AccessControlSections.Owner;
|
||||||
}
|
}
|
||||||
if (GroupModified)
|
if (GroupModified)
|
||||||
{
|
{
|
||||||
none |= AccessControlSections.Group;
|
none |= AccessControlSections.Group;
|
||||||
}
|
}
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the specified sections of the security descriptor associated with this <see cref="TaskSecurity"/> object to permanent storage. We recommend that the values of the <paramref name="includeSections"/> parameters passed to the constructor and persist methods be identical.
|
/// Saves the specified sections of the security descriptor associated with this <see cref="TaskSecurity"/> object to permanent storage. We recommend that the values of the <paramref name="includeSections"/> parameters passed to the constructor and persist methods be identical.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="task">The task used to retrieve the persisted information.</param>
|
/// <param name="task">The task used to retrieve the persisted information.</param>
|
||||||
/// <param name="includeSections">One of the <see cref="AccessControlSections"/> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
|
/// <param name="includeSections">One of the <see cref="AccessControlSections"/> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
internal void Persist([NotNull] Task task, AccessControlSections includeSections = Task.defaultAccessControlSections)
|
internal void Persist([NotNull] Task task, AccessControlSections includeSections = Task.defaultAccessControlSections)
|
||||||
{
|
{
|
||||||
WriteLock();
|
WriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AccessControlSections accessControlSectionsFromChanges = GetAccessControlSectionsFromChanges();
|
AccessControlSections accessControlSectionsFromChanges = GetAccessControlSectionsFromChanges();
|
||||||
if (accessControlSectionsFromChanges != AccessControlSections.None)
|
if (accessControlSectionsFromChanges != AccessControlSections.None)
|
||||||
{
|
{
|
||||||
task.SetSecurityDescriptorSddlForm(GetSecurityDescriptorSddlForm(accessControlSectionsFromChanges));
|
task.SetSecurityDescriptorSddlForm(GetSecurityDescriptorSddlForm(accessControlSectionsFromChanges));
|
||||||
OwnerModified = GroupModified = AccessRulesModified = AuditRulesModified = false;
|
OwnerModified = GroupModified = AccessRulesModified = AuditRulesModified = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
WriteUnlock();
|
WriteUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the specified sections of the security descriptor associated with this <see cref="TaskSecurity" /> object to permanent storage. We recommend that the values of the <paramref name="includeSections" /> parameters passed to the constructor and persist methods be identical.
|
/// Saves the specified sections of the security descriptor associated with this <see cref="TaskSecurity" /> object to permanent storage. We recommend that the values of the <paramref name="includeSections" /> parameters passed to the constructor and persist methods be identical.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="folder">The task folder used to retrieve the persisted information.</param>
|
/// <param name="folder">The task folder used to retrieve the persisted information.</param>
|
||||||
/// <param name="includeSections">One of the <see cref="AccessControlSections" /> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
|
/// <param name="includeSections">One of the <see cref="AccessControlSections" /> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
internal void Persist([NotNull] TaskFolder folder, AccessControlSections includeSections = Task.defaultAccessControlSections)
|
internal void Persist([NotNull] TaskFolder folder, AccessControlSections includeSections = Task.defaultAccessControlSections)
|
||||||
{
|
{
|
||||||
WriteLock();
|
WriteLock();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AccessControlSections accessControlSectionsFromChanges = GetAccessControlSectionsFromChanges();
|
AccessControlSections accessControlSectionsFromChanges = GetAccessControlSectionsFromChanges();
|
||||||
if (accessControlSectionsFromChanges != AccessControlSections.None)
|
if (accessControlSectionsFromChanges != AccessControlSections.None)
|
||||||
{
|
{
|
||||||
folder.SetSecurityDescriptorSddlForm(GetSecurityDescriptorSddlForm(accessControlSectionsFromChanges));
|
folder.SetSecurityDescriptorSddlForm(GetSecurityDescriptorSddlForm(accessControlSectionsFromChanges));
|
||||||
OwnerModified = GroupModified = AccessRulesModified = AuditRulesModified = false;
|
OwnerModified = GroupModified = AccessRulesModified = AuditRulesModified = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
WriteUnlock();
|
WriteUnlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Saves the specified sections of the security descriptor associated with this <see cref="T:System.Security.AccessControl.ObjectSecurity" /> object to permanent storage. We recommend that the values of the <paramref name="includeSections" /> parameters passed to the constructor and persist methods be identical. For more information, see Remarks.
|
/// Saves the specified sections of the security descriptor associated with this <see cref="T:System.Security.AccessControl.ObjectSecurity" /> object to permanent storage. We recommend that the values of the <paramref name="includeSections" /> parameters passed to the constructor and persist methods be identical. For more information, see Remarks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name used to retrieve the persisted information.</param>
|
/// <param name="name">The name used to retrieve the persisted information.</param>
|
||||||
/// <param name="includeSections">One of the <see cref="T:System.Security.AccessControl.AccessControlSections" /> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
|
/// <param name="includeSections">One of the <see cref="T:System.Security.AccessControl.AccessControlSections" /> enumeration values that specifies the sections of the security descriptor (access rules, audit rules, owner, primary group) of the securable object to save.</param>
|
||||||
protected override void Persist([NotNull] string name, AccessControlSections includeSections = Task.defaultAccessControlSections)
|
protected override void Persist([NotNull] string name, AccessControlSections includeSections = Task.defaultAccessControlSections)
|
||||||
{
|
{
|
||||||
using (var ts = new TaskService())
|
using (var ts = new TaskService())
|
||||||
{
|
{
|
||||||
var task = ts.GetTask(name);
|
var task = ts.GetTask(name);
|
||||||
Persist(task, includeSections);
|
Persist(task, includeSections);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3,11 +3,8 @@ using System.Collections;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||||
using winPEAS.TaskScheduler.V1;
|
using winPEAS.TaskScheduler.V1;
|
||||||
@@ -15,129 +12,129 @@ using winPEAS.TaskScheduler.V2;
|
|||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
[XmlRoot("Triggers", Namespace = TaskDefinition.tns, IsNullable = false)]
|
[XmlRoot("Triggers", Namespace = TaskDefinition.tns, IsNullable = false)]
|
||||||
public sealed class TriggerCollection : IList<Trigger>, IDisposable, IXmlSerializable, IList, INotifyCollectionChanged, INotifyPropertyChanged
|
public sealed class TriggerCollection : IList<Trigger>, IDisposable, IXmlSerializable, IList, INotifyCollectionChanged, INotifyPropertyChanged
|
||||||
{
|
{
|
||||||
private const string IndexerName = "Item[]";
|
private const string IndexerName = "Item[]";
|
||||||
private readonly ITriggerCollection v2Coll;
|
private readonly ITriggerCollection v2Coll;
|
||||||
private bool inV2set;
|
private bool inV2set;
|
||||||
private ITask v1Task;
|
private ITask v1Task;
|
||||||
private ITaskDefinition v2Def;
|
private ITaskDefinition v2Def;
|
||||||
|
|
||||||
internal TriggerCollection([NotNull] ITask iTask) => v1Task = iTask;
|
internal TriggerCollection([NotNull] ITask iTask) => v1Task = iTask;
|
||||||
|
|
||||||
internal TriggerCollection([NotNull] ITaskDefinition iTaskDef)
|
internal TriggerCollection([NotNull] ITaskDefinition iTaskDef)
|
||||||
{
|
{
|
||||||
v2Def = iTaskDef;
|
v2Def = iTaskDef;
|
||||||
v2Coll = v2Def.Triggers;
|
v2Coll = v2Def.Triggers;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Occurs when a collection changes.</summary>
|
/// <summary>Occurs when a collection changes.</summary>
|
||||||
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||||
|
|
||||||
/// <summary>Occurs when a property value changes.</summary>
|
/// <summary>Occurs when a property value changes.</summary>
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
/// <summary>Gets the number of triggers in the collection.</summary>
|
/// <summary>Gets the number of triggers in the collection.</summary>
|
||||||
public int Count => v2Coll?.Count ?? v1Task.GetTriggerCount();
|
public int Count => v2Coll?.Count ?? v1Task.GetTriggerCount();
|
||||||
|
|
||||||
bool IList.IsFixedSize => false;
|
bool IList.IsFixedSize => false;
|
||||||
|
|
||||||
bool ICollection<Trigger>.IsReadOnly => false;
|
bool ICollection<Trigger>.IsReadOnly => false;
|
||||||
|
|
||||||
bool IList.IsReadOnly => false;
|
bool IList.IsReadOnly => false;
|
||||||
|
|
||||||
bool ICollection.IsSynchronized => false;
|
bool ICollection.IsSynchronized => false;
|
||||||
|
|
||||||
object ICollection.SyncRoot => this;
|
object ICollection.SyncRoot => this;
|
||||||
|
|
||||||
/// <summary>Gets or sets a specified trigger from the collection.</summary>
|
/// <summary>Gets or sets a specified trigger from the collection.</summary>
|
||||||
/// <value>The <see cref="Trigger"/>.</value>
|
/// <value>The <see cref="Trigger"/>.</value>
|
||||||
/// <param name="triggerId">The id ( <see cref="Trigger.Id"/>) of the trigger to be retrieved.</param>
|
/// <param name="triggerId">The id ( <see cref="Trigger.Id"/>) of the trigger to be retrieved.</param>
|
||||||
/// <returns>Specialized <see cref="Trigger"/> instance.</returns>
|
/// <returns>Specialized <see cref="Trigger"/> instance.</returns>
|
||||||
/// <exception cref="ArgumentNullException"></exception>
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
/// <exception cref="ArgumentOutOfRangeException"></exception>
|
||||||
/// <exception cref="NullReferenceException"></exception>
|
/// <exception cref="NullReferenceException"></exception>
|
||||||
/// <exception cref="InvalidOperationException">Mismatching Id for trigger and lookup.</exception>
|
/// <exception cref="InvalidOperationException">Mismatching Id for trigger and lookup.</exception>
|
||||||
public Trigger this[[NotNull] string triggerId]
|
public Trigger this[[NotNull] string triggerId]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(triggerId))
|
if (string.IsNullOrEmpty(triggerId))
|
||||||
throw new ArgumentNullException(nameof(triggerId));
|
throw new ArgumentNullException(nameof(triggerId));
|
||||||
foreach (var t in this)
|
foreach (var t in this)
|
||||||
if (string.Equals(t.Id, triggerId))
|
if (string.Equals(t.Id, triggerId))
|
||||||
return t;
|
return t;
|
||||||
throw new ArgumentOutOfRangeException(nameof(triggerId));
|
throw new ArgumentOutOfRangeException(nameof(triggerId));
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new NullReferenceException();
|
throw new NullReferenceException();
|
||||||
if (string.IsNullOrEmpty(triggerId))
|
if (string.IsNullOrEmpty(triggerId))
|
||||||
throw new ArgumentNullException(nameof(triggerId));
|
throw new ArgumentNullException(nameof(triggerId));
|
||||||
if (triggerId != value.Id)
|
if (triggerId != value.Id)
|
||||||
throw new InvalidOperationException("Mismatching Id for trigger and lookup.");
|
throw new InvalidOperationException("Mismatching Id for trigger and lookup.");
|
||||||
var index = IndexOf(triggerId);
|
var index = IndexOf(triggerId);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
{
|
{
|
||||||
var orig = this[index].Clone();
|
var orig = this[index].Clone();
|
||||||
inV2set = true;
|
inV2set = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RemoveAt(index);
|
RemoveAt(index);
|
||||||
Insert(index, value);
|
Insert(index, value);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
inV2set = true;
|
inV2set = true;
|
||||||
}
|
}
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, orig, index));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, orig, index));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Add(value);
|
Add(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets a specified trigger from the collection.</summary>
|
/// <summary>Gets a specified trigger from the collection.</summary>
|
||||||
/// <param name="index">The index of the trigger to be retrieved.</param>
|
/// <param name="index">The index of the trigger to be retrieved.</param>
|
||||||
/// <returns>Specialized <see cref="Trigger"/> instance.</returns>
|
/// <returns>Specialized <see cref="Trigger"/> instance.</returns>
|
||||||
public Trigger this[int index]
|
public Trigger this[int index]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
return Trigger.CreateTrigger(v2Coll[++index], v2Def);
|
return Trigger.CreateTrigger(v2Coll[++index], v2Def);
|
||||||
return Trigger.CreateTrigger(v1Task.GetTrigger((ushort)index));
|
return Trigger.CreateTrigger(v1Task.GetTrigger((ushort)index));
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (index < 0 || Count <= index)
|
if (index < 0 || Count <= index)
|
||||||
throw new ArgumentOutOfRangeException(nameof(index), index, @"Index is not a valid index in the TriggerCollection");
|
throw new ArgumentOutOfRangeException(nameof(index), index, @"Index is not a valid index in the TriggerCollection");
|
||||||
var orig = this[index].Clone();
|
var orig = this[index].Clone();
|
||||||
inV2set = true;
|
inV2set = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Insert(index, value);
|
Insert(index, value);
|
||||||
RemoveAt(index + 1);
|
RemoveAt(index + 1);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
inV2set = false;
|
inV2set = false;
|
||||||
}
|
}
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, orig, index));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, value, orig, index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object IList.this[int index]
|
object IList.this[int index]
|
||||||
{
|
{
|
||||||
get => this[index];
|
get => this[index];
|
||||||
set => this[index] = (Trigger)value;
|
set => this[index] = (Trigger)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*/// <summary>
|
/*/// <summary>
|
||||||
/// Add an unbound <see cref="Trigger"/> to the task. </summary> <param name="unboundTrigger"><see cref="Trigger"/> derivative to
|
/// Add an unbound <see cref="Trigger"/> to the task. </summary> <param name="unboundTrigger"><see cref="Trigger"/> derivative to
|
||||||
/// add to the task.</param> <returns>Bound trigger.</returns> <exception cref="System.ArgumentNullException"><c>unboundTrigger</c>
|
/// add to the task.</param> <returns>Bound trigger.</returns> <exception cref="System.ArgumentNullException"><c>unboundTrigger</c>
|
||||||
/// is <c>null</c>.</exception>
|
/// is <c>null</c>.</exception>
|
||||||
@@ -152,387 +149,387 @@ namespace winPEAS.TaskScheduler
|
|||||||
return unboundTrigger;
|
return unboundTrigger;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
/// <summary>Add an unbound <see cref="Trigger"/> to the task.</summary>
|
/// <summary>Add an unbound <see cref="Trigger"/> to the task.</summary>
|
||||||
/// <typeparam name="TTrigger">A type derived from <see cref="Trigger"/>.</typeparam>
|
/// <typeparam name="TTrigger">A type derived from <see cref="Trigger"/>.</typeparam>
|
||||||
/// <param name="unboundTrigger"><see cref="Trigger"/> derivative to add to the task.</param>
|
/// <param name="unboundTrigger"><see cref="Trigger"/> derivative to add to the task.</param>
|
||||||
/// <returns>Bound trigger.</returns>
|
/// <returns>Bound trigger.</returns>
|
||||||
/// <exception cref="ArgumentNullException"><c>unboundTrigger</c> is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException"><c>unboundTrigger</c> is <c>null</c>.</exception>
|
||||||
public TTrigger Add<TTrigger>([NotNull] TTrigger unboundTrigger) where TTrigger : Trigger
|
public TTrigger Add<TTrigger>([NotNull] TTrigger unboundTrigger) where TTrigger : Trigger
|
||||||
{
|
{
|
||||||
if (unboundTrigger == null)
|
if (unboundTrigger == null)
|
||||||
throw new ArgumentNullException(nameof(unboundTrigger));
|
throw new ArgumentNullException(nameof(unboundTrigger));
|
||||||
if (v2Def != null)
|
if (v2Def != null)
|
||||||
unboundTrigger.Bind(v2Def);
|
unboundTrigger.Bind(v2Def);
|
||||||
else
|
else
|
||||||
unboundTrigger.Bind(v1Task);
|
unboundTrigger.Bind(v1Task);
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, unboundTrigger));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, unboundTrigger));
|
||||||
return unboundTrigger;
|
return unboundTrigger;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Add a new trigger to the collections of triggers for the task.</summary>
|
/// <summary>Add a new trigger to the collections of triggers for the task.</summary>
|
||||||
/// <param name="taskTriggerType">The type of trigger to create.</param>
|
/// <param name="taskTriggerType">The type of trigger to create.</param>
|
||||||
/// <returns>A <see cref="Trigger"/> instance of the specified type.</returns>
|
/// <returns>A <see cref="Trigger"/> instance of the specified type.</returns>
|
||||||
public Trigger AddNew(TaskTriggerType taskTriggerType)
|
public Trigger AddNew(TaskTriggerType taskTriggerType)
|
||||||
{
|
{
|
||||||
if (v1Task != null)
|
if (v1Task != null)
|
||||||
return Trigger.CreateTrigger(v1Task.CreateTrigger(out _), Trigger.ConvertToV1TriggerType(taskTriggerType));
|
return Trigger.CreateTrigger(v1Task.CreateTrigger(out _), Trigger.ConvertToV1TriggerType(taskTriggerType));
|
||||||
|
|
||||||
return Trigger.CreateTrigger(v2Coll.Create(taskTriggerType), v2Def);
|
return Trigger.CreateTrigger(v2Coll.Create(taskTriggerType), v2Def);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Adds a collection of unbound triggers to the end of the <see cref="TriggerCollection"/>.</summary>
|
/// <summary>Adds a collection of unbound triggers to the end of the <see cref="TriggerCollection"/>.</summary>
|
||||||
/// <param name="triggers">
|
/// <param name="triggers">
|
||||||
/// The triggers to be added to the end of the <see cref="TriggerCollection"/>. The collection itself cannot be <c>null</c> and
|
/// The triggers to be added to the end of the <see cref="TriggerCollection"/>. The collection itself cannot be <c>null</c> and
|
||||||
/// cannot contain <c>null</c> elements.
|
/// cannot contain <c>null</c> elements.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="triggers"/> is <c>null</c>.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="triggers"/> is <c>null</c>.</exception>
|
||||||
public void AddRange([NotNull] IEnumerable<Trigger> triggers)
|
public void AddRange([NotNull] IEnumerable<Trigger> triggers)
|
||||||
{
|
{
|
||||||
if (triggers == null)
|
if (triggers == null)
|
||||||
throw new ArgumentNullException(nameof(triggers));
|
throw new ArgumentNullException(nameof(triggers));
|
||||||
foreach (var item in triggers)
|
foreach (var item in triggers)
|
||||||
Add(item);
|
Add(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Clears all triggers from the task.</summary>
|
/// <summary>Clears all triggers from the task.</summary>
|
||||||
public void Clear()
|
public void Clear()
|
||||||
{
|
{
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
v2Coll.Clear();
|
v2Coll.Clear();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inV2set = true;
|
inV2set = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
for (var i = Count - 1; i >= 0; i--)
|
for (var i = Count - 1; i >= 0; i--)
|
||||||
RemoveAt(i);
|
RemoveAt(i);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
inV2set = false;
|
inV2set = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines whether the <see cref="ICollection{T}"/> contains a specific value.</summary>
|
/// <summary>Determines whether the <see cref="ICollection{T}"/> contains a specific value.</summary>
|
||||||
/// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to locate in the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <returns>true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.</returns>
|
/// <returns>true if <paramref name="item"/> is found in the <see cref="ICollection{T}"/>; otherwise, false.</returns>
|
||||||
public bool Contains([NotNull] Trigger item) => Find(a => a.Equals(item)) != null;
|
public bool Contains([NotNull] Trigger item) => Find(a => a.Equals(item)) != null;
|
||||||
|
|
||||||
/// <summary>Determines whether the specified trigger type is contained in this collection.</summary>
|
/// <summary>Determines whether the specified trigger type is contained in this collection.</summary>
|
||||||
/// <param name="triggerType">Type of the trigger.</param>
|
/// <param name="triggerType">Type of the trigger.</param>
|
||||||
/// <returns><c>true</c> if the specified trigger type is contained in this collection; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified trigger type is contained in this collection; otherwise, <c>false</c>.</returns>
|
||||||
public bool ContainsType(Type triggerType) => Find(a => a.GetType() == triggerType) != null;
|
public bool ContainsType(Type triggerType) => Find(a => a.GetType() == triggerType) != null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies the elements of the <see cref="ICollection{T}"/> to an <see cref="Array"/>, starting at a particular <see cref="Array"/> index.
|
/// Copies the elements of the <see cref="ICollection{T}"/> to an <see cref="Array"/>, starting at a particular <see cref="Array"/> index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="array">
|
/// <param name="array">
|
||||||
/// The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ICollection{T}"/>. The
|
/// The one-dimensional <see cref="Array"/> that is the destination of the elements copied from <see cref="ICollection{T}"/>. The
|
||||||
/// <see cref="Array"/> must have zero-based indexing.
|
/// <see cref="Array"/> must have zero-based indexing.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
/// <param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||||
public void CopyTo(Trigger[] array, int arrayIndex) => CopyTo(0, array, arrayIndex, Count);
|
public void CopyTo(Trigger[] array, int arrayIndex) => CopyTo(0, array, arrayIndex, Count);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Copies the elements of the <see cref="TriggerCollection"/> to a <see cref="Trigger"/> array, starting at a particular <see
|
/// Copies the elements of the <see cref="TriggerCollection"/> to a <see cref="Trigger"/> array, starting at a particular <see
|
||||||
/// cref="Trigger"/> array index.
|
/// cref="Trigger"/> array index.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="index">The zero-based index in the source at which copying begins.</param>
|
/// <param name="index">The zero-based index in the source at which copying begins.</param>
|
||||||
/// <param name="array">
|
/// <param name="array">
|
||||||
/// The <see cref="Trigger"/> array that is the destination of the elements copied from <see cref="TriggerCollection"/>. The <see
|
/// The <see cref="Trigger"/> array that is the destination of the elements copied from <see cref="TriggerCollection"/>. The <see
|
||||||
/// cref="Trigger"/> array must have zero-based indexing.
|
/// cref="Trigger"/> array must have zero-based indexing.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="arrayIndex">The zero-based index in <see cref="Trigger"/> array at which copying begins.</param>
|
/// <param name="arrayIndex">The zero-based index in <see cref="Trigger"/> array at which copying begins.</param>
|
||||||
/// <param name="count">The number of elements to copy.</param>
|
/// <param name="count">The number of elements to copy.</param>
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>
|
/// <exception cref="ArgumentNullException"><paramref name="array"/> is null.</exception>
|
||||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than 0.</exception>
|
/// <exception cref="ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than 0.</exception>
|
||||||
/// <exception cref="ArgumentException">
|
/// <exception cref="ArgumentException">
|
||||||
/// The number of elements in the source <see cref="TriggerCollection"/> is greater than the available space from <paramref
|
/// The number of elements in the source <see cref="TriggerCollection"/> is greater than the available space from <paramref
|
||||||
/// name="arrayIndex"/> to the end of the destination <paramref name="array"/>.
|
/// name="arrayIndex"/> to the end of the destination <paramref name="array"/>.
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public void CopyTo(int index, Trigger[] array, int arrayIndex, int count)
|
public void CopyTo(int index, Trigger[] array, int arrayIndex, int count)
|
||||||
{
|
{
|
||||||
if (array == null)
|
if (array == null)
|
||||||
throw new ArgumentNullException(nameof(array));
|
throw new ArgumentNullException(nameof(array));
|
||||||
if (index < 0 || index >= Count)
|
if (index < 0 || index >= Count)
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
if (arrayIndex < 0)
|
if (arrayIndex < 0)
|
||||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||||
if (count < 0 || count > (Count - index))
|
if (count < 0 || count > (Count - index))
|
||||||
throw new ArgumentOutOfRangeException(nameof(count));
|
throw new ArgumentOutOfRangeException(nameof(count));
|
||||||
if ((Count - index) > (array.Length - arrayIndex))
|
if ((Count - index) > (array.Length - arrayIndex))
|
||||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||||
for (var i = 0; i < count; i++)
|
for (var i = 0; i < count; i++)
|
||||||
array[arrayIndex + i] = (Trigger)this[index + i].Clone();
|
array[arrayIndex + i] = (Trigger)this[index + i].Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
if (v2Coll != null) Marshal.ReleaseComObject(v2Coll);
|
if (v2Coll != null) Marshal.ReleaseComObject(v2Coll);
|
||||||
v2Def = null;
|
v2Def = null;
|
||||||
v1Task = null;
|
v1Task = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the first
|
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the first
|
||||||
/// occurrence within the entire collection.
|
/// occurrence within the entire collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="match">
|
/// <param name="match">
|
||||||
/// The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the <see cref="Trigger"/> to search for.
|
/// The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the <see cref="Trigger"/> to search for.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The first <see cref="Trigger"/> that matches the conditions defined by the specified predicate, if found; otherwise, <c>null</c>.
|
/// The first <see cref="Trigger"/> that matches the conditions defined by the specified predicate, if found; otherwise, <c>null</c>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public Trigger Find([NotNull] Predicate<Trigger> match)
|
public Trigger Find([NotNull] Predicate<Trigger> match)
|
||||||
{
|
{
|
||||||
if (match == null)
|
if (match == null)
|
||||||
throw new ArgumentNullException(nameof(match));
|
throw new ArgumentNullException(nameof(match));
|
||||||
foreach (var item in this)
|
foreach (var item in this)
|
||||||
if (match(item)) return item;
|
if (match(item)) return item;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the zero-based
|
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the zero-based
|
||||||
/// index of the first occurrence within the collection that starts at the specified index and contains the specified number of elements.
|
/// index of the first occurrence within the collection that starts at the specified index and contains the specified number of elements.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="startIndex">The zero-based starting index of the search.</param>
|
/// <param name="startIndex">The zero-based starting index of the search.</param>
|
||||||
/// <param name="count">The number of elements in the collection to search.</param>
|
/// <param name="count">The number of elements in the collection to search.</param>
|
||||||
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the element to search for.</param>
|
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the element to search for.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
|
/// The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public int FindIndexOf(int startIndex, int count, [NotNull] Predicate<Trigger> match)
|
public int FindIndexOf(int startIndex, int count, [NotNull] Predicate<Trigger> match)
|
||||||
{
|
{
|
||||||
if (startIndex < 0 || startIndex >= Count)
|
if (startIndex < 0 || startIndex >= Count)
|
||||||
throw new ArgumentOutOfRangeException(nameof(startIndex));
|
throw new ArgumentOutOfRangeException(nameof(startIndex));
|
||||||
if (startIndex + count > Count)
|
if (startIndex + count > Count)
|
||||||
throw new ArgumentOutOfRangeException(nameof(count));
|
throw new ArgumentOutOfRangeException(nameof(count));
|
||||||
if (match == null)
|
if (match == null)
|
||||||
throw new ArgumentNullException(nameof(match));
|
throw new ArgumentNullException(nameof(match));
|
||||||
for (var i = startIndex; i < startIndex + count; i++)
|
for (var i = startIndex; i < startIndex + count; i++)
|
||||||
if (match(this[i])) return i;
|
if (match(this[i])) return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the zero-based
|
/// Searches for an <see cref="Trigger"/> that matches the conditions defined by the specified predicate, and returns the zero-based
|
||||||
/// index of the first occurrence within the collection.
|
/// index of the first occurrence within the collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the element to search for.</param>
|
/// <param name="match">The <see cref="Predicate{Trigger}"/> delegate that defines the conditions of the element to search for.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
|
/// The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public int FindIndexOf([NotNull] Predicate<Trigger> match) => FindIndexOf(0, Count, match);
|
public int FindIndexOf([NotNull] Predicate<Trigger> match) => FindIndexOf(0, Count, match);
|
||||||
|
|
||||||
/// <summary>Gets the collection enumerator for this collection.</summary>
|
/// <summary>Gets the collection enumerator for this collection.</summary>
|
||||||
/// <returns>The <see cref="IEnumerator{T}"/> for this collection.</returns>
|
/// <returns>The <see cref="IEnumerator{T}"/> for this collection.</returns>
|
||||||
public IEnumerator<Trigger> GetEnumerator()
|
public IEnumerator<Trigger> GetEnumerator()
|
||||||
{
|
{
|
||||||
if (v1Task != null)
|
if (v1Task != null)
|
||||||
return new V1TriggerEnumerator(v1Task);
|
return new V1TriggerEnumerator(v1Task);
|
||||||
return new ComEnumerator<Trigger, ITrigger>(() => v2Coll.Count, i => v2Coll[i], o => Trigger.CreateTrigger(o, v2Def));
|
return new ComEnumerator<Trigger, ITrigger>(() => v2Coll.Count, i => v2Coll[i], o => Trigger.CreateTrigger(o, v2Def));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Determines the index of a specific item in the <see cref="IList{T}"/>.</summary>
|
/// <summary>Determines the index of a specific item in the <see cref="IList{T}"/>.</summary>
|
||||||
/// <param name="item">The object to locate in the <see cref="IList{T}"/>.</param>
|
/// <param name="item">The object to locate in the <see cref="IList{T}"/>.</param>
|
||||||
/// <returns>The index of <paramref name="item"/> if found in the list; otherwise, -1.</returns>
|
/// <returns>The index of <paramref name="item"/> if found in the list; otherwise, -1.</returns>
|
||||||
public int IndexOf([NotNull] Trigger item) => FindIndexOf(a => a.Equals(item));
|
public int IndexOf([NotNull] Trigger item) => FindIndexOf(a => a.Equals(item));
|
||||||
|
|
||||||
/// <summary>Determines the index of a specific item in the <see cref="IList{T}"/>.</summary>
|
/// <summary>Determines the index of a specific item in the <see cref="IList{T}"/>.</summary>
|
||||||
/// <param name="triggerId">The id ( <see cref="Trigger.Id"/>) of the trigger to be retrieved.</param>
|
/// <param name="triggerId">The id ( <see cref="Trigger.Id"/>) of the trigger to be retrieved.</param>
|
||||||
/// <returns>The index of <paramref name="triggerId"/> if found in the list; otherwise, -1.</returns>
|
/// <returns>The index of <paramref name="triggerId"/> if found in the list; otherwise, -1.</returns>
|
||||||
public int IndexOf([NotNull] string triggerId)
|
public int IndexOf([NotNull] string triggerId)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(triggerId))
|
if (string.IsNullOrEmpty(triggerId))
|
||||||
throw new ArgumentNullException(triggerId);
|
throw new ArgumentNullException(triggerId);
|
||||||
return FindIndexOf(a => string.Equals(a.Id, triggerId));
|
return FindIndexOf(a => string.Equals(a.Id, triggerId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Inserts an trigger at the specified index.</summary>
|
/// <summary>Inserts an trigger at the specified index.</summary>
|
||||||
/// <param name="index">The zero-based index at which trigger should be inserted.</param>
|
/// <param name="index">The zero-based index at which trigger should be inserted.</param>
|
||||||
/// <param name="trigger">The trigger to insert into the list.</param>
|
/// <param name="trigger">The trigger to insert into the list.</param>
|
||||||
public void Insert(int index, [NotNull] Trigger trigger)
|
public void Insert(int index, [NotNull] Trigger trigger)
|
||||||
{
|
{
|
||||||
if (trigger == null)
|
if (trigger == null)
|
||||||
throw new ArgumentNullException(nameof(trigger));
|
throw new ArgumentNullException(nameof(trigger));
|
||||||
if (index >= Count)
|
if (index >= Count)
|
||||||
throw new ArgumentOutOfRangeException(nameof(index));
|
throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
|
||||||
var pushItems = new Trigger[Count - index];
|
var pushItems = new Trigger[Count - index];
|
||||||
CopyTo(index, pushItems, 0, Count - index);
|
CopyTo(index, pushItems, 0, Count - index);
|
||||||
for (var j = Count - 1; j >= index; j--)
|
for (var j = Count - 1; j >= index; j--)
|
||||||
RemoveAt(j);
|
RemoveAt(j);
|
||||||
Add(trigger);
|
Add(trigger);
|
||||||
foreach (var t in pushItems)
|
foreach (var t in pushItems)
|
||||||
Add(t);
|
Add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.</summary>
|
/// <summary>Removes the first occurrence of a specific object from the <see cref="ICollection{T}"/>.</summary>
|
||||||
/// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
|
/// <param name="item">The object to remove from the <see cref="ICollection{T}"/>.</param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method
|
/// true if <paramref name="item"/> was successfully removed from the <see cref="ICollection{T}"/>; otherwise, false. This method
|
||||||
/// also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.
|
/// also returns false if <paramref name="item"/> is not found in the original <see cref="ICollection{T}"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public bool Remove([NotNull] Trigger item)
|
public bool Remove([NotNull] Trigger item)
|
||||||
{
|
{
|
||||||
var idx = IndexOf(item);
|
var idx = IndexOf(item);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RemoveAt(idx);
|
RemoveAt(idx);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Removes the trigger at a specified index.</summary>
|
/// <summary>Removes the trigger at a specified index.</summary>
|
||||||
/// <param name="index">Index of trigger to remove.</param>
|
/// <param name="index">Index of trigger to remove.</param>
|
||||||
/// <exception cref="ArgumentOutOfRangeException">Index out of range.</exception>
|
/// <exception cref="ArgumentOutOfRangeException">Index out of range.</exception>
|
||||||
public void RemoveAt(int index)
|
public void RemoveAt(int index)
|
||||||
{
|
{
|
||||||
if (index < 0 || index >= Count)
|
if (index < 0 || index >= Count)
|
||||||
throw new ArgumentOutOfRangeException(nameof(index), index, @"Failed to remove Trigger. Index out of range.");
|
throw new ArgumentOutOfRangeException(nameof(index), index, @"Failed to remove Trigger. Index out of range.");
|
||||||
var item = this[index].Clone();
|
var item = this[index].Clone();
|
||||||
if (v2Coll != null)
|
if (v2Coll != null)
|
||||||
v2Coll.Remove(++index);
|
v2Coll.Remove(++index);
|
||||||
else
|
else
|
||||||
v1Task.DeleteTrigger((ushort)index); //Remove the trigger from the Task Scheduler
|
v1Task.DeleteTrigger((ushort)index); //Remove the trigger from the Task Scheduler
|
||||||
if (!inV2set)
|
if (!inV2set)
|
||||||
{
|
{
|
||||||
OnNotifyPropertyChanged(nameof(Count));
|
OnNotifyPropertyChanged(nameof(Count));
|
||||||
OnNotifyPropertyChanged(IndexerName);
|
OnNotifyPropertyChanged(IndexerName);
|
||||||
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
|
CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Copies the elements of the <see cref="TriggerCollection"/> to a new array.</summary>
|
/// <summary>Copies the elements of the <see cref="TriggerCollection"/> to a new array.</summary>
|
||||||
/// <returns>An array containing copies of the elements of the <see cref="TriggerCollection"/>.</returns>
|
/// <returns>An array containing copies of the elements of the <see cref="TriggerCollection"/>.</returns>
|
||||||
public Trigger[] ToArray()
|
public Trigger[] ToArray()
|
||||||
{
|
{
|
||||||
var ret = new Trigger[Count];
|
var ret = new Trigger[Count];
|
||||||
CopyTo(ret, 0);
|
CopyTo(ret, 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Returns a <see cref="string"/> that represents the triggers in this collection.</summary>
|
/// <summary>Returns a <see cref="string"/> that represents the triggers in this collection.</summary>
|
||||||
/// <returns>A <see cref="string"/> that represents the triggers in this collection.</returns>
|
/// <returns>A <see cref="string"/> that represents the triggers in this collection.</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
if (Count == 1)
|
if (Count == 1)
|
||||||
return this[0].ToString();
|
return this[0].ToString();
|
||||||
if (Count > 1)
|
if (Count > 1)
|
||||||
return Properties.Resources.MultipleTriggers;
|
return Properties.Resources.MultipleTriggers;
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ICollection<Trigger>.Add(Trigger item) => Add(item);
|
void ICollection<Trigger>.Add(Trigger item) => Add(item);
|
||||||
|
|
||||||
int IList.Add(object value)
|
int IList.Add(object value)
|
||||||
{
|
{
|
||||||
Add((Trigger)value);
|
Add((Trigger)value);
|
||||||
return Count - 1;
|
return Count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IList.Contains(object value) => Contains((Trigger)value);
|
bool IList.Contains(object value) => Contains((Trigger)value);
|
||||||
|
|
||||||
void ICollection.CopyTo(Array array, int index)
|
void ICollection.CopyTo(Array array, int index)
|
||||||
{
|
{
|
||||||
if (array != null && array.Rank != 1)
|
if (array != null && array.Rank != 1)
|
||||||
throw new RankException("Multi-dimensional arrays are not supported.");
|
throw new RankException("Multi-dimensional arrays are not supported.");
|
||||||
var src = new Trigger[Count];
|
var src = new Trigger[Count];
|
||||||
CopyTo(src, 0);
|
CopyTo(src, 0);
|
||||||
Array.Copy(src, 0, array, index, Count);
|
Array.Copy(src, 0, array, index, Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() => null;
|
System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema() => null;
|
||||||
|
|
||||||
int IList.IndexOf(object value) => IndexOf((Trigger)value);
|
int IList.IndexOf(object value) => IndexOf((Trigger)value);
|
||||||
|
|
||||||
void IList.Insert(int index, object value) => Insert(index, (Trigger)value);
|
void IList.Insert(int index, object value) => Insert(index, (Trigger)value);
|
||||||
|
|
||||||
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
|
void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
|
||||||
{
|
{
|
||||||
reader.ReadStartElement(XmlSerializationHelper.GetElementName(this), TaskDefinition.tns);
|
reader.ReadStartElement(XmlSerializationHelper.GetElementName(this), TaskDefinition.tns);
|
||||||
while (reader.MoveToContent() == System.Xml.XmlNodeType.Element)
|
while (reader.MoveToContent() == System.Xml.XmlNodeType.Element)
|
||||||
{
|
{
|
||||||
switch (reader.LocalName)
|
switch (reader.LocalName)
|
||||||
{
|
{
|
||||||
case "BootTrigger":
|
case "BootTrigger":
|
||||||
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Boot));
|
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Boot));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "IdleTrigger":
|
case "IdleTrigger":
|
||||||
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Idle));
|
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Idle));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "TimeTrigger":
|
case "TimeTrigger":
|
||||||
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Time));
|
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Time));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "LogonTrigger":
|
case "LogonTrigger":
|
||||||
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Logon));
|
XmlSerializationHelper.ReadObject(reader, AddNew(TaskTriggerType.Logon));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "CalendarTrigger":
|
case "CalendarTrigger":
|
||||||
Add(CalendarTrigger.GetTriggerFromXml(reader));
|
Add(CalendarTrigger.GetTriggerFromXml(reader));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
reader.Skip();
|
reader.Skip();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.ReadEndElement();
|
reader.ReadEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IList.Remove(object value) => Remove((Trigger)value);
|
void IList.Remove(object value) => Remove((Trigger)value);
|
||||||
|
|
||||||
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
|
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
|
||||||
{
|
{
|
||||||
foreach (var t in this)
|
foreach (var t in this)
|
||||||
XmlSerializationHelper.WriteObject(writer, t);
|
XmlSerializationHelper.WriteObject(writer, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Bind()
|
internal void Bind()
|
||||||
{
|
{
|
||||||
foreach (var t in this)
|
foreach (var t in this)
|
||||||
t.SetV1TriggerData();
|
t.SetV1TriggerData();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Called when a property has changed to notify any attached elements.</summary>
|
/// <summary>Called when a property has changed to notify any attached elements.</summary>
|
||||||
/// <param name="propertyName">Name of the property.</param>
|
/// <param name="propertyName">Name of the property.</param>
|
||||||
private void OnNotifyPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
private void OnNotifyPropertyChanged([CallerMemberName] string propertyName = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
|
||||||
private sealed class V1TriggerEnumerator : IEnumerator<Trigger>
|
private sealed class V1TriggerEnumerator : IEnumerator<Trigger>
|
||||||
{
|
{
|
||||||
private short curItem = -1;
|
private short curItem = -1;
|
||||||
private ITask iTask;
|
private ITask iTask;
|
||||||
|
|
||||||
internal V1TriggerEnumerator(ITask task) => iTask = task;
|
internal V1TriggerEnumerator(ITask task) => iTask = task;
|
||||||
|
|
||||||
public Trigger Current => Trigger.CreateTrigger(iTask.GetTrigger((ushort)curItem));
|
public Trigger Current => Trigger.CreateTrigger(iTask.GetTrigger((ushort)curItem));
|
||||||
|
|
||||||
object IEnumerator.Current => Current;
|
object IEnumerator.Current => Current;
|
||||||
|
|
||||||
/// <summary>Releases all resources used by this class.</summary>
|
/// <summary>Releases all resources used by this class.</summary>
|
||||||
public void Dispose() => iTask = null;
|
public void Dispose() => iTask = null;
|
||||||
|
|
||||||
public bool MoveNext() => (++curItem < iTask.GetTriggerCount());
|
public bool MoveNext() => (++curItem < iTask.GetTriggerCount());
|
||||||
|
|
||||||
public void Reset() => curItem = -1;
|
public void Reset() => curItem = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,151 +1,147 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using winPEAS.TaskScheduler.TaskEditor.Native;
|
using winPEAS.TaskScheduler.TaskEditor.Native;
|
||||||
|
|
||||||
namespace winPEAS.TaskScheduler
|
namespace winPEAS.TaskScheduler
|
||||||
{
|
{
|
||||||
/// <summary>Represents a system account.</summary>
|
/// <summary>Represents a system account.</summary>
|
||||||
internal class User : IEquatable<User>, IDisposable
|
internal class User : IEquatable<User>, IDisposable
|
||||||
{
|
{
|
||||||
private static readonly WindowsIdentity cur = WindowsIdentity.GetCurrent();
|
private static readonly WindowsIdentity cur = WindowsIdentity.GetCurrent();
|
||||||
private SecurityIdentifier sid;
|
private SecurityIdentifier sid;
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="User"/> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="User"/> class.</summary>
|
||||||
/// <param name="userName">
|
/// <param name="userName">
|
||||||
/// Name of the user. This can be in the format <c>DOMAIN\username</c> or <c>username@domain.com</c> or <c>username</c> or
|
/// Name of the user. This can be in the format <c>DOMAIN\username</c> or <c>username@domain.com</c> or <c>username</c> or
|
||||||
/// <c>null</c> (for current user).
|
/// <c>null</c> (for current user).
|
||||||
/// </param>
|
/// </param>
|
||||||
public User(string userName = null)
|
public User(string userName = null)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(userName)) userName = null;
|
if (string.IsNullOrEmpty(userName)) userName = null;
|
||||||
// 2018-03-02: Hopefully not a breaking change, but by adding in the comparison of an account name without a domain and the
|
// 2018-03-02: Hopefully not a breaking change, but by adding in the comparison of an account name without a domain and the
|
||||||
// current user, there is a chance that current implementations will break given the condition that a local account with the same
|
// current user, there is a chance that current implementations will break given the condition that a local account with the same
|
||||||
// name as a domain account exists and the intention was to prefer the local account. In such a case, the developer should
|
// name as a domain account exists and the intention was to prefer the local account. In such a case, the developer should
|
||||||
// prepend the user name in TaskDefinition.Principal.UserId with the machine name of the local machine.
|
// prepend the user name in TaskDefinition.Principal.UserId with the machine name of the local machine.
|
||||||
if (userName == null || cur.Name.Equals(userName, StringComparison.InvariantCultureIgnoreCase) || GetUser(cur.Name).Equals(userName, StringComparison.InvariantCultureIgnoreCase))
|
if (userName == null || cur.Name.Equals(userName, StringComparison.InvariantCultureIgnoreCase) || GetUser(cur.Name).Equals(userName, StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
Identity = cur;
|
Identity = cur;
|
||||||
sid = Identity.User;
|
sid = Identity.User;
|
||||||
}
|
}
|
||||||
else if (userName.Contains("\\") && !userName.StartsWith(@"NT AUTHORITY\"))
|
else if (userName.Contains("\\") && !userName.StartsWith(@"NT AUTHORITY\"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (var ds = new NativeMethods.DomainService())
|
using (var ds = new NativeMethods.DomainService())
|
||||||
{
|
{
|
||||||
Identity = new WindowsIdentity(ds.CrackName(userName));
|
Identity = new WindowsIdentity(ds.CrackName(userName));
|
||||||
sid = Identity.User;
|
sid = Identity.User;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Identity == null)
|
if (Identity == null)
|
||||||
{
|
{
|
||||||
if (userName != null && userName.Contains("@"))
|
if (userName != null && userName.Contains("@"))
|
||||||
{
|
{
|
||||||
Identity = new WindowsIdentity(userName);
|
Identity = new WindowsIdentity(userName);
|
||||||
sid = Identity.User;
|
sid = Identity.User;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Identity == null && userName != null)
|
if (Identity == null && userName != null)
|
||||||
{
|
{
|
||||||
var ntacct = new NTAccount(userName);
|
var ntacct = new NTAccount(userName);
|
||||||
try { sid = (SecurityIdentifier)ntacct.Translate(typeof(SecurityIdentifier)); } catch { }
|
try { sid = (SecurityIdentifier)ntacct.Translate(typeof(SecurityIdentifier)); } catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string GetUser(string domUser)
|
string GetUser(string domUser)
|
||||||
{
|
{
|
||||||
var split = domUser.Split('\\');
|
var split = domUser.Split('\\');
|
||||||
return split.Length == 2 ? split[1] : domUser;
|
return split.Length == 2 ? split[1] : domUser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Initializes a new instance of the <see cref="User"/> class.</summary>
|
/// <summary>Initializes a new instance of the <see cref="User"/> class.</summary>
|
||||||
/// <param name="wid">The <see cref="WindowsIdentity"/>.</param>
|
/// <param name="wid">The <see cref="WindowsIdentity"/>.</param>
|
||||||
internal User(WindowsIdentity wid) { Identity = wid; sid = wid.User; }
|
internal User(WindowsIdentity wid) { Identity = wid; sid = wid.User; }
|
||||||
|
|
||||||
/// <summary>Gets the current user.</summary>
|
/// <summary>Gets the current user.</summary>
|
||||||
/// <value>The current user.</value>
|
/// <value>The current user.</value>
|
||||||
public static User Current => new User(cur);
|
public static User Current => new User(cur);
|
||||||
|
|
||||||
/// <summary>Gets the identity.</summary>
|
/// <summary>Gets the identity.</summary>
|
||||||
/// <value>The identity.</value>
|
/// <value>The identity.</value>
|
||||||
public WindowsIdentity Identity { get; private set; }
|
public WindowsIdentity Identity { get; private set; }
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether this instance is in an administrator role.</summary>
|
/// <summary>Gets a value indicating whether this instance is in an administrator role.</summary>
|
||||||
/// <value><c>true</c> if this instance is an admin; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance is an admin; otherwise, <c>false</c>.</value>
|
||||||
public bool IsAdmin => Identity != null ? new WindowsPrincipal(Identity).IsInRole(WindowsBuiltInRole.Administrator) : false;
|
public bool IsAdmin => Identity != null ? new WindowsPrincipal(Identity).IsInRole(WindowsBuiltInRole.Administrator) : false;
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether this instance is the interactive user.</summary>
|
/// <summary>Gets a value indicating whether this instance is the interactive user.</summary>
|
||||||
/// <value><c>true</c> if this instance is the current user; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance is the current user; otherwise, <c>false</c>.</value>
|
||||||
public bool IsCurrent => Identity?.User.Equals(cur.User) ?? false;
|
public bool IsCurrent => Identity?.User.Equals(cur.User) ?? false;
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether this instance is a service account.</summary>
|
/// <summary>Gets a value indicating whether this instance is a service account.</summary>
|
||||||
/// <value><c>true</c> if this instance is a service account; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance is a service account; otherwise, <c>false</c>.</value>
|
||||||
public bool IsServiceAccount
|
public bool IsServiceAccount
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return (sid != null && (sid.IsWellKnown(WellKnownSidType.LocalSystemSid) || sid.IsWellKnown(WellKnownSidType.NetworkServiceSid) || sid.IsWellKnown(WellKnownSidType.LocalServiceSid)));
|
return (sid != null && (sid.IsWellKnown(WellKnownSidType.LocalSystemSid) || sid.IsWellKnown(WellKnownSidType.NetworkServiceSid) || sid.IsWellKnown(WellKnownSidType.LocalServiceSid)));
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Gets a value indicating whether this instance is the SYSTEM account.</summary>
|
/// <summary>Gets a value indicating whether this instance is the SYSTEM account.</summary>
|
||||||
/// <value><c>true</c> if this instance is the SYSTEM account; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance is the SYSTEM account; otherwise, <c>false</c>.</value>
|
||||||
public bool IsSystem => sid != null && sid.IsWellKnown(WellKnownSidType.LocalSystemSid);
|
public bool IsSystem => sid != null && sid.IsWellKnown(WellKnownSidType.LocalSystemSid);
|
||||||
|
|
||||||
/// <summary>Gets the SID string.</summary>
|
/// <summary>Gets the SID string.</summary>
|
||||||
/// <value>The SID string.</value>
|
/// <value>The SID string.</value>
|
||||||
public string SidString => sid?.ToString();
|
public string SidString => sid?.ToString();
|
||||||
|
|
||||||
/// <summary>Gets the NT name (DOMAIN\username).</summary>
|
/// <summary>Gets the NT name (DOMAIN\username).</summary>
|
||||||
/// <value>The name of the user.</value>
|
/// <value>The name of the user.</value>
|
||||||
public string Name => Identity?.Name ?? ((NTAccount)sid?.Translate(typeof(NTAccount)))?.Value;
|
public string Name => Identity?.Name ?? ((NTAccount)sid?.Translate(typeof(NTAccount)))?.Value;
|
||||||
|
|
||||||
/// <summary>Create a <see cref="User"/> instance from a SID string.</summary>
|
/// <summary>Create a <see cref="User"/> instance from a SID string.</summary>
|
||||||
/// <param name="sid">The SID string.</param>
|
/// <param name="sid">The SID string.</param>
|
||||||
/// <returns>A <see cref="User"/> instance.</returns>
|
/// <returns>A <see cref="User"/> instance.</returns>
|
||||||
public static User FromSidString(string sid) => new User(((NTAccount)new SecurityIdentifier(sid).Translate(typeof(NTAccount))).Value);
|
public static User FromSidString(string sid) => new User(((NTAccount)new SecurityIdentifier(sid).Translate(typeof(NTAccount))).Value);
|
||||||
|
|
||||||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||||
public void Dispose() => Identity?.Dispose();
|
public void Dispose() => Identity?.Dispose();
|
||||||
|
|
||||||
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
|
/// <summary>Determines whether the specified <see cref="System.Object"/>, is equal to this instance.</summary>
|
||||||
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
|
/// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
|
||||||
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
/// <returns><c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.</returns>
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
if (obj is User user)
|
if (obj is User user)
|
||||||
return Equals(user);
|
return Equals(user);
|
||||||
if (obj is WindowsIdentity wid && sid != null)
|
if (obj is WindowsIdentity wid && sid != null)
|
||||||
return sid.Equals(wid.User);
|
return sid.Equals(wid.User);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (obj is string un)
|
if (obj is string un)
|
||||||
return Equals(new User(un));
|
return Equals(new User(un));
|
||||||
}
|
}
|
||||||
catch { }
|
catch { }
|
||||||
return base.Equals(obj);
|
return base.Equals(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
|
/// <summary>Indicates whether the current object is equal to another object of the same type.</summary>
|
||||||
/// <param name="other">An object to compare with this object.</param>
|
/// <param name="other">An object to compare with this object.</param>
|
||||||
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
|
/// <returns>true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.</returns>
|
||||||
public bool Equals(User other) => (other != null && sid != null) ? sid.Equals(other.sid) : false;
|
public bool Equals(User other) => (other != null && sid != null) ? sid.Equals(other.sid) : false;
|
||||||
|
|
||||||
/// <summary>Returns a hash code for this instance.</summary>
|
/// <summary>Returns a hash code for this instance.</summary>
|
||||||
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
|
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
|
||||||
public override int GetHashCode() => sid?.GetHashCode() ?? 0;
|
public override int GetHashCode() => sid?.GetHashCode() ?? 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user