Inheritance: SafeHandleZeroOrMinusOneIsInvalid
 private void Initialize(string fileMappingName, int fileMappingSize, int initialOffset)
 {
     string lpName = fileMappingName;
     SharedUtils.CheckEnvironment();
     SafeLocalMemHandle pSecurityDescriptor = null;
     new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert();
     try
     {
         string stringSecurityDescriptor = "D:(A;OICI;FRFWGRGW;;;AU)(A;OICI;FRFWGRGW;;;S-1-5-33)";
         if (!SafeLocalMemHandle.ConvertStringSecurityDescriptorToSecurityDescriptor(stringSecurityDescriptor, 1, out pSecurityDescriptor, IntPtr.Zero))
         {
             throw new InvalidOperationException(SR.GetString("SetSecurityDescriptorFailed"));
         }
         Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES lpFileMappingAttributes = new Microsoft.Win32.NativeMethods.SECURITY_ATTRIBUTES {
             lpSecurityDescriptor = pSecurityDescriptor,
             bInheritHandle = false
         };
         int num = 14;
         int millisecondsTimeout = 0;
         bool flag = false;
         while (!flag && (num > 0))
         {
             this.fileMappingHandle = Microsoft.Win32.NativeMethods.CreateFileMapping((IntPtr) (-1), lpFileMappingAttributes, 4, 0, fileMappingSize, lpName);
             if ((Marshal.GetLastWin32Error() != 5) || !this.fileMappingHandle.IsInvalid)
             {
                 flag = true;
             }
             else
             {
                 this.fileMappingHandle.SetHandleAsInvalid();
                 this.fileMappingHandle = Microsoft.Win32.NativeMethods.OpenFileMapping(2, false, lpName);
                 if ((Marshal.GetLastWin32Error() != 2) || !this.fileMappingHandle.IsInvalid)
                 {
                     flag = true;
                     continue;
                 }
                 num--;
                 if (millisecondsTimeout == 0)
                 {
                     millisecondsTimeout = 10;
                 }
                 else
                 {
                     Thread.Sleep(millisecondsTimeout);
                     millisecondsTimeout *= 2;
                 }
             }
         }
         if (this.fileMappingHandle.IsInvalid)
         {
             throw new InvalidOperationException(SR.GetString("CantCreateFileMapping"));
         }
         this.fileViewAddress = SafeFileMapViewHandle.MapViewOfFile(this.fileMappingHandle, 2, 0, 0, UIntPtr.Zero);
         if (this.fileViewAddress.IsInvalid)
         {
             throw new InvalidOperationException(SR.GetString("CantMapFileView"));
         }
         Microsoft.Win32.NativeMethods.MEMORY_BASIC_INFORMATION buffer = new Microsoft.Win32.NativeMethods.MEMORY_BASIC_INFORMATION();
         if (Microsoft.Win32.NativeMethods.VirtualQuery(this.fileViewAddress, ref buffer, (IntPtr) sizeof(Microsoft.Win32.NativeMethods.MEMORY_BASIC_INFORMATION)) == IntPtr.Zero)
         {
             throw new InvalidOperationException(SR.GetString("CantGetMappingSize"));
         }
         this.FileMappingSize = (int) ((uint) buffer.RegionSize);
     }
     finally
     {
         if (pSecurityDescriptor != null)
         {
             pSecurityDescriptor.Close();
         }
         CodeAccessPermission.RevertAssert();
     }
     Microsoft.Win32.SafeNativeMethods.InterlockedCompareExchange(this.fileViewAddress.DangerousGetHandle(), initialOffset, 0);
 }
            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);
            }
Exemplo n.º 3
0
 unsafe internal static extern IntPtr VirtualQuery(SafeFileMapViewHandle address, ref MEMORY_BASIC_INFORMATION buffer, IntPtr sizeOfBuffer);