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

[win-pv-devel] [PATCH for 8.1] Make sure XENBUS interfaces are released when going into S4



Because a transition into and out of S4 means a new domain is built, it's
crucial that all XENBUS interfaces are released (so that things like
event channels, grant tables and the xenstore ring get re-constructed).

This patch fixes code paths where this was not being done. It also adds
some more logging during AdapterEnable/Disable and when moving between
D0 and D3.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/xennet/adapter.c     | 2719 +++++++++++++++++++++++-----------------------
 src/xennet/adapter.h     |    2 +-
 src/xennet/miniport.c    |   21 +-
 src/xennet/receiver.c    |   18 +
 src/xennet/receiver.h    |   10 +
 src/xennet/transmitter.c |   63 +-
 src/xennet/transmitter.h |   10 +
 7 files changed, 1471 insertions(+), 1372 deletions(-)

diff --git a/src/xennet/adapter.c b/src/xennet/adapter.c
index f9b3cf1..2c35636 100644
--- a/src/xennet/adapter.c
+++ b/src/xennet/adapter.c
@@ -1074,1576 +1074,1671 @@ AdapterGetReceiver(
     return Adapter->Receiver;
 }
 
-NDIS_STATUS
-AdapterEnable(
-    IN  PXENNET_ADAPTER     Adapter
+static FORCEINLINE PVOID
+__AdapterAllocate(
+    IN  ULONG   Length
     )
 {
-    NTSTATUS        status;
-
-    if (Adapter->Enabled)
-        return NDIS_STATUS_SUCCESS;
-
-    status = XENVIF_VIF(Enable,
-                        &Adapter->VifInterface,
-                        AdapterVifCallback,
-                        Adapter);
-    if (!NT_SUCCESS(status))
-        goto fail1;
-
-    Adapter->Enabled = TRUE;
-
-    return NDIS_STATUS_SUCCESS;
+    return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
+}
 
-fail1:
-    return NDIS_STATUS_FAILURE;
+static FORCEINLINE VOID
+__AdapterFree(
+    IN  PVOID   Buffer
+    )
+{
+    __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
 }
 
-BOOLEAN
-AdapterDisable(
-    IN  PXENNET_ADAPTER     Adapter
+static FORCEINLINE PANSI_STRING
+__AdapterMultiSzToUpcaseAnsi(
+    IN  PCHAR       Buffer
     )
 {
-    if (!Adapter->Enabled)
-        return FALSE;
+    PANSI_STRING    Ansi;
+    LONG            Index;
+    LONG            Count;
+    NTSTATUS        status;
 
-    XENVIF_VIF(Disable,
-               &Adapter->VifInterface);
+    Index = 0;
+    Count = 0;
+    for (;;) {
+        if (Buffer[Index] == '\0') {
+            Count++;
+            Index++;
 
-    AdapterMediaStateChange(Adapter);
+            // Check for double NUL
+            if (Buffer[Index] == '\0')
+                break;
+        } else {
+            Buffer[Index] = (CHAR)toupper(Buffer[Index]);
+            Index++;
+        }
+    }
 
-    Adapter->Enabled = FALSE;
+    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
 
-    return TRUE;
-}
+    status = STATUS_NO_MEMORY;
+    if (Ansi == NULL)
+        goto fail1;
 
-VOID
-AdapterMediaStateChange(
-    IN  PXENNET_ADAPTER     Adapter
-    )
-{
-    NDIS_LINK_STATE         LinkState;
-    NDIS_STATUS_INDICATION  StatusIndication;
+    for (Index = 0; Index < Count; Index++) {
+        ULONG   Length;
 
-    RtlZeroMemory(&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);
+        Length = (ULONG)strlen(Buffer);
+        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
+        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
 
-    XENVIF_VIF(MacQueryState,
-               &Adapter->VifInterface,
-               &LinkState.MediaConnectState,
-               &LinkState.RcvLinkSpeed,
-               &LinkState.MediaDuplexState);
+        status = STATUS_NO_MEMORY;
+        if (Ansi[Index].Buffer == NULL)
+            goto fail2;
 
-    if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
-        Info("LINK: STATE UNKNOWN\n");
-    } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
-        Info("LINK: DOWN\n");
-    } else {
-        ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
+        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
+        Ansi[Index].Length = (USHORT)Length;
 
-        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);
+        Buffer += Length + 1;
     }
 
-    LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
+    return Ansi;
 
-    RtlZeroMemory(&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);
+fail2:
+    Error("fail2\n");
 
-    StatusIndication.SourceHandle = Adapter->NdisAdapterHandle;
-    StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE;
-    StatusIndication.StatusBuffer = &LinkState;
-    StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE);
+    while (--Index >= 0)
+        __AdapterFree(Ansi[Index].Buffer);
 
-    NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
+    __AdapterFree(Ansi);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
 }
 
-NDIS_STATUS
-AdapterSetInformation(
-    IN  PXENNET_ADAPTER     Adapter,
-    IN  PNDIS_OID_REQUEST   Request
+static FORCEINLINE VOID
+__AdapterFreeAnsi(
+    IN  PANSI_STRING    Ansi
     )
 {
-    PVOID                   Buffer;
-    ULONG                   BufferLength;
-    ULONG                   BytesNeeded;
-    ULONG                   BytesRead;
-    BOOLEAN                 Warn;
-    NDIS_STATUS             ndisStatus;
+    ULONG               Index;
 
-    Buffer = Request->DATA.SET_INFORMATION.InformationBuffer;
-    BufferLength = Request->DATA.SET_INFORMATION.InformationBufferLength;
-    BytesNeeded = BytesRead = 0;
-    Warn = TRUE;
-    ndisStatus = NDIS_STATUS_SUCCESS;
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+        __AdapterFree(Ansi[Index].Buffer);
 
-    switch (Request->DATA.SET_INFORMATION.Oid) {
-    case OID_PNP_SET_POWER:
-        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
-        // do nothing
-        break;
+    __AdapterFree(Ansi);
+}
 
-    case OID_GEN_CURRENT_LOOKAHEAD:
-        BytesNeeded = sizeof(ULONG);
-        Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
-        if (BufferLength == BytesNeeded) {
-            Adapter->CurrentLookahead = *(PULONG)Buffer;
-            BytesRead = sizeof(ULONG);
-        }
-        break;
+static FORCEINLINE BOOLEAN
+__AdapterMatchDistribution(
+    IN  PXENNET_ADAPTER Adapter,
+    IN  PCHAR           Buffer
+    )
+{
+    PCHAR               Vendor;
+    PCHAR               Product;
+    PCHAR               Context;
+    const CHAR          *Text;
+    BOOLEAN             Match;
+    ULONG               Index;
+    NTSTATUS            status;
 
-    case OID_GEN_CURRENT_PACKET_FILTER:
-        BytesNeeded = sizeof(ULONG);
-        if (BufferLength == BytesNeeded) {
-            ndisStatus = AdapterSetPacketFilter(Adapter,
-                                                (PULONG)Buffer);
-            BytesRead = sizeof(ULONG);
-        }
-        break;
+    UNREFERENCED_PARAMETER(Adapter);
 
-    case OID_802_3_MULTICAST_LIST:
-        BytesNeeded = ETHERNET_ADDRESS_LENGTH;
-        if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
-            ndisStatus = AdapterSetMulticastAddresses(Adapter,
-                                                      Buffer,
-                                                      BufferLength / 
ETHERNET_ADDRESS_LENGTH);
-            if (ndisStatus == NDIS_STATUS_SUCCESS)
-                BytesRead = BufferLength;
-        } else {
-            ndisStatus = NDIS_STATUS_INVALID_LENGTH;
-        }
-        break;
+    status = STATUS_INVALID_PARAMETER;
 
-    case OID_OFFLOAD_ENCAPSULATION:
-        BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
-        if (BufferLength >= BytesNeeded) {
-            ndisStatus = AdapterGetOffloadEncapsulation(Adapter,
-                                                        
(PNDIS_OFFLOAD_ENCAPSULATION)Buffer);
-            if (ndisStatus == NDIS_STATUS_SUCCESS)
-                BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
-        }
-        break;
+    Vendor = __strtok_r(Buffer, " ", &Context);
+    if (Vendor == NULL)
+        goto fail1;
 
-    case OID_TCP_OFFLOAD_PARAMETERS:
-        BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS);
-        if (BufferLength >= BytesNeeded) {
-            ndisStatus = AdapterGetTcpOffloadParameters(Adapter,
-                                                        
(PNDIS_OFFLOAD_PARAMETERS)Buffer);
-            if (ndisStatus == NDIS_STATUS_SUCCESS)
-                BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS);
-        }
-        break;
+    Product = __strtok_r(NULL, " ", &Context);
+    if (Product == NULL)
+        goto fail2;
 
-    case OID_GEN_HD_SPLIT_PARAMETERS:
-        BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS);
-        if (BufferLength >= BytesNeeded) {
-            ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter,
-                                                             
(PNDIS_HD_SPLIT_PARAMETERS)Buffer);
-            if (ndisStatus == NDIS_STATUS_SUCCESS)
-                BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS);
-        }
-        break;
+    Match = TRUE;
 
-    case OID_GEN_INTERRUPT_MODERATION:
-    case OID_GEN_MACHINE_NAME:
-        Warn = FALSE;
-        /*FALLTHRU*/
-    default:
-        if (Warn)
-            Warning("UNSUPPORTED OID %08x\n", 
Request->DATA.QUERY_INFORMATION.Oid);
+    Text = VENDOR_NAME_STR;
 
-        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-        break;
+    for (Index = 0; Text[Index] != 0; Index++) {
+        if (!isalnum((UCHAR)Text[Index])) {
+            if (Vendor[Index] != '_') {
+                Match = FALSE;
+                break;
+            }
+        } else {
+            if (Vendor[Index] != Text[Index]) {
+                Match = FALSE;
+                break;
+            }
+        }
     }
 
-    Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
-    if (ndisStatus == NDIS_STATUS_SUCCESS)
-        Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
+    Text = "XENNET";
 
-    return ndisStatus;
-}
+    if (_stricmp(Product, Text) != 0)
+        Match = FALSE;
 
-static FORCEINLINE NDIS_STATUS
-__CopyBuffer(
-    IN  PVOID   Destination,
-    IN  ULONG   DestinationLength,
-    IN  PVOID   Source,
-    IN  ULONG   SourceLength,
-    OUT PULONG  CopyLength
-    )
-{
-    *CopyLength = __min(SourceLength, DestinationLength);
-    RtlCopyMemory(Destination, Source, *CopyLength);
+    return Match;
 
-    return (DestinationLength >= SourceLength) ?
-           NDIS_STATUS_SUCCESS :
-           NDIS_STATUS_BUFFER_TOO_SHORT;
-}
+fail2:
+    Error("fail2\n");
 
-static FORCEINLINE NDIS_STATUS
-__SetUlong(
-    IN  PVOID   Destination,
-    IN  ULONG   DestinationLength,
-    IN  ULONG   Source,
-    OUT PULONG  CopyLength
-    )
-{
-    return __CopyBuffer(Destination,
-                        DestinationLength & ~3,
-                        &Source,
-                        sizeof (ULONG),
-                        CopyLength);
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return FALSE;
 }
 
