Link to home
Avatar of tdyck12345
tdyck12345

asked on

Marshal.StringToBSTR(String str) and Windows SNMP API Calls

Please see the attached code snippet.

In the code I perform windows api calls to set up the snmp message and send it to my local computer, but for some reason I never get a response. Instead the response always times out.

I have a vb6 sample that I works, but I would prefer to do this in .NET.

Can you see what is wrong?

I'm thinking it may be a problem with the line

contextOct.octets = Marshal.StringToBSTR(context);
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        private IntPtr m_Session;
        private SNMP.API.SnmpCallback m_cb;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void ButtonSend_Click(object sender, EventArgs e)
        {
            if (m_Session != IntPtr.Zero)
            {
                SNMP.API.Status status = SNMP.API.SnmpSetTranslateMode(SNMP.API.TranslateMode.TRANSLATED);
                String srcAddr = "127.0.0.1";
                IntPtr srcEntity = SNMP.API.SnmpStrToEntity(m_Session, srcAddr);
                status = SNMP.API.SnmpGetLastError(m_Session);
 
                if (srcEntity == IntPtr.Zero)
                {
                    status = SNMP.API.SnmpSetTranslateMode(SNMP.API.TranslateMode.UNTRANSLATEDV1);
                    srcEntity = SNMP.API.SnmpStrToEntity(m_Session, srcAddr);
                    status = SNMP.API.SnmpGetLastError(m_Session);
                }
                String destAddr = "127.0.0.1";
                status = SNMP.API.SnmpSetTranslateMode(SNMP.API.TranslateMode.TRANSLATED);
                IntPtr destEntity = SNMP.API.SnmpStrToEntity(m_Session, destAddr);
                status = SNMP.API.SnmpGetLastError(m_Session);
 
                if (destEntity == IntPtr.Zero)
                {
                    status = SNMP.API.SnmpSetTranslateMode(SNMP.API.TranslateMode.UNTRANSLATEDV1);
                    destEntity = SNMP.API.SnmpStrToEntity(m_Session, destAddr);
                    status = SNMP.API.SnmpGetLastError(m_Session);
                }
 
                if (srcEntity == IntPtr.Zero)
                {
                    MessageBox.Show("Unknown Source Entity", "Error");
                }
                else if (destEntity == IntPtr.Zero) 
                {
                    MessageBox.Show("Unknown Destination Entity", "Error");
                }
                else 
                {
                    //status = SNMPAPI.SnmpSetPort(destEntity, 161);
                    SNMP.API.smiOID getOid = new SNMP.API.smiOID(); 
                    IntPtr vbl ;
                    IntPtr pdu ;
                    SNMP.API.smiValue  NullValue = new SNMP.API.smiValue();
                    SNMP.API.smiOctetString contextOct;
 
                    NullValue.type = SNMP.API.Syntax.NULL;
 
                    String context = "public";
                    contextOct.size = (uint)context.Length;
                    contextOct.octets = Marshal.StringToBSTR(context);
 
                    status = SNMP.API.SnmpSetTranslateMode(SNMP.API.TranslateMode.TRANSLATED);
                    IntPtr srcContext = SNMP.API.SnmpStrToContext(m_Session, ref contextOct);
                    status = SNMP.API.SnmpGetLastError(m_Session);
                    if (srcContext == IntPtr.Zero)
                    {
                        status = SNMP.API.SnmpSetTranslateMode(SNMP.API.TranslateMode.UNTRANSLATEDV1);
                        srcContext = SNMP.API.SnmpStrToContext(m_Session, ref contextOct);
                        status = SNMP.API.SnmpGetLastError(m_Session);
                    }
 
                    if (srcContext == IntPtr.Zero)
                    {   
                        MessageBox.Show("Invalid context");
                        return;
                    }
 
                    status = SNMP.API.SnmpStrToOid("1.3.6.1.2.1.1.1.0", ref getOid);
                    vbl = SNMP.API.SnmpCreateVbl(m_Session,ref getOid,  ref NullValue);
                    pdu = SNMP.API.SnmpCreatePdu(m_Session, SNMP.API.PDUType.GET, 1234, 0, 0, vbl);
                    status = SNMP.API.SnmpSendMsg(m_Session, srcEntity, destEntity, srcContext, pdu);
                    // gh.Free();
 
                    if (status == SNMP.API.Status.FAILURE) 
                    {
                         status = SNMP.API.SnmpGetLastError(m_Session);
                    }
                    else
                    {   
                        //Message Sent. . . ;
                    }
 
                    status = SNMP.API.SnmpFreeDescriptor(SNMP.API.Syntax.OID, ref getOid);
                    status = SNMP.API.SnmpFreeEntity(srcEntity);
                    status = SNMP.API.SnmpFreeEntity(destEntity);
                    status = SNMP.API.SnmpFreeContext(srcContext);
                    status = SNMP.API.SnmpFreePdu(pdu);
                }
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            m_cb = SNMPAPICallBackHandler;
            int major;int minor; int level; int tmode;int rmode ;
            SNMP.API.Status status = SNMP.API.SnmpStartup(out major, out minor, out level, out tmode, out rmode);
            status = SNMP.API.SnmpSetRetransmitMode(SNMP.API.TransmitMode.ON);
            m_Session = SNMP.API.SnmpCreateSession(IntPtr.Zero, 0, m_cb, IntPtr.Zero);
            status = SNMP.API.SnmpGetLastError(m_Session);
            this.ButtonSend.Enabled = (status == SNMP.API.Status.SUCCESS);
        }
 
        private SNMP.API.Status SNMPAPICallBackHandler(IntPtr session, IntPtr hwnd, int msg, uint wparam, uint lparam, IntPtr data)
        {
            if (wparam == 108)
            {
                // we timed out
            }
            else
            {
                // receive the message
            }
            return SNMP.API.Status.SUCCESS;
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
           SNMP.API.Status status  = SNMP.API.SnmpClose(m_Session);
           status = SNMP.API.SnmpCleanup();
        }
    }
}
 
 
 
 
using System;
using System.Runtime.InteropServices;
 
