private static IntPtr CreateInheritedFile(string file) { NativeMethods.SECURITY_ATTRIBUTES sec_attribs = new NativeMethods.SECURITY_ATTRIBUTES(); sec_attribs.nLength = Marshal.SizeOf(sec_attribs); sec_attribs.bInheritHandle = true; IntPtr handle = UnsafeNativeMethods.CreateFile(file, NativeMethods.GENERIC_WRITE, NativeMethods.FILE_SHARE_READ, sec_attribs, NativeMethods.CREATE_ALWAYS, NativeMethods.FILE_ATTRIBUTE_NORMAL, IntPtr.Zero); if (handle == NativeMethods.INVALID_HANDLE_VALUE) { throw new ExternalException(SR.GetString(SR.ExecFailedToCreate, file), Marshal.GetLastWin32Error()); } return handle; }
public unsafe Semaphore(int initialCount, int maximumCount, string name, out bool createdNew, SemaphoreSecurity semaphoreSecurity) #endif { if (initialCount < 0) { throw new ArgumentOutOfRangeException("initialCount", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNumRequired)); } if (maximumCount < 1) { throw new ArgumentOutOfRangeException("maximumCount", SR.GetString(SR.ArgumentOutOfRange_NeedNonNegNumRequired)); } if (initialCount > maximumCount) { throw new ArgumentException(SR.GetString(SR.Argument_SemaphoreInitialMaximum)); } if(null != name && MAX_PATH < name.Length) { throw new ArgumentException(SR.GetString(SR.Argument_WaitHandleNameTooLong)); } SafeWaitHandle myHandle; #if !FEATURE_PAL && !FEATURE_NETCORE // For ACL's, get the security descriptor from the SemaphoreSecurity. if (semaphoreSecurity != null) { NativeMethods.SECURITY_ATTRIBUTES secAttrs = null; secAttrs = new NativeMethods.SECURITY_ATTRIBUTES(); secAttrs.nLength = (int)Marshal.SizeOf(secAttrs); byte[] sd = semaphoreSecurity.GetSecurityDescriptorBinaryForm(); fixed(byte* pSecDescriptor = sd) { secAttrs.lpSecurityDescriptor = new SafeLocalMemHandle((IntPtr) pSecDescriptor, false); myHandle = SafeNativeMethods.CreateSemaphore(secAttrs, initialCount, maximumCount, name); } } else { #endif myHandle = SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name); #if !FEATURE_PAL && !FEATURE_NETCORE } #endif int errorCode = Marshal.GetLastWin32Error(); if (myHandle.IsInvalid) { if(null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode) throw new WaitHandleCannotBeOpenedException(SR.GetString(SR.WaitHandleCannotBeOpenedException_InvalidHandle,name)); InternalResources.WinIOError(); } createdNew = errorCode != NativeMethods.ERROR_ALREADY_EXISTS; this.SafeWaitHandle = myHandle; }
private unsafe void Initialize(string fileMappingName, int fileMappingSize, int initialOffset) { string mappingName = fileMappingName; SharedUtils.CheckEnvironment(); SafeLocalMemHandle securityDescriptorPointer = null; new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); try { // The sddl string consists of these parts: // D: it's a DACL // (A; this is an allow ACE // OICI; object inherit and container inherit // FRFWGRGW;;; allow file read, file write, generic read and generic write // AU) granted to Authenticated Users // ;S-1-5-33) the same permission granted to AU is also granted to restricted services string sddlString = "D:(A;OICI;FRFWGRGW;;;AU)(A;OICI;FRFWGRGW;;;S-1-5-33)"; if (!SafeLocalMemHandle.ConvertStringSecurityDescriptorToSecurityDescriptor(sddlString, NativeMethods.SDDL_REVISION_1, out securityDescriptorPointer, IntPtr.Zero)) throw new InvalidOperationException(SR.GetString(SR.SetSecurityDescriptorFailed)); NativeMethods.SECURITY_ATTRIBUTES securityAttributes = new NativeMethods.SECURITY_ATTRIBUTES(); securityAttributes.lpSecurityDescriptor = securityDescriptorPointer; securityAttributes.bInheritHandle = false; // // // Here we call CreateFileMapping to create the memory mapped file. When CreateFileMapping fails // with ERROR_ACCESS_DENIED, we know the file mapping has been created and we then open it with OpenFileMapping. // // There is chance of a race condition between CreateFileMapping and OpenFileMapping; The memory mapped file // may actually be closed in between these two calls. When this happens, OpenFileMapping returns ERROR_FILE_NOT_FOUND. // In this case, we need to loop back and retry creating the memory mapped file. // // This loop will timeout in approximately 1.4 minutes. An InvalidOperationException is thrown in the timeout case. // // int waitRetries = 14; //((2^13)-1)*10ms == approximately 1.4mins int waitSleep = 0; bool created = false; while (!created && waitRetries > 0) { fileMappingHandle = NativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, NativeMethods.PAGE_READWRITE, 0, fileMappingSize, mappingName); if ((Marshal.GetLastWin32Error() != NativeMethods.ERROR_ACCESS_DENIED) || !fileMappingHandle.IsInvalid) { created = true; } else { // Invalidate the old safehandle before we get rid of it. This prevents it from trying to finalize fileMappingHandle.SetHandleAsInvalid(); fileMappingHandle = NativeMethods.OpenFileMapping(NativeMethods.FILE_MAP_WRITE, false, mappingName); if ((Marshal.GetLastWin32Error() != NativeMethods.ERROR_FILE_NOT_FOUND) || !fileMappingHandle.IsInvalid) { created = true; } else { --waitRetries; if (waitSleep == 0) { waitSleep = 10; } else { System.Threading.Thread.Sleep(waitSleep); waitSleep *= 2; } } } } if (fileMappingHandle.IsInvalid) { throw new InvalidOperationException(SR.GetString(SR.CantCreateFileMapping)); } fileViewAddress = SafeFileMapViewHandle.MapViewOfFile(fileMappingHandle, NativeMethods.FILE_MAP_WRITE, 0,0, UIntPtr.Zero); if (fileViewAddress.IsInvalid) throw new InvalidOperationException(SR.GetString(SR.CantMapFileView)); // figure out what size the share memory really is. NativeMethods.MEMORY_BASIC_INFORMATION meminfo = new NativeMethods.MEMORY_BASIC_INFORMATION(); if (NativeMethods.VirtualQuery(fileViewAddress, ref meminfo, (IntPtr) sizeof(NativeMethods.MEMORY_BASIC_INFORMATION)) == IntPtr.Zero) throw new InvalidOperationException(SR.GetString(SR.CantGetMappingSize)); FileMappingSize = (int) meminfo.RegionSize; } finally { if (securityDescriptorPointer != null) securityDescriptorPointer.Close(); SecurityPermission.RevertAssert(); } SafeNativeMethods.InterlockedCompareExchange(fileViewAddress.DangerousGetHandle(), initialOffset, 0); }