1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*============================================================
**
** Class: OAVariantLib
**
**
** Purpose: This class only exists to provide support for
** implenting IDispatch on managed objects. It is
** used to provide OleAut style coercion rules.
**
**
===========================================================*/
namespace Microsoft.Win32 {
using System;
using System.Diagnostics.Contracts;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using CultureInfo = System.Globalization.CultureInfo;
internal static class OAVariantLib
{
#region Constants
// Constants for VariantChangeType from OleAuto.h
public const int NoValueProp = 0x01;
public const int AlphaBool = 0x02;
public const int NoUserOverride = 0x04;
public const int CalendarHijri = 0x08;
public const int LocalBool = 0x10;
internal static readonly Type [] ClassTypes = {
typeof(Empty),
typeof(void),
typeof(Boolean),
typeof(Char),
typeof(SByte),
typeof(Byte),
typeof(Int16),
typeof(UInt16),
typeof(Int32),
typeof(UInt32),
typeof(Int64),
typeof(UInt64),
typeof(Single),
typeof(Double),
typeof(String),
typeof(void),
typeof(DateTime),
typeof(TimeSpan),
typeof(Object),
typeof(Decimal),
null, // Enums - what do we do here?
typeof(Missing),
typeof(DBNull),
};
// Keep these numbers in [....] w/ the above array.
private const int CV_OBJECT=0x12;
#endregion
#region Internal Methods
/**
* Changes a Variant from one type to another, calling the OLE
* Automation VariantChangeTypeEx routine. Note the legal types here are
* restricted to the subset of what can be legally found in a VB
* Variant and the types that CLR supports explicitly in the
* CLR Variant class.
*/
[System.Security.SecurityCritical] // auto-generated
internal static Variant ChangeType(Variant source, Type targetClass, short options, CultureInfo culture)
{
if (targetClass == null)
throw new ArgumentNullException("targetClass");
if (culture == null)
throw new ArgumentNullException("culture");
Variant result = new Variant ();
ChangeTypeEx(ref result, ref source,
#if FEATURE_USE_LCID
culture.LCID,
#else
// @CORESYSTODO: what does CoreSystem expect for this argument?
0,
#endif
targetClass.TypeHandle.Value, GetCVTypeFromClass(targetClass), options);
return result;
}
#endregion
#region Private Helpers
private static int GetCVTypeFromClass(Type ctype)
{
Contract.Requires(ctype != null);
#if _DEBUG
BCLDebug.Assert(ClassTypes[CV_OBJECT] == typeof(Object), "OAVariantLib::ClassTypes[CV_OBJECT] == Object.class");
#endif
int cvtype=-1;
for (int i=0; i<ClassTypes.Length; i++) {
if (ctype.Equals(ClassTypes[i])) {
cvtype=i;
break;
}
}
// OleAut Binder works better if unrecognized
// types were changed to Object. So don't throw here.
if (cvtype == -1)
cvtype = CV_OBJECT;
return cvtype;
}
#endregion
#region Private FCalls
[System.Security.SecurityCritical] // auto-generated
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ResourceExposure(ResourceScope.None)]
private static extern void ChangeTypeEx(ref Variant result, ref Variant source, int lcid, IntPtr typeHandle, int cvType, short flags);
#endregion
}
}
|