namespace SNMP
{
    /// <summary>
    /// Snmp API Functions
    /// </summary>
    public class API
    {
        [StructLayout(LayoutKind.Sequential)]
        public struct VendorInfo
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string vendorName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string vendorContact;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string vendorVersionId;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string vendorVersionDate;
 
            public int vendorEnterprise;
        }
 
        [StructLayout(LayoutKind.Sequential)]
        public struct smiOctetString
        {
            public uint size;
            public IntPtr octets;
        }
 
        [StructLayout(LayoutKind.Sequential)]
        public struct smiOID
        {
            public uint size;
            public IntPtr dwords;
        }
 
        [StructLayout(LayoutKind.Explicit)]
        public struct smiValueUnion
        {
            [FieldOffset(0)]
            public int sNumber;
            [FieldOffset(0)]
            public UInt32 uNumber;
            [FieldOffset(0)]
            public Int64 hNumber;
            [FieldOffset(0)]
            public smiOctetString str;
            [FieldOffset(0)]
            public smiOID oid;
            [FieldOffset(0)]
            public byte empty;
        }
 
        [StructLayout(LayoutKind.Explicit)]
        public struct smiValue
        {
            [FieldOffset(0)]
            public Syntax type;
            [FieldOffset(4)]
            public smiValueUnion val;
        }
 
        /// <summary>
        /// Snmp API enumerations
        /// </summary>
        public enum TransmitMode : int
        {
            OFF = 0,
            ON = 1
        }
 
        public enum TranslateMode : int
        {
            TRANSLATED = 0,
            UNTRANSLATEDV1 = 1,
            UNTRANSLATEDV2 = 2
        }
 
        public enum Status : uint
        {
            FAILURE = 0,		/* Generic error code */
            SUCCESS = 1,		/* Generic success code */
 
