Example #1
0
NDIS_STATUS NICRegisterDevice(VOID)
{
    NDIS_STATUS         Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING      DeviceName;
    UNICODE_STRING      DeviceLinkUnicodeString;
    PDRIVER_DISPATCH    DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
    PAGED_CODE();
    DEBUGP(MP_TRACE, ("[HT_STARTUP]-->NICRegisterDevice\n"));
    NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));

    DispatchTable[IRP_MJ_CREATE]            = NICDispatch;
    DispatchTable[IRP_MJ_CLEANUP]           = NICDispatch;
    DispatchTable[IRP_MJ_CLOSE]             = NICDispatch;
    DispatchTable[IRP_MJ_DEVICE_CONTROL]    = NICDispatch;
    
    NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
    NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);

    Status = NdisMRegisterDevice(
                NdisWrapperHandle, 
                &DeviceName,
                &DeviceLinkUnicodeString,
                &DispatchTable[0],
                &g_ControlDeviceObject,
                &g_NdisDeviceHandle
            );

    DEBUGP(MP_TRACE, ("[HT_STARTUP]<--NICRegisterDevice: %x\n", Status));
    return Status;
}
Example #2
0
NDIS_STATUS 
DriverEntry(
    IN  PDRIVER_OBJECT      DriverObject,
    IN  PUNICODE_STRING     RegistryPath )
{
    NDIS_FILTER_DRIVER_CHARACTERISTICS  FilterCharacteristics;
    NDIS_STATUS NdisStatus;

    DPF(("%s!%s DriverObject=%p RegistryPath=%wZ\n", __MODULE__, __FUNCTION__, 
        DriverObject, RegistryPath )); 

    DriverObject->DriverUnload = DriverUnload;

    GlobalNDISLWF.FilterDriverHandle = NULL;

    // Setup the FilterCharacteristics structure
    // Handlers implemented by the driver are :
    // AttachHandler, DetachHandler, RestartHandler, PauseHandler, StatusHandler
    // ReceiveNetBufferListsHandler, ReturnNetBufferListsHandler
    NdisZeroMemory(&FilterCharacteristics, sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS));

    FilterCharacteristics.Header.Type = NDIS_OBJECT_TYPE_FILTER_DRIVER_CHARACTERISTICS;
    FilterCharacteristics.Header.Size = sizeof(NDIS_FILTER_DRIVER_CHARACTERISTICS);
    FilterCharacteristics.Header.Revision = NDIS_FILTER_CHARACTERISTICS_REVISION_1;
    FilterCharacteristics.MajorNdisVersion = NDISLWF_NDIS_MAJOR_VERSION;
    FilterCharacteristics.MinorNdisVersion = NDISLWF_NDIS_MINOR_VERSION;
    FilterCharacteristics.MajorDriverVersion = NDISLWF_DRIVER_MAJOR_VERSION;
    FilterCharacteristics.MinorDriverVersion = NDISLWF_DRIVER_MINOR_VERSION;
    FilterCharacteristics.Flags = 0;
    NdisInitUnicodeString ( &FilterCharacteristics.FriendlyName, NDISLWF_FRIENDLY_NAME );
    NdisInitUnicodeString ( &FilterCharacteristics.UniqueName, NDISLWF_UNIQUE_NAME);
    NdisInitUnicodeString ( &FilterCharacteristics.ServiceName, NDISLWF_SERVICE_NAME);
    FilterCharacteristics.AttachHandler = NDISLWF_AttachHandler;
    FilterCharacteristics.DetachHandler = NDISLWF_DetachHandler;
    FilterCharacteristics.RestartHandler = NDISLWF_RestartHandler;
    FilterCharacteristics.PauseHandler = NDISLWF_PauseHandler;
    FilterCharacteristics.StatusHandler = NDISLWF_StatusHandler;
    FilterCharacteristics.ReceiveNetBufferListsHandler = NDISLWF_ReceiveNetBufferListsHandler;
    FilterCharacteristics.ReturnNetBufferListsHandler = NDISLWF_ReturnNetBufferListsHandler;

    // Register the filter driver using the FilterCharacteristics structure
    // NdisFRegisterFilterDriver())
    NdisStatus = NdisFRegisterFilterDriver(
        DriverObject,
        (NDIS_HANDLE)DriverObject, // no driver-wide context
        &FilterCharacteristics, 
        &GlobalNDISLWF.FilterDriverHandle);

    if (NdisStatus != NDIS_STATUS_SUCCESS) {
        DPF(("%s!%s NdisFRegisterFilterDriver() FAIL=%08x\n", __MODULE__, __FUNCTION__, NdisStatus));
        goto Exit1;
    }

    DPF(("%s!%s NdisFRegisterFilterDriver() FilterDriverHandle=%p\n", __MODULE__, __FUNCTION__, 
        GlobalNDISLWF.FilterDriverHandle )); 

Exit1 :
    return NdisStatus;
}
Example #3
0
/*
 * --------------------------------------------------------------------------
 * Creates the communication device between user and kernel, and also
 * initializes the data associated data structures.
 * --------------------------------------------------------------------------
 */
