Skip to content

Refactor GetFileShares#26155

Closed
xtqqczze wants to merge 1 commit into
PowerShell:masterfrom
xtqqczze:NetApiBufferFree2
Closed

Refactor GetFileShares#26155
xtqqczze wants to merge 1 commit into
PowerShell:masterfrom
xtqqczze:NetApiBufferFree2

Conversation

@xtqqczze
Copy link
Copy Markdown
Contributor

@xtqqczze xtqqczze commented Oct 7, 2025

  • Use unmanaged pointers instead of nint
  • Avoid pointer arithmetic, use Span instead
  • Fix PInvoke definitions
  • Avoid PtrToStructure and use blittable struct for performance.

Follow-up to: #25896

* Use unmanaged pointers instead of `nint`
* Avoid pointer arithmetic, use Span instead
* Fix PInvoke definitions
* Avoid `PtrToStructure` and use blittable struct for performance.
public ushort* remark;
}

internal static uint NetShareEnum<T>(string? servername, out T* pShareInfo, out int count) where T : unmanaged
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Since it is high level helper it could return just List so that we have no interop/unsafe code in call site.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We need to free the unmanaged buffer, so we cannot return just a managed type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I considered implementing a class deriving from SafeBuffer, but this would be much more code and abstraction for a method that is only called once.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If we build List in the method we can free the buffer in the method too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

If we build List in the method we can free the buffer in the method too.

This is exactly what the GetFileShares method does already :p

Copy link
Copy Markdown
Contributor Author

@xtqqczze xtqqczze Oct 17, 2025

Choose a reason for hiding this comment

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

@iSazonov I think the current changes are a reasonable balance between safety and avoiding unnecessary abstraction. In terms of safety, we now avoid pointer arithmetic and use a span implementation.

@microsoft-github-policy-service microsoft-github-policy-service Bot added the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Oct 13, 2025
@xtqqczze xtqqczze marked this pull request as ready for review October 15, 2025 01:21
@microsoft-github-policy-service microsoft-github-policy-service Bot removed the Waiting on Author The PR was reviewed and requires changes or comments from the author before being accept label Oct 17, 2025
@iSazonov iSazonov requested a review from Copilot October 22, 2025 11:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the GetFileShares method to improve performance and type safety by transitioning from managed pointer types (nint) to unmanaged pointers, eliminating the need for Marshal.PtrToStructure, and using Span<T> for safer iteration. The changes also correct PInvoke definitions to align with the Windows API specifications.

  • Replaced nint with typed unmanaged pointers (byte*, void*, T*) for better type safety
  • Introduced a blittable SHARE_INFO_1 struct to avoid marshalling overhead
  • Replaced manual pointer arithmetic with ReadOnlySpan<T> for safer iteration

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
NetShareEnum.cs Redefined PInvoke signature with unmanaged pointers, added blittable SHARE_INFO_1 struct, and introduced generic wrapper method
NetApiBufferFree.cs Updated to accept void* instead of nint
CompletionCompleters.cs Refactored GetFileShares to use unmanaged pointers, Span<T> iteration, and manual string marshalling

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

if (typeof(T) == typeof(SHARE_INFO_1))
return 1;

throw new NotSupportedException();
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

The NotSupportedException lacks a descriptive message. Consider adding a message that specifies which type was unsupported, e.g., throw new NotSupportedException($\"Unsupported structure type: {typeof(T).Name}\");

Suggested change
throw new NotSupportedException();
throw new NotSupportedException($"Unsupported structure type: {typeof(T).Name}");

Copilot uses AI. Check for mistakes.
continue;
}

string share = Utf16StringMarshaller.ConvertToManaged(shareInfo.netname);
Copy link

Copilot AI Oct 22, 2025

Choose a reason for hiding this comment

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

Potential null reference exception: Utf16StringMarshaller.ConvertToManaged may return null if shareInfo.netname is null, but the result is used without null checking on line 5221. Add null handling, e.g., string? share = Utf16StringMarshaller.ConvertToManaged(shareInfo.netname); if (share == null) continue;

Suggested change
string share = Utf16StringMarshaller.ConvertToManaged(shareInfo.netname);
string? share = Utf16StringMarshaller.ConvertToManaged(shareInfo.netname);
if (share == null)
{
continue;
}

Copilot uses AI. Check for mistakes.
@iSazonov
Copy link
Copy Markdown
Collaborator

@xtqqczze Thank you for your efforts! This change looks interesting, but it's not worth it - it's not a hot path, users usually deal with a very limited amount of shares, so I'm closing this. It also requires manual testing, which creates significant regression risks.
If you want to invest in this area, then look at what hasn't migrated from DllImport to LibraryImport yet.

@iSazonov iSazonov closed this Oct 23, 2025
@microsoft-github-policy-service
Copy link
Copy Markdown
Contributor

microsoft-github-policy-service Bot commented Oct 23, 2025

📣 Hey @@xtqqczze, how did we do? We would love to hear your feedback with the link below! 🗣️

🔗 https://aka.ms/PSRepoFeedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants