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