Удаление осиротевших sids VB.NET
Я пытаюсь создать программу для удаления осиротевших Sid из пользовательских папок. То, что у меня есть, может перечислить осиротевшие Sid и перечислить их в списке, но не очищает их от ACL. Вот что у меня есть до сих пор:
Imports System.ComponentModel Imports System.IO Imports System.Security.AccessControl Imports System.Security.Principal Imports System.Threading Public Class Form1 Dim bw As BackgroundWorker = New BackgroundWorker Public Delegate Sub PictureVisibilityDelegate(ByVal visibility As Boolean) Dim ChangePictureVisibility As PictureVisibilityDelegate Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load AddHandler bw.DoWork, AddressOf bw_DoWork AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted ChangePictureVisibility = AddressOf ChangeVisibility TextBox1.Focus() End Sub '-----------------------------------------------Go Button Click-------------------------------------------------- Private Sub BtnGo_Click(sender As Object, e As EventArgs) Handles BtnGo.Click Me.Invoke(ChangePictureVisibility, True) Me.BtnGo.Enabled = False Me.BtnClear.Enabled = False Me.BtnExit.Enabled = True If Not bw.IsBusy = True Then bw.RunWorkerAsync() End If End Sub '-----------------------------------------------Folder Browser Selection----------------------------------------- Private Sub FoldBrowse_Click(sender As Object, e As EventArgs) Handles FoldBrowse.Click If FolderBrowserDialog1.ShowDialog() = DialogResult.OK Then Me.TextBox1.Text = FolderBrowserDialog1.SelectedPath End If End Sub Private Sub BtnClear_Click(sender As Object, e As EventArgs) Handles BtnClear.Click TextBox1.Text = "" End Sub '-----------------------------------------------Exit Button Click-------------------------------------------------- Private Sub BtnExit_Click(sender As Object, e As EventArgs) Handles BtnExit.Click If bw.IsBusy Then 'If it supports cancellation, Cancel It If bw.WorkerSupportsCancellation Then ' Tell the Background Worker to stop working. bw.CancelAsync() End If End If ' Disable Buttons Me.BtnExit.Enabled = False Me.Close() End Sub '-----------------------------------------------Background Worker-------------------------------------------------- Private Sub bw_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) CheckForIllegalCrossThreadCalls = False Dim setFolder As String = TextBox1.Text HandleDir(setFolder) End Sub '-----------------------------------------------Background Work Completed------------------------------------------ Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) ' Enable Buttons WaitStatus.Close() Me.BtnGo.Enabled = True Me.BtnClear.Enabled = True Me.Refresh() MessageBox.Show("Orphaned SID Cleaner has finished cleaning your selection.", "Orphaned SID Cleaner", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.ServiceNotification, False) End Sub '-----------------------------------------------Check if log file is in use---------------------------------------- Public Function FileInUse(ByVal sFile As String) As Boolean If System.IO.File.Exists(sFile) Then Try Dim F As Short = FreeFile() FileOpen(F, sFile, OpenMode.Binary, OpenAccess.ReadWrite, OpenShare.LockReadWrite) FileClose(F) Catch Return True End Try End If End Function '-----------------------------------------------Recursion--------------------------------------------------------- Sub HandleDir(Path As String) Dim dinfo As New DirectoryInfo(TextBox1.Text) Dim dSecurity As DirectorySecurity = dinfo.GetAccessControl(AccessControlSections.All) Try If FileInUse("c:\orphansid.txt") = True Then Thread.Sleep(2) My.Computer.FileSystem.WriteAllText("c:\orphansid.txt", "Scanning:" & Path & vbCrLf, True) Else My.Computer.FileSystem.WriteAllText("c:\orphansid.txt", "Scanning:" & Path & vbCrLf, True) Thread.Sleep(2) End If Dim security As DirectorySecurity = Directory.GetAccessControl(Path) Dim rules = security.GetAccessRules(True, False, GetType(SecurityIdentifier)) 'Tracks the SIDs to remove Dim removeList = New List(Of IdentityReference)() For Each rule In rules.OfType(Of FileSystemAccessRule)() Try Dim account = rule.IdentityReference.Translate(GetType(NTAccount)) Catch generatedExceptionName As IdentityNotMappedException 'Assume invalid so remove it If Not removeList.Any(Function(sid) sid.Value = rule.IdentityReference.Value) Then removeList.Add(rule.IdentityReference) End If End Try Next 'Remove all rules associated with the given SID For Each id In removeList 'Remove all permissions If FileInUse("c:\orphansid.txt") = True Then Thread.Sleep(2) ListBox1.Items.Add("Removed the following SID:" & id.ToString & " From " & Path & vbCrLf) My.Computer.FileSystem.WriteAllText("c:\orphansid.txt", "Removed the following SID:" & id.ToString & " From " & Path & vbCrLf, True) Else ListBox1.Items.Add("Removed the following SID:" & id.ToString & " From " & Path & vbCrLf) My.Computer.FileSystem.WriteAllText("c:\orphansid.txt", "Removed the following SID:" & id.ToString & " From " & Path & vbCrLf, True) Thread.Sleep(2) End If Dim DirACLs As New Security.AccessControl.DirectorySecurity(Path, AccessControlSections.All) DirACLs.PurgeAccessRules(id) 'dSecurity.PurgeAccessRules(id) dinfo.SetAccessControl(dSecurity) Next For Each subdir As String In System.IO.Directory.GetDirectories(Path) HandleDir(subdir) Next subdir Catch ex As System.Exception End Try End Sub Public Sub ChangeVisibility(ByVal visibility As Boolean) WaitStatus.Show() End Sub End Class
Часть, которая не очищает SID, - это:
'Remove all rules associated with the given SID For Each id In removeList 'Remove all permissions If FileInUse("c:\orphansid.txt") = True Then Thread.Sleep(2) ListBox1.Items.Add("Removed the following SID:" & id.ToString & " From " & Path & vbCrLf) My.Computer.FileSystem.WriteAllText("c:\orphansid.txt", "Removed the following SID:" & id.ToString & " From " & Path & vbCrLf, True) Else ListBox1.Items.Add("Removed the following SID:" & id.ToString & " From " & Path & vbCrLf) My.Computer.FileSystem.WriteAllText("c:\orphansid.txt", "Removed the following SID:" & id.ToString & " From " & Path & vbCrLf, True) Thread.Sleep(2) End If Dim DirACLs As New Security.AccessControl.DirectorySecurity(Path, AccessControlSections.All) DirACLs.PurgeAccessRules(id) 'dSecurity.PurgeAccessRules(id) dinfo.SetAccessControl(dSecurity) Next
Я хочу, чтобы программа очистила осиротевший SID, а затем внесла его в список и имела возможность скопировать список осиротевших Sid в буфер обмена.
Может ли кто-нибудь помочь мне выяснить, почему это работает не так, как я хочу, и/или найти альтернативное решение?
Что я уже пробовал:
Я попробовал код, приведенный выше, и он успешно перечисляет осиротевшие Sid и добавляет их в список в нужном мне формате, но он не очищает осиротевшие Sid.