NDIS_STATUS
OvsCreateDeviceObject(NDIS_HANDLE ovsExtDriverHandle)
{
    NDIS_STATUS status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING deviceName;
    UNICODE_STRING symbolicDeviceName;
    PDRIVER_DISPATCH dispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
    NDIS_DEVICE_OBJECT_ATTRIBUTES deviceAttributes;
    OVS_LOG_TRACE("ovsExtDriverHandle: %p", ovsExtDriverHandle);

    RtlZeroMemory(dispatchTable,
                  (IRP_MJ_MAXIMUM_FUNCTION + 1) * sizeof (PDRIVER_DISPATCH));
    dispatchTable[IRP_MJ_CREATE] = OvsOpenCloseDevice;
    dispatchTable[IRP_MJ_CLOSE] = OvsOpenCloseDevice;
    dispatchTable[IRP_MJ_CLEANUP] = OvsCleanupDevice;
    dispatchTable[IRP_MJ_DEVICE_CONTROL] = OvsDeviceControl;

    NdisInitUnicodeString(&deviceName, OVS_DEVICE_NAME_NT);
    NdisInitUnicodeString(&symbolicDeviceName, OVS_DEVICE_NAME_DOS);

    RtlZeroMemory(&deviceAttributes, sizeof (NDIS_DEVICE_OBJECT_ATTRIBUTES));

    OVS_INIT_OBJECT_HEADER(&deviceAttributes.Header,
                           NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES,
                           NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1,
                           sizeof (NDIS_DEVICE_OBJECT_ATTRIBUTES));

    deviceAttributes.DeviceName = &deviceName;
    deviceAttributes.SymbolicName = &symbolicDeviceName;
    deviceAttributes.MajorFunctions = dispatchTable;
    deviceAttributes.ExtensionSize = sizeof (OVS_DEVICE_EXTENSION);

    status = NdisRegisterDeviceEx(ovsExtDriverHandle,
                                  &deviceAttributes,
                                  &gOvsDeviceObject,
                                  &gOvsDeviceHandle);
    if (status != NDIS_STATUS_SUCCESS) {
        POVS_DEVICE_EXTENSION ovsExt =
            (POVS_DEVICE_EXTENSION)NdisGetDeviceReservedExtension(gOvsDeviceObject);
        ASSERT(gOvsDeviceObject != NULL);
        ASSERT(gOvsDeviceHandle != NULL);

        if (ovsExt) {
            ovsExt->numberOpenInstance = 0;
        }
    } else {
        /* Initialize the associated data structures. */
        OvsInit();
    }
    OVS_LOG_TRACE("DeviceObject: %p", gOvsDeviceObject);
    return status;
}
//------------------------------------------------------------------------------
static void registerDrvIntf(NDIS_HANDLE driverHandle_p)
{
    NDIS_STATUS                     status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING                  deviceName;
    UNICODE_STRING                  deviceLinkUnicodeString;
    NDIS_DEVICE_OBJECT_ATTRIBUTES   deviceObjectAttributes;
    PDRIVER_DISPATCH                dispatchTable[IRP_MJ_MAXIMUM_FUNCTION + 1];

    DEBUG_LVL_ALWAYS_TRACE("PLK %s()...\n", __func__);

    plkDriverInstance_l.driverHandle = driverHandle_p;

    NdisZeroMemory(dispatchTable, (IRP_MJ_MAXIMUM_FUNCTION + 1) * sizeof(PDRIVER_DISPATCH));
    dispatchTable[IRP_MJ_CREATE] = powerlinkCreate;
    dispatchTable[IRP_MJ_CLEANUP] = powerlinkCleanup;
    dispatchTable[IRP_MJ_CLOSE] = powerlinkClose;
    dispatchTable[IRP_MJ_DEVICE_CONTROL] = powerlinkIoctl;

    NdisInitUnicodeString(&deviceName, PLK_DEV_STRING);
    NdisInitUnicodeString(&deviceLinkUnicodeString, PLK_LINK_NAME);

    NdisZeroMemory(&deviceObjectAttributes, sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES));
    // type implicit from the context
    deviceObjectAttributes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    deviceObjectAttributes.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
    deviceObjectAttributes.Header.Size = sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES);
    deviceObjectAttributes.DeviceName = &deviceName;
    deviceObjectAttributes.SymbolicName = &deviceLinkUnicodeString;
    deviceObjectAttributes.MajorFunctions = &dispatchTable[0];
    deviceObjectAttributes.ExtensionSize = 0;
    deviceObjectAttributes.DefaultSDDLString = NULL;
    deviceObjectAttributes.DeviceClassGuid = 0;

    status = NdisRegisterDeviceEx(driverHandle_p,
                                  &deviceObjectAttributes,
                                  &plkDriverInstance_l.pDrvDeviceObject,
                                  &plkDriverInstance_l.pDrvDeviceHandle);

    if (status != NDIS_STATUS_SUCCESS)
    {
        DEBUG_LVL_ERROR_TRACE("%s() Failed to register interface device (0x%X)\n", status);
        return;
    }

    plkDriverInstance_l.pDrvDeviceObject->Flags |= DO_BUFFERED_IO;

    DEBUG_LVL_ALWAYS_TRACE("PLK %s() - OK\n", __func__);
}
void ParaNdis_DebugInitialize(PVOID DriverObject,PVOID RegistryPath)
{
	NDIS_STRING usRegister, usDeregister, usPrint;
	PVOID pr, pd;
	BOOLEAN res;
	WPP_INIT_TRACING(DriverObject, RegistryPath);

	NdisAllocateSpinLock(&CrashLock);
	KeInitializeCallbackRecord(&CallbackRecord);
	ParaNdis_PrepareBugCheckData();
	NdisInitUnicodeString(&usPrint, L"vDbgPrintEx");
	NdisInitUnicodeString(&usRegister, L"KeRegisterBugCheckReasonCallback");
	NdisInitUnicodeString(&usDeregister, L"KeDeregisterBugCheckReasonCallback");
	pd = MmGetSystemRoutineAddress(&usPrint);
	if (pd) PrintProcedure = (vDbgPrintExType)pd;
	pr = MmGetSystemRoutineAddress(&usRegister);
	pd = MmGetSystemRoutineAddress(&usDeregister);
	if (pr && pd)
	{
		BugCheckRegisterCallback = (KeRegisterBugCheckReasonCallbackType)pr;
		BugCheckDeregisterCallback = (KeDeregisterBugCheckReasonCallbackType)pd;
	}
	res = BugCheckRegisterCallback(&CallbackRecord, ParaNdis_OnBugCheck, KbCallbackSecondaryDumpData, "NetKvm");
	DPrintf(0, ("[%s] Crash callback %sregistered", __FUNCTION__, res ? "" : "NOT "));

#ifdef OVERRIDE_DEBUG_BREAK
	if (sizeof(PVOID) == sizeof(ULONG))
	{
		UCHAR replace[5] = {0xe9,0,0,0,0};
		ULONG replacement;
		NDIS_STRING usDbgBreakPointName;
		NdisInitUnicodeString(&usDbgBreakPointName, L"DbgBreakPoint");
		pDbgBreakPoint = (PUCHAR)MmGetSystemRoutineAddress(&usDbgBreakPointName);
		if (pDbgBreakPoint)
		{
			DPrintf(0, ("Replacing original BP handler at %p", pDbgBreakPoint));
			replacement = RtlPointerToOffset(pDbgBreakPoint + 5, AnotherDbgBreak);
			RtlCopyMemory(replace + 1, &replacement, sizeof(replacement));
			RtlCopyMemory(DbgBreakPointChunk, pDbgBreakPoint, sizeof(DbgBreakPointChunk));
			RtlCopyMemory(pDbgBreakPoint, replace, sizeof(replace));
		}
	}
#endif
}
/* ssh_virtual_adapter_device_add_ref()
 *
 * Increments the reference count of underlying virtual NIC's device object
 * thus ensuring that the virtual NIC can't be unloaded from memory.
 *
 * This function must be run on IRQL PASSIVE_LEVEL.
 *
 */
