Files
cyberark-PipeViewer/PipeViewer/Form1.cs
T
2023-03-05 16:44:43 +02:00

1067 lines
42 KiB
C#

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;
using PipeViewer.Control;
using NtApiDotNet;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;
using System.DirectoryServices.AccountManagement;
namespace PipeViewer
{
public partial class Form1 : Form
{
private int m_NamedPipesNumber;
private ListView m_LastListViewColumnFilter = new ListView();
private ListView m_LastListViewHighlighFilter = new ListView();
private const int SW_SHOW = 5;
private const uint SEE_MASK_INVOKEIDLIST = 12;
private string m_LastSearchValue;
private bool m_IsGridButtonPressed = false;
private static Dictionary<string, int> m_ColumnIndexes = new Dictionary<string, int>();
private static Dictionary<int, string> m_ProcessPIDsDictionary = new Dictionary<int, string>();
int m_CurrentRowIndexRightClick, m_CurrentColumnIndexRightClick;
private IDictionary<string, List<ListViewItem>> m_IncludeFilterDict = new Dictionary<string, List<ListViewItem>>();
private IDictionary<string, List<ListViewItem>> m_ExcludeFilterDict = new Dictionary<string, List<ListViewItem>>();
private IDictionary<string, List<ListViewItem>> m_IncludeHighlightDict = new Dictionary<string, List<ListViewItem>>();
private IDictionary<string, List<ListViewItem>> m_ExcludeHighlightDict = new Dictionary<string, List<ListViewItem>>();
private string m_CurrentUserSid;
private WindowsIdentity m_CurrentIdentity;
private bool m_showPermissionColor = true;
private IDictionary<string, string> m_SidDict = new Dictionary<string, string>();
// https://stackoverflow.com/questions/1936682/how-do-i-display-a-files-properties-dialog-from-c
// https://stackoverflow.com/a/32503655/2153777
// https://stackoverflow.com/a/28297300/2153777
[DllImport("shell32.dll", CharSet = CharSet.Auto)]
static extern bool ShellExecuteEx(ref SHELLEXECUTEINFO lpExecInfo);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SHELLEXECUTEINFO
{
public int cbSize;
public uint fMask;
public IntPtr hwnd;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpVerb;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpParameters;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpDirectory;
public int nShow;
public IntPtr hInstApp;
public IntPtr lpIDList;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpClass;
public IntPtr hkeyClass;
public uint dwHotKey;
public IntPtr hIcon;
public IntPtr hProcess;
}
public static bool ShowFileProperties(string Filename)
{
SHELLEXECUTEINFO info = new SHELLEXECUTEINFO();
info.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(info);
info.lpVerb = "properties";
info.lpFile = Filename;
info.nShow = SW_SHOW;
info.fMask = SEE_MASK_INVOKEIDLIST;
info.lpParameters = "Security";
return ShellExecuteEx(ref info);
}
public Form1()
{
InitializeComponent();
InitalizeColumnsHeaderDictionary();
m_CurrentIdentity = WindowsIdentity.GetCurrent();
m_CurrentUserSid = m_CurrentIdentity.User.ToString();
typeof(DataGridView).InvokeMember(
"DoubleBuffered",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.SetProperty,
null,
dataGridView1,
new object[] { true });
//Task.Run(() => Utils.CreateDummyPipeForTesting());
//dummRowsForDebug();
//dummyLoopRowsForDebug();
//Task.Run(() => dummyLoopRowsForDebug());
Task.Run(() => InitializePipeListWithProcesses());
//Thread t = new Thread(new ThreadStart(InitializePipeListWithProcesses));
//t.Start();
}
//private delegate void InitializePipeListWithProcessesCallBack();
//private void InitializePipeListWithProcesses()
//{
// if (this.InvokeRequired)
// {
// InitializePipeListWithProcessesCallBack s = new InitializePipeListWithProcessesCallBack(InitializePipeListWithProcesses);
// this.Invoke(s);
// }
// else
// {
// Process[] processCollection = Process.GetProcesses();
// foreach (Process p in processCollection)
// {
// m_ProcessPIDsDictionary.Add(p.Id, p.ProcessName);
// }
// initializePipeList();
// }
//}
private void InitializePipeListWithProcesses()
{
Process[] processCollection = Process.GetProcesses();
foreach (Process p in processCollection)
{
m_ProcessPIDsDictionary.Add(p.Id, p.ProcessName);
}
initializePipeList();
}
private delegate void addNamedPipeToDataGridViewCallBack(string i_NamedPipe);
private void InitalizeColumnsHeaderDictionary()
{
// Populate the dictionary with the column header text and its index
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
m_ColumnIndexes[dataGridView1.Columns[i].HeaderText] = i;
}
}
private void initializePipeList()
{
int numOfPipe = 0;
String[] listOfPipes = System.IO.Directory.GetFiles(@"\\.\pipe\");
foreach (var namedPipe in listOfPipes)
{
addNamedPipeToDataGridView(namedPipe);
highlightPermittedPipes(namedPipe, numOfPipe);
numOfPipe++;
}
}
private void highlightPermittedPipes(string namdePipe, int numOfPipe)
{
Color color = Color.White;
try
{
PipeSecurity pipeSecurity = new PipeSecurity();
pipeSecurity.AddAccessRule(new PipeAccessRule("Everyone", PipeAccessRights.ReadWrite, AccessControlType.Allow));
using (NamedPipeServerStream server = new NamedPipeServerStream(namdePipe, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 0, 0, pipeSecurity))
{
Console.WriteLine("Access control entries:");
foreach (PipeAccessRule rule in pipeSecurity.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
{
Console.WriteLine("User/Group: {0}", rule.IdentityReference);
Console.WriteLine("Access: {0}", rule.AccessControlType);
Console.WriteLine("Rights: {0}", rule.PipeAccessRights);
Console.WriteLine();
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error: {0}", ex.Message);
}
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
List<string> groups = new List<string>();
foreach (IdentityReference group in currentUser.Groups)
{
try
{
SecurityIdentifier sid = group.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
NTAccount account = (NTAccount)sid.Translate(typeof(NTAccount));
groups.Add(account.Value);
}
catch { }
}
dataGridView1.Rows[numOfPipe].DefaultCellStyle.BackColor = color;
}
//private delegate void initializePipeListCallBack();
//private void initializePipeList()
//{
// if (this.InvokeRequired)
// {
// initializePipeListCallBack s = new initializePipeListCallBack(initializePipeList);
// this.Invoke(s);
// }else
// {
// String[] listOfPipes = System.IO.Directory.GetFiles(@"\\.\pipe\");
// foreach (var namedPipe in listOfPipes)
// {
// addNamedPipeToDataGridView(namedPipe);
// }
// }
//}
// https://blog.cjwdev.co.uk/2011/06/28/permissions-not-included-in-net-accessrule-filesystemrights-enum/
private void addNamedPipeToDataGridView(string i_NamedPipe)
{
// i_NamedPipe = @"\\.\pipe\myPipe";
string permissions;
if (this.InvokeRequired)
{
addNamedPipeToDataGridViewCallBack s = new addNamedPipeToDataGridViewCallBack(addNamedPipeToDataGridView);
this.Invoke(s, i_NamedPipe);
}
else
{
DataGridViewRow row = new DataGridViewRow();
row.CreateCells(dataGridView1);
row.Cells[m_ColumnIndexes[ColumnName.HeaderText]].Value = i_NamedPipe;
row.DefaultCellStyle.Font = new Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Regular);
NtNamedPipeFileBase namedPipeObject = Engine.GetNamedPipeObject(i_NamedPipe, Engine.NamedPipeFunctionEndType.Client);
if (namedPipeObject == null)
{
namedPipeObject = Engine.GetNamedPipeObject(i_NamedPipe, Engine.NamedPipeFunctionEndType.Server);
}
// NtNamedPipeFileBase namedPipeObjectClient = Engine.GetNamedPipeClientObject(i_NamedPipe);
// We added a check for empty name because it caused an exception with named pipe \\.\pipe\dbxsvc which wasn't NULL
// but add partial value exist on one machine.
// We added try\catch because one specific bug with \\.\pipe\dbxsvc (DropBox). Maybe there is a better way to handle it?
try
{
if (namedPipeObject != null)
{
row.Cells[m_ColumnIndexes[ColumnSddl.HeaderText]].Value = namedPipeObject.Sddl;
Color cellColor = Color.White;
if (namedPipeObject.SecurityDescriptor.Dacl.Count != 0)
{
permissions = "";
foreach (Ace dacl in namedPipeObject.SecurityDescriptor.Dacl)
{
string permissionReadOrWrite = Engine.ConvertAccessMaskToSimplePermissions(dacl.Mask.Access);
string allowedOrNotAllowed = dacl.Type.ToString();
// TODO: why adding to a new group doesn't show the new group
foreach (IdentityReference group in m_CurrentIdentity.Groups)
{
SecurityIdentifier sid = (SecurityIdentifier)group.Translate(typeof(SecurityIdentifier));
if ((m_CurrentUserSid.Equals(dacl.Sid.ToString()) || sid.Value.Equals(dacl.Sid.ToString())) && allowedOrNotAllowed.Contains("Allowed"))
{
if (!m_SidDict.ContainsKey(dacl.Sid.Name))
{
m_SidDict.Add(dacl.Sid.Name, dacl.Sid.ToString());
}
if (permissionReadOrWrite.Contains("R"))
{
cellColor = Color.Yellow;
}
if (permissionReadOrWrite.Contains("W") || permissionReadOrWrite.Contains("Full") || permissionReadOrWrite.Contains("RW"))
{
cellColor = Color.LightGreen;
break;
}
}
}
row.Cells[m_ColumnIndexes[ColumnPermissions.HeaderText]].Style.BackColor = cellColor;
permissions += allowedOrNotAllowed + " ";
permissions += permissionReadOrWrite;
permissions += " " + dacl.Sid.Name + "; \n";
}
row.Cells[m_ColumnIndexes[ColumnPermissions.HeaderText]].Value = permissions;
} else
{
row.Cells[m_ColumnIndexes[ColumnPermissions.HeaderText]].Value = "NO DACL -> FULL permissions";
//row.Cells[m_ColumnIndexes[ColumnPermissions.HeaderText]].Style.Font = new Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Bold);
row.Cells[m_ColumnIndexes[ColumnPermissions.HeaderText]].Style.BackColor = Color.Red;
}
row.Cells[m_ColumnIndexes[ColumnOwnerSid.HeaderText]].Value = namedPipeObject.SecurityDescriptor.Owner.Sid.ToString();
row.Cells[m_ColumnIndexes[ColumnOwnerName.HeaderText]].Value = namedPipeObject.SecurityDescriptor.Owner.Sid.Name;
row.Cells[m_ColumnIndexes[ColumnGroupSid.HeaderText]].Value = namedPipeObject.SecurityDescriptor.Group.Sid.ToString();
row.Cells[m_ColumnIndexes[ColumnGroupName.HeaderText]].Value = namedPipeObject.SecurityDescriptor.Group.Sid.Name;
row.Cells[m_ColumnIndexes[ColumnIntegrityLevel.HeaderText]].Value = namedPipeObject.SecurityDescriptor.IntegrityLevel;
row.Cells[m_ColumnIndexes[ColumnEndPointType.HeaderText]].Value = namedPipeObject.EndPointType;
row.Cells[m_ColumnIndexes[ColumnConfiguration.HeaderText]].Value = namedPipeObject.Configuration;
row.Cells[m_ColumnIndexes[ColumnPipeType.HeaderText]].Value = namedPipeObject.PipeType;
row.Cells[m_ColumnIndexes[ColumnReadMode.HeaderText]].Value = namedPipeObject.ReadMode;
row.Cells[m_ColumnIndexes[ColumnDirectoryGrantedAccess.HeaderText]].Value = namedPipeObject.DirectoryGrantedAccess;
row.Cells[m_ColumnIndexes[ColumnGrantedAccess.HeaderText]].Value = namedPipeObject.GrantedAccess;
row.Cells[m_ColumnIndexes[ColumnGrantedAccessGeneric.HeaderText]].Value = namedPipeObject.GrantedAccessGeneric;
row.Cells[m_ColumnIndexes[ColumnHandle.HeaderText]].Value = namedPipeObject.Handle.ToString();
row.Cells[m_ColumnIndexes[ColumnCreationTime.HeaderText]].Value = namedPipeObject.CreationTime;
row.Cells[m_ColumnIndexes[ColumnClientPID.HeaderText]].Value = getProcessNameWithProcessPIDs(namedPipeObject);
row.Cells[m_ColumnIndexes[ColumnNumberOfLinks.HeaderText]].Value = namedPipeObject.NumberOfLinks;
row.Cells[m_ColumnIndexes[ColumnFileCreationTime.HeaderText]].Value = namedPipeObject.FileCreationTime;
row.Cells[m_ColumnIndexes[ColumnLastAccessTime.HeaderText]].Value = namedPipeObject.LastAccessTime;
row.Cells[m_ColumnIndexes[ColumnLastWriteTime.HeaderText]].Value = namedPipeObject.LastWriteTime;
row.Cells[m_ColumnIndexes[ColumnChangeTime.HeaderText]].Value = namedPipeObject.ChangeTime;
}
}
catch (Exception)
{
// TODO: write to log
}
dataGridView1.Rows.Add(row);
this.m_NamedPipesNumber += 1;
this.toolStripStatusLabelTotalNamedPipes.Text = "Total Named Pipes: " + this.m_NamedPipesNumber;
}
}
private string getProcessNameWithProcessPIDs(NtNamedPipeFileBase i_NamedPipe)
{
var processNames = i_NamedPipe.GetUsingProcessIds()
.Select(pid =>
{
if (m_ProcessPIDsDictionary.TryGetValue(pid, out string processName))
{
return processName + " (" + pid.ToString() + ")";
}
else
{
try
{
using (var p = Process.GetProcessById(pid))
{
m_ProcessPIDsDictionary.Add(p.Id, p.ProcessName);
return p.ProcessName + " (" + pid.ToString() + ")";
}
}
catch
{
m_ProcessPIDsDictionary.Add(pid, "<no_process>");
return "<no_process>" + "(" + pid.ToString() + ")";
}
}
});
return string.Join("; ", processNames.Select(nameAndPid => nameAndPid));
}
//private string getProcessNameWithProcessPIDs(NtNamedPipeFileBase i_NamedPipe)
//{
// string clientPids = "";
// foreach (int pid in i_NamedPipe.GetUsingProcessIds())
// {
// if (m_ProcessPIDsDictionary.ContainsKey(pid))
// {
// clientPids += m_ProcessPIDsDictionary[pid] + " (" + pid.ToString() + "); ";
// }
// else
// {
// try
// {
// using (var p = Process.GetProcessById(pid))
// {
// clientPids += p.ProcessName + " (" + pid.ToString() + "); ";
// m_ProcessPIDsDictionary.Add(p.Id, p.ProcessName);
// }
// }
// catch
// {
// clientPids += "<no_process>" + " (" + pid.ToString() + "); ";
// m_ProcessPIDsDictionary.Add(pid, "<no_process>");
// }
// }
// }
// return clientPids;
//}
// TODO: For testing right click on named pipe and display permissions
//private void button1_Click(object sender, EventArgs e)
//{
// string path = @"\\.\pipe\InitShutdown";
// //path = @"\Device\NamedPipe\InitShutdown";
// //path = @"C:\tmp";
// //ShowFileProperties(path);
// PermissionDialog.Show(IntPtr.Zero, path);
//}
private void toolStripButtonClear_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
dataGridView1.Refresh();
m_NamedPipesNumber = 0;
toolStripStatusLabelTotalNamedPipes.Text = "Total Named Pipes: 0";
}
private void toolStripButtonGrid_Click(object sender, EventArgs e)
{
if (!m_IsGridButtonPressed)
{
toolStripButtonGrid.Image = global::PipeViewer.Properties.Resources.grid;
m_IsGridButtonPressed = true;
this.dataGridView1.AdvancedCellBorderStyle.All = DataGridViewAdvancedCellBorderStyle.None;
}
else
{
toolStripButtonGrid.Image = global::PipeViewer.Properties.Resources.grid_disable;
m_IsGridButtonPressed = false;
this.dataGridView1.AdvancedCellBorderStyle.All = DataGridViewAdvancedCellBorderStyle.Single;
}
}
private void toolStripButtonFind_Click(object sender, EventArgs e)
{
openFindWindow();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
bool result = false;
if (keyData == (Keys.Control | Keys.L))
{
openColumnFilterWindow();
result = true;
}
else if (keyData == (Keys.Control | Keys.B))
{
Font boldFont = new Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Bold);
Font font = new Font(dataGridView1.DefaultCellStyle.Font, FontStyle.Regular);
foreach (DataGridViewCell cell in dataGridView1.SelectedCells)
{
if (!dataGridView1.Rows[cell.RowIndex].DefaultCellStyle.Font.Bold)
{
font = boldFont;
}
dataGridView1.Rows[cell.RowIndex].DefaultCellStyle.Font = font;
}
foreach (DataGridViewRow selectedRow in dataGridView1.SelectedRows)
{
if (!selectedRow.DefaultCellStyle.Font.Bold)
{
font = boldFont;
}
dataGridView1.Rows[selectedRow.Index].DefaultCellStyle.Font = font;
}
result = true;
}
else if (keyData == (Keys.Control | Keys.F))
{
openFindWindow();
result = true;
}
else if (keyData == (Keys.Control | Keys.H))
{
openHighlightWindows();
result = true;
}
else if (keyData == (Keys.F3))
{
// We need to implement the options for the search
FindWindow_searchForMatch(m_LastSearchValue, true, false, false);
}
else if (keyData == (Keys.Shift | Keys.F3))
{
// We need to implement the options for the search
FindWindow_searchForMatch(m_LastSearchValue, false, false, false);
}
return result;
}
private void toolStripButtonRefresh_Click(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
dataGridView1.Refresh();
m_NamedPipesNumber = 0;
Task.Run(() => initializePipeList());
}
private void openFindWindow()
{
FormSearch findWindow = new FormSearch();
findWindow.searchForMatch += new FormSearch.searchEventHandler(FindWindow_searchForMatch);
findWindow.ShowDialog();
}
private void FindWindow_searchForMatch(string i_SearchString, bool i_SearchDown, bool i_MatchWholeWord, bool i_MatchSensitive)
{
int startIndex = 0;
m_LastSearchValue = i_SearchString;
bool foundMatch = false;
int step = 1;
if (!i_SearchDown)
{
step = -1;
}
if (dataGridView1.SelectedRows != null && dataGridView1.SelectedRows.Count > 0)
{
DataGridViewRow selectedRow = dataGridView1.SelectedRows[0];
startIndex = selectedRow.Index;
}
if (dataGridView1.SelectedCells != null && dataGridView1.SelectedCells.Count > 0)
{
DataGridViewCell selectedCell = dataGridView1.SelectedCells[0];
startIndex = selectedCell.RowIndex;
}
startIndex += step;
for (int i = startIndex; i < dataGridView1.Rows.Count; i += step)
{
if (i < 0)
{
break;
}
foreach (DataGridViewCell cell in dataGridView1.Rows[i].Cells)
{
// TODO: Add support in Case Sensitive, replicate to RPCMon.
if (dataGridView1.Rows[i].Visible && cell.Value != null && cell.Value.ToString().ToLower().Contains(i_SearchString.ToLower()))
{
cleanAllSelectedCells();
dataGridView1.Rows[i].Selected = true;
foundMatch = true;
dataGridView1.CurrentCell = dataGridView1.Rows[i].Cells[0];
break;
}
}
if (foundMatch)
{
break;
}
}
if (!foundMatch)
{
MessageBox.Show(string.Format("Cannot find string \"{0}\"", i_SearchString), "PipeViewer", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
}
private void cleanAllSelectedCells()
{
for (int i = 0; i < dataGridView1.SelectedCells.Count; i++)
{
dataGridView1.SelectedCells[i].Selected = false;
}
}
private void openColumnSelectionWindow()
{
ColumnSelection columnSelection = new ColumnSelection(dataGridView1);
columnSelection.selectColumnsUpdate += new selectColumnsEventHandler(this.ColumnSelection_selectColumnsUpdate);
columnSelection.ShowDialog();
}
private void ColumnSelection_selectColumnsUpdate(GroupBox i_NamedPipe, GroupBox i_Access, GroupBox i_SecurityDescriptor, GroupBox i_TimeStamp)
{
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
modifyColumnSelection(column, i_NamedPipe);
modifyColumnSelection(column, i_Access);
modifyColumnSelection(column, i_SecurityDescriptor);
modifyColumnSelection(column, i_TimeStamp);
}
}
private void modifyColumnSelection(DataGridViewColumn i_Column, GroupBox i_GroupBox)
{
foreach (CheckBox checkBox in i_GroupBox.Controls)
{
if (checkBox.Text == i_Column.HeaderText)
{
if (checkBox.Checked)
{
dataGridView1.Columns[i_Column.Index].Visible = true;
}
else
{
dataGridView1.Columns[i_Column.Index].Visible = false;
}
}
}
}
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
openColumnSelectionWindow();
}
}
private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
// TODO: Whenimplement...
}
#region Column Filter
private void toolStripButtonFilter_Click(object sender, EventArgs e)
{
openColumnFilterWindow();
}
private void openColumnFilterWindow()
{
FormColumnFilter columnFilter = new FormColumnFilter(ref m_LastListViewColumnFilter);
columnFilter.FilterOKUpdate += new FilterOKEventHandler(ColumnFilter_OKFilter);
columnFilter.ShowDialog();
}
private void openHighlightWindows()
{
FormHighlighting hightlightWindow = new FormHighlighting(ref m_LastListViewHighlighFilter);
hightlightWindow.hightlightRowsUpdate += HightlightWindow_hightlightRowsUpdate;
hightlightWindow.ShowDialog();
}
private void HightlightWindow_hightlightRowsUpdate(ListView i_ListView)
{
m_LastListViewHighlighFilter = i_ListView;
updateFilterDicts(i_ListView, Utils.eFormNames.FormHighlighFilter);
if (m_IncludeHighlightDict.Count.Equals(0))
{
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
this.dataGridView1.Rows[row.Index].DefaultCellStyle.BackColor = Color.White;
}
return;
}
filterRowsByFilterRules(Utils.eFormNames.FormHighlighFilter);
}
private void ColumnFilter_OKFilter(ListView i_ListView)
{
m_LastListViewColumnFilter = i_ListView;
updateFilterDicts(i_ListView, Utils.eFormNames.FormColumnFilter);
if (m_IncludeFilterDict.Count.Equals(0))
{
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
row.Visible = true;
}
}
filterRowsByFilterRules(Utils.eFormNames.FormColumnFilter);
}
private void filterRowsByFilterRules(Utils.eFormNames i_FormName)
{
// TODO: What happens if one row is already Filtered\Highlight? It will hide it. Need to fix it
// so there will be OR between the rules
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
filterSingleRowByFilterRules(i_FormName, row);
}
}
private void filterSingleRowByFilterRules(Utils.eFormNames i_FormName, DataGridViewRow row)
{
if (i_FormName == Utils.eFormNames.FormColumnFilter)
{
filterRow(i_FormName, row, m_IncludeFilterDict, m_ExcludeFilterDict);
}
else
{
filterRow(i_FormName, row, m_IncludeHighlightDict, m_ExcludeHighlightDict);
}
}
private void filterRow(Utils.eFormNames i_FormName, DataGridViewRow row, IDictionary<string, List<ListViewItem>> includeDict, IDictionary<string, List<ListViewItem>> excludeDict)
{
bool visable = false;
foreach (var pair in excludeDict)
{
foreach (var rule in pair.Value)
{
if (checkIfShouldBeVisable(rule, row, pair.Key))
{
hideFilterRowBasedOnForm(i_FormName, row.Index);
return;
}
}
}
if (!excludeDict.Count.Equals(0))
{
filterRowBasedOnForm(i_FormName, row.Index, "Include");
}
foreach (var pair in includeDict)
{
foreach (var rule in pair.Value)
{
if (checkIfShouldBeVisable(rule, row, pair.Key))
{
visable = true;
break;
}
}
if (!visable)
{
hideFilterRowBasedOnForm(i_FormName, row.Index);
return;
}
visable = false;
}
if (!includeDict.Count.Equals(0))
{
filterRowBasedOnForm(i_FormName, row.Index, "Include");
}
}
private bool checkIfShouldBeVisable(ListViewItem rule, DataGridViewRow row, String key)
{
DataGridViewCell cellValueFromGridViewCell = row.Cells["Column" + rule.SubItems[0].Text];
string valueFromFilter = rule.SubItems[(int)Utils.eFilterNames.Value].Text;
if (rule.SubItems[(int)Utils.eFilterNames.Relation].Text == "contains")
{
if (row.Cells["Column" + key].Value != null && row.Cells["Column" + key].Value.ToString().Contains(rule.SubItems[(int)Utils.eFilterNames.Value].Text))
{
if (cellValueFromGridViewCell.Value.ToString().Contains(valueFromFilter))
{
return true;
}
}
}
else if (rule.SubItems[(int)Utils.eFilterNames.Relation].Text == "is")
{
if (cellValueFromGridViewCell.Value.ToString() == valueFromFilter)
{
return true;
}
}
else if (rule.SubItems[(int)Utils.eFilterNames.Relation].Text == "begins with")
{
if (cellValueFromGridViewCell.Value.ToString().StartsWith(valueFromFilter))
{
return true;
}
}
else if (rule.SubItems[(int)Utils.eFilterNames.Relation].Text == "ends with")
{
if (cellValueFromGridViewCell.Value.ToString().EndsWith(valueFromFilter))
{
return true;
}
}
return false;
}
private void updateFilterDicts(ListView i_ListView, Utils.eFormNames i_FormName)
{
if (i_FormName == Utils.eFormNames.FormColumnFilter)
{
m_IncludeFilterDict.Clear();
m_ExcludeFilterDict.Clear();
}
else
{
m_IncludeHighlightDict.Clear();
m_ExcludeHighlightDict.Clear();
}
foreach (ListViewItem rule in i_ListView.Items)
{
if (rule.Checked)
{
addItemToFilterDict(rule, rule.SubItems[(int)Utils.eFilterNames.Action].Text == "Exclude", i_FormName);
}
}
}
private void addItemToFilterDict(ListViewItem rule, bool addToExcludeList, Utils.eFormNames i_FormName)
{
if (i_FormName == Utils.eFormNames.FormColumnFilter)
{
if (addToExcludeList)
{
if (!m_ExcludeFilterDict.ContainsKey(rule.SubItems[0].Text))
{
m_ExcludeFilterDict.Add(rule.SubItems[0].Text, new List<ListViewItem>());
}
m_ExcludeFilterDict[rule.SubItems[0].Text].Add(rule);
}
else
{
if (!m_IncludeFilterDict.ContainsKey(rule.SubItems[0].Text))
{
m_IncludeFilterDict.Add(rule.SubItems[0].Text, new List<ListViewItem>());
}
m_IncludeFilterDict[rule.SubItems[0].Text].Add(rule);
}
}
else
{
if (addToExcludeList)
{
if (!m_ExcludeHighlightDict.ContainsKey(rule.SubItems[0].Text))
{
m_ExcludeHighlightDict.Add(rule.SubItems[0].Text, new List<ListViewItem>());
}
m_ExcludeHighlightDict[rule.SubItems[0].Text].Add(rule);
}
else
{
if (!m_IncludeHighlightDict.ContainsKey(rule.SubItems[0].Text))
{
m_IncludeHighlightDict.Add(rule.SubItems[0].Text, new List<ListViewItem>());
}
m_IncludeHighlightDict[rule.SubItems[0].Text].Add(rule);
}
}
}
private void filterRowBasedOnForm(Utils.eFormNames i_FormName, int i_RowIndex, string i_Action)
{
if (i_FormName == Utils.eFormNames.FormColumnFilter)
{
this.dataGridView1.Rows[i_RowIndex].Visible = (i_Action == "Include");
}
else
{
this.dataGridView1.Rows[i_RowIndex].DefaultCellStyle.BackColor = getHighlighColorIfRequired(i_Action);
}
}
private void hideFilterRowBasedOnForm(Utils.eFormNames i_FormName, int i_RowIndex)
{
if (i_FormName == Utils.eFormNames.FormColumnFilter)
{
this.dataGridView1.Rows[i_RowIndex].Visible = false;
}
else
{
this.dataGridView1.Rows[i_RowIndex].DefaultCellStyle.BackColor = Color.White;
}
}
private Color getHighlighColorIfRequired(string i_Action)
{
Color resultColor = Color.White;
if (i_Action == "Include")
{
resultColor = Color.Cyan;
}
return resultColor;
}
#endregion Column Filter
private void toolStripButtonHighLight_Click(object sender, EventArgs e)
{
openHighlightWindows();
}
private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
{
FormAbout about = new FormAbout();
about.ShowDialog();
// MessageBox.Show(@"Author: Eviatar Gerzi (@g3rzi)
//Contributers: Natan Tunik
//Version: 1.0
//Link: https://github.com/cyberark/PipeViewer
//Copyright (c) 2022 CyberArk Software Ltd. All rights reserved", "About");
}
#region Cell Mouse Click
private void dataGridView1_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{
m_CurrentRowIndexRightClick = e.RowIndex;
m_CurrentColumnIndexRightClick = e.ColumnIndex;
contextMenuStripRightClickGridView.Show(Cursor.Position.X, Cursor.Position.Y);
}
}
private void copyRowToolStripMenuItem_Click(object sender, EventArgs e)
{
string copiedRow = "";
foreach (DataGridViewCell cell in dataGridView1.Rows[m_CurrentRowIndexRightClick].Cells)
{
copiedRow += cell.Value + " ";
}
if (copiedRow != "")
{
System.Windows.Forms.Clipboard.SetText(copiedRow);
}
}
#endregion
#region Save
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Title = "Save results as CSV";
saveDialog.InitialDirectory = @"c:\";
saveDialog.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*";
saveDialog.FilterIndex = 2;
saveDialog.RestoreDirectory = true;
if (saveDialog.ShowDialog() == DialogResult.OK)
{
saveDataGridViewToCSV(saveDialog.FileName);
}
}
// Taken from https://stackoverflow.com/a/26259909/2153777
private void saveDataGridViewToCSV(string filename)
{
DataGridView tempDataGridView = dataGridView1;
foreach (DataGridViewColumn column in tempDataGridView.Columns)
{
tempDataGridView.Columns[column.Index].Visible = true;
}
// Choose whether to write header. Use EnableWithoutHeaderText instead to omit header.
tempDataGridView.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
// Select all the cells
tempDataGridView.SelectAll();
// Copy selected cells to DataObject
DataObject dataObject = tempDataGridView.GetClipboardContent();
// Get the text of the DataObject, and serialize it to a file
File.WriteAllText(filename, dataObject.GetText(TextDataFormat.CommaSeparatedValue).Replace("\n", ""));
}
private void showPermissionsByColorButton(object sender, EventArgs e)
{
if (m_showPermissionColor)
{
colorPermissionsButton.Image = global::PipeViewer.Properties.Resources.permission_disable;
m_showPermissionColor = false;
removeHighlightedPermissions();
}
else
{
colorPermissionsButton.Image = global::PipeViewer.Properties.Resources.permission;
m_showPermissionColor = true;
colorPermissions();
}
}
private void removeHighlightedPermissions()
{
var permissionColumnIndex = dataGridView1.Columns["ColumnPermissions"].Index;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.Cells[permissionColumnIndex].Style.BackColor != Color.Red)
{
row.Cells[permissionColumnIndex].Style.BackColor = Color.White;
}
}
}
private void colorPermissions()
{
var permissionColumnIndex = dataGridView1.Columns["ColumnPermissions"].Index;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
CheckIfShouldBeColored(row, permissionColumnIndex);
}
}
private void CheckIfShouldBeColored(DataGridViewRow row, int permissionColumnIndex)
{
string[] splittedStrings = null;
if (row.Cells[permissionColumnIndex].Style.BackColor != Color.Red && row.Cells[permissionColumnIndex].Value != null)
{
splittedStrings = row.Cells[permissionColumnIndex].Value.ToString().Split('\n');
}
if (splittedStrings == null)
{
return;
}
foreach (String permission in splittedStrings)
{
foreach (String permissionKey in m_SidDict.Keys)
{
if (permission.Contains(permissionKey))
{
if (permission.Contains("Allowed R"))
{
row.Cells[permissionColumnIndex].Style.BackColor = Color.Yellow;
}
if (permission.Contains("Allowed RW") || permission.Contains("Allowed Full")|| permission.Contains("Allowed W"))
{
row.Cells[permissionColumnIndex].Style.BackColor = Color.LightGreen;
return;
}
}
}
}
}
private void copyCellToolStripMenuItem_Click(object sender, EventArgs e)
{
string copiedCell = "";
if (dataGridView1.Rows[m_CurrentRowIndexRightClick] != null)
{
if (dataGridView1.Rows[m_CurrentRowIndexRightClick].Cells[m_CurrentColumnIndexRightClick].Value != null)
{
copiedCell = dataGridView1.Rows[m_CurrentRowIndexRightClick].Cells[m_CurrentColumnIndexRightClick].Value.ToString();
}
}
if (copiedCell != "")
{
System.Windows.Forms.Clipboard.SetText(copiedCell);
}
}
#endregion
}
}