]> xenbits.xensource.com Git - pvdrivers/win/xennet.git/commitdiff
Publish distribution information to xenstore 8.1.0-rc4
authorPaul Durrant <paul.durrant@citrix.com>
Tue, 24 Nov 2015 15:41:10 +0000 (15:41 +0000)
committerPaul Durrant <paul.durrant@citrix.com>
Thu, 26 Nov 2015 18:03:39 +0000 (18:03 +0000)
My recent patch series to Xen added a documented path and format for
publishing information about PV driver distributions to xenstore.

This patch adds code to populate the documented path (should it exist)
with information about the XENNET driver package.

Suggested-by: Owen Smith <owen.smith@citrix.com>
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
include/store_interface.h [new file with mode: 0644]
include/suspend_interface.h [new file with mode: 0644]
src/xennet.inf
src/xennet/adapter.c
vs2012/xennet/xennet.vcxproj
vs2013/xennet/xennet.vcxproj

diff --git a/include/store_interface.h b/include/store_interface.h
new file mode 100644 (file)
index 0000000..f2b2147
--- /dev/null
@@ -0,0 +1,347 @@
+/* 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.
+ */
+
+/*! \file store_interface.h
+    \brief XENBUS STORE Interface
+
+    This interface provides access to XenStore
+*/
+
+#ifndef _XENBUS_STORE_INTERFACE_H
+#define _XENBUS_STORE_INTERFACE_H
+
+#ifndef _WINDLL
+
+/*! \typedef XENBUS_STORE_TRANSACTION
+    \brief XenStore transaction handle
+*/
+typedef struct _XENBUS_STORE_TRANSACTION    XENBUS_STORE_TRANSACTION, *PXENBUS_STORE_TRANSACTION;
+
+/*! \typedef XENBUS_STORE_WATCH
+    \brief XenStore watch handle
+*/
+typedef struct _XENBUS_STORE_WATCH          XENBUS_STORE_WATCH, *PXENBUS_STORE_WATCH;
+
+/*! \typedef XENBUS_STORE_PERMISSION_MASK
+    \brief Bitmask of XenStore key permissions
+*/
+typedef enum _XENBUS_STORE_PERMISSION_MASK {
+    XENBUS_STORE_PERM_NONE = 0,
+    XENBUS_STORE_PERM_READ = 1,
+    XENBUS_STORE_PERM_WRITE = 2,
+} XENBUS_STORE_PERMISSION_MASK;
+
+/*! \typedef XENBUS_STORE_PERMISSION
+    \brief XenStore key permissions entry for a single domain
+*/
+typedef struct _XENBUS_STORE_PERMISSION {
+    USHORT                          Domain;
+    XENBUS_STORE_PERMISSION_MASK    Mask;
+} XENBUS_STORE_PERMISSION, *PXENBUS_STORE_PERMISSION;
+
+/*! \typedef XENBUS_STORE_ACQUIRE
+    \brief Acquire a reference to the STORE interface
+
+    \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_ACQUIRE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_STORE_RELEASE
+    \brief Release a reference to the STORE interface
+
+    \param Interface The interface header
+*/
+typedef VOID
+(*XENBUS_STORE_RELEASE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_STORE_FREE
+    \brief Free a memory buffer allocated by the STORE interface
+
+    \param Interface The interface header
+    \param Buffer Pointer to the memory buffer
+*/
+typedef VOID
+(*XENBUS_STORE_FREE)(
+    IN  PINTERFACE  Interface,
+    IN  PCHAR       Buffer
+    );
+
+/*! \typedef XENBUS_STORE_READ
+    \brief Read a value from XenStore
+
+    \param Interface The interface header
+    \param Transaction The transaction handle (NULL if this read is not
+    part of a transaction)
+    \param Prefix An optional prefix for the \a Node
+    \param Node The concatenation of the \a Prefix and this value specifies
+    the XenStore key to read
+    \param A pointer to a pointer that will be initialized with a memory
+    buffer containing the value read
+
+    The \a Buffer should be freed using \a XENBUS_STORE_FREE
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_READ)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_STORE_TRANSACTION   Transaction OPTIONAL,
+    IN  PCHAR                       Prefix OPTIONAL,
+    IN  PCHAR                       Node,
+    OUT PCHAR                       *Buffer
+    );
+
+/*! \typedef XENBUS_STORE_PRINTF
+    \brief Write a value to XenStore
+
+    \param Interface The interface header
+    \param Transaction The transaction handle (NULL if this write is not
+    part of a transaction)
+    \param Prefix An optional prefix for the \a Node
+    \param Node The concatenation of the \a Prefix and this value specifies
+    the XenStore key to write
+    \param Format A format specifier
+    \param ... Additional parameters required by \a Format
+
+    If the \a Node does not exist then it is created
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_PRINTF)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_STORE_TRANSACTION   Transaction OPTIONAL,
+    IN  PCHAR                       Prefix OPTIONAL,
+    IN  PCHAR                       Node,
+    IN  const CHAR                  *Format,
+    ...
+    );
+
+/*! \typedef XENBUS_STORE_REMOVE
+    \brief Remove a key from XenStore
+
+    \param Interface The interface header
+    \param Transaction The transaction handle (NULL if this removal is not
+    part of a transaction)
+    \param Prefix An optional prefix for the \a Node
+    \param Node The concatenation of the \a Prefix and this value specifies
+    the XenStore key to remove
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_REMOVE)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_STORE_TRANSACTION   Transaction OPTIONAL,
+    IN  PCHAR                       Prefix OPTIONAL,
+    IN  PCHAR                       Node
+    );
+
+/*! \typedef XENBUS_STORE_DIRECTORY
+    \brief Enumerate all immediate child keys of a XenStore key
+
+    \param Interface The interface header
+    \param Transaction The transaction handle (NULL if this removal is not
+    part of a transaction)
+    \param Prefix An optional prefix for the \a Node
+    \param Node The concatenation of the \a Prefix and this value specifies
+    the XenStore key to enumerate
+    \param A pointer to a pointer that will be initialized with a memory
+    buffer containing a NUL separated list of key names
+
+    The \a Buffer should be freed using \a XENBUS_STORE_FREE
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_DIRECTORY)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_STORE_TRANSACTION   Transaction OPTIONAL,
+    IN  PCHAR                       Prefix OPTIONAL,
+    IN  PCHAR                       Node,
+    OUT PCHAR                       *Buffer
+    );
+
+/*! \typedef XENBUS_STORE_TRANSACTION_START
+    \brief Start a XenStore transaction
+
+    \param Interface The interface header
+    \param Transaction Pointer to a transaction handle to be initialized
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_TRANSACTION_START)(
+    IN  PINTERFACE                  Interface,
+    OUT PXENBUS_STORE_TRANSACTION   *Transaction
+    );
+
+/*! \typedef XENBUS_STORE_TRANSACTION_END
+    \brief End a XenStore transaction
+
+    \param Interface The interface header
+    \param Transaction The transaction handle
+    \param Commit Set to TRUE if actions performed within the transaction should
+    be made visible, or FALSE if they should not be
+
+    If \a Commit is TRUE and the transaction to found to clash then
+    STATUS_RETRY will be returned
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_TRANSACTION_END)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_STORE_TRANSACTION   Transaction,
+    IN  BOOLEAN                     Commit
+    );
+
+/*! \typedef XENBUS_STORE_WATCH_ADD
+    \brief Add a XenStore watch
+
+    \param Interface The interface header
+    \param Prefix An optional prefix for the \a Node
+    \param Node The concatenation of the \a Prefix and this value specifies
+    the XenStore key to watch
+    \param Event A pointer to an event object to be signalled when the
+    watch fires
+    \param Watch A pointer to a watch handle to be initialized
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_WATCH_ADD)(
+    IN  PINTERFACE          Interface,
+    IN  PCHAR               Prefix OPTIONAL,
+    IN  PCHAR               Node,
+    IN  PKEVENT             Event,
+    OUT PXENBUS_STORE_WATCH *Watch
+    );
+
+/*! \typedef XENBUS_STORE_WATCH_REMOVE
+    \brief Remove a XenStore watch
+
+    \param Interface The interface header
+    \param Watch The watch handle
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_WATCH_REMOVE)(
+    IN  PINTERFACE          Interface,
+    IN  PXENBUS_STORE_WATCH Watch
+    );
+
+/*! \typedef XENBUS_STORE_POLL
+    \brief Poll for XenStore activity
+
+    \param Interface The interface header
+
+    If it is necessary to spin at DISPATCH_LEVEL waiting for XenStore
+    activity then this will block the normal STORE interface DPC so this
+    method must be regularly invoked during the spin loop to check for
+    XenStore activity
+*/
+typedef VOID
+(*XENBUS_STORE_POLL)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_STORE_PERMISSIONS_SET
+    \brief Set permissions for a XenStore key
+
+    \param Interface The interface header
+    \param Transaction The transaction handle (NULL if this is not
+    part of a transaction)
+    \param Prefix An optional prefix for the \a Node
+    \param Node The concatenation of the \a Prefix and this value specifies
+    the XenStore key to set permissions of
+    \param Permissions An array of permissions to set
+    \param NumberPermissions Number of elements in the \a Permissions array
+*/
+typedef NTSTATUS
+(*XENBUS_STORE_PERMISSIONS_SET)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_STORE_TRANSACTION   Transaction OPTIONAL,
+    IN  PCHAR                       Prefix OPTIONAL,
+    IN  PCHAR                       Node,
+    IN  PXENBUS_STORE_PERMISSION    Permissions,
+    IN  ULONG                       NumberPermissions
+    );
+
+// {86824C3B-D34E-4753-B281-2F1E3AD214D7}
+DEFINE_GUID(GUID_XENBUS_STORE_INTERFACE,
+0x86824c3b, 0xd34e, 0x4753, 0xb2, 0x81, 0x2f, 0x1e, 0x3a, 0xd2, 0x14, 0xd7);
+
+/*! \struct _XENBUS_STORE_INTERFACE_V1
+    \brief STORE interface version 1
+    \ingroup interfaces
+*/
+struct _XENBUS_STORE_INTERFACE_V1 {
+    INTERFACE                       Interface;
+    XENBUS_STORE_ACQUIRE            StoreAcquire;
+    XENBUS_STORE_RELEASE            StoreRelease;
+    XENBUS_STORE_FREE               StoreFree;
+    XENBUS_STORE_READ               StoreRead;
+    XENBUS_STORE_PRINTF             StorePrintf;
+    XENBUS_STORE_REMOVE             StoreRemove;
+    XENBUS_STORE_DIRECTORY          StoreDirectory;
+    XENBUS_STORE_TRANSACTION_START  StoreTransactionStart;
+    XENBUS_STORE_TRANSACTION_END    StoreTransactionEnd;
+    XENBUS_STORE_WATCH_ADD          StoreWatchAdd;
+    XENBUS_STORE_WATCH_REMOVE       StoreWatchRemove;
+    XENBUS_STORE_POLL               StorePoll;
+};
+
+/*! \struct _XENBUS_STORE_INTERFACE_V2
+    \brief STORE interface version 2
+    \ingroup interfaces
+*/
+struct _XENBUS_STORE_INTERFACE_V2 {
+    INTERFACE                       Interface;
+    XENBUS_STORE_ACQUIRE            StoreAcquire;
+    XENBUS_STORE_RELEASE            StoreRelease;
+    XENBUS_STORE_FREE               StoreFree;
+    XENBUS_STORE_READ               StoreRead;
+    XENBUS_STORE_PRINTF             StorePrintf;
+    XENBUS_STORE_PERMISSIONS_SET    StorePermissionsSet;
+    XENBUS_STORE_REMOVE             StoreRemove;
+    XENBUS_STORE_DIRECTORY          StoreDirectory;
+    XENBUS_STORE_TRANSACTION_START  StoreTransactionStart;
+    XENBUS_STORE_TRANSACTION_END    StoreTransactionEnd;
+    XENBUS_STORE_WATCH_ADD          StoreWatchAdd;
+    XENBUS_STORE_WATCH_REMOVE       StoreWatchRemove;
+    XENBUS_STORE_POLL               StorePoll;
+};
+
+typedef struct _XENBUS_STORE_INTERFACE_V2 XENBUS_STORE_INTERFACE, *PXENBUS_STORE_INTERFACE;
+
+/*! \def XENBUS_STORE
+    \brief Macro at assist in method invocation
+*/
+#define XENBUS_STORE(_Method, _Interface, ...)    \
+    (_Interface)->Store ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif  // _WINDLL
+
+#define XENBUS_STORE_INTERFACE_VERSION_MIN  1
+#define XENBUS_STORE_INTERFACE_VERSION_MAX  2
+
+#endif  // _XENBUS_STORE_INTERFACE_H
diff --git a/include/suspend_interface.h b/include/suspend_interface.h
new file mode 100644 (file)
index 0000000..9ef386b
--- /dev/null
@@ -0,0 +1,176 @@
+/* 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.
+ */
+
+/*! \file suspend_interface.h
+    \brief XENBUS SUSPEND Interface
+
+    This interface provides primitives to handle VM suspend/resume
+*/
+
+#ifndef _XENBUS_SUSPEND_INTERFACE_H
+#define _XENBUS_SUSPEND_INTERFACE_H
+
+#ifndef _WINDLL
+
+/*! \enum _XENBUS_SUSPEND_CALLBACK_TYPE
+    \brief Suspend callback type to be registered
+*/
+typedef enum _XENBUS_SUSPEND_CALLBACK_TYPE {
+    SUSPEND_CALLBACK_TYPE_INVALID = 0,
+    SUSPEND_CALLBACK_EARLY,             /*!< Early */
+    SUSPEND_CALLBACK_LATE               /*!< Late */
+} XENBUS_SUSPEND_CALLBACK_TYPE, *PXENBUS_SUSPEND_CALLBACK_TYPE;
+
+/*! \typedef XENBUS_SUSPEND_CALLBACK
+    \brief Suspend callback handle
+*/
+typedef struct _XENBUS_SUSPEND_CALLBACK   XENBUS_SUSPEND_CALLBACK, *PXENBUS_SUSPEND_CALLBACK;
+
+/*! \typedef XENBUS_SUSPEND_ACQUIRE
+    \brief Acquire a reference to the SUSPEND interface
+
+    \param Interface The interface header
+*/
+typedef NTSTATUS
+(*XENBUS_SUSPEND_ACQUIRE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_SUSPEND_RELEASE
+    \brief Release a reference to the SUSPEND interface
+
+    \param Interface The interface header
+*/
+typedef VOID
+(*XENBUS_SUSPEND_RELEASE)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_SUSPEND_FUNCTION
+    \brief Suspend callback function
+
+    \param Argument Context \a Argument supplied to \a XENBUS_SUSPEND_REGISTER
+
+    Suspend callback functions are always invoked on one vCPU with all other
+    vCPUs corralled at the same IRQL as the callback. \a Early callback
+    functions are always invoked with IRQL == HIGH_LEVEL and \a Late callback
+    functions are always invoked with IRQL == DISPATCH_LEVEL
+*/
+typedef VOID
+(*XENBUS_SUSPEND_FUNCTION)(
+    IN  PVOID   Argument
+    );
+
+/*! \typedef XENBUS_SUSPEND_REGISTER
+    \brief Register a suspend callback function
+
+    \param Interface The interface header
+    \param Type The type of callback function to register
+    \param Function The callback function
+    \param Argument An optional context argument passed to the callback
+    \param Callback A pointer to a callback handle to be initialized
+*/
+typedef NTSTATUS
+(*XENBUS_SUSPEND_REGISTER)(
+    IN  PINTERFACE                      Interface,
+    IN  XENBUS_SUSPEND_CALLBACK_TYPE    Type,
+    IN  XENBUS_SUSPEND_FUNCTION         Function,
+    IN  PVOID                           Argument OPTIONAL,
+    OUT PXENBUS_SUSPEND_CALLBACK        *Callback
+    );
+
+/*! \typedef XENBUS_SUSPEND_DEREGISTER
+    \brief Deregister a suspend callback function
+
+    \param Interface The interface header
+    \param Callback The callback handle
+*/
+typedef VOID
+(*XENBUS_SUSPEND_DEREGISTER)(
+    IN  PINTERFACE                  Interface,
+    IN  PXENBUS_SUSPEND_CALLBACK    Callback
+    );
+
+/*! \typedef XENBUS_SUSPEND_TRIGGER
+    \brief Trigger a VM suspend
+
+    \param Interface The interface header
+
+    This method must always be invoked with IRQL == PASSIVE_LEVEL
+*/
+typedef NTSTATUS
+(*XENBUS_SUSPEND_TRIGGER)(
+    IN  PINTERFACE  Interface
+    );
+
+/*! \typedef XENBUS_SUSPEND_GET_COUNT
+    \brief Get the number of VM suspends that have occurred since boot
+
+    \param Interface The interface header
+    \return The number of VM suspends
+*/
+typedef ULONG
+(*XENBUS_SUSPEND_GET_COUNT)(
+    IN  PINTERFACE  Interface
+    );
+
+// {0554F2AF-B510-4C71-AC03-1C503E394238}
+DEFINE_GUID(GUID_XENBUS_SUSPEND_INTERFACE,
+0x554f2af, 0xb510, 0x4c71, 0xac, 0x3, 0x1c, 0x50, 0x3e, 0x39, 0x42, 0x38);
+
+/*! \struct _XENBUS_SUSPEND_INTERFACE_V1
+    \brief SUSPEND interface version 1
+    \ingroup interfaces
+*/
+struct _XENBUS_SUSPEND_INTERFACE_V1 {
+    INTERFACE                   Interface;
+    XENBUS_SUSPEND_ACQUIRE      Acquire;
+    XENBUS_SUSPEND_RELEASE      Release;
+    XENBUS_SUSPEND_REGISTER     Register;
+    XENBUS_SUSPEND_DEREGISTER   Deregister;
+    XENBUS_SUSPEND_TRIGGER      Trigger;
+    XENBUS_SUSPEND_GET_COUNT    GetCount;
+};
+
+typedef struct _XENBUS_SUSPEND_INTERFACE_V1 XENBUS_SUSPEND_INTERFACE, *PXENBUS_SUSPEND_INTERFACE;
+
+/*! \def XENBUS_SUSPEND
+    \brief Macro at assist in method invocation
+*/
+#define XENBUS_SUSPEND(_Method, _Interface, ...)    \
+    (_Interface)-> ## _Method((PINTERFACE)(_Interface), __VA_ARGS__)
+
+#endif  // _WINDLL
+
+#define XENBUS_SUSPEND_INTERFACE_VERSION_MIN    1
+#define XENBUS_SUSPEND_INTERFACE_VERSION_MAX    1
+
+#endif  // _XENBUS_SUSPEND_INTERFACE_H
index 7e9d9e69ec3e76c092f8db62f793f87bdb593691..bbec43f59832bf755f2a484e608be247e9e1daf0 100644 (file)
@@ -61,9 +61,9 @@ xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll
 ; DisplayName          Section         DeviceID
 ; -----------          -------         --------
 
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_08000002
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_08000002
-%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_08000002
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_@VENDOR_PREFIX@@VENDOR_DEVICE_ID@&DEV_NET&REV_08000005
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_@VENDOR_PREFIX@0001&DEV_NET&REV_08000005
+%XenNetDesc%           =XenNet_Inst,   XENVIF\VEN_@VENDOR_PREFIX@0002&DEV_NET&REV_08000005
 
 [XenNet_Inst] 
 Characteristics=0x84
index a1460c74685ff00c2ff21214de4ab41cf36e4444..20aabeed96ef18473d70cff0eedb883889297576 100644 (file)
 #define INITGUID 1
 
 #include <ndis.h>
+#include <ntstrsafe.h>
 #include <stdlib.h>
 #include <version.h>
 
 #include <vif_interface.h>
 #include <cache_interface.h>
+#include <store_interface.h>
+#include <suspend_interface.h>
 
 #include "adapter.h"
 #include "transmitter.h"
 #include "receiver.h"
+#include "util.h"
 #include "dbg_print.h"
 #include "assert.h"
 
+#define MAXNAMELEN  128
+
 struct _XENNET_ADAPTER {
-    XENVIF_VIF_INTERFACE    VifInterface;
-    XENBUS_CACHE_INTERFACE  CacheInterface;
+    XENVIF_VIF_INTERFACE        VifInterface;
+    XENBUS_CACHE_INTERFACE      CacheInterface;
+    XENBUS_STORE_INTERFACE      StoreInterface;
+    XENBUS_SUSPEND_INTERFACE    SuspendInterface;
+
+    PXENBUS_SUSPEND_CALLBACK    SuspendCallbackLate;
 
-    ULONG                   MaximumFrameSize;
-    ULONG                   CurrentLookahead;
+    ULONG                       MaximumFrameSize;
+    ULONG                       CurrentLookahead;
 
-    NDIS_HANDLE             NdisAdapterHandle;
-    NDIS_HANDLE             NdisDmaHandle;
-    NDIS_PNP_CAPABILITIES   Capabilities;
-    NDIS_OFFLOAD            Offload;
-    PROPERTIES              Properties;
+    NDIS_HANDLE                 NdisAdapterHandle;
+    NDIS_HANDLE                 NdisDmaHandle;
+    NDIS_PNP_CAPABILITIES       Capabilities;
+    NDIS_OFFLOAD                Offload;
+    PROPERTIES                  Properties;
 
-    PXENNET_RECEIVER        Receiver;
-    PXENNET_TRANSMITTER     Transmitter;
-    BOOLEAN                 Enabled;
+    PXENNET_RECEIVER            Receiver;
+    PXENNET_TRANSMITTER         Transmitter;
+    BOOLEAN                     Enabled;
 };
 
+static LONG AdapterCount;
+
 static NDIS_OID XennetSupportedOids[] =
 {
     OID_GEN_SUPPORTED_LIST,
@@ -2151,6 +2163,395 @@ AdapterSetOffloadAttributes(
     return ndisStatus;
 }
 
+static FORCEINLINE PVOID
+__AdapterAllocate(
+    IN  ULONG   Length
+    )
+{
+    return __AllocateNonPagedPoolWithTag(Length, ADAPTER_POOL_TAG);
+}
+
+static FORCEINLINE VOID
+__AdapterFree(
+    IN  PVOID   Buffer
+    )
+{
+    __FreePoolWithTag(Buffer, ADAPTER_POOL_TAG);
+}
+
+static FORCEINLINE PANSI_STRING
+__AdapterMultiSzToUpcaseAnsi(
+    IN  PCHAR       Buffer
+    )
+{
+    PANSI_STRING    Ansi;
+    LONG            Index;
+    LONG            Count;
+    NTSTATUS        status;
+
+    Index = 0;
+    Count = 0;
+    for (;;) {
+        if (Buffer[Index] == '\0') {
+            Count++;
+            Index++;
+
+            // Check for double NUL
+            if (Buffer[Index] == '\0')
+                break;
+        } else {
+            Buffer[Index] = (CHAR)toupper(Buffer[Index]);
+            Index++;
+        }
+    }
+
+    Ansi = __AdapterAllocate(sizeof (ANSI_STRING) * (Count + 1));
+
+    status = STATUS_NO_MEMORY;
+    if (Ansi == NULL)
+        goto fail1;
+
+    for (Index = 0; Index < Count; Index++) {
+        ULONG   Length;
+
+        Length = (ULONG)strlen(Buffer);
+        Ansi[Index].MaximumLength = (USHORT)(Length + 1);
+        Ansi[Index].Buffer = __AdapterAllocate(Ansi[Index].MaximumLength);
+
+        status = STATUS_NO_MEMORY;
+        if (Ansi[Index].Buffer == NULL)
+            goto fail2;
+
+        RtlCopyMemory(Ansi[Index].Buffer, Buffer, Length);
+        Ansi[Index].Length = (USHORT)Length;
+
+        Buffer += Length + 1;
+    }
+
+    return Ansi;
+
+fail2:
+    Error("fail2\n");
+
+    while (--Index >= 0)
+        __AdapterFree(Ansi[Index].Buffer);
+
+    __AdapterFree(Ansi);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return NULL;
+}
+
+static FORCEINLINE VOID
+__AdapterFreeAnsi(
+    IN  PANSI_STRING    Ansi
+    )
+{
+    ULONG               Index;
+
+    for (Index = 0; Ansi[Index].Buffer != NULL; Index++)
+        __AdapterFree(Ansi[Index].Buffer);
+
+    __AdapterFree(Ansi);
+}
+
+static FORCEINLINE BOOLEAN
+__AdapterMatchDistribution(
+    IN  PXENNET_ADAPTER Adapter,
+    IN  PCHAR           Buffer
+    )
+{
+    PCHAR               Vendor;
+    PCHAR               Product;
+    PCHAR               Context;
+    const CHAR          *Text;
+    BOOLEAN             Match;
+    ULONG               Index;
+    NTSTATUS            status;
+
+    UNREFERENCED_PARAMETER(Adapter);
+
+    status = STATUS_INVALID_PARAMETER;
+
+    Vendor = __strtok_r(Buffer, " ", &Context);
+    if (Vendor == NULL)
+        goto fail1;
+
+    Product = __strtok_r(NULL, " ", &Context);
+    if (Product == NULL)
+        goto fail2;
+
+    Match = TRUE;
+
+    Text = VENDOR_NAME_STR;
+
+    for (Index = 0; Text[Index] != 0; Index++) {
+        if (!isalnum((UCHAR)Text[Index])) {
+            if (Vendor[Index] != '_') {
+                Match = FALSE;
+                break;
+            }
+        } else {
+            if (Vendor[Index] != Text[Index]) {
+                Match = FALSE;
+                break;
+            }
+        }
+    }
+
+    Text = "XENNET";
+
+    if (_stricmp(Product, Text) != 0)
+        Match = FALSE;
+
+    return Match;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return FALSE;
+}
+
+static FORCEINLINE VOID
+__AdapterClearDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    PCHAR               Buffer;
+    PANSI_STRING        Distributions;
+    ULONG               Index;
+    NTSTATUS            status;
+
+    Trace("====>\n");
+
+    status = XENBUS_STORE(Directory,
+                          &Adapter->StoreInterface,
+                          NULL,
+                          NULL,
+                          "drivers",
+                          &Buffer);
+    if (NT_SUCCESS(status)) {
+        Distributions = __AdapterMultiSzToUpcaseAnsi(Buffer);
+
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
+    } else {
+        Distributions = NULL;
+    }
+
+    if (Distributions == NULL)
+        goto done;
+
+    for (Index = 0; Distributions[Index].Buffer != NULL; Index++) {
+        PANSI_STRING    Distribution = &Distributions[Index];
+
+        status = XENBUS_STORE(Read,
+                              &Adapter->StoreInterface,
+                              NULL,
+                              "drivers",
+                              Distribution->Buffer,
+                              &Buffer);
+        if (!NT_SUCCESS(status))
+            continue;
+
+        if (__AdapterMatchDistribution(Adapter, Buffer))
+            (VOID) XENBUS_STORE(Remove,
+                                &Adapter->StoreInterface,
+                                NULL,
+                                "drivers",
+                                Distribution->Buffer);
+
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
+    }
+
+    __AdapterFreeAnsi(Distributions);
+
+done:
+    Trace("<====\n");
+}
+
+#define MAXIMUM_INDEX   255
+
+static FORCEINLINE NTSTATUS
+__AdapterSetDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    ULONG               Index;
+    CHAR                Distribution[MAXNAMELEN];
+    CHAR                Vendor[MAXNAMELEN];
+    const CHAR          *Product;
+    NTSTATUS            status;
+
+    Trace("====>\n");
+
+    Index = 0;
+    while (Index <= MAXIMUM_INDEX) {
+        PCHAR   Buffer;
+
+        status = RtlStringCbPrintfA(Distribution,
+                                    MAXNAMELEN,
+                                    "%u",
+                                    Index);
+        ASSERT(NT_SUCCESS(status));
+
+        status = XENBUS_STORE(Read,
+                              &Adapter->StoreInterface,
+                              NULL,
+                              "drivers",
+                              Distribution,
+                              &Buffer);
+        if (!NT_SUCCESS(status)) {
+            if (status == STATUS_OBJECT_NAME_NOT_FOUND)
+                goto update;
+
+            goto fail1;
+        }
+
+        XENBUS_STORE(Free,
+                     &Adapter->StoreInterface,
+                     Buffer);
+
+        Index++;
+    }
+
+    status = STATUS_UNSUCCESSFUL;
+    goto fail2;
+
+update:
+    status = RtlStringCbPrintfA(Vendor,
+                                MAXNAMELEN,
+                                "%s",
+                                VENDOR_NAME_STR);
+    ASSERT(NT_SUCCESS(status));
+
+    for (Index  = 0; Vendor[Index] != '\0'; Index++)
+        if (!isalnum((UCHAR)Vendor[Index]))
+            Vendor[Index] = '_';
+
+    Product = "XENNET";
+
+#if DBG
+#define ATTRIBUTES   "(DEBUG)"
+#else
+#define ATTRIBUTES   ""
+#endif
+
+    (VOID) XENBUS_STORE(Printf,
+                        &Adapter->StoreInterface,
+                        NULL,
+                        "drivers",
+                        Distribution,
+                        "%s %s %u.%u.%u %s",
+                        Vendor,
+                        Product,
+                        MAJOR_VERSION,
+                        MINOR_VERSION,
+                        MICRO_VERSION,
+                        ATTRIBUTES
+                        );
+
+#undef  ATTRIBUTES
+
+    Trace("<====\n");
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static DECLSPEC_NOINLINE VOID
+AdapterSuspendCallbackLate(
+    IN  PVOID       Argument
+    )
+{
+    PXENNET_ADAPTER Adapter = Argument;
+
+    (VOID) __AdapterSetDistribution(Adapter);
+}
+
+static NTSTATUS
+AdapterSetDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    LONG                Count;
+    NTSTATUS            status;
+
+    Trace("====>\n");
+
+    Count = InterlockedIncrement(&AdapterCount);
+    ASSERT(Count != 0);
+
+    if (Count != 1)
+        goto done;
+
+    status = __AdapterSetDistribution(Adapter);
+    if (!NT_SUCCESS(status))
+        goto fail1;
+
+    status = XENBUS_SUSPEND(Register,
+                            &Adapter->SuspendInterface,
+                            SUSPEND_CALLBACK_LATE,
+                            AdapterSuspendCallbackLate,
+                            Adapter,
+                            &Adapter->SuspendCallbackLate);
+    if (!NT_SUCCESS(status))
+        goto fail2;
+
+done:
+    Trace("<====\n");
+    return STATUS_SUCCESS;
+
+fail2:
+    Error("fail2\n");
+
+    __AdapterClearDistribution(Adapter);
+
+fail1:
+    Error("fail1 (%08x)\n", status);
+
+    return status;
+}
+
+static VOID
+AdapterClearDistribution(
+    IN  PXENNET_ADAPTER Adapter
+    )
+{
+    LONG                Count;
+
+    Trace("====>\n");
+
+    Count = InterlockedDecrement(&AdapterCount);
+
+    if (Count != 0)
+        goto done;
+
+    XENBUS_SUSPEND(Deregister,
+                   &Adapter->SuspendInterface,
+                   Adapter->SuspendCallbackLate);
+    Adapter->SuspendCallbackLate = NULL;
+
+    __AdapterClearDistribution(Adapter);
+
+done:
+    Trace("<====\n");
+}
+
 NDIS_STATUS
 AdapterInitialize(
     IN  NDIS_HANDLE         Handle,
@@ -2162,9 +2563,7 @@ AdapterInitialize(
     PDEVICE_OBJECT          DeviceObject;
     NDIS_SG_DMA_DESCRIPTION Dma;
 
-    *Adapter = ExAllocatePoolWithTag(NonPagedPool,
-                                     sizeof(XENNET_ADAPTER),
-                                     ADAPTER_POOL_TAG);
+    *Adapter = __AdapterAllocate(sizeof (XENNET_ADAPTER));
 
     ndisStatus = NDIS_STATUS_RESOURCES;
     if (*Adapter == NULL)
@@ -2199,41 +2598,71 @@ AdapterInitialize(
     if (!NT_SUCCESS(status))
         goto fail3;
 
+    status = __QueryInterface(DeviceObject,
+                              &GUID_XENBUS_STORE_INTERFACE,
+                              XENBUS_STORE_INTERFACE_VERSION_MAX,
+                              (PINTERFACE)&(*Adapter)->StoreInterface,
+                              sizeof(XENBUS_STORE_INTERFACE),
+                              FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail4;
+
+    status = __QueryInterface(DeviceObject,
+                              &GUID_XENBUS_SUSPEND_INTERFACE,
+                              XENBUS_SUSPEND_INTERFACE_VERSION_MAX,
+                              (PINTERFACE)&(*Adapter)->SuspendInterface,
+                              sizeof(XENBUS_SUSPEND_INTERFACE),
+                              FALSE);
+    if (!NT_SUCCESS(status))
+        goto fail5;
+
     status = XENVIF_VIF(Acquire,
                         &(*Adapter)->VifInterface);
     if (!NT_SUCCESS(status))
-        goto fail4;
+        goto fail6;
 
     status = XENBUS_CACHE(Acquire,
                           &(*Adapter)->CacheInterface);
     if (!NT_SUCCESS(status))
-        goto fail5;
+        goto fail7;
+
+    status = XENBUS_STORE(Acquire,
+                          &(*Adapter)->StoreInterface);
+    if (!NT_SUCCESS(status))
+        goto fail8;
+
+    status = XENBUS_SUSPEND(Acquire,
+                            &(*Adapter)->SuspendInterface);
+    if (!NT_SUCCESS(status))
+        goto fail9;
+
+    (VOID) AdapterSetDistribution(*Adapter);
 
     (*Adapter)->NdisAdapterHandle = Handle;
 
     ndisStatus = TransmitterInitialize(*Adapter, &(*Adapter)->Transmitter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail6;
+        goto fail10;
 
     ndisStatus = ReceiverInitialize(*Adapter, &(*Adapter)->Receiver);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail7;
+        goto fail11;
 
     ndisStatus = AdapterGetAdvancedSettings(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail8;
+        goto fail12;
 
     ndisStatus = AdapterSetRegistrationAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail9;
+        goto fail13;
 
     ndisStatus = AdapterSetGeneralAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail10;
+        goto fail14;
 
     ndisStatus = AdapterSetOffloadAttributes(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail11;
+        goto fail15;
 
     RtlZeroMemory(&Dma, sizeof(NDIS_SG_DMA_DESCRIPTION));
     Dma.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
@@ -2252,35 +2681,57 @@ AdapterInitialize(
 
     ndisStatus = AdapterEnable(*Adapter);
     if (ndisStatus != NDIS_STATUS_SUCCESS)
-        goto fail12;
+        goto fail16;
 
     return NDIS_STATUS_SUCCESS;
 
-fail12:
+fail16:
     if ((*Adapter)->NdisDmaHandle)
         NdisMDeregisterScatterGatherDma((*Adapter)->NdisDmaHandle);
     (*Adapter)->NdisDmaHandle = NULL;
-fail11:
-fail10:
-fail9:
-fail8:
+
+fail15:
+fail14:
+fail13:
+fail12:
     ReceiverTeardown((*Adapter)->Receiver);
     (*Adapter)->Receiver = NULL;
-fail7:
+fail11:
+
     TransmitterTeardown((*Adapter)->Transmitter);
     (*Adapter)->Transmitter = NULL;
-fail6:
+
+fail10:
     (*Adapter)->NdisAdapterHandle = NULL;
 
+    AdapterClearDistribution(*Adapter);
+
+    XENBUS_SUSPEND(Release, &(*Adapter)->SuspendInterface);
+
+fail9:
+    XENBUS_STORE(Release, &(*Adapter)->StoreInterface);
+
+fail8:
     XENBUS_CACHE(Release, &(*Adapter)->CacheInterface);
-fail5:
+
+fail7:
     XENVIF_VIF(Release, &(*Adapter)->VifInterface);
+
+fail6:
+    RtlZeroMemory(&(*Adapter)->SuspendInterface, sizeof(XENBUS_SUSPEND_INTERFACE));
+
+fail5:
+    RtlZeroMemory(&(*Adapter)->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
+
 fail4:
     RtlZeroMemory(&(*Adapter)->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
+
 fail3:
     RtlZeroMemory(&(*Adapter)->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
+
 fail2:
-    ExFreePoolWithTag(*Adapter, ADAPTER_POOL_TAG);
+    __AdapterFree(*Adapter);
+
 fail1:
     return ndisStatus;
 }
@@ -2300,11 +2751,17 @@ AdapterTeardown(
         NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
     Adapter->NdisDmaHandle = NULL;
 
-    XENBUS_CACHE(Release, &Adapter->CacheInterface);
-    RtlZeroMemory(&Adapter->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
+    AdapterClearDistribution(Adapter);
 
+    XENBUS_SUSPEND(Release, &Adapter->SuspendInterface);
+    XENBUS_STORE(Release, &Adapter->StoreInterface);
+    XENBUS_CACHE(Release, &Adapter->CacheInterface);
     XENVIF_VIF(Release, &Adapter->VifInterface);
+
+    RtlZeroMemory(&Adapter->SuspendInterface, sizeof(XENBUS_SUSPEND_INTERFACE));
+    RtlZeroMemory(&Adapter->StoreInterface, sizeof(XENBUS_STORE_INTERFACE));
+    RtlZeroMemory(&Adapter->CacheInterface, sizeof(XENBUS_CACHE_INTERFACE));
     RtlZeroMemory(&Adapter->VifInterface, sizeof(XENVIF_VIF_INTERFACE));
 
-    ExFreePoolWithTag(Adapter, ADAPTER_POOL_TAG);
+    __AdapterFree(Adapter);
 }
index 8c1862e646ea4b684be054c4ded03d022893322f..e78e41be05237f89271e9e71f95fbbbb28226c22 100644 (file)
@@ -40,7 +40,7 @@
                </ClCompile>
                <Link>
                        <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-                       <AdditionalDependencies>$(DDK_LIB_PATH)\ndis.lib;%(AdditionalDependencies)</AdditionalDependencies>
+                       <AdditionalDependencies>$(DDK_LIB_PATH)\ndis.lib;$(DDK_LIB_PATH)/libcntpr.lib;%(AdditionalDependencies)</AdditionalDependencies>
                        <EnableCOMDATFolding>false</EnableCOMDATFolding>
                </Link>
                <Inf>
index 0aa30a65e91f8467fd6c7fe9dcc1207e70e4f025..4e81fc42b75f339a204a2ca5687770590c75cbc2 100644 (file)
     <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
   </PropertyGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|x64'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Release|Win32'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows8 Debug|x64'">
-    <PlatformToolset>v120</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|Win32'">
-    <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
-  </PropertyGroup>
-  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Windows 8 Debug|x64'">
+  <PropertyGroup Label="Configuration">
     <PlatformToolset>WindowsKernelModeDriver8.1</PlatformToolset>
   </PropertyGroup>
   <PropertyGroup Label="Globals">
@@ -72,7 +36,7 @@
     </ClCompile>
     <Link>
       <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
-      <AdditionalDependencies>$(DDK_LIB_PATH)\ndis.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>$(DDK_LIB_PATH)/libcntpr.lib;$(DDK_LIB_PATH)\ndis.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <EnableCOMDATFolding>false</EnableCOMDATFolding>
     </Link>
     <Inf>