我需要创建共享文件夹,显然我必须使用pinvoke NetShare *方法。 这部分没问题,但我想为共享文件夹添加一些共享权限。 我使用SetEntriesInAcl,但我一直收到错误1332:帐户名和安全ID之间没有映射。
定义:
internal enum MULTIPLE_TRUSTEE_OPERATION : uint
{
NO_MULTIPLE_TRUSTEE = 0,
TRUSTEE_IS_IMPERSONATE = 1
}
internal enum TRUSTEE_FORM : uint
{
TRUSTEE_IS_SID = 0,
TRUSTEE_IS_NAME = 1,
...
}
internal enum TRUSTEE_TYPE : uint
{
TRUSTEE_IS_UNKNOWN = 0,
TRUSTEE_IS_USER = 1,
TRUSTEE_IS_GROUP = 2,
...
}
internal enum ACCESS_MODE : uint
{
NOT_USED_ACCESS = 0,
GRANT_ACCESS = 1,
...
}
internal enum ACCESS_MASK : uint
{
GENERIC_ALL = 0x10000000, //268435456,
GENERIC_READ = 0x80000000, //2147483648L,
GENERIC_WRITE = 0x40000000, //1073741824,
GENERIC_EXECUTE = 0x20000000, //536870912,
STANDARD_RIGHTS_READ = 0x00020000, //131072
STANDARD_RIGHTS_WRITE = 0x00020000,
}
[DllImport("advapi32.dll", SetLastError = true)]
private static extern uint SetEntriesInAcl(
int cCountOfExplicitEntries,
ref EXPLICIT_ACCESS pListOfExplicitEntries,
IntPtr OldAcl,
out IntPtr NewAcl
);
以下是我如何调用它:
//This pointer will hold the full ACL (access control list) once the loop below has completed
IntPtr aclPtr = default(IntPtr);
EXPLICIT_ACCESS explicitAccessRule = new EXPLICIT_ACCESS();
TRUSTEE account = new TRUSTEE();
{
account.MultipleTrusteeOperation = MULTIPLE_TRUSTEE_OPERATION.NO_MULTIPLE_TRUSTEE;
account.pMultipleTrustee = 0;
account.TrusteeForm = TRUSTEE_FORM.TRUSTEE_IS_NAME;
account.ptstrName = "Everyone";
account.TrusteeType = TRUSTEE_TYPE.TRUSTEE_IS_USER;
}
explicitAccessRule.grfAccessMode = ACCESS_MODE.GRANT_ACCESS;
explicitAccessRule.grfAccessPermissions = ACCESS_MASK.GENERIC_READ | ACCESS_MASK.STANDARD_RIGHTS_READ | ACCESS_MASK.GENERIC_EXECUTE;
explicitAccessRule.grfInheritance = NO_INHERITANCE;
//Set the Trustee to the TRUSTEE structure we created earlier in the loop
explicitAccessRule.Trustee = account;
//Add this explicit access rule to the ACL
uint SetEntriesResult = SetEntriesInAcl(1, ref explicitAccessRule, aclPtr, out aclPtr);
任何人都知道我错过了什么? 或者还有另一种方法吗?
感谢。
答案 0 :(得分:1)
似乎无法映射Ansi名称。 如果您使用Unicode版本SetEntriesInAclW或明确设置CharSet属性,它将起作用。
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern uint SetEntriesInAcl(
int cCountOfExplicitEntries,
ref EXPLICIT_ACCESS pListOfExplicitEntries,
IntPtr OldAcl,
out IntPtr NewAcl);
您还可以使用BuildExplicitAccessWithName函数使用EXPLICIT_ACCESS结构。
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern void BuildExplicitAccessWithName(
ref EXPLICIT_ACCESS pExplicitAccess,
string pTrusteeName,
uint AccessPermissions,
uint AccessMode,
uint Inheritance);
答案 1 :(得分:0)
由于缺少CharSet,我的结构和方法定义中的定义不一致以及字符串参数的编组错误,我遇到了所有相同的问题。
我将代码示例放在不同的线程上,这样您就不必花费太多时间来尝试清除那些并不总是如此有用的Win32错误。
更新文件共享的权限:
A working .NET example using SetEntriesInAcl interop in action
答案 2 :(得分:-1)
对于初学者来说,变量aclPtr是一个输入变量。理想情况下,它应该从API GetSecurityInfo获得它的价值。 (http://msdn.microsoft.com/en-us/library/windows/desktop/aa446654(v=vs.85).aspx)谢谢。