Exemple #1
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT   pDriverObject,
    IN PUNICODE_STRING  pRegistryPath
    )
/*++

Routine Description:

    Called on loading. We create a device object to handle user-mode requests
    on, and register ourselves as a protocol with NDIS.

Arguments:

    pDriverObject - Pointer to driver object created by system.

    pRegistryPath - Pointer to the Unicode name of the registry path
        for this driver.

Return Value:

    NT Status code
    
--*/
{
    NDIS_PROTOCOL_CHARACTERISTICS   protocolChar;
    NTSTATUS                        status = STATUS_SUCCESS;
    NDIS_STRING                     protoName = NDIS_STRING_CONST("NdisProt");     
    UNICODE_STRING                  ntDeviceName;
    UNICODE_STRING                  win32DeviceName;
    BOOLEAN                         fSymbolicLink = FALSE;
    PDEVICE_OBJECT                  deviceObject = NULL;

    UNREFERENCED_PARAMETER(pRegistryPath);

    DEBUGP(DL_LOUD, ("DriverEntry\n"));

    Globals.pDriverObject = pDriverObject;
    NPROT_INIT_EVENT(&Globals.BindsComplete);

    do
    {

        //
        // Create our device object using which an application can
        // access NDIS devices.
        //
        RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);
#ifndef WIN9X
        status = IoCreateDeviceSecure(pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &SDDL_DEVOBJ_SYS_ALL_ADM_ALL,
                                 NULL,
                                 &deviceObject);

#elif     
        status = IoCreateDevice(pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &deviceObject);
#endif
        if (!NT_SUCCESS (status))
        {
            //
            // Either not enough memory to create a deviceobject or another
            // deviceobject with the same name exits. This could happen
            // if you install another instance of this device.
            //
            break;
        }

        RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

        status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
            break;
        }

        fSymbolicLink = TRUE;
    
        deviceObject->Flags |= DO_DIRECT_IO;
        Globals.ControlDeviceObject = deviceObject;

        NPROT_INIT_LIST_HEAD(&Globals.OpenList);
        NPROT_INIT_LOCK(&Globals.GlobalLock);

        //
        // Initialize the protocol characterstic structure
        //
    
        NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        protocolChar.MajorNdisVersion            = 5;
        protocolChar.MinorNdisVersion            = 0;
        protocolChar.Name                        = protoName;
        protocolChar.OpenAdapterCompleteHandler  = NdisProtOpenAdapterComplete;
        protocolChar.CloseAdapterCompleteHandler = NdisProtCloseAdapterComplete;
        protocolChar.SendCompleteHandler         = NdisProtSendComplete;
        protocolChar.TransferDataCompleteHandler = NdisProtTransferDataComplete;
        protocolChar.ResetCompleteHandler        = NdisProtResetComplete;
        protocolChar.RequestCompleteHandler      = NdisProtRequestComplete;
        protocolChar.ReceiveHandler              = NdisProtReceive;
        protocolChar.ReceiveCompleteHandler      = NdisProtReceiveComplete;
        protocolChar.StatusHandler               = NdisProtStatus;
        protocolChar.StatusCompleteHandler       = NdisProtStatusComplete;
        protocolChar.BindAdapterHandler          = NdisProtBindAdapter;
        protocolChar.UnbindAdapterHandler        = NdisProtUnbindAdapter;
        protocolChar.UnloadHandler               = NULL;
        protocolChar.ReceivePacketHandler        = NdisProtReceivePacket;
        protocolChar.PnPEventHandler             = NdisProtPnPEventHandler;

        //
        // Register as a protocol driver
        //
    
        NdisRegisterProtocol(
            (PNDIS_STATUS)&status,
            &Globals.NdisProtocolHandle,
            &protocolChar,
            sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

        if (status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
            status = STATUS_UNSUCCESSFUL;
            break;
        }

#ifdef NDIS51
        Globals.PartialCancelId = NdisGeneratePartialCancelId();
        Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
        DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));