-static FORCEINLINE NDIS_STATUS
-__SetUlong64(
-    IN  PVOID   Destination,
-    IN  ULONG   DestinationLength,
-    IN  ULONG64 Source,
-    OUT PULONG  CopyLength
+static FORCEINLINE VOID
+__AdapterClearDistribution(
+    IN  PXENNET_ADAPTER Adapter
     )
 {
-    NDIS_STATUS ndisStatus;
+    PCHAR               Buffer;
+    PANSI_STRING        Distributions;
+    ULONG               Index;
+    NTSTATUS            status;
 
-    ndisStatus =  __CopyBuffer(Destination,
-                               DestinationLength & ~3,
-                               &Source,
-                               sizeof (ULONG64),
-                               CopyLength);
-    if (DestinationLength >= 4)
-        ndisStatus = NDIS_STATUS_SUCCESS;
+    Trace("====>\n");
 
-    return ndisStatus;
-}
+    status = XENBUS_STORE(Directory,
+                          &Adapter->StoreInterface,
+                          NULL,
+                          NULL,
+                          "drivers",
+                          &Buffer);
+    if (NT_SUCCESS(status)) {
+        Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
 
-NDIS_STATUS
-AdapterQueryInformation(
-    IN  PXENNET_ADAPTER     Adapter,
-    IN  PNDIS_OID_REQUEST   Request
-    )
-{
-    PVOID                   Buffer;
-    ULONG                   BufferLength;
-    ULONG                   BytesNeeded;
-    ULONG                   BytesWritten;
-    ULONG                   Value32;
-    ULONGLONG               Value64;
-    ETHERNET_ADDRESS        EthernetAddress;
-    BOOLEAN                 Warn;
-    NDIS_STATUS             ndisStatus;
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
+    } else {
+        Distributions = NULL;
+    }
 
-    Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
-    BufferLength = Request->DATA.QUERY_INFORMATION.InformationBufferLength;
-    BytesNeeded = BytesWritten = 0;
-    Warn = TRUE;
-    ndisStatus = NDIS_STATUS_SUCCESS;
+    if (Distributions == NULL)
+        goto done;
 
-    switch (Request->DATA.QUERY_INFORMATION.Oid) {
-    case OID_PNP_CAPABILITIES:
-        BytesNeeded = sizeof(Adapter->Capabilities);
-        ndisStatus = __CopyBuffer(Buffer,
-                                  BufferLength,
-                                  &Adapter->Capabilities,
-                                  BytesNeeded,
-                                  &BytesWritten);
-        break;
+    for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
+        PANSI_STRING    Distribution = &Distributions[Index];
 
-    case OID_PNP_QUERY_POWER:
-        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
-        BytesWritten = 0;
-        // do nothing
-        break;
+        status = XENBUS_STORE(Read,
+                              &Adapter->StoreInterface,
+                              NULL,
+                              "drivers",
+                              Distribution->Buffer,
+                              &Buffer);
+        if (!NT_SUCCESS(status))
+            continue;
 
-    case OID_GEN_SUPPORTED_LIST:
-        BytesNeeded = sizeof(XennetSupportedOids);
-        ndisStatus = __CopyBuffer(Buffer,
-                                  BufferLength,
-                                  &XennetSupportedOids[0],
-                                  BytesNeeded,
-                                  &BytesWritten);
-        break;
+        if (__AdapterMatchDistribution(Adapter, Buffer))
+            (VOID) XENBUS_STORE(Remove,
+                                &Adapter->StoreInterface,
+                                NULL,
+                                "drivers",
+                                Distribution->Buffer);
 
-    case OID_GEN_HARDWARE_STATUS:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                NdisHardwareStatusReady,
-                                &BytesWritten);
-        break;
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
+    }
 
-    case OID_GEN_MEDIA_SUPPORTED:
-    case OID_GEN_MEDIA_IN_USE:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                XENNET_MEDIA_TYPE,
-                                &BytesWritten);
-        break;
+    __AdapterFreeAnsi(Distributions);
 
-    case OID_GEN_MAXIMUM_LOOKAHEAD:
-    case OID_GEN_TRANSMIT_BLOCK_SIZE:
-    case OID_GEN_RECEIVE_BLOCK_SIZE:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Adapter->MaximumFrameSize,
-                                &BytesWritten);
-        break;
+done:
+    Trace("<====\n");
+}
 
-    case OID_GEN_TRANSMIT_BUFFER_SPACE:
-    case OID_GEN_RECEIVE_BUFFER_SPACE:
-        XENVIF_VIF(TransmitterQueryRingSize,
-                    &Adapter->VifInterface,
-                    (PULONG)&Value32);
-        Value32 *= Adapter->MaximumFrameSize;
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Value32,
-                                &BytesWritten);
-        break;
+#define MAXIMUM_INDEX   255
 
-    case OID_GEN_VENDOR_DESCRIPTION:
-        BytesNeeded = (ULONG)strlen(VENDOR_NAME_STR) + 1;
-        ndisStatus = __CopyBuffer(Buffer,
-                                  BufferLength,
-                                  VENDOR_NAME_STR,
-                                  BytesNeeded,
-                                  &BytesWritten);
-        break;
+static FORCEINLINE NTSTATUS
+__AdapterSetDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    ULONG               Index;
+    CHAR                Distribution[MAXNAMELEN];
+    CHAR                Vendor[MAXNAMELEN];
+    const CHAR          *Product;
+    NTSTATUS            status;
 
-    case OID_GEN_VENDOR_DRIVER_VERSION:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8,
-                                &BytesWritten);
-        break;
+    Trace("====>\n");
 
-    case OID_GEN_DRIVER_VERSION:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (6 << 8) | 0, // NDIS 6.0
-                                &BytesWritten);
-        break;
+    Index = 0;
+    while (Index <= MAXIMUM_INDEX) {
+        PCHAR   Buffer;
 
-    case OID_GEN_MAC_OPTIONS:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                XENNET_MAC_OPTIONS,
-                                &BytesWritten);
-        break;
+        status = RtlStringCbPrintfA(Distribution,
+                                    MAXNAMELEN,
+                                    "%u",
+                                    Index);
+        ASSERT(NT_SUCCESS(status));
 
-    case OID_GEN_STATISTICS:
-        BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
-        ndisStatus = AdapterQueryGeneralStatistics(Adapter,
-                                                   
(PNDIS_STATISTICS_INFO)Buffer,
-                                                   BufferLength,
-                                                   &BytesWritten);
-        break;
+        status = XENBUS_STORE(Read,
+                              &Adapter->StoreInterface,
+                              NULL,
+                              "drivers",
+                              Distribution,
+                              &Buffer);
+        if (!NT_SUCCESS(status)) {
+            if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+                goto update;
 
-    case OID_802_3_MULTICAST_LIST:
-        ndisStatus = AdapterQueryMulticastList(Adapter,
-                                               Buffer,
-                                               BufferLength,
-                                               &BytesNeeded,
-                                               &BytesWritten);
-        break;
+            goto fail1;
+        }
 
-    case OID_802_3_PERMANENT_ADDRESS:
-        XENVIF_VIF(MacQueryPermanentAddress,
-                    &Adapter->VifInterface,
-                    &EthernetAddress);
-        BytesNeeded = sizeof(ETHERNET_ADDRESS);
-        ndisStatus = __CopyBuffer(Buffer,
-                                  BufferLength,
-                                  &EthernetAddress,
-                                  BytesNeeded,
-                                  &BytesWritten);
-        break;
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
 
-    case OID_802_3_CURRENT_ADDRESS:
-        XENVIF_VIF(MacQueryCurrentAddress,
-                    &Adapter->VifInterface,
-                    &EthernetAddress);
-        BytesNeeded = sizeof(ETHERNET_ADDRESS);
-        ndisStatus = __CopyBuffer(Buffer,
-                                  BufferLength,
-                                  &EthernetAddress,
-                                  BytesNeeded,
-                                  &BytesWritten);
-        break;
+        Index++;
+    }
 
-    case OID_GEN_MAXIMUM_FRAME_SIZE:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Adapter->MaximumFrameSize -
-                                    sizeof(ETHERNET_TAGGED_HEADER),
-                                &BytesWritten);
-        break;
+    status = STATUS_UNSUCCESSFUL;
+    goto fail2;
 
-    case OID_GEN_MAXIMUM_TOTAL_SIZE:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Adapter->MaximumFrameSize -
-                                    sizeof(ETHERNET_TAGGED_HEADER) +
-                                    sizeof (ETHERNET_UNTAGGED_HEADER),
-                                &BytesWritten);
-        break;
+update:
+    status = RtlStringCbPrintfA(Vendor,
+                                MAXNAMELEN,
+                                "%s",
+                                VENDOR_NAME_STR);
+    ASSERT(NT_SUCCESS(status));
 
-    case OID_GEN_CURRENT_LOOKAHEAD:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Adapter->CurrentLookahead,
-                                &BytesWritten);
-        break;
+    for (Index  = 0; Vendor[Index] != '\0'; Index++)
+        if (!isalnum((UCHAR)Vendor[Index]))
+            Vendor[Index] = '_';
 
-    case OID_GEN_VENDOR_ID:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                0x5853,
-                                &BytesWritten);
-        break;
+    Product = "XENNET";
 
-    case OID_GEN_LINK_SPEED:
-        XENVIF_VIF(MacQueryState,
-                   &Adapter->VifInterface,
-                   NULL,
-                   &Value64,
-                   NULL);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)(Value64 / 100),
-                                &BytesWritten);
-        break;
+#if DBG
+#define ATTRIBUTES   "(DEBUG)"
+#else
+#define ATTRIBUTES   ""
+#endif
 
-    case OID_GEN_MEDIA_CONNECT_STATUS:
-        XENVIF_VIF(MacQueryState,
-                    &Adapter->VifInterface,
-                    (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
-                    NULL,
-                    NULL);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Value32,
-                                &BytesWritten);
-        break;
+    (VOID) XENBUS_STORE(Printf,
+                        &Adapter->StoreInterface,
+                        NULL,
+                        "drivers",
+                        Distribution,
+                        "%s %s %u.%u.%u %s",
+                        Vendor,
+                        Product,
+                        MAJOR_VERSION,
+                        MINOR_VERSION,
+                        MICRO_VERSION,
+                        ATTRIBUTES
+                        );
 
-    case OID_GEN_MAXIMUM_SEND_PACKETS:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                16,
-                                &BytesWritten);
-        break;
+#undef  ATTRIBUTES
 
-    case OID_GEN_CURRENT_PACKET_FILTER:
-        AdapterGetPacketFilter(Adapter, &Value32);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Value32,
-                                &BytesWritten);
-        break;
+    Trace("<====\n");
+    return STATUS_SUCCESS;
 
-    case OID_GEN_XMIT_OK:
-        AdapterGetXmitOk(Adapter, &Value64);
-        BytesNeeded = sizeof(ULONG64);
-        ndisStatus = __SetUlong64(Buffer,
-                                  BufferLength,
-                                  Value64,
-                                  &BytesWritten);
-        break;
+fail2:
+    Error("fail2\n");
 
-    case OID_GEN_RCV_OK:
-        AdapterGetRcvOk(Adapter, &Value64);
-        BytesNeeded = sizeof(ULONG64);
-        ndisStatus = __SetUlong64(Buffer,
-                                  BufferLength,
-                                  Value64,
-                                  &BytesWritten);
-        break;
+fail1:
+    Error("fail1 (%08x)\n", status);
 
-    case OID_GEN_XMIT_ERROR:
-        AdapterGetXmitError(Adapter, &Value32);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Value32,
-                                &BytesWritten);
-        break;
+    return status;
+}
 
-    case OID_GEN_RCV_ERROR:
-        AdapterGetRcvError(Adapter, &Value32);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                Value32,
-                                &BytesWritten);
-        break;
+static DECLSPEC_NOINLINE VOID
+AdapterSuspendCallbackLate(
+    IN  PVOID       Argument
+    )
+{
+    PXENNET_ADAPTER Adapter = Argument;
 
-    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:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                0,
-                                &BytesWritten);
-        break;
+    (VOID) __AdapterSetDistribution(Adapter);
+}
 
-    case OID_802_3_MAXIMUM_LIST_SIZE:
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                32,
-                                &BytesWritten);
-        break;
+static NTSTATUS
+AdapterSetDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    LONG                Count;
+    NTSTATUS            status;
 
-    case OID_GEN_DIRECTED_BYTES_XMIT:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_TRANSMITTER_UNICAST_OCTETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    Trace("====>\n");
 
-    case OID_GEN_DIRECTED_FRAMES_XMIT:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_TRANSMITTER_UNICAST_PACKETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    Count = InterlockedIncrement(&AdapterCount);
+    ASSERT(Count != 0);
 
