8000 Move OLE sources to Core assembly (#12859) · dotnet/winforms@23cb171 · GitHub
[go: up one dir, main page]

Skip to content

Commit 23cb171

Browse files
authored
Move OLE sources to Core assembly (#12859)
Move OLE sources to Core assembly This moves and renames files to build in the Core assembly. - Adds a few more scenarios missed to IOleServices - Fix nits from last PR - Adds global suppressions for trimming for moved code - Rename a few other files that were moved previously It is sort of odd that we force GetImage through HBITMAP instead of using the serialized System.Drawing.Bitmap. This tweaks the colors (at least transparent ones) as Clipboard_SetImage_InvokeBitmap_GetReturnsExpected shows. Not sure this is the right behavior, but it is what we have currently.
1 parent 524fbef commit 23cb171

29 files changed

+173
-86
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
// Compatibility suppressions.
5+
6+
[assembly: SuppressMessage("Usage", "CA2201:Do not raise reserved exception types", Justification = "Compat", Scope = "member", Target = "~M:System.Private.Windows.Ole.Composition`2.NativeToManagedAdapter.ReadByteStreamFromHGLOBAL(Windows.Win32.Foundation.HGLOBAL,System.Boolean@)~System.IO.MemoryStream")]
7+
[assembly: SuppressMessage("Usage", "CA2201:Do not raise reserved exception types", Justification = "Compat", Scope = "member", Target = "~M:System.Private.Windows.Ole.Composition`2.NativeToRuntimeAdapter.EnumFormatEtc(System.Runtime.InteropServices.ComTypes.DATADIR)~System.Runtime.InteropServices.ComTypes.IEnumFORMATETC")]
8+
9+
// OLE related trimming suppressions. Suppressing here so we can find and fix in the future as we try to be trim compatible.
10+
// Not disabling globally to try and keep new code trim compatible and clean.
11+
[assembly: SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Trimming not supported", Scope = "member", Target = "~M:System.Private.Windows.Nrbf.SerializationRecordExtensions.TryGetObjectFromJson``1(System.Formats.Nrbf.SerializationRecord,System.Private.Windows.BinaryFormat.ITypeResolver,System.Object@)~System.Boolean")]
12+
[assembly: SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Trimming not supported", Scope = "member", Target = "~M:System.Private.Windows.Ole.BinaryFormatUtilities`1.WriteObjectToStream(System.IO.MemoryStream,System.Object,System.Boolean)")]
13+
[assembly: SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Trimming not supported", Scope = "member", Target = "~M:System.Private.Windows.Ole.BinaryFormatUtilities`1.ReadObjectFromStream``1(System.IO.MemoryStream,System.Private.Windows.Ole.DataRequest@)~System.Object")]
14+
[assembly: SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "Trimming not supported", Scope = "member", Target = "~M:System.Private.Windows.Ole.BinaryFormatUtilities`1.TypeNameIsAssignableToType(System.Reflection.Metadata.TypeName,System.Type,System.Private.Windows.BinaryFormat.ITypeResolver)~System.Boolean")]
15+
[assembly: SuppressMessage("Trimming", "IL2046:'RequiresUnreferencedCodeAttribute' annotations must match across all interface implementations or overrides.", Justification = "Trimming not supported", Scope = "member", Target = "~M:System.Private.Windows.Ole.TypeBinder`1.BindToType(System.Reflection.Metadata.TypeName)~System.Type")]
16+
[assembly: SuppressMessage("Trimming", "IL2093:'DynamicallyAccessedMemberTypes' on the return value of method don't match overridden return value of method. All overridden members must have the same 'DynamicallyAccessedMembersAttribute' usage.", Justification = "Trimming not supported", Scope = "member", Target = "~M:System.Private.Windows.Ole.TypeBinder`1.BindToType(System.Reflection.Metadata.TypeName)~System.Type")]

src/System.Private.Windows.Core/src/NativeMethods.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ BI_COMPRESSION
33
BitBlt
44
BOOL
55
CallWindowProc
6+
CFSTR_DROPDESCRIPTION
67
CFSTR_FILENAME
78
CFSTR_FILENAMEA
8-
CFSTR_DROPDESCRIPTION
99
CFSTR_INDRAGLOOP
1010
CLIPBOARD_FORMAT
1111
CLIPBRD_E_BAD_DATA
@@ -62,6 +62,8 @@ DrawIconEx
6262
DROPDESCRIPTION
6363
DROPFILES
6464
DROPIMAGETYPE
65+
DSH_FLAGS
66+
DVASPECT
6567
DV_E_*
6668
E_ABORT
6769
E_ACCESSDENIED
@@ -136,13 +138,19 @@ HWND
136138
HWND_*
137139
IDataObject
138140
IDI_*
141+
IDispatchEx
139142
IDragSourceHelper2
143+
IDropSource
144+
IDropSourceNotify
145+
IDropTarget
146+
IDropTargetHelper
147+
IEnumFORMATETC
140148
IEnumUnknown
141149
IGlobalInterfaceTable
142150
ImageLockMode
151+
INK_SERIALIZED_FORMAT
143152
INPLACE_E_NOTOOLSPACE
144153
IntersectClipRect
145-
INK_SERIALIZED_FORMAT
146154
IPicture
147155
IPictureDisp
148156
IStream

src/System.Private.Windows.Core/src/Resources/SR.resx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,40 @@
131131
<data name="ClipboardOrDragDrop_JsonDeserializationFailed" xml:space="preserve">
132132
<value>Failed to deserialize JSON data.</value>
133133
</data>
134+
<data name="ExternalException" xml:space="preserve">
135+
<value>External exception</value>
136+
</data>
137+
<data name="BinaryFormatterNotSupported" xml:space="preserve">
138+
<value>BinaryFormatter serialization and deserialization are disabled within this application. See https://aka.ms/binaryformatter for more information.</value>
139+
</data>
140+
<data name="BinaryFormatter_NotSupported_InClipboardOrDragDrop" xml:space="preserve">
141+
<value>BinaryFormatter is not supported in clipboard or drag-and-drop operations.</value>
142+
</data>
143+
<data name="BinaryFormatter_NotSupported_InClipboardOrDragDrop_UseTypedAPI" xml:space="preserve">
144+
<value>BinaryFormatter is not supported in clipboard or drag-and-drop operations. Please enable it and use 'TryGetData&lt;T&gt;' APIs with a 'resolver' function that defines a set of allowed types to deserialize '{0}'.</value>
145+
</data>
146+
<data name="ClipboardOrDragDrop_UseTypedAPI" xml:space="preserve">
147+
<value>Please use 'TryGetData&lt;T&gt;' APIs with a 'resolver' function that defines a set of allowed types to deserialize '{0}'.</value>
148+
</data>
149+
<data name=< 4146 span class="pl-s">"ClipboardOrDragDrop_TypedAPI_InvalidResolver" xml:space="preserve">
150+
<value>Type {0} is not found. If this type is allowed, please ensure that the 'resolver' function provided in 'TryGetData&lt;T&gt;' APIs supports it.</value>
151+
</data>
152+
<data name="ClipboardOrDragDrop_InvalidType" xml:space="preserve">
153+
<value>'{0}' is not a concrete type, and could result in an unbounded deserialization attempt. Please use a concrete type or alternatively define a 'resolver' function that supports types that you are expecting to retrieve from the clipboard or use in drag-and-drop operations.</value>
154+
</data>
155+
<data name="ClipboardOrDragDrop_InvalidFormatTypeCombination" xml:space="preserve">
156+
<value>The specified type '{0}' is not compatible with the specified format '{1}'.</value>
157+
</data>
158+
<data name="ClipboardOrDragDrop_CannotJsonSerializeDataObject">
159+
<value>An object of type 'DataObject' will serialize as empty. Use 'DataObject.SetDataAsJson' APIs on your object to JSON-serialize the data within your object, then use the '{0}' API with your object.</value>
160+
</data>
161+
<data name="NotSupportedExceptionOnClipboard">
162+
<value>Clipboard contains a 'NotSupportedException' that indicates that write operation failed. '{0}'.</value>
163+
</data>
164+
<data name="UnexpectedClipboardType" xml:space="preserve">
165+
<value>Clipboard contains an unexpected type.</value>
166+
</data>
167+
<data name="UnexpectedTypeForClipboardFormat" xml:space="preserve">
168+
<value>The specified Clipboard format is not compatible with '{0}' type.</value>
169+
</data>
134170
</root>

src/System.Private.Windows.Core/src/System/Private/Windows/Nrbf/SerializationRecordExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,6 @@ private static bool IsPrimitiveArrayRecord(SerializationRecord serializationReco
577577
/// </returns>
578578
/// <exception cref="SerializationException">If the data was supposed to be our <see cref="JsonData{T}"/>, but was serialized incorrectly./></exception>
579579
/// <exception cref="NotSupportedException">If an exception occurred while JSON deserializing.</exception>
580-
[RequiresUnreferencedCode("Calls System.Private.Windows.BinaryFormat.ITypeResolver.GetType(TypeName)")]
581580
public static bool TryGetObjectFromJson<T>(this SerializationRecord record, ITypeResolver resolver, out object? @object)
582581
{
583582
@object = null;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,13 @@ private static bool TypeNameIsAssignableToType(TypeName typeName, Type type, ITy
217217
#pragma warning disable CA2300 // Do not use insecure deserializer BinaryFormatter
218218
#pragma warning disable CA2302 // Ensure BinaryFormatter.Binder is set before calling BinaryFormatter.Deserialize
219219
// cs/dangerous-binary-deserialization
220+
#pragma warning disable IL2026 // Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code
220221
return new BinaryFormatter()
221222
{
222223
Binder = binder,
223224
AssemblyFormat = FormatterAssemblyStyle.Simple
224225
}.Deserialize(stream); // CodeQL[SM03722] : BinaryFormatter is intended to be used as a fallback for unsupported types. Users must explicitly opt into this behavior.
226+
#pragma warning restore IL2026
225227
#pragma warning restore CA2300
226228
#pragma warning restore CA2302
227229
#pragma warning restore SYSLIB0050, SYSLIB0011
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Drawing;
45
using System.Runtime.Serialization;
56
using System.Text;
67
using Windows.Win32.System.Com;
8+
using Windows.Win32.System.Memory;
9+
using Windows.Win32.UI.Shell;
710
using ComTypes = System.Runtime.InteropServices.ComTypes;
811

912
namespace System.Private.Windows.Ole;
Lines changed: 7 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System.Drawing;
54
using System.Reflection.Metadata;
65
using System.Runtime.InteropServices;
76
using System.Runtime.InteropServices.ComTypes;
87
using System.Text;
8+
using Windows.Win32.UI.Shell;
9+
using Windows.Win32.System.Memory;
910
using Com = Windows.Win32.System.Com;
1011

1112
namespace System.Private.Windows.Ole;
@@ -126,7 +127,7 @@ private static bool TryGetDataFromHGLOBAL<T>(
126127
{
127128
MemoryStream stream = ReadByteStreamFromHGLOBAL(hglobal, out bool isSerializedObject);
128129
return !isSerializedObject
129-
? stream
130+
? stream
130131
: DataFormatNames.RestrictDeserializationToSafeTypes(request.Format)
131132
? BinaryFormatUtilities<TRuntime>.ReadRestrictedObjectFromStream<T>(stream, in request)
132133
: BinaryFormatUtilities<TRuntime>.ReadObjectFromStream<T>(stream, in request);
@@ -256,10 +257,9 @@ private static bool TryGetObjectFromDataObject<T>(
256257
try
257258
{
258259
// Try to get the data as a bitmap first.
259-
if ((typeof(Bitmap) == typeof(T) || typeof(Image) == typeof(T))
260-
&& TryGetBitmapData(dataObject, request.Format, out Bitmap? bitmap))
260+
if (request.Format == DataFormatNames.Bitmap
261+
&& TRuntime.TryGetBitmapFromDataObject(dataObject, out data))
261262
{
262-
data = (T)(object)bitmap;
263263
return true;
264264
}
265265

@@ -397,59 +397,11 @@ private static unsafe bool TryGetIStreamData<T>(
397397
}
398398
}
399399

400-
private static bool TryGetBitmapData(Com.IDataObject* dataObject, string format, [NotNullWhen(true)] out Bitmap? data)
401-
{
402-
data = default;
403-
if (format != DataFormatNames.Bitmap)
404-
{
405-
return false;
406-
}
407-
408-
Com.FORMATETC formatEtc = new()
409-
{
410-
cfFormat = (ushort)DataFormatsCore<TDataFormat>.GetOrAddFormat(format).Id,
411-
dwAspect = (uint)Com.DVASPECT.DVASPECT_CONTENT,
412-
lindex = -1,
413-
tymed = (uint)Com.TYMED.TYMED_GDI
414-
};
415-
416-
Com.STGMEDIUM medium = default;
417-
418-
if (dataObject->QueryGetData(formatEtc).Succeeded)
419-
{
420-
HRESULT hr = dataObject->GetData(formatEtc, out medium);
421-
// One of the ways this can happen is when we attempt to put binary formatted data onto the
422-
// clipboard, which will succeed as Windows ignores all errors when putting data on the clipboard.
423-
// The data state, however, is not good, and this error will be returned by Windows when asking to
424-
// get the data out.
425-
Debug.WriteLineIf(hr == HRESULT.CLIPBRD_E_BAD_DATA, "CLIPBRD_E_BAD_DATA returned when trying to get clipboard data.");
426-
}
427-
428-
try
429-
{
430-
// GDI+ doesn't own this HBITMAP, but we can't delete it while the object is still around. So we
431-
// have to do the really expensive thing of cloning the image so we can release the HBITMAP.
432-
if ((uint)medium.tymed == (uint)TYMED.TYMED_GDI
433-
&& !medium.hGlobal.IsNull
434-
&& Image.FromHbitmap(medium.hGlobal) is Bitmap clipboardBitmap)
435-
{
436-
data = (Bitmap)clipboardBitmap.Clone();
437-
clipboardBitmap.Dispose();
438-
return true;
439-
}
440-
}
441-
finally
442-
{
443-
PInvokeCore.ReleaseStgMedium(ref medium);
444-
}
445-
446-
return false;
447-
}
448-
449400
private static void ThrowIfFormatAndTypeRequireResolver<T>(string format)
450401
{
451402
// Restricted format is either read directly from the HGLOBAL or serialization record is read manually.
452403
if (!DataFormatNames.IsRestrictedFormat(format)
404+
&& !TRuntime.AllowWithoutResolver<T>()
453405
// This check is a convenience for simple usages if TryGetData APIs that don't take the resolver.
454406
&& IsUnboundedType())
455407
{
@@ -466,8 +418,7 @@ static bool IsUnboundedType()
466418
}
467419

468420
Type type = typeof(T);
469-
// Image is a special case because we are reading Bitmaps directly from the SerializationRecord.
470-
return type.IsInterface || (typeof(T) != typeof(Image) && type.IsAbstract);
421+
return type.IsInterface || type.IsAbstract;
471422
}
472423
}
473424

0 commit comments

Comments
 (0)
0