Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Support long path
  • Loading branch information
nxtn committed Dec 7, 2020
commit 638594bf7d12f5fc6bcf832bc442107d366c3448
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ private static ProcessModuleCollection GetModules(int processId, bool firstModul

var modules = new ProcessModuleCollection(firstModuleOnly ? 1 : modulesCount);

char[] chars = ArrayPool<char>.Shared.Rent(1024);
const int MaxShortPath = 260;
int minimumLength = MaxShortPath;
char[]? chars = ArrayPool<char>.Shared.Rent(minimumLength);
try
{
for (int i = 0; i < modulesCount; i++)
Expand Down Expand Up @@ -171,14 +173,29 @@ private static ProcessModuleCollection GetModules(int processId, bool firstModul

module.ModuleName = new string(chars, 0, length);

length = Interop.Kernel32.GetModuleFileNameEx(processHandle, moduleHandle, chars, chars.Length);
for (; ; )
{
length = Interop.Kernel32.GetModuleFileNameEx(processHandle, moduleHandle, chars, chars.Length);
if (length == chars.Length)
{
char[] toReturn = chars;
chars = null;
ArrayPool<char>.Shared.Return(toReturn);
Comment on lines +187 to +189
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the purpose of toReturn - can't you do:

                               ArrayPool<char>.Shared.Return(chars);
                                minimumLength = Math.Min(minimumLength * 2, short.MaxValue);
                                chars = ArrayPool<char>.Shared.Rent(minimumLength);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@danmosemsft This would call Return multiple timeswhenRent` throws an exception.

It would be fine to write it this way if the Return is not inside finally block (ie we let GC take care of collecting the buffer when exception is thrown).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes - tricky. might be worth a comment.

minimumLength = Math.Min(minimumLength * 2, short.MaxValue);
chars = ArrayPool<char>.Shared.Rent(minimumLength);
continue;
}

break;
}

if (length == 0)
{
HandleLastWin32Error();
continue;
}

module.FileName = (length >= 4 && chars[0] == '\\' && chars[1] == '\\' && chars[2] == '?' && chars[3] == '\\') ?
module.FileName = chars.AsSpan().StartsWith(@"\\?\") ?
new string(chars, 4, length - 4) :
new string(chars, 0, length);

Expand All @@ -187,7 +204,10 @@ private static ProcessModuleCollection GetModules(int processId, bool firstModul
}
finally
{
ArrayPool<char>.Shared.Return(chars);
if (chars != null)
{
ArrayPool<char>.Shared.Return(chars);
}
}

return modules;
Expand Down