IridiumIO / CompactGUI

Transparently compress active games and programs using Windows 10/11 APIs
GNU General Public License v3.0
4.71k stars 223 forks source link

Program crash when trying to compress Microsoft Flight Simulator package folder #434

Closed Roadou closed 1 week ago

Roadou commented 2 weeks ago

Hello, when i try to compress the MSFS2020 folder, both including official and community packages (basically plane/maps...), the program crash, The folder is located in C:\Users\Road\AppData\Local\Packages\Microsoft.FlightSimulator_8wekyb3d8bbwe\LocalCache\Packages Here's the crashlog

Application: CompactGUI.exe
CoreCLR Version: 6.0.2724.6912
.NET Version: 6.0.27
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at CompactGUI.Application.Application_Startup(Object sender, StartupEventArgs e)
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run()
   at CompactGUI.Application.Main()
Application: CompactGUI.exe
CoreCLR Version: 6.0.2724.6912
.NET Version: 6.0.27
Description: The process was terminated due to an unhandled exception.
Exception Info: System.InvalidCastException: Specified cast is not valid.
   at CompactGUI.Core.Analyser.HasDirectoryWritePermission()
   at CompactGUI.MainViewModel.AnalyseBegin()
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_0(Object state)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.Run()
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run()
   at CompactGUI.Application.Main()

It may be because the buffer that hold directory name is not large enough ? Thank you.

Roadou commented 2 weeks ago

I asked ChatGPT to rewrite the HasDirectoryWritePermission function, and it is now working properly:

   Public Function HasDirectoryWritePermission() As Boolean
       Try
           Dim writeAllow As Boolean = False

           ' Replace FolderName with the actual path you're checking
           Dim ACRules = New DirectoryInfo(folderName).GetAccessControl().GetAccessRules(True, True, GetType(Security.Principal.NTAccount))
           If ACRules Is Nothing Then Return False

           Dim identity = Security.Principal.WindowsIdentity.GetCurrent()
           Dim principal = New Security.Principal.WindowsPrincipal(identity)

           For Each rule As FileSystemAccessRule In ACRules
               If (rule.FileSystemRights And FileSystemRights.Write) = FileSystemRights.Write Then
                   Dim identityReference = rule.IdentityReference

                   ' Check the type of identityReference
                   If TypeOf identityReference Is Security.Principal.NTAccount Then
                       Dim ntAccount As Security.Principal.NTAccount = DirectCast(identityReference, Security.Principal.NTAccount)
                       If principal.IsInRole(ntAccount.Value) Then
                           If rule.AccessControlType = AccessControlType.Deny Then
                               Return False
                           End If
                           writeAllow = True
                       End If
                   ElseIf TypeOf identityReference Is Security.Principal.SecurityIdentifier Then
                       ' Handle SecurityIdentifier if needed
                       ' You can choose to handle SecurityIdentifier differently if required.
                       ' For example, you could log or skip these cases.
                       ' For now, let's just log a message.
                       Console.WriteLine("Found a SecurityIdentifier: " & DirectCast(identityReference, Security.Principal.SecurityIdentifier).ToString())
                   End If
               End If
           Next

           Return writeAllow

       Catch ex As UnauthorizedAccessException
           ' Handle unauthorized access exception
           Console.WriteLine("UnauthorizedAccessException: " & ex.Message)
           Return False
       Catch ex As Exception
           ' Handle other exceptions
           Console.WriteLine("Exception occurred: " & ex.Message)
           Return False
       End Try
   End Function