コード例 #1
0
        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();
                }
            }
        }
コード例 #2
0
        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());
                }
            }
        }
コード例 #3
0
ファイル: NativeMethods.cs プロジェクト: CDEApp/CDE
            /// <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;
            }
コード例 #4
0
 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;
    }
 }
コード例 #5
0
        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;
            }
        }
コード例 #6
0
ファイル: BackupFileStream.cs プロジェクト: CDEApp/CDE
        public bool 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 (SafeGlobalMemoryBufferHandle safeBuffer = new SafeGlobalMemoryBufferHandle(count))
            {
                safeBuffer.CopyFrom(buffer, offset, count);

                uint bytesWritten;

                if (!NativeMethods.BackupWrite(SafeFileHandle, safeBuffer, (uint)safeBuffer.Capacity, out bytesWritten, false, processSecurity, out _context))
                {
                    // Throws IOException.
                    NativeError.ThrowException(Marshal.GetLastWin32Error(), true);
                }
            }

            return(true);
        }
コード例 #7
0
        internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat)
        {
            if (pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            if (objectSecurity == null)
            {
                throw new ArgumentNullException("objectSecurity");
            }


            var managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm();

            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                var pathLp = Path.GetExtendedLengthPathCore(null, path, pathFormat, GetFullPathOptions.RemoveTrailingDirectorySeparator | GetFullPathOptions.CheckInvalidPathChars);

                safeBuffer.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);

                SECURITY_DESCRIPTOR_CONTROL control;
                uint revision;


                var success = Security.NativeMethods.GetSecurityDescriptorControl(safeBuffer, out control, out revision);

                var lastError = Marshal.GetLastWin32Error();
                if (!success)
                {
                    NativeError.ThrowException(lastError, pathLp);
                }


                PrivilegeEnabler privilegeEnabler = null;

                try
                {
                    var securityInfo = SECURITY_INFORMATION.None;
                    var pDacl        = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Access) != 0)
                    {
                        bool daclDefaulted, daclPresent;


                        success = Security.NativeMethods.GetSecurityDescriptorDacl(safeBuffer, out daclPresent, out pDacl, out daclDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (daclPresent)
                        {
                            securityInfo |= SECURITY_INFORMATION.DACL_SECURITY_INFORMATION;
                            securityInfo |= (control & SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0 ? SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION : SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION;
                        }
                    }


                    var pSacl = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Audit) != 0)
                    {
                        bool saclDefaulted, saclPresent;


                        success = Security.NativeMethods.GetSecurityDescriptorSacl(safeBuffer, out saclPresent, out pSacl, out saclDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (saclPresent)
                        {
                            securityInfo |= SECURITY_INFORMATION.SACL_SECURITY_INFORMATION;
                            securityInfo |= (control & SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0 ? SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION : SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION;

                            privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                        }
                    }


                    var pOwner = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Owner) != 0)
                    {
                        bool ownerDefaulted;


                        success = Security.NativeMethods.GetSecurityDescriptorOwner(safeBuffer, out pOwner, out ownerDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (pOwner != IntPtr.Zero)
                        {
                            securityInfo |= SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION;
                        }
                    }


                    var pGroup = IntPtr.Zero;

                    if ((includeSections & AccessControlSections.Group) != 0)
                    {
                        bool groupDefaulted;


                        success = Security.NativeMethods.GetSecurityDescriptorGroup(safeBuffer, out pGroup, out groupDefaulted);

                        lastError = Marshal.GetLastWin32Error();
                        if (!success)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }


                        if (pGroup != IntPtr.Zero)
                        {
                            securityInfo |= SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
                        }
                    }



                    if (!Utils.IsNullOrWhiteSpace(pathLp))
                    {
                        // SetNamedSecurityInfo()
                        // 2013-01-13: MSDN does not confirm LongPath usage but a Unicode version of this function exists.

                        lastError = (int)Security.NativeMethods.SetNamedSecurityInfo(pathLp, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, pOwner, pGroup, pDacl, pSacl);

                        if (lastError != Win32Errors.ERROR_SUCCESS)
                        {
                            NativeError.ThrowException(lastError, pathLp);
                        }
                    }

                    else
                    {
                        if (NativeMethods.IsValidHandle(handle))
                        {
                            lastError = (int)Security.NativeMethods.SetSecurityInfo(handle, SE_OBJECT_TYPE.SE_FILE_OBJECT, securityInfo, pOwner, pGroup, pDacl, pSacl);

                            if (lastError != Win32Errors.ERROR_SUCCESS)
                            {
                                NativeError.ThrowException(lastError);
                            }
                        }
                    }
                }
                finally
                {
                    if (null != privilegeEnabler)
                    {
                        privilegeEnabler.Dispose();
                    }
                }
            }
        }
