如何使用P / Invoke复制文件/目录权限?

时间:2011-07-11 18:10:09

标签: c# security pinvoke file-permissions

我正在寻找解决方案几个小时,但文档很少,我无法找到我需要的东西。

如果我有一个文件或目录,我怎么能在C#with P / Invoke中将权限(即所有者和SID及其权限)从一个文件复制到另一个文件或从一个目录复制到另一个目录,假设这些文件和目录是在同一台机器上还是由同一台Active Directory服务器控制的网络上?

1 个答案:

答案 0 :(得分:0)

以下是使用GetNamedSecurityInfo和的示例 SetNamedSecurityInfo

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Security.AccessControl;

namespace PermissionsExample
{
    class Program
    {
        static void Main(string[] args)
        {
            string source = "C:\\source.txt";
            string dest = "C:\\dest.txt";

            string result = CopyPermissions(source, dest);
            if (!string.IsNullOrEmpty(result)) { Console.WriteLine(result); }
            else { Console.WriteLine("SUCCESS"); }
        }

        public static string CopyPermissions(string source_file, string dest_file)
        {
            string errmsg = string.Empty;
            IntPtr sidOwner = IntPtr.Zero;
            IntPtr sidOwnerDescriptor = IntPtr.Zero;
            IntPtr sidGroup = IntPtr.Zero;
            IntPtr sidGroupDescriptor = IntPtr.Zero;
            IntPtr dacl = IntPtr.Zero;
            IntPtr daclDescriptor = IntPtr.Zero;
            IntPtr sacl = IntPtr.Zero;
            try
            {
                int result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.DiscretionaryAcl, out sidOwner, out sidGroup, out dacl, out sacl, out daclDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }
                result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.Owner, out sidOwner, out sidGroup, out dacl, out sacl, out sidGroupDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }

                result = GetNamedSecurityInfo(source_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfos.Group, out sidOwner, out sidGroup, out dacl, out sacl, out sidGroupDescriptor);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }

                SecurityInfos info = SecurityInfos.DiscretionaryAcl | SecurityInfos.Group | SecurityInfos.Owner;
                result = SetNamedSecurityInfo(dest_file, SE_OBJECT_TYPE.SE_FILE_OBJECT, info, sidOwner, sidGroup, dacl, sacl);
                if (result != 0)
                {
                    Win32Exception e = new Win32Exception(result);
                    errmsg = "ERROR: " + e.Message;
                    return errmsg;
                }
            }
            finally
            {
                if (sidOwnerDescriptor != IntPtr.Zero && LocalFree(sidOwnerDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
                if (sidGroupDescriptor != IntPtr.Zero && LocalFree(sidGroupDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
                if (daclDescriptor != IntPtr.Zero && LocalFree(daclDescriptor) != IntPtr.Zero)
                {
                    int err = Marshal.GetLastWin32Error();
                    Win32Exception e = new Win32Exception(err);
                    errmsg += "ERROR: " + e.Message;
                }
            }

            return errmsg;
        }

        public enum SE_OBJECT_TYPE
        {
            SE_UNKNOWN_OBJECT_TYPE = 0,
            SE_FILE_OBJECT,
            SE_SERVICE,
            SE_PRINTER,
            SE_REGISTRY_KEY,
            SE_LMSHARE,
            SE_KERNEL_OBJECT,
            SE_WINDOW_OBJECT,
            SE_DS_OBJECT,
            SE_DS_OBJECT_ALL,
            SE_PROVIDER_DEFINED_OBJECT,
            SE_WMIGUID_OBJECT,
            SE_REGISTRY_WOW64_32KEY
        }

        [DllImport("advapi32.dll", EntryPoint = "GetNamedSecurityInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int GetNamedSecurityInfo(string objectName, SE_OBJECT_TYPE objectType,
            System.Security.AccessControl.SecurityInfos securityInfo, out IntPtr sidOwner,
            out IntPtr sidGroup, out IntPtr dacl, out IntPtr sacl, out IntPtr securityDescriptor);

        [DllImport("advapi32.dll", EntryPoint = "SetNamedSecurityInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)]
        private static extern int SetNamedSecurityInfo(string objectName, SE_OBJECT_TYPE objectType,
            System.Security.AccessControl.SecurityInfos securityInfo, IntPtr sidOwner,
            IntPtr sidGroup, IntPtr dacl, IntPtr sacl);

        [DllImport("kernel32.dll", EntryPoint = "LocalFree", ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr LocalFree(IntPtr hMem);
    }
}