[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH 1/4] Refactor for maintainability/coding style



Removes common headers and the disabling of warnings via #pragmas
Fits code into driver.c (DriverEntry/Dispatch overrides), adapter.c
(NDIS miniport). Resolves differences in receiver/transmitter
implementations.

Signed-off-by: Owen Smith <owen.smith@xxxxxxxxxx>
---
 src/xennet/adapter.c         | 3833 +++++++++++++++++++-----------------------
 src/xennet/adapter.h         |  154 +-
 src/xennet/common.h          |   36 -
 src/xennet/driver.c          |  550 ++++++
 src/xennet/main.c            |  361 ----
 src/xennet/miniport.c        |  297 ----
 src/xennet/project.h         |   66 -
 src/xennet/receiver.c        |  393 +++--
 src/xennet/receiver.h        |   59 +-
 src/xennet/std.h             |   45 -
 src/xennet/transmitter.c     |  330 ++--
 src/xennet/transmitter.h     |   61 +-
 vs2012/xennet/xennet.vcxproj |    3 +-
 vs2013/xennet/xennet.vcxproj |    3 +-
 14 files changed, 2770 insertions(+), 3421 deletions(-)
 delete mode 100644 src/xennet/common.h
 create mode 100644 src/xennet/driver.c
 delete mode 100644 src/xennet/main.c
 delete mode 100644 src/xennet/miniport.c
 delete mode 100644 src/xennet/project.h
 delete mode 100644 src/xennet/std.h

diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
index 7cc49fb..6b32d1a 100644
--- a/src/xennet/adapter.c
+++ b/src/xennet/adapter.c
@@ -28,51 +28,44 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  * SUCH DAMAGE.
  */
+#define INITGUID
 
+#include <ndis.h>
+#include <ntstrsafe.h>
 #include <version.h>
-#include "common.h"
 
-#pragma warning(disable:4711)
+#include "adapter.h"
+#include "registry.h"
+#include "dbg_print.h"
+#include "assert.h"
 
-//
-// List of supported OIDs.
-//
+struct _XENNET_ADAPTER {
+    XENVIF_VIF_INTERFACE        VifInterface;
 
-static NDIS_STATUS
-AdapterSetRegistrationAttributes (
-    IN  PADAPTER Adapter
-    );
+    BOOLEAN                     Enabled;
+    ULONG                       MaximumFrameSize;
+    ULONG                       CurrentLookahead;
 
-static NDIS_STATUS
-AdapterSetGeneralAttributes (
-    IN  PADAPTER Adapter
-    );
+    NDIS_HANDLE                 NdisHandle;
+    NDIS_HANDLE                 NdisDmaHandle;
+    NDIS_PNP_CAPABILITIES       Capabilities;
+    NDIS_OFFLOAD                Offload;
+    XENNET_PROPERTIES           Properties;
 
-static NDIS_STATUS
-AdapterSetOffloadAttributes (
-    IN  PADAPTER Adapter
-    );
+    PXENNET_RECEIVER            Receiver;
+    PXENNET_TRANSMITTER         Transmitter;
+};
 
-static MINIPORT_PROCESS_SG_LIST AdapterProcessSGList;
-static VOID
-AdapterProcessSGList (
-    IN PDEVICE_OBJECT       DeviceObject,
-    IN PVOID                Reserved,
-    IN PSCATTER_GATHER_LIST SGL,
-    IN PVOID                Context
-    );
+#define XENNET_POOL_TAG         'tenX'
 
-static NDIS_STATUS
-AdapterSetInformation (
-    IN  PADAPTER            Adapter,
-    IN  PNDIS_OID_REQUEST   NdisRequest
-    );
+#define XENNET_MEDIA_MAX_SPEED  1000000000ull
 
-static NDIS_STATUS
-AdapterQueryInformation (
-    IN  PADAPTER            Adapter,
-    IN  PNDIS_OID_REQUEST   NdisRequest
-    );
+#define XENNET_SUPPORTED_PACKET_FILTERS     \
+        (NDIS_PACKET_TYPE_DIRECTED |        \
+         NDIS_PACKET_TYPE_MULTICAST |       \
+         NDIS_PACKET_TYPE_ALL_MULTICAST |   \
+         NDIS_PACKET_TYPE_BROADCAST |       \
+         NDIS_PACKET_TYPE_PROMISCUOUS)
 
 static NDIS_OID XennetSupportedOids[] =
 {
@@ -129,31 +122,9 @@ static NDIS_OID XennetSupportedOids[] =
     OID_PNP_SET_POWER,
 };
 
-#define INITIALIZE_NDIS_OBJ_HEADER(obj, type) do {               \
-    (obj).Header.Type = NDIS_OBJECT_TYPE_ ## type ;              \
-    (obj).Header.Revision = NDIS_ ## type ## _REVISION_1;        \
-    (obj).Header.Size = sizeof(obj);                             \
-} while (0)
-
-NTSTATUS AllocAdapter(OUT PADAPTER *Adapter)
-{
-    if (Adapter == NULL)
-        return STATUS_INVALID_PARAMETER;
-
-    *Adapter = (PADAPTER)ExAllocatePoolWithTag(NonPagedPool, sizeof (ADAPTER), 
' TEN');
-    if (*Adapter == NULL)
-        return STATUS_INSUFFICIENT_RESOURCES;
-
-    return STATUS_SUCCESS;
-}
-
-//
-// Scatter gather allocate handler callback.
-// Should never get called.
-//
 __drv_functionClass(MINIPORT_ALLOCATE_SHARED_MEM_COMPLETE)
 static VOID
-AdapterAllocateComplete (
+AdapterAllocateComplete(
     IN NDIS_HANDLE              MiniportAdapterContext,
     IN PVOID                    VirtualAddress,
     IN PNDIS_PHYSICAL_ADDRESS   PhysicalAddress,
@@ -168,139 +139,33 @@ AdapterAllocateComplete (
     UNREFERENCED_PARAMETER(Context);
 
     ASSERT(FALSE);
-
-    return;
-}
-
-//
-// Required NDIS6 handler.
-// Should never get called.
-//
-VOID
-AdapterCancelOidRequest (
-    IN  NDIS_HANDLE NdisHandle,
-    IN  PVOID       RequestId
-    )
-{
-    UNREFERENCED_PARAMETER(NdisHandle);
-    UNREFERENCED_PARAMETER(RequestId);
-
-    return;
-}
-
-//
-// Required NDIS6 handler.
-// Should never get called.
-//
-
-VOID 
-AdapterCancelSendNetBufferLists (
-    IN  NDIS_HANDLE NdisHandle,
-    IN  PVOID       CancelId
-    )
-{
-    UNREFERENCED_PARAMETER(NdisHandle);
-    UNREFERENCED_PARAMETER(CancelId);
-
-    return;
-}
-
-BOOLEAN 
-AdapterCheckForHang (
-    IN  NDIS_HANDLE NdisHandle
-    )
-{
-    UNREFERENCED_PARAMETER(NdisHandle);
-
-    return FALSE;
-}
-
-//
-// Frees resources obtained by AdapterInitialize.
-//
-VOID
-AdapterCleanup (
-    IN  PADAPTER Adapter
-    )
-{
-    Trace("====>\n");
-
-    TransmitterDelete(&Adapter->Transmitter);
-    ReceiverCleanup(&Adapter->Receiver);
-
-    if (Adapter->NdisDmaHandle != NULL)
-        NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
-
-    XENVIF_VIF(Release, &Adapter->VifInterface);
-    Adapter->AcquiredInterfaces = FALSE;
-
-    Trace("<====\n");
-    return;
 }
 
+__drv_functionClass(MINIPORT_PROCESS_SG_LIST)
 static VOID
-AdapterMediaStateChange(
-    IN  PADAPTER                Adapter
+AdapterProcessSGList(
+    IN PDEVICE_OBJECT           DeviceObject,
+    IN PVOID                    Reserved,
+    IN PSCATTER_GATHER_LIST     SGL,
+    IN PVOID                    Context
     )
 {
-    NDIS_LINK_STATE             LinkState;
-    NDIS_STATUS_INDICATION      StatusIndication;
-
-    NdisZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE));
-
-    LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1;
-    LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
-    LinkState.Header.Size = sizeof(NDIS_LINK_STATE);
-
-    XENVIF_VIF(MacQueryState,
-               &Adapter->VifInterface,
-               &LinkState.MediaConnectState,
-               &LinkState.RcvLinkSpeed,
-               &LinkState.MediaDuplexState);
-
-    if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
-        Info("LINK: STATE UNKNOWN\n");
-    } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
-        Info("LINK: DOWN\n");
-    } else {
-        ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
-
-        if (LinkState.MediaDuplexState == MediaDuplexStateHalf) 
-            Info("LINK: UP: SPEED=%u DUPLEX=HALF\n", LinkState.RcvLinkSpeed);
-        else if (LinkState.MediaDuplexState == MediaDuplexStateFull)
-            Info("LINK: UP: SPEED=%u DUPLEX=FULL\n", LinkState.RcvLinkSpeed);
-        else
-            Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n", 
LinkState.RcvLinkSpeed);
-    }
-
-    LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
-
-    NdisZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION));
-
-    StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
-    StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
-    StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION);
-    StatusIndication.SourceHandle = Adapter->NdisAdapterHandle;
-    StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE;
-    StatusIndication.StatusBuffer = &LinkState;
-    StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE);
+    UNREFERENCED_PARAMETER(DeviceObject);
+    UNREFERENCED_PARAMETER(Reserved);
+    UNREFERENCED_PARAMETER(SGL);
+    UNREFERENCED_PARAMETER(Context);
 
-    NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
+    ASSERT(FALSE);
 }
 
-
-//
-// Initializes adapter by allocating required resources and connects to 
-// netback.
-//
-
 static VOID
 AdapterVifCallback(
     IN  PVOID                       Context,
     IN  XENVIF_VIF_CALLBACK_TYPE    Type,
-    ...)
+    ...
+    )
 {
-    PADAPTER                        Adapter = Context;
+    PXENNET_ADAPTER                 Adapter = Context;
     va_list                         Arguments;
 
     va_start(Arguments, Type);
@@ -319,7 +184,7 @@ AdapterVifCallback(
 
         List = va_arg(Arguments, PLIST_ENTRY);
 
-        ReceiverReceivePackets(&Adapter->Receiver, List);
+        ReceiverReceivePackets(Adapter->Receiver, List);
         break;
     }
     case XENVIF_MAC_STATE_CHANGE: {
@@ -331,39 +196,220 @@ AdapterVifCallback(
     va_end(Arguments);
 }
 
-NDIS_STATUS
-AdapterGetAdvancedSettings(
-    IN PADAPTER pAdapter
+#define SERVICES_KEY        
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"
+
+static FORCEINLINE NTSTATUS
+__QueryInterface(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  const WCHAR     *ProviderName,
+    IN  const CHAR      *InterfaceName,
+    IN  const GUID      *Guid,
+    IN  ULONG           Version,
+    OUT PINTERFACE      Interface,
+    IN  ULONG           Size,
+    IN  BOOLEAN         Optional
     )
 {
-    NDIS_CONFIGURATION_OBJECT configObject;
-    NDIS_HANDLE hConfigurationHandle;
-    NDIS_STRING ndisValue;
-    PNDIS_CONFIGURATION_PARAMETER pNdisData;
-    NDIS_STATUS ndisStatus;
-    NTSTATUS status;
+    UNICODE_STRING      Unicode;
+    HANDLE              InterfacesKey;
+    HANDLE              SubscriberKey;
+    KEVENT              Event;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) +
+                                      1 +
+                                      wcslen(ProviderName) +
+                                      1 +
+                                      wcslen(L"Interfaces") +
+                                      1) * sizeof (WCHAR));
+
+    Unicode.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                           Unicode.MaximumLength,
+                                           'TEN');
+
+    status = STATUS_NO_MEMORY;
+    if (Unicode.Buffer == NULL)
+        goto fail1;
+
+    status = RtlStringCbPrintfW(Unicode.Buffer,
+                                Unicode.MaximumLength,
+                                SERVICES_KEY L"\\%ws\\Interfaces",
+                                ProviderName);
+    ASSERT(NT_SUCCESS(status));
 
-    configObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
-    configObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
-    configObject.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
-    configObject.NdisHandle = pAdapter->NdisAdapterHandle;
-    configObject.Flags = 0;
+    Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR));
 
-    ndisStatus = NdisOpenConfigurationEx(&configObject, &hConfigurationHandle);
+    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RegistryCreateSubKey(InterfacesKey, 
+                                  "XENNET", 
+                                  REG_OPTION_NON_VOLATILE, 
+                                  &SubscriberKey);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+                   
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+                                       DeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &StatusBlock);
 
     status = STATUS_UNSUCCESSFUL;
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
+    if (Irp == NULL)
+        goto fail4;
+
+    StackLocation = IoGetNextIrpStackLocation(Irp);
+    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+
+    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
+    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
+    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
+    StackLocation->Parameters.QueryInterface.Interface = Interface;
+    
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+    status = IoCallDriver(DeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = StatusBlock.Status;
+    }
+
+    if (!NT_SUCCESS(status)) {
+        if (status == STATUS_NOT_SUPPORTED && Optional)
+            goto done;
+
+        goto fail5;
+    }
+
+    status = RegistryUpdateDwordValue(SubscriberKey,
+                                      (PCHAR)InterfaceName,
+                                      Version);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
+done:
+    RegistryCloseKey(SubscriberKey);
+
+    RegistryCloseKey(InterfacesKey);
+
+    ExFreePool(Unicode.Buffer);
+
+    return STATUS_SUCCESS;
+
+fail6:
+    Error("fail6\n");
+
+fail5:
+    Error("fail5\n");
+
+fail4:
+    Error("fail4\n");
+
+    RegistryCloseKey(SubscriberKey);
+
+fail3:
+    Error("fail3\n");
+
+    RegistryCloseKey(InterfacesKey);
+
+fail2:
+    Error("fail2\n");
+
+    ExFreePool(Unicode.Buffer);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+#define QUERY_INTERFACE(                                                       
         \
+    _DeviceObject,                                                             
         \
+    _ProviderName,                                                             
         \
+    _InterfaceName,                                                            
         \
+    _Version,                                                                  
         \
+    _Interface,                                                                
         \
+    _Size,                                                                     
         \
+    _Optional)                                                                 
         \