            /* WinSNMP API Error Codes (for SnmpGetLastError) */
            /* (NOT SNMP Response-PDU error_status codes) */
            ALLOC_ERROR = 2,		/* Error allocating memory */
            CONTEXT_INVALID = 3,		/* Invalid context parameter */
            CONTEXT_UNKNOWN = 4,		/* Unknown context parameter */
            ENTITY_INVALID = 5,		/* Invalid entity parameter */
            ENTITY_UNKNOWN = 6,		/* Unknown entity parameter */
            INDEX_INVALID = 7,		/* Invalid VBL index parameter */
            NOOP = 8,		/* No operation performed */
            OID_INVALID = 9,		/* Invalid OID parameter */
            OPERATION_INVALID = 10,	/* Invalid/unsupported operation */
            OUTPUT_TRUNCATED = 11,	/* Insufficient output buf len */
            PDU_INVALID = 12,	/* Invalid PDU parameter */
            SESSION_INVALID = 13,	/* Invalid session parameter */
            SYNTAX_INVALID = 14,	/* Invalid syntax in smiVALUE */
            VBL_INVALID = 15,	/* Invalid VBL parameter */
            MODE_INVALID = 16,	/* Invalid mode parameter */
            SIZE_INVALID = 17,	/* Invalid size/length parameter */
            NOT_INITIALIZED = 18,	/* SnmpStartup failed/not called */
            MESSAGE_INVALID = 19,	/* Invalid SNMP message format */
            HWND_INVALID = 20,	/* Invalid Window handle */
            OTHER_ERROR = 99,	/* For internal/undefined errors */
 
            /* Generic Transport Layer (TL) Errors */
            TL_NOT_INITIALIZED = 100,	/* TL not initialized */
            TL_NOT_SUPPORTED = 101,	/* TL does not support protocol */
            TL_NOT_AVAILABLE = 102,	/* Network subsystem has failed */
            TL_RESOURCE_ERROR = 103,	/* TL resource error */
            TL_UNDELIVERABLE = 104,	/* Destination unreachable */
            TL_SRC_INVALID = 105,	/* Source endpoint invalid */
            TL_INVALID_PARAM = 106,	/* Input parameter invalid */
            TL_IN_USE = 107,	/* Source endpoint in use */
            TL_TIMEOUT = 108,	/* No response before timeout */
            TL_PDU_TOO_BIG = 109,	/* PDU too big for send/receive */
            TL_OTHER = 199	/* Undefined TL error */
        }
 
        public enum PDUType : int
        {
            GET = 0xa0,
            GETNEXT = 0xa1,
            RESPONSE = 0xa2,
            SET = 0xa3,
            V1TRAP = 0xa4,
            GETBULK = 0xa5,
            INFORM = 0xa6,
            TRAP = 0xa7
        }
 
        public enum Syntax : int
        {
            // SNMP ObjectSyntax Values
            SEQUENCE = 0x30,
 
            // These values are used in the "syntax" member of the smiVALUE structure which follows
            INT = 0x02,
            INT32 = INT,
            BITS = 0x03,
            OCTETS = 0x04,
            NULL = 0x05,
            OID = 0x06,
 
            IPADDR = 0x40,
            CNTR32 = 0x41,
            GAUGE32 = 0x42,
            TIMETICKS = 0x43,
            OPAQUE = 0x44,
            NSAPADDR = 0x45,
            CNTR64 = 0x46,
            UINT32 = 0x47,
 
            // Exception conditions in response PDUs for SNMPv2
            NOSUCHOBJECT = 0x80,
            NOSUCHINSTANCE = 0x81,
            ENDOFMIBVIEW = 0x82
        }
 
        public enum ErrorStatus : int
        {
            NOERROR = 0,
            TOOBIG = 1,
            NOSUCHNAME = 2,
            BADVALUE = 3,
            READONLY = 4,
            GENERR = 5,
            NOACCESS = 6,
            WRONGTYPE = 7,
            WRONGLENGTH = 8,
            WRONGENCODING = 9,
            WRONGVALUE = 10,
            NOCREATION = 11,
            INCONSISTENTVALUE = 12,
            RESOURCEUNAVAILABLE = 13,
            COMMITFAILED = 14,
            UNDOFAILED = 15,
            AUTHORIZATIONERROR = 16,
            NOTWRITABLE = 17,
            INCONSISTENTNAME = 18
        }
 
