使用 ABE 以编程方式创建共享文件夹

Creating a shared folder programaticly with ABE

我正在远程 computer/server 上创建一个共享文件夹并且可以正常工作,但我无法找到是否可以更改共享设置。我希望能够关闭允许缓存共享并打开基于访问的枚举,但我无法在此处通过搜索 google 找到任何相关内容。有人知道 C# 是否可行吗?

我用来创建共享的代码是:

public static void CreateRemoteShare(string servername, string FolderPath, string ShareName, string Description)
    {
        try
        {
            string scope = string.Format("\\{0}\root\cimv2", servername);

            ManagementScope ms = new ManagementScope(scope);

            ManagementClass managementClass = new ManagementClass("Win32_Share");
            managementClass.Scope = ms;                
            ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
            ManagementBaseObject outParams;

            inParams["Description"] = Description;
            inParams["Name"] = ShareName;
            inParams["Path"] = FolderPath;
            inParams["Type"] = 0x0;                

            NTAccount everyoneAccount = new NTAccount(null, "EVERYONE");
            SecurityIdentifier sid = (SecurityIdentifier)everyoneAccount.Translate(typeof(SecurityIdentifier));
            byte[] sidArray = new byte[sid.BinaryLength];
            sid.GetBinaryForm(sidArray, 0);

            ManagementObject everyone = new ManagementClass("Win32_Trustee");
            everyone["Domain"] = null;
            everyone["Name"] = "EVERYONE";
            everyone["SID"] = sidArray;

            ManagementObject dacl = new ManagementClass("Win32_Ace");
            dacl["AccessMask"] = 2032127;
            dacl["AceFlags"] = 3;
            dacl["AceType"] = 0;
            dacl["Trustee"] = everyone;

            ManagementObject securityDescriptor = new ManagementClass("Win32_SecurityDescriptor");
            securityDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT 
            securityDescriptor["DACL"] = new object[] { dacl };

            inParams["Access"] = securityDescriptor;

            outParams = managementClass.InvokeMethod("Create", inParams, null);

        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);                
        }
    }

如果有人知道有什么方法可以做到这一点,我将永远感激不尽。

在进一步研究之后,我发现了一个网站,其中包含一种在 PowerShell 中执行此操作的方法,我从该网站将其添加到我的 C# 代码中。该站点是:ABE Powershell

提取出来的结果代码如下:

