Пример #1
0
        internal void _Init(String path, int fAccess, FileShare share, UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs, FileIOPermissionAccess secAccess,
                            FileMode mode, int flagsAndAttributes, bool seekToEnd)
        {
            String filePath = Path.GetFullPath(path);

            _fileName = filePath;

            new FileIOPermission(secAccess, new String[] { filePath }).Demand();

            // Don't pop up a dialog for reading from an emtpy floppy drive
            int oldMode = UnsafeNativeMethods.SetErrorMode(UnsafeNativeMethods.SEM_FAILCRITICALERRORS);

            try {
                _handle = UnsafeNativeMethods.SafeCreateFile(filePath, fAccess, share, secAttrs, mode, flagsAndAttributes, UnsafeNativeMethods.NULL);
                int errorCode = Marshal.GetLastWin32Error();

                if (_handle.IsInvalid)
                {
                    // Return a meaningful exception, using the RELATIVE path to
                    // the file to avoid returning extra information to the caller
                    // unless they have path discovery permission, in which case
                    // the full path is fine & useful.

                    // We need to give an exception, and preferably it would include
                    // the fully qualified path name.  Do security check here.  If
                    // we fail, give back the msgPath, which should not reveal much.
                    // While this logic is largely duplicated in
                    // __Error.WinIOError, we need this for
                    // IsolatedStorageLogFileStream.
                    bool canGiveFullPath = false;

                    try {
                        new FileIOPermission(FileIOPermissionAccess.PathDiscovery, new String[] { _fileName }).Demand();
                        canGiveFullPath = true;
                    }
                    catch (SecurityException) {}

                    if (canGiveFullPath)
                    {
                        __Error.WinIOError(errorCode, _fileName);
                    }
                    else
                    {
                        __Error.WinIOError(errorCode, Path.GetFileName(_fileName));
                    }
                }
            }
            finally {
                UnsafeNativeMethods.SetErrorMode(oldMode);
            }
            Debug.Assert(UnsafeNativeMethods.GetFileType(_handle) == UnsafeNativeMethods.FILE_TYPE_DISK, "did someone accidentally removed the device type check from SafeCreateFile P/Invoke wrapper?");

            pos = 0;

            // For Append mode...
            if (seekToEnd)
            {
                SeekCore(0, SeekOrigin.End);
            }
        }
Пример #2
0
        private unsafe static UnsafeNativeMethods.SECURITY_ATTRIBUTES GetSecAttrs(HandleInheritability inheritability,
                                                                                  MemoryMappedFileSecurity memoryMappedFileSecurity, out Object pinningHandle)
        {
            pinningHandle = null;
            UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = null;
            if ((inheritability & HandleInheritability.Inheritable) != 0 ||
                memoryMappedFileSecurity != null)
            {
                secAttrs         = new UnsafeNativeMethods.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (Int32)Marshal.SizeOf(secAttrs);

                if ((inheritability & HandleInheritability.Inheritable) != 0)
                {
                    secAttrs.bInheritHandle = 1;
                }

                // For ACLs, get the security descriptor from the MemoryMappedFileSecurity.
                if (memoryMappedFileSecurity != null)
                {
                    byte[] sd = memoryMappedFileSecurity.GetSecurityDescriptorBinaryForm();
                    pinningHandle = GCHandle.Alloc(sd, GCHandleType.Pinned);

                    fixed(byte *pSecDescriptor = sd)
                    secAttrs.pSecurityDescriptor = pSecDescriptor;
                }
            }
            return(secAttrs);
        }
Пример #3
0
        private static UnsafeNativeMethods.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
        {
            UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = null;
            if ((share & FileShare.Inheritable) != 0)
            {
                secAttrs         = new UnsafeNativeMethods.SECURITY_ATTRIBUTES();
                secAttrs.nLength = (int)Marshal.SizeOf(secAttrs);

                secAttrs.bInheritHandle = 1;
            }
            return(secAttrs);
        }
