public void Write(byte[] buffer, int offset, int count, bool processSecurity) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", Resources.OffsetMustNotBeNegative); } if (count < 0) { throw new ArgumentOutOfRangeException("count", Resources.CountMustNotBeNegative); } if (offset + count > buffer.Length) { throw new ArgumentException(Resources.BufferIsNotLargeEnoughForTheRequestedOperation); } using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(count)) { hBuf.CopyFrom(buffer, offset, count); uint bytesWritten; if (!NativeMethods.BackupWrite(mFileHandle, hBuf, (uint)hBuf.Capacity, out bytesWritten, false, processSecurity, ref mContext)) { NativeError.ThrowException(); } } }
public SecurityAttributes(ObjectSecurity securityDescriptor) { SafeGlobalMemoryBufferHandle safeBuffer = ToUnmanagedSecurityAttributes(securityDescriptor); _length = safeBuffer.Capacity; _securityDescriptor = safeBuffer; }
public BackupStreamInfo ReadStreamInfo() { using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)))) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, (uint)Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)), out numberOfBytesRead, false, mProcessSecurity, ref m_context)) { NativeError.ThrowException(); } if (numberOfBytesRead == 0) { return(null); } if (numberOfBytesRead < Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID))) { throw new IOException(Resources.IncompleteHeaderRead); } NativeMethods.WIN32_STREAM_ID streamID = hBuf.PtrToStructure <NativeMethods.WIN32_STREAM_ID>(); uint nameLength = (uint)Math.Min(streamID.StreamNameSize, hBuf.Capacity); if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, mProcessSecurity, ref m_context)) { NativeError.ThrowException(); } string name = hBuf.PtrToStringUni((int)nameLength / 2); return(new BackupStreamInfo(streamID, name)); } }
internal static FileIdInfo GetFileIdInfoCore(KernelTransaction transaction, string path, PathFormat pathFormat) { using (var handle = CreateFileCore(transaction, path, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, false, pathFormat)) { if (NativeMethods.IsAtLeastWindows8) { // ReFS is supported. using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.FILE_ID_INFO)))) { var success = NativeMethods.GetFileInformationByHandleEx(handle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_ID_INFO, safeBuffer, (uint)safeBuffer.Capacity); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, path); } return(new FileIdInfo(safeBuffer.PtrToStructure <NativeMethods.FILE_ID_INFO>(0))); } } // Only NTFS is supported. return(GetFileIdInfo(handle)); } }
public SecurityAttributes(ObjectSecurity securityDescriptor) { var safeBuffer = ToUnmanagedSecurityAttributes(securityDescriptor); nLength = safeBuffer.Capacity; lpSecurityDescriptor = safeBuffer; }
private static NativeMethods.TOKEN_ELEVATION_TYPE GetProcessElevationType() { SafeTokenHandle tokenHandle; var success = NativeMethods.OpenProcessToken(Process.GetCurrentProcess().Handle, NativeMethods.TOKEN.TOKEN_READ, out tokenHandle); var lastError = Marshal.GetLastWin32Error(); if (!success) { throw new Win32Exception(lastError, string.Format(CultureInfo.CurrentCulture, "{0}: OpenProcessToken failed with error: {1}", MethodBase.GetCurrentMethod().Name, lastError.ToString(CultureInfo.CurrentCulture))); } using (tokenHandle) using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(Enum.GetUnderlyingType(typeof(NativeMethods.TOKEN_ELEVATION_TYPE))))) { uint bytesReturned; success = NativeMethods.GetTokenInformation(tokenHandle, NativeMethods.TOKEN_INFORMATION_CLASS.TokenElevationType, safeBuffer, (uint)safeBuffer.Capacity, out bytesReturned); lastError = Marshal.GetLastWin32Error(); if (!success) { throw new Win32Exception(lastError, string.Format(CultureInfo.CurrentCulture, "{0}: GetTokenInformation failed with error: {1}", MethodBase.GetCurrentMethod().Name, lastError.ToString(CultureInfo.CurrentCulture))); } return((NativeMethods.TOKEN_ELEVATION_TYPE)safeBuffer.ReadInt32()); } }
private static string GetDeviceInstanceId(SafeCmConnectMachineHandle safeMachineHandle, string hostName, NativeMethods.SP_DEVINFO_DATA diData) { uint ptrPrevious; var lastError = NativeMethods.CM_Get_Parent_Ex(out ptrPrevious, diData.DevInst, 0, safeMachineHandle); if (lastError != Win32Errors.CR_SUCCESS) { NativeError.ThrowException(lastError, hostName); } using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize / 8)) // 512 { lastError = NativeMethods.CM_Get_Device_ID_Ex(diData.DevInst, safeBuffer, (uint)safeBuffer.Capacity, 0, safeMachineHandle); if (lastError != Win32Errors.CR_SUCCESS) { NativeError.ThrowException(lastError, hostName); } // Device InstanceID, such as: "USB\VID_8087&PID_0A2B\5&2EDA7E1E&0&7", "SCSI\DISK&VEN_SANDISK&PROD_X400\4&288ED25&0&000200", ... return(safeBuffer.PtrToStringUni()); } }
private static string GetDeviceRegistryProperty(SafeHandle safeHandle, NativeMethods.SP_DEVINFO_DATA infoData, NativeMethods.SetupDiGetDeviceRegistryPropertyEnum property) { var bufferSize = NativeMethods.DefaultFileBufferSize / 8; // 512 while (true) { using (var safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize)) { var success = NativeMethods.SetupDiGetDeviceRegistryProperty(safeHandle, ref infoData, property, IntPtr.Zero, safeBuffer, (uint)safeBuffer.Capacity, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (success) { var value = safeBuffer.PtrToStringUni(); return(!Utils.IsNullOrWhiteSpace(value) ? value.Trim() : null); } // MSDN: SetupDiGetDeviceRegistryProperty returns ERROR_INVALID_DATA error code if // the requested property does not exist for a device or if the property data is not valid. if (lastError == Win32Errors.ERROR_INVALID_DATA) { return(null); } bufferSize = GetDoubledBufferSizeOrThrowException(lastError, safeBuffer, bufferSize, property.ToString()); } } }
internal static IEnumerable<AlternateDataStreamInfo> EnumerateAlternateDataStreamsInternal(KernelTransaction transaction, string path, PathFormat pathFormat) { using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA)))) { path = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.CheckAdditional); using (var handle = transaction == null ? NativeMethods.FindFirstStreamW(path, NativeMethods.StreamInfoLevels.FindStreamInfoStandard, buffer, 0) : NativeMethods.FindFirstStreamTransactedW(path, NativeMethods.StreamInfoLevels.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle)) { if (handle.IsInvalid) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == Win32Errors.ERROR_HANDLE_EOF) yield break; NativeError.ThrowException(errorCode); } while (true) { NativeMethods.WIN32_FIND_STREAM_DATA data = buffer.PtrToStructure<NativeMethods.WIN32_FIND_STREAM_DATA>(); yield return new AlternateDataStreamInfo(path, data); if (!NativeMethods.FindNextStreamW(handle, buffer)) { int lastError = Marshal.GetLastWin32Error(); if (lastError == Win32Errors.ERROR_HANDLE_EOF) break; NativeError.ThrowException(lastError, path); } } } } }
public void Write(byte[] buffer, int offset, int count, bool processSecurity) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", offset, Resources.Negative_Offset); } if (count < 0) { throw new ArgumentOutOfRangeException("count", count, Resources.Negative_Count); } if (offset + count > buffer.Length) { throw new ArgumentException(Resources.Buffer_Not_Large_Enough); } using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count)) { safeBuffer.CopyFrom(buffer, offset, count); uint bytesWritten; if (!NativeMethods.BackupWrite(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out bytesWritten, false, processSecurity, ref _context)) { NativeError.ThrowException(Marshal.GetLastWin32Error()); } } }
public SecurityAttributes(ObjectSecurity securityDescriptor) { SafeGlobalMemoryBufferHandle safeBuffer = ToUnmanagedSecurityAttributes(securityDescriptor); nLength = safeBuffer.Capacity; lpSecurityDescriptor = safeBuffer; bInheritHandle = false; }
public static extern bool SetupDiGetDeviceRegistryProperty( SafeHandle deviceInfoSet, ref SP_DEVINFO_DATA deviceInfoData, SetupDiGetDeviceRegistryPropertyEnum property, [MarshalAs(UnmanagedType.U4)] out uint propertyRegDataType, SafeGlobalMemoryBufferHandle propertyBuffer, [MarshalAs(UnmanagedType.U4)] uint propertyBufferSize, IntPtr requiredSize);
public static extern bool DeviceIoControl( SafeFileHandle hDevice, [MarshalAs(UnmanagedType.U4)] uint dwIoControlCode, IntPtr lpInBuffer, [MarshalAs(UnmanagedType.U4)] uint nInBufferSize, SafeGlobalMemoryBufferHandle lpOutBuffer, [MarshalAs(UnmanagedType.U4)] uint nOutBufferSize, [MarshalAs(UnmanagedType.U4)] out uint lpBytesReturned, IntPtr lpOverlapped);
public static extern uint GetSecurityInfo( SafeHandle handle, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor);
public static extern uint GetNamedSecurityInfo( [MarshalAs(UnmanagedType.LPWStr)] string pObjectName, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor);
internal static NativeMethods.REMOTE_NAME_INFO GetRemoteNameInfoCore(string path, bool continueOnException) { if (Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } path = Path.GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars); // If path already is a network share path, we fill the REMOTE_NAME_INFO structure ourselves. if (Path.IsUncPathCore(path, true, false)) { return new NativeMethods.REMOTE_NAME_INFO { lpUniversalName = Path.AddTrailingDirectorySeparator(path, false), lpConnectionName = Path.RemoveTrailingDirectorySeparator(path, false), lpRemainingPath = Path.DirectorySeparator } } ; uint lastError; // Use large enough buffer to prevent a 2nd call. uint bufferSize = 1024; do { using (var buffer = new SafeGlobalMemoryBufferHandle((int)bufferSize)) { // Structure: UNIVERSAL_NAME_INFO_LEVEL = 1 (not used in AlphaFS). // Structure: REMOTE_NAME_INFO_LEVEL = 2 lastError = NativeMethods.WNetGetUniversalName(path, 2, buffer, out bufferSize); switch (lastError) { case Win32Errors.NO_ERROR: return(buffer.PtrToStructure <NativeMethods.REMOTE_NAME_INFO>(0)); case Win32Errors.ERROR_MORE_DATA: //bufferSize = Received the required buffer size, retry. break; } } } while (lastError == Win32Errors.ERROR_MORE_DATA); if (!continueOnException && lastError != Win32Errors.NO_ERROR) { throw new NetworkInformationException((int)lastError); } // Return an empty structure (all fields set to null). return(new NativeMethods.REMOTE_NAME_INFO()); }
internal static DateTime GetChangeTimeCore(KernelTransaction transaction, SafeFileHandle safeFileHandle, bool isFolder, string path, bool getUtc, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message); } var callerHandle = null != safeFileHandle; if (!callerHandle) { if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeFileHandle = CreateFileCore(transaction, isFolder, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, false, PathFormat.LongFullPath); } try { NativeMethods.IsValidHandle(safeFileHandle); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FILE_BASIC_INFO)))) { NativeMethods.FILE_BASIC_INFO fbi; var success = NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeFileHandle, NativeMethods.FILE_INFO_BY_HANDLE_CLASS.FILE_BASIC_INFO, out fbi, (uint)safeBuffer.Capacity); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError, !Utils.IsNullOrWhiteSpace(path) ? path : null); } safeBuffer.StructureToPtr(fbi, true); var changeTime = safeBuffer.PtrToStructure <NativeMethods.FILE_BASIC_INFO>(0).ChangeTime; return(getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime)); } } finally { // Handle is ours, dispose. if (!callerHandle && null != safeFileHandle) { safeFileHandle.Close(); } } }
internal static DateTime GetChangeTimeCore(bool isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, bool getUtc, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) { throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher); } bool callerHandle = safeHandle != null; if (!callerHandle) { if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeHandle = CreateFileCore(transaction, pathLp, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, PathFormat.LongFullPath); } try { NativeMethods.IsValidHandle(safeHandle); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FILE_BASIC_INFO)))) { NativeMethods.FILE_BASIC_INFO fbi; if (!NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeHandle, NativeMethods.FileInfoByHandleClass.FileBasicInfo, out fbi, (uint)safeBuffer.Capacity)) { NativeError.ThrowException(Marshal.GetLastWin32Error()); } safeBuffer.StructureToPtr(fbi, true); NativeMethods.FILETIME changeTime = safeBuffer.PtrToStructure <NativeMethods.FILE_BASIC_INFO>(0).ChangeTime; return(getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime)); } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } }
/// <summary>[AlphaFS] Enumerates the streams of type :$DATA from the specified file or directory.</summary> /// <param name="transaction">The transaction.</param> /// <param name="path">The path to the file or directory to enumerate streams of.</param> /// <param name="pathFormat">Indicates the format of the path parameter(s).</param> /// <returns>The streams of type :$DATA in the specified file or directory.</returns> internal static IEnumerable <AlternateDataStreamInfo> EnumerateAlternateDataStreamsCore(KernelTransaction transaction, string path, PathFormat pathFormat) { using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA)))) { var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.CheckAdditional); using (var safeHandle = null == transaction // FindFirstStreamW() / FindFirstStreamTransactedW() // 2018-01-15: MSDN does not confirm LongPath usage but a Unicode version of this function exists. ? NativeMethods.FindFirstStreamW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0) : NativeMethods.FindFirstStreamTransactedW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle)) { var lastError = Marshal.GetLastWin32Error(); var reachedEOF = lastError == Win32Errors.ERROR_HANDLE_EOF; if (!NativeMethods.IsValidHandle(safeHandle, false)) { if (reachedEOF) { yield break; } NativeError.ThrowException(lastError, pathLp); } while (true) { yield return(new AlternateDataStreamInfo(pathLp, buffer.PtrToStructure <NativeMethods.WIN32_FIND_STREAM_DATA>(0))); var success = NativeMethods.FindNextStreamW(safeHandle, buffer); lastError = Marshal.GetLastWin32Error(); if (!success) { if (lastError == Win32Errors.ERROR_HANDLE_EOF) { break; } NativeError.ThrowException(lastError, pathLp); } } } } }
/// <summary>[AlphaFS] Creates an NTFS directory junction (similar to CMD command: "MKLINK /J").</summary> internal static void CreateDirectoryJunction(SafeFileHandle safeHandle, string directoryPath) { var targetDirBytes = Encoding.Unicode.GetBytes(Path.NonInterpretedPathPrefix + Path.GetRegularPathCore(directoryPath, GetFullPathOptions.AddTrailingDirectorySeparator, false)); var header = new NativeMethods.ReparseDataBufferHeader { ReparseTag = ReparsePointTag.MountPoint, ReparseDataLength = (ushort)(targetDirBytes.Length + 12) }; var mountPoint = new NativeMethods.MountPointReparseBuffer { SubstituteNameOffset = 0, SubstituteNameLength = (ushort)targetDirBytes.Length, PrintNameOffset = (ushort)(targetDirBytes.Length + UnicodeEncoding.CharSize), PrintNameLength = 0 }; var reparseDataBuffer = new NativeMethods.REPARSE_DATA_BUFFER { ReparseTag = header.ReparseTag, ReparseDataLength = header.ReparseDataLength, SubstituteNameOffset = mountPoint.SubstituteNameOffset, SubstituteNameLength = mountPoint.SubstituteNameLength, PrintNameOffset = mountPoint.PrintNameOffset, PrintNameLength = mountPoint.PrintNameLength, PathBuffer = new byte[NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 16] // 16368 }; targetDirBytes.CopyTo(reparseDataBuffer.PathBuffer, 0); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(reparseDataBuffer))) { safeBuffer.StructureToPtr(reparseDataBuffer, false); uint bytesReturned; var succes = NativeMethods.DeviceIoControl2(safeHandle, NativeMethods.FSCTL_SET_REPARSE_POINT, safeBuffer, (uint)(targetDirBytes.Length + 20), IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (!succes) { NativeError.ThrowException(lastError, directoryPath); } } }
private static NativeMethods.RemoteNameInfo GetMappedInfoInternal(string path) { if (path == null) { throw new ArgumentNullException("path", "The specified path cannot be NULL."); } if (IsLongPath(path)) { throw new ArgumentException("Long paths are not supported but this method."); } if (path.Length > NativeMethods.MAX_PATH) { throw new System.IO.PathTooLongException(); } int bufferSize = 0; SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize); try { uint retVal; // first call is to get correct buffer size to store results. if ((retVal = NativeMethods.WNetGetUniversalName(path, NativeMethods.REMOTE_NAME_INFO_LEVEL, safeBuffer, ref bufferSize)) != Win32Errors.ERROR_MORE_DATA) { NativeError.ThrowException(retVal); } safeBuffer.Dispose(); safeBuffer = null; safeBuffer = new SafeGlobalMemoryBufferHandle(bufferSize); if ((retVal = NativeMethods.WNetGetUniversalName(path, NativeMethods.REMOTE_NAME_INFO_LEVEL, safeBuffer, ref bufferSize)) != Win32Errors.NO_ERROR) { NativeError.ThrowException(retVal); } return((NativeMethods.RemoteNameInfo)Marshal.PtrToStructure(safeBuffer.DangerousGetHandle(), typeof(NativeMethods.RemoteNameInfo))); } finally { if (safeBuffer != null) { safeBuffer.Dispose(); } } }
public int Read(byte[] buffer, int offset, int count, bool processSecurity) { if (buffer == null) { throw new ArgumentNullException("buffer"); } if (!CanRead) { throw new NotSupportedException("Stream does not support reading"); } if (offset + count > buffer.Length) { throw new ArgumentException("The sum of offset and count is larger than the size of the buffer.", "offset"); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", offset, Resources.Negative_Offset); } if (count < 0) { throw new ArgumentOutOfRangeException("count", count, Resources.Negative_Count); } using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count)) { uint numberOfBytesRead; var success = NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, ref _context); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError); } // See File.GetAccessControlCore(): .CopyTo() does not work there? // 2017-06-13: Is .CopyTo() doing anything useful here? safeBuffer.CopyTo(buffer, offset, count); return((int)numberOfBytesRead); } }
/// <summary> /// Initializes the SecurityAttributes structure from an instance of <see cref="ObjectSecurity"/>. /// </summary> /// <param name="memoryHandle">A handle that will refer to the memory allocated by this object for storage of the /// security descriptor. As long as this object is used, the memory handle should be kept alive, and afterwards it /// should be disposed as soon as possible.</param> /// <param name="securityDescriptor">The security descriptor to assign to this object. This parameter may be <see langword="null"/>.</param> public void Initialize(out SafeGlobalMemoryBufferHandle memoryHandle, ObjectSecurity securityDescriptor) { nLength = (uint)Marshal.SizeOf(this); if (securityDescriptor == null) { memoryHandle = new SafeGlobalMemoryBufferHandle(); } else { byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); memoryHandle = new SafeGlobalMemoryBufferHandle(src.Length); memoryHandle.CopyFrom(src, 0, src.Length); } bInheritHandle = 0; }
public BackupStreamInfo ReadStreamInfo() { var sizeOf = Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)); using (var hBuf = new SafeGlobalMemoryBufferHandle(sizeOf)) { uint numberOfBytesRead; var success = NativeMethods.BackupRead(SafeFileHandle, hBuf, (uint)sizeOf, out numberOfBytesRead, false, _processSecurity, ref _context); var lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError); } if (numberOfBytesRead == 0) { return(null); } if (numberOfBytesRead < sizeOf) { throw new IOException(Resources.Read_Incomplete_Header); } var streamID = hBuf.PtrToStructure <NativeMethods.WIN32_STREAM_ID>(0); var nameLength = (uint)Math.Min(streamID.dwStreamNameSize, hBuf.Capacity); success = NativeMethods.BackupRead(SafeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, _processSecurity, ref _context); lastError = Marshal.GetLastWin32Error(); if (!success) { NativeError.ThrowException(lastError); } var name = hBuf.PtrToStringUni(0, (int)nameLength / UnicodeEncoding.CharSize); return(new BackupStreamInfo(streamID, name)); } }
internal static void SetFsoDateTimeInternal(bool isFolder, KernelTransaction transaction, string path, DateTime?creationTimeUtc, DateTime?lastAccessTimeUtc, DateTime?lastWriteTimeUtc, PathFormat pathFormat) { // Because we already check here, use false for CreateFileInternal() to prevent another check. if (pathFormat == PathFormat.RelativePath) { Path.CheckValidPath(path, false, false); } using (SafeGlobalMemoryBufferHandle creationTime = SafeGlobalMemoryBufferHandle.FromLong(creationTimeUtc.HasValue ? creationTimeUtc.Value.ToFileTimeUtc() : (long?)null)) using (SafeGlobalMemoryBufferHandle lastAccessTime = SafeGlobalMemoryBufferHandle.FromLong(lastAccessTimeUtc.HasValue ? lastAccessTimeUtc.Value.ToFileTimeUtc() : (long?)null)) using (SafeGlobalMemoryBufferHandle lastWriteTime = SafeGlobalMemoryBufferHandle.FromLong(lastWriteTimeUtc.HasValue ? lastWriteTimeUtc.Value.ToFileTimeUtc() : (long?)null)) using (SafeFileHandle safeHandle = CreateFileInternal(transaction, path, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.WriteAttributes, FileShare.Delete | FileShare.Write, false, pathFormat)) if (!NativeMethods.SetFileTime(safeHandle, creationTime, lastAccessTime, lastWriteTime)) { NativeError.ThrowException(path); } }
private static SafeGlobalMemoryBufferHandle GetLinkTargetData(SafeFileHandle safeHandle, string reparsePath) { var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.MAXIMUM_REPARSE_DATA_BUFFER_SIZE); while (true) { uint bytesReturned; var success = NativeMethods.DeviceIoControl(safeHandle, NativeMethods.FSCTL_GET_REPARSE_POINT, IntPtr.Zero, 0, safeBuffer, (uint)safeBuffer.Capacity, out bytesReturned, IntPtr.Zero); var lastError = Marshal.GetLastWin32Error(); if (!success) { switch ((uint)lastError) { case Win32Errors.ERROR_MORE_DATA: case Win32Errors.ERROR_INSUFFICIENT_BUFFER: // Should not happen since we already use the maximum size. if (safeBuffer.Capacity < bytesReturned) { safeBuffer.Close(); } break; default: if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError, reparsePath); } break; } } else { break; } } return(safeBuffer); }
public int Read(byte[] buffer, int offset, int count, bool processSecurity) { if (!CanRead) { throw new NotSupportedException("Stream does not support reading"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset + count > buffer.Length) { throw new ArgumentException("The sum of offset and count is larger than the size of the buffer."); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", offset, Resources.OffsetMustNotBeNegative); } if (count < 0) { throw new ArgumentOutOfRangeException("count", count, Resources.CountMustNotBeNegative); } using (SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(count)) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, out _context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), true); } // See File.GetAccessControlInternal(): .CopyTo() does not work there? safeBuffer.CopyTo(buffer, offset, count); return((int)numberOfBytesRead); } }
private static SafeGlobalMemoryBufferHandle ToUnmanagedSecurityAttributes(ObjectSecurity securityDescriptor) { if (securityDescriptor == null) return new SafeGlobalMemoryBufferHandle(); byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); var safeBuffer = new SafeGlobalMemoryBufferHandle(src.Length); try { safeBuffer.CopyFrom(src, 0, src.Length); return safeBuffer; } catch { safeBuffer.Close(); throw; } }
/// <summary>[AlphaFS] Enumerates the streams of type :$DATA from the specified file or directory.</summary> /// <param name="transaction">The transaction.</param> /// <param name="path">The path to the file or directory to enumerate streams of.</param> /// <param name="pathFormat">Indicates the format of the path parameter(s).</param> /// <returns>The streams of type :$DATA in the specified file or directory.</returns> internal static IEnumerable <AlternateDataStreamInfo> EnumerateAlternateDataStreamsCore(KernelTransaction transaction, string path, PathFormat pathFormat) { using (var buffer = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_FIND_STREAM_DATA)))) { string pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars | GetFullPathOptions.CheckAdditional); using (SafeFindFileHandle handle = transaction == null ? NativeMethods.FindFirstStreamW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0) : NativeMethods.FindFirstStreamTransactedW(pathLp, NativeMethods.STREAM_INFO_LEVELS.FindStreamInfoStandard, buffer, 0, transaction.SafeHandle)) { int errorCode = Marshal.GetLastWin32Error(); if (handle.IsInvalid) { if (errorCode == Win32Errors.ERROR_HANDLE_EOF) { yield break; } NativeError.ThrowException(errorCode); } while (true) { yield return(new AlternateDataStreamInfo(pathLp, buffer.PtrToStructure <NativeMethods.WIN32_FIND_STREAM_DATA>(0))); if (!NativeMethods.FindNextStreamW(handle, buffer)) { int lastError = Marshal.GetLastWin32Error(); if (lastError == Win32Errors.ERROR_HANDLE_EOF) { break; } NativeError.ThrowException(lastError, pathLp); } } } } }
private static SafeGlobalMemoryBufferHandle ToUnmanagedSecurityAttributes(ObjectSecurity securityDescriptor) { if (securityDescriptor == null) { return(new SafeGlobalMemoryBufferHandle()); } byte[] src = securityDescriptor.GetSecurityDescriptorBinaryForm(); var safeBuffer = new SafeGlobalMemoryBufferHandle(src.Length); try { safeBuffer.CopyFrom(src, 0, src.Length); return(safeBuffer); } catch { safeBuffer.Close(); throw; } }
internal static NativeMethods.REMOTE_NAME_INFO GetRemoteNameInfoCore(string path, bool continueOnException) { if (Utils.IsNullOrWhiteSpace(path)) { throw new ArgumentNullException("path"); } path = Path.GetRegularPathCore(path, GetFullPathOptions.CheckInvalidPathChars, false); uint lastError; uint bufferSize = 1024; do { using (var buffer = new SafeGlobalMemoryBufferHandle((int)bufferSize)) { // Structure: UNIVERSAL_NAME_INFO_LEVEL = 1 (not used in AlphaFS). // Structure: REMOTE_NAME_INFO_LEVEL = 2 lastError = NativeMethods.WNetGetUniversalName(path, 2, buffer, out bufferSize); if (lastError == Win32Errors.NO_ERROR) { return(buffer.PtrToStructure <NativeMethods.REMOTE_NAME_INFO>(0)); } } } while (lastError == Win32Errors.ERROR_MORE_DATA); if (lastError != Win32Errors.NO_ERROR && !continueOnException) { throw new NetworkInformationException((int)lastError); } // Return an empty structure (all fields set to null). return(new NativeMethods.REMOTE_NAME_INFO()); }
public int Read(byte[] buffer, int offset, int count, bool processSecurity) { if (!CanRead) { throw new NotSupportedException("Stream does not support reading"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } if (offset + count > buffer.Length) { throw new ArgumentException("The sum of offset and count is larger than the size of the buffer."); } if (offset < 0) { throw new ArgumentOutOfRangeException("offset", Resources.OffsetMustNotBeNegative); } if (count < 0) { throw new ArgumentOutOfRangeException("count", Resources.CountMustNotBeNegative); } using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(count)) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(mFileHandle, hBuf, (uint)hBuf.Capacity, out numberOfBytesRead, false, processSecurity, ref mContext)) { NativeError.ThrowException(); } hBuf.CopyTo(buffer, offset, count); return((int)numberOfBytesRead); } }
internal static extern bool DeviceIoControl(SafeFileHandle hDevice, [MarshalAs(UnmanagedType.U4)] uint dwIoControlCode, IntPtr lpInBuffer, [MarshalAs(UnmanagedType.U4)] uint nInBufferSize, SafeGlobalMemoryBufferHandle lpOutBuffer, [MarshalAs(UnmanagedType.U4)] uint nOutBufferSize, [MarshalAs(UnmanagedType.U4)] out uint lpBytesReturned, IntPtr lpOverlapped);
internal static extern bool GetSecurityDescriptorSacl(SafeGlobalMemoryBufferHandle pSecurityDescriptor, [MarshalAs(UnmanagedType.Bool)] out bool lpbSaclPresent, out IntPtr pSacl, [MarshalAs(UnmanagedType.Bool)] out bool lpbSaclDefaulted);
internal static extern bool BackupRead(SafeFileHandle hFile, SafeGlobalMemoryBufferHandle lpBuffer, [MarshalAs(UnmanagedType.U4)] uint nNumberOfBytesToRead, [MarshalAs(UnmanagedType.U4)] out uint lpNumberOfBytesRead, [MarshalAs(UnmanagedType.Bool)] bool bAbort, [MarshalAs(UnmanagedType.Bool)] bool bProcessSecurity, ref IntPtr lpContext);
public SecurityAttributes(ObjectSecurity securityDescriptor) { var safeBuffer = ToUnmanagedSecurityAttributes(securityDescriptor); nLength = safeBuffer.Capacity; lpSecurityDescriptor = safeBuffer; }
internal static extern uint GetNamedSecurityInfo([MarshalAs(UnmanagedType.LPWStr)] string pObjectName, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor);
internal static extern bool GetSecurityDescriptorOwner(SafeGlobalMemoryBufferHandle pSecurityDescriptor, out IntPtr pOwner, [MarshalAs(UnmanagedType.Bool)] out bool lpbOwnerDefaulted);
public static extern int CM_Get_Device_ID_Ex([MarshalAs(UnmanagedType.U4)] uint dnDevInst, SafeGlobalMemoryBufferHandle buffer, [MarshalAs(UnmanagedType.U4)] uint bufferLen, [MarshalAs(UnmanagedType.U4)] uint ulFlags, SafeCmConnectMachineHandle hMachine);
internal static extern uint GetSecurityInfo(SafeHandle handle, ObjectType objectType, SecurityInformation securityInfo, out IntPtr pSidOwner, out IntPtr pSidGroup, out IntPtr pDacl, out IntPtr pSacl, out SafeGlobalMemoryBufferHandle pSecurityDescriptor);
internal static DateTime GetChangeTimeInternal(bool isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, bool getUtc, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher); bool callerHandle = safeHandle != null; if (!callerHandle) { if (pathFormat != PathFormat.LongFullPath && Utils.IsNullOrWhiteSpace(path)) throw new ArgumentNullException("path"); string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeHandle = CreateFileInternal(transaction, pathLp, isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, true, PathFormat.LongFullPath); } try { NativeMethods.IsValidHandle(safeHandle); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(IntPtr.Size + Marshal.SizeOf(typeof(NativeMethods.FileBasicInfo)))) { NativeMethods.FileBasicInfo fbi; if (!NativeMethods.GetFileInformationByHandleEx_FileBasicInfo(safeHandle, NativeMethods.FileInfoByHandleClass.FileBasicInfo, out fbi, (uint)safeBuffer.Capacity)) NativeError.ThrowException(Marshal.GetLastWin32Error()); safeBuffer.StructureToPtr(fbi, true); NativeMethods.FileTime changeTime = safeBuffer.PtrToStructure<NativeMethods.FileBasicInfo>().ChangeTime; return getUtc ? DateTime.FromFileTimeUtc(changeTime) : DateTime.FromFileTime(changeTime); } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) safeHandle.Close(); } }
internal static extern bool SetFileTime(SafeFileHandle hFile, SafeGlobalMemoryBufferHandle lpCreationTime, SafeGlobalMemoryBufferHandle lpLastAccessTime, SafeGlobalMemoryBufferHandle lpLastWriteTime);
internal static void SetAccessControlInternal(string path, SafeHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat) { if (pathFormat == PathFormat.RelativePath) Path.CheckValidPath(path, true, true); if (objectSecurity == null) throw new ArgumentNullException("objectSecurity"); byte[] managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm(); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length)) { string pathLp = Path.GetExtendedLengthPathInternal(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars); safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length); SecurityDescriptorControl control; uint revision; if (!Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision)) NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); PrivilegeEnabler privilegeEnabler = null; try { var securityInfo = SecurityInformation.None; IntPtr pDacl = IntPtr.Zero; if ((includeSections & AccessControlSections.Access) != 0) { bool daclDefaulted, daclPresent; if (!Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted)) NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); if (daclPresent) { securityInfo |= SecurityInformation.Dacl; securityInfo |= (control & SecurityDescriptorControl.DaclProtected) != 0 ? SecurityInformation.ProtectedDacl : SecurityInformation.UnprotectedDacl; } } IntPtr pSacl = IntPtr.Zero; if ((includeSections & AccessControlSections.Audit) != 0) { bool saclDefaulted, saclPresent; if (!Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted)) NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); if (saclPresent) { securityInfo |= SecurityInformation.Sacl; securityInfo |= (control & SecurityDescriptorControl.SaclProtected) != 0 ? SecurityInformation.ProtectedSacl : SecurityInformation.UnprotectedSacl; privilegeEnabler = new PrivilegeEnabler(Privilege.Security); } } IntPtr pOwner = IntPtr.Zero; if ((includeSections & AccessControlSections.Owner) != 0) { bool ownerDefaulted; if (!Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted)) NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); if (pOwner != IntPtr.Zero) securityInfo |= SecurityInformation.Owner; } IntPtr pGroup = IntPtr.Zero; if ((includeSections & AccessControlSections.Group) != 0) { bool groupDefaulted; if (!Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted)) NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp); if (pGroup != IntPtr.Zero) securityInfo |= SecurityInformation.Group; } uint lastError; if (!Utils.IsNullOrWhiteSpace(pathLp)) { // SetNamedSecurityInfo() // In the ANSI version of this function, the name is limited to MAX_PATH characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists. lastError = Security.NativeMethods.SetNamedSecurityInfo(pathLp, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl); if (lastError != Win32Errors.ERROR_SUCCESS) NativeError.ThrowException(lastError, pathLp); } else if (NativeMethods.IsValidHandle(handle)) { lastError = Security.NativeMethods.SetSecurityInfo(handle, ObjectType.FileObject, securityInfo, pOwner, pGroup, pDacl, pSacl); if (lastError != Win32Errors.ERROR_SUCCESS) NativeError.ThrowException((int)lastError); } } finally { if (privilegeEnabler != null) privilegeEnabler.Dispose(); } } }
internal static extern bool SetupDiGetDeviceRegistryProperty(SafeHandle deviceInfoSet, ref SpDeviceInfoData deviceInfoData, SetupDiGetDeviceRegistryPropertyEnum property, [MarshalAs(UnmanagedType.U4)] out uint propertyRegDataType, SafeGlobalMemoryBufferHandle propertyBuffer, [MarshalAs(UnmanagedType.U4)] uint propertyBufferSize, IntPtr requiredSize);
internal static extern uint GetSecurityDescriptorLength(SafeGlobalMemoryBufferHandle pSecurityDescriptor);
public void Write(byte[] buffer, int offset, int count, bool processSecurity) { if (buffer == null) throw new ArgumentNullException("buffer"); if (offset < 0) throw new ArgumentOutOfRangeException("offset", offset, Resources.OffsetMustNotBeNegative); if (count < 0) throw new ArgumentOutOfRangeException("count", count, Resources.CountMustNotBeNegative); if (offset + count > buffer.Length) throw new ArgumentException(Resources.BufferIsNotLargeEnoughForTheRequestedOperation); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count)) { safeBuffer.CopyFrom(buffer, offset, count); uint bytesWritten; if (!NativeMethods.BackupWrite(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out bytesWritten, false, processSecurity, out m_context)) NativeError.ThrowException(Marshal.GetLastWin32Error()); } }
internal static IEnumerable<FileIdBothDirectoryInfo> EnumerateFileIdBothDirectoryInfoInternal(KernelTransaction transaction, SafeFileHandle safeHandle, string path, FileShare shareMode, bool continueOnException, PathFormat pathFormat) { if (!NativeMethods.IsAtLeastWindowsVista) throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher); bool callerHandle = safeHandle != null; if (!callerHandle) { if (Utils.IsNullOrWhiteSpace(path)) throw new ArgumentNullException("path"); string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.FullCheck); safeHandle = File.CreateFileInternal(transaction, pathLp, ExtendedFileAttributes.BackupSemantics, null, FileMode.Open, FileSystemRights.ReadData, shareMode, true, PathFormat.LongFullPath); } try { if (!NativeMethods.IsValidHandle(safeHandle, Marshal.GetLastWin32Error(), !continueOnException)) yield break; // 2014-10-16: Number of returned items depends on the size of the buffer. // That does not seem right, investigate. using (var safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { NativeMethods.IsValidHandle(safeBuffer, Marshal.GetLastWin32Error()); long fileNameOffset = Marshal.OffsetOf(typeof(NativeMethods.FileIdBothDirInfo), "FileName").ToInt64(); while (NativeMethods.GetFileInformationByHandleEx(safeHandle, NativeMethods.FileInfoByHandleClass.FileIdBothDirectoryInfo, safeBuffer.DangerousGetHandle(), NativeMethods.DefaultFileBufferSize)) { // CA2001:AvoidCallingProblematicMethods IntPtr buffer = IntPtr.Zero; bool successRef = false; safeBuffer.DangerousAddRef(ref successRef); // MSDN: The DangerousGetHandle method poses a security risk because it can return a handle that is not valid. if (successRef) buffer = safeBuffer.DangerousGetHandle(); safeBuffer.DangerousRelease(); if (buffer == IntPtr.Zero) NativeError.ThrowException(Resources.HandleDangerousRef); // CA2001:AvoidCallingProblematicMethods while (buffer != IntPtr.Zero) { NativeMethods.FileIdBothDirInfo fibdi = Utils.MarshalPtrToStructure<NativeMethods.FileIdBothDirInfo>(0, buffer); string fileName = Marshal.PtrToStringUni(new IntPtr(fileNameOffset + buffer.ToInt64()), (int)(fibdi.FileNameLength / 2)); if (!Utils.IsNullOrWhiteSpace(fileName) && !fileName.Equals(Path.CurrentDirectoryPrefix, StringComparison.OrdinalIgnoreCase) && !fileName.Equals(Path.ParentDirectoryPrefix, StringComparison.OrdinalIgnoreCase)) yield return new FileIdBothDirectoryInfo(fibdi, fileName); buffer = fibdi.NextEntryOffset == 0 ? IntPtr.Zero : new IntPtr(buffer.ToInt64() + fibdi.NextEntryOffset); } } int lastError = Marshal.GetLastWin32Error(); switch ((uint)lastError) { case Win32Errors.ERROR_SUCCESS: case Win32Errors.ERROR_NO_MORE_FILES: case Win32Errors.ERROR_HANDLE_EOF: yield break; default: NativeError.ThrowException(lastError, path); break; } } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) safeHandle.Close(); } }
public BackupStreamInfo ReadStreamInfo() { using (SafeGlobalMemoryBufferHandle hBuf = new SafeGlobalMemoryBufferHandle(Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)))) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, (uint)Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID)), out numberOfBytesRead, false, mProcessSecurity, ref m_context)) NativeError.ThrowException(); if (numberOfBytesRead == 0) return null; if (numberOfBytesRead < Marshal.SizeOf(typeof(NativeMethods.WIN32_STREAM_ID))) throw new IOException(Resources.IncompleteHeaderRead); NativeMethods.WIN32_STREAM_ID streamID = hBuf.PtrToStructure<NativeMethods.WIN32_STREAM_ID>(); uint nameLength = (uint)Math.Min(streamID.StreamNameSize, hBuf.Capacity); if (!NativeMethods.BackupRead(_safeFileHandle, hBuf, nameLength, out numberOfBytesRead, false, mProcessSecurity, ref m_context)) NativeError.ThrowException(); string name = hBuf.PtrToStringUni((int)nameLength / 2); return new BackupStreamInfo(streamID, name); } }
public int Read(byte[] buffer, int offset, int count, bool processSecurity) { if (!CanRead) throw new NotSupportedException("Stream does not support reading"); if (buffer == null) throw new ArgumentNullException("buffer"); if (offset + count > buffer.Length) throw new ArgumentException("The sum of offset and count is larger than the size of the buffer."); if (offset < 0) throw new ArgumentOutOfRangeException("offset", offset, Resources.OffsetMustNotBeNegative); if (count < 0) throw new ArgumentOutOfRangeException("count", count, Resources.CountMustNotBeNegative); using (var safeBuffer = new SafeGlobalMemoryBufferHandle(count)) { uint numberOfBytesRead; if (!NativeMethods.BackupRead(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out numberOfBytesRead, false, processSecurity, ref m_context)) NativeError.ThrowException(Marshal.GetLastWin32Error()); // See File.GetAccessControlInternal(): .CopyTo() does not work there? safeBuffer.CopyTo(buffer, offset, count); return (int)numberOfBytesRead; } }
internal static extern SafeFindFileHandle FindFirstStreamW(string fileName, StreamInfoLevels infoLevel, SafeGlobalMemoryBufferHandle lpFindStreamData, int flags);
internal static extern bool FindNextStreamW(SafeFindFileHandle handle, SafeGlobalMemoryBufferHandle lpFindStreamData);
internal static extern bool GetSecurityDescriptorControl(SafeGlobalMemoryBufferHandle pSecurityDescriptor, out SecurityDescriptorControl pControl, out uint lpdwRevision);