]> xenbits.xensource.com Git - pvdrivers/win/xennet.git/commitdiff
Implement new API version scheme
authorPaul Durrant <paul.durrant@citrix.com>
Wed, 16 Jul 2014 12:16:43 +0000 (13:16 +0100)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 14 Aug 2014 14:24:44 +0000 (15:24 +0100)
This patch changes the way APIs work in an incompatible way. (See README.md
for details).
The patch also includes a *lot* of code tidying and movement and as such
is not really suitable for review as a patch; the resulting code should
itself be reviewed.
Given the scale of the change, the major version number has been revised to
8 and other version numbers reset to zero.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
19 files changed:
CHANGELOG
README.md
build.py
include/util.h
include/vif_interface.h
proj/xennet/xennet.vcxproj
src/coinst/coinst.c
src/xennet.inf
src/xennet/adapter.c
src/xennet/adapter.h
src/xennet/assert.h
src/xennet/main.c
src/xennet/miniport.c
src/xennet/receiver.c
src/xennet/receiver.h
src/xennet/registry.c [new file with mode: 0644]
src/xennet/registry.h [new file with mode: 0644]
src/xennet/transmitter.c
src/xennet/transmitter.h

index 5609a7eefdad84b9831d56d336374d02f76f9022..ca78a6cd76a0d48195ead48332d501250f49d265 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -8,3 +8,6 @@
 7.2.0 (2013-09-27):
 * Drivers compatible with upstream Xen, QEMU and Linux dom0
 
+7.3.0 (2014-07-16):
+* Drivers with new API version scheme
+
index cb78325b7d9175361f8b43dca4f21d8dd7b43de5..d9d7273ddadb7b8bb6014d818d647162c5018276 100644 (file)
--- a/README.md
+++ b/README.md
@@ -51,6 +51,35 @@ Installing the driver
 
 See INSTALL.md
 
+API Versions
+============
+
+It is important that introduction of a new API, introduction of a new
+version of an existing API or retirement of an old version of an API is
+managed carefully to avoid incompatibilities between clients and
+providers. The general API versioning policy is described below:
+
+Each distinct set of API versions exported by a driver maps to a PDO
+revision. The DeviceID of each PDO created by the driver will specify the
+latest revision supported and all others will be contained within the
+HardwareIDs and CompatibleIDs.
+Hence, when a new version of an API is added, a new PDO revision will be
+added. When a version of an API is removed then ALL revisions that API
+version maps to will be removed.
+
+To avoid a situation where a new version of the package is installed that
+is incompatible with any child drivers that make use of the APIs, each
+child 'subscribes' to an API by writing a registry value with the version
+number of that API that they consume into a registry key under the service
+key of the providing driver. E.g. if driver 'foo' consumes version 1 of
+driver 'bar''s 'widget' API, then it will write
+HLKM/CurrentControlSet/Services/BAR/Interfaces/FOO/WIDGET with the value 1.
+The 'bar' package co-installer can then check, prior to installation of a
+new version of a driver, that it can still support all of its subscribers.
+If any of the API versions subscribed to has been removed then installation
+will be vetoed until all the subscriber drivers have been updated to use
+the newer versions of the APIs exported by the newer providing driver.
+
 Miscellaneous
 =============
 
index 1cec347b93be3c17bf7c73a57966f448afbf2871..77ac55c78d5737d456c4c845ba34ed66cec716b0 100644 (file)
--- a/build.py
+++ b/build.py
@@ -362,7 +362,7 @@ if __name__ == '__main__':
     driver = 'xennet'
 
     os.environ['MAJOR_VERSION'] = '7'
-    os.environ['MINOR_VERSION'] = '2'
+    os.environ['MINOR_VERSION'] = '3'
     os.environ['MICRO_VERSION'] = '0'
 
     if 'BUILD_NUMBER' not in os.environ.keys():
index 9b338b627cdd711e532e9451a75b1226b0028eae..c00896019c12d2446984abd3b5397fbd9292466b 100644 (file)
@@ -34,6 +34,8 @@
 
 #include <ntddk.h>
 
+#include "assert.h"
+
 #define        P2ROUNDUP(_x, _a)   \
         (-(-(_x) & -(_a)))
 
@@ -76,6 +78,32 @@ __ffs(
 #define __ffu(_mask)  \
         __ffs(~(_mask))
 
+static FORCEINLINE VOID
+__CpuId(
+    IN  ULONG   Leaf,
+    OUT PULONG  EAX OPTIONAL,
+    OUT PULONG  EBX OPTIONAL,
+    OUT PULONG  ECX OPTIONAL,
+    OUT PULONG  EDX OPTIONAL
+    )
+{
+    ULONG       Value[4] = {0};
+
+    __cpuid(Value, Leaf);
+
+    if (EAX)
+        *EAX = Value[0];
+
+    if (EBX)
+        *EBX = Value[1];
+
+    if (ECX)
+        *ECX = Value[2];
+
+    if (EDX)
+        *EDX = Value[3];
+}
+
 static FORCEINLINE LONG
 __InterlockedAdd(
     IN  LONG    *Value,
@@ -110,4 +138,206 @@ __InterlockedSubtract(
     return New;
 }
 
+typedef struct _NON_PAGED_BUFFER_HEADER {
+    SIZE_T  Length;
+    ULONG   Tag;
+} NON_PAGED_BUFFER_HEADER, *PNON_PAGED_BUFFER_HEADER;
+
+typedef struct _NON_PAGED_BUFFER_TRAILER {
+    ULONG   Tag;
+} NON_PAGED_BUFFER_TRAILER, *PNON_PAGED_BUFFER_TRAILER;
+
+static FORCEINLINE PVOID
+__AllocateNonPagedPoolWithTag(
+    IN  SIZE_T                  Length,
+    IN  ULONG                   Tag
+    )
+{
+    PUCHAR                      Buffer;
+    PNON_PAGED_BUFFER_HEADER    Header;
+    PNON_PAGED_BUFFER_TRAILER   Trailer;
+
+    ASSERT(Length != 0);
+
+    Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                   sizeof (NON_PAGED_BUFFER_HEADER) +
+                                   Length +
+                                   sizeof (NON_PAGED_BUFFER_TRAILER),
+                                   Tag);
+    if (Buffer == NULL)
+        goto done;
+
+    RtlZeroMemory(Buffer, 
+                  sizeof (NON_PAGED_BUFFER_HEADER) +
+                  Length +
+                  sizeof (NON_PAGED_BUFFER_TRAILER));
+
+    Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
+    Header->Length = Length;
+    Header->Tag = Tag;
+
+    Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
+
+    Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
+    Trailer->Tag = Tag;
+
+done:
+    return Buffer;
+}
+
+static FORCEINLINE VOID
+__FreePoolWithTag(
+    IN  PVOID                   _Buffer,
+    IN  ULONG                   Tag
+    )
+{
+    PUCHAR                      Buffer = _Buffer;
+    SIZE_T                      Length;
+    PNON_PAGED_BUFFER_HEADER    Header;
+    PNON_PAGED_BUFFER_TRAILER   Trailer;
+
+    ASSERT(Buffer != NULL);
+
+    Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
+
+    Header = (PNON_PAGED_BUFFER_HEADER)Buffer;
+    ASSERT3U(Tag, ==, Header->Tag);
+    Length = Header->Length;
+
+    Buffer += sizeof (NON_PAGED_BUFFER_HEADER);
+
+    Trailer = (PNON_PAGED_BUFFER_TRAILER)(Buffer + Length);
+    ASSERT3U(Tag, ==, Trailer->Tag);
+
+    Buffer -= sizeof (NON_PAGED_BUFFER_HEADER);
+
+    RtlFillMemory(Buffer, 
+                  sizeof (NON_PAGED_BUFFER_HEADER) +
+                  Length +
+                  sizeof (NON_PAGED_BUFFER_TRAILER),
+                  0xAA);
+
+    ExFreePoolWithTag(Buffer, Tag);
+}
+
+static FORCEINLINE PMDL
+__AllocatePage(
+    VOID
+    )
+{
+    PHYSICAL_ADDRESS    LowAddress;
+    PHYSICAL_ADDRESS    HighAddress;
+    LARGE_INTEGER       SkipBytes;
+    SIZE_T              TotalBytes;
+    PMDL                Mdl;
+    PUCHAR              MdlMappedSystemVa;
+    NTSTATUS            status;
+
+    LowAddress.QuadPart = 0ull;
+    HighAddress.QuadPart = ~0ull;
+    SkipBytes.QuadPart = 0ull;
+    TotalBytes = (SIZE_T)PAGE_SIZE;
+
+    Mdl = MmAllocatePagesForMdlEx(LowAddress,
+                                  HighAddress,
+                                  SkipBytes,
+                                  TotalBytes,
+                                  MmCached,
+                                  0);
+
+    status = STATUS_NO_MEMORY;
+    if (Mdl == NULL)
+        goto fail1;
+
+    ASSERT((Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |
+                             MDL_PARTIAL_HAS_BEEN_MAPPED |
+                             MDL_PARTIAL |
+                             MDL_PARENT_MAPPED_SYSTEM_VA |
+                             MDL_SOURCE_IS_NONPAGED_POOL |
+                             MDL_IO_SPACE)) == 0);
+
+    MdlMappedSystemVa = MmMapLockedPagesSpecifyCache(Mdl,
+                                                     KernelMode,
+                                                                            MmCached,   
+                                                                            NULL,
+                                                                            FALSE,
+                                                                            NormalPagePriority);
+
+    status = STATUS_UNSUCCESSFUL;
+    if (MdlMappedSystemVa == NULL)
+        goto fail2;
+
+    ASSERT3P(MdlMappedSystemVa, ==, Mdl->MappedSystemVa);
+
+    RtlZeroMemory(MdlMappedSystemVa, PAGE_SIZE);
+
+    return Mdl;
+
+fail2:
+    Error("fail2\n");
+
+    MmFreePagesFromMdl(Mdl);
+    ExFreePool(Mdl);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
+}
+
+static FORCEINLINE VOID
+__FreePage(
+    IN PMDL    Mdl
+    )
+{
+    PUCHAR     MdlMappedSystemVa;
+
+    ASSERT(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA);
+    MdlMappedSystemVa = Mdl->MappedSystemVa;
+
+    RtlFillMemory(MdlMappedSystemVa, PAGE_SIZE, 0xAA);
+    
+    MmUnmapLockedPages(MdlMappedSystemVa, Mdl);
+
+    MmFreePagesFromMdl(Mdl);
+}
+
+static FORCEINLINE PCHAR
+__strtok_r(
+    IN      PCHAR   Buffer,
+    IN      PCHAR   Delimiter,
+    IN OUT  PCHAR   *Context
+    )
+{
+    PCHAR           Token;
+    PCHAR           End;
+
+    if (Buffer != NULL)
+        *Context = Buffer;
+
+    Token = *Context;
+
+    if (Token == NULL)
+        return NULL;
+
+    while (*Token != L'\0' &&
+           strchr(Delimiter, *Token) != NULL)
+        Token++;
+
+    if (*Token == L'\0')
+        return NULL;
+
+    End = Token + 1;
+    while (*End != L'\0' &&
+           strchr(Delimiter, *End) == NULL)
+        End++;
+
+    if (*End != L'\0')
+        *End++ = L'\0';
+
+    *Context = End;
+
+    return Token;
+}
+
 #endif  // _UTIL_H
index d582b6a31bdb0f6c10470d779acf17ee978a2e0d..60a3e9c568bb2bba9582984f5e6259ccac0ada9a 100644 (file)
 #ifndef _XENVIF_VIF_INTERFACE_H
 #define _XENVIF_VIF_INTERFACE_H
 
+#ifndef _WINDLL
+
 #include <ifdef.h>
 #include <ethernet.h>
 
-typedef UCHAR   XENVIF_PACKET_STATUS, *PXENVIF_PACKET_STATUS;
-
-#define PACKET_STATUS_INVALID   0
-#define PACKET_PENDING          1
-#define PACKET_OK               2
-#define PACKET_DROPPED          3
-#define PACKET_ERROR            4
-
-typedef struct  _XENVIF_PACKET_HEADER {
+struct  _XENVIF_PACKET_HEADER_V1 {
     ULONG   Offset;
     ULONG   Length;
-} XENVIF_PACKET_HEADER, *PXENVIF_PACKET_HEADER;
-
-#pragma warning(push)
-#pragma warning(disable:4214)   // nonstandard extension used : bit field types other than int
-#pragma warning(disable:4201)   // nonstandard extension used : nameless struct/union
-
-typedef struct _XENVIF_PACKET_FLAGS {
-    struct {
-        ULONG   IsAFragment:1;
-        ULONG   Reserved:31;
-    };
-} XENVIF_PACKET_FLAGS, *PXENVIF_PACKET_FLAGS;
+};
 
-#pragma warning(pop)
+struct _XENVIF_PACKET_INFO_V1 {
+    ULONG                           Length;
+    USHORT                          TagControlInformation;
+    BOOLEAN                         IsAFragment;
+    struct _XENVIF_PACKET_HEADER_V1 EthernetHeader;
+    struct _XENVIF_PACKET_HEADER_V1 LLCSnapHeader;
+    struct _XENVIF_PACKET_HEADER_V1 IpHeader;
+    struct _XENVIF_PACKET_HEADER_V1 IpOptions;
+    struct _XENVIF_PACKET_HEADER_V1 TcpHeader;
+    struct _XENVIF_PACKET_HEADER_V1 TcpOptions;
+    struct _XENVIF_PACKET_HEADER_V1 UdpHeader;
+};
 
-typedef struct _XENVIF_PACKET_INFO {
-    XENVIF_PACKET_HEADER    EthernetHeader;
-    XENVIF_PACKET_HEADER    LLCSnapHeader;
-    XENVIF_PACKET_HEADER    IpHeader;
-    XENVIF_PACKET_HEADER    IpOptions;
-    XENVIF_PACKET_HEADER    TcpHeader;
-    XENVIF_PACKET_HEADER    TcpOptions;
-    XENVIF_PACKET_HEADER    UdpHeader;
-    XENVIF_PACKET_FLAGS     Flags;
-    ULONG                   Length;
-} XENVIF_PACKET_INFO, *PXENVIF_PACKET_INFO;
+typedef struct _XENVIF_PACKET_INFO_V1   XENVIF_PACKET_INFO, *PXENVIF_PACKET_INFO;
 
 #pragma warning(push)
 #pragma warning(disable:4214)   // nonstandard extension used : bit field types other than int
 #pragma warning(disable:4201)   // nonstandard extension used : nameless struct/union
 