+    __QueryInterface((_DeviceObject),                                          
         \
+                     L ## #_ProviderName,                                      
         \
+                     #_InterfaceName,                                          
         \
+                     &GUID_ ## _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE,      \
+                     (_Version),                                               
         \
+                     (_Interface),                                             
         \
+                     (_Size),                                                  
         \
+                     (_Optional))
+
+static FORCEINLINE NDIS_STATUS
+AdapterSetRegistrationAttributes(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES Attribs;
+    NDIS_STATUS                                   status;
+
+    RtlZeroMemory(&Attribs, 
sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
+    Attribs.Header.Type                 = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
+    Attribs.Header.Size                 = 
sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
+    Attribs.Header.Revision             = 
NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
+    Attribs.MiniportAdapterContext      = (NDIS_HANDLE)Adapter;
+    Attribs.AttributeFlags              = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER |
+                                          
NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
+    Attribs.CheckForHangTimeInSeconds   = 0;
+    Attribs.InterfaceType               = XENNET_INTERFACE_TYPE;
+
+    status = NdisMSetMiniportAttributes(Adapter->NdisHandle,
+                                        
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+    return status;
+}
+
+static FORCEINLINE NDIS_STATUS
+AdapterGetAdvancedSettings(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    NDIS_CONFIGURATION_OBJECT   Config;
+    NDIS_HANDLE                 Handle;
+    NDIS_STRING                 Value;
+    PNDIS_CONFIGURATION_PARAMETER Data;
+    NDIS_STATUS                 NdisStatus;
+
+    RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT));
+    Config.Header.Type      = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
+    Config.Header.Size      = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
+    Config.Header.Revision  = NDIS_CONFIGURATION_OBJECT_REVISION_1;
+    Config.NdisHandle       = Adapter->NdisHandle;
+    Config.Flags            = 0;
+
+    NdisStatus = NdisOpenConfigurationEx(&Config, &Handle);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
         goto fail1;
 
-#define read_property(field, name, default_val) \
-    do { \
-        RtlInitUnicodeString(&ndisValue, name); \
-        NdisReadConfiguration(&ndisStatus, &pNdisData, hConfigurationHandle, 
&ndisValue, NdisParameterInteger); \
-        if (ndisStatus == NDIS_STATUS_SUCCESS) { \
-            pAdapter->Properties.field = pNdisData->ParameterData.IntegerData; 
\
-        } else { \
-            pAdapter->Properties.field = default_val; \
-        } \
+#define read_property(_field, _name, _default_val)                             
             \
+    do {                                                                       
             \
+        RtlInitUnicodeString(&Value, _name);                                   
             \
+        NdisReadConfiguration(&NdisStatus, &Data, Handle, &Value, 
NdisParameterInteger);    \
+        if (NdisStatus == NDIS_STATUS_SUCCESS) {                               
             \
+            Adapter->Properties._field = Data->ParameterData.IntegerData;      
             \
+        } else {                                                               
             \
+            Adapter->Properties._field = _default_val;                         
             \
+        }                                                                      
             \
     } while (FALSE);
 
     read_property(ipv4_csum, L"*IPChecksumOffloadIPv4", 3);
@@ -377,465 +423,827 @@ AdapterGetAdvancedSettings(
     read_property(lrov6, L"LROIPv6", 1);
     read_property(need_csum_value, L"NeedChecksumValue", 1);
 
-    NdisCloseConfiguration(hConfigurationHandle);
-
+    NdisCloseConfiguration(Handle);
     return NDIS_STATUS_SUCCESS;
 
 fail1:
-    Error("fail1\n");
-    return NDIS_STATUS_FAILURE;
+    Error("fail1 (%08x)\n", NdisStatus);
+    return NdisStatus;
 }
 
-NDIS_STATUS 
-AdapterInitialize (
-    IN  PADAPTER    Adapter,
-    IN  NDIS_HANDLE AdapterHandle
+static FORCEINLINE NDIS_STATUS
+AdapterSetGeneralAttributes(
+    IN  PXENNET_ADAPTER         Adapter
     )
 {
-    NDIS_STATUS ndisStatus;
-    NDIS_SG_DMA_DESCRIPTION DmaDescription;
-    NTSTATUS status;
-
-    status = XENVIF_VIF(Acquire, &Adapter->VifInterface);
-    if (!NT_SUCCESS(status))
-        return NDIS_STATUS_FAILURE;
+    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES    Attribs;
 
-    Adapter->AcquiredInterfaces = TRUE;
+    XENVIF_VIF(MacQueryMaximumFrameSize,
+               &Adapter->VifInterface,
+               (PULONG)&Adapter->MaximumFrameSize);
 
-    Trace("====>\n");
+    RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
+
+    Attribs.Header.Type         = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
+    Attribs.Header.Size         = 
sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
+    Attribs.Header.Revision     = 
NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
+    Attribs.MediaType               = XENNET_MEDIA_TYPE;
+    Attribs.MtuSize                 = Adapter->MaximumFrameSize - sizeof 
(ETHERNET_TAGGED_HEADER);
+    Attribs.MaxXmitLinkSpeed        = XENNET_MEDIA_MAX_SPEED;
+    Attribs.MaxRcvLinkSpeed         = XENNET_MEDIA_MAX_SPEED;
+    Attribs.XmitLinkSpeed           = XENNET_MEDIA_MAX_SPEED;
+    Attribs.RcvLinkSpeed            = XENNET_MEDIA_MAX_SPEED;
+    Attribs.MediaConnectState       = MediaConnectStateConnected;
+    Attribs.MediaDuplexState        = MediaDuplexStateFull;
+    Attribs.LookaheadSize           = Adapter->MaximumFrameSize;
+    Attribs.PowerManagementCapabilities = &Adapter->Capabilities;
+    Attribs.MacOptions              = XENNET_MAC_OPTIONS;
+    Attribs.SupportedPacketFilters  = XENNET_SUPPORTED_PACKET_FILTERS;
+    Attribs.MaxMulticastListSize    = 32;
+    Attribs.MacAddressLength        = ETHERNET_ADDRESS_LENGTH;
+    Attribs.PhysicalMediumType      = NdisPhysicalMedium802_3;
+    Attribs.RecvScaleCapabilities   = NULL;
+    Attribs.AccessType              = NET_IF_ACCESS_BROADCAST;
+    Attribs.DirectionType           = NET_IF_DIRECTION_SENDRECEIVE;
+    Attribs.ConnectionType          = NET_IF_CONNECTION_DEDICATED;
+    Attribs.IfType                  = IF_TYPE_ETHERNET_CSMACD; 
+    Attribs.IfConnectorPresent      = TRUE;
+    Attribs.SupportedStatistics     = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
+                                      NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
+                                      
NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
+                                      
NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED |
+                                      
NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
+                                      
NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
+                                      
NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED |
+                                      
NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
+                                      NDIS_STATISTICS_RCV_OK_SUPPORTED |
+                                      NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
+                                      
NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
+                                      
NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
+                                      
NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
+                                      
NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED |
+                                      
NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
+                                      
NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED |
+                                      NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
+    Attribs.SupportedOidList        = XennetSupportedOids;
+    Attribs.SupportedOidListLength  = sizeof(XennetSupportedOids);
 
-    Adapter->NdisAdapterHandle = AdapterHandle;
+    XENVIF_VIF(MacQueryPermanentAddress,
+               &Adapter->VifInterface,
+               (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress);
+    XENVIF_VIF(MacQueryCurrentAddress,
+               &Adapter->VifInterface,
+               (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
 
-    RtlZeroMemory(&Adapter->Capabilities, sizeof (Adapter->Capabilities));
+    return NdisMSetMiniportAttributes(Adapter->NdisHandle,
+                                      
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+}
 
-    Adapter->Transmitter = (PTRANSMITTER)ExAllocatePoolWithTag(NonPagedPool, 
sizeof(TRANSMITTER), ' TEN');
-    if (!Adapter->Transmitter) {
-        ndisStatus = NDIS_STATUS_RESOURCES;
-        goto exit;
+static FORCEINLINE NDIS_STATUS
+AdapterSetOffloadAttributes(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES    Attribs;
+    PXENVIF_VIF_OFFLOAD_OPTIONS                 RxOptions;
+    PXENVIF_VIF_OFFLOAD_OPTIONS                 TxOptions;
+    NDIS_OFFLOAD                                Default;
+    NDIS_OFFLOAD                                Supported;
+
+    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
+    RxOptions->Value = 0;
+    RxOptions->OffloadTagManipulation = 1;
+
+    if (Adapter->Properties.need_csum_value) {
+        RxOptions->NeedChecksumValue = 1;
     }
-
-    RtlZeroMemory(Adapter->Transmitter, sizeof (TRANSMITTER));
-
-    ndisStatus = ReceiverInitialize(&Adapter->Receiver);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+    if (Adapter->Properties.lrov4) {
+        RxOptions->OffloadIpVersion4LargePacket = 1;
+        RxOptions->NeedLargePacketSplit = 1;
     }
-
-    ndisStatus = TransmitterInitialize(Adapter->Transmitter, Adapter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+    if (Adapter->Properties.lrov6) {
+        RxOptions->OffloadIpVersion6LargePacket = 1;
+        RxOptions->NeedLargePacketSplit = 1;
     }
+    XENVIF_VIF(ReceiverSetOffloadOptions,
+               &Adapter->VifInterface,
+               *RxOptions);
 
-    ndisStatus = AdapterGetAdvancedSettings(Adapter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
+    XENVIF_VIF(TransmitterQueryOffloadOptions,
+               &Adapter->VifInterface,
+               TxOptions);
+
+    RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD));
+    Supported.Header.Type       = NDIS_OBJECT_TYPE_OFFLOAD;
+    Supported.Header.Size       = sizeof(NDIS_OFFLOAD);
+    Supported.Header.Revision   = NDIS_OFFLOAD_REVISION_1;
+
+    Supported.Checksum.IPv4Receive.Encapsulation        = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    Supported.Checksum.IPv4Receive.IpChecksum           = 1;
+    Supported.Checksum.IPv4Receive.IpOptionsSupported   = 1;
+    Supported.Checksum.IPv4Receive.TcpChecksum          = 1;
+    Supported.Checksum.IPv4Receive.TcpOptionsSupported  = 1;
+    Supported.Checksum.IPv4Receive.UdpChecksum          = 1;
+
+    Supported.Checksum.IPv6Receive.Encapsulation        = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+    Supported.Checksum.IPv6Receive.TcpChecksum          = 1;
+    Supported.Checksum.IPv6Receive.TcpOptionsSupported  = 1;
+    Supported.Checksum.IPv6Receive.UdpChecksum          = 1;
+
+    Supported.Checksum.IPv4Transmit.Encapsulation       = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    if (TxOptions->OffloadIpVersion4HeaderChecksum) {
+        Supported.Checksum.IPv4Transmit.IpChecksum          = 1;
+        Supported.Checksum.IPv4Transmit.IpOptionsSupported  = 1;
     }
-
-    ndisStatus = AdapterSetRegistrationAttributes(Adapter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+    if (TxOptions->OffloadIpVersion4TcpChecksum) {
+        Supported.Checksum.IPv4Transmit.TcpChecksum         = 1;
+        Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+    }
+    if (TxOptions->OffloadIpVersion4UdpChecksum) {
+        Supported.Checksum.IPv4Transmit.UdpChecksum         = 1;
     }
 
-    ndisStatus = AdapterSetGeneralAttributes(Adapter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+    Supported.Checksum.IPv6Transmit.Encapsulation       = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+    if (TxOptions->OffloadIpVersion6TcpChecksum) {
+        Supported.Checksum.IPv6Transmit.TcpChecksum         = 1;
+        Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+    }
+    if (TxOptions->OffloadIpVersion6UdpChecksum) {
+        Supported.Checksum.IPv6Transmit.UdpChecksum         = 1;
     }
 
-    ndisStatus = AdapterSetOffloadAttributes(Adapter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+    if (TxOptions->OffloadIpVersion4LargePacket) {
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   4,
+                   &Supported.LsoV2.IPv4.MaxOffLoadSize);
+        Supported.LsoV2.IPv4.Encapsulation              = 
NDIS_ENCAPSULATION_IEEE_802_3;
+        Supported.LsoV2.IPv4.MinSegmentCount            = 2;
     }
 
-    NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));
+    if (TxOptions->OffloadIpVersion6LargePacket) {
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   6,
+                   &Supported.LsoV2.IPv6.MaxOffLoadSize);
+        Supported.LsoV2.IPv6.Encapsulation              = 
NDIS_ENCAPSULATION_IEEE_802_3;
+        Supported.LsoV2.IPv6.MinSegmentCount            = 2;
+        Supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
+        Supported.LsoV2.IPv6.TcpOptionsSupported        = 1;
+    }
 
-    DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
-    DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;
-    DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);
-    DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;
-    DmaDescription.MaximumPhysicalMapping = 65536;    
-    DmaDescription.ProcessSGListHandler = AdapterProcessSGList;
-    DmaDescription.SharedMemAllocateCompleteHandler = AdapterAllocateComplete;
+    Default = Supported;
 
-    ndisStatus = NdisMRegisterScatterGatherDma(Adapter->NdisAdapterHandle,
-                                               &DmaDescription,
-                                               &Adapter->NdisDmaHandle);
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        Adapter->NdisDmaHandle = NULL;
+    if (!(Adapter->Properties.ipv4_csum & 2))
+        Default.Checksum.IPv4Receive.IpChecksum = 0;
+    if (!(Adapter->Properties.tcpv4_csum & 2))
+        Default.Checksum.IPv4Receive.TcpChecksum = 0;
+    if (!(Adapter->Properties.udpv4_csum & 2))
+        Default.Checksum.IPv4Receive.UdpChecksum = 0;
+    if (!(Adapter->Properties.tcpv6_csum & 2))
+        Default.Checksum.IPv6Receive.TcpChecksum = 0;
+    if (!(Adapter->Properties.udpv6_csum & 2))
+        Default.Checksum.IPv6Receive.UdpChecksum = 0;
+    if (!(Adapter->Properties.ipv4_csum & 1))
+        Default.Checksum.IPv4Transmit.IpChecksum = 0;
+    if (!(Adapter->Properties.tcpv4_csum & 1))
+        Default.Checksum.IPv4Transmit.TcpChecksum = 0;
+    if (!(Adapter->Properties.udpv4_csum & 1))
+        Default.Checksum.IPv4Transmit.UdpChecksum = 0;
+    if (!(Adapter->Properties.tcpv6_csum & 1))
+        Default.Checksum.IPv6Transmit.TcpChecksum = 0;
+    if (!(Adapter->Properties.udpv6_csum & 1))
+        Default.Checksum.IPv6Transmit.UdpChecksum = 0;
+    if (!(Adapter->Properties.lsov4)) {
+        Default.LsoV2.IPv4.MaxOffLoadSize = 0;
+        Default.LsoV2.IPv4.MinSegmentCount = 0;
+    }
+    if (!(Adapter->Properties.lsov6)) {
+        Default.LsoV2.IPv6.MaxOffLoadSize = 0;
+        Default.LsoV2.IPv6.MinSegmentCount = 0;
+    }
 
-    ASSERT(!Adapter->Enabled);
-    status = XENVIF_VIF(Enable,
-                        &Adapter->VifInterface,
-                        AdapterVifCallback,
-                        Adapter);
-    if (NT_SUCCESS(status)) {
-        TransmitterEnable(Adapter->Transmitter);
-        Adapter->Enabled = TRUE;
-        ndisStatus = NDIS_STATUS_SUCCESS;
-    } else {
-        ndisStatus = NDIS_STATUS_FAILURE;
+    if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof(NDIS_OFFLOAD))) {
+        Adapter->Offload = Default;
+        //DISPLAY_OFFLOAD(Default);
     }
 
-exit:
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        XENVIF_VIF(Release, &Adapter->VifInterface);
+    RtlZeroMemory(&Attribs, sizeof(Attribs));
+    Attribs.Header.Type         = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
+    Attribs.Header.Size         = sizeof(Attribs);
+    Attribs.Header.Revision     = 
NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
+    Attribs.DefaultOffloadConfiguration = &Default;
+    Attribs.HardwareOffloadCapabilities = &Supported;
 
-    Trace("<==== (%08x)\n", ndisStatus);
-    return ndisStatus;
+    return NdisMSetMiniportAttributes(Adapter->NdisHandle,
+                                      
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
 }
 
-//
-// Scatter gather process handler callback.
-// Should never get called.
-//
 static VOID
-AdapterProcessSGList (
-    IN PDEVICE_OBJECT       DeviceObject,
-    IN PVOID                Reserved,
-    IN PSCATTER_GATHER_LIST SGL,
-    IN PVOID                Context
+AdapterIndicateOffloadChanged(
+    IN  PXENNET_ADAPTER         Adapter
     )
 {
-    UNREFERENCED_PARAMETER(DeviceObject);
-    UNREFERENCED_PARAMETER(Reserved);
-    UNREFERENCED_PARAMETER(SGL);
-    UNREFERENCED_PARAMETER(Context);
-
-    ASSERT(FALSE);
-
-    return;
-}
+    NDIS_STATUS_INDICATION      Indication;
+    NDIS_OFFLOAD                Offload;
+    PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions;
+    PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions;
 
-//
-// Get\Set OID handler.
-//
-NDIS_STATUS 
-AdapterOidRequest (
-    IN  NDIS_HANDLE         NdisHandle,
-    IN  PNDIS_OID_REQUEST   NdisRequest
-    )
-{
-    NDIS_STATUS ndisStatus;
-    PADAPTER Adapter = (PADAPTER)NdisHandle;
+    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
 
-    switch (NdisRequest->RequestType) {
-        case NdisRequestSetInformation:            
-            ndisStatus = AdapterSetInformation(Adapter, NdisRequest);
-            break;
-                
-        case NdisRequestQueryInformation:
-        case NdisRequestQueryStatistics:
-            ndisStatus = AdapterQueryInformation(Adapter, NdisRequest);
-            break;
+    RtlZeroMemory(&Offload, sizeof(NDIS_OFFLOAD));
+    Offload.Header.Type         = NDIS_OBJECT_TYPE_OFFLOAD;
+    Offload.Header.Size         = sizeof(NDIS_OFFLOAD);
+    Offload.Header.Revision     = NDIS_OFFLOAD_REVISION_1;
+    
+    Offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+    if (RxOptions->OffloadIpVersion4HeaderChecksum) {
+        Offload.Checksum.IPv4Receive.IpChecksum = 1;
+        Offload.Checksum.IPv4Receive.IpOptionsSupported = 1;
+    }
+    if (RxOptions->OffloadIpVersion4TcpChecksum) {
+        Offload.Checksum.IPv4Receive.TcpChecksum = 1;
+        Offload.Checksum.IPv4Receive.TcpOptionsSupported = 1;
+    }
+    if (RxOptions->OffloadIpVersion4UdpChecksum) {
+        Offload.Checksum.IPv4Receive.UdpChecksum = 1;
+    }
 
-        default:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-            break;
-    };
+    Offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+    Offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+    if (RxOptions->OffloadIpVersion6TcpChecksum) {
+        Offload.Checksum.IPv6Receive.TcpChecksum = 1;
+        Offload.Checksum.IPv6Receive.TcpOptionsSupported = 1;
+    }
+    if (RxOptions->OffloadIpVersion6UdpChecksum) {
+        Offload.Checksum.IPv6Receive.UdpChecksum = 1;
+    }
 
-    return ndisStatus;
-}
+    XENVIF_VIF(ReceiverSetOffloadOptions,
+               &Adapter->VifInterface,
+               *RxOptions);
 
-//
-// Temporarily pauses adapter.
-//
-NDIS_STATUS
-AdapterPause (
-    IN  NDIS_HANDLE                     NdisHandle,
-    IN  PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters
-    )
-{
-    PADAPTER Adapter = (PADAPTER)NdisHandle;
-    UNREFERENCED_PARAMETER(MiniportPauseParameters);
+    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
 
-    Trace("====>\n");
+    Offload.Checksum.IPv4Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    if (TxOptions->OffloadIpVersion4HeaderChecksum) {
+        Offload.Checksum.IPv4Transmit.IpChecksum = 1;
+        Offload.Checksum.IPv4Transmit.IpOptionsSupported = 1;
+    }
+    if (TxOptions->OffloadIpVersion4TcpChecksum) {
+        Offload.Checksum.IPv4Transmit.TcpChecksum = 1;
+        Offload.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+    }
+    if (TxOptions->OffloadIpVersion4UdpChecksum) {
+        Offload.Checksum.IPv4Transmit.UdpChecksum = 1;
+    }
 
-    if (!Adapter->Enabled)
-        goto done;
+    Offload.Checksum.IPv6Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    Offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+    if (TxOptions->OffloadIpVersion6TcpChecksum) {
+        Offload.Checksum.IPv6Transmit.TcpChecksum = 1;
+        Offload.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+    }
+    if (TxOptions->OffloadIpVersion6UdpChecksum) {
+        Offload.Checksum.IPv6Transmit.UdpChecksum = 1;
+    }
 
-    XENVIF_VIF(Disable,
-               &Adapter->VifInterface);
+    if (TxOptions->OffloadIpVersion4LargePacket) {
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   4,
+                   &Offload.LsoV2.IPv4.MaxOffLoadSize);
+        Offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+        Offload.LsoV2.IPv4.MinSegmentCount = 2;
+    }
+    if (TxOptions->OffloadIpVersion6LargePacket) {
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   6,
+                   &Offload.LsoV2.IPv6.MaxOffLoadSize);
+        Offload.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+        Offload.LsoV2.IPv6.MinSegmentCount = 2;
+        Offload.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
+        Offload.LsoV2.IPv6.TcpOptionsSupported = 1;
+    }
 
-    AdapterMediaStateChange(Adapter);
+    if (!RtlEqualMemory(&Adapter->Offload, &Offload, sizeof (NDIS_OFFLOAD))) {
+        Adapter->Offload = Offload;
+        //DISPLAY_OFFLOAD(Offload);
+    }
 
-    Adapter->Enabled = FALSE;
+    RtlZeroMemory(&Indication, sizeof(Indication));
+    Indication.Header.Type      = NDIS_OBJECT_TYPE_STATUS_INDICATION;
+    Indication.Header.Size      = sizeof(Indication);
+    Indication.Header.Revision  = NDIS_STATUS_INDICATION_REVISION_1;
+    Indication.SourceHandle     = Adapter->NdisHandle;
+    Indication.StatusCode       = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG;
+    Indication.StatusBuffer     = &Offload;
+    Indication.StatusBufferSize = sizeof(Offload);
 
-done:
-    Trace("<====\n");
-    return NDIS_STATUS_SUCCESS;
+    NdisMIndicateStatusEx(Adapter->NdisHandle, &Indication);
 }
 
-//
-// Handles PNP and Power events. NOP.
-//
-VOID 
-AdapterPnPEventHandler (
-    IN  NDIS_HANDLE             NdisHandle,
-    IN  PNET_DEVICE_PNP_EVENT   NetDevicePnPEvent
+static NDIS_STATUS
+AdapterSetPacketFilter(
+    IN  PXENNET_ADAPTER         Adapter,
+    IN  PULONG                  PacketFilter
     )
 {
-    UNREFERENCED_PARAMETER(NdisHandle);
+    XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel;
+    XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
+    XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
 
+    if (*PacketFilter & ~XENNET_SUPPORTED_PACKET_FILTERS)
+        return NDIS_STATUS_INVALID_PARAMETER;
 
-    switch (NetDevicePnPEvent->DevicePnPEvent) {
-        case NdisDevicePnPEventQueryRemoved:
-            break;
+    if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
+        UnicastFilterLevel = XENVIF_MAC_FILTER_ALL;
+        MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
+        BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
+        goto done;
+    }
 
-        case NdisDevicePnPEventRemoved:
-            break;       
+    if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED)
+        UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
+    else
+        UnicastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
-        case NdisDevicePnPEventSurpriseRemoved:
-            break;
+    if (*PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
+        MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
+    else if (*PacketFilter & NDIS_PACKET_TYPE_MULTICAST)
+        MulticastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
+    else
+        MulticastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
-        case NdisDevicePnPEventQueryStopped:
-            break;
+    if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
+        BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
+    else
+        BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
-        case NdisDevicePnPEventStopped:
-            break;      
-            
-        case NdisDevicePnPEventPowerProfileChanged:
-            break;      
-            
-        default:
-            break;         
-    };
+done:
+    XENVIF_VIF(MacSetFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_UNICAST,
+               UnicastFilterLevel);
+
+    XENVIF_VIF(MacSetFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_MULTICAST,
+               MulticastFilterLevel);
+
+    XENVIF_VIF(MacSetFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_BROADCAST,
+               BroadcastFilterLevel);
 
-    return;
+    return NDIS_STATUS_SUCCESS;
 }
 
-//
-// Reports general statistics to NDIS.
-//
-static NDIS_STATUS 
-AdapterQueryGeneralStatistics (
-    IN  PADAPTER                Adapter,
-    IN  PNDIS_STATISTICS_INFO   NdisStatisticsInfo
+static NDIS_STATUS
+AdapterSetMulticastAddresses(
+    IN  PXENNET_ADAPTER         Adapter,
+    IN  PETHERNET_ADDRESS       Address,
+    IN  ULONG                   Count
     )
 {
-    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
-    ULONGLONG   Value;
-
-    NdisZeroMemory(NdisStatisticsInfo, sizeof(NDIS_STATISTICS_INFO));
-    NdisStatisticsInfo->Header.Revision = NDIS_OBJECT_REVISION_1;
-    NdisStatisticsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
-    NdisStatisticsInfo->Header.Size = sizeof(NDIS_STATISTICS_INFO);
+    NTSTATUS status;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR;
+    status = XENVIF_VIF(MacSetMulticastAddresses,
+                        &Adapter->VifInterface,
+                        Address,
+                        Count);
+    if (!NT_SUCCESS(status))
+        return NDIS_STATUS_INVALID_DATA;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_BACKEND_ERRORS,
-                      &Value);
+    return NDIS_STATUS_SUCCESS;
+}
 
-    NdisStatisticsInfo->ifInErrors = Value;
+static NDIS_STATUS
+AdapterSetOffloadEncapsulation(
+    IN  PXENNET_ADAPTER             Adapter,
+    IN  PNDIS_OFFLOAD_ENCAPSULATION Encapsulation
+    )
+{
+    XENVIF_VIF_OFFLOAD_OPTIONS  Options;
+    PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions;
+    PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_FRONTEND_ERRORS,
-                      &Value);
+    if (Encapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON &&
+        Encapsulation->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
+        goto fail1;
+    if (Encapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON &&
+        Encapsulation->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
+        goto fail2;
 
-    NdisStatisticsInfo->ifInErrors += Value;
+    XENVIF_VIF(TransmitterQueryOffloadOptions,
+                &Adapter->VifInterface,
+                &Options);
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS;
+    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
+        
+    TxOptions->Value = 0;
+    TxOptions->OffloadTagManipulation = 1;
+
+    if ((Adapter->Properties.lsov4) && (Options.OffloadIpVersion4LargePacket))
+        TxOptions->OffloadIpVersion4LargePacket = 1;
+    if ((Adapter->Properties.lsov6) && (Options.OffloadIpVersion6LargePacket))
+        TxOptions->OffloadIpVersion6LargePacket = 1;
+    if ((Adapter->Properties.ipv4_csum & 1) && 
Options.OffloadIpVersion4HeaderChecksum)
+        TxOptions->OffloadIpVersion4HeaderChecksum = 1;
+    if ((Adapter->Properties.tcpv4_csum & 1) && 
Options.OffloadIpVersion4TcpChecksum)
+        TxOptions->OffloadIpVersion4TcpChecksum = 1;
+    if ((Adapter->Properties.udpv4_csum & 1) && 
Options.OffloadIpVersion4UdpChecksum)
+        TxOptions->OffloadIpVersion4UdpChecksum = 1;
+    if ((Adapter->Properties.tcpv6_csum & 1) && 
Options.OffloadIpVersion6TcpChecksum)
+        TxOptions->OffloadIpVersion6TcpChecksum = 1;
+    if ((Adapter->Properties.udpv6_csum & 1) && 
Options.OffloadIpVersion6UdpChecksum)
+        TxOptions->OffloadIpVersion6UdpChecksum = 1;
+
+    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
+
+    RxOptions->Value = 0;
+    RxOptions->OffloadTagManipulation = 1;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_PACKETS_DROPPED,
-                      &Value);
+    if (Adapter->Properties.need_csum_value)
+        RxOptions->NeedChecksumValue = 1;
+    if (Adapter->Properties.lrov4) {
+        RxOptions->OffloadIpVersion4LargePacket = 1;
+        RxOptions->NeedLargePacketSplit = 1;
+    }
+    if (Adapter->Properties.lrov6) {
+        RxOptions->OffloadIpVersion6LargePacket = 1;
+        RxOptions->NeedLargePacketSplit = 1;
+    }
+    if (Adapter->Properties.ipv4_csum & 2)
+        RxOptions->OffloadIpVersion4HeaderChecksum = 1;
+    if (Adapter->Properties.tcpv4_csum & 2)
+        RxOptions->OffloadIpVersion4TcpChecksum = 1;
+    if (Adapter->Properties.udpv4_csum & 2)
+        RxOptions->OffloadIpVersion4UdpChecksum = 1;
+    if (Adapter->Properties.tcpv6_csum & 2)
+        RxOptions->OffloadIpVersion6TcpChecksum = 1;
+    if (Adapter->Properties.udpv6_csum & 2)
+        RxOptions->OffloadIpVersion6UdpChecksum = 1;
+
+    AdapterIndicateOffloadChanged(Adapter);
+    return NDIS_STATUS_SUCCESS;
 
-    NdisStatisticsInfo->ifInDiscards = Value;
+fail2:
+    Error("fail2\n");
+fail1:
+    Error("fail1 (%08x)\n", NDIS_STATUS_INVALID_PARAMETER);
+    return NDIS_STATUS_INVALID_PARAMETER;
+}
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV;
+static NDIS_STATUS
+AdapterSetTcpOffloadParameters(
+    IN  PXENNET_ADAPTER             Adapter,
+    IN  PNDIS_OFFLOAD_PARAMETERS    Parameters
+    )
+{
+    BOOLEAN     Changed = FALSE;
+    PXENVIF_VIF_OFFLOAD_OPTIONS TxOptions;
+    PXENVIF_VIF_OFFLOAD_OPTIONS RxOptions;
+
+    if (Parameters->IPsecV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE ||
+        Parameters->LsoV1 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE ||
+        Parameters->TcpConnectionIPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE ||
+        Parameters->TcpConnectionIPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) {
+        goto fail1;
+    }
+    if (Parameters->LsoV2IPv4 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) {
+        XENVIF_VIF_OFFLOAD_OPTIONS  Options;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_UNICAST_OCTETS,
-                      &Value);
+        XENVIF_VIF(TransmitterQueryOffloadOptions,
+                    &Adapter->VifInterface,
+                    &Options);
 
-    NdisStatisticsInfo->ifHCInOctets = Value;
+        if (!(Options.OffloadIpVersion4LargePacket))
+            goto fail2;
+    }
+    if (Parameters->LsoV2IPv6 != NDIS_OFFLOAD_PARAMETERS_NO_CHANGE) {
+        XENVIF_VIF_OFFLOAD_OPTIONS  Options;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_MULTICAST_OCTETS,
-                      &Value);
+        XENVIF_VIF(TransmitterQueryOffloadOptions,
+                    &Adapter->VifInterface,
+                    &Options);
 
-    NdisStatisticsInfo->ifHCInOctets += Value;
+        if (!(Options.OffloadIpVersion6LargePacket))
+            goto fail3;
+    }
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_BROADCAST_OCTETS,
-                      &Value);
+    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
+    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
 
-    NdisStatisticsInfo->ifHCInOctets += Value;
+#define rx_enabled(x)       ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ||   
       \
+                             (x) == 
NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED)
+#define tx_enabled(x)       ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ||   
       \
+                             (x) == 
NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED)
+#define set_value(x, y)     ((x) == (y)) ? FALSE : ( ((x) = (y)) == (y) )
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV;
+    if (Parameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
+        Changed |= set_value(TxOptions->OffloadIpVersion4LargePacket, 1);
+    } else if (Parameters->LsoV2IPv4 == 
NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
+        Changed |= set_value(TxOptions->OffloadIpVersion4LargePacket, 0);
+    }
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_UNICAST_OCTETS,
-                      &Value);
+    if (Parameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
+        Changed |= set_value(TxOptions->OffloadIpVersion6LargePacket, 1);
+    } else if (Parameters->LsoV2IPv6 == 
NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
+        Changed |= set_value(TxOptions->OffloadIpVersion6LargePacket, 0);
+    }
 
-    NdisStatisticsInfo->ifHCInUcastOctets = Value;
+    if (tx_enabled(Parameters->IPv4Checksum)) {
+        Changed |= set_value(TxOptions->OffloadIpVersion4HeaderChecksum, 1);
+    } else {
+        Changed |= set_value(TxOptions->OffloadIpVersion4HeaderChecksum, 0);
+    }
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV;
+    if (tx_enabled(Parameters->TCPIPv4Checksum)) {
+        Changed |= set_value(TxOptions->OffloadIpVersion4TcpChecksum, 1);
+    } else {
+        Changed |= set_value(TxOptions->OffloadIpVersion4TcpChecksum, 0);
+    }
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_UNICAST_PACKETS,
-                      &Value);
+    if (tx_enabled(Parameters->UDPIPv4Checksum)) {
+        Changed |= set_value(TxOptions->OffloadIpVersion4UdpChecksum, 1);
+    } else {
+        Changed |= set_value(TxOptions->OffloadIpVersion4UdpChecksum, 0);
+    }
 
-    NdisStatisticsInfo->ifHCInUcastPkts = Value;
+    if (tx_enabled(Parameters->TCPIPv6Checksum)) {
+        Changed |= set_value(TxOptions->OffloadIpVersion6TcpChecksum, 1);
+    } else {
+        Changed |= set_value(TxOptions->OffloadIpVersion6TcpChecksum, 0);
+    }
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV;
+    if (tx_enabled(Parameters->UDPIPv6Checksum)) {
+        Changed |= set_value(TxOptions->OffloadIpVersion6UdpChecksum, 1);
+    } else {
+        Changed |= set_value(TxOptions->OffloadIpVersion6UdpChecksum, 0);
+    }
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_MULTICAST_OCTETS,
-                      &Value);
+    if (rx_enabled(Parameters->IPv4Checksum)) {
+        Changed |= set_value(RxOptions->OffloadIpVersion4HeaderChecksum, 1);
+    } else {
+        Changed |= set_value(RxOptions->OffloadIpVersion4HeaderChecksum, 0);
+    }
 
-    NdisStatisticsInfo->ifHCInMulticastOctets = Value;
+    if (rx_enabled(Parameters->TCPIPv4Checksum)) {
+        Changed |= set_value(RxOptions->OffloadIpVersion4TcpChecksum, 1);
+    } else {
+        Changed |= set_value(RxOptions->OffloadIpVersion4TcpChecksum, 0);
+    }
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV;
+    if (rx_enabled(Parameters->UDPIPv4Checksum)) {
+        Changed |= set_value(RxOptions->OffloadIpVersion4UdpChecksum, 1);
+    } else {
+        Changed |= set_value(RxOptions->OffloadIpVersion4UdpChecksum, 0);
+    }
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_MULTICAST_PACKETS,
-                      &Value);
+    if (rx_enabled(Parameters->TCPIPv6Checksum)) {
+        Changed |= set_value(RxOptions->OffloadIpVersion6TcpChecksum, 1);
+    } else {
+        Changed |= set_value(RxOptions->OffloadIpVersion6TcpChecksum, 0);
+    }
 
-    NdisStatisticsInfo->ifHCInMulticastPkts = Value;
+    if (rx_enabled(Parameters->UDPIPv6Checksum)) {
+        Changed |= set_value(RxOptions->OffloadIpVersion6UdpChecksum, 1);
+    } else {
+        Changed |= set_value(RxOptions->OffloadIpVersion6UdpChecksum, 0);
+    }
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV;
+#undef tx_enabled
+#undef rx_enabled
+#undef set_value
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_BROADCAST_OCTETS,
-                      &Value);
+    if (Changed)
+        AdapterIndicateOffloadChanged(Adapter);
 
-    NdisStatisticsInfo->ifHCInBroadcastOctets = Value;
+    return NDIS_STATUS_SUCCESS;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV;
+fail3:
+    Error("fail3\n");
+fail2:
+    Error("fail2\n");
+fail1:
+    Error("fail1 (%08x)\n", NDIS_STATUS_INVALID_PARAMETER);
+    return NDIS_STATUS_INVALID_PARAMETER;
+}
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_RECEIVER_BROADCAST_PACKETS,
-                      &Value);
+static NDIS_STATUS
+AdapterSetInformation(
+    IN  PXENNET_ADAPTER         Adapter,
+    IN  PNDIS_OID_REQUEST       Request
+    )
+{
+    PVOID           Buffer;
+    ULONG           BufferLength;
+    ULONG           BytesNeeded = 0;
+    ULONG           BytesRead   = 0;
+    NDIS_STATUS     NdisStatus  = NDIS_STATUS_SUCCESS;
 
-    NdisStatisticsInfo->ifHCInBroadcastPkts = Value;
+    Buffer          = Request->DATA.SET_INFORMATION.InformationBuffer;
+    BufferLength    = Request->DATA.SET_INFORMATION.InformationBufferLength;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR;
+    switch (Request->DATA.QUERY_INFORMATION.Oid) {
+        case OID_PNP_SET_POWER:
+            BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
+            break;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_BACKEND_ERRORS,
-                      &Value);
+        case OID_GEN_CURRENT_LOOKAHEAD:
+            BytesNeeded = sizeof(ULONG);
+            Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
+            if (BufferLength == sizeof(ULONG)) {
+                Adapter->CurrentLookahead = *(PULONG)Buffer;
+                BytesRead = sizeof(ULONG);
+            }
+            break;
 
-    NdisStatisticsInfo->ifOutErrors = Value;
+        case OID_GEN_CURRENT_PACKET_FILTER:
+            BytesNeeded = sizeof(ULONG);
+            if (BufferLength == sizeof(ULONG)) {
+                NdisStatus = AdapterSetPacketFilter(Adapter, (PULONG)Buffer);
+                BytesRead = sizeof(ULONG);
+            }
+            break;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_FRONTEND_ERRORS,
-                      &Value);
+        case OID_802_3_MULTICAST_LIST:
+            BytesNeeded = ETHERNET_ADDRESS_LENGTH;
+            if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
+                ULONG   Count = BufferLength / ETHERNET_ADDRESS_LENGTH;
+                NdisStatus = AdapterSetMulticastAddresses(Adapter, Buffer, 
Count);
+                BytesRead = BufferLength;
+            } else {
+                NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+            }
+            break;
 
