    ' main.vb SNF-SDK-WIN CPP OEM Demonstration Code
    ' Copyright (C) 2009 ARM Research Labs, LLC
    '
    ' This app simply exercises the API provided by snfmultidll.

    Imports System.Runtime.InteropServices
    Imports System.Text

    Module SNFMultiDLLExample

    #Region "DLL Imports"

        ' Location of SNFMulti.dll.
        Const SNFMULTI_DLL As String = "..\..\..\..\64bitDll\SNFMulti.dll" ' Set CPU type to "Any CPU"
        'Const SNFMULTI_DLL As String = "..\..\..\..\..\64bitDll\SNFMulti.dll" ' Set CPU type to "x64"
        'Const SNFMULTI_DLL As String = "..\..\..\..\..\32bitDll\SNFMulti.dll" ' Set CPU type to "x86"

        'int setThrottle(int Threads);                                                   /* Set scan thread limit. */
        'int startupSNF(char* Path);                                                     /* Start SNF with configuration. */
        'int startupSNFAuthenticated(char* Path, char* Lic, char* Auth);                 /* Start SNF with conf & auth. */
        'int shutdownSNF();                                                              /* Shutdown SNF. */
        'int testIP(unsigned long int IPToCheck);                                        /* Test the IP for a GBUdb range. */
        'double getIPReputation(unsigned long int IPToCheck);                            /* Get reputation figure for IP. */
        'int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup);          /* Scan msgBuffer, name, setup time. */
        'int scanFile(char* FilePath, int Setup);                                        /* Scan msgFile, setup time. */
        'int getScanXHeaders(int ScanHandle, char** Bfr, int* Length);                   /* Get result & XHeaders. */
        'int getScanXMLLog(int ScanHandle, char** Bfr, int* Length);                     /* Get result & XML Log. */
        'int getScanClassicLog(int ScanHandle, char** Bfr, int* Length);                 /* Get result & Classic Log. */
        'int getScanResult(int ScanHandle);                                              /* Get just the scan result. */
        'int closeScan(int ScanHandle);                                                  /* Close the scan result. */

        'Set scan thread limit
        <DllImport(SNFMULTI_DLL, EntryPoint:="setThrottle", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function setThrottle(ByVal Threads As Int32) As Int32
        End Function

        'Startup
        <DllImport(SNFMULTI_DLL, EntryPoint:="startupSNF", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function startupSNF(ByVal PathToConfigurationFile As String) As Int32
        End Function

        'Start SNF with conf & auth.
        <DllImport(SNFMULTI_DLL, EntryPoint:="startupSNFAuthenticated", CharSet:=CharSet.Ansi, _
                   CallingConvention:=CallingConvention.Winapi)> _
        Public Function startupSNFAuthenticated( _
            ByVal Path As String, _
            ByVal Lic As String, _
            ByVal Auth As String) As Int32
        End Function

        'Shutdown
        <DllImport(SNFMULTI_DLL, EntryPoint:="shutdownSNF", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function shutdownSNF() As Int32
        End Function

        'Test IP
        <DllImport(SNFMULTI_DLL, EntryPoint:="testIP", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function testIP(ByVal IPToCheck As UInt32) As Int32
        End Function

        'getIPReputation
        <DllImport(SNFMULTI_DLL, EntryPoint:="getIPReputation", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function getIPReputation(ByVal IPToCheck As UInt32) As Double
        End Function

        'ScanBuffer - returns scannerhandle
        <DllImport(SNFMULTI_DLL, EntryPoint:="scanBuffer", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function scanBuffer(ByVal MsgBfr As StringBuilder, ByVal MsgBfrLen As Int32, ByVal MsgID As String, ByVal SetupTime As Int32) As Int32
        End Function

        'ScanFile
        <DllImport(SNFMULTI_DLL, EntryPoint:="scanFile", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function scanFile(ByVal FilePath As String, ByVal Setup As Int32) As Int32
        End Function

        'GetScanXHeaders - use scannerhandle returned from previous - returns ScanResult Code
        <DllImport(SNFMULTI_DLL, EntryPoint:="getScanXHeaders", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function getScanXHeaders(ByVal ScannerHandle As Int32, ByRef HeadersPtr As IntPtr, ByRef HeadersLength As Int32) As Int32
        End Function

        'GetScanXMLLog - Get result & XML Log
        <DllImport(SNFMULTI_DLL, EntryPoint:="getScanXMLLog", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function getScanXMLLog(ByVal ScannerHandle As Int32, ByRef LogPtr As IntPtr, ByRef LogLength As Int32) As Int32
        End Function

        'GetScanClassicLog - Get result & Classic Log
        <DllImport(SNFMULTI_DLL, EntryPoint:="getScanClassicLog", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function getScanClassicLog(ByVal ScannerHandle As Int32, ByRef LogPtr As IntPtr, ByRef LogLength As Int32) As Int32
        End Function

        'GetScanResult - Get just the scan result
        <DllImport(SNFMULTI_DLL, EntryPoint:="getScanResult", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function getScanResult(ByVal ScannerHandle As Int32) As Int32
        End Function

        'Close Scan
        <DllImport(SNFMULTI_DLL, EntryPoint:="closeScan", CharSet:=CharSet.Ansi, CallingConvention:=CallingConvention.Winapi)> _
        Public Function closeScan(ByVal ScannerHandle As Int32) As Int32
        End Function

    #End Region

        Sub Main()

            ' Setup the basics we need to run this test.

            'Const LicenseID As String = "licensid"                                 ' SNF License ID can be passed
            'Const Authentication As String = "authentication"                      ' directly or read from the
                                                                                    ' configuration. OEMs go direct!
            Const ConfigurationPath As String = "..\..\..\snf_engine.xml"           ' For "Any CPU" platform.
            'Const ConfigurationPath As String = "..\..\..\..\snf_engine.xml"        ' For "x86" or "x64" platforms.

            Const IPToTest As UInt32 = &HC22384E                                   ' Same as IP 12.34.56.78

            Const SampleMessage As String = _
                "Received: from mx-out.example.com [12.34.56.78] (HELO Somebody)\r\n" + _
                "  by mx-in.example.com (nosuchserver v1.0) for nobody@example.com\r\n" + _
                "From: <somebody@example.com>\r\n" + _
                "To: <nobody@example.com>\r\n" + _
                "Subject: Nothing to see here\r\n" + _
                "\r\n" + _
                "So this is the big thing that's not here to see.\r\n" + _
                "I thought it would be more interesting than this.\r\n" + _
                "\r\n" + _
                "_M\r\n" + _
                ".\r\n"

            '' Here is a simple example. Startup, exercise the API, shut down.
            '' Note that we're doing this in a very "C" style becuase the DLL API is C

            Dim Result As Integer = 0

            Result = startupSNF(ConfigurationPath)

            'Result = startupSNFAuthenticated( _
            '    ConfigurationPath, _
            '    LicenseID, _
            '    Authentication)

            Console.WriteLine("Started with config " + ConfigurationPath + " Result: " + Result.ToString("D"))

            ' IP tests can be done asynchrounously - they do not have to be part of any particular scan.

            Result = testIP(IPToTest)
            Console.WriteLine("IP test result: " + Result.ToString("D"))

            Dim IPReputation As Double = getIPReputation(IPToTest)
            Console.WriteLine("IP Reputation: " + IPReputation.ToString())

            ' Messgae scans happen in a scan, read, close cycle as shown inside this loop.

            Const NumberOfScans As Integer = 10
            For i As Integer = 0 To NumberOfScans

                ' Show how the IP reputation changes over time.

                IPReputation = getIPReputation(IPToTest)
                Console.WriteLine("IP Reputation: " + IPReputation.ToString())

                ' Scan a message from a buffer.

                Dim SetupTime As Integer = 12
                Dim ScanHandle As Integer = 0
                Dim MsgBuffer As New StringBuilder
                MsgBuffer.Append(SampleMessage)
                ScanHandle = scanBuffer(MsgBuffer, MsgBuffer.Length(), "TestMessage", SetupTime)

                Console.WriteLine("Scan Handle: " + ScanHandle.ToString("D"))

                ' Retrieve the X-Headers for the scan.

                Dim XHeadersBuffer As IntPtr = IntPtr.Zero
                Dim XHeadersLength As Int32
                Dim XHeaders As String

                Dim ScanResult As Integer = 0
                ScanResult = getScanXHeaders(ScanHandle, XHeadersBuffer, XHeadersLength)
                XHeaders = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(XHeadersBuffer, XHeadersLength)

                ' Close the scan.

                Result = closeScan(ScanHandle)

                Console.WriteLine("Scan Close Result: " + Result.ToString("D"))

                ' X- headers were captured in a string BEFORE closing the scan so we can
                ' use them here.

                Console.WriteLine("Scan result code: " + ScanResult.ToString("D"))
                Console.WriteLine("Scan X- headers: " + XHeaders)

            Next i

            ' Now that all scanning is done we shut down.

            Result = shutdownSNF()

        End Sub

    End Module