        // Callback
        public delegate Status SnmpCallback(IntPtr session, IntPtr hwnd, int msg, uint wparam, uint lparam, IntPtr data);
 
        // Communication functions
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpStartup(out int major, out int minor, out int level, out int translate, out int retransmit);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpCleanup();
        [DllImport("wsnmp32.dll")]
        public static extern IntPtr SnmpCreateSession(IntPtr hwnd, int msg, SnmpCallback callback, IntPtr data);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpClose(IntPtr session);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpRegister(IntPtr session, IntPtr src, IntPtr dest, IntPtr context, IntPtr notification, int state);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpListen(IntPtr entity, IntPtr status);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSendMsg(IntPtr session, IntPtr src, IntPtr dest, IntPtr context, IntPtr pdu);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpRecvMsg(IntPtr session, out IntPtr src, out IntPtr dest, out IntPtr context, out IntPtr pdu);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpCancelMsg(IntPtr session, IntPtr reqid);
 
        // Entity and Context functions
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpContextToStr(IntPtr context, ref smiOctetString octets);
        [DllImport("wsnmp32.dll")]
        public static extern IntPtr SnmpStrToContext(IntPtr session, ref smiOctetString octets);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpFreeEntity(IntPtr entity);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpEntityToStr(ref smiOID entity, int size, IntPtr str);
        [DllImport("wsnmp32.dll")]
        public static extern IntPtr SnmpStrToEntity(IntPtr session, [MarshalAs(UnmanagedType.LPStr)] string str);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpFreeContext(IntPtr context);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetPort(IntPtr entity, int port);
 
        // Database functions
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetRetransmitMode(out uint mode);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetRetry(IntPtr entity, out uint policy, out uint actual);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetTimeout(IntPtr entity, out int policy, out int actual);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetTranslateMode(out uint mode);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetVendorInfo(ref VendorInfo Info);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetRetransmitMode(TransmitMode mode);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetRetry(IntPtr entity, int policy);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetTimeout(IntPtr entity, int policy);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetTranslateMode(TranslateMode mode);
 
        // PDU functions
        [DllImport("wsnmp32.dll")]
        public static extern IntPtr SnmpCreatePdu(IntPtr session, PDUType type, int reqid, int status, int index, IntPtr vblist);
        [DllImport("wsnmp32.dll")]
        public static extern IntPtr SnmpDuplicatePdu(IntPtr session, IntPtr pdu);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpFreePdu(IntPtr pdu);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetPduData(IntPtr pdu, out PDUType type, out int reqid, out int status, out int index, out IntPtr vblist);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetPduData(IntPtr pdu, ref PDUType type, ref int reqid, ref int nonrepeaters, ref int maxreps, ref IntPtr vblist);
 
        // Utility functions
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpDecodeMsg(IntPtr session, out IntPtr src, out IntPtr dest, out IntPtr context, out IntPtr pdu, ref smiOctetString octets);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpEncodeMsg(IntPtr session, IntPtr src, IntPtr dest, IntPtr context, IntPtr pdu, ref smiOctetString octets);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpFreeDescriptor(Syntax syntax, ref smiOID desc);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpFreeDescriptor(Syntax syntax, ref smiOctetString desc);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetLastError(IntPtr session);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpOidCompare(IntPtr oid1, IntPtr oid2, int max, ref int result);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpOidCopy(IntPtr src, IntPtr dest);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpOidToStr(ref smiOID oid, int size, IntPtr str);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpStrToOid(string str, ref smiOID oid);
 
        // Variable Binding functions
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpCountVbl(IntPtr vbl);
        [DllImport("wsnmp32.dll")]
        public static extern IntPtr SnmpCreateVbl(IntPtr session, ref smiOID name, ref smiValue value);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpDeleteVb(IntPtr vbl, int index);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpDuplicateVbl(IntPtr session, IntPtr vbl);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpFreeVbl(IntPtr vbl);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpGetVb(IntPtr vbl, int index, ref smiOID name, ref smiValue value);
        [DllImport("wsnmp32.dll")]
        public static extern Status SnmpSetVb(IntPtr vbl, int index, ref smiOID name, ref smiValue value);
    }
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of tdyck12345
tdyck12345

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial