Skip to content

Commit 06715cb

Browse files
authored
Fix crash when enumerating folder contents on certain devices (#2886)
1 parent ee9fcd1 commit 06715cb

File tree

3 files changed

+74
-48
lines changed

3 files changed

+74
-48
lines changed

Files/Helpers/NativeWinApiHelper.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,5 +196,41 @@ public enum TokenAccess : uint
196196

197197
TOKEN_EXECUTE = 0x00020000
198198
}
199+
200+
[DllImport("api-ms-win-core-wow64-l1-1-1.dll", SetLastError = true)]
201+
private static extern bool IsWow64Process2(
202+
IntPtr process,
203+
out ushort processMachine,
204+
out ushort nativeMachine);
205+
206+
// https://stackoverflow.com/questions/54456140/how-to-detect-were-running-under-the-arm64-version-of-windows-10-in-net
207+
// https://docs.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants
208+
private static bool? isRunningOnArm = null;
209+
210+
public static bool IsRunningOnArm
211+
{
212+
get
213+
{
214+
if (isRunningOnArm == null)
215+
{
216+
isRunningOnArm = IsArmProcessor();
217+
NLog.LogManager.GetCurrentClassLogger().Info("Running on ARM: {0}", isRunningOnArm);
218+
}
219+
return isRunningOnArm ?? false;
220+
}
221+
}
222+
223+
private static bool IsArmProcessor()
224+
{
225+
var handle = System.Diagnostics.Process.GetCurrentProcess().Handle;
226+
if (!IsWow64Process2(handle, out _, out var nativeMachine))
227+
{
228+
return false;
229+
}
230+
return (nativeMachine == 0xaa64 ||
231+
nativeMachine == 0x01c0 ||
232+
nativeMachine == 0x01c2 ||
233+
nativeMachine == 0x01c4);
234+
}
199235
}
200236
}

Files/Helpers/NaturalStringComparer.cs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,20 +35,38 @@ Int32 param
3535
);
3636
}
3737

38-
public class NaturalStringComparer : IComparer<object>
38+
public class NaturalStringComparer
3939
{
40-
public int Compare(object a, object b)
40+
public static IComparer<object> GetForProcessor()
4141
{
42-
return SafeNativeMethods.CompareStringEx(
43-
SafeNativeMethods.LOCALE_NAME_USER_DEFAULT,
44-
SafeNativeMethods.SORT_DIGITSASNUMBERS, // Add other flags if required.
45-
a.ToString(),
46-
a.ToString().Length,
47-
b.ToString(),
48-
b.ToString().Length,
49-
IntPtr.Zero,
50-
IntPtr.Zero,
51-
0) - 2;
42+
return NativeWinApiHelper.IsRunningOnArm ?
43+
(IComparer<object>)new StringComparerArm64() :
44+
(IComparer<object>)new StringComparerDefault();
45+
}
46+
47+
private class StringComparerArm64 : IComparer<object>
48+
{
49+
public int Compare(object a, object b)
50+
{
51+
return StringComparer.CurrentCulture.Compare(a, b);
52+
}
53+
}
54+
55+
private class StringComparerDefault : IComparer<object>
56+
{
57+
public int Compare(object a, object b)
58+
{
59+
return SafeNativeMethods.CompareStringEx(
60+
SafeNativeMethods.LOCALE_NAME_USER_DEFAULT,
61+
SafeNativeMethods.SORT_DIGITSASNUMBERS, // Add other flags if required.
62+
a?.ToString(),
63+
a?.ToString().Length ?? 0,
64+
b?.ToString(),
65+
b?.ToString().Length ?? 0,
66+
IntPtr.Zero,
67+
IntPtr.Zero,
68+
0) - 2;
69+
}
5270
}
5371
}
5472
}

Files/ViewModels/ItemViewModel.cs

Lines changed: 8 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ private IList<ListedItem> OrderFiles2(IList<ListedItem> listToSort)
496496

497497
static object orderByNameFunc(ListedItem item) => item.ItemName;
498498
Func<ListedItem, object> orderFunc = orderByNameFunc;
499-
NaturalStringComparer naturalStringComparer = new NaturalStringComparer();
499+
var naturalStringComparer = NaturalStringComparer.GetForProcessor();
500500
switch (FolderSettings.DirectorySortOption)
501501
{
502502
case SortOption.Name:
@@ -553,54 +553,26 @@ private IList<ListedItem> OrderFiles2(IList<ListedItem> listToSort)
553553
}
554554
else
555555
{
556-
if (FolderSettings.DirectorySortOption == SortOption.FileType)
556+
if (FolderSettings.DirectorySortOption == SortOption.Name)
557557
{
558-
if (FolderSettings.DirectorySortOption == SortOption.Name)
558+
if (AppSettings.ListAndSortDirectoriesAlongsideFiles)
559559
{
560-
if (AppSettings.ListAndSortDirectoriesAlongsideFiles)
561-
{
562-
ordered = listToSort.OrderBy(orderFunc, naturalStringComparer);
563-
}
564-
else
565-
{
566-
ordered = listToSort.OrderByDescending(orderFunc, naturalStringComparer);
567-
}
560+
ordered = listToSort.OrderByDescending(orderFunc, naturalStringComparer);
568561
}
569562
else
570563
{
571-
if (AppSettings.ListAndSortDirectoriesAlongsideFiles)
572-
{
573-
ordered = listToSort.OrderByDescending(orderFunc);
574-
}
575-
else
576-
{
577-
ordered = listToSort.OrderBy(folderThenFileAsync).ThenByDescending(orderFunc);
578-
}
564+
ordered = listToSort.OrderByDescending(folderThenFileAsync).ThenByDescending(orderFunc, naturalStringComparer);
579565
}
580566
}
581567
else
582568
{
583-
if (FolderSettings.DirectorySortOption == SortOption.Name)
569+
if (AppSettings.ListAndSortDirectoriesAlongsideFiles)
584570
{
585-
if (AppSettings.ListAndSortDirectoriesAlongsideFiles)
586-
{
587-
ordered = listToSort.OrderByDescending(orderFunc, naturalStringComparer);
588-
}
589-
else
590-
{
591-
ordered = listToSort.OrderByDescending(folderThenFileAsync).ThenByDescending(orderFunc, naturalStringComparer);
592-
}
571+
ordered = listToSort.OrderByDescending(orderFunc);
593572
}
594573
else
595574
{
596-
if (AppSettings.ListAndSortDirectoriesAlongsideFiles)
597-
{
598-
ordered = listToSort.OrderByDescending(orderFunc);
599-
}
600-
else
601-
{
602-
ordered = listToSort.OrderByDescending(folderThenFileAsync).ThenByDescending(orderFunc);
603-
}
575+
ordered = listToSort.OrderByDescending(folderThenFileAsync).ThenByDescending(orderFunc);
604576
}
605577
}
606578
}

0 commit comments

Comments
 (0)