-typedef struct _XENVIF_CHECKSUM_FLAGS {
-    struct {
-        ULONG   IpChecksumSucceeded:1;
-        ULONG   IpChecksumFailed:1;
-        ULONG   IpChecksumPresent:1;
-        ULONG   TcpChecksumSucceeded:1;
-        ULONG   TcpChecksumFailed:1;
-        ULONG   TcpChecksumPresent:1;
-        ULONG   UdpChecksumSucceeded:1;
-        ULONG   UdpChecksumFailed:1;
-        ULONG   UdpChecksumPresent:1;
-        ULONG   Reserved:23;
+struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 {
+    union {
+        struct {
+            ULONG   IpChecksumSucceeded:1;
+            ULONG   IpChecksumFailed:1;
+            ULONG   IpChecksumPresent:1;
+            ULONG   TcpChecksumSucceeded:1;
+            ULONG   TcpChecksumFailed:1;
+            ULONG   TcpChecksumPresent:1;
+            ULONG   UdpChecksumSucceeded:1;
+            ULONG   UdpChecksumFailed:1;
+            ULONG   UdpChecksumPresent:1;
+            ULONG   Reserved:23;
+        };
+
+        ULONG   Value;
     };
-} XENVIF_CHECKSUM_FLAGS, *PXENVIF_CHECKSUM_FLAGS;
+};
+
+typedef struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 XENVIF_PACKET_CHECKSUM_FLAGS, *PXENVIF_PACKET_CHECKSUM_FLAGS;
 
 #pragma warning(pop)
 
-typedef struct _XENVIF_RECEIVER_PACKET {
-    LIST_ENTRY              ListEntry;
-    ULONG                   Offset;
-    ULONG                   Length;
-    XENVIF_PACKET_INFO      Info;
-    XENVIF_CHECKSUM_FLAGS   Flags;
-    USHORT                  TagControlInformation;
-    USHORT                  MaximumSegmentSize;
-    PVOID                   Cookie;
-    MDL                     Mdl;
-    PFN_NUMBER              __Pfn;
-} XENVIF_RECEIVER_PACKET, *PXENVIF_RECEIVER_PACKET;
-
-typedef struct _XENVIF_RECEIVER_PACKET_STATISTICS {
-    ULONGLONG   Drop;
-    ULONGLONG   BackendError;
-    ULONGLONG   FrontendError;
-    ULONGLONG   Unicast;
-    ULONGLONG   UnicastBytes;
-    ULONGLONG   Multicast;
-    ULONGLONG   MulticastBytes;
-    ULONGLONG   Broadcast;
-    ULONGLONG   BroadcastBytes;
-} XENVIF_RECEIVER_PACKET_STATISTICS, *PXENVIF_RECEIVER_PACKET_STATISTICS;
+struct _XENVIF_RECEIVER_PACKET_V1 {
+    LIST_ENTRY                              ListEntry;
+    struct _XENVIF_PACKET_INFO_V1           *Info;
+    ULONG                                   Offset;
+    ULONG                                   Length;
+    struct _XENVIF_PACKET_CHECKSUM_FLAGS_V1 Flags;
+    USHORT                                  MaximumSegmentSize;
+    PVOID                                   Cookie;
+    MDL                                     Mdl;
+    PFN_NUMBER                              __Pfn;
+};
+
+typedef struct _XENVIF_RECEIVER_PACKET_V1 XENVIF_RECEIVER_PACKET, *PXENVIF_RECEIVER_PACKET;
 
 #pragma warning(push)
 #pragma warning(disable:4214)   // nonstandard extension used : bit field types other than int
 #pragma warning(disable:4201)   // nonstandard extension used : nameless struct/union
 
-typedef struct _XENVIF_OFFLOAD_OPTIONS {
+struct _XENVIF_VIF_OFFLOAD_OPTIONS_V1 {
     union {
         struct {
             USHORT  OffloadTagManipulation:1;
@@ -141,290 +120,276 @@ typedef struct _XENVIF_OFFLOAD_OPTIONS {
 
         USHORT  Value;
     };
-} XENVIF_OFFLOAD_OPTIONS, *PXENVIF_OFFLOAD_OPTIONS;
+};
 
-#pragma warning(pop)
+typedef struct _XENVIF_VIF_OFFLOAD_OPTIONS_V1 XENVIF_VIF_OFFLOAD_OPTIONS, *PXENVIF_VIF_OFFLOAD_OPTIONS;
 
-typedef struct _XENVIF_TRANSMITTER_PACKET   XENVIF_TRANSMITTER_PACKET, *PXENVIF_TRANSMITTER_PACKET;
+#pragma warning(pop)
 
 // To fit into the reserved space in NDIS_PACKET and NET_BUFFER structures the XENVIF_TRANSMITTER_PACKET
 // structure must be at most the size of 3 pointer types.
 
 #pragma pack(push, 1) 
-typedef struct _XENVIF_SEND_INFO {
-    XENVIF_OFFLOAD_OPTIONS  OffloadOptions;
-    USHORT                  MaximumSegmentSize;     // Only used if OffloadOptions.OffloadIpVersion[4|6}LargePacket is set
-    USHORT                  TagControlInformation;  // Only used if OffloadOptions.OffloadTagManipulation is set
-} XENVIF_SEND_INFO, *PXENVIF_SEND_INFO;
-
-typedef struct _XENVIF_COMPLETION_INFO {
-    UCHAR                   Type;
-    XENVIF_PACKET_STATUS    Status;
-    USHORT                  PacketLength;
-    USHORT                  PayloadLength;
-} XENVIF_COMPLETION_INFO, *PXENVIF_COMPLETION_INFO;
+struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1 {
+    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
+    USHORT                      MaximumSegmentSize;     // Only used if OffloadOptions.OffloadIpVersion[4|6]LargePacket is set
+    USHORT                      TagControlInformation;  // Only used if OffloadOptions.OffloadTagManipulation is set
+};
+
+typedef struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1 XENVIF_TRANSMITTER_PACKET_SEND_INFO, *PXENVIF_TRANSMITTER_PACKET_SEND_INFO;
+
+struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1 {
+    UCHAR   Type;
+    UCHAR   Status;
+
+#define XENVIF_TRANSMITTER_PACKET_PENDING   1
+#define XENVIF_TRANSMITTER_PACKET_OK        2
+#define XENVIF_TRANSMITTER_PACKET_DROPPED   3
+#define XENVIF_TRANSMITTER_PACKET_ERROR     4
+
+    USHORT  PacketLength;
+    USHORT  PayloadLength;
+};
+
+typedef struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1 XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO, *PXENVIF_TRANSMITTER_PACKET_COMPLETION_INFO;
 
 #pragma warning(push)
 #pragma warning(disable:4201)   // nonstandard extension used : nameless struct/union
 
-struct _XENVIF_TRANSMITTER_PACKET {
-    PXENVIF_TRANSMITTER_PACKET  Next;
+struct _XENVIF_TRANSMITTER_PACKET_V1 {
+    struct _XENVIF_TRANSMITTER_PACKET_V1                        *Next;
     union {
-        XENVIF_SEND_INFO        Send;
-        XENVIF_COMPLETION_INFO  Completion;
+        struct _XENVIF_TRANSMITTER_PACKET_SEND_INFO_V1          Send;
+        struct _XENVIF_TRANSMITTER_PACKET_COMPLETION_INFO_V1    Completion;
     };
 };
 
+typedef struct _XENVIF_TRANSMITTER_PACKET_V1 XENVIF_TRANSMITTER_PACKET, *PXENVIF_TRANSMITTER_PACKET;
+
 #pragma warning(pop)
 
 #pragma pack(pop) 
 
-C_ASSERT(sizeof (XENVIF_TRANSMITTER_PACKET) <= (3 * sizeof (PVOID)));
-
-// Because we're so tight on space in the XENVIF_TRANSMITTER_PACKET structure, certain packet metadata
-// needs to be accessed via magic offsets
-typedef struct _XENVIF_TRANSMITTER_PACKET_METADATA {
-    LONG_PTR    OffsetOffset;
-    LONG_PTR    LengthOffset;
-    LONG_PTR    MdlOffset;
-} XENVIF_TRANSMITTER_PACKET_METADATA, *PXENVIF_TRANSMITTER_PACKET_METADATA;
-
-typedef struct _XENVIF_TRANSMITTER_PACKET_STATISTICS {
-    ULONGLONG   Drop;
-    ULONGLONG   BackendError;
-    ULONGLONG   FrontendError;
-    ULONGLONG   Unicast;
-    ULONGLONG   UnicastBytes;
-    ULONGLONG   Multicast;
-    ULONGLONG   MulticastBytes;
-    ULONGLONG   Broadcast;
-    ULONGLONG   BroadcastBytes;
-} XENVIF_TRANSMITTER_PACKET_STATISTICS, *PXENVIF_TRANSMITTER_PACKET_STATISTICS;
-
-typedef struct _XENVIF_PACKET_STATISTICS {
-    XENVIF_RECEIVER_PACKET_STATISTICS       Receiver;
-    XENVIF_TRANSMITTER_PACKET_STATISTICS    Transmitter;
-} XENVIF_PACKET_STATISTICS, *PXENVIF_PACKET_STATISTICS;
-
-#define MAXIMUM_MULTICAST_ADDRESS_COUNT 32  // Minimum number to pass WHQL
+C_ASSERT(sizeof (struct _XENVIF_TRANSMITTER_PACKET_V1) <= (3 * sizeof (PVOID)));
+
+typedef enum _XENVIF_TRANSMITTER_PACKET_OFFSET {
+    XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET = 0,
+    XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET,
+    XENVIF_TRANSMITTER_PACKET_MDL_OFFSET,
+    XENVIF_TRANSMITTER_PACKET_OFFSET_COUNT
+} XENVIF_TRANSMITTER_PACKET_OFFSET, *PXENVIF_TRANSMITTER_PACKET_OFFSET;
+
+typedef enum _XENVIF_VIF_STATISTIC {
+    XENVIF_TRANSMITTER_PACKETS_DROPPED = 0,
+    XENVIF_TRANSMITTER_BACKEND_ERRORS,
+    XENVIF_TRANSMITTER_FRONTEND_ERRORS,
+    XENVIF_TRANSMITTER_UNICAST_PACKETS,
+    XENVIF_TRANSMITTER_UNICAST_OCTETS,
+    XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+    XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+    XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+    XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+    XENVIF_RECEIVER_PACKETS_DROPPED,
+    XENVIF_RECEIVER_BACKEND_ERRORS,
+    XENVIF_RECEIVER_FRONTEND_ERRORS,
+    XENVIF_RECEIVER_UNICAST_PACKETS,
+    XENVIF_RECEIVER_UNICAST_OCTETS,
+    XENVIF_RECEIVER_MULTICAST_PACKETS,
+    XENVIF_RECEIVER_MULTICAST_OCTETS,
+    XENVIF_RECEIVER_BROADCAST_PACKETS,
+    XENVIF_RECEIVER_BROADCAST_OCTETS,
+    XENVIF_VIF_STATISTIC_COUNT
+} XENVIF_VIF_STATISTIC, *PXENVIF_VIF_STATISTIC;
 
 typedef enum _XENVIF_MAC_FILTER_LEVEL {
-    MAC_FILTER_NONE = 0,
-    MAC_FILTER_MATCHING = 1,
-    MAC_FILTER_ALL = 2
+    XENVIF_MAC_FILTER_NONE = 0,
+    XENVIF_MAC_FILTER_MATCHING = 1,
+    XENVIF_MAC_FILTER_ALL = 2
 } XENVIF_MAC_FILTER_LEVEL, *PXENVIF_MAC_FILTER_LEVEL;
 
-typedef struct _XENVIF_MEDIA_STATE {
-    NET_IF_MEDIA_CONNECT_STATE  MediaConnectState;
-    ULONG64                     LinkSpeed;
-    NET_IF_MEDIA_DUPLEX_STATE   MediaDuplexState;
-} XENVIF_MEDIA_STATE, *PXENVIF_MEDIA_STATE;
-
-typedef enum XENVIF_CALLBACK_TYPE {
-    XENVIF_CALLBACK_TYPE_INVALID = 0,
-    XENVIF_CALLBACK_COMPLETE_PACKETS,
-    XENVIF_CALLBACK_RECEIVE_PACKETS,
-    XENVIF_CALLBACK_MEDIA_STATE_CHANGE
-} XENVIF_CALLBACK_TYPE, *PXENVIF_CALLBACK_TYPE;
-
-#define DEFINE_VIF_OPERATIONS                                                                   \
-        VIF_OPERATION(VOID,                                                                     \
-                      Acquire,                                                                  \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT  Context                                          \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      Release,                                                                  \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT  Context                                          \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(NTSTATUS,                                                                 \
-                      Enable,                                                                   \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT  Context,                                         \
-                      IN  VOID                 (*Function)(PVOID, XENVIF_CALLBACK_TYPE, ...),   \
-                      IN  PVOID                Argument OPTIONAL                                \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      Disable,                                                                  \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT  Context                                          \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryPacketStatistics,                                                    \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      OUT PXENVIF_PACKET_STATISTICS Statistics                                  \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      UpdatePacketMetadata,                                                     \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT                   Context,                        \
-                      IN  PXENVIF_TRANSMITTER_PACKET_METADATA   Metadata                        \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      ReturnPacket,                                                             \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      IN  PXENVIF_RECEIVER_PACKET   Packet                                      \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(NTSTATUS,                                                                 \
-                      QueuePackets,                                                             \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT           Context,                                \
-                      IN  PXENVIF_TRANSMITTER_PACKET    HeadPacket                              \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryOffloadOptions,                                                      \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      OUT PXENVIF_OFFLOAD_OPTIONS   Options                                     \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      UpdateOffloadOptions,                                                     \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      IN  XENVIF_OFFLOAD_OPTIONS    Options                                     \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryLargePacketSize,                                                     \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      IN  UCHAR                 Version,                                        \
-                      OUT PULONG                Size                                            \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryMediaState,                                                          \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT           Context,                                \
-                      OUT PNET_IF_MEDIA_CONNECT_STATE   MediaConnectState OPTIONAL,             \
-                      OUT PULONG64                      LinkSpeed OPTIONAL,                     \
-                      OUT PNET_IF_MEDIA_DUPLEX_STATE    MediaDuplexState OPTIONAL               \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryMaximumFrameSize,                                                    \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      OUT PULONG                Size                                            \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryPermanentAddress,                                                    \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      OUT PETHERNET_ADDRESS     Address                                         \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryCurrentAddress,                                                      \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      OUT PETHERNET_ADDRESS     Address                                         \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(NTSTATUS,                                                                 \
-                      UpdateCurrentAddress,                                                     \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      IN  PETHERNET_ADDRESS     Address                                         \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(NTSTATUS,                                                                 \
-                      QueryMulticastAddresses,                                                  \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      OUT PETHERNET_ADDRESS     Address OPTIONAL,                               \
-                      OUT PULONG                Count                                           \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(NTSTATUS,                                                                 \
-                      UpdateMulticastAddresses,                                                 \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT   Context,                                        \
-                      IN  PETHERNET_ADDRESS     Address,                                        \
-                      IN  ULONG                 Count                                           \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryFilterLevel,                                                         \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      IN  ETHERNET_ADDRESS_TYPE     Type,                                       \
-                      OUT PXENVIF_MAC_FILTER_LEVEL  Level                                       \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(NTSTATUS,                                                                 \
-                      UpdateFilterLevel,                                                        \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      IN  ETHERNET_ADDRESS_TYPE     Type,                                       \
-                      IN  XENVIF_MAC_FILTER_LEVEL   Level                                       \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryReceiverRingSize,                                                    \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      OUT PULONG                    Size                                        \
-                      )                                                                         \
-                      )                                                                         \
-        VIF_OPERATION(VOID,                                                                     \
-                      QueryTransmitterRingSize,                                                 \
-                      (                                                                         \
-                      IN  PXENVIF_VIF_CONTEXT       Context,                                    \
-                      OUT PULONG                    Size                                        \
-                      )                                                                         \
-                      )
-
-typedef struct _XENVIF_VIF_CONTEXT  XENVIF_VIF_CONTEXT, *PXENVIF_VIF_CONTEXT;
-
-#define VIF_OPERATION(_Type, _Name, _Arguments) \
-        _Type (*VIF_ ## _Name) _Arguments;
-
-typedef struct _XENVIF_VIF_OPERATIONS {
-    DEFINE_VIF_OPERATIONS
-} XENVIF_VIF_OPERATIONS, *PXENVIF_VIF_OPERATIONS;
-
-#undef VIF_OPERATION
-
-typedef struct _XENVIF_VIF_INTERFACE XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
-
-// {BAA55367-D5CD-4fab-8A2D-BB40476795C3}
-DEFINE_GUID(GUID_VIF_INTERFACE, 
-            0xbaa55367,
-            0xd5cd,
-            0x4fab,
-            0x8a,
-            0x2d,
-            0xbb,
-            0x40,
-            0x47,
-            0x67,
-            0x95,
-            0xc3);
-
-#define VIF_INTERFACE_VERSION    14
-
-#define VIF_OPERATIONS(_Interface) \
-        (PXENVIF_VIF_OPERATIONS *)((ULONG_PTR)(_Interface))
-
-#define VIF_CONTEXT(_Interface) \
-        (PXENVIF_VIF_CONTEXT *)((ULONG_PTR)(_Interface) + sizeof (PVOID))
-
-#define VIF(_Operation, _Interface, ...) \
-        (*VIF_OPERATIONS(_Interface))->VIF_ ## _Operation((*VIF_CONTEXT(_Interface)), __VA_ARGS__)
+typedef enum _XENVIF_VIF_CALLBACK_TYPE {
+    XENVIF_TRANSMITTER_RETURN_PACKETS = 0,
+    XENVIF_RECEIVER_QUEUE_PACKETS,
+    XENVIF_MAC_STATE_CHANGE
+} XENVIF_VIF_CALLBACK_TYPE, *PXENVIF_VIF_CALLBACK_TYPE;
+
+typedef NTSTATUS
+(*XENVIF_VIF_ACQUIRE)(
+    IN  PINTERFACE  Interface
+    );
+
+typedef VOID
+(*XENVIF_VIF_RELEASE)(
+    IN  PINTERFACE  Interface
+    );
+
+typedef VOID
+(*XENVIF_VIF_CALLBACK)(
+    IN  PVOID                       Argument,
+    IN  XENVIF_VIF_CALLBACK_TYPE    Type,
+    ...
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_ENABLE)(
+    IN  PINTERFACE          Interface,
+    IN  XENVIF_VIF_CALLBACK Callback,
+    IN  PVOID               Argument OPTIONAL
+    );
+
+typedef VOID
+(*XENVIF_VIF_DISABLE)(
+    IN  PINTERFACE  Interface
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_QUERY_STATISTIC)(
+    IN  PINTERFACE              Interface,
+    IN  XENVIF_VIF_STATISTIC    Index,
+    OUT PULONGLONG              Value
+    );
+
+typedef VOID
+(*XENVIF_VIF_RECEIVER_RETURN_PACKETS)(
+    IN  PINTERFACE  Interface,
+    IN  PLIST_ENTRY List
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET)(
+    IN  PINTERFACE                          Interface,
+    IN  XENVIF_TRANSMITTER_PACKET_OFFSET    Type,
+    IN  LONG_PTR                            Value
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENVIF_TRANSMITTER_PACKET  Head
+    );
+
+typedef VOID
+(*XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS)(
+    IN  PINTERFACE                  Interface,
+    OUT PXENVIF_VIF_OFFLOAD_OPTIONS Options
+    );
+
+typedef VOID
+(*XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS)(
+    IN  PINTERFACE                  Interface,
+    IN  XENVIF_VIF_OFFLOAD_OPTIONS  Options
+    );
+
+typedef VOID
+(*XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE)(
+    IN  PINTERFACE  Interface,
+    IN  UCHAR       Version,
+    OUT PULONG      Size
+    );
+
+typedef VOID
+(*XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE)(
+    IN  PINTERFACE  Interface,
+    OUT PULONG      Size
+    );
+
+typedef VOID
+(*XENVIF_VIF_RECEIVER_QUERY_RING_SIZE)(
+    IN  PINTERFACE  Interface,
+    OUT PULONG      Size
+    );
+
+typedef VOID
+(*XENVIF_VIF_MAC_QUERY_STATE)(
+    IN  PINTERFACE                  Interface,
+    OUT PNET_IF_MEDIA_CONNECT_STATE MediaConnectState OPTIONAL,
+    OUT PULONG64                    LinkSpeed OPTIONAL,
+    OUT PNET_IF_MEDIA_DUPLEX_STATE  MediaDuplexState OPTIONAL
+    );
+
+typedef VOID
+(*XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE)(
+    IN  PINTERFACE  Interface,
+    OUT PULONG      Size
+    );
+
+typedef VOID
+(*XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS)(
+    IN  PINTERFACE          Interface,
+    OUT PETHERNET_ADDRESS   Address
+    );
+
+typedef VOID
+(*XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS)(
+    IN  PINTERFACE          Interface,
+    OUT PETHERNET_ADDRESS   Address
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES)(
+    IN      PINTERFACE          Interface,
+    OUT     PETHERNET_ADDRESS   Address OPTIONAL,
+    IN OUT  PULONG              Count
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES)(
+    IN  PINTERFACE          Interface,
+    IN  PETHERNET_ADDRESS   Address OPTIONAL,
+    IN  ULONG               Count
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_MAC_SET_FILTER_LEVEL)(
+    IN  PINTERFACE              Interface,
+    IN  ETHERNET_ADDRESS_TYPE   Type,
+    IN  XENVIF_MAC_FILTER_LEVEL Level
+    );
+
+typedef NTSTATUS
+(*XENVIF_VIF_MAC_QUERY_FILTER_LEVEL)(
+    IN  PINTERFACE                  Interface,
+    IN  ETHERNET_ADDRESS_TYPE       Type,
+    OUT PXENVIF_MAC_FILTER_LEVEL    Level
+    );
+
+// {76F279CD-CA11-418B-92E8-C57F77DE0E2E}
+DEFINE_GUID(GUID_XENVIF_VIF_INTERFACE, 
+0x76f279cd, 0xca11, 0x418b, 0x92, 0xe8, 0xc5, 0x7f, 0x77, 0xde, 0xe, 0x2e);
+
+struct _XENVIF_VIF_INTERFACE_V1 {
+    INTERFACE                                       Interface;
+    XENVIF_VIF_ACQUIRE                              Acquire;
+    XENVIF_VIF_RELEASE                              Release;
+    XENVIF_VIF_ENABLE                               Enable;
+    XENVIF_VIF_DISABLE                              Disable;
+    XENVIF_VIF_QUERY_STATISTIC                      QueryStatistic;
+    XENVIF_VIF_RECEIVER_RETURN_PACKETS              ReceiverReturnPackets;
+    XENVIF_VIF_RECEIVER_SET_OFFLOAD_OPTIONS         ReceiverSetOffloadOptions;
+    XENVIF_VIF_RECEIVER_QUERY_RING_SIZE             ReceiverQueryRingSize;
+    XENVIF_VIF_TRANSMITTER_SET_PACKET_OFFSET        TransmitterSetPacketOffset;
+    XENVIF_VIF_TRANSMITTER_QUEUE_PACKETS            TransmitterQueuePackets;
+    XENVIF_VIF_TRANSMITTER_QUERY_OFFLOAD_OPTIONS    TransmitterQueryOffloadOptions;
+    XENVIF_VIF_TRANSMITTER_QUERY_LARGE_PACKET_SIZE  TransmitterQueryLargePacketSize;
+    XENVIF_VIF_TRANSMITTER_QUERY_RING_SIZE          TransmitterQueryRingSize;
+    XENVIF_VIF_MAC_QUERY_STATE                      MacQueryState;
+    XENVIF_VIF_MAC_QUERY_MAXIMUM_FRAME_SIZE         MacQueryMaximumFrameSize;
+    XENVIF_VIF_MAC_QUERY_PERMANENT_ADDRESS          MacQueryPermanentAddress;
+    XENVIF_VIF_MAC_QUERY_CURRENT_ADDRESS            MacQueryCurrentAddress;
+    XENVIF_VIF_MAC_QUERY_MULTICAST_ADDRESSES        MacQueryMulticastAddresses;
+    XENVIF_VIF_MAC_SET_MULTICAST_ADDRESSES          MacSetMulticastAddresses;
+    XENVIF_VIF_MAC_SET_FILTER_LEVEL                 MacSetFilterLevel;
+    XENVIF_VIF_MAC_QUERY_FILTER_LEVEL               MacQueryFilterLevel;
+};
 
-#endif  // _XENVIF_INTERFACE_H
+typedef struct _XENVIF_VIF_INTERFACE_V1 XENVIF_VIF_INTERFACE, *PXENVIF_VIF_INTERFACE;
 
+#define XENVIF_VIF(_Method, _Interface, ...)    \
+    (_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif  // _WINDLL
+
+#define XENVIF_VIF_INTERFACE_VERSION_MIN    1
+#define XENVIF_VIF_INTERFACE_VERSION_MAX    1
+
+#endif  // _XENVIF_INTERFACE_H
index 9aa2bda4def1357298a66507483e2f38ac41e098..9bcaf7cdddb1285d96379fbfd6c656f29a729611 100644 (file)
@@ -73,6 +73,7 @@
                <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
        </ItemGroup>
        <ItemGroup>
+               <ClCompile Include="../../src/xennet/registry.c" />
                <ClCompile Include="../../src/xennet/adapter.c" />
                <ClCompile Include="../../src/xennet/main.c" />
                <ClCompile Include="../../src/xennet/miniport.c" />
index 3f6b64193a5e725643c222ae7a330051d75a0895..450dc5fd8404a6cd1e6775c1ceb6bd8a62898ebc 100644 (file)
@@ -43,6 +43,7 @@
 #include <strsafe.h>
 #include <malloc.h>
 #include <stdarg.h>
+#include <assert.h>
 
 #include <tcpip.h>
 #include <version.h>
@@ -59,14 +60,11 @@ __user_code;
 #define PARAMETERS_KEY(_Driver) \
         SERVICE_KEY(_Driver) ## "\\Parameters"
 
-#define ADDRESSES_KEY(_Driver)  \
-        SERVICE_KEY(_Driver) ## "\\Addresses"
+#define ADDRESSES_KEY   \
+        SERVICE_KEY(XENVIF) ## "\\Addresses"
 
-#define ALIASES_KEY(_Driver)    \
-        SERVICE_KEY(_Driver) ## "\\Aliases"
-
-#define UNPLUG_KEY(_Driver)     \
-        SERVICE_KEY(_Driver) ## "\\Unplug"
+#define UNPLUG_KEY  \
+        SERVICE_KEY(XENFILT) ## "\\Unplug"
 
 #define CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control"
 
@@ -78,11 +76,6 @@ __user_code;
 
 #define ENUM_KEY "SYSTEM\\CurrentControlSet\\Enum"
 
-#define SOFTWARE_KEY "SOFTWARE\\Citrix"
-
-#define INSTALLER_KEY   \
-        SOFTWARE_KEY ## "\\XenToolsNetSettings\\XEN\\VIF"
-
 static VOID
 #pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
 __Log(
@@ -463,10 +456,11 @@ fail1:
 }
 
 
-static PETHERNET_ADDRESS
+static BOOLEAN
 GetPermanentAddress(
     IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData
+    IN  PSP_DEVINFO_DATA    DeviceInfoData,
+    OUT PETHERNET_ADDRESS   Address
     )
 {
     PTCHAR                  Location;
@@ -477,7 +471,6 @@ GetPermanentAddress(
     PTCHAR                  Buffer;
     DWORD                   Type;
     BOOLEAN                 Success;
-    PETHERNET_ADDRESS       Address;
 
     Location = GetProperty(DeviceInfoSet,
                            DeviceInfoData,
@@ -486,7 +479,7 @@ GetPermanentAddress(
         goto fail1;
 
     Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         ADDRESSES_KEY(XENVIF),
+                         ADDRESSES_KEY,
                          0,
                          KEY_READ,
                          &AddressesKey);
@@ -534,13 +527,9 @@ GetPermanentAddress(
         goto fail6;
     }
 
-    Address = calloc(1, sizeof (ETHERNET_ADDRESS));
-    if (Address == NULL)
-        goto fail7;
-
     Success = ParseMacAddress(Buffer, Address);
     if (!Success)
-        goto fail8;
+        goto fail7;
 
     free(Buffer);
 
@@ -556,12 +545,7 @@ GetPermanentAddress(
         Address->Byte[4],
         Address->Byte[5]);
 
-    return Address;
-
-fail8:
-    Log("fail8");
-
-    free(Address);
+    return TRUE;
 
 fail7:
     Log("fail7");
@@ -598,7 +582,7 @@ fail1:
         LocalFree(Message);
     }
 
-    return NULL;
+    return FALSE;
 }
 
 static BOOLEAN
@@ -621,7 +605,11 @@ GetNetLuid(
     for (Index = 0; Index < Table->NumEntries; Index++) {
         Row = &Table->Table[Index];
 
-        if (!(Row->InterfaceAndOperStatusFlags.HardwareInterface))
+        if (!(Row->InterfaceAndOperStatusFlags.HardwareInterface) ||
+            !(Row->InterfaceAndOperStatusFlags.ConnectorPresent))
+            continue;
+
+        if (Row->OperStatus != IfOperStatusUp)
             continue;
 
         if (Row->PhysicalAddressLength != sizeof (ETHERNET_ADDRESS))
@@ -935,78 +923,37 @@ fail1:
     return FALSE;
 }
 
-static BOOLEAN
-WalkSubKeys(
-    IN  HKEY    Key,
-    IN  BOOLEAN (*Match)(HKEY, PTCHAR, PVOID),
-    IN  PVOID   Argument,
-    OUT PTCHAR  *SubKeyName
+static HKEY
+OpenAliasSoftwareKey(
+    IN  PTCHAR  Name
     )
 {
+    HRESULT     Result;
+    TCHAR       KeyName[MAX_PATH];
+    HKEY        Key;
     HRESULT     Error;
-    DWORD       SubKeys;
-    DWORD       MaxSubKeyLength;
-    DWORD       SubKeyLength;
-    DWORD       Index;
 
-    Error = RegQueryInfoKey(Key,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &SubKeys,
-                            &MaxSubKeyLength,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
+    Result = StringCbPrintf(KeyName,
+                            MAX_PATH,
+                            "%s\\%s",
+                            CLASS_KEY,
+                            Name);
+    if (!SUCCEEDED(Result)) {
+        SetLastError(ERROR_BUFFER_OVERFLOW);
         goto fail1;
     }
 
-    SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
-
-    *SubKeyName = malloc(SubKeyLength);
-    if (*SubKeyName == NULL)
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         KeyName,
+                         0,
+                         KEY_READ,
+                         &Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
         goto fail2;
-
-    for (Index = 0; Index < SubKeys; Index++) {
-        SubKeyLength = MaxSubKeyLength + sizeof (TCHAR);
-        memset(*SubKeyName, 0, SubKeyLength);
-
-        Error = RegEnumKeyEx(Key,
-                             Index,
-                             (LPTSTR)*SubKeyName,
-                             &SubKeyLength,
-                             NULL,
-                             NULL,
-                             NULL,
-                             NULL);
-        if (Error != ERROR_SUCCESS) {
-            SetLastError(Error);
-            goto fail3;
-        }
-
-        if (Match(Key, *SubKeyName, Argument))
-            goto done;
     }
 
-    SetLastError(ERROR_FILE_NOT_FOUND);
-    goto fail4;
-        
-done:
-    return TRUE;
-
-fail4:
-    Log("fail4");
-
-fail3:
-    Log("fail3");
-
-    free(*SubKeyName);
-    *SubKeyName = NULL;
+    return Key;
 
 fail2:
     Log("fail2");
@@ -1021,43 +968,32 @@ fail1:
         LocalFree(Message);
     }
 
-    return FALSE;
+    return NULL;
 }
 
-typedef struct _DEVICE_WALK {
-    PTCHAR  Driver;
-    PTCHAR  Device;
-    PTCHAR  Instance;
-} DEVICE_WALK, *PDEVICE_WALK;
-
-static BOOLEAN
-IsInstance(
-    IN  HKEY        Key,
-    IN  PTCHAR      SubKeyName,
-    IN  PVOID       Argument
+static PTCHAR
+GetInterfaceName(
+    IN  HKEY    SoftwareKey
     )
 {
-    PDEVICE_WALK    Walk = Argument;
-    HKEY            SubKey;
-    HRESULT         Error;
-    DWORD           MaxValueLength;
-    DWORD           DriverLength;
-    PTCHAR          Driver;
-    DWORD           Type;
-
-    Log("====> (%s)", SubKeyName);
+    HRESULT     Error;
+    HKEY        LinkageKey;
+    DWORD       MaxValueLength;
+    DWORD       RootDeviceLength;
+    PTCHAR      RootDevice;
+    DWORD       Type;
 
-    Error = RegOpenKeyEx(Key,
-                         SubKeyName,
+    Error = RegOpenKeyEx(SoftwareKey,
+                         "Linkage",
                          0,
                          KEY_READ,
-                         &SubKey);
+                         &LinkageKey);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
         goto fail1;
     }
 
-    Error = RegQueryInfoKey(SubKey,
+    Error = RegQueryInfoKey(LinkageKey,
                             NULL,
                             NULL,
                             NULL,
@@ -1074,1126 +1010,203 @@ IsInstance(
         goto fail2;
     }
 
-    DriverLength = MaxValueLength + sizeof (TCHAR);
+    RootDeviceLength = MaxValueLength + sizeof (TCHAR);
 
-    Driver = calloc(1, DriverLength);
-    if (Driver == NULL)
-        goto fail3;
+    RootDevice = calloc(1, RootDeviceLength);
+    if (RootDevice == NULL)
+        goto fail2;
 
-    Error = RegQueryValueEx(SubKey,
-                            "Driver",
+    Error = RegQueryValueEx(LinkageKey,
+                            "RootDevice",
                             NULL,
                             &Type,
-                            (LPBYTE)Driver,
-                            &DriverLength);
+                            (LPBYTE)RootDevice,
+                            &RootDeviceLength);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail4;
+        goto fail3;
     }
 
-    if (Type != REG_SZ) {
-        SetLastError(ERROR_BAD_FORMAT);
-        goto fail5;
+    Error = RegQueryValueEx(LinkageKey,
+                            "RootDevice",
+                            NULL,
+                            &Type,
+                            (LPBYTE)RootDevice,
+                            &RootDeviceLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
     }
 
-    if (strncmp(Driver, Walk->Driver, DriverLength) != 0) {
-        SetLastError(ERROR_FILE_NOT_FOUND);
-        goto fail6;
+    if (Type != REG_MULTI_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail4;
     }
 
-    free(Driver);
-
-    Log("<====");
-
-    return TRUE;
+    Log("%s", RootDevice);
 
-fail6:
-    Log("fail6");
+    RegCloseKey(LinkageKey);
 
-fail5:
-    Log("fail5");
+    return RootDevice;
 
 fail4:
     Log("fail4");
 
-    free(Driver);
-
 fail3:
     Log("fail3");
 
+    free(RootDevice);
+
 fail2:
     Log("fail2");
 
-    RegCloseKey(SubKey);
+    RegCloseKey(LinkageKey);
 
 fail1:
     Error = GetLastError();
 
     {
         PTCHAR  Message;
+
         Message = __GetErrorMessage(Error);
         Log("fail1 (%s)", Message);
         LocalFree(Message);
     }
 
-    return FALSE;
+    return NULL;
 }
 
 static BOOLEAN
-IsDevice(
-    IN  HKEY        Key,
-    IN  PTCHAR      SubKeyName,
-    IN  PVOID       Argument
+CopyKeyValues(
+    IN  HKEY    DestinationKey,
+    IN  HKEY    SourceKey
     )
 {
-    PDEVICE_WALK    Walk = Argument;
-    HRESULT         Error;
-    HKEY            SubKey;
+    HRESULT     Error;
+    DWORD       Values;
+    DWORD       MaxNameLength;
+    PTCHAR      Name;
+    DWORD       MaxValueLength;
+    LPBYTE      Value;
+    DWORD       Index;
 
-    Log("====> (%s)", SubKeyName);
+    Log("====>");
 
-    Error = RegOpenKeyEx(Key,
-                         SubKeyName,
-                         0,
-                         KEY_READ,
-                         &SubKey);
+    Error = RegQueryInfoKey(SourceKey,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            NULL,
+                            &Values,
+                            &MaxNameLength,
+                            &MaxValueLength,
+                            NULL,
+                            NULL);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
         goto fail1;
     }
 
-    if (!WalkSubKeys(SubKey,
-                     IsInstance,
-                     Walk,
-                     &Walk->Instance)) {
-        SetLastError(ERROR_FILE_NOT_FOUND);
+    Log("%d VALUES", Values);
+
+    if (Values == 0)
+        goto done;
+
+    MaxNameLength += sizeof (TCHAR);
+
+    Name = malloc(MaxNameLength);
+    if (Name == NULL)
         goto fail2;
+
+    Value = malloc(MaxValueLength);
+    if (Value == NULL)
+        goto fail3;
+
+    for (Index = 0; Index < Values; Index++) {
+        DWORD   NameLength;
+        DWORD   ValueLength;
+        DWORD   Type;
+
+        NameLength = MaxNameLength;
+        memset(Name, 0, NameLength);
+
+        ValueLength = MaxValueLength;
+        memset(Value, 0, ValueLength);
+
+        Error = RegEnumValue(SourceKey,
+                             Index,
+                             (LPTSTR)Name,
+                             &NameLength,
+                             NULL,
+                             &Type,
+                             Value,
+                             &ValueLength);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail4;
+        }
+
+        Error = RegSetValueEx(DestinationKey,
+                              Name,
+                              0,
+                              Type,
+                              Value,
+                              ValueLength);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(Error);
+            goto fail5;
+        }
+
+        Log("COPIED %s", Name);
     }
 
+    free(Value);
+    free(Name);
+
+done:
     Log("<====");
 
     return TRUE;
 
+fail5:
+    Log("fail5");
+
+fail4:
+    Log("fail4");
+
+    free(Value);
+
+fail3:
+    Log("fail3");
+
+    free(Name);
+
 fail2:
     Log("fail2");
 
-    RegCloseKey(SubKey);
-
 fail1:
+    Log("fail1");
+
     Error = GetLastError();
 
     {
         PTCHAR  Message;
+
         Message = __GetErrorMessage(Error);
         Log("fail1 (%s)", Message);
         LocalFree(Message);
     }
 
     return FALSE;
+
 }
 
 static BOOLEAN
-OpenEnumKey(
-    IN  const TCHAR *Bus,
-    OUT PHKEY       Key
-    )
-{   
-    TCHAR           KeyName[MAX_PATH];
-    HRESULT         Result;
-    HRESULT         Error;
-
-    Result = StringCbPrintf(KeyName,
-                            MAX_PATH,
-                            "%s\\%s",
-                            ENUM_KEY,
-                            Bus);
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail1;
-    }
-
-    Log("%s", KeyName);
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         KeyName,
-                         0,
-                         KEY_READ,
-                         Key);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    return TRUE;
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static BOOLEAN
-FindAliasHardwareKeyName(
-    IN  PETHERNET_ADDRESS   Address,
-    OUT PTCHAR              *Name
-    )
-{
-    PTCHAR                  SoftwareKeyName;
-    DEVICE_WALK             Walk;
-    BOOLEAN                 Success;
-    HKEY                    PciKey;
-    HRESULT                 Error;
-    DWORD                   NameLength;
-    HRESULT                 Result;
-
-    Log("====>");
-
-    if (!FindAliasSoftwareKeyName(Address, &SoftwareKeyName))
-        goto fail1;
-
-    *Name = NULL;
-
-    if (SoftwareKeyName == NULL)
-        goto done;
-
-    Walk.Driver = SoftwareKeyName;
-
-    Success = OpenEnumKey("PCI", &PciKey);
-    if (!Success)
-        goto fail2;
-
-    if (!WalkSubKeys(PciKey,
-                     IsDevice,
-                     &Walk,
-                     &Walk.Device)) {
-        SetLastError(ERROR_FILE_NOT_FOUND);
-        goto fail3;
-    }
-
-    NameLength = (DWORD)((strlen(ENUM_KEY) + 1 +
-                          strlen("PCI") + 1 +
-                          strlen(Walk.Device) + 1 +
-                          strlen(Walk.Instance) + 1) *
-                         sizeof (TCHAR));
-
-    *Name = calloc(1, NameLength);
-    if (*Name == NULL)
-        goto fail4;
-
-    Result = StringCbPrintf(*Name,
-                            NameLength,
-                            "%s\\PCI\\%s\\%s",
-                            ENUM_KEY,
-                            Walk.Device,
-                            Walk.Instance);
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail4;
-    }
-
-    free(Walk.Instance);
-    free(Walk.Device);
-
-    RegCloseKey(PciKey);
-
-    free(SoftwareKeyName);
-
-done:
-    Log("%s", (*Name == NULL) ? "[NONE]" : *Name);
-
-    Log("<====");
-
-    return TRUE;
-
-fail4:
-    Log("fail4");
-
-    free(Walk.Instance);
-    free(Walk.Device);
-
-fail3:
-    Log("fail3");
-
-    RegCloseKey(PciKey);
-    
-fail2:
-    Log("fail2");
-
-    free(SoftwareKeyName);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static BOOLEAN
-SetAliasHardwareKeyName(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData,
-    IN  PTCHAR              Name
-    )
-{
-    PTCHAR                  Location;
-    HKEY                    AliasesKey;
-    HRESULT                 Error;
-
-    Location = GetProperty(DeviceInfoSet,
-                           DeviceInfoData,
-                           SPDRP_LOCATION_INFORMATION);
-    if (Location == NULL)
-        goto fail1;
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         ALIASES_KEY(XENVIF),
-                         0,
-                         KEY_ALL_ACCESS,
-                         &AliasesKey);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    if (Name == NULL)
-        Name = "";
-
-    Error = RegSetValueEx(AliasesKey,
-                          Location,
-                          0,
-                          REG_SZ,
-                          (LPBYTE)Name,
-                          (DWORD)((strlen(Name) + 1) * sizeof (TCHAR)));
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    Log("%s", (strlen(Name) == 0) ? "[NONE]" : Name);
-
-    RegCloseKey(AliasesKey);
-
-    free(Location);
-
-    return TRUE;
-
-fail3:
-    Log("fail3");
-
-    RegCloseKey(AliasesKey);
-
-fail2:
-    Log("fail2");
-
-    free(Location);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static BOOLEAN
-GetAliasHardwareKeyName(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData,
-    OUT PTCHAR              *Name
-    )
-{
-    PTCHAR                  Location;
-    HKEY                    AliasesKey;
-    DWORD                   MaxValueLength;
-    DWORD                   NameLength;
-    DWORD                   Type;
-    HRESULT                 Error;
-
-    Location = GetProperty(DeviceInfoSet,
-                           DeviceInfoData,
-                           SPDRP_LOCATION_INFORMATION);
-    if (Location == NULL)
-        goto fail1;
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         ALIASES_KEY(XENVIF),
-                         0,
-                         KEY_READ,
-                         &AliasesKey);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    Error = RegQueryInfoKey(AliasesKey,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &MaxValueLength,
-                            NULL,
-                            NULL);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    NameLength = MaxValueLength + sizeof (TCHAR);
-
-    *Name = calloc(1, NameLength);
-    if (*Name == NULL)
-        goto fail4;
-
-    Error = RegQueryValueEx(AliasesKey,
-                            Location,
-                            NULL,
-                            &Type,
-                            (LPBYTE)*Name,
-                            &NameLength);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail5;
-    }
-
-    if (Type != REG_SZ) {
-        SetLastError(ERROR_BAD_FORMAT);
-        goto fail6;
-    }
-
-    if (strlen(*Name) == 0) {
-        free(*Name);
-        *Name = NULL;
-    }
-
-    RegCloseKey(AliasesKey);
-
-    free(Location);
-
-    Log("%s", (*Name == NULL) ? "[NONE]" : *Name);
-
-    return TRUE;
-
-fail6:
-    Log("fail6");
-
-fail5:
-    Log("fail5");
-
-    free(*Name);
-
-fail4:
-    Log("fail4");
-
-fail3:
-    Log("fail3");
-
-    RegCloseKey(AliasesKey);
-
-fail2:
-    Log("fail2");
-
-    free(Location);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static BOOLEAN
-GetAliasSoftwareKeyName(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData,
-    OUT PTCHAR              *Name
-    )
-{
-    BOOLEAN                 Success;
-    PTCHAR                  HardwareKeyName;
-    HRESULT                 Error;
-    HKEY                    HardwareKey;
-    DWORD                   MaxValueLength;
-    DWORD                   NameLength;
-    DWORD                   Type;
-
-    Success = GetAliasHardwareKeyName(DeviceInfoSet,
-                                      DeviceInfoData,
-                                      &HardwareKeyName);
-    if (!Success)
-        goto fail1;
-
-    *Name = NULL;
-
-    if (HardwareKeyName == NULL)
-        goto done;
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         HardwareKeyName,
-                         0,
-                         KEY_READ,
-                         &HardwareKey);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    Error = RegQueryInfoKey(HardwareKey,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &MaxValueLength,
-                            NULL,
-                            NULL);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    NameLength = MaxValueLength + sizeof (TCHAR);
-
-    *Name = calloc(1, NameLength);
-    if (*Name == NULL)
-        goto fail4;
-
-    Error = RegQueryValueEx(HardwareKey,
-                            "Driver",
-                            NULL,
-                            &Type,
-                            (LPBYTE)*Name,
-                            &NameLength);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail5;
-    }
-
-    if (Type != REG_SZ) {
-        SetLastError(ERROR_BAD_FORMAT);
-        goto fail6;
-    }
-
-    RegCloseKey(HardwareKey);
-
-    free(HardwareKeyName);
-
-done:
-    Log("%s", (*Name == NULL) ? "[NONE]" : *Name);
-
-    return TRUE;
-
-fail6:
-    Log("fail6");
-
-fail5:
-    Log("fail5");
-
-    free(*Name);
-
-fail4:
-    Log("fail4");
-
-fail3:
-    Log("fail3");
-
-    RegCloseKey(HardwareKey);
-
-fail2:
-    Log("fail2");
-
-    free(HardwareKeyName);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static BOOLEAN
-ClearAliasHardwareKeyName(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData
-    )
-{
-    PTCHAR                  Location;
-    HKEY                    AliasesKey;
-    HRESULT                 Error;
-
-    Log("====>");
-
-    Location = GetProperty(DeviceInfoSet,
-                           DeviceInfoData,
-                           SPDRP_LOCATION_INFORMATION);
-    if (Location == NULL)
-        goto fail1;
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         ALIASES_KEY(XENVIF),
-                         0,
-                         KEY_ALL_ACCESS,
-                         &AliasesKey);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    Error = RegDeleteValue(AliasesKey,
-                           Location);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    RegCloseKey(AliasesKey);
-
-    free(Location);
-
-    Log("<====");
-
-    return TRUE;
-
-fail3:
-    Log("fail3");
-
-    RegCloseKey(AliasesKey);
-
-fail2:
-    Log("fail2");
-
-    free(Location);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static HKEY
-OpenAliasSoftwareKey(
-    IN  PTCHAR  Name
-    )
-{
-    HRESULT     Result;
-    TCHAR       KeyName[MAX_PATH];
-    HKEY        Key;
-    HRESULT     Error;
-
-    Result = StringCbPrintf(KeyName,
-                            MAX_PATH,
-                            "%s\\%s",
-                            CLASS_KEY,
-                            Name);
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail1;
-    }
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         KeyName,
-                         0,
-                         KEY_READ,
-                         &Key);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    return Key;
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return NULL;
-}
-
-static BOOLEAN
-GetInstallerSettingsKeyName(
-    IN  HDEVINFO            DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA    DeviceInfoData,
-    OUT PTCHAR              *Name
-    )
-{
-    PTCHAR                  Location;
-    HKEY                    InstallerKey;
-    HKEY                    SubKey;
-    HRESULT                 Error;
-
-    Log("====>");
-
-    Location = GetProperty(DeviceInfoSet,
-                           DeviceInfoData,
-                           SPDRP_LOCATION_INFORMATION);
-    if (Location == NULL)
-        goto fail1;
-
-    *Name = NULL;
-    InstallerKey = NULL;
-    SubKey = NULL;
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         INSTALLER_KEY,
-                         0,
-                         KEY_READ,
-                         &InstallerKey);
-    if (Error != ERROR_SUCCESS) {
-        if (Error == ERROR_FILE_NOT_FOUND)
-            goto done;
-
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    Error = RegOpenKeyEx(InstallerKey,
-                         Location,
-                         0,
-                         KEY_READ,
-                         &SubKey);
-    if (Error != ERROR_SUCCESS) {
-        if (Error == ERROR_FILE_NOT_FOUND)
-            goto done;
-
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    *Name = Location;
-
-    if (strlen(*Name) == 0) {
-        free(*Name);
-        *Name = NULL;
-    }
-
-done:
-    if (SubKey != NULL)
-        RegCloseKey(SubKey);
-
-    if (InstallerKey != NULL)
-        RegCloseKey(InstallerKey);
-
-    Log("%s", (*Name == NULL) ? "[NONE]" : *Name);
-
-    Log("<====");
-
-    return TRUE;
-
-fail3:
-    Log("fail3");
-
-    RegCloseKey(InstallerKey);
-
-fail2:
-    Log("fail2");
-
-    free(Location);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static PTCHAR
-GetInstallerSettingsPath(
-    IN  PTCHAR  Name
-    )
-{
-    HRESULT     Result;
-    PTCHAR      PathName;
-    HRESULT     Error;
-    DWORD       BufferSize;
-    
-    BufferSize = (DWORD)(strlen(INSTALLER_KEY) +
-                         strlen("\\") +
-                         strlen(Name) +
-                         sizeof(TCHAR));
-
-    PathName = malloc(BufferSize);
-
-    if (PathName == NULL)
-        goto fail1;
-
-    Result = StringCbPrintf(PathName,
-                            MAX_PATH,
-                            "%s\\%s",
-                            INSTALLER_KEY,
-                            Name);
-    
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail2;
-    } 
-
-    return PathName;
-
-fail2:
-    Log("fail2");
-    free(PathName);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return NULL;
-
-}
-
-static HKEY
-OpenInstallerSettingsKey(
-    IN  PTCHAR  Name,
-    IN  PTCHAR  SubKey
-    )
-{
-    HRESULT     Result;
-    TCHAR       KeyName[MAX_PATH];
-    HKEY        Key;
-    HRESULT     Error;
-
-    Result = StringCbPrintf(KeyName,
-                            MAX_PATH,
-                            "%s\\%s\\%s",
-                            INSTALLER_KEY,
-                            Name,
-                            SubKey);
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail1;
-    }
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         KeyName,
-                         0,
-                         KEY_READ,
-                         &Key);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    return Key;
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return NULL;
-}
-
-static PTCHAR
-GetInterfaceName(
-    IN  HKEY    SoftwareKey
-    )
-{
-    HRESULT     Error;
-    HKEY        LinkageKey;
-    DWORD       MaxValueLength;
-    DWORD       RootDeviceLength;
-    PTCHAR      RootDevice;
-    DWORD       Type;
-
-    Error = RegOpenKeyEx(SoftwareKey,
-                         "Linkage",
-                         0,
-                         KEY_READ,
-                         &LinkageKey);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail1;
-    }
-
-    Error = RegQueryInfoKey(LinkageKey,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &MaxValueLength,
-                            NULL,
-                            NULL);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    RootDeviceLength = MaxValueLength + sizeof (TCHAR);
-
-    RootDevice = calloc(1, RootDeviceLength);
-    if (RootDevice == NULL)
-        goto fail2;
-
-    Error = RegQueryValueEx(LinkageKey,
-                            "RootDevice",
-                            NULL,
-                            &Type,
-                            (LPBYTE)RootDevice,
-                            &RootDeviceLength);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    Error = RegQueryValueEx(LinkageKey,
-                            "RootDevice",
-                            NULL,
-                            &Type,
-                            (LPBYTE)RootDevice,
-                            &RootDeviceLength);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail3;
-    }
-
-    if (Type != REG_MULTI_SZ) {
-        SetLastError(ERROR_BAD_FORMAT);
-        goto fail4;
-    }
-
-    Log("%s", RootDevice);
-
-    RegCloseKey(LinkageKey);
-
-    return RootDevice;
-
-fail4:
-    Log("fail4");
-
-fail3:
-    Log("fail3");
-
-    free(RootDevice);
-
-fail2:
-    Log("fail2");
-
-    RegCloseKey(LinkageKey);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return NULL;
-}
-
-static BOOLEAN
-CopyKeyValues(
-    IN  HKEY    DestinationKey,
-    IN  HKEY    SourceKey
-    )
-{
-    HRESULT     Error;
-    DWORD       Values;
-    DWORD       MaxNameLength;
-    PTCHAR      Name;
-    DWORD       MaxValueLength;
-    LPBYTE      Value;
-    DWORD       Index;
-
-    Log("====>");
-
-    Error = RegQueryInfoKey(SourceKey,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            NULL,
-                            &Values,
-                            &MaxNameLength,
-                            &MaxValueLength,
-                            NULL,
-                            NULL);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail1;
-    }
-
-    Log("%d VALUES", Values);
-
-    if (Values == 0)
-        goto done;
-
-    MaxNameLength += sizeof (TCHAR);
-
-    Name = malloc(MaxNameLength);
-    if (Name == NULL)
-        goto fail2;
-
-    Value = malloc(MaxValueLength);
-    if (Value == NULL)
-        goto fail3;
-
-    for (Index = 0; Index < Values; Index++) {
-        DWORD   NameLength;
-        DWORD   ValueLength;
-        DWORD   Type;
-
-        NameLength = MaxNameLength;
-        memset(Name, 0, NameLength);
-
-        ValueLength = MaxValueLength;
-        memset(Value, 0, ValueLength);
-
-        Error = RegEnumValue(SourceKey,
-                             Index,
-                             (LPTSTR)Name,
-                             &NameLength,
-                             NULL,
-                             &Type,
-                             Value,
-                             &ValueLength);
-        if (Error != ERROR_SUCCESS) {
-            SetLastError(Error);
-            goto fail4;
-        }
-
-        Error = RegSetValueEx(DestinationKey,
-                              Name,
-                              0,
-                              Type,
-                              Value,
-                              ValueLength);
-        if (Error != ERROR_SUCCESS) {
-            SetLastError(Error);
-            goto fail5;
-        }
-
-        Log("COPIED %s", Name);
-    }
-
-    free(Value);
-    free(Name);
-
-done:
-    Log("<====");
-
-    return TRUE;
-
-fail5:
-    Log("fail5");
-
-fail4:
-    Log("fail4");
-
-    free(Value);
-
-fail3:
-    Log("fail3");
-
-    free(Name);
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Log("fail1");
-
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-
-}
-
-static BOOLEAN
-CopyValues(
-    IN  PTCHAR  DestinationKeyName,
-    IN  PTCHAR  SourceKeyName
+CopyValues(
+    IN  PTCHAR  DestinationKeyName,
+    IN  PTCHAR  SourceKeyName
     )
 {
     HRESULT     Error;
@@ -2589,356 +1602,55 @@ GetIpVersion6AddressValueName(
     if (Type != REG_DWORD) {
         SetLastError(ERROR_BAD_FORMAT);
         goto fail6;
-    }
-
-    NetLuid.Info.IfType = *Value;
-
-    BufferLength = ((sizeof (ULONG64) * 2) + 1) * sizeof (TCHAR);
-
-    Buffer = calloc(1, BufferLength);
-    if (Buffer == NULL)
-        goto fail7;
-
-    Result = StringCbPrintf(Buffer,
-                            BufferLength,
-                            "%016llx",
-                            _byteswap_uint64(NetLuid.Value));
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail8;
-    }
-
-    free(Value);
-
-    return Buffer;
-
-fail8:
-    Log("fail8");
-
-    free(Buffer);
-
-fail7:
-    Log("fail7");
-
-fail6:
-    Log("fail6");
-
-fail5:
-    Log("fail5");
-
-fail4:
-    Log("fail4");
-
-fail3:
-    Log("fail3");
-
-    free(Value);
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return NULL;
-}
-
-static BOOLEAN
-CopySettings(
-    IN  HKEY    DestinationKey,
-    IN  HKEY    SourceKey
-    )
-{
-    PTCHAR      DestinationName;
-    PTCHAR      SourceName;
-    BOOLEAN     Success;
-    HRESULT     Error;
-
-    Log("====>");
-
-    Success = TRUE;
-
-    SourceName = GetInterfaceName(SourceKey);
-
-    if (SourceName == NULL)
-        goto fail1;
-
-    DestinationName = GetInterfaceName(DestinationKey);
-
-    if (DestinationName == NULL)
-        goto fail2;
-
-    Success &= CopyParameters(PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_",
-                              DestinationName,
-                              SourceName);
-    Success &= CopyParameters(PARAMETERS_KEY(Tcpip) "\\Interfaces\\",
-                              DestinationName,
-                              SourceName);
-    Success &= CopyParameters(PARAMETERS_KEY(Tcpip6) "\\Interfaces\\",
-                              DestinationName,
-                              SourceName);
-
-    free(DestinationName);
-    free(SourceName);
-
-    SourceName = GetIpVersion6AddressValueName(SourceKey);
-
-    if (SourceName == NULL)
-        goto fail3;
-
-    DestinationName = GetIpVersion6AddressValueName(DestinationKey);
-
-    if (DestinationName == NULL)
-        goto fail4;
-
-    Success &= CopyIpVersion6Addresses(NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\",
-                                       NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\",
-                                       DestinationName,
-                                       SourceName);
-
-    free(DestinationName);
-    free(SourceName);
-
-    Log("<====");
-
-    return Success;
-
-fail4:
-    Log("fail4");
-
-    free(SourceName);
-    goto fail1;
-
-fail3:
-    Log("fail3");
-
-fail2:
-    Log("fail2");
-
-    free(SourceName);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static HKEY 
-CreateFormattedKey(
-    IN LPCTSTR Format, 
-    IN ...
-    )
-{
-
-    HRESULT     Result;
-    TCHAR       KeyName[MAX_PATH];
-    HKEY        Key;
-    HRESULT     Error;
-    va_list     Args;
-    
-    va_start(Args, Format);
-
-    Result = StringCbVPrintf(KeyName,
-                            MAX_PATH,
-                            Format,
-                            Args);
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
-        goto fail1;
-    }
-
-    Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
-                           KeyName,
-                           0,
-                           NULL,
-                           REG_OPTION_NON_VOLATILE,
-                           KEY_ALL_ACCESS,
-                           NULL,
-                           &Key,
-                           NULL);
-    if (Error != ERROR_SUCCESS) {
-        Log("Unable to find key %s",KeyName);
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    va_end(Format);
-   
-    return Key;
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    va_end(Format);
-    return NULL;
-}
-
-static BOOLEAN
-CopySettingsFromInstaller(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PTCHAR                      Name
-    )
-{
-    HKEY                            Destination;
-    HRESULT                         Error;
-    PTCHAR                          DestinationName;
-    HKEY                            Tcpip6Dst;
-    HKEY                            TcpipDst;
-    HKEY                            NetbtDst;
-    HKEY                            Tcpip6Src;
-    HKEY                            TcpipSrc;
-    HKEY                            NetbtSrc;
-    PTCHAR                          InstallerSettingsPath;
-    PTCHAR                          IPv6DstName;
-
-    Destination = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
-    if (Destination == NULL)
-        goto fail1;
-
-    DestinationName = GetInterfaceName(Destination);
-    if (DestinationName == NULL)
-        goto fail2;
-
-
-    NetbtSrc = OpenInstallerSettingsKey(Name, "nbt");
-    if (NetbtSrc == NULL)
-        goto fail3;
-
-    Log("Looking for destination %s", DestinationName);
-    NetbtDst = CreateFormattedKey(PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_%s", DestinationName);
-    if (NetbtDst == NULL)
-        goto fail4;
-
-    if (!CopyKeyValues(NetbtDst, NetbtSrc))
-        goto fail5;
-
-    TcpipSrc = OpenInstallerSettingsKey(Name, "tcpip");
-    if (TcpipSrc == NULL)
-        goto fail6;
-
-    TcpipDst = CreateFormattedKey(PARAMETERS_KEY(Tcpip) "\\Interfaces\\%s", DestinationName);
-    if (TcpipDst == NULL)
-        goto fail7;
-
-    if (!CopyKeyValues(TcpipDst, TcpipSrc))
-        goto fail8;
-
-    Tcpip6Src = OpenInstallerSettingsKey(Name, "tcpip6");
-    if (Tcpip6Src == NULL)
-        goto fail9;
-
-    Tcpip6Dst = CreateFormattedKey(PARAMETERS_KEY(Tcpip6) "\\Interfaces\\%s", DestinationName);
-    if (Tcpip6Dst == NULL)
-        goto fail10;
-
-    if (!CopyKeyValues(Tcpip6Dst, Tcpip6Src))
-        goto fail11;
-
-    InstallerSettingsPath = GetInstallerSettingsPath(Name);
-
-    if (InstallerSettingsPath == NULL)
-        goto fail12;
-
-    IPv6DstName = GetIpVersion6AddressValueName(Destination);
-
-    if (IPv6DstName == NULL)
-        goto fail13;
-
-    if (!CopyIpVersion6Addresses(NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\",
-                                 InstallerSettingsPath,
-                                 IPv6DstName,
-                                 "IPv6_Address_____"))
-        goto fail14;
+    }
 
-    free(IPv6DstName);
-    free(InstallerSettingsPath);
-    RegCloseKey(Tcpip6Dst);
-    RegCloseKey(Tcpip6Src);
-    RegCloseKey(TcpipDst);
-    RegCloseKey(TcpipSrc);
-    RegCloseKey(NetbtDst);
-    RegCloseKey(NetbtSrc);
-    free(DestinationName);
-    RegCloseKey(Destination);
-    return TRUE;
+    NetLuid.Info.IfType = *Value;
 
-fail14:
-    Log("fail14");
-    free(IPv6DstName);
+    BufferLength = ((sizeof (ULONG64) * 2) + 1) * sizeof (TCHAR);
 
-fail13:
-    Log("fail13");
-    free(InstallerSettingsPath);
+    Buffer = calloc(1, BufferLength);
+    if (Buffer == NULL)
+        goto fail7;
 
-fail12:
-    Log("fail12");
+    Result = StringCbPrintf(Buffer,
+                            BufferLength,
+                            "%016llx",
+                            _byteswap_uint64(NetLuid.Value));
+    if (!SUCCEEDED(Result)) {
+        SetLastError(ERROR_BUFFER_OVERFLOW);
+        goto fail8;
+    }
 
-fail11:
-    Log("fail11");
-    RegCloseKey(Tcpip6Dst);
+    free(Value);
 
-fail10:
-    Log("fail10");
-    RegCloseKey(TcpipSrc);
+    return Buffer;
 
-fail9:
-    Log("fail9");
 fail8:
     Log("fail8");
-    RegCloseKey(TcpipDst);
+
+    free(Buffer);
 
 fail7:
     Log("fail7");
-    RegCloseKey(TcpipSrc);
 
 fail6:
     Log("fail6");
+
 fail5:
     Log("fail5");
-    RegCloseKey(NetbtDst);
 
 fail4:
     Log("fail4");
-    RegCloseKey(NetbtSrc);
 
 fail3:
     Log("fail3");
-    free(DestinationName);
+
+    free(Value);
 
 fail2:
     Log("fail2");
-    RegCloseKey(Destination);
 
 fail1:
-    Log("fail1");
-
     Error = GetLastError();
 
     {
@@ -2949,44 +1661,86 @@ fail1:
         LocalFree(Message);
     }
 
-    return FALSE;
+    return NULL;
 }
 
 static BOOLEAN
-CopySettingsFromAlias(
-    IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData,
-    IN  PTCHAR                      Name
+CopySettings(
+    IN  HKEY    DestinationKey,
+    IN  HKEY    SourceKey
     )
 {
-    HKEY                            Source;
-    HKEY                            Destination;
-    BOOLEAN                         Success;
-    HRESULT                         Error;
+    PTCHAR      DestinationName;
+    PTCHAR      SourceName;
+    BOOLEAN     Success;
+    HRESULT     Error;
 
-    Source = OpenAliasSoftwareKey(Name);
-    if (Source == NULL)
+    Log("====>");
+
+    Success = TRUE;
+
+    SourceName = GetInterfaceName(SourceKey);
+
+    if (SourceName == NULL)
         goto fail1;
 
-    Destination = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
-    if (Destination == NULL)
+    DestinationName = GetInterfaceName(DestinationKey);
+
+    if (DestinationName == NULL)
         goto fail2;
 
-    Success = CopySettings(Destination, Source);
-    if (!Success)
+    if (_stricmp(SourceName, DestinationName) == 0)
+        goto done;
+
+    Success &= CopyParameters(PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_",
+                              DestinationName,
+                              SourceName);
+    Success &= CopyParameters(PARAMETERS_KEY(Tcpip) "\\Interfaces\\",
+                              DestinationName,
+                              SourceName);
+    Success &= CopyParameters(PARAMETERS_KEY(Tcpip6) "\\Interfaces\\",
+                              DestinationName,
+                              SourceName);
+
+    free(DestinationName);
+    free(SourceName);
+
+    SourceName = GetIpVersion6AddressValueName(SourceKey);
+
+    if (SourceName == NULL)
         goto fail3;
 
-    return TRUE;
+    DestinationName = GetIpVersion6AddressValueName(DestinationKey);
+
+    if (DestinationName == NULL)
+        goto fail4;
+
+    Success &= CopyIpVersion6Addresses(NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\",
+                                       NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\",
+                                       DestinationName,
+                                       SourceName);
+
+done:
+    free(DestinationName);
+    free(SourceName);
+
+    Log("<====");
+
+    return Success;
+
+fail4:
+    Log("fail4");
+
+    free(SourceName);
+    goto fail1;
 
 fail3:
     Log("fail3");
 
-    RegCloseKey(Destination);
-
 fail2:
     Log("fail2");
 
-    RegCloseKey(Source);
+    free(SourceName);
 
 fail1:
     Error = GetLastError();
@@ -3003,10 +1757,10 @@ fail1:
 }
 
 static BOOLEAN
-CopySettingsToAlias(
-    IN  PTCHAR                      Name,
+CopySettingsFromAlias(
     IN  HDEVINFO                    DeviceInfoSet,
-    IN  PSP_DEVINFO_DATA            DeviceInfoData
+    IN  PSP_DEVINFO_DATA            DeviceInfoData,
+    IN  PTCHAR                      Name
     )
 {
     HKEY                            Source;
@@ -3014,11 +1768,13 @@ CopySettingsToAlias(
     BOOLEAN                         Success;
     HRESULT                         Error;
 
-    Source = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
+    Log("====> (%s)", Name);
+
+    Source = OpenAliasSoftwareKey(Name);
     if (Source == NULL)
         goto fail1;
 
-    Destination = OpenAliasSoftwareKey(Name);
+    Destination = OpenSoftwareKey(DeviceInfoSet, DeviceInfoData);
     if (Destination == NULL)
         goto fail2;
 
@@ -3026,6 +1782,12 @@ CopySettingsToAlias(
     if (!Success)
         goto fail3;
 
+    RegCloseKey(Destination);
+
+    RegCloseKey(Source);
+
+    Log("<====");
+
     return TRUE;
 
 fail3:
@@ -3053,180 +1815,126 @@ fail1:
 }
 
 static BOOLEAN
-RequestUnplug(
-    VOID          
+InstallUnplugService(
+    IN  PTCHAR      ClassName,
+    IN  PTCHAR      ServiceName
     )
 {
-    HKEY    UnplugKey;
-    DWORD   NicsLength;
-    PTCHAR  Nics;
-    DWORD   Offset;
-    HRESULT Error;
-    HRESULT Result;
+    HKEY            UnplugKey;
+    HRESULT         Error;
+    DWORD           Type;
+    DWORD           OldLength;
+    DWORD           NewLength;
+    PTCHAR          ServiceNames;
+    ULONG           Offset;
 
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         UNPLUG_KEY(XENFILT),
-                         0,
-                         KEY_ALL_ACCESS,
-                         &UnplugKey);
+    Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+                           UNPLUG_KEY,
+                           0,
+                           NULL,
+                           REG_OPTION_NON_VOLATILE,
+                           KEY_ALL_ACCESS,
+                           NULL,
+                           &UnplugKey,
+                           NULL);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
         goto fail1;
     }
 
-    NicsLength = (DWORD)((strlen("XENVIF") + 1 +
-                          strlen("XENNET") + 1 +
-                          1) * sizeof (TCHAR));
-
-    Nics = calloc(1, NicsLength);
-    if (Nics == NULL)
-        goto fail2;
-
-    Offset = 0;
+    Error = RegQueryValueEx(UnplugKey,
+                            ClassName,
+                            NULL,
+                            &Type,
+                            NULL,
+                            &OldLength);
+    if (Error != ERROR_SUCCESS) {
+        if (Error == ERROR_FILE_NOT_FOUND) {
+            Type = REG_MULTI_SZ;
+            OldLength = sizeof (TCHAR);
+        } else {
+            SetLastError(Error);
+            goto fail2;
+        }
+    }
 
-    Result = StringCbPrintf(Nics + Offset,
-                            NicsLength - (Offset * sizeof (TCHAR)),
-                            "XENVIF");
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
+    if (Type != REG_MULTI_SZ) {
+        SetLastError(ERROR_BAD_FORMAT);
         goto fail3;
     }
 
-    Offset += (DWORD)(strlen("XENVIF") + 1);
+    NewLength = OldLength + (DWORD)((strlen(ServiceName) + 1) * sizeof (TCHAR));
 
-    Result = StringCbPrintf(Nics + Offset,
-                            NicsLength - (Offset * sizeof (TCHAR)),
-                            "XENNET");
-    if (!SUCCEEDED(Result)) {
-        SetLastError(ERROR_BUFFER_OVERFLOW);
+    ServiceNames = calloc(1, NewLength);
+    if (ServiceNames == NULL)
         goto fail4;
-    }
 
-    Offset += (DWORD)(strlen("XENNET") + 1);
+    Offset = 0;
+    if (OldLength != sizeof (TCHAR)) {
+        Error = RegQueryValueEx(UnplugKey,
+                                ClassName,
+                                NULL,
+                                &Type,
+                                (LPBYTE)ServiceNames,
+                                &OldLength);
+        if (Error != ERROR_SUCCESS) {
+            SetLastError(ERROR_BAD_FORMAT);
+            goto fail5;
+        }
+
+        while (ServiceNames[Offset] != '\0') {
+            ULONG   ServiceNameLength;
 
-    *(Nics + Offset) = '\0';
+            ServiceNameLength = (ULONG)strlen(&ServiceNames[Offset]) / sizeof (TCHAR);
+
+            if (_stricmp(&ServiceNames[Offset], ServiceName) == 0) {
+                Log("%s already present", ServiceName);
+                goto done;
+            }
+
+            Offset += ServiceNameLength + 1;
+        }
+    }
+
+    memmove(&ServiceNames[Offset], ServiceName, strlen(ServiceName));
+    Log("added %s", ServiceName);
 
     Error = RegSetValueEx(UnplugKey,
-                          "NICS",
+                          ClassName,
                           0,
                           REG_MULTI_SZ,
-                          (LPBYTE)Nics,
-                          NicsLength);
+                          (LPBYTE)ServiceNames,
+                          NewLength);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail5;
+        goto fail6;
     }
 
-    free(Nics);
+done:
+    free(ServiceNames);
 
     RegCloseKey(UnplugKey);
 
     return TRUE;
 
-fail5:
+fail6:
     Log("fail5");
 
-fail4:
-    Log("fail4");
-
-fail3:
-    Log("fail3");
-
-    free(Nics);
-
-fail2:
-    Log("fail2");
-
-    RegCloseKey(UnplugKey);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return FALSE;
-}
-
-static BOOLEAN
-IncrementServiceCount(
-    OUT PDWORD  Count
-    )
-{
-    HKEY        ServiceKey;
-    DWORD       Value;
-    DWORD       ValueLength;
-    DWORD       Type;
-    HRESULT     Error;
-
-    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         SERVICE_KEY(XENNET),
-                         0,
-                         KEY_ALL_ACCESS,
-                         &ServiceKey);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail1;
-    }
-
-    ValueLength = sizeof (DWORD);
-
-    Error = RegQueryValueEx(ServiceKey,
-                            "Count",
-                            NULL,
-                            &Type,
-                            (LPBYTE)&Value,
-                            &ValueLength);
-    if (Error != ERROR_SUCCESS) {
-        if (Error == ERROR_FILE_NOT_FOUND) {
-            Value = 0;
-            goto done;
-        }
-
-        SetLastError(Error);
-        goto fail2;
-    }
-
-    if (Type != REG_DWORD) {
-        SetLastError(ERROR_BAD_FORMAT);
-        goto fail3;
-    }
-
-done:
-    Value++;
-
-    Error = RegSetValueEx(ServiceKey,
-                          "Count",
-                          0,
-                          REG_DWORD,
-                          (LPBYTE)&Value,
-                          ValueLength);
-    if (Error != ERROR_SUCCESS) {
-        SetLastError(Error);
-        goto fail4;
-    }
-
-    *Count = Value;
-
-    RegCloseKey(ServiceKey);
+fail5:
+    Log("fail5");
 
-    return TRUE;
+    free(ServiceNames);
 
 fail4:
-    Log("fail4");
+    Log("fail5");
 
 fail3:
-    Log("fail3");
+    Log("fail5");
 
 fail2:
-    Log("fail2");
+    Log("fail5");
 
-    RegCloseKey(ServiceKey);
+    RegCloseKey(UnplugKey);
 
 fail1:
     Error = GetLastError();
@@ -3243,75 +1951,109 @@ fail1:
 }
 
 static BOOLEAN
-DecrementServiceCount(
-    OUT PDWORD  Count
+RemoveUnplugService(
+    IN  PTCHAR      ClassName,
+    IN  PTCHAR      ServiceName
     )
 {
-    HKEY        ServiceKey;
-    DWORD       Value;
-    DWORD       ValueLength;
-    DWORD       Type;
-    HRESULT     Error;
-
-    Log("====>");
+    HKEY            UnplugKey;
+    HRESULT         Error;
+    DWORD           Type;
+    DWORD           OldLength;
+    DWORD           NewLength;
+    PTCHAR          ServiceNames;
+    ULONG           Offset;
+    ULONG           ServiceNameLength;
 
     Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                         SERVICE_KEY(XENNET),
+                         UNPLUG_KEY,
                          0,
                          KEY_ALL_ACCESS,
-                         &ServiceKey);
+                         &UnplugKey);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
         goto fail1;
     }
 
-    ValueLength = sizeof (DWORD);
-
-    Error = RegQueryValueEx(ServiceKey,
-                            "Count",
+    Error = RegQueryValueEx(UnplugKey,
+                            ClassName,
                             NULL,
                             &Type,
-                            (LPBYTE)&Value,
-                            &ValueLength);
+                            NULL,
+                            &OldLength);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
         goto fail2;
     }
 
-    if (Type != REG_DWORD) {
+    if (Type != REG_MULTI_SZ) {
         SetLastError(ERROR_BAD_FORMAT);
         goto fail3;
     }
 
-    if (Value == 0) {
-        SetLastError(ERROR_INVALID_DATA);
+    ServiceNames = calloc(1, OldLength);
+    if (ServiceNames == NULL)
         goto fail4;
+
+    Error = RegQueryValueEx(UnplugKey,
+                            ClassName,
+                            NULL,
+                            &Type,
+                            (LPBYTE)ServiceNames,
+                            &OldLength);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(ERROR_BAD_FORMAT);
+        goto fail5;
+    }
+
+    Offset = 0;
+    ServiceNameLength = 0;
+    while (ServiceNames[Offset] != '\0') {
+        ServiceNameLength = (ULONG)strlen(&ServiceNames[Offset]) / sizeof (TCHAR);
+
+        if (_stricmp(&ServiceNames[Offset], ServiceName) == 0)
+            goto remove;
+
+        Offset += ServiceNameLength + 1;
     }
 
-    --Value;
+    goto done;
+
+remove:
+    NewLength = OldLength - ((ServiceNameLength + 1) * sizeof (TCHAR));
+
+    memmove(&ServiceNames[Offset],
+            &ServiceNames[Offset + ServiceNameLength + 1],
+            (NewLength - Offset) * sizeof (TCHAR));
+
+    Log("removed %s", ServiceName);
 
-    Error = RegSetValueEx(ServiceKey,
-                          "Count",
+    Error = RegSetValueEx(UnplugKey,
+                          ClassName,
                           0,
-                          REG_DWORD,
-                          (LPBYTE)&Value,
-                          ValueLength);
+                          REG_MULTI_SZ,
+                          (LPBYTE)ServiceNames,
+                          NewLength);
     if (Error != ERROR_SUCCESS) {
         SetLastError(Error);
-        goto fail5;
+        goto fail6;
     }
 
-    *Count = Value;
-
-    RegCloseKey(ServiceKey);
+done:
+    free(ServiceNames);
 
-    Log("<====");
+    RegCloseKey(UnplugKey);
 
     return TRUE;
 
+fail6:
+    Log("fail6");
+
 fail5:
     Log("fail5");
 
+    free(ServiceNames);
+
 fail4:
     Log("fail4");
 
@@ -3321,7 +2063,7 @@ fail3:
 fail2:
     Log("fail2");
 
-    RegCloseKey(ServiceKey);
+    RegCloseKey(UnplugKey);
 
 fail1:
     Error = GetLastError();
@@ -3344,6 +2086,7 @@ RequestReboot(
     )
 {
     SP_DEVINSTALL_PARAMS    DeviceInstallParams;
+    HRESULT                 Error;
 
     DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
 
@@ -3364,7 +2107,19 @@ RequestReboot(
     return TRUE;
 
 fail2:
+    Log("fail2");
+
 fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
     return FALSE;
 }
 
@@ -3375,67 +2130,13 @@ __DifInstallPreProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    PETHERNET_ADDRESS               Address;
-    PTCHAR                          Name;
-    BOOLEAN                         Success;
-    HRESULT                         Error;
-
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
     UNREFERENCED_PARAMETER(Context);
 
-    Log("====>");
-
-    Success = GetAliasHardwareKeyName(DeviceInfoSet,
-                                      DeviceInfoData,
-                                      &Name);
-    if (Success)
-        goto done;
-
-    Address = GetPermanentAddress(DeviceInfoSet, DeviceInfoData);
-    if (Address == NULL)
-        goto fail1;
-
-    Success = FindAliasHardwareKeyName(Address, &Name);
-    if (!Success)
-        goto fail2;
-
-    Success = SetAliasHardwareKeyName(DeviceInfoSet,
-                                      DeviceInfoData,
-                                      Name);
-    if (!Success)
-        goto fail3;
-
-    free(Address);
-
-done:
-    if (Name != NULL)
-        free(Name);
-
-    Log("<====");
+    Log("<===>");
 
     return NO_ERROR; 
-
-fail3:
-    Log("fail3");
-
-    free(Name);
-
-fail2:
-    Log("fail2");
-
-    free(Address);
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return Error;
 }
 
 static FORCEINLINE HRESULT
@@ -3446,87 +2147,51 @@ __DifInstallPostProcess(
     )
 {
     BOOLEAN                         Success;
-    PTCHAR                          Name;
-    DWORD                           Count;
+    ETHERNET_ADDRESS                Address;
+    PTCHAR                          SoftwareKeyName;
     HRESULT                         Error;
 
-    UNREFERENCED_PARAMETER(DeviceInfoSet);
-    UNREFERENCED_PARAMETER(DeviceInfoData);
+    UNREFERENCED_PARAMETER(Context);
 
     Log("====>");
 
-    Error = Context->InstallResult;
-    if (Error != NO_ERROR) {
-        SetLastError(Error);
+    Success = GetPermanentAddress(DeviceInfoSet,
+                                  DeviceInfoData,
+                                  &Address);
+    if (!Success)
         goto fail1;
-    }
 
-    Success = SetFriendlyName(DeviceInfoSet,
-                              DeviceInfoData);
+    Success = FindAliasSoftwareKeyName(&Address, &SoftwareKeyName);
     if (!Success)
         goto fail2;
 
-    Success = GetInstallerSettingsKeyName(DeviceInfoSet,
-                                          DeviceInfoData,
-                                          &Name);
-    if (!Success)
-        goto fail3;
-
-    if (Name != NULL) {
-        Success = CopySettingsFromInstaller(DeviceInfoSet,
-                                            DeviceInfoData,
-                                            Name);
-
-        free(Name);
-
-        if (!Success)
-            goto fail4;
-
-        goto done;
-    }
-
-    Success = GetAliasSoftwareKeyName(DeviceInfoSet,
-                                      DeviceInfoData,
-                                      &Name);
-    if (!Success)
-        goto fail5;
-
-    if (Name != NULL) {
+    if (SoftwareKeyName != NULL) {
         Success = CopySettingsFromAlias(DeviceInfoSet,
                                         DeviceInfoData,
-                                        Name);
-
-        free(Name);
-
+                                        SoftwareKeyName);
         if (!Success)
-            goto fail6;
+            goto fail3;
     }
 
-done:
-    Success = RequestUnplug();
+    Success = SetFriendlyName(DeviceInfoSet,
+                              DeviceInfoData);
     if (!Success)
-        goto fail7;
+        goto fail4;
 
-    Success = IncrementServiceCount(&Count);
+    Success = InstallUnplugService("NICS", "XENNET");
     if (!Success)
-        goto fail8;
+        goto fail5;
 
-    if (Count == 1)
+    if (SoftwareKeyName != NULL) {
         (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
 
+        free(SoftwareKeyName);
+    }
+
     Log("<====");
 
     return NO_ERROR;
 
-fail8:
-    Log("fail8");
-
-fail7:
-    Log("fail7");
-
-fail6:
-    Log("fail6");
-
 fail5:
     Log("fail5");
 
@@ -3536,6 +2201,9 @@ fail4:
 fail3:
     Log("fail3");
 
+    if (SoftwareKeyName != NULL)
+        free(SoftwareKeyName);
+
 fail2:
     Log("fail2");
 
@@ -3560,44 +2228,24 @@ DifInstall(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    SP_DEVINSTALL_PARAMS            DeviceInstallParams;
     HRESULT                         Error;
 
-    DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
-
-    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
-                                       DeviceInfoData,
-                                       &DeviceInstallParams))
-        goto fail1;
-
-    Log("Flags = %08x", DeviceInstallParams.Flags);
-
     if (!Context->PostProcessing) {
         Error = __DifInstallPreProcess(DeviceInfoSet, DeviceInfoData, Context);
-
-        Context->PrivateData = (PVOID)Error;
-
-        Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
+        if (Error == NO_ERROR)
+            Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
     } else {
-        Error = (HRESULT)(DWORD_PTR)Context->PrivateData;
+        Error = Context->InstallResult;
         
-        if (Error == NO_ERROR)
+        if (Error == NO_ERROR) {
             (VOID) __DifInstallPostProcess(DeviceInfoSet, DeviceInfoData, Context);
+        } else {
+            PTCHAR  Message;
 
-        Error = NO_ERROR; 
-    }
-
-    return Error;
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
+            Message = __GetErrorMessage(Error);
+            Log("NOT RUNNING (__DifInstallPreProcess Error: %s)", Message);
+            LocalFree(Message);
+        }
     }
 
     return Error;
@@ -3610,58 +2258,16 @@ __DifRemovePreProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    BOOLEAN                         Success;
-    PTCHAR                          Name;
-    HRESULT                         Error;
-
     UNREFERENCED_PARAMETER(Context);
 
     Log("====>");
 
-    Success = GetAliasSoftwareKeyName(DeviceInfoSet,
-                                      DeviceInfoData,
-                                      &Name);
-    if (!Success)
-        goto fail1;
-
-    if (Name != NULL) {
-        Success = CopySettingsToAlias(Name,
-                                      DeviceInfoSet,
-                                      DeviceInfoData);
-
-        free(Name);
-
-        if (!Success)
-            goto fail2;
-    }
-
-    Success = ClearAliasHardwareKeyName(DeviceInfoSet,
-                                        DeviceInfoData);
-    if (!Success)
-        goto fail3;
+    (VOID) RemoveUnplugService("NICS", "XENNET");
+    (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
 
     Log("<====");
 
     return NO_ERROR;
-
-fail3:
-    Log("fail3");
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return Error;
 }
 
 static FORCEINLINE HRESULT
@@ -3671,44 +2277,13 @@ __DifRemovePostProcess(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    BOOLEAN                         Success;
-    DWORD                           Count;
-    HRESULT                         Error;
-
-    Log("====>");
-
-    Error = Context->InstallResult;
-    if (Error != NO_ERROR) {
-        SetLastError(Error);
-        goto fail1;
-    }
-
-    Success = DecrementServiceCount(&Count);
-    if (!Success)
-        goto fail2;
-
-    if (Count == 0)
-        (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
+    UNREFERENCED_PARAMETER(DeviceInfoSet);
+    UNREFERENCED_PARAMETER(DeviceInfoData);
+    UNREFERENCED_PARAMETER(Context);
 
-    Log("<====");
+    Log("<===>");
 
     return NO_ERROR;
-
-fail2:
-    Log("fail2");
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
-    }
-
-    return Error;
 }
 
 static DECLSPEC_NOINLINE HRESULT
@@ -3718,44 +2293,25 @@ DifRemove(
     IN  PCOINSTALLER_CONTEXT_DATA   Context
     )
 {
-    SP_DEVINSTALL_PARAMS            DeviceInstallParams;
     HRESULT                         Error;
 
-    DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
-
-    if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
-                                       DeviceInfoData,
-                                       &DeviceInstallParams))
-        goto fail1;
-
-    Log("Flags = %08x", DeviceInstallParams.Flags);
-
     if (!Context->PostProcessing) {
         Error = __DifRemovePreProcess(DeviceInfoSet, DeviceInfoData, Context);
 
-        Context->PrivateData = (PVOID)Error;
-
-        Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
+        if (Error == NO_ERROR)
+            Error = ERROR_DI_POSTPROCESSING_REQUIRED; 
     } else {
-        Error = (HRESULT)(DWORD_PTR)Context->PrivateData;
+        Error = Context->InstallResult;
         
-        if (Error == NO_ERROR)
+        if (Error == NO_ERROR) {
             (VOID) __DifRemovePostProcess(DeviceInfoSet, DeviceInfoData, Context);
+        } else {
+            PTCHAR  Message;
 
-        Error = NO_ERROR; 
-    }
-
-    return Error;
-
-fail1:
-    Error = GetLastError();
-
-    {
-        PTCHAR  Message;
-
-        Message = __GetErrorMessage(Error);
-        Log("fail1 (%s)", Message);
-        LocalFree(Message);
+            Message = __GetErrorMessage(Error);
+            Log("NOT RUNNING (__DifRemovePreProcess Error: %s)", Message);
+            LocalFree(Message);
+        }
     }
 
     return Error;
@@ -3797,9 +2353,9 @@ Entry(
                               FALSE;
 
         // The NET class installer will call DIF_REMOVE even in the event of
-        // a NULL driver add, so we don't need to do it here. However, the
-        // default installer (for the NULL driver) fails for some reason so
-        // we squash the error in post-processing.
+        // a NULL driver add. However, the default installer (for the NULL
+        // driver) then fails for some reason so we squash the error in
+        // post-processing.
         if (DriverInfoAvailable) {
             Error = DifInstall(DeviceInfoSet, DeviceInfoData, Context);
         } else {
index b86dbb234741f03eca2cb6986bde854d8f672a86..44acfcf1b2818c52d2a814e3a40bf3d228bdefb8 100644 (file)
@@ -60,9 +60,9 @@ xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll
 ; DisplayName          Section         DeviceID
 ; -----------          -------         --------
 
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XSC000&DEV_NET&REV_00000000
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0001&DEV_NET&REV_00000000
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0002&DEV_NET&REV_00000000
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XSC000&DEV_NET&REV_00000001
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0001&DEV_NET&REV_00000001
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_XS0002&DEV_NET&REV_00000001
 
 [XenNet_Inst] 
 Characteristics=0x84
@@ -167,6 +167,10 @@ StartType=%SERVICE_DEMAND_START%
 ErrorControl=%SERVICE_ERROR_NORMAL% 
 ServiceBinary=%12%\xennet.sys 
 LoadOrderGroup="NDIS"
+AddReg = XenNet_BootFlags
+
+[XenNet_BootFlags]
+HKR,"BootFlags",,0x00010003,0x81
 
 [XenNet_EventLog]
 AddReg=XenNet_EventLog_AddReg
index 2a8a7deb9c7b60a8d8e149cd9e8a362ad9a3e5d2..6a852ee70f8022d315cbb3cd583647a154ee4412 100644 (file)
 // List of supported OIDs.
 //
 
-static NDIS_STATUS
-AdapterStop (
-    IN  PADAPTER    Adapter
-    );
-
 static NDIS_STATUS
 AdapterSetRegistrationAttributes (
     IN  PADAPTER Adapter
@@ -223,7 +218,7 @@ AdapterCheckForHang (
 //
 // Frees resources obtained by AdapterInitialize.
 //
-static VOID
+VOID
 AdapterCleanup (
     IN  PADAPTER Adapter
     )
@@ -236,57 +231,13 @@ AdapterCleanup (
     if (Adapter->NdisDmaHandle != NULL)
         NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
 
-    if (Adapter->AcquiredInterfaces) {
-        VIF(Release, Adapter->VifInterface);
-        Adapter->VifInterface = NULL;
-    }
+    XENVIF_VIF(Release, &Adapter->VifInterface);
+    Adapter->AcquiredInterfaces = FALSE;
 
     Trace("<====\n");
     return;
 }
 
-//
-// Frees adapter storage.
-//
-VOID
-AdapterDelete (
-    IN  OUT PADAPTER* Adapter
-    )
-{
-    ASSERT(Adapter != NULL);
-
-    if (*Adapter) {
-        AdapterCleanup(*Adapter);
-        ExFreePool(*Adapter);
-        *Adapter = NULL;
-    }
-
-    return;
-}
-
-//
-// Stops adapter and frees all resources.
-//
-VOID 
-AdapterHalt (
-    IN  NDIS_HANDLE             NdisHandle,
-    IN  NDIS_HALT_ACTION        HaltAction
-    )
-{
-    NDIS_STATUS ndisStatus;
-    PADAPTER Adapter = (PADAPTER)NdisHandle;
-
-    UNREFERENCED_PARAMETER(HaltAction);
-
-
-    ndisStatus = AdapterStop(Adapter);
-    if (ndisStatus == NDIS_STATUS_SUCCESS) {
-        AdapterDelete(&Adapter);
-    }
-
-    return;
-}
-
 static VOID
 AdapterMediaStateChange(
     IN  PADAPTER                Adapter
@@ -301,11 +252,11 @@ AdapterMediaStateChange(
     LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
     LinkState.Header.Size = sizeof(NDIS_LINK_STATE);
 
-    VIF(QueryMediaState,
-        Adapter->VifInterface,
-        &LinkState.MediaConnectState,
-        &LinkState.RcvLinkSpeed,
-        &LinkState.MediaDuplexState);
+    XENVIF_VIF(MacQueryState,
+               &Adapter->VifInterface,
+               &LinkState.MediaConnectState,
+               &LinkState.RcvLinkSpeed,
+               &LinkState.MediaDuplexState);
 
     if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
         Info("LINK: STATE UNKNOWN\n");
@@ -345,17 +296,17 @@ AdapterMediaStateChange(
 
 static VOID
 AdapterVifCallback(
-    IN  PVOID                   Context,
-    IN  XENVIF_CALLBACK_TYPE    Type,
+    IN  PVOID                       Context,
+    IN  XENVIF_VIF_CALLBACK_TYPE    Type,
     ...)
 {
-    PADAPTER                    Adapter = Context;
-    va_list                     Arguments;
+    PADAPTER                        Adapter = Context;
+    va_list                         Arguments;
 
     va_start(Arguments, Type);
 
     switch (Type) {
-    case XENVIF_CALLBACK_COMPLETE_PACKETS: {
+    case XENVIF_TRANSMITTER_RETURN_PACKETS: {
         PXENVIF_TRANSMITTER_PACKET HeadPacket;
 
         HeadPacket = va_arg(Arguments, PXENVIF_TRANSMITTER_PACKET);
@@ -363,7 +314,7 @@ AdapterVifCallback(
         TransmitterCompletePackets(Adapter->Transmitter, HeadPacket);
         break;
     }
-    case XENVIF_CALLBACK_RECEIVE_PACKETS: {
+    case XENVIF_RECEIVER_QUEUE_PACKETS: {
         PLIST_ENTRY List;
 
         List = va_arg(Arguments, PLIST_ENTRY);
@@ -371,7 +322,7 @@ AdapterVifCallback(
         ReceiverReceivePackets(&Adapter->Receiver, List);
         break;
     }
-    case XENVIF_CALLBACK_MEDIA_STATE_CHANGE: {
+    case XENVIF_MAC_STATE_CHANGE: {
         AdapterMediaStateChange(Adapter);
         break;
     }
@@ -445,6 +396,12 @@ AdapterInitialize (
     NDIS_SG_DMA_DESCRIPTION DmaDescription;
     NTSTATUS status;
 
+    status = XENVIF_VIF(Acquire, &Adapter->VifInterface);
+    if (!NT_SUCCESS(status))
+        return NDIS_STATUS_FAILURE;
+
+    Adapter->AcquiredInterfaces = TRUE;
+
     Trace("====>\n");
 
     Adapter->NdisAdapterHandle = AdapterHandle;
@@ -506,12 +463,10 @@ AdapterInitialize (
         Adapter->NdisDmaHandle = NULL;
 
     ASSERT(!Adapter->Enabled);
-    VIF(Acquire, Adapter->VifInterface);
-
-    status = VIF(Enable,
-                 Adapter->VifInterface,
-                 AdapterVifCallback,
-                 Adapter);
+    status = XENVIF_VIF(Enable,
+                        &Adapter->VifInterface,
+                        AdapterVifCallback,
+                        Adapter);
     if (NT_SUCCESS(status)) {
         TransmitterEnable(Adapter->Transmitter);
         Adapter->Enabled = TRUE;
@@ -521,6 +476,9 @@ AdapterInitialize (
     }
 
 exit:
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        XENVIF_VIF(Release, &Adapter->VifInterface);
+
     Trace("<==== (%08x)\n", ndisStatus);
     return ndisStatus;
 }
@@ -594,8 +552,8 @@ AdapterPause (
     if (!Adapter->Enabled)
         goto done;
 
-    VIF(Disable,
-        Adapter->VifInterface);
+    XENVIF_VIF(Disable,
+               &Adapter->VifInterface);
 
     AdapterMediaStateChange(Adapter);
 
@@ -654,11 +612,7 @@ AdapterQueryGeneralStatistics (
     )
 {
     NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
-    XENVIF_PACKET_STATISTICS Statistics;
-
-    VIF(QueryPacketStatistics,
-        Adapter->VifInterface,
-        &Statistics);
+    ULONGLONG   Value;
 
     NdisZeroMemory(NdisStatisticsInfo, sizeof(NDIS_STATISTICS_INFO));
     NdisStatisticsInfo->Header.Revision = NDIS_OBJECT_REVISION_1;
@@ -666,63 +620,199 @@ AdapterQueryGeneralStatistics (
     NdisStatisticsInfo->Header.Size = sizeof(NDIS_STATISTICS_INFO);
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR;
-    NdisStatisticsInfo->ifInErrors =
-        Statistics.Receiver.BackendError +
-        Statistics.Receiver.FrontendError;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BACKEND_ERRORS,
+                      &Value);
+
+    NdisStatisticsInfo->ifInErrors = Value;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_FRONTEND_ERRORS,
+                      &Value);
+
+    NdisStatisticsInfo->ifInErrors += Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS;
-    NdisStatisticsInfo->ifInDiscards = Statistics.Receiver.Drop;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_PACKETS_DROPPED,
+                      &Value);
+
+    NdisStatisticsInfo->ifInDiscards = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV;
-    NdisStatisticsInfo->ifHCInOctets = Statistics.Receiver.UnicastBytes +
-                                       Statistics.Receiver.MulticastBytes +
-                                       Statistics.Receiver.BroadcastBytes;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_UNICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInOctets = Value;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_MULTICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInOctets += Value;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BROADCAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInOctets += Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV;
-    NdisStatisticsInfo->ifHCInUcastOctets = Statistics.Receiver.UnicastBytes;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_UNICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInUcastOctets = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV;
-    NdisStatisticsInfo->ifHCInUcastPkts = Statistics.Receiver.Unicast;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_UNICAST_PACKETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInUcastPkts = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV;
-    NdisStatisticsInfo->ifHCInMulticastOctets = Statistics.Receiver.MulticastBytes;  
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_MULTICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInMulticastOctets = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV;
-    NdisStatisticsInfo->ifHCInMulticastPkts = Statistics.Receiver.Multicast;  
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_MULTICAST_PACKETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInMulticastPkts = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV;
-    NdisStatisticsInfo->ifHCInBroadcastOctets = Statistics.Receiver.BroadcastBytes;  
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BROADCAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInBroadcastOctets = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV;
-    NdisStatisticsInfo->ifHCInBroadcastPkts = Statistics.Receiver.Broadcast;  
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_RECEIVER_BROADCAST_PACKETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCInBroadcastPkts = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR;
-    NdisStatisticsInfo->ifOutErrors =
-        Statistics.Transmitter.BackendError +
-        Statistics.Transmitter.FrontendError;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BACKEND_ERRORS,
+                      &Value);
+
+    NdisStatisticsInfo->ifOutErrors = Value;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_FRONTEND_ERRORS,
+                      &Value);
+
+    NdisStatisticsInfo->ifOutErrors += Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT;
-    NdisStatisticsInfo->ifHCOutOctets = Statistics.Transmitter.UnicastBytes + 
-                                        Statistics.Transmitter.MulticastBytes + 
-                                        Statistics.Transmitter.BroadcastBytes;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutOctets = Value;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutOctets += Value;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutOctets += Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT;
-    NdisStatisticsInfo->ifHCOutUcastOctets = Statistics.Transmitter.UnicastBytes;     
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutUcastOctets = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT;
-    NdisStatisticsInfo->ifHCOutUcastPkts = Statistics.Transmitter.Unicast;     
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutUcastPkts = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT;    
-    NdisStatisticsInfo->ifHCOutMulticastOctets = Statistics.Transmitter.MulticastBytes; 
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutMulticastOctets = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT;    
-    NdisStatisticsInfo->ifHCOutMulticastPkts = Statistics.Transmitter.MulticastBytes;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutMulticastPkts = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
-    NdisStatisticsInfo->ifHCOutBroadcastOctets = Statistics.Transmitter.BroadcastBytes; 
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutBroadcastOctets = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT;
-    NdisStatisticsInfo->ifHCOutBroadcastPkts = Statistics.Transmitter.Broadcast;
+
+    (VOID) XENVIF_VIF(QueryStatistic,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                      &Value);
+
+    NdisStatisticsInfo->ifHCOutBroadcastPkts = Value;
 
     NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS;
     NdisStatisticsInfo->ifOutDiscards = 0;
@@ -737,39 +827,39 @@ GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
     XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
     XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
 
-    VIF(QueryFilterLevel,
-        Adapter->VifInterface,
-        ETHERNET_ADDRESS_UNICAST,
-        &UnicastFilterLevel);
+    XENVIF_VIF(MacQueryFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_UNICAST,
+               &UnicastFilterLevel);
 
-    VIF(QueryFilterLevel,
-        Adapter->VifInterface,
-        ETHERNET_ADDRESS_MULTICAST,
-        &MulticastFilterLevel);
+    XENVIF_VIF(MacQueryFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_MULTICAST,
+               &MulticastFilterLevel);
 
-    VIF(QueryFilterLevel,
-        Adapter->VifInterface,
-        ETHERNET_ADDRESS_BROADCAST,
-        &BroadcastFilterLevel);
+    XENVIF_VIF(MacQueryFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_BROADCAST,
+               &BroadcastFilterLevel);
 
     *PacketFilter = 0;
 
-    if (UnicastFilterLevel == MAC_FILTER_ALL) {
-        ASSERT3U(MulticastFilterLevel, ==, MAC_FILTER_ALL);
-        ASSERT3U(BroadcastFilterLevel, ==, MAC_FILTER_ALL);
+    if (UnicastFilterLevel == XENVIF_MAC_FILTER_ALL) {
+        ASSERT3U(MulticastFilterLevel, ==, XENVIF_MAC_FILTER_ALL);
+        ASSERT3U(BroadcastFilterLevel, ==, XENVIF_MAC_FILTER_ALL);
 
         *PacketFilter |= NDIS_PACKET_TYPE_PROMISCUOUS;
         return;
-    } else if (UnicastFilterLevel == MAC_FILTER_MATCHING) {
+    } else if (UnicastFilterLevel == XENVIF_MAC_FILTER_MATCHING) {
         *PacketFilter |= NDIS_PACKET_TYPE_DIRECTED;
     }
 
-    if (MulticastFilterLevel == MAC_FILTER_ALL)
+    if (MulticastFilterLevel == XENVIF_MAC_FILTER_ALL)
         *PacketFilter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
-    else if (MulticastFilterLevel == MAC_FILTER_MATCHING)
+    else if (MulticastFilterLevel == XENVIF_MAC_FILTER_MATCHING)
         *PacketFilter |= NDIS_PACKET_TYPE_MULTICAST;
 
-    if (BroadcastFilterLevel == MAC_FILTER_ALL)
+    if (BroadcastFilterLevel == XENVIF_MAC_FILTER_ALL)
         *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST;
 }
 
@@ -862,18 +952,18 @@ AdapterQueryInformation (
             break;
 
         case OID_GEN_TRANSMIT_BUFFER_SPACE:
-            VIF(QueryTransmitterRingSize,
-                Adapter->VifInterface,
-                (PULONG)&infoData);
+            XENVIF_VIF(TransmitterQueryRingSize,
+                       &Adapter->VifInterface,
+                       (PULONG)&infoData);
             infoData *= Adapter->MaximumFrameSize;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
 
         case OID_GEN_RECEIVE_BUFFER_SPACE:
-            VIF(QueryTransmitterRingSize,
-                Adapter->VifInterface,
-                (PULONG)&infoData);
+            XENVIF_VIF(TransmitterQueryRingSize,
+                       &Adapter->VifInterface,
+                       (PULONG)&infoData);
             infoData *= Adapter->MaximumFrameSize;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
@@ -926,19 +1016,19 @@ AdapterQueryInformation (
 
             doCopy = FALSE;
 
-            VIF(QueryMulticastAddresses,
-                Adapter->VifInterface,
-                NULL,
-                &Count);
+            XENVIF_VIF(MacQueryMulticastAddresses,
+                       &Adapter->VifInterface,
+                       NULL,
+                       &Count);
             bytesAvailable = Count * ETHERNET_ADDRESS_LENGTH;
 
             if (informationBufferLength >= bytesAvailable) {
                 NTSTATUS status;
 
-                status = VIF(QueryMulticastAddresses,
-                             Adapter->VifInterface,
-                             informationBuffer,
-                             &Count);
+                status = XENVIF_VIF(MacQueryMulticastAddresses,
+                                    &Adapter->VifInterface,
+                                    informationBuffer,
+                                    &Count);
                 if (!NT_SUCCESS(status))
                     ndisStatus = NDIS_STATUS_FAILURE;
             }
@@ -946,17 +1036,17 @@ AdapterQueryInformation (
             break;
         }
         case OID_802_3_PERMANENT_ADDRESS:
-            VIF(QueryPermanentAddress,
-                Adapter->VifInterface,
-                (PETHERNET_ADDRESS)&infoData);
+            XENVIF_VIF(MacQueryPermanentAddress,
+                       &Adapter->VifInterface,
+                       (PETHERNET_ADDRESS)&infoData);
             info = &infoData;
             bytesAvailable = sizeof (ETHERNET_ADDRESS);
             break;
 
         case OID_802_3_CURRENT_ADDRESS:
-            VIF(QueryCurrentAddress,
-                Adapter->VifInterface,
-                (PETHERNET_ADDRESS)&infoData);
+            XENVIF_VIF(MacQueryCurrentAddress,
+                       &Adapter->VifInterface,
+                       (PETHERNET_ADDRESS)&infoData);
             info = &infoData;
             bytesAvailable = sizeof (ETHERNET_ADDRESS);
             break;
@@ -992,33 +1082,26 @@ AdapterQueryInformation (
         case OID_GEN_LINK_SPEED: {
             ULONG64 LinkSpeed;
 
-            VIF(QueryMediaState,
-                Adapter->VifInterface,
-                NULL,
-                &LinkSpeed,
-                NULL);
+            XENVIF_VIF(MacQueryState,
+                       &Adapter->VifInterface,
+                       NULL,
+                       &LinkSpeed,
+                       NULL);
 
             infoData = (ULONG)(LinkSpeed / 100);
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
-        case OID_GEN_MEDIA_CONNECT_STATUS: {
-            NET_IF_MEDIA_CONNECT_STATE MediaConnectState;
-
-            VIF(QueryMediaState,
-                Adapter->VifInterface,
-                &MediaConnectState,
-                NULL,
-                NULL);
-
-            infoData = (MediaConnectState != MediaConnectStateDisconnected) ?
-                       NdisMediaStateConnected :
-                       NdisMediaStateDisconnected;
+        case OID_GEN_MEDIA_CONNECT_STATUS:
+            XENVIF_VIF(MacQueryState,
+                       &Adapter->VifInterface,
+                       (PNET_IF_MEDIA_CONNECT_STATE)&infoData,
+                       NULL,
+                       NULL);
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
-        }
         case OID_GEN_MAXIMUM_SEND_PACKETS:
             infoData = 16;
             info = &infoData;
@@ -1032,57 +1115,99 @@ AdapterQueryInformation (
             break;
 
         case OID_GEN_XMIT_OK: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                       &Value);
+
+            infoData = Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData += Value;
 
-            infoData = Statistics.Transmitter.Unicast +
-                       Statistics.Transmitter.Multicast +
-                       Statistics.Transmitter.Broadcast;
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                       &Value);
+
+            infoData += Value;
 
             info = &infoData;
             bytesAvailable = sizeof(ULONGLONG);
             break;
         }
         case OID_GEN_RCV_OK: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_UNICAST_PACKETS,
+                       &Value);
+
+            infoData = Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_MULTICAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData += Value;
 
-            infoData = Statistics.Receiver.Unicast +
-                       Statistics.Receiver.Multicast +
-                       Statistics.Receiver.Broadcast;
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_BROADCAST_PACKETS,
+                       &Value);
+
+            infoData += Value;
 
             info = &infoData;
             bytesAvailable = sizeof(ULONGLONG);
             break;
         }
         case OID_GEN_XMIT_ERROR: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_BACKEND_ERRORS,
+                       &Value);
+
+            infoData = Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_FRONTEND_ERRORS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData += Value;
 
-            infoData = (ULONG)(Statistics.Transmitter.BackendError +
-                               Statistics.Transmitter.FrontendError);
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_RCV_ERROR: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_BACKEND_ERRORS,
+                       &Value);
+
+            infoData = Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_FRONTEND_ERRORS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData += Value;
 
-            infoData = (ULONG)(Statistics.Receiver.BackendError +
-                               Statistics.Receiver.FrontendError);
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
@@ -1100,7 +1225,7 @@ AdapterQueryInformation (
             break;
 
         case OID_802_3_MAXIMUM_LIST_SIZE:
-            infoData = MAXIMUM_MULTICAST_ADDRESS_COUNT;
+            infoData = 32;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
@@ -1126,145 +1251,169 @@ AdapterQueryInformation (
             break;
 
         case OID_GEN_DIRECTED_BYTES_XMIT: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_UNICAST_OCTETS,
+                       &Value);
+
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Transmitter.UnicastBytes;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_DIRECTED_FRAMES_XMIT: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_UNICAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Transmitter.Unicast;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_MULTICAST_BYTES_XMIT: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_MULTICAST_OCTETS,
+                       &Value);
+
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Transmitter.MulticastBytes;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_MULTICAST_FRAMES_XMIT: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_MULTICAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Transmitter.Multicast;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_BROADCAST_BYTES_XMIT: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_BROADCAST_OCTETS,
+                       &Value);
+
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Transmitter.BroadcastBytes;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_BROADCAST_FRAMES_XMIT: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_TRANSMITTER_BROADCAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Transmitter.Broadcast;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_DIRECTED_BYTES_RCV: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_UNICAST_OCTETS,
+                       &Value);
+
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Receiver.UnicastBytes;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_DIRECTED_FRAMES_RCV: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_UNICAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Receiver.Unicast;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_MULTICAST_BYTES_RCV: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_MULTICAST_OCTETS,
+                       &Value);
+
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Receiver.MulticastBytes;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_MULTICAST_FRAMES_RCV: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_MULTICAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Receiver.Multicast;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_BROADCAST_BYTES_RCV: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_BROADCAST_OCTETS,
+                       &Value);
+
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Receiver.BroadcastBytes;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
         }
         case OID_GEN_BROADCAST_FRAMES_RCV: {
-            XENVIF_PACKET_STATISTICS    Statistics;
+            ULONGLONG   Value;
+
+            XENVIF_VIF(QueryStatistic,
+                       &Adapter->VifInterface,
+                       XENVIF_RECEIVER_BROADCAST_PACKETS,
+                       &Value);
 
-            VIF(QueryPacketStatistics,
-                Adapter->VifInterface,
-                &Statistics);
+            infoData = Value;
 
-            infoData = (ULONG)Statistics.Receiver.Broadcast;
             info = &infoData;
             bytesAvailable = sizeof(ULONG);
             break;
@@ -1357,8 +1506,8 @@ AdapterRestart (
         goto done;
     }
 
-    status = VIF(Enable,
-                 Adapter->VifInterface,
+    status = XENVIF_VIF(Enable,
+                 &Adapter->VifInterface,
                  AdapterVifCallback,
                  Adapter);
     if (NT_SUCCESS(status)) {
@@ -1447,9 +1596,9 @@ AdapterSetGeneralAttributes (
 
     generalAttributes.MediaType = XENNET_MEDIA_TYPE;
 
-    VIF(QueryMaximumFrameSize,
-        Adapter->VifInterface,
-        (PULONG)&Adapter->MaximumFrameSize);
+    XENVIF_VIF(MacQueryMaximumFrameSize,
+               &Adapter->VifInterface,
+               (PULONG)&Adapter->MaximumFrameSize);
 
     generalAttributes.MtuSize = Adapter->MaximumFrameSize - sizeof (ETHERNET_TAGGED_HEADER);
     generalAttributes.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
@@ -1464,15 +1613,15 @@ AdapterSetGeneralAttributes (
 
     generalAttributes.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS;
         
-    generalAttributes.MaxMulticastListSize = MAXIMUM_MULTICAST_ADDRESS_COUNT;
+    generalAttributes.MaxMulticastListSize = 32;
     generalAttributes.MacAddressLength = ETHERNET_ADDRESS_LENGTH;
 
-    VIF(QueryPermanentAddress,
-        Adapter->VifInterface,
-        (PETHERNET_ADDRESS)&generalAttributes.PermanentMacAddress);
-    VIF(QueryCurrentAddress,
-        Adapter->VifInterface,
-        (PETHERNET_ADDRESS)&generalAttributes.CurrentMacAddress);
+    XENVIF_VIF(MacQueryPermanentAddress,
+               &Adapter->VifInterface,
+               (PETHERNET_ADDRESS)&generalAttributes.PermanentMacAddress);
+    XENVIF_VIF(MacQueryCurrentAddress,
+               &Adapter->VifInterface,
+               (PETHERNET_ADDRESS)&generalAttributes.CurrentMacAddress);
 
     generalAttributes.PhysicalMediumType = NdisPhysicalMedium802_3;
     generalAttributes.RecvScaleCapabilities = NULL;
@@ -1583,7 +1732,7 @@ AdapterSetOffloadAttributes(
 {
     PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
     NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offloadAttributes;
-    XENVIF_OFFLOAD_OPTIONS Options;
+    XENVIF_VIF_OFFLOAD_OPTIONS Options;
     NDIS_OFFLOAD current;
     NDIS_OFFLOAD supported;
     NDIS_STATUS ndisStatus;
@@ -1611,9 +1760,9 @@ AdapterSetOffloadAttributes(
     NdisZeroMemory(&current, sizeof(current));
     NdisZeroMemory(&supported, sizeof(supported));
     
-    VIF(UpdateOffloadOptions,
-        Adapter->VifInterface,
-        Adapter->Receiver.OffloadOptions);
+    XENVIF_VIF(ReceiverSetOffloadOptions,
+               &Adapter->VifInterface,
+               Adapter->Receiver.OffloadOptions);
 
     supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
     supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
@@ -1638,9 +1787,9 @@ AdapterSetOffloadAttributes(
 
     supported.Checksum.IPv6Receive.UdpChecksum = 1;
 
-    VIF(QueryOffloadOptions,
-        Adapter->VifInterface,
-        &Options);
+    XENVIF_VIF(TransmitterQueryOffloadOptions,
+               &Adapter->VifInterface,
+               &Options);
 
     supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
 
@@ -1672,10 +1821,10 @@ AdapterSetOffloadAttributes(
     if (Options.OffloadIpVersion4LargePacket) {
         ULONG Size;
 
-        VIF(QueryLargePacketSize,
-            Adapter->VifInterface,
-            4,
-            &Size);
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   4,
+                   &Size);
 
         supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
         supported.LsoV2.IPv4.MaxOffLoadSize = Size;
@@ -1685,10 +1834,10 @@ AdapterSetOffloadAttributes(
     if (Options.OffloadIpVersion6LargePacket) {
         ULONG Size;
 
-        VIF(QueryLargePacketSize,
-            Adapter->VifInterface,
-            6,
-            &Size);
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   6,
+                   &Size);
 
         supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
         supported.LsoV2.IPv6.MaxOffLoadSize = Size;
@@ -1801,9 +1950,9 @@ AdapterIndicateOffloadChanged (
         offload.Checksum.IPv6Receive.UdpChecksum = 1;
     }
 
-    VIF(UpdateOffloadOptions,
-        Adapter->VifInterface,
-        Adapter->Receiver.OffloadOptions);
+    XENVIF_VIF(ReceiverSetOffloadOptions,
+               &Adapter->VifInterface,
+               Adapter->Receiver.OffloadOptions);
 
     offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
 
@@ -1837,10 +1986,10 @@ AdapterIndicateOffloadChanged (
     if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
         ULONG Size;
 
-        VIF(QueryLargePacketSize,
-            Adapter->VifInterface,
-            4,
-            &Size);
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   4,
+                   &Size);
 
         offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
         offload.LsoV2.IPv4.MaxOffLoadSize = Size;
@@ -1850,10 +1999,10 @@ AdapterIndicateOffloadChanged (
     if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
         ULONG Size;
 
-        VIF(QueryLargePacketSize,
-            Adapter->VifInterface,
-            6,
-            &Size);
+        XENVIF_VIF(TransmitterQueryLargePacketSize,
+                   &Adapter->VifInterface,
+                   6,
+                   &Size);
 
         offload.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
         offload.LsoV2.IPv6.MaxOffLoadSize = Size;
@@ -1884,12 +2033,10 @@ SetMulticastAddresses(PADAPTER Adapter, PETHERNET_ADDRESS Address, ULONG Count)
 {
     NTSTATUS status;
 
-    ASSERT3U(Count, <=, MAXIMUM_MULTICAST_ADDRESS_COUNT);
-
-    status = VIF(UpdateMulticastAddresses,
-                 Adapter->VifInterface,
-                 Address,
-                 Count);
+    status = XENVIF_VIF(MacSetMulticastAddresses,
+                        &Adapter->VifInterface,
+                        Address,
+                        Count);
     if (!NT_SUCCESS(status))
         return NDIS_STATUS_INVALID_DATA;
 
@@ -1907,44 +2054,44 @@ SetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
         return NDIS_STATUS_INVALID_PARAMETER;
 
     if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
-        UnicastFilterLevel = MAC_FILTER_ALL;
-        MulticastFilterLevel = MAC_FILTER_ALL;
-        BroadcastFilterLevel = MAC_FILTER_ALL;
+        UnicastFilterLevel = XENVIF_MAC_FILTER_ALL;
+        MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
+        BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
         goto done;
     }
 
     if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED)
-        UnicastFilterLevel = MAC_FILTER_MATCHING;
+        UnicastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
     else
-        UnicastFilterLevel = MAC_FILTER_NONE;
+        UnicastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
     if (*PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
-        MulticastFilterLevel = MAC_FILTER_ALL;
+        MulticastFilterLevel = XENVIF_MAC_FILTER_ALL;
     else if (*PacketFilter & NDIS_PACKET_TYPE_MULTICAST)
-        MulticastFilterLevel = MAC_FILTER_MATCHING;
+        MulticastFilterLevel = XENVIF_MAC_FILTER_MATCHING;
     else
-        MulticastFilterLevel = MAC_FILTER_NONE;
+        MulticastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
     if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
-        BroadcastFilterLevel = MAC_FILTER_ALL;
+        BroadcastFilterLevel = XENVIF_MAC_FILTER_ALL;
     else
-        BroadcastFilterLevel = MAC_FILTER_NONE;
+        BroadcastFilterLevel = XENVIF_MAC_FILTER_NONE;
 
 done:
-    VIF(UpdateFilterLevel,
-        Adapter->VifInterface,
-        ETHERNET_ADDRESS_UNICAST,
-        UnicastFilterLevel);
+    XENVIF_VIF(MacSetFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_UNICAST,
+               UnicastFilterLevel);
 
-    VIF(UpdateFilterLevel,
-        Adapter->VifInterface,
-        ETHERNET_ADDRESS_MULTICAST,
-        MulticastFilterLevel);
+    XENVIF_VIF(MacSetFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_MULTICAST,
+               MulticastFilterLevel);
 
-    VIF(UpdateFilterLevel,
-        Adapter->VifInterface,
-        ETHERNET_ADDRESS_BROADCAST,
-        BroadcastFilterLevel);
+    XENVIF_VIF(MacSetFilterLevel,
+               &Adapter->VifInterface,
+               ETHERNET_ADDRESS_BROADCAST,
+               BroadcastFilterLevel);
 
     return NDIS_STATUS_SUCCESS;
 }
@@ -2043,7 +2190,7 @@ AdapterSetInformation (
 
             bytesNeeded = sizeof(*offloadEncapsulation);
             if (informationBufferLength >= bytesNeeded) {
-                XENVIF_OFFLOAD_OPTIONS Options;
+                XENVIF_VIF_OFFLOAD_OPTIONS Options;
 
                 bytesRead = bytesNeeded;
                 offloadEncapsulation = informationBuffer;
@@ -2059,9 +2206,9 @@ AdapterSetInformation (
                         ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
                 }
 
-                VIF(QueryOffloadOptions,
-                    Adapter->VifInterface,
-                    &Options);
+                XENVIF_VIF(TransmitterQueryOffloadOptions,
+                           &Adapter->VifInterface,
+                           &Options);
                 
                 Adapter->Transmitter->OffloadOptions.Value = 0;
                 Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1;
@@ -2146,22 +2293,22 @@ AdapterSetInformation (
                     ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
 
                 if (!no_change(offloadParameters->LsoV2IPv4)) {
-                    XENVIF_OFFLOAD_OPTIONS  Options;
+                    XENVIF_VIF_OFFLOAD_OPTIONS  Options;
 
-                    VIF(QueryOffloadOptions,
-                        Adapter->VifInterface,
-                        &Options);
+                    XENVIF_VIF(TransmitterQueryOffloadOptions,
+                               &Adapter->VifInterface,
+                               &Options);
 
                     if (!(Options.OffloadIpVersion4LargePacket))
                         ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
                 }
 
                 if (!no_change(offloadParameters->LsoV2IPv6)) {
-                    XENVIF_OFFLOAD_OPTIONS  Options;
+                    XENVIF_VIF_OFFLOAD_OPTIONS  Options;
 
-                    VIF(QueryOffloadOptions,
-                        Adapter->VifInterface,
-                        &Options);
+                    XENVIF_VIF(TransmitterQueryOffloadOptions,
+                               &Adapter->VifInterface,
+                               &Options);
 
                     if (!(Options.OffloadIpVersion6LargePacket))
                         ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
@@ -2409,7 +2556,7 @@ AdapterShutdown (
 // Stops transmission of new packets.
 // Stops received packet indication to NDIS.
 //
-static NDIS_STATUS
+NDIS_STATUS
 AdapterStop (
 IN  PADAPTER    Adapter
 )
@@ -2419,8 +2566,8 @@ IN  PADAPTER    Adapter
     if (!Adapter->Enabled)
         goto done;
 
-    VIF(Disable,
-        Adapter->VifInterface);
+    XENVIF_VIF(Disable,
+               &Adapter->VifInterface);
 
     Adapter->Enabled = FALSE;
 
index 529b4445c43f2d89c65d2f1db12eae817491557d..e64e40d5724f2388d6146c57bba7a6549fcd2bab 100644 (file)
@@ -56,7 +56,7 @@ typedef struct _PROPERTIES {
 
 struct _ADAPTER {
     LIST_ENTRY              ListEntry;
-    PXENVIF_VIF_INTERFACE   VifInterface;
+    XENVIF_VIF_INTERFACE    VifInterface;
     BOOLEAN                 AcquiredInterfaces;
     ULONG                   MaximumFrameSize;
     ULONG                   CurrentLookahead;
@@ -91,15 +91,8 @@ AdapterCheckForHang (
     );
 
 VOID
-AdapterDelete (
-    IN  OUT PADAPTER* Adapter
-    );
-
-MINIPORT_HALT AdapterHalt;
-VOID 
-AdapterHalt (
-    IN  NDIS_HANDLE         NdisHandle,
-    IN  NDIS_HALT_ACTION    HaltAction
+AdapterCleanup (
+    IN PADAPTER Adapter
     );
 
 NDIS_STATUS 
@@ -160,7 +153,13 @@ AdapterSendNetBufferLists (
     IN  ULONG               SendFlags
     );
 
+NDIS_STATUS
+AdapterStop (
+    IN  PADAPTER    Adapter
+    );
+
 MINIPORT_SHUTDOWN AdapterShutdown;
+
 VOID 
 AdapterShutdown (
     IN  NDIS_HANDLE             MiniportAdapterContext,
index 66d3734e54eaa425689e07e6fbf31e8720131748..93334ea6df39f75e8c6996088d67acacbfef2bef 100644 (file)
@@ -98,7 +98,7 @@ __Bug(
             if (!(_Lval _OP _Rval)) {               \
                 Error("%s = %llu\n", #_X, _Lval);   \
                 Error("%s = %llu\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
+                ASSERT((_X) _OP (_Y));              \
             }                                       \
         } while (FALSE)
 
@@ -109,7 +109,7 @@ __Bug(
             if (!(_Lval _OP _Rval)) {               \
                 Error("%s = %lld\n", #_X, _Lval);   \
                 Error("%s = %lld\n", #_Y, _Rval);   \
-                ASSERT(_X _OP _Y);                  \
+                ASSERT((_X) _OP (_Y));              \
             }                                       \
         } while (FALSE)
 
@@ -120,27 +120,34 @@ __Bug(
             if (!(_Lval _OP _Rval)) {               \
                 Error("%s = %p\n", #_X, _Lval);     \
                 Error("%s = %p\n", #_Y, _Rval);     \
-                ASSERT(_X _OP _Y);                  \
+                ASSERT((_X) _OP (_Y));              \
             }                                       \
         } while (FALSE)
 
 #else   // DBG
 
-#pragma warning(disable:4100)
+static FORCEINLINE VOID
+_IgnoreAssertion(
+    IN  BOOLEAN Value
+    )
+{
+    UNREFERENCED_PARAMETER(Value);
+}
 
-#define ASSERT(_EXP)                    \
-        do {                            \
-            __analysis_assume(_EXP);    \
+#define ASSERT(_EXP)                        \
+        do {                                \
+            _IgnoreAssertion(_EXP);         \
+            __analysis_assume(_EXP);        \
         } while (FALSE)
 
 #define ASSERT3U(_X, _OP, _Y)           \
-        ASSERT(_X _OP _Y)
+        ASSERT((_X) _OP (_Y))
 
 #define ASSERT3S(_X, _OP, _Y)           \
-        ASSERT(_X _OP _Y)
+        ASSERT((_X) _OP (_Y))
 
 #define ASSERT3P(_X, _OP, _Y)           \
-        ASSERT(_X _OP _Y)
+        ASSERT((_X) _OP (_Y))
 
 #endif  // DBG
 
@@ -172,15 +179,29 @@ _IsZeroMemory(
     return TRUE;
 }
 
-#define IsZeroMemory(_Buffer, _Length) \
-        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
-
 #else   // TEST_MEMORY
 
-#define IsZeroMemory(_Buffer, _Length)  TRUE
+static __inline BOOLEAN
+_IsZeroMemory(
+    IN  const PCHAR Caller,
+    IN  const PCHAR Name,
+    IN  PVOID       Buffer,
+    IN  ULONG       Length
+    )
+{
+    UNREFERENCED_PARAMETER(Caller);
+    UNREFERENCED_PARAMETER(Name);
+    UNREFERENCED_PARAMETER(Buffer);
+    UNREFERENCED_PARAMETER(Length);
+
+    return TRUE;
+}
 
 #endif  // TEST_MEMORY
 
+#define IsZeroMemory(_Buffer, _Length) \
+        _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
+
 #define IMPLY(_X, _Y)   (!(_X) || (_Y))
 #define EQUIV(_X, _Y)   (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
 
index 6786982c59ce2113a2ca04fe83b4bc58eecd162a..6622e82755c05b19734694c8a730c02596ebdccd 100644 (file)
@@ -32,6 +32,7 @@
 #include <version.h>
 
 #include "common.h"
+#include "registry.h"
 
 #pragma NDIS_INIT_FUNCTION(DriverEntry)
 
@@ -42,6 +43,7 @@
 static NDIS_HANDLE MiniportDriverHandle;
 
 extern MINIPORT_INITIALIZE MiniportInitialize;
+
 extern NDIS_STATUS 
 MiniportInitialize (
     IN  NDIS_HANDLE                        MiniportAdapterHandle,
@@ -49,6 +51,14 @@ MiniportInitialize (
     IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
     );
 
+MINIPORT_HALT MiniportHalt;
+
+extern VOID 
+MiniportHalt (
+    IN  NDIS_HANDLE                        MiniportAdapterHandle,
+    IN  NDIS_HALT_ACTION                   HaltAction
+    );
+
 typedef struct _XENNET_CONTEXT {
     PDEVICE_CAPABILITIES    Capabilities;
     PIO_COMPLETION_ROUTINE  CompletionRoutine;
@@ -187,18 +197,33 @@ DriverEntry (
     PNDIS_CONFIGURATION_PARAMETER ParameterValue;
     ULONG FailCreateClose;
     ULONG FailDeviceControl;
+    NTSTATUS status;
 
     ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
 
     Trace("====>\n");
 
-    Info("%s (%s)\n",
-         MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
-         DAY_STR "/" MONTH_STR "/" YEAR_STR);
-
     if (*InitSafeBootMode > 0)
         return NDIS_STATUS_SUCCESS;
 
+    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+    status = RegistryInitialize(RegistryPath);
+
+    ndisStatus = (NT_SUCCESS(status)) ?
+                 NDIS_STATUS_SUCCESS :
+                 NDIS_STATUS_FAILURE;
+
+    if (ndisStatus != NDIS_STATUS_SUCCESS)
+        goto fail;
+
     //
     // Register miniport with NDIS.
     //
@@ -217,7 +242,7 @@ DriverEntry (
     mpChars.CancelSendHandler = AdapterCancelSendNetBufferLists;
     mpChars.CheckForHangHandlerEx = AdapterCheckForHang;
     mpChars.InitializeHandlerEx = MiniportInitialize;
-    mpChars.HaltHandlerEx = AdapterHalt;
+    mpChars.HaltHandlerEx = MiniportHalt;
     mpChars.OidRequestHandler = AdapterOidRequest;    
     mpChars.PauseHandler = AdapterPause;      
     mpChars.DevicePnPEventNotifyHandler  = AdapterPnPEventHandler;
@@ -297,9 +322,12 @@ DriverEntry (
         DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail;
     }
 
-fail:
     Trace("<====\n");
     return ndisStatus;
+
+fail:
+    Error("fail\n");
+    return ndisStatus;
 }
 
 VOID 
@@ -311,8 +339,23 @@ DriverUnload (
 
     Trace("====>\n");
 
+    if (*InitSafeBootMode > 0)
+        goto done;
+
     if (MiniportDriverHandle)
         NdisMDeregisterMiniportDriver(MiniportDriverHandle);
 
+    RegistryTeardown();
+
+    Info("XENNET %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+         MAJOR_VERSION,
+         MINOR_VERSION,
+         MICRO_VERSION,
+         BUILD_NUMBER,
+         DAY,
+         MONTH,
+         YEAR);
+
+done:
     Trace("<====\n");
 }
index 9e0d77982b545611aed1094c108ebe47ae356055..a1d605fe49a893d93016712545c8c04eec3ea3e1 100644 (file)
 #define INITGUID 1
 
 #include "common.h"
+#include "registry.h"
 
 #pragma warning( disable : 4098 )
 
 extern NTSTATUS AllocAdapter(PADAPTER *Adapter);
 
-static NTSTATUS
-QueryVifInterface(
-    IN  PDEVICE_OBJECT      DeviceObject,
-    IN  PADAPTER            Adapter
+#define SERVICES_KEY        L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"
+
+static FORCEINLINE NTSTATUS
+__QueryInterface(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  const WCHAR     *ProviderName,
+    IN  const CHAR      *InterfaceName,
+    IN  const GUID      *Guid,
+    IN  ULONG           Version,
+    OUT PINTERFACE      Interface,
+    IN  ULONG           Size,
+    IN  BOOLEAN         Optional
     )
 {
-    KEVENT                  Event;
-    IO_STATUS_BLOCK         StatusBlock;
-    PIRP                    Irp;
-    PIO_STACK_LOCATION      StackLocation;
-    INTERFACE               Interface;
-    NTSTATUS                status;
+    UNICODE_STRING      Unicode;
+    HANDLE              InterfacesKey;
+    HANDLE              SubscriberKey;
+    KEVENT              Event;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
+
+    ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+    Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) +
+                                      1 +
+                                      wcslen(ProviderName) +
+                                      1 +
+                                      wcslen(L"Interfaces") +
+                                      1) * sizeof (WCHAR));
+
+    Unicode.Buffer = ExAllocatePoolWithTag(NonPagedPool,
+                                           Unicode.MaximumLength,
+                                           'TEN');
+
+    status = STATUS_NO_MEMORY;
+    if (Unicode.Buffer == NULL)
+        goto fail1;
+
+    status = RtlStringCbPrintfW(Unicode.Buffer,
+                                Unicode.MaximumLength,
+                                SERVICES_KEY L"\\%ws\\Interfaces",
+                                ProviderName);
+    ASSERT(NT_SUCCESS(status));
+
+    Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR));
 
+    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = RegistryCreateSubKey(InterfacesKey, 
+                                  "XENNET", 
+                                  REG_OPTION_NON_VOLATILE, 
+                                  &SubscriberKey);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+                   
     KeInitializeEvent(&Event, NotificationEvent, FALSE);
     RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
-    RtlZeroMemory(&Interface, sizeof(INTERFACE));
 
     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
                                        DeviceObject,
@@ -64,51 +110,94 @@ QueryVifInterface(
 
     status = STATUS_UNSUCCESSFUL;
     if (Irp == NULL)
-        goto fail1;
+        goto fail4;
 
     StackLocation = IoGetNextIrpStackLocation(Irp);
     StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
 
-    StackLocation->Parameters.QueryInterface.InterfaceType = &GUID_VIF_INTERFACE;
-    StackLocation->Parameters.QueryInterface.Size = sizeof (INTERFACE);
-    StackLocation->Parameters.QueryInterface.Version = VIF_INTERFACE_VERSION;
-    StackLocation->Parameters.QueryInterface.Interface = &Interface;
+    StackLocation->Parameters.QueryInterface.InterfaceType = Guid;
+    StackLocation->Parameters.QueryInterface.Size = (USHORT)Size;
+    StackLocation->Parameters.QueryInterface.Version = (USHORT)Version;
+    StackLocation->Parameters.QueryInterface.Interface = Interface;
     
     Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
 
     status = IoCallDriver(DeviceObject, Irp);
     if (status == STATUS_PENDING) {
-        KeWaitForSingleObject(&Event,
-                              Executive,
-                              KernelMode,
-                              FALSE,
-                              NULL);
+        (VOID) KeWaitForSingleObject(&Event,
+                                     Executive,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
         status = StatusBlock.Status;
     }
 
+    if (!NT_SUCCESS(status)) {
+        if (status == STATUS_NOT_SUPPORTED && Optional)
+            goto done;
+
+        goto fail5;
+    }
+
+    status = RegistryUpdateDwordValue(SubscriberKey,
+                                      (PCHAR)InterfaceName,
+                                      Version);
     if (!NT_SUCCESS(status))
-        goto fail2;
+        goto fail6;
 
-    status = STATUS_INVALID_PARAMETER;
-    if (Interface.Version != VIF_INTERFACE_VERSION)
-        goto fail3;
+done:
+    RegistryCloseKey(SubscriberKey);
+
+    RegistryCloseKey(InterfacesKey);
 
-    Adapter->VifInterface = Interface.Context;
+    ExFreePool(Unicode.Buffer);
 
     return STATUS_SUCCESS;
 
+fail6:
+    Error("fail6\n");
+
+fail5:
+    Error("fail5\n");
+
+fail4:
+    Error("fail4\n");
+
+    RegistryCloseKey(SubscriberKey);
+
 fail3:
     Error("fail3\n");
 
+    RegistryCloseKey(InterfacesKey);
+
 fail2:
     Error("fail2\n");
 
+    ExFreePool(Unicode.Buffer);
+
 fail1:
     Error("fail1 (%08x)\n", status);
 
     return status;
 }
 
+#define QUERY_INTERFACE(                                                                \
+    _DeviceObject,                                                                      \
+    _ProviderName,                                                                      \
+    _InterfaceName,                                                                     \
+    _Version,                                                                           \
+    _Interface,                                                                         \
+    _Size,                                                                              \
+    _Optional)                                                                          \
+    __QueryInterface((_DeviceObject),                                                   \
+                     L ## #_ProviderName,                                               \
+                     #_InterfaceName,                                                   \
+                     &GUID_ ## _ProviderName ## _ ## _InterfaceName ## _INTERFACE,      \
+                     (_Version),                                                        \
+                     (_Interface),                                                      \
+                     (_Size),                                                           \
+                     (_Optional))
+
 NDIS_STATUS 
 MiniportInitialize (
     IN  NDIS_HANDLE                        MiniportAdapterHandle,
@@ -116,9 +205,9 @@ MiniportInitialize (
     IN  PNDIS_MINIPORT_INIT_PARAMETERS     MiniportInitParameters
     )
 {
-    PADAPTER adapter = NULL;
+    PADAPTER Adapter = NULL;
     NDIS_STATUS ndisStatus;
-    PDEVICE_OBJECT pdo;
+    PDEVICE_OBJECT DeviceObject;
     NTSTATUS status;
 
     UNREFERENCED_PARAMETER(MiniportDriverContext);
@@ -126,43 +215,83 @@ MiniportInitialize (
 
     Trace("====>\n");
 
-    status = AllocAdapter(&adapter);
+    status = AllocAdapter(&Adapter);
 
-    if (!NT_SUCCESS(status) || adapter == NULL) {
+    if (!NT_SUCCESS(status) || Adapter == NULL) {
         ndisStatus = NDIS_STATUS_RESOURCES;
-        goto exit;
+        goto fail1;
     }
 
-    RtlZeroMemory(adapter, sizeof (ADAPTER));
+    RtlZeroMemory(Adapter, sizeof (ADAPTER));
 
-    pdo = NULL;
+    DeviceObject = NULL;
     NdisMGetDeviceProperty(MiniportAdapterHandle,
-                           &pdo,
+                           &DeviceObject,
                            NULL,
                            NULL,
                            NULL,
                            NULL);
 
-    status = QueryVifInterface(pdo, adapter);
+    status = QUERY_INTERFACE(DeviceObject,
+                             XENVIF,
+                             VIF,
+                             XENVIF_VIF_INTERFACE_VERSION_MAX,
+                             (PINTERFACE)&Adapter->VifInterface,
+                             sizeof (Adapter->VifInterface),
+                             FALSE);
+
     if (!NT_SUCCESS(status)) {
         ndisStatus = NDIS_STATUS_ADAPTER_NOT_FOUND;
-        goto exit;
-    }
-
-    adapter->AcquiredInterfaces = TRUE;
-
-    ndisStatus = AdapterInitialize(adapter, MiniportAdapterHandle);
-    if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        goto exit;
+        goto fail2;
     }
 
-exit:
+    ndisStatus = AdapterInitialize(Adapter, MiniportAdapterHandle);
     if (ndisStatus != NDIS_STATUS_SUCCESS) {
-        if (adapter != NULL) {
-            AdapterDelete(&adapter);
-        }
+        goto fail3;
     }
 
     Trace("<====\n");
     return ndisStatus;
+
+fail3:
+    Error("fail3\n");
+
+    RtlZeroMemory(&Adapter->VifInterface,
+                  sizeof (XENVIF_VIF_INTERFACE));
+
+fail2:
+    Error("fail2\n");
+
+    ExFreePool(Adapter);
+
+fail1:
+    Error("fail1\n");
+
+    return ndisStatus;
+}
+
+//
+// Stops adapter and frees all resources.
+//
+VOID 
+MiniportHalt (
+    IN  NDIS_HANDLE             MiniportAdapterHandle,
+    IN  NDIS_HALT_ACTION        HaltAction
+    )
+{
+    PADAPTER Adapter = (PADAPTER)MiniportAdapterHandle;
+
+    UNREFERENCED_PARAMETER(HaltAction);
+
+    if (Adapter == NULL)
+        return;
+
+    (VOID) AdapterStop(Adapter);
+
+    AdapterCleanup(Adapter);
+
+    RtlZeroMemory(&Adapter->VifInterface,
+                  sizeof (XENVIF_VIF_INTERFACE));
+
+    ExFreePool(Adapter);
 }
index efa45fac18c2c25badd3172aaa9312351a7a04b6..54bdc15b1717c5cbf190e5647575a0e74cb45c2f 100644 (file)
@@ -190,10 +190,13 @@ __ReceiverReturnNetBufferLists(
     )
 {
     PADAPTER                Adapter;
+    LIST_ENTRY              List;
     ULONG                   Count;
 
     Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
 
+    InitializeListHead(&List);
+
     Count = 0;
     while (NetBufferList != NULL) {
         PNET_BUFFER_LIST        Next;
@@ -213,14 +216,17 @@ __ReceiverReturnNetBufferLists(
 
         Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl);
 
-        VIF(ReturnPacket,
-            Adapter->VifInterface,
-            Packet);
+        InsertTailList(&List, &Packet->ListEntry);
 
         Count++;
         NetBufferList = Next;
     }
 
+    if (Count != 0)
+        XENVIF_VIF(ReceiverReturnPackets,
+                   &Adapter->VifInterface,
+                   &List);
+
     return Count;
 }
 
@@ -245,7 +251,7 @@ ReceiverReceivePacket(
     IN  PMDL                                    Mdl,
     IN  ULONG                                   Offset,
     IN  ULONG                                   Length,
-    IN  XENVIF_CHECKSUM_FLAGS                   Flags,
+    IN  XENVIF_PACKET_CHECKSUM_FLAGS            Flags,
     IN  USHORT                                  TagControlInformation
     )
 {
@@ -371,10 +377,11 @@ again:
     while (!IsListEmpty(List)) {
         PLIST_ENTRY                     ListEntry;
         PXENVIF_RECEIVER_PACKET         Packet;
+        PXENVIF_PACKET_INFO             Info;
         PMDL                            Mdl;
         ULONG                           Offset;
         ULONG                           Length;
-        XENVIF_CHECKSUM_FLAGS           Flags;
+        XENVIF_PACKET_CHECKSUM_FLAGS    Flags;
         USHORT                          TagControlInformation;
         PNET_BUFFER_LIST                NetBufferList;
 
@@ -392,7 +399,10 @@ again:
         Offset = Packet->Offset;
         Length = Packet->Length;
         Flags = Packet->Flags;
-        TagControlInformation = Packet->TagControlInformation;
+
+        Info = Packet->Info;
+
+        TagControlInformation = Info->TagControlInformation;
 
         NetBufferList = ReceiverReceivePacket(Receiver, Mdl, Offset, Length, Flags, TagControlInformation);
 
@@ -401,9 +411,14 @@ again:
             TailNetBufferList = &NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
             Count++;
         } else {
-            VIF(ReturnPacket,
-                Adapter->VifInterface,
-                Packet);
+            LIST_ENTRY  List;
+
+            InitializeListHead(&List);
+            InsertTailList(&List, &Packet->ListEntry);
+
+            XENVIF_VIF(ReceiverReturnPackets,
+                       &Adapter->VifInterface,
+                       &List);
         }
     }
 
index fe320571dc20a653594ff4328a74048ef33bc5fd..1a58053306e5aae1427ebdb3b2b3e08e20ca4c83 100644 (file)
 #pragma once
 
 typedef struct _RECEIVER {
-    NDIS_HANDLE             NetBufferListPool;
-    PNET_BUFFER_LIST        PutList;
-    PNET_BUFFER_LIST        GetList[MAXIMUM_PROCESSORS];
-    LONG                    InNDIS;
-    LONG                    InNDISMax;
-    XENVIF_OFFLOAD_OPTIONS  OffloadOptions;
+    NDIS_HANDLE                 NetBufferListPool;
+    PNET_BUFFER_LIST            PutList;
+    PNET_BUFFER_LIST            GetList[MAXIMUM_PROCESSORS];
+    LONG                        InNDIS;
+    LONG                        InNDISMax;
+    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
 } RECEIVER, *PRECEIVER;
 
 VOID
diff --git a/src/xennet/registry.c b/src/xennet/registry.c
new file mode 100644 (file)
index 0000000..5843ef5
--- /dev/null
@@ -0,0 +1,1200 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#include <ntddk.h>
+#include <util.h>
+
+#include "registry.h"
+#include "assert.h"
+
+#define REGISTRY_POOL 'GERX'
+
+static UNICODE_STRING   RegistryPath;
+
+static FORCEINLINE PVOID
+__RegistryAllocate(
+    IN  ULONG   Length
+    )
+{
+    return __AllocateNonPagedPoolWithTag(Length, REGISTRY_POOL);
+}
+
+static FORCEINLINE VOID
+__RegistryFree(
+    IN  PVOID   Buffer
+    )
+{
+    __FreePoolWithTag(Buffer, REGISTRY_POOL);
+}
+
+NTSTATUS
+RegistryInitialize(
+    IN PUNICODE_STRING  Path
+    )
+{
+    NTSTATUS            status;
+
+    ASSERT3P(RegistryPath.Buffer, ==, NULL);
+
+    status = RtlUpcaseUnicodeString(&RegistryPath, Path, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+VOID
+RegistryTeardown(
+    VOID
+    )
+{
+    RtlFreeUnicodeString(&RegistryPath);
+    RegistryPath.Buffer = NULL;
+    RegistryPath.MaximumLength = RegistryPath.Length = 0;
+}
+
+NTSTATUS
+RegistryOpenKey(
+    IN  HANDLE          Parent,
+    IN  PUNICODE_STRING Path,
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    )
+{
+    OBJECT_ATTRIBUTES   Attributes;
+    NTSTATUS            status;
+
+    InitializeObjectAttributes(&Attributes,
+                               Path,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               Parent,
+                               NULL);
+
+    status = ZwOpenKey(Key,
+                       DesiredAccess,
+                       &Attributes);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryOpenServiceKey(
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    )
+{
+    return RegistryOpenKey(NULL, &RegistryPath, DesiredAccess, Key);
+}
+
+NTSTATUS
+RegistryOpenSoftwareKey(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    )
+{
+    NTSTATUS            status;
+
+    status = IoOpenDeviceRegistryKey(DeviceObject,
+                                     PLUGPLAY_REGKEY_DRIVER,
+                                     DesiredAccess,
+                                     Key);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    return STATUS_SUCCESS;
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryOpenHardwareKey(
+    IN  PDEVICE_OBJECT      DeviceObject,
+    IN  ACCESS_MASK         DesiredAccess,
+    OUT PHANDLE             Key
+    )
+{
+    HANDLE                  SubKey;
+    ULONG                   Length;
+    PKEY_NAME_INFORMATION   Info;
+    PWCHAR                  Cursor;
+    UNICODE_STRING          Unicode;
+    NTSTATUS                status;
+
+    status = IoOpenDeviceRegistryKey(DeviceObject,
+                                     PLUGPLAY_REGKEY_DEVICE,
+                                     KEY_READ,
+                                     &SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    Length = 0;
+    (VOID) ZwQueryKey(SubKey,
+                      KeyNameInformation,
+                      NULL,
+                      0,
+                      &Length);
+
+    status = STATUS_INVALID_PARAMETER;
+    if (Length == 0)
+        goto fail2;
+    
+    Info = __RegistryAllocate(Length + sizeof (WCHAR));
+
+    status = STATUS_NO_MEMORY;
+    if (Info == NULL)
+        goto fail3;
+
+    status = ZwQueryKey(SubKey,
+                        KeyNameInformation,
+                        Info,
+                        Length,
+                        &Length);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    Info->Name[Info->NameLength / sizeof (WCHAR)] = '\0';
+
+    Cursor = wcsrchr(Info->Name, L'\\');
+    ASSERT(Cursor != NULL);
+
+    *Cursor = L'\0';
+    
+    RtlInitUnicodeString(&Unicode, Info->Name);
+
+    status = RegistryOpenKey(NULL, &Unicode, DesiredAccess, Key);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
+    __RegistryFree(Info);
+
+    RegistryCloseKey(SubKey);
+
+    return STATUS_SUCCESS;
+
+fail5:
+fail4:
+    __RegistryFree(Info);
+
+fail3:
+fail2:
+    RegistryCloseKey(SubKey);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryOpenSubKey(
+    IN  PHANDLE         Key,
+    IN  PCHAR           Name,
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         SubKey
+    )
+{
+    ANSI_STRING         Ansi;
+    UNICODE_STRING      Unicode;
+    NTSTATUS            status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryOpenKey(Key, &Unicode, DesiredAccess, SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryCreateSubKey(
+    IN  PHANDLE         Key,
+    IN  PCHAR           Name,
+    IN  ULONG           Options,
+    OUT PHANDLE         SubKey
+    )
+{
+    ANSI_STRING         Ansi;
+    UNICODE_STRING      Unicode;
+    OBJECT_ATTRIBUTES   Attributes;
+    NTSTATUS            status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    InitializeObjectAttributes(&Attributes,
+                               &Unicode,
+                               OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+                               Key,
+                               NULL);
+
+    status = ZwCreateKey(SubKey,
+                         KEY_ALL_ACCESS,
+                         &Attributes,
+                         0,
+                         NULL,
+                         Options,
+                         NULL
+                         );
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryDeleteSubKey(
+    IN  PHANDLE         Key,
+    IN  PCHAR           Name
+    )
+{
+    ANSI_STRING         Ansi;
+    UNICODE_STRING      Unicode;
+    HANDLE              SubKey;
+    NTSTATUS            status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryOpenKey(Key, &Unicode, KEY_ALL_ACCESS, &SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    status = ZwDeleteKey(SubKey);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    ZwClose(SubKey);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    ZwClose(SubKey);
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryEnumerateSubKeys(
+    IN  HANDLE              Key,
+    IN  NTSTATUS            (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  PVOID               Context
+    )
+{
+    ULONG                   Size;
+    NTSTATUS                status;
+    PKEY_FULL_INFORMATION   Full;
+    PKEY_BASIC_INFORMATION  Basic;
+    ULONG                   Index;
+
+    status = ZwQueryKey(Key,
+                        KeyFullInformation,
+                        NULL,
+                        0,
+                        &Size);
+    if (status != STATUS_BUFFER_TOO_SMALL)
+        goto fail1;
+
+    Full = __RegistryAllocate(Size);
+
+    status = STATUS_NO_MEMORY;
+    if (Full == NULL)
+        goto fail2;
+
+    status = ZwQueryKey(Key,
+                        KeyFullInformation,
+                        Full,
+                        Size,
+                        &Size);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
+           Full->MaxNameLen;
+
+    Basic = __RegistryAllocate(Size);
+    status = STATUS_NO_MEMORY;
+    if (Basic == NULL)
+        goto fail4;
+
+    for (Index = 0; Index < Full->SubKeys; Index++) {
+        UNICODE_STRING  Unicode;
+        ANSI_STRING     Ansi;
+
+        status = ZwEnumerateKey(Key,
+                                Index,
+                                KeyBasicInformation,
+                                Basic,
+                                Size,
+                                &Size);
+        if (!NT_SUCCESS(status))
+            goto fail5;
+
+        Unicode.MaximumLength = (USHORT)Basic->NameLength;
+        Unicode.Buffer = Basic->Name;
+        Unicode.Length = (USHORT)Basic->NameLength;
+
+        Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
+        Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
+
+        status = STATUS_NO_MEMORY;
+        if (Ansi.Buffer == NULL)
+            goto fail6;
+
+        status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
+        ASSERT(NT_SUCCESS(status));
+
+        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        
+
+        status = Callback(Context, Key, Ansi.Buffer);
+
+        __RegistryFree(Ansi.Buffer);
+        Ansi.Buffer = NULL;
+
+        if (!NT_SUCCESS(status))
+            goto fail7;
+    }
+
+    __RegistryFree(Basic);
+
+    __RegistryFree(Full);
+
+    return STATUS_SUCCESS;
+
+fail7:
+fail6:
+fail5:
+    __RegistryFree(Basic);
+
+fail4:
+fail3:
+    __RegistryFree(Full);
+    
+fail2:
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryEnumerateValues(
+    IN  HANDLE                      Key,
+    IN  NTSTATUS                    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  PVOID                       Context
+    )
+{
+    ULONG                           Size;
+    NTSTATUS                        status;
+    PKEY_FULL_INFORMATION           Full;
+    PKEY_VALUE_BASIC_INFORMATION    Basic;
+    ULONG                           Index;
+
+    status = ZwQueryKey(Key,
+                        KeyFullInformation,
+                        NULL,
+                        0,
+                        &Size);
+    if (status != STATUS_BUFFER_TOO_SMALL)
+        goto fail1;
+
+    Full = __RegistryAllocate(Size);
+
+    status = STATUS_NO_MEMORY;
+    if (Full == NULL)
+        goto fail2;
+
+    status = ZwQueryKey(Key,
+                        KeyFullInformation,
+                        Full,
+                        Size,
+                        &Size);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
+           Full->MaxValueNameLen;
+
+    Basic = __RegistryAllocate(Size);
+    status = STATUS_NO_MEMORY;
+    if (Basic == NULL)
+        goto fail4;
+
+    for (Index = 0; Index < Full->Values; Index++) {
+        UNICODE_STRING  Unicode;
+        ANSI_STRING     Ansi;
+
+        status = ZwEnumerateValueKey(Key,
+                                     Index,
+                                     KeyValueBasicInformation,
+                                     Basic,
+                                     Size,
+                                     &Size);
+        if (!NT_SUCCESS(status))
+            goto fail5;
+
+        Unicode.MaximumLength = (USHORT)Basic->NameLength;
+        Unicode.Buffer = Basic->Name;
+        Unicode.Length = (USHORT)Basic->NameLength;
+
+        Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
+        Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
+
+        status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
+        ASSERT(NT_SUCCESS(status));
+
+        Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));        
+
+        status = Callback(Context, Key, Ansi.Buffer);
+
+        __RegistryFree(Ansi.Buffer);
+
+        if (!NT_SUCCESS(status))
+            goto fail6;
+    }
+
+    __RegistryFree(Basic);
+
+    __RegistryFree(Full);
+
+    return STATUS_SUCCESS;
+
+fail6:
+fail5:
+    __RegistryFree(Basic);
+
+fail4:
+fail3:
+    __RegistryFree(Full);
+    
+fail2:
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryDeleteValue(
+    IN  PHANDLE         Key,
+    IN  PCHAR           Name
+    )
+{
+    ANSI_STRING         Ansi;
+    UNICODE_STRING      Unicode;
+    NTSTATUS            status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = ZwDeleteValueKey(Key, &Unicode);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryQueryDwordValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    OUT PULONG                      Value
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    ULONG                           Size;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+        
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             NULL,
+                             0,
+                             &Size);
+    if (status != STATUS_BUFFER_TOO_SMALL)
+        goto fail2;
+
+    Partial = __RegistryAllocate(Size);
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail3;
+
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             Partial,
+                             Size,
+                             &Size);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    status = STATUS_INVALID_PARAMETER;
+    if (Partial->Type != REG_DWORD ||
+        Partial->DataLength != sizeof (ULONG))
+        goto fail5;
+
+    *Value = *(PULONG)Partial->Data;            
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail5:
+fail4:
+    __RegistryFree(Partial);
+
+fail3:
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryUpdateDwordValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    IN  ULONG                       Value
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+        
+    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+                                 sizeof (ULONG));
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail2;
+
+    Partial->TitleIndex = 0;
+    Partial->Type = REG_DWORD;
+    Partial->DataLength = sizeof (ULONG);
+    *(PULONG)Partial->Data = Value;            
+
+    status = ZwSetValueKey(Key,
+                           &Unicode,
+                           Partial->TitleIndex,
+                           Partial->Type,
+                           Partial->Data,
+                           Partial->DataLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    __RegistryFree(Partial);
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+
+    return status;
+}
+
+static PANSI_STRING
+RegistrySzToAnsi(
+    IN  PWCHAR      Buffer
+    )
+{
+    PANSI_STRING    Ansi;
+    ULONG           Length;
+    UNICODE_STRING  Unicode;
+    NTSTATUS        status;
+
+    Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * 2);
+
+    status = STATUS_NO_MEMORY;
+    if (Ansi == NULL)
+        goto fail1;
+
+    Length = (ULONG)wcslen(Buffer);
+    Ansi[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
+    Ansi[0].Buffer = __RegistryAllocate(Ansi[0].MaximumLength);
+
+    status = STATUS_NO_MEMORY;
+    if (Ansi[0].Buffer == NULL)
+        goto fail2;
+
+    RtlInitUnicodeString(&Unicode, Buffer);
+    status = RtlUnicodeStringToAnsiString(&Ansi[0], &Unicode, FALSE);
+    ASSERT(NT_SUCCESS(status));
+
+    Ansi[0].Length = (USHORT)Length * sizeof (CHAR);
+
+    return Ansi;
+
+fail2:
+    __RegistryFree(Ansi);
+
+fail1:
+    return NULL;
+}
+
+static PANSI_STRING
+RegistryMultiSzToAnsi(
+    IN  PWCHAR      Buffer
+    )
+{
+    PANSI_STRING    Ansi;
+    LONG            Index;
+    LONG            Count;
+    NTSTATUS        status;
+
+    Index = 0;
+    Count = 0;
+    for (;;) {
+        ULONG   Length;
+
+        Length = (ULONG)wcslen(&Buffer[Index]);
+        if (Length == 0)
+            break;
+
+        Index += Length + 1;
+        Count++;
+    }
+
+    Ansi = __RegistryAllocate(sizeof (ANSI_STRING) * (Count + 1));
+
+    status = STATUS_NO_MEMORY;
+    if (Ansi == NULL)
+        goto fail1;
+
+    for (Index = 0; Index < Count; Index++) {
+        ULONG           Length;
+        UNICODE_STRING  Unicode;
+
+        Length = (ULONG)wcslen(Buffer);
+        Ansi[Index].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
+        Ansi[Index].Buffer = __RegistryAllocate(Ansi[Index].MaximumLength);
+
+        status = STATUS_NO_MEMORY;
+        if (Ansi[Index].Buffer == NULL)
+            goto fail2;
+
+        RtlInitUnicodeString(&Unicode, Buffer);
+
+        status = RtlUnicodeStringToAnsiString(&Ansi[Index], &Unicode, FALSE);
+        ASSERT(NT_SUCCESS(status));
+
+        Ansi[Index].Length = (USHORT)Length * sizeof (CHAR);
+        Buffer += Length + 1;
+    }
+
+    return Ansi;
+
+fail2:
+    while (--Index >= 0)
+        __RegistryFree(Ansi[Index].Buffer);
+
+    __RegistryFree(Ansi);
+
+fail1:
+    return NULL;
+}
+
+NTSTATUS
+RegistryQuerySzValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    OUT PANSI_STRING                *Array
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    PKEY_VALUE_PARTIAL_INFORMATION  Value;
+    ULONG                           Size;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+        
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             NULL,
+                             0,
+                             &Size);
+    if (status != STATUS_BUFFER_TOO_SMALL)
+        goto fail2;
+
+    Value = __RegistryAllocate(Size);
+
+    status = STATUS_NO_MEMORY;
+    if (Value == NULL)
+        goto fail3;
+
+    status = ZwQueryValueKey(Key,
+                             &Unicode,
+                             KeyValuePartialInformation,
+                             Value,
+                             Size,
+                             &Size);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    switch (Value->Type) {
+    case REG_SZ:
+        status = STATUS_NO_MEMORY;
+        *Array = RegistrySzToAnsi((PWCHAR)Value->Data);
+        break;
+
+    case REG_MULTI_SZ:
+        status = STATUS_NO_MEMORY;
+        *Array = RegistryMultiSzToAnsi((PWCHAR)Value->Data);
+        break;
+
+    default:
+        status = STATUS_INVALID_PARAMETER;
+        *Array = NULL;
+        break;
+    }
+
+    if (*Array == NULL)
+        goto fail5;
+
+    __RegistryFree(Value);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail5:
+fail4:
+    __RegistryFree(Value);
+
+fail3:
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryQueryKeyName(
+    IN  HANDLE              Key,
+    OUT PANSI_STRING        *Array
+    )
+{
+    PKEY_NAME_INFORMATION   Value;
+    ULONG                   Size;
+    NTSTATUS                status;
+
+    status = ZwQueryKey(Key,
+                        KeyNameInformation,
+                        NULL,
+                        0,
+                        &Size);
+    if (status != STATUS_BUFFER_TOO_SMALL)
+        goto fail1;
+
+    // Name information is not intrinsically NULL terminated
+    Value = __RegistryAllocate(Size + sizeof (WCHAR));
+
+    status = STATUS_NO_MEMORY;
+    if (Value == NULL)
+        goto fail2;
+
+    status = ZwQueryKey(Key,
+                        KeyNameInformation,
+                        Value,
+                        Size,
+                        &Size);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    Value->Name[Value->NameLength / sizeof (WCHAR)] = L'\0';
+    *Array = RegistrySzToAnsi((PWCHAR)Value->Name);
+
+    status = STATUS_NO_MEMORY;
+    if (*Array == NULL)
+        goto fail4;
+
+    __RegistryFree(Value);
+
+    return STATUS_SUCCESS;
+
+fail4:
+fail3:
+    __RegistryFree(Value);
+
+fail2:
+fail1:
+    return status;
+}
+
+NTSTATUS
+RegistryQuerySystemStartOption(
+    IN  PCHAR                       Prefix,
+    OUT PANSI_STRING                *Value
+    )
+{
+    UNICODE_STRING                  Unicode;
+    HANDLE                          Key;
+    PANSI_STRING                    Ansi;
+    ULONG                           Length;
+    PCHAR                           Option;
+    PCHAR                           Context;
+    NTSTATUS                        status;
+
+    RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
+    
+    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &Key);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = RegistryQuerySzValue(Key, "SystemStartOptions", &Ansi);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    // SystemStartOptions is a space separated list of options.
+    // Scan it looking for the one we want.
+    Length = (ULONG)strlen(Prefix);
+
+    Option = __strtok_r(Ansi[0].Buffer, " ", &Context);
+    if (strncmp(Prefix, Option, Length) == 0)
+        goto found;
+
+    while ((Option = __strtok_r(NULL, " ", &Context)) != NULL)
+        if (strncmp(Prefix, Option, Length) == 0)
+            goto found;
+
+    status = STATUS_OBJECT_NAME_NOT_FOUND;
+    goto fail3;
+
+found:
+    *Value = __RegistryAllocate(sizeof (ANSI_STRING) * 2);
+
+    status = STATUS_NO_MEMORY;
+    if (*Value == NULL)
+        goto fail4;
+
+    Length = (ULONG)strlen(Option);
+    (*Value)[0].MaximumLength = (USHORT)(Length + 1) * sizeof (CHAR);
+    (*Value)[0].Buffer = __RegistryAllocate((*Value)[0].MaximumLength);
+
+    status = STATUS_NO_MEMORY;
+    if ((*Value)[0].Buffer == NULL)
+        goto fail5;
+
+    RtlCopyMemory((*Value)[0].Buffer, Option, Length * sizeof (CHAR));
+
+    (*Value)[0].Length = (USHORT)Length * sizeof (CHAR);
+
+    RegistryFreeSzValue(Ansi);
+
+    ZwClose(Key);
+
+    return STATUS_SUCCESS;
+
+fail5:
+    __RegistryFree(*Value);
+
+fail4:
+fail3:
+    RegistryFreeSzValue(Ansi);
+
+fail2:
+    ZwClose(Key);
+
+fail1:
+    return status;
+}
+
+static PKEY_VALUE_PARTIAL_INFORMATION
+RegistryAnsiToSz(
+    PANSI_STRING                    Ansi
+    )
+{
+    ULONG                           Length;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    UNICODE_STRING                  Unicode;
+    NTSTATUS                        status;
+
+    Length = Ansi->Length + 1;
+    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+                                 Length * sizeof (WCHAR));
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail1;
+
+    Partial->TitleIndex = 0;
+    Partial->Type = REG_SZ;
+    Partial->DataLength = Length * sizeof (WCHAR);
+
+    Unicode.MaximumLength = (UCHAR)Partial->DataLength;
+    Unicode.Buffer = (PWCHAR)Partial->Data;
+    Unicode.Length = 0;
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, Ansi, FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+    return Partial;
+
+fail2:
+    __RegistryFree(Partial);
+
+fail1:
+    return NULL;
+}
+
+static PKEY_VALUE_PARTIAL_INFORMATION
+RegistryAnsiToMultiSz(
+    PANSI_STRING                    Ansi
+    )
+{
+    ULONG                           Length;
+    ULONG                           Index;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    UNICODE_STRING                  Unicode;
+    NTSTATUS                        status;
+
+    Length = 1;
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+        Length += Ansi[Index].Length + 1;
+
+    Partial = __RegistryAllocate(FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) +
+                               Length * sizeof (WCHAR));
+
+    status = STATUS_NO_MEMORY;
+    if (Partial == NULL)
+        goto fail1;
+
+    Partial->TitleIndex = 0;
+    Partial->Type = REG_MULTI_SZ;
+    Partial->DataLength = Length * sizeof (WCHAR);
+
+    Unicode.MaximumLength = (USHORT)Partial->DataLength;
+    Unicode.Buffer = (PWCHAR)Partial->Data;
+    Unicode.Length = 0;
+
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++) {
+        status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi[Index], FALSE);
+        if (!NT_SUCCESS(status))
+            goto fail2;
+
+        Length = Unicode.Length / sizeof (WCHAR);
+
+        ASSERT3U(Unicode.MaximumLength, >=, (Length + 1) * sizeof (WCHAR));
+        Unicode.MaximumLength -= (USHORT)((Length + 1) * sizeof (WCHAR));
+        Unicode.Buffer += Length + 1;
+        Unicode.Length = 0;
+    }
+    *Unicode.Buffer = L'\0';
+
+    return Partial;
+
+fail2:
+    __RegistryFree(Partial);
+
+fail1:
+    return NULL;
+}
+
+NTSTATUS
+RegistryUpdateSzValue(
+    IN  HANDLE                      Key,
+    IN  PCHAR                       Name,
+    IN  ULONG                       Type,
+    ...
+    )
+{
+    ANSI_STRING                     Ansi;
+    UNICODE_STRING                  Unicode;
+    va_list                         Arguments;
+    PKEY_VALUE_PARTIAL_INFORMATION  Partial;
+    NTSTATUS                        status;
+
+    RtlInitAnsiString(&Ansi, Name);
+
+    status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+        
+    va_start(Arguments, Type);
+    switch (Type) {
+    case REG_SZ: {
+        PANSI_STRING    Argument;
+
+        Argument = va_arg(Arguments, PANSI_STRING);
+
+        status = STATUS_NO_MEMORY;
+        Partial = RegistryAnsiToSz(Argument);        
+        break;
+    }
+    case REG_MULTI_SZ: {
+        PANSI_STRING    Argument;
+
+        Argument = va_arg(Arguments, PANSI_STRING);
+
+        status = STATUS_NO_MEMORY;
+        Partial = RegistryAnsiToMultiSz(Argument);        
+        break;
+    }
+    default:
+        status = STATUS_INVALID_PARAMETER;
+        Partial = NULL;
+        break;
+    }
+    va_end(Arguments);
+
+    if (Partial == NULL)
+        goto fail2;
+
+    status = ZwSetValueKey(Key,
+                           &Unicode,
+                           Partial->TitleIndex,
+                           Partial->Type,
+                           Partial->Data,
+                           Partial->DataLength);
+    if (!NT_SUCCESS(status))
+        goto fail3;
+
+    __RegistryFree(Partial);
+
+    RtlFreeUnicodeString(&Unicode);
+
+    return STATUS_SUCCESS;
+
+fail3:
+    __RegistryFree(Partial);
+
+fail2:
+    RtlFreeUnicodeString(&Unicode);
+
+fail1:
+    return status;
+}
+
+VOID
+RegistryFreeSzValue(
+    IN  PANSI_STRING    Array
+    )
+{
+    ULONG               Index;
+
+    if (Array == NULL)
+        return;
+
+    for (Index = 0; Array[Index].Buffer != NULL; Index++)
+        __RegistryFree(Array[Index].Buffer);
+
+    __RegistryFree(Array);
+}
+
+VOID
+RegistryCloseKey(
+    IN  HANDLE  Key
+    )
+{
+    ZwClose(Key);
+}
diff --git a/src/xennet/registry.h b/src/xennet/registry.h
new file mode 100644 (file)
index 0000000..7d7dc01
--- /dev/null
@@ -0,0 +1,168 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENNET_REGISTRY_H
+#define _XENNET_REGISTRY_H
+
+#include <ntddk.h>
+
+extern NTSTATUS
+RegistryInitialize(
+    IN PUNICODE_STRING  Path
+    );
+
+extern VOID
+RegistryTeardown(
+    VOID
+    );
+
+extern NTSTATUS
+RegistryOpenKey(
+    IN  HANDLE          Parent,
+    IN  PUNICODE_STRING Path,
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    );
+
+extern NTSTATUS
+RegistryOpenServiceKey(
+    IN  ACCESS_MASK DesiredAccess,
+    OUT PHANDLE     Key
+    );
+
+extern NTSTATUS
+RegistryOpenSoftwareKey(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    );
+
+extern NTSTATUS
+RegistryOpenHardwareKey(
+    IN  PDEVICE_OBJECT  DeviceObject,
+    IN  ACCESS_MASK     DesiredAccess,
+    OUT PHANDLE         Key
+    );
+
+extern NTSTATUS
+RegistryOpenSubKey(
+    IN  HANDLE      Key,
+    IN  PCHAR       Name,
+    IN  ACCESS_MASK DesiredAccess,
+    OUT PHANDLE     SubKey
+    );
+
+extern NTSTATUS
+RegistryCreateSubKey(
+    IN  HANDLE      Key,
+    IN  PCHAR       Name,
+    IN  ULONG       Options,
+    OUT PHANDLE     SubKey
+    );
+
+extern NTSTATUS
+RegistryDeleteSubKey(
+    IN  HANDLE      Key,
+    IN  PCHAR       Name
+    );
+
+extern NTSTATUS
+RegistryEnumerateSubKeys(
+    IN  HANDLE      Key,
+    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  PVOID       Context
+    );
+
+extern NTSTATUS
+RegistryEnumerateValues(
+    IN  HANDLE      Key,
+    IN  NTSTATUS    (*Callback)(PVOID, HANDLE, PCHAR),
+    IN  PVOID       Context
+    );
+
+extern NTSTATUS
+RegistryDeleteValue(
+    IN  HANDLE      Key,
+    IN  PCHAR       Name
+    );
+
+extern NTSTATUS
+RegistryQueryDwordValue(
+    IN  HANDLE          Key,
+    IN  PCHAR           Name,
+    OUT PULONG          Value
+    );
+    
+extern NTSTATUS
+RegistryUpdateDwordValue(
+    IN  HANDLE          Key,
+    IN  PCHAR           Name,
+    IN  ULONG           Value
+    );
+    
+extern NTSTATUS
+RegistryQuerySzValue(
+    IN  HANDLE          Key,
+    IN  PCHAR           Name,
+    OUT PANSI_STRING    *Array
+    );
+
+extern NTSTATUS
+RegistryQueryKeyName(
+    IN  HANDLE              Key,
+    OUT PANSI_STRING        *Array
+    );
+
+extern NTSTATUS
+RegistryQuerySystemStartOption(
+    IN  PCHAR           Name,
+    OUT PANSI_STRING    *Option
+    );
+
+extern VOID
+RegistryFreeSzValue(
+    IN  PANSI_STRING    Array
+    );
+
+extern NTSTATUS
+RegistryUpdateSzValue(
+    IN  HANDLE          Key,
+    IN  PCHAR           Name,
+    IN  ULONG           Type,
+    ...
+    );
+
+extern VOID
+RegistryCloseKey(
+    IN  HANDLE  Key
+    );
+
+#endif  // _XENNET_REGISTRY_H
index d1bfff3e686a1fa9c43008a7366ba26dcd3893f7..6a18a1976faf1ea2ea75245ecbf6faacb9135691 100644 (file)
@@ -49,18 +49,25 @@ TransmitterEnable(
     IN  PTRANSMITTER    Transmitter
     )
 {
-    XENVIF_TRANSMITTER_PACKET_METADATA  Metadata;
-
-    Metadata.OffsetOffset = (LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) -
-                            (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL);
-    Metadata.LengthOffset = (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) -
-                            (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL);
-    Metadata.MdlOffset = (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) -
-                         (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL);
-
-    VIF(UpdatePacketMetadata,
-        Transmitter->Adapter->VifInterface,
-        &Metadata);
+    PADAPTER            Adapter = Transmitter->Adapter;
+
+    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_PACKET_OFFSET_OFFSET,
+                      (LONG_PTR)&NET_BUFFER_CURRENT_MDL_OFFSET((PNET_BUFFER)NULL) -
+                      (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
+
+    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_PACKET_LENGTH_OFFSET,
+                      (LONG_PTR)&NET_BUFFER_DATA_LENGTH((PNET_BUFFER)NULL) -
+                      (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
+
+    (VOID) XENVIF_VIF(TransmitterSetPacketOffset,
+                      &Adapter->VifInterface,
+                      XENVIF_TRANSMITTER_PACKET_MDL_OFFSET,
+                      (LONG_PTR)&NET_BUFFER_CURRENT_MDL((PNET_BUFFER)NULL) -
+                      (LONG_PTR)&NET_BUFFER_MINIPORT_RESERVED((PNET_BUFFER)NULL));
 }
 
 VOID 
@@ -142,6 +149,7 @@ TransmitterSendNetBufferLists(
     IN  ULONG                   SendFlags
     )
 {
+    PADAPTER                    Adapter = Transmitter->Adapter;
     PXENVIF_TRANSMITTER_PACKET  HeadPacket;
     PXENVIF_TRANSMITTER_PACKET  *TailPacket;
     KIRQL                       Irql;
@@ -249,9 +257,9 @@ TransmitterSendNetBufferLists(
     if (HeadPacket != NULL) {
         NTSTATUS    status; 
 
-        status = VIF(QueuePackets,
-                     Transmitter->Adapter->VifInterface,
-                     HeadPacket);
+        status = XENVIF_VIF(TransmitterQueuePackets,
+                            &Adapter->VifInterface,
+                            HeadPacket);
         if (!NT_SUCCESS(status))
             TransmitterAbortPackets(Transmitter, HeadPacket);
     }
@@ -265,6 +273,7 @@ TransmitterCompleteNetBufferList(
     IN  PNET_BUFFER_LIST                                NetBufferList
     )
 {
+    PADAPTER                                            Adapter = Transmitter->Adapter;
     PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO   LargeSendInfo;
 
     ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
@@ -277,7 +286,7 @@ TransmitterCompleteNetBufferList(
 
     NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_SUCCESS;
 
-    NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle,
+    NdisMSendNetBufferListsComplete(Adapter->NdisAdapterHandle,
                                     NetBufferList,
                                     NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
 }
index 93d734bf622fa2289e59144dfd2974145c607986..8dc7e8d086bef0afa571ca584d3d4bab41c230d7 100644 (file)
@@ -32,8 +32,8 @@
 #pragma once
 
 typedef struct _TRANSMITTER {
-    PADAPTER                Adapter;
-    XENVIF_OFFLOAD_OPTIONS  OffloadOptions;
+    PADAPTER                    Adapter;
+    XENVIF_VIF_OFFLOAD_OPTIONS  OffloadOptions;
 } TRANSMITTER, *PTRANSMITTER;
 
 VOID