#endif

        //
        // Now set only the dispatch points we would like to handle.
        //
        pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisProtOpen;
        pDriverObject->MajorFunction[IRP_MJ_CLOSE]  = NdisProtClose;
        pDriverObject->MajorFunction[IRP_MJ_READ]   = NdisProtRead;
        pDriverObject->MajorFunction[IRP_MJ_WRITE]  = NdisProtWrite;
        pDriverObject->MajorFunction[IRP_MJ_CLEANUP]  = NdisProtCleanup;
        pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = NdisProtIoControl;
        pDriverObject->DriverUnload = NdisProtUnload;

        status = STATUS_SUCCESS;
        
    }
    while (FALSE);
       

    if (!NT_SUCCESS(status))
    {
        if (deviceObject)
        {
            IoDeleteDevice(deviceObject);
            Globals.ControlDeviceObject = NULL;
        }

        if (fSymbolicLink)
        {
            IoDeleteSymbolicLink(&win32DeviceName);
        }
        
    }
    
    return status;

}
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT   DriverObject,
    IN PUNICODE_STRING  RegistryPath
    )
/*++

Routine Description:

    Called on loading. We create a device object to handle user-mode requests
    on, and register ourselves as a protocol with NDIS.

Arguments:

    pDriverObject - Pointer to driver object created by system.

    pRegistryPath - Pointer to the Unicode name of the registry path
        for this driver.

Return Value:

    NT Status code

--*/
{
    NDIS_PROTOCOL_DRIVER_CHARACTERISTICS   protocolChar;
    NTSTATUS                        status = STATUS_SUCCESS;
    NDIS_STRING                     protoName = NDIS_STRING_CONST("NDISPROT");
    WDF_DRIVER_CONFIG               config;
    WDFDRIVER                       hDriver;
    PWDFDEVICE_INIT                 pInit = NULL;

    UNREFERENCED_PARAMETER(RegistryPath);

    DEBUGP(DL_LOUD, ("DriverEntry\n"));

    Globals.DriverObject = DriverObject;
    Globals.EthType = NPROT_ETH_TYPE;
    NPROT_INIT_EVENT(&Globals.BindsComplete);

    WDF_DRIVER_CONFIG_INIT(
        &config,
        WDF_NO_EVENT_CALLBACK // This is a non-pnp driver.
    );

    //
    // Tell the framework that this is non-pnp driver so that it doesn't
    // set the default AddDevice routine.
    //
    config.DriverInitFlags |= WdfDriverInitNonPnpDriver;


    //
    // We need an unload routine to free control device created below. For
    // non-pnp drivers, framework doesn't provide Unload routine.
    //
    config.EvtDriverUnload = NdisProtEvtDriverUnload;

    //
    // Create a framework driver object to represent our driver.
    //
    status = WdfDriverCreate(DriverObject,
                            RegistryPath,
                            WDF_NO_OBJECT_ATTRIBUTES,
                            &config,
                            &hDriver);
    if (!NT_SUCCESS(status)) {
        DEBUGP(DL_ERROR, ("WdfDriverCreate failed with status 0x%x\n", status));
        return status;
    }

    //
    //
    // In order to create a control device, we first need to allocate a
    // WDFDEVICE_INIT structure and set all properties.
    //
    pInit = WdfControlDeviceInitAllocate(
                            hDriver,
                            &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R
                            );

    if (pInit == NULL) {
        status = STATUS_INSUFFICIENT_RESOURCES;
        return status;
    }

    //
    // Call NdisProtDeviceAdd to create WDFDEVICE to represent our
    // software device.
    //
    status = NdisProtCreateControlDevice(hDriver, pInit);
    if (!NT_SUCCESS(status)) {
        DEBUGP (DL_ERROR, ("NdisProtCreateControlDevice failed with status 0x%x\n", status));
        return status;
    }

    //
    // Initialize the protocol characterstic structure
    //

    NdisZeroMemory(&protocolChar,sizeof(NDIS_PROTOCOL_DRIVER_CHARACTERISTICS));


    protocolChar.Header.Type                = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
    protocolChar.Header.Size                = sizeof(NDIS_PROTOCOL_DRIVER_CHARACTERISTICS);
    protocolChar.Header.Revision            = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;

    protocolChar.MajorNdisVersion            = 6;
    protocolChar.MinorNdisVersion            = 0;
    protocolChar.Name                        = protoName;
    protocolChar.SetOptionsHandler           = NULL;
    protocolChar.OpenAdapterCompleteHandlerEx  = NdisprotOpenAdapterComplete;
    protocolChar.CloseAdapterCompleteHandlerEx = NdisprotCloseAdapterComplete;
    protocolChar.SendNetBufferListsCompleteHandler = NdisprotSendComplete;
    protocolChar.OidRequestCompleteHandler   = NdisprotRequestComplete;
    protocolChar.StatusHandlerEx             = NdisprotStatus;
    protocolChar.UninstallHandler            = NULL;
    protocolChar.ReceiveNetBufferListsHandler = NdisprotReceiveNetBufferLists;
    protocolChar.NetPnPEventHandler          = NdisprotPnPEventHandler;
    protocolChar.BindAdapterHandlerEx        = NdisprotBindAdapter;
    protocolChar.UnbindAdapterHandlerEx      = NdisprotUnbindAdapter;

    //
    // Register as a protocol driver
    //

    status = NdisRegisterProtocolDriver(NULL,           // driver context
                                        &protocolChar,
                                        &Globals.NdisProtocolHandle);

    if (status != NDIS_STATUS_SUCCESS)
    {
        DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
        return STATUS_UNSUCCESSFUL;
    }

    NPROT_INIT_LIST_HEAD(&Globals.OpenList);
    NPROT_INIT_LOCK(&Globals.GlobalLock);

    Globals.PartialCancelId = NdisGeneratePartialCancelId();
    Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
    DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));

    return status;

}
Exemple #3
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT   pDriverObject,
    IN PUNICODE_STRING  pRegistryPath
    )
