none
NDIS 6.0, what's next? RRS feed

  • Question

  • Hi,

    I'm back on this project I left behind a few weeks ago (first thread, second thread).

    Now I have a loading driver, the platform is running just fine.

    ipconfig returns the following:

    Windows IP configuration
    
    IP connection:
    
             IPv4 Address ...... : 0.0.0.0
             Subnet Mask ....... : 0.0.0.0
             Default Gateway ... : 0.0.0.0
             Adapter Name ...... : DAVEDRIVER1
             Description ....... : DAVEDRIVER1
             Adapter Index ..... : 4
             Physical Address... : 20-44-41-56-44-ff
             DHCP Enabled....... : NO
             Primary WinsServer  :
             Secondary WinsServer:

    The registry settings is:

    IF BSP_DRIVER_DAVEDRIVER
    [HKEY_LOCAL_MACHINE\Drivers\DAVEDRIVER]
       "Dll"="ndis.dll"
       "Prefix"="NDS"
       "Miniport"="DAVEDRIVER"
    
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER]
       "DisplayName"="Dave Driver for Serial Redundancy"
       "Group"="NDIS"
       "ImagePath"="davedriver.dll"
    
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER\Linkage]
       "Route"=multi_sz:"DAVEDRIVER1"
       
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER1\Parms]
       "BusNumber"=dword:0
       "BusType"=dword:0
       "RebindOnResume"=dword:0
       "*IfType"=dword:1               ; for IF_TYPE_OTHER
       "*MediaType"=dword:0             ; for NdisMedium802_3 0
       "*PhysicalMediaType"=dword:0    ; for NdisPhysicalMediumOther
       ;;"*NdisDeviceType"=dword:1        ; for NDIS_DEVICE_TYPE_ENDPOINT 0x00000001
       "DisablePowerManagement"=dword:1
    
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER1\Parms\TcpIp]
       "EnableDHCP"=dword:0
       "IpAddress"=multi_sz:"100.0.0.1"
       "Subnetmask"=multi_sz:"255.255.255.0"
    
    ENDIF BSP_DRIVER_DAVEDRIVER

    I was wondering why ipconfig is not showing the IP address? Before going further in making the serial side to work, I want to make sure the ndis part is OK. 

    • Why the IP address is not showing?
    • What is the next NDIS step before writing the serial hardware part of the driver?
    • Would I need to specialize the driver into a WDM driver? Intermediate driver? Or am I ok with a standard NDIS driver?

    Thanks

    David

    Wednesday, December 11, 2013 7:14 PM

Answers

  • Found it !

    The SendNetBufferListsHandler handler was empty... I added the following content and it now works:

    void MpSendNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferList, NDIS_PORT_NUMBER PortNumber, ULONG SendFlags)
    {
        PDAVEDRIVER_ADAPTER pAdapter = (PDAVEDRIVER_ADAPTER)MiniportAdapterContext;
        NdisMSendNetBufferListsComplete(pAdapter->hMiniportAdapter, NetBufferList, 0);
    }

    It's not how it will work in the final version, but at least I do have an IPV4 address.

    Let's attack the receive part.

    David

    • Marked as answer by David Mercier Tuesday, January 14, 2014 9:45 PM
    Tuesday, January 14, 2014 9:45 PM

