--- /dev/null
+Copyright (c) Citrix Systems Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms,
+with or without modification, are permitted provided
+that the following conditions are met:
+
+* Redistributions of source code must retain the above
+ copyright notice, this list of conditions and the
+ following disclaimer.
+* Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
--- /dev/null
+#!python -u
+
+import os, sys
+import datetime
+import re
+import glob
+import tarfile
+import subprocess
+
+def next_build_number():
+ try:
+ file = open('.build_number', 'r')
+ build_number = file.read()
+ file.close()
+ except IOError:
+ build_number = '0'
+
+ file = open('.build_number', 'w')
+ file.write(str(int(build_number) + 1))
+ file.close()
+
+ return build_number
+
+
+def make_header():
+ now = datetime.datetime.now()
+
+ file = open('include\\version.h', 'w')
+ file.write('#define MAJOR_VERSION\t' + os.environ['MAJOR_VERSION'] + '\n')
+ file.write('#define MAJOR_VERSION_STR\t"' + os.environ['MAJOR_VERSION'] + '"\n')
+ file.write('\n')
+
+ file.write('#define MINOR_VERSION\t' + os.environ['MINOR_VERSION'] + '\n')
+ file.write('#define MINOR_VERSION_STR\t"' + os.environ['MINOR_VERSION'] + '"\n')
+ file.write('\n')
+
+ file.write('#define MICRO_VERSION\t' + os.environ['MICRO_VERSION'] + '\n')
+ file.write('#define MICRO_VERSION_STR\t"' + os.environ['MICRO_VERSION'] + '"\n')
+ file.write('\n')
+
+ file.write('#define BUILD_NUMBER\t' + os.environ['BUILD_NUMBER'] + '\n')
+ file.write('#define BUILD_NUMBER_STR\t"' + os.environ['BUILD_NUMBER'] + '"\n')
+ file.write('\n')
+
+ file.write('#define YEAR\t' + str(now.year) + '\n')
+ file.write('#define YEAR_STR\t"' + str(now.year) + '"\n')
+
+ file.write('#define MONTH\t' + str(now.month) + '\n')
+ file.write('#define MONTH_STR\t"' + str(now.month) + '"\n')
+
+ file.write('#define DAY\t' + str(now.day) + '\n')
+ file.write('#define DAY_STR\t"' + str(now.day) + '"\n')
+
+ file.close()
+
+
+def copy_inf(name):
+ src = open('src\\%s.inf' % name, 'r')
+ dst = open('proj\\%s.inf' % name, 'w')
+
+ for line in src:
+ line = re.sub('@MAJOR_VERSION@', os.environ['MAJOR_VERSION'], line)
+ line = re.sub('@MINOR_VERSION@', os.environ['MINOR_VERSION'], line)
+ line = re.sub('@MICRO_VERSION@', os.environ['MICRO_VERSION'], line)
+ line = re.sub('@BUILD_NUMBER@', os.environ['BUILD_NUMBER'], line)
+ dst.write(line)
+
+ dst.close()
+ src.close()
+
+
+def get_expired_symbols(name, age = 30):
+ path = os.path.join(os.environ['SYMBOL_SERVER'], '000Admin\\history.txt')
+
+ try:
+ file = open(path, 'r')
+ except IOError:
+ return []
+
+ threshold = datetime.datetime.utcnow() - datetime.timedelta(days = age)
+
+ expired = []
+
+ for line in file:
+ item = line.split(',')
+
+ if (re.match('add', item[1])):
+ id = item[0]
+ date = item[3].split('/')
+ time = item[4].split(':')
+ tag = item[5].strip('"')
+
+ age = datetime.datetime(year = int(date[2]),
+ month = int(date[0]),
+ day = int(date[1]),
+ hour = int(time[0]),
+ minute = int(time[1]),
+ second = int(time[2]))
+ if (tag == name and age < threshold):
+ expired.append(id)
+
+ elif (re.match('del', item[1])):
+ id = item[2].rstrip()
+ try:
+ expired.remove(id)
+ except ValueError:
+ pass
+
+ file.close()
+
+ return expired
+
+
+def get_configuration(debug):
+ configuration = 'Windows Vista'
+
+ if debug:
+ configuration += ' Debug'
+ else:
+ configuration += ' Release'
+
+ return configuration
+
+def get_configuration_name(debug):
+ configuration = 'WindowsVista'
+
+ if debug:
+ configuration += 'Debug'
+ else:
+ configuration += 'Release'
+
+ return configuration
+
+def get_target_path(arch, debug):
+ configuration = get_configuration_name(debug)
+
+ target = { 'x86': 'proj', 'x64': os.sep.join(['proj', 'x64']) }
+ target_path = os.sep.join([target[arch], configuration])
+
+ return target_path
+
+
+def shell(command):
+ print(command)
+ sys.stdout.flush()
+
+ pipe = os.popen(command, 'r', 1)
+
+ for line in pipe:
+ print(line.rstrip())
+
+ return pipe.close()
+
+
+class msbuild_failure(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+def msbuild(name, arch, debug):
+ cwd = os.getcwd()
+ configuration = get_configuration(debug)
+
+ os.environ['SOLUTION'] = name
+
+ if arch == 'x86':
+ os.environ['PLATFORM'] = 'Win32'
+ elif arch == 'x64':
+ os.environ['PLATFORM'] = 'x64'
+
+ os.environ['CONFIGURATION'] = configuration
+ os.environ['TARGET'] = 'Build'
+
+ os.chdir('proj')
+ status = shell('msbuild.bat')
+ os.chdir(cwd)
+
+ if (status != None):
+ raise msbuild_failure(configuration)
+
+
+def symstore_del(name, age):
+ symstore_path = [os.environ['KIT'], 'Debuggers']
+ if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86':
+ symstore_path.append('x86')
+ else:
+ symstore_path.append('x64')
+ symstore_path.append('symstore.exe')
+
+ symstore = os.path.join(*symstore_path)
+
+ for id in get_expired_symbols(name, age):
+ command=['"' + symstore + '"']
+ command.append('del')
+ command.append('/i')
+ command.append(str(id))
+ command.append('/s')
+ command.append(os.environ['SYMBOL_SERVER'])
+
+ shell(' '.join(command))
+
+def symstore_add(name, arch, debug):
+ cwd = os.getcwd()
+ configuration = get_configuration_name(debug)
+ target_path = get_target_path(arch, debug)
+
+ symstore_path = [os.environ['KIT'], 'Debuggers']
+ if os.environ['PROCESSOR_ARCHITECTURE'] == 'x86':
+ symstore_path.append('x86')
+ else:
+ symstore_path.append('x64')
+ symstore_path.append('symstore.exe')
+
+ symstore = os.path.join(*symstore_path)
+
+ version = '.'.join([os.environ['MAJOR_VERSION'],
+ os.environ['MINOR_VERSION'],
+ os.environ['MICRO_VERSION'],
+ os.environ['BUILD_NUMBER']])
+
+ os.chdir(target_path)
+ command=['"' + symstore + '"']
+ command.append('add')
+ command.append('/s')
+ command.append(os.environ['SYMBOL_SERVER'])
+ command.append('/r')
+ command.append('/f')
+ command.append('*.pdb')
+ command.append('/t')
+ command.append(name)
+ command.append('/v')
+ command.append(version)
+
+ shell(' '.join(command))
+
+ os.chdir(cwd)
+
+
+def callfnout(cmd):
+ print(cmd)
+
+ sub = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ output = sub.communicate()[0]
+ ret = sub.returncode
+
+ if ret != 0:
+ raise(Exception("Error %d in : %s" % (ret, cmd)))
+
+ return output.decode('utf-8')
+
+
+def archive(filename, files, tgz=False):
+ access='w'
+ if tgz:
+ access='w:gz'
+ tar = tarfile.open(filename, access)
+ for name in files :
+ try:
+ print('adding '+name)
+ tar.add(name)
+ except:
+ pass
+ tar.close()
+
+
+if __name__ == '__main__':
+ debug = { 'checked': True, 'free': False }
+ driver = 'xennet'
+
+ os.environ['MAJOR_VERSION'] = '7'
+ os.environ['MINOR_VERSION'] = '0'
+ os.environ['MICRO_VERSION'] = '0'
+
+ if 'BUILD_NUMBER' not in os.environ.keys():
+ os.environ['BUILD_NUMBER'] = next_build_number()
+
+ print("BUILD_NUMBER=%s" % os.environ['BUILD_NUMBER'])
+
+ if 'MERCURIAL_REVISION' in os.environ.keys():
+ revision = open('revision', 'w')
+ print(os.environ['MERCURIAL_REVISION'], file=revision)
+ revision.close()
+
+ make_header()
+
+ copy_inf(driver)
+
+ symstore_del(driver, 30)
+
+ msbuild(driver, 'x86', debug[sys.argv[1]])
+ msbuild(driver, 'x64', debug[sys.argv[1]])
+
+ symstore_add(driver, 'x86', debug[sys.argv[1]])
+ symstore_add(driver, 'x64', debug[sys.argv[1]])
+
+ listfile = callfnout(['hg','manifest'])
+ archive(driver + '\\source.tgz', listfile.splitlines(), tgz=True)
+ archive(driver + '.tar', [driver,'revision'])
+
+
--- /dev/null
+#!/usr/bin/env python
+
+import os, sys
+
+file = os.popen('hg status')
+
+for line in file:
+ item = line.split(' ')
+ if item[0] == '?':
+ path = ' '.join(item[1:]).rstrip()
+ print(path)
+ os.remove(path)
+
+file.close()
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _ETHERNET_H_
+#define _ETHERNET_H_
+
+#pragma warning(push)
+#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
+
+#pragma pack(push, 1)
+
+// Ethernet data structures
+//
+// NOTE: Fields are in network byte order
+
+#define ETHERNET_MTU 1500
+#define ETHERNET_MIN 60
+#define ETHERNET_MAX 1514
+
+typedef struct _ETHERNET_ADDRESS {
+ UCHAR Byte[6];
+} ETHERNET_ADDRESS, *PETHERNET_ADDRESS;
+
+#define ETHERNET_ADDRESS_LENGTH (sizeof (ETHERNET_ADDRESS))
+
+typedef enum _ETHERNET_ADDRESS_TYPE {
+ ETHERNET_ADDRESS_TYPE_INVALID = 0,
+ ETHERNET_ADDRESS_UNICAST,
+ ETHERNET_ADDRESS_MULTICAST,
+ ETHERNET_ADDRESS_BROADCAST,
+ ETHERNET_ADDRESS_TYPE_COUNT
+} ETHERNET_ADDRESS_TYPE, *PETHERNET_ADDRESS_TYPE;
+
+#define GET_ETHERNET_ADDRESS_TYPE(_Address) \
+ (((_Address)->Byte[0] & 0x01) ? \
+ (((((_Address)->Byte[0] & ~0x03) == 0xFC) && \
+ (((_Address)->Byte[1] ) == 0xFF) && \
+ (((_Address)->Byte[2] ) == 0xFF) && \
+ (((_Address)->Byte[3] ) == 0xFF) && \
+ (((_Address)->Byte[4] ) == 0xFF) && \
+ (((_Address)->Byte[5] ) == 0xFF) \
+ ) ? \
+ ETHERNET_ADDRESS_BROADCAST : \
+ ETHERNET_ADDRESS_MULTICAST \
+ ) : \
+ ETHERNET_ADDRESS_UNICAST \
+ )
+
+typedef struct _ETHERNET_UNTAGGED_HEADER {
+ ETHERNET_ADDRESS DestinationAddress;
+ ETHERNET_ADDRESS SourceAddress;
+ USHORT TypeOrLength;
+
+#define ETHERTYPE_IPV4 0x0800
+#define ETHERTYPE_IPV6 0x86DD
+#define ETHERTYPE_ARP 0x0806
+#define ETHERTYPE_RARP 0x0835
+#define ETHERTYPE_TPID 0x8100
+#define ETHERTYPE_LOOPBACK 0x9000
+
+} ETHERNET_UNTAGGED_HEADER, *PETHERNET_UNTAGGED_HEADER;
+
+typedef struct _ETHERNET_TAG {
+ USHORT ProtocolID; // == ETHERTYPE_TPID
+ USHORT ControlInformation;
+
+#define PACK_TAG_CONTROL_INFORMATION(_ControlInformation, _UserPriority, _CanonicalFormatId, _VlanId) \
+ do { \
+ (_ControlInformation) = (USHORT)(_VlanId) & 0x0FFF; \
+ (_ControlInformation) |= (USHORT)((_CanonicalFormatId) << 12) & 0x1000; \
+ (_ControlInformation) |= (USHORT)((_UserPriority) << 13) & 0xE000; \
+ } while (FALSE)
+
+#define UNPACK_TAG_CONTROL_INFORMATION(_ControlInformation, _UserPriority, _CanonicalFormatId, _VlanId) \
+ do { \
+ (_VlanId) = (_ControlInformation) & 0xFFF; \
+ (_CanonicalFormatId) = ((_ControlInformation) & 0x1000) >> 12; \
+ (_UserPriority) = ((_ControlInformation) & 0xE000) >> 13; \
+ } while (FALSE)
+
+} ETHERNET_TAG, *PETHERNET_TAG;
+
+typedef struct _ETHERNET_TAGGED_HEADER {
+ ETHERNET_ADDRESS DestinationAddress;
+ ETHERNET_ADDRESS SourceAddress;
+ ETHERNET_TAG Tag;
+ USHORT TypeOrLength;
+} ETHERNET_TAGGED_HEADER, *PETHERNET_TAGGED_HEADER;
+
+typedef union _ETHERNET_HEADER {
+ ETHERNET_UNTAGGED_HEADER Untagged;
+ ETHERNET_TAGGED_HEADER Tagged;
+} ETHERNET_HEADER, *PETHERNET_HEADER;
+
+#define ETHERNET_HEADER_IS_TAGGED(_Header) \
+ ((_Header)->Untagged.TypeOrLength == NTOHS(ETHERTYPE_TPID))
+
+#define ETHERNET_HEADER_LENGTH(_Header) \
+ ETHERNET_HEADER_IS_TAGGED(_Header) ? \
+ sizeof (ETHERNET_TAGGED_HEADER) : \
+ sizeof (ETHERNET_UNTAGGEDHEADER))
+
+#pragma pack(pop)
+
+#pragma warning(pop)
+
+#endif // _ETHERNET_H
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "ethernet.h"
+
+#ifndef _TCPIP_H
+#define _TCPIP_H
+
+#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
+
+#define NTOHS(_Value) _byteswap_ushort(_Value)
+#define HTONS(_Value) _byteswap_ushort(_Value)
+#define NTOHL(_Value) _byteswap_ulong(_Value)
+#define HTONL(_Value) _byteswap_ulong(_Value)
+
+#pragma pack(push, 1)
+
+// TCP/IP data structures
+//
+// NOTE: Fields are in network byte order
+
+// IPv4
+
+typedef struct _IPV4_ADDRESS {
+ union {
+ ULONG Dword[1];
+ UCHAR Byte[4];
+ };
+} IPV4_ADDRESS, *PIPV4_ADDRESS;
+
+#define IPV4_ADDRESS_LENGTH (sizeof (IPV4_ADDRESS))
+
+typedef struct _IPV4_HEADER {
+ UCHAR HeaderLength:4;
+ UCHAR Version:4;
+ UCHAR TypeOfService;
+ USHORT PacketLength;
+ USHORT PacketID;
+ USHORT FragmentOffsetAndFlags;
+
+#define IPV4_FRAGMENT_OFFSET(_FragmentOffsetAndFlags) \
+ ((_FragmentOffsetAndFlags) & 0x1fff)
+#define IPV4_DONT_FRAGMENT(_FragmentOffsetAndFlags) \
+ ((_FragmentOffsetAndFlags) & 0x4000)
+#define IPV4_MORE_FRAGMENTS(_FragmentOffsetAndFlags) \
+ ((_FragmentOffsetAndFlags) & 0x2000)
+#define IPV4_IS_A_FRAGMENT(_FragmentOffsetAndFlags) \
+ ((_FragmentOffsetAndFlags) & 0x3fff)
+
+ UCHAR TimeToLive;
+ UCHAR Protocol;
+ USHORT Checksum;
+ IPV4_ADDRESS SourceAddress;
+ IPV4_ADDRESS DestinationAddress;
+} IPV4_HEADER, *PIPV4_HEADER;
+
+#define IPV4_HEADER_LENGTH(_Header) \
+ (((ULONG)((_Header)->HeaderLength)) << 2)
+
+#define MAXIMUM_IPV4_HEADER_LENGTH \
+ (0xF << 2)
+
+// IPv6
+
+typedef struct _IPV6_ADDRESS {
+ union {
+ ULONG Dword[4];
+ UCHAR Byte[16];
+ };
+} IPV6_ADDRESS, *PIPV6_ADDRESS;
+
+#define IPV6_ADDRESS_LENGTH (sizeof (IPV6_ADDRESS))
+
+typedef struct _IPV6_HEADER {
+ union {
+ struct {
+ UCHAR __Pad:4;
+ UCHAR Version:4;
+ };
+ ULONG VCF;
+ };
+ USHORT PayloadLength;
+ UCHAR NextHeader;
+ UCHAR HopLimit;
+ IPV6_ADDRESS SourceAddress;
+ IPV6_ADDRESS DestinationAddress;
+} IPV6_HEADER, *PIPV6_HEADER;
+
+#define IPV6_HEADER_LENGTH(_Header) \
+ (ULONG)(sizeof (IPV6_HEADER))
+
+// IP
+
+typedef union _IP_ADDRESS {
+ IPV4_ADDRESS Version4;
+ IPV6_ADDRESS Version6;
+} IP_ADDRESS, *PIP_ADDRESS;
+
+typedef union _IP_HEADER {
+ struct {
+ UCHAR __Pad:4;
+ UCHAR Version:4;
+ };
+ IPV4_HEADER Version4;
+ IPV6_HEADER Version6;
+} IP_HEADER, *PIP_HEADER;
+
+#define IP_HEADER_LENGTH(_Header) \
+ (((_Header)->Version == 4) ? \
+ IPV4_HEADER_LENGTH(&(_Header)->Version4) : \
+ IPV6_HEADER_LENGTH(&(_Header)->Version6))
+
+#define IPPROTO_HOP_OPTIONS 0
+#define IPPROTO_DST_OPTIONS 60
+#define IPPROTO_ROUTING 43
+
+// Options
+
+typedef struct _IPV6_OPTION_HEADER {
+ UCHAR NextHeader;
+ UCHAR PayloadLength;
+} IPV6_OPTION_HEADER, *PIPV6_OPTION_HEADER;
+
+#define IPV6_OPTION_HEADER_LENGTH(_Header) \
+ (ULONG)(sizeof (IPV6_OPTION_HEADER) + (_Header)->PayloadLength)
+
+#define IPPROTO_TCP 6
+
+// TCP
+
+typedef struct _TCP_HEADER {
+ USHORT SourcePort;
+ USHORT DestinationPort;
+ ULONG Seq;
+ ULONG Ack;
+ UCHAR Reserved:4;
+ UCHAR HeaderLength:4;
+ UCHAR Flags;
+
+#define TCP_FIN 0x01
+#define TCP_SYN 0x02
+#define TCP_RST 0x04
+#define TCP_PSH 0x08
+#define TCP_ACK 0x10
+#define TCP_URG 0x20
+#define TCP_ECE 0x40
+#define TCP_CWR 0x80
+
+ USHORT Window;
+ USHORT Checksum;
+ USHORT UrgentPointer;
+} TCP_HEADER, *PTCP_HEADER;
+
+#define TCP_HEADER_LENGTH(_Header) \
+ (((ULONG)((_Header)->HeaderLength)) << 2)
+
+#define MAXIMUM_TCP_HEADER_LENGTH \
+ (0xF << 2)
+
+#define TCPOPT_NOP 1
+#define TCPOPT_TIMESTAMP 8
+#define TCPOLEN_TIMESTAMP 10
+
+#define IPPROTO_UDP 17
+
+// UDP
+
+typedef struct _UDP_HEADER {
+ USHORT SourcePort;
+ USHORT DestinationPort;
+ USHORT PacketLength;
+ USHORT Checksum;
+} UDP_HEADER, *PUDP_HEADER;
+
+#define UDP_HEADER_LENGTH(_Header) \
+ (ULONG)(sizeof (UDP_HEADER))
+
+#define IPPROTO_NONE 59
+
+// Checksum
+
+typedef struct _IPV4_PSEUDO_HEADER {
+ IPV4_ADDRESS SourceAddress;
+ IPV4_ADDRESS DestinationAddress;
+ UCHAR Zero;
+ UCHAR Protocol; // TCP or UDP
+ USHORT Length; // Including TCP/UDP header
+} IPV4_PSEUDO_HEADER, *PIPV4_PSEUDO_HEADER;
+
+typedef struct _IPV6_PSEUDO_HEADER {
+ IPV6_ADDRESS SourceAddress;
+ IPV6_ADDRESS DestinationAddress;
+ USHORT Length; // Including TCP/UDP header
+ UCHAR Zero[3];
+ UCHAR NextHeader; // TCP or UDP
+} IPV6_PSEUDO_HEADER, *PIPV6_PSEUDO_HEADER;
+
+typedef union _PSEUDO_HEADER {
+ IPV4_PSEUDO_HEADER Version4;
+ IPV6_PSEUDO_HEADER Version6;
+} PSEUDO_HEADER, *PPSEUDO_HEADER;
+
+// ARP
+
+typedef struct _ARP_HEADER {
+ USHORT HardwareType;
+
+#define HARDWARE_ETHER 1
+
+ USHORT ProtocolType;
+
+#define PROTOCOL_IPV4 ETHERTYPE_IPV4
+
+ UCHAR HardwareAddressLength;
+ UCHAR ProtocolAddressLength;
+ USHORT Operation;
+
+#define ARP_REQUEST 1
+#define ARP_REPLY 2
+#define RARP_REQUEST 3
+#define RARP_REPLY 4
+
+} ARP_HEADER, *PARP_HEADER;
+
+#define ARP_HEADER_LENGTH(_Header) \
+ (ULONG)(sizeof (ARP_HEADER))
+
+#pragma pack(pop)
+
+#pragma warning(pop)
+
+#endif //_TCPIP_H
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _UTIL_H
+#define _UTIL_H
+
+#include <ntddk.h>
+
+#define P2ROUNDUP(_x, _a) \
+ (-(-(_x) & -(_a)))
+
+static FORCEINLINE LONG
+__ffs(
+ IN unsigned long long mask
+ )
+{
+ unsigned char *array = (unsigned char *)&mask;
+ unsigned int byte;
+ unsigned int bit;
+ unsigned char val;
+
+ val = 0;
+
+ byte = 0;
+ while (byte < 8) {
+ val = array[byte];
+
+ if (val != 0)
+ break;
+
+ byte++;
+ }
+ if (byte == 8)
+ return -1;
+
+ bit = 0;
+ while (bit < 8) {
+ if (val & 0x01)
+ break;
+
+ val >>= 1;
+ bit++;
+ }
+
+ return (byte * 8) + bit;
+}
+
+#define __ffu(_mask) \
+ __ffs(~(_mask))
+
+static FORCEINLINE LONG
+__InterlockedAdd(
+ IN LONG *Value,
+ IN LONG Delta
+ )
+{
+ LONG New;
+ LONG Old;
+
+ do {
+ Old = *Value;
+ New = Old + Delta;
+ } while (InterlockedCompareExchange(Value, New, Old) != Old);
+
+ return New;
+}
+
+static FORCEINLINE LONG
+__InterlockedSubtract(
+ IN LONG *Value,
+ IN LONG Delta
+ )
+{
+ LONG New;
+ LONG Old;
+
+ do {
+ Old = *Value;
+ New = Old - Delta;
+ } while (InterlockedCompareExchange(Value, New, Old) != Old);
+
+ return New;
+}
+
+#endif // _UTIL_H
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENVIF_VIF_INTERFACE_H
+#define _XENVIF_VIF_INTERFACE_H
+
+#include <ifdef.h>
+#include <ethernet.h>
+
+#define MAX_SKB_FRAGS ((65536/PAGE_SIZE) + 2)
+
+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 {
+ ULONG Offset;
+ ULONG Length;
+} XENVIF_PACKET_HEADER, *PXENVIF_PACKET_HEADER;
+
+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;
+ ULONG Length;
+} 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;
+ };
+} XENVIF_CHECKSUM_FLAGS, *PXENVIF_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;
+
+#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 {
+ union {
+ struct {
+ USHORT OffloadTagManipulation:1;
+ USHORT OffloadIpVersion4LargePacket:1;
+ USHORT OffloadIpVersion4HeaderChecksum:1;
+ USHORT OffloadIpVersion4TcpChecksum:1;
+ USHORT OffloadIpVersion4UdpChecksum:1;
+ USHORT OffloadIpVersion6LargePacket:1;
+ USHORT OffloadIpVersion6TcpChecksum:1;
+ USHORT OffloadIpVersion6UdpChecksum:1;
+ USHORT NeedChecksumValue:1;
+ USHORT NeedLargePacketSplit:1;
+ USHORT Reserved:6;
+ };
+
+ USHORT Value;
+ };
+} XENVIF_OFFLOAD_OPTIONS, *PXENVIF_OFFLOAD_OPTIONS;
+
+#pragma warning(pop)
+
+typedef struct _XENVIF_TRANSMITTER_PACKET XENVIF_TRANSMITTER_PACKET, *PXENVIF_TRANSMITTER_PACKET;
+
+// 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;
+
+#pragma warning(push)
+#pragma warning(disable:4201) // nonstandard extension used : nameless struct/union
+
+struct _XENVIF_TRANSMITTER_PACKET {
+ PXENVIF_TRANSMITTER_PACKET Next;
+ union {
+ XENVIF_SEND_INFO Send;
+ XENVIF_COMPLETION_INFO Completion;
+ };
+};
+
+#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 {
+ ULONG Drop;
+ ULONG BackendError;
+ ULONG FrontendError;
+ ULONG Unicast;
+ ULONG UnicastBytes;
+ ULONG Multicast;
+ ULONG MulticastBytes;
+ ULONG Broadcast;
+ ULONG 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
+
+typedef enum _XENVIF_MAC_FILTER_LEVEL {
+ MAC_FILTER_NONE = 0,
+ MAC_FILTER_MATCHING = 1,
+ 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 12
+
+#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__)
+
+#endif // _XENVIF_INTERFACE_H
+
--- /dev/null
+#!python -u
+
+import os, sys
+import subprocess
+import glob
+from pprint import pprint
+
+def regenerate_kdfiles(filename, arch, pkg, source):
+ cwd = os.getcwd()
+ file = open(filename, 'w')
+ os.chdir(pkg + '/' + arch)
+ drivers = glob.glob('*.sys')
+ pprint(drivers)
+ for driver in drivers:
+ file.write("map\n")
+ file.write('\SystemRoot\System32\drivers\\' + driver + '\n')
+ file.write(source + '\\' + pkg + '\\' + arch + '\\' + driver + '\n')
+ file.write('\n')
+ os.chdir(cwd)
+ file.close()
+
+if __name__ == '__main__':
+ pkg = 'xennet'
+ source = os.getcwd()
+ regenerate_kdfiles('kdfiles32.txt', 'x86', pkg, source)
+ regenerate_kdfiles('kdfiles64.txt', 'x64', pkg, source)
--- /dev/null
+call "%VS%\VC\vcvarsall.bat" x86
+msbuild.exe /m:4 /p:Configuration="%CONFIGURATION%" /p:Platform="%PLATFORM%" /t:"%TARGET%" /p:SignMode="ProductionSign" %SOLUTION%.sln
+if errorlevel 1 goto error
+exit 0
+
+:error
+exit 1
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Windows Developer Preview Debug|Win32">
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Release|Win32">
+ <Configuration>Windows Developer Preview Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|Win32">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|Win32">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|Win32">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|Win32">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Debug|x64">
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Release|x64">
+ <Configuration>Windows Developer Preview Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|x64">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|x64">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|x64">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|x64">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{445FD18F-97E3-4E5D-825F-151026242C05}</ProjectGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
+ <ConfigurationType>Utility</ConfigurationType>
+ <DriverType>Package</DriverType>
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|x64'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <EnableInf2cat>true</EnableInf2cat>
+ <Inf2CatWindowsVersionList Condition="'$(Platform)'=='x64'">Vista_$(DDKPlatform);7_$(DDKPlatform);Server2008_$(DDKPlatform);Server2008R2_$(DDKPlatform)</Inf2CatWindowsVersionList>
+ <Inf2CatWindowsVersionList Condition="'$(Platform)'=='Win32'">Vista_$(DDKPlatform);7_$(DDKPlatform);Server2008_$(DDKPlatform)</Inf2CatWindowsVersionList>
+ </PropertyGroup>
+ <PropertyGroup>
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ <EnableDeployment>False</EnableDeployment>
+ <ImportToStore>False</ImportToStore>
+ <InstallMode>None</InstallMode>
+ <HardwareIdString />
+ <CommandLine />
+ <ScriptPath />
+ <DeployFiles />
+ <ScriptName />
+ <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>
+ <EnableVerifier>False</EnableVerifier>
+ <AllDrivers>False</AllDrivers>
+ <VerifyProjectOutput>True</VerifyProjectOutput>
+ <VerifyDrivers />
+ <VerifyFlags>133563</VerifyFlags>
+ <PackageDir>..\..\xennet\$(DDKPlatform)</PackageDir>
+ </PropertyGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\xennet\xennet.vcxproj">
+ <Project>{97D9942B-5EA3-488C-B512-C96E5D077F8E}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\xennet_coinst\xennet_coinst.vcxproj">
+ <Project>{3EDD837A-C1BE-47D4-9603-16B61353670B}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x86\dpinst.exe" Condition="'$(Platform)'=='Win32'" />
+ <FilesToPackage Include="$(KIT)\Redist\DIFx\dpinst\EngMui\x64\dpinst.exe" Condition="'$(Platform)'=='x64'" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SignMode>ProductionSign</SignMode>
+ <ProductionCertificate>CN="Citrix Systems, Inc.", OU=Digital ID Class 3 - Microsoft Software Validation v2, O="Citrix Systems, Inc.", L=Santa Clara, S=California, C=US | 9505C081954CC0A3E8B904458ACACD72EABD98B5</ProductionCertificate>
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 11
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xennet", "xennet\xennet.vcxproj", "{97D9942B-5EA3-488C-B512-C96E5D077F8E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xennet_coinst", "xennet_coinst\xennet_coinst.vcxproj", "{3EDD837A-C1BE-47D4-9603-16B61353670B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "package\package.vcxproj", "{445FD18F-97E3-4E5D-825F-151026242C05}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3EDD837A-C1BE-47D4-9603-16B61353670B} = {3EDD837A-C1BE-47D4-9603-16B61353670B}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Windows 7 Debug|Win32 = Windows 7 Debug|Win32
+ Windows 7 Debug|x64 = Windows 7 Debug|x64
+ Windows 7 Release|Win32 = Windows 7 Release|Win32
+ Windows 7 Release|x64 = Windows 7 Release|x64
+ Windows Developer Preview Debug|Win32 = Windows Developer Preview Debug|Win32
+ Windows Developer Preview Debug|x64 = Windows Developer Preview Debug|x64
+ Windows Developer Preview Release|Win32 = Windows Developer Preview Release|Win32
+ Windows Developer Preview Release|x64 = Windows Developer Preview Release|x64
+ Windows Vista Debug|Win32 = Windows Vista Debug|Win32
+ Windows Vista Debug|x64 = Windows Vista Debug|x64
+ Windows Vista Release|Win32 = Windows Vista Release|Win32
+ Windows Vista Release|x64 = Windows Vista Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Debug|Win32.Build.0 = Windows 7 Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Debug|x64.ActiveCfg = Windows 7 Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Debug|x64.Build.0 = Windows 7 Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Debug|x64.Deploy.0 = Windows 7 Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Release|Win32.ActiveCfg = Windows 7 Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Release|Win32.Build.0 = Windows 7 Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Release|Win32.Deploy.0 = Windows 7 Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Release|x64.ActiveCfg = Windows 7 Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Release|x64.Build.0 = Windows 7 Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows 7 Release|x64.Deploy.0 = Windows 7 Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Debug|Win32.ActiveCfg = Windows Developer Preview Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Debug|Win32.Build.0 = Windows Developer Preview Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Debug|Win32.Deploy.0 = Windows Developer Preview Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Debug|x64.ActiveCfg = Windows Developer Preview Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Debug|x64.Build.0 = Windows Developer Preview Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Debug|x64.Deploy.0 = Windows Developer Preview Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Release|Win32.ActiveCfg = Windows Developer Preview Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Release|Win32.Build.0 = Windows Developer Preview Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Release|Win32.Deploy.0 = Windows Developer Preview Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Release|x64.ActiveCfg = Windows Developer Preview Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Release|x64.Build.0 = Windows Developer Preview Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Developer Preview Release|x64.Deploy.0 = Windows Developer Preview Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Debug|Win32.ActiveCfg = Windows Vista Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Debug|Win32.Build.0 = Windows Vista Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Debug|Win32.Deploy.0 = Windows Vista Debug|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Debug|x64.ActiveCfg = Windows Vista Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Debug|x64.Build.0 = Windows Vista Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Debug|x64.Deploy.0 = Windows Vista Debug|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Release|Win32.ActiveCfg = Windows Vista Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Release|Win32.Build.0 = Windows Vista Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Release|Win32.Deploy.0 = Windows Vista Release|Win32
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Release|x64.ActiveCfg = Windows Vista Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Release|x64.Build.0 = Windows Vista Release|x64
+ {3EDD837A-C1BE-47D4-9603-16B61353670B}.Windows Vista Release|x64.Deploy.0 = Windows Vista Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Debug|Win32.Build.0 = Windows 7 Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Debug|x64.ActiveCfg = Windows 7 Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Debug|x64.Build.0 = Windows 7 Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Debug|x64.Deploy.0 = Windows 7 Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Release|Win32.ActiveCfg = Windows 7 Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Release|Win32.Build.0 = Windows 7 Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Release|Win32.Deploy.0 = Windows 7 Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Release|x64.ActiveCfg = Windows 7 Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Release|x64.Build.0 = Windows 7 Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows 7 Release|x64.Deploy.0 = Windows 7 Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Debug|Win32.ActiveCfg = Windows Developer Preview Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Debug|Win32.Build.0 = Windows Developer Preview Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Debug|Win32.Deploy.0 = Windows Developer Preview Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Debug|x64.ActiveCfg = Windows Developer Preview Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Debug|x64.Build.0 = Windows Developer Preview Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Debug|x64.Deploy.0 = Windows Developer Preview Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Release|Win32.ActiveCfg = Windows Developer Preview Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Release|Win32.Build.0 = Windows Developer Preview Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Release|Win32.Deploy.0 = Windows Developer Preview Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Release|x64.ActiveCfg = Windows Developer Preview Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Release|x64.Build.0 = Windows Developer Preview Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Developer Preview Release|x64.Deploy.0 = Windows Developer Preview Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Debug|Win32.ActiveCfg = Windows Vista Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Debug|Win32.Build.0 = Windows Vista Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Debug|Win32.Deploy.0 = Windows Vista Debug|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Debug|x64.ActiveCfg = Windows Vista Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Debug|x64.Build.0 = Windows Vista Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Debug|x64.Deploy.0 = Windows Vista Debug|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Release|Win32.ActiveCfg = Windows Vista Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Release|Win32.Build.0 = Windows Vista Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Release|Win32.Deploy.0 = Windows Vista Release|Win32
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Release|x64.ActiveCfg = Windows Vista Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Release|x64.Build.0 = Windows Vista Release|x64
+ {445FD18F-97E3-4E5D-825F-151026242C05}.Windows Vista Release|x64.Deploy.0 = Windows Vista Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Debug|Win32.ActiveCfg = Windows 7 Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Debug|Win32.Build.0 = Windows 7 Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Debug|Win32.Deploy.0 = Windows 7 Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Debug|x64.ActiveCfg = Windows 7 Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Debug|x64.Build.0 = Windows 7 Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Debug|x64.Deploy.0 = Windows 7 Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Release|Win32.ActiveCfg = Windows 7 Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Release|Win32.Build.0 = Windows 7 Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Release|Win32.Deploy.0 = Windows 7 Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Release|x64.ActiveCfg = Windows 7 Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Release|x64.Build.0 = Windows 7 Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows 7 Release|x64.Deploy.0 = Windows 7 Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Debug|Win32.ActiveCfg = Windows Developer Preview Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Debug|Win32.Build.0 = Windows Developer Preview Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Debug|Win32.Deploy.0 = Windows Developer Preview Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Debug|x64.ActiveCfg = Windows Developer Preview Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Debug|x64.Build.0 = Windows Developer Preview Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Debug|x64.Deploy.0 = Windows Developer Preview Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Release|Win32.ActiveCfg = Windows Developer Preview Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Release|Win32.Build.0 = Windows Developer Preview Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Release|Win32.Deploy.0 = Windows Developer Preview Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Release|x64.ActiveCfg = Windows Developer Preview Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Release|x64.Build.0 = Windows Developer Preview Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Developer Preview Release|x64.Deploy.0 = Windows Developer Preview Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Debug|Win32.ActiveCfg = Windows Vista Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Debug|Win32.Build.0 = Windows Vista Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Debug|Win32.Deploy.0 = Windows Vista Debug|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Debug|x64.ActiveCfg = Windows Vista Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Debug|x64.Build.0 = Windows Vista Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Debug|x64.Deploy.0 = Windows Vista Debug|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Release|Win32.ActiveCfg = Windows Vista Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Release|Win32.Build.0 = Windows Vista Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Release|Win32.Deploy.0 = Windows Vista Release|Win32
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Release|x64.ActiveCfg = Windows Vista Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Release|x64.Build.0 = Windows Vista Release|x64
+ {97D9942B-5EA3-488C-B512-C96E5D077F8E}.Windows Vista Release|x64.Deploy.0 = Windows Vista Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Windows Developer Preview Debug|Win32">
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Release|Win32">
+ <Configuration>Windows Developer Preview Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|Win32">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|Win32">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|Win32">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|Win32">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Debug|x64">
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Release|x64">
+ <Configuration>Windows Developer Preview Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|x64">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|x64">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|x64">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|x64">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{97D9942B-5EA3-488C-B512-C96E5D077F8E}</ProjectGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <ProjectName>xennet</ProjectName>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
+ <ConfigurationType>Driver</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|x64'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <EnableInf2cat>false</EnableInf2cat>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>__i386__;__MODULE__="XENNET";NDIS_MINIPORT_DRIVER;NDIS60_MINIPORT=1;POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <EnablePREfast>true</EnablePREfast>
+ </ClCompile>
+ <Link>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\ndis.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Inf>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <Architecture>x86</Architecture>
+ <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
+ <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
+ <EnableVerbose>true</EnableVerbose>
+ </Inf>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>__x86_64__;__MODULE__="XENNET";NDIS_MINIPORT_DRIVER;NDIS60_MINIPORT=1;POOL_NX_OPTIN=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <EnablePREfast>true</EnablePREfast>
+ </ClCompile>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>$(DDK_LIB_PATH)\ndis.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <Inf>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <Architecture>amd64</Architecture>
+ <SpecifyDriverVerDirectiveVersion>true</SpecifyDriverVerDirectiveVersion>
+ <TimeStamp>$(MAJOR_VERSION).$(MINOR_VERSION).$(MICRO_VERSION).$(BUILD_NUMBER)</TimeStamp>
+ <EnableVerbose>true</EnableVerbose>
+ </Inf>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="../../src/xennet/adapter.c" />
+ <ClCompile Include="../../src/xennet/main.c" />
+ <ClCompile Include="../../src/xennet/miniport.c" />
+ <ClCompile Include="../../src/xennet/receiver.c" />
+ <ClCompile Include="../../src/xennet/transmitter.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\src\xennet\xennet.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Include="..\xennet.inf" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SignMode>ProductionSign</SignMode>
+ <ProductionCertificate>CN="Citrix Systems, Inc.", OU=Digital ID Class 3 - Microsoft Software Validation v2, O="Citrix Systems, Inc.", L=Santa Clara, S=California, C=US | 9505C081954CC0A3E8B904458ACACD72EABD98B5</ProductionCertificate>
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Windows Developer Preview Debug|Win32">
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Release|Win32">
+ <Configuration>Windows Developer Preview Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|Win32">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|Win32">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|Win32">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|Win32">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Debug|x64">
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Developer Preview Release|x64">
+ <Configuration>Windows Developer Preview Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Debug|x64">
+ <Configuration>Windows 7 Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows 7 Release|x64">
+ <Configuration>Windows 7 Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Debug|x64">
+ <Configuration>Windows Vista Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Windows Vista Release|x64">
+ <Configuration>Windows Vista Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{3EDD837A-C1BE-47D4-9603-16B61353670B}</ProjectGuid>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
+ <ProjectName>xennet_coinst</ProjectName>
+ </PropertyGroup>
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsApplicationForDrivers8.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <DriverType>WDM</DriverType>
+ <Configuration>Windows Developer Preview Debug</Configuration>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|Win32'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|Win32'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Developer Preview Release|x64'" Label="Configuration">
+ <TargetVersion>Windows8</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows 7 Release|x64'" Label="Configuration">
+ <TargetVersion>Windows7</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Debug|x64'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Windows Vista Release|x64'" Label="Configuration">
+ <TargetVersion>Vista</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup>
+ <DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
+ </PropertyGroup>
+ <PropertyGroup>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <EnableInf2cat>false</EnableInf2cat>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>__i386__;__MODULE__="XENNET_COINST";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <EnablePREfast>true</EnablePREfast>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>../../src/coinst/xennet_coinst.def</ModuleDefinitionFile>
+ <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+ <ClCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>__x86_64__;__MODULE__="XENNET_COINST";%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <WarningLevel>EnableAllWarnings</WarningLevel>
+ <DisableSpecificWarnings>4548;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <EnablePREfast>true</EnablePREfast>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
+ <RuntimeLibrary Condition="'$(UseDebugLibraries)'=='false'">MultiThreaded</RuntimeLibrary>
+ </ClCompile>
+ <Link>
+ <ModuleDefinitionFile>../../src/coinst/xennet_coinst.def</ModuleDefinitionFile>
+ <AdditionalDependencies>setupapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <FilesToPackage Include="$(TargetPath)" />
+ <FilesToPackage Include="$(OutDir)$(TargetName).pdb" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\src\coinst\coinst.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\src\coinst\xennet_coinst.def" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <SignMode>ProductionSign</SignMode>
+ <ProductionCertificate>CN="Citrix Systems, Inc.", OU=Digital ID Class 3 - Microsoft Software Validation v2, O="Citrix Systems, Inc.", L=Santa Clara, S=California, C=US | 9505C081954CC0A3E8B904458ACACD72EABD98B5</ProductionCertificate>
+ <TimeStampServer>http://timestamp.verisign.com/scripts/timstamp.dll</TimeStampServer>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define INITGUID
+
+#include <windows.h>
+#include <Ifdef.h>
+#include <setupapi.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <strsafe.h>
+#include <malloc.h>
+
+#include <version.h>
+
+__user_code;
+
+#define MAXIMUM_BUFFER_SIZE 1024
+
+#define ENUM_KEY "SYSTEM\\CurrentControlSet\\Enum"
+
+#define CLASS_KEY "SYSTEM\\CurrentControlSet\\Control\\Class"
+
+#define SERVICES_KEY "SYSTEM\\CurrentControlSet\\Services"
+
+#define NSI_KEY "SYSTEM\\CurrentControlSet\\Control\\Nsi"
+
+#define PARAMETERS_KEY(_Driver) \
+ SERVICES_KEY ## "\\" ## #_Driver ## "\\Parameters"
+
+#define ALIASES_KEY(_Driver) \
+ SERVICES_KEY ## "\\" ## #_Driver ## "\\Aliases"
+
+#define STATUS_KEY(_Driver) \
+ SERVICES_KEY ## "\\" ## #_Driver ## "\\Status"
+
+#define SOFTWARE_KEY "SOFTWARE\\Citrix"
+
+#define NET_SETTINGS_KEY \
+ SOFTWARE_KEY ## "\\" ## "XenToolsNetSettings\\XEN\\VIF"
+
+static VOID
+#pragma prefast(suppress:6262) // Function uses '1036' bytes of stack: exceeds /analyze:stacksize'1024'
+__Log(
+ IN const CHAR *Format,
+ IN ...
+ )
+{
+ TCHAR Buffer[MAXIMUM_BUFFER_SIZE];
+ va_list Arguments;
+ size_t Length;
+ SP_LOG_TOKEN LogToken;
+ DWORD Category;
+ DWORD Flags;
+ HRESULT Result;
+
+ va_start(Arguments, Format);
+ Result = StringCchVPrintf(Buffer, MAXIMUM_BUFFER_SIZE, Format, Arguments);
+ va_end(Arguments);
+
+ if (Result != S_OK && Result != STRSAFE_E_INSUFFICIENT_BUFFER)
+ return;
+
+ Result = StringCchLength(Buffer, MAXIMUM_BUFFER_SIZE, &Length);
+ if (Result != S_OK)
+ return;
+
+ LogToken = SetupGetThreadLogToken();
+ Category = TXTLOG_VENDOR;
+ Flags = TXTLOG_DETAILS;
+
+ SetupWriteTextLog(LogToken, Category, Flags, Buffer);
+
+ __analysis_assume(Length < MAXIMUM_BUFFER_SIZE);
+ __analysis_assume(Length >= 2);
+ Length = __min(MAXIMUM_BUFFER_SIZE - 1, Length + 2);
+ Buffer[Length] = '\0';
+ Buffer[Length - 1] = '\n';
+ Buffer[Length - 2] = '\r';
+
+ OutputDebugString(Buffer);
+}
+
+#define Log(_Format, ...) \
+ __Log(__MODULE__ "|" __FUNCTION__ ": " _Format, __VA_ARGS__)
+
+static PTCHAR
+GetErrorMessage(
+ IN DWORD Error
+ )
+{
+ PTCHAR Message;
+ ULONG Index;
+
+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ Error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&Message,
+ 0,
+ NULL);
+
+ for (Index = 0; Message[Index] != '\0'; Index++) {
+ if (Message[Index] == '\r' || Message[Index] == '\n') {
+ Message[Index] = '\0';
+ break;
+ }
+ }
+
+ return Message;
+}
+
+static const CHAR *
+FunctionName(
+ IN DI_FUNCTION Function
+ )
+{
+#define _NAME(_Function) \
+ case DIF_ ## _Function: \
+ return #_Function;
+
+ switch (Function) {
+ _NAME(INSTALLDEVICE);
+ _NAME(REMOVE);
+ _NAME(SELECTDEVICE);
+ _NAME(ASSIGNRESOURCES);
+ _NAME(PROPERTIES);
+ _NAME(FIRSTTIMESETUP);
+ _NAME(FOUNDDEVICE);
+ _NAME(SELECTCLASSDRIVERS);
+ _NAME(VALIDATECLASSDRIVERS);
+ _NAME(INSTALLCLASSDRIVERS);
+ _NAME(CALCDISKSPACE);
+ _NAME(DESTROYPRIVATEDATA);
+ _NAME(VALIDATEDRIVER);
+ _NAME(MOVEDEVICE);
+ _NAME(DETECT);
+ _NAME(INSTALLWIZARD);
+ _NAME(DESTROYWIZARDDATA);
+ _NAME(PROPERTYCHANGE);
+ _NAME(ENABLECLASS);
+ _NAME(DETECTVERIFY);
+ _NAME(INSTALLDEVICEFILES);
+ _NAME(ALLOW_INSTALL);
+ _NAME(SELECTBESTCOMPATDRV);
+ _NAME(REGISTERDEVICE);
+ _NAME(NEWDEVICEWIZARD_PRESELECT);
+ _NAME(NEWDEVICEWIZARD_SELECT);
+ _NAME(NEWDEVICEWIZARD_PREANALYZE);
+ _NAME(NEWDEVICEWIZARD_POSTANALYZE);
+ _NAME(NEWDEVICEWIZARD_FINISHINSTALL);
+ _NAME(INSTALLINTERFACES);
+ _NAME(DETECTCANCEL);
+ _NAME(REGISTER_COINSTALLERS);
+ _NAME(ADDPROPERTYPAGE_ADVANCED);
+ _NAME(ADDPROPERTYPAGE_BASIC);
+ _NAME(TROUBLESHOOTER);
+ _NAME(POWERMESSAGEWAKE);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _NAME
+}
+
+#define MAXIMUM_DEVICE_NAME_LENGTH 32
+#define MAXIMUM_ALIAS_LENGTH 128
+
+typedef struct _EMULATED_DEVICE {
+ TCHAR Device[MAXIMUM_DEVICE_NAME_LENGTH];
+ TCHAR Alias[MAXIMUM_ALIAS_LENGTH];
+} EMULATED_DEVICE, *PEMULATED_DEVICE;
+
+static PEMULATED_DEVICE
+GetEmulatedDeviceTable(
+ VOID
+ )
+{
+ HKEY Key;
+ HRESULT Error;
+ DWORD Values;
+ DWORD Index;
+ PEMULATED_DEVICE Table;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ ALIASES_KEY(XENFILT) "\\VIF",
+ 0,
+ KEY_READ,
+ &Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Error = RegQueryInfoKey(Key,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &Values,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ Table = malloc(sizeof (EMULATED_DEVICE) * (Values + 1));
+ if (Table == NULL)
+ goto fail3;
+
+ memset(Table, 0, sizeof (EMULATED_DEVICE) * (Values + 1));
+
+ for (Index = 0; Index < Values; Index++) {
+ PEMULATED_DEVICE Entry = &Table[Index];
+ ULONG DeviceNameLength;
+ ULONG AliasLength;
+ ULONG Type;
+
+ DeviceNameLength = MAXIMUM_DEVICE_NAME_LENGTH * sizeof (TCHAR);
+ AliasLength = MAXIMUM_ALIAS_LENGTH * sizeof (TCHAR);
+
+ Error = RegEnumValue(Key,
+ Index,
+ (LPTSTR)Entry->Device,
+ &DeviceNameLength,
+ NULL,
+ &Type,
+ (LPBYTE)Entry->Alias,
+ &AliasLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail4;
+ }
+
+ if (Type != REG_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail5;
+ }
+ }
+
+ RegCloseKey(Key);
+
+ return Table;
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ free(Table);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(Key);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return NULL;
+}
+
+static DECLSPEC_NOINLINE HRESULT
+OpenSoftwareKey(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ OUT PHKEY SoftwareKey
+ )
+{
+ HKEY Key;
+ HRESULT Error;
+
+ Key = SetupDiOpenDevRegKey(DeviceInfoSet,
+ DeviceInfoData,
+ DICS_FLAG_GLOBAL,
+ 0,
+ DIREG_DRV,
+ KEY_READ);
+ if (Key == INVALID_HANDLE_VALUE) {
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ goto fail1;
+ }
+
+ *SoftwareKey = Key;
+
+ return ERROR_SUCCESS;
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+// {4d36e972-e325-11ce-bfc1-08002be10318}
+DEFINE_GUID(GUID_NET_DEVICE,
+ 0x4d36e972,
+ 0xe325,
+ 0x11ce,
+ 0xbf,
+ 0xc1,
+ 0x08,
+ 0x00,
+ 0x2b,
+ 0xe1,
+ 0x03,
+ 0x18
+ );
+
+static HRESULT
+OpenAliasHardwareKey(
+ IN PTCHAR AliasDeviceID,
+ IN PTCHAR AliasInstanceID,
+ OUT PHKEY HardwareKey
+ )
+{
+ DWORD PathLength;
+ PTCHAR Path;
+ HRESULT Result;
+ HKEY Key;
+ HRESULT Error;
+ DWORD SubKeys;
+ DWORD MaxSubKeyLength;
+ PTCHAR Name;
+ DWORD Index;
+ HKEY SubKey;
+
+ Log("====> (%s) (%s)", AliasDeviceID, AliasInstanceID);
+
+ PathLength = (DWORD)(strlen(ENUM_KEY) +
+ 1 +
+ strlen(AliasDeviceID) +
+ 1) * sizeof (TCHAR);
+
+ Path = malloc(PathLength);
+ if (Path == NULL)
+ goto fail1;
+
+ Result = StringCbPrintf(Path,
+ PathLength,
+ "%s\\%s",
+ ENUM_KEY,
+ AliasDeviceID);
+ if (!SUCCEEDED(Result)) {
+ SetLastError(ERROR_BUFFER_OVERFLOW);
+ goto fail2;
+ }
+
+ Log("%s", Path);
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ Path,
+ 0,
+ KEY_READ,
+ &Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ Error = RegQueryInfoKey(Key,
+ NULL,
+ NULL,
+ NULL,
+ &SubKeys,
+ &MaxSubKeyLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail4;
+ }
+
+ Name = malloc(MaxSubKeyLength + sizeof (TCHAR));
+ if (Name == NULL)
+ goto fail5;
+
+ for (Index = 0; Index < SubKeys; Index++) {
+ DWORD NameLength;
+ PTCHAR InstanceID;
+
+ NameLength = MaxSubKeyLength + sizeof (TCHAR);
+ memset(Name, 0, NameLength);
+
+ Error = RegEnumKeyEx(Key,
+ Index,
+ (LPTSTR)Name,
+ &NameLength,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail6;
+ }
+
+ Log("%s", Name);
+
+ Error = RegOpenKeyEx(Key,
+ Name,
+ 0,
+ KEY_READ,
+ &SubKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail7;
+ }
+
+ InstanceID = strrchr(Name, '&');
+ InstanceID++;
+
+ if (_stricmp(AliasInstanceID, InstanceID) == 0)
+ goto done;
+
+ RegCloseKey(SubKey);
+ }
+
+ Error = ERROR_FILE_NOT_FOUND;
+ goto fail8;
+
+done:
+ free(Name);
+
+ RegCloseKey(Key);
+
+ free(Path);
+
+ *HardwareKey = SubKey;
+
+ Log("<====");
+
+ return ERROR_SUCCESS;
+
+fail8:
+ Log("fail8");
+
+fail7:
+ Log("fail7");
+
+fail6:
+ Log("fail6");
+
+ free(Name);
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ RegCloseKey(Key);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ free(Path);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+static HRESULT
+OpenAliasSoftwareKey(
+ IN PTCHAR Alias,
+ OUT PHKEY SoftwareKey
+ )
+{
+ DWORD BufferLength;
+ PTCHAR Buffer;
+ PTCHAR AliasDeviceID;
+ PTCHAR AliasInstanceID;
+ HRESULT Error;
+ HKEY HardwareKey;
+ DWORD MaxValueLength;
+ DWORD DriverLength;
+ PTCHAR Driver;
+ DWORD Type;
+ DWORD PathLength;
+ PTCHAR Path;
+ HRESULT Result;
+ HKEY Key;
+
+ Log("====>");
+
+ BufferLength = (DWORD)(strlen(Alias) +
+ 1) * sizeof (TCHAR);
+
+ Buffer = malloc(BufferLength);
+ if (Buffer == NULL)
+ goto fail1;
+
+ memset(Buffer, 0, BufferLength);
+
+ memcpy(Buffer, Alias, strlen(Alias));
+
+ AliasDeviceID = Buffer;
+
+ AliasInstanceID = strchr(Buffer, '#');
+ *AliasInstanceID++ = '\0';
+
+ Error = OpenAliasHardwareKey(AliasDeviceID,
+ AliasInstanceID,
+ &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;
+ }
+
+ DriverLength = MaxValueLength + sizeof (TCHAR);
+
+ Driver = malloc(DriverLength);
+ if (Driver == NULL)
+ goto fail4;
+
+ memset(Driver, 0, DriverLength);
+
+ Error = RegQueryValueEx(HardwareKey,
+ "Driver",
+ NULL,
+ &Type,
+ (LPBYTE)Driver,
+ &DriverLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail5;
+ }
+
+ if (Type != REG_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail6;
+ }
+
+ Log("%s", Driver);
+
+ PathLength = (ULONG)(strlen(CLASS_KEY) +
+ 1 +
+ strlen(Driver) +
+ 1) * sizeof (TCHAR);
+
+ Path = malloc(PathLength);
+ if (Path == NULL)
+ goto fail7;
+
+ Result = StringCbPrintf(Path,
+ PathLength,
+ "%s\\%s",
+ CLASS_KEY,
+ Driver);
+ if (!SUCCEEDED(Result)) {
+ SetLastError(ERROR_BUFFER_OVERFLOW);
+ goto fail8;
+ }
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ Path,
+ 0,
+ KEY_READ,
+ &Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail9;
+ }
+
+ free(Path);
+
+ free(Driver);
+
+ RegCloseKey(HardwareKey);
+
+ free(Buffer);
+
+ *SoftwareKey = Key;
+
+ Log("<====");
+
+ return ERROR_SUCCESS;
+
+fail9:
+ Log("fail9");
+
+fail8:
+ Log("fail8");
+
+ free(Path);
+
+fail7:
+ Log("fail7");
+
+fail6:
+ Log("fail6");
+
+fail5:
+ Log("fail5");
+
+ free(Driver);
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+ RegCloseKey(HardwareKey);
+
+fail2:
+ Log("fail2");
+
+ free(Buffer);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+static PTCHAR
+GetInterface(
+ IN HKEY Key
+ )
+{
+ HRESULT Error;
+ HKEY SubKey;
+ DWORD MaxValueLength;
+ DWORD RootDeviceLength;
+ PTCHAR RootDevice;
+ DWORD Type;
+
+ Error = RegOpenKeyEx(Key,
+ "Linkage",
+ 0,
+ KEY_READ,
+ &SubKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Error = RegQueryInfoKey(SubKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ RootDeviceLength = MaxValueLength + sizeof (TCHAR);
+
+ RootDevice = malloc(RootDeviceLength);
+ if (RootDevice == NULL)
+ goto fail2;
+
+ memset(RootDevice, 0, RootDeviceLength);
+
+ Error = RegQueryValueEx(SubKey,
+ "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;
+ }
+
+ RegCloseKey(SubKey);
+
+ return RootDevice;
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+ free(RootDevice);
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(SubKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return NULL;
+}
+
+static BOOLEAN
+CopyValues(
+ IN PTCHAR TargetPath,
+ IN PTCHAR SourcePath
+ )
+{
+ HKEY TargetKey;
+ HKEY SourceKey;
+ HRESULT Error;
+ DWORD Values;
+ DWORD MaxNameLength;
+ PTCHAR Name;
+ DWORD MaxValueLength;
+ LPBYTE Value;
+ DWORD Index;
+
+ Log("TARGET: %s", TargetPath);
+ Log("SOURCE: %s", SourcePath);
+
+ Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ TargetPath,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &TargetKey,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ SourcePath,
+ 0,
+ KEY_ALL_ACCESS,
+ &SourceKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ Error = RegQueryInfoKey(SourceKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &Values,
+ &MaxNameLength,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ if (Values == 0)
+ goto done;
+
+ MaxNameLength += sizeof (TCHAR);
+
+ Name = malloc(MaxNameLength);
+ if (Name == NULL)
+ goto fail4;
+
+ Value = malloc(MaxValueLength);
+ if (Value == NULL)
+ goto fail5;
+
+ 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 fail6;
+ }
+
+ Error = RegSetValueEx(TargetKey,
+ Name,
+ 0,
+ Type,
+ Value,
+ ValueLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail7;
+ }
+
+ Log("COPIED %s", Name);
+ }
+
+ free(Value);
+ free(Name);
+
+ RegCloseKey(SourceKey);
+ RegCloseKey(TargetKey);
+
+done:
+ return TRUE;
+
+fail7:
+ Log("fail7");
+
+fail6:
+ Log("fail6");
+
+ free(Value);
+
+fail5:
+ Log("fail5");
+
+ free(Name);
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+ RegCloseKey(SourceKey);
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(TargetKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+CopyParameters(
+ IN PTCHAR TargetPrefix,
+ IN PTCHAR TargetNode,
+ IN PTCHAR SourcePrefix,
+ IN PTCHAR SourceNode
+ )
+{
+ DWORD Length;
+ PTCHAR SourcePath;
+ PTCHAR TargetPath;
+ HRESULT Result;
+ HRESULT Error;
+ BOOLEAN Success;
+
+ Length = (DWORD)((strlen(TargetPrefix) +
+ strlen(TargetNode) +
+ 1) * sizeof (TCHAR));
+
+ TargetPath = malloc(Length);
+ if (TargetPath == NULL)
+ goto fail1;
+
+ Result = StringCbPrintf(TargetPath,
+ Length,
+ "%s%s",
+ TargetPrefix,
+ TargetNode);
+ if (!SUCCEEDED(Result)) {
+ SetLastError(ERROR_BUFFER_OVERFLOW);
+ goto fail2;
+ }
+
+ Length = (DWORD)((strlen(SourcePrefix) +
+ strlen(SourceNode) +
+ 1) * sizeof (TCHAR));
+
+ SourcePath = malloc(Length);
+ if (SourcePath == NULL)
+ goto fail3;
+
+ Result = StringCbPrintf(SourcePath,
+ Length,
+ "%s%s",
+ SourcePrefix,
+ SourceNode);
+ if (!SUCCEEDED(Result)) {
+ SetLastError(ERROR_BUFFER_OVERFLOW);
+ goto fail4;
+ }
+
+ Success = CopyValues(TargetPath, SourcePath);
+
+ free(SourcePath);
+ free(TargetPath);
+
+ return Success;
+
+fail4:
+ Log("fail4");
+
+ free(SourcePath);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ free(TargetPath);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+CopyIpVersion6Addresses(
+ IN PTCHAR TargetPath,
+ IN PTCHAR TargetPrefix,
+ IN PTCHAR SourcePath,
+ IN PTCHAR SourcePrefix
+ )
+{
+ HKEY TargetKey;
+ HKEY SourceKey;
+ HRESULT Error;
+ DWORD Values;
+ DWORD MaxNameLength;
+ PTCHAR Name;
+ DWORD MaxValueLength;
+ LPBYTE Value;
+ DWORD Index;
+
+ Log("TARGET: %s", TargetPath);
+ Log("SOURCE: %s", SourcePath);
+
+ Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ TargetPath,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &TargetKey,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ SourcePath,
+ 0,
+ KEY_ALL_ACCESS,
+ &SourceKey);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ Error = RegQueryInfoKey(SourceKey,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &Values,
+ &MaxNameLength,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ if (Values == 0)
+ goto done;
+
+ MaxNameLength += sizeof (TCHAR);
+
+ Name = malloc(MaxNameLength);
+ if (Name == NULL)
+ goto fail4;
+
+ Value = malloc(MaxValueLength);
+ if (Value == NULL)
+ goto fail5;
+
+ 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 fail6;
+ }
+
+ if (strncmp(Name, SourcePrefix, sizeof (ULONG64) * 2) != 0)
+ continue;
+
+ Log("READ: %s", Name);
+
+ memcpy(Name, TargetPrefix, sizeof (ULONG64) * 2);
+
+ Log("WRITE: %s", Name);
+
+ Error = RegSetValueEx(TargetKey,
+ Name,
+ 0,
+ Type,
+ Value,
+ ValueLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail7;
+ }
+ }
+
+ free(Value);
+ free(Name);
+
+ RegCloseKey(SourceKey);
+ RegCloseKey(TargetKey);
+
+done:
+
+ return TRUE;
+
+fail7:
+ Log("fail7");
+
+fail6:
+ Log("fail6");
+
+ free(Value);
+
+fail5:
+ Log("fail5");
+
+ free(Name);
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+ RegCloseKey(SourceKey);
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(TargetKey);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static PTCHAR
+GetNetLuid(
+ IN HKEY Key
+ )
+{
+ HRESULT Error;
+ DWORD MaxValueLength;
+ DWORD ValueLength;
+ LPDWORD Value;
+ DWORD Type;
+ NET_LUID NetLuid;
+ DWORD BufferLength;
+ PTCHAR Buffer;
+ HRESULT Result;
+
+ memset(&NetLuid, 0, sizeof (NetLuid));
+
+ Error = RegQueryInfoKey(Key,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &MaxValueLength,
+ NULL,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ ValueLength = MaxValueLength;
+
+ Value = malloc(ValueLength);
+ if (Value == NULL)
+ goto fail2;
+
+ memset(Value, 0, ValueLength);
+
+ Error = RegQueryValueEx(Key,
+ "NetLuidIndex",
+ NULL,
+ &Type,
+ (LPBYTE)Value,
+ &ValueLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail3;
+ }
+
+ if (Type != REG_DWORD) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail4;
+ }
+
+ NetLuid.Info.NetLuidIndex = *Value;
+
+ Error = RegQueryValueEx(Key,
+ "*IfType",
+ NULL,
+ &Type,
+ (LPBYTE)Value,
+ &ValueLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail5;
+ }
+
+ if (Type != REG_DWORD) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail6;
+ }
+
+ NetLuid.Info.IfType = *Value;
+
+ BufferLength = ((sizeof (ULONG64) * 2) + 1) * sizeof (TCHAR);
+
+ Buffer = malloc(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
+MigrateSettings(
+ IN HKEY SourceKey,
+ IN HKEY TargetKey
+ )
+{
+ PTCHAR SourcePrefix;
+ PTCHAR TargetPrefix;
+ BOOLEAN Success;
+ HRESULT Error;
+
+ Log("====>");
+
+ Success = TRUE;
+
+ SourcePrefix = GetInterface(SourceKey);
+
+ if (SourcePrefix == NULL)
+ goto fail1;
+
+ TargetPrefix = GetInterface(TargetKey);
+
+ if (TargetPrefix == NULL)
+ goto fail2;
+
+ Success &= CopyParameters(PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_", TargetPrefix,
+ PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_", SourcePrefix);
+ Success &= CopyParameters(PARAMETERS_KEY(Tcpip) "\\Interfaces\\", TargetPrefix,
+ PARAMETERS_KEY(Tcpip) "\\Interfaces\\", SourcePrefix);
+ Success &= CopyParameters(PARAMETERS_KEY(Tcpip6) "\\Interfaces\\", TargetPrefix,
+ PARAMETERS_KEY(Tcpip6) "\\Interfaces\\", SourcePrefix);
+
+ free(TargetPrefix);
+ free(SourcePrefix);
+
+ SourcePrefix = GetNetLuid(SourceKey);
+
+ if (SourcePrefix == NULL)
+ goto fail3;
+
+ TargetPrefix = GetNetLuid(TargetKey);
+
+ if (TargetPrefix == NULL)
+ goto fail4;
+
+ Success &= CopyIpVersion6Addresses(NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\", TargetPrefix,
+ NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\", SourcePrefix);
+
+ free(TargetPrefix);
+ free(SourcePrefix);
+
+ Log("<====");
+
+ return Success;
+
+fail4:
+ Log("fail4");
+
+ free(SourcePrefix);
+ goto fail1;
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ free(SourcePrefix);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static FORCEINLINE BOOLEAN
+__MigrateFromEmulated(
+ IN PTCHAR Location,
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData
+ )
+{
+ PEMULATED_DEVICE Table;
+ DWORD Index;
+ BOOLEAN Success;
+ HRESULT Error;
+ HKEY SourceKey;
+ HKEY TargetKey;
+
+ Log("====>");
+
+ Table = GetEmulatedDeviceTable();
+ if (Table == NULL)
+ goto fail1;
+
+ Success = FALSE;
+
+ for (Index = 0; strlen(Table[Index].Alias) != 0; Index++) {
+ if (_stricmp(Location, Table[Index].Device) == 0) {
+ Error = OpenAliasSoftwareKey(Table[Index].Alias,
+ &SourceKey);
+ if (Error != ERROR_SUCCESS)
+ goto fail2;
+
+ Error = OpenSoftwareKey(DeviceInfoSet,
+ DeviceInfoData,
+ &TargetKey);
+ if (Error != ERROR_SUCCESS)
+ goto fail3;
+
+ Success = MigrateSettings(SourceKey, TargetKey);
+
+ RegCloseKey(TargetKey);
+ RegCloseKey(SourceKey);
+
+ break;
+ }
+ }
+
+ free(Table);
+
+ Log("<====");
+
+ return Success;
+
+fail3:
+ RegCloseKey(SourceKey);
+
+fail2:
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static FORCEINLINE BOOLEAN
+__MigrateToEmulated(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PTCHAR Location
+ )
+{
+ PEMULATED_DEVICE Table;
+ DWORD Index;
+ BOOLEAN Success;
+ HRESULT Error;
+ HKEY SourceKey;
+ HKEY TargetKey;
+
+ Log("====>");
+
+ Table = GetEmulatedDeviceTable();
+ if (Table == NULL)
+ goto fail1;
+
+ Success = FALSE;
+
+ for (Index = 0; strlen(Table[Index].Alias) != 0; Index++) {
+ if (_stricmp(Location, Table[Index].Device) == 0) {
+ Error = OpenSoftwareKey(DeviceInfoSet,
+ DeviceInfoData,
+ &SourceKey);
+ if (Error != ERROR_SUCCESS)
+ goto fail3;
+
+ Error = OpenAliasSoftwareKey(Table[Index].Alias,
+ &TargetKey);
+ if (Error != ERROR_SUCCESS)
+ goto fail2;
+
+ Success = MigrateSettings(SourceKey, TargetKey);
+ break;
+ }
+ }
+
+ free(Table);
+
+ Log("<====");
+
+ return Success;
+
+fail3:
+ RegCloseKey(SourceKey);
+
+fail2:
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static FORCEINLINE BOOLEAN
+__MigrateFromPV(
+ IN PTCHAR Location,
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData
+ )
+{
+ HKEY TargetKey;
+ PTCHAR TargetPrefix;
+ DWORD Length;
+ PTCHAR SourcePrefix;
+ BOOLEAN Success;
+ HRESULT Result;
+ HRESULT Error;
+
+ Log("====>");
+
+ Success = TRUE;
+
+ Length = (DWORD)((strlen(NET_SETTINGS_KEY) +
+ strlen("\\") +
+ strlen(Location) +
+ strlen("\\") +
+ 1) * sizeof (TCHAR));
+
+ SourcePrefix = malloc(Length);
+ if (SourcePrefix == NULL)
+ goto fail1;
+
+ Result = StringCbPrintf(SourcePrefix,
+ Length,
+ "%s\\%s\\",
+ NET_SETTINGS_KEY,
+ Location);
+ if (!SUCCEEDED(Result)) {
+ SetLastError(ERROR_BUFFER_OVERFLOW);
+ goto fail2;
+ }
+
+ Error = OpenSoftwareKey(DeviceInfoSet,
+ DeviceInfoData,
+ &TargetKey);
+ if (Error != ERROR_SUCCESS)
+ goto fail3;
+
+ TargetPrefix = GetInterface(TargetKey);
+
+ if (TargetPrefix == NULL)
+ goto fail4;
+
+ Success &= CopyParameters(PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_", TargetPrefix,
+ SourcePrefix, "nbt");
+ Success &= CopyParameters(PARAMETERS_KEY(Tcpip) "\\Interfaces\\", TargetPrefix,
+ SourcePrefix, "tcpip");
+ Success &= CopyParameters(PARAMETERS_KEY(Tcpip6) "\\Interfaces\\", TargetPrefix,
+ SourcePrefix, "tcpip6");
+
+ free(TargetPrefix);
+
+ TargetPrefix = GetNetLuid(TargetKey);
+
+ if (TargetPrefix == NULL)
+ goto fail5;
+
+ Success &= CopyIpVersion6Addresses(NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\", TargetPrefix,
+ SourcePrefix, "IPv6_Address____");
+
+ free(TargetPrefix);
+
+ RegCloseKey(TargetKey);
+ free(SourcePrefix);
+
+ Log("<====");
+
+ return Success;
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ RegCloseKey(TargetKey);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail");
+
+ free(SourcePrefix);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static FORCEINLINE BOOLEAN
+__MigrateToPV(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PTCHAR Location
+ )
+{
+ PTCHAR TargetPrefix;
+ DWORD Length;
+ HKEY SourceKey;
+ PTCHAR SourcePrefix;
+ BOOLEAN Success;
+ HRESULT Result;
+ HRESULT Error;
+
+ Log("====>");
+
+ Success = TRUE;
+
+ Length = (DWORD)((strlen(NET_SETTINGS_KEY) +
+ strlen("\\") +
+ strlen(Location) +
+ strlen("\\") +
+ 1) * sizeof (TCHAR));
+
+ TargetPrefix = malloc(Length);
+ if (TargetPrefix == NULL)
+ goto fail1;
+
+ Result = StringCbPrintf(TargetPrefix,
+ Length,
+ "%s\\%s\\",
+ NET_SETTINGS_KEY,
+ Location);
+ if (!SUCCEEDED(Result)) {
+ SetLastError(ERROR_BUFFER_OVERFLOW);
+ goto fail2;
+ }
+
+ Error = OpenSoftwareKey(DeviceInfoSet,
+ DeviceInfoData,
+ &SourceKey);
+ if (Error != ERROR_SUCCESS)
+ goto fail3;
+
+ SourcePrefix = GetInterface(SourceKey);
+
+ if (SourcePrefix == NULL)
+ goto fail4;
+
+ Success &= CopyParameters(TargetPrefix, "nbt",
+ PARAMETERS_KEY(NetBT) "\\Interfaces\\Tcpip_", SourcePrefix);
+ Success &= CopyParameters(TargetPrefix, "tcpip",
+ PARAMETERS_KEY(Tcpip) "\\Interfaces\\", SourcePrefix);
+ Success &= CopyParameters(TargetPrefix, "tcpip6",
+ PARAMETERS_KEY(Tcpip6) "\\Interfaces\\", SourcePrefix);
+
+ free(SourcePrefix);
+
+ SourcePrefix = GetNetLuid(SourceKey);
+
+ if (SourcePrefix == NULL)
+ goto fail5;
+
+ Success &= CopyIpVersion6Addresses(TargetPrefix, "IPv6_Address____",
+ NSI_KEY "\\{eb004a01-9b1a-11d4-9123-0050047759bc}\\10\\", SourcePrefix);
+
+ free(SourcePrefix);
+
+ RegCloseKey(SourceKey);
+ free(TargetPrefix);
+
+ Log("<====");
+
+ return Success;
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ RegCloseKey(SourceKey);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ free(TargetPrefix);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static PTCHAR
+GetProperty(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN DWORD Index
+ )
+{
+ DWORD Type;
+ DWORD PropertyLength;
+ PTCHAR Property;
+ HRESULT Error;
+
+ if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ Index,
+ &Type,
+ NULL,
+ 0,
+ &PropertyLength)) {
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ goto fail1;
+ }
+
+ if (Type != REG_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail2;
+ }
+
+ PropertyLength += sizeof (TCHAR);
+
+ Property = malloc(PropertyLength);
+ if (Property == NULL)
+ goto fail3;
+
+ memset(Property, 0, PropertyLength);
+
+ if (!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ Index,
+ NULL,
+ (PBYTE)Property,
+ PropertyLength,
+ NULL))
+ goto fail4;
+
+ return Property;
+
+fail4:
+ free(Property);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return NULL;
+}
+
+static BOOLEAN
+SetFriendlyName(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PTCHAR Description,
+ IN PTCHAR Location
+ )
+{
+ TCHAR FriendlyName[MAX_PATH];
+ DWORD FriendlyNameLength;
+ HRESULT Result;
+ HRESULT Error;
+
+ Result = StringCbPrintf(FriendlyName,
+ MAX_PATH,
+ TEXT("%s #%s"),
+ Description,
+ Location);
+ if (!SUCCEEDED(Result))
+ goto fail1;
+
+ FriendlyNameLength = (DWORD)(strlen(FriendlyName) + sizeof (TCHAR));
+
+ if (!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ SPDRP_FRIENDLYNAME,
+ (PBYTE)FriendlyName,
+ FriendlyNameLength))
+ goto fail2;
+
+ Log("%s", FriendlyName);
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+InstallDevice(
+ IN PTCHAR Class,
+ IN PTCHAR Device
+ )
+{
+ HKEY Key;
+ DWORD OldLength;
+ DWORD NewLength;
+ DWORD Type;
+ HRESULT Error;
+ PTCHAR Devices;
+ ULONG Offset;
+
+ Error = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
+ PARAMETERS_KEY(XENFILT),
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &Key,
+ NULL);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ OldLength = 0;
+ Error = RegQueryValueEx(Key,
+ Class,
+ NULL,
+ &Type,
+ NULL,
+ &OldLength);
+ if (Error != ERROR_SUCCESS) {
+ if (Error != ERROR_FILE_NOT_FOUND) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ OldLength = sizeof (TCHAR);
+ Type = REG_MULTI_SZ;
+ }
+
+ if (Type != REG_MULTI_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail3;
+ }
+
+ NewLength = OldLength + (DWORD)((strlen(Device) + 1) * sizeof (TCHAR));
+
+ Devices = malloc(NewLength);
+ if (Devices == NULL)
+ goto fail4;
+
+ memset(Devices, 0, NewLength);
+
+ Offset = 0;
+ if (OldLength != sizeof (TCHAR)) {
+ Error = RegQueryValueEx(Key,
+ Class,
+ NULL,
+ NULL,
+ (PBYTE)Devices,
+ &OldLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail5;
+ }
+
+ while (Devices[Offset] != '\0') {
+ ULONG DeviceLength;
+
+ DeviceLength = (ULONG)strlen(&Devices[Offset]) / sizeof (TCHAR);
+
+ if (_stricmp(&Devices[Offset], Device) == 0) {
+ Log("%s already present", Device);
+ goto done;
+ }
+
+ Offset += DeviceLength + 1;
+ }
+ }
+
+ memmove(&Devices[Offset], Device, strlen(Device));
+ Log("added %s", Device);
+
+ Error = RegSetValueEx(Key,
+ Class,
+ 0,
+ Type,
+ (PBYTE)Devices,
+ NewLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail6;
+ }
+
+done:
+ free(Devices);
+
+ RegCloseKey(Key);
+
+ return TRUE;
+
+fail6:
+ Log("fail6");
+
+fail5:
+ Log("fail5");
+
+ free(Devices);
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(Key);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+RemoveDevice(
+ IN PTCHAR Class,
+ IN PTCHAR Device
+ )
+{
+ HKEY Key;
+ DWORD OldLength;
+ DWORD NewLength;
+ DWORD Type;
+ HRESULT Error;
+ PTCHAR Devices;
+ ULONG Offset;
+ ULONG DeviceLength;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ PARAMETERS_KEY(XENFILT),
+ 0,
+ KEY_ALL_ACCESS,
+ &Key);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ OldLength = 0;
+ Error = RegQueryValueEx(Key,
+ Class,
+ NULL,
+ &Type,
+ NULL,
+ &OldLength);
+ if (Error != ERROR_SUCCESS) {
+ if (Error != ERROR_FILE_NOT_FOUND) {
+ SetLastError(Error);
+ goto fail2;
+ }
+
+ goto done;
+ }
+
+ if (Type != REG_MULTI_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail3;
+ }
+
+ Devices = malloc(OldLength);
+ if (Devices == NULL)
+ goto fail4;
+
+ memset(Devices, 0, OldLength);
+
+ Error = RegQueryValueEx(Key,
+ Class,
+ NULL,
+ NULL,
+ (PBYTE)Devices,
+ &OldLength);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail5;
+ }
+
+ Offset = 0;
+ DeviceLength = 0;
+ while (Devices[Offset] != '\0') {
+ DeviceLength = (ULONG)strlen(&Devices[Offset]) / sizeof (TCHAR);
+
+ if (_stricmp(&Devices[Offset], Device) == 0)
+ goto remove;
+
+ Offset += DeviceLength + 1;
+ }
+
+ free(Devices);
+ goto done;
+
+remove:
+ NewLength = OldLength - ((DeviceLength + 1) * sizeof (TCHAR));
+
+ memmove(&Devices[Offset],
+ &Devices[Offset + DeviceLength + 1],
+ (NewLength - Offset) * sizeof (TCHAR));
+
+ Log("removed %s", Device);
+
+ if (NewLength == 1) {
+ Error = RegDeleteValue(Key,
+ Class);
+ } else {
+ Error = RegSetValueEx(Key,
+ Class,
+ 0,
+ Type,
+ (PBYTE)Devices,
+ NewLength);
+ }
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail6;
+ }
+
+ free(Devices);
+
+done:
+ RegCloseKey(Key);
+
+ return TRUE;
+
+fail6:
+ Log("fail6");
+
+fail5:
+ Log("fail5");
+
+ free(Devices);
+
+fail4:
+ Log("fail4");
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(Key);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+IsDeviceEmulated(
+ IN PTCHAR Class,
+ IN PTCHAR Device,
+ OUT PBOOLEAN Present
+ )
+{
+ HKEY Key;
+ DWORD Length;
+ DWORD Type;
+ HRESULT Error;
+ PTCHAR Devices;
+ ULONG Offset;
+
+ *Present = FALSE;
+
+ Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ STATUS_KEY(XENFILT),
+ 0,
+ KEY_READ,
+ &Key);
+ if (Error != ERROR_SUCCESS) {
+ if (Error == ERROR_FILE_NOT_FOUND)
+ goto done;
+
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Length = 0;
+ Error = RegQueryValueEx(Key,
+ Class,
+ NULL,
+ &Type,
+ NULL,
+ &Length);
+ if (Error != ERROR_SUCCESS) {
+ if (Error == ERROR_FILE_NOT_FOUND)
+ goto done;
+ }
+
+ if (Type != REG_MULTI_SZ) {
+ SetLastError(ERROR_BAD_FORMAT);
+ goto fail2;
+ }
+
+ Devices = malloc(Length);
+ if (Devices == NULL)
+ goto fail3;
+
+ memset(Devices, 0, Length);
+
+ Error = RegQueryValueEx(Key,
+ Class,
+ NULL,
+ NULL,
+ (PBYTE)Devices,
+ &Length);
+ if (Error != ERROR_SUCCESS) {
+ SetLastError(Error);
+ goto fail4;
+ }
+
+ Offset = 0;
+ while (Devices[Offset] != '\0') {
+ ULONG DeviceLength;
+
+ DeviceLength = (ULONG)strlen(&Devices[Offset]) / sizeof (TCHAR);
+
+ if (_stricmp(&Devices[Offset], Device) == 0) {
+ *Present = TRUE;
+ break;
+ }
+
+ Offset += DeviceLength + 1;
+ }
+
+ free(Devices);
+
+ RegCloseKey(Key);
+
+done:
+ return TRUE;
+
+fail4:
+ Log("fail4");
+
+ free(Devices);
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ RegCloseKey(Key);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static BOOLEAN
+RequestReboot(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData
+ )
+{
+ SP_DEVINSTALL_PARAMS DeviceInstallParams;
+ HRESULT Error;
+
+ DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
+
+ if (!SetupDiGetDeviceInstallParams(DeviceInfoSet,
+ DeviceInfoData,
+ &DeviceInstallParams))
+ goto fail1;
+
+ DeviceInstallParams.Flags |= DI_NEEDREBOOT;
+
+ Log("Flags = %08x", DeviceInstallParams.Flags);
+
+ if (!SetupDiSetDeviceInstallParams(DeviceInfoSet,
+ DeviceInfoData,
+ &DeviceInstallParams))
+ goto fail2;
+
+ return TRUE;
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return FALSE;
+}
+
+static FORCEINLINE HRESULT
+__DifInstallPreProcess(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PCOINSTALLER_CONTEXT_DATA Context
+ )
+{
+ HRESULT Error;
+ HKEY Key;
+ PTCHAR Interface;
+ BOOLEAN NeedMigrateSettings;
+
+ Log("====>");
+
+ Error = OpenSoftwareKey(DeviceInfoSet,
+ DeviceInfoData,
+ &Key);
+
+ if (Error == ERROR_SUCCESS) {
+ Interface = GetInterface(Key);
+ RegCloseKey(Key);
+ } else {
+ Interface = NULL;
+ }
+
+ if (Interface != NULL) {
+ free(Interface);
+
+ NeedMigrateSettings = FALSE;
+ } else {
+ NeedMigrateSettings = TRUE;
+ }
+
+ Log("NeedMigrateSettings = %s",
+ (NeedMigrateSettings) ? "TRUE" : "FALSE");
+
+ Context->PrivateData = (PVOID)NeedMigrateSettings;
+
+ Log("<====");
+
+ return ERROR_DI_POSTPROCESSING_REQUIRED;
+}
+
+static FORCEINLINE HRESULT
+__DifInstallPostProcess(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PCOINSTALLER_CONTEXT_DATA Context
+ )
+{
+ HRESULT Error;
+ BOOLEAN NeedMigrateSettings;
+ PTCHAR Description;
+ PTCHAR Location;
+ BOOLEAN MigratedSettings;
+ BOOLEAN Present;
+ BOOLEAN Success;
+
+ Log("====>");
+
+ Error = Context->InstallResult;
+ if (Error != NO_ERROR) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ NeedMigrateSettings = (BOOLEAN)(ULONG_PTR)Context->PrivateData;
+
+ Description = GetProperty(DeviceInfoSet, DeviceInfoData, SPDRP_DEVICEDESC);
+ if (Description == NULL)
+ goto fail2;
+
+ Location = GetProperty(DeviceInfoSet, DeviceInfoData, SPDRP_LOCATION_INFORMATION);
+ if (Location == NULL)
+ goto fail3;
+
+ Success = SetFriendlyName(DeviceInfoSet, DeviceInfoData, Description, Location);
+ if (!Success)
+ goto fail4;
+
+ MigratedSettings = FALSE;
+
+ if (NeedMigrateSettings) {
+ MigratedSettings = __MigrateFromPV(Location, DeviceInfoSet, DeviceInfoData);
+ if (!MigratedSettings)
+ MigratedSettings = __MigrateFromEmulated(Location, DeviceInfoSet, DeviceInfoData);
+ }
+
+ Success = InstallDevice("VIF", Location);
+ if (!Success)
+ goto fail5;
+
+ Success = IsDeviceEmulated("VIF", Location, &Present);
+ if (!Success)
+ goto fail6;
+
+ if (!MigratedSettings && !Present)
+ goto done;
+
+ Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
+ if (!Success)
+ goto fail7;
+
+done:
+ free(Location);
+ free(Description);
+
+ Log("<====");
+
+ return NO_ERROR;
+
+fail7:
+ Log("fail7");
+
+fail6:
+ Log("fail6");
+
+fail5:
+ Log("fail5");
+
+fail4:
+ Log("fail4");
+
+ free(Location);
+
+fail3:
+ Log("fail3");
+
+ free(Description);
+
+fail2:
+ Log("fail2");
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+static DECLSPEC_NOINLINE HRESULT
+DifInstall(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ 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);
+
+ Error = (!Context->PostProcessing) ?
+ __DifInstallPreProcess(DeviceInfoSet, DeviceInfoData, Context) :
+ __DifInstallPostProcess(DeviceInfoSet, DeviceInfoData, Context);
+
+ return Error;
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+static FORCEINLINE HRESULT
+__DifRemovePreProcess(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PCOINSTALLER_CONTEXT_DATA Context
+ )
+{
+ PTCHAR Location;
+ HRESULT Error;
+
+ Log("====>");
+
+ Location = GetProperty(DeviceInfoSet, DeviceInfoData, SPDRP_LOCATION_INFORMATION);
+ if (Location == NULL)
+ goto fail1;
+
+ Context->PrivateData = Location;
+
+ (VOID) __MigrateToEmulated(DeviceInfoSet, DeviceInfoData, Location);
+ (VOID) __MigrateToPV(DeviceInfoSet, DeviceInfoData, Location);
+
+ Log("<====");
+
+ return ERROR_DI_POSTPROCESSING_REQUIRED;
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+static FORCEINLINE HRESULT
+__DifRemovePostProcess(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PCOINSTALLER_CONTEXT_DATA Context
+ )
+{
+ HRESULT Error;
+ PTCHAR Location;
+ PEMULATED_DEVICE Table;
+ BOOLEAN Success;
+
+ Log("====>");
+
+ Error = Context->InstallResult;
+ if (Error != NO_ERROR) {
+ SetLastError(Error);
+ goto fail1;
+ }
+
+ Location = Context->PrivateData;
+
+ Success = RemoveDevice("VIF", Location);
+ if (!Success)
+ goto fail2;
+
+ Table = GetEmulatedDeviceTable();
+ if (Table == NULL) {
+ Success = FALSE;
+ } else {
+ ULONG Index;
+
+ Success = TRUE;
+
+ for (Index = 0; strlen(Table[Index].Alias) != 0; Index++) {
+ if (_stricmp(Location, Table[Index].Device) == 0) {
+ Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
+ break;
+ }
+ }
+
+ free(Table);
+ }
+
+ if (!Success)
+ goto fail3;
+
+ free(Location);
+
+ Log("<====");
+
+ return NO_ERROR;
+
+fail3:
+ Log("fail3");
+
+fail2:
+ Log("fail2");
+
+ free(Location);
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+static DECLSPEC_NOINLINE HRESULT
+DifRemove(
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ 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);
+
+ Error = (!Context->PostProcessing) ?
+ __DifRemovePreProcess(DeviceInfoSet, DeviceInfoData, Context) :
+ __DifRemovePostProcess(DeviceInfoSet, DeviceInfoData, Context);
+
+ return Error;
+
+fail1:
+ Error = GetLastError();
+
+ {
+ PTCHAR Message;
+
+ Message = GetErrorMessage(Error);
+ Log("fail1 (%s)", Message);
+ LocalFree(Message);
+ }
+
+ return Error;
+}
+
+DWORD CALLBACK
+Entry(
+ IN DI_FUNCTION Function,
+ IN HDEVINFO DeviceInfoSet,
+ IN PSP_DEVINFO_DATA DeviceInfoData,
+ IN PCOINSTALLER_CONTEXT_DATA Context
+ )
+{
+ HRESULT Error;
+
+ Log("%s (%s) ===>",
+ MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+ DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+ switch (Function) {
+ case DIF_INSTALLDEVICE: {
+ SP_DRVINFO_DATA DriverInfoData;
+ BOOLEAN DriverInfoAvailable;
+
+ DriverInfoData.cbSize = sizeof (DriverInfoData);
+ DriverInfoAvailable = SetupDiGetSelectedDriver(DeviceInfoSet,
+ DeviceInfoData,
+ &DriverInfoData) ?
+ TRUE :
+ 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.
+ if (DriverInfoAvailable) {
+ Error = DifInstall(DeviceInfoSet, DeviceInfoData, Context);
+ } else {
+ if (!Context->PostProcessing) {
+ Log("%s PreProcessing",
+ FunctionName(Function));
+
+ Error = ERROR_DI_POSTPROCESSING_REQUIRED;
+ } else {
+ Log("%s PostProcessing (%08x)",
+ FunctionName(Function),
+ Context->InstallResult);
+
+ Error = NO_ERROR;
+ }
+ }
+ break;
+ }
+ case DIF_REMOVE:
+ Error = DifRemove(DeviceInfoSet, DeviceInfoData, Context);
+ break;
+ default:
+ if (!Context->PostProcessing) {
+ Log("%s PreProcessing",
+ FunctionName(Function));
+
+ Error = NO_ERROR;
+ } else {
+ Log("%s PostProcessing (%08x)",
+ FunctionName(Function),
+ Context->InstallResult);
+
+ Error = Context->InstallResult;
+ }
+
+ break;
+ }
+
+ Log("%s (%s) <===",
+ MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+ DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+ return (DWORD)Error;
+}
+
+DWORD CALLBACK
+Version(
+ IN HWND Window,
+ IN HINSTANCE Module,
+ IN PTCHAR Buffer,
+ IN INT Reserved
+ )
+{
+ UNREFERENCED_PARAMETER(Window);
+ UNREFERENCED_PARAMETER(Module);
+ UNREFERENCED_PARAMETER(Buffer);
+ UNREFERENCED_PARAMETER(Reserved);
+
+ Log("%s (%s)",
+ MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+ DAY_STR "/" MONTH_STR "/" YEAR_STR);
+
+ return NO_ERROR;
+}
+
+static FORCEINLINE const CHAR *
+__ReasonName(
+ IN DWORD Reason
+ )
+{
+#define _NAME(_Reason) \
+ case DLL_ ## _Reason: \
+ return #_Reason;
+
+ switch (Reason) {
+ _NAME(PROCESS_ATTACH);
+ _NAME(PROCESS_DETACH);
+ _NAME(THREAD_ATTACH);
+ _NAME(THREAD_DETACH);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _NAME
+}
+
+BOOL WINAPI
+DllMain(
+ IN HINSTANCE Module,
+ IN DWORD Reason,
+ IN PVOID Reserved
+ )
+{
+ UNREFERENCED_PARAMETER(Module);
+ UNREFERENCED_PARAMETER(Reserved);
+
+ Log("%s (%s): %s",
+ MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
+ DAY_STR "/" MONTH_STR "/" YEAR_STR,
+ __ReasonName(Reason));
+
+ return TRUE;
+}
--- /dev/null
+; Copyright (c) Citrix Systems Inc.
+; All rights reserved.
+;
+; Redistribution and use in source and binary forms,
+; with or without modification, are permitted provided
+; that the following conditions are met:
+;
+; * Redistributions of source code must retain the above
+; copyright notice, this list of conditions and the
+; following disclaimer.
+; * Redistributions in binary form must reproduce the above
+; copyright notice, this list of conditions and the
+; following disclaimer in the documentation and/or other
+; materials provided with the distribution.
+;
+; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+; BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+; SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+; SUCH DAMAGE.
+
+LIBRARY XENNET_COINST
+
+EXPORTS
+ Entry
+ Version
+
+ DllMain PRIVATE
--- /dev/null
+; Copyright 2011 Citrix Systems Inc. All rights reserved.
+; Use is subject to license terms.
+;
+
+[Version]
+Signature="$Windows NT$"
+Class=Net
+ClassGUID={4d36e972-e325-11ce-bfc1-08002be10318}
+Provider=%Citrix%
+CatalogFile=xennet.cat
+DriverVer=01/01/1900,0.0.0.0
+
+[DestinationDirs]
+DefaultDestDir=12
+CoInst_CopyFiles=11
+
+[SourceDisksNames]
+0=%DiskDesc%
+
+[SourceDisksFiles]
+xennet.sys=0,,
+xennet_coinst.dll=0,,
+
+[XenNet_Copyfiles]
+xennet.sys
+
+[CoInst_CopyFiles]
+xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,xennet_coinst.dll
+
+[Manufacturer]
+%Citrix%=Citrix,NT$ARCH$
+
+[Citrix.NT$ARCH$]
+%DriverDesc%=XenNet_Inst,XENVIF\DEVICE&REV_02
+
+[XenNet_Inst]
+Characteristics=0x84
+BusType=1
+*IfType=6 ; IF_TYPE_ETHERNET_CSMACD
+*MediaType=0 ; NdisMedium802_3
+*PhysicalMediaType=0 ; NdisPhysicalMediumUnspecified
+CopyFiles=XenNet_Copyfiles
+AddReg=Xennet_Inst_AddReg
+
+[XenNet_Inst_AddReg]
+HKR, Ndi, Service, 0, "xennet"
+HKR, Ndi\Interfaces, UpperRange, 0, "ndis5"
+HKR, Ndi\Interfaces, LowerRange, 0, "ethernet"
+
+HKR, Ndi\params\*IPChecksumOffloadIPv4, ParamDesc, 0, %IPChecksumOffloadIPv4%
+HKR, Ndi\params\*IPChecksumOffloadIPv4, Type, 0, "enum"
+HKR, Ndi\params\*IPChecksumOffloadIPv4, Default, 0, "3"
+HKR, Ndi\params\*IPChecksumOffloadIPv4, Optional, 0, "0"
+HKR, Ndi\params\*IPChecksumOffloadIPv4\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*IPChecksumOffloadIPv4\enum, "1", 0, %Enabled-Tx%
+HKR, Ndi\params\*IPChecksumOffloadIPv4\enum, "2", 0, %Enabled-Rx%
+HKR, Ndi\params\*IPChecksumOffloadIPv4\enum, "3", 0, %Enabled-TxRx%
+
+HKR, Ndi\params\*TCPChecksumOffloadIPv4, ParamDesc, 0, %TCPChecksumOffloadIPv4%
+HKR, Ndi\params\*TCPChecksumOffloadIPv4, Type, 0, "enum"
+HKR, Ndi\params\*TCPChecksumOffloadIPv4, Default, 0, "3"
+HKR, Ndi\params\*TCPChecksumOffloadIPv4, Optional, 0, "0"
+HKR, Ndi\params\*TCPChecksumOffloadIPv4\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*TCPChecksumOffloadIPv4\enum, "1", 0, %Enabled-Tx%
+HKR, Ndi\params\*TCPChecksumOffloadIPv4\enum, "2", 0, %Enabled-Rx%
+HKR, Ndi\params\*TCPChecksumOffloadIPv4\enum, "3", 0, %Enabled-TxRx%
+
+HKR, Ndi\params\*UDPChecksumOffloadIPv4, ParamDesc, 0, %UDPChecksumOffloadIPv4%
+HKR, Ndi\params\*UDPChecksumOffloadIPv4, Type, 0, "enum"
+HKR, Ndi\params\*UDPChecksumOffloadIPv4, Default, 0, "3"
+HKR, Ndi\params\*UDPChecksumOffloadIPv4, Optional, 0, "0"
+HKR, Ndi\params\*UDPChecksumOffloadIPv4\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*UDPChecksumOffloadIPv4\enum, "1", 0, %Enabled-Tx%
+HKR, Ndi\params\*UDPChecksumOffloadIPv4\enum, "2", 0, %Enabled-Rx%
+HKR, Ndi\params\*UDPChecksumOffloadIPv4\enum, "3", 0, %Enabled-TxRx%
+
+HKR, Ndi\params\*TCPChecksumOffloadIPv6, ParamDesc, 0, %TCPChecksumOffloadIPv6%
+HKR, Ndi\params\*TCPChecksumOffloadIPv6, Type, 0, "enum"
+HKR, Ndi\params\*TCPChecksumOffloadIPv6, Default, 0, "3"
+HKR, Ndi\params\*TCPChecksumOffloadIPv6, Optional, 0, "0"
+HKR, Ndi\params\*TCPChecksumOffloadIPv6\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*TCPChecksumOffloadIPv6\enum, "1", 0, %Enabled-Tx%
+HKR, Ndi\params\*TCPChecksumOffloadIPv6\enum, "2", 0, %Enabled-Rx%
+HKR, Ndi\params\*TCPChecksumOffloadIPv6\enum, "3", 0, %Enabled-TxRx%
+
+HKR, Ndi\params\*UDPChecksumOffloadIPv6, ParamDesc, 0, %UDPChecksumOffloadIPv6%
+HKR, Ndi\params\*UDPChecksumOffloadIPv6, Type, 0, "enum"
+HKR, Ndi\params\*UDPChecksumOffloadIPv6, Default, 0, "3"
+HKR, Ndi\params\*UDPChecksumOffloadIPv6, Optional, 0, "0"
+HKR, Ndi\params\*UDPChecksumOffloadIPv6\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*UDPChecksumOffloadIPv6\enum, "1", 0, %Enabled-Tx%
+HKR, Ndi\params\*UDPChecksumOffloadIPv6\enum, "2", 0, %Enabled-Rx%
+HKR, Ndi\params\*UDPChecksumOffloadIPv6\enum, "3", 0, %Enabled-TxRx%
+
+HKR, Ndi\params\NeedChecksumValue, ParamDesc, 0, %NeedChecksumValue%
+HKR, Ndi\params\NeedChecksumValue, Type, 0, "enum"
+HKR, Ndi\params\NeedChecksumValue, Default, 0, "1"
+HKR, Ndi\params\NeedChecksumValue, Optional, 0, "0"
+HKR, Ndi\params\NeedChecksumValue\enum, "0", 0, %Disabled%
+HKR, Ndi\params\NeedChecksumValue\enum, "1", 0, %Enabled%
+
+HKR, Ndi\params\*LSOV2IPv4, ParamDesc, 0, %LSOV2IPv4%
+HKR, Ndi\params\*LSOV2IPv4, Type, 0, "enum"
+HKR, Ndi\params\*LSOV2IPv4, Default, 0, "1"
+HKR, Ndi\params\*LSOV2IPv4, Optional, 0, "0"
+HKR, Ndi\params\*LSOV2IPv4\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*LSOV2IPv4\enum, "1", 0, %Enabled%
+
+HKR, Ndi\params\*LSOV2IPv6, ParamDesc, 0, %LSOV2IPv6%
+HKR, Ndi\params\*LSOV2IPv6, Type, 0, "enum"
+HKR, Ndi\params\*LSOV2IPv6, Default, 0, "1"
+HKR, Ndi\params\*LSOV2IPv6, Optional, 0, "0"
+HKR, Ndi\params\*LSOV2IPv6\enum, "0", 0, %Disabled%
+HKR, Ndi\params\*LSOV2IPv6\enum, "1", 0, %Enabled%
+
+HKR, Ndi\params\LROIPv4, ParamDesc, 0, %LROIPv4%
+HKR, Ndi\params\LROIPv4, Type, 0, "enum"
+HKR, Ndi\params\LROIPv4, Default, 0, "1"
+HKR, Ndi\params\LROIPv4, Optional, 0, "0"
+HKR, Ndi\params\LROIPv4\enum, "0", 0, %Disabled%
+HKR, Ndi\params\LROIPv4\enum, "1", 0, %Enabled%
+
+HKR, Ndi\params\LROIPv6, ParamDesc, 0, %LROIPv6%
+HKR, Ndi\params\LROIPv6, Type, 0, "enum"
+HKR, Ndi\params\LROIPv6, Default, 0, "1"
+HKR, Ndi\params\LROIPv6, Optional, 0, "0"
+HKR, Ndi\params\LROIPv6\enum, "0", 0, %Disabled%
+HKR, Ndi\params\LROIPv6\enum, "1", 0, %Enabled%
+
+[XenNet_Inst.Services]
+AddService=xennet,0x02,XenNet_Service,XenNet_EventLog
+
+[XenNet_Service]
+ServiceType=%SERVICE_KERNEL_DRIVER%
+StartType=%SERVICE_DEMAND_START%
+ErrorControl=%SERVICE_ERROR_NORMAL%
+ServiceBinary=%12%\xennet.sys
+LoadOrderGroup="NDIS"
+
+[XenNet_EventLog]
+AddReg=XenNet_EventLog_AddReg
+
+[XenNet_EventLog_AddReg]
+HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\netevent.dll"
+HKR,,TypesSupported,0x00010001,7
+
+[XenNet_Inst.CoInstallers]
+CopyFiles=CoInst_CopyFiles
+AddReg=CoInst_AddReg
+
+[CoInst_AddReg]
+HKR,,CoInstallers32,0x00010000,"xennet_coinst_@MAJOR_VERSION@_@MINOR_VERSION@_@MICRO_VERSION@_@BUILD_NUMBER@.dll,Entry"
+
+[Strings]
+
+Citrix="Citrix Systems Inc."
+DiskDesc="Citrix Tools for Virtual Machines"
+DriverDesc="Citrix PV Network Adapter"
+IPChecksumOffloadIPv4="IPv4 Checksum Offload"
+TCPChecksumOffloadIPv4="TCP Checksum Offload (IPv4)"
+UDPChecksumOffloadIPv4="UDP Checksum Offload (IPv4)"
+TCPChecksumOffloadIPv6="TCP Checksum Offload (IPv6)"
+UDPChecksumOffloadIPv6="UDP Checksum Offload (IPv6)"
+NeedChecksumValue="Correct TCP/UDP Checksum Value"
+LSOV2IPv4="Large Send Offload V2 (IPv4)"
+LSOV2IPv6="Large Send Offload V2 (IPv6)"
+LROIPv4="Large Receive Offload (IPv4)"
+LROIPv6="Large Receive Offload (IPv6)"
+Disabled="Disabled"
+Enabled="Enabled"
+Enabled-Rx="Rx Enabled"
+Enabled-Tx="Tx Enabled"
+Enabled-TxRx="Rx & Tx Enabled"
+
+SERVICE_BOOT_START=0x0
+SERVICE_SYSTEM_START=0x1
+SERVICE_AUTO_START=0x2
+SERVICE_DEMAND_START=0x3
+SERVICE_DISABLED=0x4
+
+SERVICE_KERNEL_DRIVER=0x1
+SERVICE_ERROR_IGNORE=0x0
+SERVICE_ERROR_NORMAL=0x1
+SERVICE_ERROR_SEVERE=0x2
+SERVICE_ERROR_CRITICAL=0x3
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <version.h>
+#include "common.h"
+
+#pragma warning(disable:4711)
+
+//
+// List of supported OIDs.
+//
+
+static NDIS_STATUS
+AdapterStop (
+ IN PADAPTER Adapter
+ );
+
+static NDIS_STATUS
+AdapterSetRegistrationAttributes (
+ IN PADAPTER Adapter
+ );
+
+static NDIS_STATUS
+AdapterSetGeneralAttributes (
+ IN PADAPTER Adapter
+ );
+
+static NDIS_STATUS
+AdapterSetOffloadAttributes (
+ IN PADAPTER Adapter
+ );
+
+static VOID
+AdapterProcessSGList (
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Reserved,
+ IN PSCATTER_GATHER_LIST SGL,
+ IN PVOID Context
+ );
+
+static NDIS_STATUS
+AdapterSetInformation (
+ IN PADAPTER Adapter,
+ IN PNDIS_OID_REQUEST NdisRequest
+ );
+
+static NDIS_STATUS
+AdapterQueryInformation (
+ IN PADAPTER Adapter,
+ IN PNDIS_OID_REQUEST NdisRequest
+ );
+
+static NDIS_OID XennetSupportedOids[] =
+{
+ OID_GEN_SUPPORTED_LIST,
+ OID_GEN_HARDWARE_STATUS,
+ OID_GEN_MEDIA_SUPPORTED,
+ OID_GEN_MEDIA_IN_USE,
+ OID_GEN_PHYSICAL_MEDIUM,
+ OID_GEN_CURRENT_LOOKAHEAD,
+ OID_GEN_MAXIMUM_LOOKAHEAD,
+ OID_GEN_MAXIMUM_FRAME_SIZE,
+ OID_GEN_MAXIMUM_TOTAL_SIZE,
+ OID_GEN_RECEIVE_BLOCK_SIZE,
+ OID_GEN_TRANSMIT_BLOCK_SIZE,
+ OID_GEN_MAC_OPTIONS,
+ OID_GEN_LINK_SPEED,
+ OID_GEN_MEDIA_CONNECT_STATUS,
+ OID_GEN_VENDOR_DESCRIPTION,
+ OID_GEN_VENDOR_DRIVER_VERSION,
+ OID_GEN_DRIVER_VERSION,
+ OID_GEN_MAXIMUM_SEND_PACKETS,
+ OID_GEN_VENDOR_ID,
+ OID_GEN_CURRENT_PACKET_FILTER,
+ OID_GEN_XMIT_OK,
+ OID_GEN_RCV_OK,
+ OID_GEN_XMIT_ERROR,
+ OID_GEN_RCV_ERROR,
+ OID_GEN_RCV_CRC_ERROR,
+ OID_GEN_RCV_NO_BUFFER,
+ OID_GEN_TRANSMIT_QUEUE_LENGTH,
+ OID_GEN_TRANSMIT_BUFFER_SPACE,
+ OID_GEN_RECEIVE_BUFFER_SPACE,
+ OID_GEN_STATISTICS,
+ OID_GEN_DIRECTED_BYTES_XMIT,
+ OID_GEN_DIRECTED_FRAMES_XMIT,
+ OID_GEN_MULTICAST_BYTES_XMIT,
+ OID_GEN_MULTICAST_FRAMES_XMIT,
+ OID_GEN_BROADCAST_BYTES_XMIT,
+ OID_GEN_BROADCAST_FRAMES_XMIT,
+ OID_GEN_DIRECTED_BYTES_RCV,
+ OID_GEN_DIRECTED_FRAMES_RCV,
+ OID_GEN_MULTICAST_BYTES_RCV,
+ OID_GEN_MULTICAST_FRAMES_RCV,
+ OID_GEN_BROADCAST_BYTES_RCV,
+ OID_GEN_BROADCAST_FRAMES_RCV,
+ OID_GEN_INTERRUPT_MODERATION,
+ OID_802_3_RCV_ERROR_ALIGNMENT,
+ OID_802_3_XMIT_ONE_COLLISION,
+ OID_802_3_XMIT_MORE_COLLISIONS,
+ OID_OFFLOAD_ENCAPSULATION,
+ OID_TCP_OFFLOAD_PARAMETERS,
+ OID_PNP_CAPABILITIES,
+ OID_PNP_QUERY_POWER,
+ OID_PNP_SET_POWER,
+};
+
+#define INITIALIZE_NDIS_OBJ_HEADER(obj, type) do { \
+ (obj).Header.Type = NDIS_OBJECT_TYPE_ ## type ; \
+ (obj).Header.Revision = NDIS_ ## type ## _REVISION_1; \
+ (obj).Header.Size = sizeof(obj); \
+} while (0)
+
+//
+// Scatter gather allocate handler callback.
+// Should never get called.
+//
+static VOID
+AdapterAllocateComplete (
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PVOID VirtualAddress,
+ IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ IN ULONG Length,
+ IN PVOID Context
+ )
+{
+ UNREFERENCED_PARAMETER(MiniportAdapterContext);
+ UNREFERENCED_PARAMETER(VirtualAddress);
+ UNREFERENCED_PARAMETER(PhysicalAddress);
+ UNREFERENCED_PARAMETER(Length);
+ UNREFERENCED_PARAMETER(Context);
+
+ ASSERT(FALSE);
+
+ return;
+}
+
+//
+// Required NDIS6 handler.
+// Should never get called.
+//
+VOID
+AdapterCancelOidRequest (
+ IN PADAPTER Adapter,
+ IN PVOID RequestId
+ )
+{
+ UNREFERENCED_PARAMETER(Adapter);
+ UNREFERENCED_PARAMETER(RequestId);
+
+ return;
+}
+
+//
+// Required NDIS6 handler.
+// Should never get called.
+//
+
+VOID
+AdapterCancelSendNetBufferLists (
+ IN PADAPTER Adapter,
+ IN PVOID CancelId
+ )
+{
+ UNREFERENCED_PARAMETER(Adapter);
+ UNREFERENCED_PARAMETER(CancelId);
+
+ return;
+}
+
+BOOLEAN
+AdapterCheckForHang (
+ IN PADAPTER Adapter
+ )
+{
+ UNREFERENCED_PARAMETER(Adapter);
+
+ return FALSE;
+}
+
+//
+// Frees resources obtained by AdapterInitialize.
+//
+static VOID
+AdapterCleanup (
+ IN PADAPTER Adapter
+ )
+{
+ Trace("====>\n");
+
+ TransmitterDelete(&Adapter->Transmitter);
+ ReceiverCleanup(&Adapter->Receiver);
+
+ if (Adapter->NdisDmaHandle != NULL)
+ NdisMDeregisterScatterGatherDma(Adapter->NdisDmaHandle);
+
+ if (Adapter->AcquiredInterfaces) {
+ VIF(Release, Adapter->VifInterface);
+ Adapter->VifInterface = NULL;
+ }
+
+ 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 PADAPTER Adapter,
+ IN NDIS_HALT_ACTION HaltAction
+ )
+{
+ NDIS_STATUS ndisStatus;
+
+ UNREFERENCED_PARAMETER(HaltAction);
+
+
+ ndisStatus = AdapterStop(Adapter);
+ if (ndisStatus == NDIS_STATUS_SUCCESS) {
+ AdapterDelete(&Adapter);
+ }
+
+ return;
+}
+
+static VOID
+AdapterMediaStateChange(
+ IN PADAPTER Adapter
+ )
+{
+ NDIS_LINK_STATE LinkState;
+ NDIS_STATUS_INDICATION StatusIndication;
+
+ NdisZeroMemory(&LinkState, sizeof (NDIS_LINK_STATE));
+
+ LinkState.Header.Revision = NDIS_LINK_STATE_REVISION_1;
+ LinkState.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
+ LinkState.Header.Size = sizeof(NDIS_LINK_STATE);
+
+ VIF(QueryMediaState,
+ Adapter->VifInterface,
+ &LinkState.MediaConnectState,
+ &LinkState.RcvLinkSpeed,
+ &LinkState.MediaDuplexState);
+
+ if (LinkState.MediaConnectState == MediaConnectStateUnknown) {
+ Info("LINK: STATE UNKNOWN\n");
+ } else if (LinkState.MediaConnectState == MediaConnectStateDisconnected) {
+ Info("LINK: DOWN\n");
+ } else {
+ ASSERT3U(LinkState.MediaConnectState, ==, MediaConnectStateConnected);
+
+ if (LinkState.MediaDuplexState == MediaDuplexStateHalf)
+ Info("LINK: UP: SPEED=%u DUPLEX=HALF\n", LinkState.RcvLinkSpeed);
+ else if (LinkState.MediaDuplexState == MediaDuplexStateFull)
+ Info("LINK: UP: SPEED=%u DUPLEX=FULL\n", LinkState.RcvLinkSpeed);
+ else
+ Info("LINK: UP: SPEED=%u DUPLEX=UNKNOWN\n", LinkState.RcvLinkSpeed);
+ }
+
+ LinkState.XmitLinkSpeed = LinkState.RcvLinkSpeed;
+
+ NdisZeroMemory(&StatusIndication, sizeof (NDIS_STATUS_INDICATION));
+
+ StatusIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
+ StatusIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
+ StatusIndication.Header.Size = sizeof (NDIS_STATUS_INDICATION);
+ StatusIndication.SourceHandle = Adapter->NdisAdapterHandle;
+ StatusIndication.StatusCode = NDIS_STATUS_LINK_STATE;
+ StatusIndication.StatusBuffer = &LinkState;
+ StatusIndication.StatusBufferSize = sizeof (NDIS_LINK_STATE);
+
+ NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &StatusIndication);
+}
+
+
+//
+// Initializes adapter by allocating required resources and connects to
+// netback.
+//
+
+static VOID
+AdapterVifCallback(
+ IN PVOID Context,
+ IN XENVIF_CALLBACK_TYPE Type,
+ ...)
+{
+ PADAPTER Adapter = Context;
+ va_list Arguments;
+
+ va_start(Arguments, Type);
+
+ switch (Type) {
+ case XENVIF_CALLBACK_COMPLETE_PACKETS: {
+ PXENVIF_TRANSMITTER_PACKET HeadPacket;
+
+ HeadPacket = va_arg(Arguments, PXENVIF_TRANSMITTER_PACKET);
+
+ TransmitterCompletePackets(Adapter->Transmitter, HeadPacket);
+ break;
+ }
+ case XENVIF_CALLBACK_RECEIVE_PACKETS: {
+ PLIST_ENTRY List;
+
+ List = va_arg(Arguments, PLIST_ENTRY);
+
+ ReceiverReceivePackets(&Adapter->Receiver, List);
+ break;
+ }
+ case XENVIF_CALLBACK_MEDIA_STATE_CHANGE: {
+ AdapterMediaStateChange(Adapter);
+ break;
+ }
+ }
+
+ va_end(Arguments);
+}
+
+NDIS_STATUS
+AdapterGetAdvancedSettings(
+ IN PADAPTER pAdapter
+ )
+{
+ NDIS_CONFIGURATION_OBJECT configObject;
+ NDIS_HANDLE hConfigurationHandle;
+ NDIS_STRING ndisValue;
+ PNDIS_CONFIGURATION_PARAMETER pNdisData;
+ NDIS_STATUS ndisStatus;
+ NTSTATUS status;
+
+ configObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
+ configObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
+ configObject.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
+ configObject.NdisHandle = pAdapter->NdisAdapterHandle;
+ configObject.Flags = 0;
+
+ ndisStatus = NdisOpenConfigurationEx(&configObject, &hConfigurationHandle);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ goto fail1;
+
+#define read_property(field, name, default_val) \
+ do { \
+ RtlInitUnicodeString(&ndisValue, name); \
+ NdisReadConfiguration(&ndisStatus, &pNdisData, hConfigurationHandle, &ndisValue, NdisParameterInteger); \
+ if (ndisStatus == NDIS_STATUS_SUCCESS) { \
+ pAdapter->Properties.field = pNdisData->ParameterData.IntegerData; \
+ } else { \
+ pAdapter->Properties.field = default_val; \
+ } \
+ } while (FALSE);
+
+ read_property(ipv4_csum, L"*IPChecksumOffloadIPv4", 3);
+ read_property(tcpv4_csum, L"*TCPChecksumOffloadIPv4", 3);
+ read_property(udpv4_csum, L"*UDPChecksumOffloadIPv4", 3);
+ read_property(tcpv6_csum, L"*TCPChecksumOffloadIPv6", 3);
+ read_property(udpv6_csum, L"*UDPChecksumOffloadIPv6", 3);
+ read_property(lsov4, L"*LSOv2IPv4", 1);
+ read_property(lsov6, L"*LSOv2IPv6", 1);
+ read_property(lrov4, L"LROIPv4", 1);
+ read_property(lrov6, L"LROIPv6", 1);
+ read_property(need_csum_value, L"NeedChecksumValue", 1);
+
+ NdisCloseConfiguration(hConfigurationHandle);
+
+ return NDIS_STATUS_SUCCESS;
+
+fail1:
+ Error("fail1\n");
+ return NDIS_STATUS_FAILURE;
+}
+
+NDIS_STATUS
+AdapterInitialize (
+ IN PADAPTER Adapter,
+ IN NDIS_HANDLE AdapterHandle
+ )
+{
+ NDIS_STATUS ndisStatus;
+ NDIS_SG_DMA_DESCRIPTION DmaDescription;
+ NTSTATUS status;
+
+ Trace("====>\n");
+
+ Adapter->NdisAdapterHandle = AdapterHandle;
+
+ RtlZeroMemory(&Adapter->Capabilities, sizeof (Adapter->Capabilities));
+
+ Adapter->Transmitter = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSMITTER), ' TEN');
+ if (!Adapter->Transmitter) {
+ ndisStatus = NDIS_STATUS_RESOURCES;
+ goto exit;
+ }
+
+ RtlZeroMemory(Adapter->Transmitter, sizeof (TRANSMITTER));
+
+ ndisStatus = ReceiverInitialize(&Adapter->Receiver);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ goto exit;
+ }
+
+ ndisStatus = TransmitterInitialize(Adapter->Transmitter, Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ goto exit;
+ }
+
+ ndisStatus = AdapterGetAdvancedSettings(Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ goto exit;
+ }
+
+ ndisStatus = AdapterSetRegistrationAttributes(Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ goto exit;
+ }
+
+ ndisStatus = AdapterSetGeneralAttributes(Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ goto exit;
+ }
+
+ ndisStatus = AdapterSetOffloadAttributes(Adapter);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ goto exit;
+ }
+
+ NdisZeroMemory(&DmaDescription, sizeof(DmaDescription));
+
+ DmaDescription.Header.Type = NDIS_OBJECT_TYPE_SG_DMA_DESCRIPTION;
+ DmaDescription.Header.Revision = NDIS_SG_DMA_DESCRIPTION_REVISION_1;
+ DmaDescription.Header.Size = sizeof(NDIS_SG_DMA_DESCRIPTION);
+ DmaDescription.Flags = NDIS_SG_DMA_64_BIT_ADDRESS;
+ DmaDescription.MaximumPhysicalMapping = 65536;
+ DmaDescription.ProcessSGListHandler = AdapterProcessSGList;
+ DmaDescription.SharedMemAllocateCompleteHandler = AdapterAllocateComplete;
+
+ ndisStatus = NdisMRegisterScatterGatherDma(Adapter->NdisAdapterHandle,
+ &DmaDescription,
+ &Adapter->NdisDmaHandle);
+ if (ndisStatus != NDIS_STATUS_SUCCESS)
+ Adapter->NdisDmaHandle = NULL;
+
+ ASSERT(!Adapter->Enabled);
+ VIF(Acquire, Adapter->VifInterface);
+
+ status = VIF(Enable,
+ Adapter->VifInterface,
+ AdapterVifCallback,
+ Adapter);
+ if (NT_SUCCESS(status)) {
+ TransmitterEnable(Adapter->Transmitter);
+ Adapter->Enabled = TRUE;
+ ndisStatus = NDIS_STATUS_SUCCESS;
+ } else {
+ ndisStatus = NDIS_STATUS_FAILURE;
+ }
+
+exit:
+ Trace("<==== (%08x)\n", ndisStatus);
+ return ndisStatus;
+}
+
+//
+// Scatter gather process handler callback.
+// Should never get called.
+//
+static VOID
+AdapterProcessSGList (
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PVOID Reserved,
+ IN PSCATTER_GATHER_LIST SGL,
+ IN PVOID Context
+ )
+{
+ UNREFERENCED_PARAMETER(DeviceObject);
+ UNREFERENCED_PARAMETER(Reserved);
+ UNREFERENCED_PARAMETER(SGL);
+ UNREFERENCED_PARAMETER(Context);
+
+ ASSERT(FALSE);
+
+ return;
+}
+
+//
+// Get\Set OID handler.
+//
+NDIS_STATUS
+AdapterOidRequest (
+ IN PADAPTER Adapter,
+ IN PNDIS_OID_REQUEST NdisRequest
+ )
+{
+ NDIS_STATUS ndisStatus;
+
+ UNREFERENCED_PARAMETER(Adapter);
+ UNREFERENCED_PARAMETER(NdisRequest);
+
+ switch (NdisRequest->RequestType) {
+ case NdisRequestSetInformation:
+ ndisStatus = AdapterSetInformation(Adapter, NdisRequest);
+ break;
+
+ case NdisRequestQueryInformation:
+ case NdisRequestQueryStatistics:
+ ndisStatus = AdapterQueryInformation(Adapter, NdisRequest);
+ break;
+
+ default:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ };
+
+ return ndisStatus;
+}
+
+//
+// Temporarily pauses adapter.
+//
+NDIS_STATUS
+AdapterPause (
+ IN PADAPTER Adapter,
+ IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters
+ )
+{
+ UNREFERENCED_PARAMETER(MiniportPauseParameters);
+
+ Trace("====>\n");
+
+ if (!Adapter->Enabled)
+ goto done;
+
+ VIF(Disable,
+ Adapter->VifInterface);
+
+ AdapterMediaStateChange(Adapter);
+
+ Adapter->Enabled = FALSE;
+
+done:
+ Trace("<====\n");
+ return NDIS_STATUS_SUCCESS;
+}
+
+//
+// Handles PNP and Power events. NOP.
+//
+VOID
+AdapterPnPEventHandler (
+ IN PADAPTER Adapter,
+ IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent
+ )
+{
+ UNREFERENCED_PARAMETER(Adapter);
+
+
+ switch (NetDevicePnPEvent->DevicePnPEvent) {
+ case NdisDevicePnPEventQueryRemoved:
+ break;
+
+ case NdisDevicePnPEventRemoved:
+ break;
+
+ case NdisDevicePnPEventSurpriseRemoved:
+ break;
+
+ case NdisDevicePnPEventQueryStopped:
+ break;
+
+ case NdisDevicePnPEventStopped:
+ break;
+
+ case NdisDevicePnPEventPowerProfileChanged:
+ break;
+
+ default:
+ break;
+ };
+
+ return;
+}
+
+//
+// Reports general statistics to NDIS.
+//
+static NDIS_STATUS
+AdapterQueryGeneralStatistics (
+ IN PADAPTER Adapter,
+ IN PNDIS_STATISTICS_INFO NdisStatisticsInfo
+ )
+{
+ NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ NdisZeroMemory(NdisStatisticsInfo, sizeof(NDIS_STATISTICS_INFO));
+ NdisStatisticsInfo->Header.Revision = NDIS_OBJECT_REVISION_1;
+ NdisStatisticsInfo->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
+ NdisStatisticsInfo->Header.Size = sizeof(NDIS_STATISTICS_INFO);
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR;
+ NdisStatisticsInfo->ifInErrors =
+ Statistics.Receiver.BackendError +
+ Statistics.Receiver.FrontendError;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS;
+ NdisStatisticsInfo->ifInDiscards = Statistics.Receiver.Drop;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV;
+ NdisStatisticsInfo->ifHCInOctets = Statistics.Receiver.UnicastBytes +
+ Statistics.Receiver.MulticastBytes +
+ Statistics.Receiver.BroadcastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV;
+ NdisStatisticsInfo->ifHCInUcastOctets = Statistics.Receiver.UnicastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV;
+ NdisStatisticsInfo->ifHCInUcastPkts = Statistics.Receiver.Unicast;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV;
+ NdisStatisticsInfo->ifHCInMulticastOctets = Statistics.Receiver.MulticastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV;
+ NdisStatisticsInfo->ifHCInMulticastPkts = Statistics.Receiver.Multicast;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV;
+ NdisStatisticsInfo->ifHCInBroadcastOctets = Statistics.Receiver.BroadcastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV;
+ NdisStatisticsInfo->ifHCInBroadcastPkts = Statistics.Receiver.Broadcast;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR;
+ NdisStatisticsInfo->ifOutErrors =
+ Statistics.Transmitter.BackendError +
+ Statistics.Transmitter.FrontendError;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT;
+ NdisStatisticsInfo->ifHCOutOctets = Statistics.Transmitter.UnicastBytes +
+ Statistics.Transmitter.MulticastBytes +
+ Statistics.Transmitter.BroadcastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT;
+ NdisStatisticsInfo->ifHCOutUcastOctets = Statistics.Transmitter.UnicastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT;
+ NdisStatisticsInfo->ifHCOutUcastPkts = Statistics.Transmitter.Unicast;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT;
+ NdisStatisticsInfo->ifHCOutMulticastOctets = Statistics.Transmitter.MulticastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT;
+ NdisStatisticsInfo->ifHCOutMulticastPkts = Statistics.Transmitter.MulticastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT;
+ NdisStatisticsInfo->ifHCOutBroadcastOctets = Statistics.Transmitter.BroadcastBytes;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT;
+ NdisStatisticsInfo->ifHCOutBroadcastPkts = Statistics.Transmitter.Broadcast;
+
+ NdisStatisticsInfo->SupportedStatistics |= NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS;
+ NdisStatisticsInfo->ifOutDiscards = 0;
+
+ return ndisStatus;
+}
+
+static VOID
+GetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
+{
+ XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel;
+ XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
+ XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
+
+ VIF(QueryFilterLevel,
+ Adapter->VifInterface,
+ ETHERNET_ADDRESS_UNICAST,
+ &UnicastFilterLevel);
+
+ VIF(QueryFilterLevel,
+ Adapter->VifInterface,
+ ETHERNET_ADDRESS_MULTICAST,
+ &MulticastFilterLevel);
+
+ VIF(QueryFilterLevel,
+ Adapter->VifInterface,
+ ETHERNET_ADDRESS_BROADCAST,
+ &BroadcastFilterLevel);
+
+ *PacketFilter = 0;
+
+ if (UnicastFilterLevel == MAC_FILTER_ALL) {
+ ASSERT3U(MulticastFilterLevel, ==, MAC_FILTER_ALL);
+ ASSERT3U(BroadcastFilterLevel, ==, MAC_FILTER_ALL);
+
+ *PacketFilter |= NDIS_PACKET_TYPE_PROMISCUOUS;
+ return;
+ } else if (UnicastFilterLevel == MAC_FILTER_MATCHING) {
+ *PacketFilter |= NDIS_PACKET_TYPE_DIRECTED;
+ }
+
+ if (MulticastFilterLevel == MAC_FILTER_ALL)
+ *PacketFilter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
+ else if (MulticastFilterLevel == MAC_FILTER_MATCHING)
+ *PacketFilter |= NDIS_PACKET_TYPE_MULTICAST;
+
+ if (BroadcastFilterLevel == MAC_FILTER_ALL)
+ *PacketFilter |= NDIS_PACKET_TYPE_BROADCAST;
+}
+
+#define MIN(_x, _y) (((_x) < (_y)) ? (_x) : (_y))
+
+//
+// Handles OID queries.
+//
+static NDIS_STATUS
+AdapterQueryInformation (
+ IN PADAPTER Adapter,
+ IN PNDIS_OID_REQUEST NdisRequest
+ )
+{
+ ULONG bytesAvailable = 0;
+ ULONG bytesNeeded = 0;
+ ULONG bytesWritten = 0;
+ BOOLEAN doCopy = TRUE;
+ PVOID info = NULL;
+ ULONGLONG infoData;
+ ULONG informationBufferLength;
+ PVOID informationBuffer;
+ NDIS_INTERRUPT_MODERATION_PARAMETERS intModParams;
+ NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
+ NDIS_OID oid;
+
+ informationBuffer = NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer;
+ informationBufferLength = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
+ oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
+ switch (oid) {
+ case OID_PNP_CAPABILITIES:
+ Trace("PNP_CAPABILITIES\n");
+
+ info = &Adapter->Capabilities;
+ bytesAvailable = sizeof(Adapter->Capabilities);
+ break;
+
+ case OID_PNP_QUERY_POWER:
+ Trace("QUERY_POWER\n");
+
+ bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
+ if (informationBufferLength >= bytesNeeded) {
+ PNDIS_DEVICE_POWER_STATE state;
+
+ state = (PNDIS_DEVICE_POWER_STATE)informationBuffer;
+ switch (*state) {
+ case NdisDeviceStateD0:
+ Trace("D0\n");
+ break;
+
+ case NdisDeviceStateD1:
+ Trace("D1\n");
+ break;
+
+ case NdisDeviceStateD2:
+ Trace("D2\n");
+ break;
+
+ case NdisDeviceStateD3:
+ Trace("D3\n");
+ break;
+ }
+ }
+ break;
+
+ case OID_GEN_SUPPORTED_LIST:
+ info = &XennetSupportedOids[0];
+ bytesAvailable = sizeof(XennetSupportedOids);
+ break;
+
+ case OID_GEN_HARDWARE_STATUS:
+ infoData = NdisHardwareStatusReady;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_MEDIA_SUPPORTED:
+ case OID_GEN_MEDIA_IN_USE:
+ infoData = XENNET_MEDIA_TYPE;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_MAXIMUM_LOOKAHEAD:
+ infoData = Adapter->MaximumFrameSize;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_TRANSMIT_BUFFER_SPACE:
+ VIF(QueryTransmitterRingSize,
+ 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);
+ infoData *= Adapter->MaximumFrameSize;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_TRANSMIT_BLOCK_SIZE:
+ case OID_GEN_RECEIVE_BLOCK_SIZE:
+ infoData = Adapter->MaximumFrameSize;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_VENDOR_DESCRIPTION:
+ info = "Citrix";
+ bytesAvailable = (ULONG)strlen(info) + 1;
+ break;
+
+ case OID_GEN_VENDOR_DRIVER_VERSION:
+ infoData = ((MAJOR_VERSION << 8) | MINOR_VERSION) << 8;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_DRIVER_VERSION:
+ infoData = (6 << 8) | 0;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_MAC_OPTIONS:
+ infoData = XENNET_MAC_OPTIONS;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_STATISTICS:
+ doCopy = FALSE;
+
+ bytesAvailable = sizeof(NDIS_STATISTICS_INFO);
+ if (informationBufferLength >= bytesAvailable) {
+ ndisStatus = AdapterQueryGeneralStatistics(Adapter,
+ informationBuffer);
+
+ }
+
+ break;
+
+ case OID_802_3_MULTICAST_LIST: {
+ ULONG Count;
+
+ doCopy = FALSE;
+
+ VIF(QueryMulticastAddresses,
+ Adapter->VifInterface,
+ NULL,
+ &Count);
+ bytesAvailable = Count * ETHERNET_ADDRESS_LENGTH;
+
+ if (informationBufferLength >= bytesAvailable) {
+ NTSTATUS status;
+
+ status = VIF(QueryMulticastAddresses,
+ Adapter->VifInterface,
+ informationBuffer,
+ &Count);
+ if (!NT_SUCCESS(status))
+ ndisStatus = NDIS_STATUS_FAILURE;
+ }
+
+ break;
+ }
+ case OID_802_3_PERMANENT_ADDRESS:
+ VIF(QueryPermanentAddress,
+ Adapter->VifInterface,
+ (PETHERNET_ADDRESS)&infoData);
+ info = &infoData;
+ bytesAvailable = ETH_LENGTH_OF_ADDRESS;
+ break;
+
+ case OID_802_3_CURRENT_ADDRESS:
+ VIF(QueryCurrentAddress,
+ Adapter->VifInterface,
+ (PETHERNET_ADDRESS)&infoData);
+ info = &infoData;
+ bytesAvailable = ETH_LENGTH_OF_ADDRESS;
+ break;
+
+ case OID_GEN_MAXIMUM_FRAME_SIZE:
+ infoData = Adapter->MaximumFrameSize - sizeof (ETHERNET_HEADER);
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ case OID_GEN_MAXIMUM_TOTAL_SIZE: {
+ infoData = Adapter->MaximumFrameSize - 4;
+
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ infoData = Adapter->CurrentLookahead;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_VENDOR_ID:
+ infoData = 0x5853;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_LINK_SPEED: {
+ ULONG64 LinkSpeed;
+
+ VIF(QueryMediaState,
+ 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;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_MAXIMUM_SEND_PACKETS:
+ infoData = 16;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ GetPacketFilter(Adapter, (PULONG)&infoData);
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_XMIT_OK: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = Statistics.Transmitter.Unicast +
+ Statistics.Transmitter.Multicast +
+ Statistics.Transmitter.Broadcast;
+
+ info = &infoData;
+ bytesAvailable = sizeof(ULONGLONG);
+ break;
+ }
+ case OID_GEN_RCV_OK: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = Statistics.Receiver.Unicast +
+ Statistics.Receiver.Multicast +
+ Statistics.Receiver.Broadcast;
+
+ info = &infoData;
+ bytesAvailable = sizeof(ULONGLONG);
+ break;
+ }
+ case OID_GEN_XMIT_ERROR: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)(Statistics.Transmitter.BackendError +
+ Statistics.Transmitter.FrontendError);
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_RCV_ERROR: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)(Statistics.Receiver.BackendError +
+ Statistics.Receiver.FrontendError);
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_RCV_NO_BUFFER:
+ infoData = 0; // We'd need to query VIF TX drop stats from dom0
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_TRANSMIT_QUEUE_LENGTH:
+ infoData = 0;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_802_3_MAXIMUM_LIST_SIZE:
+ infoData = MAXIMUM_MULTICAST_ADDRESS_COUNT;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_IP4_OFFLOAD_STATS:
+ case OID_IP6_OFFLOAD_STATS:
+ case OID_GEN_SUPPORTED_GUIDS:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+
+ case OID_GEN_RCV_CRC_ERROR:
+ infoData = 0;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_802_3_RCV_ERROR_ALIGNMENT:
+ case OID_802_3_XMIT_ONE_COLLISION:
+ case OID_802_3_XMIT_MORE_COLLISIONS:
+ infoData = 0;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+
+ case OID_GEN_DIRECTED_BYTES_XMIT: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Transmitter.UnicastBytes;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_DIRECTED_FRAMES_XMIT: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Transmitter.Unicast;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_MULTICAST_BYTES_XMIT: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Transmitter.MulticastBytes;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_MULTICAST_FRAMES_XMIT: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Transmitter.Multicast;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_BROADCAST_BYTES_XMIT: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Transmitter.BroadcastBytes;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_BROADCAST_FRAMES_XMIT: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Transmitter.Broadcast;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_DIRECTED_BYTES_RCV: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Receiver.UnicastBytes;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_DIRECTED_FRAMES_RCV: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Receiver.Unicast;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_MULTICAST_BYTES_RCV: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Receiver.MulticastBytes;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_MULTICAST_FRAMES_RCV: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Receiver.Multicast;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_BROADCAST_BYTES_RCV: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Receiver.BroadcastBytes;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_BROADCAST_FRAMES_RCV: {
+ XENVIF_PACKET_STATISTICS Statistics;
+
+ VIF(QueryPacketStatistics,
+ Adapter->VifInterface,
+ &Statistics);
+
+ infoData = (ULONG)Statistics.Receiver.Broadcast;
+ info = &infoData;
+ bytesAvailable = sizeof(ULONG);
+ break;
+ }
+ case OID_GEN_INTERRUPT_MODERATION:
+ intModParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
+ intModParams.Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
+ intModParams.Header.Size = sizeof(NDIS_INTERRUPT_MODERATION_PARAMETERS);
+ intModParams.Flags = 0;
+ intModParams.InterruptModeration = NdisInterruptModerationNotSupported;
+ info = &intModParams;
+ bytesAvailable = sizeof(intModParams);
+ break;
+
+ // We don't handle these since NDIS 6.0 is supposed to do this for us
+ case OID_GEN_MAC_ADDRESS:
+ case OID_GEN_MAX_LINK_SPEED:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+
+ // ignore these common unwanted OIDs
+ case OID_GEN_INIT_TIME_MS:
+ case OID_GEN_RESET_COUNTS:
+ case OID_GEN_MEDIA_SENSE_COUNTS:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+
+ default:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ };
+
+ if (ndisStatus == NDIS_STATUS_SUCCESS) {
+ if (bytesAvailable <= informationBufferLength) {
+ bytesNeeded = bytesAvailable;
+ bytesWritten = bytesAvailable;
+ } else {
+ bytesNeeded = bytesAvailable;
+ bytesWritten = informationBufferLength;
+ ndisStatus = NDIS_STATUS_BUFFER_TOO_SHORT;
+ }
+
+ if (bytesWritten && doCopy) {
+ NdisMoveMemory(informationBuffer, info, bytesWritten);
+
+ if (oid == OID_GEN_XMIT_OK || oid == OID_GEN_RCV_OK)
+ ndisStatus = NDIS_STATUS_SUCCESS;
+ }
+ }
+
+ NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = bytesWritten;
+ NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = bytesNeeded;
+ return ndisStatus;
+}
+
+NDIS_STATUS
+AdapterReset (
+ IN NDIS_HANDLE MiniportAdapterContext,
+ OUT PBOOLEAN AddressingReset
+ )
+{
+ UNREFERENCED_PARAMETER(MiniportAdapterContext);
+
+
+ *AddressingReset = FALSE;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+//
+// Restarts a paused adapter.
+//
+NDIS_STATUS
+AdapterRestart (
+ IN PADAPTER Adapter,
+ IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters
+ )
+{
+ NTSTATUS status;
+ NDIS_STATUS ndisStatus;
+
+ UNREFERENCED_PARAMETER(MiniportRestartParameters);
+
+ Trace("====>\n");
+
+ if (Adapter->Enabled) {
+ ndisStatus = NDIS_STATUS_SUCCESS;
+ goto done;
+ }
+
+ status = VIF(Enable,
+ Adapter->VifInterface,
+ AdapterVifCallback,
+ Adapter);
+ if (NT_SUCCESS(status)) {
+ TransmitterEnable(Adapter->Transmitter);
+ Adapter->Enabled = TRUE;
+ ndisStatus = NDIS_STATUS_SUCCESS;
+ } else {
+ ndisStatus = NDIS_STATUS_FAILURE;
+ }
+
+done:
+ Trace("<====\n");
+ return ndisStatus;
+}
+
+//
+// Recycle of received net buffer lists.
+//
+VOID
+AdapterReturnNetBufferLists (
+ IN PADAPTER Adapter,
+ IN PNET_BUFFER_LIST NetBufferLists,
+ IN ULONG ReturnFlags
+ )
+{
+ ReceiverReturnNetBufferLists(&Adapter->Receiver,
+ NetBufferLists,
+ ReturnFlags);
+
+ return;
+}
+
+//
+// Used to send net buffer lists.
+//
+VOID
+AdapterSendNetBufferLists (
+ IN PADAPTER Adapter,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN ULONG SendFlags
+ )
+{
+ TransmitterSendNetBufferLists(Adapter->Transmitter,
+ NetBufferList,
+ PortNumber,
+ SendFlags);
+}
+
+#define XENNET_MEDIA_MAX_SPEED 1000000000ull
+
+#define XENNET_SUPPORTED_PACKET_FILTERS \
+ (NDIS_PACKET_TYPE_DIRECTED | \
+ NDIS_PACKET_TYPE_MULTICAST | \
+ NDIS_PACKET_TYPE_ALL_MULTICAST | \
+ NDIS_PACKET_TYPE_BROADCAST | \
+ NDIS_PACKET_TYPE_PROMISCUOUS)
+
+//
+// Sets general adapter attributes.
+//
+static NDIS_STATUS
+AdapterSetGeneralAttributes (
+ IN PADAPTER Adapter
+ )
+{
+ PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
+ NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES generalAttributes;
+ NDIS_STATUS ndisStatus;
+
+ NdisZeroMemory(&generalAttributes,
+ sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES));
+
+ generalAttributes.Header.Type =
+ NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
+
+ generalAttributes.Header.Revision =
+ NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
+
+ generalAttributes.Header.Size =
+ sizeof(NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES);
+
+ generalAttributes.MediaType = XENNET_MEDIA_TYPE;
+
+ VIF(QueryMaximumFrameSize,
+ Adapter->VifInterface,
+ (PULONG)&Adapter->MaximumFrameSize);
+
+ generalAttributes.MtuSize = Adapter->MaximumFrameSize - sizeof (ETHERNET_HEADER);
+ generalAttributes.MaxXmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
+ generalAttributes.MaxRcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
+ generalAttributes.XmitLinkSpeed = XENNET_MEDIA_MAX_SPEED;
+ generalAttributes.RcvLinkSpeed = XENNET_MEDIA_MAX_SPEED;
+ generalAttributes.MediaConnectState = MediaConnectStateConnected;
+ generalAttributes.MediaDuplexState = MediaDuplexStateFull;
+ generalAttributes.LookaheadSize = Adapter->MaximumFrameSize;
+ generalAttributes.PowerManagementCapabilities = &Adapter->Capabilities;
+ generalAttributes.MacOptions = XENNET_MAC_OPTIONS;
+
+ generalAttributes.SupportedPacketFilters = XENNET_SUPPORTED_PACKET_FILTERS;
+
+ generalAttributes.MaxMulticastListSize = MAXIMUM_MULTICAST_ADDRESS_COUNT;
+ generalAttributes.MacAddressLength = ETHERNET_ADDRESS_LENGTH;
+
+ VIF(QueryPermanentAddress,
+ Adapter->VifInterface,
+ (PETHERNET_ADDRESS)&generalAttributes.PermanentMacAddress);
+ VIF(QueryCurrentAddress,
+ Adapter->VifInterface,
+ (PETHERNET_ADDRESS)&generalAttributes.CurrentMacAddress);
+
+ generalAttributes.PhysicalMediumType = NdisPhysicalMedium802_3;
+ generalAttributes.RecvScaleCapabilities = NULL;
+ generalAttributes.AccessType = NET_IF_ACCESS_BROADCAST;
+ generalAttributes.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
+ generalAttributes.ConnectionType = NET_IF_CONNECTION_DEDICATED;
+ generalAttributes.IfType = IF_TYPE_ETHERNET_CSMACD;
+ generalAttributes.IfConnectorPresent = TRUE;
+
+ generalAttributes.SupportedStatistics = NDIS_STATISTICS_XMIT_OK_SUPPORTED |
+ NDIS_STATISTICS_XMIT_ERROR_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_BYTES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_FRAMES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_BYTES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_FRAMES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_BYTES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_FRAMES_XMIT_SUPPORTED |
+ NDIS_STATISTICS_RCV_OK_SUPPORTED |
+ NDIS_STATISTICS_RCV_ERROR_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_BYTES_RCV_SUPPORTED |
+ NDIS_STATISTICS_DIRECTED_FRAMES_RCV_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_BYTES_RCV_SUPPORTED |
+ NDIS_STATISTICS_MULTICAST_FRAMES_RCV_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_BYTES_RCV_SUPPORTED |
+ NDIS_STATISTICS_BROADCAST_FRAMES_RCV_SUPPORTED |
+ NDIS_STATISTICS_GEN_STATISTICS_SUPPORTED;
+
+ generalAttributes.SupportedOidList = XennetSupportedOids;
+ generalAttributes.SupportedOidListLength = sizeof(XennetSupportedOids);
+ adapterAttributes =
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&generalAttributes;
+
+ ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ adapterAttributes);
+
+ return ndisStatus;
+}
+
+#define DISPLAY_OFFLOAD(_Offload) \
+ do { \
+ if ((_Offload).Checksum.IPv4Receive.IpChecksum) \
+ Info("Checksum.IPv4Receive.IpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv4Receive.IpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv4Receive.TcpChecksum) \
+ Info("Checksum.IPv4Receive.TcpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv4Receive.TcpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv4Receive.UdpChecksum) \
+ Info("Checksum.IPv4Receive.UdpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv4Receive.UdpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv6Receive.TcpChecksum) \
+ Info("Checksum.IPv6Receive.TcpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv6Receive.TcpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv6Receive.UdpChecksum) \
+ Info("Checksum.IPv6Receive.UdpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv6Receive.UdpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv4Transmit.IpChecksum) \
+ Info("Checksum.IPv4Transmit.IpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv4Transmit.IpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv4Transmit.TcpChecksum) \
+ Info("Checksum.IPv4Transmit.TcpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv4Transmit.TcpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv4Transmit.UdpChecksum) \
+ Info("Checksum.IPv4Transmit.UdpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv4Transmit.UdpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv6Transmit.TcpChecksum) \
+ Info("Checksum.IPv6Transmit.TcpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv6Transmit.TcpChecksum OFF\n"); \
+ \
+ if ((_Offload).Checksum.IPv6Transmit.UdpChecksum) \
+ Info("Checksum.IPv6Transmit.UdpChecksum ON\n"); \
+ else \
+ Info("Checksum.IPv6Transmit.UdpChecksum OFF\n"); \
+ \
+ if ((_Offload).LsoV2.IPv4.MaxOffLoadSize != 0) \
+ Info("LsoV2.IPv4.MaxOffLoadSize = %u\n", \
+ (_Offload).LsoV2.IPv4.MaxOffLoadSize); \
+ else \
+ Info("LsoV2.IPv4 OFF\n"); \
+ \
+ if ((_Offload).LsoV2.IPv6.MaxOffLoadSize != 0) \
+ Info("LsoV2.IPv6.MaxOffLoadSize = %u\n", \
+ (_Offload).LsoV2.IPv6.MaxOffLoadSize); \
+ else \
+ Info("LsoV2.IPv6 OFF\n"); \
+ } while (FALSE)
+
+static NDIS_STATUS
+AdapterSetOffloadAttributes(
+ IN PADAPTER Adapter
+ )
+{
+ PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
+ NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES offloadAttributes;
+ XENVIF_OFFLOAD_OPTIONS Options;
+ NDIS_OFFLOAD current;
+ NDIS_OFFLOAD supported;
+ NDIS_STATUS ndisStatus;
+
+ Adapter->Receiver.OffloadOptions.Value = 0;
+ Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1;
+
+ if (Adapter->Properties.need_csum_value)
+ Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1;
+
+ if (Adapter->Properties.lrov4) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1;
+ Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
+ }
+
+ if (Adapter->Properties.lrov6) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1;
+ Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
+ }
+
+ Adapter->Transmitter->OffloadOptions.Value = 0;
+ Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1;
+
+ NdisZeroMemory(&offloadAttributes, sizeof(offloadAttributes));
+ NdisZeroMemory(¤t, sizeof(current));
+ NdisZeroMemory(&supported, sizeof(supported));
+
+ VIF(UpdateOffloadOptions,
+ Adapter->VifInterface,
+ Adapter->Receiver.OffloadOptions);
+
+ supported.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
+ supported.Header.Revision = NDIS_OFFLOAD_REVISION_1;
+ supported.Header.Size = sizeof(supported);
+
+ supported.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ supported.Checksum.IPv4Receive.IpChecksum = 1;
+ supported.Checksum.IPv4Receive.IpOptionsSupported = 1;
+
+ supported.Checksum.IPv4Receive.TcpChecksum = 1;
+ supported.Checksum.IPv4Receive.TcpOptionsSupported = 1;
+
+ supported.Checksum.IPv4Receive.UdpChecksum = 1;
+
+ supported.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ supported.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+
+ supported.Checksum.IPv6Receive.TcpChecksum = 1;
+ supported.Checksum.IPv6Receive.TcpOptionsSupported = 1;
+
+ supported.Checksum.IPv6Receive.UdpChecksum = 1;
+
+ VIF(QueryOffloadOptions,
+ Adapter->VifInterface,
+ &Options);
+
+ supported.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ if (Options.OffloadIpVersion4HeaderChecksum) {
+ supported.Checksum.IPv4Transmit.IpChecksum = 1;
+ supported.Checksum.IPv4Transmit.IpOptionsSupported = 1;
+ }
+
+ if (Options.OffloadIpVersion4TcpChecksum) {
+ supported.Checksum.IPv4Transmit.TcpChecksum = 1;
+ supported.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+ }
+
+ if (Options.OffloadIpVersion4UdpChecksum)
+ supported.Checksum.IPv4Transmit.UdpChecksum = 1;
+
+ supported.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ supported.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+
+ if (Options.OffloadIpVersion6TcpChecksum) {
+ supported.Checksum.IPv6Transmit.TcpChecksum = 1;
+ supported.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+ }
+
+ if (Options.OffloadIpVersion6UdpChecksum)
+ supported.Checksum.IPv6Transmit.UdpChecksum = 1;
+
+ if (Options.OffloadIpVersion4LargePacket) {
+ ULONG Size;
+
+ VIF(QueryLargePacketSize,
+ Adapter->VifInterface,
+ 4,
+ &Size);
+
+ supported.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ supported.LsoV2.IPv4.MaxOffLoadSize = Size;
+ supported.LsoV2.IPv4.MinSegmentCount = 2;
+ }
+
+ if (Options.OffloadIpVersion6LargePacket) {
+ ULONG Size;
+
+ VIF(QueryLargePacketSize,
+ Adapter->VifInterface,
+ 6,
+ &Size);
+
+ supported.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ supported.LsoV2.IPv6.MaxOffLoadSize = Size;
+ supported.LsoV2.IPv6.MinSegmentCount = 2;
+ supported.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
+ supported.LsoV2.IPv6.TcpOptionsSupported = 1;
+ }
+
+ current = supported;
+
+ if (!(Adapter->Properties.ipv4_csum & 2))
+ current.Checksum.IPv4Receive.IpChecksum = 0;
+
+ if (!(Adapter->Properties.tcpv4_csum & 2))
+ current.Checksum.IPv4Receive.TcpChecksum = 0;
+
+ if (!(Adapter->Properties.udpv4_csum & 2))
+ current.Checksum.IPv4Receive.UdpChecksum = 0;
+
+ if (!(Adapter->Properties.tcpv6_csum & 2))
+ current.Checksum.IPv6Receive.TcpChecksum = 0;
+
+ if (!(Adapter->Properties.udpv6_csum & 2))
+ current.Checksum.IPv6Receive.UdpChecksum = 0;
+
+ if (!(Adapter->Properties.ipv4_csum & 1))
+ current.Checksum.IPv4Transmit.IpChecksum = 0;
+
+ if (!(Adapter->Properties.tcpv4_csum & 1))
+ current.Checksum.IPv4Transmit.TcpChecksum = 0;
+
+ if (!(Adapter->Properties.udpv4_csum & 1))
+ current.Checksum.IPv4Transmit.UdpChecksum = 0;
+
+ if (!(Adapter->Properties.tcpv6_csum & 1))
+ current.Checksum.IPv6Transmit.TcpChecksum = 0;
+
+ if (!(Adapter->Properties.udpv6_csum & 1))
+ current.Checksum.IPv6Transmit.UdpChecksum = 0;
+
+ if (!(Adapter->Properties.lsov4)) {
+ current.LsoV2.IPv4.MaxOffLoadSize = 0;
+ current.LsoV2.IPv4.MinSegmentCount = 0;
+ }
+
+ if (!(Adapter->Properties.lsov6)) {
+ current.LsoV2.IPv6.MaxOffLoadSize = 0;
+ current.LsoV2.IPv6.MinSegmentCount = 0;
+ }
+
+ if (!RtlEqualMemory(&Adapter->Offload, ¤t, sizeof (NDIS_OFFLOAD))) {
+ Adapter->Offload = current;
+
+ DISPLAY_OFFLOAD(current);
+ }
+
+ offloadAttributes.Header.Type =
+ NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES;
+ offloadAttributes.Header.Revision =
+ NDIS_MINIPORT_ADAPTER_OFFLOAD_ATTRIBUTES_REVISION_1;
+ offloadAttributes.Header.Size = sizeof(offloadAttributes);
+ offloadAttributes.DefaultOffloadConfiguration = ¤t;
+ offloadAttributes.HardwareOffloadCapabilities = &supported;
+
+ adapterAttributes =
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&offloadAttributes;
+ ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ adapterAttributes);
+
+ return ndisStatus;
+}
+
+static void
+AdapterIndicateOffloadChanged (
+ IN PADAPTER Adapter
+ )
+{
+ NDIS_STATUS_INDICATION indication;
+ NDIS_OFFLOAD offload;
+
+ NdisZeroMemory(&offload, sizeof(offload));
+ INITIALIZE_NDIS_OBJ_HEADER(offload, OFFLOAD);
+
+ offload.Checksum.IPv4Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
+ offload.Checksum.IPv4Receive.IpChecksum = 1;
+ offload.Checksum.IPv4Receive.IpOptionsSupported = 1;
+ }
+
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
+ offload.Checksum.IPv4Receive.TcpChecksum = 1;
+ offload.Checksum.IPv4Receive.TcpOptionsSupported = 1;
+ }
+
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
+ offload.Checksum.IPv4Receive.UdpChecksum = 1;
+ }
+
+ offload.Checksum.IPv6Receive.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ offload.Checksum.IPv6Receive.IpExtensionHeadersSupported = 1;
+
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
+ offload.Checksum.IPv6Receive.TcpChecksum = 1;
+ offload.Checksum.IPv6Receive.TcpOptionsSupported = 1;
+ }
+
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
+ offload.Checksum.IPv6Receive.UdpChecksum = 1;
+ }
+
+ VIF(UpdateOffloadOptions,
+ Adapter->VifInterface,
+ Adapter->Receiver.OffloadOptions);
+
+ offload.Checksum.IPv4Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
+ offload.Checksum.IPv4Transmit.IpChecksum = 1;
+ offload.Checksum.IPv4Transmit.IpOptionsSupported = 1;
+ }
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
+ offload.Checksum.IPv4Transmit.TcpChecksum = 1;
+ offload.Checksum.IPv4Transmit.TcpOptionsSupported = 1;
+ }
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
+ offload.Checksum.IPv4Transmit.UdpChecksum = 1;
+ }
+
+ offload.Checksum.IPv6Transmit.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+
+ offload.Checksum.IPv6Transmit.IpExtensionHeadersSupported = 1;
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
+ offload.Checksum.IPv6Transmit.TcpChecksum = 1;
+ offload.Checksum.IPv6Transmit.TcpOptionsSupported = 1;
+ }
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
+ offload.Checksum.IPv6Transmit.UdpChecksum = 1;
+ }
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
+ ULONG Size;
+
+ VIF(QueryLargePacketSize,
+ Adapter->VifInterface,
+ 4,
+ &Size);
+
+ offload.LsoV2.IPv4.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ offload.LsoV2.IPv4.MaxOffLoadSize = Size;
+ offload.LsoV2.IPv4.MinSegmentCount = 2;
+ }
+
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
+ ULONG Size;
+
+ VIF(QueryLargePacketSize,
+ Adapter->VifInterface,
+ 6,
+ &Size);
+
+ offload.LsoV2.IPv6.Encapsulation = NDIS_ENCAPSULATION_IEEE_802_3;
+ offload.LsoV2.IPv6.MaxOffLoadSize = Size;
+ offload.LsoV2.IPv6.MinSegmentCount = 2;
+ offload.LsoV2.IPv6.IpExtensionHeadersSupported = 1;
+ offload.LsoV2.IPv6.TcpOptionsSupported = 1;
+ }
+
+ if (!RtlEqualMemory(&Adapter->Offload, &offload, sizeof (NDIS_OFFLOAD))) {
+ Adapter->Offload = offload;
+
+ DISPLAY_OFFLOAD(offload);
+ }
+
+ NdisZeroMemory(&indication, sizeof(indication));
+ INITIALIZE_NDIS_OBJ_HEADER(indication, STATUS_INDICATION);
+ indication.SourceHandle = Adapter->NdisAdapterHandle;
+ indication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG;
+ indication.StatusBuffer = &offload;
+ indication.StatusBufferSize = sizeof(offload);
+
+ NdisMIndicateStatusEx(Adapter->NdisAdapterHandle, &indication);
+
+}
+
+static NDIS_STATUS
+SetMulticastAddresses(PADAPTER Adapter, PETHERNET_ADDRESS Address, ULONG Count)
+{
+ NTSTATUS status;
+
+ ASSERT3U(Count, <=, MAXIMUM_MULTICAST_ADDRESS_COUNT);
+
+ status = VIF(UpdateMulticastAddresses,
+ Adapter->VifInterface,
+ Address,
+ Count);
+ if (!NT_SUCCESS(status))
+ return NDIS_STATUS_INVALID_DATA;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+static NDIS_STATUS
+SetPacketFilter(PADAPTER Adapter, PULONG PacketFilter)
+{
+ XENVIF_MAC_FILTER_LEVEL UnicastFilterLevel;
+ XENVIF_MAC_FILTER_LEVEL MulticastFilterLevel;
+ XENVIF_MAC_FILTER_LEVEL BroadcastFilterLevel;
+
+ if (*PacketFilter & ~XENNET_SUPPORTED_PACKET_FILTERS)
+ return NDIS_STATUS_INVALID_PARAMETER;
+
+ if (*PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) {
+ UnicastFilterLevel = MAC_FILTER_ALL;
+ MulticastFilterLevel = MAC_FILTER_ALL;
+ BroadcastFilterLevel = MAC_FILTER_ALL;
+ goto done;
+ }
+
+ if (*PacketFilter & NDIS_PACKET_TYPE_DIRECTED)
+ UnicastFilterLevel = MAC_FILTER_MATCHING;
+ else
+ UnicastFilterLevel = MAC_FILTER_NONE;
+
+ if (*PacketFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
+ MulticastFilterLevel = MAC_FILTER_ALL;
+ else if (*PacketFilter & NDIS_PACKET_TYPE_MULTICAST)
+ MulticastFilterLevel = MAC_FILTER_MATCHING;
+ else
+ MulticastFilterLevel = MAC_FILTER_NONE;
+
+ if (*PacketFilter & NDIS_PACKET_TYPE_BROADCAST)
+ BroadcastFilterLevel = MAC_FILTER_ALL;
+ else
+ BroadcastFilterLevel = MAC_FILTER_NONE;
+
+done:
+ VIF(UpdateFilterLevel,
+ Adapter->VifInterface,
+ ETHERNET_ADDRESS_UNICAST,
+ UnicastFilterLevel);
+
+ VIF(UpdateFilterLevel,
+ Adapter->VifInterface,
+ ETHERNET_ADDRESS_MULTICAST,
+ MulticastFilterLevel);
+
+ VIF(UpdateFilterLevel,
+ Adapter->VifInterface,
+ ETHERNET_ADDRESS_BROADCAST,
+ BroadcastFilterLevel);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+//
+// Set OID handler.
+//
+static NDIS_STATUS
+AdapterSetInformation (
+ IN PADAPTER Adapter,
+ IN PNDIS_OID_REQUEST NdisRequest
+ )
+{
+ ULONG addressCount;
+ ULONG bytesNeeded = 0;
+ ULONG bytesRead = 0;
+ PVOID informationBuffer;
+ ULONG informationBufferLength;
+ NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
+ NDIS_OID oid;
+ BOOLEAN offloadChanged;
+
+ informationBuffer = NdisRequest->DATA.SET_INFORMATION.InformationBuffer;
+ informationBufferLength = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
+ oid = NdisRequest->DATA.QUERY_INFORMATION.Oid;
+ switch (oid) {
+ case OID_PNP_SET_POWER:
+ bytesNeeded = sizeof(NDIS_DEVICE_POWER_STATE);
+ if (informationBufferLength >= bytesNeeded) {
+ PNDIS_DEVICE_POWER_STATE state;
+
+ state = (PNDIS_DEVICE_POWER_STATE)informationBuffer;
+ switch (*state) {
+ case NdisDeviceStateD0:
+ Info("SET_POWER: D0\n");
+ break;
+
+ case NdisDeviceStateD1:
+ Info("SET_POWER: D1\n");
+ break;
+
+ case NdisDeviceStateD2:
+ Info("SET_POWER: D2\n");
+ break;
+
+ case NdisDeviceStateD3:
+ Info("SET_POWER: D3\n");
+ break;
+ }
+ }
+ break;
+
+ case OID_GEN_MACHINE_NAME:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+
+ case OID_GEN_CURRENT_LOOKAHEAD:
+ bytesNeeded = sizeof(ULONG);
+ Adapter->CurrentLookahead = Adapter->MaximumFrameSize;
+ if (informationBufferLength == sizeof(ULONG)) {
+ Adapter->CurrentLookahead = *(PULONG)informationBuffer;
+ bytesRead = sizeof(ULONG);
+ }
+
+ break;
+
+ case OID_GEN_CURRENT_PACKET_FILTER:
+ bytesNeeded = sizeof(ULONG);
+ if (informationBufferLength == sizeof(ULONG)) {
+ ndisStatus = SetPacketFilter(Adapter, (PULONG)informationBuffer);
+ bytesRead = sizeof(ULONG);
+ }
+
+ break;
+
+ case OID_802_3_MULTICAST_LIST:
+ bytesNeeded = ETHERNET_ADDRESS_LENGTH;
+ if (informationBufferLength % ETHERNET_ADDRESS_LENGTH == 0) {
+ addressCount = informationBufferLength / ETHERNET_ADDRESS_LENGTH;
+
+ ndisStatus = SetMulticastAddresses(Adapter, informationBuffer, addressCount);
+ if (ndisStatus == NDIS_STATUS_SUCCESS)
+ bytesRead = informationBufferLength;
+ } else {
+ ndisStatus = NDIS_STATUS_INVALID_LENGTH;
+ }
+
+ break;
+
+ case OID_GEN_INTERRUPT_MODERATION:
+ ndisStatus = NDIS_STATUS_INVALID_DATA;
+ break;
+
+ case OID_OFFLOAD_ENCAPSULATION: {
+ PNDIS_OFFLOAD_ENCAPSULATION offloadEncapsulation;
+
+ bytesNeeded = sizeof(*offloadEncapsulation);
+ if (informationBufferLength >= bytesNeeded) {
+ XENVIF_OFFLOAD_OPTIONS Options;
+
+ bytesRead = bytesNeeded;
+ offloadEncapsulation = informationBuffer;
+ ndisStatus = NDIS_STATUS_SUCCESS;
+
+ if (offloadEncapsulation->IPv4.Enabled == NDIS_OFFLOAD_SET_ON) {
+ if (offloadEncapsulation->IPv4.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+ }
+
+ if (offloadEncapsulation->IPv6.Enabled == NDIS_OFFLOAD_SET_ON) {
+ if (offloadEncapsulation->IPv6.EncapsulationType != NDIS_ENCAPSULATION_IEEE_802_3)
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+ }
+
+ VIF(QueryOffloadOptions,
+ Adapter->VifInterface,
+ &Options);
+
+ Adapter->Transmitter->OffloadOptions.Value = 0;
+ Adapter->Transmitter->OffloadOptions.OffloadTagManipulation = 1;
+
+ if ((Adapter->Properties.lsov4) && (Options.OffloadIpVersion4LargePacket))
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1;
+
+ if ((Adapter->Properties.lsov6) && (Options.OffloadIpVersion6LargePacket))
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1;
+
+ if ((Adapter->Properties.ipv4_csum & 1) && Options.OffloadIpVersion4HeaderChecksum)
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+
+ if ((Adapter->Properties.tcpv4_csum & 1) && Options.OffloadIpVersion4TcpChecksum)
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+
+ if ((Adapter->Properties.udpv4_csum & 1) && Options.OffloadIpVersion4UdpChecksum)
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+
+ if ((Adapter->Properties.tcpv6_csum & 1) && Options.OffloadIpVersion6TcpChecksum)
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+
+ if ((Adapter->Properties.udpv6_csum & 1) && Options.OffloadIpVersion6UdpChecksum)
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+
+ Adapter->Receiver.OffloadOptions.Value = 0;
+ Adapter->Receiver.OffloadOptions.OffloadTagManipulation = 1;
+
+ if (Adapter->Properties.need_csum_value)
+ Adapter->Receiver.OffloadOptions.NeedChecksumValue = 1;
+
+ if (Adapter->Properties.lrov4) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4LargePacket = 1;
+ Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
+ }
+
+ if (Adapter->Properties.lrov6) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6LargePacket = 1;
+ Adapter->Receiver.OffloadOptions.NeedLargePacketSplit = 1;
+ }
+
+ if (Adapter->Properties.ipv4_csum & 2)
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+
+ if (Adapter->Properties.tcpv4_csum & 2)
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+
+ if (Adapter->Properties.udpv4_csum & 2)
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+
+ if (Adapter->Properties.tcpv6_csum & 2)
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+
+ if (Adapter->Properties.udpv6_csum & 2)
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+
+ AdapterIndicateOffloadChanged(Adapter);
+ }
+ break;
+ }
+ case OID_TCP_OFFLOAD_PARAMETERS: {
+ PNDIS_OFFLOAD_PARAMETERS offloadParameters;
+
+ bytesNeeded = sizeof(*offloadParameters);
+ if (informationBufferLength >= bytesNeeded) {
+ bytesRead = bytesNeeded;
+ offloadParameters = informationBuffer;
+ ndisStatus = NDIS_STATUS_SUCCESS;
+
+#define no_change(x) ((x) == NDIS_OFFLOAD_PARAMETERS_NO_CHANGE)
+
+ if (!no_change(offloadParameters->IPsecV1))
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+
+ if (!no_change(offloadParameters->LsoV1))
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+
+ if (!no_change(offloadParameters->TcpConnectionIPv4))
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+
+ if (!no_change(offloadParameters->TcpConnectionIPv6))
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+
+ if (!no_change(offloadParameters->LsoV2IPv4)) {
+ XENVIF_OFFLOAD_OPTIONS Options;
+
+ VIF(QueryOffloadOptions,
+ Adapter->VifInterface,
+ &Options);
+
+ if (!(Options.OffloadIpVersion4LargePacket))
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+ }
+
+ if (!no_change(offloadParameters->LsoV2IPv6)) {
+ XENVIF_OFFLOAD_OPTIONS Options;
+
+ VIF(QueryOffloadOptions,
+ Adapter->VifInterface,
+ &Options);
+
+ if (!(Options.OffloadIpVersion6LargePacket))
+ ndisStatus = NDIS_STATUS_INVALID_PARAMETER;
+ }
+
+#define rx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \
+ (x) == NDIS_OFFLOAD_PARAMETERS_RX_ENABLED_TX_DISABLED)
+#define tx_enabled(x) ((x) == NDIS_OFFLOAD_PARAMETERS_TX_RX_ENABLED || \
+ (x) == NDIS_OFFLOAD_PARAMETERS_TX_ENABLED_RX_DISABLED)
+
+ if (ndisStatus == NDIS_STATUS_SUCCESS) {
+ offloadChanged = FALSE;
+
+ if (offloadParameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 1;
+ offloadChanged = TRUE;
+ }
+ } else if (offloadParameters->LsoV2IPv4 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4LargePacket = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (offloadParameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_ENABLED) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 1;
+ offloadChanged = TRUE;
+ }
+ } else if (offloadParameters->LsoV2IPv6 == NDIS_OFFLOAD_PARAMETERS_LSOV2_DISABLED) {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6LargePacket = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (tx_enabled(offloadParameters->IPv4Checksum)) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4HeaderChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (tx_enabled(offloadParameters->TCPIPv4Checksum)) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4TcpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (tx_enabled(offloadParameters->UDPIPv4Checksum)) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion4UdpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (tx_enabled(offloadParameters->TCPIPv6Checksum)) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6TcpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (tx_enabled(offloadParameters->UDPIPv6Checksum)) {
+ if (!Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum) {
+ Adapter->Transmitter->OffloadOptions.OffloadIpVersion6UdpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (rx_enabled(offloadParameters->IPv4Checksum)) {
+ if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4HeaderChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (rx_enabled(offloadParameters->TCPIPv4Checksum)) {
+ if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4TcpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (rx_enabled(offloadParameters->UDPIPv4Checksum)) {
+ if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion4UdpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (rx_enabled(offloadParameters->TCPIPv6Checksum)) {
+ if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6TcpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+ if (rx_enabled(offloadParameters->UDPIPv6Checksum)) {
+ if (!Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+ offloadChanged = TRUE;
+ }
+ } else {
+ if (Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum) {
+ Adapter->Receiver.OffloadOptions.OffloadIpVersion6UdpChecksum = 0;
+ offloadChanged = TRUE;
+ }
+ }
+
+#undef tx_enabled
+#undef rx_enabled
+#undef no_change
+
+ if (offloadChanged)
+ AdapterIndicateOffloadChanged(Adapter);
+ }
+ } else {
+ ndisStatus = NDIS_STATUS_INVALID_LENGTH;
+ }
+ break;
+ }
+ default:
+ ndisStatus = NDIS_STATUS_NOT_SUPPORTED;
+ break;
+ };
+
+ NdisRequest->DATA.SET_INFORMATION.BytesNeeded = bytesNeeded;
+ if (ndisStatus == NDIS_STATUS_SUCCESS) {
+ NdisRequest->DATA.SET_INFORMATION.BytesRead = bytesRead;
+ }
+
+ return ndisStatus;
+}
+
+//
+// Sets miniport registration attributes.
+//
+static NDIS_STATUS
+AdapterSetRegistrationAttributes (
+ IN PADAPTER Adapter
+ )
+{
+ PNDIS_MINIPORT_ADAPTER_ATTRIBUTES adapterAttributes;
+ NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES registrationAttributes;
+ NDIS_STATUS ndisStatus;
+
+
+ NdisZeroMemory(®istrationAttributes,
+ sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES));
+
+ registrationAttributes.Header.Type =
+ NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
+
+ registrationAttributes.Header.Revision =
+ NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
+
+ registrationAttributes.Header.Size =
+ sizeof(NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES);
+
+ registrationAttributes.MiniportAdapterContext = (NDIS_HANDLE)Adapter;
+ registrationAttributes.AttributeFlags = NDIS_MINIPORT_ATTRIBUTES_BUS_MASTER |
+ NDIS_MINIPORT_ATTRIBUTES_NO_HALT_ON_SUSPEND;
+
+ registrationAttributes.CheckForHangTimeInSeconds = 0;
+ registrationAttributes.InterfaceType = XENNET_INTERFACE_TYPE;
+
+ adapterAttributes =
+ (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)®istrationAttributes;
+
+ ndisStatus = NdisMSetMiniportAttributes(Adapter->NdisAdapterHandle,
+ adapterAttributes);
+
+ return ndisStatus;
+}
+
+//
+// Shuts down adapter.
+//
+VOID
+AdapterShutdown (
+ IN PADAPTER Adapter,
+ IN NDIS_SHUTDOWN_ACTION ShutdownAction
+ )
+{
+ UNREFERENCED_PARAMETER(ShutdownAction);
+
+ if (ShutdownAction != NdisShutdownBugCheck)
+ AdapterStop(Adapter);
+
+ return;
+}
+
+//
+// Stops adapter. Waits for currently transmitted packets to complete.
+// Stops transmission of new packets.
+// Stops received packet indication to NDIS.
+//
+static NDIS_STATUS
+AdapterStop (
+IN PADAPTER Adapter
+)
+{
+ Trace("====>\n");
+
+ if (!Adapter->Enabled)
+ goto done;
+
+ VIF(Disable,
+ Adapter->VifInterface);
+
+ Adapter->Enabled = FALSE;
+
+done:
+ Trace("<====\n");
+ return NDIS_STATUS_SUCCESS;
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#define XENNET_INTERFACE_TYPE NdisInterfaceInternal
+
+#define XENNET_MEDIA_TYPE NdisMedium802_3
+
+#define XENNET_MAC_OPTIONS (NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA | \
+ NDIS_MAC_OPTION_TRANSFERS_NOT_PEND | \
+ NDIS_MAC_OPTION_NO_LOOPBACK | \
+ NDIS_MAC_OPTION_8021P_PRIORITY | \
+ NDIS_MAC_OPTION_SUPPORTS_MAC_ADDRESS_OVERWRITE)
+
+typedef struct _PROPERTIES {
+ int ipv4_csum;
+ int tcpv4_csum;
+ int udpv4_csum;
+ int tcpv6_csum;
+ int udpv6_csum;
+ int need_csum_value;
+ int lsov4;
+ int lsov6;
+ int lrov4;
+ int lrov6;
+} PROPERTIES, *PPROPERTIES;
+
+struct _ADAPTER {
+ LIST_ENTRY ListEntry;
+ PXENVIF_VIF_INTERFACE VifInterface;
+ BOOLEAN AcquiredInterfaces;
+ ULONG MaximumFrameSize;
+ ULONG CurrentLookahead;
+ NDIS_HANDLE NdisAdapterHandle;
+ NDIS_HANDLE NdisDmaHandle;
+ NDIS_PNP_CAPABILITIES Capabilities;
+ PROPERTIES Properties;
+ RECEIVER Receiver;
+ PTRANSMITTER Transmitter;
+ BOOLEAN Enabled;
+ NDIS_OFFLOAD Offload;
+};
+
+VOID
+AdapterCancelOidRequest (
+ IN PADAPTER Adapter,
+ IN PVOID RequestId
+ );
+
+VOID
+AdapterCancelSendNetBufferLists (
+ IN PADAPTER Adapter,
+ IN PVOID CancelId
+ );
+
+BOOLEAN
+AdapterCheckForHang (
+ IN PADAPTER Adapter
+ );
+
+VOID
+AdapterDelete (
+ IN OUT PADAPTER* Adapter
+ );
+
+VOID
+AdapterHalt (
+ IN PADAPTER Adapter,
+ IN NDIS_HALT_ACTION HaltAction
+ );
+
+NDIS_STATUS
+AdapterInitialize (
+ IN PADAPTER Adapter,
+ IN NDIS_HANDLE AdapterHandle
+ );
+
+NDIS_STATUS
+AdapterOidRequest (
+ IN PADAPTER Adapter,
+ IN PNDIS_OID_REQUEST NdisRequest
+ );
+
+NDIS_STATUS
+AdapterPause (
+ IN PADAPTER Adapter,
+ IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters
+ );
+
+VOID
+AdapterPnPEventHandler (
+ IN PADAPTER Adapter,
+ IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent
+ );
+
+NDIS_STATUS
+AdapterReset (
+ IN NDIS_HANDLE MiniportAdapterContext,
+ OUT PBOOLEAN AddressingReset
+ );
+
+NDIS_STATUS
+AdapterRestart (
+ IN PADAPTER Adapter,
+ IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters
+ );
+
+VOID
+AdapterReturnNetBufferLists (
+ IN PADAPTER Adapter,
+ IN PNET_BUFFER_LIST NetBufferLists,
+ IN ULONG ReturnFlags
+ );
+
+VOID
+AdapterSendNetBufferLists (
+ IN PADAPTER Adapter,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN ULONG SendFlags
+ );
+
+VOID
+AdapterShutdown (
+ IN PADAPTER Adapter,
+ IN NDIS_SHUTDOWN_ACTION ShutdownAction
+ );
+
+extern VOID
+ReceiverReceivePackets(
+ IN PRECEIVER Receiver,
+ IN PLIST_ENTRY List
+ );
+
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENNET_ASSERT_H
+#define _XENNET_ASSERT_H
+
+#include <ntddk.h>
+
+#include "log.h"
+
+static FORCEINLINE VOID
+__BugCheck(
+ IN ULONG Code,
+ IN ULONG_PTR Parameter1,
+ IN ULONG_PTR Parameter2,
+ IN ULONG_PTR Parameter3,
+ IN ULONG_PTR Parameter4
+ )
+{
+#pragma prefast(suppress:28159)
+ KeBugCheckEx(Code,
+ Parameter1,
+ Parameter2,
+ Parameter3,
+ Parameter4);
+}
+
+#define ASSERTION_FAILURE 0x0000DEAD
+
+#define BUG(_TEXT) \
+ do { \
+ const CHAR *_Text = (_TEXT); \
+ const CHAR *_File = __FILE__; \
+ ULONG _Line = __LINE__; \
+ \
+ Error("BUG: " _TEXT "\n"); \
+ __BugCheck(ASSERTION_FAILURE, \
+ (ULONG_PTR)_Text, \
+ (ULONG_PTR)_File, \
+ (ULONG_PTR)_Line, \
+ 0); \
+ } while (FALSE)
+
+#define BUG_ON(_EXP) \
+ if (_EXP) BUG(#_EXP)
+
+#if DBG
+
+#define __NT_ASSERT(_EXP) \
+ ((!(_EXP)) ? \
+ (Error("ASSERTION FAILED: " #_EXP "\n"), \
+ __annotation(L"Debug", L"AssertFail", L#_EXP), \
+ DbgRaiseAssertionFailure(), FALSE) : \
+ TRUE)
+
+#define __ASSERT(_EXP) __NT_ASSERT(_EXP)
+
+#else // DBG
+
+#define __ASSERT(_EXP) BUG_ON(!(_EXP))
+
+#endif // DBG
+
+#undef ASSERT
+
+#define ASSERT(_EXP) \
+ do { \
+ __ASSERT(_EXP); \
+ } while (FALSE)
+
+#define ASSERT3U(_X, _OP, _Y) \
+ do { \
+ ULONGLONG _Lval = (ULONGLONG)(_X); \
+ ULONGLONG _Rval = (ULONGLONG)(_Y); \
+ if (!(_Lval _OP _Rval)) { \
+ Error("%s = %llu\n", #_X, _Lval); \
+ Error("%s = %llu\n", #_Y, _Rval); \
+ ASSERT(_X _OP _Y); \
+ } \
+ } while (FALSE)
+
+#define ASSERT3S(_X, _OP, _Y) \
+ do { \
+ LONGLONG _Lval = (LONGLONG)(_X); \
+ LONGLONG _Rval = (LONGLONG)(_Y); \
+ if (!(_Lval _OP _Rval)) { \
+ Error("%s = %lld\n", #_X, _Lval); \
+ Error("%s = %lld\n", #_Y, _Rval); \
+ ASSERT(_X _OP _Y); \
+ } \
+ } while (FALSE)
+
+#define ASSERT3P(_X, _OP, _Y) \
+ do { \
+ PVOID _Lval = (PVOID)(_X); \
+ PVOID _Rval = (PVOID)(_Y); \
+ if (!(_Lval _OP _Rval)) { \
+ Error("%s = %p\n", #_X, _Lval); \
+ Error("%s = %p\n", #_Y, _Rval); \
+ ASSERT(_X _OP _Y); \
+ } \
+ } while (FALSE)
+
+#ifndef TEST_MEMORY
+#define TEST_MEMORY DBG
+#endif
+
+#if TEST_MEMORY
+
+static __inline BOOLEAN
+_IsZeroMemory(
+ IN const PCHAR Caller,
+ IN const PCHAR Name,
+ IN PVOID Buffer,
+ IN ULONG Length
+ )
+{
+ ULONG Offset;
+
+ Offset = 0;
+ while (Offset < Length) {
+ if (*((PUCHAR)Buffer + Offset) != 0) {
+ Error("%s: non-zero byte in %s (0x%p+0x%x)\n", Caller, Name, Buffer, Offset);
+ return FALSE;
+ }
+ Offset++;
+ }
+
+ return TRUE;
+}
+
+#define IsZeroMemory(_Buffer, _Length) \
+ _IsZeroMemory(__FUNCTION__, #_Buffer, (_Buffer), (_Length))
+
+#else // TEST_MEMORY
+
+#define IsZeroMemory(_Buffer, _Length) TRUE
+
+#endif // TEST_MEMORY
+
+#define IMPLY(_X, _Y) (!(_X) || (_Y))
+#define EQUIV(_X, _Y) (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
+
+#endif // _XENNET_ASSERT_H
+
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#pragma once
+
+#include "std.h"
+#include "project.h"
+#include "log.h"
+#include "assert.h"
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _XENNET_LOG_H
+#define _XENNET_LOG_H
+
+#include <stdarg.h>
+
+#pragma warning(disable:4127) // conditional expression is constant
+
+static __inline VOID
+__Error(
+ IN const CHAR *Prefix,
+ IN const CHAR *Format,
+ ...
+ )
+{
+ va_list Arguments;
+
+ va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+ vDbgPrintExWithPrefix(Prefix,
+ DPFLTR_IHVDRIVER_ID,
+ DPFLTR_ERROR_LEVEL,
+ Format,
+ Arguments);
+ va_end(Arguments);
+}
+
+#define Error(...) \
+ __Error(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+static __inline VOID
+__Warning(
+ IN const CHAR *Prefix,
+ IN const CHAR *Format,
+ ...
+ )
+{
+ va_list Arguments;
+
+ va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+ vDbgPrintExWithPrefix(Prefix,
+ DPFLTR_IHVDRIVER_ID,
+ DPFLTR_WARNING_LEVEL,
+ Format,
+ Arguments);
+ va_end(Arguments);
+}
+
+#define Warning(...) \
+ __Warning(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+#if DBG
+static __inline VOID
+__Trace(
+ IN const CHAR *Prefix,
+ IN const CHAR *Format,
+ ...
+ )
+{
+ va_list Arguments;
+
+ va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+ vDbgPrintExWithPrefix(Prefix,
+ DPFLTR_IHVDRIVER_ID,
+ DPFLTR_TRACE_LEVEL,
+ Format,
+ Arguments);
+ va_end(Arguments);
+}
+
+#define Trace(...) \
+ __Trace(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+#else // DBG
+#define Trace(...) (VOID)(__VA_ARGS__)
+#endif // DBG
+
+static __inline VOID
+__Info(
+ IN const CHAR *Prefix,
+ IN const CHAR *Format,
+ ...
+ )
+{
+ va_list Arguments;
+
+ va_start(Arguments, Format);
+
+#pragma prefast(suppress:6001) // Using uninitialized memory
+ vDbgPrintExWithPrefix(Prefix,
+ DPFLTR_IHVDRIVER_ID,
+ DPFLTR_INFO_LEVEL,
+ Format,
+ Arguments);
+ va_end(Arguments);
+}
+
+#define Info(...) \
+ __Info(__MODULE__ "|" __FUNCTION__ ": ", __VA_ARGS__)
+
+#endif // _XENNET_LOG_H
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <version.h>
+
+#include "common.h"
+
+#pragma NDIS_INIT_FUNCTION(DriverEntry)
+
+//
+// Global miniport data.
+//
+
+static NDIS_HANDLE MiniportDriverHandle;
+
+extern NDIS_STATUS
+MiniportInitialize (
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE MiniportDriverContext,
+ IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters
+ );
+
+typedef struct _XENNET_CONTEXT {
+ PDEVICE_CAPABILITIES Capabilities;
+ PIO_COMPLETION_ROUTINE CompletionRoutine;
+ PVOID CompletionContext;
+ UCHAR CompletionControl;
+} XENNET_CONTEXT, *PXENNET_CONTEXT;
+
+static NTSTATUS (*NdisDispatchPnp)(PDEVICE_OBJECT, PIRP);
+
+static NTSTATUS
+__QueryCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp,
+ IN PVOID _Context
+ )
+{
+ PXENNET_CONTEXT Context = _Context;
+ NTSTATUS status;
+
+ Trace("====>\n");
+
+ Context->Capabilities->SurpriseRemovalOK = 1;
+
+ if (Context->CompletionRoutine != NULL &&
+ (Context->CompletionControl & SL_INVOKE_ON_SUCCESS))
+ status = Context->CompletionRoutine(DeviceObject, Irp, Context->CompletionContext);
+ else
+ status = STATUS_SUCCESS;
+
+ ExFreePool(Context);
+
+ Trace("<====\n");
+
+ return status;
+}
+
+NTSTATUS
+QueryCapabilities(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ PXENNET_CONTEXT Context;
+ NTSTATUS status;
+
+ Trace("====>\n");
+
+ Trace("%p\n", DeviceObject);
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+
+ Context = ExAllocatePoolWithTag(NonPagedPool, sizeof (XENNET_CONTEXT), ' TEN');
+ if (Context != NULL) {
+ Context->Capabilities = StackLocation->Parameters.DeviceCapabilities.Capabilities;
+ Context->CompletionRoutine = StackLocation->CompletionRoutine;
+ Context->CompletionContext = StackLocation->Context;
+ Context->CompletionControl = StackLocation->Control;
+
+ StackLocation->CompletionRoutine = __QueryCapabilities;
+ StackLocation->Context = Context;
+ StackLocation->Control = SL_INVOKE_ON_SUCCESS;
+ }
+
+ status = NdisDispatchPnp(DeviceObject, Irp);
+
+ Trace("<====\n");
+
+ return status;
+}
+
+NTSTATUS
+DispatchPnp(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ PIO_STACK_LOCATION StackLocation;
+ UCHAR MinorFunction;
+ NTSTATUS status;
+
+ StackLocation = IoGetCurrentIrpStackLocation(Irp);
+ MinorFunction = StackLocation->MinorFunction;
+
+ switch (StackLocation->MinorFunction) {
+ case IRP_MN_QUERY_CAPABILITIES:
+ status = QueryCapabilities(DeviceObject, Irp);
+ break;
+
+ default:
+ status = NdisDispatchPnp(DeviceObject, Irp);
+ break;
+ }
+
+ return status;
+}
+
+NTSTATUS
+DispatchFail(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp
+ )
+{
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(DeviceObject);
+
+ Trace("%p\n", Irp);
+
+ status = STATUS_UNSUCCESSFUL;
+
+ Irp->IoStatus.Status = status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return status;
+}
+
+NTSTATUS
+DriverEntry (
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+{
+ NDIS_STATUS ndisStatus;
+ NDIS_MINIPORT_DRIVER_CHARACTERISTICS mpChars;
+ NDIS_CONFIGURATION_OBJECT ConfigurationObject;
+ NDIS_HANDLE ConfigurationHandle;
+ NDIS_STRING ParameterName;
+ PNDIS_CONFIGURATION_PARAMETER ParameterValue;
+ ULONG FailCreateClose;
+ ULONG FailDeviceControl;
+
+ 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;
+
+ //
+ // Register miniport with NDIS.
+ //
+
+ NdisZeroMemory(&mpChars, sizeof(mpChars));
+ mpChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS,
+ mpChars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
+ mpChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
+
+ mpChars.MajorNdisVersion = 6;
+ mpChars.MinorNdisVersion = 0;
+ mpChars.MajorDriverVersion = MAJOR_VERSION;
+ mpChars.MinorDriverVersion = MINOR_VERSION;
+
+ mpChars.CancelOidRequestHandler = AdapterCancelOidRequest;
+ mpChars.CancelSendHandler = AdapterCancelSendNetBufferLists;
+ mpChars.CheckForHangHandlerEx = AdapterCheckForHang;
+ mpChars.InitializeHandlerEx = MiniportInitialize;
+ mpChars.HaltHandlerEx = AdapterHalt;
+ mpChars.OidRequestHandler = AdapterOidRequest;
+ mpChars.PauseHandler = AdapterPause;
+ mpChars.DevicePnPEventNotifyHandler = AdapterPnPEventHandler;
+ mpChars.ResetHandlerEx = AdapterReset;
+ mpChars.RestartHandler = AdapterRestart;
+ mpChars.ReturnNetBufferListsHandler = AdapterReturnNetBufferLists;
+ mpChars.SendNetBufferListsHandler = AdapterSendNetBufferLists;
+ mpChars.ShutdownHandlerEx = AdapterShutdown;
+ mpChars.UnloadHandler = DriverUnload;
+
+ MiniportDriverHandle = NULL;
+ ndisStatus = NdisMRegisterMiniportDriver(DriverObject,
+ RegistryPath,
+ NULL,
+ &mpChars,
+ &MiniportDriverHandle);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ Error("Failed (0x%08X) to register miniport.\n", ndisStatus);
+ goto fail;
+ }
+
+ ConfigurationObject.Header.Type = NDIS_OBJECT_TYPE_CONFIGURATION_OBJECT;
+ ConfigurationObject.Header.Revision = NDIS_CONFIGURATION_OBJECT_REVISION_1;
+ ConfigurationObject.Header.Size = NDIS_SIZEOF_CONFIGURATION_OBJECT_REVISION_1;
+ ConfigurationObject.NdisHandle = MiniportDriverHandle;
+ ConfigurationObject.Flags = 0;
+
+ ndisStatus = NdisOpenConfigurationEx(&ConfigurationObject, &ConfigurationHandle);
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ Error("Failed (0x%08X) to open driver configuration.\n", ndisStatus);
+ NdisMDeregisterMiniportDriver(MiniportDriverHandle);
+ goto fail;
+ }
+
+ RtlInitUnicodeString(&ParameterName, L"FailCreateClose");
+
+ NdisReadConfiguration(&ndisStatus,
+ &ParameterValue,
+ ConfigurationHandle,
+ &ParameterName,
+ NdisParameterInteger);
+ if (ndisStatus == NDIS_STATUS_SUCCESS &&
+ ParameterValue->ParameterType == NdisParameterInteger)
+ FailCreateClose = ParameterValue->ParameterData.IntegerData;
+ else
+ FailCreateClose = 0;
+
+ RtlInitUnicodeString(&ParameterName, L"FailDeviceControl");
+
+ NdisReadConfiguration(&ndisStatus,
+ &ParameterValue,
+ ConfigurationHandle,
+ &ParameterName,
+ NdisParameterInteger);
+ if (ndisStatus == NDIS_STATUS_SUCCESS &&
+ ParameterValue->ParameterType == NdisParameterInteger)
+ FailDeviceControl = ParameterValue->ParameterData.IntegerData;
+ else
+ FailDeviceControl = 0;
+
+ NdisCloseConfiguration(ConfigurationHandle);
+ ndisStatus = NDIS_STATUS_SUCCESS;
+
+ NdisDispatchPnp = DriverObject->MajorFunction[IRP_MJ_PNP];
+ DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp;
+
+ if (FailCreateClose != 0) {
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchFail;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchFail;
+ }
+
+ if (FailDeviceControl != 0) {
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchFail;
+ }
+
+fail:
+ Trace("<====\n");
+ return ndisStatus;
+}
+
+VOID
+DriverUnload (
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ UNREFERENCED_PARAMETER(DriverObject);
+
+ Trace("====>\n");
+
+ if (MiniportDriverHandle)
+ NdisMDeregisterMiniportDriver(MiniportDriverHandle);
+
+ Trace("<====\n");
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define INITGUID 1
+
+#include "common.h"
+
+#pragma warning( disable : 4098 )
+
+static NTSTATUS
+QueryVifInterface(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PADAPTER Adapter
+ )
+{
+ KEVENT Event;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ INTERFACE Interface;
+ NTSTATUS status;
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ DeviceObject,
+ NULL,
+ 0,
+ NULL,
+ &Event,
+ &StatusBlock);
+
+ status = STATUS_UNSUCCESSFUL;
+ if (Irp == NULL)
+ goto fail1;
+
+ 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;
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(DeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Interface.Version != VIF_INTERFACE_VERSION)
+ goto fail3;
+
+ Adapter->VifInterface = Interface.Context;
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+fail2:
+ Error("fail2\n");
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+NDIS_STATUS
+MiniportInitialize (
+ IN NDIS_HANDLE MiniportAdapterHandle,
+ IN NDIS_HANDLE MiniportDriverContext,
+ IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters
+ )
+{
+ PADAPTER adapter = NULL;
+ NDIS_STATUS ndisStatus;
+ PDEVICE_OBJECT pdo;
+ NTSTATUS status;
+
+ UNREFERENCED_PARAMETER(MiniportDriverContext);
+ UNREFERENCED_PARAMETER(MiniportInitParameters);
+
+ Trace("====>\n");
+
+ adapter = ExAllocatePoolWithTag(NonPagedPool, sizeof (ADAPTER), ' TEN');
+
+ if (adapter == NULL) {
+ ndisStatus = NDIS_STATUS_RESOURCES;
+ goto exit;
+ }
+
+ RtlZeroMemory(adapter, sizeof (ADAPTER));
+
+ pdo = NULL;
+ NdisMGetDeviceProperty(MiniportAdapterHandle,
+ &pdo,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ status = QueryVifInterface(pdo, adapter);
+ 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;
+ }
+
+exit:
+ if (ndisStatus != NDIS_STATUS_SUCCESS) {
+ if (adapter != NULL) {
+ AdapterDelete(&adapter);
+ }
+ }
+
+ Trace("<====\n");
+ return ndisStatus;
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <util.h>
+#include <ethernet.h>
+#include <tcpip.h>
+#include <vif_interface.h>
+
+typedef struct _ADAPTER ADAPTER, *PADAPTER;
+
+NTSTATUS
+DriverEntry (
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ );
+
+VOID
+DriverUnload (
+ IN PDRIVER_OBJECT DriverObject
+ );
+
+NDIS_STATUS
+MpSetAdapterSettings(
+ IN PADAPTER Adapter
+ );
+
+NDIS_STATUS
+MpGetAdvancedSettings(
+ IN PADAPTER Adapter
+ );
+
+#include "transmitter.h"
+#include "receiver.h"
+#include "adapter.h"
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "common.h"
+
+#pragma warning(disable:4711)
+
+NDIS_STATUS
+ReceiverInitialize (
+ IN PRECEIVER Receiver
+ )
+{
+ PADAPTER Adapter;
+ NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
+ NET_BUFFER_LIST_POOL_PARAMETERS poolParameters;
+ ULONG Cpu;
+
+ Receiver->PutList = NULL;
+ for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++)
+ Receiver->GetList[Cpu] = NULL;
+
+ Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+
+ NdisZeroMemory(&poolParameters, sizeof(NET_BUFFER_LIST_POOL_PARAMETERS));
+ poolParameters.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
+ poolParameters.Header.Revision =
+ NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
+ poolParameters.Header.Size = sizeof(poolParameters);
+ poolParameters.ProtocolId = 0;
+ poolParameters.ContextSize = 0;
+ poolParameters.fAllocateNetBuffer = TRUE;
+ poolParameters.PoolTag = ' TEN';
+
+ Receiver->NetBufferListPool =
+ NdisAllocateNetBufferListPool(Adapter->NdisAdapterHandle,
+ &poolParameters);
+
+ if (!Receiver->NetBufferListPool)
+ ndisStatus = NDIS_STATUS_RESOURCES;
+
+ return ndisStatus;
+}
+
+VOID
+ReceiverCleanup (
+ IN PRECEIVER Receiver
+ )
+{
+ ULONG Cpu;
+ PNET_BUFFER_LIST NetBufferList;
+
+ ASSERT(Receiver != NULL);
+
+ for (Cpu = 0; Cpu < MAXIMUM_PROCESSORS; Cpu++) {
+ NetBufferList = Receiver->GetList[Cpu];
+ while (NetBufferList != NULL) {
+ PNET_BUFFER_LIST Next;
+
+ Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+ NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+ NdisFreeNetBufferList(NetBufferList);
+
+ NetBufferList = Next;
+ }
+ }
+
+ NetBufferList = Receiver->PutList;
+ while (NetBufferList != NULL) {
+ PNET_BUFFER_LIST Next;
+
+ Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+ NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+ NdisFreeNetBufferList(NetBufferList);
+
+ NetBufferList = Next;
+ }
+
+ if (Receiver->NetBufferListPool) {
+ NdisFreeNetBufferListPool(Receiver->NetBufferListPool);
+ Receiver->NetBufferListPool = NULL;
+ }
+
+ return;
+}
+
+PNET_BUFFER_LIST
+ReceiverAllocateNetBufferList(
+ IN PRECEIVER Receiver,
+ IN PMDL Mdl,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ ULONG Cpu;
+ PNET_BUFFER_LIST NetBufferList;
+
+ Cpu = KeGetCurrentProcessorNumber();
+
+ NetBufferList = Receiver->GetList[Cpu];
+
+ if (NetBufferList == NULL)
+ Receiver->GetList[Cpu] = InterlockedExchangePointer(&Receiver->PutList, NULL);
+
+ NetBufferList = Receiver->GetList[Cpu];
+
+ if (NetBufferList != NULL) {
+ PNET_BUFFER NetBuffer;
+
+ Receiver->GetList[Cpu] = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+ NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+ NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
+ NET_BUFFER_FIRST_MDL(NetBuffer) = Mdl;
+ NET_BUFFER_CURRENT_MDL(NetBuffer) = Mdl;
+ NET_BUFFER_DATA_OFFSET(NetBuffer) = Offset;
+ NET_BUFFER_DATA_LENGTH(NetBuffer) = Length;
+ NET_BUFFER_CURRENT_MDL_OFFSET(NetBuffer) = Offset;
+ } else {
+ NetBufferList = NdisAllocateNetBufferAndNetBufferList(Receiver->NetBufferListPool,
+ 0,
+ 0,
+ Mdl,
+ Offset,
+ Length);
+ ASSERT(IMPLY(NetBufferList != NULL, NET_BUFFER_LIST_NEXT_NBL(NetBufferList) == NULL));
+ }
+
+ return NetBufferList;
+}
+
+VOID
+ReceiverReleaseNetBufferList(
+ IN PRECEIVER Receiver,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN BOOLEAN Cache
+ )
+{
+ if (Cache) {
+ PNET_BUFFER_LIST Old;
+ PNET_BUFFER_LIST New;
+
+ ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
+
+ do {
+ Old = Receiver->PutList;
+
+ NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = Old;
+ New = NetBufferList;
+ } while (InterlockedCompareExchangePointer(&Receiver->PutList, New, Old) != Old);
+ } else {
+ NdisFreeNetBufferList(NetBufferList);
+ }
+}
+
+static FORCEINLINE ULONG
+__ReceiverReturnNetBufferLists(
+ IN PRECEIVER Receiver,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN BOOLEAN Cache
+ )
+{
+ PADAPTER Adapter;
+ ULONG Count;
+
+ Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+
+ Count = 0;
+ while (NetBufferList != NULL) {
+ PNET_BUFFER_LIST Next;
+ PNET_BUFFER NetBuffer;
+ PMDL Mdl;
+ PXENVIF_RECEIVER_PACKET Packet;
+
+ Next = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+ NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+ NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
+ ASSERT3P(NET_BUFFER_NEXT_NB(NetBuffer), ==, NULL);
+
+ Mdl = NET_BUFFER_FIRST_MDL(NetBuffer);
+
+ ReceiverReleaseNetBufferList(Receiver, NetBufferList, Cache);
+
+ Packet = CONTAINING_RECORD(Mdl, XENVIF_RECEIVER_PACKET, Mdl);
+
+ VIF(ReturnPacket,
+ Adapter->VifInterface,
+ Packet);
+
+ Count++;
+ NetBufferList = Next;
+ }
+
+ return Count;
+}
+
+VOID
+ReceiverReturnNetBufferLists(
+ IN PRECEIVER Receiver,
+ IN PNET_BUFFER_LIST HeadNetBufferList,
+ IN ULONG Flags
+ )
+{
+ ULONG Count;
+
+ UNREFERENCED_PARAMETER(Flags);
+
+ Count = __ReceiverReturnNetBufferLists(Receiver, HeadNetBufferList, TRUE);
+ (VOID) __InterlockedSubtract(&Receiver->InNDIS, Count);
+}
+
+static PNET_BUFFER_LIST
+ReceiverReceivePacket(
+ IN PRECEIVER Receiver,
+ IN PMDL Mdl,
+ IN ULONG Offset,
+ IN ULONG Length,
+ IN XENVIF_CHECKSUM_FLAGS Flags,
+ IN USHORT TagControlInformation
+ )
+{
+ PADAPTER Adapter;
+ PNET_BUFFER_LIST NetBufferList;
+ NDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO csumInfo;
+
+ Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+
+ NetBufferList = ReceiverAllocateNetBufferList(Receiver,
+ Mdl,
+ Offset,
+ Length);
+ if (NetBufferList == NULL)
+ goto fail1;
+
+ NetBufferList->SourceHandle = Adapter->NdisAdapterHandle;
+
+ csumInfo.Value = 0;
+
+ csumInfo.Receive.IpChecksumSucceeded = Flags.IpChecksumSucceeded;
+ csumInfo.Receive.IpChecksumFailed = Flags.IpChecksumFailed;
+
+ csumInfo.Receive.TcpChecksumSucceeded = Flags.TcpChecksumSucceeded;
+ csumInfo.Receive.TcpChecksumFailed = Flags.TcpChecksumFailed;
+
+ csumInfo.Receive.UdpChecksumSucceeded = Flags.UdpChecksumSucceeded;
+ csumInfo.Receive.UdpChecksumFailed = Flags.UdpChecksumFailed;
+
+ NET_BUFFER_LIST_INFO(NetBufferList, TcpIpChecksumNetBufferListInfo) = (PVOID)(ULONG_PTR)csumInfo.Value;
+
+ if (TagControlInformation != 0) {
+ NDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo;
+
+ UNPACK_TAG_CONTROL_INFORMATION(TagControlInformation,
+ Ieee8021QInfo.TagHeader.UserPriority,
+ Ieee8021QInfo.TagHeader.CanonicalFormatId,
+ Ieee8021QInfo.TagHeader.VlanId);
+
+ if (Ieee8021QInfo.TagHeader.VlanId != 0)
+ goto fail2;
+
+ NET_BUFFER_LIST_INFO(NetBufferList, Ieee8021QNetBufferListInfo) = Ieee8021QInfo.Value;
+ }
+
+ return NetBufferList;
+
+fail2:
+ ReceiverReleaseNetBufferList(Receiver, NetBufferList, TRUE);
+
+fail1:
+ return NULL;
+}
+
+static VOID
+ReceiverPushPackets(
+ IN PRECEIVER Receiver,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN ULONG Count,
+ IN BOOLEAN LowResources
+ )
+{
+ PADAPTER Adapter;
+ ULONG Flags;
+ LONG InNDIS;
+
+ Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+
+ InNDIS = Receiver->InNDIS;
+
+ Flags = NDIS_RECEIVE_FLAGS_DISPATCH_LEVEL;
+ if (LowResources) {
+ Flags |= NDIS_RECEIVE_FLAGS_RESOURCES;
+ } else {
+ InNDIS = __InterlockedAdd(&Receiver->InNDIS, Count);
+ }
+
+ for (;;) {
+ LONG InNDISMax;
+
+ InNDISMax = Receiver->InNDISMax;
+ KeMemoryBarrier();
+
+ if (InNDIS <= InNDISMax)
+ break;
+
+ if (InterlockedCompareExchange(&Receiver->InNDISMax, InNDIS, InNDISMax) == InNDISMax)
+ break;
+ }
+
+ NdisMIndicateReceiveNetBufferLists(Adapter->NdisAdapterHandle,
+ NetBufferList,
+ NDIS_DEFAULT_PORT_NUMBER,
+ Count,
+ Flags);
+
+ if (LowResources)
+ (VOID) __ReceiverReturnNetBufferLists(Receiver, NetBufferList, FALSE);
+}
+
+#define IN_NDIS_MAX 1024
+
+VOID
+ReceiverReceivePackets(
+ IN PRECEIVER Receiver,
+ IN PLIST_ENTRY List
+ )
+{
+ PADAPTER Adapter;
+ PNET_BUFFER_LIST HeadNetBufferList;
+ PNET_BUFFER_LIST *TailNetBufferList;
+ ULONG Count;
+ BOOLEAN LowResources;
+
+ Adapter = CONTAINING_RECORD(Receiver, ADAPTER, Receiver);
+ LowResources = FALSE;
+
+again:
+ HeadNetBufferList = NULL;
+ TailNetBufferList = &HeadNetBufferList;
+ Count = 0;
+
+ while (!IsListEmpty(List)) {
+ PLIST_ENTRY ListEntry;
+ PXENVIF_RECEIVER_PACKET Packet;
+ PMDL Mdl;
+ ULONG Offset;
+ ULONG Length;
+ XENVIF_CHECKSUM_FLAGS Flags;
+ USHORT TagControlInformation;
+ PNET_BUFFER_LIST NetBufferList;
+
+ if (!LowResources &&
+ Receiver->InNDIS + Count > IN_NDIS_MAX)
+ break;
+
+ ListEntry = RemoveHeadList(List);
+ ASSERT(ListEntry != List);
+
+ RtlZeroMemory(ListEntry, sizeof (LIST_ENTRY));
+
+ Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, ListEntry);
+ Mdl = &Packet->Mdl;
+ Offset = Packet->Offset;
+ Length = Packet->Length;
+ Flags = Packet->Flags;
+ TagControlInformation = Packet->TagControlInformation;
+
+ NetBufferList = ReceiverReceivePacket(Receiver, Mdl, Offset, Length, Flags, TagControlInformation);
+
+ if (NetBufferList != NULL) {
+ *TailNetBufferList = NetBufferList;
+ TailNetBufferList = &NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+ Count++;
+ } else {
+ VIF(ReturnPacket,
+ Adapter->VifInterface,
+ Packet);
+ }
+ }
+
+ if (Count != 0) {
+ ASSERT(HeadNetBufferList != NULL);
+
+ ReceiverPushPackets(Receiver, HeadNetBufferList, Count, LowResources);
+ }
+
+ if (!IsListEmpty(List)) {
+ ASSERT(!LowResources);
+ LowResources = TRUE;
+ goto again;
+ }
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#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;
+} RECEIVER, *PRECEIVER;
+
+VOID
+ReceiverDebugDump (
+ IN PRECEIVER Receiver
+ );
+
+VOID
+ReceiverCleanup (
+ IN PRECEIVER Receiver
+ );
+
+VOID
+ReceiverHandleNotification (
+ IN PRECEIVER Receiver
+ );
+
+NDIS_STATUS
+ReceiverInitialize (
+ IN PRECEIVER Receiver
+ );
+
+VOID
+ReceiverReturnNetBufferLists (
+ IN PRECEIVER Receiver,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN ULONG ReturnFlags
+ );
+
+VOID
+ReceiverWaitForPacketReturn(
+ IN PRECEIVER Receiver,
+ IN BOOLEAN Locked
+ );
+
+void ReceiverPause(PRECEIVER receiver);
+void ReceiverUnpause(PRECEIVER receiver);
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+#pragma warning(disable:4214) // bit field types other than int
+
+#pragma warning(disable:4201) // nameless struct/union
+#pragma warning(disable:4115) // named type definition in parentheses
+#pragma warning(disable:4127) // conditional expression is constant
+#pragma warning(disable:4054) // cast of function pointer to PVOID
+#pragma warning(disable:4206) // translation unit is empty
+
+#include <ndis.h>
+#include <ntstrsafe.h>
+
+extern PULONG InitSafeBootMode;
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "common.h"
+
+#pragma warning(disable:4711)
+
+NDIS_STATUS
+TransmitterInitialize(
+ IN PTRANSMITTER Transmitter,
+ IN PADAPTER Adapter
+ )
+{
+ Transmitter->Adapter = Adapter;
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+VOID
+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);
+}
+
+VOID
+TransmitterDelete (
+ IN OUT PTRANSMITTER *Transmitter
+ )
+{
+ ASSERT(Transmitter != NULL);
+
+ if (*Transmitter) {
+ ExFreePool(*Transmitter);
+ *Transmitter = NULL;
+ }
+}
+
+typedef struct _NET_BUFFER_LIST_RESERVED {
+ LONG Reference;
+} NET_BUFFER_LIST_RESERVED, *PNET_BUFFER_LIST_RESERVED;
+
+C_ASSERT(sizeof (NET_BUFFER_LIST_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER_LIST, MiniportReserved));
+
+typedef struct _NET_BUFFER_RESERVED {
+ XENVIF_TRANSMITTER_PACKET Packet;
+ PNET_BUFFER_LIST NetBufferList;
+} NET_BUFFER_RESERVED, *PNET_BUFFER_RESERVED;
+
+C_ASSERT(sizeof (NET_BUFFER_RESERVED) <= RTL_FIELD_SIZE(NET_BUFFER, MiniportReserved));
+
+static VOID
+TransmitterAbortNetBufferList(
+ IN PTRANSMITTER Transmitter,
+ IN PNET_BUFFER_LIST NetBufferList
+ )
+{
+ ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
+
+ NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_NOT_ACCEPTED;
+
+ NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle,
+ NetBufferList,
+ NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
+}
+
+VOID
+TransmitterAbortPackets(
+ IN PTRANSMITTER Transmitter,
+ IN PXENVIF_TRANSMITTER_PACKET Packet
+ )
+{
+ while (Packet != NULL) {
+ PXENVIF_TRANSMITTER_PACKET Next;
+ PNET_BUFFER_RESERVED Reserved;
+ PNET_BUFFER_LIST NetBufferList;
+ PNET_BUFFER_LIST_RESERVED ListReserved;
+
+ Next = Packet->Next;
+ Packet->Next = NULL;
+
+ Reserved = CONTAINING_RECORD(Packet, NET_BUFFER_RESERVED, Packet);
+
+ NetBufferList = Reserved->NetBufferList;
+ ASSERT(NetBufferList != NULL);
+
+ ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+
+ ASSERT(ListReserved->Reference != 0);
+ if (InterlockedDecrement(&ListReserved->Reference) == 0)
+ TransmitterAbortNetBufferList(Transmitter, NetBufferList);
+
+ Packet = Next;
+ }
+}
+
+VOID
+TransmitterSendNetBufferLists(
+ IN PTRANSMITTER Transmitter,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN ULONG SendFlags
+ )
+{
+ PXENVIF_TRANSMITTER_PACKET HeadPacket;
+ PXENVIF_TRANSMITTER_PACKET *TailPacket;
+ KIRQL Irql;
+
+ UNREFERENCED_PARAMETER(PortNumber);
+
+ HeadPacket = NULL;
+ TailPacket = &HeadPacket;
+
+ if (!NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags)) {
+ ASSERT3U(NDIS_CURRENT_IRQL(), <=, DISPATCH_LEVEL);
+ NDIS_RAISE_IRQL_TO_DISPATCH(&Irql);
+ } else {
+ Irql = DISPATCH_LEVEL;
+ }
+
+ while (NetBufferList != NULL) {
+ PNET_BUFFER_LIST ListNext;
+ PNET_BUFFER_LIST_RESERVED ListReserved;
+ PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo;
+ PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO ChecksumInfo;
+ PNDIS_NET_BUFFER_LIST_8021Q_INFO Ieee8021QInfo;
+ PNET_BUFFER NetBuffer;
+
+ ListNext = NET_BUFFER_LIST_NEXT_NBL(NetBufferList);
+ NET_BUFFER_LIST_NEXT_NBL(NetBufferList) = NULL;
+
+ ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+ RtlZeroMemory(ListReserved, sizeof (NET_BUFFER_LIST_RESERVED));
+
+ LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
+ TcpLargeSendNetBufferListInfo);
+ ChecksumInfo = (PNDIS_TCP_IP_CHECKSUM_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
+ TcpIpChecksumNetBufferListInfo);
+ Ieee8021QInfo = (PNDIS_NET_BUFFER_LIST_8021Q_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
+ Ieee8021QNetBufferListInfo);
+
+ NetBuffer = NET_BUFFER_LIST_FIRST_NB(NetBufferList);
+ while (NetBuffer != NULL) {
+ PNET_BUFFER_RESERVED Reserved;
+ PXENVIF_TRANSMITTER_PACKET Packet;
+
+ Reserved = (PNET_BUFFER_RESERVED)NET_BUFFER_MINIPORT_RESERVED(NetBuffer);
+ RtlZeroMemory(Reserved, sizeof (NET_BUFFER_RESERVED));
+
+ Reserved->NetBufferList = NetBufferList;
+ ListReserved->Reference++;
+
+ Packet = &Reserved->Packet;
+
+ if (ChecksumInfo->Transmit.IsIPv4) {
+ if (ChecksumInfo->Transmit.IpHeaderChecksum)
+ Packet->Send.OffloadOptions.OffloadIpVersion4HeaderChecksum = 1;
+
+ if (ChecksumInfo->Transmit.TcpChecksum)
+ Packet->Send.OffloadOptions.OffloadIpVersion4TcpChecksum = 1;
+
+ if (ChecksumInfo->Transmit.UdpChecksum)
+ Packet->Send.OffloadOptions.OffloadIpVersion4UdpChecksum = 1;
+ }
+
+ if (ChecksumInfo->Transmit.IsIPv6) {
+ if (ChecksumInfo->Transmit.TcpChecksum)
+ Packet->Send.OffloadOptions.OffloadIpVersion6TcpChecksum = 1;
+
+ if (ChecksumInfo->Transmit.UdpChecksum)
+ Packet->Send.OffloadOptions.OffloadIpVersion6UdpChecksum = 1;
+ }
+
+ if (Ieee8021QInfo->TagHeader.UserPriority != 0) {
+ Packet->Send.OffloadOptions.OffloadTagManipulation = 1;
+
+ ASSERT3U(Ieee8021QInfo->TagHeader.CanonicalFormatId, ==, 0);
+ ASSERT3U(Ieee8021QInfo->TagHeader.VlanId, ==, 0);
+
+ PACK_TAG_CONTROL_INFORMATION(Packet->Send.TagControlInformation,
+ Ieee8021QInfo->TagHeader.UserPriority,
+ Ieee8021QInfo->TagHeader.CanonicalFormatId,
+ Ieee8021QInfo->TagHeader.VlanId);
+ }
+
+ if (LargeSendInfo->LsoV2Transmit.MSS != 0) {
+ if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv4)
+ Packet->Send.OffloadOptions.OffloadIpVersion4LargePacket = 1;
+
+ if (LargeSendInfo->LsoV2Transmit.IPVersion == NDIS_TCP_LARGE_SEND_OFFLOAD_IPv6)
+ Packet->Send.OffloadOptions.OffloadIpVersion6LargePacket = 1;
+
+ ASSERT3U(LargeSendInfo->LsoV2Transmit.MSS >> 16, ==, 0);
+ Packet->Send.MaximumSegmentSize = (USHORT)LargeSendInfo->LsoV2Transmit.MSS;
+ }
+
+ Packet->Send.OffloadOptions.Value &= Transmitter->OffloadOptions.Value;
+
+ ASSERT3P(Packet->Next, ==, NULL);
+ *TailPacket = Packet;
+ TailPacket = &Packet->Next;
+
+ NetBuffer = NET_BUFFER_NEXT_NB(NetBuffer);
+ }
+
+ NetBufferList = ListNext;
+ }
+
+ if (HeadPacket != NULL) {
+ NTSTATUS status;
+
+ status = VIF(QueuePackets,
+ Transmitter->Adapter->VifInterface,
+ HeadPacket);
+ if (!NT_SUCCESS(status))
+ TransmitterAbortPackets(Transmitter, HeadPacket);
+ }
+
+ NDIS_LOWER_IRQL(Irql, DISPATCH_LEVEL);
+}
+
+static VOID
+TransmitterCompleteNetBufferList(
+ IN PTRANSMITTER Transmitter,
+ IN PNET_BUFFER_LIST NetBufferList
+ )
+{
+ PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO LargeSendInfo;
+
+ ASSERT3P(NET_BUFFER_LIST_NEXT_NBL(NetBufferList), ==, NULL);
+
+ LargeSendInfo = (PNDIS_TCP_LARGE_SEND_OFFLOAD_NET_BUFFER_LIST_INFO)&NET_BUFFER_LIST_INFO(NetBufferList,
+ TcpLargeSendNetBufferListInfo);
+
+ if (LargeSendInfo->LsoV2Transmit.MSS != 0)
+ LargeSendInfo->LsoV2TransmitComplete.Reserved = 0;
+
+ NET_BUFFER_LIST_STATUS(NetBufferList) = NDIS_STATUS_SUCCESS;
+
+ NdisMSendNetBufferListsComplete(Transmitter->Adapter->NdisAdapterHandle,
+ NetBufferList,
+ NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL);
+}
+
+VOID
+TransmitterCompletePackets(
+ IN PTRANSMITTER Transmitter,
+ IN PXENVIF_TRANSMITTER_PACKET Packet
+ )
+{
+ while (Packet != NULL) {
+ PXENVIF_TRANSMITTER_PACKET Next;
+ PNET_BUFFER_RESERVED Reserved;
+ PNET_BUFFER_LIST NetBufferList;
+ PNET_BUFFER_LIST_RESERVED ListReserved;
+
+ Next = Packet->Next;
+ Packet->Next = NULL;
+
+ Reserved = CONTAINING_RECORD(Packet, NET_BUFFER_RESERVED, Packet);
+
+ NetBufferList = Reserved->NetBufferList;
+ ASSERT(NetBufferList != NULL);
+
+ ListReserved = (PNET_BUFFER_LIST_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(NetBufferList);
+
+ ASSERT(ListReserved->Reference != 0);
+ if (InterlockedDecrement(&ListReserved->Reference) == 0)
+ TransmitterCompleteNetBufferList(Transmitter, NetBufferList);
+
+ Packet = Next;
+ }
+}
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#pragma once
+
+typedef struct _TRANSMITTER {
+ PADAPTER Adapter;
+ XENVIF_OFFLOAD_OPTIONS OffloadOptions;
+} TRANSMITTER, *PTRANSMITTER;
+
+VOID
+TransmitterCleanup (
+ IN OUT PTRANSMITTER* Transmitter
+ );
+
+NDIS_STATUS
+TransmitterInitialize (
+ IN PTRANSMITTER Transmitter,
+ IN PADAPTER Adapter
+ );
+
+VOID
+TransmitterEnable (
+ IN PTRANSMITTER Transmitter
+ );
+
+VOID
+TransmitterDelete (
+ IN OUT PTRANSMITTER* Transmitter
+ );
+
+VOID
+TransmitterSendNetBufferLists (
+ IN PTRANSMITTER Transmitter,
+ IN PNET_BUFFER_LIST NetBufferList,
+ IN NDIS_PORT_NUMBER PortNumber,
+ IN ULONG SendFlags
+ );
+
+VOID
+TransmitterCompletePackets(
+ IN PTRANSMITTER Transmitter,
+ IN PXENVIF_TRANSMITTER_PACKET Packet
+ );
+
+void TransmitterPause(PTRANSMITTER Transmitter);
+void TransmitterUnpause(PTRANSMITTER Transmitter);
--- /dev/null
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <windows.h>
+#include <ntverp.h>
+
+
+#undef VER_COMPANYNAME_STR
+#undef VER_PRODUCTNAME_STR
+#undef VER_PRODUCTVERSION
+#undef VER_PRODUCTVERSION_STR
+
+#define VER_COMPANYNAME_STR "Citrix Systems Inc."
+#define VER_LEGALCOPYRIGHT_STR "Copyright " YEAR_STR VER_COMPANYNAME_STR
+
+#include <version.h>
+
+#define VER_PRODUCTNAME_STR "Citrix PV Tools for Virtual Machines"
+#define VER_PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,MICRO_VERSION,BUILD_NUMBER
+#define VER_PRODUCTVERSION_STR MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR
+
+#define VER_INTERNALNAME_STR "XENNET.SYS"
+#define VER_FILEDESCRIPTION_STR "Citrix PV Network Driver"
+
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_SYSTEM
+
+#include <common.ver>