static Boolean
ssh_virtual_adapter_device_add_ref(SshVirtualAdapter va)
{
  Boolean status = TRUE;
#ifndef _WIN32_WCE
  PDEVICE_OBJECT device_object = NULL;
  UNICODE_STRING device_name;
#endif /* _WIN32_WCE */

  SSH_DEBUG(SSH_D_MIDSTART, ("ssh_virtual_adapter_device_add_ref()"));

  SSH_ASSERT(va != NULL);
  SSH_ASSERT(va->adapter != NULL);
  SSH_ASSERT(va->file_object == NULL);

#ifndef _WIN32_WCE
  SSH_ASSERT(SSH_GET_IRQL() == SSH_PASSIVE_LEVEL);

  NdisInitUnicodeString(&device_name, NULL);

  if (ssh_adapter_device_object_name_get(va->adapter, &device_name))
    {
      SSH_ASSERT(device_name.Buffer != NULL);
      SSH_ASSERT(device_name.Length > 0);

      if (!NT_SUCCESS(IoGetDeviceObjectPointer(
				       &device_name, FILE_ALL_ACCESS,
				       (PFILE_OBJECT *)&va->file_object,
				       &device_object)))
        {
          SSH_DEBUG(SSH_D_FAIL, ("IoGetDeviceObjectPointer() FAILED!"));

          status = FALSE;
        }

      ssh_free(device_name.Buffer);
    }
  else
    {
      SSH_DEBUG(SSH_D_FAIL, ("ssh_device_object_name_get() FAILED!"));
      status = FALSE;
    }

#else /* not _WIN32_WCE */

  /* Just initialize with a bogus value... */
  va->file_object = (void *)0x00BEEF00;

#endif /* not _WIN32_WCE */

  return (status);
}
Example #7
0
NDIS_HANDLE RegisterFakeNDISProtocol ()
/*++

Routine Description:

	Registers a fake NDIS routines.


Arguments:

	None.


Return Value:

	Handle to the fake NDIS protocol if successful, otherwise returns NULL.


Author:

	xiaonie

	2012/07/12


--*/
{
	NTSTATUS status = STATUS_SUCCESS;
	NDIS_HANDLE hFakeProtocol = NULL;
	NDIS_PROTOCOL_CHARACTERISTICS FakeProtocol;
	NDIS_STRING ProtocolName;

	NdisZeroMemory(&FakeProtocol, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
	FakeProtocol.MajorNdisVersion = 0x05;
	FakeProtocol.MinorNdisVersion = 0x00;

	NdisInitUnicodeString(&ProtocolName, L"FakeProtocol");
	FakeProtocol.Name = ProtocolName;
	FakeProtocol.ReceiveHandler = FakeNdisProtocolReceive;
	FakeProtocol.BindAdapterHandler = FakeBind;
	FakeProtocol.UnbindAdapterHandler = FakeUnBind;

	NdisRegisterProtocol(&status, &hFakeProtocol, &FakeProtocol,
		sizeof(NDIS50_PROTOCOL_CHARACTERISTICS));

	if (status == STATUS_SUCCESS) {
		return hFakeProtocol;
	} else {
		DbgPrint("RegisterFakeNDISProtocol failed: 0x%08x!\r\n", status);
		return NULL;
	}
}
void ParaNdis_DebugInitialize()
{
    NDIS_STRING usRegister, usDeregister, usPrint;
    PVOID pr, pd;
    BOOLEAN res;

    NdisAllocateSpinLock(&CrashLock);
    KeInitializeCallbackRecord(&CallbackRecord);
    ParaNdis_PrepareBugCheckData();
    NdisInitUnicodeString(&usPrint, L"vDbgPrintEx");
    NdisInitUnicodeString(&usRegister, L"KeRegisterBugCheckReasonCallback");
    NdisInitUnicodeString(&usDeregister, L"KeDeregisterBugCheckReasonCallback");
    pd = MmGetSystemRoutineAddress(&usPrint);
    if (pd) PrintProcedure = (vDbgPrintExType)pd;
    pr = MmGetSystemRoutineAddress(&usRegister);
    pd = MmGetSystemRoutineAddress(&usDeregister);
    if (pr && pd)
    {
        BugCheckRegisterCallback = (KeRegisterBugCheckReasonCallbackType)pr;
        BugCheckDeregisterCallback = (KeDeregisterBugCheckReasonCallbackType)pd;
    }
    res = BugCheckRegisterCallback(&CallbackRecord, ParaNdis_OnBugCheck, KbCallbackSecondaryDumpData, (const PUCHAR)"NetKvm");
    DPrintf(0, ("[%s] Crash callback %sregistered\n", __FUNCTION__, res ? "" : "NOT "));
}
Example #9
0
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_DRIVER_CHARACTERISTICS   PChars;
    NDIS_MINIPORT_DRIVER_CHARACTERISTICS   MChars;
    NDIS_HANDLE  MiniportDriverContext;
    NDIS_HANDLE  ProtocolDriverContext;
    NDIS_STRING                     Name;
    

    NdisInitializeListHead(&AdapterList);
    NdisInitializeListHead(&VElanList);
    MiniportDriverContext=NULL;
    ProtocolDriverContext=NULL;
    
    MUX_INIT_MUTEX(&GlobalMutex);
    MUX_INIT_MUTEX(&ControlDeviceMutex);
    NdisAllocateSpinLock(&GlobalLock);


    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_DRIVER_CHARACTERISTICS));

        MChars.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
        MChars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
        MChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
        
        MChars.MajorNdisVersion = MUX_MAJOR_NDIS_VERSION;
        MChars.MinorNdisVersion = MUX_MINOR_NDIS_VERSION;

        MChars.MajorDriverVersion = MUX_MAJOR_DRIVER_VERSION;
        MChars.MinorDriverVersion = MUX_MINOR_DRIVER_VERSION;

        MChars.SetOptionsHandler = MpSetOptions;
        MChars.InitializeHandlerEx = MPInitialize;
        MChars.UnloadHandler = MPUnload;
        MChars.HaltHandlerEx = MPHalt;

        MChars.OidRequestHandler = MPOidRequest;

        MChars.CancelSendHandler = MPCancelSendNetBufferLists;
        MChars.DevicePnPEventNotifyHandler = MPDevicePnPEvent;
        MChars.ShutdownHandlerEx = MPAdapterShutdown;
        MChars.CancelOidRequestHandler =  MPCancelOidRequest;

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

        MChars.ReturnNetBufferListsHandler = MPReturnNetBufferLists;
        MChars.SendNetBufferListsHandler = MPSendNetBufferLists;

        MChars.PauseHandler = MPPause;
        MChars.RestartHandler = MPRestart;

        MChars.Flags = NDIS_INTERMEDIATE_DRIVER;
        Status = NdisMRegisterMiniportDriver(DriverObject,
                                             RegistryPath,
                                             MiniportDriverContext,
                                             &MChars,
                                             &DriverHandle);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            break;
        }

        //
        // Now register the protocol.
        //
        NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_DRIVER_CHARACTERISTICS));

        PChars.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
        PChars.Header.Size = sizeof(NDIS_PROTOCOL_DRIVER_CHARACTERISTICS);
        PChars.Header.Revision = NDIS_PROTOCOL_DRIVER_CHARACTERISTICS_REVISION_1;
            
        PChars.MajorNdisVersion = MUX_PROT_MAJOR_NDIS_VERSION;
        PChars.MinorNdisVersion = MUX_PROT_MINOR_NDIS_VERSION;
        
        PChars.MajorDriverVersion = MUX_MAJOR_DRIVER_VERSION;
        PChars.MinorDriverVersion = MUX_MINOR_DRIVER_VERSION;

        PChars.SetOptionsHandler = PtSetOptions;
        
        //
        // 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"MUXP");    // Protocol name
        PChars.Name = Name;
        PChars.OpenAdapterCompleteHandlerEx = PtOpenAdapterComplete;
        PChars.CloseAdapterCompleteHandlerEx = PtCloseAdapterComplete;

        PChars.ReceiveNetBufferListsHandler = PtReceiveNBL;
        PChars.SendNetBufferListsCompleteHandler = PtSendNBLComplete;
        PChars.OidRequestCompleteHandler = PtRequestComplete;
        PChars.StatusHandlerEx = PtStatus;
        PChars.BindAdapterHandlerEx = PtBindAdapter;
        PChars.UnbindAdapterHandlerEx = PtUnbindAdapter;
        PChars.NetPnPEventHandler= PtPNPHandler;
        Status = NdisRegisterProtocolDriver(ProtocolDriverContext,
                                            &PChars,
                                            &ProtHandle);

        if (Status != NDIS_STATUS_SUCCESS)
        {
            NdisMDeregisterMiniportDriver(DriverHandle);
            break;
        }
        //
        // Let NDIS know of the association between our protocol
        // and miniport entities.
        //
        NdisIMAssociateMiniport(DriverHandle, ProtHandle);
    }while (FALSE);

    return(Status);
}
Example #10
0
NDIS_STATUS
NDISFilterDriverRegisterDevice(OUT PFILTER_DEVICE_EXTENSION *Extension)
{
    NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         DeviceLinkUnicodeString;
    PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
    NDIS_DEVICE_OBJECT_ATTRIBUTES   DeviceAttribute;
    PFILTER_DEVICE_EXTENSION        FilterDeviceExtension;
    PDRIVER_OBJECT                  DriverObject;
   
    DEBUGP(DL_TRACE, "==>NDISFilterDriverRegisterDevice\n");
   
    
    NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
    
    DispatchTable[IRP_MJ_CREATE] = NDISFilterDriverDispatch;
    DispatchTable[IRP_MJ_CLEANUP] = NDISFilterDriverDispatch;
    DispatchTable[IRP_MJ_CLOSE] = NDISFilterDriverDispatch;
    DispatchTable[IRP_MJ_DEVICE_CONTROL] = NDISFilterDriverDeviceIoControl;
    
    
    NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
    NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);
    
    //
    // Create a device object and register our dispatch handlers
    //
    NdisZeroMemory(&DeviceAttribute, sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES));
    
    DeviceAttribute.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES;
    DeviceAttribute.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
    DeviceAttribute.Header.Size = sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES);
    
    DeviceAttribute.DeviceName = &DeviceName;
    DeviceAttribute.SymbolicName = &DeviceLinkUnicodeString;
    DeviceAttribute.MajorFunctions = &DispatchTable[0];
    DeviceAttribute.ExtensionSize = sizeof(FILTER_DEVICE_EXTENSION);
    
    Status = NdisRegisterDeviceEx(
                FilterDriverHandle,
                &DeviceAttribute,
                &DeviceObject,
                &NdisFilterDeviceHandle
                );
   
   
    if (Status == NDIS_STATUS_SUCCESS)
    {
		*Extension = FilterDeviceExtension = NdisGetDeviceReservedExtension(DeviceObject);
   
        FilterDeviceExtension->Signature = 'FTDR';
        FilterDeviceExtension->Handle = FilterDriverHandle;
		KeInitializeSpinLock(&FilterDeviceExtension->QLock);
		PRULES_LISTS FilterRules = ExAllocatePool(PagedPool, sizeof(RULES_LISTS));
		FilterRules->IsActive = FALSE;
		FilterRules->FirstRuleIPv4 = NULL;
		FilterRules->FirstRuleIPv6 = NULL;
		FilterDeviceExtension->FilterRules = FilterRules;

        //
        // Workaround NDIS bug
        //
        DriverObject = (PDRIVER_OBJECT)FilterDriverObject;
    }
              
        
    DEBUGP(DL_TRACE, "<==NDISFilterDriverRegisterDevice: %x\n", Status);
        
    return (Status);
        
}
DWORD	GetProtocolHeaderXP()
{
	NDIS_STATUS                        Status;
	NDIS_PROTOCOL_CHARACTERISTICS      PChars;
	NDIS_HANDLE ProtHandle;
	NDIS_STRING                        Name;
	PKK_NDIS_PROTOCOL_BLOCK			pHeader=NULL;


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

	//
	// 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"SUPERCI");    // 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.BindAdapterHandler = PtBindAdapter;
	PChars.UnbindAdapterHandler = PtUnbindAdapter;

	//GetReal_NdisRegisterProtocol
	//if NdisRegisterProtocol is hook by eat.
	//we can search ff 15 xxxxxx,it means a long call [xxxxxx] instruction
	NdisRegisterProtocol(&Status,
		&ProtHandle,
		&PChars,
		sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
	if (Status != NDIS_STATUS_SUCCESS||ProtHandle==0)
	{
		return 0;
	}

	pHeader	=	(PKK_NDIS_PROTOCOL_BLOCK)ProtHandle;
	ProtHandle	=	(NDIS_HANDLE)pHeader->NextProtocol;
	NdisDeregisterProtocol(&Status, pHeader);
	if (Status != NDIS_STATUS_SUCCESS)
	{
		kprintf("NdisDeregisterProtocol() fail in ReturnProtocolHeader()\n ");
		return 0;
	}
	return (ULONG)ProtHandle;

}
Example #12
0
NDIS_STATUS
PtRegisterDevice(
    VOID
    )
/*++

Routine Description:

    Register an ioctl interface - a device object to be used for this
    purpose is created by NDIS when we call NdisMRegisterDevice.

    This routine is called whenever a new miniport instance is
    initialized. However, we only create one global device object,
    when the first miniport instance is initialized. This routine
    handles potential race conditions with PtDeregisterDevice via
    the ControlDeviceState and MiniportCount variables.

    NOTE: do not call this from DriverEntry; it will prevent the driver
    from being unloaded (e.g. on uninstall).

Arguments:

    None

Return Value:

    NDIS_STATUS_SUCCESS if we successfully register a device object.

--*/
{
    NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         DeviceLinkUnicodeString;
    PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];

    DBGPRINT(("==>PtRegisterDevice\n"));

    NdisAcquireSpinLock(&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(&GlobalLock);
            NdisMSleep(1);
            NdisAcquireSpinLock(&GlobalLock);
        }

        ControlDeviceState = PS_DEVICE_STATE_CREATING;

        NdisReleaseSpinLock(&GlobalLock);

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

        DispatchTable[IRP_MJ_CREATE] = NdisProtOpen;
        DispatchTable[IRP_MJ_CLEANUP] = NdisProtCleanup;
        DispatchTable[IRP_MJ_CLOSE] = NdisProtClose;
//	DispatchTable[IRP_MJ_READ]  = NdisProtRead;
	DispatchTable[IRP_MJ_READ]  = divert_read;
//	DispatchTable[IRP_MJ_WRITE] = PtDispatch;
	DispatchTable[IRP_MJ_WRITE] = divert_write;
//        DispatchTable[IRP_MJ_DEVICE_CONTROL] = NdisProtIoControl;
        DispatchTable[IRP_MJ_DEVICE_CONTROL] = PtDispatch;
        

        NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
        NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);

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

        ControlDeviceObject->Flags |= DO_DIRECT_IO;

        NdisAcquireSpinLock(&GlobalLock);

        ControlDeviceState = PS_DEVICE_STATE_READY;
    }

    NdisReleaseSpinLock(&GlobalLock);

    DBGPRINT(("<==PtRegisterDevice: %x\n", Status));

    return (Status);
}
Example #13
0
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;
    NDIS_STRING                        Name;

    divert_init();

    Status = NDIS_STATUS_SUCCESS;
    NdisAllocateSpinLock(&GlobalLock);

    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 = NULL;
        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);
}
Example #14
0
NTSTATUS
DriverEntry(
    IN PDRIVER_OBJECT        DriverObject,
    IN PUNICODE_STRING       RegistryPath
    )
{
    NDIS_STATUS                        Status;
    NDIS40_PROTOCOL_CHARACTERISTICS    PChars40;
    NDIS40_MINIPORT_CHARACTERISTICS    MChars40;
    NDIS50_PROTOCOL_CHARACTERISTICS    PChars50;
    NDIS51_MINIPORT_CHARACTERISTICS    MChars51;
    NDIS_STRING                        Name;

    Status = NDIS_STATUS_SUCCESS;

	g_ArpFw_ShareMem = NULL;

    NdisAllocateSpinLock(&GlobalLock);

	g_CurrentDriver = DriverObject;

	LoadDynamicFunction();  //识别版本并加载额外函数

//	Status = InitPacketList();

//	if( Status != STATUS_SUCCESS)
//	{
//		return Status;
//	}

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

	if(IS_NDIS51())
	{
	    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(&MChars51, sizeof(NDIS51_MINIPORT_CHARACTERISTICS));

        	MChars51.MajorNdisVersion = 5;
        	MChars51.MinorNdisVersion = 1;

        	MChars51.InitializeHandler 			= MiniportInitialize5;
        	MChars51.QueryInformationHandler 	= MiniportQueryInformation5;
        	MChars51.SetInformationHandler 		= MiniportSetInformation5;
        	MChars51.ResetHandler 				= NULL;
        	MChars51.TransferDataHandler 		= MiniportTransferData5;
        	MChars51.HaltHandler 				= MiniportHalt5;

			//NDIS51++
        	MChars51.CancelSendPacketsHandler 	= MiniportCancelSendPackets5;
        	MChars51.PnPEventNotifyHandler 		= MiniportDevicePnPEvent5;
        	MChars51.AdapterShutdownHandler 	= MiniportAdapterShutdown5;
			//--NDIS51

        	//
        	// We will disable the check for hang timeout so we do not
        	// need a check for hang handler!
        	//
        	MChars51.CheckForHangHandler 		= MiniportCheckForHang5;
        	MChars51.ReturnPacketHandler 		= MiniportReturnPacket5;

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

        	Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,
                                                  (PVOID)&MChars51,
                                                  sizeof(NDIS51_MINIPORT_CHARACTERISTICS),
                                                  &DriverHandle);
        	if (Status != NDIS_STATUS_SUCCESS)
        	{
            	break;
        	}

        	NdisMRegisterUnloadHandler(NdisWrapperHandle, ProtocolUnload);


        	//
        	// Now register the protocol.
        	//
        	NdisZeroMemory(&PChars50, sizeof(NDIS50_PROTOCOL_CHARACTERISTICS));
        	PChars50.MajorNdisVersion = 5;
        	PChars50.MinorNdisVersion = 0;

        	//
        	// 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, PROTOCOL_NAME);    // Protocol name
        	PChars50.Name 							= Name;
        	PChars50.OpenAdapterCompleteHandler 	= ProtocolOpenAdapterComplete5;
        	PChars50.CloseAdapterCompleteHandler 	= ProtocolCloseAdapterComplete5;
        	PChars50.SendCompleteHandler 			= ProtocolSendComplete5;
        	PChars50.TransferDataCompleteHandler 	= ProtocolTransferDataComplete5;
    
        	PChars50.ResetCompleteHandler 			= ProtocolResetComplete5;
        	PChars50.RequestCompleteHandler 		= ProtocolRequestComplete5;
        	PChars50.ReceiveHandler 				= ProtocolReceive5;
        	PChars50.ReceiveCompleteHandler 		= ProtocolReceiveComplete5;
        	PChars50.StatusHandler 					= ProtocolStatus5;
        	PChars50.StatusCompleteHandler 			= ProtocolStatusComplete5;
        	PChars50.BindAdapterHandler 			= ProtocolBindAdapter5;
        	PChars50.UnbindAdapterHandler 			= ProtocolUnbindAdapter5;
        	PChars50.UnloadHandler 					= ProtocolUnloadProtocol5;

        	PChars50.ReceivePacketHandler 			= ProtocolReceivePacket5;
        	PChars50.PnPEventHandler				= ProtocolPNPHandler5;

        	NdisRegisterProtocol(&Status,
                             &ProtHandle,
                             (PVOID)&PChars50,
                             sizeof(NDIS50_PROTOCOL_CHARACTERISTICS));

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

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

	}
	else
	{
		do
		{
			//注册 Miniport
			NdisZeroMemory(&MChars40, sizeof(NDIS40_MINIPORT_CHARACTERISTICS));

			MChars40.MajorNdisVersion = 4;
			MChars40.MinorNdisVersion = 0;

			MChars40.InitializeHandler 			= MiniportInitialize4;
			MChars40.QueryInformationHandler 	= MiniportQueryInformation4;
			MChars40.SetInformationHandler 		= MiniportSetInformation4;
			MChars40.ResetHandler 				= NULL;
			MChars40.TransferDataHandler 		= MiniportTransferData4;
			MChars40.HaltHandler 				= MiniportHalt4;

			MChars40.CheckForHangHandler 		= MiniportCheckForHang4;
			MChars40.ReturnPacketHandler 		= MiniportReturnPacket4;

			MChars40.SendHandler 				= NULL;
			MChars40.SendPacketsHandler 		= MiniportSendPackets4;

			Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,
													  (PVOID)&MChars40,
													  sizeof(MChars40),
													  &DriverHandle);
			if (Status != NDIS_STATUS_SUCCESS)
			{
				break;
			}

			NdisMRegisterUnloadHandler(NdisWrapperHandle, ProtocolUnload);

			//
			// Now register the protocol.
			//
			NdisZeroMemory(&PChars40, sizeof(NDIS40_PROTOCOL_CHARACTERISTICS));
			PChars40.MajorNdisVersion = 4;
			PChars40.MinorNdisVersion = 0;

			NdisInitUnicodeString(&Name, PROTOCOL_NAME);    // Protocol name
			PChars40.Name 							= Name;
			PChars40.OpenAdapterCompleteHandler 	= ProtocolOpenAdapterComplete4;
			PChars40.CloseAdapterCompleteHandler 	= ProtocolCloseAdapterComplete4;
			PChars40.SendCompleteHandler 			= ProtocolSendComplete4;
			PChars40.TransferDataCompleteHandler 	= ProtocolTransferDataComplete4;
    
			PChars40.ResetCompleteHandler 			= ProtocolResetComplete4;
			PChars40.RequestCompleteHandler 		= ProtocolRequestComplete4;
			PChars40.ReceiveHandler 				= ProtocolReceive4;
			PChars40.ReceiveCompleteHandler 		= ProtocolReceiveComplete4;
			PChars40.StatusHandler 					= ProtocolStatus4;
			PChars40.StatusCompleteHandler 			= ProtocolStatusComplete4;
			PChars40.BindAdapterHandler 			= ProtocolBindAdapter4;
			PChars40.UnbindAdapterHandler 			= ProtocolUnbindAdapter4;
			PChars40.UnloadHandler 					= ProtocolUnloadProtocol4;

			PChars40.ReceivePacketHandler 			= ProtocolReceivePacket4;
			PChars40.PnPEventHandler				= ProtocolPNPHandler4;

			NdisRegisterProtocol(&Status,
								 &ProtHandle,
								 (PVOID)&PChars40,
								 sizeof(NDIS40_PROTOCOL_CHARACTERISTICS));
			if (Status != NDIS_STATUS_SUCCESS)
			{
				NdisIMDeregisterLayeredMiniport(DriverHandle);
				break;
			}

			NdisIMAssociateMiniport(DriverHandle, ProtHandle);

		}
		while (FALSE);
	}

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

    return(Status);
}
Example #15
0
NDIS_STATUS
ProtocolRegisterDevice(
    VOID
    )
{
    NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         DeviceLinkUnicodeString;
    PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];

    NdisAcquireSpinLock(&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(&GlobalLock);
            NdisMSleep(1);
            NdisAcquireSpinLock(&GlobalLock);
        }

        ControlDeviceState = PS_DEVICE_STATE_CREATING;

        NdisReleaseSpinLock(&GlobalLock);

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

        DispatchTable[IRP_MJ_CREATE]			= DispatchCreate;
        DispatchTable[IRP_MJ_CLOSE]				= DispatchClose;
        DispatchTable[IRP_MJ_DEVICE_CONTROL]	= DispatchIoCtrl;
		DispatchTable[IRP_MJ_WRITE]				= DispatchWrite;

        NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
        NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);

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

        NdisAcquireSpinLock(&GlobalLock);

		ControlDeviceObject->Flags |= DO_BUFFERED_IO;

        ControlDeviceState = PS_DEVICE_STATE_READY;
    }

    NdisReleaseSpinLock(&GlobalLock);

    return (Status);
}
Example #16
0
/**
 This implementation picks the NDIS 6.2 Read/Write lock structures & API on OS versions 
 where NDIS support those and would pick the older API on NDIS 6.0. Since the new API 
 are not available on NDIS 6.0 OS, it does not link the new API into the binary, instead 
 it dynamically loads the API address & uses them. This way the same binary can run on 
 both NDIS 6.0 & 6.2 OSes, using the correct API for that OS.
 */