-    case OID_GEN_MULTICAST_BYTES_XMIT:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_TRANSMITTER_MULTICAST_OCTETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    if (Count != 1)
+        goto done;
 
-    case OID_GEN_MULTICAST_FRAMES_XMIT:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_TRANSMITTER_MULTICAST_PACKETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    status = __AdapterSetDistribution(Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = XENBUS_SUSPEND(Register,
+                            &Adapter->SuspendInterface,
+                            SUSPEND_CALLBACK_LATE,
+                            AdapterSuspendCallbackLate,
+                            Adapter,
+                            &Adapter->SuspendCallbackLate);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+done:
+    Trace("<====\n");
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    __AdapterClearDistribution(Adapter);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static VOID
+AdapterClearDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    LONG                Count;
+
+    Trace("====>\n");
+
+    Count = InterlockedDecrement(&AdapterCount);
+
+    if (Count != 0)
+        goto done;
+
+    XENBUS_SUSPEND(Deregister,
+                   &Adapter->SuspendInterface,
+                   Adapter->SuspendCallbackLate);
+    Adapter->SuspendCallbackLate = NULL;
+
+    __AdapterClearDistribution(Adapter);
+
+done:
+    Trace("<====\n");
+}
+
+NDIS_STATUS
+AdapterEnable(
+    IN  PXENNET_ADAPTER     Adapter
+    )
+{
+    NTSTATUS                status;
+    NDIS_STATUS             ndisStatus;
+
+    ASSERT(!Adapter->Enabled);
+
+    status = XENBUS_CACHE(Acquire,
+                          &Adapter->CacheInterface);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = XENBUS_STORE(Acquire,
+                          &Adapter->StoreInterface);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = XENBUS_SUSPEND(Acquire,
+                            &Adapter->SuspendInterface);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    (VOID) AdapterSetDistribution(Adapter);
+
+    ndisStatus = TransmitterEnable(Adapter->Transmitter);
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail4;
+
+    ndisStatus = ReceiverEnable(Adapter->Receiver);
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail5;
+
+    status = XENVIF_VIF(Enable,
+                        &Adapter->VifInterface,
+                        AdapterVifCallback,
+                        Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail6;
+
+    AdapterMediaStateChange(Adapter);
+
+    Adapter->Enabled = TRUE;
+
+    return NDIS_STATUS_SUCCESS;
+
+fail6:
+    ReceiverDisable(Adapter->Receiver);
+
+fail5:
+    TransmitterDisable(Adapter->Transmitter);
+
+fail4:
+    AdapterClearDistribution(Adapter);
+
+    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
+
+fail3:
+    XENBUS_STORE(Release, &Adapter->StoreInterface);
+
+fail2:
+    XENBUS_CACHE(Release, &Adapter->CacheInterface);
+
+fail1:
+    return NDIS_STATUS_FAILURE;
+}
 
-    case OID_GEN_BROADCAST_BYTES_XMIT:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_TRANSMITTER_BROADCAST_OCTETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+VOID
+AdapterDisable(
+    IN  PXENNET_ADAPTER     Adapter
+    )
+{
+    ASSERT(Adapter->Enabled);
+    Adapter->Enabled = FALSE;
 
-    case OID_GEN_BROADCAST_FRAMES_XMIT:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_TRANSMITTER_BROADCAST_PACKETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    XENVIF_VIF(Disable,
+               &Adapter->VifInterface);
 
-    case OID_GEN_DIRECTED_BYTES_RCV:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_RECEIVER_UNICAST_OCTETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    AdapterMediaStateChange(Adapter);
 
-    case OID_GEN_DIRECTED_FRAMES_RCV:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_RECEIVER_UNICAST_PACKETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    ReceiverDisable(Adapter->Receiver);
+    TransmitterDisable(Adapter->Transmitter);
 
-    case OID_GEN_MULTICAST_BYTES_RCV:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_RECEIVER_MULTICAST_OCTETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    AdapterClearDistribution(Adapter);
 
-    case OID_GEN_MULTICAST_FRAMES_RCV:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_RECEIVER_MULTICAST_PACKETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
+    XENBUS_STORE(Release, &Adapter->StoreInterface);
+    XENBUS_CACHE(Release, &Adapter->CacheInterface);
+}
 
-    case OID_GEN_BROADCAST_BYTES_RCV:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_RECEIVER_BROADCAST_OCTETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+VOID
+AdapterMediaStateChange(
+    IN  PXENNET_ADAPTER     Adapter
+    )
+{
+    NDIS_LINK_STATE         LinkState;
+    NDIS_STATUS_INDICATION  StatusIndication;
 
-    case OID_GEN_BROADCAST_FRAMES_RCV:
-        XENVIF_VIF(QueryStatistic,
-                   &Adapter->VifInterface,
-                   XENVIF_RECEIVER_BROADCAST_PACKETS,
-                   &Value64);
-        BytesNeeded = sizeof(ULONG);
-        ndisStatus = __SetUlong(Buffer,
-                                BufferLength,
-                                (ULONG)Value64,
-                                &BytesWritten);
-        break;
+    RtlZeroMemory(&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);
 
-    case OID_GEN_INTERRUPT_MODERATION:
-        BytesNeeded = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
-        ndisStatus = AdapterInterruptModeration(Adapter,
-                                                
(PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer,
-                                                BufferLength,
-                                                &BytesWritten);
-        break;
+    XENVIF_VIF(MacQueryState,
+               &Adapter->VifInterface,
+               &LinkState.MediaConnectState,
+               &LinkState.RcvLinkSpeed,
+               &LinkState.MediaDuplexState);
 
-    case OID_IP4_OFFLOAD_STATS:
-    case OID_IP6_OFFLOAD_STATS:
-    case OID_GEN_SUPPORTED_GUIDS:
-        // 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:
-        // ignore these common unwanted OIDs
-       case OID_GEN_INIT_TIME_MS:
-       case OID_GEN_RESET_COUNTS:
-       case OID_GEN_MEDIA_SENSE_COUNTS:
-        Warn = FALSE;
-        /*FALLTHRU*/
-    default:
-        if (Warn)
-            Warning("UNSUPPORTED OID %08x\n", 
Request->DATA.QUERY_INFORMATION.Oid);
+    if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
+        Info("LINK: STATE UNKNOWN\n");
+    } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
+        Info("LINK: DOWN\n");
+    } else {
+        ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
 
-        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
-        break;
+        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);
     }
 
-    Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
-    Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
+    LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
 
-    return ndisStatus;
+    RtlZeroMemory(&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);
+
+    NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
 }
 
-static NTSTATUS
-__QueryInterface(
-    IN  PDEVICE_OBJECT  DeviceObject,
-    IN  const GUID      *Guid,
-    IN  ULONG           Version,
-    OUT PINTERFACE      Interface,
-    IN  ULONG           Size,
-    IN  BOOLEAN         Optional
+NDIS_STATUS
+AdapterSetInformation(
+    IN  PXENNET_ADAPTER     Adapter,
+    IN  PNDIS_OID_REQUEST   Request
     )
 {
-    KEVENT              Event;
-    IO_STATUS_BLOCK     StatusBlock;
-    PIRP                Irp;
-    PIO_STACK_LOCATION  StackLocation;
-    NTSTATUS            status;
+    PVOID                   Buffer;
+    ULONG                   BufferLength;
+    ULONG                   BytesNeeded;
+    ULONG                   BytesRead;
+    BOOLEAN                 Warn;
+    NDIS_STATUS             ndisStatus;
 
-    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+    Buffer = Request->DATA.SET_INFORMATION.InformationBuffer;
+    BufferLength = Request->DATA.SET_INFORMATION.InformationBufferLength;
+    BytesNeeded = BytesRead = 0;
+    Warn = TRUE;
+    ndisStatus = NDIS_STATUS_SUCCESS;
 
-    KeInitializeEvent(&Event, NotificationEvent, FALSE);
-    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+    switch (Request->DATA.SET_INFORMATION.Oid) {
+    case OID_PNP_SET_POWER:
+        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
+        if (BufferLength >= BytesNeeded) {
+            PNDIS_DEVICE_POWER_STATE PowerState;
 
-    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
-                                       DeviceObject,
-                                       NULL,
-                                       0,
-                                       NULL,
-                                       &Event,
-                                       &StatusBlock);
+            PowerState = (PNDIS_DEVICE_POWER_STATE)Buffer;
+            switch (*PowerState) {
+            case NdisDeviceStateD0:
+                Info("SET_POWER: D0\n");
+                break;
 
-    status = STATUS_UNSUCCESSFUL;
-    if (Irp == NULL)
-        goto fail1;
+            case NdisDeviceStateD1:
+                Info("SET_POWER: D1\n");
+                break;
 
-    StackLocation = IoGetNextIrpStackLocation(Irp);
-    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
+            case NdisDeviceStateD2:
+                Info("SET_POWER: D2\n");
+                break;
 
-    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
-    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
-    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
-    StackLocation->Parameters.QueryInterface.Interface = Interface;
+            case NdisDeviceStateD3:
+                Info("SET_POWER: D3\n");
+                break;
+            }
+        }
+        // do nothing
+        break;
 
-    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+    case OID_GEN_CURRENT_LOOKAHEAD:
+        BytesNeeded = sizeof(ULONG);
+        Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
+        if (BufferLength == BytesNeeded) {
+            Adapter->CurrentLookahead = *(PULONG)Buffer;
+            BytesRead = sizeof(ULONG);
+        }
+        break;
 
-    status = IoCallDriver(DeviceObject, Irp);
-    if (status == STATUS_PENDING) {
-        (VOID) KeWaitForSingleObject(&Event,
-                                     Executive,
-                                     KernelMode,
-                                     FALSE,
-                                     NULL);
-        status = StatusBlock.Status;
-    }
+    case OID_GEN_CURRENT_PACKET_FILTER:
+        BytesNeeded = sizeof(ULONG);
+        if (BufferLength == BytesNeeded) {
+            ndisStatus = AdapterSetPacketFilter(Adapter,
+                                                (PULONG)Buffer);
+            BytesRead = sizeof(ULONG);
+        }
+        break;
 
-    if (!NT_SUCCESS(status)) {
-        if (status == STATUS_NOT_SUPPORTED && Optional)
-            goto done;
+    case OID_802_3_MULTICAST_LIST:
+        BytesNeeded = ETHERNET_ADDRESS_LENGTH;
+        if (BufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
+            ndisStatus = AdapterSetMulticastAddresses(Adapter,
+                                                      Buffer,
+                                                      BufferLength / 
ETHERNET_ADDRESS_LENGTH);
+            if (ndisStatus == NDIS_STATUS_SUCCESS)
+                BytesRead = BufferLength;
+        } else {
+            ndisStatus = NDIS_STATUS_INVALID_LENGTH;
+        }
+        break;
 
-        goto fail2;
-    }
+    case OID_OFFLOAD_ENCAPSULATION:
+        BytesNeeded = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
+        if (BufferLength >= BytesNeeded) {
+            ndisStatus = AdapterGetOffloadEncapsulation(Adapter,
+                                                        
(PNDIS_OFFLOAD_ENCAPSULATION)Buffer);
+            if (ndisStatus == NDIS_STATUS_SUCCESS)
+                BytesRead = sizeof(NDIS_OFFLOAD_ENCAPSULATION);
+        }
+        break;
 
-done:
-    return STATUS_SUCCESS;
+    case OID_TCP_OFFLOAD_PARAMETERS:
+        BytesNeeded = sizeof(NDIS_OFFLOAD_PARAMETERS);
+        if (BufferLength >= BytesNeeded) {
+            ndisStatus = AdapterGetTcpOffloadParameters(Adapter,
+                                                        
(PNDIS_OFFLOAD_PARAMETERS)Buffer);
+            if (ndisStatus == NDIS_STATUS_SUCCESS)
+                BytesRead = sizeof(NDIS_OFFLOAD_PARAMETERS);
+        }
+        break;
 
-fail2:
-    Error("fail2\n");
+    case OID_GEN_HD_SPLIT_PARAMETERS:
+        BytesNeeded = sizeof(NDIS_HD_SPLIT_PARAMETERS);
+        if (BufferLength >= BytesNeeded) {
+            ndisStatus = AdapterGetHeaderDataSplitParameters(Adapter,
+                                                             
(PNDIS_HD_SPLIT_PARAMETERS)Buffer);
+            if (ndisStatus == NDIS_STATUS_SUCCESS)
+                BytesRead = sizeof(NDIS_HD_SPLIT_PARAMETERS);
+        }
+        break;
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+    case OID_GEN_INTERRUPT_MODERATION:
+    case OID_GEN_MACHINE_NAME:
+        Warn = FALSE;
+        /*FALLTHRU*/
+    default:
+        if (Warn)
+            Warning("UNSUPPORTED OID %08x\n", 
Request->DATA.QUERY_INFORMATION.Oid);
 
-    return status;
-}
+        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+        break;
+    }
 
