Exemple #1
0
        internal static SafeFileHandle CreateFileCore(KernelTransaction transaction, bool? isFolder, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, bool continueOnException, PathFormat pathFormat)
        {
            if (checkPath && pathFormat == PathFormat.RelativePath)

            Path.CheckSupportedPathFormat(path, true, true);

             // When isFile == null, we're working with a device.
             // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
             // the path string should be the following form: "\\.\X:"
             // Do not use a trailing backslash ('\'), which indicates the root.

             var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

             // CreateFileXxx() does not support FileMode.Append mode.
             var isAppend = fileMode == FileMode.Append;
             if (isAppend)
             {
            fileMode = FileMode.OpenOrCreate;
            fileSystemRights |= FileSystemRights.AppendData;
             }

             if (null != fileSecurity)
            fileSystemRights |= (FileSystemRights)SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION;

             using ((fileSystemRights & (FileSystemRights)SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION) != 0 || (fileSystemRights & (FileSystemRights) SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION) != 0 ? new PrivilegeEnabler(Privilege.Security) : null)

             using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
             {
            var safeHandle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

               // CreateFile() / CreateFileTransacted()
               // 2013-01-13: MSDN confirms LongPath usage.

               ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)

               : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

            var lastError = Marshal.GetLastWin32Error();

            NativeMethods.CloseHandleAndPossiblyThrowException(safeHandle, lastError, isFolder, path, !continueOnException);

            if (isAppend)
            {
               var success = NativeMethods.SetFilePointerEx(safeHandle, 0, IntPtr.Zero, SeekOrigin.End);

               lastError = Marshal.GetLastWin32Error();

               if (!success)
               {
                  NativeMethods.CloseHandleAndPossiblyThrowException(safeHandle, lastError, isFolder, path, !continueOnException);

                  return null;
               }
            }

            return safeHandle;
             }
        }
      public KernelTransaction(ObjectSecurity securityDescriptor, uint timeout, string description)
      {
         if (!NativeMethods.IsAtLeastWindowsVista)
            throw new PlatformNotSupportedException(Resources.RequiresWindowsVistaOrHigher);

         using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(securityDescriptor))
         {

            _hTrans = NativeMethods.CreateTransaction(securityAttributes, IntPtr.Zero, 0, 0, 0, timeout, description);
            int lastError = Marshal.GetLastWin32Error();            

            NativeMethods.IsValidHandle(_hTrans, lastError);
         }
      }
Exemple #3
0
        public KernelTransaction(ObjectSecurity securityDescriptor, int timeout, string description)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(Resources.Requires_Windows_Vista_Or_Higher);
            }

            using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(securityDescriptor))
            {
                _hTrans = NativeMethods.CreateTransaction(securityAttributes, IntPtr.Zero, 0, 0, 0, timeout, description);
                int lastError = Marshal.GetLastWin32Error();

                NativeMethods.IsValidHandle(_hTrans, lastError);
            }
        }
Exemple #4
0
        public KernelTransaction(ObjectSecurity securityDescriptor, int timeout, string description)
        {
            if (!NativeMethods.IsAtLeastWindowsVista)
            {
                throw new PlatformNotSupportedException(new Win32Exception((int)Win32Errors.ERROR_OLD_WIN_VERSION).Message);
            }

            using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(securityDescriptor))
            {
                _hTrans = NativeMethods.CreateTransaction(securityAttributes, IntPtr.Zero, 0, 0, 0, timeout, description);
                int lastError = Marshal.GetLastWin32Error();

                NativeMethods.IsValidHandle(_hTrans, lastError);
            }
        }
