forked from ClearFoundry/ClearScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRawCOMHelpers.cs
More file actions
160 lines (130 loc) · 5.29 KB
/
RawCOMHelpers.cs
File metadata and controls
160 lines (130 loc) · 5.29 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
using System;
using System.Runtime.InteropServices;
namespace Microsoft.ClearScript.Util
{
internal static class RawCOMHelpers
{
public static readonly int VariantSize = sizeof(ushort) * 4 + IntPtr.Size * 2;
public static IntPtr CreateInstance<T>(string progID)
{
IntPtr pInterface;
var clsid = CLSIDFromProgID(progID);
var iid = typeof(T).GUID;
HResult.Check(NativeMethods.CoCreateInstance(ref clsid, IntPtr.Zero, 1, ref iid, out pInterface));
return pInterface;
}
public static IntPtr QueryInterface<T>(IntPtr pUnknown)
{
IntPtr pInterface;
var iid = typeof(T).GUID;
HResult.Check(Marshal.QueryInterface(pUnknown, ref iid, out pInterface));
return pInterface;
}
public static IntPtr QueryInterfaceNoThrow<T>(IntPtr pUnknown)
{
IntPtr pInterface;
var iid = typeof(T).GUID;
var result = Marshal.QueryInterface(pUnknown, ref iid, out pInterface);
return (result == HResult.S_OK) ? pInterface : IntPtr.Zero;
}
public static T GetMethodDelegate<T>(IntPtr pInterface, int methodIndex) where T : class
{
var pVTable = Marshal.ReadIntPtr(pInterface);
var pMethod = Marshal.ReadIntPtr(pVTable + methodIndex * IntPtr.Size);
return Marshal.GetDelegateForFunctionPointer(pMethod, typeof(T)) as T;
}
public static void ReleaseAndEmpty(ref IntPtr pInterface)
{
if (pInterface != IntPtr.Zero)
{
Marshal.Release(pInterface);
pInterface = IntPtr.Zero;
}
}
private static Guid CLSIDFromProgID(string progID)
{
Guid clsid;
if (!Guid.TryParseExact(progID, "B", out clsid))
{
HResult.Check(NativeMethods.CLSIDFromProgID(progID, out clsid));
}
return clsid;
}
#region Nested type: HResult
public static class HResult
{
// ReSharper disable InconsistentNaming
public const int SEVERITY_SUCCESS = 0;
public const int SEVERITY_ERROR = 1;
public const int FACILITY_NULL = 0;
public const int FACILITY_RPC = 1;
public const int FACILITY_DISPATCH = 2;
public const int FACILITY_STORAGE = 3;
public const int FACILITY_ITF = 4;
public const int FACILITY_WIN32 = 7;
public const int FACILITY_WINDOWS = 8;
public const int FACILITY_CONTROL = 10;
public const int FACILITY_INTERNET = 12;
public const int FACILITY_URT = 19;
public const int S_OK = 0;
public const int S_FALSE = 1;
public static readonly int E_NOINTERFACE = 0x80004002U.ToSigned();
public static readonly int E_ABORT = 0x80004004U.ToSigned();
public static readonly int E_FAIL = 0x80004005U.ToSigned();
public static readonly int E_INVALIDARG = 0x80070057U.ToSigned();
public static readonly int DISP_E_UNKNOWNNAME = 0x80020006U.ToSigned();
public static readonly int DISP_E_MEMBERNOTFOUND = 0x80020003U.ToSigned();
public static readonly int SCRIPT_E_REPORTED = 0x80020101U.ToSigned();
public static readonly int CLEARSCRIPT_E_HOSTEXCEPTION = MakeResult(SEVERITY_ERROR, FACILITY_URT, 0xBAFF);
public static readonly int CLEARSCRIPT_E_SCRIPTITEMEXCEPTION = MakeResult(SEVERITY_ERROR, FACILITY_URT, 0xB0FF);
// ReSharper restore InconsistentNaming
public static void Check(uint result)
{
Check(result.ToSigned());
}
public static void Check(int result)
{
Marshal.ThrowExceptionForHR(result);
}
public static bool Succeeded(uint result)
{
return GetSeverity(result) == SEVERITY_SUCCESS;
}
public static bool Succeeded(int result)
{
return GetSeverity(result) == SEVERITY_SUCCESS;
}
public static int GetSeverity(uint result)
{
return GetSeverity(result.ToSigned());
}
public static int GetSeverity(int result)
{
return (result >> 31) & 0x1;
}
public static int GetFacility(uint result)
{
return GetFacility(result.ToSigned());
}
public static int GetFacility(int result)
{
return (result >> 16) & 0x1FFF;
}
public static int GetCode(uint result)
{
return GetCode(result.ToSigned());
}
public static int GetCode(int result)
{
return result & 0xFFFF;
}
public static int MakeResult(int severity, int facility, int code)
{
return ((uint)(code & 0xFFFF) | ((uint)(facility & 0x1FFF) << 16) | ((uint)(severity & 0x1) << 31)).ToSigned();
}
}
#endregion
}
}