Hello, I am working with developing an application that uses the Netmon 3.2 API. Currently they have a PInvoke wrapper to access unmanaged C++ DLL functions.
Basically what I am attempting to do is rewrite an example application (written in C++ and provided in their documentation) in C#. Everything compiles fine and executes, but I have no .cap file at the end of the run. Some things that may be wrong: the ADAPTER_INDEX is not correct OR the IntPtr associated with the capture file is not getting passed correctly. Interesting note: when I set a breakpoint in the callback function the program never enters this block (which it should leading me to suspect the ADAPTER_INDEX)
Here is my code:
And here is the code provided in the Network Monitor API documentation, doing the same thing in C++. Network Monitor 3.2 is a free download from Microsoft Downloads.
Basically what I am attempting to do is rewrite an example application (written in C++ and provided in their documentation) in C#. Everything compiles fine and executes, but I have no .cap file at the end of the run. Some things that may be wrong: the ADAPTER_INDEX is not correct OR the IntPtr associated with the capture file is not getting passed correctly. Interesting note: when I set a breakpoint in the callback function the program never enters this block (which it should leading me to suspect the ADAPTER_INDEX)
Here is my code:
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Protocols.TestTools.Netmon.API;
using System.Windows.Forms;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
namespace Network_Monitor_Demo
{
public struct Constants
{
public static UInt32 ADAPTER_INDEX = 0;
}
public class Netmon
{
public Netmon()
{
uint ret;
//Open a capture file for saving frames.
string path = @"C:\\Capture\\10sec.cap";
IntPtr myCapFile;
uint CapSize;
ret = NetmonAPI.NmCreateCaptureFile(path, 20000000, NmCaptureFileFlag.WrapAround, out myCapFile, out CapSize);
if (ret != 0)
{
MessageBox.Show("Error Opening Capture File" + "10sec.cap");
return;
}
//Open the capture engine
IntPtr myCaptureEngine;
ret = NetmonAPI.NmOpenCaptureEngine(out myCaptureEngine);
if (ret != 0)
{
MessageBox.Show("Error opening capture engine.");
NetmonAPI.NmCloseHandle(myCapFile);
return;
}
ret = NetmonAPI.NmConfigAdapter(myCaptureEngine, Constants.ADAPTER_INDEX, new CaptureCallbackDelegate(FrameIndicationCallback), myCapFile, NmCaptureCallbackExitMode.ReturnRemainFrames);
if (ret != 0)
{
MessageBox.Show("Error configuration adapter.");
NetmonAPI.NmCloseHandle(myCaptureEngine);
NetmonAPI.NmCloseHandle(myCapFile);
return;
}
MessageBox.Show("Capturing for 10 seconds.");
NetmonAPI.NmStartCapture(myCaptureEngine, Constants.ADAPTER_INDEX, NmCaptureMode.Promiscuous);
Thread.Sleep(10000);
MessageBox.Show("Stopping Capture.");
NetmonAPI.NmStopCapture(myCaptureEngine, Constants.ADAPTER_INDEX);
NetmonAPI.NmCloseHandle(myCaptureEngine);
NetmonAPI.NmCloseHandle(myCapFile);
return;
}
public void FrameIndicationCallback(IntPtr hCapEng, UInt32 ulAdatIdx, IntPtr pContext, IntPtr hRawFrame)
{
IntPtr capFile = pContext;
NetmonAPI.NmAddFrame(capFile, hRawFrame);
}
}
}
And here is the code provided in the Network Monitor API documentation, doing the same thing in C++. Network Monitor 3.2 is a free download from Microsoft Downloads.
Code:
#include "windows.h"
#include "stdio.h"
#include "stdlib.h"
#include "objbase.h"
#include "ntddndis.h"
#include "NMApi.h"
#define ADAPTER_INDEX 0
void __stdcall
MyFrameIndication(HANDLE hCapEng, ULONG ulAdaptIdx, PVOID pContext, HANDLE hRawFrame)
{
HANDLE capFile = (HANDLE)pContext;
NmAddFrame(capFile, hRawFrame);
}
int __cdecl wmain(int argc, WCHAR* argv[])
{
ULONG ret;
// Open a capture file for saving frames.
HANDLE myCapFile;
ULONG CapSize;
ret = NmCreateCaptureFile(L"20sec.cap", 20000000, NmCaptureFileWrapAround, &myCapFile, &CapSize);
if(ret != ERROR_SUCCESS)
{
wprintf(L"Error opening capture file, 0x%X\n", ret);
return ret;
}
// Open the capture engine.
HANDLE myCaptureEngine;
ret = NmOpenCaptureEngine(&myCaptureEngine);
if(ret != ERROR_SUCCESS)
{
wprintf(L"Error opening capture engine, 0x%X\n", ret);
NmCloseHandle(myCapFile);
return ret;
}
ret = NmConfigAdapter(myCaptureEngine, ADAPTER_INDEX, MyFrameIndication, myCapFile);
if(ret != ERROR_SUCCESS)
{
wprintf(L"Error configuration adapter, 0x%X\n", ret);
NmCloseHandle(myCaptureEngine);
NmCloseHandle(myCapFile);
return ret;
}
wprintf(L"Capturing for 20 seconds\n");
NmStartCapture(myCaptureEngine, ADAPTER_INDEX, NmLocalOnly);
Sleep(20000);
wprintf(L"Stopping capture\n");
NmStopCapture(myCaptureEngine, ADAPTER_INDEX);
NmCloseHandle(myCaptureEngine);
NmCloseHandle(myCapFile);
return 0;
}
Comment