locked
Windows Embedded Compact 7 - USB NDIS Driver RRS feed

  • Question

  • Hello,

    We are developing a USB Ethernet Driver using NDIS for Windows Embedded Compact 7 (WEC7). 

    We have followed below paper, which clearly documented about WinCE USB Client Driver.

    http://www.techonline.com/electrical-engineers/education-training/tech-papers/4125897/Writing-Your-First-WinCE-USB-Device-Driver

    We've got the USB part working -- USBInstallDriver & USBDeviceAttach getting called.  Now, how to make the driver as NDIS-Driver ?.  NDIS-Driver gets loaded by ndis.dll itself, but our driver (.dll) is already loaded by USBInstallDriver and USBDeviceAttach.

    1. We tried invoking ActivateDevice from USBDeviceAttach, but getting error 1. Any reason for this ? Can't Network-Adapter's new instance be created with ActivateDevice  ? 

    2 I referred to NdisRegisterAdapter. But not sure from where should we invoke this function? USBDeviceAttach or Should Stream-Device interface functions be implemented ? Should Init function invoke NdisRegisterAdapter?

    3. What should be the Registry-Entries for this USB based NDIS Driver? I couldn't find anything in documentation.

    4. How and from where should I invoke NdisMRegisterMiniport function to Register the Miniport callback functions with NDIS ?

    Thanks in Advance


    Deepu

    Tuesday, April 30, 2013 6:50 PM

Answers

  • Hi,

    A few tidbits regarding your questions:

    "We've got the USB part working -- USBInstallDriver & USBDeviceAttach getting called.  Now, how to make the driver as NDIS-Driver ?.  NDIS-Driver gets loaded by ndis.dll itself, but our driver (.dll) is already loaded by USBInstallDriver and USBDeviceAttach." -

    -- NDIS.dll should not load your driver in cases where you have something like a bus driver or a lower edge driver that loads on device enumeration.

    I believe you should now implement DLLEntry , DriverEntry , MiniportInitialize , MiniportISr and other required miniport functions like MiniportOidRequest etc which the NDIS framework will use to establish communication. I don't think you would be  required to do activatedevice to invoke anything.

    "I referred to NdisRegisterAdapter. But not sure from where should we invoke this function? USBDeviceAttach or Should Stream-Device interface functions be implemented ? Should Init function invoke NdisRegisterAdapter?"

    -- NdisRegisterAdapter would need to be called from some place in your driver when you are done with USB device inits. If you have something like a stream driver interface implemented inside the driver XXX_Init is the place to call this from.

    "How and from where should I invoke NdisMRegisterMiniport function to Register the Miniport callback functions with NDIS ?"

    -- NdisRegisterMiniport needs to be called from DriverEntry. This is the first function to be called by NDIS upon your successful call to NdisRegisterAdapter.

    WEC7 has a good reference for implementing Miniport drivers. This link can be a good starting point:

    http://msdn.microsoft.com/en-us/library/gg157723.aspx

    Regards,

    Balaji.


    • Edited by balajitrv1 Wednesday, May 1, 2013 2:43 PM
    • Marked as answer by Deepu27 Wednesday, May 8, 2013 2:02 PM
    Wednesday, May 1, 2013 2:41 PM

  • 2. You should be able to invoke the NdisRegisterAdapter function from the USBDeviceAttach. You may have to do this in different thread context to avoid possible deadlock with USB stack. May be spin a thread from USBDeviceAttach and call NdisRegisterAdapter from that thread.

    3. You have to setup registries if you want your miniport driver to be loaded. following are few of the registries that you may need to create either from USBInstallDriver or boottime.

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER]
       "DisplayName"="MyMiniportDriver"
       "Group"="NDIS"
       "ImagePath"="MYMINIPORTDRIVER.DLL"

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER\Linkage]
       "Route"=multi_sz:"MYMINIPORTDRIVER1"

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER1]
       "DisplayName"="MYMINIPORTDRIVER"
       "Group"="NDIS"
       "ImagePath"="MYMINIPORTDRIVER.DLL"

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER1\Parms]
       "BusNumber"=dword:0
       "BusType"=dword:0
       "RebindOnResume"=dword:0

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER1\Parms\Tcpip]
        "EnableWINS"=dword:1

    Regards,

    Rakesh.

    • Marked as answer by Deepu27 Wednesday, May 8, 2013 2:02 PM
    Thursday, May 2, 2013 4:24 AM

