Ejemplo n.º 1
0
        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;
        }
Ejemplo n.º 2
0
        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);
            }