Moved from IntPtr to byte[] in more places

This commit is contained in:
Yoshi Askharoun
2021-10-04 14:17:40 -05:00
parent d0f576c266
commit 5ba04306df
19 changed files with 213 additions and 127 deletions
@@ -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<byte>(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(
@@ -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;
+9 -12
View File
@@ -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;
}
+6 -14
View File
@@ -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;
@@ -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);
}
}
@@ -112,7 +112,7 @@ namespace Microsoft.Iris.Drawing
}
else
{
SetBuffer(_resource.Buffer, _resource.Length);
SetBuffer(_resource.Buffer);
if (_resource.Length <= 0U)
return;
if (!ProcessBuffer())
+3 -3
View File
@@ -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,
+3 -4
View File
@@ -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()
+14 -22
View File
@@ -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<byte>(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()
+11 -8
View File
@@ -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()
+9 -3
View File
@@ -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;
}
}
+115 -13
View File
@@ -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,
@@ -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<byte>(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);