-    NdisStatisticsInfo->ifOutErrors += Value;
+        case OID_OFFLOAD_ENCAPSULATION:
+            BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
+            if (BufferLength == sizeof(NDIS_OFFLOAD_ENCAPSULATION)) {
+                NdisStatus = AdapterSetOffloadEncapsulation(Adapter, Buffer);
+                BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
+            } else {
+                NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+            }
+            break;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT;
+        case OID_TCP_OFFLOAD_PARAMETERS:
+            BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS);
+            if (BufferLength == sizeof(NDIS_OFFLOAD_PARAMETERS)) {
+                NdisStatus = AdapterSetTcpOffloadParameters(Adapter, Buffer);
+                BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS);
+            } else {
+                NdisStatus = NDIS_STATUS_INVALID_LENGTH;
+            }
+            break;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_UNICAST_OCTETS,
-                      &Value);
+        case OID_GEN_INTERRUPT_MODERATION:
+            NdisStatus = NDIS_STATUS_INVALID_DATA;
+            break;
 
-    NdisStatisticsInfo->ifHCOutOctets = Value;
+        case OID_GEN_MACHINE_NAME:
+        default:
+            NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
+            break;
+    };
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_MULTICAST_OCTETS,
-                      &Value);
+    Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
+    if (NdisStatus == NDIS_STATUS_SUCCESS) {
+        Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
+    }
 
-    NdisStatisticsInfo->ifHCOutOctets += Value;
+    return NdisStatus;
+}
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_BROADCAST_OCTETS,
-                      &Value);
+static FORCEINLINE ULONG64
+AdapterGetXmitOk(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    ULONGLONG   Value;
+    ULONG64     Result = 0;
+
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                &Value);
+    Result = Value;
+
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                &Value);
+    Result += Value;
+
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                &Value);
+    Result += Value;
+
+    return Result;
+}
 
-    NdisStatisticsInfo->ifHCOutOctets += Value;
+static FORCEINLINE ULONG64
+AdapterGetRcvOk(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    ULONGLONG   Value;
+    ULONG64     Result = 0;
+
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_RECEIVER_UNICAST_PACKETS,
+                &Value);
+    Result = Value;
+
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_RECEIVER_MULTICAST_PACKETS,
+                &Value);
+    Result += Value;
+
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_RECEIVER_BROADCAST_PACKETS,
+                &Value);
+    Result += Value;
+
+    return Result;
+}
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT;
+static FORCEINLINE ULONG64
+AdapterGetXmitError(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    ULONGLONG   Value;
+    ULONG64     Result = 0;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_UNICAST_OCTETS,
-                      &Value);
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_TRANSMITTER_BACKEND_ERRORS,
+                &Value);
+    Result = Value;
 
-    NdisStatisticsInfo->ifHCOutUcastOctets = Value;
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_TRANSMITTER_FRONTEND_ERRORS,
+                &Value);
+    Result += Value;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT;
+    return Result;
+}
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_UNICAST_PACKETS,
-                      &Value);
+static FORCEINLINE ULONG64
+AdapterGetRcvError(
+    IN  PXENNET_ADAPTER         Adapter
+    )
+{
+    ULONGLONG   Value;
+    ULONG64     Result = 0;
 
-    NdisStatisticsInfo->ifHCOutUcastPkts = Value;
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_RECEIVER_BACKEND_ERRORS,
+                &Value);
+    Result = Value;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT;    
+    XENVIF_VIF(QueryStatistic,
+                &Adapter->VifInterface,
+                XENVIF_RECEIVER_FRONTEND_ERRORS,
+                &Value);
+    Result += Value;
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_MULTICAST_OCTETS,
-                      &Value);
+    return Result;
+}
 
-    NdisStatisticsInfo->ifHCOutMulticastOctets = Value;
+static VOID
+AdapterGetPacketFilter(
+    IN  PXENNET_ADAPTER         Adapter,
+    OUT PULONG                  PacketFilter
+    )
+{
+    XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel;
+    XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
+    XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
 
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT;    
+    XENVIF_VIF(MacQueryFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_UNICAST,
+               &UnicastFilterLevel);
 
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_MULTICAST_PACKETS,
-                      &Value);
-
-    NdisStatisticsInfo->ifHCOutMulticastPkts = Value;
-
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
-
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_BROADCAST_OCTETS,
-                      &Value);
-
-    NdisStatisticsInfo->ifHCOutBroadcastOctets = Value;
-
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT;
-
-    (VOID) XENVIF_VIF(QueryStatistic,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_BROADCAST_PACKETS,
-                      &Value);
-
-    NdisStatisticsInfo->ifHCOutBroadcastPkts = Value;
-
-    NdisStatisticsInfo->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS;
-    NdisStatisticsInfo->ifOutDiscards = 0;
-
-    return ndisStatus;
-}
-
-static VOID
-GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
-{
-    XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel;
-    XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
-    XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
-
-    XENVIF_VIF(MacQueryFilterLevel,
-               &Adapter->VifInterface,
-               ETHERNET_ADDRESS_UNICAST,
-               &UnicastFilterLevel);
-
-    XENVIF_VIF(MacQueryFilterLevel,
-               &Adapter->VifInterface,
-               ETHERNET_ADDRESS_MULTICAST,
-               &MulticastFilterLevel);
+    XENVIF_VIF(MacQueryFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_MULTICAST,
+               &MulticastFilterLevel);
 
     XENVIF_VIF(MacQueryFilterLevel,
                &Adapter->VifInterface,
@@ -863,1715 +1271,934 @@ GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
         *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST;
 }
 
-#define MIN(_x, _y) (((_x) < (_y)) ? (_x) : (_y))
-
-//
-// Handles OID queries.
-//
-#pragma warning(push)
-#pragma warning(disable:6262)
 static NDIS_STATUS 
-AdapterQueryInformation (
-    IN  PADAPTER            Adapter,
-    IN  PNDIS_OID_REQUEST   NdisRequest
+AdapterQueryGeneralStatistics (
+    IN  PXENNET_ADAPTER         Adapter,
+    IN  PNDIS_STATISTICS_INFO   Stats
     )
 {
-    ULONG bytesAvailable = 0;
-    ULONG bytesNeeded = 0;
-    ULONG bytesWritten = 0;
-    BOOLEAN doCopy = TRUE;
-    PVOID info = NULL;
-    ULONGLONG infoData;
-    ULONG informationBufferLength;
-    PVOID informationBuffer;
-    NDIS_INTERRUPT_MODERATION_PARAMETERS intModParams;
-    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
-    NDIS_OID oid;
-
-    informationBuffer = NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
-    informationBufferLength = 
NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
-    oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
-    switch (oid) {
-        case OID_PNP_CAPABILITIES:
-            Trace("PNP_CAPABILITIES\n");
+    ULONGLONG                   Value;
 
-            info = &Adapter->Capabilities;
-            bytesAvailable = sizeof(Adapter->Capabilities);
-            break;
+    RtlZeroMemory(Stats, sizeof(NDIS_STATISTICS_INFO));
+    Stats->Header.Type         = NDIS_OBJECT_TYPE_DEFAULT;
+    Stats->Header.Size         = sizeof(NDIS_STATISTICS_INFO);
+    Stats->Header.Revision     = NDIS_OBJECT_REVISION_1;
 
-        case OID_PNP_QUERY_POWER:
-            Trace("QUERY_POWER\n");
+    Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BACKEND_ERRORS,
+                      &Value);
+    Stats->ifInErrors = Value;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_FRONTEND_ERRORS,
+                      &Value);
+    Stats->ifInErrors += Value;
+
+    Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_PACKETS_DROPPED,
+                      &Value);
+    Stats->ifInDiscards = Value;
+
+    Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_UNICAST_OCTETS,
+                      &Value);
+    Stats->ifHCInOctets = Value;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_MULTICAST_OCTETS,
+                      &Value);
+    Stats->ifHCInOctets += Value;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BROADCAST_OCTETS,
+                      &Value);
+    Stats->ifHCInOctets += Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_UNICAST_OCTETS,
+                      &Value);
+    Stats->ifHCInUcastOctets = Value;
 
-            bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
-            if (informationBufferLength >= bytesNeeded) {
-                PNDIS_DEVICE_POWER_STATE state;
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_UNICAST_PACKETS,
+                      &Value);
+    Stats->ifHCInUcastPkts = Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_MULTICAST_OCTETS,
+                      &Value);
+    Stats->ifHCInMulticastOctets = Value;
 
-                state = (PNDIS_DEVICE_POWER_STATE)informationBuffer;
-                switch (*state) {
-                case NdisDeviceStateD0:
-                    Trace("D0\n");
-                    break;
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_MULTICAST_PACKETS,
+                      &Value);
+    Stats->ifHCInMulticastPkts = Value;
 
-                case NdisDeviceStateD1:
-                    Trace("D1\n");
-                    break;
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BROADCAST_OCTETS,
+                      &Value);
+    Stats->ifHCInBroadcastOctets = Value;
 
-                case NdisDeviceStateD2:
-                    Trace("D2\n");
-                    break;
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BROADCAST_PACKETS,
+                      &Value);
+    Stats->ifHCInBroadcastPkts = Value;
 