All replies

  • Hi,

    Is the adapter state modified to connected?. Is link state modified to connected somewhere?. Only then would IP address be assigned.

    More on this here

    http://msdn.microsoft.com/en-us/library/windows/hardware/ff567391(v=vs.85).aspx

    Regards,

    balaji.

    Wednesday, December 11, 2013 7:28 PM
  • Thanks for your help, it did help me to advance a bit. I now have an IPV6 address with ipconfig.
    IP connection:
    
             IPv4 Address ...... : 0.0.0.0
             Subnet Mask ....... : 0.0.0.0
             IPv6 Address ...... : fe80::cc25:7daf:b500:905b%4
             Default Gateway ... : 0.0.0.0
             Adapter Name ...... : DAVEDRIVER1
             Description ....... : DAVEDRIVER1
             Adapter Index ..... : 4
             Physical Address... : 20-44-41-56-44-ff
             DHCP Enabled....... : NO
             Primary WinsServer  :
             Secondary WinsServer:
    But IPV4 is still missing.

    I get the following traces
    +DAVED: MpOidRequest with OID 0x00000001.
    +MpSetInformation
    OID_GEN_NETWORK_LAYER_ADDRESSES
        [1]: 100.0.0.1
    -MpSetInformation-DAVED: MpOidRequest.
    Which indicates me that NDIS finds my values in the registry.

    But I also get the following a few times in my traces:
    IpHlpAPI:: CE_DnsQueryConfig()failed to open [Comm\Tcpip\Parms]
    +DAVED: MpOidRequest with OID 0x00000000.
    +DAVED:MpQueryInformation: 0xFC010209 (OID_IP4_OFFLOAD_STATS)
    -DAVED:MpQueryInformation
    -DAVED: MpOidRequest.
    Why IpHlpApi is unhappy? Do I absolutely need to specify a DNS server?
    Would it help to get my ipv4 address to become available for the adapter?

    Also, I get the following query: OID_WAN_IPV6CP_INTERFACE_ID (0x04010220).
    Why and what should I respond? it is not clear to me...

    Thanks again

    David
    Thursday, December 12, 2013 9:35 PM
  • Hi,

    You can always provide maximum info , which could help. What i am trying to figure out is 

    why the OID named: OID_WAN_IPv6CP_INTERFACE_ID is being pushed. This seems to suggest that it either is assuming a WAN miniport driver or somewhere physical medium used is defined as WAN. For example OID_GEN_PHYSICAL_MEDIUM reports WAN media(NdisPhysicalMediumWiredWAN)?.

    Again why it should configure IPv6 address and not IPv4 i am not sure.

    Regards,

    Balaji.

    Friday, December 13, 2013 7:05 AM
  • Thanks for your help. I verified and there is nothing related to WAN... Maybe the code included can help you to help me ?!?.

    Here is the complete code. There is a lot of "try" and "quick test" in it... :)

    The macro definitions: $(CDEFINES) -DDaveDriver_EXPORTS -DNDIS_MINIPORT_DRIVER -DNDIS60_MINIPORT -DNDIS60

    The reg file:

    IF BSP_DRIVER_DAVEDRIVER
    [HKEY_LOCAL_MACHINE\Drivers\DAVEDRIVER]
       "Dll"="ndis.dll"
       "Prefix"="NDS"
       "Miniport"="DAVEDRIVER"
    
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER]
       "DisplayName"="Dave Driver for Serial Redundancy"
       "Group"="NDIS"
       "ImagePath"="davedriver.dll"
    
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER\Linkage]
       "Route"=multi_sz:"DAVEDRIVER1"
       
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER1\Parms]
       "BusNumber"=dword:0
       "BusType"=dword:0
       "RebindOnResume"=dword:0
       "*IfType"=dword:1               ; for IF_TYPE_OTHER
       "*MediaType"=dword:0             ; for NdisMedium802_3 0
       "*PhysicalMediaType"=dword:14    ; for NdisPhysicalMediumOther 20
       ;;"*NdisDeviceType"=dword:1        ; for NDIS_DEVICE_TYPE_ENDPOINT 0x00000001
       "DisablePowerManagement"=dword:1
    
    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER1\Parms\TcpIp]
       "EnableDHCP"=dword:0
       "IpAddress"=multi_sz:"100.0.0.1"
       "Subnetmask"=multi_sz:"255.255.255.0"
    
    ENDIF BSP_DRIVER_DAVEDRIVER

    The DaveDriver.h file

    #include <ndis.h>
    
    // ----------------------------------------------------------------
    //
    // Debug Defines
    //
    // ----------------------------------------------------------------
    #ifdef DEBUG
    #define ZONE_INIT      DEBUGZONE(0)        // 0x0001
    //#define ZONE_???     DEBUGZONE(1)        // 0x0002
    //#define ZONE_???     DEBUGZONE(2)        // 0x0004
    //#define ZONE_???     DEBUGZONE(3)        // 0x0008
    //#define ZONE_???     DEBUGZONE(4)        // 0x0010
    #define ZONE_SEND      DEBUGZONE(5)        // 0x0020
    //#define ZONE_???     DEBUGZONE(6)        // 0x0040
    #define ZONE_NDIS      DEBUGZONE(7)        // 0x0080
    #define ZONE_TAPI      DEBUGZONE(8)        // 0x0100
    #define ZONE_RECV      DEBUGZONE(9)        // 0x0200
    #define ZONE_INTERFACE DEBUGZONE(10)        // 0x0400
    #define ZONE_MISC      DEBUGZONE(11)        // 0x0800
    #define ZONE_ALLOC     DEBUGZONE(12)        // 0x1000
    #define ZONE_FUNCTION  DEBUGZONE(13)        // 0x2000
    #define ZONE_WARN      DEBUGZONE(14)        // 0x4000
    #define ZONE_ERROR     DEBUGZONE(15)        // 0x8000
    #endif
    
    #define MINIPORT_NDIS_MAJOR_VERSION  0x06
    #define MINIPORT_NDIS_MINOR_VERSION  0x00
    #define DD_VENDOR_MAJOR_VERSION      0x01
    #define DD_VENDOR_MINOR_VERSION      0x00
    
    //
    //    The bigger this value is, the fewer the number of calls to ReadFile
    //    to receive bytes.
    //
    //    This value may be overridden with the registry setting:
    //        HKLM\Comm\AsyncMac1\Parms\ReceiveBufferSize
    //
    #define DEFAULT_RX_BUF_SIZE    2000
    
    //
    //    Maximum number of simultaneous pending transmits to allow.
    //
    //    This value may be overridden with the registry setting:
    //        HKLM\Comm\AsyncMac1\Parms\MaxTxPackets
    //
    #define MAX_TRANSMIT    16
    #define DEFAULT_BAUDRATE    115200
    #define ROUND_UP_TO_MULTIPLE_OF_N(value, N)    ((value + N - 1) & ~(N - 1))
    
    //
    //    Default send/receive thread priority.
    //
    //    This value may be overridden with the registry setting:
    //        HKLM\Comm\AsyncMac1\Parms\ReceiveThreadPriority256
    //        HKLM\Comm\AsyncMac1\Parms\TransmitThreadPriority256
    //
    //
    #define DEFAULT_RX_THREAD_PRIORITY  130
    #define DEFAULT_TX_THREAD_PRIORITY  130
    #define MAX_FRAME_SIZE              1502
    #define FRAME_PADDING               256
    #define DEFAULT_DESIRED_ACCM        0
    
    #define ETH_BUFFER_SIZE                     1520
    
    // Size of an Ethernet header (in bytes).
    #define ETH_HEADER_SIZE                     14
    
    // Size of an Ethernet address (in bytes).
    #define ETH_LENGTH_OF_ADDRESS               6
    
    // Maximum size of data field in an Ethernet frame (in bytes).
    #define ETH_MAX_DATA_SIZE                   1500
    
    #define DD_MAX_LOOKAHEAD               (ETH_BUFFER_SIZE - ETH_HEADER_SIZE)
    
    #define NIC_MAX_PACKET_SIZE             1514
    #define NIC_MIN_PACKET_SIZE             60
    #define NIC_HEADER_SIZE                 14
    #define NIC_MEDIA_MAX_SPEED             1000000 // maximum link speed for send dna recv in bps
    #define NIC_MAX_MCAST_LIST              32
    
    
    typedef struct _DAVEDRIVER_ADAPTER_ *PDAVEDRIVER_ADAPTER;
    typedef struct _DAVEDRIVER_CONTEXT_ *PDAVEDRIVER_CONTEXT;
    
    typedef struct _DAVEDRIVER_CONTEXT_
    {
        DWORD               dwflag;
        NDIS_HANDLE         hMiniportHandle;
    } DAVEDRIVER_CONTEXT, *PDAVEDRIVER_CONTEXT;
    
    typedef struct _DAVEDRIVER_ADAPTER_
    {
        NDIS_HANDLE         hMiniportAdapter;
        NDIS_HANDLE         hNdisLinkContext;
        DWORD               dwMaxSendFrameSize;
        DWORD               dwMaxRecvFrameSize;
        DWORD               dwRecvBufSize;        // Size of buffer passed to ReadFile
        DWORD               dwRecvThreadPrio;    // Priority of RxThread
        DWORD               dwSendThreadPrio;    // Priority of RxThread
        NDIS_SPIN_LOCK      lock;
        TCHAR               portName[_MAX_PATH];
        HANDLE              hPort;        // The serial port handle
        DWORD               dwType;     // The serial mode (232, 485)
        DWORD               dwBaudRate;    // The link baud rate (in 100's b/s)
        DWORD               dwFlags;    // Some state flags
    #define FLAGS_RUN_RXTHREAD    0x00000001
    #define FLAGS_RUN_TXTHREAD    0x00000002
        HANDLE                  hRxThrd;    // Recv Thread handle
        HANDLE                  hTxThrd;    // Send Thread handle
        LIST_ENTRY              txPacketList;
        NDIS_EVENT              txPacketEvent;
        UCHAR                   permanentAddress[ETH_LENGTH_OF_ADDRESS];
        UCHAR                   currentAddress[ETH_LENGTH_OF_ADDRESS];
    } DAVEDRIVER_ADAPTER, *PDAVEDRIVER_ADAPTER;
    
    NDIS_STATUS MpSetOptions(NDIS_HANDLE NdisDriverHandle, NDIS_HANDLE DriverContext);
    NDIS_STATUS MpInitialize(NDIS_HANDLE MiniportAdapterHandle, NDIS_HANDLE MiniportDriverContext, PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters);
    void MpHalt(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction);
    void MpDriverUnload(PDRIVER_OBJECT DriverObject);
    NDIS_STATUS MpPause(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters);
    NDIS_STATUS MpRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters);
    NDIS_STATUS MpOidRequest(NDIS_HANDLE MiniportAdapterContext, PNDIS_OID_REQUEST OidRequest);
    void MpSendNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferList, NDIS_PORT_NUMBER PortNumber, ULONG SendFlags);
    void MpReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferLists, ULONG ReturnFlags);
    void MpCancelSend(NDIS_HANDLE MiniportAdapterContext, PVOID CancelId);
    BOOLEAN MpCheckForHangEx(NDIS_HANDLE MiniportAdapterContext);
    NDIS_STATUS MpResetEx(NDIS_HANDLE MiniportAdapterContext, PBOOLEAN AddressingReset);
    void MpDevicePnPEventNotify(NDIS_HANDLE MiniportAdapterContext, PNET_DEVICE_PNP_EVENT NetDevicePnPEvent);
    void MpShutdownEx(NDIS_HANDLE MiniportAdapterContext, NDIS_SHUTDOWN_ACTION ShutdownAction);
    void MpCancelOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId);
    NDIS_STATUS MpMethodRequest(IN PDAVEDRIVER_ADAPTER Adapter, IN PNDIS_OID_REQUEST NdisRequest);
    NDIS_STATUS MpSetInformation(IN PDAVEDRIVER_ADAPTER Adapter, IN PNDIS_OID_REQUEST NdisRequest);
    NDIS_STATUS MpQueryInformation(IN PDAVEDRIVER_ADAPTER Adapter, IN PNDIS_OID_REQUEST NdisRequest);
    

    The DaveDriver.c file

    // DaveDriver.cpp : Defines the entry point for the DLL application.
    //
    
    #include <Windows.h>
    #include <ndis.h>
    
    #include "DaveDriver.h"
    #include "Hardware.h"
    
    NTSTATUS DriverEntry (PDRIVER_OBJECT driverObject, PUNICODE_STRING registryPath);
    
    #pragma NDIS_INIT_FUNCTION(DriverEntry)
    
    #ifdef DEBUG
    DBGPARAM dpCurSettings = {
        TEXT("DaveDriver"), {
            TEXT("Init"),     TEXT("Undefined"),TEXT("Undefined"),TEXT("Undefined"),
                TEXT("Undefined"),TEXT("Send"),        TEXT("Undefined"),TEXT("Undefined"),
                TEXT("Undefined"),TEXT("Recv"),     TEXT("Interface"),TEXT("Misc"),
                TEXT("Alloc"),    TEXT("Function"), TEXT("Warning"),  TEXT("Error") },
                0x0000C000
    };
    #endif // DEBUG
    
    PDRIVER_OBJECT g_pDriverObject;
    NDIS_HANDLE    g_hDriver;
    NDIS_HANDLE    g_hMiniportDriverContext = NULL;
    PDAVEDRIVER_CONTEXT g_pDriverContext;
    DWORD               g_adapterCount;
    
    static NDIS_OID NICSupportedOids[58] =
    {
        // Mandatory
        OID_GEN_CURRENT_LOOKAHEAD,
        OID_GEN_CURRENT_PACKET_FILTER,
        OID_GEN_INTERRUPT_MODERATION,
        OID_GEN_LINK_PARAMETERS,
        OID_GEN_MAXIMUM_FRAME_SIZE,
        OID_GEN_MAXIMUM_TOTAL_SIZE,
        OID_GEN_RCV_OK,
        OID_GEN_RECEIVE_BLOCK_SIZE,
        OID_GEN_RECEIVE_BUFFER_SPACE,
        OID_GEN_STATISTICS,
        OID_GEN_TRANSMIT_BLOCK_SIZE,
        OID_GEN_TRANSMIT_BUFFER_SPACE,
        OID_GEN_VENDOR_DESCRIPTION,
        OID_GEN_VENDOR_DRIVER_VERSION,
        OID_GEN_VENDOR_ID,
        OID_GEN_XMIT_OK,
    
        // Other supported
        OID_GEN_NETWORK_LAYER_ADDRESSES
    
        ///////////////////////////////////
        ///////////////////////////////////
        //OID_GEN_MACHINE_NAME,
        //OID_GEN_CURRENT_PACKET_FILTER,
        //OID_GEN_SUPPORTED_LIST,
        //OID_GEN_HARDWARE_STATUS,
        //OID_GEN_MEDIA_SUPPORTED,
        //OID_GEN_MEDIA_IN_USE,
        //OID_GEN_MAXIMUM_LOOKAHEAD,
        //OID_GEN_MAXIMUM_FRAME_SIZE,
        //OID_GEN_LINK_SPEED,
        //OID_GEN_TRANSMIT_BUFFER_SPACE,
        //OID_GEN_RECEIVE_BUFFER_SPACE,
        //OID_GEN_TRANSMIT_BLOCK_SIZE,
        //OID_GEN_RECEIVE_BLOCK_SIZE,
        //OID_GEN_VENDOR_ID,
        //OID_GEN_VENDOR_DESCRIPTION,
        //OID_GEN_VENDOR_DRIVER_VERSION,
        //OID_GEN_CURRENT_LOOKAHEAD,
        //OID_GEN_DRIVER_VERSION,
        //OID_GEN_MAXIMUM_TOTAL_SIZE,
        //OID_GEN_MAC_OPTIONS,
        //OID_GEN_MEDIA_CONNECT_STATUS,
        //OID_GEN_MAXIMUM_SEND_PACKETS,
        //OID_GEN_SUPPORTED_GUIDS,
        //OID_GEN_XMIT_OK,
        //OID_GEN_RCV_OK,
        //OID_GEN_XMIT_ERROR,
        //OID_GEN_RCV_ERROR,
        //OID_GEN_RCV_NO_BUFFER,
        //OID_GEN_STATISTICS,
        //OID_GEN_RCV_CRC_ERROR,
        //OID_GEN_TRANSMIT_QUEUE_LENGTH,
        //OID_GEN_PHYSICAL_MEDIUM,
        //OID_GEN_DIRECTED_BYTES_XMIT,
        //OID_GEN_DIRECTED_FRAMES_XMIT,
        //OID_GEN_MULTICAST_BYTES_XMIT,
        //OID_GEN_MULTICAST_FRAMES_XMIT,
        //OID_GEN_BROADCAST_BYTES_XMIT,
        //OID_GEN_BROADCAST_FRAMES_XMIT,
        //OID_GEN_DIRECTED_BYTES_RCV,
        //OID_GEN_DIRECTED_FRAMES_RCV,
        //OID_GEN_MULTICAST_BYTES_RCV,
        //OID_GEN_MULTICAST_FRAMES_RCV,
        //OID_GEN_BROADCAST_BYTES_RCV,
        //OID_GEN_BROADCAST_FRAMES_RCV,
        //OID_802_3_PERMANENT_ADDRESS,
        //OID_802_3_CURRENT_ADDRESS,
        //OID_802_3_MULTICAST_LIST,
        //OID_802_3_MAXIMUM_LIST_SIZE,
        //OID_802_3_RCV_ERROR_ALIGNMENT,
        //OID_802_3_XMIT_ONE_COLLISION,
        //OID_802_3_XMIT_MORE_COLLISIONS,
        //OID_802_3_XMIT_DEFERRED,
        //OID_802_3_XMIT_MAX_COLLISIONS,
        //OID_802_3_RCV_OVERRUN,
        //OID_802_3_XMIT_UNDERRUN,
        //OID_802_3_XMIT_HEARTBEAT_FAILURE,
        //OID_802_3_XMIT_TIMES_CRS_LOST,
        //OID_802_3_XMIT_LATE_COLLISIONS,
        //
        // TBD: Supporting this OID is mandatory for NDIS 6.0 miniports
        // OID_GEN_LINK_PARAMETERS,
        // 
    };
    
    PUCHAR GetOidString(NDIS_OID Oid)
    {
        PUCHAR OidName = NULL;
    #define OID_CASE(oid) case (oid): OidName = #oid; break
        switch (Oid)
        {
            OID_CASE(OID_GEN_NETWORK_LAYER_ADDRESSES);
            OID_CASE(OID_GEN_STATISTICS);
            OID_CASE(OID_GEN_MACHINE_NAME);
            OID_CASE(OID_GEN_CURRENT_PACKET_FILTER);
            OID_CASE(OID_GEN_CURRENT_LOOKAHEAD);
            OID_CASE(OID_GEN_DRIVER_VERSION);
            OID_CASE(OID_GEN_HARDWARE_STATUS);
            OID_CASE(OID_GEN_LINK_SPEED);
            OID_CASE(OID_GEN_MAC_OPTIONS);
            OID_CASE(OID_GEN_MAXIMUM_LOOKAHEAD);
            OID_CASE(OID_GEN_MAXIMUM_FRAME_SIZE);
            OID_CASE(OID_GEN_MAXIMUM_TOTAL_SIZE);
            OID_CASE(OID_GEN_MEDIA_SUPPORTED);
            OID_CASE(OID_GEN_MEDIA_IN_USE);
            OID_CASE(OID_GEN_RECEIVE_BLOCK_SIZE);
            OID_CASE(OID_GEN_RECEIVE_BUFFER_SPACE);
            OID_CASE(OID_GEN_SUPPORTED_LIST);
            OID_CASE(OID_GEN_TRANSMIT_BLOCK_SIZE);
            OID_CASE(OID_GEN_TRANSMIT_BUFFER_SPACE);
            OID_CASE(OID_GEN_VENDOR_DESCRIPTION);
            OID_CASE(OID_GEN_VENDOR_ID);
            OID_CASE(OID_802_3_CURRENT_ADDRESS);
            OID_CASE(OID_802_3_MULTICAST_LIST);
            OID_CASE(OID_TAPI_ACCEPT);
            OID_CASE(OID_TAPI_ANSWER);
            OID_CASE(OID_TAPI_CLOSE);
            OID_CASE(OID_TAPI_CLOSE_CALL);
            OID_CASE(OID_TAPI_CONDITIONAL_MEDIA_DETECTION);
            OID_CASE(OID_TAPI_CONFIG_DIALOG);
            OID_CASE(OID_TAPI_DEV_SPECIFIC);
            OID_CASE(OID_TAPI_DIAL);
            OID_CASE(OID_TAPI_DROP);
            OID_CASE(OID_TAPI_GET_ADDRESS_CAPS);
            OID_CASE(OID_TAPI_GET_ADDRESS_ID);
            OID_CASE(OID_TAPI_GET_ADDRESS_STATUS);
            OID_CASE(OID_TAPI_GET_CALL_ADDRESS_ID);
            OID_CASE(OID_TAPI_GET_CALL_INFO);
            OID_CASE(OID_TAPI_GET_CALL_STATUS);
            OID_CASE(OID_TAPI_GET_DEV_CAPS);
            OID_CASE(OID_TAPI_GET_DEV_CONFIG);
            OID_CASE(OID_TAPI_GET_EXTENSION_ID);
            OID_CASE(OID_TAPI_GET_ID);
            OID_CASE(OID_TAPI_GET_LINE_DEV_STATUS);
            OID_CASE(OID_TAPI_MAKE_CALL);
            OID_CASE(OID_TAPI_NEGOTIATE_EXT_VERSION);
            OID_CASE(OID_TAPI_OPEN);
            OID_CASE(OID_TAPI_PROVIDER_INITIALIZE);
            OID_CASE(OID_TAPI_PROVIDER_SHUTDOWN);
            OID_CASE(OID_TAPI_SECURE_CALL);
            OID_CASE(OID_TAPI_SELECT_EXT_VERSION);
            OID_CASE(OID_TAPI_SEND_USER_USER_INFO);
            OID_CASE(OID_TAPI_SET_APP_SPECIFIC);
            OID_CASE(OID_TAPI_SET_CALL_PARAMS);
            OID_CASE(OID_TAPI_SET_DEFAULT_MEDIA_DETECTION);
            OID_CASE(OID_TAPI_SET_DEV_CONFIG);
            OID_CASE(OID_TAPI_SET_MEDIA_MODE);
            OID_CASE(OID_TAPI_SET_STATUS_MESSAGES);
            OID_CASE(OID_TAPI_TRANSLATE_ADDRESS);
            OID_CASE(OID_WAN_CURRENT_ADDRESS);
            OID_CASE(OID_WAN_GET_BRIDGE_INFO);
            OID_CASE(OID_WAN_GET_COMP_INFO);
            OID_CASE(OID_WAN_GET_INFO);
            OID_CASE(OID_WAN_GET_LINK_INFO);
            OID_CASE(OID_WAN_GET_STATS_INFO);
            OID_CASE(OID_WAN_HEADER_FORMAT);
            OID_CASE(OID_WAN_LINE_COUNT);
            OID_CASE(OID_WAN_MEDIUM_SUBTYPE);
            OID_CASE(OID_WAN_PERMANENT_ADDRESS);
            OID_CASE(OID_WAN_PROTOCOL_TYPE);
            OID_CASE(OID_WAN_QUALITY_OF_SERVICE);
            OID_CASE(OID_WAN_SET_BRIDGE_INFO);
            OID_CASE(OID_WAN_SET_COMP_INFO);
            OID_CASE(OID_WAN_SET_LINK_INFO);
            OID_CASE(OID_WAN_IPV6CP_INTERFACE_ID);
            OID_CASE(OID_IP4_OFFLOAD_STATS);
    
        default:
            OidName = "Unknown OID";
            break;
        }
        return OidName;
    }
    
    
    void* DDAllocateMemory(NDIS_HANDLE hNdis, UINT nBytes)
    {
        void *pMem;
        pMem = NdisAllocateMemoryWithTagPriority(hNdis, nBytes, 'maDN', NormalPoolPriority);
        if(pMem == NULL)
        {
            DEBUGMSG (ZONE_ERROR, (TEXT("+DAVED: AllocMem %d bytes failed\n")));
        }
        else
        {
            memset(pMem, 0, nBytes);
        }
        return pMem;
    }
    
    void DDFreeMemory(void *pMem, UINT nBytes)
    {
        NdisFreeMemory(pMem, nBytes, 0);
    }
    
    
    BOOL APIENTRY DllEntry( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    {
        switch (ul_reason_for_call)
        {
        case DLL_PROCESS_ATTACH:
            DEBUGREGISTER(hModule);
            DisableThreadLibraryCalls ((HMODULE)hModule);
            DEBUGMSG(ZONE_INIT, (TEXT("DAVED: DLL_PROCESS_ATTACH\n")));
            RETAILMSG(1, (TEXT("DAVED: DLL_PROCESS_ATTACH\n")));
            break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
        }
        return TRUE;
    }
    
    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    {
        NDIS_STATUS initStatus;
        NDIS_MINIPORT_DRIVER_CHARACTERISTICS mpCharacteristics;
    
        RETAILMSG(1, (TEXT("+DAVED: DriverEntry(0x%X, 0x%X)\r\n"), DriverObject, RegistryPath));
    
        g_pDriverObject = DriverObject;
        g_pDriverContext = (PDAVEDRIVER_CONTEXT)NULL;
    
        NdisZeroMemory(&mpCharacteristics, sizeof(mpCharacteristics));
        mpCharacteristics.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
        mpCharacteristics.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1; // For NDIS 6.0
        mpCharacteristics.Header.Size = NDIS_SIZEOF_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
        mpCharacteristics.MajorNdisVersion = 0x06; // For NDIS 6.0
        mpCharacteristics.MinorNdisVersion = 0x00; // For NDIS 6.0
        mpCharacteristics.MajorDriverVersion = 0x01;
        mpCharacteristics.MinorDriverVersion = 0x00;
        mpCharacteristics.Flags = 0;//NDIS_WDM_DRIVER; // TODO DM: Not sure of this one.
        // Function pointers
        mpCharacteristics.SetOptionsHandler = MpSetOptions;
        mpCharacteristics.InitializeHandlerEx = MpInitialize;
        mpCharacteristics.HaltHandlerEx = MpHalt;
        mpCharacteristics.UnloadHandler = MpDriverUnload;
        mpCharacteristics.PauseHandler = MpPause;
        mpCharacteristics.RestartHandler = MpRestart;
        mpCharacteristics.OidRequestHandler = MpOidRequest;
        mpCharacteristics.SendNetBufferListsHandler = MpSendNetBufferLists;
        mpCharacteristics.ReturnNetBufferListsHandler = MpReturnNetBufferLists;
        mpCharacteristics.CancelSendHandler = MpCancelSend;
        mpCharacteristics.CheckForHangHandlerEx = NULL; //MpCheckForHangEx;
        mpCharacteristics.ResetHandlerEx = MpResetEx;
        mpCharacteristics.DevicePnPEventNotifyHandler = MpDevicePnPEventNotify;
        mpCharacteristics.ShutdownHandlerEx = MpShutdownEx;
        mpCharacteristics.CancelOidRequestHandler = MpCancelOidRequest;
    
        initStatus = NdisMRegisterMiniportDriver(DriverObject, RegistryPath, g_hMiniportDriverContext, &mpCharacteristics, &g_hDriver);
        RETAILMSG(1, (TEXT("DAVED: DriverEntry: MiniportHandle = 0x%08x\r\n"), g_hDriver));
    
        if(initStatus == NDIS_STATUS_BAD_CHARACTERISTICS)
        {
            RETAILMSG(1, (TEXT("DAVED: DriverEntry: Error NDIS_STATUS_BAD_CHARACTERISTICS")));
        }
    
        if(initStatus == NDIS_STATUS_BAD_VERSION)
        {
            RETAILMSG(1, (TEXT("DAVED: DriverEntry: Error NDIS_STATUS_BAD_VERSION")));
        }
    
        if(initStatus == NDIS_STATUS_RESOURCES)
        {
            RETAILMSG(1, (TEXT("DAVED: DriverEntry: Error NDIS_STATUS_RESOURCES")));
        }
    
        if (initStatus != NDIS_STATUS_SUCCESS)
        {
            RETAILMSG(1, (TEXT("-DAVED: DriverEntry: Returning STATUS_FAILURE.\r\n"),
                DriverObject, RegistryPath));
    
            NdisMDeregisterMiniportDriver(g_hDriver);
            return NDIS_STATUS_FAILURE;
        }
    
        g_pDriverContext = (PDAVEDRIVER_CONTEXT)DDAllocateMemory(g_hDriver, sizeof(DAVEDRIVER_CONTEXT));
        g_adapterCount = 0;
    
        RETAILMSG(1, (TEXT("-DAVED: DriverEntry: Returning STATUS_SUCCESS\r\n"), DriverObject, RegistryPath));
        return NDIS_STATUS_SUCCESS;
    }
    
    NDIS_STATUS MpSetOptions(NDIS_HANDLE NdisDriverHandle, NDIS_HANDLE DriverContext)
    {
        return NDIS_STATUS_SUCCESS;
    }
    
    NDIS_STATUS MpInitialize(NDIS_HANDLE MiniportAdapterHandle, NDIS_HANDLE MiniportDriverContext, PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters)
    {
        NDIS_STATUS status = NDIS_STATUS_SUCCESS;
        PDAVEDRIVER_ADAPTER pAdapter = NULL;
    
        NDIS_HANDLE hRegistryConfiguration;
        NDIS_CONFIGURATION_OBJECT configObject;
        PNDIS_CONFIGURATION_PARAMETER   returnedValue;
        NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registrationAttributes;
        NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES generalAttributes;
        NDIS_STRING                     maxFrameSizeStr = NDIS_STRING_CONST("MaxFrameSize");
        NDIS_STRING                     maxSendFrameSizeStr = NDIS_STRING_CONST("MaxSendFrameSize");
        NDIS_STRING                     maxRecvFrameSizeStr = NDIS_STRING_CONST("MaxRecvFrameSize");
        NDIS_STRING                     maxTxPacketsStr = NDIS_STRING_CONST("MaxTxPackets");
        NDIS_STRING                     recvBufSizeStr = NDIS_STRING_CONST("ReceiveBufferSize");
        NDIS_STRING                     recvThreadPrioStr = NDIS_STRING_CONST("ReceiveThreadPriority256");
        NDIS_STRING                     sendThreadPrioStr = NDIS_STRING_CONST("TransmitThreadPriority256");
        NDIS_STRING                     driverNameStr = NDIS_STRING_CONST("Port");
        NDIS_STRING                     speedStr = NDIS_STRING_CONST("Speed");
        NDIS_STRING                     typeStr = NDIS_STRING_CONST("Interface485");
        NDIS_STRING                     ifTypeStr = NDIS_STRING_CONST("*IfType");
        NDIS_STRING                     mediaTypeStr = NDIS_STRING_CONST("*MediaType");
        NDIS_STRING                     physicalMediaTypeStr = NDIS_STRING_CONST("*PhysicalMediaType");
        NDIS_STRING                     busStr = NDIS_STRING_CONST("BusNumber");
        UCHAR                           macAddress[6] = {' ','D','A','V','D','D'};
        DWORD ifType = 0;
    
        RETAILMSG(1, (TEXT("+DAVED: MpInitialize\r\n")));
    
        do 
        {
            //
            // We only support a single instance of DaveDriver
            //
            if(g_adapterCount != 0)
            {
                RETAILMSG(1, (TEXT("DAVED: Can't instantiate more than 1 adapter.\r\n")));
                status = NDIS_STATUS_FAILURE;
                break;
            }
    
            // Indicate we have 1 instance of the adapter
            NdisInterlockedIncrement(&g_adapterCount);
    
            //
            // Let's allocate a DaveDriver adapter structure.
            //
            pAdapter = DDAllocateMemory(g_hDriver, sizeof(DAVEDRIVER_ADAPTER));
            if (pAdapter == NULL)
            {
                status = NDIS_STATUS_RESOURCES;
                break;
            }
            pAdapter->hMiniportAdapter = MiniportAdapterHandle;
    
            NdisZeroMemory(&registrationAttributes, sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
            NdisZeroMemory(&generalAttributes, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
    
            // Setting registration attributes
            registrationAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
            registrationAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
            registrationAttributes.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
            registrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)pAdapter;
            registrationAttributes.AttributeFlags = 0;//NDIS_MINIPORT_ATTRIBUTES_NDIS_WDM;
            registrationAttributes.CheckForHangTimeInSeconds = 0;
            registrationAttributes.InterfaceType = NdisInterfaceInternal;
    
            status = NdisMSetMiniportAttributes(MiniportAdapterHandle, (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&registrationAttributes);
            if(status != NDIS_STATUS_SUCCESS)
            {
                RETAILMSG(1, (TEXT("DAVED: Can't set adapter attributes.\r\n")));
                break;
            }
    
            // Setting generic attributes
            generalAttributes.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
            generalAttributes.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
            generalAttributes.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
            generalAttributes.MediaType = NdisMedium802_3;
            generalAttributes.MtuSize = NIC_MAX_PACKET_SIZE - NIC_HEADER_SIZE;
            generalAttributes.MaxXmitLinkSpeed = NIC_MEDIA_MAX_SPEED;
            generalAttributes.MaxRcvLinkSpeed = NIC_MEDIA_MAX_SPEED;
            generalAttributes.XmitLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;
            generalAttributes.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;
            generalAttributes.MediaConnectState = MediaConnectStateUnknown;
            generalAttributes.MediaDuplexState = MediaDuplexStateUnknown;
            generalAttributes.LookaheadSize = NIC_MAX_PACKET_SIZE - NIC_HEADER_SIZE;
            generalAttributes.PowerManagementCapabilities = NULL;
            generalAttributes.MacOptions = NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
                                           NDIS_MAC_OPTION_NO_LOOPBACK;
            generalAttributes.SupportedPacketFilters = NDIS_PACKET_TYPE_DIRECTED |
                                                       NDIS_PACKET_TYPE_MULTICAST |
                                                       NDIS_PACKET_TYPE_BROADCAST;
            generalAttributes.MaxMulticastListSize = NIC_MAX_MCAST_LIST;
            generalAttributes.MacAddressLength = ETH_LENGTH_OF_ADDRESS;
            NdisMoveMemory(generalAttributes.PermanentMacAddress, macAddress, ETH_LENGTH_OF_ADDRESS);
            NdisMoveMemory(generalAttributes.CurrentMacAddress, macAddress, ETH_LENGTH_OF_ADDRESS);
            generalAttributes.PhysicalMediumType = NdisPhysicalMediumOther; // NdisPhysicalMediumUnspecified;
            generalAttributes.RecvScaleCapabilities = NULL;
            generalAttributes.AccessType = NET_IF_ACCESS_BROADCAST; // TODO DM: verify this one for p2p maybe...
            generalAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
            generalAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
            generalAttributes.IfType = IF_TYPE_OTHER; // TODO DM: VERIFY this one for IF_TYPE_PROP_POINT2POINT_SERIAL
            generalAttributes.IfConnectorPresent = FALSE;
            
            // TODO DM: Doc says as an NDIS 6.0, we should support all statistics... which is not the case here... to be validated
            generalAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
                                                    NDIS_STATISTICS_RCV_OK_SUPPORTED |
                                                    NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
                                                    NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
                                                    NDIS_STATISTICS_RCV_CRC_ERROR_SUPPORTED |
                                                    NDIS_STATISTICS_RCV_NO_BUFFER_SUPPORTED |
                                                    NDIS_STATISTICS_TRANSMIT_QUEUE_LENGTH_SUPPORTED |
                                                    NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
            generalAttributes.SupportedOidList = NICSupportedOids;
            generalAttributes.SupportedOidListLength = sizeof(NICSupportedOids);
            
            RETAILMSG(1, (TEXT("DAVED: IfType is %u.\r\n"), generalAttributes.IfType));
            RETAILMSG(1, (TEXT("DAVED: MediaType is %u.\r\n"), generalAttributes.MediaType));
            RETAILMSG(1, (TEXT("DAVED: PhysicalMediumType is %u.\r\n"), generalAttributes.PhysicalMediumType));
    
            status = NdisMSetMiniportAttributes(MiniportAdapterHandle,
                (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&generalAttributes);
    
            if(status != NDIS_STATUS_SUCCESS)
            {
                RETAILMSG(1, (TEXT("DAVED: Can't set general attributes.\r\n")));
                break;
            }
    
            // Initialize the configuration object with the adapter handle:
            configObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
            configObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
            configObject.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
            configObject.NdisHandle = MiniportAdapterHandle;
            configObject.Flags = 0;
    
            // Get the configuration handle:
            status = NdisOpenConfigurationEx(&configObject, &hRegistryConfiguration);
            if (status != NDIS_STATUS_SUCCESS)
            {
                DDFreeMemory(pAdapter, sizeof(DAVEDRIVER_ADAPTER));
                RETAILMSG(1, (TEXT("DAVED:Initialize: NdisOpenConfigurationEx failed 0x%x\r\n"), status));
                break;
            }
    
            NdisReadConfiguration(&status, &returnedValue, hRegistryConfiguration, &busStr, NdisParameterInteger);
            if (status == NDIS_STATUS_SUCCESS)
                RETAILMSG(1,(TEXT("DAVED: BusNumber=%u\r\n"), returnedValue->ParameterData.IntegerData));
    
            // RecvThreadPrio
            //pAdapter->dwRecvThreadPrio = DEFAULT_RX_THREAD_PRIORITY;
            //NdisReadConfiguration(&status, &returnedValue, hRegistryConfiguration, &recvThreadPrioStr, NdisParameterInteger);
            //if (status == NDIS_STATUS_SUCCESS)
            //    pAdapter->dwRecvThreadPrio = returnedValue->ParameterData.IntegerData;
            //RETAILMSG(1,(TEXT("DAVED: RecvThreadPrio=%d\r\n"), pAdapter->dwRecvThreadPrio));
    
            //// SendThreadPrio
            //pAdapter->dwSendThreadPrio = DEFAULT_TX_THREAD_PRIORITY;
            //NdisReadConfiguration(&status, &returnedValue, hRegistryConfiguration, &sendThreadPrioStr, NdisParameterInteger);
            //if (status == NDIS_STATUS_SUCCESS)
            //    pAdapter->dwSendThreadPrio = returnedValue->ParameterData.IntegerData;
            //RETAILMSG(1,(TEXT("DAVED: SendThreadPrio=%d\r\n"), pAdapter->dwSendThreadPrio));
    
            // Port name
            memset(pAdapter->portName, 0, sizeof(pAdapter->portName));
            _tcscpy(pAdapter->portName, _T("COM1:"));
            //NdisReadConfiguration(&status, &returnedValue, hRegistryConfiguration,  &driverNameStr, NdisParameterString);
            //if (status == NDIS_STATUS_SUCCESS)
            //{
            //    memset(pAdapter->portName, 0, sizeof(pAdapter->portName));
            //    _tcsncpy(pAdapter->portName, returnedValue->ParameterData.StringData.Buffer, sizeof(pAdapter->portName) - 1);
            //    pAdapter->portName[sizeof(pAdapter->portName) - 1] = 0;
            //    RETAILMSG(1, (TEXT("DAVED: Serial Port is: \"%s\"\r\n"), pAdapter->portName));
            //}
            //else
            //{
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Port\".\r\n")));
            //    break;
            //}
    
            //pAdapter->dwBaudRate = DEFAULT_BAUDRATE;
            //NdisReadConfiguration(&status, &returnedValue, hRegistryConfiguration,  &speedStr, NdisParameterInteger);
            //if (status == NDIS_STATUS_SUCCESS)
            //{
            //    pAdapter->dwBaudRate = returnedValue->ParameterData.IntegerData;
            //    RETAILMSG(1, (TEXT("DAVED: Serial speed is %d.\r\n"), pAdapter->dwBaudRate));
            //}
            //else
            //{
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Speed\".\r\n")));
            //    break;
            //}
    
            //NdisReadConfiguration(&status, &returnedValue, hRegistryConfiguration,  &typeStr, NdisParameterInteger);
            //if (status == NDIS_STATUS_SUCCESS)
            //{
            //    if(returnedValue->ParameterData.IntegerData)
            //    {
            //        pAdapter->dwType = 1;//SCC_INTERFACE_RS485;
            //        RETAILMSG(1, (TEXT("DAVED:  Interface type is 485.\r\n")));
            //    }
            //    else
            //    {
            //        pAdapter->dwType = 0;//SCC_INTERFACE_RS232;
            //        RETAILMSG(1, (TEXT("DAVED:  Interface type is 232.\r\n")));
            //    }
            //    // TODO dm
            //    pAdapter->dwType = 0;//SCC_INTERFACE_RS232;
            //    RETAILMSG(1, (TEXT("DAVED:  Interface type is 232.\r\n")));
            //}
            //else
            //{
            //    // TODO DM: Remettre la valeur 485 dans le registr.
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Interface485\".\r\n")));
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Interface485\".\r\n")));
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Interface485\".\r\n")));
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Interface485\".\r\n")));
            //    RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Interface485\".\r\n")));
            //    RETAILMSG(1, (TEXT("DAVED: Forcing value to 232.\r\n")));
            //    // TODO dm
            //    pAdapter->dwType = 0;//SCC_INTERFACE_RS232;
            //    status = NDIS_STATUS_SUCCESS;
            //    //RETAILMSG(1, (TEXT("DAVED: Missing registry key \"Interface485\".\r\n")));
            //    //break;
            //}
    
            InitHardware(pAdapter);
    
            // Just close the config handle
            NdisCloseConfiguration (hRegistryConfiguration);
        } while(FALSE);
    
        if(pAdapter && status != NDIS_STATUS_SUCCESS)
        {
            NdisInterlockedDecrement(&g_adapterCount);
            DDFreeMemory(pAdapter, sizeof(DAVEDRIVER_ADAPTER));
        }
    
        return status;
    }
    
    void MpHalt(NDIS_HANDLE MiniportAdapterContext, NDIS_HALT_ACTION HaltAction)
    {
    }
    
    void MpDriverUnload(PDRIVER_OBJECT DriverObject)
    {
        RETAILMSG(1, (TEXT("+DAVED: MpDriverUnload: Unloading the driver with driver object 0x%08x.\r\n"), *DriverObject));
        DDFreeMemory(g_pDriverContext, sizeof(DAVEDRIVER_CONTEXT));
        NdisMDeregisterMiniportDriver(g_hDriver);
        RETAILMSG(1, (TEXT("-DAVED: MpDriverUnload.\r\n")));
    }
    
    NDIS_STATUS MpPause(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters)
    {
        return NDIS_STATUS_SUCCESS;
    }
    
    NDIS_STATUS MpRestart(NDIS_HANDLE MiniportAdapterContext, PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)
    {
        return NDIS_STATUS_SUCCESS;
    }
    
    NDIS_STATUS MpOidRequest(NDIS_HANDLE MiniportAdapterContext, PNDIS_OID_REQUEST OidRequest)
    {
        PDAVEDRIVER_ADAPTER pAdapter = (PDAVEDRIVER_ADAPTER)MiniportAdapterContext;
        NDIS_STATUS status = NDIS_STATUS_SUCCESS;
        RETAILMSG(0, (TEXT("+DAVED: MpOidRequest with OID 0x%08x.\r\n"), OidRequest->RequestType));
    
        // DM: Should verify for reset in progress here...
    
        switch(OidRequest->RequestType)
        {
        case NdisRequestMethod :
            status = MpMethodRequest(pAdapter, OidRequest);
            break;
        case NdisRequestSetInformation :
            status = MpSetInformation(pAdapter, OidRequest);
            break;
        case NdisRequestQueryInformation :
        case NdisRequestQueryStatistics :
            status = MpQueryInformation(pAdapter, OidRequest);
            break;
        default:
            status = NDIS_STATUS_NOT_SUPPORTED;
            break;
        }
    
        RETAILMSG(0, (TEXT("-DAVED: MpOidRequest.\r\n")));
        return status;
    }
    
    void MpSendNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferList, NDIS_PORT_NUMBER PortNumber, ULONG SendFlags)
    {
    }
    
    void MpReturnNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferLists, ULONG ReturnFlags)
    {
    }
    
    void MpCancelSend(NDIS_HANDLE MiniportAdapterContext, PVOID CancelId)
    {
    }
    
    BOOLEAN MpCheckForHangEx(NDIS_HANDLE MiniportAdapterContext)
    {
        return TRUE;
    }
    
    NDIS_STATUS MpResetEx(NDIS_HANDLE MiniportAdapterContext, PBOOLEAN AddressingReset)
    {
        return NDIS_STATUS_SUCCESS;
    }
    
    void MpDevicePnPEventNotify(NDIS_HANDLE MiniportAdapterContext, PNET_DEVICE_PNP_EVENT NetDevicePnPEvent)
    {
        RETAILMSG(1, (TEXT("+DAVED: MpDevicePnPEventNotify.\r\n")));
    }
    
    void MpShutdownEx(NDIS_HANDLE MiniportAdapterContext, NDIS_SHUTDOWN_ACTION ShutdownAction)
    {
    }
    
    void MpCancelOidRequest(NDIS_HANDLE MiniportAdapterContext, PVOID RequestId)
    {
    }
    
    NDIS_STATUS MpMethodRequest(IN PDAVEDRIVER_ADAPTER Adapter, IN PNDIS_OID_REQUEST NdisRequest)
    {
        return NDIS_STATUS_SUCCESS;
    }
    
    NDIS_STATUS MpSetInformation(IN PDAVEDRIVER_ADAPTER Adapter, IN OUT PNDIS_OID_REQUEST NdisRequest)
    {
        NDIS_OID    oid = NdisRequest->DATA.SET_INFORMATION.Oid;
        PVOID       informationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
        UINT        informationBufferLength = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
        PUINT       bytesRead = &NdisRequest->DATA.SET_INFORMATION.BytesRead;
        PUINT       bytesNeeded = &NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
        PNDIS_LINK_PARAMETERS pLinkParam;
        PNETWORK_ADDRESS_LIST pNetAddrList;
        PNETWORK_ADDRESS      pNetAddr;
        PBYTE                 p;
        DWORD                 ipListCount;
        DWORD*                pGenericDW;
        UINT32      i;
        NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    
        RETAILMSG(1, (TEXT("+DAVED: MpSetInformation: 0x%X (%S)\r\n"), oid, GetOidString(oid)));
    
        // Initialize the output
        bytesRead   = 0;
        bytesNeeded = 0;
    
        switch (oid)
        {
        case OID_GEN_CURRENT_LOOKAHEAD:
            // Protocols can specify a lookahead size, but we ignore it
            // since we always indicate complete packets to the stack.
            // Do not remove this set OID, or protocols will refuse to
            // talk to us!
            //
            break;
        case OID_GEN_CURRENT_PACKET_FILTER:
            pGenericDW = (DWORD*)informationBuffer;
            if(*pGenericDW)
            {
                if(*pGenericDW & NDIS_PACKET_TYPE_DIRECTED)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_DIRECTED is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_MULTICAST)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_MULTICAST is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_ALL_MULTICAST)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_ALL_MULTICAST is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_BROADCAST)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_BROADCAST is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_SOURCE_ROUTING)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_SOURCE_ROUTING is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_PROMISCUOUS)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_PROMISCUOUS is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_SMT)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_SMT is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_ALL_LOCAL)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_ALL_LOCAL is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_GROUP)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_GROUP is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_ALL_FUNCTIONAL)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_ALL_FUNCTIONAL is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_FUNCTIONAL)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_FUNCTIONAL is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_MAC_FRAME)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_MAC_FRAME is supported\r\n")));
                if(*pGenericDW & NDIS_PACKET_TYPE_NO_LOCAL)
                    RETAILMSG(1, (TEXT(" DD: NDIS_PACKET_TYPE_NO_LOCAL is supported\r\n")));
            }
            else
            {
                RETAILMSG(1, (TEXT(" DD: no flags are set for OID_GEN_CURRENT_PACKET_FILTER\r\n")));
            }
            break;
    
        case OID_GEN_INTERRUPT_MODERATION:
            status = NDIS_STATUS_INVALID_DATA;
            break;
    
        case OID_GEN_LINK_PARAMETERS:
            pLinkParam = (PNDIS_LINK_PARAMETERS)informationBuffer;
            RETAILMSG(1, (TEXT(" DD: pLinkParam->Header.Type = %u\r\n"), pLinkParam->Header.Type));
            RETAILMSG(1, (TEXT(" DD: pLinkParam->Header.Revision = %u\r\n"), pLinkParam->Header.Revision));
            RETAILMSG(1, (TEXT(" DD: pLinkParam->Header.Size = %u\r\n"), pLinkParam->Header.Size));
            
            switch(pLinkParam->MediaDuplexState)
            {
            case MediaDuplexStateHalf:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->MediaDuplexState = MediaDuplexStateHalf\r\n")));
                break;
            case MediaDuplexStateFull:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->MediaDuplexState = MediaDuplexStateFull\r\n")));
                break;
            case MediaDuplexStateUnknown:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->MediaDuplexState = MediaDuplexStateUnknown\r\n")));
                break;
            default:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->MediaDuplexState = OTHER... IT'S BAD\r\n")));
                break;
            }
    
            RETAILMSG(1, (TEXT(" DD: pLinkParam->XmitLinkSpeed = %u\r\n"), pLinkParam->XmitLinkSpeed));
            RETAILMSG(1, (TEXT(" DD: pLinkParam->RcvLinkSpeed = %u\r\n"), pLinkParam->RcvLinkSpeed));
    
            switch(pLinkParam->PauseFunctions)
            {
            case NdisPauseFunctionsUnsupported:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->PauseFunctions = NdisPauseFunctionsUnsupported\r\n")));
                break;
            case NdisPauseFunctionsSendOnly:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->PauseFunctions = NdisPauseFunctionsSendOnly\r\n")));
                break;
            case NdisPauseFunctionsReceiveOnly:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->PauseFunctions = NdisPauseFunctionsReceiveOnly\r\n")));
                break;
            case NdisPauseFunctionsSendAndReceive:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->PauseFunctions = NdisPauseFunctionsSendAndReceive\r\n")));
                break;
            default:
                RETAILMSG(1, (TEXT(" DD: pLinkParam->PauseFunctions = OTHER... IT'S BAD\r\n")));
                break;
            }
    
            if(pLinkParam->AutoNegotiationFlags)
            {
                if(pLinkParam->AutoNegotiationFlags & NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED)
                    RETAILMSG(1, (TEXT(" DD: pLinkParam->AutoNegotiationFlags NDIS_LINK_STATE_XMIT_LINK_SPEED_AUTO_NEGOTIATED is set\r\n")));
                if(pLinkParam->AutoNegotiationFlags & NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED)
                    RETAILMSG(1, (TEXT(" DD: pLinkParam->AutoNegotiationFlags NDIS_LINK_STATE_RCV_LINK_SPEED_AUTO_NEGOTIATED is set\r\n")));
                if(pLinkParam->AutoNegotiationFlags & NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED)
                    RETAILMSG(1, (TEXT(" DD: pLinkParam->AutoNegotiationFlags NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED is set\r\n")));
                if(pLinkParam->AutoNegotiationFlags & NDIS_LINK_STATE_PAUSE_FUNCTIONS_AUTO_NEGOTIATED)
                    RETAILMSG(1, (TEXT(" DD: pLinkParam->AutoNegotiationFlags NDIS_LINK_STATE_PAUSE_FUNCTIONS_AUTO_NEGOTIATED is set\r\n")));
            }
            else
            {
                RETAILMSG(1, (TEXT(" DD: pLinkParam->AutoNegotiationFlags no flags are set\r\n")));
            }
            break;
    
        case OID_GEN_NETWORK_LAYER_ADDRESSES:
            RETAILMSG(1, (L"OID_GEN_NETWORK_LAYER_ADDRESSES\r\n"));
            pNetAddrList = (PNETWORK_ADDRESS_LIST)informationBuffer;
            ipListCount = 0;
    
            if (pNetAddrList->AddressCount) {
                p = (PBYTE)pNetAddrList->Address;
                pNetAddr = (PNETWORK_ADDRESS)p;
                for (i = 0 ; i < (ULONG)pNetAddrList->AddressCount ; i++)
                {
                    if (pNetAddr->AddressType == NDIS_PROTOCOL_ID_TCP_IP)
                    {
                        // IP Address is bytes 4-7.
                        RETAILMSG(1, (L"    [%u]: %u.%u.%u.%u\r\n", ipListCount + 1, pNetAddr->Address[4], pNetAddr->Address[5], pNetAddr->Address[6], pNetAddr->Address[7]));
                    }
                    p += (pNetAddr->AddressLength + (2 * sizeof(USHORT)));
                    pNetAddr = (PNETWORK_ADDRESS)p;
                }
            }
            break;
    
        // Unrecognized/Invalid OIDs
        default:
            RETAILMSG(1, (TEXT(" DAVED: Set unsupported OID %#x\r\n"), oid));
            status = NDIS_STATUS_NOT_SUPPORTED;
            break;
        }
    
        if(status == NDIS_STATUS_SUCCESS)
        {
            bytesNeeded = 0;
        }
        else
        {
            bytesRead = 0;
        }
    
        RETAILMSG(1, (TEXT("-DAVED: MpSetInformation\r\n")));
    
        return status;
    }
    
    NDIS_STATUS MpQueryInformation(IN PDAVEDRIVER_ADAPTER Adapter, IN OUT PNDIS_OID_REQUEST NdisRequest)
    {
        NDIS_OID oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
        PVOID   informationBuffer = NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
        UINT    informationBufferLength = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
        PUINT   bytesWritten = &NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
        PUINT   bytesNeeded = &NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
        ULONG   genericULong = 0;
        USHORT  genericUShort = 0;
        UINT    moveBytes = sizeof(ULONG);
        PVOID   moveSource = (PVOID)(&genericULong);
        NDIS_MEDIUM medium = NdisMedium802_3;
        NDIS_PHYSICAL_MEDIUM  physMedium = NdisPhysicalMediumOther;
        NDIS_STATUS status = NDIS_STATUS_SUCCESS;
        NDIS_HARDWARE_STATUS hardwareStatus = NdisHardwareStatusReady;
        NDIS_STATISTICS_INFO statsInfo;
        NDIS_INTERRUPT_MODERATION_PARAMETERS interruptModeration;
    
        RETAILMSG(1, (TEXT("+DAVED: MpQueryInformation: 0x%X (%S)\r\n"), oid, GetOidString(oid)));
    
        switch (oid)
        {
            // General OIDs
        case OID_GEN_INTERRUPT_MODERATION:
            moveSource = (PVOID)(&interruptModeration);
            interruptModeration.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
            interruptModeration.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
            interruptModeration.Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
            interruptModeration.Flags = 0;
            interruptModeration.InterruptModeration = NdisInterruptModerationNotSupported;
            break;
    
        case OID_GEN_MAXIMUM_FRAME_SIZE:
            genericULong = ETH_MAX_DATA_SIZE;
            break;
        case OID_GEN_MAXIMUM_TOTAL_SIZE:
            genericULong = ETH_HEADER_SIZE + ETH_MAX_DATA_SIZE;
            break;
    
        case OID_GEN_RCV_OK:
            genericULong = 10; // TODO DM: Change that to the real statistic
            break;
    
        case OID_GEN_RECEIVE_BLOCK_SIZE:
            genericULong = ETH_BUFFER_SIZE;
            break;
    
        case OID_GEN_RECEIVE_BUFFER_SPACE:
            genericULong = ETH_BUFFER_SIZE;
            break;
    
        case OID_GEN_STATISTICS:
            moveSource = (PVOID)(&statsInfo);
            statsInfo.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
            statsInfo.Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
            statsInfo.Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
    
            statsInfo.SupportedStatistics = NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS |
                NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR |
                NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT |
                NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT |
                NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT |
                NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT |
                NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR |
                NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS |
                NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV |
                NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT |
                NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT |
                NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
    
            statsInfo.ifInDiscards = 0;
            statsInfo.ifInErrors = 0;
            statsInfo.ifHCInOctets = 0;
            statsInfo.ifHCInUcastPkts = 0;
            statsInfo.ifHCInMulticastPkts = 0;
            statsInfo.ifHCInBroadcastPkts = 0;
            statsInfo.ifHCOutOctets = 0;
            statsInfo.ifHCOutUcastPkts = 0;
            statsInfo.ifHCOutMulticastPkts = 0;
            statsInfo.ifHCOutBroadcastPkts = 0;
            statsInfo.ifOutErrors = 0;
            statsInfo.ifOutDiscards = 0;
            statsInfo.ifHCInUcastOctets = 0;
            statsInfo.ifHCInMulticastOctets = 0;
            statsInfo.ifHCInBroadcastOctets = 0;
            statsInfo.ifHCOutUcastOctets = 0;
            statsInfo.ifHCOutMulticastOctets = 0;
            statsInfo.ifHCOutBroadcastOctets = 0;
            moveBytes = sizeof(NDIS_STATISTICS_INFO);
            break;
    
        case OID_GEN_TRANSMIT_BLOCK_SIZE:
            genericULong = ETH_BUFFER_SIZE;
            break;
    
        case OID_GEN_TRANSMIT_BUFFER_SPACE:
            genericULong = ETH_BUFFER_SIZE;
            break;
    
        case OID_GEN_VENDOR_DESCRIPTION:
            if(informationBufferLength >= 34)
            {
                moveSource = (PVOID)"Eaton's Cooper Power Systems Inc.\0";
                moveBytes = strlen((char *)moveSource) + 1;
            }
            else
            {
                moveSource = (PVOID)"CPS\0";
                moveBytes = strlen((char *)moveSource) + 1;
            }
            break;
    
        case OID_GEN_VENDOR_DRIVER_VERSION:
            genericULong = (ULONG) (DD_VENDOR_MAJOR_VERSION << 16) + DD_VENDOR_MINOR_VERSION;
            break;
    
        case OID_GEN_VENDOR_ID:
            genericULong = ((DWORD)Adapter->permanentAddress[0] << 16) | ((DWORD)Adapter->permanentAddress[1] << 8) | ((DWORD)Adapter->permanentAddress[2]);
            break;
    
        case OID_GEN_XMIT_OK:
            genericULong = 10; // TODO DM: Change this for the real statistic
            break;
    
        case OID_IP4_OFFLOAD_STATS:
            status = NDIS_STATUS_NOT_SUPPORTED;
            break;
    
        //case OID_GEN_MAXIMUM_LOOKAHEAD:
        //    genericULong = DD_MAX_LOOKAHEAD;
        //    break;
        //case OID_GEN_DRIVER_VERSION:
        //    genericUShort = ((USHORT)MINIPORT_NDIS_MAJOR_VERSION << 8) | MINIPORT_NDIS_MINOR_VERSION;
        //    moveSource    = (PVOID)(&genericUShort);
        //    moveBytes     = sizeof(genericUShort);
        //    break;
    
        //case OID_GEN_HARDWARE_STATUS:
        //    moveSource     = (PVOID)(&hardwareStatus);
        //    moveBytes      = sizeof(NDIS_HARDWARE_STATUS);
        //    break;
    
        //case OID_GEN_LINK_SPEED:
        //    // This OID wants data in units of 100bps.  So divide the normal numbers by 100.  (100,000,000 is 10g)
        //    genericULong = Adapter->dwBaudRate / 100;
        //    break;
    
        //case OID_GEN_MAC_OPTIONS:
        //    genericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND
        //        | NDIS_MAC_OPTION_NO_LOOPBACK);
        //    break;
    
        //case OID_GEN_MEDIA_IN_USE:
        //case OID_GEN_MEDIA_SUPPORTED:
        //    moveSource = (PVOID)(&medium);
        //    moveBytes = sizeof(NDIS_MEDIUM);
        //    break;
    
        //case OID_GEN_PHYSICAL_MEDIUM:
        //    moveSource = (PVOID)&physMedium;
        //    moveBytes = sizeof(NDIS_PHYSICAL_MEDIUM);
        //    break;
    
        //case OID_GEN_SUPPORTED_LIST:
        //    moveSource = (PVOID)(NICSupportedOids);
        //    moveBytes  = sizeof(NICSupportedOids);
        //    break;
    
        //// Ethernet-specific OIDs
        //case OID_802_3_CURRENT_ADDRESS:
        //    moveSource = (PVOID)(Adapter->permanentAddress);
        //    moveBytes = ETH_LENGTH_OF_ADDRESS;
        //    break;
    
        //case OID_802_3_MAXIMUM_LIST_SIZE:
        //    genericULong = 1;
        //    break;
    
        //case OID_802_3_MULTICAST_LIST:
        //    status = ((informationBufferLength % ETH_LENGTH_OF_ADDRESS) != 0) ? NDIS_STATUS_INVALID_LENGTH : NDIS_STATUS_SUCCESS;
        //    break;
    
        //case OID_802_3_PERMANENT_ADDRESS:
        //    moveSource = (PVOID)(Adapter->permanentAddress);
        //    moveBytes = ETH_LENGTH_OF_ADDRESS;
        //    break;
    
        default:
            RETAILMSG(1, (TEXT(" DAVED: Query unsupported OID %#x\r\n"), oid));
            status = NDIS_STATUS_NOT_SUPPORTED;
            break;
        }
    
        if (status == NDIS_STATUS_SUCCESS) {
            if (moveBytes > informationBufferLength) {
                // Not enough room in informationBuffer.
                *bytesNeeded    = moveBytes;
                (*bytesWritten) = 0;
                status = NDIS_STATUS_INVALID_LENGTH;
    
            } else {
                NdisMoveMemory(informationBuffer, moveSource, moveBytes);
                (*bytesWritten) += moveBytes;
                *bytesNeeded     = 0;
            }
        }
    
        RETAILMSG(1, (TEXT("-DAVED: MpQueryInformation\r\n")));
    
        return status;
    }
    

    The Hardware.h file

    #include <ndis.h>
    
    typedef enum _COMMON_LINK_STATE
    {
    #ifdef NDIS60_MINIPORT
        CommonLinkStateUnknown      = -1,  // NDIS5x does not support unknown
    #endif
        CommonLinkStateDisconnected = 0,
        CommonLinkStateConnected    = 1
    } COMMON_LINK_STATE, *PCOMMON_LINK_STATE;
    
    void InitHardware(NDIS_HANDLE MiniportAdapterContext);

    The Hardware.c file

    #pragma once
    
    #include "Hardware.h"
    #include "DaveDriver.h"
    
    DWORD WINAPI RxThread(LPVOID pVArg)
    {
        PDAVEDRIVER_ADAPTER pAdapter;
    
        RETAILMSG(1, (TEXT("DD: +RxThread: Starting\r\n")));
    
        pAdapter = (PDAVEDRIVER_ADAPTER)pVArg;
    
        while(pAdapter->dwFlags & FLAGS_RUN_RXTHREAD)
        {
            Sleep(100);
        }
    
        return 0;
    }
    
    DWORD WINAPI TxThread(LPVOID pVArg)
    {
        PDAVEDRIVER_ADAPTER pAdapter;
    
        RETAILMSG(1, (TEXT("DD: +TxThread: Starting\r\n")));
    
        pAdapter = (PDAVEDRIVER_ADAPTER)pVArg;
    
        while(pAdapter->dwFlags & FLAGS_RUN_TXTHREAD)
        {
            Sleep(100);
        }
    
        return 0;
    }
    
    void IndicateLinkState(PDAVEDRIVER_ADAPTER pAdapter, COMMON_LINK_STATE LinkState)
    {
        NDIS_LINK_STATE NdisLinkState = {0};
        NDIS_STATUS_INDICATION SI = {0};
    
        // TODO DM: Spinlock here?
    
        // Fill out the NdisLinkState structure that NDIS expects
        NdisLinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
        NdisLinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1;
        NdisLinkState.Header.Size = sizeof(NDIS_LINK_STATE);
    
        switch (LinkState)
        {
        case CommonLinkStateUnknown:
            RETAILMSG(1, (TEXT(" DD: Indicating Link UNKNOWN\r\n")));
            NdisLinkState.MediaConnectState = MediaConnectStateUnknown;
            NdisLinkState.XmitLinkSpeed = NdisLinkState.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;
            NdisLinkState.MediaDuplexState = MediaDuplexStateUnknown;
            break;
    
        case CommonLinkStateDisconnected:
            RETAILMSG(1, (TEXT(" DD: Indicating Link DOWN\r\n")));
            NdisLinkState.MediaConnectState = MediaConnectStateDisconnected;
            NdisLinkState.XmitLinkSpeed = NdisLinkState.RcvLinkSpeed = NDIS_LINK_SPEED_UNKNOWN;
            NdisLinkState.MediaDuplexState = MediaDuplexStateUnknown;
            break;
    
        case CommonLinkStateConnected:
            RETAILMSG(1, (TEXT(" DD: Indicating Link UP\r\n")));
            NdisLinkState.MediaConnectState = MediaConnectStateConnected;
            NdisLinkState.XmitLinkSpeed = NdisLinkState.RcvLinkSpeed = NIC_MEDIA_MAX_SPEED;
            NdisLinkState.MediaDuplexState = MediaDuplexStateFull;
            NdisLinkState.AutoNegotiationFlags = 0;
            break;
    
        default:
            ASSERT(0);
            // fallthrough...
        }
    
        // Next, prepare the status indication structure.  Point to our LinkState structure.
        SI.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
        SI.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
        SI.Header.Size = sizeof(NDIS_STATUS_INDICATION);
        SI.SourceHandle = pAdapter->hMiniportAdapter;
        SI.StatusCode = NDIS_STATUS_LINK_STATE;
        SI.StatusBuffer = &NdisLinkState;
        SI.StatusBufferSize = sizeof(NDIS_LINK_STATE);
    
        NdisMIndicateStatusEx(pAdapter->hMiniportAdapter, &SI);
    }
    
    void InitHardware(NDIS_HANDLE MiniportAdapterContext)
    {
        NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
        DWORD dwID;
        PDAVEDRIVER_ADAPTER pAdapter = (PDAVEDRIVER_ADAPTER)MiniportAdapterContext;
    
        pAdapter->dwFlags |= FLAGS_RUN_RXTHREAD;
        pAdapter->dwFlags |= FLAGS_RUN_TXTHREAD;
    
        //
        //    Create the RxThread, if not yet created.
        //
        if (pAdapter->hRxThrd == NULL)
        {
            pAdapter->hRxThrd = CreateThread (NULL, 0, RxThread, pAdapter, 0, &dwID);
            if (pAdapter->hRxThrd == NULL)
            {
                Status = NDIS_STATUS_RESOURCES;
            }
            else
            {
                // Set the receive thread priority
                CeSetThreadPriority(pAdapter->hRxThrd, pAdapter->dwRecvThreadPrio);
            }
        }
        //
        //    Create the TxThread, if not yet created.
        //
        if (pAdapter->hTxThrd == NULL)
        {
            pAdapter->hTxThrd = CreateThread (NULL, 0, TxThread, pAdapter, 0, &dwID);
            if (pAdapter->hTxThrd == NULL)
            {
                Status = NDIS_STATUS_RESOURCES;
            }
            else
            {
                // Set the receive thread priority
                CeSetThreadPriority(pAdapter->hTxThrd, pAdapter->dwSendThreadPrio);
            }
        }
        
        IndicateLinkState(pAdapter, CommonLinkStateConnected);
    }
    

    Friday, December 13, 2013 9:57 PM
  • Hi,

    the code atleast on a quick browse looks fine to me. The reason you are getting IPv6 address assigned is maybe due to AutoConfig being enabled soon after indicating media state as connected.

    http://msdn.microsoft.com/en-us/library/ee494881(v=winembedded.70).aspx

    However if you want to just get the NDIS portions working , can you try using Iftype as CSMA-CD , the physical medium as NdisPhysicalMediumUnspecified, and the medium type as NdisMedium802_3.

    This is the configuration used for virtual ethernet miniports. Matching configurations in registry and driver source.

    Good Luck.

    Regards,

    balaji.

     

    Saturday, December 14, 2013 6:13 AM
  • Thank you again for your time and help!

    I tried your suggestion about IfType, medium type and physical medium type... without success.

    I'm going to take a real driver (with physical device) and trace it from the beginning to see if I can't find something that I'm missing.

    Meanwhile, if you have any other suggestion, I'm willing to try it! I definitely need to get this working.

    Thanks

    David

    Monday, December 16, 2013 2:16 PM
  • Oh, is it OK to use the following for BusType and BusNumber?

    [HKEY_LOCAL_MACHINE\Comm\DAVEDRIVER1\Parms]
       "BusNumber"=dword:0
       "BusType"=dword:0
       "*IfType"=dword:6
       "*MediaType"=dword:0             ; for NdisMedium802_3 0
       "*PhysicalMediaType"=dword:0    ; for NdisPhysicalMediumUnspecified 0
       "DisablePowerManagement"=dword:1

    David

    Monday, December 16, 2013 2:17 PM
  • Hi,

    Yes BusNumber BusType values seem correct.

    Regards,

    Balaji.

    Monday, December 16, 2013 3:41 PM
  • Found it !

    The SendNetBufferListsHandler handler was empty... I added the following content and it now works:

    void MpSendNetBufferLists(NDIS_HANDLE MiniportAdapterContext, PNET_BUFFER_LIST NetBufferList, NDIS_PORT_NUMBER PortNumber, ULONG SendFlags)
    {
        PDAVEDRIVER_ADAPTER pAdapter = (PDAVEDRIVER_ADAPTER)MiniportAdapterContext;
        NdisMSendNetBufferListsComplete(pAdapter->hMiniportAdapter, NetBufferList, 0);
    }

    It's not how it will work in the final version, but at least I do have an IPV4 address.

    Let's attack the receive part.

    David

    • Marked as answer by David Mercier Tuesday, January 14, 2014 9:45 PM
    Tuesday, January 14, 2014 9:45 PM