Example #1
0
        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);
            }
        }
Example #2
0
        /// <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);
Example #3
0
        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)));
        }
Example #4
0
        /// <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();
        }
Example #5
0
        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();
                }
            }
        }