WrappedIUnknown.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //------------------------------------------------------------------------------
  2. // <copyright file="WrappedIUnknown.cs" company="Microsoft">
  3. // Copyright (c) Microsoft Corporation. All rights reserved.
  4. // </copyright>
  5. // <owner current="true" primary="true">[....]</owner>
  6. // <owner current="true" primary="false">[....]</owner>
  7. //------------------------------------------------------------------------------
  8. namespace System.Data.ProviderBase {
  9. using System;
  10. using System.Data.Common;
  11. using System.Runtime.CompilerServices;
  12. using System.Runtime.ConstrainedExecution;
  13. using System.Runtime.InteropServices;
  14. using System.Security;
  15. using System.Security.Permissions;
  16. using System.Threading;
  17. // We wrap the interface as a native IUnknown IntPtr so that every
  18. // thread that creates a connection will fake the correct context when
  19. // in transactions, otherwise everything is marshalled. We do this
  20. // for two reasons: first for the connection pooler, this is a significant
  21. // performance gain, second for the OLE DB provider, it doesn't marshal.
  22. internal class WrappedIUnknown : SafeHandle {
  23. internal WrappedIUnknown() : base(IntPtr.Zero, true) {
  24. }
  25. internal WrappedIUnknown(object unknown) : this() {
  26. if (null != unknown) {
  27. RuntimeHelpers.PrepareConstrainedRegions();
  28. try {} finally {
  29. #if !FULL_AOT_RUNTIME
  30. base.handle = Marshal.GetIUnknownForObject(unknown); //
  31. #endif
  32. }
  33. }
  34. }
  35. public override bool IsInvalid {
  36. get {
  37. return (IntPtr.Zero == base.handle);
  38. }
  39. }
  40. internal object ComWrapper() {
  41. // NOTE: Method, instead of property, to avoid being evaluated at
  42. // runtime in the debugger.
  43. object value = null;
  44. bool mustRelease = false;
  45. RuntimeHelpers.PrepareConstrainedRegions();
  46. try {
  47. DangerousAddRef(ref mustRelease);
  48. IntPtr handle = DangerousGetHandle();
  49. value = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(handle);
  50. }
  51. finally {
  52. if (mustRelease) {
  53. DangerousRelease();
  54. }
  55. }
  56. return value;
  57. }
  58. override protected bool ReleaseHandle() {
  59. // NOTE: The SafeHandle class guarantees this will be called exactly once.
  60. IntPtr ptr = base.handle;
  61. base.handle = IntPtr.Zero;
  62. if (IntPtr.Zero != ptr) {
  63. Marshal.Release(ptr);
  64. }
  65. return true;
  66. }
  67. }
  68. }