NDIS_STATUS
MpDetermineRWLockType()
{
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_SUCCESS;    
    ULONG                       ndisVersion;
    NDIS_STRING                 allocateRoutineName;
    NDIS_STRING                 freeRoutineName;
    NDIS_STRING                 acquireReadRoutineName;
    NDIS_STRING                 acquireWriteRoutineName;
    NDIS_STRING                 releaseRoutineName;

    do
    {
        NdisZeroMemory(&GlobalRWLockHandlers, sizeof(MP_RW_LOCK_HANDLERS));
            
        // Start with pre NDIS 6.2 using the old API. If this is NDIS 6.2+ and
        // we cannot find address of new API, we will fail
        GlobalRWLockHandlers.AllocateHandler = MpAllocateOldRWLock;
        GlobalRWLockHandlers.FreeHandler = MpFreeOldRWLock;
        GlobalRWLockHandlers.AcquireReadHandler = MpAcquireOldRWLockForRead;
        GlobalRWLockHandlers.AcquireWriteHandler = MpAcquireOldRWLockForWrite;
        GlobalRWLockHandlers.ReleaseHandler = MpReleaseOldRWLock;
        
        ndisVersion = NdisGetVersion();
        if (ndisVersion > MP_NDIS_VERSION_NEEDS_COMPATIBILITY)        
        {
            // NDIS 6.2 or above. Use the new API

            // Load the address of the new NDisRead/Write lock API
            NdisInitUnicodeString(&allocateRoutineName, L"NdisAllocateRWLock");
            
            NdisInitUnicodeString(&freeRoutineName, L"NdisFreeRWLock");
            NdisInitUnicodeString(&acquireReadRoutineName, L"NdisAcquireRWLockRead");
            NdisInitUnicodeString(&acquireWriteRoutineName, L"NdisAcquireRWLockWrite");
            NdisInitUnicodeString(&releaseRoutineName, L"NdisReleaseRWLock");
            
            *((PVOID *)&MpNdisAllocateRWLock) = NdisGetRoutineAddress(&allocateRoutineName);
            if (MpNdisAllocateRWLock == NULL)
            {
                MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisAllocateRWLock\n"));
                break;                
            }

            *((PVOID *)&MpNdisFreeRWLock) = NdisGetRoutineAddress(&freeRoutineName);
            if (MpNdisFreeRWLock == NULL)
            {
                MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisFreeRWLock\n"));
                break;                
            }

            *((PVOID *)&MpNdisAcquireRWLockRead) = NdisGetRoutineAddress(&acquireReadRoutineName);
            if (MpNdisAcquireRWLockRead == NULL)
            {
                MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisAcquireRWLockRead\n"));
                break;                
            }

            *((PVOID *)&MpNdisAcquireRWLockWrite) = NdisGetRoutineAddress(&acquireWriteRoutineName);
            if (MpNdisAcquireRWLockWrite == NULL)
            {
                MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisAcquireRWLockWrite\n"));
                break;                
            }

            *((PVOID *)&MpNdisReleaseRWLock) = NdisGetRoutineAddress(&releaseRoutineName);
            if (MpNdisReleaseRWLock == NULL)
            {
                MpTrace(COMP_INIT_PNP, DBG_SERIOUS, ("Failed to find address of NdisReleaseRWLock\n"));
                break;                
            }

            // Set our pointers
            GlobalRWLockHandlers.AllocateHandler = MpAllocateNewRWLock;
            GlobalRWLockHandlers.FreeHandler = MpFreeNewRWLock;
            GlobalRWLockHandlers.AcquireReadHandler = MpAcquireNewRWLockForRead;
            GlobalRWLockHandlers.AcquireWriteHandler = MpAcquireNewRWLockForWrite;
            GlobalRWLockHandlers.ReleaseHandler = MpReleaseNewRWLock;

        }
    }while (FALSE);

    return ndisStatus;
}
NTSTATUS GingkoNdisDriverEntry(
    IN PDRIVER_OBJECT        DriverObject,
    IN PUNICODE_STRING       RegistryPath
    )
{
	NDIS_STATUS                        Status;
    NDIS_PROTOCOL_CHARACTERISTICS      PChars;
    NDIS_MINIPORT_CHARACTERISTICS      MChars;
    NDIS_STRING                        Name;

    Status = NDIS_STATUS_SUCCESS;
    NdisAllocateSpinLock(&GlobalLock);
    NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);
	KdPrint(("Calling NdisMInitializeWrapper Before\n"));

    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 = GingkoNdisInitialize;
        MChars.QueryInformationHandler = GingkoNdisQueryInformation;
        MChars.SetInformationHandler = GingkoNdisSetInformation;
        MChars.ResetHandler = NULL;
        MChars.TransferDataHandler = GingkoNdisTransferData;
        MChars.HaltHandler = GingkoNdisHalt;
