forked from winsw/winsw
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathWmi.cs
executable file
·217 lines (183 loc) · 7.29 KB
/
Wmi.cs
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
using System;
using System.Management;
using System.Reflection;
using DynamicProxy;
namespace WMI
{
//Reference: http://msdn2.microsoft.com/en-us/library/aa389390(VS.85).aspx
public enum ReturnValue
{
Success = 0,
NotSupported = 1,
AccessDenied = 2,
DependentServicesRunning = 3,
InvalidServiceControl = 4,
ServiceCannotAcceptControl = 5,
ServiceNotActive = 6,
ServiceRequestTimeout = 7,
UnknownFailure = 8,
PathNotFound = 9,
ServiceAlreadyRunning = 10,
ServiceDatabaseLocked = 11,
ServiceDependencyDeleted = 12,
ServiceDependencyFailure = 13,
ServiceDisabled = 14,
ServiceLogonFailure = 15,
ServiceMarkedForDeletion = 16,
ServiceNoThread = 17,
StatusCircularDependency = 18,
StatusDuplicateName = 19,
StatusInvalidName = 20,
StatusInvalidParameter = 21,
StatusInvalidServiceAccount = 22,
StatusServiceExists = 23,
ServiceAlreadyPaused = 24,
NoSuchService = 200
}
/// <summary>
/// Signals a problem in WMI related operations
/// </summary>
public class WmiException : Exception
{
public readonly ReturnValue ErrorCode;
public WmiException(string msg, ReturnValue code)
: base(msg)
{
ErrorCode = code;
}
public WmiException(ReturnValue code)
: this(code.ToString(), code)
{
}
}
/// <summary>
/// Associated a WMI class name to the proxy interface (which should extend from IWmiCollection)
/// </summary>
public class WmiClassName : Attribute
{
public readonly string Name;
public WmiClassName(string name) { Name = name; }
}
/// <summary>
/// Marker interface to denote a collection in WMI.
/// </summary>
public interface IWmiCollection {}
/// <summary>
/// Marker interface to denote an individual managed object
/// </summary>
public interface IWmiObject
{
/// <summary>
/// Reflect updates made to this object to the WMI provider.
/// </summary>
void Commit();
}
public class WmiRoot
{
private readonly ManagementScope scope;
public WmiRoot() : this(null) { }
public WmiRoot(string machineName)
{
ConnectionOptions options = new ConnectionOptions();
options.EnablePrivileges = true;
options.Impersonation = ImpersonationLevel.Impersonate;
options.Authentication = AuthenticationLevel.PacketPrivacy;
string path;
if (machineName != null)
path = String.Format(@"\\{0}\root\cimv2", machineName);
else
path = @"\root\cimv2";
scope = new ManagementScope(path, options);
scope.Connect();
}
private static string Capitalize(string s)
{
return char.ToUpper(s[0]) + s.Substring(1);
}
abstract class BaseHandler : IProxyInvocationHandler
{
public abstract object Invoke(object proxy, MethodInfo method, object[] args);
protected void CheckError(ManagementBaseObject result)
{
int code = Convert.ToInt32(result["returnValue"]);
if (code != 0)
throw new WmiException((ReturnValue)code);
}
}
class InstanceHandler : BaseHandler, IWmiObject
{
private readonly ManagementObject _mo;
public InstanceHandler(ManagementObject o) { _mo = o; }
public override object Invoke(object proxy, MethodInfo method, object[] args)
{
if (method.DeclaringType == typeof(IWmiObject))
{
return method.Invoke(this, args);
}
// TODO: proper property support
if (method.Name.StartsWith("set_"))
{
_mo[method.Name.Substring(4)] = args[0];
return null;
}
if (method.Name.StartsWith("get_"))
{
return _mo[method.Name.Substring(4)];
}
// method invocations
ParameterInfo[] methodArgs = method.GetParameters();
ManagementBaseObject wmiArgs = _mo.GetMethodParameters(method.Name);
for (int i = 0; i < args.Length; i++)
wmiArgs[Capitalize(methodArgs[i].Name)] = args[i];
CheckError(_mo.InvokeMethod(method.Name, wmiArgs, null));
return null;
}
public void Commit()
{
_mo.Put();
}
}
class ClassHandler : BaseHandler
{
private readonly ManagementClass _mc;
private readonly string _wmiClass;
public ClassHandler(ManagementClass mc, string wmiClass) { _mc = mc; _wmiClass = wmiClass; }
public override object Invoke(object proxy, MethodInfo method, object[] args)
{
ParameterInfo[] methodArgs = method.GetParameters();
if (method.Name.StartsWith("Select"))
{
// select method to find instances
string query = "SELECT * FROM " + _wmiClass + " WHERE ";
for (int i = 0; i < args.Length; i++)
{
if (i != 0) query += " AND ";
query += ' ' + Capitalize(methodArgs[i].Name) + " = '" + args[i] + "'";
}
ManagementObjectSearcher searcher = new ManagementObjectSearcher(_mc.Scope, new ObjectQuery(query));
ManagementObjectCollection results = searcher.Get();
// TODO: support collections
foreach (ManagementObject manObject in results)
return ProxyFactory.GetInstance().Create(new InstanceHandler(manObject), method.ReturnType, true);
return null;
}
ManagementBaseObject wmiArgs = _mc.GetMethodParameters(method.Name);
for (int i = 0; i < args.Length; i++)
wmiArgs[Capitalize(methodArgs[i].Name)] = args[i];
CheckError(_mc.InvokeMethod(method.Name, wmiArgs, null));
return null;
}
}
/// <summary>
/// Obtains an object that corresponds to a table in WMI, which is a collection of a managed object.
/// </summary>
public T GetCollection<T>() where T : IWmiCollection
{
WmiClassName cn = (WmiClassName)typeof(T).GetCustomAttributes(typeof(WmiClassName), false)[0];
ObjectGetOptions getOptions = new ObjectGetOptions();
ManagementPath path = new ManagementPath(cn.Name);
ManagementClass manClass = new ManagementClass(scope, path, getOptions);
return (T)ProxyFactory.GetInstance().Create(new ClassHandler(manClass, cn.Name), typeof(T), true);
}
}
}