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
+
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
=============
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():
#include <ntddk.h>
+#include "assert.h"
+
#define P2ROUNDUP(_x, _a) \
(-(-(_x) & -(_a)))
#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,
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
#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;
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
<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" />
#include <strsafe.h>
#include <malloc.h>
#include <stdarg.h>
+#include <assert.h>
#include <tcpip.h>
#include <version.h>
#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"
#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(
}
-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;
PTCHAR Buffer;
DWORD Type;
BOOLEAN Success;
- PETHERNET_ADDRESS Address;
Location = GetProperty(DeviceInfoSet,
DeviceInfoData,
goto fail1;
Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- ADDRESSES_KEY(XENVIF),
+ ADDRESSES_KEY,
0,
KEY_READ,
&AddressesKey);
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);
Address->Byte[4],
Address->Byte[5]);
- return Address;
-
-fail8:
- Log("fail8");
-
- free(Address);
+ return TRUE;
fail7:
Log("fail7");
LocalFree(Message);
}
- return NULL;
+ return FALSE;
}
static BOOLEAN
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))
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");
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,
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;
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();
{
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();
}
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;
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;
if (!Success)
goto fail3;
+ RegCloseKey(Destination);
+
+ RegCloseKey(Source);
+
+ Log("<====");
+
return TRUE;
fail3:
}
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();
}
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");
fail2:
Log("fail2");
- RegCloseKey(ServiceKey);
+ RegCloseKey(UnplugKey);
fail1:
Error = GetLastError();
)
{
SP_DEVINSTALL_PARAMS DeviceInstallParams;
+ HRESULT Error;
DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
return TRUE;
fail2:
+ Log("fail2");
+
fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = __GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
return FALSE;
}
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
)
{
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");
fail3:
Log("fail3");
+ if (SoftwareKeyName != NULL)
+ free(SoftwareKeyName);
+
fail2:
Log("fail2");
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;
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
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
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;
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 {
; 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
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
// List of supported OIDs.
//
-static NDIS_STATUS
-AdapterStop (
- IN PADAPTER Adapter
- );
-
static NDIS_STATUS
AdapterSetRegistrationAttributes (
IN PADAPTER Adapter
//
// Frees resources obtained by AdapterInitialize.
//
-static VOID
+VOID
AdapterCleanup (
IN PADAPTER Adapter
)
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
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");
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);
TransmitterCompletePackets(Adapter->Transmitter, HeadPacket);
break;
}
- case XENVIF_CALLBACK_RECEIVE_PACKETS: {
+ case XENVIF_RECEIVER_QUEUE_PACKETS: {
PLIST_ENTRY List;
List = va_arg(Arguments, PLIST_ENTRY);
ReceiverReceivePackets(&Adapter->Receiver, List);
break;
}
- case XENVIF_CALLBACK_MEDIA_STATE_CHANGE: {
+ case XENVIF_MAC_STATE_CHANGE: {
AdapterMediaStateChange(Adapter);
break;
}
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;
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;
}
exit:
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ XENVIF_VIF(Release, &Adapter->VifInterface);
+
Trace("<==== (%08x)\n", ndisStatus);
return ndisStatus;
}
if (!Adapter->Enabled)
goto done;
- VIF(Disable,
- Adapter->VifInterface);
+ XENVIF_VIF(Disable,
+ &Adapter->VifInterface);
AdapterMediaStateChange(Adapter);
)
{
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;
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;
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;
}
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);
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;
}
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;
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;
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;
break;
case OID_802_3_MAXIMUM_LIST_SIZE:
- infoData = MAXIMUM_MULTICAST_ADDRESS_COUNT;
+ infoData = 32;
info = &infoData;
bytesAvailable = sizeof(ULONG);
break;
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;
goto done;
}
- status = VIF(Enable,
- Adapter->VifInterface,
+ status = XENVIF_VIF(Enable,
+ &Adapter->VifInterface,
AdapterVifCallback,
Adapter);
if (NT_SUCCESS(status)) {
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;
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;
{
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;
NdisZeroMemory(¤t, 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;
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;
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;
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;
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;
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;
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;
{
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;
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;
}
bytesNeeded = sizeof(*offloadEncapsulation);
if (informationBufferLength >= bytesNeeded) {
- XENVIF_OFFLOAD_OPTIONS Options;
+ XENVIF_VIF_OFFLOAD_OPTIONS Options;
bytesRead = bytesNeeded;
offloadEncapsulation = informationBuffer;
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;
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;
// Stops transmission of new packets.
// Stops received packet indication to NDIS.
//
-static NDIS_STATUS
+NDIS_STATUS
AdapterStop (
IN PADAPTER Adapter
)
if (!Adapter->Enabled)
goto done;
- VIF(Disable,
- Adapter->VifInterface);
+ XENVIF_VIF(Disable,
+ &Adapter->VifInterface);
Adapter->Enabled = FALSE;
struct _ADAPTER {
LIST_ENTRY ListEntry;
- PXENVIF_VIF_INTERFACE VifInterface;
+ XENVIF_VIF_INTERFACE VifInterface;
BOOLEAN AcquiredInterfaces;
ULONG MaximumFrameSize;
ULONG CurrentLookahead;
);
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
IN ULONG SendFlags
);
+NDIS_STATUS
+AdapterStop (
+ IN PADAPTER Adapter
+ );
+
MINIPORT_SHUTDOWN AdapterShutdown;
+
VOID
AdapterShutdown (
IN NDIS_HANDLE MiniportAdapterContext,
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)
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)
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
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)))
#include <version.h>
#include "common.h"
+#include "registry.h"
#pragma NDIS_INIT_FUNCTION(DriverEntry)
static NDIS_HANDLE MiniportDriverHandle;
extern MINIPORT_INITIALIZE MiniportInitialize;
+
extern NDIS_STATUS
MiniportInitialize (
IN NDIS_HANDLE MiniportAdapterHandle,
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;
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.
//
mpChars.CancelSendHandler = AdapterCancelSendNetBufferLists;
mpChars.CheckForHangHandlerEx = AdapterCheckForHang;
mpChars.InitializeHandlerEx = MiniportInitialize;
- mpChars.HaltHandlerEx = AdapterHalt;
+ mpChars.HaltHandlerEx = MiniportHalt;
mpChars.OidRequestHandler = AdapterOidRequest;
mpChars.PauseHandler = AdapterPause;
mpChars.DevicePnPEventNotifyHandler = AdapterPnPEventHandler;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail;
}
-fail:
Trace("<====\n");
return ndisStatus;
+
+fail:
+ Error("fail\n");
+ return ndisStatus;
}
VOID
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");
}
#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,
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,
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);
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);
}
)
{
PADAPTER Adapter;
+ LIST_ENTRY List;
ULONG Count;
Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+ InitializeListHead(&List);
+
Count = 0;
while (NetBufferList != NULL) {
PNET_BUFFER_LIST Next;
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;
}
IN PMDL Mdl,
IN ULONG Offset,
IN ULONG Length,
- IN XENVIF_CHECKSUM_FLAGS Flags,
+ IN XENVIF_PACKET_CHECKSUM_FLAGS Flags,
IN USHORT TagControlInformation
)
{
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;
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);
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);
}
}
#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
--- /dev/null
+/* 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);
+}
--- /dev/null
+/* 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
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
IN ULONG SendFlags
)
{
+ PADAPTER Adapter = Transmitter->Adapter;
PXENVIF_TRANSMITTER_PACKET HeadPacket;
PXENVIF_TRANSMITTER_PACKET *TailPacket;
KIRQL Irql;
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);
}
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);
NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_SUCCESS;
- NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle,
+ NdisMSendNetBufferListsComplete(Adapter->NdisAdapterHandle,
NetBufferList,
NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
}
#pragma once
typedef struct _TRANSMITTER {
- PADAPTER Adapter;
- XENVIF_OFFLOAD_OPTIONS OffloadOptions;
+ PADAPTER Adapter;
+ XENVIF_VIF_OFFLOAD_OPTIONS OffloadOptions;
} TRANSMITTER, *PTRANSMITTER;
VOID