#ifdef NDIS51_MINIPORT
        MChars.CancelSendPacketsHandler = GingkoNdisCancelSendPackets;
        MChars.PnPEventNotifyHandler = GingkoNdisDevicePnPEvent;
        MChars.AdapterShutdownHandler = GingkoNdisAdapterShutdown;
#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 = GingkoNdisReturnPacket;

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

        Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,
                                                  &MChars,
                                                  sizeof(MChars),
                                                  &DriverHandle);

		KdPrint(("Calling NdisIMRegisterLayeredMiniport After\n"));
		///return 0;
        if (Status != NDIS_STATUS_SUCCESS)
        {
            break;
        }


#ifndef WIN9X
        NdisMRegisterUnloadHandler(NdisWrapperHandle, GingkoNdisUnload);
#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"GingkoFilter");    // Protocol name
        PChars.Name = Name;
        PChars.OpenAdapterCompleteHandler = GingkoNdisOpenAdapterComplete;
        PChars.CloseAdapterCompleteHandler = GingkoNdisCloseAdapterComplete;
        PChars.SendCompleteHandler = GingkoNdisSendComplete;
        PChars.TransferDataCompleteHandler = GingkoNdisTransferDataComplete;
    
        PChars.ResetCompleteHandler = GingkoNdisResetComplete;
        PChars.RequestCompleteHandler = GingkoNdisRequestComplete;
        PChars.ReceiveHandler = GingkoNdisReceive;
        PChars.ReceiveCompleteHandler = GingkoNdisReceiveComplete;
        PChars.StatusHandler = GingkoNdisStatus;
        PChars.StatusCompleteHandler = GingkoNdisStatusComplete;
        PChars.BindAdapterHandler = GingkoNdisBindAdapter;
        PChars.UnbindAdapterHandler = GingkoNdisUnbindAdapter;
        PChars.UnloadHandler = GingkoNdisUnloadProtocol;

        PChars.ReceivePacketHandler = GingkoNdisReceivePacket;
        PChars.PnPEventHandler= GingkoNdisPNPHandler;

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

		KdPrint(("Calling NdisRegisterProtocol After\n"));
        if (Status != NDIS_STATUS_SUCCESS)
        {
            NdisIMDeregisterLayeredMiniport(DriverHandle);
            break;
        }

        NdisIMAssociateMiniport(DriverHandle, ProtHandle);

		KdPrint(("Calling NdisIMAssociateMiniport After\n"));
    }
    while (FALSE);

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

    return(Status);
}
Example #18
0
NDIS_STATUS
PtRegisterDevice(
    VOID
    )
