问题描述
编辑:还有一个后续的http://stackoverflow.com/questions/1799742/shouldnt-netusermodalsget-tell-me-what-domain-a-machine-is-part-of-and-where
由于贡萨洛的帮助下,我能使用NetUserModalsGet()从C#。但是,还是有一些扭结:字符串成员( usrmod1_primary
和 usrmod2_domain_name
)问世搞砸了。这里的code:
Thanks to Gonzalo's help, I'm able to use the NetUserModalsGet() from C#. But there's still some kinks: the string members (usrmod1_primary
and usrmod2_domain_name
) come out messed up. Here's the code:
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern uint NetUserModalsGet(
string server,
int level,
out IntPtr BufPtr
);
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
public static extern uint NetApiBufferFree(
IntPtr bufptr
);
public struct USER_MODALS_INFO_0
{
public uint usrmod0_min_passwd_len;
public uint usrmod0_max_passwd_age;
public uint usrmod0_min_passwd_age;
public uint usrmod0_force_logoff;
public uint usrmod0_password_hist_len;
};
public struct USER_MODALS_INFO_1
{
public uint usrmod1_role;
public string usrmod1_primary;
};
public struct USER_MODALS_INFO_2
{
public string usrmod2_domain_name;
public uint usrmod2_domain_id;
};
public struct USER_MODALS_INFO_3
{
public uint usrmod3_lockout_duration;
public uint usrmod3_lockout_observation_window;
public uint usrmod3_lockout_threshold;
};
...
uint retVal;
IntPtr myBuf;
USER_MODALS_INFO_0 myInfo0 = new USER_MODALS_INFO_0();
USER_MODALS_INFO_1 myInfo1 = new USER_MODALS_INFO_1();
USER_MODALS_INFO_2 myInfo2 = new USER_MODALS_INFO_2();
USER_MODALS_INFO_3 myInfo3 = new USER_MODALS_INFO_3();
retVal = NetUserModalsGet("\\\\" + tbHost.Text, 0, out myBuf);
if (retVal == 0)
{
myInfo0 = (USER_MODALS_INFO_0)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_0));
myResults += String.Format("usrmod0_force_logoff={0}\nusrmod0_max_passwd_age={1}\nusrmod0_min_passwd_age={2}\nusrmod0_min_passwd_len={3}\nusrmod0_password_hist_len={4}\n",
myInfo0.usrmod0_force_logoff.ToString("X8"),
myInfo0.usrmod0_max_passwd_age.ToString("X8"),
myInfo0.usrmod0_min_passwd_age.ToString("X8"),
myInfo0.usrmod0_min_passwd_len.ToString("X8"),
myInfo0.usrmod0_password_hist_len.ToString("X8")
);
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);
retVal = NetUserModalsGet("\\\\" + tbHost.Text, 1, out myBuf);
if (retVal == 0)
{
myInfo1 = (USER_MODALS_INFO_1)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_1));
myResults += String.Format("usrmod1_primary={0}\nusrmod1_role={1}\n",
myInfo1.usrmod1_primary,
myInfo1.usrmod1_role.ToString("X8")
);
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);
retVal = NetUserModalsGet("\\\\" + tbHost.Text, 2, out myBuf);
if (retVal == 0)
{
myInfo2 = (USER_MODALS_INFO_2)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_2));
myResults += String.Format("usrmod2_domain_id={0}\nusrmod2_domain_name={1}\n",
myInfo2.usrmod2_domain_id.ToString("X8"),
myInfo2.usrmod2_domain_name
);
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);
retVal = NetUserModalsGet("\\\\" + tbHost.Text, 3, out myBuf);
if (retVal == 0)
{
myInfo3 = (USER_MODALS_INFO_3)Marshal.PtrToStructure(myBuf, typeof(USER_MODALS_INFO_3));
myResults += String.Format("usrmod3_lockout_duration={0}\nusrmod3_lockout_observation_window={1}\nusrmod3_lockout_threshold={2}\n",
myInfo3.usrmod3_lockout_duration.ToString("X8"),
myInfo3.usrmod3_lockout_observation_window.ToString("X8"),
myInfo3.usrmod3_lockout_threshold.ToString("X8")
);
}
myResults += String.Format("retVal={0}\n\n", retVal);
retVal = NetApiBufferFree(myBuf);
我所得到的结果是:
What I get as a result is:
usrmod0_force_logoff=FFFFFFFF
usrmod0_max_passwd_age=00375F00
usrmod0_min_passwd_age=00000000
usrmod0_min_passwd_len=00000000
usrmod0_password_hist_len=00000000
retVal=0
usrmod1_primary=
usrmod1_role=00000003
retVal=0
usrmod2_domain_id=08C409B0
usrmod2_domain_name=M
retVal=0
usrmod3_lockout_duration=0000012C
usrmod3_lockout_observation_window=0000012C
usrmod3_lockout_threshold=00000000
retVal=0
所有的,除了 usrmod1_primary
和 usrmod2_domain_name
有道理。被测试的机器是域的成员,他的名字的确实的开始与M.我闻到了一些统一code hijinx,但我看不出有什么不对。
All of that except usrmod1_primary
and usrmod2_domain_name
makes sense. The tested machine is a member of a domain, whose name does start with an M. I smell some Unicode hijinx, but I can't see what's wrong.
推荐答案
在你的结构中的字符串被编组为ANSI默认,但净* API的工作几乎完全统一code字符串。因此,应用属性
The strings in your structs are marshaled as ANSI by default, but the Net* APIs work almost exclusively with Unicode strings. So apply the attribute
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
要USER_MODALS_INFO_1和_2和你应该是不错的。
to USER_MODALS_INFO_1 and _2 and your should be good.
一对夫妇的其他东西:
-
有没有在指定没有意义在侑的DllImport SetLastError =真属性在这种情况下,因为NetUserModalsGet不返回错误通过SetLastError信息(你得到它的返回值)。
There's no point in specifyingSetLastError=true in yor DllImportattributes in this case, becauseNetUserModalsGet doesn't return errorinfo via SetLastError (you get it inthe return value).
USER_MODALS_INFO_2.usrmod2_domain_id是一个指针,因此更好建模为一个IntPtr(用于基于x64兼容)。
USER_MODALS_INFO_2.usrmod2_domain_idis a pointer and therefore bettermodeled as an IntPtr (for x64compatibility).
这篇关于NetUserModalsGet()返回一个字符串错误地为C#.NET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!