SharedMemory.cs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. //----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Activation
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Runtime;
  9. using System.Runtime.InteropServices;
  10. using System.Runtime.Versioning;
  11. using System.Security;
  12. using System.Security.Principal;
  13. using System.Security.Permissions;
  14. using System.ServiceModel.Channels;
  15. using System.Threading;
  16. using System.ServiceModel;
  17. using System.ComponentModel;
  18. unsafe class SharedMemory : IDisposable
  19. {
  20. SafeFileMappingHandle fileMapping;
  21. SharedMemory(SafeFileMappingHandle fileMapping)
  22. {
  23. this.fileMapping = fileMapping;
  24. }
  25. [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
  26. public static unsafe SharedMemory Create(string name, Guid content, List<SecurityIdentifier> allowedSids)
  27. {
  28. int errorCode = UnsafeNativeMethods.ERROR_SUCCESS;
  29. byte[] binarySecurityDescriptor = SecurityDescriptorHelper.FromSecurityIdentifiers(allowedSids, UnsafeNativeMethods.GENERIC_READ);
  30. SafeFileMappingHandle fileMapping;
  31. UnsafeNativeMethods.SECURITY_ATTRIBUTES securityAttributes = new UnsafeNativeMethods.SECURITY_ATTRIBUTES();
  32. fixed (byte* pinnedSecurityDescriptor = binarySecurityDescriptor)
  33. {
  34. securityAttributes.lpSecurityDescriptor = (IntPtr)pinnedSecurityDescriptor;
  35. fileMapping = UnsafeNativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, UnsafeNativeMethods.PAGE_READWRITE, 0, sizeof(SharedMemoryContents), name);
  36. errorCode = Marshal.GetLastWin32Error();
  37. }
  38. if (fileMapping.IsInvalid)
  39. {
  40. fileMapping.SetHandleAsInvalid();
  41. fileMapping.Close();
  42. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
  43. }
  44. SharedMemory sharedMemory = new SharedMemory(fileMapping);
  45. SafeViewOfFileHandle view;
  46. // Ignore return value.
  47. GetView(fileMapping, true, out view);
  48. try
  49. {
  50. SharedMemoryContents* contents = (SharedMemoryContents*)view.DangerousGetHandle();
  51. contents->pipeGuid = content;
  52. Thread.MemoryBarrier();
  53. contents->isInitialized = true;
  54. return sharedMemory;
  55. }
  56. finally
  57. {
  58. view.Close();
  59. }
  60. }
  61. public void Dispose()
  62. {
  63. if (fileMapping != null)
  64. {
  65. fileMapping.Close();
  66. fileMapping = null;
  67. }
  68. }
  69. static bool GetView(SafeFileMappingHandle fileMapping, bool writable, out SafeViewOfFileHandle handle)
  70. {
  71. handle = UnsafeNativeMethods.MapViewOfFile(fileMapping, writable ? UnsafeNativeMethods.FILE_MAP_WRITE : UnsafeNativeMethods.FILE_MAP_READ, 0, 0, (IntPtr)sizeof(SharedMemoryContents));
  72. int errorCode = Marshal.GetLastWin32Error();
  73. if (!handle.IsInvalid)
  74. {
  75. return true;
  76. }
  77. else
  78. {
  79. handle.SetHandleAsInvalid();
  80. fileMapping.Close();
  81. // Only return false when it's reading time.
  82. if (!writable && errorCode == UnsafeNativeMethods.ERROR_FILE_NOT_FOUND)
  83. {
  84. return false;
  85. }
  86. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
  87. }
  88. }
  89. [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
  90. public static string Read(string name)
  91. {
  92. string content;
  93. if (Read(name, out content))
  94. {
  95. return content;
  96. }
  97. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(UnsafeNativeMethods.ERROR_FILE_NOT_FOUND));
  98. }
  99. [PermissionSet(SecurityAction.Demand, Unrestricted = true), SecuritySafeCritical]
  100. [ResourceConsumption(ResourceScope.Machine)]
  101. public static bool Read(string name, out string content)
  102. {
  103. content = null;
  104. SafeFileMappingHandle fileMapping = UnsafeNativeMethods.OpenFileMapping(UnsafeNativeMethods.FILE_MAP_READ, false, ListenerConstants.GlobalPrefix + name);
  105. int errorCode = Marshal.GetLastWin32Error();
  106. if (fileMapping.IsInvalid)
  107. {
  108. fileMapping.SetHandleAsInvalid();
  109. fileMapping.Close();
  110. if (errorCode == UnsafeNativeMethods.ERROR_FILE_NOT_FOUND)
  111. {
  112. return false;
  113. }
  114. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
  115. }
  116. try
  117. {
  118. SafeViewOfFileHandle view;
  119. if (!GetView(fileMapping, false, out view))
  120. {
  121. return false;
  122. }
  123. try
  124. {
  125. SharedMemoryContents* contents = (SharedMemoryContents*)view.DangerousGetHandle();
  126. content = contents->isInitialized ? contents->pipeGuid.ToString() : null;
  127. return true;
  128. }
  129. finally
  130. {
  131. view.Close();
  132. }
  133. }
  134. finally
  135. {
  136. fileMapping.Close();
  137. }
  138. }
  139. [StructLayout(LayoutKind.Sequential)]
  140. struct SharedMemoryContents
  141. {
  142. public bool isInitialized;
  143. public Guid pipeGuid;
  144. }
  145. }
  146. }