/*++

Routine Description:

    Register an ioctl interface - a device object to be used for this
    purpose is created by NDIS when we call NdisMRegisterDevice.

    This routine is called whenever a new miniport instance is
    initialized. However, we only create one global device object,
    when the first miniport instance is initialized. This routine
    handles potential race conditions with PtDeregisterDevice via
    the ControlDeviceMutex.

    NOTE: do not call this from DriverEntry; it will prevent the driver
    from being unloaded (e.g. on uninstall).

Arguments:

    None

Return Value:

    NDIS_STATUS_SUCCESS if we successfully register a device object.

--*/
{
    NDIS_STATUS         Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING      DeviceName;
    UNICODE_STRING      DeviceLinkUnicodeString;
    NDIS_DEVICE_OBJECT_ATTRIBUTES   DeviceObjectAttributes;
    PDRIVER_DISPATCH    DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];



    DBGPRINT(MUX_LOUD, ("==>PtRegisterDevice\n"));

    MUX_ACQUIRE_MUTEX(&ControlDeviceMutex);

    ++MiniportCount;
    
    if (1 == MiniportCount)
    {
        NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
        
        DispatchTable[IRP_MJ_CREATE] = PtDispatch;
        DispatchTable[IRP_MJ_CLEANUP] = PtDispatch;
        DispatchTable[IRP_MJ_CLOSE] = PtDispatch;
        DispatchTable[IRP_MJ_DEVICE_CONTROL] = PtDispatch;
        

        NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
        NdisInitUnicodeString(&DeviceLinkUnicodeString, GLOBAL_LINKNAME_STRING);

        NdisZeroMemory(&DeviceObjectAttributes, sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES));

        DeviceObjectAttributes.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; // type implicit from the context
        DeviceObjectAttributes.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
        DeviceObjectAttributes.Header.Size = sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES);
        DeviceObjectAttributes.DeviceName = &DeviceName;
        DeviceObjectAttributes.SymbolicName = &DeviceLinkUnicodeString;
        DeviceObjectAttributes.MajorFunctions = &DispatchTable[0];
        DeviceObjectAttributes.ExtensionSize = 0;
        DeviceObjectAttributes.DefaultSDDLString = NULL;
        DeviceObjectAttributes.DeviceClassGuid = 0;

        Status = NdisRegisterDeviceEx(
                    DriverHandle,
                    &DeviceObjectAttributes,
                    &ControlDeviceObject,
                    &NdisDeviceHandle);
        
    }

    MUX_RELEASE_MUTEX(&ControlDeviceMutex);

    DBGPRINT(MUX_INFO, ("<==PtRegisterDevice: %x\n", Status));

    return (Status);
}
Example #19
0
NDIS_STATUS
FilterRegisterDevice(
    VOID
    )
{
    NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
    UNICODE_STRING         DeviceName;
    UNICODE_STRING         DeviceLinkUnicodeString;
    PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
    NDIS_DEVICE_OBJECT_ATTRIBUTES   DeviceAttribute;
    PFILTER_DEVICE_EXTENSION        FilterDeviceExtension;

    DEBUGP(DL_TRACE, "==>FilterRegisterDevice\n");

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

    DispatchTable[IRP_MJ_CREATE] = FilterDispatch;
    DispatchTable[IRP_MJ_CLEANUP] = FilterDispatch;
    DispatchTable[IRP_MJ_CLOSE] = FilterDispatch;
    DispatchTable[IRP_MJ_DEVICE_CONTROL] = FilterDeviceIoControl;
    DispatchTable[IRP_MJ_INTERNAL_DEVICE_CONTROL] = FilterInternalDeviceIoControl;

    NdisInitUnicodeString(&DeviceName, NETMAP_NDIS_NTDEVICE_STRING);
    NdisInitUnicodeString(&DeviceLinkUnicodeString, NETMAP_NDIS_LINKNAME_STRING);

    //
    // Create a device object and register our dispatch handlers
    //
    NdisZeroMemory(&DeviceAttribute, sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES));

    DeviceAttribute.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES;
    DeviceAttribute.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
    DeviceAttribute.Header.Size = sizeof(NDIS_DEVICE_OBJECT_ATTRIBUTES);

    DeviceAttribute.DeviceName = &DeviceName;
    DeviceAttribute.SymbolicName = &DeviceLinkUnicodeString;
    DeviceAttribute.MajorFunctions = &DispatchTable[0];
    DeviceAttribute.ExtensionSize = sizeof(FILTER_DEVICE_EXTENSION);

    Status = NdisRegisterDeviceEx(
                FilterDriverHandle,
                &DeviceAttribute,
                &DeviceObject,
                &NdisFilterDeviceHandle
                );


    if (Status == NDIS_STATUS_SUCCESS)
    {
        FilterDeviceExtension = NdisGetDeviceReservedExtension(DeviceObject);

        FilterDeviceExtension->Signature = 'FTDR';
        FilterDeviceExtension->Handle = FilterDriverHandle;
    }


    DEBUGP(DL_TRACE, "<==FilterRegisterDevice: %x\n", Status);

    return (Status);

}
Example #20
0
// Called at <= DISPATCH_LEVEL
static NDIS_STATUS
XenNet_Init(
  OUT PNDIS_STATUS OpenErrorStatus,
  OUT PUINT SelectedMediumIndex,
  IN PNDIS_MEDIUM MediumArray,
  IN UINT MediumArraySize,
  IN NDIS_HANDLE MiniportAdapterHandle,
  IN NDIS_HANDLE WrapperConfigurationContext
  )
{
  NDIS_STATUS status;
  BOOLEAN medium_found = FALSE;
  struct xennet_info *xi = NULL;
  UINT nrl_length;
  PNDIS_RESOURCE_LIST nrl;
  PCM_PARTIAL_RESOURCE_DESCRIPTOR prd;
  KIRQL irq_level = 0;
  ULONG irq_vector = 0;
  ULONG irq_mode = 0;
  NDIS_HANDLE config_handle;
  NDIS_STRING config_param_name;
  PNDIS_CONFIGURATION_PARAMETER config_param;
  ULONG i;
  PUCHAR ptr;
  UCHAR type;
  PCHAR setting, value;
  ULONG length;
  //CHAR buf[128];
  PVOID network_address;
  UINT network_address_length;
  BOOLEAN qemu_hide_filter = FALSE;
  ULONG qemu_hide_flags_value = 0;
  
  UNREFERENCED_PARAMETER(OpenErrorStatus);

  FUNCTION_ENTER();

  KdPrint((__DRIVER_NAME "     IRQL = %d\n", KeGetCurrentIrql()));

  /* deal with medium stuff */
  for (i = 0; i < MediumArraySize; i++)
  {
    if (MediumArray[i] == NdisMedium802_3)
    {
      medium_found = TRUE;
      break;
    }
  }
  if (!medium_found)
  {
    KdPrint(("NIC_MEDIA_TYPE not in MediumArray\n"));
    return NDIS_STATUS_UNSUPPORTED_MEDIA;
  }
  *SelectedMediumIndex = i;

  /* Alloc memory for adapter private info */
  status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status));
    status = NDIS_STATUS_RESOURCES;
    goto err;
  }
  RtlZeroMemory(xi, sizeof(*xi));
  xi->adapter_handle = MiniportAdapterHandle;
  xi->rx_target     = RX_DFL_MIN_TARGET;
  xi->rx_min_target = RX_DFL_MIN_TARGET;
  xi->rx_max_target = RX_MAX_TARGET;
  xi->inactive      = TRUE;
  NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi, 0, 0 /* the last zero is to give the next | something to | with */