-#pragma prefast(push)
-#pragma prefast(disable:6102)
+    Request->DATA.SET_INFORMATION.BytesNeeded = BytesNeeded;
+    if (ndisStatus == NDIS_STATUS_SUCCESS)
+        Request->DATA.SET_INFORMATION.BytesRead = BytesRead;
 
-#define READ_PROPERTY(field, name, defaultval, handle)  \
-    do {                                                \
-        NDIS_STATUS                     _Status;        \
-        NDIS_STRING                     _Value;         \
-        PNDIS_CONFIGURATION_PARAMETER   _Data;          \
-        RtlInitUnicodeString(&_Value, name);            \
-        NdisReadConfiguration(&_Status, &_Data, handle, \
-                        &_Value, NdisParameterInteger); \
-        if (_Status == NDIS_STATUS_SUCCESS)             \
-            field = _Data->ParameterData.IntegerData;   \
-        else                                            \
-            field = defaultval;                         \
-    } while (FALSE);
+    return ndisStatus;
+}
 
-static NDIS_STATUS
-AdapterGetAdvancedSettings(
-    IN  PXENNET_ADAPTER Adapter
+static FORCEINLINE NDIS_STATUS
+__CopyBuffer(
+    IN  PVOID   Destination,
+    IN  ULONG   DestinationLength,
+    IN  PVOID   Source,
+    IN  ULONG   SourceLength,
+    OUT PULONG  CopyLength
     )
 {
-    NDIS_CONFIGURATION_OBJECT   Config;
-    NDIS_HANDLE                 Handle;
-    NDIS_STATUS                 ndisStatus;
-
-    RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT));
-    Config.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
-    Config.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
-    Config.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
-    Config.NdisHandle = Adapter->NdisAdapterHandle;
-    Config.Flags = 0;
-
-    ndisStatus = NdisOpenConfigurationEx(&Config, &Handle);
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail1;
-
-    READ_PROPERTY(Adapter->Properties.ipv4_csum, L"*IPChecksumOffloadIPv4", 3, 
Handle);
-    READ_PROPERTY(Adapter->Properties.tcpv4_csum, L"*TCPChecksumOffloadIPv4", 
3, Handle);
-    READ_PROPERTY(Adapter->Properties.udpv4_csum, L"*UDPChecksumOffloadIPv4", 
3, Handle);
-    READ_PROPERTY(Adapter->Properties.tcpv6_csum, L"*TCPChecksumOffloadIPv6", 
3, Handle);
-    READ_PROPERTY(Adapter->Properties.udpv6_csum, L"*UDPChecksumOffloadIPv6", 
3, Handle);
-    READ_PROPERTY(Adapter->Properties.lsov4, L"*LSOv2IPv4", 1, Handle);
-    READ_PROPERTY(Adapter->Properties.lsov6, L"*LSOv2IPv6", 1, Handle);
-    READ_PROPERTY(Adapter->Properties.lrov4, L"LROIPv4", 1, Handle);
-    READ_PROPERTY(Adapter->Properties.lrov6, L"LROIPv6", 1, Handle);
-    READ_PROPERTY(Adapter->Properties.need_csum_value, L"NeedChecksumValue", 
1, Handle);
-    READ_PROPERTY(Adapter->Properties.HeaderDataSplit, L"*HeaderDataSplit", 1, 
Handle);
-
-    NdisCloseConfiguration(Handle);
-
-    return NDIS_STATUS_SUCCESS;
+    *CopyLength = __min(SourceLength, DestinationLength);
+    RtlCopyMemory(Destination, Source, *CopyLength);
 
-fail1:
-    return NDIS_STATUS_FAILURE;
+    return (DestinationLength >= SourceLength) ?
+           NDIS_STATUS_SUCCESS :
+           NDIS_STATUS_BUFFER_TOO_SHORT;
 }
 
-#undef READ_PROPERTY
-
-#pragma prefast(pop)
-
-static NDIS_STATUS
-AdapterSetRegistrationAttributes(
-    IN  PXENNET_ADAPTER Adapter
+static FORCEINLINE NDIS_STATUS
+__SetUlong(
+    IN  PVOID   Destination,
+    IN  ULONG   DestinationLength,
+    IN  ULONG   Source,
+    OUT PULONG  CopyLength
     )
 {
-    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES   Attribs;
-    NDIS_STATUS                                     ndisStatus;
+    return __CopyBuffer(Destination,
+                        DestinationLength & ~3,
+                        &Source,
+                        sizeof (ULONG),
+                        CopyLength);
+}
 
-    RtlZeroMemory(&Attribs, 
sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
-    Attribs.Header.Type = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
-    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
-    Attribs.Header.Size = 
sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
-    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;
+static FORCEINLINE NDIS_STATUS
+__SetUlong64(
+    IN  PVOID   Destination,
+    IN  ULONG   DestinationLength,
+    IN  ULONG64 Source,
+    OUT PULONG  CopyLength
+    )
+{
+    NDIS_STATUS ndisStatus;
 
-    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+    ndisStatus =  __CopyBuffer(Destination,
+                               DestinationLength & ~3,
+                               &Source,
+                               sizeof (ULONG64),
+                               CopyLength);
+    if (DestinationLength >= 4)
+        ndisStatus = NDIS_STATUS_SUCCESS;
 
     return ndisStatus;
 }
 
-static NDIS_STATUS
-AdapterSetGeneralAttributes(
-    IN  PXENNET_ADAPTER Adapter
+NDIS_STATUS
+AdapterQueryInformation(
+    IN  PXENNET_ADAPTER     Adapter,
+    IN  PNDIS_OID_REQUEST   Request
     )
 {
-    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES    Attribs;
-    NDIS_STATUS                                 ndisStatus;
-
-    RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
-    Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
-    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
-    Attribs.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
-    Attribs.MediaType = XENNET_MEDIA_TYPE;
-
-    XENVIF_VIF(MacQueryMaximumFrameSize,
-               &Adapter->VifInterface,
-               (PULONG)&Adapter->MaximumFrameSize);
-
-    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;
-
-    XENVIF_VIF(MacQueryPermanentAddress,
-               &Adapter->VifInterface,
-               (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress);
-    XENVIF_VIF(MacQueryCurrentAddress,
-               &Adapter->VifInterface,
-               (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
+    PVOID                   Buffer;
+    ULONG                   BufferLength;
+    ULONG                   BytesNeeded;
+    ULONG                   BytesWritten;
+    ULONG                   Value32;
+    ULONGLONG               Value64;
+    ETHERNET_ADDRESS        EthernetAddress;
+    BOOLEAN                 Warn;
+    NDIS_STATUS             ndisStatus;
 
-    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);
+    Buffer = Request->DATA.QUERY_INFORMATION.InformationBuffer;
+    BufferLength = Request->DATA.QUERY_INFORMATION.InformationBufferLength;
+    BytesNeeded = BytesWritten = 0;
+    Warn = TRUE;
+    ndisStatus = NDIS_STATUS_SUCCESS;
 
-    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+    switch (Request->DATA.QUERY_INFORMATION.Oid) {
+    case OID_PNP_CAPABILITIES:
+        BytesNeeded = sizeof(Adapter->Capabilities);
+        ndisStatus = __CopyBuffer(Buffer,
+                                  BufferLength,
+                                  &Adapter->Capabilities,
+                                  BytesNeeded,
+                                  &BytesWritten);
+        break;
 
-    return ndisStatus;
-}
+    case OID_PNP_QUERY_POWER:
+        BytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
 
-static NDIS_STATUS
-AdapterSetOffloadAttributes(
-    IN  PXENNET_ADAPTER Adapter
-    )
-{
-    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES    Attribs;
-    XENVIF_VIF_OFFLOAD_OPTIONS                  Options;
-    PXENVIF_VIF_OFFLOAD_OPTIONS                 RxOptions;
-    PXENVIF_VIF_OFFLOAD_OPTIONS                 TxOptions;
-    NDIS_OFFLOAD                                Default;
-    NDIS_OFFLOAD                                Supported;
-    NDIS_STATUS                                 ndisStatus;
+        if (BufferLength >= BytesNeeded) {
+            PNDIS_DEVICE_POWER_STATE PowerState;
 
-    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
-    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
+            PowerState = (PNDIS_DEVICE_POWER_STATE)Buffer;
+            switch (*PowerState) {
+            case NdisDeviceStateD0:
+                Info("QUERY_POWER: D0\n");
+                break;
 
-    TxOptions->Value = 0;
-    TxOptions->OffloadTagManipulation = 1;
+            case NdisDeviceStateD1:
+                Info("QUERY_POWER: D1\n");
+                break;
 
-    RxOptions->Value = 0;
-    RxOptions->OffloadTagManipulation = 1;
+            case NdisDeviceStateD2:
+                Info("QUERY_POWER: D2\n");
+                break;
 
-    if (Adapter->Properties.need_csum_value)
-        RxOptions->NeedChecksumValue = 1;
+            case NdisDeviceStateD3:
+                Info("QUERY_POWER: D3\n");
+                break;
+            }
+        }
 
-    if (Adapter->Properties.lrov4) {
-        RxOptions->OffloadIpVersion4LargePacket = 1;
-        RxOptions->NeedLargePacketSplit = 1;
-    }
+        BytesWritten = 0;
+        // do nothing
+        break;
 
-    if (Adapter->Properties.lrov6) {
-        RxOptions->OffloadIpVersion6LargePacket = 1;
-        RxOptions->NeedLargePacketSplit = 1;
-    }
+    case OID_GEN_SUPPORTED_LIST:
+        BytesNeeded = sizeof(XennetSupportedOids);
+        ndisStatus = __CopyBuffer(Buffer,
+                                  BufferLength,
+                                  &XennetSupportedOids[0],
+                                  BytesNeeded,
+                                  &BytesWritten);
+        break;
 
-    XENVIF_VIF(ReceiverSetOffloadOptions,
-               &Adapter->VifInterface,
-               *RxOptions);
+    case OID_GEN_HARDWARE_STATUS:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                NdisHardwareStatusReady,
+                                &BytesWritten);
+        break;
 
-    XENVIF_VIF(TransmitterQueryOffloadOptions,
-               &Adapter->VifInterface,
-               &Options);
+    case OID_GEN_MEDIA_SUPPORTED:
+    case OID_GEN_MEDIA_IN_USE:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                XENNET_MEDIA_TYPE,
+                                &BytesWritten);
+        break;
 
-    RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD));
-    Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
-    Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
-    Supported.Header.Size = sizeof(NDIS_OFFLOAD);
+    case OID_GEN_MAXIMUM_LOOKAHEAD:
+    case OID_GEN_TRANSMIT_BLOCK_SIZE:
+    case OID_GEN_RECEIVE_BLOCK_SIZE:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Adapter->MaximumFrameSize,
+                                &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv4Receive.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    case OID_GEN_TRANSMIT_BUFFER_SPACE:
+    case OID_GEN_RECEIVE_BUFFER_SPACE:
+        XENVIF_VIF(TransmitterQueryRingSize,
+                    &Adapter->VifInterface,
+                    (PULONG)&Value32);
+        Value32 *= Adapter->MaximumFrameSize;
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Value32,
+                                &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv4Receive.IpChecksum = 1;
-    Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
+    case OID_GEN_VENDOR_DESCRIPTION:
+        BytesNeeded = (ULONG)strlen(VENDOR_NAME_STR) + 1;
+        ndisStatus = __CopyBuffer(Buffer,
+                                  BufferLength,
+                                  VENDOR_NAME_STR,
+                                  BytesNeeded,
+                                  &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv4Receive.TcpChecksum = 1;
-    Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
+    case OID_GEN_VENDOR_DRIVER_VERSION:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8,
+                                &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv4Receive.UdpChecksum = 1;
+    case OID_GEN_DRIVER_VERSION:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (6 << 8) | 0, // NDIS 6.0
+                                &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv6Receive.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    case OID_GEN_MAC_OPTIONS:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                XENNET_MAC_OPTIONS,
+                                &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+    case OID_GEN_STATISTICS:
+        BytesNeeded = sizeof(NDIS_STATISTICS_INFO);
+        ndisStatus = AdapterQueryGeneralStatistics(Adapter,
+                                                   
(PNDIS_STATISTICS_INFO)Buffer,
+                                                   BufferLength,
+                                                   &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv6Receive.TcpChecksum = 1;
-    Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
+    case OID_802_3_MULTICAST_LIST:
+        ndisStatus = AdapterQueryMulticastList(Adapter,
+                                               Buffer,
+                                               BufferLength,
+                                               &BytesNeeded,
+                                               &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv6Receive.UdpChecksum = 1;
+    case OID_802_3_PERMANENT_ADDRESS:
+        XENVIF_VIF(MacQueryPermanentAddress,
+                    &Adapter->VifInterface,
+                    &EthernetAddress);
+        BytesNeeded = sizeof(ETHERNET_ADDRESS);
+        ndisStatus = __CopyBuffer(Buffer,
+                                  BufferLength,
+                                  &EthernetAddress,
+                                  BytesNeeded,
+                                  &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv4Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    case OID_802_3_CURRENT_ADDRESS:
+        XENVIF_VIF(MacQueryCurrentAddress,
+                    &Adapter->VifInterface,
+                    &EthernetAddress);
+        BytesNeeded = sizeof(ETHERNET_ADDRESS);
+        ndisStatus = __CopyBuffer(Buffer,
+                                  BufferLength,
+                                  &EthernetAddress,
+                                  BytesNeeded,
+                                  &BytesWritten);
+        break;
+
+    case OID_GEN_MAXIMUM_FRAME_SIZE:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Adapter->MaximumFrameSize -
+                                    sizeof(ETHERNET_TAGGED_HEADER),
+                                &BytesWritten);
+        break;
+
+    case OID_GEN_MAXIMUM_TOTAL_SIZE:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Adapter->MaximumFrameSize -
+                                    sizeof(ETHERNET_TAGGED_HEADER) +
+                                    sizeof (ETHERNET_UNTAGGED_HEADER),
+                                &BytesWritten);
+        break;
+
+    case OID_GEN_CURRENT_LOOKAHEAD:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Adapter->CurrentLookahead,
+                                &BytesWritten);
+        break;
+
+    case OID_GEN_VENDOR_ID:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                0x5853,
+                                &BytesWritten);
+        break;
+
+    case OID_GEN_LINK_SPEED:
+        XENVIF_VIF(MacQueryState,
+                   &Adapter->VifInterface,
+                   NULL,
+                   &Value64,
+                   NULL);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)(Value64 / 100),
+                                &BytesWritten);
+        break;
+
+    case OID_GEN_MEDIA_CONNECT_STATUS:
+        XENVIF_VIF(MacQueryState,
+                    &Adapter->VifInterface,
+                    (PNET_IF_MEDIA_CONNECT_STATE)&Value32,
+                    NULL,
+                    NULL);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Value32,
+                                &BytesWritten);
+        break;
+
+    case OID_GEN_MAXIMUM_SEND_PACKETS:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                16,
+                                &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion4HeaderChecksum) {
-        Supported.Checksum.IPv4Transmit.IpChecksum = 1;
-        Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
-    }
+    case OID_GEN_CURRENT_PACKET_FILTER:
+        AdapterGetPacketFilter(Adapter, &Value32);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Value32,
+                                &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion4TcpChecksum) {
-        Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
-        Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
-    }
+    case OID_GEN_XMIT_OK:
+        AdapterGetXmitOk(Adapter, &Value64);
+        BytesNeeded = sizeof(ULONG64);
+        ndisStatus = __SetUlong64(Buffer,
+                                  BufferLength,
+                                  Value64,
+                                  &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion4UdpChecksum)
-        Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
+    case OID_GEN_RCV_OK:
+        AdapterGetRcvOk(Adapter, &Value64);
+        BytesNeeded = sizeof(ULONG64);
+        ndisStatus = __SetUlong64(Buffer,
+                                  BufferLength,
+                                  Value64,
+                                  &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv6Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+    case OID_GEN_XMIT_ERROR:
+        AdapterGetXmitError(Adapter, &Value32);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Value32,
+                                &BytesWritten);
+        break;
 