All replies

  • Hi,

    A few tidbits regarding your questions:

    "We've got the USB part working -- USBInstallDriver & USBDeviceAttach getting called.  Now, how to make the driver as NDIS-Driver ?.  NDIS-Driver gets loaded by ndis.dll itself, but our driver (.dll) is already loaded by USBInstallDriver and USBDeviceAttach." -

    -- NDIS.dll should not load your driver in cases where you have something like a bus driver or a lower edge driver that loads on device enumeration.

    I believe you should now implement DLLEntry , DriverEntry , MiniportInitialize , MiniportISr and other required miniport functions like MiniportOidRequest etc which the NDIS framework will use to establish communication. I don't think you would be  required to do activatedevice to invoke anything.

    "I referred to NdisRegisterAdapter. But not sure from where should we invoke this function? USBDeviceAttach or Should Stream-Device interface functions be implemented ? Should Init function invoke NdisRegisterAdapter?"

    -- NdisRegisterAdapter would need to be called from some place in your driver when you are done with USB device inits. If you have something like a stream driver interface implemented inside the driver XXX_Init is the place to call this from.

    "How and from where should I invoke NdisMRegisterMiniport function to Register the Miniport callback functions with NDIS ?"

    -- NdisRegisterMiniport needs to be called from DriverEntry. This is the first function to be called by NDIS upon your successful call to NdisRegisterAdapter.

    WEC7 has a good reference for implementing Miniport drivers. This link can be a good starting point:

    http://msdn.microsoft.com/en-us/library/gg157723.aspx

    Regards,

    Balaji.


    • Edited by balajitrv1 Wednesday, May 1, 2013 2:43 PM
    • Marked as answer by Deepu27 Wednesday, May 8, 2013 2:02 PM
    Wednesday, May 1, 2013 2:41 PM

  • 2. You should be able to invoke the NdisRegisterAdapter function from the USBDeviceAttach. You may have to do this in different thread context to avoid possible deadlock with USB stack. May be spin a thread from USBDeviceAttach and call NdisRegisterAdapter from that thread.

    3. You have to setup registries if you want your miniport driver to be loaded. following are few of the registries that you may need to create either from USBInstallDriver or boottime.

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER]
       "DisplayName"="MyMiniportDriver"
       "Group"="NDIS"
       "ImagePath"="MYMINIPORTDRIVER.DLL"

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER\Linkage]
       "Route"=multi_sz:"MYMINIPORTDRIVER1"

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER1]
       "DisplayName"="MYMINIPORTDRIVER"
       "Group"="NDIS"
       "ImagePath"="MYMINIPORTDRIVER.DLL"

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER1\Parms]
       "BusNumber"=dword:0
       "BusType"=dword:0
       "RebindOnResume"=dword:0

    [HKEY_LOCAL_MACHINE\Comm\MYMINIPORTDRIVER1\Parms\Tcpip]
        "EnableWINS"=dword:1

    Regards,

    Rakesh.

    • Marked as answer by Deepu27 Wednesday, May 8, 2013 2:02 PM
    Thursday, May 2, 2013 4:24 AM
  • Hi Balaji, Rakesh

    Thanks for the useful information. 

    1. Since I don't have stream-driver interface implemented in driver, I tried calling NdisRegisterAdapter from USBDeviceAttach . But it fails with NDIS_STATUS code as 0xc0000001, which corresponds to NDIS_STATUS_FAILURE. What could be the reason for this ?

    2. As per this link (http://msdn.microsoft.com/en-us/library/ms904133.aspx), before calling the NdisRegisterAdapter, there should be few registry entries created. I've created them in .reg file, I could verify with remote-registry editor that values are intact.

    My query is what would be the BusNumber and BusType registry key values for USB based NDIS-Driver ?

    BusType can be any of the values shown in this link (http://msdn.microsoft.com/en-us/library/ee486234(v=winembedded.60).aspx).  I've used PNPBus, as that's the only value, which looked suitable for USB-NDIS Driver. 

    3. How to find the BUS numbers in target CEPC-platform?

    4. Below is my registry-entries. Can you please review and let me know, if Iam missing something here?

    [HKEY_LOCAL_MACHINE\Comm\ETHUSB]
        "DisplayName"="Ethernet USB Adapter"
        "Group"="NDIS"
        "ImagePath"="ETHUSB.dll"

    [HKEY_LOCAL_MACHINE\Comm\ETHUSB\Linkage]
        "Route"=multi_sz:"ETHUSB1"

    [HKEY_LOCAL_MACHINE\Comm\ETHUSB1]
        "DisplayName"="Ethernet USB Adapter"
        "Group"="NDIS"
        "ImagePath"="ETHUSB.dll"
        
    [HKEY_LOCAL_MACHINE\Comm\ETHUSB1\Parms]
       "BusNumber"=dword:0
       "BusType"=dword:15 

    [HKEY_LOCAL_MACHINE\Drivers\USB\ClientDrivers\ETHUSB]
    "Prefix"="EUB"
    "Dll"="ETHUSB.DLL"

    Thanks in Advance for your reply.


    Deepu



    • Edited by Deepu27 Thursday, May 2, 2013 12:08 PM
    Thursday, May 2, 2013 11:22 AM
  • Hi Deepu27,

    You can chek into these links and see if this help..

    http://blogs.msdn.com/b/mikehall/archive/2006/02/28/540912.aspx

    http://msdn.microsoft.com/en-us/library/windows/hardware/gg463293.aspx

    Thursday, May 2, 2013 12:49 PM
  • The BusNumber and Bustype should be 0. Please refer the USB8023 registry entries at,

    \WINCE700\public\common\oak\files\common.reg

    Best Regards,

    Rakesh.

    Thursday, May 2, 2013 2:16 PM
  • Hi All,

    Thanks a lot for your replies and pointers!

    Even though NdisRegisterAdapter returns failure, when I added debug-prints in DriverEntry, I found that it is getting invoked and registering MiniportDriver successfully (with NdisMRegisterMiniportDriver). Thanks Rakesh for registry-entry details and suggesting for creation of Thread from DeviceAttach to call NdisRegisterAdapter.

    Now the issue is immediately after DriverEntry returns success (NDIS_STATUS_SUCCESS), NDIS calls ndisMUnloadEx. Not sure, what could be the reason for this, even though NdisMRegisterMiniportDriver returns success. Below is code-snippet for filling and calling NdisMRegisterMiniportDriver.

    Can anyone tell what could be reason for NDIS to call UnloadEx callback immediately after DriverEntry returns success (NDIS_STATUS_SUCCESS)? 
                                                        

    NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS));
    
            //
            // Set the type and version of this structure
            //
            ndisVersion = NdisGetVersion();
    	// NDIS Version 6.0
            MChars.Header.Type      = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
            MChars.Header.Size      = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
            MChars.Header.Revision  = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
    
    	MChars.MajorNdisVersion = 6;
            MChars.MinorNdisVersion = 0;			
    
            MChars.MajorDriverVersion = 1;
            MChars.MinorDriverVersion = 0;
    
            //
            // Init/PnP handlers
            //
            MChars.InitializeHandlerEx      = MPInitialize;
            MChars.RestartHandler           = MPRestart;
            MChars.PauseHandler             = MPPause;
            MChars.ShutdownHandlerEx        = MPAdapterShutdown;
            MChars.DevicePnPEventNotifyHandler  = MPDevicePnPEvent;
            MChars.HaltHandlerEx            = MPHalt; 
            MChars.UnloadHandler            = DriverUnload;
    
            //
            // Query/Set/Method requests handlers
            //
            MChars.OidRequestHandler        = MPRequest;
            MChars.CancelOidRequestHandler  = MPCancelRequest;
    
            //
            // Set optional miniport services handler
            //
            MChars.SetOptionsHandler        = MPSetOptions;
    
            //
            // Send/Receive handlers
            //
            MChars.SendNetBufferListsHandler    = MPSendNetBufferLists;
            MChars.CancelSendHandler            = MPCancelSendNetBufferLists;
            MChars.ReturnNetBufferListsHandler  = MPReturnNetBufferLists;
    
            //
            // Fault handling handlers
            //
            MChars.CheckForHangHandlerEx        = MPCheckForHang;
            MChars.ResetHandlerEx               = MPReset;
    
            //
            // Register the miniport driver with NDIS
            //
            Status = NdisMRegisterMiniportDriver(
                        pDriverObject,
                        RegistryPath,
                        GlobalDriverContext,
                        &MChars,
                        &GlobalDriverHandle
                        );
            if (Status != NDIS_STATUS_SUCCESS)
            {
                DbgPrint("Failed to register miniport with NDIS. Status = 0x%x\n", Status);
                break;
            }
    	DbgPrint("%s: Success in registering miniport \n",__FUNCTION__);


    Deepu

    Friday, May 3, 2013 7:22 AM
  • Hi,

    Are other Miniport functions implemented?. For e.g. is MpInitialize implemented for you to call NdisMSetAttributesEx and so on..

    Regards,

    Balaji.

    Friday, May 3, 2013 9:49 AM
  • Hi Balaji, Rakesh,

    Thanks for your support on this.

    After modifying the registry entries, I could see MpInitialize is getting invoked.

    Currently MPInitialize is implemented in minimal form, just to see if it gets invoked. Only NdisMSetMiniportAttributes is invoked from MPInitialize, and returning NDIS_STATUS_SUCCESS.

    1. With this, I see a ASSERT being hit in NDIS.Dll. Do I need to do call any other NDIS functions to complete initialization ?

    ########### ****** MPInitialize MiniportAdapterHandle: ACB0DB10******* ########
    4294771501 PID:400002 TID:c30006 ==>NdisMRegisterAdapterShutdownHandler: Miniport ACB0DB10
    4294771501 PID:400002 TID:c30006 <==NdisMRegisterAdapterShutdownHandler: Miniport ACB0DB10
    4294771501 PID:400002 TID:c30006 Exception 'Access Violation' (0xe): Thread-Id=00c30006(pth=a04065f8), Proc-Id=00400002(pprc=83ae3108) 'NK.EXE', VM-active=01e1001a(pprc=a040fc9c) 'udevice.exe'
    4294771501 PID:400002 TID:c30006 PC=ef657c49(ndis.dll+0x00057c49) RA=ef6499f8(ndis.dll+0x000499f8) SP=ac62e010, BVA=000000a8

    2. Another thing is that with above registry entries, (what Rakesh has suggested) I see the driver is getting loaded by NDIS, even without connecting the device ? How to avoid this and make the driver get  loaded by USB-Stack, only when device is connected to Target ?

    Thanks



    Deepu

    Tuesday, May 7, 2013 12:27 PM
  • 1. I would recommended you implement(stub) all the required set of function and add the debug messages and see what all functions are getting invoked during/after initialization.

    2. Not sure, but can you try this. Remove the registry and create them at runtime (when ever your USB device is attaching )  from function USBDeviceAttach() and USBInstallDriver. You can remove them when USB device is detaching.

    Regards,

    Rakesh.

    Wednesday, May 8, 2013 6:11 AM
  • Thanks Rakesh for your suggestion.

    By moving the registry-entry creation to runtime in USBDeviceAttach(), it avoided the loading of driver by NDIS, when device is not connected to target machine. 

    Now Iam blocked with a USB-device initialization, which is part of MPInitialize function. 

    But anyway, I could proceed till this point, with support from you guys. 

    Thanks for your support.


    Deepu

    Wednesday, May 8, 2013 2:02 PM