/*++

Routine Description:

    Called on loading. We create a device object to handle user-mode requests
    on, and register ourselves as a protocol with NDIS.

Arguments:

    pDriverObject - Pointer to driver object created by system.

    pRegistryPath - Pointer to the Unicode name of the registry path
        for this driver.

Return Value:

    NT Status code
    
--*/
{
    NDIS_PROTOCOL_DRIVER_CHARACTERISTICS   protocolChar = {0};
    NTSTATUS                        status = STATUS_SUCCESS;
    NDIS_STRING                     protoName = NDIS_STRING_CONST("NDISPROT");     
    UNICODE_STRING                  ntDeviceName;
    UNICODE_STRING                  win32DeviceName;
    BOOLEAN                         fSymbolicLink = FALSE;
    PDEVICE_OBJECT                  deviceObject = NULL;
    NDIS_HANDLE  ProtocolDriverContext={0};

    UNREFERENCED_PARAMETER(pRegistryPath);
	
    DEBUGP(DL_LOUD, ("DriverEntry\n"));

    Globals.pDriverObject = pDriverObject;
    Globals.EthType = NPROT_ETH_TYPE;
    NPROT_INIT_EVENT(&Globals.BindsComplete);

    do
    {
        //
        // Create our device object using which an application can
        // access NDIS devices.
        //
        RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);

        status = IoCreateDevice (pDriverObject,
                                 0,
                                 &ntDeviceName,
                                 FILE_DEVICE_NETWORK,
                                 FILE_DEVICE_SECURE_OPEN,
                                 FALSE,
                                 &deviceObject);
    
        if (!NT_SUCCESS (status))
        {
            //
            // Either not enough memory to create a deviceobject or another
            // deviceobject with the same name exits. This could happen
            // if you install another instance of this device.
            //
            break;
        }

        RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

        status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);

        if (!NT_SUCCESS(status))
        {
            break;
        }

        fSymbolicLink = TRUE;
    
        deviceObject->Flags |= DO_DIRECT_IO;
        Globals.ControlDeviceObject = deviceObject;

        NPROT_INIT_LIST_HEAD(&Globals.OpenList);
        NPROT_INIT_LOCK(&Globals.GlobalLock);

        //
        // Initialize the protocol characterstic structure
        //     
