1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.ServiceModel.Administration
8 using System.Collections.Generic;
9 using System.Diagnostics;
10 using System.Globalization;
12 using System.Runtime.Diagnostics;
13 using System.Runtime.InteropServices;
14 using System.Security;
15 using System.ServiceModel;
16 using System.ServiceModel.Diagnostics;
17 using System.Text.RegularExpressions;
18 using System.Threading;
20 class WbemProvider : WbemNative.IWbemProviderInit, WbemNative.IWbemServices
22 object syncRoot = new object();
23 WbemNative.IWbemDecoupledRegistrar wbemRegistrar = null;
24 WbemNative.IWbemServices wbemServices = null;
25 Dictionary<string, IWmiProvider> wmiProviders = new Dictionary<string, IWmiProvider>(StringComparer.OrdinalIgnoreCase);
28 bool initialized = false;
30 internal WbemProvider(string nameSpace, string appName)
32 this.nameSpace = nameSpace;
33 this.appName = appName;
36 internal void Initialize()
40 AppDomain.CurrentDomain.DomainUnload += new EventHandler(ExitOrUnloadEventHandler);
41 AppDomain.CurrentDomain.ProcessExit += new EventHandler(ExitOrUnloadEventHandler);
42 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(ExitOrUnloadEventHandler);
43 MTAExecute(new WaitCallback(RegisterWbemProvider), null);
44 this.initialized = true;
46 catch (SecurityException)
48 // WMI is not supported in PT, rethrow a meaningful exception (will fail the service activation)
49 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
50 new InvalidOperationException(SR.GetString(SR.PartialTrustWMINotEnabled)));
54 void RegisterWbemProvider(object state)
56 this.wbemRegistrar = (WbemNative.IWbemDecoupledRegistrar)new WbemNative.WbemDecoupledRegistrar();
57 int hr = this.wbemRegistrar.Register(0, null, null, null,
58 this.nameSpace, this.appName, this);
59 if ((int)WbemNative.WbemStatus.WBEM_S_NO_ERROR != hr)
61 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
62 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
63 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiRegistrationFailed,
64 TraceUtility.CreateSourceString(this),
65 hr.ToString("x", CultureInfo.InvariantCulture));
67 this.wbemRegistrar = null;
71 void UnRegisterWbemProvider(object state)
73 if (this.wbemRegistrar != null)
75 int hr = this.wbemRegistrar.UnRegister();
76 if ((int)WbemNative.WbemStatus.WBEM_S_NO_ERROR != hr)
78 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
79 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
80 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiUnregistrationFailed,
81 TraceUtility.CreateSourceString(this),
82 hr.ToString("x", CultureInfo.InvariantCulture));
84 this.wbemRegistrar = null;
88 void ExitOrUnloadEventHandler(object sender, EventArgs e)
90 if (this.wbemRegistrar != null)
92 MTAExecute(new WaitCallback(UnRegisterWbemProvider), null);
96 public void Register(string className, IWmiProvider wmiProvider)
100 if (!this.initialized)
105 this.wmiProviders.Add(className, wmiProvider);
109 IWmiProvider GetProvider(string className)
111 IWmiProvider wmiProvider;
112 lock (this.wmiProviders)
114 if (!this.wmiProviders.TryGetValue(className, out wmiProvider))
116 wmiProvider = NoInstanceWMIProvider.Default;
122 int WbemNative.IWbemProviderInit.Initialize(
127 WbemNative.IWbemServices wbemServices,
128 WbemNative.IWbemContext wbemContext,
129 WbemNative.IWbemProviderInitSink wbemSink
132 if (wbemServices == null || wbemContext == null || wbemSink == null)
133 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
137 MTAExecute(new WaitCallback(this.RelocateWbemServicesRCWToMTA), wbemServices);
138 wbemSink.SetStatus((int)WbemNative.tag_WBEM_EXTRA_RETURN_CODES.WBEM_S_INITIALIZED, 0);
140 catch (WbemException e)
142 wbemSink.SetStatus(e.ErrorCode, 0);
145 #pragma warning suppress 56500 // covered by FxCOP
148 wbemSink.SetStatus((int)WbemNative.WbemStatus.WBEM_E_FAILED, 0);
149 return (int)WbemNative.WbemStatus.WBEM_E_FAILED;
153 // WMI relies on destructor of this interface to perform certain task
154 // explicitly release this so that the GC won't hold on to the ref of
155 // this after the function
156 Marshal.ReleaseComObject(wbemSink);
159 return (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
162 void RelocateWbemServicesRCWToMTA(object comObject)
164 IntPtr pUnk = Marshal.GetIUnknownForObject(comObject);
165 Marshal.ReleaseComObject(comObject);
166 this.wbemServices = (WbemNative.IWbemServices)Marshal.GetObjectForIUnknown(pUnk);
167 Marshal.Release(pUnk);
170 int WbemNative.IWbemServices.OpenNamespace(
173 WbemNative.IWbemContext wbemContext,
174 ref WbemNative.IWbemServices wbemServices,
175 IntPtr wbemCallResult
178 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
181 int WbemNative.IWbemServices.CancelAsyncCall(
182 WbemNative.IWbemObjectSink wbemSink
185 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
188 int WbemNative.IWbemServices.QueryObjectSink(
190 out WbemNative.IWbemObjectSink wbemSink
194 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
197 int WbemNative.IWbemServices.GetObject(
200 WbemNative.IWbemContext wbemContext,
201 ref WbemNative.IWbemClassObject wbemObject,
205 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
208 int WbemNative.IWbemServices.GetObjectAsync(
211 WbemNative.IWbemContext wbemContext,
212 WbemNative.IWbemObjectSink wbemSink)
214 if (wbemContext == null || wbemSink == null || this.wbemServices == null)
215 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
217 using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ?
218 ServiceModelActivity.CreateActivity(true, SR.GetString(SR.WmiGetObject, string.IsNullOrEmpty(objectPath) ? string.Empty : objectPath), ActivityType.WmiGetObject) : null)
222 ObjectPathRegex objPathRegex = new ObjectPathRegex(objectPath);
223 ParameterContext parms = new ParameterContext(objPathRegex.ClassName, this.wbemServices, wbemContext, wbemSink);
224 WbemInstance wbemInstance = new WbemInstance(parms, objPathRegex);
225 IWmiProvider wmiProvider = this.GetProvider(parms.ClassName);
226 if (wmiProvider.GetInstance(new InstanceContext(wbemInstance)))
228 wbemInstance.Indicate();
231 WbemException.ThrowIfFail(wbemSink.SetStatus(
232 (int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
233 (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR,
237 catch (WbemException e)
239 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi, (uint)System.Runtime.Diagnostics.EventLogEventId.WmiGetObjectFailed,
240 TraceUtility.CreateSourceString(this), e.ToString());
241 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
242 e.ErrorCode, null, null);
245 #pragma warning suppress 56500 // covered by FxCOP
248 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi, (uint)System.Runtime.Diagnostics.EventLogEventId.WmiGetObjectFailed,
249 TraceUtility.CreateSourceString(this), e.ToString());
250 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
251 (int)WbemNative.WbemStatus.WBEM_E_FAILED, null, null);
252 return (int)WbemNative.WbemStatus.WBEM_E_FAILED;
256 Marshal.ReleaseComObject(wbemSink);
259 return (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
262 int WbemNative.IWbemServices.PutClass(
263 WbemNative.IWbemClassObject wbemObject,
265 WbemNative.IWbemContext wbemContext,
266 IntPtr wbemCallResult)
268 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
271 int WbemNative.IWbemServices.PutClassAsync(
272 WbemNative.IWbemClassObject wbemObject,
274 WbemNative.IWbemContext wbemContext,
275 WbemNative.IWbemObjectSink wbemSink)
277 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
280 int WbemNative.IWbemServices.DeleteClass(
283 WbemNative.IWbemContext wbemContext,
284 IntPtr wbemCallResult)
286 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
289 int WbemNative.IWbemServices.DeleteClassAsync(
292 WbemNative.IWbemContext wbemContext,
293 WbemNative.IWbemObjectSink wbemSink)
295 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
298 int WbemNative.IWbemServices.CreateClassEnum(
299 string superClassName,
301 WbemNative.IWbemContext wbemContext,
302 out WbemNative.IEnumWbemClassObject wbemEnum)
305 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
308 int WbemNative.IWbemServices.CreateClassEnumAsync(
309 string superClassName,
311 WbemNative.IWbemContext wbemContext,
312 WbemNative.IWbemObjectSink wbemSink)
314 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
317 int WbemNative.IWbemServices.PutInstance(
318 WbemNative.IWbemClassObject pInst,
320 WbemNative.IWbemContext wbemContext,
321 IntPtr wbemCallResult)
323 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
326 int WbemNative.IWbemServices.PutInstanceAsync(
327 WbemNative.IWbemClassObject wbemObject,
329 WbemNative.IWbemContext wbemContext,
330 WbemNative.IWbemObjectSink wbemSink
333 if (wbemObject == null || wbemContext == null || wbemSink == null || this.wbemServices == null)
334 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
336 using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
343 WbemException.ThrowIfFail(wbemObject.Get("__CLASS", 0, ref val, ref type, ref favor));
344 string className = (string)val;
345 ServiceModelActivity.Start(activity, SR.GetString(SR.WmiPutInstance, string.IsNullOrEmpty(className) ? string.Empty : className), ActivityType.WmiPutInstance);
347 ParameterContext parms = new ParameterContext(className, this.wbemServices, wbemContext, wbemSink);
348 WbemInstance wbemInstance = new WbemInstance(parms, wbemObject);
349 IWmiProvider wmiProvider = this.GetProvider(parms.ClassName);
350 if (wmiProvider.PutInstance(new InstanceContext(wbemInstance)))
352 wbemInstance.Indicate();
355 WbemException.ThrowIfFail(wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
356 (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR, null, null));
358 catch (WbemException e)
360 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi, (uint)System.Runtime.Diagnostics.EventLogEventId.WmiPutInstanceFailed,
361 TraceUtility.CreateSourceString(this), e.ToString());
362 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
363 e.ErrorCode, null, null);
366 #pragma warning suppress 56500 // covered by FxCOP
369 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error, (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi, (uint)System.Runtime.Diagnostics.EventLogEventId.WmiPutInstanceFailed,
370 TraceUtility.CreateSourceString(this), e.ToString());
371 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
372 (int)WbemNative.WbemStatus.WBEM_E_FAILED, null, null);
373 return (int)WbemNative.WbemStatus.WBEM_E_FAILED;
377 Marshal.ReleaseComObject(wbemSink);
380 return (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
383 int WbemNative.IWbemServices.DeleteInstance(
386 WbemNative.IWbemContext wbemContext,
387 IntPtr wbemCallResult)
389 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
392 int WbemNative.IWbemServices.DeleteInstanceAsync(
395 WbemNative.IWbemContext wbemContext,
396 WbemNative.IWbemObjectSink wbemSink)
398 if (wbemContext == null || wbemSink == null || this.wbemServices == null)
399 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
403 ObjectPathRegex objPathRegex = new ObjectPathRegex(objectPath);
404 ParameterContext parms = new ParameterContext(objPathRegex.ClassName, this.wbemServices, wbemContext, wbemSink);
405 WbemInstance wbemInstance = new WbemInstance(parms, objPathRegex);
406 IWmiProvider wmiProvider = this.GetProvider(parms.ClassName);
407 if (wmiProvider.DeleteInstance(new InstanceContext(wbemInstance)))
409 wbemInstance.Indicate();
412 WbemException.ThrowIfFail(wbemSink.SetStatus(
413 (int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
414 (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR, null, null));
416 catch (WbemException e)
418 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
419 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
420 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiDeleteInstanceFailed,
422 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
423 e.ErrorCode, null, null);
426 #pragma warning suppress 56500 // covered by FxCOP
429 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
430 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
431 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiDeleteInstanceFailed,
433 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
434 (int)WbemNative.WbemStatus.WBEM_E_FAILED, null, null);
435 return (int)WbemNative.WbemStatus.WBEM_E_FAILED;
439 Marshal.ReleaseComObject(wbemSink);
441 return (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
444 int WbemNative.IWbemServices.CreateInstanceEnum(
447 WbemNative.IWbemContext wbemContext,
448 out WbemNative.IEnumWbemClassObject wbemEnum
452 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
455 int WbemNative.IWbemServices.CreateInstanceEnumAsync(
458 WbemNative.IWbemContext wbemContext,
459 WbemNative.IWbemObjectSink wbemSink)
461 if (wbemContext == null || wbemSink == null || this.wbemServices == null)
462 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
466 ParameterContext parms = new ParameterContext(className, this.wbemServices, wbemContext, wbemSink);
467 IWmiProvider wmiProvider = this.GetProvider(parms.ClassName);
468 wmiProvider.EnumInstances(new InstancesContext(parms));
470 WbemException.ThrowIfFail(wbemSink.SetStatus(
471 (int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
472 (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR,
476 catch (WbemException e)
478 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
479 e.ErrorCode, null, null);
480 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
481 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
482 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiCreateInstanceFailed,
487 #pragma warning suppress 56500 // covered by FxCOP
490 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
491 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
492 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiCreateInstanceFailed,
495 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
496 (int)WbemNative.WbemStatus.WBEM_E_FAILED, null, null);
497 return (int)WbemNative.WbemStatus.WBEM_E_FAILED;
501 Marshal.ReleaseComObject(wbemSink);
503 return (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
506 int WbemNative.IWbemServices.ExecQuery(
507 string queryLanguage,
510 WbemNative.IWbemContext wbemContext,
511 out WbemNative.IEnumWbemClassObject wbemEnum)
514 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
517 int WbemNative.IWbemServices.ExecQueryAsync(
518 string queryLanguage,
521 WbemNative.IWbemContext wbemContext,
522 WbemNative.IWbemObjectSink wbemSink)
524 if (wbemContext == null || wbemSink == null || this.wbemServices == null)
525 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
529 QueryRegex queryRegex = new QueryRegex(query);
530 ParameterContext parms = new ParameterContext(queryRegex.ClassName, this.wbemServices, wbemContext, wbemSink);
531 IWmiProvider wmiProvider = this.GetProvider(parms.ClassName);
532 //we let WMI to parse WQL to filter results from appropriate provider
533 wmiProvider.EnumInstances(new InstancesContext(parms));
535 WbemException.ThrowIfFail(wbemSink.SetStatus(
536 (int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
537 (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR, null, null));
539 catch (WbemException e)
541 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
542 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
543 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiExecQueryFailed,
545 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
546 e.ErrorCode, null, null);
549 #pragma warning suppress 56500 // covered by FxCOP
552 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
553 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
554 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiExecQueryFailed,
556 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
557 (int)WbemNative.WbemStatus.WBEM_E_FAILED, null, null);
558 return (int)WbemNative.WbemStatus.WBEM_E_FAILED;
562 Marshal.ReleaseComObject(wbemSink);
564 return (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
567 int WbemNative.IWbemServices.ExecNotificationQuery(
568 string queryLanguage,
571 WbemNative.IWbemContext wbemContext,
572 out WbemNative.IEnumWbemClassObject wbemEnum)
575 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
578 int WbemNative.IWbemServices.ExecNotificationQueryAsync(
579 string queryLanguage,
582 WbemNative.IWbemContext wbemContext,
583 WbemNative.IWbemObjectSink wbemSink)
585 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
587 int WbemNative.IWbemServices.ExecMethod(
591 WbemNative.IWbemContext wbemContext,
592 WbemNative.IWbemClassObject wbemInParams,
593 ref WbemNative.IWbemClassObject wbemOutParams,
594 IntPtr wbemCallResult)
596 return (int)WbemNative.WbemStatus.WBEM_E_NOT_SUPPORTED;
599 int WbemNative.IWbemServices.ExecMethodAsync(
603 WbemNative.IWbemContext wbemContext,
604 WbemNative.IWbemClassObject wbemInParams,
605 WbemNative.IWbemObjectSink wbemSink)
607 if (wbemContext == null || wbemInParams == null || wbemSink == null || this.wbemServices == null)
608 return (int)WbemNative.WbemStatus.WBEM_E_INVALID_PARAMETER;
610 int result = (int)WbemNative.WbemStatus.WBEM_S_NO_ERROR;
614 ObjectPathRegex objPathRegex = new ObjectPathRegex(objectPath);
615 ParameterContext parms = new ParameterContext(objPathRegex.ClassName, this.wbemServices, wbemContext, wbemSink);
616 WbemInstance wbemInstance = new WbemInstance(parms, objPathRegex);
618 MethodContext methodContext = new MethodContext(parms, methodName, wbemInParams, wbemInstance);
619 IWmiProvider wmiProvider = this.GetProvider(parms.ClassName);
620 if (!wmiProvider.InvokeMethod(methodContext))
622 result = (int)WbemNative.WbemStatus.WBEM_E_NOT_FOUND;
625 WbemException.ThrowIfFail(wbemSink.SetStatus(
626 (int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
631 catch (WbemException e)
633 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
634 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
635 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiExecMethodFailed,
637 result = e.ErrorCode;
638 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
641 #pragma warning suppress 56500 // covered by FxCOP
644 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
645 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
646 (uint)System.Runtime.Diagnostics.EventLogEventId.WmiExecMethodFailed,
648 result = (int)WbemNative.WbemStatus.WBEM_E_FAILED;
649 wbemSink.SetStatus((int)WbemNative.tag_WBEM_STATUS_TYPE.WBEM_STATUS_COMPLETE,
650 (int)result, null, null);
654 Marshal.ReleaseComObject(wbemSink);
659 class InstancesContext : IWmiInstances
661 ParameterContext parms;
663 internal InstancesContext(ParameterContext parms)
668 IWmiInstance IWmiInstances.NewInstance(string className)
670 return new InstanceContext(new WbemInstance(this.parms, className));
673 void IWmiInstances.AddInstance(IWmiInstance inst)
675 WbemException.ThrowIfFail(this.parms.WbemSink.Indicate(1,
676 new WbemNative.IWbemClassObject[] { ((InstanceContext)inst).WbemObject }));
680 class InstanceContext : IWmiInstance
682 WbemInstance wbemInstance;
684 internal InstanceContext(WbemInstance wbemInstance)
686 this.wbemInstance = wbemInstance;
689 internal WbemNative.IWbemClassObject WbemObject
691 get { return this.wbemInstance.WbemObject; }
694 IWmiInstance IWmiInstance.NewInstance(string className)
696 return new InstanceContext(new WbemInstance(this.wbemInstance, className));
699 object IWmiInstance.GetProperty(string name)
701 return wbemInstance.GetProperty(name);
704 void IWmiInstance.SetProperty(string name, object val)
706 this.wbemInstance.SetProperty(name, val);
710 class MethodContext : IWmiMethodContext
712 ParameterContext parms;
714 WbemNative.IWbemClassObject wbemInParms;
715 WbemNative.IWbemClassObject wbemOutParms;
716 IWmiInstance instance;
718 internal MethodContext(ParameterContext parms, string methodName, WbemNative.IWbemClassObject wbemInParms, WbemInstance wbemInstance)
721 this.methodName = methodName;
722 this.wbemInParms = wbemInParms;
723 this.instance = new InstanceContext(wbemInstance);
725 WbemNative.IWbemClassObject wbemObject = null;
726 WbemException.ThrowIfFail(parms.WbemServices.GetObject(parms.ClassName, 0, parms.WbemContext,
727 ref wbemObject, IntPtr.Zero));
729 WbemNative.IWbemClassObject wbemMethod = null;
730 WbemException.ThrowIfFail(wbemObject.GetMethod(methodName, 0, IntPtr.Zero, out wbemMethod));
731 WbemException.ThrowIfFail(wbemMethod.SpawnInstance(0, out this.wbemOutParms));
734 string IWmiMethodContext.MethodName
736 get { return this.methodName; }
739 IWmiInstance IWmiMethodContext.Instance
741 get { return this.instance; }
744 object IWmiMethodContext.ReturnParameter
749 WbemException.ThrowIfFail(this.wbemOutParms.Put("ReturnValue",
751 WbemException.ThrowIfFail(this.parms.WbemSink.Indicate(1,
752 new WbemNative.IWbemClassObject[] { this.wbemOutParms }));
756 object IWmiMethodContext.GetParameter(string name)
758 Fx.Assert(null != this.wbemInParms, "");
762 WbemException.ThrowIfFail(this.wbemInParms.Get(name, 0, ref val, ref type, ref favor));
766 void IWmiMethodContext.SetParameter(string name, object value)
768 WbemException.ThrowIfFail(this.wbemOutParms.Put(name, 0, ref value, 0));
772 class ObjectPathRegex
774 //No support for boolean keys
775 static Regex nsRegEx = new Regex("^(?<namespace>[^\"]*?:)(?<path>.*)");
776 static Regex classRegEx = new Regex("^(?<className>.*?)\\.(?<keys>.*)");
777 static Regex keysRegEx = new Regex("(?<key>.*?)=((?<ival>[\\d]+)|\"(?<sval>.*?)\"),?");
780 Dictionary<string, object> keys = new Dictionary<string, object>();
782 public ObjectPathRegex(string objectPath)
784 //WMI infrastructure will double all backslashes. We need to get back to the originals
785 objectPath = objectPath.Replace("\\\\", "\\");
786 Match match = nsRegEx.Match(objectPath);
789 objectPath = match.Groups["path"].Value;
791 match = classRegEx.Match(objectPath);
792 this.className = match.Groups["className"].Value;
793 string keyValues = match.Groups["keys"].Value;
794 match = keysRegEx.Match(keyValues);
797 WbemException.Throw(WbemNative.WbemStatus.WBEM_E_INVALID_OBJECT_PATH);
799 while (match.Success)
801 if (!String.IsNullOrEmpty(match.Groups["ival"].Value))
803 this.keys.Add(match.Groups["key"].Value, Int32.Parse(match.Groups["ival"].Value, CultureInfo.CurrentCulture));
807 this.keys.Add(match.Groups["key"].Value, match.Groups["sval"].Value);
809 match = match.NextMatch();
813 internal string ClassName { get { return this.className; } }
814 internal Dictionary<string, object> Keys { get { return this.keys; } }
819 static Regex regEx = new Regex("\\bfrom\\b\\s+(?<className>\\w+)", RegexOptions.IgnoreCase);
822 internal QueryRegex(string query)
824 Match match = regEx.Match(query);
827 WbemException.Throw(WbemNative.WbemStatus.WBEM_E_INVALID_QUERY);
829 this.className = match.Groups["className"].Value;
832 internal string ClassName { get { return this.className; } }
835 class ParameterContext
838 WbemNative.IWbemServices wbemServices;
839 WbemNative.IWbemContext wbemContext;
840 WbemNative.IWbemObjectSink wbemSink;
842 internal ParameterContext(
844 WbemNative.IWbemServices wbemServices,
845 WbemNative.IWbemContext wbemContext,
846 WbemNative.IWbemObjectSink wbemSink)
848 this.className = className;
849 this.wbemServices = wbemServices;
850 this.wbemContext = wbemContext;
851 this.wbemSink = wbemSink;
854 internal string ClassName
856 get { return this.className; }
858 internal WbemNative.IWbemServices WbemServices
860 get { return this.wbemServices; }
862 internal WbemNative.IWbemContext WbemContext
864 get { return this.wbemContext; }
866 internal WbemNative.IWbemObjectSink WbemSink
868 get { return this.wbemSink; }
875 ParameterContext parms;
876 WbemNative.IWbemClassObject wbemObject;
878 internal WbemInstance(ParameterContext parms, ObjectPathRegex objPathRegex)
879 : this(parms, objPathRegex.ClassName)
881 foreach (KeyValuePair<string, object> kv in objPathRegex.Keys)
883 this.SetProperty(kv.Key, kv.Value);
887 internal WbemInstance(WbemInstance wbemInstance, string className)
888 : this(wbemInstance.parms, className)
892 internal WbemInstance(ParameterContext parms, string className)
895 if (String.IsNullOrEmpty(className))
897 className = parms.ClassName;
899 this.className = className;
900 WbemNative.IWbemClassObject tempObj = null;
901 WbemException.ThrowIfFail(
902 parms.WbemServices.GetObject(className, 0, parms.WbemContext, ref tempObj, IntPtr.Zero)
908 WbemException.ThrowIfFail(tempObj.SpawnInstance(0, out this.wbemObject));
912 internal WbemInstance(ParameterContext parms, WbemNative.IWbemClassObject wbemObject)
915 this.wbemObject = wbemObject;
918 internal WbemNative.IWbemClassObject WbemObject
922 Fx.Assert(null != this.wbemObject, "");
923 return this.wbemObject;
927 internal void SetProperty(string name, object val)
929 Fx.Assert(null != this.wbemObject, name + " may not be available to WMI");
932 WbemNative.CIMTYPE type = 0;
935 val = ((DateTime)val).ToString("yyyyMMddhhmmss.ffffff", CultureInfo.InvariantCulture) + "+000";
937 else if (val is TimeSpan)
939 TimeSpan ts = (TimeSpan)val;
940 long microSeconds = (ts.Ticks % 1000) / 10;
941 val = string.Format(CultureInfo.InvariantCulture, "{0:00000000}{1:00}{2:00}{3:00}.{4:000}{5:000}:000",
942 new object[] { ts.Days, ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds, microSeconds });
944 else if (val is InstanceContext)
946 InstanceContext inst = (InstanceContext)val;
947 val = inst.WbemObject;
949 else if (val is Array)
951 Array objs = (Array)val;
952 if (objs.GetLength(0) > 0 && objs.GetValue(0) is InstanceContext)
954 WbemNative.IWbemClassObject[] insts = new WbemNative.IWbemClassObject[objs.GetLength(0)];
955 for (int i = 0; i < insts.Length; ++i)
957 insts[i] = ((InstanceContext)objs.GetValue(i)).WbemObject;
962 else if (val is Int64)
964 val = ((Int64)val).ToString(CultureInfo.InvariantCulture);
965 type = WbemNative.CIMTYPE.CIM_SINT64;
968 int hResult = this.wbemObject.Put(name, 0, ref val, (int)type);
969 if ((int)WbemNative.WbemStatus.WBEM_E_TYPE_MISMATCH == hResult || (int)WbemNative.WbemStatus.WBEM_E_NOT_FOUND == hResult)
971 //This would be most likely a product
972 System.Runtime.Diagnostics.EventLogEventId eventId;
973 if ((int)WbemNative.WbemStatus.WBEM_E_TYPE_MISMATCH == hResult)
975 eventId = System.Runtime.Diagnostics.EventLogEventId.WmiAdminTypeMismatch;
979 eventId = System.Runtime.Diagnostics.EventLogEventId.WmiPropertyMissing;
981 DiagnosticUtility.EventLog.LogEvent(TraceEventType.Error,
982 (ushort)System.Runtime.Diagnostics.EventLogCategory.Wmi,
986 val.GetType().ToString());
990 WbemException.ThrowIfFail(hResult);
995 internal object GetProperty(string name)
1000 WbemException.ThrowIfFail(this.wbemObject.Get(name, 0, ref val, ref type, ref favor));
1004 internal void Indicate()
1006 WbemException.ThrowIfFail(this.parms.WbemSink.Indicate(1,
1007 new WbemNative.IWbemClassObject[] { this.wbemObject }));
1011 class ThreadJob : IDisposable
1013 WaitCallback callback;
1015 ManualResetEvent evtDone = new ManualResetEvent(false);
1016 Exception exception = null;
1018 public ThreadJob(WaitCallback callback, object state)
1020 this.callback = callback;
1028 this.callback(this.state);
1030 #pragma warning suppress 56500 // covered by FxCOP
1041 public Exception Wait()
1043 this.evtDone.WaitOne();
1047 public void Dispose()
1049 if (null != this.evtDone)
1051 this.evtDone.Close();
1052 this.evtDone = null;
1057 internal static void MTAExecute(WaitCallback callback, object state)
1059 if (Thread.CurrentThread.GetApartmentState() != ApartmentState.MTA)
1061 using (ThreadJob job = new ThreadJob(callback, state))
1063 Thread thread = new Thread(new ThreadStart(job.Run));
1064 thread.SetApartmentState(ApartmentState.MTA);
1065 thread.IsBackground = true;
1067 Exception exception = job.Wait();
1068 if (null != exception)
1070 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ApplicationException(SR.GetString(SR.AdminMTAWorkerThreadException), exception));
1080 class NoInstanceWMIProvider : IWmiProvider
1082 static NoInstanceWMIProvider singleton;
1083 internal static NoInstanceWMIProvider Default
1087 if (null == singleton)
1089 singleton = new NoInstanceWMIProvider();
1095 void IWmiProvider.EnumInstances(IWmiInstances instances) { }
1096 bool IWmiProvider.GetInstance(IWmiInstance instance) { return false; }
1097 bool IWmiProvider.PutInstance(IWmiInstance instance) { return false; }
1098 bool IWmiProvider.DeleteInstance(IWmiInstance instance) { return false; }
1099 bool IWmiProvider.InvokeMethod(IWmiMethodContext method) { return false; }
1103 internal interface IWmiProvider
1105 //methods with return value should return false if instance is not found
1106 void EnumInstances(IWmiInstances instances);
1107 bool GetInstance(IWmiInstance instance);
1108 bool PutInstance(IWmiInstance instance);
1109 bool DeleteInstance(IWmiInstance instance);
1110 bool InvokeMethod(IWmiMethodContext method);
1113 internal interface IWmiInstances
1115 IWmiInstance NewInstance(string className);
1116 void AddInstance(IWmiInstance inst);
1119 internal interface IWmiInstance
1121 IWmiInstance NewInstance(string className);
1122 object GetProperty(string name);
1123 void SetProperty(string name, object value);
1126 internal interface IWmiMethodContext
1128 string MethodName { get; }
1129 IWmiInstance Instance { get; }
1130 object ReturnParameter { set; }
1131 object GetParameter(string name);
1132 void SetParameter(string name, object value);
1135 internal interface IWmiInstanceProvider
1137 string GetInstanceType();
1138 void FillInstance(IWmiInstance wmiInstance);