Пример #4
0
        internal LogStream(String path, int bufferSize, LogRetentionOption retention, long maxFileSize, int maxNumOfFiles)
        {
            Debug.Assert(!String.IsNullOrEmpty(path));

            // Get absolute path - Security needs this to prevent something
            // like trying to create a file in c:\tmp with the name
            // "..\WinNT\System32\ntoskrnl.exe".  Store it for user convenience.
            //String filePath = Path.GetFullPathInternal(path);
            String filePath = Path.GetFullPath(path);

            _fileName = filePath;

            // Prevent access to your disk drives as raw block devices.
            if (filePath.StartsWith("\\\\.\\", StringComparison.Ordinal))
            {
                throw new NotSupportedException(SR.GetString(SR.NotSupported_IONonFileDevices));
            }

            UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(FileShare.Read);

            // For mitigating local elevation of privilege attack through named pipes
            // make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
            // named pipe server can't impersonate a high privileged client security context
            int flagsAndAttributes = (int)FileOptions.None | (UnsafeNativeMethods.SECURITY_SQOS_PRESENT | UnsafeNativeMethods.SECURITY_ANONYMOUS);

            // Only write is enabled
            //_canRead = false;
            //_canSeek = false;
            _canWrite = true;

            _pathSav               = filePath;
            _fAccessSav            = UnsafeNativeMethods.GENERIC_WRITE;
            _shareSav              = FileShare.Read;
            _secAttrsSav           = secAttrs;
            _secAccessSav          = FileIOPermissionAccess.Write;
            _modeSav               = (retention != LogRetentionOption.SingleFileUnboundedSize)? FileMode.Create : FileMode.OpenOrCreate;
            _flagsAndAttributesSav = flagsAndAttributes;
            _seekToEndSav          = (retention != LogRetentionOption.SingleFileUnboundedSize)? false : true;

            this.bufferSize   = bufferSize;
            _retention        = retention;
            _maxFileSize      = maxFileSize;
            _maxNumberOfFiles = maxNumOfFiles;

            _Init(filePath, _fAccessSav, _shareSav, _secAttrsSav, _secAccessSav, _modeSav, _flagsAndAttributesSav, _seekToEndSav);
        }
Пример #5
0
        public static unsafe SharedMemory Create(string name, Guid content, List <SecurityIdentifier> allowedSids)
        {
            int errorCode = UnsafeNativeMethods.ERROR_SUCCESS;

            byte[] binarySecurityDescriptor = SecurityDescriptorHelper.FromSecurityIdentifiers(allowedSids, UnsafeNativeMethods.GENERIC_READ);
            SafeFileMappingHandle fileMapping;

            UnsafeNativeMethods.SECURITY_ATTRIBUTES securityAttributes = new UnsafeNativeMethods.SECURITY_ATTRIBUTES();
            fixed(byte *pinnedSecurityDescriptor = binarySecurityDescriptor)
            {
                securityAttributes.lpSecurityDescriptor = (IntPtr)pinnedSecurityDescriptor;
                fileMapping = UnsafeNativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, UnsafeNativeMethods.PAGE_READWRITE, 0, sizeof(SharedMemoryContents), name);
                errorCode   = Marshal.GetLastWin32Error();
            }

            if (fileMapping.IsInvalid)
            {
                fileMapping.SetHandleAsInvalid();
                fileMapping.Close();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode));
            }

            SharedMemory         sharedMemory = new SharedMemory(fileMapping);
            SafeViewOfFileHandle view;

            // Ignore return value.
            GetView(fileMapping, true, out view);

            try
            {
                SharedMemoryContents *contents = (SharedMemoryContents *)view.DangerousGetHandle();
                contents->pipeGuid = content;
                Thread.MemoryBarrier();
                contents->isInitialized = true;
                return(sharedMemory);
            }
            finally
            {
                view.Close();
            }
        }
Пример #6
0
        private static SafeMemoryMappedFileHandle CreateCore(SafeFileHandle fileHandle, String mapName,
                                                             HandleInheritability inheritability,
                                                             MemoryMappedFileSecurity memoryMappedFileSecurity,
                                                             MemoryMappedFileAccess access, MemoryMappedFileOptions options,
                                                             Int64 capacity)
        {
            SafeMemoryMappedFileHandle handle = null;
            Object pinningHandle;

            UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability, memoryMappedFileSecurity, out pinningHandle);

            // split the long into two ints
            Int32 capacityLow  = (Int32)(capacity & 0x00000000FFFFFFFFL);
            Int32 capacityHigh = (Int32)(capacity >> 32);

            try {
                handle = UnsafeNativeMethods.CreateFileMapping(fileHandle, secAttrs, GetPageAccess(access) | (int)options,
                                                               capacityHigh, capacityLow, mapName);

                Int32 errorCode = Marshal.GetLastWin32Error();
                if (!handle.IsInvalid && errorCode == UnsafeNativeMethods.ERROR_ALREADY_EXISTS)
                {
                    handle.Dispose();
                    __Error.WinIOError(errorCode, String.Empty);
                }
                else if (handle.IsInvalid)
                {
                    __Error.WinIOError(errorCode, String.Empty);
                }
            }
            finally {
                if (pinningHandle != null)
                {
                    GCHandle pinHandle = (GCHandle)pinningHandle;
                    pinHandle.Free();
                }
            }
            return(handle);
        }
        public static unsafe SharedMemory Create(string name, Guid content, List <SecurityIdentifier> allowedSids)
        {
            SafeFileMappingHandle handle;
            SafeViewOfFileHandle  handle2;
            SharedMemory          memory2;
            int error = 0;

            byte[] buffer = SecurityDescriptorHelper.FromSecurityIdentifiers(allowedSids, -2147483648);
            UnsafeNativeMethods.SECURITY_ATTRIBUTES securityAttributes = new UnsafeNativeMethods.SECURITY_ATTRIBUTES();
            fixed(byte *numRef = buffer)
            {
                securityAttributes.lpSecurityDescriptor = (IntPtr)numRef;
                handle = UnsafeNativeMethods.CreateFileMapping((IntPtr)(-1), securityAttributes, 4, 0, sizeof(SharedMemoryContents), name);
                error  = Marshal.GetLastWin32Error();
            }

            if (handle.IsInvalid)
            {
                handle.SetHandleAsInvalid();
                handle.Close();
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            }
            SharedMemory memory = new SharedMemory(handle);

            GetView(handle, true, out handle2);
            try
            {
                SharedMemoryContents *contentsPtr = (SharedMemoryContents *)handle2.DangerousGetHandle();
                contentsPtr->pipeGuid = content;
                Thread.MemoryBarrier();
                contentsPtr->isInitialized = true;
                memory2 = memory;
            }
            finally
            {
                handle2.Close();
            }
            return(memory2);
        }
