Skip to content

Commit 4312a64

Browse files
committed
fix: convert properties to strings for sorting instead of to byte arrays
This *should* prevent an InvalidOperationException thrown by `System.Collection.Generic.ArraySortHelper<T>.Sort(Span<T> keys, Comparison<T> comparison)`. Its inner exception, an ArgumentException "At least one object must implement IComparable", is thrown by System.Collection.Comparer.Compare(Object a, Object b).
1 parent f5e5c72 commit 4312a64

File tree

1 file changed

+16
-37
lines changed

1 file changed

+16
-37
lines changed

deadlock-dotnet-sdk/Domain/FileLockerEx.cs

Lines changed: 16 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -40,50 +40,29 @@ public enum SortByProperty
4040
ProcessId
4141
}
4242

43-
// TODO: order by Process ID and then by handle value. Later todo: allow user-specified sorting rule (e.g. by column/property)
4443
/// <summary>Get or set the List of handles that are locking the file</summary>
4544
public List<SafeFileHandleEx> Lockers
4645
{
4746
get
4847
{
4948
return lockers
50-
.OrderBy(h =>
51-
{
52-
switch (SortByPrimary) // returns byte[]
53-
{
54-
//case SortByProperty.FileShareAccess: return h.FileShareAccess; // not possible without a kernel mode driver; see IoCheckShareAccess
55-
case SortByProperty.HandleAttributes: return Encoding.ASCII.GetBytes(h.HandleAttributes.ToString());
56-
case SortByProperty.HandleSubType: return Encoding.ASCII.GetBytes(h.FileHandleType.v?.ToString() ?? string.Empty);
57-
case SortByProperty.HandleType: return Encoding.ASCII.GetBytes(h.HandleObjectType.v?.ToString() ?? string.Empty);
58-
case SortByProperty.HandleValue: return Encoding.ASCII.GetBytes(h.HandleValue.ToString());
59-
case SortByProperty.GrantedAccessHexadecimal: return BitConverter.GetBytes(h.GrantedAccess.Value);
60-
case SortByProperty.GrantedAccessSymbolic: return Encoding.ASCII.GetBytes(h.GrantedAccessString);
61-
case SortByProperty.ObjectOriginalName: return Encoding.ASCII.GetBytes(h.ObjectName.v ?? string.Empty);
62-
case SortByProperty.ObjectRealName: return Encoding.ASCII.GetBytes(h.FileFullPath.v ?? h.FileNameInfo.v ?? string.Empty); // TODO: implement Registry key parsing
63-
case SortByProperty.ObjectAddress: return BitConverter.GetBytes((ulong)h.ObjectAddress);
64-
case SortByProperty.ProcessId: return BitConverter.GetBytes(h.ProcessId);
65-
default: goto case SortByProperty.ProcessId;
66-
}
67-
})
68-
.ThenBy(h =>
69-
{
70-
switch (SortBySecondary) // returns byte[]
71-
{
72-
//case SortByProperty.FileShareAccess: return h.FileShareAccess; // not possible without a kernel mode driver; see IoCheckShareAccess
73-
case SortByProperty.HandleAttributes: return Encoding.ASCII.GetBytes(h.HandleAttributes.ToString());
74-
case SortByProperty.HandleSubType: return Encoding.ASCII.GetBytes(h.FileHandleType.v?.ToString() ?? string.Empty);
75-
case SortByProperty.HandleType: return Encoding.ASCII.GetBytes(h.HandleObjectType.v?.ToString() ?? string.Empty);
76-
case SortByProperty.HandleValue: return Encoding.ASCII.GetBytes(h.HandleValue.ToString());
77-
case SortByProperty.GrantedAccessHexadecimal: return BitConverter.GetBytes(h.GrantedAccess.Value);
78-
case SortByProperty.GrantedAccessSymbolic: return Encoding.ASCII.GetBytes(h.GrantedAccessString);
79-
case SortByProperty.ObjectOriginalName: return Encoding.ASCII.GetBytes(h.ObjectName.v ?? string.Empty);
80-
case SortByProperty.ObjectRealName: return Encoding.ASCII.GetBytes(h.FileFullPath.v ?? h.FileNameInfo.v ?? string.Empty); // TODO: implement Registry key parsing
81-
case SortByProperty.ObjectAddress: return BitConverter.GetBytes((ulong)h.ObjectAddress);
82-
case SortByProperty.ProcessId: return BitConverter.GetBytes(h.ProcessId);
83-
default: goto case SortByProperty.ProcessId;
84-
}
85-
})
49+
.OrderBy(h => SortBy(h, SortByPrimary))
50+
.ThenBy(h => SortBy(h, SortBySecondary))
8651
.ToList();
52+
static string SortBy(SafeFileHandleEx h, SortByProperty property) => property switch // returns string
53+
{
54+
//case SortByProperty.FileShareAccess: return h.FileShareAccess; // not possible without a kernel mode driver; see IoCheckShareAccess
55+
SortByProperty.HandleAttributes => h.HandleAttributes.ToString(),
56+
SortByProperty.HandleSubType => h.FileHandleType.v?.ToString() ?? string.Empty,
57+
SortByProperty.HandleType => h.HandleObjectType.v?.ToString() ?? string.Empty,
58+
SortByProperty.HandleValue => h.HandleValue.ToString(),
59+
SortByProperty.GrantedAccessHexadecimal => h.GrantedAccess.Value.ToString(),
60+
SortByProperty.GrantedAccessSymbolic => h.GrantedAccessString,
61+
SortByProperty.ObjectOriginalName => h.ObjectName.v ?? string.Empty,
62+
SortByProperty.ObjectRealName => h.FileFullPath.v ?? h.FileNameInfo.v ?? string.Empty,// TODO: implement Registry key parsing
63+
SortByProperty.ObjectAddress => h.ObjectAddress.ToString(),
64+
_ => h.ProcessId.ToString(),
65+
};
8766
}
8867
}
8968

0 commit comments

Comments
 (0)