Question

The search term RpcMgmtEpEltInqNext on both Stackoverflow and PInvoke.net yields zero results, so this should be worth asking. I've been fiddling around on MSDN and looking through Win SDK *.h files all day, and feeling a bit out of my element.

I'm basically attempting to query the MSRPC endpoint mapper with managed code. Here is what I have so far:

[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);
}

The above code isn't complete, but it illustrates my point. The code consistently returns:

RpcMgmtEpEltIngNext: 87

87 meaning Parameter is Incorrect according to here.

So I'm basically stumped at this point, and I'm sure it's because of my extremely crappy PInvoke code.

Was it helpful?

Solution

The p/invoke declaration is wrong. It needs to be:

[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
);

The first parameter must be passed by value.

You'll need to translate the RPC_IF_ID struct. It's quite a simple one.

public struct RPC_IF_ID
{
    public Guid Uuid;
    public ushort VersMajor;
    public ushort VersMinor;
}

The two string parameters you used were just wrong. They lead to the marshaller calling CoTaskMemFree on the returned value for Annotation. You don't want that. You will need to use Marshal.PtrToStringAnsi to read the value.

Don't forget to call RpcBindingFree and RpcStringFree as per the docs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top