-                case NdisDeviceStateD3:
-                    Trace("D3\n");
-                    break;
-                }
-            }
+    Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BACKEND_ERRORS,
+                      &Value);
+    Stats->ifOutErrors = Value;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_FRONTEND_ERRORS,
+                      &Value);
+    Stats->ifOutErrors += Value;
+
+    Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                      &Value);
+    Stats->ifHCOutOctets = Value;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                      &Value);
+    Stats->ifHCOutOctets += Value;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                      &Value);
+    Stats->ifHCOutOctets += Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                      &Value);
+    Stats->ifHCOutUcastOctets = Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                      &Value);
+    Stats->ifHCOutUcastPkts = Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT;    
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                      &Value);
+    Stats->ifHCOutMulticastOctets = Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT;    
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                      &Value);
+    Stats->ifHCOutMulticastPkts = Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                      &Value);
+    Stats->ifHCOutBroadcastOctets = Value;
+
+    Stats->SupportedStatistics |= 
NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT;
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                      &Value);
+    Stats->ifHCOutBroadcastPkts = Value;
+
+    Stats->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS;
+    Stats->ifOutDiscards = 0;
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+static FORCEINLINE VOID
+AdapterGetInterruptModeration(
+    IN  PXENNET_ADAPTER         Adapter,
+    OUT PNDIS_INTERRUPT_MODERATION_PARAMETERS   Parameters
+    )
+{
+    UNREFERENCED_PARAMETER(Adapter);
+
+    RtlZeroMemory(Parameters, sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS));
+    Parameters->Header.Type      = NDIS_OBJECT_TYPE_DEFAULT;
+    Parameters->Header.Size      = 
sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
+    Parameters->Header.Revision  = 
NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
+    Parameters->Flags            = 0;
+    Parameters->InterruptModeration = NdisInterruptModerationNotSupported;
+}
+
+static NDIS_STATUS
+AdapterQueryInformation(
+    IN  PXENNET_ADAPTER             Adapter,
+    IN  PNDIS_OID_REQUEST           Request
+    )
+{
+    ULONG           Value32;
+    ULONG64         Value64;
+    PVOID           Buffer;
+    ULONG           BufferLength;
+    BOOLEAN         DoCopy = TRUE;
+    ULONG           BytesAvailable = 0;
+    PVOID           BytesToCopy = NULL;
+    NDIS_STATUS     NdisStatus  = NDIS_STATUS_SUCCESS;
+
+    Buffer          = Request->DATA.QUERY_INFORMATION.InformationBuffer;
+    BufferLength    = Request->DATA.QUERY_INFORMATION.InformationBufferLength;
+
+    switch (Request->DATA.QUERY_INFORMATION.Oid) {
+        case OID_PNP_CAPABILITIES:
+            BytesToCopy = &Adapter->Capabilities;
+            BytesAvailable = sizeof(Adapter->Capabilities);
             break;
 
         case OID_GEN_SUPPORTED_LIST:
-            info = &XennetSupportedOids[0];
-            bytesAvailable = sizeof(XennetSupportedOids);
+            BytesToCopy = &XennetSupportedOids[0];
+            BytesAvailable = sizeof(XennetSupportedOids);
             break;
 
         case OID_GEN_HARDWARE_STATUS:
-            infoData = NdisHardwareStatusReady;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = NdisHardwareStatusReady;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_MEDIA_SUPPORTED:
         case OID_GEN_MEDIA_IN_USE:
-            infoData = XENNET_MEDIA_TYPE;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = XENNET_MEDIA_TYPE;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_MAXIMUM_LOOKAHEAD:
-            infoData = Adapter->MaximumFrameSize;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_GEN_TRANSMIT_BUFFER_SPACE:
-            XENVIF_VIF(TransmitterQueryRingSize,
-                       &Adapter->VifInterface,
-                       (PULONG)&infoData);
-            infoData *= Adapter->MaximumFrameSize;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_GEN_RECEIVE_BUFFER_SPACE:
-            XENVIF_VIF(TransmitterQueryRingSize,
-                       &Adapter->VifInterface,
-                       (PULONG)&infoData);
-            infoData *= Adapter->MaximumFrameSize;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
         case OID_GEN_TRANSMIT_BLOCK_SIZE:
         case OID_GEN_RECEIVE_BLOCK_SIZE:
-            infoData = Adapter->MaximumFrameSize;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = Adapter->MaximumFrameSize;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_VENDOR_DESCRIPTION:
-            info = COMPANY_NAME_STR;
-            bytesAvailable = (ULONG)strlen(info) + 1;
+            BytesToCopy = COMPANY_NAME_STR;
+            BytesAvailable = (ULONG)strlen(BytesToCopy) + 1;
             break;
 
         case OID_GEN_VENDOR_DRIVER_VERSION:
-            infoData = ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_DRIVER_VERSION:
-            infoData = (6 << 8) | 0;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = (6 << 8) | 0;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_MAC_OPTIONS:
-            infoData = XENNET_MAC_OPTIONS;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        
-        case OID_GEN_STATISTICS:
-            doCopy = FALSE;
-
-            bytesAvailable = sizeof(NDIS_STATISTICS_INFO);
-            if (informationBufferLength >= bytesAvailable) {
-                ndisStatus = AdapterQueryGeneralStatistics(Adapter, 
-                                                           informationBuffer);
-
-            }
-
+            Value32 = XENNET_MAC_OPTIONS;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
-        case OID_802_3_MULTICAST_LIST: {
-            ULONG Count;
-
-            doCopy = FALSE;
-
-            XENVIF_VIF(MacQueryMulticastAddresses,
+        case OID_GEN_TRANSMIT_BUFFER_SPACE:
+        case OID_GEN_RECEIVE_BUFFER_SPACE:
+            XENVIF_VIF(TransmitterQueryRingSize,
                        &Adapter->VifInterface,
-                       NULL,
-                       &Count);
-            bytesAvailable = Count * ETHERNET_ADDRESS_LENGTH;
-
-            if (informationBufferLength >= bytesAvailable) {
-                NTSTATUS status;
-
-                status = XENVIF_VIF(MacQueryMulticastAddresses,
-                                    &Adapter->VifInterface,
-                                    informationBuffer,
-                                    &Count);
-                if (!NT_SUCCESS(status))
-                    ndisStatus = NDIS_STATUS_FAILURE;
-            }
-
+                       (PULONG)&Value32);
+            Value32 *= Adapter->MaximumFrameSize;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
-        }
+
         case OID_802_3_PERMANENT_ADDRESS:
             XENVIF_VIF(MacQueryPermanentAddress,
                        &Adapter->VifInterface,
-                       (PETHERNET_ADDRESS)&infoData);
-            info = &infoData;
-            bytesAvailable = sizeof (ETHERNET_ADDRESS);
+                       (PETHERNET_ADDRESS)&Value32);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_802_3_CURRENT_ADDRESS:
             XENVIF_VIF(MacQueryCurrentAddress,
                        &Adapter->VifInterface,
-                       (PETHERNET_ADDRESS)&infoData);
-            info = &infoData;
-            bytesAvailable = sizeof (ETHERNET_ADDRESS);
+                       (PETHERNET_ADDRESS)&Value32);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_MAXIMUM_FRAME_SIZE:
-            infoData = Adapter->MaximumFrameSize -
+            Value32 = Adapter->MaximumFrameSize -
                        sizeof (ETHERNET_TAGGED_HEADER);
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_MAXIMUM_TOTAL_SIZE:
-            infoData = Adapter->MaximumFrameSize -
+            Value32 = Adapter->MaximumFrameSize -
                        sizeof (ETHERNET_TAGGED_HEADER) +
                        sizeof (ETHERNET_UNTAGGED_HEADER);
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_CURRENT_LOOKAHEAD:
-            infoData = Adapter->CurrentLookahead;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = Adapter->CurrentLookahead;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_VENDOR_ID:
-            infoData = 0x5853;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
+            Value32 = 0x5853;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
-        case OID_GEN_LINK_SPEED: {
-            ULONG64 LinkSpeed;
-
-            XENVIF_VIF(MacQueryState,
-                       &Adapter->VifInterface,
-                       NULL,
-                       &LinkSpeed,
-                       NULL);
-
-            infoData = (ULONG)(LinkSpeed / 100);
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_MEDIA_CONNECT_STATUS:
+        case OID_GEN_LINK_SPEED:
             XENVIF_VIF(MacQueryState,
                        &Adapter->VifInterface,
-                       (PNET_IF_MEDIA_CONNECT_STATE)&infoData,
                        NULL,
+                       &Value64,
                        NULL);
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        case OID_GEN_MAXIMUM_SEND_PACKETS:
-            infoData = 16;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_GEN_CURRENT_PACKET_FILTER:
-            GetPacketFilter(Adapter, (PULONG)&infoData);
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_GEN_XMIT_OK: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_UNICAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_MULTICAST_PACKETS,
-                       &Value);
-
-            infoData += Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_BROADCAST_PACKETS,
-                       &Value);
-
-            infoData += Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONGLONG);
-            break;
-        }
-        case OID_GEN_RCV_OK: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_UNICAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_MULTICAST_PACKETS,
-                       &Value);
-
-            infoData += Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_BROADCAST_PACKETS,
-                       &Value);
-
-            infoData += Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONGLONG);
+            Value32 = (ULONG)(Value64 / 100);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
-        }
-        case OID_GEN_XMIT_ERROR: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_BACKEND_ERRORS,
-                       &Value);
-
-            infoData = Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_FRONTEND_ERRORS,
-                       &Value);
-
-            infoData += Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_RCV_ERROR: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_BACKEND_ERRORS,
-                       &Value);
-
-            infoData = Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_FRONTEND_ERRORS,
-                       &Value);
-
-            infoData += Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_RCV_NO_BUFFER:
-            infoData = 0;   // We'd need to query VIF TX drop stats from dom0
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_GEN_TRANSMIT_QUEUE_LENGTH:
-            infoData = 0;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_802_3_MAXIMUM_LIST_SIZE:
-            infoData = 32;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_IP4_OFFLOAD_STATS:
-        case OID_IP6_OFFLOAD_STATS:
-        case OID_GEN_SUPPORTED_GUIDS:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-            break;
-
-        case OID_GEN_RCV_CRC_ERROR:
-            infoData = 0;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_802_3_RCV_ERROR_ALIGNMENT:
-        case OID_802_3_XMIT_ONE_COLLISION:
-        case OID_802_3_XMIT_MORE_COLLISIONS:
-            infoData = 0;
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-
-        case OID_GEN_DIRECTED_BYTES_XMIT: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_UNICAST_OCTETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_DIRECTED_FRAMES_XMIT: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_UNICAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_MULTICAST_BYTES_XMIT: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_MULTICAST_OCTETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_MULTICAST_FRAMES_XMIT: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_MULTICAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_BROADCAST_BYTES_XMIT: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_BROADCAST_OCTETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_BROADCAST_FRAMES_XMIT: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_TRANSMITTER_BROADCAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_DIRECTED_BYTES_RCV: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_UNICAST_OCTETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_DIRECTED_FRAMES_RCV: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_UNICAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_MULTICAST_BYTES_RCV: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_MULTICAST_OCTETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_MULTICAST_FRAMES_RCV: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_MULTICAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_BROADCAST_BYTES_RCV: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_BROADCAST_OCTETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_BROADCAST_FRAMES_RCV: {
-            ULONGLONG   Value;
-
-            XENVIF_VIF(QueryStatistic,
-                       &Adapter->VifInterface,
-                       XENVIF_RECEIVER_BROADCAST_PACKETS,
-                       &Value);
-
-            infoData = Value;
-
-            info = &infoData;
-            bytesAvailable = sizeof(ULONG);
-            break;
-        }
-        case OID_GEN_INTERRUPT_MODERATION:
-            intModParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
-            intModParams.Header.Revision = 
NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
-            intModParams.Header.Size = 
sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
-            intModParams.Flags = 0;
-            intModParams.InterruptModeration = 
NdisInterruptModerationNotSupported;
-            info = &intModParams;
-            bytesAvailable = sizeof(intModParams);
-            break;
-
-        // We don't handle these since NDIS 6.0 is supposed to do this for us
-        case OID_GEN_MAC_ADDRESS:
-        case OID_GEN_MAX_LINK_SPEED:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-            break;
-
-               // ignore these common unwanted OIDs
-               case OID_GEN_INIT_TIME_MS:
-               case OID_GEN_RESET_COUNTS:
-               case OID_GEN_MEDIA_SENSE_COUNTS:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-            break;
-
-        default:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-            break;
-    };
-
-    if (ndisStatus == NDIS_STATUS_SUCCESS) {
-        if (bytesAvailable <= informationBufferLength) {
-            bytesNeeded = bytesAvailable;
-            bytesWritten = bytesAvailable;
-        } else {
-            bytesNeeded = bytesAvailable;
-            bytesWritten = informationBufferLength;
-            ndisStatus = NDIS_STATUS_BUFFER_TOO_SHORT;
-        }
-
-        if (bytesWritten && doCopy) {
-            NdisMoveMemory(informationBuffer, info, bytesWritten);
-
-            if (oid == OID_GEN_XMIT_OK || oid == OID_GEN_RCV_OK)
-                ndisStatus = NDIS_STATUS_SUCCESS;
-        }
-    }
-    
-    NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = bytesWritten;
-    NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = bytesNeeded;
-    return ndisStatus;
-}
-#pragma warning(pop)
-
-NDIS_STATUS 
-AdapterReset (
-    IN  NDIS_HANDLE     MiniportAdapterContext,
-    OUT PBOOLEAN        AddressingReset
-    )
-{
-    UNREFERENCED_PARAMETER(MiniportAdapterContext);
-
-
-    *AddressingReset = FALSE;
-
-    return NDIS_STATUS_SUCCESS;
-}
-
-//
-// Restarts a paused adapter.
-//
-NDIS_STATUS
-AdapterRestart (
-    IN  NDIS_HANDLE                         MiniportAdapterContext,
-    IN  PNDIS_MINIPORT_RESTART_PARAMETERS   MiniportRestartParameters
-    )
-{
-    NTSTATUS                                status;
-    NDIS_STATUS                             ndisStatus;
-    PADAPTER                                Adapter = 
(PADAPTER)MiniportAdapterContext;
-
-    UNREFERENCED_PARAMETER(MiniportRestartParameters);
-
-    Trace("====>\n");
-
-    if (Adapter->Enabled) {
-        ndisStatus = NDIS_STATUS_SUCCESS;
-        goto done;
-    }
-
-    status = XENVIF_VIF(Enable,
-                 &Adapter->VifInterface,
-                 AdapterVifCallback,
-                 Adapter);
-    if (NT_SUCCESS(status)) {
-        TransmitterEnable(Adapter->Transmitter);
-        Adapter->Enabled = TRUE;
-        ndisStatus = NDIS_STATUS_SUCCESS;
-    } else {
-        ndisStatus = NDIS_STATUS_FAILURE;
-    }
-
-done:
-    Trace("<====\n");
-    return ndisStatus;
-}
-
-//
-// Recycle of received net buffer lists.
-//
-VOID 
-AdapterReturnNetBufferLists (
-    IN  NDIS_HANDLE         MiniportAdapterContext,
-    IN  PNET_BUFFER_LIST    NetBufferLists,
-    IN  ULONG               ReturnFlags
-    )
-{
-    PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
-
-    ReceiverReturnNetBufferLists(&Adapter->Receiver,
-                                 NetBufferLists,
-                                 ReturnFlags);
-
-    return;
-}
-
-//
-// Used to send net buffer lists.
-//
-VOID 
-AdapterSendNetBufferLists (
-    IN  NDIS_HANDLE         MiniportAdapterContext,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  NDIS_PORT_NUMBER    PortNumber,
-    IN  ULONG               SendFlags
-    )
-{
-    PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
-
-    TransmitterSendNetBufferLists(Adapter->Transmitter,
-                                  NetBufferList,
-                                  PortNumber,
-                                  SendFlags);
-}
-
-#define XENNET_MEDIA_MAX_SPEED 1000000000ull
-
-#define XENNET_SUPPORTED_PACKET_FILTERS     \
-        (NDIS_PACKET_TYPE_DIRECTED |        \
-         NDIS_PACKET_TYPE_MULTICAST |       \
-         NDIS_PACKET_TYPE_ALL_MULTICAST |   \
-         NDIS_PACKET_TYPE_BROADCAST |       \
-         NDIS_PACKET_TYPE_PROMISCUOUS)
-
-//
-// Sets general adapter attributes. 
-//
-static NDIS_STATUS
-AdapterSetGeneralAttributes (
-    IN  PADAPTER Adapter
-    )
-{
-    PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
-    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES generalAttributes;
-    NDIS_STATUS ndisStatus;
-
-    NdisZeroMemory(&generalAttributes, 
-                   sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
-
-    generalAttributes.Header.Type = 
-                    NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
-
-    generalAttributes.Header.Revision = 
-                    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
-
-    generalAttributes.Header.Size = 
-                    sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
-
-    generalAttributes.MediaType = XENNET_MEDIA_TYPE;
-
-    XENVIF_VIF(MacQueryMaximumFrameSize,
-               &Adapter->VifInterface,
-               (PULONG)&Adapter->MaximumFrameSize);
-
-    generalAttributes.MtuSize = Adapter->MaximumFrameSize - sizeof 
(ETHERNET_TAGGED_HEADER);
-    generalAttributes.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
-    generalAttributes.MaxRcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
-    generalAttributes.XmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
-    generalAttributes.RcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
-    generalAttributes.MediaConnectState = MediaConnectStateConnected;
-    generalAttributes.MediaDuplexState = MediaDuplexStateFull;
-    generalAttributes.LookaheadSize = Adapter->MaximumFrameSize;
-    generalAttributes.PowerManagementCapabilities = &Adapter->Capabilities;
-    generalAttributes.MacOptions = XENNET_MAC_OPTIONS;
-
-    generalAttributes.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS;
-        
-    generalAttributes.MaxMulticastListSize = 32;
-    generalAttributes.MacAddressLength = ETHERNET_ADDRESS_LENGTH;
-
-    XENVIF_VIF(MacQueryPermanentAddress,
-               &Adapter->VifInterface,
-               (PETHERNET_ADDRESS)&generalAttributes.PermanentMacAddress);
-    XENVIF_VIF(MacQueryCurrentAddress,
-               &Adapter->VifInterface,
-               (PETHERNET_ADDRESS)&generalAttributes.CurrentMacAddress);
-
-    generalAttributes.PhysicalMediumType = NdisPhysicalMedium802_3;
-    generalAttributes.RecvScaleCapabilities = NULL;
-    generalAttributes.AccessType = NET_IF_ACCESS_BROADCAST;
-    generalAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
-    generalAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
-    generalAttributes.IfType = IF_TYPE_ETHERNET_CSMACD; 
-    generalAttributes.IfConnectorPresent = TRUE;
-
-    generalAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
-                                            
NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
-                                            
NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
-                                            
NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED |
-                                            
NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
-                                            
NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
-                                            
NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED |
-                                            
NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
-                                            NDIS_STATISTICS_RCV_OK_SUPPORTED |
-                                            
NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
-                                            
NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
-                                            
NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
-                                            
NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
-                                            
NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED |
-                                            
NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
-                                            
NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED |
-                                            
NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
-                      
-    generalAttributes.SupportedOidList = XennetSupportedOids;
-    generalAttributes.SupportedOidListLength = sizeof(XennetSupportedOids);
-    adapterAttributes = 
-                (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&generalAttributes;
-
-    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            adapterAttributes);
-
-    return ndisStatus;
-}
-
-#define DISPLAY_OFFLOAD(_Offload)                                   \
-        do {                                                        \
-            if ((_Offload).Checksum.IPv4Receive.IpChecksum)         \
-                Info("Checksum.IPv4Receive.IpChecksum ON\n");       \
-            else                                                    \
-                Info("Checksum.IPv4Receive.IpChecksum OFF\n");      \
-                                                                    \
-            if ((_Offload).Checksum.IPv4Receive.TcpChecksum)        \
-                Info("Checksum.IPv4Receive.TcpChecksum ON\n");      \
-            else                                                    \
-                Info("Checksum.IPv4Receive.TcpChecksum OFF\n");     \
-                                                                    \
-            if ((_Offload).Checksum.IPv4Receive.UdpChecksum)        \
-                Info("Checksum.IPv4Receive.UdpChecksum ON\n");      \
-            else                                                    \
-                Info("Checksum.IPv4Receive.UdpChecksum OFF\n");     \
-                                                                    \
-            if ((_Offload).Checksum.IPv6Receive.TcpChecksum)        \
-                Info("Checksum.IPv6Receive.TcpChecksum ON\n");      \
-            else                                                    \
-                Info("Checksum.IPv6Receive.TcpChecksum OFF\n");     \
-                                                                    \
-            if ((_Offload).Checksum.IPv6Receive.UdpChecksum)        \
-                Info("Checksum.IPv6Receive.UdpChecksum ON\n");      \
-            else                                                    \
-                Info("Checksum.IPv6Receive.UdpChecksum OFF\n");     \
-                                                                    \
-            if ((_Offload).Checksum.IPv4Transmit.IpChecksum)        \
-                Info("Checksum.IPv4Transmit.IpChecksum ON\n");      \
-            else                                                    \
-                Info("Checksum.IPv4Transmit.IpChecksum OFF\n");     \
-                                                                    \
-            if ((_Offload).Checksum.IPv4Transmit.TcpChecksum)       \
-                Info("Checksum.IPv4Transmit.TcpChecksum ON\n");     \
-            else                                                    \
-                Info("Checksum.IPv4Transmit.TcpChecksum OFF\n");    \
-                                                                    \
-            if ((_Offload).Checksum.IPv4Transmit.UdpChecksum)       \
-                Info("Checksum.IPv4Transmit.UdpChecksum ON\n");     \
-            else                                                    \
-                Info("Checksum.IPv4Transmit.UdpChecksum OFF\n");    \
-                                                                    \
-            if ((_Offload).Checksum.IPv6Transmit.TcpChecksum)       \
-                Info("Checksum.IPv6Transmit.TcpChecksum ON\n");     \
-            else                                                    \
-                Info("Checksum.IPv6Transmit.TcpChecksum OFF\n");    \
-                                                                    \
-            if ((_Offload).Checksum.IPv6Transmit.UdpChecksum)       \
-                Info("Checksum.IPv6Transmit.UdpChecksum ON\n");     \
-            else                                                    \
-                Info("Checksum.IPv6Transmit.UdpChecksum OFF\n");    \
-                                                                    \
-            if ((_Offload).LsoV2.IPv4.MaxOffLoadSize != 0)          \
-                Info("LsoV2.IPv4.MaxOffLoadSize = %u\n",            \
-                     (_Offload).LsoV2.IPv4.MaxOffLoadSize);         \
-            else                                                    \
-                Info("LsoV2.IPv4 OFF\n");                           \
-                                                                    \
-            if ((_Offload).LsoV2.IPv6.MaxOffLoadSize != 0)          \
-                Info("LsoV2.IPv6.MaxOffLoadSize = %u\n",            \
-                     (_Offload).LsoV2.IPv6.MaxOffLoadSize);         \
-            else                                                    \
-                Info("LsoV2.IPv6 OFF\n");                           \
-        } while (FALSE)
-
-static NDIS_STATUS
-AdapterSetOffloadAttributes(
-    IN  PADAPTER Adapter
-    )
-{
-    PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
-    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offloadAttributes;
-    XENVIF_VIF_OFFLOAD_OPTIONS Options;
-    NDIS_OFFLOAD current;
-    NDIS_OFFLOAD supported;
-    NDIS_STATUS ndisStatus;
-
-    Adapter->Receiver.OffloadOptions.Value = 0;
-    Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1;
-
-    if (Adapter->Properties.need_csum_value)
-        Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1;
-
-    if (Adapter->Properties.lrov4) {
-        Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1;
-        Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
-    }
-
-    if (Adapter->Properties.lrov6) {
-        Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1;
-        Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
-    }
-
-    Adapter->Transmitter->OffloadOptions.Value = 0;
-    Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1;
-
-    NdisZeroMemory(&offloadAttributes, sizeof(offloadAttributes));
-    NdisZeroMemory(&current, sizeof(current));
-    NdisZeroMemory(&supported, sizeof(supported));
-    
-    XENVIF_VIF(ReceiverSetOffloadOptions,
-               &Adapter->VifInterface,
-               Adapter->Receiver.OffloadOptions);
-
-    supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
-    supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
-    supported.Header.Size = sizeof(supported);
-
-    supported.Checksum.IPv4Receive.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
-
-    supported.Checksum.IPv4Receive.IpChecksum = 1;
-    supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
-
-    supported.Checksum.IPv4Receive.TcpChecksum = 1;
-    supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
-
-    supported.Checksum.IPv4Receive.UdpChecksum = 1;
-
-    supported.Checksum.IPv6Receive.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
-
-    supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
-
-    supported.Checksum.IPv6Receive.TcpChecksum = 1;
-    supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
-
-    supported.Checksum.IPv6Receive.UdpChecksum = 1;
-
-    XENVIF_VIF(TransmitterQueryOffloadOptions,
-               &Adapter->VifInterface,
-               &Options);
-
-    supported.Checksum.IPv4Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
-
-    if (Options.OffloadIpVersion4HeaderChecksum) {
-        supported.Checksum.IPv4Transmit.IpChecksum = 1;
-        supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
-    }
-
-    if (Options.OffloadIpVersion4TcpChecksum) {
-        supported.Checksum.IPv4Transmit.TcpChecksum = 1;
-        supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
-    }
-
-    if (Options.OffloadIpVersion4UdpChecksum)
-        supported.Checksum.IPv4Transmit.UdpChecksum = 1;
-
-    supported.Checksum.IPv6Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
-
-    supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
-
-    if (Options.OffloadIpVersion6TcpChecksum) {
-        supported.Checksum.IPv6Transmit.TcpChecksum = 1;
-        supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
-    }
-
-    if (Options.OffloadIpVersion6UdpChecksum)
-        supported.Checksum.IPv6Transmit.UdpChecksum = 1;
-
-    if (Options.OffloadIpVersion4LargePacket) {
-        ULONG Size;
-
-        XENVIF_VIF(TransmitterQueryLargePacketSize,
-                   &Adapter->VifInterface,
-                   4,
-                   &Size);
-
-        supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-        supported.LsoV2.IPv4.MaxOffLoadSize = Size;
-        supported.LsoV2.IPv4.MinSegmentCount = 2;
-    }
-
-    if (Options.OffloadIpVersion6LargePacket) {
-        ULONG Size;
-
-        XENVIF_VIF(TransmitterQueryLargePacketSize,
-                   &Adapter->VifInterface,
-                   6,
-                   &Size);
-
-        supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-        supported.LsoV2.IPv6.MaxOffLoadSize = Size;
-        supported.LsoV2.IPv6.MinSegmentCount = 2;
-        supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
-        supported.LsoV2.IPv6.TcpOptionsSupported = 1;
-    }
-
-    current = supported;
-
-    if (!(Adapter->Properties.ipv4_csum & 2))
-        current.Checksum.IPv4Receive.IpChecksum = 0;
-
-    if (!(Adapter->Properties.tcpv4_csum & 2))
-        current.Checksum.IPv4Receive.TcpChecksum = 0;
-
-    if (!(Adapter->Properties.udpv4_csum & 2))
-        current.Checksum.IPv4Receive.UdpChecksum = 0;
-
-    if (!(Adapter->Properties.tcpv6_csum & 2))
-        current.Checksum.IPv6Receive.TcpChecksum = 0;
-
-    if (!(Adapter->Properties.udpv6_csum & 2))
-        current.Checksum.IPv6Receive.UdpChecksum = 0;
-
-    if (!(Adapter->Properties.ipv4_csum & 1))
-        current.Checksum.IPv4Transmit.IpChecksum = 0;
-
-    if (!(Adapter->Properties.tcpv4_csum & 1))
-        current.Checksum.IPv4Transmit.TcpChecksum = 0;
-
-    if (!(Adapter->Properties.udpv4_csum & 1))
-        current.Checksum.IPv4Transmit.UdpChecksum = 0;
-
-    if (!(Adapter->Properties.tcpv6_csum & 1))
-        current.Checksum.IPv6Transmit.TcpChecksum = 0;
-
-    if (!(Adapter->Properties.udpv6_csum & 1))
-        current.Checksum.IPv6Transmit.UdpChecksum = 0;
-
-    if (!(Adapter->Properties.lsov4)) {
-        current.LsoV2.IPv4.MaxOffLoadSize = 0;
-        current.LsoV2.IPv4.MinSegmentCount = 0;
-    }
-
-    if (!(Adapter->Properties.lsov6)) {
-        current.LsoV2.IPv6.MaxOffLoadSize = 0;
-        current.LsoV2.IPv6.MinSegmentCount = 0;
-    }
-
-    if (!RtlEqualMemory(&Adapter->Offload, &current, sizeof (NDIS_OFFLOAD))) {
-        Adapter->Offload = current;
-
-        DISPLAY_OFFLOAD(current);
-    }
-
-    offloadAttributes.Header.Type =
-        NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
-    offloadAttributes.Header.Revision =
-        NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
-    offloadAttributes.Header.Size = sizeof(offloadAttributes);
-    offloadAttributes.DefaultOffloadConfiguration = &current;
-    offloadAttributes.HardwareOffloadCapabilities = &supported;
-
-    adapterAttributes =
-        (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offloadAttributes;
-    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            adapterAttributes);
-
-    return ndisStatus;
-}
-
-static void
-AdapterIndicateOffloadChanged (
-    IN  PADAPTER Adapter
-    )
-{
-    NDIS_STATUS_INDICATION indication;
-    NDIS_OFFLOAD offload;
-
-    NdisZeroMemory(&offload, sizeof(offload));
-    INITIALIZE_NDIS_OBJ_HEADER(offload, OFFLOAD);
-
-    offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-
-    if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
-        offload.Checksum.IPv4Receive.IpChecksum = 1;
-        offload.Checksum.IPv4Receive.IpOptionsSupported = 1;
-    }
-
-    if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
-        offload.Checksum.IPv4Receive.TcpChecksum = 1;
-        offload.Checksum.IPv4Receive.TcpOptionsSupported = 1;
-    }
-
-    if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
-        offload.Checksum.IPv4Receive.UdpChecksum = 1;
-    }
-
-    offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-
-    offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
-
-    if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
-        offload.Checksum.IPv6Receive.TcpChecksum = 1;
-        offload.Checksum.IPv6Receive.TcpOptionsSupported = 1;
-    }
-
-    if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
-        offload.Checksum.IPv6Receive.UdpChecksum = 1;
-    }
-
-    XENVIF_VIF(ReceiverSetOffloadOptions,
-               &Adapter->VifInterface,
-               Adapter->Receiver.OffloadOptions);
-
-    offload.Checksum.IPv4Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
-        offload.Checksum.IPv4Transmit.IpChecksum = 1;
-        offload.Checksum.IPv4Transmit.IpOptionsSupported = 1;
-    }
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
-        offload.Checksum.IPv4Transmit.TcpChecksum = 1;
-        offload.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
-    }
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
-        offload.Checksum.IPv4Transmit.UdpChecksum = 1;
-    }
-
-    offload.Checksum.IPv6Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
-
-    offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
-        offload.Checksum.IPv6Transmit.TcpChecksum = 1;
-        offload.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
-    }
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
-        offload.Checksum.IPv6Transmit.UdpChecksum = 1;
-    }
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
-        ULONG Size;
-
-        XENVIF_VIF(TransmitterQueryLargePacketSize,
-                   &Adapter->VifInterface,
-                   4,
-                   &Size);
-
-        offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-        offload.LsoV2.IPv4.MaxOffLoadSize = Size;
-        offload.LsoV2.IPv4.MinSegmentCount = 2;
-    }
-
-    if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
-        ULONG Size;
-
-        XENVIF_VIF(TransmitterQueryLargePacketSize,
-                   &Adapter->VifInterface,
-                   6,
-                   &Size);
-
-        offload.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-        offload.LsoV2.IPv6.MaxOffLoadSize = Size;
-        offload.LsoV2.IPv6.MinSegmentCount = 2;
-        offload.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
-        offload.LsoV2.IPv6.TcpOptionsSupported = 1;
-    }
-
-    if (!RtlEqualMemory(&Adapter->Offload, &offload, sizeof (NDIS_OFFLOAD))) {
-        Adapter->Offload = offload;
-
-        DISPLAY_OFFLOAD(offload);
-    }
-
-    NdisZeroMemory(&indication, sizeof(indication));
-    INITIALIZE_NDIS_OBJ_HEADER(indication, STATUS_INDICATION);
-    indication.SourceHandle = Adapter->NdisAdapterHandle;
-    indication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG;
-    indication.StatusBuffer = &offload;
-    indication.StatusBufferSize = sizeof(offload);
-
-    NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &indication);
-
-}
-
-static NDIS_STATUS
-SetMulticastAddresses(PADAPTER Adapter, PETHERNET_ADDRESS Address, ULONG Count)
-{
-    NTSTATUS status;
-
-    status = XENVIF_VIF(MacSetMulticastAddresses,
-                        &Adapter->VifInterface,
-                        Address,
-                        Count);
-    if (!NT_SUCCESS(status))
-        return NDIS_STATUS_INVALID_DATA;
-
-    return NDIS_STATUS_SUCCESS;
-}
-
-static NDIS_STATUS
-SetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
-{
-    XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel;
-    XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
-    XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
-
-    if (*PacketFilter & ~XENNET_SUPPORTED_PACKET_FILTERS)
-        return NDIS_STATUS_INVALID_PARAMETER;
-
-    if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
-        UnicastFilterLevel = XENVIF_MAC_FILTER_ALL;
-        MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
-        BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
-        goto done;
-    }
-
-    if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED)
-        UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
-    else
-        UnicastFilterLevel = XENVIF_MAC_FILTER_NONE;
-
-    if (*PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
-        MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
-    else if (*PacketFilter & NDIS_PACKET_TYPE_MULTICAST)
-        MulticastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
-    else
-        MulticastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
-    if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
-        BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
-    else
-        BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE;
+        case OID_GEN_MEDIA_CONNECT_STATUS:
+            XENVIF_VIF(MacQueryState,
+                       &Adapter->VifInterface,
+                       (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
+                       NULL,
+                       NULL);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-done:
-    XENVIF_VIF(MacSetFilterLevel,
-               &Adapter->VifInterface,
-               ETHERNET_ADDRESS_UNICAST,
-               UnicastFilterLevel);
+        case OID_GEN_MAXIMUM_SEND_PACKETS:
+            Value32 = 16;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-    XENVIF_VIF(MacSetFilterLevel,
-               &Adapter->VifInterface,
-               ETHERNET_ADDRESS_MULTICAST,
-               MulticastFilterLevel);
+        case OID_GEN_RCV_NO_BUFFER:
+        case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+        case OID_GEN_RCV_CRC_ERROR:
+        case OID_802_3_RCV_ERROR_ALIGNMENT:
+        case OID_802_3_XMIT_ONE_COLLISION:
+        case OID_802_3_XMIT_MORE_COLLISIONS:
+            Value32 = 0;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-    XENVIF_VIF(MacSetFilterLevel,
-               &Adapter->VifInterface,
-               ETHERNET_ADDRESS_BROADCAST,
-               BroadcastFilterLevel);
+        case OID_802_3_MAXIMUM_LIST_SIZE:
+            Value32 = 32;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-    return NDIS_STATUS_SUCCESS;
-}
+        case OID_GEN_STATISTICS:
+            DoCopy = FALSE;
+            BytesAvailable = sizeof(NDIS_STATISTICS_INFO);
+            if (BufferLength >= sizeof(NDIS_STATISTICS_INFO))
+                NdisStatus = AdapterQueryGeneralStatistics(Adapter, Buffer);
+            break;
 
-//
-// Set OID handler.
-//
-static NDIS_STATUS 
-AdapterSetInformation (
-    IN  PADAPTER            Adapter,
-    IN  PNDIS_OID_REQUEST   NdisRequest
-    )
-{
-    ULONG addressCount;
-    ULONG bytesNeeded = 0;
-    ULONG bytesRead = 0;
-    PVOID informationBuffer;
-    ULONG informationBufferLength;
-    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
-    NDIS_OID oid;
-    BOOLEAN offloadChanged;
-
-    informationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
-    informationBufferLength = 
NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
-    oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
-    switch (oid) {
-        case OID_PNP_SET_POWER:
-            bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
-            if (informationBufferLength >= bytesNeeded) {
-                PNDIS_DEVICE_POWER_STATE state;
-
-                state = (PNDIS_DEVICE_POWER_STATE)informationBuffer;
-                switch (*state) {
-                case NdisDeviceStateD0:
-                    Info("SET_POWER: D0\n");
-                    break;
-
-                case NdisDeviceStateD1:
-                    Info("SET_POWER: D1\n");
-                    break;
-
-                case NdisDeviceStateD2:
-                    Info("SET_POWER: D2\n");
-                    break;
-
-                case NdisDeviceStateD3:
-                    Info("SET_POWER: D3\n");
-                    break;
+        case OID_802_3_MULTICAST_LIST:
+            DoCopy = FALSE;
+            XENVIF_VIF(MacQueryMulticastAddresses,
+                       &Adapter->VifInterface,
+                       NULL,
+                       &Value32);
+            BytesAvailable = Value32 * ETHERNET_ADDRESS_LENGTH;
+            if (BufferLength >= BytesAvailable) {
+                if (!NT_SUCCESS(XENVIF_VIF(MacQueryMulticastAddresses,
+                                           &Adapter->VifInterface,
+                                           Buffer,
+                                           &Value32))) {
+                    NdisStatus = NDIS_STATUS_FAILURE;
                 }
             }
             break;
 
-        case OID_GEN_MACHINE_NAME:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+        case OID_GEN_CURRENT_PACKET_FILTER:
+            AdapterGetPacketFilter(Adapter, &Value32);
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
-        case OID_GEN_CURRENT_LOOKAHEAD:
-            bytesNeeded = sizeof(ULONG);
-            Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
-            if (informationBufferLength == sizeof(ULONG)) {
-                Adapter->CurrentLookahead = *(PULONG)informationBuffer;
-                bytesRead = sizeof(ULONG);
-            }
-
+        case OID_GEN_XMIT_OK:
+            Value64 = AdapterGetXmitOk(Adapter);
+            BytesToCopy = &Value64;
+            BytesAvailable = sizeof(ULONG64);
             break;
 
-        case OID_GEN_CURRENT_PACKET_FILTER:
-            bytesNeeded = sizeof(ULONG);
-            if (informationBufferLength == sizeof(ULONG)) {
-                ndisStatus = SetPacketFilter(Adapter, 
(PULONG)informationBuffer);
-                bytesRead = sizeof(ULONG);
-            }
-
+        case OID_GEN_RCV_OK:
+            Value64 = AdapterGetRcvOk(Adapter);
+            BytesToCopy = &Value64;
+            BytesAvailable = sizeof(ULONG64);
             break;
 
-        case OID_802_3_MULTICAST_LIST:
-            bytesNeeded = ETHERNET_ADDRESS_LENGTH;
-            if (informationBufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
-                addressCount = informationBufferLength / 
ETHERNET_ADDRESS_LENGTH;
+        case OID_GEN_XMIT_ERROR:
+            Value64 = AdapterGetXmitError(Adapter);
+            BytesToCopy = &Value64;
+            BytesAvailable = sizeof(ULONG64);
+            break;
 
-                ndisStatus = SetMulticastAddresses(Adapter, informationBuffer, 
addressCount);
-                if (ndisStatus == NDIS_STATUS_SUCCESS)
-                    bytesRead = informationBufferLength;
-            } else {
-                ndisStatus = NDIS_STATUS_INVALID_LENGTH;
-            }
+        case OID_GEN_RCV_ERROR:
+            Value64 = AdapterGetRcvError(Adapter);
+            BytesToCopy = &Value64;
+            BytesAvailable = sizeof(ULONG64);
+            break;
 
+        case OID_GEN_DIRECTED_BYTES_XMIT:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
-        case OID_GEN_INTERRUPT_MODERATION:
-            ndisStatus = NDIS_STATUS_INVALID_DATA;
+        case OID_GEN_DIRECTED_FRAMES_XMIT:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
             break;
 
-        case OID_OFFLOAD_ENCAPSULATION: {
-            PNDIS_OFFLOAD_ENCAPSULATION offloadEncapsulation;
+        case OID_GEN_MULTICAST_BYTES_XMIT:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-            bytesNeeded = sizeof(*offloadEncapsulation);
-            if (informationBufferLength >= bytesNeeded) {
-                XENVIF_VIF_OFFLOAD_OPTIONS Options;
+        case OID_GEN_MULTICAST_FRAMES_XMIT:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                bytesRead = bytesNeeded;
-                offloadEncapsulation = informationBuffer;
-                ndisStatus = NDIS_STATUS_SUCCESS;
+        case OID_GEN_BROADCAST_BYTES_XMIT:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if (offloadEncapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON) 
{
-                    if (offloadEncapsulation->IPv4.EncapsulationType != 
NDIS_ENCAPSULATION_IEEE_802_3)
-                        ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-                }
+        case OID_GEN_BROADCAST_FRAMES_XMIT:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if (offloadEncapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON) 
{
-                    if (offloadEncapsulation->IPv6.EncapsulationType != 
NDIS_ENCAPSULATION_IEEE_802_3)
-                        ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-                }
+        case OID_GEN_DIRECTED_BYTES_RCV:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_UNICAST_OCTETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                XENVIF_VIF(TransmitterQueryOffloadOptions,
-                           &Adapter->VifInterface,
-                           &Options);
-                
-                Adapter->Transmitter->OffloadOptions.Value = 0;
-                Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 
1;
+        case OID_GEN_DIRECTED_FRAMES_RCV:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_UNICAST_PACKETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if ((Adapter->Properties.lsov4) && 
(Options.OffloadIpVersion4LargePacket))
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1;
+        case OID_GEN_MULTICAST_BYTES_RCV:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_MULTICAST_OCTETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if ((Adapter->Properties.lsov6) && 
(Options.OffloadIpVersion6LargePacket))
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1;
+        case OID_GEN_MULTICAST_FRAMES_RCV:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_MULTICAST_PACKETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if ((Adapter->Properties.ipv4_csum & 1) && 
Options.OffloadIpVersion4HeaderChecksum)
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+        case OID_GEN_BROADCAST_BYTES_RCV:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_BROADCAST_OCTETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if ((Adapter->Properties.tcpv4_csum & 1) && 
Options.OffloadIpVersion4TcpChecksum)
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+        case OID_GEN_BROADCAST_FRAMES_RCV:
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_BROADCAST_PACKETS,
+                       &Value64);
+            Value32 = (ULONG)Value64;
+            BytesToCopy = &Value32;
+            BytesAvailable = sizeof(ULONG);
+            break;
 
-                if ((Adapter->Properties.udpv4_csum & 1) && 
Options.OffloadIpVersion4UdpChecksum)
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+        case OID_GEN_INTERRUPT_MODERATION:
+            DoCopy = FALSE;
+            BytesAvailable = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
+            if (BufferLength >= BytesAvailable)
+                AdapterGetInterruptModeration(Adapter, Buffer);
+            else
+                NdisStatus = NDIS_STATUS_FAILURE;
+            break;
 
-                if ((Adapter->Properties.tcpv6_csum & 1) && 
Options.OffloadIpVersion6TcpChecksum)
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+        case OID_PNP_QUERY_POWER:
+            // do nothing!
+            break;
 
-                if ((Adapter->Properties.udpv6_csum & 1) && 
Options.OffloadIpVersion6UdpChecksum)
-                    
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+        case OID_GEN_MAC_ADDRESS:
+        case OID_GEN_MAX_LINK_SPEED:
+        case OID_IP4_OFFLOAD_STATS:
+        case OID_IP6_OFFLOAD_STATS:
+        case OID_GEN_SUPPORTED_GUIDS:
+               case OID_GEN_INIT_TIME_MS:
+               case OID_GEN_RESET_COUNTS:
+               case OID_GEN_MEDIA_SENSE_COUNTS:
+        default:
+            NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
+            break;
 
-                Adapter->Receiver.OffloadOptions.Value = 0;
-                Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1;
+    }
 
-                if (Adapter->Properties.need_csum_value)
-                    Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1;
+    if (NdisStatus == NDIS_STATUS_SUCCESS) {
+        Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesAvailable;
+        if (BytesAvailable <= BufferLength) {
+            Request->DATA.QUERY_INFORMATION.BytesWritten = BytesAvailable;
+        } else {
+            Request->DATA.QUERY_INFORMATION.BytesWritten = BufferLength;
+            NdisStatus = NDIS_STATUS_BUFFER_TOO_SHORT;
+        }
+        if (Request->DATA.QUERY_INFORMATION.BytesWritten && DoCopy) {
+            RtlMoveMemory(Buffer, BytesToCopy, 
Request->DATA.QUERY_INFORMATION.BytesWritten);
 
-                if (Adapter->Properties.lrov4) {
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1;
-                    Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
-                }
+            // Its Ok to short transfers on these Oids
+            if (Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_XMIT_OK ||
+                Request->DATA.QUERY_INFORMATION.Oid == OID_GEN_RCV_OK)
+                NdisStatus = NDIS_STATUS_SUCCESS;
+        }
+    }
 
-                if (Adapter->Properties.lrov6) {
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1;
-                    Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
-                }
+    return NdisStatus;
+}
 
-                if (Adapter->Properties.ipv4_csum & 2)
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+NDIS_STATUS
+AdapterOidRequest(
+    IN  PXENNET_ADAPTER             Adapter,
+    IN  PNDIS_OID_REQUEST           Request
+    )
+{
+    NDIS_STATUS     NdisStatus;
+    
+    switch (Request->RequestType) {
+        case NdisRequestSetInformation:            
+            NdisStatus = AdapterSetInformation(Adapter, Request);
+            break;
+                
+        case NdisRequestQueryInformation:
+        case NdisRequestQueryStatistics:
+            NdisStatus = AdapterQueryInformation(Adapter, Request);
+            break;
 
-                if (Adapter->Properties.tcpv4_csum & 2)
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+        default:
+            NdisStatus = NDIS_STATUS_NOT_SUPPORTED;
+            break;
+    };
 
-                if (Adapter->Properties.udpv4_csum & 2)
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+    return NdisStatus;
+}
 
-                if (Adapter->Properties.tcpv6_csum & 2)
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+NTSTATUS
+AdapterEnable(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    NTSTATUS        status;
 
-                if (Adapter->Properties.udpv6_csum & 2)
-                    
Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+    if (Adapter->Enabled)
+        goto done;
 
-                AdapterIndicateOffloadChanged(Adapter);
-            }
-            break;
-        }
-        case OID_TCP_OFFLOAD_PARAMETERS: {
-            PNDIS_OFFLOAD_PARAMETERS offloadParameters;
+    status = XENVIF_VIF(Enable,
+                        &Adapter->VifInterface,
+                        AdapterVifCallback,
+                        Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+    
+    TransmitterEnable(Adapter->Transmitter);
+    Adapter->Enabled = TRUE;
 
-            bytesNeeded = sizeof(*offloadParameters);
-            if (informationBufferLength >= bytesNeeded) {
-                bytesRead = bytesNeeded;
-                offloadParameters = informationBuffer;
-                ndisStatus = NDIS_STATUS_SUCCESS;
+done:
+    return STATUS_SUCCESS;
 
-#define no_change(x)  ((x) == NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
+}
 
-                if (!no_change(offloadParameters->IPsecV1))
-                    ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-                    
-                if (!no_change(offloadParameters->LsoV1))
-                    ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+BOOLEAN
+AdapterDisable(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    if (!Adapter->Enabled)
+        return FALSE;
 
-                if (!no_change(offloadParameters->TcpConnectionIPv4))
-                    ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+    XENVIF_VIF(Disable, &Adapter->VifInterface);
+    Adapter->Enabled = FALSE;
+    return TRUE;
+}
 
-                if (!no_change(offloadParameters->TcpConnectionIPv6))
-                    ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+VOID
+AdapterMediaStateChange(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    NDIS_LINK_STATE                 LinkState;
+    NDIS_STATUS_INDICATION          StatusIndication;
 
-                if (!no_change(offloadParameters->LsoV2IPv4)) {
-                    XENVIF_VIF_OFFLOAD_OPTIONS  Options;
+    RtlZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE));
+    LinkState.Header.Type       = NDIS_OBJECT_TYPE_DEFAULT;
+    LinkState.Header.Size       = sizeof(NDIS_LINK_STATE);
+    LinkState.Header.Revision   = NDIS_LINK_STATE_REVISION_1;
 
-                    XENVIF_VIF(TransmitterQueryOffloadOptions,
-                               &Adapter->VifInterface,
-                               &Options);
+    XENVIF_VIF(MacQueryState,
+               &Adapter->VifInterface,
+               &LinkState.MediaConnectState,
+               &LinkState.RcvLinkSpeed,
+               &LinkState.MediaDuplexState);
 
-                    if (!(Options.OffloadIpVersion4LargePacket))
-                        ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-                }
+    if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
+        Info("LINK: STATE UNKNOWN\n");
+    } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
+        Info("LINK: DOWN\n");
+    } else {
+        ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
 
-                if (!no_change(offloadParameters->LsoV2IPv6)) {
-                    XENVIF_VIF_OFFLOAD_OPTIONS  Options;
+        if (LinkState.MediaDuplexState == MediaDuplexStateHalf) 
+            Info("LINK: UP: SPEED=%u DUPLEX=HALF\n", LinkState.RcvLinkSpeed);
+        else if (LinkState.MediaDuplexState == MediaDuplexStateFull)
+            Info("LINK: UP: SPEED=%u DUPLEX=FULL\n", LinkState.RcvLinkSpeed);
+        else
+            Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n", 
LinkState.RcvLinkSpeed);
+    }
 
-                    XENVIF_VIF(TransmitterQueryOffloadOptions,
-                               &Adapter->VifInterface,
-                               &Options);
+    LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
 
-                    if (!(Options.OffloadIpVersion6LargePacket))
-                        ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
-                }
+    RtlZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION));
+    StatusIndication.Header.Type        = NDIS_OBJECT_TYPE_STATUS_INDICATION;
+    StatusIndication.Header.Size        = sizeof (NDIS_STATUS_INDICATION);
+    StatusIndication.Header.Revision    = NDIS_STATUS_INDICATION_REVISION_1;
+    StatusIndication.SourceHandle       = Adapter->NdisHandle;
+    StatusIndication.StatusCode         = NDIS_STATUS_LINK_STATE;
+    StatusIndication.StatusBuffer       = &LinkState;
+    StatusIndication.StatusBufferSize   = sizeof (NDIS_LINK_STATE);
 