Пример #8
0
        private static SafeMemoryMappedFileHandle CreateOrOpenCore(SafeFileHandle fileHandle, String mapName,
                                                                   HandleInheritability inheritability,
                                                                   MemoryMappedFileSecurity memoryMappedFileSecurity,
                                                                   MemoryMappedFileAccess access, MemoryMappedFileOptions options,
                                                                   Int64 capacity)
        {
            Debug.Assert(access != MemoryMappedFileAccess.Write, "Callers requesting write access shouldn't try to create a mmf");

            SafeMemoryMappedFileHandle handle = null;
            Object pinningHandle;

            UnsafeNativeMethods.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(inheritability, memoryMappedFileSecurity, out pinningHandle);

            // split the long into two ints
            Int32 capacityLow  = (Int32)(capacity & 0x00000000FFFFFFFFL);
            Int32 capacityHigh = (Int32)(capacity >> 32);

            try {
                int waitRetries = 14;   //((2^13)-1)*10ms == approximately 1.4mins
                int waitSleep   = 0;

                // keep looping until we've exhausted retries or break as soon we we get valid handle
                while (waitRetries > 0)
                {
                    // try to create
                    handle = UnsafeNativeMethods.CreateFileMapping(fileHandle, secAttrs,
                                                                   GetPageAccess(access) | (int)options, capacityHigh, capacityLow, mapName);

                    Int32 createErrorCode = Marshal.GetLastWin32Error();
                    if (!handle.IsInvalid)
                    {
                        break;
                    }
                    else
                    {
                        if (createErrorCode != UnsafeNativeMethods.ERROR_ACCESS_DENIED)
                        {
                            __Error.WinIOError(createErrorCode, String.Empty);
                        }

                        // the mapname exists but our ACL is preventing us from opening it with CreateFileMapping.
                        // Let's try to open it with OpenFileMapping.
                        handle.SetHandleAsInvalid();
                    }

                    // try to open
                    handle = UnsafeNativeMethods.OpenFileMapping(GetFileMapAccess(access), (inheritability &
                                                                                            HandleInheritability.Inheritable) != 0, mapName);

                    Int32 openErrorCode = Marshal.GetLastWin32Error();

                    // valid handle
                    if (!handle.IsInvalid)
                    {
                        break;
                    }
                    // didn't get valid handle; have to retry
                    else
                    {
                        if (openErrorCode != UnsafeNativeMethods.ERROR_FILE_NOT_FOUND)
                        {
                            __Error.WinIOError(openErrorCode, String.Empty);
                        }

                        // increase wait time
                        --waitRetries;
                        if (waitSleep == 0)
                        {
                            waitSleep = 10;
                        }
                        else
                        {
                            System.Threading.Thread.Sleep(waitSleep);
                            waitSleep *= 2;
                        }
                    }
                }

                // finished retrying but couldn't create or open
                if (handle == null || handle.IsInvalid)
                {
                    throw new InvalidOperationException(SR.GetString(SR.InvalidOperation_CantCreateFileMapping));
                }
            }

            finally {
                if (pinningHandle != null)
                {
                    GCHandle pinHandle = (GCHandle)pinningHandle;
                    pinHandle.Free();
                }
            }
            return(handle);
        }