Exemple #5
0
 internal static extern SafeKernelTransactionHandle CreateTransaction([MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpTransactionAttributes, IntPtr uow, [MarshalAs(UnmanagedType.U4)] uint createOptions, [MarshalAs(UnmanagedType.U4)] uint isolationLevel, [MarshalAs(UnmanagedType.U4)] uint isolationFlags, [MarshalAs(UnmanagedType.U4)] int timeout, [MarshalAs(UnmanagedType.LPWStr)] string description);
Exemple #6
0
        internal static SafeFileHandle CreateFileCore(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat)
        {
            if (checkPath && pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            // When isFile == null, we're working with a device.
            // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
            // the path string should be the following form: "\\.\X:"
            // Do not use a trailing backslash (\), which indicates the root.

            var pathLp = Path.GetExtendedLengthPathCore(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

            PrivilegeEnabler privilegeEnabler = null;


            var isAppend = fileMode == FileMode.Append;


            // CreateFileXxx() does not support FileMode.Append mode.
            if (isAppend)
            {
                fileMode          = FileMode.OpenOrCreate;
                fileSystemRights &= FileSystemRights.AppendData; // Add right.
            }


            if (fileSecurity != null)
            {
                fileSystemRights |= (FileSystemRights)0x1000000; // Set right.
            }
            // AccessSystemSecurity = 0x1000000    AccessSystemAcl access type.
            // MaximumAllowed       = 0x2000000    MaximumAllowed  access type.

            if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 ||
                (fileSystemRights & (FileSystemRights)0x2000000) != 0)
            {
                privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
            }


            using (privilegeEnabler)
                using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
                {
                    var handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

                                 // CreateFile() / CreateFileTransacted()
                                 // 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 confirms LongPath usage.

               ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)
               : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

                    var lastError = Marshal.GetLastWin32Error();

                    if (handle.IsInvalid)
                    {
                        handle.Close();
                        NativeError.ThrowException(lastError, pathLp);
                    }


                    if (isAppend)
                    {
                        var stream = new FileStream(handle, FileAccess.Write, NativeMethods.DefaultFileBufferSize, (attributes & ExtendedFileAttributes.Overlapped) != 0);
                        stream.Seek(0, SeekOrigin.End);
                    }

                    return(handle);
                }
        }
 internal static extern bool CreateDirectoryEx([MarshalAs(UnmanagedType.LPWStr)] string lpTemplateDirectory, [MarshalAs(UnmanagedType.LPWStr)] string lpPathName, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes);
 internal static extern bool CreateDirectoryTransacted([MarshalAs(UnmanagedType.LPWStr)] string lpTemplateDirectory, [MarshalAs(UnmanagedType.LPWStr)] string lpNewDirectory, [MarshalAs(UnmanagedType.LPStruct)] Security.NativeMethods.SecurityAttributes lpSecurityAttributes, SafeHandle hTransaction);
      internal static DirectoryInfo CreateDirectoryInternal(KernelTransaction transaction, string path, string templatePath, ObjectSecurity directorySecurity, bool compress, PathFormat pathFormat)
      {
         if (pathFormat == PathFormat.RelativePath)
         {
            if (path != null && path[0] == Path.VolumeSeparatorChar)
               throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.PathFormatUnsupported, path));

            if (templatePath != null && templatePath[0] == Path.VolumeSeparatorChar)
               throw new ArgumentException(String.Format(CultureInfo.CurrentCulture, Resources.PathFormatUnsupported, templatePath));

            Path.CheckValidPath(path, true, true);
            Path.CheckValidPath(templatePath, true, true);
         }
         else
            // MSDN:. NET 3.5+: NotSupportedException: Path contains a colon character (:) that is not part of a drive label ("C:\").
            Path.CheckValidPath(path, false, false);

         string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

         // Return DirectoryInfo instance if the directory specified by path already exists.
         if (File.ExistsInternal(true, transaction, pathLp, PathFormat.LongFullPath))
            return new DirectoryInfo(transaction, pathLp, PathFormat.LongFullPath);

         // MSDN: .NET 3.5+: IOException: The directory specified by path is a file or the network name was not found.
         if (File.ExistsInternal(false, transaction, pathLp, PathFormat.LongFullPath))
            NativeError.ThrowException(Win32Errors.ERROR_ALREADY_EXISTS, pathLp);


         string templatePathLp = Utils.IsNullOrWhiteSpace(templatePath)
            ? null
            : Path.GetExtendedLengthPathInternal(transaction, templatePath, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

         #region Construct Full Path

         string longPathPrefix = Path.IsUncPath(path, false) ? Path.LongPathUncPrefix : Path.LongPathPrefix;
         path = Path.GetRegularPathInternal(pathLp, GetFullPathOptions.None);

         int length = path.Length;
         if (length >= 2 && Path.IsDVsc(path[length - 1], false))
            --length;

         int rootLength = Path.GetRootLength(path, false);
         if (length == 2 && Path.IsDVsc(path[1], false))
            throw new ArgumentException(Resources.CannotCreateDirectory, path);


         // Check if directories are missing.
         Stack<string> list = new Stack<string>(100);

         if (length > rootLength)
         {
            for (int index = length - 1; index >= rootLength; --index)
            {
               string path1 = path.Substring(0, index + 1);
               string path2 = longPathPrefix + path1.TrimStart('\\');

               if (!File.ExistsInternal(true, transaction, path2, PathFormat.LongFullPath))
                  list.Push(path2);

               while (index > rootLength && !Path.IsDVsc(path[index], false))
                  --index;
            }
         }

         #endregion // Construct Full Path

         // Directory security.
         using (Security.NativeMethods.SecurityAttributes securityAttributes = new Security.NativeMethods.SecurityAttributes(directorySecurity))
         {
            // Create the directory paths.
            while (list.Count > 0)
            {
               string folderLp = list.Pop();

               // 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 confirms LongPath usage.

               bool createOk = (transaction == null || !NativeMethods.IsAtLeastWindowsVista
                  ? (templatePathLp == null
                     ? NativeMethods.CreateDirectory(folderLp, securityAttributes)
                     : NativeMethods.CreateDirectoryEx(templatePathLp, folderLp, securityAttributes))
                  : NativeMethods.CreateDirectoryTransacted(templatePathLp, folderLp, securityAttributes, transaction.SafeHandle));

               if (!createOk)
               {
                  int lastError = Marshal.GetLastWin32Error();

                  switch ((uint)lastError)
                  {
                     // MSDN: .NET 3.5+: If the directory already exists, this method does nothing.
                     // MSDN: .NET 3.5+: IOException: The directory specified by path is a file.
                     case Win32Errors.ERROR_ALREADY_EXISTS:
                        if (File.ExistsInternal(false, transaction, pathLp, PathFormat.LongFullPath))
                           NativeError.ThrowException(lastError, pathLp);

                        if (File.ExistsInternal(false, transaction, folderLp, PathFormat.LongFullPath))
                           NativeError.ThrowException(Win32Errors.ERROR_PATH_NOT_FOUND, folderLp);
                        break;

                     case Win32Errors.ERROR_BAD_NET_NAME:
                        NativeError.ThrowException(lastError, pathLp);
                        break;

                     case Win32Errors.ERROR_DIRECTORY:
                        // MSDN: .NET 3.5+: NotSupportedException: path contains a colon character (:) that is not part of a drive label ("C:\").
                        throw new NotSupportedException(String.Format(CultureInfo.CurrentCulture, Resources.PathFormatUnsupported, path));

                     default:
                        NativeError.ThrowException(lastError, folderLp);
                        break;
                  }
               }
               else if (compress)
                  Device.ToggleCompressionInternal(true, transaction, folderLp, true, PathFormat.LongFullPath);
            }
         }

         return new DirectoryInfo(transaction, pathLp, PathFormat.FullPath);
      }
        internal static SafeFileHandle CreateFileInternal(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat)
        {
            if (checkPath && pathFormat == PathFormat.RelativePath)
            {
                Path.CheckValidPath(path, true, true);
            }

            // When isFile == null, we're working with a device.
            // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
            // the path string should be the following form: "\\.\X:"
            // Do not use a trailing backslash (\), which indicates the root.

            string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

            PrivilegeEnabler privilegeEnabler = null;

            try
            {
                if (fileSecurity != null)
                {
                    fileSystemRights |= (FileSystemRights)0x1000000;
                }

                // AccessSystemSecurity = 0x1000000    AccessSystemAcl access type.
                // MaximumAllowed       = 0x2000000    MaximumAllowed access type.
                if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 ||
                    (fileSystemRights & (FileSystemRights)0x2000000) != 0)
                {
                    privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                }


                using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
                {
                    SafeFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

                                            // CreateFile() / CreateFileTransacted()
                                            // 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 confirms LongPath usage.

                  ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)
                  : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

                    int lastError = Marshal.GetLastWin32Error();
                    if (handle.IsInvalid)
                    {
                        handle.Close();
                        NativeError.ThrowException(lastError, pathLp);
                    }

                    return(handle);
                }
            }
            finally
            {
                if (privilegeEnabler != null)
                {
                    privilegeEnabler.Dispose();
                }
            }
        }
