Port more streams code to 'WinRT.Runtime'#2314
Merged
Sergio0694 merged 23 commits intostaging/3.0from Mar 8, 2026
Merged
Conversation
Add IStorageItemHandleAccess and IStorageFolderHandleAccess vftbl types, Methods classes, handle option enums (HandleAccessOptions, HandleCreationOptions, HandleSharingOptions, HandleOptions), and WindowsRuntimeStorageHelpers with conversion methods from System.IO types. Add IIDs for both interfaces to WellKnownWindowsInterfaceIIDs. Add exception messages for unsupported Inheritable/Encrypted options. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use 'in' keyword when passing IID references to TryAsUnsafe, matching the convention used throughout the rest of the WinRT.Runtime codebase. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace all private conversion helpers (FileAccessToHandleAccessOptions, FileShareToHandleSharingOptions, FileOptionsToHandleOptions, FileModeToCreationOptions) and old HANDLE_* enum types with calls to WindowsRuntimeStorageHelpers, IStorageItemHandleAccessMethods, and IStorageFolderHandleAccessMethods from WinRT.Runtime. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Move HandleAccessOptions, HandleCreationOptions, HandleSharingOptions, and HandleOptions from InteropServices/Streams to InteropServices/Platform, renaming them to match their Win32 counterparts (HANDLE_ACCESS_OPTIONS, etc.) and making them internal. Update WindowsRuntimeStorageHelpers to return uint instead of the enum types, and update all callsites accordingly. Also add throw helper extensions (ThrowIfFileShareOutOfRange, ThrowIfFileOptionsOutOfRange, ThrowIfFileModeOutOfRange) and update WindowsRuntimeStorageHelpers to use them. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add public Create overloads to IStorageItemHandleAccessMethods and IStorageFolderHandleAccessMethods that take System.IO types (FileAccess, FileShare, FileOptions, FileMode) and handle the conversion internally. Make the uint-based overloads private, and make WindowsRuntimeStorageHelpers internal since it is no longer needed from outside the assembly. This simplifies callsites in WindowsRuntimeStorageExtensions.cs which now just pass the System.IO values directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Delete HANDLE_ACCESS_OPTIONS.cs, HANDLE_CREATION_OPTIONS.cs, HANDLE_OPTIONS.cs, HANDLE_SHARING_OPTION.cs, IStorageFolderHandleAccess.cs, and IStorageItemHandleAccess.cs from the additions folder, as these types have been migrated to WinRT.Runtime. Update cswinrt.vcxproj and cswinrt.vcxproj.filters accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the .NET Foundation license header with Microsoft copyright/MIT and add XML documentation comments for the WindowsRuntimeStorageExtensions APIs. Documents were added for file- and folder-based OpenStreamForReadAsync/OpenStreamForWriteAsync overloads and for CreateSafeFileHandle overloads (params, returns, exceptions). Also tightened argument validation (added braces around if checks), added exception documentation for null/whitespace inputs, and applied minor formatting adjustments to improve readability and API discoverability.
Add XML documentation to indicate that an IOException is thrown when a file cannot be opened or retrieved as a stream. Applied to multiple Windows.Storage.IO extension methods: OpenStreamForReadAsync(IStorageFile), OpenStreamForWriteAsync(IStorageFile), OpenStreamForReadAsync(IStorageFolder, string), and OpenStreamForWriteAsync(IStorageFolder, string, CreationCollisionOption). Improves API documentation and IntelliSense.
Add System.Runtime.Versioning using and replace fully-qualified SupportedOSPlatform attributes with the shorter attribute. Restructure multiple OpenStreamForRead/Write extension methods to use local/static helper implementations (OpenStreamForReadCoreAsync, OpenStreamForWriteCoreAsync and a new OpenStreamForWriteCoreAsync overload) to consolidate async logic and exception handling. Centralize exception translation to WindowsRuntimeIOHelpers.GetExceptionDispatchInfo(...).Throw() so callers receive IOExceptions as expected. Also tighten assertions/messages, use pattern matching for FileMode.Append check, and preserve existing public APIs while improving readability and error semantics.
Add an exception filter to skip IOException in the catch block inside WindowsRuntimeStorageExtensions.OpenStreamForWrite flow. This prevents re-catching and re-throwing an IOException (which OpenStreamForWriteCoreAsync already throws) and clarifies the intent in the updated comment.
Delete the generated Windows.Storage.SR.cs resource file and remove its inclusion from cswinrt.vcxproj and the project filters. Replace manual null/whitespace checks in WindowsRuntimeStorageExtensions.cs with ArgumentException.ThrowIfNullOrWhiteSpace(relativePath), simplifying validation and removing the dependency on the SR resource string.
Delete the <Filter Include="strings\\additions\\Windows.Storage.Streams"> entry from src/cswinrt/cswinrt.vcxproj.filters (GUID {4035db1f-9a59-42da-84a0-e3c3227fe586}). Cleans up the project filters by removing an unused/obsolete filter entry.
Replace raw uints with strongly-typed HANDLE_* enums for storage handle parameters and return values to improve type-safety and clarity. Updated method signatures in IStorageFolderHandleAccessMethods and IStorageItemHandleAccessMethods, corresponding vtable delegates and CreateUnsafe wrappers in IStorageFolderHandleAccessVftbl and IStorageItemHandleAccessVftbl, and conversion helpers in WindowsRuntimeStorageHelpers to return HANDLE_ACCESS_OPTIONS, HANDLE_SHARING_OPTIONS, HANDLE_OPTIONS, and HANDLE_CREATION_OPTIONS (with appropriate casts for FileOptions/FileMode where needed). Files changed: IStorageFolderHandleAccessMethods.cs, IStorageItemHandleAccessMethods.cs, WindowsRuntimeStorageHelpers.cs, IStorageFolderHandleAccessVftbl.cs, IStorageItemHandleAccessVftbl.cs.
Replace nint-typed parameters and return values with concrete pointer/HANDLE types in IStorageFolder/ItemHandleAccess VFTBLs and methods. Change Create delegate signatures to use char*/void*/HANDLE* and update CreateUnsafe wrappers accordingly. Update calling code to pass named arguments, use null for oplockBreakingHandler, remove nint casts, switch interopHandle to HANDLE, and use target-typed new for SafeFileHandle. These changes improve type safety and clarity for native interop with storage handle APIs.
Replace direct calls to WindowsRuntimeStorageHelpers with instance-style extension methods. Updated IStorageFolderHandleAccessMethods.cs and IStorageItemHandleAccessMethods.cs to call ToHandleCreationOptions/ToHandleAccessOptions/ToHandleSharingOptions/ToHandleOptions on the FileMode/FileAccess/FileShare/FileOptions values. Removed the old WindowsRuntimeStorageHelpers.cs and added WindowsRuntimeStorageOptionsExtensions.cs containing the new conversion extensions.
Replace the inline throw in WindowsRuntimeStorageOptionsExtensions with a call to a new helper GetFileAccessOutOfRangeException. Adds the helper method to WindowsRuntimeExceptionExtensions.cs (marked [MethodImpl(NoInlining)]) that constructs and returns an ArgumentOutOfRangeException for invalid FileAccess values, centralizing exception creation.
Refactor interop calls in IStorageFolderHandleAccessMethods.cs and IStorageItemHandleAccessMethods.cs to store the HRESULT returned by CreateUnsafe in a local variable, then pass that value to RestrictedErrorInfo.ThrowExceptionForHR. This ensures CreateUnsafe is invoked and its result inspected explicitly before throwing, improving clarity and the order of operations for error handling.
…WindowsRuntimeObject Use WindowsRuntimeComWrappersMarshal.TryUnwrapObjectReference to unwrap the object reference, so callers don't need to cast to WindowsRuntimeObject. This avoids throwing if someone implemented the storage interface on their own type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Ports additional Windows.Storage/Streams interop helpers from cswinrt projection “additions” into WinRT.Runtime2, keeping only the public projection extensions that require projected interfaces.
Changes:
- Refactors
WindowsRuntimeStorageExtensionsto use local helpers, updated argument validation, and routes handle creation through newWindowsRuntime.InteropServices.*HandleAccessMethods. - Moves Storage handle access COM interop (IIDs, vtables, option enums, conversion helpers) into
WinRT.Runtime2/InteropServices. - Removes legacy projection-local SR strings and handle-access interop/enum helpers from the cswinrt additions set.
Reviewed changes
Copilot reviewed 23 out of 23 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/cswinrt/strings/additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs | Updates storage stream + handle extension logic and routes handle creation via runtime interop methods. |
| src/cswinrt/strings/additions/Windows.Storage/Windows.Storage.SR.cs | Removes projection-local SR strings (moved/replaced by runtime messages). |
| src/cswinrt/strings/additions/Windows.Storage/IStorageItemHandleAccess.cs | Removes projection-local COM interop for IStorageItemHandleAccess. |
| src/cswinrt/strings/additions/Windows.Storage/IStorageFolderHandleAccess.cs | Removes projection-local COM interop for IStorageFolderHandleAccess. |
| src/cswinrt/strings/additions/Windows.Storage/HANDLE_*.cs | Removes projection-local handle option enums now defined in runtime interop. |
| src/cswinrt/cswinrt.vcxproj / src/cswinrt/cswinrt.vcxproj.filters | Drops removed additions files from the native project lists. |
| src/WinRT.Runtime2/Properties/WindowsRuntimeExceptionMessages.cs | Adds new NotSupported messages for handle option validation paths. |
| src/WinRT.Runtime2/Properties/WindowsRuntimeExceptionExtensions.cs | Adds helpers for FileShare/FileOptions/FileMode validation + FileAccess AOOE creation. |
| src/WinRT.Runtime2/InteropServices/WellKnownWindowsInterfaceIIDs.tt (+ .g.cs) | Adds well-known IIDs for storage handle access COM interfaces. |
| src/WinRT.Runtime2/InteropServices/Vtables/IStorage*HandleAccessVftbl.cs | Adds vtable bindings for IStorageItemHandleAccess/IStorageFolderHandleAccess. |
| src/WinRT.Runtime2/InteropServices/Streams/*HandleAccessMethods.cs | Adds runtime COM invocation helpers returning SafeFileHandle from storage items/folders. |
| src/WinRT.Runtime2/InteropServices/Streams/WindowsRuntimeStorageOptionsExtensions.cs | Adds conversions from System.IO enums to WinRT HANDLE_* enums with validation. |
| src/WinRT.Runtime2/InteropServices/Platform/HANDLE_*.cs | Introduces runtime definitions for HANDLE_* enums used by COM interop. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
src/cswinrt/strings/additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs
Show resolved
Hide resolved
src/WinRT.Runtime2/InteropServices/Streams/IStorageItemHandleAccessMethods.cs
Show resolved
Hide resolved
src/WinRT.Runtime2/InteropServices/Streams/IStorageFolderHandleAccessMethods.cs
Show resolved
Hide resolved
src/cswinrt/strings/additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs
Outdated
Show resolved
Hide resolved
src/cswinrt/strings/additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs
Outdated
Show resolved
Hide resolved
src/cswinrt/strings/additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs
Outdated
Show resolved
Hide resolved
src/cswinrt/strings/additions/Windows.Storage/WindowsRuntimeStorageExtensions.cs
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Enable nullable reference types in WindowsRuntimeStorageExtensions and mark SafeFileHandle return types as nullable. Updated XML docs to indicate methods may return null for CreateSafeFileHandle overloads (IStorageFile and IStorageFolder variants). Added #nullable enable at top and #nullable restore at end and applied minor whitespace cleanup. This improves nullable analysis and documents possible null returns.
Insert a using directive for global::System into WindowsRuntimeStorageExtensions.cs so System types can be referenced in this file. This is a non-functional change that updates imports only.
Rename the private helper OpenStreamForWriteCoreAsync to OpenStreamForWriteWithOffsetAsync and update internal callsites and comment references accordingly. Clarifies the helper's purpose of opening a write stream with a specified offset without changing behavior.
manodasanW
approved these changes
Mar 7, 2026
Reformat the multi-argument Create invocations in IStorageFolderHandleAccessVftbl.cs and IStorageItemHandleAccessVftbl.cs to a one-argument-per-line style for improved readability. This is a whitespace/formatting-only change and does not modify behavior.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Title. Just left the actual public extensions in the projections since they need the projected interfaces.