public enum Share_Type : uint
    {
        STYPE_DISKTREE = 0x00000000,   // Disk Drive
        STYPE_PRINTQ = 0x00000001,   // Print Queue
        STYPE_DEVICE = 0x00000002,   // Communications Device
        STYPE_IPC = 0x00000003,   // InterProcess Communications
        STYPE_SPECIAL = 0x80000000,   // Special share types (C$, ADMIN$, IPC$, etc)
        STYPE_TEMPORARY = 0x40000000   // Temporary share 
    }

    public enum Share_ReturnValue : int
    {
        NERR_Success = 0,
        ERROR_ACCESS_DENIED = 5,
        ERROR_NOT_ENOUGH_MEMORY = 8,
        ERROR_INVALID_PARAMETER = 87,
        ERROR_INVALID_LEVEL = 124, // unimplemented level for info
        ERROR_MORE_DATA = 234,
        NERR_BufTooSmall = 2123, // The API return buffer is too small.
        NERR_NetNameNotFound = 2310 // This shared resource does not exist.
    }

    [System.Flags]
    public enum Shi1005_flags
    {
        SHI1005_FLAGS_DFS = 0x0001,  // Part of a DFS tree (Cannot be set)
        SHI1005_FLAGS_DFS_ROOT = 0x0002,  // Root of a DFS tree (Cannot be set)
        SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS = 0x0100,  // Disallow Exclusive file open
        SHI1005_FLAGS_FORCE_SHARED_DELETE = 0x0200,  // Open files can be force deleted
        SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING = 0x0400,  // Clients can cache the namespace
        SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM = 0x0800,  // Only directories for which a user has FILE_LIST_DIRECTORY will be listed
        SHI1005_FLAGS_FORCE_LEVELII_OPLOCK = 0x1000,  // Prevents exclusive caching
        SHI1005_FLAGS_ENABLE_HASH = 0x2000,  // Used for server side support for peer caching
        SHI1005_FLAGS_ENABLE_CA = 0X4000   // Used for Clustered shares
    }

    public static class NetApi32
    {

        // ********** Structures **********

        // SHARE_INFO_502
        [StructLayout(LayoutKind.Sequential)]
        public struct SHARE_INFO_502
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string shi502_netname;
            public uint shi502_type;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string shi502_remark;
            public Int32 shi502_permissions;
            public Int32 shi502_max_uses;
            public Int32 shi502_current_uses;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string shi502_path;
            public IntPtr shi502_passwd;
            public Int32 shi502_reserved;
            public IntPtr shi502_security_descriptor;
        }

        // SHARE_INFO_1005
        [StructLayout(LayoutKind.Sequential)]
        public struct SHARE_INFO_1005
        {
            public Int32 Shi1005_flags;
        }



        private class unmanaged
        {

            //NetShareGetInfo
            [DllImport("Netapi32.dll", SetLastError = true)]
            internal static extern int NetShareGetInfo(
                [MarshalAs(UnmanagedType.LPWStr)] string serverName,
                [MarshalAs(UnmanagedType.LPWStr)] string netName,
                Int32 level,
                ref IntPtr bufPtr
            );

            [DllImport("Netapi32.dll", SetLastError = true)]
            public extern static Int32 NetShareSetInfo(
                [MarshalAs(UnmanagedType.LPWStr)] string servername,
                [MarshalAs(UnmanagedType.LPWStr)] string netname, Int32 level, IntPtr bufptr, out Int32 parm_err);


        }

        // ***** Functions *****
        public static SHARE_INFO_502 NetShareGetInfo_502(string ServerName, string ShareName)
        {
            Int32 level = 502;
            IntPtr lShareInfo = IntPtr.Zero;
            SHARE_INFO_502 shi502_Info = new SHARE_INFO_502();
            Int32 result = unmanaged.NetShareGetInfo(ServerName, ShareName, level, ref lShareInfo);
            if ((Share_ReturnValue)result == Share_ReturnValue.NERR_Success)
            {
                shi502_Info = (SHARE_INFO_502)Marshal.PtrToStructure(lShareInfo, typeof(SHARE_INFO_502));
            }
            else
            {
                throw new Exception("Unable to get 502 structure.  Function returned: " + (Share_ReturnValue)result);
            }
            return shi502_Info;
        }

        public static SHARE_INFO_1005 NetShareGetInfo_1005(string ServerName, string ShareName)
        {
            Int32 level = 1005;
            IntPtr lShareInfo = IntPtr.Zero;
            SHARE_INFO_1005 shi1005_Info = new SHARE_INFO_1005();
            Int32 result = unmanaged.NetShareGetInfo(ServerName, ShareName, level, ref lShareInfo);
            if ((Share_ReturnValue)result == Share_ReturnValue.NERR_Success)
            {
                shi1005_Info = (SHARE_INFO_1005)Marshal.PtrToStructure(lShareInfo, typeof(SHARE_INFO_1005));
            }
            else
            {
                throw new Exception("Unable to get 1005 structure.  Function returned: " + (Share_ReturnValue)result);
            }
            return shi1005_Info;
        }

        public static int NetShareSetInfo_1005(string ServerName, string ShareName, SHARE_INFO_1005 shi1005_Info) //  Int32 Shi1005_flags
        {
            Int32 level = 1005;
            Int32 err;

            IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(shi1005_Info));
            Marshal.StructureToPtr(shi1005_Info, ptr, false);

            var result = unmanaged.NetShareSetInfo(ServerName, ShareName, level, ptr, out err);

            return result;
        }

    }


    static void Main(string[] args)
    {
        abeTest();
    }        

    public static void abeTest()
    {            
        NetApi32.SHARE_INFO_1005 test = new NetApi32.SHARE_INFO_1005();
        test.Shi1005_flags = 2048;
        NetApi32.NetShareSetInfo_1005("FileStore2", "TestShare2$", test);
    }

通过组合此代码和上述代码,您可以创建共享并设置基于访问权限的枚举。