-    Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+    case OID_GEN_RCV_ERROR:
+        AdapterGetRcvError(Adapter, &Value32);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                Value32,
+                                &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion6TcpChecksum) {
-        Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
-        Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
-    }
+    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:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                0,
+                                &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion6UdpChecksum)
-        Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
+    case OID_802_3_MAXIMUM_LIST_SIZE:
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                32,
+                                &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion4LargePacket) {
-        XENVIF_VIF(TransmitterQueryLargePacketSize,
+    case OID_GEN_DIRECTED_BYTES_XMIT:
+        XENVIF_VIF(QueryStatistic,
                    &Adapter->VifInterface,
-                   4,
-                   &Supported.LsoV2.IPv4.MaxOffLoadSize);
-        Supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
-        Supported.LsoV2.IPv4.MinSegmentCount = 2;
-    }
+                   XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (Options.OffloadIpVersion6LargePacket) {
-        XENVIF_VIF(TransmitterQueryLargePacketSize,
+    case OID_GEN_DIRECTED_FRAMES_XMIT:
+        XENVIF_VIF(QueryStatistic,
                    &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;
-    }
-
-    Default = Supported;
+                   XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.ipv4_csum & 2))
-        Default.Checksum.IPv4Receive.IpChecksum = 0;
+    case OID_GEN_MULTICAST_BYTES_XMIT:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.tcpv4_csum & 2))
-        Default.Checksum.IPv4Receive.TcpChecksum = 0;
+    case OID_GEN_MULTICAST_FRAMES_XMIT:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.udpv4_csum & 2))
-        Default.Checksum.IPv4Receive.UdpChecksum = 0;
+    case OID_GEN_BROADCAST_BYTES_XMIT:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.tcpv6_csum & 2))
-        Default.Checksum.IPv6Receive.TcpChecksum = 0;
+    case OID_GEN_BROADCAST_FRAMES_XMIT:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.udpv6_csum & 2))
-        Default.Checksum.IPv6Receive.UdpChecksum = 0;
+    case OID_GEN_DIRECTED_BYTES_RCV:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_RECEIVER_UNICAST_OCTETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.ipv4_csum & 1))
-        Default.Checksum.IPv4Transmit.IpChecksum = 0;
+    case OID_GEN_DIRECTED_FRAMES_RCV:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_RECEIVER_UNICAST_PACKETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.tcpv4_csum & 1))
-        Default.Checksum.IPv4Transmit.TcpChecksum = 0;
+    case OID_GEN_MULTICAST_BYTES_RCV:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_RECEIVER_MULTICAST_OCTETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.udpv4_csum & 1))
-        Default.Checksum.IPv4Transmit.UdpChecksum = 0;
+    case OID_GEN_MULTICAST_FRAMES_RCV:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_RECEIVER_MULTICAST_PACKETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.tcpv6_csum & 1))
-        Default.Checksum.IPv6Transmit.TcpChecksum = 0;
+    case OID_GEN_BROADCAST_BYTES_RCV:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_RECEIVER_BROADCAST_OCTETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.udpv6_csum & 1))
-        Default.Checksum.IPv6Transmit.UdpChecksum = 0;
+    case OID_GEN_BROADCAST_FRAMES_RCV:
+        XENVIF_VIF(QueryStatistic,
+                   &Adapter->VifInterface,
+                   XENVIF_RECEIVER_BROADCAST_PACKETS,
+                   &Value64);
+        BytesNeeded = sizeof(ULONG);
+        ndisStatus = __SetUlong(Buffer,
+                                BufferLength,
+                                (ULONG)Value64,
+                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.lsov4)) {
-        Default.LsoV2.IPv4.MaxOffLoadSize = 0;
-        Default.LsoV2.IPv4.MinSegmentCount = 0;
-    }
+    case OID_GEN_INTERRUPT_MODERATION:
+        BytesNeeded = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
+        ndisStatus = AdapterInterruptModeration(Adapter,
+                                                
(PNDIS_INTERRUPT_MODERATION_PARAMETERS)Buffer,
+                                                BufferLength,
+                                                &BytesWritten);
+        break;
 
-    if (!(Adapter->Properties.lsov6)) {
-        Default.LsoV2.IPv6.MaxOffLoadSize = 0;
-        Default.LsoV2.IPv6.MinSegmentCount = 0;
-    }
+    case OID_IP4_OFFLOAD_STATS:
+    case OID_IP6_OFFLOAD_STATS:
+    case OID_GEN_SUPPORTED_GUIDS:
+        // 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:
+        // ignore these common unwanted OIDs
+       case OID_GEN_INIT_TIME_MS:
+       case OID_GEN_RESET_COUNTS:
+       case OID_GEN_MEDIA_SENSE_COUNTS:
+        Warn = FALSE;
+        /*FALLTHRU*/
+    default:
+        if (Warn)
+            Warning("UNSUPPORTED OID %08x\n", 
Request->DATA.QUERY_INFORMATION.Oid);
 
-    if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof (NDIS_OFFLOAD))) {
-        Adapter->Offload = Default;
-        DISPLAY_OFFLOAD(Default);
+        ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+        break;
     }
 
-    RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));
-    Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
-    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
-    Attribs.Header.Size = sizeof(Attribs);
-    Attribs.DefaultOffloadConfiguration = &Default;
-    Attribs.HardwareOffloadCapabilities = &Supported;
+    Request->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
+    Request->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
 
-    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
     return ndisStatus;
 }
 
-static NDIS_STATUS
-AdapterSetHeaderDataSplitAttributes(
-    IN  PXENNET_ADAPTER                                 Adapter
+static NTSTATUS
+__QueryInterface(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  const GUID      *Guid,
+    IN  ULONG           Version,
+    OUT PINTERFACE      Interface,
+    IN  ULONG           Size,
+    IN  BOOLEAN         Optional
     )
 {
-    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES    Attribs;
-    NDIS_HD_SPLIT_ATTRIBUTES                            Split;
-    NDIS_STATUS                                         NdisStatus;
-
-    RtlZeroMemory(&Attribs, sizeof(Attribs));
+    KEVENT              Event;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
 
-    Attribs.Header.Type = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
-    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
-    Attribs.Header.Size = 
NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
 
-    RtlZeroMemory(&Split, sizeof(Split));
+    KeInitializeEvent(&Event, NotificationEvent, FALSE);
+    RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
 
-    Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
-    Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
-    Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
-    Split.HardwareCapabilities =
-        NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT |
-        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |
-        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |
-        NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
+    Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+                                       DeviceObject,
+                                       NULL,
+                                       0,
+                                       NULL,
+                                       &Event,
+                                       &StatusBlock);
 
-    if (Adapter->Properties.HeaderDataSplit != 0)
-        Split.CurrentCapabilities = Split.HardwareCapabilities;
+    status = STATUS_UNSUCCESSFUL;
+    if (Irp == NULL)
+        goto fail1;
 
-    Attribs.HDSplitAttributes = &Split;
+    StackLocation = IoGetNextIrpStackLocation(Irp);
+    StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
 
-    NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
-                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
-    if (NdisStatus != NDIS_STATUS_SUCCESS)
-        goto fail1;
+    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
+    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
+    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
+    StackLocation->Parameters.QueryInterface.Interface = Interface;
 
-    if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {
-        ASSERT(Split.CurrentCapabilities & 
NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT);
+    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
 
-        Info("BackfillSize = %u\n", Split.BackfillSize);
-        Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize);
+    status = IoCallDriver(DeviceObject, Irp);
+    if (status == STATUS_PENDING) {
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
+        status = StatusBlock.Status;
+    }
 
-        XENVIF_VIF(ReceiverSetBackfillSize,
-                   &Adapter->VifInterface,
-                   Split.BackfillSize);
+    if (!NT_SUCCESS(status)) {
+        if (status == STATUS_NOT_SUPPORTED && Optional)
+            goto done;
 
-        ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize);
+        goto fail2;
     }
 