コード例 #8
0
ファイル: NativeMethods.cs プロジェクト: CDEApp/CDE
        internal static void SetSecurityInfo(SafeHandle handle, NativeMethods.SE_OBJECT_TYPE objectType, NativeObjectSecurity fileSecurity)
        {
            byte[] managedDescriptor = fileSecurity.GetSecurityDescriptorBinaryForm();
            using (SafeGlobalMemoryBufferHandle hDescriptor = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                hDescriptor.CopyFrom(managedDescriptor, 0, managedDescriptor.Length);


                NativeMethods.SECURITY_DESCRIPTOR_CONTROL control;
                uint revision;
                if (!NativeMethods.GetSecurityDescriptorControl(hDescriptor, out control, out revision))
                {
                    NativeError.ThrowException();
                }

                IntPtr pDacl;
                bool   daclDefaulted, daclPresent;
                if (!NativeMethods.GetSecurityDescriptorDacl(hDescriptor, out daclPresent, out pDacl, out daclDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pSacl;
                bool   saclDefaulted, saclPresent;
                if (!NativeMethods.GetSecurityDescriptorSacl(hDescriptor, out saclPresent, out pSacl, out saclDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pOwner;
                bool   ownerDefaulted;
                if (!NativeMethods.GetSecurityDescriptorOwner(hDescriptor, out pOwner, out ownerDefaulted))
                {
                    NativeError.ThrowException();
                }

                IntPtr pGroup;
                bool   GroupDefaulted;
                if (!NativeMethods.GetSecurityDescriptorGroup(hDescriptor, out pGroup, out GroupDefaulted))
                {
                    NativeError.ThrowException();
                }

                PrivilegeEnabler privilegeEnabler = null;
                try
                {
                    NativeMethods.SECURITY_INFORMATION info = 0;

                    if (daclPresent)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.DACL_SECURITY_INFORMATION;

                        if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_DACL_PROTECTED) != 0)
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_DACL_SECURITY_INFORMATION;
                        }
                        else
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_DACL_SECURITY_INFORMATION;
                        }
                    }

                    if (saclPresent)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.SACL_SECURITY_INFORMATION;
                        if ((control & NativeMethods.SECURITY_DESCRIPTOR_CONTROL.SE_SACL_PROTECTED) != 0)
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.PROTECTED_SACL_SECURITY_INFORMATION;
                        }
                        else
                        {
                            info |= NativeMethods.SECURITY_INFORMATION.UNPROTECTED_SACL_SECURITY_INFORMATION;
                        }

                        privilegeEnabler = new PrivilegeEnabler(Privilege.Security);
                    }

                    if (pOwner != IntPtr.Zero)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.OWNER_SECURITY_INFORMATION;
                    }

                    if (pGroup != IntPtr.Zero)
                    {
                        info |= NativeMethods.SECURITY_INFORMATION.GROUP_SECURITY_INFORMATION;
                    }

                    uint errorCode = NativeMethods.SetSecurityInfo(handle, objectType, info, pOwner, pGroup, pDacl, pSacl);

                    if (errorCode != 0)
                    {
                        NativeError.ThrowException((int)errorCode);
                    }
                }
                finally
                {
                    if (privilegeEnabler != null)
                    {
                        privilegeEnabler.Dispose();
                    }
                }
            }
        }
コード例 #9
0
        internal static void SetAccessControlCore(string path, SafeFileHandle handle, ObjectSecurity objectSecurity, AccessControlSections includeSections, PathFormat pathFormat)
        {
            if (pathFormat == PathFormat.RelativePath)
            {
                Path.CheckSupportedPathFormat(path, true, true);
            }

            if (objectSecurity == null)
            {
                throw new ArgumentNullException("objectSecurity");
            }


            byte[] managedDescriptor = objectSecurity.GetSecurityDescriptorBinaryForm();

            using (var safeBuffer = new SafeGlobalMemoryBufferHandle(managedDescriptor.Length))
            {
                string pathLp = Path.GetExtendedLengthPathCore(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();
                    }
                }
            }
        }
コード例 #10
0
ファイル: BackupFileStream.cs プロジェクト: Sicos1977/AlphaFS
      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());
         }
      }
コード例 #11
0
      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();
            }
         }
      }