internal static void RemoveStreamInternal(bool?isFolder, KernelTransaction transaction, string path, string name, bool?isFullPath) { string pathLp = isFullPath == null ? path : (bool)isFullPath ? Path.GetLongPathInternal(path, false, false, false, false) : Path.GetFullPathInternal(transaction, path, true, false, false, true, false, true, false); foreach (AlternateDataStreamInfo stream in EnumerateStreamsInternal(isFolder, transaction, null, pathLp, name, StreamType.AlternateData, isFullPath)) { File.DeleteFileInternal(transaction, string.Format(CultureInfo.CurrentCulture, "{0}{1}{2}{1}$DATA", pathLp, Path.StreamSeparator, stream.OriginalName), false, null); } }
/// <summary>[AlphaFS] Initializes the specified file name.</summary> /// <param name="isFolder">Specifies that <paramref name="path"/> is a file or directory.</param> /// <param name="transaction">The transaction.</param> /// <param name="path">The full path and name of the file.</param> /// <param name="isFullPath"> /// <para><c>true</c> <paramref name="path"/> is an absolute path. Unicode prefix is applied.</para> /// <para><c>false</c> <paramref name="path"/> will be checked and resolved to an absolute path. Unicode prefix is applied.</para> /// <para><c>null</c> <paramref name="path"/> is already an absolute path with Unicode prefix. Use as is.</para> /// </param> internal void InitializeInternal(bool isFolder, KernelTransaction transaction, string path, bool?isFullPath) { if (isFullPath != null && (bool)!isFullPath) { Path.CheckValidPath(path, true, true); } LongFullName = isFullPath == null ? path : (bool)isFullPath ? Path.GetLongPathInternal(path, false, false, false, false) #if NET35 : Path.GetFullPathInternal(transaction, path, true, false, false, !isFolder, true, false, false);
public static bool PathFileExists(string path) { if (Utils.IsNullOrWhiteSpace(path)) { return(false); } // PathFileExists() // In the ANSI version of this function, the name is limited to 248 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. return(NativeMethods.PathFileExists(Path.GetFullPathInternal(null, path, GetFullPathOptions.AsLongPath | GetFullPathOptions.FullCheck | GetFullPathOptions.ContinueOnNonExist))); }
/// <summary>Initializes a Shell32Info instance. /// <remarks>Shell32 is limited to MAX_PATH length.</remarks> /// <remarks>This constructor does not check if a file exists. This constructor is a placeholder for a string that is used to access the file in subsequent operations.</remarks> /// </summary> /// <param name="fileName">The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character.</param> /// <param name="isFullPath"> /// <para><c>true</c> <paramref name="fileName"/> is an absolute path. Unicode prefix is applied.</para> /// <para><c>false</c> <paramref name="fileName"/> will be checked and resolved to an absolute path. Unicode prefix is applied.</para> /// <para><c>null</c> <paramref name="fileName"/> is already an absolute path with Unicode prefix. Use as is.</para> /// </param> public Shell32Info(string fileName, bool?isFullPath) { if (Utils.IsNullOrWhiteSpace(fileName)) { throw new ArgumentNullException("fileName"); } // Shell32 is limited to MAX_PATH length. // Get a full path of regular format. FullPath = isFullPath == null ? fileName : (bool)isFullPath ? Path.GetRegularPathInternal(fileName, false, false, true, false) : Path.GetFullPathInternal(null, fileName, false, false, false, true, false, true, true); Initialize(); }
internal static IEnumerable <AlternateDataStreamInfo> EnumerateStreamsInternal(bool?isFolder, KernelTransaction transaction, SafeFileHandle safeHandle, string path, string originalName, StreamType?streamType, bool?isFullPath) { string pathLp = null; bool callerHandle = safeHandle != null; if (!callerHandle) { pathLp = isFullPath == null ? path : (bool)isFullPath ? Path.GetLongPathInternal(path, false, false, false, false) : Path.GetFullPathInternal(transaction, path, true, false, false, true, false, true, false); if (isFolder == null) { FileAttributes attrs = File.GetAttributesExInternal <FileAttributes>(transaction, pathLp, null); isFolder = (attrs & FileAttributes.Directory) == FileAttributes.Directory; } safeHandle = File.CreateFileInternal(transaction, pathLp, (bool)isFolder ? ExtendedFileAttributes.BackupSemantics : ExtendedFileAttributes.Normal, null, FileMode.Open, FileSystemRights.Read, FileShare.ReadWrite, false, null); } else { NativeMethods.IsValidHandle(safeHandle); } try { using (new PrivilegeEnabler(Privilege.Backup)) using (SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(NativeMethods.DefaultFileBufferSize)) { Type typeWin32Stream = typeof(NativeMethods.Win32StreamId); uint sizeOfType = (uint)Marshal.SizeOf(typeWin32Stream); uint numberOfBytesRead; IntPtr context; bool doLoop = true; while (doLoop) { if (!NativeMethods.BackupRead(safeHandle, safeBuffer, sizeOfType, out numberOfBytesRead, false, true, out context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp, true); } doLoop = numberOfBytesRead == sizeOfType; if (doLoop) { string streamName = null; string streamSearchName = null; // 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 NativeMethods.Win32StreamId stream = Utils.MarshalPtrToStructure <NativeMethods.Win32StreamId>(0, buffer); if (streamType == null || stream.StreamType == streamType) { if (stream.StreamNameSize > 0) { if (!NativeMethods.BackupRead(safeHandle, safeBuffer, stream.StreamNameSize, out numberOfBytesRead, false, true, out context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp, true); } // CA2001:AvoidCallingProblematicMethods buffer = IntPtr.Zero; 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 streamName = Marshal.PtrToStringUni(buffer, (int)numberOfBytesRead / 2); // Returned stream name format: ":streamName:$DATA" streamSearchName = streamName.TrimStart(Path.StreamSeparatorChar).Replace(Path.StreamSeparator + "$DATA", string.Empty); } if (originalName == null || (streamSearchName != null && streamSearchName.Equals(originalName, StringComparison.OrdinalIgnoreCase))) { yield return(new AlternateDataStreamInfo(stream, transaction, pathLp ?? path, streamName, originalName ?? streamSearchName, isFolder, isFullPath)); } } uint lo, hi; doLoop = !NativeMethods.BackupSeek(safeHandle, uint.MinValue, uint.MaxValue, out lo, out hi, out context); } } // MSDN: To release the memory used by the data structure, // call BackupRead with the bAbort parameter set to TRUE when the backup operation is complete. if (!NativeMethods.BackupRead(safeHandle, safeBuffer, 0, out numberOfBytesRead, true, false, out context)) { // Throws IOException. NativeError.ThrowException(Marshal.GetLastWin32Error(), pathLp, true); } } } finally { // Handle is ours, dispose. if (!callerHandle && safeHandle != null) { safeHandle.Close(); } } }