-#define rx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ||       \
-                       (x) == NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED)
-#define tx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED ||       \
-                       (x) == NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED)
-
-                if (ndisStatus == NDIS_STATUS_SUCCESS) {
-                    offloadChanged = FALSE;
-
-                    if (offloadParameters->LsoV2IPv4 == 
NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else if (offloadParameters->LsoV2IPv4 == 
NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (offloadParameters->LsoV2IPv6 == 
NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else if (offloadParameters->LsoV2IPv6 == 
NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (tx_enabled(offloadParameters->IPv4Checksum)) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (tx_enabled(offloadParameters->TCPIPv4Checksum)) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (tx_enabled(offloadParameters->UDPIPv4Checksum)) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (tx_enabled(offloadParameters->TCPIPv6Checksum)) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (tx_enabled(offloadParameters->UDPIPv6Checksum)) {
-                        if 
(!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
-                            
Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (rx_enabled(offloadParameters->IPv4Checksum)) {
-                        if 
(!Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (rx_enabled(offloadParameters->TCPIPv4Checksum)) {
-                        if 
(!Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (rx_enabled(offloadParameters->UDPIPv4Checksum)) {
-                        if 
(!Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (rx_enabled(offloadParameters->TCPIPv6Checksum)) {
-                        if 
(!Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
-
-                    if (rx_enabled(offloadParameters->UDPIPv6Checksum)) {
-                        if 
(!Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
-                            offloadChanged = TRUE;
-                        }
-                    } else {
-                        if 
(Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
-                            
Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 0;
-                            offloadChanged = TRUE;
-                        }
-                    }
+    NdisMIndicateStatusEx(Adapter->NdisHandle, &StatusIndication);
+}
 
-#undef tx_enabled
-#undef rx_enabled
-#undef no_change
+PXENNET_RECEIVER
+AdapterGetReceiver(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    return Adapter->Receiver;
+}
 
-                    if (offloadChanged)
-                        AdapterIndicateOffloadChanged(Adapter);
-                }
-            } else {
-                ndisStatus = NDIS_STATUS_INVALID_LENGTH;
-            }
-            break;
-        }
-        default:
-            ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-            break;
-    };
+PXENNET_TRANSMITTER
+AdapterGetTransmitter(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    return Adapter->Transmitter;
+}
 
-    NdisRequest->DATA.SET_INFORMATION.BytesNeeded = bytesNeeded;
-    if (ndisStatus == NDIS_STATUS_SUCCESS) {
-        NdisRequest->DATA.SET_INFORMATION.BytesRead = bytesRead;
-    }
+PXENVIF_VIF_INTERFACE
+AdapterGetVifInterface(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    return &Adapter->VifInterface;
+}
 
-    return ndisStatus;
+NDIS_HANDLE
+AdapterGetHandle(
+    IN  PXENNET_ADAPTER             Adapter
+    )
+{
+    return Adapter->NdisHandle;
 }
 
-//
-// Sets miniport registration attributes.
-//
-static NDIS_STATUS
-AdapterSetRegistrationAttributes (
-    IN  PADAPTER Adapter
+NTSTATUS
+AdapterInitialize(
+    IN  NDIS_HANDLE                 NdisHandle,
+    OUT PXENNET_ADAPTER             *Adapter
     )
 {
-    PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
-    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registrationAttributes;
-    NDIS_STATUS ndisStatus;
+    PDEVICE_OBJECT          DeviceObject;
+    NTSTATUS                status;
+    NDIS_SG_DMA_DESCRIPTION DmaDescription;
+    NDIS_STATUS             NdisStatus;
+
+    status = STATUS_NO_MEMORY;
+    *Adapter = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENNET_ADAPTER), 
XENNET_POOL_TAG);
+    if (*Adapter == NULL)
+        goto fail1;
 
+    RtlZeroMemory(*Adapter, sizeof(XENNET_ADAPTER));
+    (*Adapter)->NdisHandle = NdisHandle;
+
+    DeviceObject = NULL;
+    NdisMGetDeviceProperty(NdisHandle,
+                           &DeviceObject,
+                           NULL,
+                           NULL,
+                           NULL,
+                           NULL);
+
+    status = QUERY_INTERFACE(DeviceObject,
+                             XENVIF,
+                             VIF,
+                             XENVIF_VIF_INTERFACE_VERSION_MAX,
+                             (PINTERFACE)&(*Adapter)->VifInterface,
+                             sizeof ((*Adapter)->VifInterface),
+                             FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail2;
 
-    NdisZeroMemory(&registrationAttributes, 
-                   sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
+    status = XENVIF_VIF(Acquire, &(*Adapter)->VifInterface);
+    if (!NT_SUCCESS(status))
+        goto fail3;
 
-    registrationAttributes.Header.Type = 
-                NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
+    status = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
+    if (!NT_SUCCESS(status))
+        goto fail4;
 
-    registrationAttributes.Header.Revision = 
-                NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
+    status = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
+    if (!NT_SUCCESS(status))
+        goto fail5;
 
-    registrationAttributes.Header.Size = 
-                sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
+    NdisStatus = AdapterGetAdvancedSettings(*Adapter);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+        goto fail6;
 
-    registrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)Adapter;
-    registrationAttributes.AttributeFlags = 
NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER |
-                                            
NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
-    
-    registrationAttributes.CheckForHangTimeInSeconds = 0;
-    registrationAttributes.InterfaceType = XENNET_INTERFACE_TYPE;
+    NdisStatus = AdapterSetRegistrationAttributes(*Adapter);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+        goto fail7;
 
-    adapterAttributes = 
-                (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&registrationAttributes;
+    NdisStatus = AdapterSetGeneralAttributes(*Adapter);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+        goto fail8;
 
-    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            adapterAttributes);
+    NdisStatus = AdapterSetOffloadAttributes(*Adapter);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+        goto fail9;
 
-    return ndisStatus;
-}
+    NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));
+    DmaDescription.Header.Type      = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
+    DmaDescription.Header.Size      = sizeof(NDIS_SG_DMA_DESCRIPTION);
+    DmaDescription.Header.Revision  = NDIS_SG_DMA_DESCRIPTION_REVISION_1;
+    DmaDescription.Flags            = NDIS_SG_DMA_64_BIT_ADDRESS;
+    DmaDescription.MaximumPhysicalMapping           = 65536;    
+    DmaDescription.ProcessSGListHandler             = AdapterProcessSGList;
+    DmaDescription.SharedMemAllocateCompleteHandler = AdapterAllocateComplete;
 
-//
-// Shuts down adapter.
-//
-VOID 
-AdapterShutdown (
-    IN  NDIS_HANDLE             MiniportAdapterContext,
-    IN  NDIS_SHUTDOWN_ACTION    ShutdownAction
-    )
-{
-    PADAPTER Adapter = (PADAPTER)MiniportAdapterContext;
+    NdisStatus = NdisMRegisterScatterGatherDma((*Adapter)->NdisHandle,
+                                               &DmaDescription,
+                                               &(*Adapter)->NdisDmaHandle);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+        (*Adapter)->NdisDmaHandle = NULL;
 
-    UNREFERENCED_PARAMETER(ShutdownAction);
+    status = AdapterEnable(*Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail10;
 
-    if (ShutdownAction != NdisShutdownBugCheck)
-        AdapterStop(Adapter);
+    return STATUS_SUCCESS;
 
-    return;
+fail10:
+    Error("fail10 (%08x)\n", status);
+    if ((*Adapter)->NdisDmaHandle)
+        NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
+    (*Adapter)->NdisDmaHandle = NULL;
+fail9:
+    Error("fail9\n");
+fail8:
+    Error("fail8\n");
+fail7:
+    Error("fail7\n");
+fail6:
+    Error("fail6 (%08x)\n", NdisStatus);
+    if (NT_SUCCESS(status))
+        status = STATUS_UNSUCCESSFUL;
+    ReceiverTeardown((*Adapter)->Receiver);
+    (*Adapter)->Receiver = NULL;
+fail5:
+    Error("fail5\n");
+    TransmitterTeardown((*Adapter)->Transmitter);
+    (*Adapter)->Transmitter = NULL;
+fail4:
+    Error("fail4\n");
+    XENVIF_VIF(Release, &(*Adapter)->VifInterface);
+fail3:
+    Error("fail3\n");
+    RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
+fail2:
+    Error("fail2\n");
+    ExFreePoolWithTag(*Adapter, XENNET_POOL_TAG);
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
 }
 
-//
-// Stops adapter. Waits for currently transmitted packets to complete.
-// Stops transmission of new packets.
-// Stops received packet indication to NDIS.
-//
-NDIS_STATUS
-AdapterStop (
-IN  PADAPTER    Adapter
-)
+VOID
+AdapterTeardown(
+    IN  PXENNET_ADAPTER             Adapter
+    )
 {
-    Trace("====>\n");
+    if (Adapter->NdisDmaHandle)
+        NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
+    Adapter->NdisDmaHandle = NULL;
 
-    if (!Adapter->Enabled)
-        goto done;
+    ReceiverTeardown(Adapter->Receiver);
+    Adapter->Receiver = NULL;
 
-    XENVIF_VIF(Disable,
-               &Adapter->VifInterface);
+    TransmitterTeardown(Adapter->Transmitter);
+    Adapter->Transmitter = NULL;
 
-    Adapter->Enabled = FALSE;
+    XENVIF_VIF(Release, &Adapter->VifInterface);
+    RtlZeroMemory(&Adapter->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
 
-done:
-    Trace("<====\n");
-    return NDIS_STATUS_SUCCESS;
+    ExFreePoolWithTag(Adapter, XENNET_POOL_TAG);
 }
+
+//
+//#define DISPLAY_OFFLOAD(_Offload)                                   \
+//        do {                                                        \
+//            if ((_Offload).Checksum.IPv4Receive.IpChecksum)         \
+//                Info("Checksum.IPv4Receive.IpChecksum ON\n");       \
+//            else                                                    \
+//                Info("Checksum.IPv4Receive.IpChecksum OFF\n");      \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv4Receive.TcpChecksum)        \
+//                Info("Checksum.IPv4Receive.TcpChecksum ON\n");      \
+//            else                                                    \
+//                Info("Checksum.IPv4Receive.TcpChecksum OFF\n");     \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv4Receive.UdpChecksum)        \
+//                Info("Checksum.IPv4Receive.UdpChecksum ON\n");      \
+//            else                                                    \
+//                Info("Checksum.IPv4Receive.UdpChecksum OFF\n");     \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv6Receive.TcpChecksum)        \
+//                Info("Checksum.IPv6Receive.TcpChecksum ON\n");      \
+//            else                                                    \
+//                Info("Checksum.IPv6Receive.TcpChecksum OFF\n");     \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv6Receive.UdpChecksum)        \
+//                Info("Checksum.IPv6Receive.UdpChecksum ON\n");      \
+//            else                                                    \
+//                Info("Checksum.IPv6Receive.UdpChecksum OFF\n");     \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv4Transmit.IpChecksum)        \
+//                Info("Checksum.IPv4Transmit.IpChecksum ON\n");      \
+//            else                                                    \
+//                Info("Checksum.IPv4Transmit.IpChecksum OFF\n");     \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv4Transmit.TcpChecksum)       \
+//                Info("Checksum.IPv4Transmit.TcpChecksum ON\n");     \
+//            else                                                    \
+//                Info("Checksum.IPv4Transmit.TcpChecksum OFF\n");    \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv4Transmit.UdpChecksum)       \
+//                Info("Checksum.IPv4Transmit.UdpChecksum ON\n");     \
+//            else                                                    \
+//                Info("Checksum.IPv4Transmit.UdpChecksum OFF\n");    \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv6Transmit.TcpChecksum)       \
+//                Info("Checksum.IPv6Transmit.TcpChecksum ON\n");     \
+//            else                                                    \
+//                Info("Checksum.IPv6Transmit.TcpChecksum OFF\n");    \
+//                                                                    \
+//            if ((_Offload).Checksum.IPv6Transmit.UdpChecksum)       \
+//                Info("Checksum.IPv6Transmit.UdpChecksum ON\n");     \
+//            else                                                    \
+//                Info("Checksum.IPv6Transmit.UdpChecksum OFF\n");    \
+//                                                                    \
+//            if ((_Offload).LsoV2.IPv4.MaxOffLoadSize != 0)          \
+//                Info("LsoV2.IPv4.MaxOffLoadSize = %u\n",            \
+//                     (_Offload).LsoV2.IPv4.MaxOffLoadSize);         \
+//            else                                                    \
+//                Info("LsoV2.IPv4 OFF\n");                           \
+//                                                                    \
+//            if ((_Offload).LsoV2.IPv6.MaxOffLoadSize != 0)          \
+//                Info("LsoV2.IPv6.MaxOffLoadSize = %u\n",            \
+//                     (_Offload).LsoV2.IPv6.MaxOffLoadSize);         \
+//            else                                                    \
+//                Info("LsoV2.IPv6 OFF\n");                           \
+//        } while (FALSE)
+//
diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h
index e64e40d..a1f4b85 100644
--- a/src/xennet/adapter.h
+++ b/src/xennet/adapter.h
@@ -29,19 +29,20 @@
  * SUCH DAMAGE.
  */
 
-#pragma once
+#ifndef _XENNET_ADAPTER_H_
+#define _XENNET_ADAPTER_H_
 
-#define XENNET_INTERFACE_TYPE           NdisInterfaceInternal
+#define XENNET_INTERFACE_TYPE   NdisInterfaceInternal
 
-#define XENNET_MEDIA_TYPE               NdisMedium802_3
+#define XENNET_MEDIA_TYPE       NdisMedium802_3
 
-#define XENNET_MAC_OPTIONS              (NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | 
 \
-                                         NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |  
 \
-                                         NDIS_MAC_OPTION_NO_LOOPBACK |         
 \
-                                         NDIS_MAC_OPTION_8021P_PRIORITY |      
 \
-                                         
NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE)
+#define XENNET_MAC_OPTIONS      (NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |  \
+                                 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |   \
+                                 NDIS_MAC_OPTION_NO_LOOPBACK |          \
+                                 NDIS_MAC_OPTION_8021P_PRIORITY |       \
+                                 
NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE)
 
-typedef struct _PROPERTIES {
+typedef struct _XENNET_PROPERTIES {
     int ipv4_csum;
     int tcpv4_csum;
     int udpv4_csum;
@@ -52,122 +53,63 @@ typedef struct _PROPERTIES {
     int lsov6;
     int lrov4;
     int lrov6;
-} PROPERTIES, *PPROPERTIES;
-
-struct _ADAPTER {
-    LIST_ENTRY              ListEntry;
-    XENVIF_VIF_INTERFACE    VifInterface;
-    BOOLEAN                 AcquiredInterfaces;
-    ULONG                   MaximumFrameSize;
-    ULONG                   CurrentLookahead;
-    NDIS_HANDLE             NdisAdapterHandle;
-    NDIS_HANDLE             NdisDmaHandle;
-    NDIS_PNP_CAPABILITIES   Capabilities;
-    PROPERTIES              Properties;
-    RECEIVER                Receiver;
-    PTRANSMITTER            Transmitter;
-    BOOLEAN                 Enabled;
-    NDIS_OFFLOAD            Offload;
-};
-
-MINIPORT_CANCEL_OID_REQUEST AdapterCancelOidRequest;
-VOID
-AdapterCancelOidRequest (
-    IN  NDIS_HANDLE NdisHandle,
-    IN  PVOID       RequestId
-    );
-
-MINIPORT_CANCEL_SEND AdapterCancelSendNetBufferLists;
-VOID 
-AdapterCancelSendNetBufferLists (
-    IN  NDIS_HANDLE NdisHandle,
-    IN  PVOID       CancelId
-    );
+} XENNET_PROPERTIES, *PXENNET_PROPERTIES;
 
-MINIPORT_CHECK_FOR_HANG AdapterCheckForHang;
-BOOLEAN 
-AdapterCheckForHang (
-    IN  NDIS_HANDLE NdisHandle
-    );
-
-VOID
-AdapterCleanup (
-    IN PADAPTER Adapter
-    );
+typedef struct _XENNET_ADAPTER  XENNET_ADAPTER, *PXENNET_ADAPTER;
 
-NDIS_STATUS 
-AdapterInitialize (
-    IN  PADAPTER    Adapter,
-    IN  NDIS_HANDLE AdapterHandle
+extern NDIS_STATUS
+AdapterOidRequest(
+    IN  PXENNET_ADAPTER             Adapter,
+    IN  PNDIS_OID_REQUEST           Request
     );
 
-MINIPORT_OID_REQUEST AdapterOidRequest;
-NDIS_STATUS 
-AdapterOidRequest (
-    IN  NDIS_HANDLE         NdisHandle,
-    IN  PNDIS_OID_REQUEST   NdisRequest
+extern NTSTATUS
+AdapterEnable(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-MINIPORT_PAUSE AdapterPause;
-NDIS_STATUS 
-AdapterPause (
-    IN  NDIS_HANDLE                     NdisHandle,
-    IN  PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters
+extern BOOLEAN
+AdapterDisable(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-MINIPORT_DEVICE_PNP_EVENT_NOTIFY AdapterPnPEventHandler;
-VOID 
-AdapterPnPEventHandler (
-    IN  NDIS_HANDLE             NdisHandle,
-    IN  PNET_DEVICE_PNP_EVENT   NetDevicePnPEvent
+extern VOID
+AdapterMediaStateChange(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-MINIPORT_RESET AdapterReset;
-NDIS_STATUS 
-AdapterReset (
-    IN  NDIS_HANDLE     MiniportAdapterContext,
-    OUT PBOOLEAN        AddressingReset
+#include "receiver.h"
+extern PXENNET_RECEIVER
+AdapterGetReceiver(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-MINIPORT_RESTART AdapterRestart;
-NDIS_STATUS 
-AdapterRestart (
-    IN  NDIS_HANDLE                         MiniportAdapterContext,
-    IN  PNDIS_MINIPORT_RESTART_PARAMETERS   MiniportRestartParameters
+#include "transmitter.h"
+extern PXENNET_TRANSMITTER
+AdapterGetTransmitter(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-MINIPORT_RETURN_NET_BUFFER_LISTS AdapterReturnNetBufferLists;
-VOID 
-AdapterReturnNetBufferLists (
-    IN  NDIS_HANDLE         MiniportAdapterContext,
-    IN  PNET_BUFFER_LIST    NetBufferLists,
-    IN  ULONG               ReturnFlags
+#include <vif_interface.h>
+extern PXENVIF_VIF_INTERFACE
+AdapterGetVifInterface(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-MINIPORT_SEND_NET_BUFFER_LISTS AdapterSendNetBufferLists;
-VOID 
-AdapterSendNetBufferLists (
-    IN  NDIS_HANDLE         MiniportAdapterContext,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  NDIS_PORT_NUMBER    PortNumber,
-    IN  ULONG               SendFlags
+extern NDIS_HANDLE
+AdapterGetHandle(
+    IN  PXENNET_ADAPTER             Adapter
     );
 
-NDIS_STATUS
-AdapterStop (
-    IN  PADAPTER    Adapter
-    );
-
-MINIPORT_SHUTDOWN AdapterShutdown;
-
-VOID 
-AdapterShutdown (
-    IN  NDIS_HANDLE             MiniportAdapterContext,
-    IN  NDIS_SHUTDOWN_ACTION    ShutdownAction
+extern NTSTATUS
+AdapterInitialize(
+    IN  NDIS_HANDLE                 NdisHandle,
+    OUT PXENNET_ADAPTER             *Adapter
     );
 
 extern VOID
-ReceiverReceivePackets(
-    IN  PRECEIVER   Receiver,
-    IN  PLIST_ENTRY List
+AdapterTeardown(
+    IN  PXENNET_ADAPTER             Adapter
     );
+
+#endif // _XENNET_ADAPTER_H_
diff --git a/src/xennet/common.h b/src/xennet/common.h
deleted file mode 100644
index 4d4c04a..0000000
--- a/src/xennet/common.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-#pragma once
-
-#include "std.h"
-#include "project.h"
-#include "dbg_print.h"
-#include "assert.h"
diff --git a/src/xennet/driver.c b/src/xennet/driver.c
new file mode 100644
index 0000000..66aff1d
--- /dev/null
+++ b/src/xennet/driver.c
@@ -0,0 +1,550 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#include <ndis.h>
+#include <ntstrsafe.h>
+#include <version.h>
+
+#include "adapter.h"
+#include "transmitter.h"
+#include "receiver.h"
+#include "registry.h"
+#include "dbg_print.h"
+#include "assert.h"
+
+extern PULONG InitSafeBootMode;
+
+typedef struct _XENNET_DRIVER {
+    PDRIVER_OBJECT              DriverObject;
+    NDIS_HANDLE                 MiniportHandle;
+    NTSTATUS                    (*NdisDispatchPnp)(PDEVICE_OBJECT, PIRP);
+} XENNET_DRIVER;
+
+static XENNET_DRIVER            Driver;
+
+MINIPORT_CANCEL_OID_REQUEST     DriverCancelOidRequest;
+VOID
+DriverCancelOidRequest(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  PVOID                   RequestId
+    )
+{
+    UNREFERENCED_PARAMETER(NdisHandle);
+    UNREFERENCED_PARAMETER(RequestId);
+}
+
+MINIPORT_CANCEL_SEND            DriverCancelSendNetBufferLists;
+VOID
+DriverCancelSendNetBufferLists(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  PVOID                   CancelId
+    )
+{
+    UNREFERENCED_PARAMETER(NdisHandle);
+    UNREFERENCED_PARAMETER(CancelId);
+}
+
+MINIPORT_CHECK_FOR_HANG DriverCheckForHang;
+BOOLEAN
+DriverCheckForHang(
+    IN  NDIS_HANDLE             NdisHandle
+    )
+{
+    UNREFERENCED_PARAMETER(NdisHandle);
+    return FALSE;
+}
+
+MINIPORT_DEVICE_PNP_EVENT_NOTIFY DriverPnPEventHandler;
+VOID
+DriverPnPEventHandler(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  PNET_DEVICE_PNP_EVENT   NetDevicePnPEvent
+    )
+{
+    UNREFERENCED_PARAMETER(NdisHandle);
+    UNREFERENCED_PARAMETER(NetDevicePnPEvent);
+}
+
+MINIPORT_RESET                  DriverReset;
+NDIS_STATUS
+DriverReset(
+    IN  NDIS_HANDLE             NdisHandle,
+    OUT PBOOLEAN                AddressingReset
+    )
+{
+    UNREFERENCED_PARAMETER(NdisHandle);
+    *AddressingReset = FALSE;
+    return NDIS_STATUS_SUCCESS;
+}
+
+MINIPORT_OID_REQUEST            DriverOidRequest;
+NDIS_STATUS
+DriverOidRequest(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  PNDIS_OID_REQUEST       NdisRequest
+    )
+{
+    return AdapterOidRequest((PXENNET_ADAPTER)NdisHandle, NdisRequest);
+}
+
+MINIPORT_PAUSE DriverPause;
+NDIS_STATUS
+DriverPause(
+    IN  NDIS_HANDLE                     NdisHandle,
+    IN  PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters
+    )
+{
+    UNREFERENCED_PARAMETER(MiniportPauseParameters);
+
+    if (AdapterDisable((PXENNET_ADAPTER)NdisHandle))
+        AdapterMediaStateChange((PXENNET_ADAPTER)NdisHandle);
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+MINIPORT_RESTART DriverRestart;
+NDIS_STATUS
+DriverRestart(
+    IN  NDIS_HANDLE                         NdisHandle,
+    IN  PNDIS_MINIPORT_RESTART_PARAMETERS   MiniportRestartParameters
+    )
+{
+    NTSTATUS    status;
+
+    UNREFERENCED_PARAMETER(MiniportRestartParameters);
+
+    status = AdapterEnable((PXENNET_ADAPTER)NdisHandle);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return NDIS_STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return NDIS_STATUS_FAILURE;
+}
+
+MINIPORT_RETURN_NET_BUFFER_LISTS DriverReturnNetBufferLists;
+VOID
+DriverReturnNetBufferLists(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  PNET_BUFFER_LIST        NetBufferLists,
+    IN  ULONG                   ReturnFlags
+    )
+{
+    PXENNET_RECEIVER            Receiver;
+    Receiver = AdapterGetReceiver((PXENNET_ADAPTER)NdisHandle);
+    ReceiverReturnNetBufferLists(Receiver,
+                                 NetBufferLists,
+                                 ReturnFlags);
+}
+
+MINIPORT_SEND_NET_BUFFER_LISTS  DriverSendNetBufferLists;
+VOID
+DriverSendNetBufferLists(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  NDIS_PORT_NUMBER        PortNumber,
+    IN  ULONG                   SendFlags
+    )
+{
+    PXENNET_TRANSMITTER         Transmitter;
+    Transmitter = AdapterGetTransmitter((PXENNET_ADAPTER)NdisHandle);
+    TransmitterSendNetBufferLists(Transmitter,
+                                  NetBufferList,
+                                  PortNumber,
+                                  SendFlags);
+}
+
+MINIPORT_SHUTDOWN DriverShutdown;
+VOID
+DriverShutdown(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  NDIS_SHUTDOWN_ACTION    ShutdownAction
+    )
+{
+    UNREFERENCED_PARAMETER(ShutdownAction);
+
+    if (ShutdownAction != NdisShutdownBugCheck)
+        (VOID)AdapterDisable((PXENNET_ADAPTER)NdisHandle);
+}
+
+MINIPORT_INITIALIZE             DriverInitialize;
+NDIS_STATUS 
+DriverInitialize(
+    IN  NDIS_HANDLE                        NdisHandle,
+    IN  NDIS_HANDLE                        DriverContext,
+    IN  PNDIS_MINIPORT_INIT_PARAMETERS     Parameters
+    )
+{
+    NTSTATUS            status;
+    PXENNET_ADAPTER     Adapter;
+
+    UNREFERENCED_PARAMETER(DriverContext);
+    UNREFERENCED_PARAMETER(Parameters);
+
+    status = AdapterInitialize(NdisHandle, &Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return NDIS_STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return NDIS_STATUS_ADAPTER_NOT_FOUND;
+}
+
+MINIPORT_HALT                   DriverHalt;
+VOID 
+DriverHalt(
+    IN  NDIS_HANDLE             NdisHandle,
+    IN  NDIS_HALT_ACTION        HaltAction
+    )
+{
+    if (NdisHandle == NULL)
+        return;
+
+    UNREFERENCED_PARAMETER(HaltAction);
+
+    (VOID)AdapterDisable((PXENNET_ADAPTER)NdisHandle);
+    AdapterTeardown((PXENNET_ADAPTER)NdisHandle);
+}
+
+typedef struct _XENNET_CONTEXT {
+    PDEVICE_CAPABILITIES    Capabilities;
+    PIO_COMPLETION_ROUTINE  CompletionRoutine;
+    PVOID                   CompletionContext;
+    UCHAR                   CompletionControl;
+} XENNET_CONTEXT, *PXENNET_CONTEXT;
+
+__drv_functionClass(IO_COMPLETION_ROUTINE)
+static NTSTATUS
+__QueryCapabilities(
+    IN  PDEVICE_OBJECT      DeviceObject,
+    IN  PIRP                Irp,
+    IN  PVOID               _Context
+    )
+{
+    PXENNET_CONTEXT         Context = _Context;
+    NTSTATUS                status;
+
+    Trace("====>\n");
+
+    Context->Capabilities->SurpriseRemovalOK = 1;
+
+    if (Context->CompletionRoutine != NULL &&
+        (Context->CompletionControl & SL_INVOKE_ON_SUCCESS))
+        status = Context->CompletionRoutine(DeviceObject, Irp, 
Context->CompletionContext);
+    else
+        status = STATUS_SUCCESS;
+
+    ExFreePool(Context);
+
+    Trace("<====\n");
+
+    return status;
+}
+
+NTSTATUS 
+QueryCapabilities(
+    IN PDEVICE_OBJECT       DeviceObject,
+    IN PIRP                 Irp
+    )
+{
+    PIO_STACK_LOCATION      StackLocation;
+    PXENNET_CONTEXT         Context;
+    NTSTATUS                status;
+
+    Trace("====>\n");
+
+    Trace("%p\n", DeviceObject); 
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+    Context = ExAllocatePoolWithTag(NonPagedPool, sizeof (XENNET_CONTEXT), ' 
TEN');
+    if (Context != NULL) {
+        Context->Capabilities = 
StackLocation->Parameters.DeviceCapabilities.Capabilities;
+        Context->CompletionRoutine = StackLocation->CompletionRoutine;
+        Context->CompletionContext = StackLocation->Context;
+        Context->CompletionControl = StackLocation->Control;
+
+        StackLocation->CompletionRoutine = __QueryCapabilities;
+        StackLocation->Context = Context;
+        StackLocation->Control = SL_INVOKE_ON_SUCCESS;
+    }
+
+    status = Driver.NdisDispatchPnp(DeviceObject, Irp);
+
+    Trace("<====\n");
+
+    return status;    
+}
+
+_Dispatch_type_(IRP_MJ_PNP)
+DRIVER_DISPATCH DispatchPnp;
+
+NTSTATUS 
+DispatchPnp(
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp
+    )
+{
+    PIO_STACK_LOCATION  StackLocation;
+    UCHAR               MinorFunction;
+    NTSTATUS            status;
+
+    StackLocation = IoGetCurrentIrpStackLocation(Irp);
+    MinorFunction = StackLocation->MinorFunction;
+
+    switch (StackLocation->MinorFunction) {
+    case IRP_MN_QUERY_CAPABILITIES:
+        status = QueryCapabilities(DeviceObject, Irp);
+        break;
+
+    default:
+        status = Driver.NdisDispatchPnp(DeviceObject, Irp);
+        break;
+    }
+
+    return status;
+}
+
+_Dispatch_type_(IRP_MJ_CREATE)
+_Dispatch_type_(IRP_MJ_CLOSE)
+_Dispatch_type_(IRP_MJ_DEVICE_CONTROL)
+DRIVER_DISPATCH DispatchFail;
+
+NTSTATUS 
+DispatchFail(
+    IN PDEVICE_OBJECT   DeviceObject,
+    IN PIRP             Irp
+    )
+{
+    UNREFERENCED_PARAMETER(DeviceObject);
+
+    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    
+    return STATUS_UNSUCCESSFUL;
+}
+
+MINIPORT_UNLOAD         DriverUnload;
+
+VOID 
+DriverUnload(
+    IN  PDRIVER_OBJECT  DriverObject
+    )
+{
+    Trace("====>\n");
+
+    if (*InitSafeBootMode > 0)
+        goto done;
+
+    ASSERT3P(Driver.DriverObject, ==, DriverObject);
+    Driver.DriverObject = NULL;
+
+    if (Driver.MiniportHandle)
+        NdisMDeregisterMiniportDriver(Driver.MiniportHandle);
+    Driver.MiniportHandle = NULL;
+
+    Driver.NdisDispatchPnp = NULL;
+
+    RegistryTeardown();
+
+    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+done:
+    Trace("<====\n");
+}
+
+DRIVER_INITIALIZE       DriverEntry;
+
+NTSTATUS 
+DriverEntry(
+    IN  PDRIVER_OBJECT                      DriverObject,
+    IN  PUNICODE_STRING                     RegistryPath
+    )
+{
+    NDIS_STATUS                             ndisStatus;
+    NDIS_MINIPORT_DRIVER_CHARACTERISTICS    mpChars;
+    NDIS_CONFIGURATION_OBJECT               ConfigurationObject;
+    NDIS_HANDLE                             ConfigurationHandle;
+    NDIS_STRING                             ParameterName;
+    PNDIS_CONFIGURATION_PARAMETER           ParameterValue;
+    ULONG                                   FailCreateClose;
+    ULONG                                   FailDeviceControl;
+    NTSTATUS                                status;
+
+    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
+
+    Trace("====>\n");
+
+    if (*InitSafeBootMode > 0)
+        return NDIS_STATUS_SUCCESS;
+
+    ASSERT3P(Driver.DriverObject, ==, NULL);
+    Driver.DriverObject = DriverObject;
+
+    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+    status = RegistryInitialize(RegistryPath);
+
+    ndisStatus = (NT_SUCCESS(status)) ?
+                 NDIS_STATUS_SUCCESS :
+                 NDIS_STATUS_FAILURE;
+
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail1;
+
+    //
+    // Register miniport with NDIS.
+    //
+
+    RtlZeroMemory(&mpChars, sizeof(mpChars));
+    mpChars.Header.Type         = 
NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,
+    mpChars.Header.Size         = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
+    mpChars.Header.Revision     = 
NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
+
+    mpChars.MajorNdisVersion    = 6;
+    mpChars.MinorNdisVersion    = 0;
+    mpChars.MajorDriverVersion  = MAJOR_VERSION;
+    mpChars.MinorDriverVersion  = MINOR_VERSION;
+
+    mpChars.CancelOidRequestHandler     = DriverCancelOidRequest;
+    mpChars.CancelSendHandler           = DriverCancelSendNetBufferLists;
+    mpChars.CheckForHangHandlerEx       = DriverCheckForHang;
+    mpChars.InitializeHandlerEx         = DriverInitialize;
+    mpChars.HaltHandlerEx               = DriverHalt;
+    mpChars.OidRequestHandler           = DriverOidRequest;    
+    mpChars.PauseHandler                = DriverPause;      
+    mpChars.DevicePnPEventNotifyHandler = DriverPnPEventHandler;
+    mpChars.ResetHandlerEx              = DriverReset;
+    mpChars.RestartHandler              = DriverRestart;    
+    mpChars.ReturnNetBufferListsHandler = DriverReturnNetBufferLists;
+    mpChars.SendNetBufferListsHandler   = DriverSendNetBufferLists;
+    mpChars.ShutdownHandlerEx           = DriverShutdown;
+    mpChars.UnloadHandler               = DriverUnload;
+
+    Driver.MiniportHandle = NULL;
+    ndisStatus = NdisMRegisterMiniportDriver(DriverObject,
+                                             RegistryPath,
+                                             NULL,
+                                             &mpChars,
+                                             &Driver.MiniportHandle);
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail2;
+
+    RtlZeroMemory(&ConfigurationObject, sizeof(ConfigurationObject));
+    ConfigurationObject.Header.Type     = 
NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
+    ConfigurationObject.Header.Size     = 
NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
+    ConfigurationObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
+    ConfigurationObject.NdisHandle      = Driver.MiniportHandle;
+    ConfigurationObject.Flags           = 0;
+
+    ndisStatus = NdisOpenConfigurationEx(&ConfigurationObject, 
&ConfigurationHandle);
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail3;
+
+    RtlInitUnicodeString(&ParameterName, L"FailCreateClose");
+
+    NdisReadConfiguration(&ndisStatus,
+                          &ParameterValue,
+                          ConfigurationHandle,
+                          &ParameterName,
+                          NdisParameterInteger);
+    if (ndisStatus == NDIS_STATUS_SUCCESS &&
+        ParameterValue->ParameterType == NdisParameterInteger)
+        FailCreateClose = ParameterValue->ParameterData.IntegerData;
+    else
+        FailCreateClose = 0;
+
+    RtlInitUnicodeString(&ParameterName, L"FailDeviceControl");
+
+    NdisReadConfiguration(&ndisStatus,
+                          &ParameterValue,
+                          ConfigurationHandle,
+                          &ParameterName,
+                          NdisParameterInteger);
+    if (ndisStatus == NDIS_STATUS_SUCCESS &&
+        ParameterValue->ParameterType == NdisParameterInteger)
+        FailDeviceControl = ParameterValue->ParameterData.IntegerData;
+    else
+        FailDeviceControl = 0;
+
+    NdisCloseConfiguration(ConfigurationHandle);
+
+    Driver.NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP];
+    DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+
+    if (FailCreateClose != 0) {
+        DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchFail;
+        DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchFail;
+    }
+
+    if (FailDeviceControl != 0) {
+        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail;
+    }
+
+    Trace("<====\n");
+    return NDIS_STATUS_SUCCESS;
+
+fail3:
+    Error("fail3\n");
+
+    NdisMDeregisterMiniportDriver(Driver.MiniportHandle);
+    Driver.MiniportHandle = NULL;
+
+fail2:
+    Error("fail2\n");
+
+    RegistryTeardown();
+
+fail1:
+    Error("fail1\n");
+
+    Driver.DriverObject = NULL;
+    return ndisStatus;
+}
+
diff --git a/src/xennet/main.c b/src/xennet/main.c
deleted file mode 100644
index 6622e82..0000000
--- a/src/xennet/main.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#include <version.h>
-
-#include "common.h"
-#include "registry.h"
-
-#pragma NDIS_INIT_FUNCTION(DriverEntry)
-
-//
-// Global miniport data.
-//
-
-static NDIS_HANDLE MiniportDriverHandle;
-
-extern MINIPORT_INITIALIZE MiniportInitialize;
-
-extern NDIS_STATUS 
-MiniportInitialize (
-    IN  NDIS_HANDLE                        MiniportAdapterHandle,
-    IN  NDIS_HANDLE                        MiniportDriverContext,
-    IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
-    );
-
-MINIPORT_HALT MiniportHalt;
-
-extern VOID 
-MiniportHalt (
-    IN  NDIS_HANDLE                        MiniportAdapterHandle,
-    IN  NDIS_HALT_ACTION                   HaltAction
-    );
-
-typedef struct _XENNET_CONTEXT {
-    PDEVICE_CAPABILITIES    Capabilities;
-    PIO_COMPLETION_ROUTINE  CompletionRoutine;
-    PVOID                   CompletionContext;
-    UCHAR                   CompletionControl;
-} XENNET_CONTEXT, *PXENNET_CONTEXT;
-
-static NTSTATUS (*NdisDispatchPnp)(PDEVICE_OBJECT, PIRP);
-
-__drv_functionClass(IO_COMPLETION_ROUTINE)
-static NTSTATUS
-__QueryCapabilities(
-    IN  PDEVICE_OBJECT      DeviceObject,
-    IN  PIRP                Irp,
-    IN  PVOID               _Context
-    )
-{
-    PXENNET_CONTEXT         Context = _Context;
-    NTSTATUS                status;
-
-    Trace("====>\n");
-
-    Context->Capabilities->SurpriseRemovalOK = 1;
-
-    if (Context->CompletionRoutine != NULL &&
-        (Context->CompletionControl & SL_INVOKE_ON_SUCCESS))
-        status = Context->CompletionRoutine(DeviceObject, Irp, 
Context->CompletionContext);
-    else
-        status = STATUS_SUCCESS;
-
-    ExFreePool(Context);
-
-    Trace("<====\n");
-
-    return status;
-}
-
-NTSTATUS 
-QueryCapabilities(
-    IN PDEVICE_OBJECT       DeviceObject,
-    IN PIRP                 Irp
-    )
-{
-    PIO_STACK_LOCATION      StackLocation;
-    PXENNET_CONTEXT         Context;
-    NTSTATUS                status;
-
-    Trace("====>\n");
-
-    Trace("%p\n", DeviceObject); 
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-
-    Context = ExAllocatePoolWithTag(NonPagedPool, sizeof (XENNET_CONTEXT), ' 
TEN');
-    if (Context != NULL) {
-        Context->Capabilities = 
StackLocation->Parameters.DeviceCapabilities.Capabilities;
-        Context->CompletionRoutine = StackLocation->CompletionRoutine;
-        Context->CompletionContext = StackLocation->Context;
-        Context->CompletionControl = StackLocation->Control;
-
-        StackLocation->CompletionRoutine = __QueryCapabilities;
-        StackLocation->Context = Context;
-        StackLocation->Control = SL_INVOKE_ON_SUCCESS;
-    }
-
-    status = NdisDispatchPnp(DeviceObject, Irp);
-
-    Trace("<====\n");
-
-    return status;    
-}
-
-DRIVER_DISPATCH DispatchPnp;
-
-NTSTATUS 
-DispatchPnp(
-    IN PDEVICE_OBJECT   DeviceObject,
-    IN PIRP             Irp
-    )
-{
-    PIO_STACK_LOCATION  StackLocation;
-    UCHAR               MinorFunction;
-    NTSTATUS            status;
-
-    StackLocation = IoGetCurrentIrpStackLocation(Irp);
-    MinorFunction = StackLocation->MinorFunction;
-
-    switch (StackLocation->MinorFunction) {
-    case IRP_MN_QUERY_CAPABILITIES:
-        status = QueryCapabilities(DeviceObject, Irp);
-        break;
-
-    default:
-        status = NdisDispatchPnp(DeviceObject, Irp);
-        break;
-    }
-
-    return status;
-}
-
-DRIVER_DISPATCH DispatchFail;
-
-NTSTATUS 
-DispatchFail(
-    IN PDEVICE_OBJECT   DeviceObject,
-    IN PIRP             Irp
-    )
-{
-    NTSTATUS            status;
-
-    UNREFERENCED_PARAMETER(DeviceObject);
-
-    Trace("%p\n", Irp);
-
-    status = STATUS_UNSUCCESSFUL;
-
-    Irp->IoStatus.Status = status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
-    return status;
-}
-
-DRIVER_INITIALIZE   DriverEntry;
-
-NTSTATUS 
-DriverEntry (
-    IN  PDRIVER_OBJECT   DriverObject,
-    IN  PUNICODE_STRING  RegistryPath
-    )
-{
-    NDIS_STATUS ndisStatus;
-    NDIS_MINIPORT_DRIVER_CHARACTERISTICS mpChars;
-    NDIS_CONFIGURATION_OBJECT ConfigurationObject;
-    NDIS_HANDLE ConfigurationHandle;
-    NDIS_STRING ParameterName;
-    PNDIS_CONFIGURATION_PARAMETER ParameterValue;
-    ULONG FailCreateClose;
-    ULONG FailDeviceControl;
-    NTSTATUS status;
-
-    ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
-
-    Trace("====>\n");
-
-    if (*InitSafeBootMode > 0)
-        return NDIS_STATUS_SUCCESS;
-
-    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
-         MAJOR_VERSION,
-         MINOR_VERSION,
-         MICRO_VERSION,
-         BUILD_NUMBER,
-         DAY,
-         MONTH,
-         YEAR);
-
-    status = RegistryInitialize(RegistryPath);
-
-    ndisStatus = (NT_SUCCESS(status)) ?
-                 NDIS_STATUS_SUCCESS :
-                 NDIS_STATUS_FAILURE;
-
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail;
-
-    //
-    // Register miniport with NDIS.
-    //
-
-    NdisZeroMemory(&mpChars, sizeof(mpChars));
-    mpChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,
-    mpChars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
-    mpChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
-
-    mpChars.MajorNdisVersion = 6;
-    mpChars.MinorNdisVersion = 0;
-    mpChars.MajorDriverVersion = MAJOR_VERSION;
-    mpChars.MinorDriverVersion = MINOR_VERSION;
-
-    mpChars.CancelOidRequestHandler = AdapterCancelOidRequest;
-    mpChars.CancelSendHandler = AdapterCancelSendNetBufferLists;
-    mpChars.CheckForHangHandlerEx = AdapterCheckForHang;
-    mpChars.InitializeHandlerEx = MiniportInitialize;
-    mpChars.HaltHandlerEx = MiniportHalt;
-    mpChars.OidRequestHandler = AdapterOidRequest;    
-    mpChars.PauseHandler = AdapterPause;      
-    mpChars.DevicePnPEventNotifyHandler  = AdapterPnPEventHandler;
-    mpChars.ResetHandlerEx = AdapterReset;
-    mpChars.RestartHandler = AdapterRestart;    
-    mpChars.ReturnNetBufferListsHandler  = AdapterReturnNetBufferLists;
-    mpChars.SendNetBufferListsHandler = AdapterSendNetBufferLists;
-    mpChars.ShutdownHandlerEx = AdapterShutdown;
-    mpChars.UnloadHandler = DriverUnload;
-
-    MiniportDriverHandle = NULL;
-    ndisStatus = NdisMRegisterMiniportDriver(DriverObject,
-                                             RegistryPath,
-                                             NULL,
-                                             &mpChars,
-                                             &MiniportDriverHandle);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        Error("Failed (0x%08X) to register miniport.\n", ndisStatus);
-        goto fail;
-    }
-
-    ConfigurationObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
-    ConfigurationObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
-    ConfigurationObject.Header.Size = 
NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
-    ConfigurationObject.NdisHandle = MiniportDriverHandle;
-    ConfigurationObject.Flags = 0;
-
-    ndisStatus = NdisOpenConfigurationEx(&ConfigurationObject, 
&ConfigurationHandle);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        Error("Failed (0x%08X) to open driver configuration.\n", ndisStatus);
-        NdisMDeregisterMiniportDriver(MiniportDriverHandle);
-        goto fail;
-    }
-
-    RtlInitUnicodeString(&ParameterName, L"FailCreateClose");
-
-    NdisReadConfiguration(&ndisStatus,
-                          &ParameterValue,
-                          ConfigurationHandle,
-                          &ParameterName,
-                          NdisParameterInteger);
-    if (ndisStatus == NDIS_STATUS_SUCCESS &&
-        ParameterValue->ParameterType == NdisParameterInteger)
-        FailCreateClose = ParameterValue->ParameterData.IntegerData;
-    else
-        FailCreateClose = 0;
-
-    RtlInitUnicodeString(&ParameterName, L"FailDeviceControl");
-
-    NdisReadConfiguration(&ndisStatus,
-                          &ParameterValue,
-                          ConfigurationHandle,
-                          &ParameterName,
-                          NdisParameterInteger);
-    if (ndisStatus == NDIS_STATUS_SUCCESS &&
-        ParameterValue->ParameterType == NdisParameterInteger)
-        FailDeviceControl = ParameterValue->ParameterData.IntegerData;
-    else
-        FailDeviceControl = 0;
-
-    NdisCloseConfiguration(ConfigurationHandle);
-    ndisStatus = NDIS_STATUS_SUCCESS;
-
-    NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP];
-#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation
-    DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
-
-    if (FailCreateClose != 0) {
-#pragma prefast(suppress:28168) // No matching__drv_dispatchType annotation
-        DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchFail;
-#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation
-        DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchFail;
-    }
-
-    if (FailDeviceControl != 0) {
-#pragma prefast(suppress:28168) // No matching __drv_dispatchType annotation
-        DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail;
-    }
-
-    Trace("<====\n");
-    return ndisStatus;
-
-fail:
-    Error("fail\n");
-    return ndisStatus;
-}
-
-VOID 
-DriverUnload (
-    IN  PDRIVER_OBJECT  DriverObject
-    )
-{
-    UNREFERENCED_PARAMETER(DriverObject);
-
-    Trace("====>\n");
-
-    if (*InitSafeBootMode > 0)
-        goto done;
-
-    if (MiniportDriverHandle)
-        NdisMDeregisterMiniportDriver(MiniportDriverHandle);
-
-    RegistryTeardown();
-
-    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
-         MAJOR_VERSION,
-         MINOR_VERSION,
-         MICRO_VERSION,
-         BUILD_NUMBER,
-         DAY,
-         MONTH,
-         YEAR);
-
-done:
-    Trace("<====\n");
-}
diff --git a/src/xennet/miniport.c b/src/xennet/miniport.c
deleted file mode 100644
index a1d605f..0000000
--- a/src/xennet/miniport.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#define INITGUID 1
-
-#include "common.h"
-#include "registry.h"
-
-#pragma warning( disable : 4098 )
-
-extern NTSTATUS AllocAdapter(PADAPTER *Adapter);
-
-#define SERVICES_KEY        
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"
-
-static FORCEINLINE NTSTATUS
-__QueryInterface(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  const WCHAR     *ProviderName,
-    IN  const CHAR      *InterfaceName,
-    IN  const GUID      *Guid,
-    IN  ULONG           Version,
-    OUT PINTERFACE      Interface,
-    IN  ULONG           Size,
-    IN  BOOLEAN         Optional
-    )
-{
-    UNICODE_STRING      Unicode;
-    HANDLE              InterfacesKey;
-    HANDLE              SubscriberKey;
-    KEVENT              Event;
-    IO_STATUS_BLOCK     StatusBlock;
-    PIRP                Irp;
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
-
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
-
-    Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) +
-                                      1 +
-                                      wcslen(ProviderName) +
-                                      1 +
-                                      wcslen(L"Interfaces") +
-                                      1) * sizeof (WCHAR));
-
-    Unicode.Buffer = ExAllocatePoolWithTag(NonPagedPool,
-                                           Unicode.MaximumLength,
-                                           'TEN');
-
-    status = STATUS_NO_MEMORY;
-    if (Unicode.Buffer == NULL)
-        goto fail1;
-
-    status = RtlStringCbPrintfW(Unicode.Buffer,
-                                Unicode.MaximumLength,
-                                SERVICES_KEY L"\\%ws\\Interfaces",
-                                ProviderName);
-    ASSERT(NT_SUCCESS(status));
-
-    Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR));
-
-    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = RegistryCreateSubKey(InterfacesKey, 
-                                  "XENNET", 
-                                  REG_OPTION_NON_VOLATILE, 
-                                  &SubscriberKey);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-                   
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
-
-    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
-                                       DeviceObject,
-                                       NULL,
-                                       0,
-                                       NULL,
-                                       &Event,
-                                       &StatusBlock);
-
-    status = STATUS_UNSUCCESSFUL;
-    if (Irp == NULL)
-        goto fail4;
-
-    StackLocation = IoGetNextIrpStackLocation(Irp);
-    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
-
-    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
-    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
-    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
-    StackLocation->Parameters.QueryInterface.Interface = Interface;
-    
-    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-
-    status = IoCallDriver(DeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status = StatusBlock.Status;
-    }
-
-    if (!NT_SUCCESS(status)) {
-        if (status == STATUS_NOT_SUPPORTED && Optional)
-            goto done;
-
-        goto fail5;
-    }
-
-    status = RegistryUpdateDwordValue(SubscriberKey,
-                                      (PCHAR)InterfaceName,
-                                      Version);
-    if (!NT_SUCCESS(status))
-        goto fail6;
-
-done:
-    RegistryCloseKey(SubscriberKey);
-
-    RegistryCloseKey(InterfacesKey);
-
-    ExFreePool(Unicode.Buffer);
-
-    return STATUS_SUCCESS;
-
-fail6:
-    Error("fail6\n");
-
-fail5:
-    Error("fail5\n");
-
-fail4:
-    Error("fail4\n");
-
-    RegistryCloseKey(SubscriberKey);
-
-fail3:
-    Error("fail3\n");
-
-    RegistryCloseKey(InterfacesKey);
-
-fail2:
-    Error("fail2\n");
-
-    ExFreePool(Unicode.Buffer);
-
-fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return status;
-}
-
-#define QUERY_INTERFACE(                                                       
         \
-    _DeviceObject,                                                             
         \
-    _ProviderName,                                                             
         \
-    _InterfaceName,                                                            
         \
-    _Version,                                                                  
         \
-    _Interface,                                                                
         \
-    _Size,                                                                     
         \
-    _Optional)                                                                 
         \
-    __QueryInterface((_DeviceObject),                                          
         \
-                     L ## #_ProviderName,                                      
         \
-                     #_InterfaceName,                                          
         \
-                     &GUID_ ## _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE,      \
-                     (_Version),                                               
         \
-                     (_Interface),                                             
         \
-                     (_Size),                                                  
         \
-                     (_Optional))
-
-NDIS_STATUS 
-MiniportInitialize (
-    IN  NDIS_HANDLE                        MiniportAdapterHandle,
-    IN  NDIS_HANDLE                        MiniportDriverContext,
-    IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
-    )
-{
-    PADAPTER Adapter = NULL;
-    NDIS_STATUS ndisStatus;
-    PDEVICE_OBJECT DeviceObject;
-    NTSTATUS status;
-
-    UNREFERENCED_PARAMETER(MiniportDriverContext);
-    UNREFERENCED_PARAMETER(MiniportInitParameters);
-
-    Trace("====>\n");
-
-    status = AllocAdapter(&Adapter);
-
-    if (!NT_SUCCESS(status) || Adapter == NULL) {
-        ndisStatus = NDIS_STATUS_RESOURCES;
-        goto fail1;
-    }
-
-    RtlZeroMemory(Adapter, sizeof (ADAPTER));
-
-    DeviceObject = NULL;
-    NdisMGetDeviceProperty(MiniportAdapterHandle,
-                           &DeviceObject,
-                           NULL,
-                           NULL,
-                           NULL,
-                           NULL);
-
-    status = QUERY_INTERFACE(DeviceObject,
-                             XENVIF,
-                             VIF,
-                             XENVIF_VIF_INTERFACE_VERSION_MAX,
-                             (PINTERFACE)&Adapter->VifInterface,
-                             sizeof (Adapter->VifInterface),
-                             FALSE);
-
-    if (!NT_SUCCESS(status)) {
-        ndisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND;
-        goto fail2;
-    }
-
-    ndisStatus = AdapterInitialize(Adapter, MiniportAdapterHandle);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto fail3;
-    }
-
-    Trace("<====\n");
-    return ndisStatus;
-
-fail3:
-    Error("fail3\n");
-
-    RtlZeroMemory(&Adapter->VifInterface,
-                  sizeof (XENVIF_VIF_INTERFACE));
-
-fail2:
-    Error("fail2\n");
-
-    ExFreePool(Adapter);
-
-fail1:
-    Error("fail1\n");
-
-    return ndisStatus;
-}
-
-//
-// Stops adapter and frees all resources.
-//
-VOID 
-MiniportHalt (
-    IN  NDIS_HANDLE             MiniportAdapterHandle,
-    IN  NDIS_HALT_ACTION        HaltAction
-    )
-{
-    PADAPTER Adapter = (PADAPTER)MiniportAdapterHandle;
-
-    UNREFERENCED_PARAMETER(HaltAction);
-
-    if (Adapter == NULL)
-        return;
-
-    (VOID) AdapterStop(Adapter);
-
-    AdapterCleanup(Adapter);
-
-    RtlZeroMemory(&Adapter->VifInterface,
-                  sizeof (XENVIF_VIF_INTERFACE));
-
-    ExFreePool(Adapter);
-}
diff --git a/src/xennet/project.h b/src/xennet/project.h
deleted file mode 100644
index 981cb0e..0000000
--- a/src/xennet/project.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#pragma once
-
-#include <util.h>
-#include <ethernet.h>
-#include <tcpip.h>
-#include <vif_interface.h>
-
-typedef struct _ADAPTER ADAPTER, *PADAPTER;
-
-DRIVER_INITIALIZE DriverEntry;
-NTSTATUS 
-DriverEntry (
-    IN  PDRIVER_OBJECT   DriverObject,
-    IN  PUNICODE_STRING  RegistryPath
-    );
-
-MINIPORT_UNLOAD DriverUnload;
-VOID 
-DriverUnload (
-    IN  PDRIVER_OBJECT  DriverObject
-    );
-
-NDIS_STATUS
-MpSetAdapterSettings(
-    IN PADAPTER Adapter
-    );
-
-NDIS_STATUS
-MpGetAdvancedSettings(
-    IN PADAPTER Adapter
-    );
-
-#include "transmitter.h"
-#include "receiver.h"
-#include "adapter.h"
diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c
index 54bdc15..ee01a18 100644
--- a/src/xennet/receiver.c
+++ b/src/xennet/receiver.c
@@ -29,103 +29,38 @@
  * SUCH DAMAGE.
  */
 
-#include "common.h"
-
-#pragma warning(disable:4711)
-
-NDIS_STATUS
-ReceiverInitialize (
-    IN  PRECEIVER                   Receiver
-    )
-{
-    PADAPTER                        Adapter;
-    NDIS_STATUS                     ndisStatus = NDIS_STATUS_SUCCESS;
-    NET_BUFFER_LIST_POOL_PARAMETERS poolParameters;
-    ULONG                           Cpu;
-
-    Receiver->PutList = NULL;
-    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++)
-        Receiver->GetList[Cpu] = NULL;
-
-    Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
-
-    NdisZeroMemory(&poolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
-    poolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
-    poolParameters.Header.Revision =
-        NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
-    poolParameters.Header.Size = sizeof(poolParameters);
-    poolParameters.ProtocolId = 0;
-    poolParameters.ContextSize = 0;
-    poolParameters.fAllocateNetBuffer = TRUE;
-    poolParameters.PoolTag = ' TEN';
-
-    Receiver->NetBufferListPool =
-        NdisAllocateNetBufferListPool(Adapter->NdisAdapterHandle,
-                                      &poolParameters);
-
-    if (!Receiver->NetBufferListPool)
-        ndisStatus = NDIS_STATUS_RESOURCES;
-
-    return ndisStatus;
-}
-
-VOID 
-ReceiverCleanup (
-    IN  PRECEIVER       Receiver
-    )
-{
-    ULONG               Cpu;
-    PNET_BUFFER_LIST    NetBufferList;
-
-    ASSERT(Receiver != NULL);
-
-    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
-        NetBufferList = Receiver->GetList[Cpu];
-        while (NetBufferList != NULL) {
-            PNET_BUFFER_LIST    Next;
-
-            Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
-            NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
-
-            NdisFreeNetBufferList(NetBufferList);
-
-            NetBufferList = Next;
-        }
-    }
-
-    NetBufferList = Receiver->PutList;
-    while (NetBufferList != NULL) {
-        PNET_BUFFER_LIST    Next;
-
-        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
-        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
-
-        NdisFreeNetBufferList(NetBufferList);
-
-        NetBufferList = Next;
-    }
-
-    if (Receiver->NetBufferListPool) {
-        NdisFreeNetBufferListPool(Receiver->NetBufferListPool);
-        Receiver->NetBufferListPool = NULL;
-    }
-
-    return;
-}
+#include <ndis.h>
+#include "receiver.h"
+#include "adapter.h"
+#include <util.h>
+#include "dbg_print.h"
+#include "assert.h"
+
+struct _XENNET_RECEIVER {
+    PXENNET_ADAPTER             Adapter;
+    NDIS_HANDLE                 NetBufferListPool;
+    PNET_BUFFER_LIST            PutList;
+    PNET_BUFFER_LIST            GetList[MAXIMUM_PROCESSORS];
+    LONG                        InNDIS;
+    LONG                        InNDISMax;
+    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
+};
+
+#define RECEIVER_POOL_TAG       'teNX'
+#define IN_NDIS_MAX 1024
 
-PNET_BUFFER_LIST
+static PNET_BUFFER_LIST
 ReceiverAllocateNetBufferList(
-    IN  PRECEIVER       Receiver,
-    IN  PMDL            Mdl,
-    IN  ULONG           Offset,
-    IN  ULONG           Length
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PMDL                    Mdl,
+    IN  ULONG                   Offset,
+    IN  ULONG                   Length
     )
 {
-    ULONG               Cpu;
-    PNET_BUFFER_LIST    NetBufferList;
+    ULONG                       Cpu;
+    PNET_BUFFER_LIST            NetBufferList;
 
     Cpu = KeGetCurrentProcessorNumber();
-
     NetBufferList = Receiver->GetList[Cpu];
 
     if (NetBufferList == NULL)
@@ -158,16 +93,16 @@ ReceiverAllocateNetBufferList(
     return NetBufferList;
 }        
 
-VOID
+static VOID
 ReceiverReleaseNetBufferList(
-    IN  PRECEIVER           Receiver,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  BOOLEAN             Cache
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  BOOLEAN                 Cache
     )
 {
     if (Cache) {
-        PNET_BUFFER_LIST    Old;
-        PNET_BUFFER_LIST    New;
+        PNET_BUFFER_LIST        Old;
+        PNET_BUFFER_LIST        New;
 
         ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
 
@@ -182,72 +117,9 @@ ReceiverReleaseNetBufferList(
     }
 }
 
-static FORCEINLINE ULONG
-__ReceiverReturnNetBufferLists(
-    IN  PRECEIVER           Receiver,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  BOOLEAN             Cache
-    )
-{
-    PADAPTER                Adapter;
-    LIST_ENTRY              List;
-    ULONG                   Count;
-
-    Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
-
-    InitializeListHead(&List);
-
-    Count = 0;
-    while (NetBufferList != NULL) {
-        PNET_BUFFER_LIST        Next;
-        PNET_BUFFER             NetBuffer;
-        PMDL                    Mdl;
-        PXENVIF_RECEIVER_PACKET Packet;
-
-        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
-        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
-
-        NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
-        ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL);
-
-        Mdl = NET_BUFFER_FIRST_MDL(NetBuffer);
-
-        ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache);
-
-        Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl);
-
-        InsertTailList(&List, &Packet->ListEntry);
-
-        Count++;
-        NetBufferList = Next;
-    }
-
-    if (Count != 0)
-        XENVIF_VIF(ReceiverReturnPackets,
-                   &Adapter->VifInterface,
-                   &List);
-
-    return Count;
-}
-
-VOID
-ReceiverReturnNetBufferLists(
-    IN  PRECEIVER           Receiver,
-    IN  PNET_BUFFER_LIST    HeadNetBufferList,
-    IN  ULONG               Flags
-    )
-{
-    ULONG                   Count;
-
-    UNREFERENCED_PARAMETER(Flags);
-
-    Count = __ReceiverReturnNetBufferLists(Receiver, HeadNetBufferList, TRUE);
-    (VOID) __InterlockedSubtract(&Receiver->InNDIS, Count);
-}
-
 static PNET_BUFFER_LIST
 ReceiverReceivePacket(
-    IN  PRECEIVER                               Receiver,
+    IN  PXENNET_RECEIVER                        Receiver,
     IN  PMDL                                    Mdl,
     IN  ULONG                                   Offset,
     IN  ULONG                                   Length,
@@ -255,11 +127,11 @@ ReceiverReceivePacket(
     IN  USHORT                                  TagControlInformation
     )
 {
-    PADAPTER                                    Adapter;
+    PXENNET_ADAPTER                             Adapter;
     PNET_BUFFER_LIST                            NetBufferList;
     NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO   csumInfo;
 
-    Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+    Adapter = Receiver->Adapter;
 
     NetBufferList = ReceiverAllocateNetBufferList(Receiver,
                                                   Mdl,
@@ -268,7 +140,7 @@ ReceiverReceivePacket(
     if (NetBufferList == NULL)
         goto fail1;
 
-    NetBufferList->SourceHandle = Adapter->NdisAdapterHandle;
+    NetBufferList->SourceHandle = AdapterGetHandle(Adapter);
 
     csumInfo.Value = 0;
 
@@ -281,8 +153,8 @@ ReceiverReceivePacket(
     csumInfo.Receive.UdpChecksumSucceeded = Flags.UdpChecksumSucceeded;
     csumInfo.Receive.UdpChecksumFailed = Flags.UdpChecksumFailed;
 
-    NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = 
(PVOID)(ULONG_PTR)csumInfo.Value;
-
+    NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = 
+                                            (PVOID)(ULONG_PTR)csumInfo.Value;
     if (TagControlInformation != 0) {
         NDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo;
 
@@ -306,20 +178,67 @@ fail1:
     return NULL;
 }
 
+static FORCEINLINE ULONG
+__ReceiverReturnNetBufferLists(
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  BOOLEAN                 Cache
+    )
+{
+    PXENNET_ADAPTER             Adapter;
+    LIST_ENTRY                  List;
+    ULONG                       Count;
+
+    Adapter = Receiver->Adapter;
+
+    InitializeListHead(&List);
+
+    Count = 0;
+    while (NetBufferList != NULL) {
+        PNET_BUFFER_LIST        Next;
+        PNET_BUFFER             NetBuffer;
+        PMDL                    Mdl;
+        PXENVIF_RECEIVER_PACKET Packet;
+
+        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+        NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
+        ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL);
+
+        Mdl = NET_BUFFER_FIRST_MDL(NetBuffer);
+
+        ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache);
+
+        Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl);
+
+        InsertTailList(&List, &Packet->ListEntry);
+
+        Count++;
+        NetBufferList = Next;
+    }
+
+    if (Count != 0) {
+        XENVIF_VIF(ReceiverReturnPackets,
+                   AdapterGetVifInterface(Adapter),
+                   &List);
+    }
+    return Count;
+}
+
 static VOID
 ReceiverPushPackets(
-    IN  PRECEIVER           Receiver,
+    IN  PXENNET_RECEIVER    Receiver,
     IN  PNET_BUFFER_LIST    NetBufferList,
     IN  ULONG               Count,
     IN  BOOLEAN             LowResources
     )
 {
-    PADAPTER                Adapter;
+    PXENNET_ADAPTER         Adapter;
     ULONG                   Flags;
     LONG                    InNDIS;
 
-    Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
-
+    Adapter = Receiver->Adapter;
     InNDIS = Receiver->InNDIS;
 
     Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL;
@@ -342,7 +261,7 @@ ReceiverPushPackets(
             break;
     }
 
-    NdisMIndicateReceiveNetBufferLists(Adapter->NdisAdapterHandle,
+    NdisMIndicateReceiveNetBufferLists(AdapterGetHandle(Adapter),
                                        NetBufferList,
                                        NDIS_DEFAULT_PORT_NUMBER,
                                        Count,
@@ -352,21 +271,34 @@ ReceiverPushPackets(
         (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE);
 }
 
-#define IN_NDIS_MAX 1024
+VOID
+ReceiverReturnNetBufferLists(
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PNET_BUFFER_LIST        NetBufferLists,
+    IN  ULONG                   ReturnFlags
+    )
+{
+    ULONG                   Count;
+
+    UNREFERENCED_PARAMETER(ReturnFlags);
+
+    Count = __ReceiverReturnNetBufferLists(Receiver, NetBufferLists, TRUE);
+    (VOID) __InterlockedSubtract(&Receiver->InNDIS, Count);
+}
 
 VOID
 ReceiverReceivePackets(
-    IN  PRECEIVER       Receiver,
-    IN  PLIST_ENTRY     List
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PLIST_ENTRY             List
     )
 {
-    PADAPTER            Adapter;
+    PXENNET_ADAPTER     Adapter;
     PNET_BUFFER_LIST    HeadNetBufferList;
     PNET_BUFFER_LIST    *TailNetBufferList;
     ULONG               Count;
     BOOLEAN             LowResources;
 
-    Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+    Adapter = Receiver->Adapter;
     LowResources = FALSE;
 
 again:
@@ -404,21 +336,26 @@ again:
 
         TagControlInformation = Info->TagControlInformation;
 
-        NetBufferList = ReceiverReceivePacket(Receiver, Mdl, Offset, Length, 
Flags, TagControlInformation);
+        NetBufferList = ReceiverReceivePacket(Receiver,
+                                              Mdl,
+                                              Offset,
+                                              Length,
+                                              Flags,
+                                              TagControlInformation);
 
         if (NetBufferList != NULL) {
             *TailNetBufferList = NetBufferList;
             TailNetBufferList = &NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
             Count++;
         } else {
-            LIST_ENTRY  List;
+            LIST_ENTRY  PacketList;
 
-            InitializeListHead(&List);
-            InsertTailList(&List, &Packet->ListEntry);
+            InitializeListHead(&PacketList);
+            InsertTailList(&PacketList, &Packet->ListEntry);
 
             XENVIF_VIF(ReceiverReturnPackets,
-                       &Adapter->VifInterface,
-                       &List);
+                       AdapterGetVifInterface(Adapter),
+                       &PacketList);
         }
     }
 
@@ -434,3 +371,95 @@ again:
         goto again;
     }
 }
+
+PXENVIF_VIF_OFFLOAD_OPTIONS
+ReceiverOffloadOptions(
+    IN  PXENNET_RECEIVER        Receiver
+    )
+{
+    return &Receiver->OffloadOptions;
+}
+
+NTSTATUS
+ReceiverInitialize(
+    IN  PXENNET_ADAPTER         Adapter,
+    OUT PXENNET_RECEIVER        *Receiver
+    )
+{
+    NTSTATUS                        status;
+    NET_BUFFER_LIST_POOL_PARAMETERS Pool;
+
+    status = STATUS_NO_MEMORY;
+    *Receiver = ExAllocatePoolWithTag(NonPagedPool, sizeof(XENNET_RECEIVER), 
RECEIVER_POOL_TAG);
+    if (*Receiver == NULL)
+        goto fail1;
+
+    RtlZeroMemory(*Receiver, sizeof(XENNET_RECEIVER));
+    (*Receiver)->Adapter = Adapter;
+
+    RtlZeroMemory(&Pool, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
+    Pool.Header.Type        = NDIS_OBJECT_TYPE_DEFAULT;
+    Pool.Header.Size        = sizeof(NET_BUFFER_LIST_POOL_PARAMETERS);
+    Pool.Header.Revision    = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
+    Pool.ProtocolId         = 0;
+    Pool.ContextSize        = 0;
+    Pool.fAllocateNetBuffer = TRUE;
+    Pool.PoolTag            = RECEIVER_POOL_TAG;
+
+    (*Receiver)->NetBufferListPool = 
NdisAllocateNetBufferListPool(AdapterGetHandle(Adapter),
+                                                                   &Pool);
+    if ((*Receiver)->NetBufferListPool == NULL)
+        goto fail2;
+
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+    ExFreePoolWithTag(*Receiver, RECEIVER_POOL_TAG);
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
+}
+
+VOID
+ReceiverTeardown(
+    IN  PXENNET_RECEIVER        Receiver
+    )
+{
+    ULONG               Cpu;
+    PNET_BUFFER_LIST    NetBufferList;
+
+    ASSERT(Receiver != NULL);
+
+    for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
+        NetBufferList = Receiver->GetList[Cpu];
+        while (NetBufferList != NULL) {
+            PNET_BUFFER_LIST    Next;
+
+            Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+            NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+            NdisFreeNetBufferList(NetBufferList);
+
+            NetBufferList = Next;
+        }
+    }
+
+    NetBufferList = Receiver->PutList;
+    while (NetBufferList != NULL) {
+        PNET_BUFFER_LIST    Next;
+
+        Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+        NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+        NdisFreeNetBufferList(NetBufferList);
+
+        NetBufferList = Next;
+    }
+
+    NdisFreeNetBufferListPool(Receiver->NetBufferListPool);
+    Receiver->NetBufferListPool = NULL;
+
+    ExFreePoolWithTag(Receiver, RECEIVER_POOL_TAG);
+}
+
diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h
index 1a58053..715f02e 100644
--- a/src/xennet/receiver.h
+++ b/src/xennet/receiver.h
@@ -29,49 +29,42 @@
  * SUCH DAMAGE.
  */
 
-#pragma once
+#ifndef _XENNET_RECEIVER_H_
+#define _XENNET_RECEIVER_H_
 
-typedef struct _RECEIVER {
-    NDIS_HANDLE                 NetBufferListPool;
-    PNET_BUFFER_LIST            PutList;
-    PNET_BUFFER_LIST            GetList[MAXIMUM_PROCESSORS];
-    LONG                        InNDIS;
-    LONG                        InNDISMax;
-    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
-} RECEIVER, *PRECEIVER;
+typedef struct _XENNET_RECEIVER     XENNET_RECEIVER, *PXENNET_RECEIVER;
 
-VOID
-ReceiverDebugDump (
-    IN PRECEIVER Receiver
-    );
+#include <vif_interface.h>
 
-VOID 
-ReceiverCleanup (
-    IN  PRECEIVER Receiver
+extern VOID
+ReceiverReturnNetBufferLists(
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PNET_BUFFER_LIST        NetBufferLists,
+    IN  ULONG                   ReturnFlags
     );
 
-VOID
-ReceiverHandleNotification (
-    IN  PRECEIVER Receiver
+extern VOID
+ReceiverReceivePackets(
+    IN  PXENNET_RECEIVER        Receiver,
+    IN  PLIST_ENTRY             List
     );
 
-NDIS_STATUS
-ReceiverInitialize (
-    IN  PRECEIVER   Receiver
+extern PXENVIF_VIF_OFFLOAD_OPTIONS
+ReceiverOffloadOptions(
+    IN  PXENNET_RECEIVER        Receiver
     );
 
-VOID 
-ReceiverReturnNetBufferLists (
-    IN  PRECEIVER           Receiver,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  ULONG               ReturnFlags
+#include "adapter.h"
+extern NTSTATUS
+ReceiverInitialize(
+    IN  PXENNET_ADAPTER         Adapter,
+    OUT PXENNET_RECEIVER        *Receiver
     );
 
-VOID
-ReceiverWaitForPacketReturn(
-    IN  PRECEIVER   Receiver,
-    IN  BOOLEAN     Locked
+extern VOID
+ReceiverTeardown(
+    IN  PXENNET_RECEIVER        Receiver
     );
 
-void ReceiverPause(PRECEIVER receiver);
-void ReceiverUnpause(PRECEIVER receiver);
+#endif // _XENNET_RECEIVER_H_
+
diff --git a/src/xennet/std.h b/src/xennet/std.h
deleted file mode 100644
index c72325a..0000000
--- a/src/xennet/std.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */
-
-#pragma once
-
-#pragma warning(disable:4214)   // bit field types other than int
-
-#pragma warning(disable:4201)   // nameless struct/union
-#pragma warning(disable:4115)   // named type definition in parentheses
-#pragma warning(disable:4127)   // conditional expression is constant
-#pragma warning(disable:4054)   // cast of function pointer to PVOID
-#pragma warning(disable:4206)   // translation unit is empty
-
-#include <ndis.h>
-#include <ntstrsafe.h>
-
-extern PULONG InitSafeBootMode;
diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index 6a18a19..be07458 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -29,59 +29,18 @@
  * SUCH DAMAGE.
  */
 
-#include "common.h"
+#include <ndis.h>
+#include "transmitter.h"
+#include "adapter.h"
+#include "dbg_print.h"
+#include "assert.h"
 
-#pragma warning(disable:4711)
+struct _XENNET_TRANSMITTER {
+    PXENNET_ADAPTER             Adapter;
+    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
+};
 
-NDIS_STATUS
-TransmitterInitialize(
-    IN  PTRANSMITTER    Transmitter,
-    IN  PADAPTER        Adapter
-    )
-{
-    Transmitter->Adapter = Adapter;
-
-    return NDIS_STATUS_SUCCESS;
-}
-
-VOID
-TransmitterEnable(
-    IN  PTRANSMITTER    Transmitter
-    )
-{
-    PADAPTER            Adapter = Transmitter->Adapter;
-
-    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET,
-                      
(LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) -
-                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
-
-    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET,
-                      (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) -
-                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
-
-    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
-                      &Adapter->VifInterface,
-                      XENVIF_TRANSMITTER_PACKET_MDL_OFFSET,
-                      (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) -
-                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
-}
-
-VOID 
-TransmitterDelete (
-    IN OUT PTRANSMITTER *Transmitter
-    )
-{
-    ASSERT(Transmitter != NULL);
-
-    if (*Transmitter) {
-        ExFreePool(*Transmitter);
-        *Transmitter = NULL;
-    }
-}
+#define TRANSMITTER_POOL_TAG    'teNX'
 
 typedef struct _NET_BUFFER_LIST_RESERVED {
     LONG    Reference;
@@ -97,24 +56,37 @@ typedef struct _NET_BUFFER_RESERVED {
 C_ASSERT(sizeof (NET_BUFFER_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER, 
MiniportReserved));
 
 static VOID
-TransmitterAbortNetBufferList(
-    IN  PTRANSMITTER        Transmitter,
-    IN  PNET_BUFFER_LIST    NetBufferList
+TransmitterCompleteNetBufferList(
+    IN  PXENNET_TRANSMITTER     Transmitter,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  NDIS_STATUS             NdisStatus
     )
 {
+    PXENNET_ADAPTER             Adapter = Transmitter->Adapter;
+
     ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
 
-    NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_NOT_ACCEPTED;
+    if (NdisStatus == NDIS_STATUS_SUCCESS) {
+        PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO   LargeSendInfo;
+
+        LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)
+                                    &NET_BUFFER_LIST_INFO(NetBufferList,
+                                                          
TcpLargeSendNetBufferListInfo);
+        if (LargeSendInfo->LsoV2Transmit.MSS != 0)
+            LargeSendInfo->LsoV2TransmitComplete.Reserved = 0;
+    }
+    NET_BUFFER_LIST_STATUS(NetBufferList) = NdisStatus;
 
-    NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle,
+    NdisMSendNetBufferListsComplete(AdapterGetHandle(Adapter),
                                     NetBufferList,
                                     NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
 }
 
-VOID
-TransmitterAbortPackets(
-    IN  PTRANSMITTER                Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+static VOID
+__TransmitterCompletePackets(
+    IN  PXENNET_TRANSMITTER         Transmitter,
+    IN  PXENVIF_TRANSMITTER_PACKET  Packet,
+    IN  NDIS_STATUS                 NdisStatus
     )
 {
     while (Packet != NULL) {
@@ -135,21 +107,85 @@ TransmitterAbortPackets(
 
         ASSERT(ListReserved->Reference != 0);
         if (InterlockedDecrement(&ListReserved->Reference) == 0)
-            TransmitterAbortNetBufferList(Transmitter, NetBufferList);
+            TransmitterCompleteNetBufferList(Transmitter, NetBufferList, 
NdisStatus);
 
         Packet = Next;
     }
 }
+    
+static FORCEINLINE VOID
+__OffloadOptions(
+    IN  PNET_BUFFER_LIST            NetBufferList,
+    OUT PXENVIF_VIF_OFFLOAD_OPTIONS Offload,
+    OUT PUSHORT                     TagControlInformation,
+    OUT PUSHORT                     MaximumSegmentSize
+    )
+{
+    PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO   LargeSendInfo;
+    PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO          ChecksumInfo;
+    PNDIS_NET_BUFFER_LIST_8021Q_INFO                    Ieee8021QInfo;
+    LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)
+                                    &NET_BUFFER_LIST_INFO(NetBufferList,
+                                                          
TcpLargeSendNetBufferListInfo);
+    ChecksumInfo = (PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO)
+                                    &NET_BUFFER_LIST_INFO(NetBufferList,
+                                                          
TcpIpChecksumNetBufferListInfo);
+    Ieee8021QInfo = (PNDIS_NET_BUFFER_LIST_8021Q_INFO)
+                                    &NET_BUFFER_LIST_INFO(NetBufferList,
+                                                          
Ieee8021QNetBufferListInfo);
+
+    Offload->Value = 0;
+    *TagControlInformation = 0;
+    *MaximumSegmentSize = 0;
+
+    if (ChecksumInfo->Transmit.IsIPv4) {
+        if (ChecksumInfo->Transmit.IpHeaderChecksum)
+            Offload->OffloadIpVersion4HeaderChecksum = 1;
+        if (ChecksumInfo->Transmit.TcpChecksum)
+            Offload->OffloadIpVersion4TcpChecksum = 1;
+        if (ChecksumInfo->Transmit.UdpChecksum)
+            Offload->OffloadIpVersion4UdpChecksum = 1;
+    }
+
+    if (ChecksumInfo->Transmit.IsIPv6) {
+        if (ChecksumInfo->Transmit.TcpChecksum)
+            Offload->OffloadIpVersion6TcpChecksum = 1;
+        if (ChecksumInfo->Transmit.UdpChecksum)
+            Offload->OffloadIpVersion6UdpChecksum = 1;
+    }
+
+    if (Ieee8021QInfo->TagHeader.UserPriority != 0) {
+        Offload->OffloadTagManipulation = 1;
+
+        ASSERT3U(Ieee8021QInfo->TagHeader.CanonicalFormatId, ==, 0);
+        ASSERT3U(Ieee8021QInfo->TagHeader.VlanId, ==, 0);
+
+        PACK_TAG_CONTROL_INFORMATION(*TagControlInformation,
+                                     Ieee8021QInfo->TagHeader.UserPriority,
+                                     
Ieee8021QInfo->TagHeader.CanonicalFormatId,
+                                     Ieee8021QInfo->TagHeader.VlanId);
+    }
+
+    if (LargeSendInfo->LsoV2Transmit.MSS != 0) {
+        if (LargeSendInfo->LsoV2Transmit.IPVersion == 
NDIS_TCP_LARGE_SEND_OFFLOAD_IPv4)
+            Offload->OffloadIpVersion4LargePacket = 1;
+        if (LargeSendInfo->LsoV2Transmit.IPVersion == 
NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6)
+            Offload->OffloadIpVersion6LargePacket = 1;
+
+        ASSERT3U(LargeSendInfo->LsoV2Transmit.MSS >> 16, ==, 0);
+        *MaximumSegmentSize = (USHORT)LargeSendInfo->LsoV2Transmit.MSS;
+    }
+}
 
 VOID
 TransmitterSendNetBufferLists(
-    IN  PTRANSMITTER            Transmitter,
+    IN  PXENNET_TRANSMITTER     Transmitter,
     IN  PNET_BUFFER_LIST        NetBufferList,
     IN  NDIS_PORT_NUMBER        PortNumber,
     IN  ULONG                   SendFlags
     )
 {
-    PADAPTER                    Adapter = Transmitter->Adapter;
+    PXENNET_ADAPTER             Adapter = Transmitter->Adapter;
     PXENVIF_TRANSMITTER_PACKET  HeadPacket;
     PXENVIF_TRANSMITTER_PACKET  *TailPacket;
     KIRQL                       Irql;
@@ -158,21 +194,21 @@ TransmitterSendNetBufferLists(
 
     HeadPacket = NULL;
     TailPacket = &HeadPacket;
-
+ 
     if (!NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags)) {
         ASSERT3U(NDIS_CURRENT_IRQL(), <=, DISPATCH_LEVEL);
         NDIS_RAISE_IRQL_TO_DISPATCH(&Irql);
     } else {
         Irql = DISPATCH_LEVEL;
     }
-
+ 
     while (NetBufferList != NULL) {
-        PNET_BUFFER_LIST                                    ListNext;
-        PNET_BUFFER_LIST_RESERVED                           ListReserved;
-        PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO   LargeSendInfo;
-        PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO          ChecksumInfo;
-        PNDIS_NET_BUFFER_LIST_8021Q_INFO                    Ieee8021QInfo;
-        PNET_BUFFER                                         NetBuffer;
+        PNET_BUFFER_LIST                ListNext;
+        PNET_BUFFER_LIST_RESERVED       ListReserved;
+        XENVIF_VIF_OFFLOAD_OPTIONS      Options;
+        USHORT                          TagControlInformation;
+        USHORT                          MaximumSegmentSize;
+        PNET_BUFFER                     NetBuffer;
 
         ListNext = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
         NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
@@ -180,12 +216,7 @@ TransmitterSendNetBufferLists(
         ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
         RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED));
 
-        LargeSendInfo = 
(PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
-                                                                               
                  TcpLargeSendNetBufferListInfo);
-        ChecksumInfo = 
(PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
-                                                                               
          TcpIpChecksumNetBufferListInfo);
-        Ieee8021QInfo = 
(PNDIS_NET_BUFFER_LIST_8021Q_INFO)&NET_BUFFER_LIST_INFO(NetBufferList, 
-                                                                               
 Ieee8021QNetBufferListInfo);
+        __OffloadOptions(NetBufferList, &Options, &TagControlInformation, 
&MaximumSegmentSize);
 
         NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
         while (NetBuffer != NULL) {
@@ -199,50 +230,9 @@ TransmitterSendNetBufferLists(
             ListReserved->Reference++;
 
             Packet = &Reserved->Packet;
-
-            if (ChecksumInfo->Transmit.IsIPv4) {
-                if (ChecksumInfo->Transmit.IpHeaderChecksum)
-                    
Packet->Send.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
-
-                if (ChecksumInfo->Transmit.TcpChecksum)
-                    Packet->Send.OffloadOptions.OffloadIpVersion4TcpChecksum = 
1;
-
-                if (ChecksumInfo->Transmit.UdpChecksum)
-                    Packet->Send.OffloadOptions.OffloadIpVersion4UdpChecksum = 
1;
-            }
-
-            if (ChecksumInfo->Transmit.IsIPv6) {
-                if (ChecksumInfo->Transmit.TcpChecksum)
-                    Packet->Send.OffloadOptions.OffloadIpVersion6TcpChecksum = 
1;
-
-                if (ChecksumInfo->Transmit.UdpChecksum)
-                    Packet->Send.OffloadOptions.OffloadIpVersion6UdpChecksum = 
1;
-            }
-
-            if (Ieee8021QInfo->TagHeader.UserPriority != 0) {
-                Packet->Send.OffloadOptions.OffloadTagManipulation = 1;
-
-                ASSERT3U(Ieee8021QInfo->TagHeader.CanonicalFormatId, ==, 0);
-                ASSERT3U(Ieee8021QInfo->TagHeader.VlanId, ==, 0);
-
-                
PACK_TAG_CONTROL_INFORMATION(Packet->Send.TagControlInformation,
-                                             
Ieee8021QInfo->TagHeader.UserPriority,
-                                             
Ieee8021QInfo->TagHeader.CanonicalFormatId,
-                                             Ieee8021QInfo->TagHeader.VlanId);
-            }
-
-            if (LargeSendInfo->LsoV2Transmit.MSS != 0) {
-                if (LargeSendInfo->LsoV2Transmit.IPVersion == 
NDIS_TCP_LARGE_SEND_OFFLOAD_IPv4)
-                    Packet->Send.OffloadOptions.OffloadIpVersion4LargePacket = 
1;
-
-                if (LargeSendInfo->LsoV2Transmit.IPVersion == 
NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6)
-                    Packet->Send.OffloadOptions.OffloadIpVersion6LargePacket = 
1;
-
-                ASSERT3U(LargeSendInfo->LsoV2Transmit.MSS >> 16, ==, 0);
-                Packet->Send.MaximumSegmentSize = 
(USHORT)LargeSendInfo->LsoV2Transmit.MSS;
-            }
-
-            Packet->Send.OffloadOptions.Value &= 
Transmitter->OffloadOptions.Value;
+            Packet->Send.OffloadOptions.Value   = Options.Value & 
Transmitter->OffloadOptions.Value;
+            Packet->Send.TagControlInformation  = TagControlInformation;
+            Packet->Send.MaximumSegmentSize     = MaximumSegmentSize;
 
             ASSERT3P(Packet->Next, ==, NULL);
             *TailPacket = Packet;
@@ -258,65 +248,89 @@ TransmitterSendNetBufferLists(
         NTSTATUS    status; 
 
         status = XENVIF_VIF(TransmitterQueuePackets,
-                            &Adapter->VifInterface,
+                            AdapterGetVifInterface(Adapter),
                             HeadPacket);
         if (!NT_SUCCESS(status))
-            TransmitterAbortPackets(Transmitter, HeadPacket);
+            __TransmitterCompletePackets(Transmitter, HeadPacket, 
NDIS_STATUS_NOT_ACCEPTED);
     }
 
     NDIS_LOWER_IRQL(Irql, DISPATCH_LEVEL);
 }
 
-static VOID
-TransmitterCompleteNetBufferList(
-    IN  PTRANSMITTER                                    Transmitter,
-    IN  PNET_BUFFER_LIST                                NetBufferList
+VOID
+TransmitterCompletePackets(
+    IN  PXENNET_TRANSMITTER         Transmitter,
+    IN  PXENVIF_TRANSMITTER_PACKET  Packet
     )
 {
-    PADAPTER                                            Adapter = 
Transmitter->Adapter;
-    PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO   LargeSendInfo;
+    __TransmitterCompletePackets(Transmitter,
+                                 Packet,
+                                 NDIS_STATUS_SUCCESS);
+}
 
-    ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
+VOID
+TransmitterEnable(
+    IN  PXENNET_TRANSMITTER     Transmitter
+    )
+{
+    PXENVIF_VIF_INTERFACE   Vif = AdapterGetVifInterface(Transmitter->Adapter);
 
-    LargeSendInfo = 
(PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
-                                                                               
              TcpLargeSendNetBufferListInfo);
+    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
+                      Vif,
+                      XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET,
+                      
(LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) -
+                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
 
-    if (LargeSendInfo->LsoV2Transmit.MSS != 0)
-        LargeSendInfo->LsoV2TransmitComplete.Reserved = 0;
+    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
+                      Vif,
+                      XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET,
+                      (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) -
+                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
 
-    NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_SUCCESS;
+    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
+                      Vif,
+                      XENVIF_TRANSMITTER_PACKET_MDL_OFFSET,
+                      (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) -
+                      
(LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
+}
 
-    NdisMSendNetBufferListsComplete(Adapter->NdisAdapterHandle,
-                                    NetBufferList,
-                                    NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
+PXENVIF_VIF_OFFLOAD_OPTIONS
+TransmitterOffloadOptions(
+    IN  PXENNET_TRANSMITTER     Transmitter
+    )
+{
+    return &Transmitter->OffloadOptions;
 }
 
-VOID
-TransmitterCompletePackets(
-    IN  PTRANSMITTER                Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+NTSTATUS
+TransmitterInitialize(
+    IN  PXENNET_ADAPTER         Adapter,
+    OUT PXENNET_TRANSMITTER     *Transmitter
     )
 {
-    while (Packet != NULL) {
-        PXENVIF_TRANSMITTER_PACKET  Next;
-        PNET_BUFFER_RESERVED        Reserved;
-        PNET_BUFFER_LIST            NetBufferList;
-        PNET_BUFFER_LIST_RESERVED   ListReserved;
+    NTSTATUS            status;
 
-        Next = Packet->Next;
-        Packet->Next = NULL;
+    status = STATUS_NO_MEMORY;
+    *Transmitter = ExAllocatePoolWithTag(NonPagedPool, 
sizeof(XENNET_TRANSMITTER), TRANSMITTER_POOL_TAG);
+    if (*Transmitter == NULL)
+        goto fail1;
 
-        Reserved = CONTAINING_RECORD(Packet, NET_BUFFER_RESERVED, Packet);
+    RtlZeroMemory(*Transmitter, sizeof(XENNET_TRANSMITTER));
+    (*Transmitter)->Adapter = Adapter;
 
-        NetBufferList = Reserved->NetBufferList;
-        ASSERT(NetBufferList != NULL);
+    return STATUS_SUCCESS;
 
-        ListReserved = 
(PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+fail1:
+    Error("fail1 (%08x)\n", status);
+    return status;
 
-        ASSERT(ListReserved->Reference != 0);
-        if (InterlockedDecrement(&ListReserved->Reference) == 0)
-            TransmitterCompleteNetBufferList(Transmitter, NetBufferList);
+}
 
-        Packet = Next;
-    }
+VOID
+TransmitterTeardown(
+    IN  PXENNET_TRANSMITTER     Transmitter
+    )
+{
+    ExFreePoolWithTag(Transmitter, TRANSMITTER_POOL_TAG);
 }
+
diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h
index 8dc7e8d..f99ffd3 100644
--- a/src/xennet/transmitter.h
+++ b/src/xennet/transmitter.h
@@ -29,47 +29,48 @@
  * SUCH DAMAGE.
  */
 
-#pragma once
+#ifndef _XENNET_TRANSMITTER_H_
+#define _XENNET_TRANSMITTER_H_
 
-typedef struct _TRANSMITTER {
-    PADAPTER                    Adapter;
-    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
-} TRANSMITTER, *PTRANSMITTER;
+typedef struct _XENNET_TRANSMITTER  XENNET_TRANSMITTER, *PXENNET_TRANSMITTER;
 
-VOID 
-TransmitterCleanup (
-    IN OUT PTRANSMITTER* Transmitter
+#include <vif_interface.h>
+
+extern VOID
+TransmitterSendNetBufferLists(
+    IN  PXENNET_TRANSMITTER     Transmitter,
+    IN  PNET_BUFFER_LIST        NetBufferList,
+    IN  NDIS_PORT_NUMBER        PortNumber,
+    IN  ULONG                   SendFlags
     );
 
-NDIS_STATUS
-TransmitterInitialize (
-    IN  PTRANSMITTER    Transmitter,
-    IN  PADAPTER        Adapter
+extern VOID
+TransmitterCompletePackets(
+    IN  PXENNET_TRANSMITTER         Transmitter,
+    IN  PXENVIF_TRANSMITTER_PACKET  Packet
     );
 
-VOID
-TransmitterEnable (
-    IN  PTRANSMITTER    Transmitter
+extern VOID
+TransmitterEnable(
+    IN  PXENNET_TRANSMITTER     Transmitter
     );
 
-VOID 
-TransmitterDelete (
-    IN OUT PTRANSMITTER* Transmitter
+extern PXENVIF_VIF_OFFLOAD_OPTIONS
+TransmitterOffloadOptions(
+    IN  PXENNET_TRANSMITTER     Transmitter
     );
 
-VOID
-TransmitterSendNetBufferLists (
-    IN  PTRANSMITTER        Transmitter,
-    IN  PNET_BUFFER_LIST    NetBufferList,
-    IN  NDIS_PORT_NUMBER    PortNumber,
-    IN  ULONG               SendFlags
+#include "adapter.h"
+extern NTSTATUS
+TransmitterInitialize(
+    IN  PXENNET_ADAPTER         Adapter,
+    OUT PXENNET_TRANSMITTER     *Transmitter
     );
 
-VOID
-TransmitterCompletePackets(
-    IN  PTRANSMITTER                Transmitter,
-    IN  PXENVIF_TRANSMITTER_PACKET  Packet
+extern VOID
+TransmitterTeardown(
+    IN  PXENNET_TRANSMITTER     Transmitter
     );
 
-void TransmitterPause(PTRANSMITTER Transmitter);
-void TransmitterUnpause(PTRANSMITTER Transmitter);
+#endif // _XENNET_TRANSMITTER_H_
+
diff --git a/vs2012/xennet/xennet.vcxproj b/vs2012/xennet/xennet.vcxproj
index db07e9b..4b6e780 100644
--- a/vs2012/xennet/xennet.vcxproj
+++ b/vs2012/xennet/xennet.vcxproj
@@ -84,9 +84,8 @@
        </ItemGroup>
        <ItemGroup>
                <ClCompile Include="../../src/xennet/registry.c" />
+               <ClCompile Include="../../src/xennet/driver.c" />
                <ClCompile Include="../../src/xennet/adapter.c" />
-               <ClCompile Include="../../src/xennet/main.c" />
-               <ClCompile Include="../../src/xennet/miniport.c" />
                <ClCompile Include="../../src/xennet/receiver.c" />
                <ClCompile Include="../../src/xennet/transmitter.c" />
        </ItemGroup>
diff --git a/vs2013/xennet/xennet.vcxproj b/vs2013/xennet/xennet.vcxproj
index 908bc2d..d890878 100644
--- a/vs2013/xennet/xennet.vcxproj
+++ b/vs2013/xennet/xennet.vcxproj
@@ -115,9 +115,8 @@
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="../../src/xennet/registry.c" />
+    <ClCompile Include="../../src/xennet/driver.c" />
     <ClCompile Include="../../src/xennet/adapter.c" />
-    <ClCompile Include="../../src/xennet/main.c" />
-    <ClCompile Include="../../src/xennet/miniport.c" />
     <ClCompile Include="../../src/xennet/receiver.c" />
     <ClCompile Include="../../src/xennet/transmitter.c" />
   </ItemGroup>
-- 
1.9.4.msysgit.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.