#ifdef NDIS51_MINIPORT
    |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS
#endif
    |NDIS_ATTRIBUTE_DESERIALIZE
    |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK,
    NdisInterfaceInternal); /* PnpBus option doesn't exist... */
  xi->multicast_list_size = 0;
  xi->current_lookahead = MIN_LOOKAHEAD_LENGTH;

  nrl_length = 0;
  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    NULL, (PUINT)&nrl_length);
  KdPrint((__DRIVER_NAME "     nrl_length = %d\n", nrl_length));
  status = NdisAllocateMemoryWithTag((PVOID)&nrl, nrl_length, XENNET_POOL_TAG);
  if (status != NDIS_STATUS_SUCCESS)
  {
    KdPrint((__DRIVER_NAME "     Could not get allocate memory for Adapter Resources 0x%x\n", status));
    return NDIS_STATUS_RESOURCES;
  }
  NdisMQueryAdapterResources(&status, WrapperConfigurationContext,
    nrl, (PUINT)&nrl_length);
  if (status != NDIS_STATUS_SUCCESS)
  {
    KdPrint((__DRIVER_NAME "     Could not get Adapter Resources 0x%x\n", status));
    return NDIS_STATUS_RESOURCES;
  }
  xi->event_channel = 0;
  xi->config_csum = 1;
  xi->config_csum_rx_check = 1;
  xi->config_sg = 1;
  xi->config_gso = 61440;
  xi->config_page = NULL;
  xi->config_rx_interrupt_moderation = 0;
  
  for (i = 0; i < nrl->Count; i++)
  {
    prd = &nrl->PartialDescriptors[i];

    switch(prd->Type)
    {
    case CmResourceTypeInterrupt:
      irq_vector = prd->u.Interrupt.Vector;
      irq_level = (KIRQL)prd->u.Interrupt.Level;
      irq_mode = (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?NdisInterruptLatched:NdisInterruptLevelSensitive;
      KdPrint((__DRIVER_NAME "     irq_vector = %03x, irq_level = %03x, irq_mode = %s\n", irq_vector, irq_level,
        (irq_mode == NdisInterruptLatched)?"NdisInterruptLatched":"NdisInterruptLevelSensitive"));
      break;
    case CmResourceTypeMemory:
      if (xi->config_page)
      {
        KdPrint(("More than one memory range\n"));
        return NDIS_STATUS_RESOURCES;
      }
      else
      {
        status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length);
        if (!NT_SUCCESS(status))
        {
          KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status));
          NdisFreeMemory(nrl, nrl_length, 0);
          return NDIS_STATUS_RESOURCES;
        }
      }
      break;
    }
  }
  NdisFreeMemory(nrl, nrl_length, 0);
  if (!xi->config_page)
  {
    KdPrint(("No config page given\n"));
    return NDIS_STATUS_RESOURCES;
  }

  KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi);
  KeInitializeSpinLock(&xi->resume_lock);

  KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi);
  KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0);
  KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance);

  NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo,
    &xi->lower_do, NULL, NULL);
  xi->packet_filter = 0;

  status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription,
    NAME_SIZE, xi->dev_desc, &length);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status));
    status = NDIS_STATUS_FAILURE;
    goto err;
  }

  ptr = xi->config_page;
  while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END)
  {
    switch(type)
    {
    case XEN_INIT_TYPE_VECTORS:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_VECTORS\n"));
      if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) ||
        ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC)
      {
        KdPrint((__DRIVER_NAME "     vectors mismatch (magic = %08x, length = %d)\n",
          ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length));
        FUNCTION_EXIT();
        return NDIS_STATUS_FAILURE;
      }
      else
        memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS));
      break;
    case XEN_INIT_TYPE_STATE_PTR:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value)));
      xi->device_state = (PXENPCI_DEVICE_STATE)value;
      break;
    case XEN_INIT_TYPE_QEMU_HIDE_FLAGS:
      qemu_hide_flags_value = PtrToUlong(value);
      break;
    case XEN_INIT_TYPE_QEMU_HIDE_FILTER:
      qemu_hide_filter = TRUE;
      break;
    default:
      KdPrint((__DRIVER_NAME "     XEN_INIT_TYPE_%d\n", type));
      break;
    }
  }

  if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter)
    xi->inactive = FALSE;

  xi->power_state = NdisDeviceStateD0;
  xi->power_workitem = IoAllocateWorkItem(xi->fdo);

  // now build config page
  
  NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not open config in registry (%08x)\n", status));
    status = NDIS_STATUS_RESOURCES;
    goto err;
  }

  NdisInitUnicodeString(&config_param_name, L"ScatterGather");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ScatterGather value (%08x)\n", status));
    xi->config_sg = 1;
  }
  else
  {
    KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData));
    xi->config_sg = config_param->ParameterData.IntegerData;
  }
  
  NdisInitUnicodeString(&config_param_name, L"LargeSendOffload");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read LargeSendOffload value (%08x)\n", status));
    xi->config_gso = 0;
  }
  else
  {
    KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData));
    xi->config_gso = config_param->ParameterData.IntegerData;
    if (xi->config_gso > 61440)
    {
      xi->config_gso = 61440;
      KdPrint(("(clipped to %d)\n", xi->config_gso));
    }
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffload");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffload value (%08x)\n", status));
    xi->config_csum = 1;
  }
  else
  {
    KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum = !!config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status));
    xi->config_csum_rx_check = 1;
  }
  else
  {
    KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status));
    xi->config_csum_rx_dont_fix = 0;
  }
  else
  {
    KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData));
    xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData;
  }
  
  
  
  NdisInitUnicodeString(&config_param_name, L"MTU");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read MTU value (%08x)\n", status));
    xi->config_mtu = 1500;
  }
  else
  {
    KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData));
    xi->config_mtu = config_param->ParameterData.IntegerData;
  }

  NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration");
  NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger);  
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status));
    xi->config_rx_interrupt_moderation = 1500;
  }
  else
  {
    KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData));
    xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData;
  }
  

  NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle);
  if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02))
  {
    KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status));
    memset(xi->curr_mac_addr, 0, ETH_ALEN);
  }
  else
  {
    memcpy(xi->curr_mac_addr, network_address, ETH_ALEN);
    KdPrint(("     Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n",
      xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], 
      xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5]));
  }

  xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE);
  
  NdisCloseConfiguration(config_handle);

  status = XenNet_D0Entry(xi);
  if (!NT_SUCCESS(status))
  {
    KdPrint(("Failed to go to D0 (%08x)\n", status));
    goto err;
  }
  return NDIS_STATUS_SUCCESS;
  
err:
  NdisFreeMemory(xi, 0, 0);
  *OpenErrorStatus = status;
  FUNCTION_EXIT_STATUS(status);
  return status;
}