The driver creates all device objects and names the PDOs sensibly.
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
#ifndef _XENFILT_EMULATED_INTERFACE_H
#define _XENFILT_EMULATED_INTERFACE_H
-#define DEFINE_EMULATED_OPERATIONS \
- EMULATED_OPERATION(VOID, \
- Acquire, \
- ( \
- IN PXENFILT_EMULATED_CONTEXT Context \
- ) \
- ) \
- EMULATED_OPERATION(VOID, \
- Release, \
- ( \
- IN PXENFILT_EMULATED_CONTEXT Context \
- ) \
- ) \
- EMULATED_OPERATION(BOOLEAN, \
- IsPresent, \
- ( \
- IN PXENFILT_EMULATED_CONTEXT Context, \
- IN PCHAR Class, \
- IN PCHAR Device \
- ) \
+#define DEFINE_EMULATED_OPERATIONS \
+ EMULATED_OPERATION(VOID, \
+ Acquire, \
+ ( \
+ IN PXENFILT_EMULATED_CONTEXT Context \
+ ) \
+ ) \
+ EMULATED_OPERATION(VOID, \
+ Release, \
+ ( \
+ IN PXENFILT_EMULATED_CONTEXT Context \
+ ) \
+ ) \
+ EMULATED_OPERATION(BOOLEAN, \
+ IsDevicePresent, \
+ ( \
+ IN PXENFILT_EMULATED_CONTEXT Context, \
+ IN PCHAR DeviceID, \
+ IN PCHAR InstanceID \
+ ) \
+ ) \
+ EMULATED_OPERATION(BOOLEAN, \
+ IsDiskPresent, \
+ ( \
+ IN PXENFILT_EMULATED_CONTEXT Context, \
+ IN ULONG Controller, \
+ IN ULONG Target, \
+ IN ULONG Lun \
+ ) \
)
typedef struct _XENFILT_EMULATED_CONTEXT XENFILT_EMULATED_CONTEXT, *PXENFILT_EMULATED_CONTEXT;
0xe9,
0x77);
-#define EMULATED_INTERFACE_VERSION 3
+#define EMULATED_INTERFACE_VERSION 4
#define EMULATED_OPERATIONS(_Interface) \
(PXENFILT_EMULATED_OPERATIONS *)((ULONG_PTR)(_Interface))
#define __ffu(_mask) \
__ffs(~(_mask))
+static FORCEINLINE VOID
+__CpuId(
+ IN ULONG Leaf,
+ OUT PULONG EAX OPTIONAL,
+ OUT PULONG EBX OPTIONAL,
+ OUT PULONG ECX OPTIONAL,
+ OUT PULONG EDX OPTIONAL
+ )
+{
+ ULONG Value[4] = {0};
+
+ __cpuid(Value, Leaf);
+
+ if (EAX)
+ *EAX = Value[0];
+
+ if (EBX)
+ *EBX = Value[1];
+
+ if (ECX)
+ *ECX = Value[2];
+
+ if (EDX)
+ *EDX = Value[3];
+}
+
static FORCEINLINE LONG
__InterlockedAdd(
IN LONG *Value,
MmFreePagesFromMdl(Mdl);
}
+static FORCEINLINE PWCHAR
+__wcstok_r(
+ IN PWCHAR Buffer,
+ IN PWCHAR Delimiter,
+ IN OUT PWCHAR *Context
+ )
+{
+ PWCHAR Token;
+ PWCHAR End;
+
+ if (Buffer != NULL)
+ *Context = Buffer;
+
+ Token = *Context;
+
+ if (Token == NULL)
+ return NULL;
+
+ while (*Token != L'\0' &&
+ wcschr(Delimiter, *Token) != NULL)
+ Token++;
+
+ if (*Token == L'\0')
+ return NULL;
+
+ End = Token + 1;
+ while (*End != L'\0' &&
+ wcschr(Delimiter, *End) == NULL)
+ End++;
+
+ if (*End != L'\0')
+ *End++ = L'\0';
+
+ *Context = End;
+
+ return Token;
+}
+
#endif // _UTIL_H
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- configurations -->
<Import Project="..\configs.props" />
<FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
</ItemGroup>
<ItemGroup>
+ <ClCompile Include="../../src/xenvif/bus.c" />
<ClCompile Include="../../src/xenvif/checksum.c" />
<ClCompile Include="../../src/xenvif/driver.c" />
<ClCompile Include="../../src/xenvif/fdo.c" />
#undef _NAME
}
-static BOOLEAN
-InstallClass(
- IN PTCHAR Class
- )
-{
- HKEY Key;
- DWORD OldLength;
- DWORD NewLength;
- DWORD Type;
- LONG Error;
- PTCHAR Classes;
- 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,
- "UnplugClasses",
- 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(Class) + 1) * sizeof (TCHAR));
-
- Classes = malloc(NewLength);
- if (Classes == NULL)
- goto fail4;
-
- memset(Classes, 0, NewLength);
-
- Offset = 0;
- if (OldLength != sizeof (TCHAR)) {
- Error = RegQueryValueEx(Key,
- "UnplugClasses",
- NULL,
- NULL,
- (PBYTE)Classes,
- &OldLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail5;
- }
-
- while (Classes[Offset] != '\0') {
- ULONG ClassLength;
-
- ClassLength = (ULONG)strlen(&Classes[Offset]) / sizeof (TCHAR);
-
- if (_stricmp(&Classes[Offset], Class) == 0) {
- Log("%s already present", Class);
- goto done;
- }
-
- Offset += ClassLength + 1;
- }
- }
-
- memmove(&Classes[Offset], Class, strlen(Class));
- Log("added %s", Class);
-
- Error = RegSetValueEx(Key,
- "UnplugClasses",
- 0,
- Type,
- (PBYTE)Classes,
- NewLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail6;
- }
-
-done:
- free(Classes);
-
- RegCloseKey(Key);
-
- return TRUE;
-
-fail6:
-fail5:
- free(Classes);
-
-fail4:
-fail3:
-fail2:
- RegCloseKey(Key);
-
-fail1:
- return FALSE;
-}
-
-static BOOLEAN
-RemoveClass(
- IN PTCHAR Class
- )
-{
- HKEY Key;
- DWORD OldLength;
- DWORD NewLength;
- DWORD Type;
- LONG Error;
- PTCHAR Classes;
- ULONG Offset;
- ULONG ClassLength;
-
- 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,
- "UnplugClasses",
- 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;
- }
-
- Classes = malloc(OldLength);
- if (Classes == NULL)
- goto fail4;
-
- memset(Classes, 0, OldLength);
-
- Error = RegQueryValueEx(Key,
- "UnplugClasses",
- NULL,
- NULL,
- (PBYTE)Classes,
- &OldLength);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail5;
- }
-
- Offset = 0;
- ClassLength = 0;
- while (Classes[Offset] != '\0') {
- ClassLength = (ULONG)strlen(&Classes[Offset]) / sizeof (TCHAR);
-
- if (_stricmp(&Classes[Offset], Class) == 0)
- goto remove;
-
- Offset += ClassLength + 1;
- }
-
- free(Classes);
- goto done;
-
-remove:
- NewLength = OldLength - ((ClassLength + 1) * sizeof (TCHAR));
-
- memmove(&Classes[Offset],
- &Classes[Offset + ClassLength + 1],
- (NewLength - Offset) * sizeof (TCHAR));
-
- Log("removed %s", Class);
-
- if (NewLength == 1) {
- Error = RegDeleteValue(Key,
- "UnplugClasses");
- } else {
- Error = RegSetValueEx(Key,
- "UnplugClasses",
- 0,
- Type,
- (PBYTE)Classes,
- NewLength);
- }
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail6;
- }
-
- free(Classes);
-
-done:
- RegCloseKey(Key);
-
- return TRUE;
-
-fail6:
-fail5:
- free(Classes);
-
-fail4:
-fail3:
-fail2:
- RegCloseKey(Key);
-
-fail1:
- return FALSE;
-}
-
-static BOOLEAN
-IsClassEmulated(
- IN PTCHAR Class,
- OUT PBOOLEAN Present
- )
-{
- HKEY Key;
- DWORD Length;
- DWORD Type;
- LONG Error;
- PTCHAR Devices;
- ULONG Count;
- ULONG Offset;
-
- 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) {
- RegCloseKey(Key);
- goto done;
- }
-
- SetLastError(Error);
- goto fail2;
- }
-
- if (Type != REG_MULTI_SZ) {
- SetLastError(ERROR_BAD_FORMAT);
- goto fail3;
- }
-
- Devices = malloc(Length);
- if (Devices == NULL)
- goto fail4;
-
- memset(Devices, 0, Length);
-
- Error = RegQueryValueEx(Key,
- Class,
- NULL,
- NULL,
- (PBYTE)Devices,
- &Length);
- if (Error != ERROR_SUCCESS) {
- SetLastError(Error);
- goto fail5;
- }
-
- Count = 0;
-
- Offset = 0;
- while (Devices[Offset] != '\0') {
- ULONG DeviceLength;
-
- DeviceLength = (ULONG)strlen(&Devices[Offset]) / sizeof (TCHAR);
-
- Count++;
- Offset += DeviceLength + 1;
- }
-
- *Present = (Count != 0) ? TRUE : FALSE;
-
- free(Devices);
-
- RegCloseKey(Key);
-
-done:
- return TRUE;
-
-fail5:
- free(Devices);
-
-fail4:
-fail3:
-fail2:
- RegCloseKey(Key);
-
-fail1:
- return FALSE;
-}
-
-static BOOLEAN
-RequestReboot(
- IN HDEVINFO DeviceInfoSet,
- IN PSP_DEVINFO_DATA DeviceInfoData
- )
-{
- SP_DEVINSTALL_PARAMS DeviceInstallParams;
-
- 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:
-fail1:
- return FALSE;
-}
-
static FORCEINLINE HRESULT
__DifInstallPreProcess(
IN HDEVINFO DeviceInfoSet,
)
{
HRESULT Error;
- BOOLEAN Present;
- BOOLEAN Success;
+
+ UNREFERENCED_PARAMETER(DeviceInfoSet);
+ UNREFERENCED_PARAMETER(DeviceInfoData);
Log("====>");
goto fail1;
}
- Success = InstallClass("VIF");
- if (!Success)
- goto fail2;
-
- Success = IsClassEmulated("VIF", &Present);
- if (!Success)
- goto fail3;
-
- if (!Present)
- goto done;
-
- Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
- if (!Success)
- goto fail4;
-
-done:
Log("<====");
return NO_ERROR;
-fail4:
- Log("fail4");
-
-fail3:
- Log("fail3");
-
-fail2:
- Log("fail2");
-
fail1:
Error = GetLastError();
)
{
HRESULT Error;
- BOOLEAN Success;
+
+ UNREFERENCED_PARAMETER(DeviceInfoSet);
+ UNREFERENCED_PARAMETER(DeviceInfoData);
Log("====>");
goto fail1;
}
- Success = RemoveClass("VIF");
- if (!Success)
- goto fail2;
-
- Success = RequestReboot(DeviceInfoSet, DeviceInfoData);
- if (!Success)
- goto fail3;
-
Log("<====");
return NO_ERROR;
-fail3:
- Log("fail3");
-
-fail2:
- Log("fail2");
-
fail1:
Error = GetLastError();
%Citrix%=Citrix,NT$ARCH$
[Citrix.NT$ARCH$]
-%DriverDesc%=XenVif_Inst,XENBUS\CLASS_VIF&REV_02
+; DisplayName Section DeviceID
+; ----------- ------- --------
+
+%XenVifDesc% =XenVif_Inst, XENBUS\VEN_XSC000&DEV_VIF&REV_00000001
+%XenVifDesc% =XenVif_Inst, XENBUS\VEN_XS0001&DEV_VIF&REV_00000001
+%XenVifDesc% =XenVif_Inst, XENBUS\VEN_XS0002&DEV_VIF&REV_00000001
[XenVif_Inst]
CopyFiles=XenVif_Copyfiles
AddReg = XenVif_Parameters
[XenVif_Parameters]
-HKR,"Parameters","ReceiverMaximumProtocol",0x00010001,0x00000000
+HKR,"Parameters",,0x00000010
[XenVif_Inst.CoInstallers]
CopyFiles=CoInst_CopyFiles
[Strings]
Citrix="Citrix Systems Inc."
-DiskDesc="Citrix Tools for Virtual Machines"
-DriverDesc="Citrix VIF Class"
+DiskDesc="XenServer Tools for Virtual Machines"
+XenVifDesc="XenServer PV Network Class"
SERVICE_BOOT_START=0x0
SERVICE_SYSTEM_START=0x1
#include <ntddk.h>
-#include "log.h"
+#include "dbg_print.h"
static FORCEINLINE VOID
-__BugCheck(
+__Bug(
IN ULONG Code,
IN ULONG_PTR Parameter1,
IN ULONG_PTR Parameter2,
ULONG _Line = __LINE__; \
\
Error("BUG: " _TEXT "\n"); \
- __BugCheck(ASSERTION_FAILURE, \
- (ULONG_PTR)_Text, \
- (ULONG_PTR)_File, \
- (ULONG_PTR)_Line, \
- 0); \
+ __Bug(ASSERTION_FAILURE, \
+ (ULONG_PTR)_Text, \
+ (ULONG_PTR)_File, \
+ (ULONG_PTR)_Line, \
+ 0); \
} while (FALSE)
#define BUG_ON(_EXP) \
#define EQUIV(_X, _Y) (IMPLY((_X), (_Y)) && IMPLY((_Y), (_X)))
#endif // _XENVIF_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.
+ */
+
+#include <ntddk.h>
+#include <stdarg.h>
+#include <xen.h>
+#include <util.h>
+
+#include "bus.h"
+#include "fdo.h"
+#include "pdo.h"
+#include "dbg_print.h"
+#include "assert.h"
+
+typedef struct _XENVIF_BUS_CONTEXT {
+ LONG References;
+ PXENVIF_PDO Pdo;
+ ULONG InterceptDmaAdapter;
+} XENVIF_BUS_CONTEXT, *PXENVIF_BUS_CONTEXT;
+
+#define BUS_TAG 'SUB'
+
+static FORCEINLINE PVOID
+__BusAllocate(
+ IN ULONG Length
+ )
+{
+ return __AllocateNonPagedPoolWithTag(Length, BUS_TAG);
+}
+
+static FORCEINLINE VOID
+__BusFree(
+ IN PVOID Buffer
+ )
+{
+ __FreePoolWithTag(Buffer, BUS_TAG);
+}
+
+static VOID
+BusReference(
+ IN PVOID _Context
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = _Context;
+
+ InterlockedIncrement(&Context->References);
+}
+
+static VOID
+BusDereference(
+ IN PVOID _Context
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = _Context;
+
+ ASSERT(Context->References != 0);
+ InterlockedDecrement(&Context->References);
+}
+
+static
+__drv_functionClass(TRANSLATE_BUS_ADDRESS)
+BOOLEAN
+BusTranslateAddress(
+ IN PVOID _Context,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN ULONG Length,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = _Context;
+
+ return PdoTranslateBusAddress(Context->Pdo,
+ BusAddress,
+ Length,
+ AddressSpace,
+ TranslatedAddress);
+}
+
+static
+__drv_functionClass(GET_DMA_ADAPTER)
+PDMA_ADAPTER
+BusGetDmaAdapter(
+ IN PVOID _Context,
+ IN PDEVICE_DESCRIPTION DeviceDescriptor,
+ OUT PULONG NumberOfMapRegisters
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = _Context;
+
+ return PdoGetDmaAdapter(Context->Pdo,
+ DeviceDescriptor,
+ NumberOfMapRegisters);
+}
+
+static
+__drv_functionClass(GET_SET_DEVICE_DATA)
+ULONG
+BusSetData(
+ IN PVOID _Context,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = _Context;
+
+ return PdoSetBusData(Context->Pdo,
+ DataType,
+ Buffer,
+ Offset,
+ Length);
+}
+
+static
+__drv_functionClass(GET_SET_DEVICE_DATA)
+ULONG
+BusGetData(
+ IN PVOID _Context,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = _Context;
+
+ return PdoGetBusData(Context->Pdo,
+ DataType,
+ Buffer,
+ Offset,
+ Length);
+}
+
+NTSTATUS
+BusInitialize(
+ IN PXENVIF_PDO Pdo,
+ OUT PBUS_INTERFACE_STANDARD Interface
+ )
+{
+ PXENVIF_BUS_CONTEXT Context;
+ NTSTATUS status;
+
+ Trace("====>\n");
+
+ Context = __BusAllocate(sizeof (XENVIF_BUS_CONTEXT));
+
+ status = STATUS_NO_MEMORY;
+ if (Context == NULL)
+ goto fail1;
+
+ Context->Pdo = Pdo;
+
+ Interface->Size = sizeof (BUS_INTERFACE_STANDARD);
+ Interface->Version = 1;
+ Interface->Context = Context;
+ Interface->InterfaceReference = BusReference;
+ Interface->InterfaceDereference = BusDereference;
+ Interface->TranslateBusAddress = BusTranslateAddress;
+ Interface->GetDmaAdapter = BusGetDmaAdapter;
+ Interface->SetBusData = BusSetData;
+ Interface->GetBusData = BusGetData;
+
+ Trace("<====\n");
+
+ return STATUS_SUCCESS;
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+VOID
+BusTeardown(
+ IN OUT PBUS_INTERFACE_STANDARD Interface
+ )
+{
+ PXENVIF_BUS_CONTEXT Context = Interface->Context;
+
+ Trace("====>\n");
+
+ Context->Pdo = NULL;
+
+ ASSERT(IsZeroMemory(Context, sizeof (XENVIF_BUS_CONTEXT)));
+ __BusFree(Context);
+
+ RtlZeroMemory(Interface, sizeof (BUS_INTERFACE_STANDARD));
+
+ 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.
+ */
+
+#ifndef _XENVIF_BUS_H
+#define _XENVIF_BUS_H
+
+#include <ntddk.h>
+#include <xen.h>
+
+#include "pdo.h"
+
+extern NTSTATUS
+BusInitialize(
+ IN PXENVIF_PDO Pdo,
+ OUT PBUS_INTERFACE_STANDARD Interface
+ );
+
+extern VOID
+BusTeardown(
+ IN OUT PBUS_INTERFACE_STANDARD Interface
+ );
+
+#endif // _XENVIF_BUS_H
+
#include <vif_interface.h>
#include "checksum.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE VOID
#include "pdo.h"
#include "receiver.h"
#include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
extern PULONG InitSafeBootMode;
-PDRIVER_OBJECT DriverObject;
+typedef struct _XENVIF_DRIVER {
+ PDRIVER_OBJECT DriverObject;
+ HANDLE ParametersKey;
+} XENVIF_DRIVER, *PXENVIF_DRIVER;
-XENVIF_PARAMETERS DriverParameters;
+static XENVIF_DRIVER Driver;
+
+static FORCEINLINE VOID
+__DriverSetDriverObject(
+ IN PDRIVER_OBJECT DriverObject
+ )
+{
+ Driver.DriverObject = DriverObject;
+}
+
+static FORCEINLINE PDRIVER_OBJECT
+__DriverGetDriverObject(
+ VOID
+ )
+{
+ return Driver.DriverObject;
+}
+
+PDRIVER_OBJECT
+DriverGetDriverObject(
+ VOID
+ )
+{
+ return __DriverGetDriverObject();
+}
+
+static FORCEINLINE VOID
+__DriverSetParametersKey(
+ IN HANDLE Key
+ )
+{
+ Driver.ParametersKey = Key;
+}
+
+static FORCEINLINE HANDLE
+__DriverGetParametersKey(
+ VOID
+ )
+{
+ return Driver.ParametersKey;
+}
+
+HANDLE
+DriverGetParametersKey(
+ VOID
+ )
+{
+ return __DriverGetParametersKey();
+}
DRIVER_UNLOAD DriverUnload;
VOID
DriverUnload(
- IN PDRIVER_OBJECT _DriverObject
+ IN PDRIVER_OBJECT DriverObject
)
{
- ASSERT3P(_DriverObject, ==, DriverObject);
+ HANDLE ParametersKey;
+
+ ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
Trace("====>\n");
if (*InitSafeBootMode > 0)
goto done;
- RegistryFreeSzValue(DriverParameters.UnsupportedDevices);
+ ParametersKey = __DriverGetParametersKey();
+ if (ParametersKey != NULL) {
+ RegistryCloseKey(ParametersKey);
+ __DriverSetParametersKey(NULL);
+ }
RegistryTeardown();
done:
- DriverObject = NULL;
+ __DriverSetDriverObject(NULL);
+
+ ASSERT(IsZeroMemory(&Driver, sizeof (XENVIF_DRIVER)));
Trace("<====\n");
}
NTSTATUS
AddDevice(
- IN PDRIVER_OBJECT _DriverObject,
+ IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT DeviceObject
)
{
NTSTATUS status;
- ASSERT3P(_DriverObject, ==, DriverObject);
+ ASSERT3P(DriverObject, ==, __DriverGetDriverObject());
status = FdoCreate(DeviceObject);
if (!NT_SUCCESS(status))
NTSTATUS
DriverEntry(
- IN PDRIVER_OBJECT _DriverObject,
+ IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
- HANDLE Key;
+ HANDLE ServiceKey;
+ HANDLE ParametersKey;
ULONG Index;
NTSTATUS status;
- ASSERT3P(DriverObject, ==, NULL);
+ ASSERT3P(__DriverGetDriverObject(), ==, NULL);
ExInitializeDriverRuntime(DrvRtPoolNxOptIn);
- Trace("====>\n");
+ __DbgPrintEnable();
- Info("%s (%s)\n",
- MAJOR_VERSION_STR "." MINOR_VERSION_STR "." MICRO_VERSION_STR "." BUILD_NUMBER_STR,
- DAY_STR "/" MONTH_STR "/" YEAR_STR);
+ Trace("====>\n");
- DriverObject = _DriverObject;
- DriverObject->DriverUnload = DriverUnload;
+ __DriverSetDriverObject(DriverObject);
if (*InitSafeBootMode > 0)
goto done;
+ Driver.DriverObject->DriverUnload = DriverUnload;
+
+ Info("XENVIF %d.%d.%d (%d) (%02d.%02d.%04d)\n",
+ MAJOR_VERSION,
+ MINOR_VERSION,
+ MICRO_VERSION,
+ BUILD_NUMBER,
+ DAY,
+ MONTH,
+ YEAR);
+
status = RegistryInitialize(RegistryPath);
if (!NT_SUCCESS(status))
goto fail1;
- status = RegistryOpenSubKey("Parameters", KEY_READ, &Key);
- if (NT_SUCCESS(status)) {
- status = RegistryQuerySzValue(Key,
- "UnsupportedDevices",
- &DriverParameters.UnsupportedDevices);
- if (!NT_SUCCESS(status))
- DriverParameters.UnsupportedDevices = NULL;
-
- status = RegistryQueryDwordValue(Key,
- "ReceiverMaximumProtocol",
- &DriverParameters.ReceiverMaximumProtocol);
- if (!NT_SUCCESS(status))
- DriverParameters.ReceiverMaximumProtocol = 0;
-
- status = RegistryQueryDwordValue(Key,
- "ReceiverCalculateChecksums",
- &DriverParameters.ReceiverCalculateChecksums);
- if (!NT_SUCCESS(status))
- DriverParameters.ReceiverCalculateChecksums = 0;
-
- status = RegistryQueryDwordValue(Key,
- "ReceiverAllowGsoPackets",
- &DriverParameters.ReceiverAllowGsoPackets);
- if (!NT_SUCCESS(status))
- DriverParameters.ReceiverAllowGsoPackets = 1;
-
- status = RegistryQueryDwordValue(Key,
- "ReceiverIpAlignOffset",
- &DriverParameters.ReceiverIpAlignOffset);
- if (!NT_SUCCESS(status))
- DriverParameters.ReceiverIpAlignOffset = 0;
-
- status = RegistryQueryDwordValue(Key,
- "ReceiverAlwaysPullup",
- &DriverParameters.ReceiverAlwaysPullup);
- if (!NT_SUCCESS(status))
- DriverParameters.ReceiverAlwaysPullup = 0;
-
- status = RegistryQueryDwordValue(Key,
- "CreatePDOs",
- &DriverParameters.CreatePDOs);
- if (!NT_SUCCESS(status))
- DriverParameters.CreatePDOs = 1;
-
- RegistryCloseKey(Key);
- }
+ status = RegistryOpenServiceKey(KEY_READ, &ServiceKey);
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = RegistryOpenSubKey(ServiceKey, "Parameters", KEY_READ, &ParametersKey);
+ if (NT_SUCCESS(status))
+ __DriverSetParametersKey(ParametersKey);
+
+ RegistryCloseKey(ServiceKey);
DriverObject->DriverExtension->AddDevice = AddDevice;
return STATUS_SUCCESS;
+fail2:
+ Error("fail2\n");
+
+ RegistryTeardown();
+
fail1:
Error("fail1 (%08x)\n", status);
+ __DriverSetDriverObject(NULL);
+
+ ASSERT(IsZeroMemory(&Driver, sizeof (XENVIF_DRIVER)));
+
return status;
}
#ifndef _XENVIF_DRIVER_H
#define _XENVIF_DRIVER_H
+extern PDRIVER_OBJECT
+DriverGetDriverObject(
+ VOID
+ );
+
+extern HANDLE
+DriverGetParametersKey(
+ VOID
+ );
+
typedef struct _XENVIF_PDO XENVIF_PDO, *PXENVIF_PDO;
typedef struct _XENVIF_FDO XENVIF_FDO, *PXENVIF_FDO;
#include "fdo.h"
#include "pdo.h"
-extern PDRIVER_OBJECT DriverObject;
-
-typedef struct _XENVIF_PARAMETERS {
- PANSI_STRING UnsupportedDevices;
- ULONG ReceiverMaximumProtocol;
- ULONG ReceiverCalculateChecksums;
- ULONG ReceiverAllowGsoPackets;
- ULONG ReceiverIpAlignOffset;
- ULONG ReceiverAlwaysPullup;
- ULONG CreatePDOs;
-} XENVIF_PARAMETERS, *PXENVIF_PARAMETERS;
-
-extern XENVIF_PARAMETERS DriverParameters;
-
#define MAX_DEVICE_ID_LEN 200
#pragma warning(push)
#include "mutex.h"
#include "frontend.h"
#include "names.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define FDO_POOL 'ODF'
PDEVICE_OBJECT LowerDeviceObject;
PDEVICE_OBJECT PhysicalDeviceObject;
DEVICE_CAPABILITIES LowerDeviceCapabilities;
+ BUS_INTERFACE_STANDARD LowerBusInterface;
ULONG Usage[DeviceUsageTypeDumpFile + 1];
BOOLEAN NotDisableable;
PXENVIF_THREAD DevicePowerThread;
PIRP DevicePowerIrp;
+ CHAR VendorName[MAXNAMELEN];
+
PXENVIF_THREAD ScanThread;
KEVENT ScanEvent;
PXENBUS_STORE_WATCH ScanWatch;
- XENVIF_MUTEX Mutex;
+ MUTEX Mutex;
ULONG References;
FDO_RESOURCE Resource[RESOURCE_COUNT];
return __FdoGetPhysicalDeviceObject(Fdo);
}
-static FORCEINLINE NTSTATUS
-__FdoSetName(
+PDMA_ADAPTER
+FdoGetDmaAdapter(
+ IN PXENVIF_FDO Fdo,
+ IN PDEVICE_DESCRIPTION DeviceDescriptor,
+ OUT PULONG NumberOfMapRegisters
+ )
+{
+ PBUS_INTERFACE_STANDARD LowerBusInterface;
+
+ LowerBusInterface = &Fdo->LowerBusInterface;
+
+ return LowerBusInterface->GetDmaAdapter(LowerBusInterface->Context,
+ DeviceDescriptor,
+ NumberOfMapRegisters);
+}
+
+BOOLEAN
+FdoTranslateBusAddress(
+ IN PXENVIF_FDO Fdo,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN ULONG Length,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ )
+{
+ PBUS_INTERFACE_STANDARD LowerBusInterface;
+
+ LowerBusInterface = &Fdo->LowerBusInterface;
+
+ return LowerBusInterface->TranslateBusAddress(LowerBusInterface->Context,
+ BusAddress,
+ Length,
+ AddressSpace,
+ TranslatedAddress);
+}
+
+ULONG
+FdoSetBusData(
+ IN PXENVIF_FDO Fdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ PBUS_INTERFACE_STANDARD LowerBusInterface;
+
+ LowerBusInterface = &Fdo->LowerBusInterface;
+
+ return LowerBusInterface->SetBusData(LowerBusInterface->Context,
+ DataType,
+ Buffer,
+ Offset,
+ Length);
+}
+
+ULONG
+FdoGetBusData(
+ IN PXENVIF_FDO Fdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ PBUS_INTERFACE_STANDARD LowerBusInterface;
+
+ LowerBusInterface = &Fdo->LowerBusInterface;
+
+ return LowerBusInterface->GetBusData(LowerBusInterface->Context,
+ DataType,
+ Buffer,
+ Offset,
+ Length);
+}
+
+static FORCEINLINE VOID
+__FdoSetVendorName(
IN PXENVIF_FDO Fdo,
- IN PWCHAR Name
+ IN USHORT DeviceID
)
{
- PXENVIF_DX Dx = Fdo->Dx;
- UNICODE_STRING Unicode;
- ANSI_STRING Ansi;
- ULONG Index;
NTSTATUS status;
- RtlInitUnicodeString(&Unicode, Name);
-
- Ansi.Buffer = Dx->Name;
- Ansi.MaximumLength = sizeof (Dx->Name);
- Ansi.Length = 0;
+ status = RtlStringCbPrintfA(Fdo->VendorName,
+ MAXNAMELEN,
+ "XS%04X",
+ DeviceID);
+ ASSERT(NT_SUCCESS(status));
+}
- status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
- for (Index = 0; Dx->Name[Index] != '\0'; Index++) {
- if (!isalnum((UCHAR)Dx->Name[Index]))
- Dx->Name[Index] = '_';
- }
+static FORCEINLINE PCHAR
+__FdoGetVendorName(
+ IN PXENVIF_FDO Fdo
+ )
+{
+ return Fdo->VendorName;
+}
- return STATUS_SUCCESS;
+PCHAR
+FdoGetVendorName(
+ IN PXENVIF_FDO Fdo
+ )
+{
+ return __FdoGetVendorName(Fdo);
+}
-fail1:
- Error("fail1 (%08x)\n", status);
+static FORCEINLINE VOID
+__FdoSetName(
+ IN PXENVIF_FDO Fdo
+ )
+{
+ PXENVIF_DX Dx = Fdo->Dx;
+ NTSTATUS status;
- return status;
+ status = RtlStringCbPrintfA(Dx->Name,
+ MAXNAMELEN,
+ "%s XENVIF",
+ __FdoGetVendorName(Fdo));
+ ASSERT(NT_SUCCESS(status));
}
static FORCEINLINE PCHAR
NeedInvalidate = FALSE;
- if (DriverParameters.CreatePDOs == 0)
- goto done;
-
__FdoAcquireMutex(Fdo);
ListEntry = Fdo->Dx->ListEntry.Flink;
PXENVIF_PDO Pdo = Dx->Pdo;
BOOLEAN Missing;
+ Name = PdoGetName(Pdo);
Missing = TRUE;
- // If the PDO exists in the device list
- // from xenstore then we don't want to remove it.
-
+ // If the PDO already exists ans its name is in the class list then
+ // we don't want to remove it.
for (Index = 0; Devices[Index].Buffer != NULL; Index++) {
PANSI_STRING Device = &Devices[Index];
+ if (Device->Length == 0)
+ continue;
+
if (strcmp(Name, Device->Buffer) == 0) {
Missing = FALSE;
Device->Length = 0; // avoid duplication
ListEntry = Next;
}
- // Check the device list from xenstore against the unsupported list
+ // Walk the class list and create PDOs for any new classes
for (Index = 0; Devices[Index].Buffer != NULL; Index++) {
- PANSI_STRING Device = &Devices[Index];
- ULONG Entry;
- BOOLEAN Supported;
-
- Supported = TRUE;
-
- for (Entry = 0;
- DriverParameters.UnsupportedDevices != NULL && DriverParameters.UnsupportedDevices[Entry].Buffer != NULL;
- Entry++) {
- if (strncmp(Device->Buffer,
- DriverParameters.UnsupportedDevices[Entry].Buffer,
- Device->Length) == 0) {
- Supported = FALSE;
- break;
- }
- }
-
- if (!Supported)
- Device->Length = 0; // avoid creation
- }
-
- // Walk the device list and create PDOs for any new devices
-
- for (Index = 0; Devices[Index].Buffer != NULL; Index++) {
- PANSI_STRING Device = &Devices[Index];
+ PANSI_STRING Device = &Devices[Index];
if (Device->Length != 0) {
- NTSTATUS status;
+ NTSTATUS status;
status = PdoCreate(Fdo, Device);
if (NT_SUCCESS(status))
__FdoReleaseMutex(Fdo);
-done:
Trace("<====\n");
return NeedInvalidate;
}
)
{
PXENVIF_FDO Fdo = Context;
- BOOLEAN NeedInvalidate;
PKEVENT Event;
+ HANDLE ParametersKey;
+ NTSTATUS status;
Trace("====>\n");
- NeedInvalidate = FALSE;
-
Event = ThreadGetEvent(Self);
+ ParametersKey = DriverGetParametersKey();
+
for (;;) {
PCHAR Buffer;
PANSI_STRING Devices;
- NTSTATUS status;
+ PANSI_STRING UnsupportedDevices;
+ ULONG Index;
+ BOOLEAN NeedInvalidate;
Trace("waiting...\n");
Fdo->StoreInterface,
Buffer);
- if (Devices != NULL) {
- NeedInvalidate = __FdoEnumerate(Fdo, Devices);
- __FdoFreeAnsi(Devices);
+ if (Devices == NULL)
+ goto loop;
+
+ if (ParametersKey != NULL) {
+ status = RegistryQuerySzValue(ParametersKey,
+ "UnsupportedDevices",
+ &UnsupportedDevices);
+ if (!NT_SUCCESS(status))
+ UnsupportedDevices = NULL;
+ } else {
+ UnsupportedDevices = NULL;
}
+ // NULL out anything in the Devices list that is in the
+ // UnsupportedDevices list
+ for (Index = 0; Devices[Index].Buffer != NULL; Index++) {
+ PANSI_STRING Device = &Devices[Index];
+ ULONG Entry;
+ BOOLEAN Supported;
+
+ Supported = TRUE;
+
+ for (Entry = 0;
+ UnsupportedDevices != NULL && UnsupportedDevices[Entry].Buffer != NULL;
+ Entry++) {
+ if (strncmp(Device->Buffer,
+ UnsupportedDevices[Entry].Buffer,
+ Device->Length) == 0) {
+ Supported = FALSE;
+ break;
+ }
+ }
+
+ if (!Supported)
+ Device->Length = 0;
+ }
+
+ if (UnsupportedDevices != NULL)
+ RegistryFreeSzValue(UnsupportedDevices);
+
+ NeedInvalidate = __FdoEnumerate(Fdo, Devices);
+
+ __FdoFreeAnsi(Devices);
+
if (NeedInvalidate) {
NeedInvalidate = FALSE;
IoInvalidateDeviceRelations(__FdoGetPhysicalDeviceObject(Fdo),
IN PXENVIF_FDO Fdo
)
{
- POWER_STATE PowerState;
NTSTATUS status;
Trace("====>\n");
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3);
-
- __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
STORE(Acquire, Fdo->StoreInterface);
if (!NT_SUCCESS(status))
goto fail1;
- PowerState.DeviceState = PowerDeviceD0;
- PoSetPowerState(Fdo->Dx->DeviceObject,
- DevicePowerState,
- PowerState);
-
Trace("<====\n");
return STATUS_SUCCESS;
STORE(Release, Fdo->StoreInterface);
- __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
-
return status;
}
IN PXENVIF_FDO Fdo
)
{
- POWER_STATE PowerState;
-
Trace("====>\n");
ASSERT3U(KeGetCurrentIrql(), ==, DISPATCH_LEVEL);
- ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
-
- PowerState.DeviceState = PowerDeviceD3;
- PoSetPowerState(Fdo->Dx->DeviceObject,
- DevicePowerState,
- PowerState);
-
- __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
(VOID) STORE(Unwatch,
Fdo->StoreInterface,
IN PXENVIF_FDO Fdo
)
{
+ POWER_STATE PowerState;
KIRQL Irql;
PLIST_ENTRY ListEntry;
NTSTATUS status;
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD3);
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
KeLowerIrql(Irql);
+ __FdoSetDevicePowerState(Fdo, PowerDeviceD0);
+
+ PowerState.DeviceState = PowerDeviceD0;
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
+
__FdoAcquireMutex(Fdo);
for (ListEntry = Fdo->Dx->ListEntry.Flink;
IN PXENVIF_FDO Fdo
)
{
+ POWER_STATE PowerState;
PLIST_ENTRY ListEntry;
KIRQL Irql;
ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+ ASSERT3U(__FdoGetDevicePowerState(Fdo), ==, PowerDeviceD0);
__FdoAcquireMutex(Fdo);
__FdoReleaseMutex(Fdo);
+ PowerState.DeviceState = PowerDeviceD3;
+ PoSetPowerState(Fdo->Dx->DeviceObject,
+ DevicePowerState,
+ PowerState);
+
+ __FdoSetDevicePowerState(Fdo, PowerDeviceD3);
+
KeRaiseIrql(DISPATCH_LEVEL, &Irql);
SUSPEND(Deregister,
return status;
}
+static FORCEINLINE NTSTATUS
+__FdoAcquireLowerBusInterface(
+ IN PXENVIF_FDO Fdo
+ )
+{
+ KEVENT Event;
+ IO_STATUS_BLOCK StatusBlock;
+ PIRP Irp;
+ PIO_STACK_LOCATION StackLocation;
+ NTSTATUS status;
+
+ ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
+
+ KeInitializeEvent(&Event, NotificationEvent, FALSE);
+ RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
+
+ Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
+ Fdo->LowerDeviceObject,
+ 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_BUS_INTERFACE_STANDARD;
+ StackLocation->Parameters.QueryInterface.Size = sizeof (BUS_INTERFACE_STANDARD);
+ StackLocation->Parameters.QueryInterface.Version = 1;
+ StackLocation->Parameters.QueryInterface.Interface = (PINTERFACE)&Fdo->LowerBusInterface;
+
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+
+ status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
+ if (status == STATUS_PENDING) {
+ (VOID) KeWaitForSingleObject(&Event,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+ status = StatusBlock.Status;
+ }
+
+ if (!NT_SUCCESS(status))
+ goto fail2;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Fdo->LowerBusInterface.Version != 1)
+ goto fail3;
+
+ return STATUS_SUCCESS;
+
+fail3:
+ Error("fail3\n");
+
+fail2:
+ Error("fail2\n");
+
+fail1:
+ Error("fail1 (%08x)\n", status);
+
+ return status;
+}
+
+static FORCEINLINE VOID
+__FdoReleaseLowerBusInterface(
+ IN PXENVIF_FDO Fdo
+ )
+{
+ PBUS_INTERFACE_STANDARD BusInterface;
+
+ BusInterface = &Fdo->LowerBusInterface;
+ BusInterface->InterfaceDereference(BusInterface->Context);
+
+ RtlZeroMemory(BusInterface, sizeof (BUS_INTERFACE_STANDARD));
+}
+
static NTSTATUS
FdoQueryEvtchnInterface(
IN PXENVIF_FDO Fdo
NTSTATUS
FdoCreate(
- IN PDEVICE_OBJECT PhysicalDeviceObject
+ IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
- PDEVICE_OBJECT FunctionDeviceObject;
- PXENVIF_DX Dx;
- PXENVIF_FDO Fdo;
- WCHAR Name[MAXNAMELEN * sizeof (WCHAR)];
- ULONG Size;
- NTSTATUS status;
+ PDEVICE_OBJECT FunctionDeviceObject;
+ PXENVIF_DX Dx;
+ PXENVIF_FDO Fdo;
+ PBUS_INTERFACE_STANDARD BusInterface;
+ USHORT DeviceID;
+ NTSTATUS status;
#pragma prefast(suppress:28197) // Possibly leaking memory 'FunctionDeviceObject'
- status = IoCreateDevice(DriverObject,
+ status = IoCreateDevice(DriverGetDriverObject(),
sizeof (XENVIF_DX),
NULL,
FILE_DEVICE_BUS_EXTENDER,
if (!NT_SUCCESS(status))
goto fail4;
- status = IoGetDeviceProperty(PhysicalDeviceObject,
- DevicePropertyLocationInformation,
- sizeof (Name),
- Name,
- &Size);
+ status = __FdoAcquireLowerBusInterface(Fdo);
if (!NT_SUCCESS(status))
goto fail5;
- status = __FdoSetName(Fdo, Name);
- if (!NT_SUCCESS(status))
+ BusInterface = &Fdo->LowerBusInterface;
+
+ status = STATUS_UNSUCCESSFUL;
+ if (BusInterface->GetBusData(BusInterface->Context,
+ PCI_WHICHSPACE_CONFIG,
+ &DeviceID,
+ FIELD_OFFSET(PCI_COMMON_HEADER, DeviceID),
+ FIELD_SIZE(PCI_COMMON_HEADER, DeviceID)) == 0)
goto fail6;
+ __FdoSetVendorName(Fdo, DeviceID);
+
+ __FdoSetName(Fdo);
+
status = FdoQueryEvtchnInterface(Fdo);
if (!NT_SUCCESS(status))
goto fail7;
fail7:
Error("fail7\n");
+ RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
+
fail6:
Error("fail6\n");
+ __FdoReleaseLowerBusInterface(Fdo);
+
fail5:
Error("fail5\n");
Dx->Fdo = NULL;
- RtlZeroMemory(&Fdo->Mutex, sizeof (XENVIF_MUTEX));
+ RtlZeroMemory(&Fdo->Mutex, sizeof (MUTEX));
Fdo->EmulatedInterface = NULL;
Fdo->SuspendInterface = NULL;
Fdo->DebugInterface = NULL;
Fdo->EvtchnInterface = NULL;
+ RtlZeroMemory(Fdo->VendorName, MAXNAMELEN);
+
+ __FdoReleaseLowerBusInterface(Fdo);
+
ThreadAlert(Fdo->DevicePowerThread);
ThreadJoin(Fdo->DevicePowerThread);
Fdo->DevicePowerThread = NULL;
IN PXENVIF_FDO Fdo
);
-extern VOID
-FdoReap(
- IN PXENVIF_FDO Fdo
+extern PDMA_ADAPTER
+FdoGetDmaAdapter(
+ IN PXENVIF_FDO Fdo,
+ IN PDEVICE_DESCRIPTION DeviceDescriptor,
+ OUT PULONG NumberOfMapRegisters
+ );
+
+extern BOOLEAN
+FdoTranslateBusAddress(
+ IN PXENVIF_FDO Fdo,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN ULONG Length,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+extern ULONG
+FdoSetBusData(
+ IN PXENVIF_FDO Fdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+extern ULONG
+FdoGetBusData(
+ IN PXENVIF_FDO Fdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
);
extern NTSTATUS
#include "tcpip.h"
#include "receiver.h"
#include "transmitter.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
struct _XENVIF_FRONTEND {
+++ /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_LOG_H
-#define _XENVIF_LOG_H
-
-#include <ntddk.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 // _XENVIF_LOG_H
#include "frontend.h"
#include "mac.h"
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
struct _XENVIF_MAC {
#include "assert.h"
-typedef struct _XENVIF_MUTEX {
- PKTHREAD Owner;
- KEVENT Event;
-} XENVIF_MUTEX, *PXENVIF_MUTEX;
+typedef struct _MUTEX {
+ PKTHREAD Owner;
+ KEVENT Event;
+} MUTEX, *PMUTEX;
static FORCEINLINE VOID
InitializeMutex(
- IN PXENVIF_MUTEX Mutex
+ IN PMUTEX Mutex
)
{
- RtlZeroMemory(Mutex, sizeof (XENVIF_MUTEX));
+ RtlZeroMemory(Mutex, sizeof (MUTEX));
KeInitializeEvent(&Mutex->Event, SynchronizationEvent, TRUE);
}
static FORCEINLINE VOID
__drv_maxIRQL(PASSIVE_LEVEL)
AcquireMutex(
- IN PXENVIF_MUTEX Mutex
+ IN PMUTEX Mutex
)
{
(VOID) KeWaitForSingleObject(&Mutex->Event,
static FORCEINLINE VOID
__drv_maxIRQL(PASSIVE_LEVEL)
ReleaseMutex(
- IN PXENVIF_MUTEX Mutex
+ IN PMUTEX Mutex
)
{
ASSERT3P(Mutex->Owner, ==, KeGetCurrentThread());
#include <ntddk.h>
#include <xen.h>
-#include "types.h"
-
static FORCEINLINE const CHAR *
PowerTypeName(
IN POWER_STATE_TYPE Type
#undef _POWER_MINOR_FUNCTION_NAME
}
-static FORCEINLINE const CHAR *
-PnpDeviceStateName(
- IN DEVICE_PNP_STATE State
- )
-{
-#define _PNP_DEVICE_STATE_NAME(_State) \
- case _State: \
- return #_State;
-
- switch (State) {
- _PNP_DEVICE_STATE_NAME(Invalid);
- _PNP_DEVICE_STATE_NAME(Present);
- _PNP_DEVICE_STATE_NAME(Enumerated);
- _PNP_DEVICE_STATE_NAME(Added);
- _PNP_DEVICE_STATE_NAME(Started);
- _PNP_DEVICE_STATE_NAME(StopPending);
- _PNP_DEVICE_STATE_NAME(Stopped);
- _PNP_DEVICE_STATE_NAME(RemovePending);
- _PNP_DEVICE_STATE_NAME(SurpriseRemovePending);
- _PNP_DEVICE_STATE_NAME(Deleted);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#undef _STATE_NAME
-}
-
static FORCEINLINE const CHAR *
PnpMinorFunctionName(
IN ULONG Function
#undef _PARTIAL_RESOURCE_DESCRIPTOR_TYPE_NAME
}
+static FORCEINLINE const CHAR *
+DeviceUsageTypeName(
+ IN DEVICE_USAGE_NOTIFICATION_TYPE Type
+ )
+{
+#define _DEVICE_USAGE_TYPE_NAME(_Type) \
+ case DeviceUsageType ## _Type: \
+ return #_Type;
+
+ switch (Type) {
+ _DEVICE_USAGE_TYPE_NAME(Paging);
+ _DEVICE_USAGE_TYPE_NAME(Hibernation);
+ _DEVICE_USAGE_TYPE_NAME(DumpFile);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _DEVICE_USAGE_TYPE_NAME
+}
+
+static FORCEINLINE const CHAR *
+InterfaceTypeName(
+ IN INTERFACE_TYPE Type
+ )
+{
+#define _INTERFACE_TYPE_NAME(_Type) \
+ case _Type: \
+ return #_Type;
+
+ switch (Type) {
+ _INTERFACE_TYPE_NAME(InterfaceTypeUndefined);
+ _INTERFACE_TYPE_NAME(Internal);
+ _INTERFACE_TYPE_NAME(Isa);
+ _INTERFACE_TYPE_NAME(Eisa);
+ _INTERFACE_TYPE_NAME(MicroChannel);
+ _INTERFACE_TYPE_NAME(TurboChannel);
+ _INTERFACE_TYPE_NAME(PCIBus);
+ _INTERFACE_TYPE_NAME(VMEBus);
+ _INTERFACE_TYPE_NAME(NuBus);
+ _INTERFACE_TYPE_NAME(PCMCIABus);
+ _INTERFACE_TYPE_NAME(CBus);
+ _INTERFACE_TYPE_NAME(MPIBus);
+ _INTERFACE_TYPE_NAME(MPSABus);
+ _INTERFACE_TYPE_NAME(ProcessorInternal);
+ _INTERFACE_TYPE_NAME(InternalPowerBus);
+ _INTERFACE_TYPE_NAME(PNPISABus);
+ _INTERFACE_TYPE_NAME(PNPBus);
+ _INTERFACE_TYPE_NAME(Vmcs);
+ _INTERFACE_TYPE_NAME(ACPIBus);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _INTERFACE_TYPE_NAME
+}
+
+static FORCEINLINE const CHAR *
+DmaWidthName(
+ IN DMA_WIDTH Width
+ )
+{
+#define _DMA_WIDTH_NAME(_Width) \
+ case Width ## _Width: \
+ return #_Width;
+
+ switch (Width) {
+ _DMA_WIDTH_NAME(8Bits);
+ _DMA_WIDTH_NAME(16Bits);
+ _DMA_WIDTH_NAME(32Bits);
+ _DMA_WIDTH_NAME(64Bits);
+ _DMA_WIDTH_NAME(NoWrap);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _DMA_WIDTH_NAME
+}
+
+static FORCEINLINE const CHAR *
+DmaSpeedName(
+ IN DMA_SPEED Speed
+ )
+{
+#define _DMA_SPEED_NAME(_Speed) \
+ case _Speed: \
+ return #_Speed;
+
+ switch (Speed) {
+ _DMA_SPEED_NAME(Compatible);
+ _DMA_SPEED_NAME(TypeA);
+ _DMA_SPEED_NAME(TypeB);
+ _DMA_SPEED_NAME(TypeC);
+ _DMA_SPEED_NAME(TypeF);
+ _DMA_SPEED_NAME(MaximumDmaSpeed);
+ default:
+ break;
+ }
+
+ return "UNKNOWN";
+
+#undef _DMA_SPEED_NAME
+}
+
static FORCEINLINE const PCHAR
XenbusStateName(
IN XenbusState State
#undef _STATE_NAME
}
-static FORCEINLINE const CHAR *
-DeviceUsageTypeName(
- IN DEVICE_USAGE_NOTIFICATION_TYPE Type
- )
-{
-#define _DEVICE_USAGE_TYPE_NAME(_Type) \
- case DeviceUsageType ## _Type: \
- return #_Type;
-
- switch (Type) {
- _DEVICE_USAGE_TYPE_NAME(Paging);
- _DEVICE_USAGE_TYPE_NAME(Hibernation);
- _DEVICE_USAGE_TYPE_NAME(DumpFile);
- default:
- break;
- }
-
- return "UNKNOWN";
-
-#undef _DEVICE_USAGE_TYPE_NAME
-}
-
#endif // _XENVIF_NAMES_H_
#include "notifier.h"
#include "receiver.h"
#include "transmitter.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
struct _XENVIF_NOTIFIER {
#include <vif_interface.h>
#include "parse.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
static FORCEINLINE NTSTATUS
#include "names.h"
#include "fdo.h"
#include "pdo.h"
+#include "bus.h"
#include "frontend.h"
#include "vif.h"
#include "driver.h"
#include "registry.h"
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define PDO_REVISION 0x02
#define PDO_POOL 'ODP'
-typedef enum _PDO_RESOURCE_TYPE {
- MEMORY_RESOURCE = 0,
- INTERRUPT_RESOURCE,
- RESOURCE_COUNT
-} PDO_RESOURCE_TYPE, *PPDO_RESOURCE_TYPE;
-
-typedef struct _PDO_RESOURCE {
- CM_PARTIAL_RESOURCE_DESCRIPTOR Raw;
- CM_PARTIAL_RESOURCE_DESCRIPTOR Translated;
-} PDO_RESOURCE, *PPDO_RESOURCE;
-
struct _XENVIF_PDO {
PXENVIF_DX Dx;
ULONG LuidIndex;
PCHAR Address;
+ BUS_INTERFACE_STANDARD BusInterface;
+
PXENVIF_FRONTEND Frontend;
XENVIF_VIF_INTERFACE VifInterface;
PXENVIF_DX Dx = Pdo->Dx;
NTSTATUS status;
- status = RtlStringCbPrintfA(Dx->Name, MAX_DEVICE_ID_LEN, "%Z", Ansi);
+ status = RtlStringCbPrintfA(Dx->Name,
+ MAX_DEVICE_ID_LEN,
+ "%Z",
+ Ansi);
ASSERT(NT_SUCCESS(status));
}
return __PdoGetVifInterface(Pdo);
}
+PDMA_ADAPTER
+PdoGetDmaAdapter(
+ IN PXENVIF_PDO Pdo,
+ IN PDEVICE_DESCRIPTION DeviceDescriptor,
+ OUT PULONG NumberOfMapRegisters
+ )
+{
+ Trace("<===>\n");
+
+ return FdoGetDmaAdapter(__PdoGetFdo(Pdo),
+ DeviceDescriptor,
+ NumberOfMapRegisters);
+}
+
+BOOLEAN
+PdoTranslateBusAddress(
+ IN PXENVIF_PDO Pdo,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN ULONG Length,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ )
+{
+ Trace("<===>\n");
+
+ return FdoTranslateBusAddress(__PdoGetFdo(Pdo),
+ BusAddress,
+ Length,
+ AddressSpace,
+ TranslatedAddress);
+}
+
+ULONG
+PdoSetBusData(
+ IN PXENVIF_PDO Pdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ Trace("<===>\n");
+
+ return FdoSetBusData(__PdoGetFdo(Pdo),
+ DataType,
+ Buffer,
+ Offset,
+ Length);
+}
+
+ULONG
+PdoGetBusData(
+ IN PXENVIF_PDO Pdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ )
+{
+ Trace("<===>\n");
+
+ return FdoGetBusData(__PdoGetFdo(Pdo),
+ DataType,
+ Buffer,
+ Offset,
+ Length);
+}
+
VOID
PdoRequestEject(
IN PXENVIF_PDO Pdo
if (EmulatedInterface != NULL) {
EMULATED(Acquire, EmulatedInterface);
- Present = EMULATED(IsPresent,
+ Present = EMULATED(IsDevicePresent,
EmulatedInterface,
- "VIF",
- __PdoGetName(Pdo));
+ NULL,
+ NULL);
EMULATED(Release, EmulatedInterface);
} else {
NTSTATUS status;
#pragma prefast(suppress:28197) // Possibly leaking memory 'PhysicalDeviceObject'
- status = IoCreateDevice(DriverObject,
+ status = IoCreateDevice(DriverGetDriverObject(),
sizeof(XENVIF_DX),
NULL,
FILE_DEVICE_UNKNOWN,
__PdoSetName(Pdo, Name);
- status = FrontendInitialize(Pdo, &Pdo->Frontend);
+ status = BusInitialize(Pdo, &Pdo->BusInterface);
if (!NT_SUCCESS(status))
goto fail5;
- status = VifInitialize(Pdo, &Pdo->VifInterface);
+ status = FrontendInitialize(Pdo, &Pdo->Frontend);
if (!NT_SUCCESS(status))
goto fail6;
+ status = VifInitialize(Pdo, &Pdo->VifInterface);
+ if (!NT_SUCCESS(status))
+ goto fail7;
+
Info("%p (XENVIF\\DEVICE&REV_%02X#%s)\n",
PhysicalDeviceObject,
PDO_REVISION,
return STATUS_SUCCESS;
-fail6:
- Error("fail6\n");
+fail7:
+ Error("fail7\n");
FrontendTeardown(Pdo->Frontend);
Pdo->Frontend = NULL;
+
+fail6:
+ Error("fail6\n");
+
+ BusTeardown(&Pdo->BusInterface);
+
fail5:
Error("fail5\n");
FrontendTeardown(__PdoGetFrontend(Pdo));
Pdo->Frontend = NULL;
+ BusTeardown(&Pdo->BusInterface);
+
ThreadAlert(Pdo->DevicePowerThread);
ThreadJoin(Pdo->DevicePowerThread);
Pdo->DevicePowerThread = NULL;
IN PXENVIF_PDO Pdo
);
+extern PDMA_ADAPTER
+PdoGetDmaAdapter(
+ IN PXENVIF_PDO Pdo,
+ IN PDEVICE_DESCRIPTION DeviceDescriptor,
+ OUT PULONG NumberOfMapRegisters
+ );
+
+extern BOOLEAN
+PdoTranslateBusAddress(
+ IN PXENVIF_PDO Pdo,
+ IN PHYSICAL_ADDRESS BusAddress,
+ IN ULONG Length,
+ IN OUT PULONG AddressSpace,
+ OUT PPHYSICAL_ADDRESS TranslatedAddress
+ );
+
+extern ULONG
+PdoSetBusData(
+ IN PXENVIF_PDO Pdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
+extern ULONG
+PdoGetBusData(
+ IN PXENVIF_PDO Pdo,
+ IN ULONG DataType,
+ IN PVOID Buffer,
+ IN ULONG Offset,
+ IN ULONG Length
+ );
+
extern ULONG
PdoGetLuidIndex(
IN PXENVIF_PDO Pdo
#include "pool.h"
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define POOL_POOL 'OBJE'
#include "ethernet.h"
#include "tcpip.h"
#include "pdo.h"
+#include "registry.h"
#include "frontend.h"
#include "pool.h"
#include "checksum.h"
#include "vif.h"
#include "receiver.h"
#include "driver.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define RECEIVER_POOL 'ECER'
LONG Returned;
KEVENT Event;
+ ULONG MaximumProtocol;
+ ULONG CalculateChecksums;
+ ULONG AllowGsoPackets;
+ ULONG IpAlignOffset;
+ ULONG AlwaysPullup;
+
PXENBUS_DEBUG_INTERFACE DebugInterface;
PXENBUS_STORE_INTERFACE StoreInterface;
PXENBUS_GNTTAB_INTERFACE GnttabInterface;
}
static DECLSPEC_NOINLINE VOID
-PacketProcessTag(
- IN PXENVIF_RECEIVER_PACKET Packet,
- IN PXENVIF_OFFLOAD_OPTIONS OffloadOptions,
- IN PRECEIVER_OFFLOAD_STATISTICS OffloadStatistics
+RingProcessTag(
+ IN PRECEIVER_RING Ring,
+ IN PXENVIF_RECEIVER_PACKET Packet
)
{
- PXENVIF_PACKET_INFO Info;
- ULONG PayloadLength;
- PUCHAR StartVa;
- PETHERNET_HEADER EthernetHeader;
- ULONG Offset;
+ PXENVIF_PACKET_INFO Info;
+ ULONG PayloadLength;
+ PUCHAR StartVa;
+ PETHERNET_HEADER EthernetHeader;
+ ULONG Offset;
Info = &Packet->Info;
EthernetHeader = (PETHERNET_HEADER)(StartVa + Info->EthernetHeader.Offset);
if (!ETHERNET_HEADER_IS_TAGGED(EthernetHeader) ||
- OffloadOptions->OffloadTagManipulation == 0)
+ Ring->OffloadOptions.OffloadTagManipulation == 0)
return;
Packet->TagControlInformation = NTOHS(EthernetHeader->Tagged.Tag.ControlInformation);
ASSERT3U(PayloadLength, ==, Packet->Length - Info->Length);
- OffloadStatistics->TagRemoved++;
+ Ring->OffloadStatistics.TagRemoved++;
}
static DECLSPEC_NOINLINE VOID
-PacketProcessChecksum(
- IN PXENVIF_RECEIVER_PACKET Packet,
- IN PXENVIF_OFFLOAD_OPTIONS OffloadOptions,
- IN PRECEIVER_OFFLOAD_STATISTICS OffloadStatistics
+RingProcessChecksum(
+ IN PRECEIVER_RING Ring,
+ IN PXENVIF_RECEIVER_PACKET Packet
)
{
- PXENVIF_PACKET_INFO Info;
- XENVIF_PACKET_PAYLOAD Payload;
- uint16_t flags;
- PUCHAR StartVa;
- PIP_HEADER IpHeader;
- BOOLEAN IsAFragment;
+ PXENVIF_RECEIVER Receiver;
+ PXENVIF_PACKET_INFO Info;
+ XENVIF_PACKET_PAYLOAD Payload;
+ uint16_t flags;
+ PUCHAR StartVa;
+ PIP_HEADER IpHeader;
+ BOOLEAN IsAFragment;
+
+ Receiver = Ring->Receiver;
Info = &Packet->Info;
if (IpHeader->Version == 4) {
BOOLEAN OffloadChecksum;
- if (OffloadOptions->OffloadIpVersion4HeaderChecksum)
+ if (Ring->OffloadOptions.OffloadIpVersion4HeaderChecksum)
OffloadChecksum = TRUE;
else
OffloadChecksum = FALSE;
Embedded = IpHeader->Version4.Checksum;
Calculated = ChecksumIpVersion4Header(StartVa, Info);
- OffloadStatistics->IpVersion4HeaderChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion4HeaderChecksumCalculated++;
if (Embedded == Calculated) {
Packet->Flags.IpChecksumSucceeded = 1;
- OffloadStatistics->IpVersion4HeaderChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion4HeaderChecksumSucceeded++;
} else {
Packet->Flags.IpChecksumFailed = 1;
- OffloadStatistics->IpVersion4HeaderChecksumFailed++;
+ Ring->OffloadStatistics.IpVersion4HeaderChecksumFailed++;
}
}
if (!OffloadChecksum ||
- OffloadOptions->NeedChecksumValue ||
- DriverParameters.ReceiverCalculateChecksums) { // Checksum must be present
+ Ring->OffloadOptions.NeedChecksumValue ||
+ Receiver->CalculateChecksums) { // Checksum must be present
Packet->Flags.IpChecksumPresent = 1;
- OffloadStatistics->IpVersion4HeaderChecksumPresent++;
+ Ring->OffloadStatistics.IpVersion4HeaderChecksumPresent++;
} else {
IpHeader->Version4.Checksum = 0;
}
TcpHeader = (PTCP_HEADER)(StartVa + Info->TcpHeader.Offset);
- if (IpHeader->Version == 4 && OffloadOptions->OffloadIpVersion4TcpChecksum)
+ if (IpHeader->Version == 4 && Ring->OffloadOptions.OffloadIpVersion4TcpChecksum)
OffloadChecksum = TRUE;
- else if (IpHeader->Version == 6 && OffloadOptions->OffloadIpVersion6TcpChecksum)
+ else if (IpHeader->Version == 6 && Ring->OffloadOptions.OffloadIpVersion6TcpChecksum)
OffloadChecksum = TRUE;
else
OffloadChecksum = FALSE;
Packet->Flags.TcpChecksumSucceeded = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4TcpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion4TcpChecksumSucceeded++;
else
- OffloadStatistics->IpVersion6TcpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion6TcpChecksumSucceeded++;
} else { // Checksum is present but is not validated
USHORT Embedded;
Calculated = ChecksumTcpPacket(StartVa, Info, Calculated, &Payload);
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4TcpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion4TcpChecksumCalculated++;
else
- OffloadStatistics->IpVersion6TcpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion6TcpChecksumCalculated++;
if (Embedded == Calculated) {
Packet->Flags.TcpChecksumSucceeded = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4TcpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion4TcpChecksumSucceeded++;
else
- OffloadStatistics->IpVersion6TcpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion6TcpChecksumSucceeded++;
} else {
Packet->Flags.TcpChecksumFailed = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4TcpChecksumFailed++;
+ Ring->OffloadStatistics.IpVersion4TcpChecksumFailed++;
else
- OffloadStatistics->IpVersion6TcpChecksumFailed++;
+ Ring->OffloadStatistics.IpVersion6TcpChecksumFailed++;
}
}
}
if (!OffloadChecksum ||
- OffloadOptions->NeedChecksumValue ||
- DriverParameters.ReceiverCalculateChecksums) { // Checksum must be present
- if (flags & NETRXF_csum_blank) { // Checksum is not present
+ Ring->OffloadOptions.NeedChecksumValue ||
+ Receiver->CalculateChecksums) { // Checksum must be present
+ if (flags & NETRXF_csum_blank) { // Checksum is not present
USHORT Calculated;
Calculated = ChecksumPseudoHeader(StartVa, Info);
Calculated = ChecksumTcpPacket(StartVa, Info, Calculated, &Payload);
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4TcpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion4TcpChecksumCalculated++;
else
- OffloadStatistics->IpVersion6TcpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion6TcpChecksumCalculated++;
TcpHeader->Checksum = Calculated;
}
Packet->Flags.TcpChecksumPresent = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4TcpChecksumPresent++;
+ Ring->OffloadStatistics.IpVersion4TcpChecksumPresent++;
else
- OffloadStatistics->IpVersion6TcpChecksumPresent++;
+ Ring->OffloadStatistics.IpVersion6TcpChecksumPresent++;
} else {
TcpHeader->Checksum = 0;
}
-
} else if (Info->UdpHeader.Length != 0 && !IsAFragment) {
PUDP_HEADER UdpHeader;
BOOLEAN OffloadChecksum;
UdpHeader = (PUDP_HEADER)(StartVa + Info->UdpHeader.Offset);
- if (IpHeader->Version == 4 && OffloadOptions->OffloadIpVersion4UdpChecksum)
+ if (IpHeader->Version == 4 && Ring->OffloadOptions.OffloadIpVersion4UdpChecksum)
OffloadChecksum = TRUE;
- else if (IpHeader->Version == 6 && OffloadOptions->OffloadIpVersion6UdpChecksum)
+ else if (IpHeader->Version == 6 && Ring->OffloadOptions.OffloadIpVersion6UdpChecksum)
OffloadChecksum = TRUE;
else
OffloadChecksum = FALSE;
Packet->Flags.UdpChecksumSucceeded = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4UdpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion4UdpChecksumSucceeded++;
else
- OffloadStatistics->IpVersion6UdpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion6UdpChecksumSucceeded++;
} else { // Checksum is present but is not validated
USHORT Embedded;
Calculated = ChecksumUdpPacket(StartVa, Info, Calculated, &Payload);
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4UdpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion4UdpChecksumCalculated++;
else
- OffloadStatistics->IpVersion6UdpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion6UdpChecksumCalculated++;
if (Embedded == Calculated) {
Packet->Flags.UdpChecksumSucceeded = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4UdpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion4UdpChecksumSucceeded++;
else
- OffloadStatistics->IpVersion6UdpChecksumSucceeded++;
+ Ring->OffloadStatistics.IpVersion6UdpChecksumSucceeded++;
} else {
Packet->Flags.UdpChecksumFailed = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4UdpChecksumFailed++;
+ Ring->OffloadStatistics.IpVersion4UdpChecksumFailed++;
else
- OffloadStatistics->IpVersion6UdpChecksumFailed++;
+ Ring->OffloadStatistics.IpVersion6UdpChecksumFailed++;
}
}
-
}
if (!OffloadChecksum ||
- OffloadOptions->NeedChecksumValue ||
- DriverParameters.ReceiverCalculateChecksums) { // Checksum must be present
- if (flags & NETRXF_csum_blank) { // Checksum is not present
+ Ring->OffloadOptions.NeedChecksumValue ||
+ Receiver->CalculateChecksums) { // Checksum must be present
+ if (flags & NETRXF_csum_blank) { // Checksum is not present
USHORT Calculated;
Calculated = ChecksumPseudoHeader(StartVa, Info);
Calculated = ChecksumUdpPacket(StartVa, Info, Calculated, &Payload);
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4UdpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion4UdpChecksumCalculated++;
else
- OffloadStatistics->IpVersion6UdpChecksumCalculated++;
+ Ring->OffloadStatistics.IpVersion6UdpChecksumCalculated++;
UdpHeader->Checksum = Calculated;
}
Packet->Flags.UdpChecksumPresent = 1;
if (IpHeader->Version == 4)
- OffloadStatistics->IpVersion4UdpChecksumPresent++;
+ Ring->OffloadStatistics.IpVersion4UdpChecksumPresent++;
else
- OffloadStatistics->IpVersion6UdpChecksumPresent++;
+ Ring->OffloadStatistics.IpVersion6UdpChecksumPresent++;
} else {
UdpHeader->Checksum = 0;
}
OUT PLIST_ENTRY List
)
{
+ PXENVIF_RECEIVER Receiver;
BOOLEAN Offload;
PXENVIF_PACKET_INFO Info;
uint16_t flags;
ULONG Length;
NTSTATUS status;
+ Receiver = Ring->Receiver;
+
Info = &Packet->Info;
flags = (uint16_t)(ULONG_PTR)Packet->Cookie;
if (Payload.Length < Packet->MaximumSegmentSize)
Packet->MaximumSegmentSize = 0;
- if (DriverParameters.ReceiverAlwaysPullup != 0)
+ if (Receiver->AlwaysPullup != 0)
__RingPullupPacket(Ring, Packet);
ASSERT(IsZeroMemory(&Packet->ListEntry, sizeof (LIST_ENTRY)));
}
// Copy in the extracted metadata
- Packet->Offset = DriverParameters.ReceiverIpAlignOffset;
+ Packet->Offset = Receiver->IpAlignOffset;
Packet->Length = Length;
Packet->MaximumSegmentSize = MaximumSegmentSize;
Packet->Cookie = Cookie;
// and, in practice, little else uses LLC so pull up all LLC
// packets into a single fragment.
if (Info->LLCSnapHeader.Length != 0 ||
- DriverParameters.ReceiverAlwaysPullup != 0)
+ Receiver->AlwaysPullup != 0)
__RingPullupPacket(Ring, Packet);
ASSERT(IsZeroMemory(&Packet->ListEntry, sizeof (LIST_ENTRY)));
Packet = CONTAINING_RECORD(ListEntry, XENVIF_RECEIVER_PACKET, ListEntry);
- PacketProcessTag(Packet,
- &Ring->OffloadOptions,
- &Ring->OffloadStatistics);
-
- PacketProcessChecksum(Packet,
- &Ring->OffloadOptions,
- &Ring->OffloadStatistics);
+ RingProcessTag(Ring, Packet);
+ RingProcessChecksum(Ring, Packet);
Packet->Cookie = Ring;
OUT PXENVIF_RECEIVER *Receiver
)
{
+ HANDLE ParametersKey;
ULONG Done;
NTSTATUS status;
if (*Receiver == NULL)
goto fail1;
+ ParametersKey = DriverGetParametersKey();
+
+ (*Receiver)->MaximumProtocol = 0;
+ (*Receiver)->CalculateChecksums = 1;
+ (*Receiver)->AllowGsoPackets = 1;
+ (*Receiver)->IpAlignOffset = 0;
+ (*Receiver)->AlwaysPullup = 0;
+
+ if (ParametersKey != NULL) {
+ ULONG ReceiverMaximumProtocol;
+ ULONG ReceiverCalculateChecksums;
+ ULONG ReceiverAllowGsoPackets;
+ ULONG ReceiverIpAlignOffset;
+ ULONG ReceiverAlwaysPullup;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "ReceiverMaximumProtocol",
+ &ReceiverMaximumProtocol);
+ if (NT_SUCCESS(status))
+ (*Receiver)->MaximumProtocol = ReceiverMaximumProtocol;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "ReceiverCalculateChecksums",
+ &ReceiverCalculateChecksums);
+ if (NT_SUCCESS(status))
+ (*Receiver)->CalculateChecksums = ReceiverCalculateChecksums;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "ReceiverAllowGsoPackets",
+ &ReceiverAllowGsoPackets);
+ if (NT_SUCCESS(status))
+ (*Receiver)->AllowGsoPackets = ReceiverAllowGsoPackets;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "ReceiverIpAlignOffset",
+ &ReceiverIpAlignOffset);
+ if (NT_SUCCESS(status))
+ (*Receiver)->IpAlignOffset = ReceiverIpAlignOffset;
+
+ status = RegistryQueryDwordValue(ParametersKey,
+ "ReceiverAlwaysPullup",
+ &ReceiverAlwaysPullup);
+ if (NT_SUCCESS(status))
+ (*Receiver)->AlwaysPullup = ReceiverAlwaysPullup;
+ }
+
InitializeListHead(&(*Receiver)->List);
KeInitializeEvent(&(*Receiver)->Event, NotificationEvent, FALSE);
RtlZeroMemory(&(*Receiver)->Event, sizeof (KEVENT));
RtlZeroMemory(&(*Receiver)->List, sizeof (LIST_ENTRY));
+ (*Receiver)->MaximumProtocol = 0;
+ (*Receiver)->CalculateChecksums = 0;
+ (*Receiver)->AllowGsoPackets = 0;
+ (*Receiver)->IpAlignOffset = 0;
+ (*Receiver)->AlwaysPullup = 0;
+
ASSERT(IsZeroMemory(*Receiver, sizeof (XENVIF_RECEIVER)));
__ReceiverFree(*Receiver);
}
MinimumProtocol = __max(MinimumProtocol, RECEIVER_MINIMUM_PROTOCOL);
- MaximumProtocol = __min(MaximumProtocol, DriverParameters.ReceiverMaximumProtocol);
+ MaximumProtocol = __min(MaximumProtocol, Receiver->MaximumProtocol);
status = STATUS_NOT_SUPPORTED;
if (MaximumProtocol < MinimumProtocol)
RtlZeroMemory(&Receiver->Event, sizeof (KEVENT));
RtlZeroMemory(&Receiver->List, sizeof (LIST_ENTRY));
+ Receiver->MaximumProtocol = 0;
+ Receiver->CalculateChecksums = 0;
+ Receiver->AllowGsoPackets = 0;
+ Receiver->IpAlignOffset = 0;
+ Receiver->AlwaysPullup = 0;
+
ASSERT(IsZeroMemory(Receiver, sizeof (XENVIF_RECEIVER)));
__ReceiverFree(Receiver);
}
{
PLIST_ENTRY ListEntry;
- if (DriverParameters.ReceiverAllowGsoPackets == 0) {
+ if (Receiver->AllowGsoPackets == 0) {
Options.OffloadIpVersion4LargePacket = 0;
Options.OffloadIpVersion6LargePacket = 0;
}
#include <util.h>
#include "registry.h"
-#include "log.h"
#include "assert.h"
#define REGISTRY_POOL 'GERX'
}
NTSTATUS
-RegistryOpenSubKey(
- IN PCHAR Name,
+RegistryOpenServiceKey(
IN ACCESS_MASK DesiredAccess,
OUT PHANDLE Key
)
{
- ANSI_STRING Ansi;
- UNICODE_STRING Unicode;
OBJECT_ATTRIBUTES Attributes;
- HANDLE ServiceKey;
NTSTATUS status;
- RtlInitAnsiString(&Ansi, Name);
-
- status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
- if (!NT_SUCCESS(status))
- goto fail1;
-
InitializeObjectAttributes(&Attributes,
&RegistryPath,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
- status = ZwOpenKey(&ServiceKey,
- KEY_ALL_ACCESS,
+ status = ZwOpenKey(Key,
+ DesiredAccess,
&Attributes);
if (!NT_SUCCESS(status))
- goto fail2;
+ goto fail1;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryOpenSoftwareKey(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE Key
+ )
+{
+ NTSTATUS status;
+
+ status = IoOpenDeviceRegistryKey(DeviceObject,
+ PLUGPLAY_REGKEY_DRIVER,
+ DesiredAccess,
+ Key);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryOpenHardwareKey(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE Key
+ )
+{
+ NTSTATUS status;
+
+ status = IoOpenDeviceRegistryKey(DeviceObject,
+ PLUGPLAY_REGKEY_DEVICE,
+ DesiredAccess,
+ Key);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ return STATUS_SUCCESS;
+
+fail1:
+ return status;
+}
+
+NTSTATUS
+RegistryOpenSubKey(
+ IN PHANDLE Key,
+ IN PCHAR Name,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE SubKey
+ )
+{
+ ANSI_STRING Ansi;
+ UNICODE_STRING Unicode;
+ OBJECT_ATTRIBUTES Attributes;
+ NTSTATUS status;
+
+ RtlInitAnsiString(&Ansi, Name);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail1;
InitializeObjectAttributes(&Attributes,
&Unicode,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- ServiceKey,
+ Key,
NULL);
- status = ZwOpenKey(Key,
+ status = ZwOpenKey(SubKey,
DesiredAccess,
&Attributes);
if (!NT_SUCCESS(status))
- goto fail3;
-
- ZwClose(ServiceKey);
+ goto fail2;
RtlFreeUnicodeString(&Unicode);
return STATUS_SUCCESS;
-fail3:
- ZwClose(ServiceKey);
-
fail2:
RtlFreeUnicodeString(&Unicode);
NTSTATUS
RegistryCreateSubKey(
+ IN PHANDLE Key,
IN PCHAR Name
)
{
ANSI_STRING Ansi;
UNICODE_STRING Unicode;
OBJECT_ATTRIBUTES Attributes;
- HANDLE ServiceKey;
- HANDLE Key;
+ HANDLE SubKey;
NTSTATUS status;
RtlInitAnsiString(&Ansi, Name);
if (!NT_SUCCESS(status))
goto fail1;
- InitializeObjectAttributes(&Attributes,
- &RegistryPath,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
- NULL);
-
- status = ZwOpenKey(&ServiceKey,
- KEY_ALL_ACCESS,
- &Attributes);
- if (!NT_SUCCESS(status))
- goto fail2;
-
InitializeObjectAttributes(&Attributes,
&Unicode,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- ServiceKey,
+ Key,
NULL);
- status = ZwCreateKey(&Key,
+ status = ZwCreateKey(&SubKey,
KEY_ALL_ACCESS,
&Attributes,
0,
NULL,
- REG_OPTION_VOLATILE,
+ REG_OPTION_NON_VOLATILE,
NULL
);
if (!NT_SUCCESS(status))
- goto fail3;
-
- ZwClose(Key);
+ goto fail2;
- ZwClose(ServiceKey);
+ ZwClose(SubKey);
RtlFreeUnicodeString(&Unicode);
return STATUS_SUCCESS;
-fail3:
- ZwClose(ServiceKey);
-
fail2:
RtlFreeUnicodeString(&Unicode);
NTSTATUS
RegistryDeleteSubKey(
+ IN PHANDLE Key,
IN PCHAR Name
)
{
ANSI_STRING Ansi;
UNICODE_STRING Unicode;
OBJECT_ATTRIBUTES Attributes;
- HANDLE ServiceKey;
- HANDLE Key;
+ HANDLE SubKey;
NTSTATUS status;
RtlInitAnsiString(&Ansi, Name);
goto fail1;
InitializeObjectAttributes(&Attributes,
- &RegistryPath,
+ &Unicode,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- NULL,
+ Key,
NULL);
- status = ZwOpenKey(&ServiceKey,
+ status = ZwOpenKey(&SubKey,
KEY_ALL_ACCESS,
&Attributes);
if (!NT_SUCCESS(status))
goto fail2;
- InitializeObjectAttributes(&Attributes,
- &Unicode,
- OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
- ServiceKey,
- NULL);
-
- status = ZwOpenKey(&Key,
- KEY_ALL_ACCESS,
- &Attributes);
+ status = ZwDeleteKey(SubKey);
if (!NT_SUCCESS(status))
goto fail3;
- status = ZwDeleteKey(Key);
- if (!NT_SUCCESS(status))
- goto fail4;
-
- ZwClose(Key);
-
- ZwClose(ServiceKey);
+ ZwClose(SubKey);
RtlFreeUnicodeString(&Unicode);
return STATUS_SUCCESS;
-fail4:
- ZwClose(Key);
-
fail3:
- ZwClose(ServiceKey);
+ ZwClose(SubKey);
fail2:
RtlFreeUnicodeString(&Unicode);
return status;
}
-
NTSTATUS
-RegistryOpenSoftwareKey(
- IN PDEVICE_OBJECT DeviceObject,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
+RegistryEnumerateSubKeys(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
)
{
- NTSTATUS status;
+ ULONG Size;
+ NTSTATUS status;
+ PKEY_FULL_INFORMATION Full;
+ PKEY_BASIC_INFORMATION Basic;
+ ULONG Index;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
+ goto fail1;
- status = IoOpenDeviceRegistryKey(DeviceObject,
- PLUGPLAY_REGKEY_DRIVER,
- DesiredAccess,
- Key);
+ Full = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Full == NULL)
+ goto fail2;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ Full,
+ Size,
+ &Size);
if (!NT_SUCCESS(status))
- goto fail1;
+ goto fail3;
+
+ Size = FIELD_OFFSET(KEY_BASIC_INFORMATION, Name) +
+ Full->MaxNameLen;
+
+ Basic = __RegistryAllocate(Size);
+ status = STATUS_NO_MEMORY;
+ if (Basic == NULL)
+ goto fail4;
+
+ for (Index = 0; Index < Full->SubKeys; Index++) {
+ UNICODE_STRING Unicode;
+ ANSI_STRING Ansi;
+
+ status = ZwEnumerateKey(Key,
+ Index,
+ KeyBasicInformation,
+ Basic,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ Unicode.MaximumLength = (USHORT)Basic->NameLength;
+ Unicode.Buffer = Basic->Name;
+ Unicode.Length = (USHORT)Basic->NameLength;
+
+ Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
+ Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
+
+ status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
+ ASSERT(NT_SUCCESS(status));
+
+ Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
+
+ status = Callback(Context, Key, Ansi.Buffer);
+
+ __RegistryFree(Ansi.Buffer);
+
+ if (!NT_SUCCESS(status))
+ goto fail6;
+ }
+
+ __RegistryFree(Basic);
+
+ __RegistryFree(Full);
return STATUS_SUCCESS;
+fail6:
+fail5:
+ __RegistryFree(Basic);
+
+fail4:
+fail3:
+ __RegistryFree(Full);
+
+fail2:
fail1:
return status;
}
NTSTATUS
-RegistryOpenHardwareKey(
- IN PDEVICE_OBJECT DeviceObject,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
+RegistryEnumerateValues(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
)
{
- NTSTATUS status;
+ ULONG Size;
+ NTSTATUS status;
+ PKEY_FULL_INFORMATION Full;
+ PKEY_VALUE_BASIC_INFORMATION Basic;
+ ULONG Index;
- status = IoOpenDeviceRegistryKey(DeviceObject,
- PLUGPLAY_REGKEY_DEVICE,
- DesiredAccess,
- Key);
- if (!NT_SUCCESS(status))
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
goto fail1;
+ Full = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Full == NULL)
+ goto fail2;
+
+ status = ZwQueryKey(Key,
+ KeyFullInformation,
+ Full,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail3;
+
+ Size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name) +
+ Full->MaxValueNameLen;
+
+ Basic = __RegistryAllocate(Size);
+ status = STATUS_NO_MEMORY;
+ if (Basic == NULL)
+ goto fail4;
+
+ for (Index = 0; Index < Full->Values; Index++) {
+ UNICODE_STRING Unicode;
+ ANSI_STRING Ansi;
+
+ status = ZwEnumerateValueKey(Key,
+ Index,
+ KeyValueBasicInformation,
+ Basic,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail5;
+
+ Unicode.MaximumLength = (USHORT)Basic->NameLength;
+ Unicode.Buffer = Basic->Name;
+ Unicode.Length = (USHORT)Basic->NameLength;
+
+ Ansi.MaximumLength = (USHORT)((Basic->NameLength / sizeof (WCHAR)) + sizeof (CHAR));
+ Ansi.Buffer = __RegistryAllocate(Ansi.MaximumLength);
+
+ status = RtlUnicodeStringToAnsiString(&Ansi, &Unicode, FALSE);
+ ASSERT(NT_SUCCESS(status));
+
+ Ansi.Length = (USHORT)(strlen(Ansi.Buffer) * sizeof (CHAR));
+
+ status = Callback(Context, Key, Ansi.Buffer);
+
+ __RegistryFree(Ansi.Buffer);
+
+ if (!NT_SUCCESS(status))
+ goto fail6;
+ }
+
+ __RegistryFree(Basic);
+
+ __RegistryFree(Full);
+
return STATUS_SUCCESS;
+fail6:
+fail5:
+ __RegistryFree(Basic);
+
+fail4:
+fail3:
+ __RegistryFree(Full);
+
+fail2:
fail1:
return status;
}
return status;
}
+NTSTATUS
+RegistryQuerySystemStartOption(
+ IN PCHAR Prefix,
+ OUT PANSI_STRING *Value
+ )
+{
+ UNICODE_STRING Unicode;
+ OBJECT_ATTRIBUTES Attributes;
+ HANDLE Key;
+ PKEY_VALUE_PARTIAL_INFORMATION Partial;
+ ULONG Size;
+ ANSI_STRING Ansi;
+ PWCHAR Option;
+ PWCHAR Context;
+ NTSTATUS status;
+
+ RtlInitUnicodeString(&Unicode, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control");
+
+ InitializeObjectAttributes(&Attributes,
+ &Unicode,
+ OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
+ NULL,
+ NULL);
+
+ status = ZwOpenKey(&Key,
+ KEY_READ,
+ &Attributes);
+ if (!NT_SUCCESS(status))
+ goto fail1;
+
+ RtlInitUnicodeString(&Unicode, L"SystemStartOptions");
+
+ status = ZwQueryValueKey(Key,
+ &Unicode,
+ KeyValuePartialInformation,
+ NULL,
+ 0,
+ &Size);
+ if (status != STATUS_BUFFER_TOO_SMALL)
+ goto fail2;
+
+ Partial = __RegistryAllocate(Size);
+
+ status = STATUS_NO_MEMORY;
+ if (Partial == NULL)
+ goto fail3;
+
+ status = ZwQueryValueKey(Key,
+ &Unicode,
+ KeyValuePartialInformation,
+ Partial,
+ Size,
+ &Size);
+ if (!NT_SUCCESS(status))
+ goto fail4;
+
+ status = STATUS_INVALID_PARAMETER;
+ if (Partial->Type != REG_SZ)
+ goto fail5;
+
+ RtlInitAnsiString(&Ansi, Prefix);
+
+ status = RtlAnsiStringToUnicodeString(&Unicode, &Ansi, TRUE);
+ if (!NT_SUCCESS(status))
+ goto fail6;
+
+ // SystemStartOptions is a space separated list of options.
+ // Scan it looking for the one we want.
+ Option = __wcstok_r((PWCHAR)Partial->Data, L" ", &Context);
+ if (wcsncmp(Option, Unicode.Buffer, Unicode.Length / sizeof (WCHAR)) == 0)
+ goto found;
+
+ while ((Option = __wcstok_r(NULL, L" ", &Context)) != NULL)
+ if (wcsncmp(Option, Unicode.Buffer, Unicode.Length / sizeof (WCHAR)) == 0)
+ goto found;
+
+ status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto fail7;
+
+found:
+ *Value = RegistrySzToAnsi(Option);
+
+ status = STATUS_NO_MEMORY;
+ if (*Value == NULL)
+ goto fail8;
+
+ __RegistryFree(Partial);
+
+ RtlFreeUnicodeString(&Unicode);
+
+ ZwClose(Key);
+
+ return STATUS_SUCCESS;
+
+fail8:
+fail7:
+ RtlFreeUnicodeString(&Unicode);
+
+fail6:
+fail5:
+fail4:
+ __RegistryFree(Partial);
+
+fail3:
+fail2:
+ ZwClose(Key);
+
+fail1:
+ return status;
+}
+
static PKEY_VALUE_PARTIAL_INFORMATION
RegistryAnsiToSz(
PANSI_STRING Ansi
VOID
);
+extern NTSTATUS
+RegistryOpenServiceKey(
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE Key
+ );
+
+extern NTSTATUS
+RegistryOpenSoftwareKey(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE Key
+ );
+
+extern NTSTATUS
+RegistryOpenHardwareKey(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN ACCESS_MASK DesiredAccess,
+ OUT PHANDLE Key
+ );
+
extern NTSTATUS
RegistryOpenSubKey(
+ IN HANDLE Key,
IN PCHAR Name,
IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
+ OUT PHANDLE SubKey
);
extern NTSTATUS
RegistryCreateSubKey(
+ IN HANDLE Key,
IN PCHAR Name
);
extern NTSTATUS
RegistryDeleteSubKey(
+ IN HANDLE Key,
IN PCHAR Name
);
extern NTSTATUS
-RegistryOpenSoftwareKey(
- IN PDEVICE_OBJECT DeviceObject,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
+RegistryEnumerateSubKeys(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
);
extern NTSTATUS
-RegistryOpenHardwareKey(
- IN PDEVICE_OBJECT DeviceObject,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE Key
+RegistryEnumerateValues(
+ IN HANDLE Key,
+ IN NTSTATUS (*Callback)(PVOID, HANDLE, PCHAR),
+ IN PVOID Context
);
extern NTSTATUS
OUT PANSI_STRING *Array
);
+extern NTSTATUS
+RegistryQuerySystemStartOption(
+ IN PCHAR Name,
+ OUT PANSI_STRING *Option
+ );
+
extern VOID
RegistryFreeSzValue(
IN PANSI_STRING Array
#include <util.h>
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define THREAD_POOL 'ERHT'
#include "mac.h"
#include "vif.h"
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define TRANSMITTER_POOL 'NART'
#include "vif.h"
#include "mrsw.h"
#include "thread.h"
-#include "log.h"
+#include "dbg_print.h"
#include "assert.h"
#define VIF_POOL ' FIV'
#include <version.h>
-#define VER_PRODUCTNAME_STR "Citrix PV Tools for Virtual Machines"
+#define VER_PRODUCTNAME_STR "XENVIF"
#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 "XENVIF.SYS"
-#define VER_FILEDESCRIPTION_STR "Citrix VIF Class Driver"
+#define VER_FILEDESCRIPTION_STR "XENVIF"
#define VER_FILETYPE VFT_DRV
#define VER_FILESUBTYPE VFT2_DRV_SYSTEM