none
why my ndis driver can't work on windows x64 RRS feed

  • Question

  • I designed a ndis driver, it works fine on windows xp, windows 2003 x86

    when I run it on windows 2003 x64, it can't work any more.

    the windows 2003 x64 don't call the protocal callback function

    I set break point in the protocal callback function like PtBindAdapter, no one called

    please help me!

    Thanks a lot.

    The following is part of my ndis driver code:

    NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
    {
     NDIS_STRING                        Name;
     NDIS_STATUS    status = STATUS_SUCCESS;
     NDIS_PROTOCOL_CHARACTERISTICS      PChars;
     NDIS_MINIPORT_CHARACTERISTICS      MChars;
     
     KdPrint(("SCP_NDIS: DriverEntry\n"));

      ....

     NdisAllocateSpinLock(&g_GlobalLock);

     NdisMInitializeWrapper(&g_NdisWrapperHandle, DriverObject, RegistryPath, NULL);

     do
     {
      status = RegistryMiniport();
      if (!NT_SUCCESS(status)) {
       SCP_PRINT("SCPNDIS: Failed to register miniport with NDIS; status: %08X\n", status);
       break;
      }

      status = RegistryProtocol();
      if (!NT_SUCCESS(status)) {
       SCP_PRINT("SCPNDIS: Failed to register protocol with NDIS; status: %08X\n", status);
       break;
      }

      NdisIMAssociateMiniport(g_DriverHandle, g_ProtHandle);

      Ndis_RegisterDevice();

     } while (FALSE);

    ...
     

     if (status != NDIS_STATUS_SUCCESS) {
      NdisTerminateWrapper(g_NdisWrapperHandle, NULL);
     }

     return status;
    }


    NDIS_STATUS RegistryMiniport()
    {
     NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
     NDIS_MINIPORT_CHARACTERISTICS      MChars;

     // Register the miniport with NDIS. Note that it is the miniport which was started as a driver and not the protocol. Also the miniport
     // must be registered prior to the protocol since the protocol's BindAdapter handler can be initiated anytime and when it is,
     // it must be ready to start driver instances.

     NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));

     MChars.MajorNdisVersion = 5;
     MChars.MinorNdisVersion = 1;

     MChars.InitializeHandler  = MPInitialize;
     MChars.QueryInformationHandler = MPQueryInformation;
     MChars.SetInformationHandler = MPSetInformation;
     MChars.ResetHandler    = NULL;
     MChars.TransferDataHandler  = MPTransferData;
     MChars.HaltHandler    = MPHalt;
     MChars.CancelSendPacketsHandler = MPCancelSendPackets;
     MChars.PnPEventNotifyHandler = MPDevicePnPEvent;
     MChars.AdapterShutdownHandler = MPAdapterShutdown;

     // We will disable the check for hang timeout so we do not need a check for hang handler!
     MChars.CheckForHangHandler  = NULL;
     MChars.ReturnPacketHandler  = MPReturnPacket;

     // Either the Send or the SendPackets handler should be specified. If SendPackets handler is specified, SendHandler is ignored
     MChars.SendHandler    = NULL;    // MPSend;
     MChars.SendPacketsHandler  = MPSendPackets;

     Status = NdisIMRegisterLayeredMiniport(g_NdisWrapperHandle, &MChars, sizeof(MChars), &g_DriverHandle);

     return Status;
    }


    NDIS_STATUS RegistryProtocol()
    {
     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
     NDIS_PROTOCOL_CHARACTERISTICS PChars;
     NDIS_STRING Name = SCP_NDIS_BIND_NAME;

     NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
     PChars.MajorNdisVersion = 5;
     PChars.MinorNdisVersion = 1;

     // Make sure the protocol-name matches the service-name (from the INF) under which this protocol is installed.
     // This is needed to ensure that NDIS can correctly determine the binding and call us to bind to miniports below.
     PChars.Name = Name;
     PChars.OpenAdapterCompleteHandler = PtOpenAdapterComplete;
     PChars.CloseAdapterCompleteHandler = PtCloseAdapterComplete;
     PChars.SendCompleteHandler   = PtSendComplete;
     PChars.TransferDataCompleteHandler = PtTransferDataComplete;

     PChars.ResetCompleteHandler   = PtResetComplete;
     PChars.RequestCompleteHandler  = PtRequestComplete;
     PChars.ReceiveHandler    = PtReceive;
     PChars.ReceiveCompleteHandler  = PtReceiveComplete;
     PChars.StatusHandler    = PtStatus;
     PChars.StatusCompleteHandler  = PtStatusComplete;
     PChars.BindAdapterHandler   = PtBindAdapter;
     PChars.UnbindAdapterHandler   = PtUnbindAdapter;
     PChars.UnloadHandler    = PtUnloadProtocol;

     PChars.ReceivePacketHandler   = PtReceivePacket;
     PChars.PnPEventHandler    = PtPNPHandler;

     NdisRegisterProtocol(&Status, &g_ProtHandle, &PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

     return Status;
    }

    NDIS_STATUS Ndis_RegisterDevice()
    {
        NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
        UNICODE_STRING         DeviceName;
        UNICODE_STRING         DeviceLinkUnicodeString;
        PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];

        SCP_DEBUG(__FUNCTION__);

        NdisAcquireSpinLock(&g_GlobalLock);

        ++MiniportCount;
       
        if (1 == MiniportCount) {
            ASSERT(ControlDeviceState != PS_DEVICE_STATE_CREATING);

            // Another thread could be running PtDeregisterDevice on behalf of another miniport instance. If so, wait for it to exit.
            while (ControlDeviceState != PS_DEVICE_STATE_READY)
            {
                NdisReleaseSpinLock(&g_GlobalLock);
                NdisMSleep(1);
                NdisAcquireSpinLock(&g_GlobalLock);
            }

            ControlDeviceState = PS_DEVICE_STATE_CREATING;

            NdisReleaseSpinLock(&g_GlobalLock);

            NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));

            DispatchTable[IRP_MJ_CREATE]   = Ndis_DefaultDispatch;
            DispatchTable[IRP_MJ_CLEANUP]   = Ndis_DefaultDispatch;
            DispatchTable[IRP_MJ_CLOSE]    = Ndis_DefaultDispatch;
      DispatchTable[IRP_MJ_SHUTDOWN]   = Ndis_DefaultDispatch;
            DispatchTable[IRP_MJ_DEVICE_CONTROL] = Ndis_IoCtlDispatch;

            NdisInitUnicodeString(&DeviceName, SCPNDIS_DEVICE_NAME_W);
            NdisInitUnicodeString(&DeviceLinkUnicodeString, SCPNDIS_DOS_DEVICE_NAME_W);

            // Create a device object and register our dispatch handlers
            Status = NdisMRegisterDevice(g_NdisWrapperHandle, &DeviceName, &DeviceLinkUnicodeString, &DispatchTable[0], &ControlDeviceObject, &NdisDeviceHandle);

            NdisAcquireSpinLock(&g_GlobalLock);

            ControlDeviceState = PS_DEVICE_STATE_READY;
        }

        NdisReleaseSpinLock(&g_GlobalLock);

        return Status;
    }

    Tuesday, August 25, 2015 1:55 PM

All replies

  • did you verify that the driver successfully loaded and DriverEntry executed?

    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Tuesday, August 25, 2015 4:29 PM
  • Yes, it loaded successfully, I debuged the driver entry, all the functions run successfully

    about the minor version, I change it as 0, it also don't call the callback function.

    PChars.MajorNdisVersion = 5;
     PChars.MinorNdisVersion = 0;

    Tuesday, August 25, 2015 11:31 PM
  • Post both of your INF files

     -Brian


    Azius Developer Training www.azius.com Windows device driver, internals, security, & forensics training and consulting. Blog at www.azius.com/blog

    Wednesday, August 26, 2015 1:39 AM
    Moderator