Stackoverflow和PInvoke.net上的搜索词RpcMgmtEpEltInqNext
产生的结果为零,因此值得一提。我一直在MSDN上翻阅并整天查看Win SDK * .h文件,感觉有点偏离我的元素。
我基本上是在尝试使用托管代码查询MSRPC端点映射器。以下是我到目前为止的情况:
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
public static extern int RpcBindingFromStringBinding(string StringBinding, out IntPtr Binding);
[DllImport("Rpcrt4.dll")]
public static extern int RpcBindingFree(ref IntPtr Binding);
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
public static extern int RpcMgmtEpEltInqBegin(IntPtr EpBinding,
int InquiryType, // 0x00000000 = RPC_C_EP_ALL_ELTS
int IfId,
int VersOption,
string ObjectUuid,
out IntPtr InquiryContext);
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
public static extern int RpcMgmtEpEltInqNext(ref IntPtr InquiryContext,
out int IfId,
out IntPtr Binding,
out string ObjectUuid,
out string Annotation);
public static List<int> QueryEPM(string host)
{
List<int> ports = new List<int>();
int retCode = 0; // RPC_S_OK
IntPtr bindingHandle = IntPtr.Zero;
IntPtr inquiryContext = IntPtr.Zero;
IntPtr elementBindingHandle = IntPtr.Zero;
int elementIfId = 0;
string elementUuid = string.Empty;
string elementAnnotation = string.Empty;
try
{
retCode = RpcBindingFromStringBinding("ncacn_ip_tcp:" + host, out bindingHandle);
if (retCode != 0)
throw new Exception("RpcBindingFromStringBinding: " + retCode);
retCode = RpcMgmtEpEltInqBegin(bindingHandle, 0, 0, 0, string.Empty, out inquiryContext);
if (retCode != 0)
throw new Exception("RpcMgmtEpEltInqBegin: " + retCode);
retCode = RpcMgmtEpEltInqNext (ref inquiryContext, out elementIfId, out elementBindingHandle, out elementUuid, out elementAnnotation);
if (retCode != 0)
throw new Exception("RpcMgmtEpEltInqNext: " + retCode);
}
以上代码不完整,但它说明了我的观点。代码始终如一地返回:
RpcMgmtEpEltIngNext:87
87含义根据here参数不正确。
所以我在这一点上基本上很难过,而且我确定这是因为我非常糟糕的PInvoke代码。
答案 0 :(得分:1)
p / invoke声明是错误的。它必须是:
[DllImport("Rpcrt4.dll", CharSet = CharSet.Auto)]
public static extern int RpcMgmtEpEltInqNext(
IntPtr InquiryContext,
out RPC_IF_ID IfId,
out IntPtr Binding,
out Guid ObjectUuid,
out IntPtr Annotation
);
第一个参数必须按值传递。
您需要翻译RPC_IF_ID
结构。这很简单。
public struct RPC_IF_ID
{
public Guid Uuid;
public ushort VersMajor;
public ushort VersMinor;
}
您使用的两个字符串参数错误。它们导致编组人员CoTaskMemFree
的返回值调用Annotation
。你不希望这样。您需要使用Marshal.PtrToStringAnsi
来读取值。
不要忘记根据文档致电RpcBindingFree
和RpcStringFree
。