#if (NDIS_SUPPORT_NDIS630)
        {C_ASSERT(sizeof(protocolChar) >= NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2);}
        protocolChar.Header.Type        = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
        protocolChar.Header.Size        = NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2;
        protocolChar.Header.Revision    = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_2;
#elif (NDIS_SUPPORT_NDIS6)
        {C_ASSERT(sizeof(protocolChar) >= NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1);}
        protocolChar.Header.Type        = NDIS_OBJECT_TYPE_PROTOCOL_DRIVER_CHARACTERISTICS,
        protocolChar.Header.Size        = NDIS_SIZEOF_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
        protocolChar.Header.Revision    = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
#endif // NDIS MINIPORT VERSION

        protocolChar.MajorNdisVersion            = NDIS_PROT_MAJOR_VERSION;
        protocolChar.MinorNdisVersion            = NDIS_PROT_MINOR_VERSION;
        protocolChar.MajorDriverVersion          = MAJOR_DRIVER_VERSION;
        protocolChar.MinorDriverVersion          = MINOR_DRIVER_VERISON;
        protocolChar.Name                        = protoName;
        protocolChar.SetOptionsHandler           = NULL;
        protocolChar.OpenAdapterCompleteHandlerEx  = NdisprotOpenAdapterComplete;
        protocolChar.CloseAdapterCompleteHandlerEx = NdisprotCloseAdapterComplete;
        protocolChar.SendNetBufferListsCompleteHandler = NdisprotSendComplete;
        protocolChar.OidRequestCompleteHandler   = NdisprotRequestComplete;
        protocolChar.StatusHandlerEx             = NdisprotStatus;
        protocolChar.UninstallHandler            = NULL;
        protocolChar.ReceiveNetBufferListsHandler = NdisprotReceiveNetBufferLists;
        protocolChar.NetPnPEventHandler          = NdisprotPnPEventHandler;
        protocolChar.BindAdapterHandlerEx        = NdisprotBindAdapter;
        protocolChar.UnbindAdapterHandlerEx      = NdisprotUnbindAdapter;

        //
        // Register as a protocol driver
        //
    
        status = NdisRegisterProtocolDriver(ProtocolDriverContext,           // driver context
                                            &protocolChar,
                                            &Globals.NdisProtocolHandle);

        if (status != NDIS_STATUS_SUCCESS)
        {
            DEBUGP(DL_WARN, ("Failed to register protocol with NDIS\n"));
            status = STATUS_UNSUCCESSFUL;
            break;
        }

        Globals.PartialCancelId = NdisGeneratePartialCancelId();
        Globals.PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
        DEBUGP(DL_LOUD, ("DriverEntry: CancelId %lx\n", Globals.PartialCancelId));

        //
        // Now set only the dispatch points we would like to handle.
        //

        pDriverObject->MajorFunction[IRP_MJ_CREATE] = NdisprotOpen;

        pDriverObject->MajorFunction[IRP_MJ_CLOSE]  = NdisprotClose;

        pDriverObject->MajorFunction[IRP_MJ_READ]   = NdisprotRead;

        pDriverObject->MajorFunction[IRP_MJ_WRITE]  = NdisprotWrite;

        pDriverObject->MajorFunction[IRP_MJ_CLEANUP]  = NdisprotCleanup;

        pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = NdisprotIoControl;
        

        pDriverObject->DriverUnload = NdisprotUnload;

        status = STATUS_SUCCESS;

        
    }
    while (FALSE);
       

    if (!NT_SUCCESS(status))
    {
        if (deviceObject)
        {
            KeEnterCriticalRegion();
            #pragma prefast(suppress:28107, "The deviceObject is held within the critical section")
            IoDeleteDevice(deviceObject);
            KeLeaveCriticalRegion();
            Globals.ControlDeviceObject = NULL;
        }

        if (fSymbolicLink)
        {
            IoDeleteSymbolicLink(&win32DeviceName);
            fSymbolicLink = FALSE;
        }
        
        if (Globals.NdisProtocolHandle)
        {
            NdisDeregisterProtocolDriver(Globals.NdisProtocolHandle);
            Globals.NdisProtocolHandle = NULL;
        }        
    }
    
    return status;
}
NTSTATUS
DriverEntry(
	IN	PDRIVER_OBJECT		DriverObject,
	IN	PUNICODE_STRING		RegistryPath
	)