-    return NDIS_STATUS_SUCCESS;
+done:
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
 
 fail1:
-    Error("fail1 (%08x)\n", NdisStatus);
+    Error("fail1 (%08x)\n", status);
 
-    return NdisStatus;
+    return status;
 }
 
-static FORCEINLINE PVOID
-__AdapterAllocate(
-    IN  ULONG   Length
-    )
-{
-    return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
-}
+#pragma prefast(push)
+#pragma prefast(disable:6102)
 
-static FORCEINLINE VOID
-__AdapterFree(
-    IN  PVOID   Buffer
-    )
-{
-    __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
-}
+#define READ_PROPERTY(field, name, defaultval, handle)  \
+    do {                                                \
+        NDIS_STATUS                     _Status;        \
+        NDIS_STRING                     _Value;         \
+        PNDIS_CONFIGURATION_PARAMETER   _Data;          \
+        RtlInitUnicodeString(&_Value, name);            \
+        NdisReadConfiguration(&_Status, &_Data, handle, \
+                        &_Value, NdisParameterInteger); \
+        if (_Status == NDIS_STATUS_SUCCESS)             \
+            field = _Data->ParameterData.IntegerData;   \
+        else                                            \
+            field = defaultval;                         \
+    } while (FALSE);
 
-static FORCEINLINE PANSI_STRING
-__AdapterMultiSzToUpcaseAnsi(
-    IN  PCHAR       Buffer
+static NDIS_STATUS
+AdapterGetAdvancedSettings(
+    IN  PXENNET_ADAPTER Adapter
     )
 {
-    PANSI_STRING    Ansi;
-    LONG            Index;
-    LONG            Count;
-    NTSTATUS        status;
-
-    Index = 0;
-    Count = 0;
-    for (;;) {
-        if (Buffer[Index] == '\0') {
-            Count++;
-            Index++;
-
-            // Check for double NUL
-            if (Buffer[Index] == '\0')
-                break;
-        } else {
-            Buffer[Index] = (CHAR)toupper(Buffer[Index]);
-            Index++;
-        }
-    }
+    NDIS_CONFIGURATION_OBJECT   Config;
+    NDIS_HANDLE                 Handle;
+    NDIS_STATUS                 ndisStatus;
 
-    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
+    RtlZeroMemory(&Config, sizeof(NDIS_CONFIGURATION_OBJECT));
+    Config.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
+    Config.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
+    Config.Header.Size = sizeof(NDIS_CONFIGURATION_OBJECT);
+    Config.NdisHandle = Adapter->NdisAdapterHandle;
+    Config.Flags = 0;
 
-    status = STATUS_NO_MEMORY;
-    if (Ansi == NULL)
+    ndisStatus = NdisOpenConfigurationEx(&Config, &Handle);
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
         goto fail1;
 
-    for (Index = 0; Index < Count; Index++) {
-        ULONG   Length;
-
-        Length = (ULONG)strlen(Buffer);
-        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
-        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
-
-        status = STATUS_NO_MEMORY;
-        if (Ansi[Index].Buffer == NULL)
-            goto fail2;
-
-        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
-        Ansi[Index].Length = (USHORT)Length;
-
-        Buffer += Length + 1;
-    }
-
-    return Ansi;
-
-fail2:
-    Error("fail2\n");
+    READ_PROPERTY(Adapter->Properties.ipv4_csum, L"*IPChecksumOffloadIPv4", 3, 
Handle);
+    READ_PROPERTY(Adapter->Properties.tcpv4_csum, L"*TCPChecksumOffloadIPv4", 
3, Handle);
+    READ_PROPERTY(Adapter->Properties.udpv4_csum, L"*UDPChecksumOffloadIPv4", 
3, Handle);
+    READ_PROPERTY(Adapter->Properties.tcpv6_csum, L"*TCPChecksumOffloadIPv6", 
3, Handle);
+    READ_PROPERTY(Adapter->Properties.udpv6_csum, L"*UDPChecksumOffloadIPv6", 
3, Handle);
+    READ_PROPERTY(Adapter->Properties.lsov4, L"*LSOv2IPv4", 1, Handle);
+    READ_PROPERTY(Adapter->Properties.lsov6, L"*LSOv2IPv6", 1, Handle);
+    READ_PROPERTY(Adapter->Properties.lrov4, L"LROIPv4", 1, Handle);
+    READ_PROPERTY(Adapter->Properties.lrov6, L"LROIPv6", 1, Handle);
+    READ_PROPERTY(Adapter->Properties.need_csum_value, L"NeedChecksumValue", 
1, Handle);
+    READ_PROPERTY(Adapter->Properties.HeaderDataSplit, L"*HeaderDataSplit", 1, 
Handle);
 
-    while (--Index >= 0)
-        __AdapterFree(Ansi[Index].Buffer);
+    NdisCloseConfiguration(Handle);
 
-    __AdapterFree(Ansi);
+    return NDIS_STATUS_SUCCESS;
 
 fail1:
-    Error("fail1 (%08x)\n", status);
-
-    return NULL;
+    return NDIS_STATUS_FAILURE;
 }
 
-static FORCEINLINE VOID
-__AdapterFreeAnsi(
-    IN  PANSI_STRING    Ansi
+#undef READ_PROPERTY
+
+#pragma prefast(pop)
+
+static NDIS_STATUS
+AdapterSetRegistrationAttributes(
+    IN  PXENNET_ADAPTER Adapter
     )
 {
-    ULONG               Index;
+    NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES   Attribs;
+    NDIS_STATUS                                     ndisStatus;
+
+    RtlZeroMemory(&Attribs, 
sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
+    Attribs.Header.Type = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
+    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
+    Attribs.Header.Size = 
sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
+    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;
 
-    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
-        __AdapterFree(Ansi[Index].Buffer);
+    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
 
-    __AdapterFree(Ansi);
+    return ndisStatus;
 }
 
-static FORCEINLINE BOOLEAN
-__AdapterMatchDistribution(
-    IN  PXENNET_ADAPTER Adapter,
-    IN  PCHAR           Buffer
+static NDIS_STATUS
+AdapterSetGeneralAttributes(
+    IN  PXENNET_ADAPTER Adapter
     )
 {
-    PCHAR               Vendor;
-    PCHAR               Product;
-    PCHAR               Context;
-    const CHAR          *Text;
-    BOOLEAN             Match;
-    ULONG               Index;
-    NTSTATUS            status;
+    NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES    Attribs;
+    NDIS_STATUS                                 ndisStatus;
 
-    UNREFERENCED_PARAMETER(Adapter);
+    RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
+    Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
+    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
+    Attribs.Header.Size = sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
+    Attribs.MediaType = XENNET_MEDIA_TYPE;
 
-    status = STATUS_INVALID_PARAMETER;
+    XENVIF_VIF(MacQueryMaximumFrameSize,
+               &Adapter->VifInterface,
+               (PULONG)&Adapter->MaximumFrameSize);
 
-    Vendor = __strtok_r(Buffer, " ", &Context);
-    if (Vendor == NULL)
-        goto fail1;
+    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;
 
-    Product = __strtok_r(NULL, " ", &Context);
-    if (Product == NULL)
-        goto fail2;
+    XENVIF_VIF(MacQueryPermanentAddress,
+               &Adapter->VifInterface,
+               (PETHERNET_ADDRESS)&Attribs.PermanentMacAddress);
+    XENVIF_VIF(MacQueryCurrentAddress,
+               &Adapter->VifInterface,
+               (PETHERNET_ADDRESS)&Attribs.CurrentMacAddress);
 
-    Match = TRUE;
+    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);
 
-    Text = VENDOR_NAME_STR;
+    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
 
-    for (Index = 0; Text[Index] != 0; Index++) {
-        if (!isalnum((UCHAR)Text[Index])) {
-            if (Vendor[Index] != '_') {
-                Match = FALSE;
-                break;
-            }
-        } else {
-            if (Vendor[Index] != Text[Index]) {
-                Match = FALSE;
-                break;
-            }
-        }
-    }
+    return ndisStatus;
+}
 
-    Text = "XENNET";
+static NDIS_STATUS
+AdapterSetOffloadAttributes(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES    Attribs;
+    XENVIF_VIF_OFFLOAD_OPTIONS                  Options;
+    PXENVIF_VIF_OFFLOAD_OPTIONS                 RxOptions;
+    PXENVIF_VIF_OFFLOAD_OPTIONS                 TxOptions;
+    NDIS_OFFLOAD                                Default;
+    NDIS_OFFLOAD                                Supported;
+    NDIS_STATUS                                 ndisStatus;
 
-    if (_stricmp(Product, Text) != 0)
-        Match = FALSE;
+    TxOptions = TransmitterOffloadOptions(Adapter->Transmitter);
+    RxOptions = ReceiverOffloadOptions(Adapter->Receiver);
 
-    return Match;
+    TxOptions->Value = 0;
+    TxOptions->OffloadTagManipulation = 1;
 
-fail2:
-    Error("fail2\n");
+    RxOptions->Value = 0;
+    RxOptions->OffloadTagManipulation = 1;
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+    if (Adapter->Properties.need_csum_value)
+        RxOptions->NeedChecksumValue = 1;
 
-    return FALSE;
-}
+    if (Adapter->Properties.lrov4) {
+        RxOptions->OffloadIpVersion4LargePacket = 1;
+        RxOptions->NeedLargePacketSplit = 1;
+    }
 
-static FORCEINLINE VOID
-__AdapterClearDistribution(
-    IN  PXENNET_ADAPTER Adapter
-    )
-{
-    PCHAR               Buffer;
-    PANSI_STRING        Distributions;
-    ULONG               Index;
-    NTSTATUS            status;
+    if (Adapter->Properties.lrov6) {
+        RxOptions->OffloadIpVersion6LargePacket = 1;
+        RxOptions->NeedLargePacketSplit = 1;
+    }
 
-    Trace("====>\n");
+    XENVIF_VIF(ReceiverSetOffloadOptions,
+               &Adapter->VifInterface,
+               *RxOptions);
 
-    status = XENBUS_STORE(Directory,
-                          &Adapter->StoreInterface,
-                          NULL,
-                          NULL,
-                          "drivers",
-                          &Buffer);
-    if (NT_SUCCESS(status)) {
-        Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
+    XENVIF_VIF(TransmitterQueryOffloadOptions,
+               &Adapter->VifInterface,
+               &Options);
 
-        XENBUS_STORE(Free,
-                     &Adapter->StoreInterface,
-                     Buffer);
-    } else {
-        Distributions = NULL;
-    }
+    RtlZeroMemory(&Supported, sizeof(NDIS_OFFLOAD));
+    Supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
+    Supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
+    Supported.Header.Size = sizeof(NDIS_OFFLOAD);
 
-    if (Distributions == NULL)
-        goto done;
+    Supported.Checksum.IPv4Receive.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
 
-    for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
-        PANSI_STRING    Distribution = &Distributions[Index];
+    Supported.Checksum.IPv4Receive.IpChecksum = 1;
+    Supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
 
-        status = XENBUS_STORE(Read,
-                              &Adapter->StoreInterface,
-                              NULL,
-                              "drivers",
-                              Distribution->Buffer,
-                              &Buffer);
-        if (!NT_SUCCESS(status))
-            continue;
+    Supported.Checksum.IPv4Receive.TcpChecksum = 1;
+    Supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
 
-        if (__AdapterMatchDistribution(Adapter, Buffer))
-            (VOID) XENBUS_STORE(Remove,
-                                &Adapter->StoreInterface,
-                                NULL,
-                                "drivers",
-                                Distribution->Buffer);
+    Supported.Checksum.IPv4Receive.UdpChecksum = 1;
 
-        XENBUS_STORE(Free,
-                     &Adapter->StoreInterface,
-                     Buffer);
-    }
+    Supported.Checksum.IPv6Receive.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
 
-    __AdapterFreeAnsi(Distributions);
+    Supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
 
-done:
-    Trace("<====\n");
-}
+    Supported.Checksum.IPv6Receive.TcpChecksum = 1;
+    Supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
 
-#define MAXIMUM_INDEX   255
+    Supported.Checksum.IPv6Receive.UdpChecksum = 1;
 
-static FORCEINLINE NTSTATUS
-__AdapterSetDistribution(
-    IN  PXENNET_ADAPTER Adapter
-    )
-{
-    ULONG               Index;
-    CHAR                Distribution[MAXNAMELEN];
-    CHAR                Vendor[MAXNAMELEN];
-    const CHAR          *Product;
-    NTSTATUS            status;
+    Supported.Checksum.IPv4Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
 
-    Trace("====>\n");
+    if (Options.OffloadIpVersion4HeaderChecksum) {
+        Supported.Checksum.IPv4Transmit.IpChecksum = 1;
+        Supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
+    }
 
-    Index = 0;
-    while (Index <= MAXIMUM_INDEX) {
-        PCHAR   Buffer;
+    if (Options.OffloadIpVersion4TcpChecksum) {
+        Supported.Checksum.IPv4Transmit.TcpChecksum = 1;
+        Supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+    }
 
-        status = RtlStringCbPrintfA(Distribution,
-                                    MAXNAMELEN,
-                                    "%u",
-                                    Index);
-        ASSERT(NT_SUCCESS(status));
+    if (Options.OffloadIpVersion4UdpChecksum)
+        Supported.Checksum.IPv4Transmit.UdpChecksum = 1;
 
-        status = XENBUS_STORE(Read,
-                              &Adapter->StoreInterface,
-                              NULL,
-                              "drivers",
-                              Distribution,
-                              &Buffer);
-        if (!NT_SUCCESS(status)) {
-            if (status == STATUS_OBJECT_NAME_NOT_FOUND)
-                goto update;
+    Supported.Checksum.IPv6Transmit.Encapsulation = 
NDIS_ENCAPSULATION_IEEE_802_3;
+
+    Supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
 
-            goto fail1;
-        }
+    if (Options.OffloadIpVersion6TcpChecksum) {
+        Supported.Checksum.IPv6Transmit.TcpChecksum = 1;
+        Supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+    }
 
-        XENBUS_STORE(Free,
-                     &Adapter->StoreInterface,
-                     Buffer);
+    if (Options.OffloadIpVersion6UdpChecksum)
+        Supported.Checksum.IPv6Transmit.UdpChecksum = 1;
 
-        Index++;
+    if (Options.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;
     }
 
-    status = STATUS_UNSUCCESSFUL;
-    goto fail2;
+    if (Options.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;
+    }
 
-update:
-    status = RtlStringCbPrintfA(Vendor,
-                                MAXNAMELEN,
-                                "%s",
-                                VENDOR_NAME_STR);
-    ASSERT(NT_SUCCESS(status));
+    Default = Supported;
 
-    for (Index  = 0; Vendor[Index] != '\0'; Index++)
-        if (!isalnum((UCHAR)Vendor[Index]))
-            Vendor[Index] = '_';
+    if (!(Adapter->Properties.ipv4_csum & 2))
+        Default.Checksum.IPv4Receive.IpChecksum = 0;
 
-    Product = "XENNET";
+    if (!(Adapter->Properties.tcpv4_csum & 2))
+        Default.Checksum.IPv4Receive.TcpChecksum = 0;
 
-#if DBG
-#define ATTRIBUTES   "(DEBUG)"
-#else
-#define ATTRIBUTES   ""
-#endif
+    if (!(Adapter->Properties.udpv4_csum & 2))
+        Default.Checksum.IPv4Receive.UdpChecksum = 0;
 
-    (VOID) XENBUS_STORE(Printf,
-                        &Adapter->StoreInterface,
-                        NULL,
-                        "drivers",
-                        Distribution,
-                        "%s %s %u.%u.%u %s",
-                        Vendor,
-                        Product,
-                        MAJOR_VERSION,
-                        MINOR_VERSION,
-                        MICRO_VERSION,
-                        ATTRIBUTES
-                        );
+    if (!(Adapter->Properties.tcpv6_csum & 2))
+        Default.Checksum.IPv6Receive.TcpChecksum = 0;
 
-#undef  ATTRIBUTES
+    if (!(Adapter->Properties.udpv6_csum & 2))
+        Default.Checksum.IPv6Receive.UdpChecksum = 0;
 
-    Trace("<====\n");
-    return STATUS_SUCCESS;
+    if (!(Adapter->Properties.ipv4_csum & 1))
+        Default.Checksum.IPv4Transmit.IpChecksum = 0;
 
-fail2:
-    Error("fail2\n");
+    if (!(Adapter->Properties.tcpv4_csum & 1))
+        Default.Checksum.IPv4Transmit.TcpChecksum = 0;
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+    if (!(Adapter->Properties.udpv4_csum & 1))
+        Default.Checksum.IPv4Transmit.UdpChecksum = 0;
 
-    return status;
-}
+    if (!(Adapter->Properties.tcpv6_csum & 1))
+        Default.Checksum.IPv6Transmit.TcpChecksum = 0;
 
-static DECLSPEC_NOINLINE VOID
-AdapterSuspendCallbackLate(
-    IN  PVOID       Argument
-    )
-{
-    PXENNET_ADAPTER Adapter = Argument;
+    if (!(Adapter->Properties.udpv6_csum & 1))
+        Default.Checksum.IPv6Transmit.UdpChecksum = 0;
 
-    (VOID) __AdapterSetDistribution(Adapter);
-}
+    if (!(Adapter->Properties.lsov4)) {
+        Default.LsoV2.IPv4.MaxOffLoadSize = 0;
+        Default.LsoV2.IPv4.MinSegmentCount = 0;
+    }
 
-static NTSTATUS
-AdapterSetDistribution(
-    IN  PXENNET_ADAPTER Adapter
-    )
-{
-    LONG                Count;
-    NTSTATUS            status;
+    if (!(Adapter->Properties.lsov6)) {
+        Default.LsoV2.IPv6.MaxOffLoadSize = 0;
+        Default.LsoV2.IPv6.MinSegmentCount = 0;
+    }
 
-    Trace("====>\n");
+    if (!RtlEqualMemory(&Adapter->Offload, &Default, sizeof (NDIS_OFFLOAD))) {
+        Adapter->Offload = Default;
+        DISPLAY_OFFLOAD(Default);
+    }
 
-    Count = InterlockedIncrement(&AdapterCount);
-    ASSERT(Count != 0);
+    RtlZeroMemory(&Attribs, sizeof(NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES));
+    Attribs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
+    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
+    Attribs.Header.Size = sizeof(Attribs);
+    Attribs.DefaultOffloadConfiguration = &Default;
+    Attribs.HardwareOffloadCapabilities = &Supported;
 
-    if (Count != 1)
-        goto done;
+    ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+    return ndisStatus;
+}
 
-    status = __AdapterSetDistribution(Adapter);
-    if (!NT_SUCCESS(status))
-        goto fail1;
+static NDIS_STATUS
+AdapterSetHeaderDataSplitAttributes(
+    IN  PXENNET_ADAPTER                                 Adapter
+    )
+{
+    NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES    Attribs;
+    NDIS_HD_SPLIT_ATTRIBUTES                            Split;
+    NDIS_STATUS                                         NdisStatus;
 
-    status = XENBUS_SUSPEND(Register,
-                            &Adapter->SuspendInterface,
-                            SUSPEND_CALLBACK_LATE,
-                            AdapterSuspendCallbackLate,
-                            Adapter,
-                            &Adapter->SuspendCallbackLate);
-    if (!NT_SUCCESS(status))
-        goto fail2;
+    RtlZeroMemory(&Attribs, sizeof(Attribs));
 
-done:
-    Trace("<====\n");
-    return STATUS_SUCCESS;
+    Attribs.Header.Type = 
NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES;
+    Attribs.Header.Revision = 
NDIS_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
+    Attribs.Header.Size = 
NDIS_SIZEOF_MINIPORT_ADAPTER_HARDWARE_ASSIST_ATTRIBUTES_REVISION_1;
 
-fail2:
-    Error("fail2\n");
+    RtlZeroMemory(&Split, sizeof(Split));
 
-    __AdapterClearDistribution(Adapter);
+    Split.Header.Type = NDIS_OBJECT_TYPE_HD_SPLIT_ATTRIBUTES;
+    Split.Header.Revision = NDIS_HD_SPLIT_ATTRIBUTES_REVISION_1;
+    Split.Header.Size = NDIS_SIZEOF_HD_SPLIT_ATTRIBUTES_REVISION_1;
+    Split.HardwareCapabilities =
+        NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT |
+        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV4_OPTIONS |
+        NDIS_HD_SPLIT_CAPS_SUPPORTS_IPV6_EXTENSION_HEADERS |
+        NDIS_HD_SPLIT_CAPS_SUPPORTS_TCP_OPTIONS;
 
-fail1:
-    Error("fail1 (%08x)\n", status);
+    if (Adapter->Properties.HeaderDataSplit != 0)
+        Split.CurrentCapabilities = Split.HardwareCapabilities;
 
-    return status;
-}
+    Attribs.HDSplitAttributes = &Split;
 
-static VOID
-AdapterClearDistribution(
-    IN  PXENNET_ADAPTER Adapter
-    )
-{
-    LONG                Count;
+    NdisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+                                            
(PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&Attribs);
+    if (NdisStatus != NDIS_STATUS_SUCCESS)
+        goto fail1;
 
-    Trace("====>\n");
+    if (Split.HDSplitFlags == NDIS_HD_SPLIT_ENABLE_HEADER_DATA_SPLIT) {
+        ASSERT(Split.CurrentCapabilities & 
NDIS_HD_SPLIT_CAPS_SUPPORTS_HEADER_DATA_SPLIT);
 
-    Count = InterlockedDecrement(&AdapterCount);
+        Info("BackfillSize = %u\n", Split.BackfillSize);
+        Info("MaxHeaderSize = %u\n", Split.MaxHeaderSize);
 
-    if (Count != 0)
-        goto done;
+        XENVIF_VIF(ReceiverSetBackfillSize,
+                   &Adapter->VifInterface,
+                   Split.BackfillSize);
 
-    XENBUS_SUSPEND(Deregister,
-                   &Adapter->SuspendInterface,
-                   Adapter->SuspendCallbackLate);
-    Adapter->SuspendCallbackLate = NULL;
+        ReceiverSplitHeaderData(Adapter->Receiver, Split.MaxHeaderSize);
+    }
 
-    __AdapterClearDistribution(Adapter);
+    return NDIS_STATUS_SUCCESS;
 
-done:
-    Trace("<====\n");
+fail1:
+    Error("fail1 (%08x)\n", NdisStatus);
+
+    return NdisStatus;
 }
 
 NDIS_STATUS
@@ -2715,52 +2810,35 @@ AdapterInitialize(
     if (!NT_SUCCESS(status))
         goto fail6;
 
-    status = XENBUS_CACHE(Acquire,
-                          &(*Adapter)->CacheInterface);
-    if (!NT_SUCCESS(status))
-        goto fail7;
-
-    status = XENBUS_STORE(Acquire,
-                          &(*Adapter)->StoreInterface);
-    if (!NT_SUCCESS(status))
-        goto fail8;
-
-    status = XENBUS_SUSPEND(Acquire,
-                            &(*Adapter)->SuspendInterface);
-    if (!NT_SUCCESS(status))
-        goto fail9;
-
-    (VOID) AdapterSetDistribution(*Adapter);
-
     (*Adapter)->NdisAdapterHandle = Handle;
 
     ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail10;
+        goto fail7;
 
     ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail11;
+        goto fail8;
 
     ndisStatus = AdapterGetAdvancedSettings(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail12;
+        goto fail9;
 
     ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail13;
+        goto fail10;
 
     ndisStatus = AdapterSetGeneralAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail14;
+        goto fail11;
 
     ndisStatus = AdapterSetOffloadAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail15;
+        goto fail12;
 
     ndisStatus = AdapterSetHeaderDataSplitAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail16;
+        goto fail13;
 
     RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
     Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
@@ -2777,43 +2855,23 @@ AdapterInitialize(
     if (ndisStatus != NDIS_STATUS_SUCCESS)
         (*Adapter)->NdisDmaHandle = NULL;
 
-    ndisStatus = AdapterEnable(*Adapter);
-    if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail17;
-
     return NDIS_STATUS_SUCCESS;
 
-fail17:
-    if ((*Adapter)->NdisDmaHandle)
-        NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
-    (*Adapter)->NdisDmaHandle = NULL;
-
-fail16:
-fail15:
-fail14:
 fail13:
 fail12:
+fail11:
+fail10:
+fail9:
     ReceiverTeardown((*Adapter)->Receiver);
     (*Adapter)->Receiver = NULL;
-fail11:
 
+fail8:
     TransmitterTeardown((*Adapter)->Transmitter);
     (*Adapter)->Transmitter = NULL;
 
-fail10:
+fail7:
     (*Adapter)->NdisAdapterHandle = NULL;
 
-    AdapterClearDistribution(*Adapter);
-
-    XENBUS_SUSPEND(Release, &(*Adapter)->SuspendInterface);
-
-fail9:
-    XENBUS_STORE(Release, &(*Adapter)->StoreInterface);
-
-fail8:
-    XENBUS_CACHE(Release, &(*Adapter)->CacheInterface);
-
-fail7:
     XENVIF_VIF(Release, &(*Adapter)->VifInterface);
 
 fail6:
@@ -2852,9 +2910,6 @@ AdapterTeardown(
 
     AdapterClearDistribution(Adapter);
 
-    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
-    XENBUS_STORE(Release, &Adapter->StoreInterface);
-    XENBUS_CACHE(Release, &Adapter->CacheInterface);
     XENVIF_VIF(Release, &Adapter->VifInterface);
 
     RtlZeroMemory(&Adapter->SuspendInterface, 
sizeof(XENBUS_SUSPEND_INTERFACE));
diff --git a/src/xennet/adapter.h b/src/xennet/adapter.h
index 3cc1d90..5b2495a 100644
--- a/src/xennet/adapter.h
+++ b/src/xennet/adapter.h
@@ -99,7 +99,7 @@ AdapterEnable(
     IN  PXENNET_ADAPTER     Adapter
     );
 
-extern BOOLEAN
+extern VOID
 AdapterDisable(
     IN  PXENNET_ADAPTER     Adapter
     );
diff --git a/src/xennet/miniport.c b/src/xennet/miniport.c
index 5500418..1883db5 100644
--- a/src/xennet/miniport.c
+++ b/src/xennet/miniport.c
@@ -66,7 +66,7 @@ MiniportInitializeEx(
     PXENNET_ADAPTER                     Adapter;
     NDIS_STATUS                         NdisStatus;
 
-    Trace("====>\n");
+    Info("====>\n");
 
     UNREFERENCED_PARAMETER(MiniportDriverContext);
     UNREFERENCED_PARAMETER(MiniportInitParameters);
@@ -75,7 +75,7 @@ MiniportInitializeEx(
     if (NdisStatus != NDIS_STATUS_SUCCESS)
         goto fail1;
 
-    Trace("<====\n");
+    Info("<====\n");
 
     return NDIS_STATUS_SUCCESS;
 
@@ -97,16 +97,14 @@ MiniportHaltEx(
 
     UNREFERENCED_PARAMETER(HaltAction);
 
-    Trace("====>\n");
+    Info("====>\n");
 
     if (Adapter == NULL)
         return;
 
-    (VOID) AdapterDisable(Adapter);
-
     AdapterTeardown(Adapter);
 
-    Trace("<====\n");
+    Info("<====\n");
 }
 
 static
@@ -131,12 +129,11 @@ MiniportPause(
 
     UNREFERENCED_PARAMETER(MiniportPauseParameters);
 
-    Trace("====>\n");
+    Info("====>\n");
 
-    if (AdapterDisable(Adapter))
-        AdapterMediaStateChange(Adapter);
+    AdapterDisable(Adapter);
 
-    Trace("<====\n");
+    Info("<====\n");
 
     return NDIS_STATUS_SUCCESS;
 }
@@ -154,11 +151,11 @@ MiniportRestart(
 
     UNREFERENCED_PARAMETER(MiniportRestartParameters);
 
-    Trace("====>\n");
+    Info("====>\n");
 
     NdisStatus = AdapterEnable(Adapter);
 
-    Trace("<====\n");
+    Info("<====\n");
 
     return NdisStatus;
 }
diff --git a/src/xennet/receiver.c b/src/xennet/receiver.c
index 17ab27f..8bfc10b 100644
--- a/src/xennet/receiver.c
+++ b/src/xennet/receiver.c
@@ -359,6 +359,24 @@ fail1:
     return status;
 }
 
+NDIS_STATUS
+ReceiverEnable (
+    IN  PXENNET_RECEIVER    Receiver
+    )
+{
+    UNREFERENCED_PARAMETER(Receiver);
+
+    return NDIS_STATUS_SUCCESS;
+}
+
+VOID
+ReceiverDisable (
+    IN  PXENNET_RECEIVER    Receiver
+    )
+{
+    UNREFERENCED_PARAMETER(Receiver);
+}
+
 VOID
 ReceiverTeardown(
     IN  PXENNET_RECEIVER    Receiver
diff --git a/src/xennet/receiver.h b/src/xennet/receiver.h
index b2cc809..33701a9 100644
--- a/src/xennet/receiver.h
+++ b/src/xennet/receiver.h
@@ -43,6 +43,16 @@ ReceiverInitialize(
     OUT PXENNET_RECEIVER    *Receiver
     );
 
+extern NDIS_STATUS
+ReceiverEnable(
+    IN  PXENNET_RECEIVER    Receiver
+    );
+
+extern VOID
+ReceiverDisable(
+    IN  PXENNET_RECEIVER    Receiver
+    );
+
 extern VOID
 ReceiverTeardown(
     IN  PXENNET_RECEIVER    Receiver
diff --git a/src/xennet/transmitter.c b/src/xennet/transmitter.c
index a617b7d..8c80c7e 100644
--- a/src/xennet/transmitter.c
+++ b/src/xennet/transmitter.c
@@ -141,16 +141,10 @@ TransmitterInitialize (
     OUT PXENNET_TRANSMITTER *Transmitter
     )
 {
-    NTSTATUS                status;
-    PXENBUS_CACHE_INTERFACE CacheInterface;
-
-    CacheInterface = AdapterGetCacheInterface(Adapter);
-
     *Transmitter = ExAllocatePoolWithTag(NonPagedPool,
                                          sizeof(XENNET_TRANSMITTER),
                                          TRANSMITTER_POOL_TAG);
 
-    status = STATUS_NO_MEMORY;
     if (*Transmitter == NULL)
         goto fail1;
 
@@ -160,6 +154,22 @@ TransmitterInitialize (
 
     KeInitializeSpinLock(&(*Transmitter)->Lock);
 
+    return NDIS_STATUS_SUCCESS;
+
+fail1:
+    return NDIS_STATUS_FAILURE;
+}
+
+NDIS_STATUS
+TransmitterEnable (
+    IN  PXENNET_TRANSMITTER Transmitter
+    )
+{
+    PXENBUS_CACHE_INTERFACE CacheInterface;
+    NTSTATUS                status;
+
+    CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
+
     status = XENBUS_CACHE(Create,
                           CacheInterface,
                           "packet_cache",
@@ -169,10 +179,10 @@ TransmitterInitialize (
                           __TransmitterPacketDtor,
                           __TransmitterPacketAcquireLock,
                           __TransmitterPacketReleaseLock,
-                          *Transmitter,
-                          &(*Transmitter)->PacketCache);
+                          Transmitter,
+                          &Transmitter->PacketCache);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail1;
 
     status = XENBUS_CACHE(Create,
                           CacheInterface,
@@ -183,27 +193,20 @@ TransmitterInitialize (
                           __TransmitterBufferDtor,
                           __TransmitterBufferAcquireLock,
                           __TransmitterBufferReleaseLock,
-                          *Transmitter,
-                          &(*Transmitter)->BufferCache);
+                          Transmitter,
+                          &Transmitter->BufferCache);
     if (!NT_SUCCESS(status))
-        goto fail3;
+        goto fail2;
 
     return NDIS_STATUS_SUCCESS;
 
-fail3:
-    XENBUS_CACHE(Destroy,
-                 CacheInterface,
-                 (*Transmitter)->PacketCache);
-    (*Transmitter)->PacketCache = NULL;
-
 fail2:
     Error("fail2\n");
 
-    RtlZeroMemory(&(*Transmitter)->Lock, sizeof(KSPIN_LOCK));
-
-    ExFreePoolWithTag(*Transmitter, TRANSMITTER_POOL_TAG);
-
-    *Transmitter = NULL;
+    XENBUS_CACHE(Destroy,
+                 CacheInterface,
+                 Transmitter->PacketCache);
+    Transmitter->PacketCache = NULL;
 
 fail1:
     Error("fail1\n (%08x)", status);
@@ -212,7 +215,7 @@ fail1:
 }
 
 VOID
-TransmitterTeardown(
+TransmitterDisable (
     IN  PXENNET_TRANSMITTER Transmitter
     )
 {
@@ -220,9 +223,6 @@ TransmitterTeardown(
 
     CacheInterface = AdapterGetCacheInterface(Transmitter->Adapter);
 
-    Transmitter->Adapter = NULL;
-    Transmitter->OffloadOptions.Value = 0;
-
     XENBUS_CACHE(Destroy,
                  CacheInterface,
                  Transmitter->BufferCache);
@@ -232,6 +232,15 @@ TransmitterTeardown(
                  CacheInterface,
                  Transmitter->PacketCache);
     Transmitter->PacketCache = NULL;
+}
+
+VOID
+TransmitterTeardown(
+    IN  PXENNET_TRANSMITTER Transmitter
+    )
+{
+    Transmitter->Adapter = NULL;
+    Transmitter->OffloadOptions.Value = 0;
 
     RtlZeroMemory(&Transmitter->Lock, sizeof(KSPIN_LOCK));
 
diff --git a/src/xennet/transmitter.h b/src/xennet/transmitter.h
index 0adebdc..363b91e 100644
--- a/src/xennet/transmitter.h
+++ b/src/xennet/transmitter.h
@@ -43,6 +43,16 @@ TransmitterInitialize(
     OUT PXENNET_TRANSMITTER *Transmitter
     );
 
+extern NDIS_STATUS
+TransmitterEnable(
+    IN  PXENNET_TRANSMITTER Transmitter
+    );
+
+extern VOID
+TransmitterDisable(
+    IN  PXENNET_TRANSMITTER Transmitter
+    );
+
 extern VOID
 TransmitterTeardown(
     IN  PXENNET_TRANSMITTER Transmitter
-- 
2.1.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®.