locked
ndisuio errors RRS feed

  • Question

  • Hello,

    I am trying to utilize NDISIO to write packets and receive packets from the ethernet port in WEC7 using the following code to setup up NDISUIO.

    #define NDISUIO
    
    #ifdef WIN32
    
    #include <stdio.h>
    #include <string.h>
    
    #include "nicdrv.h"
    #include "osal_win32.h"
    
    #ifdef NDISUIO
    #include <ndis.h>
    #include <Nuiouser.h>
    #include <Ntddndis.h>
    #include <service.h> // For IOCTL_SERVICE_STOP
    #include <memory.h>
    
    HANDLE hAdapter = NULL;
    #endif
    
    const uint16 priMAC[3] = { 0x0101, 0x0101, 0x0101 };
    const uint16 secMAC[3] = { 0x0404, 0x0404, 0x0404 };
    
    #define RX_PRIM priMAC[1]
    #define RX_SEC secMAC[1]
    
    
    #define NDISUIO_DEVICE_NAME TEXT("UIO1:")
    
    static char errbuf[256];
    
    void eth_adapter_config()
    {
    	char buff[1024];
    	DWORD dwReturnedBytes;
    	PNDISUIO_QUERY_BINDING pQueryBinding;
    	TCHAR pDevName[1024];
    
    	USHORT uEther = 0x88A4;	
    
    	int i;
    
    	NDISUIO_SET_OID set_oid;
    	ULONG ulData;
    	NDISUIO_QUERY_OID query_oid;
    
    	/*CreateFile to obtain a handle to the device*/
    	hAdapter = CreateFile(NDISUIO_DEVICE_NAME, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    
    	if((hAdapter == INVALID_HANDLE_VALUE) || (hAdapter == NULL))
    	{
    		printf("Error in CreateFile : %d\n",GetLastError());
    		printf("handle is %x", hAdapter);
    		return;
    	}
    	else
    	{
    		printf("Successfuly opened file...\n" );
    	}
    
    	/*Query binding to retrieve adapter name and description*/
    	pQueryBinding = (PNDISUIO_QUERY_BINDING) buff;
    
    	if (!DeviceIoControl(hAdapter, IOCTL_NDISUIO_QUERY_BINDING, pQueryBinding, sizeof(NDISUIO_QUERY_BINDING), NULL, 1024, &dwReturnedBytes, NULL))
    	{
    		printf("Error in Query Binding : %d\n", GetLastError());
    		CloseHandle(hAdapter);
    		return;
    	}
    	else
    	{
    		printf("Successfuly queried binding...\n" );
    
    		memset(pDevName, 0, 1024);
    		memcpy(pDevName,&buff[pQueryBinding->DeviceNameOffset],pQueryBinding->DeviceNameLength);
    		printf("Device name: ");
    		for(i=pQueryBinding->DeviceNameOffset;i<=pQueryBinding->DeviceNameLength;i++)
    		{
    		  printf("%c\n",buff[i]);
    		}
    	}
    
    	/*Create a binding with the network device using the handle obtained from CreateFile*/
    	if(!DeviceIoControl(hAdapter, IOCTL_NDISUIO_OPEN_DEVICE, pDevName, wcslen(pDevName) * sizeof(TCHAR), NULL, 0, &dwReturnedBytes, NULL))
    	{
    		printf("Open device Error : %d\n",GetLastError());
    		printf("handle is %x", hAdapter);
    		CloseHandle(hAdapter);
    		return;
    	}
    	else
    	{
    		printf("Successfuly opened device...\n");
    	}
    
    	/*Bind the adapter*/
    	if(!DeviceIoControl(hAdapter, IOCTL_NDIS_BIND_ADAPTER, pDevName, wcslen(pDevName+1)*sizeof(TCHAR), NULL, 0, &dwReturnedBytes, NULL))
    	{
    		printf("Bind Adapter Error : %d\n", GetLastError());
    		CloseHandle(hAdapter);
    		return;
    	}
    	else
    	{
    		printf("Successfuly binded the adapter...\n");
    	}
    
    	/*Set the type of Ethernet packet for NDISUIO to filter*/
    	if(!DeviceIoControl(hAdapter, IOCTL_NDISUIO_SET_ETHER_TYPE, &uEther, sizeof(uEther), NULL, 0, &dwReturnedBytes, NULL))
    	{
    		printf("Error setting the ethernet type %d\n",GetLastError());
    		CloseHandle(hAdapter);
    		return;
    	}
    	else
    	{
    		printf("Successfully set the Ethernet type...");
    	}
    
    	/*Set the OID of the miniport*/
    	ulData = NDIS_PACKET_TYPE_ALL_LOCAL | NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_PROMISCUOUS;
    	set_oid.Oid = OID_GEN_CURRENT_PACKET_FILTER;
    
    	CopyMemory(&set_oid.Data[0],&ulData,sizeof(ulData));
    	set_oid.ptcDeviceName = pDevName;
    
    	if(!DeviceIoControl(hAdapter, IOCTL_NDISUIO_SET_OID_VALUE, &set_oid, sizeof(set_oid), NULL,0, &dwReturnedBytes, NULL))
    	{
    		printf("Error setting the OID: %d\n", GetLastError());
    		CloseHandle(hAdapter);
    		return ;
    	}
    	else
    	{
    		printf("Successfuly set the OID of the miniport...\n");
    	}
    
    	printf("Ethernet adapter configuration complete!\n");
    }

    The issue happens with the first call to deviceiocontrol, it is failing and I'm not sure why. Am I calling the functions with regard to NDISUIO correctly? I'm not sure what I'm doing wrong at this point, any advice is helpful. If anyone has any sample code utilizing NDISUIO on WEC7 that I can try on my target that would be great as well, just to verify that the drivers are setup correctly in the image (which I believe they are).

    Thank you


    • Edited by elk84 Monday, June 3, 2013 3:03 PM
    Monday, June 3, 2013 3:03 PM

All replies

  • Define the failure mode. Did you get the last error (GetLastError)? It looks to me like you should set BindingIndex to 0, if that's your goal. Also, according to the docs:

    lpOutBuffer
    [out] Set to NULL or lpInBuffer.
    Note   If lpOutBuffer is not specified, the application returns NDIS_STATUS_INVALID_DATA.

    If you're getting back NDIS_STATUS_INVALID_DATA from GetLastError() that seems to be the problem.

    Paul T.

    Thursday, June 6, 2013 12:03 AM
  • Paul is right. In addition you may take a look at %_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\NETSAMP\NDISPWR\ndispwr.c and %_WINCEROOT%\PUBLIC\COMMON\OAK\DRIVERS\NETSAMP\ETHMAN\ethman.c to see how the various IOCTL_NDISUIO_XXX are correctly used


    Luca Calligaris lucaDOTcalligarisATeurotechDOTcom www.eurotech.com Check my blog: http://lcalligaris.wordpress.com

    Thursday, June 6, 2013 2:15 PM
  • Hello All,

    Setting the BindingIndex to 0 solved the problem, I see the ethernet port RTL81391, but when running the following portion of code:

    	/*Bind the adapter*/
    	if(!DeviceIoControl(hAdapter, IOCTL_NDIS_BIND_ADAPTER, pDevName, wcslen(pDevName+1)*sizeof(TCHAR), NULL, 0, &dwReturnedBytes, NULL))
    	{
    		printf("Bind Adapter Error : %d\n", GetLastError());
    		CloseHandle(hAdapter);
    		return;
    	}

    It returned an error of 50. I just removed the code, but I'm not sure if the adapter is actually bound without using IOCTL_NDIS_BIND_ADAPTER within DeviceIoControl as I posted earlier. I was able to utilize WriteFile afterward, but calls to ReadFile just became deadlocked (I think). I attempted to utilize a call to SetCommTimeouts so that it would force a return from the ReadFile call after a certain amount of time, but I suppose if it is already deadlocked then the timeout is ineffective. Do you think not utilizing the bind adapter function call (which I reiterated in this post) would lead to this sort of behavior?

    Thanks!

    Friday, June 7, 2013 4:25 PM