WrappedIUnknown.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. base.handle = Marshal.GetIUnknownForObject(unknown); //
  30. }
  31. }
  32. }
  33. public override bool IsInvalid {
  34. get {
  35. return (IntPtr.Zero == base.handle);
  36. }
  37. }
  38. internal object ComWrapper() {
  39. // NOTE: Method, instead of property, to avoid being evaluated at
  40. // runtime in the debugger.
  41. object value = null;
  42. bool mustRelease = false;
  43. RuntimeHelpers.PrepareConstrainedRegions();
  44. try {
  45. DangerousAddRef(ref mustRelease);
  46. IntPtr handle = DangerousGetHandle();
  47. value = System.Runtime.Remoting.Services.EnterpriseServicesHelper.WrapIUnknownWithComObject(handle);
  48. }
  49. finally {
  50. if (mustRelease) {
  51. DangerousRelease();
  52. }
  53. }
  54. return value;
  55. }
  56. override protected bool ReleaseHandle() {
  57. // NOTE: The SafeHandle class guarantees this will be called exactly once.
  58. IntPtr ptr = base.handle;
  59. base.handle = IntPtr.Zero;
  60. if (IntPtr.Zero != ptr) {
  61. Marshal.Release(ptr);
  62. }
  63. return true;
  64. }
  65. }
  66. }