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); } }
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); }
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); }
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); }
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(); } }
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); }
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); }