/*++

Routine Description:

	First entry point to be called, when this driver is loaded.
	Register with NDIS as an intermediate driver.

Arguments:

	DriverObject - pointer to the system's driver object structure
		for this driver
	
	RegistryPath - system's registry path for this driver
	
Return Value:

	STATUS_SUCCESS if all initialization is successful, STATUS_XXX
	error code if not.

--*/
{
	NDIS_STATUS						Status;
	NDIS_PROTOCOL_CHARACTERISTICS	PChars;
	NDIS_MINIPORT_CHARACTERISTICS	MChars;
	PNDIS_CONFIGURATION_PARAMETER	Param;
	NDIS_STRING						Name;

	Status = NDIS_STATUS_SUCCESS;
	NdisAllocateSpinLock(&GlobalLock);

	//初始化自定义变量
	NdisAllocateSpinLock(&PacketListLock);
	InitializeListHead(&PacketList);

	NdisAllocateSpinLock(&ReadIrpLock);
	ReadIrp = NULL;
	ReadCount=0;
	PacketCount=0;
	RecvBufferPool=NULL;
	SendBufferPool=NULL;

	PendedSendCount=0;
    NdisAllocateSpinLock(&WriteIrpLock);
    InitializeListHead(&PendedWritesList);

#ifdef NDIS51
	PartialCancelId = NdisGeneratePartialCancelId();
    PartialCancelId <<= ((sizeof(PVOID) - 1) * 8);
#endif

	pAdaptTotal=NULL;
//	TotalMacBuffer=NULL;
	CurrentNum=0;

    NdisAllocateBufferPool(
            &Status,
            &RecvBufferPool,
            MAX_RECV_PACKET_POOL_SIZE);
	NdisAllocateBufferPool(
            &Status,
            &SendBufferPool,
            MAX_SEND_PACKET_POOL_SIZE);

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

	do
	{
		//
		// 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 = PASSTHRU_MAJOR_NDIS_VERSION;
		MChars.MinorNdisVersion = PASSTHRU_MINOR_NDIS_VERSION;

		MChars.InitializeHandler = MPInitialize;
		MChars.QueryInformationHandler = MPQueryInformation;
		MChars.SetInformationHandler = MPSetInformation;
		MChars.ResetHandler = MPReset;
		MChars.TransferDataHandler = MPTransferData;
		MChars.HaltHandler = MPHalt;
#ifdef NDIS51_MINIPORT
		MChars.CancelSendPacketsHandler = MPCancelSendPackets;
		MChars.PnPEventNotifyHandler = MPDevicePnPEvent;
		MChars.AdapterShutdownHandler = MPAdapterShutdown;
#endif // NDIS51_MINIPORT

		//
		// 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(NdisWrapperHandle,
   											   &MChars,
   											   sizeof(MChars),
										   	   &DriverHandle);
		if (Status != NDIS_STATUS_SUCCESS)
		{
			break;
		}

#ifndef WIN9X
		NdisMRegisterUnloadHandler(NdisWrapperHandle, PtUnload);
#endif

		//
		// Now register the protocol.
		//
		NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
		PChars.MajorNdisVersion = PASSTHRU_PROT_MAJOR_NDIS_VERSION;
		PChars.MinorNdisVersion = PASSTHRU_PROT_MINOR_NDIS_VERSION;

		//
		// 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.
		//
		NdisInitUnicodeString(&Name, L"Passthru");	// Protocol name
		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,
 							&ProtHandle,
 							&PChars,
 							sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

		if (Status != NDIS_STATUS_SUCCESS)
		{
			NdisIMDeregisterLayeredMiniport(DriverHandle);
			break;
		}

		NdisIMAssociateMiniport(DriverHandle, ProtHandle);
	}
	while (FALSE);

	if (Status != NDIS_STATUS_SUCCESS)
	{
		NdisTerminateWrapper(NdisWrapperHandle, NULL);
	}

	return(Status);
}