Exemple #11
0
      internal static SafeFileHandle CreateFileInternal(KernelTransaction transaction, string path, ExtendedFileAttributes attributes, FileSecurity fileSecurity, FileMode fileMode, FileSystemRights fileSystemRights, FileShare fileShare, bool checkPath, PathFormat pathFormat)
      {
         if (checkPath && pathFormat == PathFormat.RelativePath)
            Path.CheckValidPath(path, true, true);

         // When isFile == null, we're working with a device.
         // When opening a VOLUME or removable media drive (for example, a floppy disk drive or flash memory thumb drive),
         // the path string should be the following form: "\\.\X:"
         // Do not use a trailing backslash (\), which indicates the root.

         string pathLp = Path.GetExtendedLengthPathInternal(transaction, path, pathFormat, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);

         PrivilegeEnabler privilegeEnabler = null;
         try
         {
            if (fileSecurity != null)
               fileSystemRights |= (FileSystemRights)0x1000000;

            // AccessSystemSecurity = 0x1000000    AccessSystemAcl access type.
            // MaximumAllowed       = 0x2000000    MaximumAllowed access type.            
            if ((fileSystemRights & (FileSystemRights)0x1000000) != 0 ||
                (fileSystemRights & (FileSystemRights)0x2000000) != 0)
               privilegeEnabler = new PrivilegeEnabler(Privilege.Security);


            using (var securityAttributes = new Security.NativeMethods.SecurityAttributes(fileSecurity))
            {
               SafeFileHandle handle = transaction == null || !NativeMethods.IsAtLeastWindowsVista

                  // CreateFile() / CreateFileTransacted()
                  // 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 confirms LongPath usage.

                  ? NativeMethods.CreateFile(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero)
                  : NativeMethods.CreateFileTransacted(pathLp, fileSystemRights, fileShare, securityAttributes, fileMode, attributes, IntPtr.Zero, transaction.SafeHandle, IntPtr.Zero, IntPtr.Zero);

               int lastError = Marshal.GetLastWin32Error();
               if (handle.IsInvalid)
               {
                  handle.Close();
                  NativeError.ThrowException(lastError, pathLp);
               }

               return handle;
            }
         }
         finally
         {
            if (privilegeEnabler != null)
               privilegeEnabler.Dispose();
         }
      }