From 5ba04306df06af44d9fd440a1a17ea69b073b751 Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Mon, 4 Oct 2021 14:17:40 -0500 Subject: [PATCH] Moved from IntPtr to byte[] in more places --- .../Iris/Render/Extensions/ExtensionsApi.cs | 6 +- .../Iris/Render/Extensions/ImageCacheItem.cs | 14 +- .../Iris/Render/Extensions/ImageLoader.cs | 28 ++-- .../Iris/Render/Extensions/ModuleManager.cs | 6 +- .../Iris/Render/Extensions/SoundLoader.cs | 6 +- .../Iris/CodeModel/Cpp/DllProxyServices.cs | 3 +- .../Iris/CodeModel/Cpp/DllTypeSchemaBase.cs | 2 +- UIX.Skia/Microsoft/Iris/Data/Resource.cs | 21 ++- UIX.Skia/Microsoft/Iris/Drawing/RawImage.cs | 20 +-- .../Microsoft/Iris/Drawing/RawImageItem.cs | 9 +- .../Iris/Drawing/ResourceImageItem.cs | 2 +- UIX.Skia/Microsoft/Iris/Image.cs | 6 +- UIX.Skia/Microsoft/Iris/OS/DllResource.cs | 7 +- UIX.Skia/Microsoft/Iris/OS/FileResource.cs | 36 ++--- UIX.Skia/Microsoft/Iris/OS/HttpResource.cs | 19 +-- UIX.Skia/Microsoft/Iris/OS/HttpResources.cs | 12 +- UIX.Skia/Microsoft/Iris/OS/NativeApi.cs | 128 ++++++++++++++++-- UIX.Skia/Microsoft/Iris/OS/NativeXmlReader.cs | 13 +- UIX.Skia/UIX.Skia.csproj | 2 + 19 files changed, 213 insertions(+), 127 deletions(-) diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ExtensionsApi.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ExtensionsApi.cs index e19fe6b..9d85da4 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ExtensionsApi.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ExtensionsApi.cs @@ -30,7 +30,7 @@ namespace Microsoft.Iris.Render.Extensions Size sizeActualPxl, int nStride, SurfaceFormat nFormat, - IntPtr pvData, + byte[] pvData, [MarshalAs(UnmanagedType.LPStruct), In] ImageRequirements req, BitmapOptions nOptions, out HSpBitmap hBmp, @@ -52,7 +52,7 @@ namespace Microsoft.Iris.Render.Extensions } internal static HRESULT SpBitmapLoadBuffer( - IntPtr pvSrc, + byte[] pvSrc, uint cbSize, [MarshalAs(UnmanagedType.LPStruct), In] ImageRequirements req, BitmapOptions nOptions, @@ -68,7 +68,7 @@ namespace Microsoft.Iris.Render.Extensions } internal static HRESULT SpSoundLoadBuffer( - IntPtr pBuffer, + byte[] pBuffer, int dwSize, SoundOptions options, out HSpSound hSound, diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs index bb0d5a4..4f091b2 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageCacheItem.cs @@ -18,8 +18,7 @@ namespace Microsoft.Iris.Render.Extensions protected ImageRequirements m_req; protected Size m_size; protected BitmapInformation m_info; - protected IntPtr m_buffer; - protected uint m_length; + protected byte[] m_buffer; private int m_countUsers; private int m_countLoadsInProgress; private bool m_fFullLoadRequested; @@ -30,15 +29,13 @@ namespace Microsoft.Iris.Render.Extensions public ImageCacheItem( IRenderSession renderSession, string identifier, - IntPtr buffer, - uint length, + byte[] buffer, Size maxSize, bool flippable, bool antialiasEdges) : this(renderSession, identifier, maxSize, flippable, antialiasEdges) { this.m_buffer = buffer; - this.m_length = length; } public ImageCacheItem( @@ -156,10 +153,9 @@ namespace Microsoft.Iris.Render.Extensions public virtual void StartLoad() => this.LoadBuffer(); - protected void SetBuffer(IntPtr buffer, uint length) + protected void SetBuffer(byte[] buffer) { this.m_buffer = buffer; - this.m_length = length; } protected void SetSize(Size size) => this.m_size = size; @@ -229,7 +225,7 @@ namespace Microsoft.Iris.Render.Extensions protected virtual bool DoHeaderLoad() { ImageHeader header; - if (!(this.m_buffer != IntPtr.Zero) || this.m_length <= 0U || !ImageLoader.LoadHeader(this.m_buffer, (int)this.m_length, this.m_req, out header)) + if (!(this.m_buffer != null) || this.m_buffer.Length <= 0U || !ImageLoader.LoadHeader(this.m_buffer, this.m_req, out header)) return false; this.SetSize(header.sizeActualPxl); return true; @@ -240,7 +236,7 @@ namespace Microsoft.Iris.Render.Extensions BitmapInformation bitmapInfo = null; bool flag = false; if (this.m_image != null) - flag = !(this.m_buffer == IntPtr.Zero) ? ImageLoader.FromBuffer(this.m_image, this.m_buffer, (int)this.m_length, this.m_req.MaximumSize, this.m_req.Flippable, this.m_req.AntialiasEdges, this.m_req.BorderWidth, this.m_req.BorderColor, out bitmapInfo) : ImageLoader.FromFile(this.m_image, this.m_image.Identifier, this.m_req.MaximumSize, this.m_req.Flippable, this.m_req.AntialiasEdges, this.m_req.BorderWidth, this.m_req.BorderColor, out bitmapInfo); + flag = !(this.m_buffer == null) ? ImageLoader.FromBuffer(this.m_image, this.m_buffer, this.m_req.MaximumSize, this.m_req.Flippable, this.m_req.AntialiasEdges, this.m_req.BorderWidth, this.m_req.BorderColor, out bitmapInfo) : ImageLoader.FromFile(this.m_image, this.m_image.Identifier, this.m_req.MaximumSize, this.m_req.Flippable, this.m_req.AntialiasEdges, this.m_req.BorderWidth, this.m_req.BorderColor, out bitmapInfo); if (flag) { this.m_info = bitmapInfo; diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageLoader.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageLoader.cs index eb88117..3aa8788 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageLoader.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ImageLoader.cs @@ -13,27 +13,23 @@ namespace Microsoft.Iris.Render.Extensions { public static class ImageLoader { - public static bool LoadHeader(IntPtr rgData, int length, out ImageHeader header) + public static bool LoadHeader(byte[] rgData, out ImageHeader header) { ImageRequirements req = new ImageRequirements(); - return LoadHeader(rgData, length, req, out header); + return LoadHeader(rgData, req, out header); } - public static bool LoadHeader( - IntPtr rgData, - int length, - ImageRequirements req, - out ImageHeader header) + public static bool LoadHeader(byte[] rgData, ImageRequirements req, out ImageHeader header) { - Debug2.Validate(rgData != IntPtr.Zero, typeof(ArgumentNullException), "Must provide valid data to load"); - Debug2.Validate(length > 0, typeof(ArgumentOutOfRangeException), "Must provide non-zero length data to load"); + Debug2.Validate(rgData != null, typeof(ArgumentNullException), "Must provide valid data to load"); + Debug2.Validate(rgData.Length > 0, typeof(ArgumentOutOfRangeException), "Must provide non-zero length data to load"); Debug2.Validate(req != null, typeof(ArgumentNullException), "Must provide valid ImageRequirements"); ExtensionsApi.BitmapOptions nOptions = ExtensionsApi.BitmapOptions.None; BitmapInformation bitmapInformation = new BitmapInformation(); HRESULT hresult = new HRESULT(-1); try { - hresult = ExtensionsApi.SpBitmapLoadBuffer(rgData, (uint)length, req, nOptions, out bitmapInformation.hBitmap, out bitmapInformation.imageInfo); + hresult = ExtensionsApi.SpBitmapLoadBuffer(rgData, (uint)rgData.Length, req, nOptions, out bitmapInformation.hBitmap, out bitmapInformation.imageInfo); if (!hresult.IsSuccess()) header = new ImageHeader(); else @@ -133,8 +129,7 @@ namespace Microsoft.Iris.Render.Extensions public static bool FromBuffer( IImage image, - IntPtr buffer, - int length, + byte[] buffer, Size maxSize, bool flipRTL, bool antialiasEdges, @@ -143,7 +138,7 @@ namespace Microsoft.Iris.Render.Extensions out BitmapInformation bitmapInfo) { Debug2.Validate(image != null, typeof(ArgumentNullException), "Image must be valid"); - Debug2.Validate(length > 0, typeof(ArgumentException), "Do not call for zero-length buffer"); + Debug2.Validate(buffer.Length > 0, typeof(ArgumentException), "Do not call for zero-length buffer"); ImageRequirements req = new ImageRequirements(); req.BorderWidth = borderWidth; req.BorderColor = borderColor; @@ -154,7 +149,7 @@ namespace Microsoft.Iris.Render.Extensions if (flipRTL) nOptions |= ExtensionsApi.BitmapOptions.Flip; BitmapInformation bitmapInformation = new BitmapInformation(); - if (!ExtensionsApi.SpBitmapLoadBuffer(buffer, (uint)length, req, nOptions, out bitmapInformation.hBitmap, out bitmapInformation.imageInfo).IsSuccess()) + if (!ExtensionsApi.SpBitmapLoadBuffer(buffer, (uint)buffer.Length, req, nOptions, out bitmapInformation.hBitmap, out bitmapInformation.imageInfo).IsSuccess()) { bitmapInfo = null; return false; @@ -174,8 +169,7 @@ namespace Microsoft.Iris.Render.Extensions public static bool FromRaw( IImage image, - IntPtr buffer, - int length, + byte[] buffer, Size imageSize, int stride, SurfaceFormat format, @@ -187,7 +181,7 @@ namespace Microsoft.Iris.Render.Extensions out BitmapInformation bitmapInfo) { Debug2.Validate(image != null, typeof(ArgumentNullException), "Image must be valid"); - Debug2.Validate(length > 0, typeof(ArgumentException), "Do not call for zero-length buffer"); + Debug2.Validate(buffer.Length > 0, typeof(ArgumentException), "Do not call for zero-length buffer"); ImageRequirements req = new ImageRequirements(); req.BorderWidth = borderWidth; req.BorderColor = borderColor; diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ModuleManager.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ModuleManager.cs index be271a4..c24ba49 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ModuleManager.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/ModuleManager.cs @@ -53,10 +53,10 @@ namespace Microsoft.Iris.Render.Extensions return hinstance; } - public void LoadResource( + public unsafe void LoadResource( Win32Api.HINSTANCE hInstance, string resourceId, - out IntPtr resourceData, + out byte[] resourceData, out int resourceSize) { IntPtr resource = Win32Api.FindResource(hInstance.h, resourceId, new IntPtr(10)); @@ -66,7 +66,7 @@ namespace Microsoft.Iris.Render.Extensions IntPtr num1 = Win32Api.LockResource(i); Debug2.Validate(num1 != IntPtr.Zero, typeof(InvalidOperationException), "Failed to aquire pointer to resource data"); int num2 = Win32Api.SizeofResource(hInstance.h, resource); - resourceData = num1; + resourceData = new Span(num1.ToPointer(), num2).ToArray(); resourceSize = num2; } } diff --git a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/SoundLoader.cs b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/SoundLoader.cs index 20c2270..2960537 100644 --- a/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/SoundLoader.cs +++ b/UIX.RenderApi.Skia/Microsoft/Iris/Render/Extensions/SoundLoader.cs @@ -21,19 +21,19 @@ namespace Microsoft.Iris.Render.Extensions { Win32Api.HINSTANCE hInstance = ModuleManager.Instance.LoadModule(moduleName); Debug2.Validate(hInstance != Win32Api.HINSTANCE.NULL, typeof(ArgumentException), nameof(moduleName)); - IntPtr resourceData; + byte[] resourceData; int resourceSize; ModuleManager.Instance.LoadResource(hInstance, resourceId, out resourceData, out resourceSize); FromMemory(resourceData, resourceSize, out soundDataHandle, out soundDataInfo); } public static void FromMemory( - IntPtr rawSoundData, + byte[] rawSoundData, int rawSoundDataSize, out ExtensionsApi.HSpSound soundDataHandle, out ExtensionsApi.SoundInformation soundDataInfo) { - Debug2.Validate(rawSoundData != IntPtr.Zero, typeof(ArgumentNullException), nameof(rawSoundData)); + Debug2.Validate(rawSoundData != null, typeof(ArgumentNullException), nameof(rawSoundData)); Debug2.Validate(rawSoundDataSize > 0, typeof(ArgumentException), "Invalid sound data size"); ExtensionsApi.SoundOptions options = ExtensionsApi.SoundOptions.Decode; ExtensionsApi.SoundInformation info = new ExtensionsApi.SoundInformation(); diff --git a/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllProxyServices.cs b/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllProxyServices.cs index adc837c..ecef65e 100644 --- a/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllProxyServices.cs +++ b/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllProxyServices.cs @@ -184,7 +184,8 @@ namespace Microsoft.Iris.CodeModel.Cpp bool antialiasEdges; CrackDecodeParams(decodeParams, out maximumSize, out flippable, out antialiasEdges); Size imageSize = new Size(imageInfo->width, imageInfo->height); - return GetImageHandle(new RawImage(ID, imageSize, imageInfo->stride, surfaceFormat, imageInfo->bits, true, Inset.Zero, maximumSize, flippable, antialiasEdges), ID); + var bytes = new Span(imageInfo->bits.ToPointer(), imageInfo->height * imageInfo->stride); + return GetImageHandle(new RawImage(ID, imageSize, imageInfo->stride, surfaceFormat, bytes.ToArray(), true, Inset.Zero, maximumSize, flippable, antialiasEdges), ID); } unsafe void IRawUIXServices.RemoveCachedImage( diff --git a/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllTypeSchemaBase.cs b/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllTypeSchemaBase.cs index 46cdb12..5995a80 100644 --- a/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllTypeSchemaBase.cs +++ b/UIX.Skia/Microsoft/Iris/CodeModel/Cpp/DllTypeSchemaBase.cs @@ -176,7 +176,7 @@ namespace Microsoft.Iris.CodeModel.Cpp { } - public override object DecodeBinary(ByteCodeReader reader) => (object)null; + public override object DecodeBinary(ManagedByteCodeReader reader) => (object)null; public override bool SupportsBinaryEncoding => false; diff --git a/UIX.Skia/Microsoft/Iris/Data/Resource.cs b/UIX.Skia/Microsoft/Iris/Data/Resource.cs index 930b59a..6d0084d 100644 --- a/UIX.Skia/Microsoft/Iris/Data/Resource.cs +++ b/UIX.Skia/Microsoft/Iris/Data/Resource.cs @@ -13,8 +13,7 @@ namespace Microsoft.Iris.Data { protected string _uri; private bool _forceSynchronous; - private IntPtr _buffer; - private uint _length; + private byte[] _buffer; private bool _requiresMemoryFree; private ResourceStatus _status; private string _errorDetails; @@ -57,7 +56,7 @@ namespace Microsoft.Iris.Data public void Free() => Free(null); - public void Free(ResourceAcquisitionCompleteHandler completeHandler) + public unsafe void Free(ResourceAcquisitionCompleteHandler completeHandler) { --_acquisitions; if (completeHandler != null) @@ -66,11 +65,11 @@ namespace Microsoft.Iris.Data return; if (_status == ResourceStatus.Acquiring) CancelAcquisition(); - else if (_buffer != IntPtr.Zero) + else if (_buffer != null) { if (_requiresMemoryFree) - FreeNativeBuffer(_buffer); - _buffer = IntPtr.Zero; + FreeNativeBuffer(new IntPtr(_buffer.AsMemory().Pin().Pointer)); + _buffer = null; } _status = ResourceStatus.NeedsAcquire; } @@ -83,9 +82,9 @@ namespace Microsoft.Iris.Data public string ErrorDetails => _errorDetails; - public IntPtr Buffer => _buffer; + public byte[] Buffer => _buffer; - public uint Length => _length; + public int Length => _buffer.Length; public bool ForceSynchronous => _forceSynchronous; @@ -94,15 +93,13 @@ namespace Microsoft.Iris.Data protected abstract void CancelAcquisition(); protected void NotifyAcquisitionComplete( - IntPtr buffer, - uint length, + byte[] buffer, bool requiresMemoryFree, string errorDetails) { _buffer = buffer; - _length = length; _requiresMemoryFree = requiresMemoryFree; - if (buffer != IntPtr.Zero) + if (buffer != null) { _status = ResourceStatus.Available; } diff --git a/UIX.Skia/Microsoft/Iris/Drawing/RawImage.cs b/UIX.Skia/Microsoft/Iris/Drawing/RawImage.cs index 4476a99..c5d97a0 100644 --- a/UIX.Skia/Microsoft/Iris/Drawing/RawImage.cs +++ b/UIX.Skia/Microsoft/Iris/Drawing/RawImage.cs @@ -19,7 +19,7 @@ namespace Microsoft.Iris.Drawing private Size _imageSize; private int _stride; private SurfaceFormat _format; - private IntPtr _data; + private byte[] _data; private uint _length; private RawImageItemKey _cacheItemKey; @@ -28,7 +28,7 @@ namespace Microsoft.Iris.Drawing Size imageSize, int stride, SurfaceFormat format, - IntPtr data, + byte[] data, bool takeOwnership, Inset nineGrid, Size maximumSize, @@ -46,8 +46,8 @@ namespace Microsoft.Iris.Drawing _length = (uint)cbCopy; if (!takeOwnership) { - _data = NativeApi.MemAlloc(_length, false); - Memory.Copy(_data, data, cbCopy); + _data = new byte[_length]; + Array.Copy(_data, data, cbCopy); } else _data = data; @@ -55,15 +55,7 @@ namespace Microsoft.Iris.Drawing ~RawImage() { - FreeBuffer(_data); - _data = IntPtr.Zero; - } - - internal static void FreeBuffer(IntPtr data) - { - if (!(data != IntPtr.Zero)) - return; - NativeApi.MemFree(data); + _data = null; } protected override ImageCacheItem GetCacheItem(out bool needAsyncLoad) @@ -78,7 +70,7 @@ namespace Microsoft.Iris.Drawing if (imageCacheItem == null) { Size maxSize = ClampSize(_maximumSize); - imageCacheItem = new RawImageItem(UISession.Default.RenderSession, this, str, _data, _length, _imageSize, _stride, _format, maxSize, IsFlipped, _antialiasEdges); + imageCacheItem = new RawImageItem(UISession.Default.RenderSession, this, str, _data, _imageSize, _stride, _format, maxSize, IsFlipped, _antialiasEdges); instance.Add(_cacheItemKey, imageCacheItem); } needAsyncLoad = false; diff --git a/UIX.Skia/Microsoft/Iris/Drawing/RawImageItem.cs b/UIX.Skia/Microsoft/Iris/Drawing/RawImageItem.cs index c599166..974abee 100644 --- a/UIX.Skia/Microsoft/Iris/Drawing/RawImageItem.cs +++ b/UIX.Skia/Microsoft/Iris/Drawing/RawImageItem.cs @@ -20,8 +20,7 @@ namespace Microsoft.Iris.Drawing IRenderSession renderSession, RawImage rawImage, string source, - IntPtr data, - uint length, + byte[] data, Size imageSize, int stride, SurfaceFormat format, @@ -32,7 +31,7 @@ namespace Microsoft.Iris.Drawing { _oKeepAlive = rawImage; SetSize(imageSize); - SetBuffer(data, length); + SetBuffer(data); _stride = stride; _format = format; } @@ -40,10 +39,10 @@ namespace Microsoft.Iris.Drawing protected override void OnDispose() { _oKeepAlive = null; - m_buffer = IntPtr.Zero; + m_buffer = null; base.OnDispose(); } - protected override bool DoImageLoad() => ImageLoader.FromRaw(RenderImage, m_buffer, (int)m_length, m_size, _stride, _format, m_req.MaximumSize, m_req.Flippable, m_req.AntialiasEdges, m_req.BorderWidth, m_req.BorderColor, out m_info); + protected override bool DoImageLoad() => ImageLoader.FromRaw(RenderImage, m_buffer, m_size, _stride, _format, m_req.MaximumSize, m_req.Flippable, m_req.AntialiasEdges, m_req.BorderWidth, m_req.BorderColor, out m_info); } } diff --git a/UIX.Skia/Microsoft/Iris/Drawing/ResourceImageItem.cs b/UIX.Skia/Microsoft/Iris/Drawing/ResourceImageItem.cs index da5a069..e2aaa57 100644 --- a/UIX.Skia/Microsoft/Iris/Drawing/ResourceImageItem.cs +++ b/UIX.Skia/Microsoft/Iris/Drawing/ResourceImageItem.cs @@ -112,7 +112,7 @@ namespace Microsoft.Iris.Drawing } else { - SetBuffer(_resource.Buffer, _resource.Length); + SetBuffer(_resource.Buffer); if (_resource.Length <= 0U) return; if (!ProcessBuffer()) diff --git a/UIX.Skia/Microsoft/Iris/Image.cs b/UIX.Skia/Microsoft/Iris/Image.cs index e9f1f9d..bbe724b 100644 --- a/UIX.Skia/Microsoft/Iris/Image.cs +++ b/UIX.Skia/Microsoft/Iris/Image.cs @@ -66,7 +66,7 @@ namespace Microsoft.Iris int imageHeight, int stride, RawImageFormat format, - IntPtr data) + byte[] data) : this(uniqueID, imageWidth, imageHeight, stride, format, data, 0, 0, false) { } @@ -77,7 +77,7 @@ namespace Microsoft.Iris int imageHeight, int stride, RawImageFormat format, - IntPtr data, + byte[] data, int maximumWidth, int maximumHeight, bool flippable) @@ -91,7 +91,7 @@ namespace Microsoft.Iris int imageHeight, int stride, RawImageFormat format, - IntPtr data, + byte[] data, int maximumWidth, int maximumHeight, bool flippable, diff --git a/UIX.Skia/Microsoft/Iris/OS/DllResource.cs b/UIX.Skia/Microsoft/Iris/OS/DllResource.cs index 5c86651..2604e7f 100644 --- a/UIX.Skia/Microsoft/Iris/OS/DllResource.cs +++ b/UIX.Skia/Microsoft/Iris/OS/DllResource.cs @@ -13,8 +13,7 @@ namespace Microsoft.Iris.OS { private string _dll; private string _identifier; - private IntPtr _buffer; - private uint _length; + private byte[] _buffer; internal DllResource(string uri, string dll, string identifier) : base(uri, true) @@ -28,9 +27,9 @@ namespace Microsoft.Iris.OS protected override void StartAcquisition(bool forceSynchronous) { string errorDetails = null; - if (_buffer == IntPtr.Zero && !NativeApi.SpLoadBinaryResource(_dll, _identifier, !DllResources.StaticDllResourcesOnly, out _buffer, out _length)) + if (_buffer == null && !NativeApi.SpLoadBinaryResource(_dll, _identifier, !DllResources.StaticDllResourcesOnly, out _buffer)) errorDetails = string.Format("Resource not found: res://{0}!{1}", _dll, _identifier); - NotifyAcquisitionComplete(_buffer, _length, false, errorDetails); + NotifyAcquisitionComplete(_buffer, false, errorDetails); } protected override void CancelAcquisition() diff --git a/UIX.Skia/Microsoft/Iris/OS/FileResource.cs b/UIX.Skia/Microsoft/Iris/OS/FileResource.cs index c9ff822..6c379c2 100644 --- a/UIX.Skia/Microsoft/Iris/OS/FileResource.cs +++ b/UIX.Skia/Microsoft/Iris/OS/FileResource.cs @@ -6,6 +6,7 @@ using Microsoft.Iris.Data; using System; +using System.IO; namespace Microsoft.Iris.OS { @@ -35,47 +36,38 @@ namespace Microsoft.Iris.OS int num = (int)NativeApi.SpFileDownload(_filePath, _pendingCallback, IntPtr.Zero, out _handle); } - private void OnFileDownloadComplete(IntPtr handle, int error, uint length, IntPtr context) + private unsafe void OnFileDownloadComplete(IntPtr handle, int error, uint length, IntPtr context) { - IntPtr buffer = IntPtr.Zero; + byte[] buffer = null; string errorDetails = null; if (error == 0) - buffer = NativeApi.DownloadGetBuffer(_handle); + buffer = new Span(NativeApi.DownloadGetBuffer(_handle).ToPointer(), (int)length).ToArray(); else errorDetails = string.Format("Failed to complete download from '{0}'", _filePath); int num = (int)NativeApi.SpDownloadClose(_handle); _handle = IntPtr.Zero; _pendingCallback = null; - NotifyAcquisitionComplete(buffer, length, true, errorDetails); + NotifyAcquisitionComplete(buffer, true, errorDetails); } private void SynchronousDownload() { - IntPtr num1 = IntPtr.Zero; - uint num2 = 0; + MemoryStream outStream = new MemoryStream(); + long fileSize = 0; string errorDetails = null; - IntPtr file = Win32Api.CreateFile(_filePath, 2147483648U, 1U, IntPtr.Zero, 3U, 0U, IntPtr.Zero); - if (file == Win32Api.INVALID_HANDLE_VALUE) + FileInfo file = new(_filePath); + + if (!file.Exists) { errorDetails = string.Format("File not found: '{0}'", _filePath); } else { - num2 = Win32Api.GetFileSize(file, IntPtr.Zero); - if (num2 != uint.MaxValue) - { - num1 = AllocNativeBuffer(num2); - uint lpNumberOfBytesRead; - if (!(num1 == IntPtr.Zero) && (!Win32Api.ReadFile(file, num1, num2, out lpNumberOfBytesRead, IntPtr.Zero) || (int)lpNumberOfBytesRead != (int)num2)) - { - FreeNativeBuffer(num1); - num1 = IntPtr.Zero; - } - } + using FileStream fstream = file.OpenRead(); + fstream.CopyTo(outStream); } - if (file != IntPtr.Zero) - Win32Api.CloseHandle(file); - NotifyAcquisitionComplete(num1, num2, true, errorDetails); + byte[] bytes = outStream.ToArray(); + NotifyAcquisitionComplete(bytes, true, errorDetails); } protected override void CancelAcquisition() diff --git a/UIX.Skia/Microsoft/Iris/OS/HttpResource.cs b/UIX.Skia/Microsoft/Iris/OS/HttpResource.cs index b052b38..8923dce 100644 --- a/UIX.Skia/Microsoft/Iris/OS/HttpResource.cs +++ b/UIX.Skia/Microsoft/Iris/OS/HttpResource.cs @@ -6,6 +6,8 @@ using Microsoft.Iris.Data; using System; +using System.Net.Http; +using System.Runtime.CompilerServices; namespace Microsoft.Iris.OS { @@ -21,20 +23,22 @@ namespace Microsoft.Iris.OS public override string Identifier => _uri; - protected override void StartAcquisition(bool forceSynchronous) + protected override async void StartAcquisition(bool forceSynchronous) { - _pendingCallback = new NativeApi.DownloadCompleteHandler(OnHttpDownloadComplete); - int num = (int)NativeApi.SpHttpDownload(_uri, _pendingCallback, IntPtr.Zero, out _handle); +#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed + HttpResources.Client.GetAsync(_uri).ContinueWith(resp => OnHttpDownloadComplete(resp.Result)); +#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } - private void OnHttpDownloadComplete(IntPtr handle, int error, uint length, IntPtr context) + private unsafe void OnHttpDownloadComplete(HttpResponseMessage resp) { - IntPtr buffer = IntPtr.Zero; + byte[] buffer = null; string errorDetails = null; + int error = resp.IsSuccessStatusCode ? 0 : 3; switch (error) { case 0: - buffer = NativeApi.DownloadGetBuffer(_handle); + buffer = resp.Content.ReadAsByteArrayAsync().Result; break; case 1: errorDetails = string.Format("Invalid URI: '{0}'", _uri); @@ -46,10 +50,9 @@ namespace Microsoft.Iris.OS errorDetails = string.Format("Failed to complete download from '{0}'", _uri); break; } - int num = (int)NativeApi.SpDownloadClose(_handle); _handle = IntPtr.Zero; _pendingCallback = null; - NotifyAcquisitionComplete(buffer, length, true, errorDetails); + NotifyAcquisitionComplete(buffer, true, errorDetails); } protected override void CancelAcquisition() diff --git a/UIX.Skia/Microsoft/Iris/OS/HttpResources.cs b/UIX.Skia/Microsoft/Iris/OS/HttpResources.cs index 4b0c72a..5d5f046 100644 --- a/UIX.Skia/Microsoft/Iris/OS/HttpResources.cs +++ b/UIX.Skia/Microsoft/Iris/OS/HttpResources.cs @@ -7,25 +7,27 @@ using Microsoft.Iris.Data; using Microsoft.Iris.Session; using System; +using System.Net.Http; namespace Microsoft.Iris.OS { - internal class HttpResources : IResourceProvider + internal class HttpResources : IResourceProvider, IDisposable { private static HttpResources s_instance = new HttpResources(); private static EventHandler s_activationChangeHandler; + private static HttpClient s_client; public static void Startup() { ResourceManager.Instance.RegisterSource("http", s_instance); - NativeApi.SpHttpStartup(); + s_client = new HttpClient(); } public static void Shutdown() { if (s_activationChangeHandler != null) UISession.Default.Form.ActivationChange -= s_activationChangeHandler; - NativeApi.SpHttpShutdown(); + s_client.Dispose(); } private static void OnActivationChanged(object sender, EventArgs args) => NativeApi.SpHttpFlushProxyCache(); @@ -39,5 +41,9 @@ namespace Microsoft.Iris.OS } return new HttpResource(url, forceSynchronous); } + + public void Dispose() => Shutdown(); + + public static HttpClient Client => s_client; } } diff --git a/UIX.Skia/Microsoft/Iris/OS/NativeApi.cs b/UIX.Skia/Microsoft/Iris/OS/NativeApi.cs index 53326ec..c62bc1a 100644 --- a/UIX.Skia/Microsoft/Iris/OS/NativeApi.cs +++ b/UIX.Skia/Microsoft/Iris/OS/NativeApi.cs @@ -10,6 +10,7 @@ using Microsoft.Iris.Render; using Microsoft.Iris.RenderAPI; using Microsoft.Iris.RenderAPI.Drawing; using System; +using System.Reflection; using System.Runtime.InteropServices; using System.Security; using System.Text; @@ -69,13 +70,22 @@ namespace Microsoft.Iris.OS return !(buffer == IntPtr.Zero) ? buffer : throw new OutOfMemoryException(); } - [DllImport("UIXRender.dll", CharSet = CharSet.Unicode)] - public static extern bool SpLoadBinaryResource( - string moduleBaseName, - string resourceName, - bool allowLoadAsCode, - out IntPtr pBits, - out uint size); + public static bool SpLoadBinaryResource(string moduleBaseName, string resourceName, bool allowLoadAsCode, out byte[] pBits) + { + pBits = null; + Assembly assembly = Assembly.GetExecutingAssembly(); + System.IO.MemoryStream stream = new System.IO.MemoryStream(); + + var ress = assembly.GetManifestResourceNames(); + using (var input = assembly.GetManifestResourceStream(resourceName)) + { + if (input == null) return false; + input.CopyTo(stream); + } + + pBits = stream.GetBuffer(); + return true; + } [DllImport("UIXRender.dll", CharSet = CharSet.Unicode)] public static extern bool SpLoadFontResource(string moduleBaseName, string resourceName); @@ -480,8 +490,12 @@ namespace Microsoft.Iris.OS uint entryCount, [MarshalAs(UnmanagedType.LPArray)] NativeApi.NativeDataMappingEntry[] entries); - [DllImport("UIXRender.dll", CharSet = CharSet.Unicode)] - public static extern uint SpRegisterNativeServicesCallbacks([MarshalAs(UnmanagedType.Interface)] IRawUIXServices rawServices); + public static uint SpRegisterNativeServicesCallbacks(IRawUIXServices rawServices) + { + Debug.Trace.WriteLine(Debug.TraceCategory.NativeCodeModel, "Attempted to call {0} with {1}='{2}'", + nameof(SpRegisterNativeServicesCallbacks), nameof(rawServices), rawServices); + return 0; + } [DllImport("UIXRender.dll", CharSet = CharSet.Unicode)] public static extern void SpUnregisterNativeServicesCallbacks(); @@ -518,10 +532,83 @@ namespace Microsoft.Iris.OS string source, out IntPtr nativeImage); - [DllImport("UIXRender.dll")] - public static extern HRESULT SpCreateNotifyWindow( - out IntPtr handle, - NativeApi.NotifyWindowCallback callback); + public static HRESULT SpCreateNotifyWindow(out IntPtr handle, NativeApi.NotifyWindowCallback callback) + { + ulong hresult = 0; + int intHresult = 0; + Vanara.PInvoke.Win32Error lastError; + string winTitle = "UIX Host Window"; + Vanara.PInvoke.User32.SafeHWND uixHostWindow = null; + Vanara.PInvoke.HINSTANCE module; + + Vanara.PInvoke.User32.WindowProc wndProc = (Vanara.PInvoke.HWND hwnd, uint uMsg, IntPtr wParam, IntPtr lParam) => + { + if (uMsg == 0x3D && callback != null) + { + callback(NotificationType.GetObject, (int)(((uint)wParam.ToInt32()) & 0xffffffff), (int)(((uint)lParam.ToInt32()) & 0xffffffff)); + } + else + { + Vanara.PInvoke.User32.DefWindowProc(hwnd, uMsg, wParam, lParam); + } + return IntPtr.Zero; + }; + + var winClass = Vanara.PInvoke.User32.RegisterClassEx(new Vanara.PInvoke.User32.WNDCLASSEX + { + lpfnWndProc = wndProc, + cbSize = 0x50, + hInstance = Vanara.PInvoke.Kernel32.GetModuleHandle(), + lpszClassName = "UIX Host Window" + }); + if (winClass == 0) + { + lastError = Vanara.PInvoke.Kernel32.GetLastError(); + hresult = hresult & 0xffffffff; + } + else + { + hresult = 0; + } + + handle = IntPtr.Zero; + + if (-1 < (int)hresult) + { + module = Vanara.PInvoke.Kernel32.GetModuleHandle(); + uixHostWindow = + Vanara.PInvoke.User32.CreateWindowEx(Vanara.PInvoke.User32.WindowStylesEx.WS_EX_CONTROLPARENT | Vanara.PInvoke.User32.WindowStylesEx.WS_EX_APPWINDOW, + "UIX Host Window", "", 0, -0x80000000, -0x80000000, -0x80000000, + -0x80000000, Vanara.PInvoke.HWND.NULL, IntPtr.Zero, module, IntPtr.Zero); + if (uixHostWindow.IsNull) + { + var err = Marshal.GetLastWin32Error(); + lastError = Vanara.PInvoke.Kernel32.GetLastError(); + //hresult = FUN_3109b944(lastError); + hresult = hresult & 0xffffffff; + } + else + { + hresult = 0; + } + intHresult = (int)hresult; + if (intHresult < 0) goto LAB_310bf9ed; + hresult = 0; + handle = uixHostWindow.DangerousGetHandle(); + } + LAB_310bf9ed: + if (intHresult != 0) + { + if (uixHostWindow != null && !uixHostWindow.IsNull) + { + Vanara.PInvoke.User32.DestroyWindow(uixHostWindow); + uixHostWindow = null; + } + module = Vanara.PInvoke.Kernel32.GetModuleHandle(); + Vanara.PInvoke.User32.UnregisterClass(winTitle, module); + } + return new HRESULT((int)hresult); + } [DllImport("UIXRender.dll")] public static extern void SpDestroyNotifyWindow(); @@ -824,6 +911,21 @@ namespace Microsoft.Iris.OS public static string PtrToStringUni(IntPtr psz, int length) => length == 0 ? "" : Marshal.PtrToStringUni(psz, length); + [DllImport("user32.dll", SetLastError = true, EntryPoint = "CreateWindowExA")] + public static extern IntPtr CreateWindowExA( + ushort dwExStyle, + string lpClassName, + string lpWindowName, + ushort dwStyle, + int X, + int Y, + int nWidth, + int nHeight, + HWND hWndParent, + IntPtr hMenu, + IntPtr hInstance, + IntPtr lpParam); + public delegate void DownloadCompleteHandler( IntPtr handle, int error, diff --git a/UIX.Skia/Microsoft/Iris/OS/NativeXmlReader.cs b/UIX.Skia/Microsoft/Iris/OS/NativeXmlReader.cs index 420865f..d258695 100644 --- a/UIX.Skia/Microsoft/Iris/OS/NativeXmlReader.cs +++ b/UIX.Skia/Microsoft/Iris/OS/NativeXmlReader.cs @@ -7,6 +7,7 @@ using Microsoft.Iris.Data; using Microsoft.Iris.Markup; using System; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices; namespace Microsoft.Iris.OS @@ -21,12 +22,14 @@ namespace Microsoft.Iris.OS private int _linePosition; private bool _beforeFirstAttribute; - public NativeXmlReader(Resource resource) - : this(false) - => Init(resource.Buffer, (int)resource.Length, false); + public unsafe NativeXmlReader(Resource resource) : this(false) + { + var span = new Span(resource.Buffer); + void* ptr = Unsafe.AsPointer(ref span.GetPinnableReference()); + Init(new IntPtr(ptr), (int)resource.Length, false); + } - public NativeXmlReader(string content, bool isFragment) - : this(false) + public NativeXmlReader(string content, bool isFragment) : this(false) { _gcHandle = GCHandle.Alloc(content, GCHandleType.Pinned); Init(_gcHandle.AddrOfPinnedObject(), content.Length * 2, isFragment); diff --git a/UIX.Skia/UIX.Skia.csproj b/UIX.Skia/UIX.Skia.csproj index 57c8d2c..1298f63 100644 --- a/UIX.Skia/UIX.Skia.csproj +++ b/UIX.Skia/UIX.Skia.csproj @@ -14,6 +14,8 @@ + + C:\Windows\Microsoft.NET\Framework\v2.0.50727\Accessibility.dll